DPDK-dev Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] net/iavf: add support for QinQ insertion
@ 2026-04-30  8:58 Anurag Mandal
  2026-05-05 15:55 ` Bruce Richardson
  2026-05-06 14:38 ` Bruce Richardson
  0 siblings, 2 replies; 6+ messages in thread
From: Anurag Mandal @ 2026-04-30  8:58 UTC (permalink / raw)
  To: dev; +Cc: bruce.richardson, vladimir.medvedkin, Anurag Mandal

QinQ insertion with VLAN TPID 0x88a8 support is absent.

This patch adds support for QinQ insertion for both
Outer VLAN TPIDs 0x88a8 (802.1ad) & 0x8100 (802.1Q).
VLAN Extend should be enabled for the same and Outer
VLAN TPID should be set properly for TPID 0x88a8.

Signed-off-by: Anurag Mandal <anurag.mandal@intel.com>
---
 doc/guides/nics/intel_vf.rst        | 19 ++++++++++
 drivers/net/intel/iavf/iavf.h       |  1 +
 drivers/net/intel/iavf/iavf_vchnl.c | 56 +++++++++++++++++++++++++++--
 3 files changed, 74 insertions(+), 2 deletions(-)

diff --git a/doc/guides/nics/intel_vf.rst b/doc/guides/nics/intel_vf.rst
index dfff69b982..ce11ea6363 100644
--- a/doc/guides/nics/intel_vf.rst
+++ b/doc/guides/nics/intel_vf.rst
@@ -802,3 +802,22 @@ To start ``testpmd``, and enable QinQ strip for default TPID on port 0:
 
    testpmd> vlan set extend on 0
    testpmd> vlan set qinq_strip on 0
+
+QinQ Configuration
+~~~~~~~~~~~~~~~~~~
+
+When using QinQ Tx offload (``RTE_ETH_TX_OFFLOAD_QINQ_INSERT``),
+you must also enable ``RTE_ETH_RX_OFFLOAD_VLAN_EXTEND``
+to configure the hardware for double VLAN mode.
+Without this, only the inner VLAN tag will be inserted.
+
+Example::
+
+  struct rte_eth_conf port_conf = {
+      .rxmode = {
+          .offloads = RTE_ETH_RX_OFFLOAD_VLAN_EXTEND,
+      },
+      .txmode = {
+          .offloads = RTE_ETH_TX_OFFLOAD_QINQ_INSERT,
+      },
+  };
diff --git a/drivers/net/intel/iavf/iavf.h b/drivers/net/intel/iavf/iavf.h
index 6a77dacf59..0b6ed221d0 100644
--- a/drivers/net/intel/iavf/iavf.h
+++ b/drivers/net/intel/iavf/iavf.h
@@ -459,6 +459,7 @@ int iavf_get_supported_rxdid(struct iavf_adapter *adapter);
 int iavf_config_vlan_strip_v2(struct iavf_adapter *adapter, bool enable);
 int iavf_config_outer_vlan_strip_v2(struct iavf_adapter *adapter, bool enable);
 int iavf_config_vlan_insert_v2(struct iavf_adapter *adapter, bool enable);
+int iavf_config_outer_vlan_insert_v2(struct iavf_adapter *adapter, bool enable);
 int iavf_add_del_vlan_v2(struct iavf_adapter *adapter, uint16_t vlanid,
 			 bool add);
 int iavf_get_vlan_offload_caps_v2(struct iavf_adapter *adapter);
diff --git a/drivers/net/intel/iavf/iavf_vchnl.c b/drivers/net/intel/iavf/iavf_vchnl.c
index c2f340db81..6dd7d455ba 100644
--- a/drivers/net/intel/iavf/iavf_vchnl.c
+++ b/drivers/net/intel/iavf/iavf_vchnl.c
@@ -920,6 +920,51 @@ iavf_config_vlan_strip_v2(struct iavf_adapter *adapter, bool enable)
 	return ret;
 }
 
+int
+iavf_config_outer_vlan_insert_v2(struct iavf_adapter *adapter, bool enable)
+{
+	struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(adapter);
+	struct virtchnl_vlan_supported_caps *insertion_caps;
+	struct virtchnl_vlan_setting vlan_insert;
+	uint8_t msg_buf[IAVF_AQ_BUF_SZ] = {0};
+	struct iavf_cmd_info args;
+	uint32_t *ethertype;
+	int ret;
+
+	memset(&vlan_insert, 0, sizeof(vlan_insert));
+	insertion_caps = &vf->vlan_v2_caps.offloads.insertion_support;
+
+	if ((insertion_caps->outer & VIRTCHNL_VLAN_ETHERTYPE_88A8) &&
+	    (insertion_caps->outer & VIRTCHNL_VLAN_TOGGLE) &&
+	    adapter->tpid == RTE_ETHER_TYPE_QINQ) {
+		ethertype = &vlan_insert.outer_ethertype_setting;
+		*ethertype = VIRTCHNL_VLAN_ETHERTYPE_88A8;
+	} else if ((insertion_caps->outer & VIRTCHNL_VLAN_ETHERTYPE_8100) &&
+		   (insertion_caps->outer & VIRTCHNL_VLAN_TOGGLE) &&
+		   adapter->tpid == RTE_ETHER_TYPE_VLAN) {
+		ethertype = &vlan_insert.outer_ethertype_setting;
+		*ethertype = VIRTCHNL_VLAN_ETHERTYPE_8100;
+	} else {
+		return -ENOTSUP;
+	}
+
+	vlan_insert.vport_id = vf->vsi_res->vsi_id;
+
+	args.ops = enable ? VIRTCHNL_OP_ENABLE_VLAN_INSERTION_V2 :
+			    VIRTCHNL_OP_DISABLE_VLAN_INSERTION_V2;
+	args.in_args = (uint8_t *)&vlan_insert;
+	args.in_args_size = sizeof(vlan_insert);
+	args.out_buffer = msg_buf;
+	args.out_size = IAVF_AQ_BUF_SZ;
+	ret = iavf_execute_vf_cmd_safe(adapter, &args);
+	if (ret)
+		PMD_DRV_LOG(ERR, "fail to execute command %s",
+			    enable ? "VIRTCHNL_OP_ENABLE_VLAN_INSERTION_V2" :
+				     "VIRTCHNL_OP_DISABLE_VLAN_INSERTION_V2");
+
+	return ret;
+}
+
 int
 iavf_config_vlan_insert_v2(struct iavf_adapter *adapter, bool enable)
 {
@@ -929,14 +974,21 @@ iavf_config_vlan_insert_v2(struct iavf_adapter *adapter, bool enable)
 	uint8_t msg_buf[IAVF_AQ_BUF_SZ] = {0};
 	struct iavf_cmd_info args;
 	uint32_t *ethertype;
+	bool qinq = adapter->dev_data->dev_conf.rxmode.offloads &
+		    RTE_ETH_RX_OFFLOAD_VLAN_EXTEND;
+	bool insert_qinq = adapter->dev_data->dev_conf.txmode.offloads &
+			   RTE_ETH_TX_OFFLOAD_QINQ_INSERT;
 	int ret;
 
+	if (qinq && insert_qinq)
+		iavf_config_outer_vlan_insert_v2(adapter, enable);
+
 	insertion_caps = &vf->vlan_v2_caps.offloads.insertion_support;
 
-	if ((insertion_caps->outer & VIRTCHNL_VLAN_ETHERTYPE_8100) &&
+	if (!qinq && (insertion_caps->outer & VIRTCHNL_VLAN_ETHERTYPE_8100) &&
 	    (insertion_caps->outer & VIRTCHNL_VLAN_TOGGLE))
 		ethertype = &vlan_insert.outer_ethertype_setting;
-	else if ((insertion_caps->inner & VIRTCHNL_VLAN_ETHERTYPE_8100) &&
+	else if (qinq && (insertion_caps->inner & VIRTCHNL_VLAN_ETHERTYPE_8100) &&
 		 (insertion_caps->inner & VIRTCHNL_VLAN_TOGGLE))
 		ethertype = &vlan_insert.inner_ethertype_setting;
 	else
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2026-05-06 14:39 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-04-30  8:58 [PATCH] net/iavf: add support for QinQ insertion Anurag Mandal
2026-05-05 15:55 ` Bruce Richardson
2026-05-05 16:58   ` Mandal, Anurag
2026-05-05 17:04     ` Bruce Richardson
2026-05-05 17:19       ` Mandal, Anurag
2026-05-06 14:38 ` Bruce Richardson

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox