14
static int phy_read(struct net_device *dev, int reg) {
17
assert(dev->drv_ops->mdio_read);
19
return dev->drv_ops->mdio_read(dev, reg);
22
static int phy_write(struct net_device *dev, int reg, int data) {
25
assert(dev->drv_ops->mdio_write);
27
return dev->drv_ops->mdio_write(dev, reg, data);
30
static void set_phyid(struct net_device *dev, int phyid) {
33
assert(dev->drv_ops->set_phyid);
35
return dev->drv_ops->set_phyid(dev, phyid);
38
int phy_detect(struct net_device *dev) {
42
for (int i = 0; i < 32; i++) {
44
if ((phyid[0] = phy_read(dev, MII_PHYSID1)) != 0xffff) {
45
phyid[1] = phy_read(dev, MII_PHYSID2);
46
log_debug("Detected phyaddr=%d ,ID=%X:%X", i, phyid[0], phyid[1]);
54
int phy_reset(struct net_device *dev) {
55
uint32_t reg, retry = 0;
57
log_debug("Reset PHY");
58
reg = phy_read(dev, MII_BMCR);
59
phy_write(dev, MII_BMCR, reg | BMCR_RESET);
61
while (phy_read(dev, MII_BMCR) & BMCR_RESET) {
63
if (retry++ > 0xffff) {
64
log_error("PHY reset failed");
72
int phy_wait_autoneg(struct net_device *dev) {
75
while (!(phy_read(dev, MII_BMSR) & BMSR_LSTATUS)) {
76
if (retry++ > 10000) {
77
log_error("Autonegotiation timeout");
87
int phy_try_speed(struct net_device *dev, int speed) {
91
phy_write(dev, MII_ADVERTISE, net_speed_to_adv(speed));
93
if (net_is_1000(speed)) {
94
reg = phy_read(dev, MII_BMCR);
96
phy_write(dev, MII_BMCR, reg | BMCR_ANRESTART);
98
phy_wait_autoneg(dev);
100
log_debug("Try 1Gbit speed");
101
reg = phy_read(dev, MII_BMSR);
102
if (reg & BMSR_ERCAP) {
104
reg = phy_read(dev, MII_CTRL1000);
105
reg |= ADVERTISE_1000HALF;
106
if (net_is_fullduplex(speed)) {
107
reg |= ADVERTISE_1000FULL;
109
phy_write(dev, MII_CTRL1000, reg);
112
gbit = phy_read(dev, MII_STAT1000) >> 2;
113
gbit &= phy_read(dev, MII_CTRL1000);
116
if (gbit & ADVERTISE_1000FULL) {
117
log_debug("Have 1Gbit full");
118
return adv_to_net_speed(ADVERTISE_1000XFULL, 1);
121
if (gbit & ADVERTISE_1000HALF) {
122
log_debug("Have 1Gbit half");
123
return adv_to_net_speed(ADVERTISE_1000XHALF, 1);
127
log_debug("Failed to setup 1Gbit link");
135
phy_write(dev, MII_CTRL1000, 0);
136
phy_write(dev, MII_ADVERTISE, net_speed_to_adv(speed));
138
reg = phy_read(dev, MII_BMCR);
140
phy_write(dev, MII_BMCR, reg | BMCR_ANRESTART);
142
phy_wait_autoneg(dev);
144
return adv_to_net_speed(phy_read(dev, MII_LPA) &
145
phy_read(dev, MII_ADVERTISE), 0);
148
int phy_autoneg(struct net_device *dev, int fixed_speed) {
155
phy_write(dev, MII_BMCR, BMCR_ANENABLE);
157
switch (fixed_speed) {
159
if (phy_try_speed(dev, NET_1000FULL)) {
160
log_info("\t1000 Mbps FULL\n");
161
dev->drv_ops->set_speed(dev, NET_1000FULL);
165
if (phy_try_speed(dev, NET_100FULL)) {
166
log_info("\t100 Mbps FULL\n");
167
dev->drv_ops->set_speed(dev, NET_100FULL);
171
if (phy_try_speed(dev, NET_10FULL)) {
172
log_info("\t10 Mbps FULL\n");
173
dev->drv_ops->set_speed(dev, NET_10FULL);
178
if ((ret = phy_try_speed(dev, NET_1000FULL | NET_1000HALF))) {
179
if (ret & NET_1000FULL) {
180
log_info("\t1000 Mpbs FULL\n");
181
dev->drv_ops->set_speed(dev, NET_1000FULL);
183
log_info("\t1000 Mpbs HALF\n");
184
dev->drv_ops->set_speed(dev, NET_1000HALF);
188
ret = phy_try_speed(dev, NET_10HALF | NET_10FULL |
189
NET_100HALF | NET_100FULL);
191
if (0 == (ret = net_top_speed(ret))) {
196
log_info("\t%d Mbps %s\n", net_to_mbps(ret),
197
net_is_fullduplex(ret) ? "FULL" : "HALF");
199
assert(dev->drv_ops->set_speed);
201
dev->drv_ops->set_speed(dev, ret);
207
log_error("Autonegotiation failed");
211
int phy_init(struct net_device *dev) {