e1000e: unexpected "Reset adapter" message when cable pulled

When there is heavy traffic and the cable is pulled, the driver must reset
the adapter to flush the Tx queue in hardware.  This causes the reset path
to be scheduled and logs the message "Reset adapter" which could be mis-
interpreted as an error by the user.  Change how the reset path is invoked
for this scenario by using the same method done in an existing work-around
for 80003es2lan (i.e. set a flag and if the flag is set in the reset code
do not log the "Reset adapter" message since the reset is expected).

Re-name the FLAG_RX_RESTART_NOW to FLAG_RESTART_NOW since it is used for
resets in both the Rx and Tx specific code.

Signed-off-by: Bruce Allan <bruce.w.allan@intel.com>
Tested-by: Aaron Brown <aaron.f.brown@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
This commit is contained in:
Bruce Allan 2012-12-05 06:26:14 +00:00 committed by Jeff Kirsher
parent 3d4d5755f1
commit 12d43f7d3c
2 changed files with 21 additions and 20 deletions

View File

@ -447,7 +447,7 @@ struct e1000_info {
#define FLAG_MSI_ENABLED (1 << 27) #define FLAG_MSI_ENABLED (1 << 27)
/* reserved (1 << 28) */ /* reserved (1 << 28) */
#define FLAG_TSO_FORCE (1 << 29) #define FLAG_TSO_FORCE (1 << 29)
#define FLAG_RX_RESTART_NOW (1 << 30) #define FLAG_RESTART_NOW (1 << 30)
#define FLAG_MSI_TEST_FAILED (1 << 31) #define FLAG_MSI_TEST_FAILED (1 << 31)
#define FLAG2_CRC_STRIPPING (1 << 0) #define FLAG2_CRC_STRIPPING (1 << 0)

View File

@ -1671,7 +1671,7 @@ static irqreturn_t e1000_intr_msi(int irq, void *data)
/* disable receives */ /* disable receives */
u32 rctl = er32(RCTL); u32 rctl = er32(RCTL);
ew32(RCTL, rctl & ~E1000_RCTL_EN); ew32(RCTL, rctl & ~E1000_RCTL_EN);
adapter->flags |= FLAG_RX_RESTART_NOW; adapter->flags |= FLAG_RESTART_NOW;
} }
/* guard against interrupt when we're going down */ /* guard against interrupt when we're going down */
if (!test_bit(__E1000_DOWN, &adapter->state)) if (!test_bit(__E1000_DOWN, &adapter->state))
@ -1734,7 +1734,7 @@ static irqreturn_t e1000_intr(int irq, void *data)
/* disable receives */ /* disable receives */
rctl = er32(RCTL); rctl = er32(RCTL);
ew32(RCTL, rctl & ~E1000_RCTL_EN); ew32(RCTL, rctl & ~E1000_RCTL_EN);
adapter->flags |= FLAG_RX_RESTART_NOW; adapter->flags |= FLAG_RESTART_NOW;
} }
/* guard against interrupt when we're going down */ /* guard against interrupt when we're going down */
if (!test_bit(__E1000_DOWN, &adapter->state)) if (!test_bit(__E1000_DOWN, &adapter->state))
@ -3013,7 +3013,7 @@ static void e1000_setup_rctl(struct e1000_adapter *adapter)
ew32(RCTL, rctl); ew32(RCTL, rctl);
/* just started the receive unit, no need to restart */ /* just started the receive unit, no need to restart */
adapter->flags &= ~FLAG_RX_RESTART_NOW; adapter->flags &= ~FLAG_RESTART_NOW;
} }
/** /**
@ -4355,11 +4355,11 @@ static void e1000e_enable_receives(struct e1000_adapter *adapter)
{ {
/* make sure the receive unit is started */ /* make sure the receive unit is started */
if ((adapter->flags & FLAG_RX_NEEDS_RESTART) && if ((adapter->flags & FLAG_RX_NEEDS_RESTART) &&
(adapter->flags & FLAG_RX_RESTART_NOW)) { (adapter->flags & FLAG_RESTART_NOW)) {
struct e1000_hw *hw = &adapter->hw; struct e1000_hw *hw = &adapter->hw;
u32 rctl = er32(RCTL); u32 rctl = er32(RCTL);
ew32(RCTL, rctl | E1000_RCTL_EN); ew32(RCTL, rctl | E1000_RCTL_EN);
adapter->flags &= ~FLAG_RX_RESTART_NOW; adapter->flags &= ~FLAG_RESTART_NOW;
} }
} }
@ -4528,8 +4528,16 @@ static void e1000_watchdog_task(struct work_struct *work)
mod_timer(&adapter->phy_info_timer, mod_timer(&adapter->phy_info_timer,
round_jiffies(jiffies + 2 * HZ)); round_jiffies(jiffies + 2 * HZ));
if (adapter->flags & FLAG_RX_NEEDS_RESTART) /* The link is lost so the controller stops DMA.
schedule_work(&adapter->reset_task); * If there is queued Tx work that cannot be done
* or if on an 8000ES2LAN which requires a Rx packet
* buffer work-around on link down event, reset the
* controller to flush the Tx/Rx packet buffers.
* (Do the reset outside of interrupt context).
*/
if ((adapter->flags & FLAG_RX_NEEDS_RESTART) ||
(e1000_desc_unused(tx_ring) + 1 < tx_ring->count))
adapter->flags |= FLAG_RESTART_NOW;
else else
pm_schedule_suspend(netdev->dev.parent, pm_schedule_suspend(netdev->dev.parent,
LINK_TIMEOUT); LINK_TIMEOUT);
@ -4551,20 +4559,14 @@ static void e1000_watchdog_task(struct work_struct *work)
adapter->gotc_old = adapter->stats.gotc; adapter->gotc_old = adapter->stats.gotc;
spin_unlock(&adapter->stats64_lock); spin_unlock(&adapter->stats64_lock);
e1000e_update_adaptive(&adapter->hw); if (adapter->flags & FLAG_RESTART_NOW) {
if (!netif_carrier_ok(netdev) &&
(e1000_desc_unused(tx_ring) + 1 < tx_ring->count)) {
/* We've lost link, so the controller stops DMA,
* but we've got queued Tx work that's never going
* to get done, so reset controller to flush Tx.
* (Do the reset outside of interrupt context).
*/
schedule_work(&adapter->reset_task); schedule_work(&adapter->reset_task);
/* return immediately since reset is imminent */ /* return immediately since reset is imminent */
return; return;
} }
e1000e_update_adaptive(&adapter->hw);
/* Simple mode for Interrupt Throttle Rate (ITR) */ /* Simple mode for Interrupt Throttle Rate (ITR) */
if (adapter->itr_setting == 4) { if (adapter->itr_setting == 4) {
/* Symmetric Tx/Rx gets a reduced ITR=2000; /* Symmetric Tx/Rx gets a reduced ITR=2000;
@ -5134,10 +5136,9 @@ static void e1000_reset_task(struct work_struct *work)
if (test_bit(__E1000_DOWN, &adapter->state)) if (test_bit(__E1000_DOWN, &adapter->state))
return; return;
if (!((adapter->flags & FLAG_RX_NEEDS_RESTART) && if (!(adapter->flags & FLAG_RESTART_NOW)) {
(adapter->flags & FLAG_RX_RESTART_NOW))) {
e1000e_dump(adapter); e1000e_dump(adapter);
e_err("Reset adapter\n"); e_err("Reset adapter unexpectedly\n");
} }
e1000e_reinit_locked(adapter); e1000e_reinit_locked(adapter);
} }