* [PATCH v3 16/19] drivers: optimize DPAA multi-entry buffer pool operations
From: Hemant Agrawal @ 2026-06-21 15:22 UTC (permalink / raw)
To: stephen, david.marchand, dev; +Cc: Jun Yang
In-Reply-To: <20260621152228.2777171-1-hemant.agrawal@nxp.com>
From: Jun Yang <jun.yang@nxp.com>
Replace the hardcoded buffer acquire count of 8 with the FSL_BM_BURST_MAX
constant when acquiring buffers from the buffer pool. Use a single
bm_hw_buf_desc structure for HW initialization of the first entry and copy
it to remaining entries, ensuring consistent HW descriptor state across
all entries in the pool.
Signed-off-by: Jun Yang <jun.yang@nxp.com>
---
drivers/bus/dpaa/base/qbman/bman.c | 51 +++++++----------------------
drivers/bus/dpaa/include/fsl_bman.h | 46 +++++++++++++++++++++-----
drivers/mempool/dpaa/dpaa_mempool.c | 8 ++---
3 files changed, 54 insertions(+), 51 deletions(-)
diff --git a/drivers/bus/dpaa/base/qbman/bman.c b/drivers/bus/dpaa/base/qbman/bman.c
index ee4232d0a0..01357d6446 100644
--- a/drivers/bus/dpaa/base/qbman/bman.c
+++ b/drivers/bus/dpaa/base/qbman/bman.c
@@ -1,7 +1,7 @@
/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
*
* Copyright 2008-2016 Freescale Semiconductor Inc.
- * Copyright 2017, 2024 NXP
+ * Copyright 2017, 2024-2026 NXP
*
*/
#include <rte_memcpy.h>
@@ -17,20 +17,6 @@
#define IRQNAME "BMan portal %d"
#define MAX_IRQNAME 16 /* big enough for "BMan portal %d" */
-
-#define MAX_U16 UINT16_MAX
-#define MAX_U32 UINT32_MAX
-#ifndef BIT_SIZE
-#define BIT_SIZE(t) (sizeof(t) * 8)
-#endif
-#define MAX_U48 \
- ((((uint64_t)MAX_U16) << BIT_SIZE(uint32_t)) | MAX_U32)
-#define HI16_OF_U48(x) \
- (((x) >> BIT_SIZE(rte_be32_t)) & MAX_U16)
-#define LO32_OF_U48(x) ((x) & MAX_U32)
-#define U48_BY_HI16_LO32(hi, lo) \
- (((hi) << BIT_SIZE(uint32_t)) | (lo))
-
struct bman_portal {
struct bm_portal p;
/* 2-element array. pools[0] is mask, pools[1] is snapshot. */
@@ -273,7 +259,7 @@ bman_release_fast(struct bman_pool *pool, const uint64_t *bufs,
struct bm_rcr_entry *r;
uint8_t i, avail;
uint64_t bpid = pool->params.bpid;
- struct bm_hw_buf_desc bm_bufs[FSL_BM_BURST_MAX];
+ struct bm_buffer bm_bufs[FSL_BM_BURST_MAX];
#ifdef RTE_LIBRTE_DPAA_HWDEBUG
if (!num || (num > FSL_BM_BURST_MAX))
@@ -290,19 +276,17 @@ bman_release_fast(struct bman_pool *pool, const uint64_t *bufs,
if (unlikely(!r))
return -EBUSY;
+ bm_bufs[0].be_desc.bpid = bpid;
+ for (i = 0; i < num; i++)
+ bm_buffer_set64_to_be(&bm_bufs[i], bufs[i]);
/*
* we can copy all but the first entry, as this can trigger badness
* with the valid-bit
*/
- bm_bufs[0].bpid = bpid;
- bm_bufs[0].hi_addr = cpu_to_be16(HI16_OF_U48(bufs[0]));
- bm_bufs[0].lo_addr = cpu_to_be32(LO32_OF_U48(bufs[0]));
- for (i = 1; i < num; i++) {
- bm_bufs[i].hi_addr = cpu_to_be16(HI16_OF_U48(bufs[i]));
- bm_bufs[i].lo_addr = cpu_to_be32(LO32_OF_U48(bufs[i]));
- }
-
- memcpy(r->bufs, bm_bufs, sizeof(struct bm_buffer) * num);
+ r->bufs[0].opaque = bm_bufs[0].opaque;
+ if (num > 1)
+ rte_memcpy(&r->bufs[1], &bm_bufs[1],
+ sizeof(struct bm_buffer) * (num - 1));
bm_rcr_pvb_commit(&p->p, BM_RCR_VERB_CMD_BPID_SINGLE |
(num & BM_RCR_VERB_BUFCOUNT_MASK));
@@ -360,16 +344,6 @@ __rte_unused bman_extract_addr(struct bm_buffer *buf)
return buf->addr;
}
-static inline uint64_t
-bman_hw_extract_addr(struct bm_hw_buf_desc *buf)
-{
- uint64_t hi, lo;
-
- hi = be16_to_cpu(buf->hi_addr);
- lo = be32_to_cpu(buf->lo_addr);
- return U48_BY_HI16_LO32(hi, lo);
-}
-
RTE_EXPORT_INTERNAL_SYMBOL(bman_acquire_fast)
int
bman_acquire_fast(struct bman_pool *pool, uint64_t *bufs, uint8_t num)
@@ -378,7 +352,7 @@ bman_acquire_fast(struct bman_pool *pool, uint64_t *bufs, uint8_t num)
struct bm_mc_command *mcc;
struct bm_mc_result *mcr;
uint8_t i, rst;
- struct bm_hw_buf_desc bm_bufs[FSL_BM_BURST_MAX];
+ struct bm_buffer bm_bufs[FSL_BM_BURST_MAX];
#ifdef RTE_LIBRTE_DPAA_HWDEBUG
if (!num || (num > FSL_BM_BURST_MAX))
@@ -397,11 +371,10 @@ bman_acquire_fast(struct bman_pool *pool, uint64_t *bufs, uint8_t num)
if (unlikely(rst < 1 || rst > FSL_BM_BURST_MAX))
return -EINVAL;
- rte_memcpy(bm_bufs, mcr->acquire.bufs,
- sizeof(struct bm_buffer) * rst);
+ rte_memcpy(bm_bufs, mcr->acquire.bufs, sizeof(struct bm_buffer) * rst);
for (i = 0; i < rst; i++)
- bufs[i] = bman_hw_extract_addr(&bm_bufs[i]);
+ bufs[i] = bm_buffer_get64_from_be(&bm_bufs[i]);
return rst;
}
diff --git a/drivers/bus/dpaa/include/fsl_bman.h b/drivers/bus/dpaa/include/fsl_bman.h
index 2d24b89889..67a7a09618 100644
--- a/drivers/bus/dpaa/include/fsl_bman.h
+++ b/drivers/bus/dpaa/include/fsl_bman.h
@@ -1,7 +1,7 @@
/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
*
* Copyright 2008-2012 Freescale Semiconductor, Inc.
- * Copyright 2024 NXP
+ * Copyright 2024-2026 NXP
*
*/
@@ -42,6 +42,13 @@ struct bm_mc_result; /* MC result */
* pool id specific to this buffer is needed (BM_RCR_VERB_CMD_BPID_MULTI,
* BM_MCC_VERB_ACQUIRE), the 'bpid' field is used.
*/
+struct __rte_packed_begin bm_hw_buf_desc {
+ uint8_t rsv;
+ uint8_t bpid;
+ rte_be16_t hi; /* High 16-bits of 48-bit address */
+ rte_be32_t lo; /* Low 32-bits of 48-bit address */
+} __rte_packed_end;
+
struct __rte_aligned(8) bm_buffer {
union {
struct {
@@ -66,17 +73,11 @@ struct __rte_aligned(8) bm_buffer {
u64 __notaddress:16;
#endif
};
+ struct bm_hw_buf_desc be_desc;
u64 opaque;
};
};
-struct __rte_packed_begin bm_hw_buf_desc {
- uint8_t rsv;
- uint8_t bpid;
- rte_be16_t hi_addr; /* High 16-bits of 48-bit address */
- rte_be32_t lo_addr; /* Low 32-bits of 48-bit address */
-} __rte_packed_end;
-
static inline u64 bm_buffer_get64(const struct bm_buffer *buf)
{
return buf->addr;
@@ -87,6 +88,17 @@ static inline dma_addr_t bm_buf_addr(const struct bm_buffer *buf)
return (dma_addr_t)buf->addr;
}
+#ifndef BIT_SIZE
+#define BIT_SIZE(t) (sizeof(t) * 8)
+#endif
+#define MAX_U48 \
+ ((((uint64_t)UINT16_MAX) << BIT_SIZE(uint32_t)) | UINT32_MAX)
+#define HI16_OF_U48(x) \
+ (((x) >> BIT_SIZE(uint32_t)) & UINT16_MAX)
+#define LO32_OF_U48(x) ((x) & UINT32_MAX)
+#define U48_BY_HI16_LO32(hi, lo) \
+ (((hi) << BIT_SIZE(uint32_t)) | (lo))
+
#define bm_buffer_set64(buf, v) \
do { \
struct bm_buffer *__buf931 = (buf); \
@@ -94,6 +106,24 @@ static inline dma_addr_t bm_buf_addr(const struct bm_buffer *buf)
__buf931->lo = lower_32_bits(v); \
} while (0)
+#define bm_buffer_set64_to_be(buf, v) \
+ do { \
+ struct bm_buffer *__buf931 = (buf); \
+ \
+ __buf931->be_desc.hi = cpu_to_be16(HI16_OF_U48(v)); \
+ __buf931->be_desc.lo = cpu_to_be32(LO32_OF_U48(v)); \
+ } while (0)
+
+#define bm_buffer_get64_from_be(buf) \
+ ({ \
+ uint64_t hi, lo; \
+ struct bm_buffer *__buf931 = (buf); \
+ \
+ hi = be16_to_cpu(__buf931->be_desc.hi); \
+ lo = be32_to_cpu(__buf931->be_desc.lo); \
+ U48_BY_HI16_LO32(hi, lo); \
+ })
+
#define FSL_BM_BURST_MAX 8
/* See 1.5.3.5.4: "Release Command" */
diff --git a/drivers/mempool/dpaa/dpaa_mempool.c b/drivers/mempool/dpaa/dpaa_mempool.c
index 2f8555a026..3fdbcba646 100644
--- a/drivers/mempool/dpaa/dpaa_mempool.c
+++ b/drivers/mempool/dpaa/dpaa_mempool.c
@@ -1,6 +1,6 @@
/* SPDX-License-Identifier: BSD-3-Clause
*
- * Copyright 2017,2019,2023-2025 NXP
+ * Copyright 2017,2019,2023-2026 NXP
*
*/
@@ -50,7 +50,7 @@ static int
dpaa_mbuf_create_pool(struct rte_mempool *mp)
{
struct bman_pool *bp;
- struct bm_buffer bufs[8];
+ struct bm_buffer bufs[FSL_BM_BURST_MAX];
struct dpaa_bp_info *bp_info;
uint8_t bpid;
int num_bufs = 0, ret = 0;
@@ -83,8 +83,8 @@ dpaa_mbuf_create_pool(struct rte_mempool *mp)
* then in 1s for the remainder.
*/
if (ret != 1)
- ret = bman_acquire(bp, bufs, 8, 0);
- if (ret < 8)
+ ret = bman_acquire(bp, bufs, FSL_BM_BURST_MAX, 0);
+ if (ret < FSL_BM_BURST_MAX)
ret = bman_acquire(bp, bufs, 1, 0);
if (ret > 0)
num_bufs += ret;
--
2.25.1
^ permalink raw reply related
* [PATCH v3 17/19] drivers: release DPAA bpid on driver destructor
From: Hemant Agrawal @ 2026-06-21 15:22 UTC (permalink / raw)
To: stephen, david.marchand, dev; +Cc: Jun Yang
In-Reply-To: <20260621152228.2777171-1-hemant.agrawal@nxp.com>
From: Jun Yang <jun.yang@nxp.com>
Track allocated BPIDs in a static per-BPID flag table and register a
driver destructor that releases any BPIDs still marked as in use at
process exit. This prevents BPID leaks when an application exits without
calling rte_mempool_free(). Also tune the per-lcore mempool cache flush
threshold to match the hardware bulk release size (DPAA_MBUF_MAX_ACQ_REL)
so that buffers are returned to HW in optimal burst sizes.
Signed-off-by: Jun Yang <jun.yang@nxp.com>
---
drivers/bus/dpaa/base/qbman/bman.c | 8 +++
drivers/bus/dpaa/dpaa_bus_base_symbols.c | 1 +
drivers/bus/dpaa/include/fsl_bman.h | 3 ++
drivers/mempool/dpaa/dpaa_mempool.c | 67 ++++++++++++++++++++++--
drivers/mempool/dpaa/dpaa_mempool.h | 3 +-
5 files changed, 78 insertions(+), 4 deletions(-)
diff --git a/drivers/bus/dpaa/base/qbman/bman.c b/drivers/bus/dpaa/base/qbman/bman.c
index 01357d6446..b69394b0cc 100644
--- a/drivers/bus/dpaa/base/qbman/bman.c
+++ b/drivers/bus/dpaa/base/qbman/bman.c
@@ -237,6 +237,14 @@ void bman_free_pool(struct bman_pool *pool)
kfree(pool);
}
+void bman_free_bpid(u8 bpid, u32 flags)
+{
+ if (flags & BMAN_POOL_FLAG_THRESH)
+ bm_pool_set(bpid, zero_thresholds);
+ if (flags & BMAN_POOL_FLAG_DYNAMIC_BPID)
+ bman_release_bpid(bpid);
+}
+
const struct bman_pool_params *bman_get_params(const struct bman_pool *pool)
{
return &pool->params;
diff --git a/drivers/bus/dpaa/dpaa_bus_base_symbols.c b/drivers/bus/dpaa/dpaa_bus_base_symbols.c
index 514ab7b1f1..8bd1a9bc6e 100644
--- a/drivers/bus/dpaa/dpaa_bus_base_symbols.c
+++ b/drivers/bus/dpaa/dpaa_bus_base_symbols.c
@@ -46,6 +46,7 @@ RTE_EXPORT_INTERNAL_SYMBOL(netcfg_acquire)
RTE_EXPORT_INTERNAL_SYMBOL(netcfg_release)
RTE_EXPORT_INTERNAL_SYMBOL(bman_new_pool)
RTE_EXPORT_INTERNAL_SYMBOL(bman_free_pool)
+RTE_EXPORT_INTERNAL_SYMBOL(bman_free_bpid)
RTE_EXPORT_INTERNAL_SYMBOL(bman_get_params)
RTE_EXPORT_INTERNAL_SYMBOL(bman_release)
RTE_EXPORT_INTERNAL_SYMBOL(bman_acquire)
diff --git a/drivers/bus/dpaa/include/fsl_bman.h b/drivers/bus/dpaa/include/fsl_bman.h
index 67a7a09618..6079eedff5 100644
--- a/drivers/bus/dpaa/include/fsl_bman.h
+++ b/drivers/bus/dpaa/include/fsl_bman.h
@@ -317,6 +317,9 @@ struct bman_pool *bman_new_pool(const struct bman_pool_params *params);
__rte_internal
void bman_free_pool(struct bman_pool *pool);
+__rte_internal
+void bman_free_bpid(u8 bpid, u32 flags);
+
/**
* bman_get_params - Returns a pool object's parameters.
* @pool: the pool object
diff --git a/drivers/mempool/dpaa/dpaa_mempool.c b/drivers/mempool/dpaa/dpaa_mempool.c
index 3fdbcba646..210ea3bcf9 100644
--- a/drivers/mempool/dpaa/dpaa_mempool.c
+++ b/drivers/mempool/dpaa/dpaa_mempool.c
@@ -25,10 +25,22 @@
#include <rte_eal.h>
#include <rte_malloc.h>
#include <rte_ring.h>
+#include <rte_common.h>
#include <dpaa_mempool.h>
#include <dpaax_iova_table.h>
+struct dpaa_bpid_flag {
+ uint32_t flags;
+ int used;
+};
+
+/** Be referenced in destructor to release bpid allocated.
+ * Destructor can't access bman_pool from eal mem,
+ * we release ID with flag directly.
+ */
+static struct dpaa_bpid_flag s_dpaa_bpid_allocated_flag[DPAA_MAX_BPOOLS];
+
#define FMAN_ERRATA_BOUNDARY ((uint64_t)4096)
#define FMAN_ERRATA_BOUNDARY_MASK (~(FMAN_ERRATA_BOUNDARY - 1))
@@ -58,6 +70,8 @@ dpaa_mbuf_create_pool(struct rte_mempool *mp)
struct bman_pool_params params = {
.flags = BMAN_POOL_FLAG_DYNAMIC_BPID
};
+ unsigned int lcore_id;
+ struct rte_mempool_cache *cache;
MEMPOOL_INIT_FUNC_TRACE();
@@ -115,7 +129,7 @@ dpaa_mbuf_create_pool(struct rte_mempool *mp)
rte_dpaa_bpid_info[bpid].ptov_off = 0;
rte_dpaa_bpid_info[bpid].flags = 0;
- bp_info = rte_malloc(NULL,
+ bp_info = rte_zmalloc(NULL,
sizeof(struct dpaa_bp_info),
RTE_CACHE_LINE_SIZE);
if (!bp_info) {
@@ -127,6 +141,20 @@ dpaa_mbuf_create_pool(struct rte_mempool *mp)
rte_memcpy(bp_info, (void *)&rte_dpaa_bpid_info[bpid],
sizeof(struct dpaa_bp_info));
mp->pool_data = (void *)bp_info;
+ s_dpaa_bpid_allocated_flag[bpid].flags = params.flags;
+ s_dpaa_bpid_allocated_flag[bpid].used = true;
+ /* Update per core mempool cache threshold to optimal value which is
+ * number of buffers that can be released to HW buffer pool in
+ * a single API call.
+ */
+ for (lcore_id = 0; lcore_id < RTE_MAX_LCORE; lcore_id++) {
+ cache = &mp->local_cache[lcore_id];
+ DPAA_MEMPOOL_DEBUG("lCore %d: cache->flushthresh %d -> %d",
+ lcore_id, cache->flushthresh,
+ (uint32_t)(cache->size + DPAA_MBUF_MAX_ACQ_REL));
+ if (cache->flushthresh)
+ cache->flushthresh = cache->size + DPAA_MBUF_MAX_ACQ_REL;
+ }
DPAA_MEMPOOL_INFO("BMAN pool created for bpid =%d", bpid);
return 0;
@@ -136,6 +164,7 @@ static void
dpaa_mbuf_free_pool(struct rte_mempool *mp)
{
struct dpaa_bp_info *bp_info = DPAA_MEMPOOL_TO_POOL_INFO(mp);
+ uint16_t i;
MEMPOOL_INIT_FUNC_TRACE();
@@ -143,10 +172,25 @@ dpaa_mbuf_free_pool(struct rte_mempool *mp)
bman_free_pool(bp_info->bp);
DPAA_MEMPOOL_INFO("BMAN pool freed for bpid =%d",
bp_info->bpid);
- rte_free(mp->pool_data);
- bp_info->bp = NULL;
+ rte_dpaa_bpid_info[bp_info->bpid].mp = NULL;
+ rte_dpaa_bpid_info[bp_info->bpid].bp = NULL;
+ s_dpaa_bpid_allocated_flag[bp_info->bpid].used = false;
+ rte_free(bp_info);
mp->pool_data = NULL;
}
+
+ if (!rte_dpaa_bpid_info)
+ return;
+
+ for (i = 0; i < DPAA_MAX_BPOOLS; i++) {
+ if (rte_dpaa_bpid_info[i].mp)
+ break;
+ }
+
+ if (i == DPAA_MAX_BPOOLS) {
+ rte_free(rte_dpaa_bpid_info);
+ rte_dpaa_bpid_info = NULL;
+ }
}
static int
@@ -481,4 +525,21 @@ static const struct rte_mempool_ops dpaa_mpool_ops = {
.populate = dpaa_populate,
};
+#define RTE_PRIORITY_104 104
+
+RTE_FINI_PRIO(dpaa_mpool_finish, 104)
+{
+ uint16_t bpid;
+
+ for (bpid = 0; bpid < DPAA_MAX_BPOOLS; bpid++) {
+ if (s_dpaa_bpid_allocated_flag[bpid].used) {
+ bman_free_bpid(bpid, s_dpaa_bpid_allocated_flag[bpid].flags);
+ s_dpaa_bpid_allocated_flag[bpid].used = false;
+ }
+ }
+ /** The rte_dpaa_bpid_info and bman_pool from EAL mem have been released
+ * with EAL mem pool being destroyed.
+ */
+}
+
RTE_MEMPOOL_REGISTER_OPS(dpaa_mpool_ops);
diff --git a/drivers/mempool/dpaa/dpaa_mempool.h b/drivers/mempool/dpaa/dpaa_mempool.h
index 865b533b8f..d7ee49b557 100644
--- a/drivers/mempool/dpaa/dpaa_mempool.h
+++ b/drivers/mempool/dpaa/dpaa_mempool.h
@@ -1,6 +1,6 @@
/* SPDX-License-Identifier: BSD-3-Clause
*
- * Copyright 2017,2019,2024 -2025 NXP
+ * Copyright 2017,2019,2024 -2026 NXP
*
*/
#ifndef __DPAA_MEMPOOL_H__
@@ -24,6 +24,7 @@
/* total number of bpools on SoC */
#define DPAA_MAX_BPOOLS 256
+#define DPAA_INVALID_BPID DPAA_MAX_BPOOLS
/* Maximum release/acquire from BMAN */
#define DPAA_MBUF_MAX_ACQ_REL FSL_BM_BURST_MAX
--
2.25.1
^ permalink raw reply related
* [PATCH v3 18/19] dma/dpaa: add SG data validation and ERR050757 fix
From: Hemant Agrawal @ 2026-06-21 15:22 UTC (permalink / raw)
To: stephen, david.marchand, dev; +Cc: Gagandeep Singh
In-Reply-To: <20260621152228.2777171-1-hemant.agrawal@nxp.com>
From: Gagandeep Singh <g.singh@nxp.com>
Add scatter-gather (SG) support to the QDMA driver, enabled by default
via the s_sg_enable flag. Add optional data validation mode controlled
by the s_data_validation flag for debugging transfer correctness.
Add a workaround for hardware errata ERR050757: when
RTE_DMA_DPAA_ERRATA_ERR050757 is defined, configure the source frame
descriptor with stride settings (sss/ssd = FSL_QDMA_CMD_SS_ERR050757_LEN)
to force PCI read transactions to stay within the errata-safe length
limit, preventing data corruption on affected silicon.
Signed-off-by: Gagandeep Singh <g.singh@nxp.com>
---
drivers/dma/dpaa/dpaa_qdma.c | 99 +++++++++++++++++++++++++++---------
1 file changed, 75 insertions(+), 24 deletions(-)
diff --git a/drivers/dma/dpaa/dpaa_qdma.c b/drivers/dma/dpaa/dpaa_qdma.c
index 0ede9ee8b5..acac770c88 100644
--- a/drivers/dma/dpaa/dpaa_qdma.c
+++ b/drivers/dma/dpaa/dpaa_qdma.c
@@ -9,9 +9,14 @@
#include "dpaa_qdma.h"
#include "dpaa_qdma_logs.h"
+static int s_data_validation;
+static int s_hw_err_check;
+static int s_sg_enable = 1;
static uint32_t s_sg_max_entry_sz = 2000;
-static bool s_hw_err_check;
+#ifdef RTE_DMA_DPAA_ERRATA_ERR050757
+static int s_pci_read = 1;
+#endif
#define DPAA_DMA_ERROR_CHECK "dpaa_dma_err_check"
static inline void
@@ -112,7 +117,8 @@ dma_pool_alloc(char *nm, int size, int aligned, dma_addr_t *phy_addr)
if (!virt_addr)
return NULL;
- *phy_addr = rte_mem_virt2iova(virt_addr);
+ if (phy_addr)
+ *phy_addr = rte_mem_virt2iova(virt_addr);
return virt_addr;
}
@@ -392,6 +398,8 @@ fsl_qdma_data_validation(struct fsl_qdma_desc *desc[],
char err_msg[512];
int offset;
+ if (likely(!s_data_validation))
+ return;
offset = sprintf(err_msg, "Fatal TC%d/queue%d: ",
fsl_queue->block_id,
@@ -716,19 +724,21 @@ fsl_qdma_enqueue_desc_single(struct fsl_qdma_queue *fsl_queue,
ft = fsl_queue->ft[fsl_queue->ci];
#ifdef RTE_DMA_DPAA_ERRATA_ERR050757
- sdf = &ft->df.sdf;
- sdf->srttype = FSL_QDMA_CMD_RWTTYPE;
+ if (s_pci_read) {
+ sdf = &ft->df.sdf;
+ sdf->srttype = FSL_QDMA_CMD_RWTTYPE;
#ifdef RTE_DMA_DPAA_ERRATA_ERR050265
- sdf->prefetch = 1;
+ sdf->prefetch = 1;
#endif
- if (len > FSL_QDMA_CMD_SS_ERR050757_LEN) {
- sdf->ssen = 1;
- sdf->sss = FSL_QDMA_CMD_SS_ERR050757_LEN;
- sdf->ssd = FSL_QDMA_CMD_SS_ERR050757_LEN;
- } else {
- sdf->ssen = 0;
- sdf->sss = 0;
- sdf->ssd = 0;
+ if (len > FSL_QDMA_CMD_SS_ERR050757_LEN) {
+ sdf->ssen = 1;
+ sdf->sss = FSL_QDMA_CMD_SS_ERR050757_LEN;
+ sdf->ssd = FSL_QDMA_CMD_SS_ERR050757_LEN;
+ } else {
+ sdf->ssen = 0;
+ sdf->sss = 0;
+ sdf->ssd = 0;
+ }
}
#endif
csgf_src = &ft->desc_sbuf;
@@ -832,19 +842,21 @@ fsl_qdma_enqueue_desc_sg(struct fsl_qdma_queue *fsl_queue)
csgf_src->length = total_len;
csgf_dest->length = total_len;
#ifdef RTE_DMA_DPAA_ERRATA_ERR050757
- sdf = &ft->df.sdf;
- sdf->srttype = FSL_QDMA_CMD_RWTTYPE;
+ if (s_pci_read) {
+ sdf = &ft->df.sdf;
+ sdf->srttype = FSL_QDMA_CMD_RWTTYPE;
#ifdef RTE_DMA_DPAA_ERRATA_ERR050265
- sdf->prefetch = 1;
+ sdf->prefetch = 1;
#endif
- if (total_len > FSL_QDMA_CMD_SS_ERR050757_LEN) {
- sdf->ssen = 1;
- sdf->sss = FSL_QDMA_CMD_SS_ERR050757_LEN;
- sdf->ssd = FSL_QDMA_CMD_SS_ERR050757_LEN;
- } else {
- sdf->ssen = 0;
- sdf->sss = 0;
- sdf->ssd = 0;
+ if (total_len > FSL_QDMA_CMD_SS_ERR050757_LEN) {
+ sdf->ssen = 1;
+ sdf->sss = FSL_QDMA_CMD_SS_ERR050757_LEN;
+ sdf->ssd = FSL_QDMA_CMD_SS_ERR050757_LEN;
+ } else {
+ sdf->ssen = 0;
+ sdf->sss = 0;
+ sdf->ssd = 0;
+ }
}
#endif
ret = fsl_qdma_enqueue_desc_to_ring(fsl_queue, num);
@@ -883,6 +895,25 @@ fsl_qdma_enqueue_desc(struct fsl_qdma_queue *fsl_queue)
fsl_queue->pending_num = 0;
}
return ret;
+ } else if (!s_sg_enable) {
+ while (fsl_queue->pending_num > 0) {
+ ret = fsl_qdma_enqueue_desc_single(fsl_queue,
+ fsl_queue->pending_desc[start].dst,
+ fsl_queue->pending_desc[start].src,
+ fsl_queue->pending_desc[start].len);
+ if (!ret) {
+ start = (start + 1) &
+ (fsl_queue->pending_max - 1);
+ fsl_queue->pending_start = start;
+ fsl_queue->pending_num--;
+ } else {
+ DPAA_QDMA_ERR("Eq pending desc failed(%d)",
+ ret);
+ return -EIO;
+ }
+ }
+
+ return 0;
}
return fsl_qdma_enqueue_desc_sg(fsl_queue);
@@ -1339,6 +1370,26 @@ dpaa_qdma_init(struct rte_dma_dev *dmadev)
DPAA_QDMA_INFO("Enable DMA error checks");
}
+ if (getenv("DPAA_QDMA_DATA_VALIDATION"))
+ s_data_validation = 1;
+
+ if (getenv("DPAA_QDMA_HW_ERR_CHECK"))
+ s_hw_err_check = 1;
+
+ penv = getenv("DPAA_QDMA_SG_ENABLE");
+ if (penv)
+ s_sg_enable = atoi(penv);
+
+ penv = getenv("DPAA_QDMA_SG_MAX_ENTRY_SIZE");
+ if (penv)
+ s_sg_max_entry_sz = atoi(penv);
+
+#ifdef RTE_DMA_DPAA_ERRATA_ERR050757
+ penv = getenv("DPAA_QDMA_PCI_READ");
+ if (penv)
+ s_pci_read = atoi(penv);
+#endif
+
fsl_qdma->n_queues = QDMA_QUEUES * QDMA_BLOCKS;
fsl_qdma->num_blocks = QDMA_BLOCKS;
fsl_qdma->block_offset = QDMA_BLOCK_OFFSET;
--
2.25.1
^ permalink raw reply related
* [PATCH v3 19/19] net/dpaa: add ONIC port checks
From: Hemant Agrawal @ 2026-06-21 15:22 UTC (permalink / raw)
To: stephen, david.marchand, dev; +Cc: Vanshika Shukla
In-Reply-To: <20260621152228.2777171-1-hemant.agrawal@nxp.com>
From: Vanshika Shukla <vanshika.shukla@nxp.com>
Add get_tx_port_type() helper that maps fman MAC type to the correct FMC
Tx port type. Handle fman_onic and fman_offline_internal MAC types as
OH_OFFLINE_PARSING on the Tx path, consistent with existing Rx port type
logic. Without this, ONIC ports used incorrect port type in flow
configuration, leading to failed FMC operations.
Signed-off-by: Vanshika Shukla <vanshika.shukla@nxp.com>
---
drivers/net/dpaa/dpaa_ethdev.c | 26 +++---
drivers/net/dpaa/dpaa_ethdev.h | 11 ++-
drivers/net/dpaa/dpaa_flow.c | 146 +++++++++++++++++++--------------
drivers/net/dpaa/dpaa_flow.h | 7 +-
4 files changed, 110 insertions(+), 80 deletions(-)
diff --git a/drivers/net/dpaa/dpaa_ethdev.c b/drivers/net/dpaa/dpaa_ethdev.c
index 63a3c110d9..638d81d7e6 100644
--- a/drivers/net/dpaa/dpaa_ethdev.c
+++ b/drivers/net/dpaa/dpaa_ethdev.c
@@ -490,7 +490,7 @@ static int dpaa_eth_dev_stop(struct rte_eth_dev *dev)
PMD_INIT_FUNC_TRACE();
dev->data->dev_started = 0;
- if (!fif->is_shared_mac) {
+ if (!fif->is_shared_mac && fif->mac_type != fman_onic) {
fman_if_bmi_stats_disable(fif);
fman_if_disable_rx(fif);
}
@@ -590,7 +590,7 @@ static int dpaa_eth_dev_close(struct rte_eth_dev *dev)
}
}
if (fif->num_profiles) {
- ret = dpaa_port_vsp_cleanup(dpaa_intf, fif);
+ ret = dpaa_port_vsp_cleanup(dpaa_intf);
if (ret) {
DPAA_PMD_WARN("%s: cleanup VSP failed(%d)",
dev->data->name, ret);
@@ -674,7 +674,7 @@ static int dpaa_eth_dev_close(struct rte_eth_dev *dev)
dev->data->name, ret);
}
if (fif->num_profiles) {
- ret = dpaa_port_vsp_cleanup(dpaa_intf, fif);
+ ret = dpaa_port_vsp_cleanup(dpaa_intf);
if (ret) {
DPAA_PMD_WARN("%s: cleanup VSP failed(%d)",
dev->data->name, ret);
@@ -1134,8 +1134,8 @@ static inline int dpaa_eth_rx_queue_bp_check(struct rte_eth_dev *dev,
vsp_id = 0;
}
- if (dpaa_intf->vsp_bpid[vsp_id] &&
- bpid != dpaa_intf->vsp_bpid[vsp_id]) {
+ if (dpaa_intf->vsp[vsp_id].vsp_bp[0] &&
+ bpid != dpaa_intf->vsp[vsp_id].vsp_bp[0]->bpid) {
DPAA_PMD_ERR("Various MPs are assigned to RXQs with same VSP");
return -1;
@@ -1232,9 +1232,9 @@ int dpaa_eth_rx_queue_setup(struct rte_eth_dev *dev, uint16_t queue_idx,
int8_t vsp_id = rxq->vsp_id;
if (vsp_id >= 0) {
- ret = dpaa_port_vsp_update(dpaa_intf, fmc_q, vsp_id,
- DPAA_MEMPOOL_TO_POOL_INFO(mp)->bpid,
- fif, buffsz + RTE_PKTMBUF_HEADROOM);
+ dpaa_intf->vsp[vsp_id].vsp_bp[0] = DPAA_MEMPOOL_TO_POOL_INFO(mp);
+ dpaa_intf->vsp[vsp_id].bp_num = 1;
+ ret = dpaa_port_vsp_update(dpaa_intf, fmc_q, vsp_id, fif);
if (ret) {
DPAA_PMD_ERR("dpaa_port_vsp_update failed");
return ret;
@@ -1247,12 +1247,14 @@ int dpaa_eth_rx_queue_setup(struct rte_eth_dev *dev, uint16_t queue_idx,
" to shared interface on DPDK.");
return -EINVAL;
}
- dpaa_intf->vsp_bpid[fif->base_profile_id] =
- DPAA_MEMPOOL_TO_POOL_INFO(mp)->bpid;
+ dpaa_intf->vsp[fif->base_profile_id].vsp_bp[0] =
+ DPAA_MEMPOOL_TO_POOL_INFO(mp);
+ dpaa_intf->vsp[fif->base_profile_id].bp_num = 1;
}
} else {
- dpaa_intf->vsp_bpid[0] =
- DPAA_MEMPOOL_TO_POOL_INFO(mp)->bpid;
+ dpaa_intf->vsp[0].vsp_bp[0] =
+ DPAA_MEMPOOL_TO_POOL_INFO(mp);
+ dpaa_intf->vsp[0].bp_num = 1;
}
dpaa_intf->valid = 1;
diff --git a/drivers/net/dpaa/dpaa_ethdev.h b/drivers/net/dpaa/dpaa_ethdev.h
index d342d98f23..d3e005b556 100644
--- a/drivers/net/dpaa/dpaa_ethdev.h
+++ b/drivers/net/dpaa/dpaa_ethdev.h
@@ -118,6 +118,13 @@ enum {
#define FMC_FILE "/tmp/fmc.bin"
+struct dpaa_if_vsp {
+ struct dpaa_bp_info *vsp_bp[FMAN_PORT_MAX_EXT_POOLS_NUM];
+ uint8_t bp_num;
+ uint32_t max_size;
+ void *vsp_handle;
+};
+
extern struct rte_mempool *dpaa_tx_sg_pool;
/* PMD related logs */
@@ -164,8 +171,8 @@ struct dpaa_if {
*/
struct qman_fq *next_tx_conf_queue;
- void *vsp_handle[DPAA_VSP_PROFILE_MAX_NUM];
- uint32_t vsp_bpid[DPAA_VSP_PROFILE_MAX_NUM];
+ struct dpaa_if_vsp vsp[DPAA_VSP_PROFILE_MAX_NUM];
+ uint8_t base_vsp;
};
struct dpaa_if_stats {
diff --git a/drivers/net/dpaa/dpaa_flow.c b/drivers/net/dpaa/dpaa_flow.c
index 559850ced7..9f0611a3c7 100644
--- a/drivers/net/dpaa/dpaa_flow.c
+++ b/drivers/net/dpaa/dpaa_flow.c
@@ -1,5 +1,5 @@
/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright 2017-2019,2021-2025 NXP
+ * Copyright 2017-2019,2021-2026 NXP
*/
/* System headers */
@@ -8,6 +8,7 @@
#include <unistd.h>
#include <sys/types.h>
+#include <dpaa_mempool.h>
#include <dpaa_ethdev.h>
#include <dpaa_flow.h>
#include <rte_dpaa_logs.h>
@@ -669,6 +670,22 @@ static inline int get_rx_port_type(struct fman_if *fif)
return e_FM_PORT_TYPE_DUMMY;
}
+static inline int get_tx_port_type(struct fman_if *fif)
+{
+ if (fif->mac_type == fman_offline_internal ||
+ fif->mac_type == fman_onic)
+ return e_FM_PORT_TYPE_OH_OFFLINE_PARSING;
+ else if (fif->mac_type == fman_mac_1g)
+ return e_FM_PORT_TYPE_TX;
+ else if (fif->mac_type == fman_mac_2_5g)
+ return e_FM_PORT_TYPE_TX_2_5G;
+ else if (fif->mac_type == fman_mac_10g)
+ return e_FM_PORT_TYPE_TX_10G;
+
+ DPAA_PMD_ERR("MAC type unsupported");
+ return e_FM_PORT_TYPE_DUMMY;
+}
+
static inline int set_fm_port_handle(struct dpaa_if *dpaa_intf,
uint64_t req_dist_set,
struct fman_if *fif)
@@ -724,9 +741,6 @@ int dpaa_fm_deconfig(struct dpaa_if *dpaa_intf,
PMD_INIT_FUNC_TRACE();
- if (!dpaa_intf->port_handle)
- return 0;
-
/* FM PORT Disable */
ret = fm_port_disable(dpaa_intf->port_handle);
if (ret != E_OK) {
@@ -786,8 +800,10 @@ int dpaa_fm_config(struct rte_eth_dev *dev, uint64_t req_dist_set)
unsigned int i = 0;
PMD_INIT_FUNC_TRACE();
- if (dpaa_fm_deconfig(dpaa_intf, fif))
- DPAA_PMD_ERR("DPAA FM deconfig failed");
+ if (dpaa_intf->port_handle) {
+ if (dpaa_fm_deconfig(dpaa_intf, fif))
+ DPAA_PMD_ERR("DPAA FM deconfig failed");
+ }
if (!dev->data->nb_rx_queues)
return 0;
@@ -806,8 +822,7 @@ int dpaa_fm_config(struct rte_eth_dev *dev, uint64_t req_dist_set)
if (fif->num_profiles) {
for (i = 0; i < dev->data->nb_rx_queues; i++)
- dpaa_intf->rx_queues[i].vsp_id =
- fm_default_vsp_id(fif);
+ dpaa_intf->rx_queues[i].vsp_id = fm_default_vsp_id(fif);
i = 0;
}
@@ -939,27 +954,16 @@ int dpaa_fm_term(void)
}
static int dpaa_port_vsp_configure(struct dpaa_if *dpaa_intf,
- uint8_t vsp_id, t_handle fman_handle,
- struct fman_if *fif, u32 mbuf_data_room_size)
+ uint8_t vsp_id, t_handle fman_handle, struct fman_if *fif)
{
+ struct dpaa_if_vsp *vsp;
t_fm_vsp_params vsp_params;
t_fm_buffer_prefix_content buf_prefix_cont;
- uint8_t idx = mac_idx[fif->mac_idx];
+ uint8_t idx = mac_idx[fif->mac_idx], i;
int ret;
+ struct t_fm_ext_pools *pools;
- if (vsp_id == fif->base_profile_id && fif->is_shared_mac) {
- /* For shared interface, VSP of base
- * profile is default pool located in kernel.
- */
- dpaa_intf->vsp_bpid[vsp_id] = 0;
- return 0;
- }
-
- if (vsp_id >= DPAA_VSP_PROFILE_MAX_NUM) {
- DPAA_PMD_ERR("VSP ID %d exceeds MAX number %d",
- vsp_id, DPAA_VSP_PROFILE_MAX_NUM);
- return -1;
- }
+ vsp = &dpaa_intf->vsp[vsp_id];
memset(&vsp_params, 0, sizeof(vsp_params));
vsp_params.h_fm = fman_handle;
@@ -973,17 +977,21 @@ static int dpaa_port_vsp_configure(struct dpaa_if *dpaa_intf,
vsp_params.port_params.port_type = get_rx_port_type(fif);
if (vsp_params.port_params.port_type == e_FM_PORT_TYPE_DUMMY) {
DPAA_PMD_ERR("Mac type %d error", fif->mac_type);
- return -1;
+ return -EINVAL;
}
- vsp_params.ext_buf_pools.num_of_pools_used = 1;
- vsp_params.ext_buf_pools.ext_buf_pool[0].id = dpaa_intf->vsp_bpid[vsp_id];
- vsp_params.ext_buf_pools.ext_buf_pool[0].size = mbuf_data_room_size;
+ pools = &vsp_params.ext_buf_pools;
- dpaa_intf->vsp_handle[vsp_id] = fm_vsp_config(&vsp_params);
- if (!dpaa_intf->vsp_handle[vsp_id]) {
- DPAA_PMD_ERR("fm_vsp_config error for profile %d", vsp_id);
- return -EINVAL;
+ pools->num_of_pools_used = vsp->bp_num;
+ for (i = 0; i < vsp->bp_num; i++) {
+ pools->ext_buf_pool[i].id = vsp->vsp_bp[i]->bpid;
+ pools->ext_buf_pool[i].size = vsp->vsp_bp[i]->size;
+ }
+
+ vsp->vsp_handle = fm_vsp_config(&vsp_params);
+ if (!vsp->vsp_handle) {
+ DPAA_PMD_ERR("Configure VSP[%d] failed!", vsp_id);
+ return -EIO;
}
/* configure the application buffer (structure, size and
@@ -1001,19 +1009,18 @@ static int dpaa_port_vsp_configure(struct dpaa_if *dpaa_intf,
buf_prefix_cont.manip_ext_space =
RTE_PKTMBUF_HEADROOM - DPAA_MBUF_HW_ANNOTATION;
- ret = fm_vsp_config_buffer_prefix_content(dpaa_intf->vsp_handle[vsp_id],
- &buf_prefix_cont);
+ ret = fm_vsp_config_buffer_prefix_content(vsp->vsp_handle,
+ &buf_prefix_cont);
if (ret != E_OK) {
- DPAA_PMD_ERR("fm_vsp_config_buffer_prefix_content error for profile %d err: %d",
- vsp_id, ret);
+ DPAA_PMD_ERR("Configure VSP[%d]'s buffer prefix failed(%d)!",
+ vsp_id, ret);
return ret;
}
/* initialize the FM VSP module */
- ret = fm_vsp_init(dpaa_intf->vsp_handle[vsp_id]);
+ ret = fm_vsp_init(vsp->vsp_handle);
if (ret != E_OK) {
- DPAA_PMD_ERR("fm_vsp_init error for profile %d err:%d",
- vsp_id, ret);
+ DPAA_PMD_ERR("Init VSP[%d] failed(%d)!", vsp_id, ret);
return ret;
}
@@ -1021,29 +1028,44 @@ static int dpaa_port_vsp_configure(struct dpaa_if *dpaa_intf,
}
int dpaa_port_vsp_update(struct dpaa_if *dpaa_intf,
- bool fmc_mode, uint8_t vsp_id, uint32_t bpid,
- struct fman_if *fif, u32 mbuf_data_room_size)
+ bool fmc_mode, uint8_t vsp_id, struct fman_if *fif)
{
int ret = 0;
t_handle fman_handle;
+ struct dpaa_if_vsp *vsp;
- if (!fif->num_profiles)
- return 0;
+ if (!fif->num_profiles) {
+ DPAA_PMD_ERR("%s: No multiple VSPs specified!",
+ dpaa_intf->name);
+ return -EINVAL;
+ }
- if (vsp_id >= fif->num_profiles)
- return 0;
+ if (vsp_id >= (fif->base_profile_id + fif->num_profiles)) {
+ DPAA_PMD_ERR("%s: Invalid VSP ID(%d) >= base(%d) + num(%d)",
+ dpaa_intf->name, vsp_id, fif->base_profile_id,
+ fif->num_profiles);
+ return -EINVAL;
+ }
- if (dpaa_intf->vsp_bpid[vsp_id] == bpid)
+ if (vsp_id == fif->base_profile_id && fif->is_shared_mac) {
+ /* For shared interface, VSP of base
+ * profile is default pool located in kernel.
+ */
+ dpaa_intf->vsp[vsp_id].bp_num = 0;
+ dpaa_intf->vsp[vsp_id].vsp_handle = NULL;
return 0;
+ }
+
+ vsp = &dpaa_intf->vsp[vsp_id];
- if (dpaa_intf->vsp_handle[vsp_id]) {
- ret = fm_vsp_free(dpaa_intf->vsp_handle[vsp_id]);
+ if (vsp->vsp_handle) {
+ ret = fm_vsp_free(vsp->vsp_handle);
if (ret != E_OK) {
- DPAA_PMD_ERR("Error fm_vsp_free: err %d vsp_handle[%d]",
- ret, vsp_id);
+ DPAA_PMD_ERR("Free VSP[%d]'s handle failed(%d)",
+ vsp_id, ret);
return ret;
}
- dpaa_intf->vsp_handle[vsp_id] = 0;
+ vsp->vsp_handle = NULL;
}
if (fmc_mode)
@@ -1051,26 +1073,26 @@ int dpaa_port_vsp_update(struct dpaa_if *dpaa_intf,
else
fman_handle = fm_info.fman_handle;
- dpaa_intf->vsp_bpid[vsp_id] = bpid;
-
- return dpaa_port_vsp_configure(dpaa_intf, vsp_id, fman_handle, fif,
- mbuf_data_room_size);
+ return dpaa_port_vsp_configure(dpaa_intf, vsp_id, fman_handle, fif);
}
-int dpaa_port_vsp_cleanup(struct dpaa_if *dpaa_intf, struct fman_if *fif)
+int dpaa_port_vsp_cleanup(struct dpaa_if *dpaa_intf)
{
- int idx, ret;
+ int ret;
+ uint8_t idx;
- for (idx = 0; idx < (uint8_t)fif->num_profiles; idx++) {
- if (dpaa_intf->vsp_handle[idx]) {
- ret = fm_vsp_free(dpaa_intf->vsp_handle[idx]);
+ for (idx = 0; idx < DPAA_VSP_PROFILE_MAX_NUM; idx++) {
+ if (dpaa_intf->vsp[idx].vsp_handle) {
+ ret = fm_vsp_free(dpaa_intf->vsp[idx].vsp_handle);
if (ret != E_OK) {
- DPAA_PMD_ERR("Error fm_vsp_free: err %d"
- " vsp_handle[%d]", ret, idx);
+ DPAA_PMD_ERR("Free VSP[%d] failed(%d)",
+ idx, ret);
return ret;
}
+ dpaa_intf->vsp[idx].vsp_handle = NULL;
}
}
return E_OK;
}
+
diff --git a/drivers/net/dpaa/dpaa_flow.h b/drivers/net/dpaa/dpaa_flow.h
index 4742b8dd0a..6a949d6dd4 100644
--- a/drivers/net/dpaa/dpaa_flow.h
+++ b/drivers/net/dpaa/dpaa_flow.h
@@ -1,5 +1,5 @@
/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright 2017,2019,2022 NXP
+ * Copyright 2017,2019,2022,2026 NXP
*/
#ifndef __DPAA_FLOW_H__
@@ -11,9 +11,8 @@ int dpaa_fm_config(struct rte_eth_dev *dev, uint64_t req_dist_set);
int dpaa_fm_deconfig(struct dpaa_if *dpaa_intf, struct fman_if *fif);
void dpaa_write_fm_config_to_file(void);
int dpaa_port_vsp_update(struct dpaa_if *dpaa_intf,
- bool fmc_mode, uint8_t vsp_id, uint32_t bpid, struct fman_if *fif,
- u32 mbuf_data_room_size);
-int dpaa_port_vsp_cleanup(struct dpaa_if *dpaa_intf, struct fman_if *fif);
+ bool fmc_mode, uint8_t vsp_id, struct fman_if *fif);
+int dpaa_port_vsp_cleanup(struct dpaa_if *dpaa_intf);
int dpaa_port_fmc_init(struct fman_if *fif,
uint32_t *fqids, int8_t *vspids, int max_nb_rxq);
--
2.25.1
^ permalink raw reply related
* [PATCH v3 0/6] bpf: JIT related bug fixes
From: Stephen Hemminger @ 2026-06-21 16:23 UTC (permalink / raw)
To: dev; +Cc: Stephen Hemminger
In-Reply-To: <20260608203322.1116296-1-stephen@networkplumber.org>
While implementing JIT for packet capture ran into several issues:
1. x86 JIT had pre-existing bug which would crash
2. ARM64 BPF JIT was missing instructions for packet access.
Which had been discovered previously [1]
3. Tests related to JIT were not being run or missing coverage.
Fixed all of these. Patches are ordered so that most urgent fix
is first, follwed by the test that should have caught the problem.
The arm64 epilogue branch fix (patch 3) was originally posted by Christophe
Fontaine [1]; that series stalled, so it is carried here with his
authorship.
Changes since v1:
- add x86 BPF_JSET encoding fix and a regression test (patches 1-2),
found once the convert test ran generated code through the JIT
- carry Christophe's arm64 epilogue fix with his sign-off (patch 3)
- convert test now runs the converted filters through the JIT, not just
loads them (patch 6)
- kept Marat's ack (patch 4)
Since tests change enough, decided to drop his ack for that part.
[1] https://inbox.dpdk.org/dev/20260319114500.9757-2-cfontain@redhat.com/
v3 -- found a couple similar places where x86 JIT was generating
invalid op codes.
Christophe Fontaine (1):
bpf/arm64: fix offset type to allow a negative jump
Stephen Hemminger (5):
bpf/x86: fix JIT encoding of BPF_JSET with immediate
test/bpf: add JSET test with small immediate
test/bpf: check that JIT was generated
bpf/arm64: add BPF_ABS/BPF_IND packet load support
test/bpf: check that bpf_convert can be JIT'd
app/test/test_bpf.c | 184 ++++++++++++++++++++++++++++++++++++----
lib/bpf/bpf_jit_arm64.c | 153 ++++++++++++++++++++++++++++++++-
lib/bpf/bpf_jit_x86.c | 6 +-
3 files changed, 323 insertions(+), 20 deletions(-)
--
2.53.0
^ permalink raw reply
* [PATCH v3 1/6] bpf/x86: fix JIT encoding of BPF_JSET with immediate
From: Stephen Hemminger @ 2026-06-21 16:23 UTC (permalink / raw)
To: dev
Cc: Stephen Hemminger, stable, Konstantin Ananyev, Marat Khalili,
Ferruh Yigit
In-Reply-To: <20260621162524.82690-1-stephen@networkplumber.org>
Several place in x86 JIT code, it assumes that for small immediate
values the instruction size is one byte; but it is not.
The immddiate form of the instruction takes a 32 bit value.
The broken version of emit_tst_imm() emits TEST (0xF7 /0)
but sized the immediate with imm_size(), which can return 1 byte.
A small mask like BPF_JSET | BPF_K #0x1 then produced a
4-byte instruction the CPU decodes as 7,
swallowing the following Jcc and crashing.
Always emit a 32-bit immediate for TEST, ROR and SHIFT.
Bugzilla ID: 1959
Fixes: cc752e43e079 ("bpf: add JIT compilation for x86_64 ISA")
Cc: stable@dpdk.org
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
lib/bpf/bpf_jit_x86.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/lib/bpf/bpf_jit_x86.c b/lib/bpf/bpf_jit_x86.c
index 88b1b5aeab..b14a574703 100644
--- a/lib/bpf/bpf_jit_x86.c
+++ b/lib/bpf/bpf_jit_x86.c
@@ -300,7 +300,7 @@ emit_ror_imm(struct bpf_jit_state *st, uint32_t dreg, uint32_t imm)
emit_rex(st, BPF_ALU, 0, dreg);
emit_bytes(st, &ops, sizeof(ops));
emit_modregrm(st, MOD_DIRECT, mods, dreg);
- emit_imm(st, imm, imm_size(imm));
+ emit_imm(st, imm, sizeof(uint8_t));
}
/*
@@ -441,7 +441,7 @@ emit_shift_imm(struct bpf_jit_state *st, uint32_t op, uint32_t dreg,
uint32_t imm)
{
emit_shift(st, op, dreg);
- emit_imm(st, imm, imm_size(imm));
+ emit_imm(st, imm, sizeof(uint8_t));
}
/*
@@ -921,7 +921,7 @@ emit_tst_imm(struct bpf_jit_state *st, uint32_t op, uint32_t dreg, uint32_t imm)
emit_rex(st, op, 0, dreg);
emit_bytes(st, &ops, sizeof(ops));
emit_modregrm(st, MOD_DIRECT, mods, dreg);
- emit_imm(st, imm, imm_size(imm));
+ emit_imm(st, imm, sizeof(int32_t));
}
static void
--
2.53.0
^ permalink raw reply related
* [PATCH v3 2/6] test/bpf: add JSET test with small immediate
From: Stephen Hemminger @ 2026-06-21 16:23 UTC (permalink / raw)
To: dev; +Cc: Stephen Hemminger, Konstantin Ananyev, Marat Khalili
In-Reply-To: <20260621162524.82690-1-stephen@networkplumber.org>
The existing jump test only used a 32-bit JSET mask,
so the broken imm8 encoding of TEST in the x86 JIT was never exercised.
Add a case with a byte-sized mask;
run_test() runs it through the interpreter and the JIT.
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
app/test/test_bpf.c | 82 +++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 82 insertions(+)
diff --git a/app/test/test_bpf.c b/app/test/test_bpf.c
index dd24722450..e70dea736f 100644
--- a/app/test/test_bpf.c
+++ b/app/test/test_bpf.c
@@ -3158,7 +3158,89 @@ static const struct ebpf_insn test_ld_mbuf3_prog[] = {
};
/* all bpf test cases */
+/*
+ * JSET with a byte-sized mask: exercises the imm8 path of the TEST
+ * encoding in the x86 JIT (a 32-bit mask takes a different path).
+ */
+static const struct ebpf_insn test_jset1_prog[] = {
+ {
+ .code = (BPF_ALU | EBPF_MOV | BPF_K),
+ .dst_reg = EBPF_REG_0,
+ .imm = 0,
+ },
+ {
+ .code = (BPF_LDX | BPF_MEM | BPF_B),
+ .dst_reg = EBPF_REG_2,
+ .src_reg = EBPF_REG_1,
+ .off = offsetof(struct dummy_offset, u8),
+ },
+ /* bit 0 is set in the input: branch is taken */
+ {
+ .code = (BPF_JMP | BPF_JSET | BPF_K),
+ .dst_reg = EBPF_REG_2,
+ .imm = 0x1,
+ .off = 1,
+ },
+ {
+ .code = (BPF_JMP | BPF_JA),
+ .off = 1,
+ },
+ {
+ .code = (EBPF_ALU64 | BPF_OR | BPF_K),
+ .dst_reg = EBPF_REG_0,
+ .imm = 0x1,
+ },
+ /* bit 1 is clear in the input: branch is not taken */
+ {
+ .code = (BPF_JMP | BPF_JSET | BPF_K),
+ .dst_reg = EBPF_REG_2,
+ .imm = 0x2,
+ .off = 1,
+ },
+ {
+ .code = (BPF_JMP | BPF_JA),
+ .off = 1,
+ },
+ {
+ .code = (EBPF_ALU64 | BPF_OR | BPF_K),
+ .dst_reg = EBPF_REG_0,
+ .imm = 0x2,
+ },
+ {
+ .code = (BPF_JMP | EBPF_EXIT),
+ },
+};
+
+static void
+test_jset1_prepare(void *arg)
+{
+ struct dummy_offset *df = arg;
+
+ memset(df, 0, sizeof(*df));
+ df->u8 = 0x1; /* bit 0 set, bit 1 clear */
+}
+
+static int
+test_jset1_check(uint64_t rc, const void *arg)
+{
+ return cmp_res(__func__, 0x1, rc, arg, arg, 0);
+}
+
static const struct bpf_test tests[] = {
+ {
+ .name = "test_jset1",
+ .arg_sz = sizeof(struct dummy_offset),
+ .prm = {
+ .ins = test_jset1_prog,
+ .nb_ins = RTE_DIM(test_jset1_prog),
+ .prog_arg = {
+ .type = RTE_BPF_ARG_PTR,
+ .size = sizeof(struct dummy_offset),
+ },
+ },
+ .prepare = test_jset1_prepare,
+ .check_result = test_jset1_check,
+ },
{
.name = "test_store1",
.arg_sz = sizeof(struct dummy_offset),
--
2.53.0
^ permalink raw reply related
* [PATCH v3 3/6] bpf/arm64: fix offset type to allow a negative jump
From: Stephen Hemminger @ 2026-06-21 16:23 UTC (permalink / raw)
To: dev
Cc: Christophe Fontaine, stable, Stephen Hemminger,
Wathsala Vithanage, Konstantin Ananyev, Marat Khalili,
Jerin Jacob
In-Reply-To: <20260621162524.82690-1-stephen@networkplumber.org>
From: Christophe Fontaine <cfontain@redhat.com>
The DPDK BPF JIT standalone test test_ld_mbuf1 fails on arm64.
It does:
r6 = r1 // mbuf
r0 = *(u8 *)pkt[0] // BPF_ABS
if ((r0 & 0xf0) == 0x40)
goto parse
r0 = 0
exit // epilogue E0
parse:
r0 = *(u8 *)pkt[r0 + 3] // BPF_IND
...
exit
emit_return_zero_if_src_zero() returns 0 by branching to a function
epilogue. The target maybe a previous epilogue so branch
might be backwards; therefore the offset needs to be negative.
The offset was stored in a uint16_t, so a negative value wrapped to a
large positive number; emit_b() then branched past the end of the
program and faulted at run time.
Fixes: 111e2a747a4f ("bpf/arm: add basic arithmetic operations")
Cc: stable@dpdk.org
Signed-off-by: Christophe Fontaine <cfontain@redhat.com>
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
lib/bpf/bpf_jit_arm64.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/lib/bpf/bpf_jit_arm64.c b/lib/bpf/bpf_jit_arm64.c
index a04ef33a9c..67e42015de 100644
--- a/lib/bpf/bpf_jit_arm64.c
+++ b/lib/bpf/bpf_jit_arm64.c
@@ -957,10 +957,12 @@ static void
emit_return_zero_if_src_zero(struct a64_jit_ctx *ctx, bool is64, uint8_t src)
{
uint8_t r0 = ebpf_to_a64_reg(ctx, EBPF_REG_0);
- uint16_t jump_to_epilogue;
+ int32_t jump_to_epilogue;
emit_cbnz(ctx, is64, src, 3);
emit_mov_imm(ctx, is64, r0, 0);
+
+ /* maybe backwards branch to earlier epilogue */
jump_to_epilogue = (ctx->program_start + ctx->program_sz) - ctx->idx;
emit_b(ctx, jump_to_epilogue);
}
--
2.53.0
^ permalink raw reply related
* [PATCH v3 4/6] test/bpf: check that JIT was generated
From: Stephen Hemminger @ 2026-06-21 16:23 UTC (permalink / raw)
To: dev; +Cc: Stephen Hemminger, Marat Khalili, Konstantin Ananyev
In-Reply-To: <20260621162524.82690-1-stephen@networkplumber.org>
Avoid silently ignoring JIT failures. The test cases should
all succeed JIT compilation; if not it is a bug in the JIT
implementation and should be reported.
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
Acked-by: Marat Khalili <marat.khalili@huawei.com>
---
app/test/test_bpf.c | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/app/test/test_bpf.c b/app/test/test_bpf.c
index e70dea736f..3a88434c3c 100644
--- a/app/test/test_bpf.c
+++ b/app/test/test_bpf.c
@@ -3590,6 +3590,14 @@ run_test(const struct bpf_test *tst)
rv, strerror(rv));
}
}
+#if defined(RTE_ARCH_X86_64) || defined(RTE_ARCH_ARM64)
+ else {
+ /* a JIT backend exists for this arch, so it must compile */
+ printf("%s@%d: %s: no JIT code generated;\n",
+ __func__, __LINE__, tst->name);
+ ret = -1;
+ }
+#endif
rte_bpf_destroy(bpf);
return ret;
--
2.53.0
^ permalink raw reply related
* [PATCH v3 5/6] bpf/arm64: add BPF_ABS/BPF_IND packet load support
From: Stephen Hemminger @ 2026-06-21 16:23 UTC (permalink / raw)
To: dev
Cc: Stephen Hemminger, Wathsala Vithanage, Konstantin Ananyev,
Marat Khalili
In-Reply-To: <20260621162524.82690-1-stephen@networkplumber.org>
The arm64 JIT rejected BPF_LD | BPF_ABS and BPF_LD | BPF_IND with
"invalid opcode", so cBPF programs converted by rte_bpf_convert() could
not be JITed. Add these opcodes, mirroring the x86 JIT: a fast path for
data held in the first mbuf segment, and a __rte_pktmbuf_read() slow
path for everything else.
The forward branches over the call cannot use fixed distances:
emit_call() materializes the helper address with a variable number of
mov/movk instructions, so the block sizes are not known up front. Size
the three blocks (fast path, slow path, common tail) in a dry run, then
emit for real with the branches resolved from the measured offsets.
Programs using these opcodes use the call register layout, since the
slow path makes a function call.
Bugzilla ID: 1427
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
lib/bpf/bpf_jit_arm64.c | 149 +++++++++++++++++++++++++++++++++++++++-
1 file changed, 148 insertions(+), 1 deletion(-)
diff --git a/lib/bpf/bpf_jit_arm64.c b/lib/bpf/bpf_jit_arm64.c
index 67e42015de..3fc16fd984 100644
--- a/lib/bpf/bpf_jit_arm64.c
+++ b/lib/bpf/bpf_jit_arm64.c
@@ -1125,6 +1125,135 @@ emit_branch(struct a64_jit_ctx *ctx, uint8_t op, uint32_t i, int16_t off)
emit_b_cond(ctx, ebpf_to_a64_cond(op), jump_offset_get(ctx, i, off));
}
+/* LD_ABS/LD_IND code block offsets (in arm64 instructions) */
+enum {
+ LDMB_FAST_OFS, /* fast path */
+ LDMB_SLOW_OFS, /* slow path */
+ LDMB_FIN_OFS, /* common tail */
+ LDMB_OFS_NUM
+};
+
+/*
+ * Helper for emit_ld_mbuf(): fast path.
+ * Compute the packet offset; if it lies inside the first segment leave the
+ * data pointer in R0, otherwise branch to the slow path.
+ */
+static void
+emit_ldmb_fast_path(struct a64_jit_ctx *ctx, uint8_t src, uint8_t mode,
+ uint32_t sz, int32_t imm, const uint32_t ofs[LDMB_OFS_NUM])
+{
+ uint8_t r0 = ebpf_to_a64_reg(ctx, EBPF_REG_0);
+ uint8_t r6 = ebpf_to_a64_reg(ctx, EBPF_REG_6);
+ uint8_t tmp1 = ebpf_to_a64_reg(ctx, TMP_REG_1);
+ uint8_t tmp2 = ebpf_to_a64_reg(ctx, TMP_REG_2);
+ uint8_t tmp3 = ebpf_to_a64_reg(ctx, TMP_REG_3);
+
+ /* off = imm (+ src for BPF_IND) */
+ emit_mov_imm(ctx, 1, tmp1, imm);
+ if (mode == BPF_IND)
+ emit_add(ctx, 1, tmp1, src);
+
+ /* if ((int64_t)(mbuf->data_len - off) < sz) goto slow_path */
+ emit_mov_imm(ctx, 1, tmp2, offsetof(struct rte_mbuf, data_len));
+ emit_ldr(ctx, BPF_H, tmp2, r6, tmp2);
+ emit_sub(ctx, 1, tmp2, tmp1);
+ emit_mov_imm(ctx, 1, tmp3, sz);
+ emit_cmp(ctx, 1, tmp2, tmp3);
+ emit_b_cond(ctx, A64_LT, (int32_t)(ofs[LDMB_SLOW_OFS] - ctx->idx));
+
+ /* R0 = mbuf->buf_addr + mbuf->data_off + off */
+ emit_mov_imm(ctx, 1, tmp2, offsetof(struct rte_mbuf, data_off));
+ emit_ldr(ctx, BPF_H, tmp2, r6, tmp2);
+ emit_mov_imm(ctx, 1, r0, offsetof(struct rte_mbuf, buf_addr));
+ emit_ldr(ctx, EBPF_DW, r0, r6, r0);
+ emit_add(ctx, 1, r0, tmp2);
+ emit_add(ctx, 1, r0, tmp1);
+
+ emit_b(ctx, (int32_t)(ofs[LDMB_FIN_OFS] - ctx->idx));
+}
+
+/*
+ * Helper for emit_ld_mbuf(): slow path.
+ * R0 = __rte_pktmbuf_read(mbuf, off, sz, buf); return 0 if NULL.
+ * The scratch buffer is the space reserved by __rte_bpf_validate() at the
+ * bottom of the eBPF stack frame, i.e. (frame_pointer - stack_ofs).
+ */
+static void
+emit_ldmb_slow_path(struct a64_jit_ctx *ctx, uint32_t sz, uint32_t stack_ofs)
+{
+ uint8_t r0 = ebpf_to_a64_reg(ctx, EBPF_REG_0);
+ uint8_t r6 = ebpf_to_a64_reg(ctx, EBPF_REG_6);
+ uint8_t fp = ebpf_to_a64_reg(ctx, EBPF_FP);
+ uint8_t tmp1 = ebpf_to_a64_reg(ctx, TMP_REG_1);
+
+ /* arguments of __rte_pktmbuf_read(mbuf, off, len, buf) */
+ emit_mov_64(ctx, A64_R(1), tmp1); /* off (held in tmp1) */
+ emit_mov_64(ctx, A64_R(0), r6); /* mbuf */
+ emit_mov_imm(ctx, 0, A64_R(2), sz); /* len */
+ emit_sub_imm_64(ctx, A64_R(3), fp, stack_ofs); /* buf */
+
+ emit_call(ctx, tmp1, (void *)(uintptr_t)__rte_pktmbuf_read);
+ emit_return_zero_if_src_zero(ctx, 1, r0);
+}
+
+/*
+ * Helper for emit_ld_mbuf(): common tail.
+ * Load the value pointed to by R0 and convert from network byte order.
+ */
+static void
+emit_ldmb_fin(struct a64_jit_ctx *ctx, uint8_t opsz, uint32_t sz)
+{
+ uint8_t r0 = ebpf_to_a64_reg(ctx, EBPF_REG_0);
+
+ emit_ldr(ctx, opsz, r0, r0, A64_ZR);
+ if (opsz != BPF_B)
+ emit_be(ctx, r0, sz * 8);
+}
+
+/*
+ * emit code for BPF_ABS/BPF_IND load.
+ * generates the following construction:
+ * fast_path:
+ * off = src + imm
+ * if (mbuf->data_len - off < sz)
+ * goto slow_path;
+ * ptr = mbuf->buf_addr + mbuf->data_off + off;
+ * goto fin_part;
+ * slow_path:
+ * typeof(sz) buf; // scratch space reserved on the eBPF stack
+ * ptr = __rte_pktmbuf_read(mbuf, off, sz, &buf);
+ * if (ptr == NULL)
+ * return 0;
+ * fin_part:
+ * res = *(typeof(sz))ptr;
+ * res = ntoh(res);
+ */
+static void
+emit_ld_mbuf(struct a64_jit_ctx *ctx, uint8_t op, uint8_t src, int32_t imm,
+ uint32_t stack_ofs)
+{
+ uint8_t mode = BPF_MODE(op);
+ uint8_t opsz = BPF_SIZE(op);
+ uint32_t sz = bpf_size(opsz);
+ uint32_t ofs[LDMB_OFS_NUM];
+
+ /* seed offsets so the dry-run branches stay in range */
+ ofs[LDMB_FAST_OFS] = ofs[LDMB_SLOW_OFS] = ofs[LDMB_FIN_OFS] = ctx->idx;
+
+ /* dry run to record block offsets */
+ emit_ldmb_fast_path(ctx, src, mode, sz, imm, ofs);
+ ofs[LDMB_SLOW_OFS] = ctx->idx;
+ emit_ldmb_slow_path(ctx, sz, stack_ofs);
+ ofs[LDMB_FIN_OFS] = ctx->idx;
+ emit_ldmb_fin(ctx, opsz, sz);
+
+ /* rewind and emit for real with resolved offsets */
+ ctx->idx = ofs[LDMB_FAST_OFS];
+ emit_ldmb_fast_path(ctx, src, mode, sz, imm, ofs);
+ emit_ldmb_slow_path(ctx, sz, stack_ofs);
+ emit_ldmb_fin(ctx, opsz, sz);
+}
+
static void
check_program_has_call(struct a64_jit_ctx *ctx, struct rte_bpf *bpf)
{
@@ -1137,8 +1266,17 @@ check_program_has_call(struct a64_jit_ctx *ctx, struct rte_bpf *bpf)
op = ins->code;
switch (op) {
- /* Call imm */
+ /*
+ * BPF_ABS/BPF_IND can fall through to __rte_pktmbuf_read(),
+ * so they need the call-clobbered register layout as well.
+ */
case (BPF_JMP | EBPF_CALL):
+ case (BPF_LD | BPF_ABS | BPF_B):
+ case (BPF_LD | BPF_ABS | BPF_H):
+ case (BPF_LD | BPF_ABS | BPF_W):
+ case (BPF_LD | BPF_IND | BPF_B):
+ case (BPF_LD | BPF_IND | BPF_H):
+ case (BPF_LD | BPF_IND | BPF_W):
ctx->foundcall = 1;
return;
}
@@ -1340,6 +1478,15 @@ emit(struct a64_jit_ctx *ctx, struct rte_bpf *bpf)
emit_mov_imm(ctx, 1, dst, u64);
i++;
break;
+ /* R0 = ntoh(*(size *)(mbuf data + (src) + imm)) */
+ case (BPF_LD | BPF_ABS | BPF_B):
+ case (BPF_LD | BPF_ABS | BPF_H):
+ case (BPF_LD | BPF_ABS | BPF_W):
+ case (BPF_LD | BPF_IND | BPF_B):
+ case (BPF_LD | BPF_IND | BPF_H):
+ case (BPF_LD | BPF_IND | BPF_W):
+ emit_ld_mbuf(ctx, op, src, imm, bpf->stack_sz);
+ break;
/* *(size *)(dst + off) = src */
case (BPF_STX | BPF_MEM | BPF_B):
case (BPF_STX | BPF_MEM | BPF_H):
--
2.53.0
^ permalink raw reply related
* [PATCH v3 6/6] test/bpf: check that bpf_convert can be JIT'd
From: Stephen Hemminger @ 2026-06-21 16:23 UTC (permalink / raw)
To: dev; +Cc: Stephen Hemminger, Konstantin Ananyev, Marat Khalili
In-Reply-To: <20260621162524.82690-1-stephen@networkplumber.org>
Add followup in bpf conversion tests to make sure resulting
code was also run through JIT and that JIT produces
same results as non-JIT.
Reduce log output to make it easier to match which
expression might be causing issues.
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
app/test/test_bpf.c | 94 +++++++++++++++++++++++++++++++++++++--------
1 file changed, 79 insertions(+), 15 deletions(-)
diff --git a/app/test/test_bpf.c b/app/test/test_bpf.c
index 3a88434c3c..973dd7d659 100644
--- a/app/test/test_bpf.c
+++ b/app/test/test_bpf.c
@@ -8,6 +8,7 @@
#include <inttypes.h>
#include <unistd.h>
+#include <rte_byteorder.h>
#include <rte_memory.h>
#include <rte_debug.h>
#include <rte_hexdump.h>
@@ -32,6 +33,7 @@ test_bpf(void)
#include <rte_bpf.h>
#include <rte_ether.h>
#include <rte_ip.h>
+#include <rte_udp.h>
/* Tests of most simple BPF programs (no instructions, one instruction etc.) */
@@ -4529,6 +4531,7 @@ test_bpf_match(pcap_t *pcap, const char *str,
int ret = -1;
uint64_t rc;
+ printf("%s '%s'\n", __func__, str);
if (pcap_compile(pcap, &fcode, str, 1, PCAP_NETMASK_UNKNOWN)) {
printf("%s@%d: pcap_compile(\"%s\") failed: %s;\n",
__func__, __LINE__, str, pcap_geterr(pcap));
@@ -4550,6 +4553,24 @@ test_bpf_match(pcap_t *pcap, const char *str,
}
rc = rte_bpf_exec(bpf, mb);
+#if defined(RTE_ARCH_X86_64) || defined(RTE_ARCH_ARM64)
+ {
+ struct rte_bpf_jit jit;
+
+ rte_bpf_get_jit(bpf, &jit);
+ if (jit.func == NULL) {
+ printf("%s@%d: no JIT generated\n", __func__, __LINE__);
+ goto error;
+ }
+
+ fflush(stdout);
+ uint64_t rc_jit = jit.func(mb);
+ if (rc_jit != rc) {
+ printf("%s@%d: JIT return code does not match\n", __func__, __LINE__);
+ goto error;
+ }
+ }
+#endif
/* The return code from bpf capture filter is non-zero if matched */
ret = (rc == 0);
error:
@@ -4560,23 +4581,16 @@ test_bpf_match(pcap_t *pcap, const char *str,
return ret;
}
-/* Basic sanity test can we match a IP packet */
-static int
-test_bpf_filter_sanity(pcap_t *pcap)
+/* Setup mbuf for filter test */
+static void
+dummy_ip_prep(void *data, uint16_t plen)
{
- const uint32_t plen = 100;
- struct rte_mbuf mb, *m;
- uint8_t tbuf[RTE_MBUF_DEFAULT_BUF_SIZE];
struct {
struct rte_ether_hdr eth_hdr;
struct rte_ipv4_hdr ip_hdr;
- } *hdr;
+ struct rte_udp_hdr udp_hdr;
+ } *hdr = data;
- memset(&mb, 0, sizeof(mb));
- dummy_mbuf_prep(&mb, tbuf, sizeof(tbuf), plen);
- m = &mb;
-
- hdr = rte_pktmbuf_mtod(m, typeof(hdr));
hdr->eth_hdr = (struct rte_ether_hdr) {
.dst_addr.addr_bytes = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff },
.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4),
@@ -4589,13 +4603,32 @@ test_bpf_filter_sanity(pcap_t *pcap)
.src_addr = rte_cpu_to_be_32(RTE_IPV4_LOOPBACK),
.dst_addr = rte_cpu_to_be_32(RTE_IPV4_BROADCAST),
};
+ hdr->udp_hdr = (struct rte_udp_hdr) {
+ .src_port = rte_rand_max(UINT16_MAX),
+ .dst_port = rte_cpu_to_be_16(9), /* discard port */
+ .dgram_len = rte_cpu_to_be_16(plen - sizeof(struct rte_ipv4_hdr)),
+ .dgram_cksum = 0,
+ };
+}
+
+
+/* Basic sanity test can we match a IP packet */
+static int
+test_bpf_filter_sanity(pcap_t *pcap)
+{
+ struct rte_mbuf mb = { 0 };
+ uint8_t tbuf[RTE_MBUF_DEFAULT_BUF_SIZE];
+ const uint32_t plen = 100;
+
+ dummy_mbuf_prep(&mb, tbuf, sizeof(tbuf), plen);
+ dummy_ip_prep(rte_pktmbuf_mtod(&mb, void *), plen);
- if (test_bpf_match(pcap, "ip", m) != 0) {
+ if (test_bpf_match(pcap, "ip", &mb) != 0) {
printf("%s@%d: filter \"ip\" doesn't match test data\n",
__func__, __LINE__);
return -1;
}
- if (test_bpf_match(pcap, "not ip", m) == 0) {
+ if (test_bpf_match(pcap, "not ip", &mb) == 0) {
printf("%s@%d: filter \"not ip\" does match test data\n",
__func__, __LINE__);
return -1;
@@ -4648,10 +4681,15 @@ static const char * const sample_filters[] = {
static int
test_bpf_filter(pcap_t *pcap, const char *s)
{
+ struct rte_mbuf mb = { 0 };
+ uint8_t tbuf[RTE_MBUF_DEFAULT_BUF_SIZE];
+ const uint32_t plen = 100;
struct bpf_program fcode;
struct rte_bpf_prm *prm = NULL;
struct rte_bpf *bpf = NULL;
+ int ret = -1;
+ printf("%s '%s'\n", __func__, s);
if (pcap_compile(pcap, &fcode, s, 1, PCAP_NETMASK_UNKNOWN)) {
printf("%s@%d: pcap_compile('%s') failed: %s;\n",
__func__, __LINE__, s, pcap_geterr(pcap));
@@ -4665,8 +4703,10 @@ test_bpf_filter(pcap_t *pcap, const char *s)
goto error;
}
+#ifdef DEBUG
printf("bpf convert for \"%s\" produced:\n", s);
rte_bpf_dump(stdout, prm->ins, prm->nb_ins);
+#endif
bpf = rte_bpf_load(prm);
if (bpf == NULL) {
@@ -4675,6 +4715,30 @@ test_bpf_filter(pcap_t *pcap, const char *s)
goto error;
}
+ dummy_mbuf_prep(&mb, tbuf, sizeof(tbuf), plen);
+ dummy_ip_prep(rte_pktmbuf_mtod(&mb, void *), plen);
+
+ uint64_t rc = rte_bpf_exec(bpf, &mb);
+#if defined(RTE_ARCH_X86_64) || defined(RTE_ARCH_ARM64)
+ {
+ struct rte_bpf_jit jit;
+
+ rte_bpf_get_jit(bpf, &jit);
+ if (jit.func == NULL) {
+ printf("%s@%d: no JIT generated\n", __func__, __LINE__);
+ goto error;
+ }
+
+ fflush(stdout);
+ uint64_t rc_jit = jit.func(&mb);
+ if (rc_jit != rc) {
+ printf("%s@%d: JIT return code does not match\n", __func__, __LINE__);
+ goto error;
+ }
+ }
+#endif
+ ret = 0;
+
error:
if (bpf)
rte_bpf_destroy(bpf);
@@ -4685,7 +4749,7 @@ test_bpf_filter(pcap_t *pcap, const char *s)
rte_free(prm);
pcap_freecode(&fcode);
- return (bpf == NULL) ? -1 : 0;
+ return ret;
}
static int
--
2.53.0
^ permalink raw reply related
* Re: [PATCH v3 00/19] dpaa: bus, net, dma and mempool improvements
From: Stephen Hemminger @ 2026-06-21 16:42 UTC (permalink / raw)
To: Hemant Agrawal; +Cc: david.marchand, dev
In-Reply-To: <20260621152228.2777171-1-hemant.agrawal@nxp.com>
On Sun, 21 Jun 2026 20:52:09 +0530
Hemant Agrawal <hemant.agrawal@nxp.com> wrote:
> This series collects correctness fixes, cleanups and feature additions
> across the NXP DPAA bus, net, mempool and DMA drivers.
>
> 1. Bus/fman infrastructure cleanups (patches 01, 02, 13)
> - Refine fman symbol naming and fix unintended global scope.
> - Scan the maximum BPID count from the device tree rather than
> using a compile-time constant.
> - Improve the DPAA bus log macro and fix bus-detection logic.
>
> 2. BMI Tx statistics (patch 03)
> - Extend fman_hw to read Tx BMI registers and expose the counters
> through the xstats interface.
>
> 3. Process-type guards (patch 04)
> - Add secondary-process checks in the net, DMA and crypto drivers
> to prevent segfaults when operations valid only in the primary
> process are called from a secondary.
>
> 4. FQ shutdown hardening (patches 05-11)
> - Introduce helpers for qman channel and work-queue lookup so that
> FQ teardown is driven by the FQ descriptor instead of ad-hoc
> parameters.
> - Add channel validation and CGR cleanup to the shutdown path.
> - Clean up the Tx-confirmation FQ on device stop and remove a
> redundant shutdown call from Rx queue setup.
>
> 5. net/dpaa improvements (patches 12, 14, 15)
> - Optimise FM de-configuration to avoid redundant portal drains.
> - Streamline FMC MAC-type parsing.
> - Report an error when deferred-start mode is requested (not
> supported by the driver).
>
> 6. mempool/dpaa (patches 16-17)
> - Optimise multi-entry buffer-pool acquire/release operations.
> - Release the BPID in the driver destructor to avoid resource leaks
> across repeated bind/unbind cycles.
>
> 7. dma/dpaa (patch 18)
> - Add SG-list data validation and a workaround for erratum
> ERR050757.
>
> 8. net/dpaa ONIC support (patch 19)
> - Add port-type checks for ONIC (Open Network Interface Card)
> shared-Ethernet ports.
>
> Changes in v3:
> - Fix out-of-bounds rte_memcpy in bman_release_fast (squashed into
> patch 16): when num == 1 the source pointer bm_bufs[1] is one past
> the array end; guard the copy with "if (num > 1)".
>
> Gagandeep Singh (2):
> bus/dpaa: enhance DPAA FQ shutdown
> dma/dpaa: add SG data validation and ERR050757 fix
>
> Hemant Agrawal (5):
> net/dpaa: clean Tx confirmation FQ on device stop
> net/dpaa: remove redundant FQ shutdown from Rx queue setup
> net/dpaa: optimize FM deconfig
> bus/dpaa: improve log macro and fix bus detection
> net/dpaa: report error on using deferred start
>
> Jun Yang (10):
> bus/dpaa: refine fman naming and fix global scope
> bus/dpaa: scan max BPID from DTS
> drivers: add BMI Tx statistics
> bus/dpaa: define helpers for qman channel and wq
> drivers: shutdown DPAA FQ by fq descriptor
> bus/dpaa: improve FQ shutdown with channel validation
> drivers: add DPAA cgrid cleanup support
> net/dpaa: optimize FMC MAC type parsing
> drivers: optimize DPAA multi-entry buffer pool operations
> drivers: release DPAA bpid on driver destructor
>
> Prashant Gupta (1):
> drivers: add process-type guards for secondary process
>
> Vanshika Shukla (1):
> net/dpaa: add ONIC port checks
>
> drivers/bus/dpaa/base/fman/fman.c | 23 ++--
> drivers/bus/dpaa/base/fman/fman_hw.c | 108 ++++++++---------
> drivers/bus/dpaa/base/qbman/bman.c | 59 ++++------
> drivers/bus/dpaa/base/qbman/bman_driver.c | 48 +++++---
> drivers/bus/dpaa/base/qbman/qman.c | 115 ++++++++++--------
> drivers/bus/dpaa/base/qbman/qman.h | 23 +++-
> drivers/bus/dpaa/base/qbman/qman_driver.c | 29 ++++-
> drivers/bus/dpaa/dpaa_bus.c | 35 ++++--
> drivers/bus/dpaa/dpaa_bus_base_symbols.c | 4 +
> drivers/bus/dpaa/include/fman.h | 30 ++++-
> drivers/bus/dpaa/include/fsl_bman.h | 49 ++++++--
> drivers/bus/dpaa/include/fsl_qman.h | 22 +++-
> drivers/crypto/dpaa_sec/dpaa_sec.c | 3 -
> drivers/dma/dpaa/dpaa_qdma.c | 103 ++++++++++++----
> drivers/mempool/dpaa/dpaa_mempool.c | 75 ++++++++++--
> drivers/mempool/dpaa/dpaa_mempool.h | 3 +-
> drivers/net/dpaa/dpaa_ethdev.c | 132 ++++++++++++++++-----
> drivers/net/dpaa/dpaa_ethdev.h | 22 +++-
> drivers/net/dpaa/dpaa_flow.c | 137 +++++++++++++---------
> drivers/net/dpaa/dpaa_flow.h | 7 +-
> drivers/net/dpaa/dpaa_fmc.c | 73 +++++++-----
> 21 files changed, 748 insertions(+), 352 deletions(-)
>
Clang build fails:
ccache clang -Idrivers/libtmp_rte_net_dpaa.a.p -Idrivers -I../drivers -Idrivers/net/dpaa -I../drivers/net/dpaa -Ilib/ethdev -I../lib/ethdev -Ilib/eal/common -I../lib/eal/common -I. -I.. -Iconfig -I../config -Ilib/eal/include -I../lib/eal/include -Ilib/eal/linux/include -I../lib/eal/linux/include -Ilib/eal/x86/include -I../lib/eal/x86/include -I../kernel/linux -Ilib/eal -I../lib/eal -Ilib/kvargs -I../lib/kvargs -Ilib/log -I../lib/log -Ilib/metrics -I../lib/metrics -Ilib/telemetry -I../lib/telemetry -Ilib/argparse -I../lib/argparse -Ilib/net -I../lib/net -Ilib/mbuf -I../lib/mbuf -Ilib/mempool -I../lib/mempool -Ilib/ring -I../lib/ring -Ilib/meter -I../lib/meter -Idrivers/bus/pci -I../drivers/bus/pci -I../drivers/bus/pci/linux -Ilib/pci -I../lib/pci -Idrivers/bus/vdev -I../drivers/bus/vdev -Idrivers/mempool/dpaa -I../drivers/mempool/dpaa -Idrivers/bus/dpaa -I../drivers/bus/dpaa -I../drivers/bus/dpaa/base -I../drivers/bus/dpaa/include -I../drivers/bus/dpaa/base/qbman -Idrivers/common/dpaax -I../drivers/common/dpaax -I../drivers/common/dpaax/caamflib -Ilib/eventdev -I../lib/eventdev -Ilib/hash -I../lib/hash -Ilib/rcu -I../lib/rcu -Ilib/timer -I../lib/timer -Ilib/cryptodev -I../lib/cryptodev -Ilib/dmadev -I../lib/dmadev -Xclang -fcolor-diagnostics -pipe -D_FILE_OFFSET_BITS=64 -Wall -Winvalid-pch -Wextra -Werror -std=c11 -O2 -g -include rte_config.h -Wvla -Wcast-qual -Wcomma -Wdeprecated -Wformat -Wformat-nonliteral -Wformat-security -Wmissing-declarations -Wmissing-prototypes -Wnested-externs -Wold-style-definition -Wpointer-arith -Wshadow -Wsign-compare -Wstrict-prototypes -Wundef -Wwrite-strings -Wno-missing-field-initializers -D_GNU_SOURCE -fPIC -march=corei7 -mrtm -DALLOW_EXPERIMENTAL_API -DALLOW_INTERNAL_API -Wno-format-truncation -Wno-address-of-packed-member -Wno-vla -Wno-shadow -Wno-pointer-arith -DRTE_COMPONENT_CLASS=pmd_net -DRTE_COMPONENT_NAME=dpaa -DRTE_LOG_DEFAULT_LOGTYPE=pmd.net.dpaa -DRTE_ANNOTATE_LOCKS -Wthread-safety -MD -MQ drivers/libtmp_rte_net_dpaa.a.p/net_dpaa_dpaa_flow.c.o -MF drivers/libtmp_rte_net_dpaa.a.p/net_dpaa_dpaa_flow.c.o.d -o drivers/libtmp_rte_net_dpaa.a.p/net_dpaa_dpaa_flow.c.o -c ../drivers/net/dpaa/dpaa_flow.c
../drivers/net/dpaa/dpaa_flow.c:673:19: error: unused function 'get_tx_port_type' [-Werror,-Wunused-function]
673 | static inline int get_tx_port_type(struct fman_if *fif)
| ^~~~~~~~~~~~~~~~
Also did more detailed AI review:
Reviewed the v3 DPAA series (19 patches) against current main; applied
cleanly with git am and traced the affected paths. Issues by patch:
Patch 12 + 19: net/dpaa FM deconfig
Error: dpaa_eth_dev_close() can call dpaa_fm_deconfig() on a NULL
port_handle. Patch 12 added a second deconfig call (guarded only by
!(default_q || fmc_q)) plus an unconditional one at the end, and made
dpaa_fm_deconfig() idempotent with an early "if (!port_handle) return
0". Patch 19 removes that early return and only re-guards the
dpaa_fm_config() caller. Final close path:
if (!(default_q||fmc_q)) if (port_handle) deconfig /* nulls handle */
...
if (!(default_q||fmc_q)) deconfig /* handle NULL */
deconfig /* unconditional */
First call closes the port and sets port_handle = NULL; the next calls
hit fm_port_disable(NULL) (and delete_pcd/scheme/netenv on stale
handles). In default_q/fmc_q mode the last call also runs with a
possibly-NULL handle. Restore the !port_handle guard in
dpaa_fm_deconfig(), or guard every call site and drop the duplicates;
there is no reason to deconfig three times. dpaa_port_vsp_cleanup() is
fine, it is idempotent.
Patch 13: bus/dpaa improve log macro and fix bus detection
Error: dpaa_bus_dev_compare() no longer returns a comparison result.
It is installed as bus->dev_compare and rte_bus_find_devargs() uses it
as "cmp(name, devargs_name) != 0 -> continue". The new body returns 0
on any DPAA platform (and short-circuits to 0 once dpaa_bus.detected is
set), so every device name compares "equal" to the first devargs in the
list, and per-device devargs get misapplied. A comparator must return
the name comparison (old strncmp(devname1, devname2, ...)). Bus
detection and pthread_key_create() side effects do not belong in a
compare callback.
Patch 03: drivers add BMI Tx statistics
Warning: the Tx BMI counters are added to dpaa_xstats_strings but
nothing reads them. fman_if_bmi_stats_get_all() and
fman_if_bmi_stats_reset() still only touch the Rx registers via
rx_bmi_map, and FMAN_IF_BMI_TX_STAT_OFFSET_START/END are defined but
unused. In dpaa_dev_xstats_get()/dpaa_xstats_get_by_id() the
regular-vs-BMI split is computed from sizeof(struct
dpaa_if_rx_bmi_stats) only, so adding 4 Tx entries shifts the boundary
and the Tx counters report stale/Rx data. Either wire get_all/reset to
read the tx_bmi_map range and fix the bmi_count split, or drop the Tx
entries from this patch.
Patch 04: drivers add process-type guards for secondary process
Error: dpaa_qdma_init() adds "char *penv;" but does not use it here;
penv is only consumed in patch 18. This commit fails to build
standalone with -Werror (-Wunused-variable), breaking bisect. Move the
declaration to patch 18.
Info: the subject says "add process-type guards" but the dpaa_sec hunk
removes the RTE_PROC_PRIMARY early-return in cryptodev_dpaa_sec_probe().
That is actually correct (secondary still attaches the cryptodev, and
dpaa_sec_dev_init() has its own primary-only guard), but the commit
message should say so.
Patch 18: dma/dpaa add SG data validation and ERR050757 fix
Warning: five new getenv() tunables (DPAA_QDMA_DATA_VALIDATION,
DPAA_QDMA_HW_ERR_CHECK, DPAA_QDMA_SG_ENABLE, DPAA_QDMA_SG_MAX_ENTRY_SIZE,
DPAA_QDMA_PCI_READ). The driver already uses devargs
(DPAA_DMA_ERROR_CHECK); these should be devargs too. checkpatch will
also flag the getenv additions.
Info: s_hw_err_check changes from bool to int; keep bool for a
true/false flag.
Patch 08: bus/dpaa enhance DPAA FQ shutdown
Info: qman_find_fq_by_cgrid() ends with "do {...} while (1);" followed
by an unreachable "return -ENODEV;" - drop the dead return. The linear
FQID probe from 1 with a hardware query per iteration relies on
qman_query_fq_np() returning -ERANGE to terminate; worth a comment.
This patch also leaves a new blank line at EOF (checkpatch).
Patch 17: drivers release DPAA bpid on driver destructor
Info: "#define RTE_PRIORITY_104 104" is unused; RTE_FINI_PRIO is called
with the literal 104. Use the macro or drop it.
^ permalink raw reply
* [PATCH v4 00/19] dpaa: driver stability and feature improvements
From: Hemant Agrawal @ 2026-06-21 17:27 UTC (permalink / raw)
To: stephen, david.marchand, dev
In-Reply-To: <20260621152228.2777171-1-hemant.agrawal@nxp.com>
This series collects a set of correctness fixes, cleanups and feature
additions across the NXP DPAA bus, net, mempool and DMA drivers.
1. Bus/fman infrastructure cleanups (patches 01, 02, 13)
- bus/dpaa: refine fman naming and fix global scope
- bus/dpaa: scan max BPID from DTS
- bus/dpaa: improve log macro and fix bus detection
2. Statistics (patch 03)
- net/dpaa: add BMI Tx statistics
3. Process-type guards (patch 04)
- dpaa: add process-type guards to prevent segfaults in secondary
4. FQ shutdown hardening (patches 05-11)
- bus/dpaa: define helpers for qman channel and wq
- drivers: shutdown DPAA FQ by fq descriptor
- bus/dpaa: improve FQ shutdown with channel validation
- bus/dpaa: enhance DPAA FQ shutdown
- drivers: add DPAA cgrid cleanup support
- net/dpaa: clean Tx confirmation FQ on device stop
- net/dpaa: remove redundant FQ shutdown from Rx queue setup
5. net/dpaa improvements (patches 12, 14, 15)
- net/dpaa: optimize FM deconfig
- net/dpaa: optimize FMC MAC type parsing
- net/dpaa: report error on using deferred start
6. mempool/dpaa (patches 16-17)
- drivers: optimize DPAA multi-entry buffer pool operations
- drivers: release DPAA bpid on driver destructor
7. dma/dpaa (patch 18)
- dma/dpaa: add SG data validation and ERR050757 fix
8. net/dpaa ONIC port support (patch 19)
- net/dpaa: add ONIC port checks
v4 changes:
- Fix dpaa_bus_dev_compare() to return the strncmp result (previously
always returned 0, breaking device matching).
- Remove the dead get_tx_port_type() function that triggered a clang
-Wunused-function CI failure.
- Guard all dpaa_fm_deconfig() call sites against NULL port_handle to
prevent a NULL dereference on partially initialised interfaces.
- Move the penv variable declaration in dpaa_qdma_init() to the point of
use (C99 inline), fixing a spurious -Wunused-variable warning during
bisect of earlier patches in the series.
Gagandeep Singh (2):
bus/dpaa: enhance DPAA FQ shutdown
dma/dpaa: add SG data validation and ERR050757 fix
Hemant Agrawal (5):
net/dpaa: clean Tx confirmation FQ on device stop
net/dpaa: remove redundant FQ shutdown from Rx queue setup
net/dpaa: optimize FM deconfig
bus/dpaa: improve log macro and fix bus detection
net/dpaa: report error on using deferred start
Jun Yang (10):
bus/dpaa: refine fman naming and fix global scope
bus/dpaa: scan max BPID from DTS
drivers: add BMI Tx statistics
bus/dpaa: define helpers for qman channel and wq
drivers: shutdown DPAA FQ by fq descriptor
bus/dpaa: improve FQ shutdown with channel validation
drivers: add DPAA cgrid cleanup support
net/dpaa: optimize FMC MAC type parsing
drivers: optimize DPAA multi-entry buffer pool operations
drivers: release DPAA bpid on driver destructor
Prashant Gupta (1):
drivers: add process-type guards for secondary process
Vanshika Shukla (1):
net/dpaa: add ONIC port checks
drivers/bus/dpaa/base/fman/fman.c | 23 ++--
drivers/bus/dpaa/base/fman/fman_hw.c | 108 +++++++++----------
drivers/bus/dpaa/base/qbman/bman.c | 59 ++++-------
drivers/bus/dpaa/base/qbman/bman_driver.c | 48 ++++++---
drivers/bus/dpaa/base/qbman/qman.c | 115 +++++++++++---------
drivers/bus/dpaa/base/qbman/qman.h | 23 +++-
drivers/bus/dpaa/base/qbman/qman_driver.c | 29 ++++-
drivers/bus/dpaa/dpaa_bus.c | 33 ++++--
drivers/bus/dpaa/dpaa_bus_base_symbols.c | 4 +
drivers/bus/dpaa/include/fman.h | 30 +++++-
drivers/bus/dpaa/include/fsl_bman.h | 49 +++++++--
drivers/bus/dpaa/include/fsl_qman.h | 22 +++-
drivers/crypto/dpaa_sec/dpaa_sec.c | 3 -
drivers/dma/dpaa/dpaa_qdma.c | 102 +++++++++++++-----
drivers/mempool/dpaa/dpaa_mempool.c | 75 +++++++++++--
drivers/mempool/dpaa/dpaa_mempool.h | 3 +-
drivers/net/dpaa/dpaa_ethdev.c | 122 ++++++++++++++++++----
drivers/net/dpaa/dpaa_ethdev.h | 22 +++-
drivers/net/dpaa/dpaa_flow.c | 120 +++++++++++----------
drivers/net/dpaa/dpaa_flow.h | 7 +-
drivers/net/dpaa/dpaa_fmc.c | 73 ++++++++-----
21 files changed, 725 insertions(+), 345 deletions(-)
--
2.25.1
^ permalink raw reply
* [PATCH v4 01/19] bus/dpaa: refine fman naming and fix global scope
From: Hemant Agrawal @ 2026-06-21 17:27 UTC (permalink / raw)
To: stephen, david.marchand, dev; +Cc: Jun Yang
In-Reply-To: <20260621172731.2916346-1-hemant.agrawal@nxp.com>
From: Jun Yang <jun.yang@nxp.com>
Rename ccsr_map to memac_map in __fman_if struct for clarity,
as it maps the MEMAC register space not generic CCSR.
Rename bmi_map to rx_bmi_map to distinguish from TX BMI.
Make fman_ccsr_map_fd static as it is only used within fman.c.
Signed-off-by: Jun Yang <jun.yang@nxp.com>
---
drivers/bus/dpaa/base/fman/fman.c | 14 ++--
drivers/bus/dpaa/base/fman/fman_hw.c | 106 ++++++++++++++-------------
drivers/bus/dpaa/include/fman.h | 6 +-
3 files changed, 63 insertions(+), 63 deletions(-)
diff --git a/drivers/bus/dpaa/base/fman/fman.c b/drivers/bus/dpaa/base/fman/fman.c
index 55311235f5..55f466d751 100644
--- a/drivers/bus/dpaa/base/fman/fman.c
+++ b/drivers/bus/dpaa/base/fman/fman.c
@@ -1,7 +1,7 @@
/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
*
* Copyright 2010-2016 Freescale Semiconductor Inc.
- * Copyright 2017-2024 NXP
+ * Copyright 2017-2026 NXP
*
*/
@@ -465,9 +465,9 @@ fman_if_init(const struct device_node *dpa_node, int fd)
mname, regs_addr);
goto err;
}
- __if->ccsr_map = mmap(NULL, __if->regs_size,
+ __if->memac_map = mmap(NULL, __if->regs_size,
PROT_READ | PROT_WRITE, MAP_SHARED, fd, phys_addr);
- if (__if->ccsr_map == MAP_FAILED) {
+ if (__if->memac_map == MAP_FAILED) {
FMAN_ERR(-errno, "mmap(0x%"PRIx64")", phys_addr);
goto err;
}
@@ -599,9 +599,9 @@ fman_if_init(const struct device_node *dpa_node, int fd)
goto err;
}
- __if->bmi_map = mmap(NULL, __if->regs_size,
+ __if->rx_bmi_map = mmap(NULL, __if->regs_size,
PROT_READ | PROT_WRITE, MAP_SHARED, fd, phys_addr);
- if (__if->bmi_map == MAP_FAILED) {
+ if (__if->rx_bmi_map == MAP_FAILED) {
FMAN_ERR(-errno, "mmap(0x%"PRIx64")", phys_addr);
goto err;
}
@@ -1167,13 +1167,13 @@ fman_finish(void)
}
/* disable Rx and Tx */
- regs = __if->ccsr_map;
+ regs = __if->memac_map;
cfg = in_be32(®s->command_config);
out_be32(®s->command_config,
cfg & (~(MEMAC_RX_ENABLE | MEMAC_TX_ENABLE)));
/* release the mapping */
- _errno = munmap(__if->ccsr_map, __if->regs_size);
+ _errno = munmap(__if->memac_map, __if->regs_size);
if (unlikely(_errno < 0))
FMAN_ERR(_errno, "munmap() = (%s)", strerror(errno));
DPAA_BUS_INFO("Tearing down %s", __if->node_path);
diff --git a/drivers/bus/dpaa/base/fman/fman_hw.c b/drivers/bus/dpaa/base/fman/fman_hw.c
index cbb0491d70..ce68581555 100644
--- a/drivers/bus/dpaa/base/fman/fman_hw.c
+++ b/drivers/bus/dpaa/base/fman/fman_hw.c
@@ -1,6 +1,6 @@
/* SPDX-License-Identifier: BSD-3-Clause
*
- * Copyright 2017,2020,2022-2023 NXP
+ * Copyright 2017,2020,2022-2023,2026 NXP
*
*/
@@ -16,6 +16,8 @@
#include <fsl_fman_crc64.h>
#include <fsl_bman.h>
+extern int fman_ccsr_map_fd;
+
#define FMAN_SP_SG_DISABLE 0x80000000
#define FMAN_SP_EXT_BUF_MARG_START_SHIFT 16
@@ -39,7 +41,7 @@ fman_if_set_mcast_filter_table(struct fman_if *p)
void *hashtable_ctrl;
uint32_t i;
- hashtable_ctrl = &((struct memac_regs *)__if->ccsr_map)->hashtable_ctrl;
+ hashtable_ctrl = &((struct memac_regs *)__if->memac_map)->hashtable_ctrl;
for (i = 0; i < 64; i++)
out_be32(hashtable_ctrl, i|HASH_CTRL_MCAST_EN);
}
@@ -51,7 +53,7 @@ fman_if_reset_mcast_filter_table(struct fman_if *p)
void *hashtable_ctrl;
uint32_t i;
- hashtable_ctrl = &((struct memac_regs *)__if->ccsr_map)->hashtable_ctrl;
+ hashtable_ctrl = &((struct memac_regs *)__if->memac_map)->hashtable_ctrl;
for (i = 0; i < 64; i++)
out_be32(hashtable_ctrl, i & ~HASH_CTRL_MCAST_EN);
}
@@ -101,7 +103,7 @@ fman_if_add_hash_mac_addr(struct fman_if *p, uint8_t *eth)
hash = get_mac_hash_code(eth_addr) & HASH_CTRL_ADDR_MASK;
hash = hash | HASH_CTRL_MCAST_EN;
- hashtable_ctrl = &((struct memac_regs *)__if->ccsr_map)->hashtable_ctrl;
+ hashtable_ctrl = &((struct memac_regs *)__if->memac_map)->hashtable_ctrl;
out_be32(hashtable_ctrl, hash);
return 0;
@@ -112,7 +114,7 @@ fman_if_get_primary_mac_addr(struct fman_if *p, uint8_t *eth)
{
struct __fman_if *__if = container_of(p, struct __fman_if, __if);
void *mac_reg =
- &((struct memac_regs *)__if->ccsr_map)->mac_addr0.mac_addr_l;
+ &((struct memac_regs *)__if->memac_map)->mac_addr0.mac_addr_l;
u32 val = in_be32(mac_reg);
int i;
@@ -130,7 +132,7 @@ fman_if_get_primary_mac_addr(struct fman_if *p, uint8_t *eth)
eth[2] = (val & 0x00ff0000) >> 16;
eth[3] = (val & 0xff000000) >> 24;
- mac_reg = &((struct memac_regs *)__if->ccsr_map)->mac_addr0.mac_addr_u;
+ mac_reg = &((struct memac_regs *)__if->memac_map)->mac_addr0.mac_addr_u;
val = in_be32(mac_reg);
eth[4] = (val & 0x000000ff) >> 0;
@@ -151,16 +153,16 @@ fman_if_clear_mac_addr(struct fman_if *p, uint8_t addr_num)
return;
if (addr_num) {
- reg = &((struct memac_regs *)m->ccsr_map)->
+ reg = &((struct memac_regs *)m->memac_map)->
mac_addr[addr_num-1].mac_addr_l;
out_be32(reg, 0x0);
- reg = &((struct memac_regs *)m->ccsr_map)->
+ reg = &((struct memac_regs *)m->memac_map)->
mac_addr[addr_num-1].mac_addr_u;
out_be32(reg, 0x0);
} else {
- reg = &((struct memac_regs *)m->ccsr_map)->mac_addr0.mac_addr_l;
+ reg = &((struct memac_regs *)m->memac_map)->mac_addr0.mac_addr_l;
out_be32(reg, 0x0);
- reg = &((struct memac_regs *)m->ccsr_map)->mac_addr0.mac_addr_u;
+ reg = &((struct memac_regs *)m->memac_map)->mac_addr0.mac_addr_u;
out_be32(reg, 0x0);
}
}
@@ -180,10 +182,10 @@ fman_if_add_mac_addr(struct fman_if *p, uint8_t *eth, uint8_t addr_num)
memcpy(&m->__if.mac_addr, eth, ETHER_ADDR_LEN);
if (addr_num)
- reg = &((struct memac_regs *)m->ccsr_map)->
+ reg = &((struct memac_regs *)m->memac_map)->
mac_addr[addr_num-1].mac_addr_l;
else
- reg = &((struct memac_regs *)m->ccsr_map)->mac_addr0.mac_addr_l;
+ reg = &((struct memac_regs *)m->memac_map)->mac_addr0.mac_addr_l;
val = (m->__if.mac_addr.addr_bytes[0] |
(m->__if.mac_addr.addr_bytes[1] << 8) |
@@ -192,10 +194,10 @@ fman_if_add_mac_addr(struct fman_if *p, uint8_t *eth, uint8_t addr_num)
out_be32(reg, val);
if (addr_num)
- reg = &((struct memac_regs *)m->ccsr_map)->
+ reg = &((struct memac_regs *)m->memac_map)->
mac_addr[addr_num-1].mac_addr_u;
else
- reg = &((struct memac_regs *)m->ccsr_map)->mac_addr0.mac_addr_u;
+ reg = &((struct memac_regs *)m->memac_map)->mac_addr0.mac_addr_u;
val = ((m->__if.mac_addr.addr_bytes[4] << 0) |
(m->__if.mac_addr.addr_bytes[5] << 8));
@@ -214,7 +216,7 @@ fman_if_set_rx_ignore_pause_frames(struct fman_if *p, bool enable)
assert(fman_ccsr_map_fd != -1);
/* Set Rx Ignore Pause Frames */
- cmdcfg = &((struct memac_regs *)__if->ccsr_map)->command_config;
+ cmdcfg = &((struct memac_regs *)__if->memac_map)->command_config;
if (enable)
value = in_be32(cmdcfg) | CMD_CFG_PAUSE_IGNORE;
else
@@ -232,7 +234,7 @@ fman_if_conf_max_frame_len(struct fman_if *p, unsigned int max_frame_len)
assert(fman_ccsr_map_fd != -1);
/* Set Max frame length */
- maxfrm = &((struct memac_regs *)__if->ccsr_map)->maxfrm;
+ maxfrm = &((struct memac_regs *)__if->memac_map)->maxfrm;
out_be32(maxfrm, (MAXFRM_RX_MASK & max_frame_len));
}
@@ -240,7 +242,7 @@ void
fman_if_stats_get(struct fman_if *p, struct rte_eth_stats *stats)
{
struct __fman_if *m = container_of(p, struct __fman_if, __if);
- struct memac_regs *regs = m->ccsr_map;
+ struct memac_regs *regs = m->memac_map;
/* read recved packet count */
stats->ipackets = (u64)in_be32(®s->rfrm_l) |
@@ -263,7 +265,7 @@ void
fman_if_stats_get_all(struct fman_if *p, uint64_t *value, int n)
{
struct __fman_if *m = container_of(p, struct __fman_if, __if);
- struct memac_regs *regs = m->ccsr_map;
+ struct memac_regs *regs = m->memac_map;
int i;
uint64_t base_offset = offsetof(struct memac_regs, reoct_l);
@@ -278,7 +280,7 @@ void
fman_if_stats_reset(struct fman_if *p)
{
struct __fman_if *m = container_of(p, struct __fman_if, __if);
- struct memac_regs *regs = m->ccsr_map;
+ struct memac_regs *regs = m->memac_map;
uint32_t tmp;
tmp = in_be32(®s->statn_config);
@@ -295,7 +297,7 @@ void
fman_if_bmi_stats_enable(struct fman_if *p)
{
struct __fman_if *m = container_of(p, struct __fman_if, __if);
- struct rx_bmi_regs *regs = (struct rx_bmi_regs *)m->bmi_map;
+ struct rx_bmi_regs *regs = (struct rx_bmi_regs *)m->rx_bmi_map;
uint32_t tmp;
tmp = in_be32(®s->fmbm_rstc);
@@ -309,7 +311,7 @@ void
fman_if_bmi_stats_disable(struct fman_if *p)
{
struct __fman_if *m = container_of(p, struct __fman_if, __if);
- struct rx_bmi_regs *regs = (struct rx_bmi_regs *)m->bmi_map;
+ struct rx_bmi_regs *regs = (struct rx_bmi_regs *)m->rx_bmi_map;
uint32_t tmp;
tmp = in_be32(®s->fmbm_rstc);
@@ -323,7 +325,7 @@ void
fman_if_bmi_stats_get_all(struct fman_if *p, uint64_t *value)
{
struct __fman_if *m = container_of(p, struct __fman_if, __if);
- struct rx_bmi_regs *regs = (struct rx_bmi_regs *)m->bmi_map;
+ struct rx_bmi_regs *regs = (struct rx_bmi_regs *)m->rx_bmi_map;
int i = 0;
value[i++] = (u32)in_be32(®s->fmbm_rfrc);
@@ -340,7 +342,7 @@ void
fman_if_bmi_stats_reset(struct fman_if *p)
{
struct __fman_if *m = container_of(p, struct __fman_if, __if);
- struct rx_bmi_regs *regs = (struct rx_bmi_regs *)m->bmi_map;
+ struct rx_bmi_regs *regs = (struct rx_bmi_regs *)m->rx_bmi_map;
out_be32(®s->fmbm_rfrc, 0);
out_be32(®s->fmbm_rfbc, 0);
@@ -361,7 +363,7 @@ fman_if_promiscuous_enable(struct fman_if *p)
assert(fman_ccsr_map_fd != -1);
/* Enable Rx promiscuous mode */
- cmdcfg = &((struct memac_regs *)__if->ccsr_map)->command_config;
+ cmdcfg = &((struct memac_regs *)__if->memac_map)->command_config;
out_be32(cmdcfg, in_be32(cmdcfg) | CMD_CFG_PROMIS_EN);
}
@@ -374,7 +376,7 @@ fman_if_promiscuous_disable(struct fman_if *p)
assert(fman_ccsr_map_fd != -1);
/* Disable Rx promiscuous mode */
- cmdcfg = &((struct memac_regs *)__if->ccsr_map)->command_config;
+ cmdcfg = &((struct memac_regs *)__if->memac_map)->command_config;
out_be32(cmdcfg, in_be32(cmdcfg) & (~CMD_CFG_PROMIS_EN));
}
@@ -386,7 +388,7 @@ fman_if_enable_rx(struct fman_if *p)
assert(fman_ccsr_map_fd != -1);
/* enable Rx and Tx */
- out_be32(__if->ccsr_map + 8, in_be32(__if->ccsr_map + 8) | 3);
+ out_be32(__if->memac_map + 8, in_be32(__if->memac_map + 8) | 3);
}
void
@@ -397,7 +399,7 @@ fman_if_disable_rx(struct fman_if *p)
assert(fman_ccsr_map_fd != -1);
/* only disable Rx, not Tx */
- out_be32(__if->ccsr_map + 8, in_be32(__if->ccsr_map + 8) & ~(u32)2);
+ out_be32(__if->memac_map + 8, in_be32(__if->memac_map + 8) & ~(u32)2);
}
int
@@ -408,7 +410,7 @@ fman_if_get_rx_status(struct fman_if *p)
assert(fman_ccsr_map_fd != -1);
/* return true if RX bit is set */
- return !!(in_be32(__if->ccsr_map + 8) & (u32)2);
+ return !!(in_be32(__if->memac_map + 8) & (u32)2);
}
void
@@ -421,11 +423,11 @@ fman_if_loopback_enable(struct fman_if *p)
/* Enable loopback mode */
if ((__if->__if.is_memac) && (__if->__if.is_rgmii)) {
unsigned int *ifmode =
- &((struct memac_regs *)__if->ccsr_map)->if_mode;
+ &((struct memac_regs *)__if->memac_map)->if_mode;
out_be32(ifmode, in_be32(ifmode) | IF_MODE_RLP);
} else{
unsigned int *cmdcfg =
- &((struct memac_regs *)__if->ccsr_map)->command_config;
+ &((struct memac_regs *)__if->memac_map)->command_config;
out_be32(cmdcfg, in_be32(cmdcfg) | CMD_CFG_LOOPBACK_EN);
}
}
@@ -439,11 +441,11 @@ fman_if_loopback_disable(struct fman_if *p)
/* Disable loopback mode */
if ((__if->__if.is_memac) && (__if->__if.is_rgmii)) {
unsigned int *ifmode =
- &((struct memac_regs *)__if->ccsr_map)->if_mode;
+ &((struct memac_regs *)__if->memac_map)->if_mode;
out_be32(ifmode, in_be32(ifmode) & ~IF_MODE_RLP);
} else {
unsigned int *cmdcfg =
- &((struct memac_regs *)__if->ccsr_map)->command_config;
+ &((struct memac_regs *)__if->memac_map)->command_config;
out_be32(cmdcfg, in_be32(cmdcfg) & ~CMD_CFG_LOOPBACK_EN);
}
}
@@ -461,11 +463,11 @@ fman_if_set_bp(struct fman_if *fm_if, unsigned num __always_unused,
assert(fman_ccsr_map_fd != -1);
fmbm_ebmpi =
- in_be32(&((struct rx_bmi_regs *)__if->bmi_map)->fmbm_ebmpi[0]);
+ in_be32(&((struct rx_bmi_regs *)__if->rx_bmi_map)->fmbm_ebmpi[0]);
fmbm_ebmpi = ebmpi_val_ace | (fmbm_ebmpi & ebmpi_mask) | (bpid << 16) |
(bufsize);
- out_be32(&((struct rx_bmi_regs *)__if->bmi_map)->fmbm_ebmpi[0],
+ out_be32(&((struct rx_bmi_regs *)__if->rx_bmi_map)->fmbm_ebmpi[0],
fmbm_ebmpi);
}
@@ -477,7 +479,7 @@ fman_if_get_fc_threshold(struct fman_if *fm_if)
assert(fman_ccsr_map_fd != -1);
- fmbm_mpd = &((struct rx_bmi_regs *)__if->bmi_map)->fmbm_mpd;
+ fmbm_mpd = &((struct rx_bmi_regs *)__if->rx_bmi_map)->fmbm_mpd;
return in_be32(fmbm_mpd);
}
@@ -490,7 +492,7 @@ fman_if_set_fc_threshold(struct fman_if *fm_if, u32 high_water,
assert(fman_ccsr_map_fd != -1);
- fmbm_mpd = &((struct rx_bmi_regs *)__if->bmi_map)->fmbm_mpd;
+ fmbm_mpd = &((struct rx_bmi_regs *)__if->rx_bmi_map)->fmbm_mpd;
out_be32(fmbm_mpd, FMAN_ENABLE_BPOOL_DEPLETION);
return bm_pool_set_hw_threshold(bpid, low_water, high_water);
@@ -503,7 +505,7 @@ fman_if_get_fc_quanta(struct fman_if *fm_if)
assert(fman_ccsr_map_fd != -1);
- return in_be32(&((struct memac_regs *)__if->ccsr_map)->pause_quanta[0]);
+ return in_be32(&((struct memac_regs *)__if->memac_map)->pause_quanta[0]);
}
int
@@ -513,7 +515,7 @@ fman_if_set_fc_quanta(struct fman_if *fm_if, u16 pause_quanta)
assert(fman_ccsr_map_fd != -1);
- out_be32(&((struct memac_regs *)__if->ccsr_map)->pause_quanta[0],
+ out_be32(&((struct memac_regs *)__if->memac_map)->pause_quanta[0],
pause_quanta);
return 0;
}
@@ -528,7 +530,7 @@ fman_if_get_fdoff(struct fman_if *fm_if)
assert(fman_ccsr_map_fd != -1);
- fmbm_rebm = in_be32(&((struct rx_bmi_regs *)__if->bmi_map)->fmbm_rebm);
+ fmbm_rebm = in_be32(&((struct rx_bmi_regs *)__if->rx_bmi_map)->fmbm_rebm);
fdoff = (fmbm_rebm >> FMAN_SP_EXT_BUF_MARG_START_SHIFT) & 0x1ff;
@@ -543,7 +545,7 @@ fman_if_set_err_fqid(struct fman_if *fm_if, uint32_t err_fqid)
assert(fman_ccsr_map_fd != -1);
unsigned int *fmbm_refqid =
- &((struct rx_bmi_regs *)__if->bmi_map)->fmbm_refqid;
+ &((struct rx_bmi_regs *)__if->rx_bmi_map)->fmbm_refqid;
out_be32(fmbm_refqid, err_fqid);
}
@@ -559,7 +561,7 @@ fman_if_get_ic_params(struct fman_if *fm_if, struct fman_if_ic_params *icp)
assert(fman_ccsr_map_fd != -1);
unsigned int *fmbm_ricp =
- &((struct rx_bmi_regs *)__if->bmi_map)->fmbm_ricp;
+ &((struct rx_bmi_regs *)__if->rx_bmi_map)->fmbm_ricp;
val = in_be32(fmbm_ricp);
icp->iceof = (val & iceof_mask) >> 12;
@@ -586,7 +588,7 @@ fman_if_set_ic_params(struct fman_if *fm_if,
val |= (icp->icsz >> 4) & icsz_mask;
unsigned int *fmbm_ricp =
- &((struct rx_bmi_regs *)__if->bmi_map)->fmbm_ricp;
+ &((struct rx_bmi_regs *)__if->rx_bmi_map)->fmbm_ricp;
out_be32(fmbm_ricp, val);
unsigned int *fmbm_ticp =
@@ -608,7 +610,7 @@ fman_if_set_fdoff(struct fman_if *fm_if, uint32_t fd_offset)
assert(fman_ccsr_map_fd != -1);
- fmbm_rebm = &((struct rx_bmi_regs *)__if->bmi_map)->fmbm_rebm;
+ fmbm_rebm = &((struct rx_bmi_regs *)__if->rx_bmi_map)->fmbm_rebm;
out_be32(fmbm_rebm, (in_be32(fmbm_rebm) & ~fmbm_mask) | val);
}
@@ -621,7 +623,7 @@ fman_if_set_maxfrm(struct fman_if *fm_if, uint16_t max_frm)
assert(fman_ccsr_map_fd != -1);
- reg_maxfrm = &((struct memac_regs *)__if->ccsr_map)->maxfrm;
+ reg_maxfrm = &((struct memac_regs *)__if->memac_map)->maxfrm;
out_be32(reg_maxfrm, (in_be32(reg_maxfrm) & 0xFFFF0000) | max_frm);
}
@@ -634,7 +636,7 @@ fman_if_get_maxfrm(struct fman_if *fm_if)
assert(fman_ccsr_map_fd != -1);
- reg_maxfrm = &((struct memac_regs *)__if->ccsr_map)->maxfrm;
+ reg_maxfrm = &((struct memac_regs *)__if->memac_map)->maxfrm;
return (in_be32(reg_maxfrm) | 0x0000FFFF);
}
@@ -655,7 +657,7 @@ fman_if_get_sg_enable(struct fman_if *fm_if)
assert(fman_ccsr_map_fd != -1);
- fmbm_rebm = in_be32(&((struct rx_bmi_regs *)__if->bmi_map)->fmbm_rebm);
+ fmbm_rebm = in_be32(&((struct rx_bmi_regs *)__if->rx_bmi_map)->fmbm_rebm);
return (fmbm_rebm & FMAN_SP_SG_DISABLE) ? 0 : 1;
}
@@ -675,7 +677,7 @@ fman_if_set_sg(struct fman_if *fm_if, int enable)
assert(fman_ccsr_map_fd != -1);
- fmbm_rebm = &((struct rx_bmi_regs *)__if->bmi_map)->fmbm_rebm;
+ fmbm_rebm = &((struct rx_bmi_regs *)__if->rx_bmi_map)->fmbm_rebm;
out_be32(fmbm_rebm, (in_be32(fmbm_rebm) & ~fmbm_mask) | val);
}
@@ -699,14 +701,14 @@ fman_if_discard_rx_errors(struct fman_if *fm_if)
struct __fman_if *__if = container_of(fm_if, struct __fman_if, __if);
unsigned int *fmbm_rfsdm, *fmbm_rfsem;
- fmbm_rfsem = &((struct rx_bmi_regs *)__if->bmi_map)->fmbm_rfsem;
+ fmbm_rfsem = &((struct rx_bmi_regs *)__if->rx_bmi_map)->fmbm_rfsem;
out_be32(fmbm_rfsem, 0);
/* Configure the discard mask to discard the error packets which have
* DMA errors, Frame size error, Header error etc. The mask 0x010EE3F0
* is to configured discard all the errors which come in the FD[STATUS]
*/
- fmbm_rfsdm = &((struct rx_bmi_regs *)__if->bmi_map)->fmbm_rfsdm;
+ fmbm_rfsdm = &((struct rx_bmi_regs *)__if->rx_bmi_map)->fmbm_rfsdm;
out_be32(fmbm_rfsdm, 0x010EE3F0);
}
@@ -718,9 +720,9 @@ fman_if_receive_rx_errors(struct fman_if *fm_if,
unsigned int *fmbm_rcfg, *fmbm_rfsdm, *fmbm_rfsem;
unsigned int val;
- fmbm_rcfg = &((struct rx_bmi_regs *)__if->bmi_map)->fmbm_rcfg;
- fmbm_rfsdm = &((struct rx_bmi_regs *)__if->bmi_map)->fmbm_rfsdm;
- fmbm_rfsem = &((struct rx_bmi_regs *)__if->bmi_map)->fmbm_rfsem;
+ fmbm_rcfg = &((struct rx_bmi_regs *)__if->rx_bmi_map)->fmbm_rcfg;
+ fmbm_rfsdm = &((struct rx_bmi_regs *)__if->rx_bmi_map)->fmbm_rfsdm;
+ fmbm_rfsem = &((struct rx_bmi_regs *)__if->rx_bmi_map)->fmbm_rfsem;
val = in_be32(fmbm_rcfg);
out_be32(fmbm_rcfg, val | BMI_PORT_CFG_FDOVR);
diff --git a/drivers/bus/dpaa/include/fman.h b/drivers/bus/dpaa/include/fman.h
index c33fe81516..a248edf4d8 100644
--- a/drivers/bus/dpaa/include/fman.h
+++ b/drivers/bus/dpaa/include/fman.h
@@ -462,8 +462,8 @@ struct __fman_if {
char node_name[IF_NAME_MAX_LEN];
char node_path[PATH_MAX];
uint64_t regs_size;
- void *ccsr_map;
- void *bmi_map;
+ void *memac_map;
+ void *rx_bmi_map;
void *tx_bmi_map;
void *qmi_map;
};
@@ -473,8 +473,6 @@ struct __fman_if {
*/
extern const struct list_head *fman_if_list;
-extern int fman_ccsr_map_fd;
-
/* To iterate the "bpool_list" for an interface. Eg;
* struct fman_if *p = get_ptr_to_some_interface();
* struct fman_if_bpool *bp;
--
2.25.1
^ permalink raw reply related
* [PATCH v4 02/19] bus/dpaa: scan max BPID from DTS
From: Hemant Agrawal @ 2026-06-21 17:27 UTC (permalink / raw)
To: stephen, david.marchand, dev; +Cc: Jun Yang
In-Reply-To: <20260621172731.2916346-1-hemant.agrawal@nxp.com>
From: Jun Yang <jun.yang@nxp.com>
Calculate the maximum BPID dynamically from the device tree
configuration instead of using a hardcoded value. This ensures
correct operation across different DPAA hardware configurations.
Signed-off-by: Jun Yang <jun.yang@nxp.com>
---
drivers/bus/dpaa/base/qbman/bman_driver.c | 48 ++++++++++++++++-------
1 file changed, 33 insertions(+), 15 deletions(-)
diff --git a/drivers/bus/dpaa/base/qbman/bman_driver.c b/drivers/bus/dpaa/base/qbman/bman_driver.c
index 23e44ac10b..85575192bf 100644
--- a/drivers/bus/dpaa/base/qbman/bman_driver.c
+++ b/drivers/bus/dpaa/base/qbman/bman_driver.c
@@ -1,7 +1,7 @@
/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
*
* Copyright 2008-2016 Freescale Semiconductor Inc.
- * Copyright 2017 NXP
+ * Copyright 2017,2026 NXP
*
*/
@@ -182,7 +182,12 @@ int bman_init_ccsr(const struct device_node *node)
int bman_global_init(void)
{
const struct device_node *dt_node;
+ const rte_be32_t *range;
+ uint32_t start, count;
+ int ret;
static int done;
+#define BPID_RANGE_START_INDEX 0
+#define BPID_RANGE_COUNT_INDEX 1
if (done)
return -EBUSY;
@@ -197,36 +202,49 @@ int bman_global_init(void)
if (of_device_is_compatible(dt_node, "fsl,bman-portal-1.0") ||
of_device_is_compatible(dt_node, "fsl,bman-portal-1.0.0")) {
bman_ip_rev = BMAN_REV10;
- bman_pool_max = 64;
} else if (of_device_is_compatible(dt_node, "fsl,bman-portal-2.0") ||
of_device_is_compatible(dt_node, "fsl,bman-portal-2.0.8")) {
bman_ip_rev = BMAN_REV20;
- bman_pool_max = 8;
} else if (of_device_is_compatible(dt_node, "fsl,bman-portal-2.1.0") ||
of_device_is_compatible(dt_node, "fsl,bman-portal-2.1.1") ||
of_device_is_compatible(dt_node, "fsl,bman-portal-2.1.2") ||
of_device_is_compatible(dt_node, "fsl,bman-portal-2.1.3")) {
bman_ip_rev = BMAN_REV21;
- bman_pool_max = 64;
} else {
- pr_warn("unknown BMan version in portal node,default "
- "to rev1.0");
+ pr_warn("unknown BMan version in portal node, default to rev1.0");
bman_ip_rev = BMAN_REV10;
- bman_pool_max = 64;
}
if (!bman_ip_rev) {
pr_err("Unknown bman portal version\n");
return -ENODEV;
}
- {
- const struct device_node *dn = of_find_compatible_node(NULL,
- NULL, "fsl,bman");
- if (!dn)
- pr_err("No bman device node available");
-
- if (bman_init_ccsr(dn))
- pr_err("BMan CCSR map failed.");
+
+ for_each_compatible_node(dt_node, NULL, "fsl,bpid-range") {
+ range = of_get_property(dt_node, "fsl,bpid-range", NULL);
+ if (!range)
+ continue;
+ start = rte_be_to_cpu_32(range[BPID_RANGE_START_INDEX]);
+ count = rte_be_to_cpu_32(range[BPID_RANGE_COUNT_INDEX]);
+ bman_pool_max = start + count;
+ pr_info("Max BPID: %d, fixed BPID < %d", bman_pool_max, start);
+ break;
+ }
+ if (!bman_pool_max) {
+ pr_err("No BPID range found");
+ return -ENODEV;
+ }
+
+ dt_node = of_find_compatible_node(NULL, NULL, "fsl,bman");
+ if (!dt_node) {
+ pr_err("No bman device node available");
+ return -ENODEV;
+ }
+
+ ret = bman_init_ccsr(dt_node);
+ if (ret) {
+ pr_err("Failed(%d) to init bman ccsr", ret);
+ return ret;
}
done = 1;
--
2.25.1
^ permalink raw reply related
* [PATCH v4 03/19] drivers: add BMI Tx statistics
From: Hemant Agrawal @ 2026-06-21 17:27 UTC (permalink / raw)
To: stephen, david.marchand, dev; +Cc: Jun Yang
In-Reply-To: <20260621172731.2916346-1-hemant.agrawal@nxp.com>
From: Jun Yang <jun.yang@nxp.com>
Add support for BMI (Buffer Manager Interface) Tx statistics
counters. Extend fman_hw to read Tx BMI registers and expose
them through the xstats interface.
Signed-off-by: Jun Yang <jun.yang@nxp.com>
---
drivers/bus/dpaa/base/fman/fman_hw.c | 2 --
drivers/bus/dpaa/include/fman.h | 24 ++++++++++++++++++++++++
drivers/net/dpaa/dpaa_ethdev.c | 10 +++++++++-
drivers/net/dpaa/dpaa_ethdev.h | 11 +++++++++--
4 files changed, 42 insertions(+), 5 deletions(-)
diff --git a/drivers/bus/dpaa/base/fman/fman_hw.c b/drivers/bus/dpaa/base/fman/fman_hw.c
index ce68581555..aab04bf76a 100644
--- a/drivers/bus/dpaa/base/fman/fman_hw.c
+++ b/drivers/bus/dpaa/base/fman/fman_hw.c
@@ -301,7 +301,6 @@ fman_if_bmi_stats_enable(struct fman_if *p)
uint32_t tmp;
tmp = in_be32(®s->fmbm_rstc);
-
tmp |= FMAN_BMI_COUNTERS_EN;
out_be32(®s->fmbm_rstc, tmp);
@@ -315,7 +314,6 @@ fman_if_bmi_stats_disable(struct fman_if *p)
uint32_t tmp;
tmp = in_be32(®s->fmbm_rstc);
-
tmp &= ~FMAN_BMI_COUNTERS_EN;
out_be32(®s->fmbm_rstc, tmp);
diff --git a/drivers/bus/dpaa/include/fman.h b/drivers/bus/dpaa/include/fman.h
index a248edf4d8..2bddf489b8 100644
--- a/drivers/bus/dpaa/include/fman.h
+++ b/drivers/bus/dpaa/include/fman.h
@@ -306,6 +306,21 @@ struct tx_bmi_regs {
uint32_t fmbm_tfene; /**< Tx Frame Enqueue Next Engine*/
uint32_t fmbm_trlmts; /**< Tx Rate Limiter Scale*/
uint32_t fmbm_trlmt; /**< Tx Rate Limiter*/
+ uint32_t reserved0034[0x73];/**< (0x0034 0x01FF) */
+ uint32_t fmbm_tstc; /**< Tx Statistics Counters*/
+ uint32_t fmbm_tfrc; /**< Tx Frame Counter*/
+ uint32_t fmbm_tfdc; /**< Tx Frames Discard Counter*/
+ uint32_t fmbm_tfledc; /**< Tx Frames Length Error Discard*/
+ uint32_t fmbm_tfufdc; /**< Tx Frames Unsupported Format*/
+ uint32_t fmbm_tbdc; /**< Tx Buffers Deallocate Counter */
+ uint32_t reserved0218[0x1a];/**< (0x0218 0x027F) */
+ uint32_t fmbm_tpc; /**< Tx Performance Counters*/
+ uint32_t fmbm_tpcp; /**< Tx Performance Count Parameters */
+ uint32_t fmbm_tccn; /**< Tx Cycle Counter*/
+ uint32_t fmbm_ttuc; /**< Tx Tasks Utilization Counter */
+ uint32_t fmbm_ttcquc; /**< Tx Transmit Confirm Queue Utilization Counter*/
+ uint32_t fmbm_tduc; /**< Tx DMA Utilization Counter */
+ uint32_t fmbm_tfuc; /**< Tx FIFO Utilization Counter */
};
/* Description FM RTC timer alarm */
@@ -468,6 +483,15 @@ struct __fman_if {
void *qmi_map;
};
+#define MEMMAC_REG_OFFSET(reg) offsetof(struct memac_regs, reg)
+#define BMI_RX_REG_OFFSET(reg) offsetof(struct rx_bmi_regs, reg)
+#define BMI_TX_REG_OFFSET(reg) offsetof(struct tx_bmi_regs, reg)
+
+#define FMAN_IF_BMI_RX_STAT_OFFSET_START BMI_RX_REG_OFFSET(fmbm_rfrc)
+#define FMAN_IF_BMI_RX_STAT_OFFSET_END BMI_RX_REG_OFFSET(fmbm_rbdc)
+#define FMAN_IF_BMI_TX_STAT_OFFSET_START BMI_TX_REG_OFFSET(fmbm_tfrc)
+#define FMAN_IF_BMI_TX_STAT_OFFSET_END BMI_TX_REG_OFFSET(fmbm_tbdc)
+
/* And this is the base list node that the interfaces are added to. (See
* fman_if_enable_all_rx() below for an example of its use.)
*/
diff --git a/drivers/net/dpaa/dpaa_ethdev.c b/drivers/net/dpaa/dpaa_ethdev.c
index 9f976d179b..8fb2e33e0a 100644
--- a/drivers/net/dpaa/dpaa_ethdev.c
+++ b/drivers/net/dpaa/dpaa_ethdev.c
@@ -1,7 +1,7 @@
/* SPDX-License-Identifier: BSD-3-Clause
*
* Copyright 2016 Freescale Semiconductor, Inc. All rights reserved.
- * Copyright 2017-2020,2022-2025 NXP
+ * Copyright 2017-2020,2022-2026 NXP
*
*/
/* System headers */
@@ -143,6 +143,14 @@ static const struct rte_dpaa_xstats_name_off dpaa_xstats_strings[] = {
offsetof(struct dpaa_if_rx_bmi_stats, fmbm_rodc)},
{"rx_buf_diallocate",
offsetof(struct dpaa_if_rx_bmi_stats, fmbm_rbdc)},
+ {"tx_bad_frames_count",
+ offsetof(struct dpaa_if_tx_bmi_stats, fmbm_tfdc)},
+ {"tx_frame_length_discard",
+ offsetof(struct dpaa_if_tx_bmi_stats, fmbm_tfledc)},
+ {"tx_frames_unsupported_format",
+ offsetof(struct dpaa_if_tx_bmi_stats, fmbm_tfufdc)},
+ {"tx_buf_diallocate",
+ offsetof(struct dpaa_if_tx_bmi_stats, fmbm_tbdc)},
};
static struct rte_dpaa_driver rte_dpaa_pmd;
diff --git a/drivers/net/dpaa/dpaa_ethdev.h b/drivers/net/dpaa/dpaa_ethdev.h
index f400030a5c..d342d98f23 100644
--- a/drivers/net/dpaa/dpaa_ethdev.h
+++ b/drivers/net/dpaa/dpaa_ethdev.h
@@ -1,7 +1,7 @@
/* SPDX-License-Identifier: BSD-3-Clause
*
* Copyright (c) 2014-2016 Freescale Semiconductor, Inc. All rights reserved.
- * Copyright 2017-2024 NXP
+ * Copyright 2017-2026 NXP
*
*/
#ifndef __DPAA_ETHDEV_H__
@@ -234,7 +234,6 @@ dpaa_rx_cb_atomic(void *event,
void **bufs);
struct dpaa_if_rx_bmi_stats {
- uint32_t fmbm_rstc; /**< Rx Statistics Counters*/
uint32_t fmbm_rfrc; /**< Rx Frame Counter*/
uint32_t fmbm_rfbc; /**< Rx Bad Frames Counter*/
uint32_t fmbm_rlfc; /**< Rx Large Frames Counter*/
@@ -245,6 +244,14 @@ struct dpaa_if_rx_bmi_stats {
uint32_t fmbm_rbdc; /**< Rx Buffers Deallocate Counter*/
};
+struct dpaa_if_tx_bmi_stats {
+ uint32_t fmbm_tfrc; /**< Tx Frame Counter*/
+ uint32_t fmbm_tfdc; /**< Tx Frames Discard Counter*/
+ uint32_t fmbm_tfledc; /**< Tx Frames Length Error Discard*/
+ uint32_t fmbm_tfufdc; /**< Tx Frames Unsupported Format*/
+ uint32_t fmbm_tbdc; /**< Tx Buffers Deallocate Counter */
+};
+
int
dpaa_tx_conf_queue_init(struct qman_fq *fq);
--
2.25.1
^ permalink raw reply related
* [PATCH v4 04/19] drivers: add process-type guards for secondary process
From: Hemant Agrawal @ 2026-06-21 17:27 UTC (permalink / raw)
To: stephen, david.marchand, dev; +Cc: Prashant Gupta
In-Reply-To: <20260621172731.2916346-1-hemant.agrawal@nxp.com>
From: Prashant Gupta <prashant.gupta_3@nxp.com>
Add RTE_PROC_PRIMARY checks in device initialization paths for
net/dpaa, crypto/dpaa_sec and dma/dpaa drivers. Secondary
processes should skip hardware initialization to prevent
segfaults when accessing hardware registers that are only
mapped in the primary process.
Signed-off-by: Prashant Gupta <prashant.gupta_3@nxp.com>
---
drivers/crypto/dpaa_sec/dpaa_sec.c | 3 ---
drivers/dma/dpaa/dpaa_qdma.c | 23 +++++++++++++++++++++++
drivers/net/dpaa/dpaa_ethdev.c | 3 +++
3 files changed, 26 insertions(+), 3 deletions(-)
diff --git a/drivers/crypto/dpaa_sec/dpaa_sec.c b/drivers/crypto/dpaa_sec/dpaa_sec.c
index 65bbd38b17..36f5819b0e 100644
--- a/drivers/crypto/dpaa_sec/dpaa_sec.c
+++ b/drivers/crypto/dpaa_sec/dpaa_sec.c
@@ -3783,9 +3783,6 @@ cryptodev_dpaa_sec_probe(struct rte_dpaa_driver *dpaa_drv __rte_unused,
RTE_DPAA_MAX_NB_SEC_QPS,
};
- if (rte_eal_process_type() != RTE_PROC_PRIMARY)
- return 0;
-
snprintf(cryptodev_name, sizeof(cryptodev_name), "%s", dpaa_dev->name);
cryptodev = rte_cryptodev_pmd_create(cryptodev_name, &dpaa_dev->device, &init_params);
diff --git a/drivers/dma/dpaa/dpaa_qdma.c b/drivers/dma/dpaa/dpaa_qdma.c
index 74e23d2ee5..af6083d2fe 100644
--- a/drivers/dma/dpaa/dpaa_qdma.c
+++ b/drivers/dma/dpaa/dpaa_qdma.c
@@ -1330,11 +1330,34 @@ dpaa_qdma_init(struct rte_dma_dev *dmadev)
int ret;
uint32_t i, j, k;
+ if (rte_eal_process_type() != RTE_PROC_PRIMARY)
+ return -ENOTSUP;
+
if (dpaa_get_devargs(dmadev->device->devargs, DPAA_DMA_ERROR_CHECK)) {
s_hw_err_check = true;
DPAA_QDMA_INFO("Enable DMA error checks");
}
+ if (getenv("DPAA_QDMA_DATA_VALIDATION"))
+ s_data_validation = 1;
+
+ if (getenv("DPAA_QDMA_HW_ERR_CHECK"))
+ s_hw_err_check = 1;
+
+ char *penv = getenv("DPAA_QDMA_SG_ENABLE");
+ if (penv)
+ s_sg_enable = atoi(penv);
+
+ penv = getenv("DPAA_QDMA_SG_MAX_ENTRY_SIZE");
+ if (penv)
+ s_sg_max_entry_sz = atoi(penv);
+
+#ifdef RTE_DMA_DPAA_ERRATA_ERR050757
+ penv = getenv("DPAA_QDMA_PCI_READ");
+ if (penv)
+ s_pci_read = atoi(penv);
+#endif
+
fsl_qdma->n_queues = QDMA_QUEUES * QDMA_BLOCKS;
fsl_qdma->num_blocks = QDMA_BLOCKS;
fsl_qdma->block_offset = QDMA_BLOCK_OFFSET;
diff --git a/drivers/net/dpaa/dpaa_ethdev.c b/drivers/net/dpaa/dpaa_ethdev.c
index 8fb2e33e0a..42ab9679d1 100644
--- a/drivers/net/dpaa/dpaa_ethdev.c
+++ b/drivers/net/dpaa/dpaa_ethdev.c
@@ -2686,6 +2686,9 @@ rte_dpaa_remove(struct rte_dpaa_device *dpaa_dev)
PMD_INIT_FUNC_TRACE();
+ if (rte_eal_process_type() != RTE_PROC_PRIMARY)
+ return 0;
+
eth_dev = dpaa_dev->eth_dev;
dpaa_eth_dev_close(eth_dev);
ret = rte_eth_dev_release_port(eth_dev);
--
2.25.1
^ permalink raw reply related
* [PATCH v4 05/19] bus/dpaa: define helpers for qman channel and wq
From: Hemant Agrawal @ 2026-06-21 17:27 UTC (permalink / raw)
To: stephen, david.marchand, dev; +Cc: Jun Yang
In-Reply-To: <20260621172731.2916346-1-hemant.agrawal@nxp.com>
From: Jun Yang <jun.yang@nxp.com>
Add inline helper functions to extract channel and work queue
from a frame queue descriptor, replacing open-coded bit
manipulation throughout the driver.
Signed-off-by: Jun Yang <jun.yang@nxp.com>
---
drivers/bus/dpaa/base/qbman/qman.c | 14 ++------------
drivers/bus/dpaa/base/qbman/qman.h | 23 ++++++++++++++++++++++-
2 files changed, 24 insertions(+), 13 deletions(-)
diff --git a/drivers/bus/dpaa/base/qbman/qman.c b/drivers/bus/dpaa/base/qbman/qman.c
index 5534e1846c..c9a8ec34a5 100644
--- a/drivers/bus/dpaa/base/qbman/qman.c
+++ b/drivers/bus/dpaa/base/qbman/qman.c
@@ -2704,14 +2704,6 @@ int qman_delete_cgr(struct qman_cgr *cgr)
return ret;
}
-#define GENMASK(h, l) \
- (((~0U) >> (sizeof(unsigned int) * 8 - ((h) - (l) + 1))) << (l))
-
-/* 'fqid' is a 24-bit field in every h/w descriptor */
-#define QM_FQID_MASK GENMASK(23, 0)
-#define qm_fqid_set(p, v) ((p)->fqid = cpu_to_be32((v) & QM_FQID_MASK))
-#define qm_fqid_get(p) (be32_to_cpu((p)->fqid) & QM_FQID_MASK)
-
static int
_qm_mr_consume_and_match_verb(struct qm_portal *p, int v)
{
@@ -2798,7 +2790,6 @@ qman_shutdown_fq(u32 fqid)
u32 res;
u8 state;
u32 channel, wq;
- u16 dest_wq;
DPAA_BUS_DEBUG("In shutdown for queue = %x", fqid);
p = get_affine_portal();
@@ -2828,9 +2819,8 @@ qman_shutdown_fq(u32 fqid)
}
/* Need to store these since the MCR gets reused */
- dest_wq = be16_to_cpu(mcr->queryfq.fqd.dest_wq);
- channel = dest_wq & 0x7;
- wq = dest_wq >> 3;
+ channel = qm_fqd_get_chan(&mcr->queryfq.fqd);
+ wq = qm_fqd_get_wq(&mcr->queryfq.fqd);
switch (state) {
case QM_MCR_NP_STATE_TEN_SCHED:
diff --git a/drivers/bus/dpaa/base/qbman/qman.h b/drivers/bus/dpaa/base/qbman/qman.h
index 43a16d1e3b..bd97689a91 100644
--- a/drivers/bus/dpaa/base/qbman/qman.h
+++ b/drivers/bus/dpaa/base/qbman/qman.h
@@ -1,12 +1,15 @@
/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
*
* Copyright 2008-2016 Freescale Semiconductor Inc.
- * Copyright 2017 NXP
+ * Copyright 2017,2026 NXP
*
*/
#include "qman_priv.h"
+#define GENMASK(h, l) \
+ (((~0U) >> (sizeof(u32) * 8 - ((h) - (l) + 1))) << (l))
+
/***************************/
/* Portal register assists */
/***************************/
@@ -42,6 +45,14 @@
#define QM_CL_RR0 0x3900
#define QM_CL_RR1 0x3940
+#define QM_FQD_CHAN_OFF 3
+#define QM_FQD_WQ_MASK GENMASK(2, 0)
+/* 'fqid' is a 24-bit field in every h/w descriptor */
+#define QM_FQID_MASK GENMASK(23, 0)
+
+#define qm_fqid_set(p, v) ((p)->fqid = cpu_to_be32((v) & QM_FQID_MASK))
+#define qm_fqid_get(p) (be32_to_cpu((p)->fqid) & QM_FQID_MASK)
+
/* BTW, the drivers (and h/w programming model) already obtain the required
* synchronisation for portal accesses via lwsync(), hwsync(), and
* data-dependencies. Use of barrier()s or other order-preserving primitives
@@ -911,3 +922,13 @@ static inline void __qm_isr_write(struct qm_portal *portal, enum qm_isr_reg n,
__qm_out(&portal->addr, QM_REG_ISR + (n << 2), val);
#endif
}
+
+static inline int qm_fqd_get_chan(const struct qm_fqd *fqd)
+{
+ return be16_to_cpu(fqd->dest_wq) >> QM_FQD_CHAN_OFF;
+}
+
+static inline int qm_fqd_get_wq(const struct qm_fqd *fqd)
+{
+ return be16_to_cpu(fqd->dest_wq) & QM_FQD_WQ_MASK;
+}
--
2.25.1
^ permalink raw reply related
* [PATCH v4 06/19] drivers: shutdown DPAA FQ by fq descriptor
From: Hemant Agrawal @ 2026-06-21 17:27 UTC (permalink / raw)
To: stephen, david.marchand, dev; +Cc: Jun Yang
In-Reply-To: <20260621172731.2916346-1-hemant.agrawal@nxp.com>
From: Jun Yang <jun.yang@nxp.com>
Pass the full FQ descriptor to qman_shutdown_fq() instead of
just the fqid, so that channel-affine portals can be correctly
accessed when shutting down push-mode Rx queues.
Signed-off-by: Jun Yang <jun.yang@nxp.com>
---
drivers/bus/dpaa/base/qbman/qman.c | 9 +++++----
drivers/bus/dpaa/include/fsl_qman.h | 11 ++++++++++-
drivers/net/dpaa/dpaa_ethdev.c | 7 +++++++
3 files changed, 22 insertions(+), 5 deletions(-)
diff --git a/drivers/bus/dpaa/base/qbman/qman.c b/drivers/bus/dpaa/base/qbman/qman.c
index c9a8ec34a5..dc8aeaa568 100644
--- a/drivers/bus/dpaa/base/qbman/qman.c
+++ b/drivers/bus/dpaa/base/qbman/qman.c
@@ -2781,18 +2781,19 @@ qm_mc_result_timeout(struct qm_portal *portal,
RTE_EXPORT_INTERNAL_SYMBOL(qman_shutdown_fq)
int
-qman_shutdown_fq(u32 fqid)
+qman_shutdown_fq(struct qman_fq *fq)
{
- struct qman_portal *p;
+ struct qman_portal *p = fq->qp;
struct qm_mc_command *mcc;
struct qm_mc_result *mcr;
int orl_empty, drain = 0, ret = 0;
- u32 res;
+ u32 res, fqid = fq->fqid;
u8 state;
u32 channel, wq;
DPAA_BUS_DEBUG("In shutdown for queue = %x", fqid);
- p = get_affine_portal();
+ if (!p)
+ p = get_affine_portal();
/* Determine the state of the FQID */
mcc = qm_mc_start(&p->p);
mcc->queryfq_np.fqid = cpu_to_be32(fqid);
diff --git a/drivers/bus/dpaa/include/fsl_qman.h b/drivers/bus/dpaa/include/fsl_qman.h
index 82269cdf99..673859ed2e 100644
--- a/drivers/bus/dpaa/include/fsl_qman.h
+++ b/drivers/bus/dpaa/include/fsl_qman.h
@@ -1896,7 +1896,16 @@ static inline void qman_release_fqid(u32 fqid)
void qman_seed_fqid_range(u32 fqid, unsigned int count);
__rte_internal
-int qman_shutdown_fq(u32 fqid);
+int qman_shutdown_fq(struct qman_fq *fq);
+
+static inline int qman_shutdown_fq_by_fqid(u32 fqid)
+{
+ struct qman_fq fq;
+
+ memset(&fq, 0, sizeof(struct qman_fq));
+ fq.fqid = fqid;
+ return qman_shutdown_fq(&fq);
+}
/**
* qman_reserve_fqid_range - Reserve the specified range of frame queue IDs
diff --git a/drivers/net/dpaa/dpaa_ethdev.c b/drivers/net/dpaa/dpaa_ethdev.c
index 42ab9679d1..94758c2748 100644
--- a/drivers/net/dpaa/dpaa_ethdev.c
+++ b/drivers/net/dpaa/dpaa_ethdev.c
@@ -2364,6 +2364,13 @@ dpaa_dev_init(struct rte_eth_dev *eth_dev)
vsp_id = dev_vspids[loop];
+ /* Shutdown FQ before configure to clean the queue */
+ ret = qman_shutdown_fq_by_fqid(fqid);
+ if (ret < 0) {
+ DPAA_PMD_ERR("Failed shutdown %s:rxq-%d-fqid = 0x%08x",
+ dpaa_intf->name, loop, fqid);
+ }
+
if (dpaa_intf->cgr_rx)
dpaa_intf->cgr_rx[loop].cgrid = cgrid[loop];
--
2.25.1
^ permalink raw reply related
* [PATCH v4 07/19] bus/dpaa: improve FQ shutdown with channel validation
From: Hemant Agrawal @ 2026-06-21 17:27 UTC (permalink / raw)
To: stephen, david.marchand, dev; +Cc: Jun Yang
In-Reply-To: <20260621172731.2916346-1-hemant.agrawal@nxp.com>
From: Jun Yang <jun.yang@nxp.com>
Fix hardcoded channel range check by using DTS-derived pool
channel start/end values. Add validation that the portal's
affine channel matches the FQ's channel for pool-channel FQs,
and only restore SDQCR when it was actually changed.
Signed-off-by: Jun Yang <jun.yang@nxp.com>
---
drivers/bus/dpaa/base/qbman/qman.c | 54 ++++++++++-------------
drivers/bus/dpaa/base/qbman/qman_driver.c | 29 ++++++++++--
drivers/bus/dpaa/dpaa_bus_base_symbols.c | 2 +
drivers/bus/dpaa/include/fsl_qman.h | 8 ++--
4 files changed, 54 insertions(+), 39 deletions(-)
diff --git a/drivers/bus/dpaa/base/qbman/qman.c b/drivers/bus/dpaa/base/qbman/qman.c
index dc8aeaa568..42618c1ab4 100644
--- a/drivers/bus/dpaa/base/qbman/qman.c
+++ b/drivers/bus/dpaa/base/qbman/qman.c
@@ -2789,7 +2789,7 @@ qman_shutdown_fq(struct qman_fq *fq)
int orl_empty, drain = 0, ret = 0;
u32 res, fqid = fq->fqid;
u8 state;
- u32 channel, wq;
+ u16 channel;
DPAA_BUS_DEBUG("In shutdown for queue = %x", fqid);
if (!p)
@@ -2803,9 +2803,10 @@ qman_shutdown_fq(struct qman_fq *fq)
ret = -ETIMEDOUT;
goto out;
}
+
state = mcr->queryfq_np.state & QM_MCR_NP_STATE_MASK;
if (state == QM_MCR_NP_STATE_OOS) {
- DPAA_BUS_ERR("Already in OOS");
+ DPAA_BUS_DEBUG("fqid(0x%x) Already in OOS", fqid);
goto out; /* Already OOS, no need to do anymore checks */
}
@@ -2821,7 +2822,6 @@ qman_shutdown_fq(struct qman_fq *fq)
/* Need to store these since the MCR gets reused */
channel = qm_fqd_get_chan(&mcr->queryfq.fqd);
- wq = qm_fqd_get_wq(&mcr->queryfq.fqd);
switch (state) {
case QM_MCR_NP_STATE_TEN_SCHED:
@@ -2840,10 +2840,9 @@ qman_shutdown_fq(struct qman_fq *fq)
}
res = mcr->result; /* Make a copy as we reuse MCR below */
- if (res == QM_MCR_RESULT_OK)
+ if (res == QM_MCR_RESULT_OK) {
drain_mr_fqrni(&p->p);
-
- if (res == QM_MCR_RESULT_PENDING) {
+ } else if (res == QM_MCR_RESULT_PENDING) {
/*
* Need to wait for the FQRN in the message ring, which
* will only occur once the FQ has been drained. In
@@ -2851,35 +2850,31 @@ qman_shutdown_fq(struct qman_fq *fq)
* to dequeue from the channel the FQ is scheduled on
*/
int found_fqrn = 0;
+ const u16 pool_ch_start = dpaa_get_qm_channel_pool();
+ const u16 pool_ch_end = pool_ch_start + dpaa_get_qm_channel_pool_num();
+ u32 sdqcr = p->sdqcr;
/* Flag that we need to drain FQ */
drain = 1;
- __maybe_unused u16 dequeue_wq = 0;
- if (channel >= qm_channel_pool1 &&
- channel < (u16)(qm_channel_pool1 + 15)) {
+ if (channel >= pool_ch_start && channel < pool_ch_end) {
/* Pool channel, enable the bit in the portal */
- dequeue_wq = (channel -
- qm_channel_pool1 + 1) << 4 | wq;
- } else if (channel < qm_channel_pool1) {
+ if (p->config->channel != channel) {
+ DPAA_BUS_ERR("Portal affine channel(0x%04x) != wq channel(0x%04x)",
+ p->config->channel, channel);
+ ret = -EINVAL;
+ goto out;
+ }
+ } else if (channel < pool_ch_start) {
/* Dedicated channel */
- dequeue_wq = wq;
+ sdqcr = QM_SDQCR_TYPE_ACTIVE | QM_SDQCR_CHANNELS_DEDICATED;
+ qm_dqrr_sdqcr_set(&p->p, sdqcr);
} else {
- DPAA_BUS_ERR("Can't recover FQ 0x%x, ch: 0x%x",
+ DPAA_BUS_ERR("Can't recover FQ 0x%x, Invalid channel: 0x%x",
fqid, channel);
ret = -EBUSY;
goto out;
}
- /* Set the sdqcr to drain this channel */
- if (channel < qm_channel_pool1)
- qm_dqrr_sdqcr_set(&p->p,
- QM_SDQCR_TYPE_ACTIVE |
- QM_SDQCR_CHANNELS_DEDICATED);
- else
- qm_dqrr_sdqcr_set(&p->p,
- QM_SDQCR_TYPE_ACTIVE |
- QM_SDQCR_CHANNELS_POOL_CONV
- (channel));
do {
/* Keep draining DQRR while checking the MR*/
qm_dqrr_drain_nomatch(&p->p);
@@ -2889,13 +2884,10 @@ qman_shutdown_fq(struct qman_fq *fq)
cpu_relax();
} while (!found_fqrn);
/* Restore SDQCR */
- qm_dqrr_sdqcr_set(&p->p,
- p->sdqcr);
- }
- if (res != QM_MCR_RESULT_OK &&
- res != QM_MCR_RESULT_PENDING) {
- DPAA_BUS_ERR("retire_fq failed: FQ 0x%x, res=0x%x",
- fqid, res);
+ if (sdqcr != p->sdqcr)
+ qm_dqrr_sdqcr_set(&p->p, p->sdqcr);
+ } else {
+ DPAA_BUS_ERR("retire_fq failed: FQ 0x%x, res=0x%x", fqid, res);
ret = -EIO;
goto out;
}
diff --git a/drivers/bus/dpaa/base/qbman/qman_driver.c b/drivers/bus/dpaa/base/qbman/qman_driver.c
index 3bab8b8337..0fcaa270ce 100644
--- a/drivers/bus/dpaa/base/qbman/qman_driver.c
+++ b/drivers/bus/dpaa/base/qbman/qman_driver.c
@@ -17,9 +17,10 @@
* where CCSR isn't available).
*/
u16 qman_ip_rev;
-u16 qm_channel_pool1 = QMAN_CHANNEL_POOL1;
-u16 qm_channel_caam = QMAN_CHANNEL_CAAM;
-u16 qm_channel_pme = QMAN_CHANNEL_PME;
+static u16 qm_channel_pool1 = QMAN_CHANNEL_POOL1;
+static u16 qm_channel_caam = QMAN_CHANNEL_CAAM;
+static u16 qm_channel_pme = QMAN_CHANNEL_PME;
+static u16 qm_channel_pool_num;
/* Ccsr map address to access ccsrbased register */
static void *qman_ccsr_map;
@@ -65,6 +66,11 @@ u16 dpaa_get_qm_channel_pool(void)
return qm_channel_pool1;
}
+u16 dpaa_get_qm_channel_pool_num(void)
+{
+ return qm_channel_pool_num;
+}
+
static int fsl_qman_portal_init(uint32_t index, int is_shared)
{
struct qman_portal *portal;
@@ -275,7 +281,7 @@ int qman_global_init(void)
uint64_t phys_addr;
uint64_t regs_size;
const u32 *clk;
-
+ u16 pool_channel;
static int done;
if (done)
@@ -336,6 +342,21 @@ int qman_global_init(void)
return -EINVAL;
}
+ if (lenp != sizeof(rte_be32_t) * 2) {
+ pr_err("pool-channel-range should have 2 items.\n");
+ return -EINVAL;
+ }
+ pool_channel = rte_be_to_cpu_32(chanid[0]);
+ qm_channel_pool_num = rte_be_to_cpu_32(chanid[1]);
+
+ if (pool_channel != qm_channel_pool1) {
+ pr_warn("Pool channel(%04x) configured != default(0x%04x)\n",
+ pool_channel, qm_channel_pool1);
+ }
+ qm_channel_pool1 = pool_channel;
+ pr_debug("Pool channel starts from 0x%04x, number=%d, lenp:%zu\n",
+ qm_channel_pool1, qm_channel_pool_num, lenp);
+
/* get ccsr base */
dt_node = of_find_compatible_node(NULL, NULL, "fsl,qman");
if (!dt_node) {
diff --git a/drivers/bus/dpaa/dpaa_bus_base_symbols.c b/drivers/bus/dpaa/dpaa_bus_base_symbols.c
index 522cdca27e..52abec2b4c 100644
--- a/drivers/bus/dpaa/dpaa_bus_base_symbols.c
+++ b/drivers/bus/dpaa/dpaa_bus_base_symbols.c
@@ -1,5 +1,6 @@
/* SPDX-License-Identifier: BSD-3-Clause
* Copyright (c) 2025 Red Hat, Inc.
+ * Copyright 2026 NXP
*/
#include <eal_export.h>
@@ -94,6 +95,7 @@ RTE_EXPORT_INTERNAL_SYMBOL(qman_create_cgr)
RTE_EXPORT_INTERNAL_SYMBOL(qman_delete_cgr)
RTE_EXPORT_INTERNAL_SYMBOL(dpaa_get_qm_channel_caam)
RTE_EXPORT_INTERNAL_SYMBOL(dpaa_get_qm_channel_pool)
+RTE_EXPORT_INTERNAL_SYMBOL(dpaa_get_qm_channel_pool_num)
RTE_EXPORT_INTERNAL_SYMBOL(qman_thread_fd)
RTE_EXPORT_INTERNAL_SYMBOL(qman_thread_irq)
RTE_EXPORT_INTERNAL_SYMBOL(qman_fq_portal_thread_irq)
diff --git a/drivers/bus/dpaa/include/fsl_qman.h b/drivers/bus/dpaa/include/fsl_qman.h
index 673859ed2e..bd46207232 100644
--- a/drivers/bus/dpaa/include/fsl_qman.h
+++ b/drivers/bus/dpaa/include/fsl_qman.h
@@ -1,7 +1,7 @@
/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
*
* Copyright 2008-2012 Freescale Semiconductor, Inc.
- * Copyright 2019-2022 NXP
+ * Copyright 2019-2022, 2026 NXP
*
*/
@@ -35,9 +35,6 @@ extern "C" {
#define QMAN_CHANNEL_POOL1_REV3 0x401
#define QMAN_CHANNEL_CAAM_REV3 0x840
#define QMAN_CHANNEL_PME_REV3 0x860
-extern u16 qm_channel_pool1;
-extern u16 qm_channel_caam;
-extern u16 qm_channel_pme;
enum qm_dc_portal {
qm_dc_portal_fman0 = 0,
qm_dc_portal_fman1 = 1,
@@ -51,6 +48,9 @@ u16 dpaa_get_qm_channel_caam(void);
__rte_internal
u16 dpaa_get_qm_channel_pool(void);
+__rte_internal
+u16 dpaa_get_qm_channel_pool_num(void);
+
/* Portal processing (interrupt) sources */
#define QM_PIRQ_CCSCI 0x00200000 /* CEETM Congestion State Change */
#define QM_PIRQ_CSCI 0x00100000 /* Congestion State Change */
--
2.25.1
^ permalink raw reply related
* [PATCH v4 08/19] bus/dpaa: enhance DPAA FQ shutdown
From: Hemant Agrawal @ 2026-06-21 17:27 UTC (permalink / raw)
To: stephen, david.marchand, dev; +Cc: Gagandeep Singh
In-Reply-To: <20260621172731.2916346-1-hemant.agrawal@nxp.com>
From: Gagandeep Singh <g.singh@nxp.com>
Improve the FQ shutdown sequence to handle edge cases more
robustly, including better handling of ORL (Order Restoration
List) presence and improved error recovery paths.
Signed-off-by: Gagandeep Singh <g.singh@nxp.com>
---
drivers/bus/dpaa/base/qbman/qman.c | 80 ++++++++++++++++++++++--------
1 file changed, 59 insertions(+), 21 deletions(-)
diff --git a/drivers/bus/dpaa/base/qbman/qman.c b/drivers/bus/dpaa/base/qbman/qman.c
index 42618c1ab4..ba7db78ca0 100644
--- a/drivers/bus/dpaa/base/qbman/qman.c
+++ b/drivers/bus/dpaa/base/qbman/qman.c
@@ -1,7 +1,7 @@
/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
*
* Copyright 2008-2016 Freescale Semiconductor Inc.
- * Copyright 2017,2019-2025 NXP
+ * Copyright 2017,2019-2026 NXP
*
*/
@@ -2840,9 +2840,10 @@ qman_shutdown_fq(struct qman_fq *fq)
}
res = mcr->result; /* Make a copy as we reuse MCR below */
- if (res == QM_MCR_RESULT_OK) {
+ if (res == QM_MCR_RESULT_OK)
drain_mr_fqrni(&p->p);
- } else if (res == QM_MCR_RESULT_PENDING) {
+
+ if (res == QM_MCR_RESULT_PENDING) {
/*
* Need to wait for the FQRN in the message ring, which
* will only occur once the FQ has been drained. In
@@ -2850,28 +2851,29 @@ qman_shutdown_fq(struct qman_fq *fq)
* to dequeue from the channel the FQ is scheduled on
*/
int found_fqrn = 0;
- const u16 pool_ch_start = dpaa_get_qm_channel_pool();
- const u16 pool_ch_end = pool_ch_start + dpaa_get_qm_channel_pool_num();
- u32 sdqcr = p->sdqcr;
/* Flag that we need to drain FQ */
drain = 1;
+ const u16 pool_ch_start = dpaa_get_qm_channel_pool();
+ const u16 pool_ch_end = pool_ch_start +
+ dpaa_get_qm_channel_pool_num();
if (channel >= pool_ch_start && channel < pool_ch_end) {
- /* Pool channel, enable the bit in the portal */
+ /* Pool channel - must use affine portal */
if (p->config->channel != channel) {
- DPAA_BUS_ERR("Portal affine channel(0x%04x) != wq channel(0x%04x)",
+ DPAA_BUS_ERR("Portal ch(0x%04x) != FQ ch(0x%04x)",
p->config->channel, channel);
ret = -EINVAL;
goto out;
}
} else if (channel < pool_ch_start) {
/* Dedicated channel */
- sdqcr = QM_SDQCR_TYPE_ACTIVE | QM_SDQCR_CHANNELS_DEDICATED;
- qm_dqrr_sdqcr_set(&p->p, sdqcr);
+ qm_dqrr_sdqcr_set(&p->p,
+ QM_SDQCR_TYPE_ACTIVE |
+ QM_SDQCR_CHANNELS_DEDICATED);
} else {
- DPAA_BUS_ERR("Can't recover FQ 0x%x, Invalid channel: 0x%x",
- fqid, channel);
+ DPAA_BUS_ERR("Invalid channel 0x%x for FQ 0x%x",
+ channel, fqid);
ret = -EBUSY;
goto out;
}
@@ -2879,15 +2881,16 @@ qman_shutdown_fq(struct qman_fq *fq)
/* Keep draining DQRR while checking the MR*/
qm_dqrr_drain_nomatch(&p->p);
/* Process message ring too */
- found_fqrn = qm_mr_drain(&p->p,
- FQRN);
+ found_fqrn = qm_mr_drain(&p->p, FQRN);
cpu_relax();
} while (!found_fqrn);
- /* Restore SDQCR */
- if (sdqcr != p->sdqcr)
- qm_dqrr_sdqcr_set(&p->p, p->sdqcr);
- } else {
- DPAA_BUS_ERR("retire_fq failed: FQ 0x%x, res=0x%x", fqid, res);
+ qm_dqrr_sdqcr_set(&p->p, p->sdqcr);
+
+ }
+ if (res != QM_MCR_RESULT_OK &&
+ res != QM_MCR_RESULT_PENDING) {
+ DPAA_BUS_ERR("retire_fq failed: FQ 0x%x, res=0x%x",
+ fqid, res);
ret = -EIO;
goto out;
}
@@ -2930,7 +2933,7 @@ qman_shutdown_fq(struct qman_fq *fq)
if (mcr->result != QM_MCR_RESULT_OK) {
DPAA_BUS_ERR("OOS after drain fail: FQ 0x%x (0x%x)",
- fqid, mcr->result);
+ fqid, mcr->result);
ret = -EIO;
goto out;
}
@@ -2949,7 +2952,7 @@ qman_shutdown_fq(struct qman_fq *fq)
if (mcr->result != QM_MCR_RESULT_OK) {
DPAA_BUS_ERR("OOS fail: FQ 0x%x (0x%x)",
- fqid, mcr->result);
+ fqid, mcr->result);
ret = -EIO;
goto out;
}
@@ -2966,3 +2969,38 @@ qman_shutdown_fq(struct qman_fq *fq)
out:
return ret;
}
+
+int qman_find_fq_by_cgrid(u32 cgrid, u32 *fqid)
+{
+ struct qman_fq fq = {
+ .fqid = 1
+ };
+ struct qm_mcr_queryfq_np np;
+ struct qm_fqd fqd;
+ int err;
+
+ do {
+ err = qman_query_fq_np(&fq, &np);
+ if (err == -ERANGE) {
+ DPAA_BUS_INFO("No FQ found with cgrid(0x%x)", cgrid);
+ return err;
+ } else if (err) {
+ DPAA_BUS_WARN("Failed(%d) to Query np FQ(fqid=0x%x)", err, fq.fqid);
+ return err;
+ }
+ if ((np.state & QM_MCR_NP_STATE_MASK) != QM_MCR_NP_STATE_OOS) {
+ err = qman_query_fq(&fq, &fqd);
+ if (err) {
+ DPAA_BUS_WARN("Failed(%d) to Query FQ(fqid=0x%x)", err, fq.fqid);
+ } else if ((fqd.fq_ctrl & QM_FQCTRL_CGE) && fqd.cgid == cgrid) {
+ if (fqid)
+ *fqid = fq.fqid;
+ return 0;
+ }
+ }
+ /* Move to the next FQID */
+ fq.fqid++;
+ } while (1);
+
+ return -ENODEV;
+}
--
2.25.1
^ permalink raw reply related
* [PATCH v4 09/19] drivers: add DPAA cgrid cleanup support
From: Hemant Agrawal @ 2026-06-21 17:27 UTC (permalink / raw)
To: stephen, david.marchand, dev; +Cc: Jun Yang
In-Reply-To: <20260621172731.2916346-1-hemant.agrawal@nxp.com>
From: Jun Yang <jun.yang@nxp.com>
Add qman_find_fq_by_cgid() to find frame queues associated with
a given CGID. This allows the driver to verify that all FQs
using a CGR are shut down before releasing the CGR ID, preventing
use-after-free of CGR resources.
Signed-off-by: Jun Yang <jun.yang@nxp.com>
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
drivers/bus/dpaa/dpaa_bus_base_symbols.c | 1 +
drivers/bus/dpaa/include/fsl_qman.h | 3 +++
drivers/net/dpaa/dpaa_ethdev.c | 29 ++++++++++++++++++++++--
3 files changed, 31 insertions(+), 2 deletions(-)
diff --git a/drivers/bus/dpaa/dpaa_bus_base_symbols.c b/drivers/bus/dpaa/dpaa_bus_base_symbols.c
index 52abec2b4c..514ab7b1f1 100644
--- a/drivers/bus/dpaa/dpaa_bus_base_symbols.c
+++ b/drivers/bus/dpaa/dpaa_bus_base_symbols.c
@@ -56,6 +56,7 @@ RTE_EXPORT_INTERNAL_SYMBOL(qman_reserve_fqid_range)
RTE_EXPORT_INTERNAL_SYMBOL(qman_alloc_pool_range)
RTE_EXPORT_INTERNAL_SYMBOL(qman_alloc_cgrid_range)
RTE_EXPORT_INTERNAL_SYMBOL(qman_release_cgrid_range)
+RTE_EXPORT_INTERNAL_SYMBOL(qman_find_fq_by_cgrid)
RTE_EXPORT_INTERNAL_SYMBOL(dpaa_intr_enable)
RTE_EXPORT_INTERNAL_SYMBOL(dpaa_intr_disable)
RTE_EXPORT_INTERNAL_SYMBOL(dpaa_get_ioctl_version_number)
diff --git a/drivers/bus/dpaa/include/fsl_qman.h b/drivers/bus/dpaa/include/fsl_qman.h
index bd46207232..20321ed355 100644
--- a/drivers/bus/dpaa/include/fsl_qman.h
+++ b/drivers/bus/dpaa/include/fsl_qman.h
@@ -1907,6 +1907,9 @@ static inline int qman_shutdown_fq_by_fqid(u32 fqid)
return qman_shutdown_fq(&fq);
}
+__rte_internal
+int qman_find_fq_by_cgrid(u32 cgrid, u32 *fqid);
+
/**
* qman_reserve_fqid_range - Reserve the specified range of frame queue IDs
* @fqid: the base FQID of the range to deallocate
diff --git a/drivers/net/dpaa/dpaa_ethdev.c b/drivers/net/dpaa/dpaa_ethdev.c
index 94758c2748..ab5a50e760 100644
--- a/drivers/net/dpaa/dpaa_ethdev.c
+++ b/drivers/net/dpaa/dpaa_ethdev.c
@@ -513,7 +513,7 @@ static int dpaa_eth_dev_close(struct rte_eth_dev *dev)
struct rte_eth_link *link = &dev->data->dev_link;
struct dpaa_if *dpaa_intf = dev->data->dev_private;
struct qman_fq *fq;
- int loop;
+ uint32_t fqid, loop;
int ret;
PMD_INIT_FUNC_TRACE();
@@ -576,28 +576,53 @@ static int dpaa_eth_dev_close(struct rte_eth_dev *dev)
/* release configuration memory */
rte_free(dpaa_intf->fc_conf);
+ /** Release congestion Groups after releasing FQIDs*/
/* Release RX congestion Groups */
if (dpaa_intf->cgr_rx) {
for (loop = 0; loop < dpaa_intf->nb_rx_queues; loop++) {
+ ret = qman_find_fq_by_cgrid(dpaa_intf->cgr_rx[loop].cgrid, &fqid);
+ if (!ret) {
+ /** Should be FQ not cleaned in previous program.*/
+ DPAA_PMD_DEBUG("FQ(fqid=0x%x) with rx cgid=%d is still alive?",
+ fqid, dpaa_intf->cgr_rx[loop].cgrid);
+ ret = qman_shutdown_fq_by_fqid(fqid);
+ if (ret) {
+ DPAA_PMD_WARN("Failed(%d) to shutdown fq(fqid=0x%x)",
+ ret, fqid);
+ }
+ }
ret = qman_delete_cgr(&dpaa_intf->cgr_rx[loop]);
if (ret) {
DPAA_PMD_WARN("%s: delete rxq%d's cgr err(%d)",
dev->data->name, loop, ret);
}
}
+ qman_release_cgrid_range(dpaa_intf->cgr_rx[0].cgrid, dpaa_intf->nb_rx_queues);
rte_free(dpaa_intf->cgr_rx);
dpaa_intf->cgr_rx = NULL;
}
/* Release TX congestion Groups */
if (dpaa_intf->cgr_tx) {
- for (loop = 0; loop < MAX_DPAA_CORES; loop++) {
+ for (loop = 0; loop < dpaa_intf->nb_tx_queues; loop++) {
+ ret = qman_find_fq_by_cgrid(dpaa_intf->cgr_tx[loop].cgrid, &fqid);
+ if (!ret) {
+ /** Should be FQ not cleaned in previous program.*/
+ DPAA_PMD_DEBUG("FQ(fqid=0x%x) with tx cgid=%d is still alive?",
+ fqid, dpaa_intf->cgr_tx[loop].cgrid);
+ ret = qman_shutdown_fq_by_fqid(fqid);
+ if (ret) {
+ DPAA_PMD_WARN("Failed(%d) to shutdown fq(fqid=0x%x)",
+ ret, fqid);
+ }
+ }
ret = qman_delete_cgr(&dpaa_intf->cgr_tx[loop]);
if (ret) {
DPAA_PMD_WARN("%s: delete txq%d's cgr err(%d)",
dev->data->name, loop, ret);
}
}
+ qman_release_cgrid_range(dpaa_intf->cgr_tx[0].cgrid, dpaa_intf->nb_tx_queues);
rte_free(dpaa_intf->cgr_tx);
dpaa_intf->cgr_tx = NULL;
}
--
2.25.1
^ permalink raw reply related
* [PATCH v4 10/19] net/dpaa: clean Tx confirmation FQ on device stop
From: Hemant Agrawal @ 2026-06-21 17:27 UTC (permalink / raw)
To: stephen, david.marchand, dev
In-Reply-To: <20260621172731.2916346-1-hemant.agrawal@nxp.com>
Ensure the Tx confirmation FQ is also cleaned up during device
stop, preventing stale FQ state on subsequent device restarts.
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
drivers/net/dpaa/dpaa_ethdev.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/drivers/net/dpaa/dpaa_ethdev.c b/drivers/net/dpaa/dpaa_ethdev.c
index ab5a50e760..314237b25a 100644
--- a/drivers/net/dpaa/dpaa_ethdev.c
+++ b/drivers/net/dpaa/dpaa_ethdev.c
@@ -575,6 +575,7 @@ static int dpaa_eth_dev_close(struct rte_eth_dev *dev)
/* release configuration memory */
rte_free(dpaa_intf->fc_conf);
+ dpaa_intf->fc_conf = NULL;
/** Release congestion Groups after releasing FQIDs*/
/* Release RX congestion Groups */
@@ -644,6 +645,10 @@ static int dpaa_eth_dev_close(struct rte_eth_dev *dev)
rte_free(dpaa_intf->tx_queues);
dpaa_intf->tx_queues = NULL;
+
+ rte_free(dpaa_intf->tx_conf_queues);
+ dpaa_intf->tx_conf_queues = NULL;
+
if (dpaa_intf->port_handle) {
ret = dpaa_fm_deconfig(dpaa_intf, fif);
if (ret) {
@@ -2538,6 +2543,8 @@ dpaa_dev_init(struct rte_eth_dev *eth_dev)
return 0;
free_tx:
+ rte_free(dpaa_intf->tx_conf_queues);
+ dpaa_intf->tx_conf_queues = NULL;
rte_free(dpaa_intf->tx_queues);
dpaa_intf->tx_queues = NULL;
dpaa_intf->nb_tx_queues = 0;
--
2.25.1
^ permalink raw reply related
* [PATCH v4 11/19] net/dpaa: remove redundant FQ shutdown from Rx queue setup
From: Hemant Agrawal @ 2026-06-21 17:27 UTC (permalink / raw)
To: stephen, david.marchand, dev
In-Reply-To: <20260621172731.2916346-1-hemant.agrawal@nxp.com>
Remove the redundant qman_shutdown_fq() call from
dpaa_eth_rx_queue_setup(). The FQ is shut down during device stop,
so calling it again at queue setup time is unnecessary and may
interfere with a clean queue initialization.
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
drivers/net/dpaa/dpaa_ethdev.c | 3 ---
1 file changed, 3 deletions(-)
diff --git a/drivers/net/dpaa/dpaa_ethdev.c b/drivers/net/dpaa/dpaa_ethdev.c
index 314237b25a..5ef3fcdb48 100644
--- a/drivers/net/dpaa/dpaa_ethdev.c
+++ b/drivers/net/dpaa/dpaa_ethdev.c
@@ -1158,9 +1158,6 @@ int dpaa_eth_rx_queue_setup(struct rte_eth_dev *dev, uint16_t queue_idx,
DPAA_PMD_INFO("Rx queue setup for queue index: %d fq_id (0x%x)",
queue_idx, rxq->fqid);
- /* Shutdown FQ before configure */
- qman_shutdown_fq(rxq->fqid);
-
if (!fif->num_profiles) {
if (dpaa_intf->bp_info && dpaa_intf->bp_info->bp &&
dpaa_intf->bp_info->mp != mp) {
--
2.25.1
^ permalink raw reply related
* [PATCH v4 12/19] net/dpaa: optimize FM deconfig
From: Hemant Agrawal @ 2026-06-21 17:27 UTC (permalink / raw)
To: stephen, david.marchand, dev
In-Reply-To: <20260621172731.2916346-1-hemant.agrawal@nxp.com>
Consolidate FM deconfiguration to avoid duplicate calls.
Move the fm_deconfig call to a single location and remove
redundant checks in the device close path.
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
drivers/net/dpaa/dpaa_ethdev.c | 27 +++++++++++++++++++++++----
drivers/net/dpaa/dpaa_flow.c | 9 +++++----
2 files changed, 28 insertions(+), 8 deletions(-)
diff --git a/drivers/net/dpaa/dpaa_ethdev.c b/drivers/net/dpaa/dpaa_ethdev.c
index 5ef3fcdb48..2e3757ca03 100644
--- a/drivers/net/dpaa/dpaa_ethdev.c
+++ b/drivers/net/dpaa/dpaa_ethdev.c
@@ -528,10 +528,12 @@ static int dpaa_eth_dev_close(struct rte_eth_dev *dev)
/* DPAA FM deconfig */
if (!(default_q || fmc_q)) {
- ret = dpaa_fm_deconfig(dpaa_intf, dev->process_private);
- if (ret) {
- DPAA_PMD_WARN("%s: FM deconfig failed(%d)",
- dev->data->name, ret);
+ if (dpaa_intf->port_handle) {
+ ret = dpaa_fm_deconfig(dpaa_intf, dev->process_private);
+ if (ret) {
+ DPAA_PMD_WARN("%s: FM deconfig failed(%d)",
+ dev->data->name, ret);
+ }
}
}
@@ -577,6 +579,23 @@ static int dpaa_eth_dev_close(struct rte_eth_dev *dev)
rte_free(dpaa_intf->fc_conf);
dpaa_intf->fc_conf = NULL;
+ /** For FMCLESS mode of share MAC, deconfig FM to direct
+ * ingress traffic to kernel before fq shutdown.
+ */
+ if (!(default_q || fmc_q) && dpaa_intf->port_handle) {
+ ret = dpaa_fm_deconfig(dpaa_intf, dev->process_private);
+ if (ret) {
+ DPAA_PMD_WARN("%s: FM deconfig failed(%d)",
+ dev->data->name, ret);
+ }
+ }
+ if (fif->num_profiles) {
+ ret = dpaa_port_vsp_cleanup(dpaa_intf, fif);
+ if (ret) {
+ DPAA_PMD_WARN("%s: cleanup VSP failed(%d)",
+ dev->data->name, ret);
+ }
+ }
/** Release congestion Groups after releasing FQIDs*/
/* Release RX congestion Groups */
if (dpaa_intf->cgr_rx) {
diff --git a/drivers/net/dpaa/dpaa_flow.c b/drivers/net/dpaa/dpaa_flow.c
index 417b9b6fbb..559850ced7 100644
--- a/drivers/net/dpaa/dpaa_flow.c
+++ b/drivers/net/dpaa/dpaa_flow.c
@@ -724,6 +724,9 @@ int dpaa_fm_deconfig(struct dpaa_if *dpaa_intf,
PMD_INIT_FUNC_TRACE();
+ if (!dpaa_intf->port_handle)
+ return 0;
+
/* FM PORT Disable */
ret = fm_port_disable(dpaa_intf->port_handle);
if (ret != E_OK) {
@@ -783,10 +786,8 @@ int dpaa_fm_config(struct rte_eth_dev *dev, uint64_t req_dist_set)
unsigned int i = 0;
PMD_INIT_FUNC_TRACE();
- if (dpaa_intf->port_handle) {
- if (dpaa_fm_deconfig(dpaa_intf, fif))
- DPAA_PMD_ERR("DPAA FM deconfig failed");
- }
+ if (dpaa_fm_deconfig(dpaa_intf, fif))
+ DPAA_PMD_ERR("DPAA FM deconfig failed");
if (!dev->data->nb_rx_queues)
return 0;
--
2.25.1
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox