diff --git a/drivers/net/ethernet/wangxun/libwx/wx_hw.c b/drivers/net/ethernet/wangxun/libwx/wx_hw.c index 2451f6b20b11..260e14d5d541 100644 --- a/drivers/net/ethernet/wangxun/libwx/wx_hw.c +++ b/drivers/net/ethernet/wangxun/libwx/wx_hw.c @@ -2520,6 +2520,7 @@ int wx_sw_init(struct wx *wx) mutex_init(&wx->reset_lock); bitmap_zero(wx->state, WX_STATE_NBITS); bitmap_zero(wx->flags, WX_PF_FLAGS_NBITS); + set_bit(WX_STATE_DOWN, wx->state); wx->misc_irq_domain = false; return 0; @@ -2875,7 +2876,7 @@ void wx_update_stats(struct wx *wx) u64 restart_queue = 0, tx_busy = 0; u32 i; - if (!netif_running(wx->netdev) || + if (test_bit(WX_STATE_DOWN, wx->state) || test_bit(WX_STATE_RESETTING, wx->state)) return; diff --git a/drivers/net/ethernet/wangxun/libwx/wx_lib.c b/drivers/net/ethernet/wangxun/libwx/wx_lib.c index 746623fa59b4..d042567b8128 100644 --- a/drivers/net/ethernet/wangxun/libwx/wx_lib.c +++ b/drivers/net/ethernet/wangxun/libwx/wx_lib.c @@ -876,7 +876,7 @@ static bool wx_clean_tx_irq(struct wx_q_vector *q_vector, if (__netif_subqueue_stopped(tx_ring->netdev, tx_ring->queue_index) && - netif_running(tx_ring->netdev)) { + !test_bit(WX_STATE_DOWN, wx->state)) { netif_wake_subqueue(tx_ring->netdev, tx_ring->queue_index); ++tx_ring->tx_stats.restart_queue; @@ -964,7 +964,7 @@ static int wx_poll(struct napi_struct *napi, int budget) if (likely(napi_complete_done(napi, work_done))) { if (wx->adaptive_itr) wx_update_dim_sample(q_vector); - if (netif_running(wx->netdev)) + if (!test_bit(WX_STATE_DOWN, wx->state)) wx_intr_enable(wx, WX_INTR_Q(q_vector->v_idx)); } @@ -2341,6 +2341,8 @@ int wx_init_interrupt_scheme(struct wx *wx) wx_cache_ring_rss(wx); + set_bit(WX_STATE_DOWN, wx->state); + return 0; } EXPORT_SYMBOL(wx_init_interrupt_scheme); @@ -3314,7 +3316,8 @@ EXPORT_SYMBOL(wx_set_ring); void wx_service_event_schedule(struct wx *wx) { - if (!test_and_set_bit(WX_STATE_SERVICE_SCHED, wx->state)) + if (!test_bit(WX_STATE_DOWN, wx->state) && + !test_and_set_bit(WX_STATE_SERVICE_SCHED, wx->state)) queue_work(system_power_efficient_wq, &wx->service_task); } EXPORT_SYMBOL(wx_service_event_schedule); diff --git a/drivers/net/ethernet/wangxun/libwx/wx_sriov.c b/drivers/net/ethernet/wangxun/libwx/wx_sriov.c index a360b06a086a..0152004a2dd3 100644 --- a/drivers/net/ethernet/wangxun/libwx/wx_sriov.c +++ b/drivers/net/ethernet/wangxun/libwx/wx_sriov.c @@ -898,7 +898,7 @@ static void wx_set_vf_link_state(struct wx *wx, int vf, int state) wx->vfinfo[vf].link_state = state; switch (state) { case IFLA_VF_LINK_STATE_AUTO: - if (netif_running(wx->netdev)) + if (!test_bit(WX_STATE_DOWN, wx->state)) wx->vfinfo[vf].link_enable = true; else wx->vfinfo[vf].link_enable = false; diff --git a/drivers/net/ethernet/wangxun/libwx/wx_type.h b/drivers/net/ethernet/wangxun/libwx/wx_type.h index 0da5565ee4ff..c7befe4cdfe9 100644 --- a/drivers/net/ethernet/wangxun/libwx/wx_type.h +++ b/drivers/net/ethernet/wangxun/libwx/wx_type.h @@ -1202,6 +1202,7 @@ struct wx_last_stats { }; enum wx_state { + WX_STATE_DOWN, WX_STATE_RESETTING, WX_STATE_SWFW_BUSY, WX_STATE_PTP_RUNNING, diff --git a/drivers/net/ethernet/wangxun/libwx/wx_vf_common.c b/drivers/net/ethernet/wangxun/libwx/wx_vf_common.c index 94ff8f5f0b4c..0d2db8d38cd5 100644 --- a/drivers/net/ethernet/wangxun/libwx/wx_vf_common.c +++ b/drivers/net/ethernet/wangxun/libwx/wx_vf_common.c @@ -68,7 +68,7 @@ static irqreturn_t wx_msix_misc_vf(int __always_unused irq, void *data) set_bit(WX_FLAG_NEED_UPDATE_LINK, wx->flags); /* Clear the interrupt */ - if (netif_running(wx->netdev)) + if (!test_bit(WX_STATE_DOWN, wx->state)) wr32(wx, WX_VXIMC, wx->eims_other); return IRQ_HANDLED; @@ -278,6 +278,7 @@ static void wxvf_up_complete(struct wx *wx) wx_configure_msix_vf(wx); smp_mb__before_atomic(); + clear_bit(WX_STATE_DOWN, wx->state); wx_napi_enable_all(wx); /* clear any pending interrupts, may auto mask */ @@ -327,6 +328,9 @@ static void wxvf_down(struct wx *wx) { struct net_device *netdev = wx->netdev; + if (test_and_set_bit(WX_STATE_DOWN, wx->state)) + return; + timer_delete_sync(&wx->service_timer); netif_tx_stop_all_queues(netdev); netif_tx_disable(netdev); @@ -360,7 +364,7 @@ static void wxvf_reset_subtask(struct wx *wx) rtnl_lock(); if (test_bit(WX_STATE_RESETTING, wx->state) || - !(netif_running(wx->netdev))) { + test_bit(WX_STATE_DOWN, wx->state)) { rtnl_unlock(); return; } diff --git a/drivers/net/ethernet/wangxun/ngbe/ngbe_main.c b/drivers/net/ethernet/wangxun/ngbe/ngbe_main.c index d51d8db95a76..f4a2dd6fa493 100644 --- a/drivers/net/ethernet/wangxun/ngbe/ngbe_main.c +++ b/drivers/net/ethernet/wangxun/ngbe/ngbe_main.c @@ -204,7 +204,7 @@ static irqreturn_t ngbe_intr(int __always_unused irq, void *data) /* shared interrupt alert! * the interrupt that we masked before the EICR read. */ - if (netif_running(wx->netdev)) + if (!test_bit(WX_STATE_DOWN, wx->state)) ngbe_irq_enable(wx, true); return IRQ_NONE; /* Not our interrupt */ } @@ -220,7 +220,7 @@ static irqreturn_t ngbe_intr(int __always_unused irq, void *data) /* would disable interrupts here but it is auto disabled */ napi_schedule_irqoff(&q_vector->napi); - if (netif_running(wx->netdev)) + if (!test_bit(WX_STATE_DOWN, wx->state)) ngbe_irq_enable(wx, false); return IRQ_HANDLED; @@ -235,7 +235,7 @@ static irqreturn_t __ngbe_msix_misc(struct wx *wx, u32 eicr) wx_ptp_check_pps_event(wx); /* re-enable the original interrupt state, no lsc, no queues */ - if (netif_running(wx->netdev)) + if (!test_bit(WX_STATE_DOWN, wx->state)) ngbe_irq_enable(wx, false); return IRQ_HANDLED; @@ -262,7 +262,7 @@ static irqreturn_t ngbe_misc_and_queue(int __always_unused irq, void *data) /* queue */ q_vector = wx->q_vector[0]; napi_schedule_irqoff(&q_vector->napi); - if (netif_running(wx->netdev)) + if (!test_bit(WX_STATE_DOWN, wx->state)) ngbe_irq_enable(wx, true); return IRQ_HANDLED; } @@ -363,6 +363,9 @@ static void ngbe_disable_device(struct wx *wx) struct net_device *netdev = wx->netdev; u32 i; + if (test_and_set_bit(WX_STATE_DOWN, wx->state)) + return; + if (wx->num_vfs) { /* Clear EITR Select mapping */ wr32(wx, WX_PX_ITRSEL, 0); @@ -428,6 +431,7 @@ void ngbe_up(struct wx *wx) /* make sure to complete pre-operations */ smp_mb__before_atomic(); + clear_bit(WX_STATE_DOWN, wx->state); wx_napi_enable_all(wx); /* enable transmits */ netif_tx_start_all_queues(wx->netdev); diff --git a/drivers/net/ethernet/wangxun/txgbe/txgbe_irq.c b/drivers/net/ethernet/wangxun/txgbe/txgbe_irq.c index aa14958d439a..8746318ad3bc 100644 --- a/drivers/net/ethernet/wangxun/txgbe/txgbe_irq.c +++ b/drivers/net/ethernet/wangxun/txgbe/txgbe_irq.c @@ -141,7 +141,7 @@ static irqreturn_t txgbe_misc_irq_handle(int irq, void *data) /* shared interrupt alert! * the interrupt that we masked before the ICR read. */ - if (netif_running(wx->netdev)) + if (!test_bit(WX_STATE_DOWN, wx->state)) txgbe_irq_enable(wx, true); return IRQ_NONE; /* Not our interrupt */ } diff --git a/drivers/net/ethernet/wangxun/txgbe/txgbe_main.c b/drivers/net/ethernet/wangxun/txgbe/txgbe_main.c index 4c549c2644ab..f9cd1caaf0a4 100644 --- a/drivers/net/ethernet/wangxun/txgbe/txgbe_main.c +++ b/drivers/net/ethernet/wangxun/txgbe/txgbe_main.c @@ -151,6 +151,7 @@ static void txgbe_up_complete(struct wx *wx) /* make sure to complete pre-operations */ smp_mb__before_atomic(); + clear_bit(WX_STATE_DOWN, wx->state); wx_napi_enable_all(wx); switch (wx->mac.type) { @@ -213,6 +214,9 @@ static void txgbe_disable_device(struct wx *wx) struct net_device *netdev = wx->netdev; u32 i; + if (test_and_set_bit(WX_STATE_DOWN, wx->state)) + return; + wx_disable_pcie_master(wx); /* disable receives */ wx_disable_rx(wx);