@@ -8692,6 +8692,8 @@ static netdev_tx_t __ixgbe_xmit_frame(struct sk_buff *skb,
86928692 return NETDEV_TX_OK ;
86938693
86948694 tx_ring = ring ? ring : adapter -> tx_ring [skb -> queue_mapping ];
8695+ if (unlikely (test_bit (__IXGBE_TX_DISABLED , & tx_ring -> state )))
8696+ return NETDEV_TX_BUSY ;
86958697
86968698 return ixgbe_xmit_frame_ring (skb , adapter , tx_ring );
86978699}
@@ -10238,6 +10240,9 @@ static int ixgbe_xdp_xmit(struct net_device *dev, int n,
1023810240 if (unlikely (!ring ))
1023910241 return - ENXIO ;
1024010242
10243+ if (unlikely (test_bit (__IXGBE_TX_DISABLED , & ring -> state )))
10244+ return - ENXIO ;
10245+
1024110246 for (i = 0 ; i < n ; i ++ ) {
1024210247 struct xdp_frame * xdpf = frames [i ];
1024310248 int err ;
@@ -10301,6 +10306,159 @@ static const struct net_device_ops ixgbe_netdev_ops = {
1030110306 .ndo_xdp_xmit = ixgbe_xdp_xmit ,
1030210307};
1030310308
10309+ static void ixgbe_disable_txr_hw (struct ixgbe_adapter * adapter ,
10310+ struct ixgbe_ring * tx_ring )
10311+ {
10312+ unsigned long wait_delay , delay_interval ;
10313+ struct ixgbe_hw * hw = & adapter -> hw ;
10314+ u8 reg_idx = tx_ring -> reg_idx ;
10315+ int wait_loop ;
10316+ u32 txdctl ;
10317+
10318+ IXGBE_WRITE_REG (hw , IXGBE_TXDCTL (reg_idx ), IXGBE_TXDCTL_SWFLSH );
10319+
10320+ /* delay mechanism from ixgbe_disable_tx */
10321+ delay_interval = ixgbe_get_completion_timeout (adapter ) / 100 ;
10322+
10323+ wait_loop = IXGBE_MAX_RX_DESC_POLL ;
10324+ wait_delay = delay_interval ;
10325+
10326+ while (wait_loop -- ) {
10327+ usleep_range (wait_delay , wait_delay + 10 );
10328+ wait_delay += delay_interval * 2 ;
10329+ txdctl = IXGBE_READ_REG (hw , IXGBE_TXDCTL (reg_idx ));
10330+
10331+ if (!(txdctl & IXGBE_TXDCTL_ENABLE ))
10332+ return ;
10333+ }
10334+
10335+ e_err (drv , "TXDCTL.ENABLE not cleared within the polling period\n" );
10336+ }
10337+
10338+ static void ixgbe_disable_txr (struct ixgbe_adapter * adapter ,
10339+ struct ixgbe_ring * tx_ring )
10340+ {
10341+ set_bit (__IXGBE_TX_DISABLED , & tx_ring -> state );
10342+ ixgbe_disable_txr_hw (adapter , tx_ring );
10343+ }
10344+
10345+ static void ixgbe_disable_rxr_hw (struct ixgbe_adapter * adapter ,
10346+ struct ixgbe_ring * rx_ring )
10347+ {
10348+ unsigned long wait_delay , delay_interval ;
10349+ struct ixgbe_hw * hw = & adapter -> hw ;
10350+ u8 reg_idx = rx_ring -> reg_idx ;
10351+ int wait_loop ;
10352+ u32 rxdctl ;
10353+
10354+ rxdctl = IXGBE_READ_REG (hw , IXGBE_RXDCTL (reg_idx ));
10355+ rxdctl &= ~IXGBE_RXDCTL_ENABLE ;
10356+ rxdctl |= IXGBE_RXDCTL_SWFLSH ;
10357+
10358+ /* write value back with RXDCTL.ENABLE bit cleared */
10359+ IXGBE_WRITE_REG (hw , IXGBE_RXDCTL (reg_idx ), rxdctl );
10360+
10361+ /* RXDCTL.EN may not change on 82598 if link is down, so skip it */
10362+ if (hw -> mac .type == ixgbe_mac_82598EB &&
10363+ !(IXGBE_READ_REG (hw , IXGBE_LINKS ) & IXGBE_LINKS_UP ))
10364+ return ;
10365+
10366+ /* delay mechanism from ixgbe_disable_rx */
10367+ delay_interval = ixgbe_get_completion_timeout (adapter ) / 100 ;
10368+
10369+ wait_loop = IXGBE_MAX_RX_DESC_POLL ;
10370+ wait_delay = delay_interval ;
10371+
10372+ while (wait_loop -- ) {
10373+ usleep_range (wait_delay , wait_delay + 10 );
10374+ wait_delay += delay_interval * 2 ;
10375+ rxdctl = IXGBE_READ_REG (hw , IXGBE_RXDCTL (reg_idx ));
10376+
10377+ if (!(rxdctl & IXGBE_RXDCTL_ENABLE ))
10378+ return ;
10379+ }
10380+
10381+ e_err (drv , "RXDCTL.ENABLE not cleared within the polling period\n" );
10382+ }
10383+
10384+ static void ixgbe_reset_txr_stats (struct ixgbe_ring * tx_ring )
10385+ {
10386+ memset (& tx_ring -> stats , 0 , sizeof (tx_ring -> stats ));
10387+ memset (& tx_ring -> tx_stats , 0 , sizeof (tx_ring -> tx_stats ));
10388+ }
10389+
10390+ static void ixgbe_reset_rxr_stats (struct ixgbe_ring * rx_ring )
10391+ {
10392+ memset (& rx_ring -> stats , 0 , sizeof (rx_ring -> stats ));
10393+ memset (& rx_ring -> rx_stats , 0 , sizeof (rx_ring -> rx_stats ));
10394+ }
10395+
10396+ /**
10397+ * ixgbe_txrx_ring_disable - Disable Rx/Tx/XDP Tx rings
10398+ * @adapter: adapter structure
10399+ * @ring: ring index
10400+ *
10401+ * This function disables a certain Rx/Tx/XDP Tx ring. The function
10402+ * assumes that the netdev is running.
10403+ **/
10404+ void ixgbe_txrx_ring_disable (struct ixgbe_adapter * adapter , int ring )
10405+ {
10406+ struct ixgbe_ring * rx_ring , * tx_ring , * xdp_ring ;
10407+
10408+ rx_ring = adapter -> rx_ring [ring ];
10409+ tx_ring = adapter -> tx_ring [ring ];
10410+ xdp_ring = adapter -> xdp_ring [ring ];
10411+
10412+ ixgbe_disable_txr (adapter , tx_ring );
10413+ if (xdp_ring )
10414+ ixgbe_disable_txr (adapter , xdp_ring );
10415+ ixgbe_disable_rxr_hw (adapter , rx_ring );
10416+
10417+ if (xdp_ring )
10418+ synchronize_sched ();
10419+
10420+ /* Rx/Tx/XDP Tx share the same napi context. */
10421+ napi_disable (& rx_ring -> q_vector -> napi );
10422+
10423+ ixgbe_clean_tx_ring (tx_ring );
10424+ if (xdp_ring )
10425+ ixgbe_clean_tx_ring (xdp_ring );
10426+ ixgbe_clean_rx_ring (rx_ring );
10427+
10428+ ixgbe_reset_txr_stats (tx_ring );
10429+ if (xdp_ring )
10430+ ixgbe_reset_txr_stats (xdp_ring );
10431+ ixgbe_reset_rxr_stats (rx_ring );
10432+ }
10433+
10434+ /**
10435+ * ixgbe_txrx_ring_enable - Enable Rx/Tx/XDP Tx rings
10436+ * @adapter: adapter structure
10437+ * @ring: ring index
10438+ *
10439+ * This function enables a certain Rx/Tx/XDP Tx ring. The function
10440+ * assumes that the netdev is running.
10441+ **/
10442+ void ixgbe_txrx_ring_enable (struct ixgbe_adapter * adapter , int ring )
10443+ {
10444+ struct ixgbe_ring * rx_ring , * tx_ring , * xdp_ring ;
10445+
10446+ rx_ring = adapter -> rx_ring [ring ];
10447+ tx_ring = adapter -> tx_ring [ring ];
10448+ xdp_ring = adapter -> xdp_ring [ring ];
10449+
10450+ /* Rx/Tx/XDP Tx share the same napi context. */
10451+ napi_enable (& rx_ring -> q_vector -> napi );
10452+
10453+ ixgbe_configure_tx_ring (adapter , tx_ring );
10454+ if (xdp_ring )
10455+ ixgbe_configure_tx_ring (adapter , xdp_ring );
10456+ ixgbe_configure_rx_ring (adapter , rx_ring );
10457+
10458+ clear_bit (__IXGBE_TX_DISABLED , & tx_ring -> state );
10459+ clear_bit (__IXGBE_TX_DISABLED , & xdp_ring -> state );
10460+ }
10461+
1030410462/**
1030510463 * ixgbe_enumerate_functions - Get the number of ports this device has
1030610464 * @adapter: adapter structure
0 commit comments