Skip to content

Commit

Permalink
e1000e: unexpected "Reset adapter" message when cable pulled
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Bruce Allan authored and Jeff Kirsher committed Jan 16, 2013
1 parent 3d4d575 commit 12d43f7
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 20 deletions.
2 changes: 1 addition & 1 deletion drivers/net/ethernet/intel/e1000e/e1000.h
Original file line number Diff line number Diff line change
Expand Up @@ -447,7 +447,7 @@ struct e1000_info {
#define FLAG_MSI_ENABLED (1 << 27)
/* reserved (1 << 28) */
#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 FLAG2_CRC_STRIPPING (1 << 0)
Expand Down
39 changes: 20 additions & 19 deletions drivers/net/ethernet/intel/e1000e/netdev.c
Original file line number Diff line number Diff line change
Expand Up @@ -1671,7 +1671,7 @@ static irqreturn_t e1000_intr_msi(int irq, void *data)
/* disable receives */
u32 rctl = er32(RCTL);
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 */
if (!test_bit(__E1000_DOWN, &adapter->state))
Expand Down Expand Up @@ -1734,7 +1734,7 @@ static irqreturn_t e1000_intr(int irq, void *data)
/* disable receives */
rctl = er32(RCTL);
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 */
if (!test_bit(__E1000_DOWN, &adapter->state))
Expand Down Expand Up @@ -3013,7 +3013,7 @@ static void e1000_setup_rctl(struct e1000_adapter *adapter)

ew32(RCTL, rctl);
/* just started the receive unit, no need to restart */
adapter->flags &= ~FLAG_RX_RESTART_NOW;
adapter->flags &= ~FLAG_RESTART_NOW;
}

/**
Expand Down Expand Up @@ -4355,11 +4355,11 @@ static void e1000e_enable_receives(struct e1000_adapter *adapter)
{
/* make sure the receive unit is started */
if ((adapter->flags & FLAG_RX_NEEDS_RESTART) &&
(adapter->flags & FLAG_RX_RESTART_NOW)) {
(adapter->flags & FLAG_RESTART_NOW)) {
struct e1000_hw *hw = &adapter->hw;
u32 rctl = er32(RCTL);
ew32(RCTL, rctl | E1000_RCTL_EN);
adapter->flags &= ~FLAG_RX_RESTART_NOW;
adapter->flags &= ~FLAG_RESTART_NOW;
}
}

Expand Down Expand Up @@ -4528,8 +4528,16 @@ static void e1000_watchdog_task(struct work_struct *work)
mod_timer(&adapter->phy_info_timer,
round_jiffies(jiffies + 2 * HZ));

if (adapter->flags & FLAG_RX_NEEDS_RESTART)
schedule_work(&adapter->reset_task);
/* The link is lost so the controller stops DMA.
* 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
pm_schedule_suspend(netdev->dev.parent,
LINK_TIMEOUT);
Expand All @@ -4551,20 +4559,14 @@ static void e1000_watchdog_task(struct work_struct *work)
adapter->gotc_old = adapter->stats.gotc;
spin_unlock(&adapter->stats64_lock);

e1000e_update_adaptive(&adapter->hw);

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).
*/
if (adapter->flags & FLAG_RESTART_NOW) {
schedule_work(&adapter->reset_task);
/* return immediately since reset is imminent */
return;
}

e1000e_update_adaptive(&adapter->hw);

/* Simple mode for Interrupt Throttle Rate (ITR) */
if (adapter->itr_setting == 4) {
/* Symmetric Tx/Rx gets a reduced ITR=2000;
Expand Down Expand Up @@ -5134,10 +5136,9 @@ static void e1000_reset_task(struct work_struct *work)
if (test_bit(__E1000_DOWN, &adapter->state))
return;

if (!((adapter->flags & FLAG_RX_NEEDS_RESTART) &&
(adapter->flags & FLAG_RX_RESTART_NOW))) {
if (!(adapter->flags & FLAG_RESTART_NOW)) {
e1000e_dump(adapter);
e_err("Reset adapter\n");
e_err("Reset adapter unexpectedly\n");
}
e1000e_reinit_locked(adapter);
}
Expand Down

0 comments on commit 12d43f7

Please sign in to comment.