diff options
author | Steve Hodgson <shodgson@solarflare.com> | 2010-06-01 07:17:51 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2010-06-02 05:21:06 -0400 |
commit | fd371e32fe53f137a0f940d61772bda92180007b (patch) | |
tree | c2ce5d564aae698ecc643d8af42696e374a60728 /drivers/net/sfc/falcon.c | |
parent | 319ba649af30321ea221740833785b46e1fe6af3 (diff) |
sfc: Workaround flush failures on Falcon B0
Under certain conditions a PHY may backpressure Falcon B0
in such a way that flushes timeout. In normal circumstances
the phy poller would fix the PHY, and the flush could complete.
But efx_nic_flush_queues() is always called after efx_stop_all(),
so the poller has been stopped. Even if this weren't the case,
how long would we have to wait for the poller to fix this? And
several callers of efx_nic_flush_queues() are about to reset
the device anyway - so we don't need to do anything.
Work around this bug by scheduling a reset. Ensure that the
MAC is never rewired back into the datapath before the reset
runs (we already ignore all rx events anyway).
Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/sfc/falcon.c')
-rw-r--r-- | drivers/net/sfc/falcon.c | 8 |
1 files changed, 5 insertions, 3 deletions
diff --git a/drivers/net/sfc/falcon.c b/drivers/net/sfc/falcon.c index 655b697b45b2..8558865ff380 100644 --- a/drivers/net/sfc/falcon.c +++ b/drivers/net/sfc/falcon.c | |||
@@ -548,7 +548,9 @@ void falcon_reconfigure_mac_wrapper(struct efx_nic *efx) | |||
548 | { | 548 | { |
549 | struct efx_link_state *link_state = &efx->link_state; | 549 | struct efx_link_state *link_state = &efx->link_state; |
550 | efx_oword_t reg; | 550 | efx_oword_t reg; |
551 | int link_speed; | 551 | int link_speed, isolate; |
552 | |||
553 | isolate = (efx->reset_pending != RESET_TYPE_NONE); | ||
552 | 554 | ||
553 | switch (link_state->speed) { | 555 | switch (link_state->speed) { |
554 | case 10000: link_speed = 3; break; | 556 | case 10000: link_speed = 3; break; |
@@ -570,7 +572,7 @@ void falcon_reconfigure_mac_wrapper(struct efx_nic *efx) | |||
570 | * discarded. */ | 572 | * discarded. */ |
571 | if (efx_nic_rev(efx) >= EFX_REV_FALCON_B0) { | 573 | if (efx_nic_rev(efx) >= EFX_REV_FALCON_B0) { |
572 | EFX_SET_OWORD_FIELD(reg, FRF_BB_TXFIFO_DRAIN_EN, | 574 | EFX_SET_OWORD_FIELD(reg, FRF_BB_TXFIFO_DRAIN_EN, |
573 | !link_state->up); | 575 | !link_state->up || isolate); |
574 | } | 576 | } |
575 | 577 | ||
576 | efx_writeo(efx, ®, FR_AB_MAC_CTRL); | 578 | efx_writeo(efx, ®, FR_AB_MAC_CTRL); |
@@ -584,7 +586,7 @@ void falcon_reconfigure_mac_wrapper(struct efx_nic *efx) | |||
584 | EFX_SET_OWORD_FIELD(reg, FRF_AZ_RX_XOFF_MAC_EN, 1); | 586 | EFX_SET_OWORD_FIELD(reg, FRF_AZ_RX_XOFF_MAC_EN, 1); |
585 | /* Unisolate the MAC -> RX */ | 587 | /* Unisolate the MAC -> RX */ |
586 | if (efx_nic_rev(efx) >= EFX_REV_FALCON_B0) | 588 | if (efx_nic_rev(efx) >= EFX_REV_FALCON_B0) |
587 | EFX_SET_OWORD_FIELD(reg, FRF_BZ_RX_INGR_EN, 1); | 589 | EFX_SET_OWORD_FIELD(reg, FRF_BZ_RX_INGR_EN, !isolate); |
588 | efx_writeo(efx, ®, FR_AZ_RX_CFG); | 590 | efx_writeo(efx, ®, FR_AZ_RX_CFG); |
589 | } | 591 | } |
590 | 592 | ||