diff options
Diffstat (limited to 'drivers/net/ibm_emac')
-rw-r--r-- | drivers/net/ibm_emac/ibm_emac_core.c | 38 | ||||
-rw-r--r-- | drivers/net/ibm_emac/ibm_emac_core.h | 2 |
2 files changed, 31 insertions, 9 deletions
diff --git a/drivers/net/ibm_emac/ibm_emac_core.c b/drivers/net/ibm_emac/ibm_emac_core.c index eb7d6947871..1da8a66f91e 100644 --- a/drivers/net/ibm_emac/ibm_emac_core.c +++ b/drivers/net/ibm_emac/ibm_emac_core.c | |||
@@ -65,7 +65,7 @@ | |||
65 | */ | 65 | */ |
66 | 66 | ||
67 | #define DRV_NAME "emac" | 67 | #define DRV_NAME "emac" |
68 | #define DRV_VERSION "3.53" | 68 | #define DRV_VERSION "3.54" |
69 | #define DRV_DESC "PPC 4xx OCP EMAC driver" | 69 | #define DRV_DESC "PPC 4xx OCP EMAC driver" |
70 | 70 | ||
71 | MODULE_DESCRIPTION(DRV_DESC); | 71 | MODULE_DESCRIPTION(DRV_DESC); |
@@ -158,6 +158,14 @@ static inline void emac_report_timeout_error(struct ocp_enet_private *dev, | |||
158 | #define PHY_POLL_LINK_ON HZ | 158 | #define PHY_POLL_LINK_ON HZ |
159 | #define PHY_POLL_LINK_OFF (HZ / 5) | 159 | #define PHY_POLL_LINK_OFF (HZ / 5) |
160 | 160 | ||
161 | /* Graceful stop timeouts in us. | ||
162 | * We should allow up to 1 frame time (full-duplex, ignoring collisions) | ||
163 | */ | ||
164 | #define STOP_TIMEOUT_10 1230 | ||
165 | #define STOP_TIMEOUT_100 124 | ||
166 | #define STOP_TIMEOUT_1000 13 | ||
167 | #define STOP_TIMEOUT_1000_JUMBO 73 | ||
168 | |||
161 | /* Please, keep in sync with struct ibm_emac_stats/ibm_emac_error_stats */ | 169 | /* Please, keep in sync with struct ibm_emac_stats/ibm_emac_error_stats */ |
162 | static const char emac_stats_keys[EMAC_ETHTOOL_STATS_COUNT][ETH_GSTRING_LEN] = { | 170 | static const char emac_stats_keys[EMAC_ETHTOOL_STATS_COUNT][ETH_GSTRING_LEN] = { |
163 | "rx_packets", "rx_bytes", "tx_packets", "tx_bytes", "rx_packets_csum", | 171 | "rx_packets", "rx_bytes", "tx_packets", "tx_bytes", "rx_packets_csum", |
@@ -222,10 +230,12 @@ static void emac_tx_disable(struct ocp_enet_private *dev) | |||
222 | 230 | ||
223 | r = in_be32(&p->mr0); | 231 | r = in_be32(&p->mr0); |
224 | if (r & EMAC_MR0_TXE) { | 232 | if (r & EMAC_MR0_TXE) { |
225 | int n = 300; | 233 | int n = dev->stop_timeout; |
226 | out_be32(&p->mr0, r & ~EMAC_MR0_TXE); | 234 | out_be32(&p->mr0, r & ~EMAC_MR0_TXE); |
227 | while (!(in_be32(&p->mr0) & EMAC_MR0_TXI) && n) | 235 | while (!(in_be32(&p->mr0) & EMAC_MR0_TXI) && n) { |
236 | udelay(1); | ||
228 | --n; | 237 | --n; |
238 | } | ||
229 | if (unlikely(!n)) | 239 | if (unlikely(!n)) |
230 | emac_report_timeout_error(dev, "TX disable timeout"); | 240 | emac_report_timeout_error(dev, "TX disable timeout"); |
231 | } | 241 | } |
@@ -248,9 +258,11 @@ static void emac_rx_enable(struct ocp_enet_private *dev) | |||
248 | if (!(r & EMAC_MR0_RXE)) { | 258 | if (!(r & EMAC_MR0_RXE)) { |
249 | if (unlikely(!(r & EMAC_MR0_RXI))) { | 259 | if (unlikely(!(r & EMAC_MR0_RXI))) { |
250 | /* Wait if previous async disable is still in progress */ | 260 | /* Wait if previous async disable is still in progress */ |
251 | int n = 100; | 261 | int n = dev->stop_timeout; |
252 | while (!(r = in_be32(&p->mr0) & EMAC_MR0_RXI) && n) | 262 | while (!(r = in_be32(&p->mr0) & EMAC_MR0_RXI) && n) { |
263 | udelay(1); | ||
253 | --n; | 264 | --n; |
265 | } | ||
254 | if (unlikely(!n)) | 266 | if (unlikely(!n)) |
255 | emac_report_timeout_error(dev, | 267 | emac_report_timeout_error(dev, |
256 | "RX disable timeout"); | 268 | "RX disable timeout"); |
@@ -273,10 +285,12 @@ static void emac_rx_disable(struct ocp_enet_private *dev) | |||
273 | 285 | ||
274 | r = in_be32(&p->mr0); | 286 | r = in_be32(&p->mr0); |
275 | if (r & EMAC_MR0_RXE) { | 287 | if (r & EMAC_MR0_RXE) { |
276 | int n = 300; | 288 | int n = dev->stop_timeout; |
277 | out_be32(&p->mr0, r & ~EMAC_MR0_RXE); | 289 | out_be32(&p->mr0, r & ~EMAC_MR0_RXE); |
278 | while (!(in_be32(&p->mr0) & EMAC_MR0_RXI) && n) | 290 | while (!(in_be32(&p->mr0) & EMAC_MR0_RXI) && n) { |
291 | udelay(1); | ||
279 | --n; | 292 | --n; |
293 | } | ||
280 | if (unlikely(!n)) | 294 | if (unlikely(!n)) |
281 | emac_report_timeout_error(dev, "RX disable timeout"); | 295 | emac_report_timeout_error(dev, "RX disable timeout"); |
282 | } | 296 | } |
@@ -395,6 +409,7 @@ static int emac_configure(struct ocp_enet_private *dev) | |||
395 | r = EMAC_MR1_BASE(emac_opb_mhz()) | EMAC_MR1_VLE | EMAC_MR1_IST; | 409 | r = EMAC_MR1_BASE(emac_opb_mhz()) | EMAC_MR1_VLE | EMAC_MR1_IST; |
396 | if (dev->phy.duplex == DUPLEX_FULL) | 410 | if (dev->phy.duplex == DUPLEX_FULL) |
397 | r |= EMAC_MR1_FDE; | 411 | r |= EMAC_MR1_FDE; |
412 | dev->stop_timeout = STOP_TIMEOUT_10; | ||
398 | switch (dev->phy.speed) { | 413 | switch (dev->phy.speed) { |
399 | case SPEED_1000: | 414 | case SPEED_1000: |
400 | if (emac_phy_gpcs(dev->phy.mode)) { | 415 | if (emac_phy_gpcs(dev->phy.mode)) { |
@@ -409,12 +424,16 @@ static int emac_configure(struct ocp_enet_private *dev) | |||
409 | r |= EMAC_MR1_MF_1000; | 424 | r |= EMAC_MR1_MF_1000; |
410 | r |= EMAC_MR1_RFS_16K; | 425 | r |= EMAC_MR1_RFS_16K; |
411 | gige = 1; | 426 | gige = 1; |
412 | 427 | ||
413 | if (dev->ndev->mtu > ETH_DATA_LEN) | 428 | if (dev->ndev->mtu > ETH_DATA_LEN) { |
414 | r |= EMAC_MR1_JPSM; | 429 | r |= EMAC_MR1_JPSM; |
430 | dev->stop_timeout = STOP_TIMEOUT_1000_JUMBO; | ||
431 | } else | ||
432 | dev->stop_timeout = STOP_TIMEOUT_1000; | ||
415 | break; | 433 | break; |
416 | case SPEED_100: | 434 | case SPEED_100: |
417 | r |= EMAC_MR1_MF_100; | 435 | r |= EMAC_MR1_MF_100; |
436 | dev->stop_timeout = STOP_TIMEOUT_100; | ||
418 | /* Fall through */ | 437 | /* Fall through */ |
419 | default: | 438 | default: |
420 | r |= EMAC_MR1_RFS_4K; | 439 | r |= EMAC_MR1_RFS_4K; |
@@ -2048,6 +2067,7 @@ static int __init emac_probe(struct ocp_device *ocpdev) | |||
2048 | dev->phy.duplex = DUPLEX_FULL; | 2067 | dev->phy.duplex = DUPLEX_FULL; |
2049 | dev->phy.autoneg = AUTONEG_DISABLE; | 2068 | dev->phy.autoneg = AUTONEG_DISABLE; |
2050 | dev->phy.pause = dev->phy.asym_pause = 0; | 2069 | dev->phy.pause = dev->phy.asym_pause = 0; |
2070 | dev->stop_timeout = STOP_TIMEOUT_100; | ||
2051 | init_timer(&dev->link_timer); | 2071 | init_timer(&dev->link_timer); |
2052 | dev->link_timer.function = emac_link_timer; | 2072 | dev->link_timer.function = emac_link_timer; |
2053 | dev->link_timer.data = (unsigned long)dev; | 2073 | dev->link_timer.data = (unsigned long)dev; |
diff --git a/drivers/net/ibm_emac/ibm_emac_core.h b/drivers/net/ibm_emac/ibm_emac_core.h index e9b44d030ac..911abbaf471 100644 --- a/drivers/net/ibm_emac/ibm_emac_core.h +++ b/drivers/net/ibm_emac/ibm_emac_core.h | |||
@@ -189,6 +189,8 @@ struct ocp_enet_private { | |||
189 | struct timer_list link_timer; | 189 | struct timer_list link_timer; |
190 | int reset_failed; | 190 | int reset_failed; |
191 | 191 | ||
192 | int stop_timeout; /* in us */ | ||
193 | |||
192 | struct ibm_emac_error_stats estats; | 194 | struct ibm_emac_error_stats estats; |
193 | struct net_device_stats nstats; | 195 | struct net_device_stats nstats; |
194 | 196 | ||