Re: [dpdk-dev] [dpdk-stable] [PATCH v2 1/5] net/txgbe: fix RSS in QINQ
From: "Jiawen Wu" <jiawenwu@trustnetic.com>
Date: 2021-05-06 03:33:33
On April 29, 2021 10:31 PM, Ferruh Yigit wrote:
On 4/29/2021 11:33 AM, Jiawen Wu wrote:quoted
Support to enable and disable QINQ hardware strip, when configure vlan offload with QINQ strip mask, to avoid RSS does not work for QINQ packets.Hi Jiawen, What was not working and fixed here? Is it RSS hash calculation is wrong when packet has double VLAN tag? Is it failing to calculate hash for VLAN field of the packet or calculation for any fields are wrong? Can't device detect/parse QinQ fields? And how enabling QinQ strip is solving the issue? Should user enable QinQ strip before configuring the RSS? What happens if user don't, should driver has checks to cover this, like fail to enable RSS if QinQ strip is not enable etc? Can you please provide more details?
Hi Ferruh, I think I might be mistaken something. At first I fixed this bug because RSS did not take effect when packet has QINQ tag. Hardware does not support to calculate VLAN field, but the insertion of QINQ causes five-tuple filed changes. The root cause is that QINQ is not properly stripped. So I add the functions to handle QINQ stripping when ETH_QINQ_STRIP_MASK set. And users should enable QINQ strip before configuring the RSS. This patch should be renamed to "fix to strip QINQ", is this more appropriate?
quoted
Fixes: 220b0e49bc47 ("net/txgbe: support VLAN") Cc: stable@dpdk.org Signed-off-by: Jiawen Wu <jiawenwu@trustnetic.com> --- drivers/net/txgbe/txgbe_ethdev.c | 39 +++++++++++++++++++++++++++----- 1 file changed, 33 insertions(+), 6 deletions(-)diff --git a/drivers/net/txgbe/txgbe_ethdev.cb/drivers/net/txgbe/txgbe_ethdev.c index 97796f040b..3d6d356102 100644--- a/drivers/net/txgbe/txgbe_ethdev.c +++ b/drivers/net/txgbe/txgbe_ethdev.c@@ -1209,7 +1209,6 @@ txgbe_vlan_hw_extend_disable(structrte_eth_devquoted
*dev) ctrl = rd32(hw, TXGBE_PORTCTL); ctrl &= ~TXGBE_PORTCTL_VLANEXT; - ctrl &= ~TXGBE_PORTCTL_QINQ; wr32(hw, TXGBE_PORTCTL, ctrl); }@@ -1217,17 +1216,38 @@ static void txgbe_vlan_hw_extend_enable(struct rte_eth_dev *dev) { struct txgbe_hw *hw = TXGBE_DEV_HW(dev); - struct rte_eth_rxmode *rxmode = &dev->data->dev_conf.rxmode; - struct rte_eth_txmode *txmode = &dev->data->dev_conf.txmode; uint32_t ctrl; PMD_INIT_FUNC_TRACE(); ctrl = rd32(hw, TXGBE_PORTCTL); ctrl |= TXGBE_PORTCTL_VLANEXT; - if (rxmode->offloads & DEV_RX_OFFLOAD_QINQ_STRIP || - txmode->offloads & DEV_TX_OFFLOAD_QINQ_INSERT) - ctrl |= TXGBE_PORTCTL_QINQ; + wr32(hw, TXGBE_PORTCTL, ctrl); +} + +static void +txgbe_qinq_hw_strip_disable(struct rte_eth_dev *dev) { + struct txgbe_hw *hw = TXGBE_DEV_HW(dev); + uint32_t ctrl; + + PMD_INIT_FUNC_TRACE(); + + ctrl = rd32(hw, TXGBE_PORTCTL); + ctrl &= ~TXGBE_PORTCTL_QINQ; + wr32(hw, TXGBE_PORTCTL, ctrl); +} + +static void +txgbe_qinq_hw_strip_enable(struct rte_eth_dev *dev) { + struct txgbe_hw *hw = TXGBE_DEV_HW(dev); + uint32_t ctrl; + + PMD_INIT_FUNC_TRACE(); + + ctrl = rd32(hw, TXGBE_PORTCTL); + ctrl |= TXGBE_PORTCTL_QINQ | TXGBE_PORTCTL_VLANEXT; wr32(hw, TXGBE_PORTCTL, ctrl); }@@ -1294,6 +1314,13 @@ txgbe_vlan_offload_config(struct rte_eth_dev*dev, int mask)quoted
txgbe_vlan_hw_extend_disable(dev); } + if (mask & ETH_QINQ_STRIP_MASK) { + if (rxmode->offloads & DEV_RX_OFFLOAD_QINQ_STRIP) + txgbe_qinq_hw_strip_enable(dev); + else + txgbe_qinq_hw_strip_disable(dev); + } + return 0; }