net/i40e: fix error disable double VLAN

Message ID 20220629095710.300200-1-kevinx.liu@intel.com (mailing list archive)
State Superseded, archived
Delegated to: Qi Zhang
Headers
Series net/i40e: fix error disable double VLAN |

Checks

Context Check Description
ci/checkpatch success coding style OK
ci/Intel-compilation success Compilation OK
ci/iol-intel-Performance success Performance Testing PASS
ci/iol-intel-Functional success Functional Testing PASS
ci/iol-aarch64-unit-testing success Testing PASS
ci/iol-aarch64-compile-testing success Testing PASS
ci/iol-x86_64-compile-testing success Testing PASS
ci/github-robot: build success github build: passed
ci/iol-x86_64-unit-testing success Testing PASS
ci/intel-Testing success Testing PASS
ci/iol-abi-testing success Testing PASS

Commit Message

Kevin Liu June 29, 2022, 9:57 a.m. UTC
  Sync the kernel driver, enable double VLAN by default after
firmware v8.3 and disable double VLAN is not allowed in subsequent
operations.

Fixes: 4f13a78f1b8f ("net/i40e: add outer VLAN processing")
Signed-off-by: Kevin Liu <kevinx.liu@intel.com>
---
 drivers/net/i40e/i40e_ethdev.c | 45 ++++++++++++----------------------
 1 file changed, 15 insertions(+), 30 deletions(-)
  

Patch

diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index dd471d487e..b07ef89220 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -2575,7 +2575,6 @@  i40e_dev_close(struct rte_eth_dev *dev)
 	struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
 	struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev);
 	struct rte_intr_handle *intr_handle = pci_dev->intr_handle;
-	struct rte_eth_rxmode *rxmode = &dev->data->dev_conf.rxmode;
 	struct i40e_filter_control_settings settings;
 	struct rte_flow *p_flow;
 	uint32_t reg;
@@ -2588,18 +2587,6 @@  i40e_dev_close(struct rte_eth_dev *dev)
 	if (rte_eal_process_type() != RTE_PROC_PRIMARY)
 		return 0;
 
-	/*
-	 * It is a workaround, if the double VLAN is disabled when
-	 * the program exits, an abnormal error will occur on the
-	 * NIC. Need to enable double VLAN when dev is closed.
-	 */
-	if (pf->fw8_3gt) {
-		if (!(rxmode->offloads & RTE_ETH_RX_OFFLOAD_VLAN_EXTEND)) {
-			rxmode->offloads |= RTE_ETH_RX_OFFLOAD_VLAN_EXTEND;
-			i40e_vlan_offload_set(dev, RTE_ETH_VLAN_EXTEND_MASK);
-		}
-	}
-
 	ret = rte_eth_switch_domain_free(pf->switch_domain_id);
 	if (ret)
 		PMD_INIT_LOG(WARNING, "failed to free switch domain: %d", ret);
@@ -3950,20 +3937,8 @@  i40e_vlan_tpid_set(struct rte_eth_dev *dev,
 			else if (vlan_type == RTE_ETH_VLAN_TYPE_INNER)
 				hw->second_tag = rte_cpu_to_le_16(tpid);
 		} else {
-			/*
-			 * If tpid is equal to 0x88A8, indicates that the
-			 * disable double VLAN operation is in progress.
-			 * Need set switch configuration back to default.
-			 */
-			if (pf->fw8_3gt && tpid == RTE_ETHER_TYPE_QINQ) {
-				sw_flags = 0;
-				valid_flags = I40E_AQ_SET_SWITCH_CFG_OUTER_VLAN;
-				if (vlan_type == RTE_ETH_VLAN_TYPE_OUTER)
-					hw->first_tag = rte_cpu_to_le_16(tpid);
-			} else {
-				if (vlan_type == RTE_ETH_VLAN_TYPE_OUTER)
-					hw->second_tag = rte_cpu_to_le_16(tpid);
-			}
+			if (vlan_type == RTE_ETH_VLAN_TYPE_OUTER)
+				hw->second_tag = rte_cpu_to_le_16(tpid);
 		}
 		ret = i40e_aq_set_switch_config(hw, sw_flags,
 						valid_flags, 0, NULL);
@@ -4043,6 +4018,12 @@  i40e_vlan_offload_set(struct rte_eth_dev *dev, int mask)
 	}
 
 	if (mask & RTE_ETH_VLAN_EXTEND_MASK) {
+		/* Sync the kernel driver. Double VLAN not allowed to be disabled.*/
+		if (pf->fw8_3gt && !(rxmode->offloads & RTE_ETH_RX_OFFLOAD_VLAN_EXTEND)) {
+			PMD_DRV_LOG(WARNING,
+				"Disable double VLAN is not allowed after firmwarev8.3!");
+			return 0;
+		}
 		i = 0;
 		num = vsi->mac_num;
 		mac_filter = rte_zmalloc("mac_filter_info_data",
@@ -4078,9 +4059,6 @@  i40e_vlan_offload_set(struct rte_eth_dev *dev, int mask)
 			i40e_vlan_tpid_set(dev, RTE_ETH_VLAN_TYPE_INNER,
 					   RTE_ETHER_TYPE_VLAN);
 		} else {
-			if (pf->fw8_3gt)
-				i40e_vlan_tpid_set(dev, RTE_ETH_VLAN_TYPE_OUTER,
-					   RTE_ETHER_TYPE_QINQ);
 			i40e_vsi_config_double_vlan(vsi, FALSE);
 		}
 		/* Restore all mac */
@@ -6176,6 +6154,7 @@  i40e_vsi_config_vlan_stripping(struct i40e_vsi *vsi, bool on)
 static int
 i40e_dev_init_vlan(struct rte_eth_dev *dev)
 {
+	struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
 	struct rte_eth_dev_data *data = dev->data;
 	int ret;
 	int mask = 0;
@@ -6185,6 +6164,12 @@  i40e_dev_init_vlan(struct rte_eth_dev *dev)
 	       RTE_ETH_QINQ_STRIP_MASK |
 	       RTE_ETH_VLAN_FILTER_MASK |
 	       RTE_ETH_VLAN_EXTEND_MASK;
+
+	/* Sync the kernel driver. Double VLAN be enabled by default.*/
+	if (pf->fw8_3gt) {
+		struct rte_eth_rxmode *rxmode = &dev->data->dev_conf.rxmode;
+		rxmode->offloads |= RTE_ETH_RX_OFFLOAD_VLAN_EXTEND;
+	}
 	ret = i40e_vlan_offload_set(dev, mask);
 	if (ret) {
 		PMD_DRV_LOG(INFO, "Failed to update vlan offload");