diff options
author | Mike Frysinger <vapier@gentoo.org> | 2010-05-10 01:39:13 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2010-05-17 20:21:00 -0400 |
commit | 2bfa0f0c9a37460ee69128da411f6d310c1c983d (patch) | |
tree | a1fecf40799f0bce399314150543db42e7b33079 /drivers/net/bfin_mac.c | |
parent | c0da776bde79e5d5e2c955ff37a8a09fe05433b2 (diff) |
netdev: bfin_mac: handle timeouts with the MDIO registers gracefully
Have the low level MDIO functions pass back up timeout information so we
don't waste time polling them multiple times when there is a problem, and
so we don't let higher layers think the device is available when it isn't.
Signed-off-by: Mike Frysinger <vapier@gentoo.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/bfin_mac.c')
-rw-r--r-- | drivers/net/bfin_mac.c | 53 |
1 files changed, 34 insertions, 19 deletions
diff --git a/drivers/net/bfin_mac.c b/drivers/net/bfin_mac.c index 8166611f3cc7..2538eaa891ad 100644 --- a/drivers/net/bfin_mac.c +++ b/drivers/net/bfin_mac.c | |||
@@ -81,9 +81,6 @@ static u16 pin_req[] = P_RMII0; | |||
81 | static u16 pin_req[] = P_MII0; | 81 | static u16 pin_req[] = P_MII0; |
82 | #endif | 82 | #endif |
83 | 83 | ||
84 | static void bfin_mac_disable(void); | ||
85 | static void bfin_mac_enable(void); | ||
86 | |||
87 | static void desc_list_free(void) | 84 | static void desc_list_free(void) |
88 | { | 85 | { |
89 | struct net_dma_desc_rx *r; | 86 | struct net_dma_desc_rx *r; |
@@ -260,7 +257,7 @@ init_error: | |||
260 | * MII operations | 257 | * MII operations |
261 | */ | 258 | */ |
262 | /* Wait until the previous MDC/MDIO transaction has completed */ | 259 | /* Wait until the previous MDC/MDIO transaction has completed */ |
263 | static void bfin_mdio_poll(void) | 260 | static int bfin_mdio_poll(void) |
264 | { | 261 | { |
265 | int timeout_cnt = MAX_TIMEOUT_CNT; | 262 | int timeout_cnt = MAX_TIMEOUT_CNT; |
266 | 263 | ||
@@ -270,22 +267,30 @@ static void bfin_mdio_poll(void) | |||
270 | if (timeout_cnt-- < 0) { | 267 | if (timeout_cnt-- < 0) { |
271 | printk(KERN_ERR DRV_NAME | 268 | printk(KERN_ERR DRV_NAME |
272 | ": wait MDC/MDIO transaction to complete timeout\n"); | 269 | ": wait MDC/MDIO transaction to complete timeout\n"); |
273 | break; | 270 | return -ETIMEDOUT; |
274 | } | 271 | } |
275 | } | 272 | } |
273 | |||
274 | return 0; | ||
276 | } | 275 | } |
277 | 276 | ||
278 | /* Read an off-chip register in a PHY through the MDC/MDIO port */ | 277 | /* Read an off-chip register in a PHY through the MDC/MDIO port */ |
279 | static int bfin_mdiobus_read(struct mii_bus *bus, int phy_addr, int regnum) | 278 | static int bfin_mdiobus_read(struct mii_bus *bus, int phy_addr, int regnum) |
280 | { | 279 | { |
281 | bfin_mdio_poll(); | 280 | int ret; |
281 | |||
282 | ret = bfin_mdio_poll(); | ||
283 | if (ret) | ||
284 | return ret; | ||
282 | 285 | ||
283 | /* read mode */ | 286 | /* read mode */ |
284 | bfin_write_EMAC_STAADD(SET_PHYAD((u16) phy_addr) | | 287 | bfin_write_EMAC_STAADD(SET_PHYAD((u16) phy_addr) | |
285 | SET_REGAD((u16) regnum) | | 288 | SET_REGAD((u16) regnum) | |
286 | STABUSY); | 289 | STABUSY); |
287 | 290 | ||
288 | bfin_mdio_poll(); | 291 | ret = bfin_mdio_poll(); |
292 | if (ret) | ||
293 | return ret; | ||
289 | 294 | ||
290 | return (int) bfin_read_EMAC_STADAT(); | 295 | return (int) bfin_read_EMAC_STADAT(); |
291 | } | 296 | } |
@@ -294,7 +299,11 @@ static int bfin_mdiobus_read(struct mii_bus *bus, int phy_addr, int regnum) | |||
294 | static int bfin_mdiobus_write(struct mii_bus *bus, int phy_addr, int regnum, | 299 | static int bfin_mdiobus_write(struct mii_bus *bus, int phy_addr, int regnum, |
295 | u16 value) | 300 | u16 value) |
296 | { | 301 | { |
297 | bfin_mdio_poll(); | 302 | int ret; |
303 | |||
304 | ret = bfin_mdio_poll(); | ||
305 | if (ret) | ||
306 | return ret; | ||
298 | 307 | ||
299 | bfin_write_EMAC_STADAT((u32) value); | 308 | bfin_write_EMAC_STADAT((u32) value); |
300 | 309 | ||
@@ -304,9 +313,7 @@ static int bfin_mdiobus_write(struct mii_bus *bus, int phy_addr, int regnum, | |||
304 | STAOP | | 313 | STAOP | |
305 | STABUSY); | 314 | STABUSY); |
306 | 315 | ||
307 | bfin_mdio_poll(); | 316 | return bfin_mdio_poll(); |
308 | |||
309 | return 0; | ||
310 | } | 317 | } |
311 | 318 | ||
312 | static int bfin_mdiobus_reset(struct mii_bus *bus) | 319 | static int bfin_mdiobus_reset(struct mii_bus *bus) |
@@ -1180,8 +1187,9 @@ static void bfin_mac_disable(void) | |||
1180 | /* | 1187 | /* |
1181 | * Enable Interrupts, Receive, and Transmit | 1188 | * Enable Interrupts, Receive, and Transmit |
1182 | */ | 1189 | */ |
1183 | static void bfin_mac_enable(void) | 1190 | static int bfin_mac_enable(void) |
1184 | { | 1191 | { |
1192 | int ret; | ||
1185 | u32 opmode; | 1193 | u32 opmode; |
1186 | 1194 | ||
1187 | pr_debug("%s: %s\n", DRV_NAME, __func__); | 1195 | pr_debug("%s: %s\n", DRV_NAME, __func__); |
@@ -1191,7 +1199,9 @@ static void bfin_mac_enable(void) | |||
1191 | bfin_write_DMA1_CONFIG(rx_list_head->desc_a.config); | 1199 | bfin_write_DMA1_CONFIG(rx_list_head->desc_a.config); |
1192 | 1200 | ||
1193 | /* Wait MII done */ | 1201 | /* Wait MII done */ |
1194 | bfin_mdio_poll(); | 1202 | ret = bfin_mdio_poll(); |
1203 | if (ret) | ||
1204 | return ret; | ||
1195 | 1205 | ||
1196 | /* We enable only RX here */ | 1206 | /* We enable only RX here */ |
1197 | /* ASTP : Enable Automatic Pad Stripping | 1207 | /* ASTP : Enable Automatic Pad Stripping |
@@ -1215,6 +1225,8 @@ static void bfin_mac_enable(void) | |||
1215 | #endif | 1225 | #endif |
1216 | /* Turn on the EMAC rx */ | 1226 | /* Turn on the EMAC rx */ |
1217 | bfin_write_EMAC_OPMODE(opmode); | 1227 | bfin_write_EMAC_OPMODE(opmode); |
1228 | |||
1229 | return 0; | ||
1218 | } | 1230 | } |
1219 | 1231 | ||
1220 | /* Our watchdog timed out. Called by the networking layer */ | 1232 | /* Our watchdog timed out. Called by the networking layer */ |
@@ -1327,7 +1339,7 @@ static void bfin_mac_shutdown(struct net_device *dev) | |||
1327 | static int bfin_mac_open(struct net_device *dev) | 1339 | static int bfin_mac_open(struct net_device *dev) |
1328 | { | 1340 | { |
1329 | struct bfin_mac_local *lp = netdev_priv(dev); | 1341 | struct bfin_mac_local *lp = netdev_priv(dev); |
1330 | int retval; | 1342 | int ret; |
1331 | pr_debug("%s: %s\n", dev->name, __func__); | 1343 | pr_debug("%s: %s\n", dev->name, __func__); |
1332 | 1344 | ||
1333 | /* | 1345 | /* |
@@ -1341,18 +1353,21 @@ static int bfin_mac_open(struct net_device *dev) | |||
1341 | } | 1353 | } |
1342 | 1354 | ||
1343 | /* initial rx and tx list */ | 1355 | /* initial rx and tx list */ |
1344 | retval = desc_list_init(); | 1356 | ret = desc_list_init(); |
1345 | 1357 | if (ret) | |
1346 | if (retval) | 1358 | return ret; |
1347 | return retval; | ||
1348 | 1359 | ||
1349 | phy_start(lp->phydev); | 1360 | phy_start(lp->phydev); |
1350 | phy_write(lp->phydev, MII_BMCR, BMCR_RESET); | 1361 | phy_write(lp->phydev, MII_BMCR, BMCR_RESET); |
1351 | setup_system_regs(dev); | 1362 | setup_system_regs(dev); |
1352 | setup_mac_addr(dev->dev_addr); | 1363 | setup_mac_addr(dev->dev_addr); |
1364 | |||
1353 | bfin_mac_disable(); | 1365 | bfin_mac_disable(); |
1354 | bfin_mac_enable(); | 1366 | ret = bfin_mac_enable(); |
1367 | if (ret) | ||
1368 | return ret; | ||
1355 | pr_debug("hardware init finished\n"); | 1369 | pr_debug("hardware init finished\n"); |
1370 | |||
1356 | netif_start_queue(dev); | 1371 | netif_start_queue(dev); |
1357 | netif_carrier_on(dev); | 1372 | netif_carrier_on(dev); |
1358 | 1373 | ||