|
|
@@ -1910,14 +1910,30 @@ static irqreturn_t e1000_msix_other(int __always_unused irq, void *data)
|
|
|
struct net_device *netdev = data;
|
|
|
struct e1000_adapter *adapter = netdev_priv(netdev);
|
|
|
struct e1000_hw *hw = &adapter->hw;
|
|
|
+ u32 icr;
|
|
|
+ bool enable = true;
|
|
|
+
|
|
|
+ icr = er32(ICR);
|
|
|
+ if (icr & E1000_ICR_RXO) {
|
|
|
+ ew32(ICR, E1000_ICR_RXO);
|
|
|
+ enable = false;
|
|
|
+ /* napi poll will re-enable Other, make sure it runs */
|
|
|
+ if (napi_schedule_prep(&adapter->napi)) {
|
|
|
+ adapter->total_rx_bytes = 0;
|
|
|
+ adapter->total_rx_packets = 0;
|
|
|
+ __napi_schedule(&adapter->napi);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (icr & E1000_ICR_LSC) {
|
|
|
+ ew32(ICR, E1000_ICR_LSC);
|
|
|
+ hw->mac.get_link_status = true;
|
|
|
+ /* guard against interrupt when we're going down */
|
|
|
+ if (!test_bit(__E1000_DOWN, &adapter->state))
|
|
|
+ mod_timer(&adapter->watchdog_timer, jiffies + 1);
|
|
|
+ }
|
|
|
|
|
|
- hw->mac.get_link_status = true;
|
|
|
-
|
|
|
- /* guard against interrupt when we're going down */
|
|
|
- if (!test_bit(__E1000_DOWN, &adapter->state)) {
|
|
|
- mod_timer(&adapter->watchdog_timer, jiffies + 1);
|
|
|
+ if (enable && !test_bit(__E1000_DOWN, &adapter->state))
|
|
|
ew32(IMS, E1000_IMS_OTHER);
|
|
|
- }
|
|
|
|
|
|
return IRQ_HANDLED;
|
|
|
}
|
|
|
@@ -2687,7 +2703,8 @@ static int e1000e_poll(struct napi_struct *napi, int weight)
|
|
|
napi_complete_done(napi, work_done);
|
|
|
if (!test_bit(__E1000_DOWN, &adapter->state)) {
|
|
|
if (adapter->msix_entries)
|
|
|
- ew32(IMS, adapter->rx_ring->ims_val);
|
|
|
+ ew32(IMS, adapter->rx_ring->ims_val |
|
|
|
+ E1000_IMS_OTHER);
|
|
|
else
|
|
|
e1000_irq_enable(adapter);
|
|
|
}
|
|
|
@@ -4204,7 +4221,7 @@ static void e1000e_trigger_lsc(struct e1000_adapter *adapter)
|
|
|
struct e1000_hw *hw = &adapter->hw;
|
|
|
|
|
|
if (adapter->msix_entries)
|
|
|
- ew32(ICS, E1000_ICS_OTHER);
|
|
|
+ ew32(ICS, E1000_ICS_LSC | E1000_ICS_OTHER);
|
|
|
else
|
|
|
ew32(ICS, E1000_ICS_LSC);
|
|
|
}
|