[PATCH 08/10] net/bnxt: fix for VLAN stripping being set incorrectly
Mohammad Shuab Siddique
mohammad-shuab.siddique at broadcom.com
Thu Jun 4 05:18:49 CEST 2026
From: Keegan Freyhof <keegan.freyhof at broadcom.com>
Driver was setting the VLAN strip ol flag based on port
settings rather than per packet for V3. This caused
TruFlow's per packet flows to incorrectly not report
VLAN_STRIPPED, as the TruFlow might set a flow to strip
VLAN based on other markers in the packet rather than
always for the port. Changed the logic to set the flag
per packet.
Fixes: 15276ba987bd ("net/bnxt: fix getting burst mode for Arm")
Cc: stable at dpdk.org
Signed-off-by: Keegan Freyhof <keegan.freyhof at broadcom.com>
Signed-off-by: Mohammad Shuab Siddique <mohammad-shuab.siddique at broadcom.com>
---
drivers/net/bnxt/bnxt_rxr.c | 6 +--
drivers/net/bnxt/bnxt_rxr.h | 12 +++---
drivers/net/bnxt/bnxt_rxtx_vec_avx2.c | 54 +++++++++++++++++++++++----
3 files changed, 56 insertions(+), 16 deletions(-)
diff --git a/drivers/net/bnxt/bnxt_rxr.c b/drivers/net/bnxt/bnxt_rxr.c
index ee49d85d43..0fab4ddf78 100644
--- a/drivers/net/bnxt/bnxt_rxr.c
+++ b/drivers/net/bnxt/bnxt_rxr.c
@@ -1127,7 +1127,6 @@ static int bnxt_rx_pkt(struct rte_mbuf **rx_pkt,
uint16_t cmp_type;
uint32_t vfr_flag = 0, mark_id = 0;
struct bnxt *bp = rxq->bp;
- struct bnxt_vnic_info *vnic = rxq->vnic;
rxcmp = (struct rx_pkt_cmpl *)
&cpr->cp_desc_ring[cp_cons];
@@ -1236,8 +1235,7 @@ static int bnxt_rx_pkt(struct rte_mbuf **rx_pkt,
if (cmp_type == CMPL_BASE_TYPE_RX_L2_V3) {
bnxt_parse_csum_v3(mbuf, rxcmp1);
bnxt_parse_pkt_type_v3(mbuf, rxcmp, rxcmp1);
- bnxt_rx_vlan_v3(mbuf, rxcmp, rxcmp1, vnic->vlan_strip);
-
+ bnxt_rx_vlan_v3(mbuf, rxcmp, rxcmp1);
/* Packet cannot be a PTP ethertype if it is detected as L4 */
if (mbuf->ol_flags & RTE_MBUF_F_RX_L4_CKSUM_GOOD) {
mbuf->ol_flags &= ~RTE_MBUF_F_RX_IEEE1588_PTP;
@@ -1259,7 +1257,7 @@ static int bnxt_rx_pkt(struct rte_mbuf **rx_pkt,
if (cmp_type == CMPL_BASE_TYPE_RX_L2_V2) {
bnxt_parse_csum_v2(mbuf, rxcmp1);
bnxt_parse_pkt_type_v2(mbuf, rxcmp, rxcmp1);
- bnxt_rx_vlan_v2(mbuf, rxcmp, rxcmp1);
+ bnxt_rx_vlan_v2(mbuf, bp, rxcmp, rxcmp1);
/* TODO Add support for cfa_code parsing */
goto reuse_rx_mbuf;
}
diff --git a/drivers/net/bnxt/bnxt_rxr.h b/drivers/net/bnxt/bnxt_rxr.h
index 352d509210..c971233dc3 100644
--- a/drivers/net/bnxt/bnxt_rxr.h
+++ b/drivers/net/bnxt/bnxt_rxr.h
@@ -276,12 +276,15 @@ static inline void bnxt_set_vlan(struct rx_pkt_cmpl_hi *rxcmp1,
RX_PKT_V2_CMPL_HI_METADATA0_PRI_MASK))
static inline void bnxt_rx_vlan_v2(struct rte_mbuf *mbuf,
+ const struct bnxt *bp,
struct rx_pkt_cmpl *rxcmp,
struct rx_pkt_cmpl_hi *rxcmp1)
{
if (RX_CMP_VLAN_VALID(rxcmp)) {
mbuf->vlan_tci = RX_CMP_METADATA0_VID(rxcmp1);
- mbuf->ol_flags |= RTE_MBUF_F_RX_VLAN | RTE_MBUF_F_RX_VLAN_STRIPPED;
+ mbuf->ol_flags |= RTE_MBUF_F_RX_VLAN;
+ if (BNXT_RX_VLAN_STRIP_EN(bp))
+ mbuf->ol_flags |= RTE_MBUF_F_RX_VLAN_STRIPPED;
}
}
@@ -483,14 +486,13 @@ bnxt_parse_pkt_type_v2(struct rte_mbuf *mbuf,
RX_PKT_V3_CMPL_HI_METADATA0_PRI_MASK))
static inline void bnxt_rx_vlan_v3(struct rte_mbuf *mbuf,
- struct rx_pkt_cmpl *rxcmp,
- struct rx_pkt_cmpl_hi *rxcmp1,
- bool stripped)
+ struct rx_pkt_cmpl *rxcmp,
+ struct rx_pkt_cmpl_hi *rxcmp1)
{
if (RX_CMP_V3_VLAN_VALID(rxcmp)) {
mbuf->vlan_tci = RX_CMP_V3_METADATA0_VID(rxcmp1);
mbuf->ol_flags |= RTE_MBUF_F_RX_VLAN;
- if (stripped)
+ if (rxcmp1->flags2 & RX_PKT_V3_CMPL_HI_FLAGS2_META_FORMAT_MASK)
mbuf->ol_flags |= RTE_MBUF_F_RX_VLAN_STRIPPED;
}
}
diff --git a/drivers/net/bnxt/bnxt_rxtx_vec_avx2.c b/drivers/net/bnxt/bnxt_rxtx_vec_avx2.c
index 5e22b4fc11..38aca98cb1 100644
--- a/drivers/net/bnxt/bnxt_rxtx_vec_avx2.c
+++ b/drivers/net/bnxt/bnxt_rxtx_vec_avx2.c
@@ -70,6 +70,17 @@ recv_burst_vec_avx2(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts)
_mm256_set1_epi32(RX_PKT_CMPL_FLAGS2_IP_TYPE);
const __m256i rss_mask =
_mm256_set1_epi32(RX_PKT_CMPL_FLAGS_RSS_VALID);
+ /*
+ * ol_flags_table already sets RX_VLAN|RX_VLAN_STRIPPED when VLAN strip
+ * is enabled. For completeness, also OR in the flags here based on the
+ * per-packet VLAN-metadata bit so that the two sources agree. The
+ * constant is broadcast once: non-zero only when strip offload is on.
+ */
+ const __m256i vlan_ol_val =
+ BNXT_RX_VLAN_STRIP_EN(rxq->bp) ?
+ _mm256_set1_epi32((uint32_t)(RTE_MBUF_F_RX_VLAN |
+ RTE_MBUF_F_RX_VLAN_STRIPPED)) :
+ _mm256_setzero_si256();
__m256i t0, t1, flags_type, flags2, index, errors;
__m256i ptype_idx, ptypes, is_tunnel;
__m256i mbuf01, mbuf23, mbuf45, mbuf67;
@@ -286,6 +297,25 @@ recv_burst_vec_avx2(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts)
rss_flags = _mm256_srli_epi32(rss_flags, 9);
ol_flags = _mm256_or_si256(ol_flags, errors);
ol_flags = _mm256_or_si256(ol_flags, rss_flags);
+ /*
+ * Set RX_VLAN | RX_VLAN_STRIPPED for packets whose vlan_tci
+ * is non-zero (i.e. hardware reported VLAN metadata, indicated
+ * by RX_PKT_CMPL_FLAGS2_META_FORMAT_VLAN in index bit 4).
+ * vlan_ol_val is the broadcast constant computed before the
+ * loop: non-zero only when VLAN RX strip offload is enabled.
+ * _mm256_cmpeq_epi32 produces 0xFFFFFFFF per lane when the
+ * VLAN bit is set, masking the constant to those lanes only.
+ */
+ {
+ const __m256i vlan_bit =
+ _mm256_set1_epi32(RX_PKT_CMPL_FLAGS2_META_FORMAT_VLAN);
+ __m256i vlan_mask =
+ _mm256_cmpeq_epi32(_mm256_and_si256(index, vlan_bit),
+ vlan_bit);
+ ol_flags = _mm256_or_si256(ol_flags,
+ _mm256_and_si256(vlan_mask,
+ vlan_ol_val));
+ }
ol_flags_hi = _mm256_permute2f128_si256(ol_flags,
ol_flags, 0x11);
@@ -908,7 +938,6 @@ static uint16_t
recv_burst_vec_avx2_v3(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts)
{
struct bnxt_rx_queue *rxq = rx_queue;
- struct bnxt_vnic_info *vnic = rxq->vnic;
const __m256i mbuf_init =
_mm256_set_epi64x(0, 0, 0, rxq->mbuf_initializer);
struct bnxt_cp_ring_info *cpr = rxq->cp_ring;
@@ -1001,8 +1030,8 @@ recv_burst_vec_avx2_v3(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pk
mbcons += BNXT_RX_DESCS_PER_LOOP_VEC256) {
__m256i desc0, desc1, desc2, desc3, desc4, desc5, desc6, desc7;
__m256i rxcmp0_1, rxcmp2_3, rxcmp4_5, rxcmp6_7, info3_v;
+ __m256i errors_v2, cs_calc, cs_valid, meta_format;
__m256i md1_0123, lo2_3, md1_4567, lo6_7;
- __m256i errors_v2, cs_calc, cs_valid;
uint32_t num_valid;
t0 = _mm256_loadu_si256((void *)&rxr->rx_buf_ring[mbcons]);
@@ -1070,7 +1099,9 @@ recv_burst_vec_avx2_v3(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pk
flags2 = _mm256_unpackhi_epi64(t0, t1);
/* fs mask used for RX_PKT_CMPL_CALC */
cs_calc = _mm256_and_si256(flags2, mask_fs);
- cs_valid = _mm256_cmpeq_epi32(cs_calc, _mm256_setzero_si256());
+ /* Add the meta_format to cs_calc */
+ cs_calc = _mm256_or_si256(cs_calc, _mm256_and_si256(flags2,
+ _mm256_slli_epi32(mask_fs, 4)));
/* Extract metadata0 and errors from high completion */
t0 = _mm256_unpackhi_epi32(rxcmp0_1, rxcmp2_3);
@@ -1082,6 +1113,11 @@ recv_burst_vec_avx2_v3(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pk
*/
errors_csum_idx = _mm256_srli_epi32(_mm256_and_si256(errors_v2,
_mm256_slli_epi32(mask_fs, 4)), 4);
+ meta_format = _mm256_cmpeq_epi32(_mm256_and_si256(cs_calc,
+ _mm256_slli_epi32(mask_fs, 4)),
+ _mm256_setzero_si256());
+ cs_valid = _mm256_cmpeq_epi32(_mm256_and_si256(cs_calc, mask_fs),
+ _mm256_setzero_si256());
errors_csum_idx = _mm256_andnot_si256(cs_valid, errors_csum_idx);
/*
@@ -1104,10 +1140,14 @@ recv_burst_vec_avx2_v3(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pk
vlan_flags = _mm256_and_si256(metadata1, _mm256_slli_epi32(mask_1s, 15));
vlan_flags = _mm256_min_epu32(vlan_flags, mask_1s);
- if (vnic->vlan_strip) {
- vlan_flags = _mm256_or_si256(vlan_flags,
- _mm256_slli_epi32(vlan_flags, 6));
- }
+ /*
+ * VLAN present in mbuf when metadata valid (vlan_flags) and
+ * meta_format is non-zero in flags2. andnot(cmpeq(tci,0), vlan_flags) is
+ * (~zero_mask) & vlan_flags.
+ */
+ t0 = _mm256_andnot_si256(meta_format, vlan_flags);
+ /* RTE_MBUF_F_RX_VLAN + STRIPPED when hardware reports valid VLAN. */
+ vlan_flags = _mm256_or_si256(vlan_flags, _mm256_slli_epi32(t0, 6));
/* Extract flags_type from low completion for eight packets */
t0 = _mm256_unpacklo_epi32(rxcmp0_1, rxcmp2_3);
--
2.47.3
More information about the dev
mailing list