Skip to content

Commit

Permalink
net/ngbe: restrict configuration of VLAN strip offload
Browse files Browse the repository at this point in the history
There is a hardware limitation that Rx ring config register is not
writable when Rx ring is enabled, i.e. the NGBE_RXCFG_ENA bit is set.
But disabling the ring when there is traffic will cause ring get stuck.
So restrict the configuration of VLAN strip offload only if device is
started.

Fixes: 59b4643 ("net/ngbe: support VLAN offload and VLAN filter")
Cc: [email protected]

Signed-off-by: Jiawen Wu <[email protected]>
  • Loading branch information
Jiawen Wu authored and ferruhy committed Nov 6, 2024
1 parent 68f04c0 commit baca8ec
Showing 1 changed file with 20 additions and 29 deletions.
49 changes: 20 additions & 29 deletions drivers/net/ngbe/ngbe_ethdev.c
Original file line number Diff line number Diff line change
Expand Up @@ -586,41 +586,25 @@ ngbe_vlan_filter_set(struct rte_eth_dev *dev, uint16_t vlan_id, int on)
}

static void
ngbe_vlan_strip_queue_set(struct rte_eth_dev *dev, uint16_t queue, int on)
ngbe_vlan_strip_q_set(struct rte_eth_dev *dev, uint16_t queue, int on)
{
struct ngbe_hw *hw = ngbe_dev_hw(dev);
struct ngbe_rx_queue *rxq;
bool restart;
uint32_t rxcfg, rxbal, rxbah;

if (on)
ngbe_vlan_hw_strip_enable(dev, queue);
else
ngbe_vlan_hw_strip_disable(dev, queue);
}

rxq = dev->data->rx_queues[queue];
rxbal = rd32(hw, NGBE_RXBAL(rxq->reg_idx));
rxbah = rd32(hw, NGBE_RXBAH(rxq->reg_idx));
rxcfg = rd32(hw, NGBE_RXCFG(rxq->reg_idx));
if (rxq->offloads & RTE_ETH_RX_OFFLOAD_VLAN_STRIP) {
restart = (rxcfg & NGBE_RXCFG_ENA) &&
!(rxcfg & NGBE_RXCFG_VLAN);
rxcfg |= NGBE_RXCFG_VLAN;
} else {
restart = (rxcfg & NGBE_RXCFG_ENA) &&
(rxcfg & NGBE_RXCFG_VLAN);
rxcfg &= ~NGBE_RXCFG_VLAN;
}
rxcfg &= ~NGBE_RXCFG_ENA;
static void
ngbe_vlan_strip_queue_set(struct rte_eth_dev *dev, uint16_t queue, int on)
{
struct ngbe_hw *hw = ngbe_dev_hw(dev);

if (restart) {
/* set vlan strip for ring */
ngbe_dev_rx_queue_stop(dev, queue);
wr32(hw, NGBE_RXBAL(rxq->reg_idx), rxbal);
wr32(hw, NGBE_RXBAH(rxq->reg_idx), rxbah);
wr32(hw, NGBE_RXCFG(rxq->reg_idx), rxcfg);
ngbe_dev_rx_queue_start(dev, queue);
if (!hw->adapter_stopped) {
PMD_DRV_LOG(ERR, "Please stop port first");
return;
}

ngbe_vlan_strip_q_set(dev, queue, on);
}

static int
Expand Down Expand Up @@ -846,9 +830,9 @@ ngbe_vlan_hw_strip_config(struct rte_eth_dev *dev)
rxq = dev->data->rx_queues[i];

if (rxq->offloads & RTE_ETH_RX_OFFLOAD_VLAN_STRIP)
ngbe_vlan_hw_strip_enable(dev, i);
ngbe_vlan_strip_q_set(dev, i, 1);
else
ngbe_vlan_hw_strip_disable(dev, i);
ngbe_vlan_strip_q_set(dev, i, 0);
}
}

Expand Down Expand Up @@ -910,6 +894,13 @@ ngbe_vlan_offload_config(struct rte_eth_dev *dev, int mask)
static int
ngbe_vlan_offload_set(struct rte_eth_dev *dev, int mask)
{
struct ngbe_hw *hw = ngbe_dev_hw(dev);

if (!hw->adapter_stopped && (mask & RTE_ETH_VLAN_STRIP_MASK)) {
PMD_DRV_LOG(ERR, "Please stop port first");
return -EPERM;
}

ngbe_config_vlan_strip_on_all_queues(dev, mask);

ngbe_vlan_offload_config(dev, mask);
Expand Down

0 comments on commit baca8ec

Please sign in to comment.