diff options
Diffstat (limited to 'drivers/net/tulip/media.c')
-rw-r--r-- | drivers/net/tulip/media.c | 40 |
1 files changed, 37 insertions, 3 deletions
diff --git a/drivers/net/tulip/media.c b/drivers/net/tulip/media.c index 20bd52b86993..b56256636543 100644 --- a/drivers/net/tulip/media.c +++ b/drivers/net/tulip/media.c | |||
@@ -44,8 +44,10 @@ static const unsigned char comet_miireg2offset[32] = { | |||
44 | 44 | ||
45 | /* MII transceiver control section. | 45 | /* MII transceiver control section. |
46 | Read and write the MII registers using software-generated serial | 46 | Read and write the MII registers using software-generated serial |
47 | MDIO protocol. See the MII specifications or DP83840A data sheet | 47 | MDIO protocol. |
48 | for details. */ | 48 | See IEEE 802.3-2002.pdf (Section 2, Chapter "22.2.4 Management functions") |
49 | or DP83840A data sheet for more details. | ||
50 | */ | ||
49 | 51 | ||
50 | int tulip_mdio_read(struct net_device *dev, int phy_id, int location) | 52 | int tulip_mdio_read(struct net_device *dev, int phy_id, int location) |
51 | { | 53 | { |
@@ -261,24 +263,56 @@ void tulip_select_media(struct net_device *dev, int startup) | |||
261 | u16 *reset_sequence = &((u16*)(p+3))[init_length]; | 263 | u16 *reset_sequence = &((u16*)(p+3))[init_length]; |
262 | int reset_length = p[2 + init_length*2]; | 264 | int reset_length = p[2 + init_length*2]; |
263 | misc_info = reset_sequence + reset_length; | 265 | misc_info = reset_sequence + reset_length; |
264 | if (startup) | 266 | if (startup) { |
267 | int timeout = 10; /* max 1 ms */ | ||
265 | for (i = 0; i < reset_length; i++) | 268 | for (i = 0; i < reset_length; i++) |
266 | iowrite32(get_u16(&reset_sequence[i]) << 16, ioaddr + CSR15); | 269 | iowrite32(get_u16(&reset_sequence[i]) << 16, ioaddr + CSR15); |
270 | |||
271 | /* flush posted writes */ | ||
272 | ioread32(ioaddr + CSR15); | ||
273 | |||
274 | /* Sect 3.10.3 in DP83840A.pdf (p39) */ | ||
275 | udelay(500); | ||
276 | |||
277 | /* Section 4.2 in DP83840A.pdf (p43) */ | ||
278 | /* and IEEE 802.3 "22.2.4.1.1 Reset" */ | ||
279 | while (timeout-- && | ||
280 | (tulip_mdio_read (dev, phy_num, MII_BMCR) & BMCR_RESET)) | ||
281 | udelay(100); | ||
282 | } | ||
267 | for (i = 0; i < init_length; i++) | 283 | for (i = 0; i < init_length; i++) |
268 | iowrite32(get_u16(&init_sequence[i]) << 16, ioaddr + CSR15); | 284 | iowrite32(get_u16(&init_sequence[i]) << 16, ioaddr + CSR15); |
285 | |||
286 | ioread32(ioaddr + CSR15); /* flush posted writes */ | ||
269 | } else { | 287 | } else { |
270 | u8 *init_sequence = p + 2; | 288 | u8 *init_sequence = p + 2; |
271 | u8 *reset_sequence = p + 3 + init_length; | 289 | u8 *reset_sequence = p + 3 + init_length; |
272 | int reset_length = p[2 + init_length]; | 290 | int reset_length = p[2 + init_length]; |
273 | misc_info = (u16*)(reset_sequence + reset_length); | 291 | misc_info = (u16*)(reset_sequence + reset_length); |
274 | if (startup) { | 292 | if (startup) { |
293 | int timeout = 10; /* max 1 ms */ | ||
275 | iowrite32(mtable->csr12dir | 0x100, ioaddr + CSR12); | 294 | iowrite32(mtable->csr12dir | 0x100, ioaddr + CSR12); |
276 | for (i = 0; i < reset_length; i++) | 295 | for (i = 0; i < reset_length; i++) |
277 | iowrite32(reset_sequence[i], ioaddr + CSR12); | 296 | iowrite32(reset_sequence[i], ioaddr + CSR12); |
297 | |||
298 | /* flush posted writes */ | ||
299 | ioread32(ioaddr + CSR12); | ||
300 | |||
301 | /* Sect 3.10.3 in DP83840A.pdf (p39) */ | ||
302 | udelay(500); | ||
303 | |||
304 | /* Section 4.2 in DP83840A.pdf (p43) */ | ||
305 | /* and IEEE 802.3 "22.2.4.1.1 Reset" */ | ||
306 | while (timeout-- && | ||
307 | (tulip_mdio_read (dev, phy_num, MII_BMCR) & BMCR_RESET)) | ||
308 | udelay(100); | ||
278 | } | 309 | } |
279 | for (i = 0; i < init_length; i++) | 310 | for (i = 0; i < init_length; i++) |
280 | iowrite32(init_sequence[i], ioaddr + CSR12); | 311 | iowrite32(init_sequence[i], ioaddr + CSR12); |
312 | |||
313 | ioread32(ioaddr + CSR12); /* flush posted writes */ | ||
281 | } | 314 | } |
315 | |||
282 | tmp_info = get_u16(&misc_info[1]); | 316 | tmp_info = get_u16(&misc_info[1]); |
283 | if (tmp_info) | 317 | if (tmp_info) |
284 | tp->advertising[phy_num] = tmp_info | 1; | 318 | tp->advertising[phy_num] = tmp_info | 1; |