Skip to content

Commit 024aa58

Browse files
Björn TöpelJeff Kirsher
authored andcommitted
ixgbe: added Rx/Tx ring disable/enable functions
Add functions for Rx/Tx ring enable/disable. Instead of resetting the whole device, only the affected ring is disabled or enabled. This plumbing is used in later commits, when zero-copy AF_XDP support is introduced. Signed-off-by: Björn Töpel <[email protected]> Tested-by: William Tu <[email protected]> Tested-by: Andrew Bowers <[email protected]> Signed-off-by: Jeff Kirsher <[email protected]>
1 parent 5d826d2 commit 024aa58

File tree

2 files changed

+159
-0
lines changed

2 files changed

+159
-0
lines changed

drivers/net/ethernet/intel/ixgbe/ixgbe.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -271,6 +271,7 @@ enum ixgbe_ring_state_t {
271271
__IXGBE_TX_DETECT_HANG,
272272
__IXGBE_HANG_CHECK_ARMED,
273273
__IXGBE_TX_XDP_RING,
274+
__IXGBE_TX_DISABLED,
274275
};
275276

276277
#define ring_uses_build_skb(ring) \

drivers/net/ethernet/intel/ixgbe/ixgbe_main.c

Lines changed: 158 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)