-
Notifications
You must be signed in to change notification settings - Fork 6
/
phy.go
83 lines (75 loc) · 2.15 KB
/
phy.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
// Copyright 2016 Platina Systems, Inc. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package ixge
import (
"github.com/platinasystems/vnet/devices/phy/xge"
)
func (d *dev) rw_phy_reg(dev_type, reg_index, v reg, is_read bool) (w reg) {
const busy_bit = 1 << 30
sync_mask := reg(1) << (1 + d.phy_index)
d.software_firmware_sync(sync_mask, 0)
if !is_read {
d.regs.xge_mac.phy_data.set(d, v)
}
// Address cycle.
x := reg_index | dev_type<<16 | d.phys[d.phy_index].mdio_address<<21
d.regs.xge_mac.phy_command.set(d, x|busy_bit)
for d.regs.xge_mac.phy_command.get(d)&busy_bit != 0 {
}
cmd := reg(1)
if is_read {
cmd = 2
}
d.regs.xge_mac.phy_command.set(d, x|busy_bit|cmd<<26)
for d.regs.xge_mac.phy_command.get(d)&busy_bit != 0 {
}
if is_read {
w = d.regs.xge_mac.phy_data.get(d) >> 16
} else {
w = v
}
d.software_firmware_sync_release(sync_mask, 0)
return
}
func (d *dev) read_phy_reg(dev_type, reg_index reg) reg {
return d.rw_phy_reg(dev_type, reg_index, 0, true)
}
func (d *dev) write_phy_reg(dev_type, reg_index, v reg) {
d.rw_phy_reg(dev_type, reg_index, v, false)
}
func (d *dev) probe_phy() (ok bool) {
phy := &d.phys[d.phy_index]
phy.mdio_address = ^phy.mdio_address // poison
for i := reg(0); i < 32; i++ {
phy.mdio_address = i
v := d.read_phy_reg(xge.PHY_DEV_TYPE_PMA_PMD, xge.PHY_ID1)
if ok = v != 0xffff && v != 0; ok {
phy.id = uint32(v)
break
}
}
return
}
func (d *dev) rw_iphy_reg(dev_type, reg_index, v reg, is_read bool) (w reg) {
sync_mask := reg(1) << (1 + d.phy_index)
d.software_firmware_sync(sync_mask, 0)
d.regs.indirect_phy.control.set(d, reg_index|dev_type<<28)
if !is_read {
d.regs.indirect_phy.data.set(d, v)
w = v
} else {
w = d.regs.indirect_phy.data.get(d)
}
const busy_bit = 1 << 31
for d.regs.indirect_phy.control.get(d)&busy_bit != 0 {
}
d.software_firmware_sync_release(sync_mask, 0)
return
}
func (d *dev) read_iphy_reg(dev_type, reg_index reg) reg {
return d.rw_iphy_reg(dev_type, reg_index, 0, true)
}
func (d *dev) write_iphy_reg(dev_type, reg_index, v reg) {
d.rw_iphy_reg(dev_type, reg_index, v, false)
}