@@ -902,6 +902,7 @@ static bool enetc_clean_tx_ring(struct enetc_bdr *tx_ring, int napi_budget)
902902
903903 if (unlikely (tx_frm_cnt && netif_carrier_ok (ndev ) &&
904904 __netif_subqueue_stopped (ndev , tx_ring -> index ) &&
905+ !test_bit (ENETC_TX_DOWN , & priv -> flags ) &&
905906 (enetc_bd_unused (tx_ring ) >= ENETC_TXBDS_MAX_NEEDED ))) {
906907 netif_wake_subqueue (ndev , tx_ring -> index );
907908 }
@@ -1377,6 +1378,9 @@ int enetc_xdp_xmit(struct net_device *ndev, int num_frames,
13771378 int xdp_tx_bd_cnt , i , k ;
13781379 int xdp_tx_frm_cnt = 0 ;
13791380
1381+ if (unlikely (test_bit (ENETC_TX_DOWN , & priv -> flags )))
1382+ return - ENETDOWN ;
1383+
13801384 enetc_lock_mdio ();
13811385
13821386 tx_ring = priv -> xdp_tx_ring [smp_processor_id ()];
@@ -1521,7 +1525,6 @@ static void enetc_xdp_drop(struct enetc_bdr *rx_ring, int rx_ring_first,
15211525 & rx_ring -> rx_swbd [rx_ring_first ]);
15221526 enetc_bdr_idx_inc (rx_ring , & rx_ring_first );
15231527 }
1524- rx_ring -> stats .xdp_drops ++ ;
15251528}
15261529
15271530static int enetc_clean_rx_ring_xdp (struct enetc_bdr * rx_ring ,
@@ -1586,6 +1589,7 @@ static int enetc_clean_rx_ring_xdp(struct enetc_bdr *rx_ring,
15861589 fallthrough ;
15871590 case XDP_DROP :
15881591 enetc_xdp_drop (rx_ring , orig_i , i );
1592+ rx_ring -> stats .xdp_drops ++ ;
15891593 break ;
15901594 case XDP_PASS :
15911595 rxbd = orig_rxbd ;
@@ -1602,6 +1606,12 @@ static int enetc_clean_rx_ring_xdp(struct enetc_bdr *rx_ring,
16021606 break ;
16031607 case XDP_TX :
16041608 tx_ring = priv -> xdp_tx_ring [rx_ring -> index ];
1609+ if (unlikely (test_bit (ENETC_TX_DOWN , & priv -> flags ))) {
1610+ enetc_xdp_drop (rx_ring , orig_i , i );
1611+ tx_ring -> stats .xdp_tx_drops ++ ;
1612+ break ;
1613+ }
1614+
16051615 xdp_tx_bd_cnt = enetc_rx_swbd_to_xdp_tx_swbd (xdp_tx_arr ,
16061616 rx_ring ,
16071617 orig_i , i );
@@ -2223,18 +2233,24 @@ static void enetc_enable_rxbdr(struct enetc_hw *hw, struct enetc_bdr *rx_ring)
22232233 enetc_rxbdr_wr (hw , idx , ENETC_RBMR , rbmr );
22242234}
22252235
2226- static void enetc_enable_bdrs (struct enetc_ndev_priv * priv )
2236+ static void enetc_enable_rx_bdrs (struct enetc_ndev_priv * priv )
22272237{
22282238 struct enetc_hw * hw = & priv -> si -> hw ;
22292239 int i ;
22302240
2231- for (i = 0 ; i < priv -> num_tx_rings ; i ++ )
2232- enetc_enable_txbdr (hw , priv -> tx_ring [i ]);
2233-
22342241 for (i = 0 ; i < priv -> num_rx_rings ; i ++ )
22352242 enetc_enable_rxbdr (hw , priv -> rx_ring [i ]);
22362243}
22372244
2245+ static void enetc_enable_tx_bdrs (struct enetc_ndev_priv * priv )
2246+ {
2247+ struct enetc_hw * hw = & priv -> si -> hw ;
2248+ int i ;
2249+
2250+ for (i = 0 ; i < priv -> num_tx_rings ; i ++ )
2251+ enetc_enable_txbdr (hw , priv -> tx_ring [i ]);
2252+ }
2253+
22382254static void enetc_disable_rxbdr (struct enetc_hw * hw , struct enetc_bdr * rx_ring )
22392255{
22402256 int idx = rx_ring -> index ;
@@ -2251,18 +2267,24 @@ static void enetc_disable_txbdr(struct enetc_hw *hw, struct enetc_bdr *rx_ring)
22512267 enetc_txbdr_wr (hw , idx , ENETC_TBMR , 0 );
22522268}
22532269
2254- static void enetc_disable_bdrs (struct enetc_ndev_priv * priv )
2270+ static void enetc_disable_rx_bdrs (struct enetc_ndev_priv * priv )
22552271{
22562272 struct enetc_hw * hw = & priv -> si -> hw ;
22572273 int i ;
22582274
2259- for (i = 0 ; i < priv -> num_tx_rings ; i ++ )
2260- enetc_disable_txbdr (hw , priv -> tx_ring [i ]);
2261-
22622275 for (i = 0 ; i < priv -> num_rx_rings ; i ++ )
22632276 enetc_disable_rxbdr (hw , priv -> rx_ring [i ]);
22642277}
22652278
2279+ static void enetc_disable_tx_bdrs (struct enetc_ndev_priv * priv )
2280+ {
2281+ struct enetc_hw * hw = & priv -> si -> hw ;
2282+ int i ;
2283+
2284+ for (i = 0 ; i < priv -> num_tx_rings ; i ++ )
2285+ enetc_disable_txbdr (hw , priv -> tx_ring [i ]);
2286+ }
2287+
22662288static void enetc_wait_txbdr (struct enetc_hw * hw , struct enetc_bdr * tx_ring )
22672289{
22682290 int delay = 8 , timeout = 100 ;
@@ -2460,9 +2482,13 @@ void enetc_start(struct net_device *ndev)
24602482 enable_irq (irq );
24612483 }
24622484
2463- enetc_enable_bdrs (priv );
2485+ enetc_enable_tx_bdrs (priv );
2486+
2487+ enetc_enable_rx_bdrs (priv );
24642488
24652489 netif_tx_start_all_queues (ndev );
2490+
2491+ clear_bit (ENETC_TX_DOWN , & priv -> flags );
24662492}
24672493EXPORT_SYMBOL_GPL (enetc_start );
24682494
@@ -2520,9 +2546,15 @@ void enetc_stop(struct net_device *ndev)
25202546 struct enetc_ndev_priv * priv = netdev_priv (ndev );
25212547 int i ;
25222548
2549+ set_bit (ENETC_TX_DOWN , & priv -> flags );
2550+
25232551 netif_tx_stop_all_queues (ndev );
25242552
2525- enetc_disable_bdrs (priv );
2553+ enetc_disable_rx_bdrs (priv );
2554+
2555+ enetc_wait_bdrs (priv );
2556+
2557+ enetc_disable_tx_bdrs (priv );
25262558
25272559 for (i = 0 ; i < priv -> bdr_int_num ; i ++ ) {
25282560 int irq = pci_irq_vector (priv -> si -> pdev ,
@@ -2533,8 +2565,6 @@ void enetc_stop(struct net_device *ndev)
25332565 napi_disable (& priv -> int_vector [i ]-> napi );
25342566 }
25352567
2536- enetc_wait_bdrs (priv );
2537-
25382568 enetc_clear_interrupts (priv );
25392569}
25402570EXPORT_SYMBOL_GPL (enetc_stop );
0 commit comments