diff options
-rw-r--r-- | drivers/net/e1000/e1000_main.c | 28 |
1 files changed, 24 insertions, 4 deletions
diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c index 5c61b921ca71..93b861d032b5 100644 --- a/drivers/net/e1000/e1000_main.c +++ b/drivers/net/e1000/e1000_main.c | |||
@@ -577,12 +577,30 @@ out: | |||
577 | 577 | ||
578 | void e1000_down(struct e1000_adapter *adapter) | 578 | void e1000_down(struct e1000_adapter *adapter) |
579 | { | 579 | { |
580 | struct e1000_hw *hw = &adapter->hw; | ||
580 | struct net_device *netdev = adapter->netdev; | 581 | struct net_device *netdev = adapter->netdev; |
582 | u32 rctl, tctl; | ||
581 | 583 | ||
582 | /* signal that we're down so the interrupt handler does not | 584 | /* signal that we're down so the interrupt handler does not |
583 | * reschedule our watchdog timer */ | 585 | * reschedule our watchdog timer */ |
584 | set_bit(__E1000_DOWN, &adapter->flags); | 586 | set_bit(__E1000_DOWN, &adapter->flags); |
585 | 587 | ||
588 | /* disable receives in the hardware */ | ||
589 | rctl = er32(RCTL); | ||
590 | ew32(RCTL, rctl & ~E1000_RCTL_EN); | ||
591 | /* flush and sleep below */ | ||
592 | |||
593 | /* can be netif_tx_disable when NETIF_F_LLTX is removed */ | ||
594 | netif_stop_queue(netdev); | ||
595 | |||
596 | /* disable transmits in the hardware */ | ||
597 | tctl = er32(TCTL); | ||
598 | tctl &= ~E1000_TCTL_EN; | ||
599 | ew32(TCTL, tctl); | ||
600 | /* flush both disables and wait for them to finish */ | ||
601 | E1000_WRITE_FLUSH(); | ||
602 | msleep(10); | ||
603 | |||
586 | napi_disable(&adapter->napi); | 604 | napi_disable(&adapter->napi); |
587 | 605 | ||
588 | e1000_irq_disable(adapter); | 606 | e1000_irq_disable(adapter); |
@@ -595,7 +613,6 @@ void e1000_down(struct e1000_adapter *adapter) | |||
595 | adapter->link_speed = 0; | 613 | adapter->link_speed = 0; |
596 | adapter->link_duplex = 0; | 614 | adapter->link_duplex = 0; |
597 | netif_carrier_off(netdev); | 615 | netif_carrier_off(netdev); |
598 | netif_stop_queue(netdev); | ||
599 | 616 | ||
600 | e1000_reset(adapter); | 617 | e1000_reset(adapter); |
601 | e1000_clean_all_tx_rings(adapter); | 618 | e1000_clean_all_tx_rings(adapter); |
@@ -3744,10 +3761,12 @@ static irqreturn_t e1000_intr(int irq, void *data) | |||
3744 | adapter->total_rx_bytes = 0; | 3761 | adapter->total_rx_bytes = 0; |
3745 | adapter->total_rx_packets = 0; | 3762 | adapter->total_rx_packets = 0; |
3746 | __napi_schedule(&adapter->napi); | 3763 | __napi_schedule(&adapter->napi); |
3747 | } else | 3764 | } else { |
3748 | /* this really should not happen! if it does it is basically a | 3765 | /* this really should not happen! if it does it is basically a |
3749 | * bug, but not a hard error, so enable ints and continue */ | 3766 | * bug, but not a hard error, so enable ints and continue */ |
3750 | e1000_irq_enable(adapter); | 3767 | if (!test_bit(__E1000_DOWN, &adapter->flags)) |
3768 | e1000_irq_enable(adapter); | ||
3769 | } | ||
3751 | 3770 | ||
3752 | return IRQ_HANDLED; | 3771 | return IRQ_HANDLED; |
3753 | } | 3772 | } |
@@ -3777,7 +3796,8 @@ static int e1000_clean(struct napi_struct *napi, int budget) | |||
3777 | if (likely(adapter->itr_setting & 3)) | 3796 | if (likely(adapter->itr_setting & 3)) |
3778 | e1000_set_itr(adapter); | 3797 | e1000_set_itr(adapter); |
3779 | napi_complete(napi); | 3798 | napi_complete(napi); |
3780 | e1000_irq_enable(adapter); | 3799 | if (!test_bit(__E1000_DOWN, &adapter->flags)) |
3800 | e1000_irq_enable(adapter); | ||
3781 | } | 3801 | } |
3782 | 3802 | ||
3783 | return work_done; | 3803 | return work_done; |