mirror of https://gitee.com/openkylin/linux.git
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:
parent
3d4d5755f1
commit
12d43f7d3c
|
@ -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)
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue