From: Bruce Richardson <bruce.richardson@intel.com>
To: dev@dpdk.org
Cc: Bruce Richardson <bruce.richardson@intel.com>,
stable@dpdk.org,
Vladimir Medvedkin <vladimir.medvedkin@intel.com>,
Anatoly Burakov <anatoly.burakov@intel.com>,
Jingjing Wu <jingjing.wu@intel.com>,
Praveen Shetty <praveen.shetty@intel.com>
Subject: [PATCH 5/7] net/intel: fix VLAN and QinQ tag position logic
Date: Mon, 31 Aug 2026 11:26:18 +0100 [thread overview]
Message-ID: <20260831102621.495759-6-bruce.richardson@intel.com> (raw)
In-Reply-To: <20260831102621.495759-1-bruce.richardson@intel.com>
The position of a single vlan tag on a Tx packet (data desc or ctx desc)
is independent across drivers from that of where the outer QinQ tag gets
put. Therefore, these should be passed as separate values to the common
scalar Tx function. For i40e, ice and idpf, the single tag can be put in
the data descriptor, and for QinQ, the context descriptor contains the
outer tag. For iavf, the tag positions depend on the capabilities
reported by the PF to the VF, but the position for the single vlan tag
and the outer QinQ tags are the same.
Fixes: 6ea6d67bebfe ("net/intel: support configurable VLAN insertion on Tx")
Cc: stable@dpdk.org
Signed-off-by: Bruce Richardson <bruce.richardson@intel.com>
---
drivers/net/intel/common/tx_scalar.h | 16 +++++++++++-----
drivers/net/intel/i40e/i40e_rxtx.c | 6 ++++--
drivers/net/intel/iavf/iavf_rxtx.c | 7 ++++---
drivers/net/intel/ice/ice_rxtx.c | 5 +++--
drivers/net/intel/idpf/idpf_common_rxtx.c | 3 ++-
5 files changed, 24 insertions(+), 13 deletions(-)
diff --git a/drivers/net/intel/common/tx_scalar.h b/drivers/net/intel/common/tx_scalar.h
index 4df279e729..7368d3abc9 100644
--- a/drivers/net/intel/common/tx_scalar.h
+++ b/drivers/net/intel/common/tx_scalar.h
@@ -372,7 +372,8 @@ static inline uint16_t
ci_xmit_pkts(struct ci_tx_queue *txq,
struct rte_mbuf **tx_pkts,
uint16_t nb_pkts,
- enum ci_l2tag_pos l2tag_pos,
+ enum ci_l2tag_pos single_vlan_pos,
+ enum ci_l2tag_pos qinq_outer_pos,
ci_get_ctx_desc_fn get_ctx_desc,
const struct ci_ipsec_ops *ipsec_ops,
const struct ci_timestamp_queue_fns *ts_fns)
@@ -480,13 +481,18 @@ ci_xmit_pkts(struct ci_tx_queue *txq,
}
/* Descriptor based VLAN/QinQ insertion */
- /* for single vlan offload, only insert in data desc when CI_TAG_IN_DATA_DESC is set
- * for qinq offload, we always put inner tag in L2Tag1
+ /* for single vlan offload, only insert in data desc when single_vlan_pos is
+ * CI_TAG_IN_DATA_DESC; for qinq offload, L2Tag1 always carries a tag, either
+ * the outer (qinq_outer_pos == CI_TAG_IN_DATA_DESC) or otherwise the inner
*/
- if (((ol_flags & RTE_MBUF_F_TX_VLAN) && l2tag_pos == CI_TAG_IN_DATA_DESC) ||
+ if (((ol_flags & RTE_MBUF_F_TX_VLAN) && single_vlan_pos == CI_TAG_IN_DATA_DESC) ||
(ol_flags & RTE_MBUF_F_TX_QINQ)) {
td_cmd |= CI_TX_DESC_CMD_IL2TAG1;
- td_tag = tx_pkt->vlan_tci;
+ if ((ol_flags & RTE_MBUF_F_TX_QINQ) &&
+ qinq_outer_pos == CI_TAG_IN_DATA_DESC)
+ td_tag = tx_pkt->vlan_tci_outer;
+ else
+ td_tag = tx_pkt->vlan_tci;
}
/* Enable checksum offloading */
diff --git a/drivers/net/intel/i40e/i40e_rxtx.c b/drivers/net/intel/i40e/i40e_rxtx.c
index ef7041cebd..e2fffdb70a 100644
--- a/drivers/net/intel/i40e/i40e_rxtx.c
+++ b/drivers/net/intel/i40e/i40e_rxtx.c
@@ -1006,8 +1006,10 @@ get_context_desc(uint64_t ol_flags, const struct rte_mbuf *tx_pkt,
uint16_t
i40e_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
{
- /* i40e does not support IPsec or timestamp queues, so pass NULL for both */
- return ci_xmit_pkts(tx_queue, tx_pkts, nb_pkts, CI_TAG_IN_DATA_DESC,
+ /* i40e does not support IPsec or timestamp queues, so pass NULL for both.
+ * QinQ always places the outer tag in the ctx desc, inner in the data desc.
+ */
+ return ci_xmit_pkts(tx_queue, tx_pkts, nb_pkts, CI_TAG_IN_DATA_DESC, CI_TAG_IN_CTX_DESC,
get_context_desc, NULL, NULL);
}
diff --git a/drivers/net/intel/iavf/iavf_rxtx.c b/drivers/net/intel/iavf/iavf_rxtx.c
index 1354e2d6d6..80c9912ccc 100644
--- a/drivers/net/intel/iavf/iavf_rxtx.c
+++ b/drivers/net/intel/iavf/iavf_rxtx.c
@@ -2596,6 +2596,9 @@ uint16_t
iavf_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
{
struct ci_tx_queue *txq = tx_queue;
+ /* vlan_flag gives both the single-VLAN and the QinQ outer tag position */
+ enum ci_l2tag_pos vlan_pos = (txq->vlan_flag & IAVF_TX_FLAGS_VLAN_TAG_LOC_L2TAG1) ?
+ CI_TAG_IN_DATA_DESC : CI_TAG_IN_CTX_DESC;
const struct ci_ipsec_ops ipsec_ops = {
.get_ipsec_desc = iavf_get_ipsec_desc,
@@ -2603,9 +2606,7 @@ iavf_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
};
/* IAVF does not support timestamp queues, so pass NULL for ts_fns */
- return ci_xmit_pkts(txq, tx_pkts, nb_pkts,
- (txq->vlan_flag & IAVF_TX_FLAGS_VLAN_TAG_LOC_L2TAG1) ?
- CI_TAG_IN_DATA_DESC : CI_TAG_IN_CTX_DESC,
+ return ci_xmit_pkts(txq, tx_pkts, nb_pkts, vlan_pos, vlan_pos,
iavf_get_context_desc, &ipsec_ops, NULL);
}
diff --git a/drivers/net/intel/ice/ice_rxtx.c b/drivers/net/intel/ice/ice_rxtx.c
index 22d1d5d602..3569ffcf82 100644
--- a/drivers/net/intel/ice/ice_rxtx.c
+++ b/drivers/net/intel/ice/ice_rxtx.c
@@ -3125,10 +3125,11 @@ ice_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
struct ci_tx_queue *txq = (struct ci_tx_queue *)tx_queue;
if (txq->tsq != NULL && txq->tsq->ts_flag > 0)
- return ci_xmit_pkts(txq, tx_pkts, nb_pkts, CI_TAG_IN_DATA_DESC,
+ return ci_xmit_pkts(txq, tx_pkts, nb_pkts, CI_TAG_IN_DATA_DESC, CI_TAG_IN_CTX_DESC,
get_context_desc, NULL, &ts_fns);
- return ci_xmit_pkts(txq, tx_pkts, nb_pkts, CI_TAG_IN_DATA_DESC,
+ /* QinQ always places the outer tag in the ctx desc, inner in the data desc. */
+ return ci_xmit_pkts(txq, tx_pkts, nb_pkts, CI_TAG_IN_DATA_DESC, CI_TAG_IN_CTX_DESC,
get_context_desc, NULL, NULL);
}
diff --git a/drivers/net/intel/idpf/idpf_common_rxtx.c b/drivers/net/intel/idpf/idpf_common_rxtx.c
index 128ebb6a88..649b5d1f99 100644
--- a/drivers/net/intel/idpf/idpf_common_rxtx.c
+++ b/drivers/net/intel/idpf/idpf_common_rxtx.c
@@ -1415,7 +1415,8 @@ uint16_t
idpf_dp_singleq_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts,
uint16_t nb_pkts)
{
- return ci_xmit_pkts(tx_queue, tx_pkts, nb_pkts, CI_TAG_IN_DATA_DESC,
+ /* QinQ always places the outer tag in the ctx desc, inner in the data desc. */
+ return ci_xmit_pkts(tx_queue, tx_pkts, nb_pkts, CI_TAG_IN_DATA_DESC, CI_TAG_IN_CTX_DESC,
idpf_get_context_desc, NULL, NULL);
}
--
2.53.0
next prev parent reply other threads:[~2026-08-31 10:26 UTC|newest]
Thread overview: 26+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-08-31 10:26 [PATCH 0/7] VLAN and QinQ fixes for iavf Bruce Richardson
2026-08-31 10:26 ` [PATCH 1/7] net/iavf: disable broken QinQ strip on Rx Bruce Richardson
2026-09-03 13:58 ` Loftus, Ciara
2026-08-31 10:26 ` [PATCH 2/7] net/iavf: fix VLAN tag placement logic Bruce Richardson
2026-09-03 13:59 ` Loftus, Ciara
2026-08-31 10:26 ` [PATCH 3/7] net/iavf: fix VLAN outer TPID setting on Tx Bruce Richardson
2026-09-03 12:58 ` Loftus, Ciara
2026-09-03 14:27 ` Bruce Richardson
2026-08-31 10:26 ` [PATCH 4/7] net/intel: fix unclear enum names Bruce Richardson
2026-09-03 14:01 ` Loftus, Ciara
2026-08-31 10:26 ` Bruce Richardson [this message]
2026-09-03 14:04 ` [PATCH 5/7] net/intel: fix VLAN and QinQ tag position logic Loftus, Ciara
2026-08-31 10:26 ` [PATCH 6/7] net/iavf: fix missing outer QinQ tag for tunnelled packets Bruce Richardson
2026-09-03 14:07 ` Loftus, Ciara
2026-08-31 10:26 ` [PATCH 7/7] net/iavf: remove undocumented conditional macros Bruce Richardson
2026-08-31 10:58 ` David Marchand
2026-08-31 11:01 ` Bruce Richardson
2026-09-03 14:15 ` Loftus, Ciara
2026-09-03 14:37 ` [PATCH v2 0/7] VLAN and QinQ fixes for iavf Bruce Richardson
2026-09-03 14:37 ` [PATCH v2 1/7] net/iavf: disable broken QinQ strip on Rx Bruce Richardson
2026-09-03 14:37 ` [PATCH v2 2/7] net/iavf: fix VLAN tag placement logic Bruce Richardson
2026-09-03 14:37 ` [PATCH v2 3/7] net/iavf: fix VLAN outer TPID setting on Tx Bruce Richardson
2026-09-03 14:37 ` [PATCH v2 4/7] net/intel: fix unclear enum names Bruce Richardson
2026-09-03 14:37 ` [PATCH v2 5/7] net/intel: fix VLAN and QinQ tag position logic Bruce Richardson
2026-09-03 14:37 ` [PATCH v2 6/7] net/iavf: fix missing outer QinQ tag for tunnelled packets Bruce Richardson
2026-09-03 14:37 ` [PATCH v2 7/7] net/iavf: remove undocumented conditional macros Bruce Richardson
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260831102621.495759-6-bruce.richardson@intel.com \
--to=bruce.richardson@intel.com \
--cc=anatoly.burakov@intel.com \
--cc=dev@dpdk.org \
--cc=jingjing.wu@intel.com \
--cc=praveen.shetty@intel.com \
--cc=stable@dpdk.org \
--cc=vladimir.medvedkin@intel.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox