* Re: [PATCH] app/testpmd: add VLAN priority insert support
From: Stephen Hemminger @ 2026-06-15 19:12 UTC (permalink / raw)
To: Xingui Yang
Cc: dev, david.marchand, aman.deep.singh, fengchengwen, yangshuaisong,
lihuisong, liuyonglong, kangfenglong
In-Reply-To: <20260612081411.2798403-1-yangxingui@huawei.com>
On Fri, 12 Jun 2026 16:14:11 +0800
Xingui Yang <yangxingui@huawei.com> wrote:
> The tx_vlan set command currently only accepts a VLAN ID in range
> [0, 4095]. This patch adds support for an extended format that includes
> 802.1p priority and CFI bits, allowing users to set the VLAN priority
> tag when inserting VLAN headers in TX packets.
>
> The extended format is:
> bit 0-11: VLAN ID (0-4095)
> bit 12: CFI (Canonical Format Indicator)
> bit 13-15: Priority (0-7, 802.1p CoS)
>
> This is consistent with the VLAN tag structure used by
> rte_eth_dev_set_vlan_pvid() where the PVID field encodes VLAN ID, CFI
> and priority in the same format.
>
> A new command line option --enable-vlan-priority is added to enable this
> feature. By default, the feature is disabled to maintain backward
> compatibility with existing users. When enabled, the
> vlan_id_is_invalid() function allows any 16-bit value to pass, while the
> full 16-bit value (including CFI and priority bits) is passed to the
> driver for hardware VLAN insertion.
>
> Signed-off-by: Xingui Yang <yangxingui@huawei.com>
> ---
Having ability to set priority bits is good, and testpmd should allow it.
The mbuf vlan_tci is already a full 16-bit TCI (priority/CFI/VID), and
the TX insert path copies tx_vlan_id straight into it. So priority
insert already works; the only thing in the way is the < 4096 check.
Do you actually need a new option for this? Both of_push_vlan +
of_set_vlan_pcp (rte_flow) and "tx_vlan set pvid" already let you set
the priority bits today, with no new code.
If you still want "tx_vlan set" itself to carry priority, I'd suggest
a smaller change: relax only the TX insert validators and drop the
option and the global. Don't touch rx_vft_set -- it feeds the VLAN
filter, which only takes a VLAN ID and rejects > 4095 anyway, so the
flag just turns a clear error into a confusing one.
Either way, if the option stays, please document it, and add a release note.
The commit message why the existing paths aren't enough.
^ permalink raw reply
* Re: [PATCH v4 0/6] net/gve: add hardware timestamping support
From: Stephen Hemminger @ 2026-06-15 18:53 UTC (permalink / raw)
To: Mark Blasko; +Cc: dev, joshwash, jtranoleary
In-Reply-To: <20260613042300.3760470-1-blasko@google.com>
On Sat, 13 Jun 2026 04:22:33 +0000
Mark Blasko <blasko@google.com> wrote:
> This patch series introduces support for GVE hardware timestamping
> on DQO queues. To support concurrent access, a mutex lock is introduced
> to protect admin queue operations. A mechanism is then added to
> periodically synchronize the NIC clock via a dedicated control thread,
> and support is introduced for the read_clock ethdev operation.
> Finally, the RX datapath is updated to reconstruct full 64-bit
> timestamps from the 32-bit values in DQO descriptors.
>
> ---
AI spotted several issues...
Reviewed the v3 series against current main. Findings on 4/6 and 5/6
below; patches 1, 2, 3, and 6 look good.
[PATCH v3 4/6] net/gve: add periodic NIC clock synchronization
Warning: gve_read_nic_clock() runs as an rte_alarm callback, i.e. on the
shared EAL interrupt thread, and calls gve_adminq_report_nic_timestamp()
-> gve_adminq_kick_and_wait(), which busy-waits via rte_delay_ms() up to
GVE_MAX_ADMINQ_EVENT_COUNTER_CHECK * GVE_ADMINQ_SLEEP_LEN = 100 * 20ms =
2s on an AdminQ timeout (tens of ms in the normal case). Blocking the
interrupt thread that long stalls link-status/reset detection and every
other device's interrupt and alarm handling for the whole process. The
existing gve_check_device_status() alarm only does a single ioread32be(),
so this is new behavior for the driver. Consider running the periodic
read off a dedicated control thread, or otherwise bounding the time spent
on the interrupt thread.
The teardown ordering itself is fine: rte_eal_alarm_cancel() is called
before gve_free_nic_ts_report(), and its spin-until-not-executing
semantics catch the self-rescheduled alarm, since the new entry is queued
during the callback before the dispatcher removes the executing one. No
use-after-free on the memzone there.
[PATCH v3 5/6] net/gve: support read clock ethdev op
Error: priv->nic_ts_lock is locked before it is initialized. In
gve_dev_init() the order is:
err = gve_init_priv(priv, false);
...
pthread_mutex_init(&priv->nic_ts_lock, &mutexattr);
but gve_init_priv() -> gve_setup_device_resources() ->
gve_setup_nic_timestamp() calls gve_read_nic_clock() synchronously when
the device reports NIC-timestamp support, and after this patch
gve_read_nic_clock() takes priv->nic_ts_lock. So on timestamp-capable
hardware the first lock runs on an uninitialized mutex, and the later
pthread_mutex_init() then re-initializes an already-used mutex - both
undefined behavior. It only appears to work because dev_private is zeroed
(a zeroed pthread_mutex_t happens to be a valid default mutex on glibc).
Initialize nic_ts_lock (and the mutexattr) before the gve_init_priv()
call.
Error: priv->nic_ts_lock is destroyed before the alarm that uses it is
cancelled. In gve_dev_close():
pthread_mutex_destroy(&priv->nic_ts_lock);
gve_free_queues(dev);
gve_teardown_device_resources(priv); /* cancels gve_read_nic_clock alarm */
The periodic gve_read_nic_clock() alarm is still armed when the mutex is
destroyed, and that callback locks nic_ts_lock; if it fires in the window
before gve_teardown_device_resources() cancels it, it locks a destroyed
mutex. Move the pthread_mutex_destroy(&priv->nic_ts_lock) to after
gve_teardown_device_resources() returns.
The two 5/6 errors are the same root cause from opposite ends: the
nic_ts_lock lifetime needs to bracket all its users - initialized before
the synchronous setup-time read, and destroyed only after the alarm is
cancelled.
^ permalink raw reply
* Re: [PATCH v9 0/1] net/mana: add device reset support
From: Stephen Hemminger @ 2026-06-15 18:50 UTC (permalink / raw)
To: Wei Hu; +Cc: dev, longli, weh
In-Reply-To: <20260612081723.27699-1-weh@linux.microsoft.com>
On Fri, 12 Jun 2026 01:17:22 -0700
Wei Hu <weh@linux.microsoft.com> wrote:
> From: Wei Hu <weh@microsoft.com>
>
> Add support for handling hardware service reset events in the
> MANA driver. When the MANA kernel driver receives a hardware
> service event, it initiates a device reset and notifies userspace
> via IBV_EVENT_DEVICE_FATAL. The MANA PMD handles this by
> performing an automatic teardown and recovery sequence.
>
> The driver uses ethdev recovery events (ERR_RECOVERING,
> RECOVERY_SUCCESS, RECOVERY_FAILED) to notify upper layers of
> the reset lifecycle, and a PCI device removal event callback
> to distinguish hot-remove from service reset.
>
> Changes since v8:
> - Fixed reset thread resource leak: previously reset_thread_active
> was cleared before emitting recovery callbacks, so no join site
> would reap the thread. Now the flag stays true throughout the
> thread lifetime. mana_join_reset_thread detects the self-join
> case (callback calling dev_stop/dev_close from the reset thread)
> using rte_thread_equal and calls rte_thread_detach instead of
> join, so thread resources are freed on exit. External callers
> continue to join normally.
> - Fixed lost condvar signal: added a predicate loop around
> pthread_cond_timedwait that checks dev_state under
> reset_cond_mutex. If mana_pci_remove_event_cb signals before
> the reset thread enters the wait, the wakeup is no longer lost.
> The PCI remove callback sets dev_state to RESET_FAILED under
> the same mutex before signaling.
> - Added a lock/unlock barrier on reset_ops_lock in
> mana_pci_remove_event_cb to ensure teardown has completed
> before emitting the INTR_RMV event.
> - Fixed mana_reset_exit_delay return type from uint32_t to int
> to match the negative error codes it stores.
> - Removed unnecessary else-after-goto in mana_probe_port.
>
> Changes since v7:
> - Moved heavy teardown (dev_stop, IPC to secondaries, dev_close,
> MR btree free) from mana_reset_enter (EAL interrupt thread)
> to mana_reset_thread (control thread). The interrupt handler
> now only sets state, drains in-flight bursts, and spawns the
> thread. Teardown runs immediately in the control thread before
> the recovery timer wait, avoiding blocking the interrupt thread
> on multi-second IPC timeouts and ibverbs calls. Each function
> now owns its own lock scope with no lock hand-off between
> threads.
> - Simplified burst_state from encoding device state in bits 1+
> to a single blocked flag (bit 1). Only one value was ever
> stored, so the multi-state encoding was misleading. Added
> MANA_BURST_BLOCKED constant.
> - Updated mana.rst to reflect that teardown runs on the control
> thread, not the interrupt handler.
>
> Changes since v6:
> - Rebased onto latest upstream for-main
> - Replaced removed RTE_ETH_DEV_TO_PCI macro with
> RTE_CLASS_TO_BUS_DEVICE (upstream commit 4757b8df04
> removed the old bus-specific ethdev convenience macros)
>
> Changes since v5:
> - Replaced RCU QSBR with per-queue atomic burst_state using a
> single-variable CAS design: bit 0 is the in-burst flag, bit 1
> is the blocked flag. The data path uses CAS(0→1) to enter
> burst and fetch_and(~1) to exit. The reset path uses fetch_or
> to set the blocked bit and polls bit 0 to drain in-flight
> bursts. This eliminates the two-variable Dekker pattern and the
> need for sequential consistency (seq_cst) ordering.
> - Removed librte_rcu dependency
> - Removed __rte_no_thread_safety_analysis annotations (no longer
> needed after mutex conversion)
> - Moved ERR_RECOVERING event emission before acquiring
> reset_ops_lock and before mana_reset_enter, so upper layers
> (e.g. netvsc) can switch data path before mana stops queues.
> Emitting outside the lock avoids deadlock if the callback
> calls dev_stop or dev_close.
> - Replaced MANA_OPS_*_LOCK macros with mana_reset_trylock()
> helper function and explicit per-operation wrappers
> - Removed unused rte_alarm.h and rte_lock_annotations.h includes
> - Added RECOVERY_FAILED event when mana_reset_enter fails
> internally, so the application always receives a terminal event
> - Added mana_clear_burst_state() helper to clear per-queue
> burst_state on failure paths (reset_failed, dev_stop_lock,
> dev_close_lock) preventing permanent silent packet drop after
> a failed reset
>
> Changes since v4:
> - Fixed stale rte_spinlock_unlock call in mana_intr_handler that
> was missed during the spinlock-to-mutex conversion, causing a
> -Wincompatible-pointer-types warning
>
> Changes since v3:
> - Converted reset_ops_lock from rte_spinlock_t to pthread_mutex_t
> with PTHREAD_PROCESS_SHARED, since the lock is held across
> blocking IB verbs calls and IPC with 5s timeout
> - Removed rte_dev_event_callback_unregister retry loop to avoid
> deadlock when interrupt thread and reset thread contend
>
> Changes since v2:
> - Added per-queue burst_state atomic variable with Dekker-like
> synchronization to block data path during reset without RCU
> - Replaced rte_alarm with condvar + control thread for reset exit
> - Made reset_thread_active atomic with CAS — flag is set by
> creator and only cleared by the joiner, not the thread itself
> - Fixed second reset crash: removed reset thread join logic from
> mana_dev_close (inner function) to avoid corrupting dev_state
> when called from mana_reset_enter
> - Made reset_thread_active RTE_ATOMIC(bool) with explicit ordering
> - Added retry loop for rte_dev_event_callback_unregister on -EAGAIN
> - Initialized condvar/mutex with PTHREAD_PROCESS_SHARED since priv
> is in hugepage shared memory
> - Added re-check of dev_state after lock acquisition in
> mana_intr_handler to prevent racing with pci_remove_event_cb
> - Replaced (void *)0 with NULL in mp.c
> - Added lock ownership comment block at mana_reset_enter
> - Documented rte_dev_event_monitor_start() requirement
> - Added mana.rst documentation and release note
>
> Changes since v1:
> - Removed net/netvsc patch from this series
> - Simplified reset exit: mana_reset_exit calls
> mana_reset_exit_delay directly instead of spawning a thread
> - Added __rte_no_thread_safety_analysis annotations for clang
> - Switched to rte_thread_create_internal_control
> - Fixed declaration-after-statement style issues
> - Removed unnecessary blank lines and stale comments
>
> Wei Hu (1):
> net/mana: add device reset support
>
> doc/guides/nics/mana.rst | 40 +
> doc/guides/rel_notes/release_26_07.rst | 8 +
> drivers/net/mana/mana.c | 1088 ++++++++++++++++++++++--
> drivers/net/mana/mana.h | 52 +-
> drivers/net/mana/mp.c | 89 +-
> drivers/net/mana/mr.c | 6 +-
> drivers/net/mana/rx.c | 23 +-
> drivers/net/mana/tx.c | 44 +-
> 8 files changed, 1242 insertions(+), 108 deletions(-)
>
Looks good, one bit of AI review.
---
The self-join and the condvar wait both look right now. The reset thread keeps
reset_thread_active true for its whole life and mana_join_reset_thread is the
only place that transitions it, using rte_thread_equal to detach on the
self-call and join otherwise, so the thread is reaped exactly once with no leak
and no self-join deadlock. The predicate loop under reset_cond_mutex closes the
lost-wakeup window. Reset logic is in good shape.
One small thing in mp.c: in the RESET_EXIT secondary handler the received fd is
only closed on the branch that maps it. If proc_priv->db_page is already
non-NULL the fd from the message is leaked. Close it whenever num_fds >= 1,
outside the if/else.
---
I can merge it as is, or you can send a revision to close that minor leak.
^ permalink raw reply
* Re: [PATCH v5 4/4] net/zxdh: optimize Tx xmit pkts performance
From: Stephen Hemminger @ 2026-06-15 18:38 UTC (permalink / raw)
To: Junlong Wang; +Cc: dev
In-Reply-To: <20260615011931.940545-5-wang.junlong1@zte.com.cn>
On Mon, 15 Jun 2026 09:19:30 +0800
Junlong Wang <wang.junlong1@zte.com.cn> wrote:
> Add simple Tx xmit functions (zxdh_xmit_pkts_simple)
> for single-segment packet xmit.
>
> Signed-off-by: Junlong Wang <wang.junlong1@zte.com.cn>
> ---
Ignore the CI AI review (9 false positives) but more detailed review found:
Series review: net/zxdh Rx/Tx optimization (v5)
The v4 issues are resolved: zxdh_queue_enable_intr() now tests
!= ENABLE and assigns ENABLE (1/4), and the fix is first in the
series against the original field name so it backports cleanly; the
simple Tx path publishes the AVAIL flag through
zxdh_queue_store_flags_packed() (rte_io_wmb); zxdh_recv_single_pkts()
now compacts surviving mbufs with rcv_pkts[nb_rx] = rxm; and a packet
that fails padding no longer has a descriptor written for it. One issue
remains.
[PATCH v5 4/4] net/zxdh: optimize Tx xmit pkts performance
Error: in submit_to_backend_simple(), when pkt_padding() fails the mbuf
is leaked and a hole is left in the packed ring.
for (j = 0; j < N_PER_LOOP; ++j) {
m = *(tx_pkts + i + j);
if (unlikely(pkt_padding(m, hw) < 0)) {
vq->txq.stats.errors++;
continue;
}
(dxp + i + j)->cookie = (void *)m;
tx1(vq, txdp + i + j, m, id + i + j);
zxdh_update_packet_stats(&vq->txq.stats, m);
}
pkt_padding() returns -1 when rte_pktmbuf_prepend() finds less headroom
than dl_net_hdr_len. On that path the loop does continue, so m is never
freed and never enqueued, yet zxdh_xmit_pkts_simple() advances
vq_avail_idx / decrements vq_free_cnt by the full count and returns
nb_pkts. The application sees the packet as accepted and will not free
it -> mbuf leak.
The descriptor at txdp[id+i+j] is also left untouched, so its flags
keep the AVAIL bit from the previous ring pass while the surrounding
slots carry the current generation. The device consumes packed
descriptors in order and stops at the first slot whose AVAIL bit does
not match the current wrap, so it stalls at the hole; the
already-published packets behind it are never processed and their
cookies never reclaimed. A single padding failure can wedge the Tx
queue.
If pkt_padding() cannot fail in the simple path (single-segment, full
headroom guaranteed), the error handling is dead code and the branch
should be dropped. If it can fail, it must not desync the ring: free m
and stop the burst at the first failure, submitting only the
contiguous successfully-padded prefix and returning that count, rather
than skipping a slot mid-run.
^ permalink raw reply
* Re: [PATCH v2 03/20] drivers: add supported packet types get callback
From: Stephen Hemminger @ 2026-06-15 18:32 UTC (permalink / raw)
To: liujie5; +Cc: dev
In-Reply-To: <20260614092328.201826-6-liujie5@linkdatatechnology.com>
On Sun, 14 Jun 2026 17:23:07 +0800
liujie5@linkdatatechnology.com wrote:
> From: Jie Liu <liujie5@linkdatatechnology.com>
>
> Implement dev_supported_ptypes_get ethdev callback for sxe2 PMD.
> This allows applications to query the packet types the driver
> is capable of identifying, such as L2, L3 (IPv4/IPv6), and
> L4 (TCP/UDP/SCTP) layers.
>
> Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
> ---
This patch has lots of other changes like link state.
> +static inline const uint32_t *
> +sxe2_dev_supported_ptypes_get(struct rte_eth_dev *dev, size_t *no_of_elements)
> +{
> + const uint32_t *ret = NULL;
> +
> + static const uint32_t ptypes[] = {
> + RTE_PTYPE_L2_ETHER,
> + RTE_PTYPE_L2_ETHER_TIMESYNC,
> + RTE_PTYPE_L2_ETHER_LLDP,
> + RTE_PTYPE_L2_ETHER_ARP,
> + RTE_PTYPE_L3_IPV4_EXT_UNKNOWN,
Why an inline for something in control path which then has to be a function
since it used as ethdev op.
> static inline void sxe2_init_ptype_list(uint32_t *ptype)
> +{
> + /* ptype[0] reserved */
> + ptype[1] = RTE_PTYPE_L2_ETHER;
> + ptype[2] = RTE_PTYPE_L2_ETHER_TIMESYNC;
> + /* ptype[3] - ptype[5] reserved */
> + ptype[6] = RTE_PTYPE_L2_ETHER_LLDP;
> + /* ECP */
> + ptype[7] = RTE_PTYPE_UNKNOWN;
> + /* ptype[8] - ptype[9] reserved */
> + /* EAPol */
> + ptype[10] = RTE_PTYPE_UNKNOWN;
> + ptype[11] = RTE_PTYPE_L2_ETHER_ARP;
> + /* ptype[12] - ptype[21] reserved */
> +
Why are you building the whole table at runtime? It could just be
one constant table setup at build time.
> +int32_t sxe2_mtu_set(struct rte_eth_dev *dev, uint16_t mtu __rte_unused)
> +{
> + int32_t ret = -1;
> + struct sxe2_adapter *adapter = SXE2_DEV_PRIVATE_TO_ADAPTER(dev);
> +
> + PMD_INIT_FUNC_TRACE();
> +
> + if (dev->data->dev_started != 0) {
> + PMD_DEV_LOG_ERR(adapter, DRV, "port %d must be stopped before configuration",
> + dev->data->port_id);
> + ret = -1;
> + goto l_end;
Just return and skip the variable ret and goto.
A good return code would be -EBUSY.
> + }
> +
> + ret = 0;
> +
> +l_end:
> + return ret;
> +}
^ permalink raw reply
* Re: [PATCH v2 07/20] net/sxe2: support IPsec inline protocol offload
From: Stephen Hemminger @ 2026-06-15 18:18 UTC (permalink / raw)
To: liujie5; +Cc: dev
In-Reply-To: <20260614092328.201826-10-liujie5@linkdatatechnology.com>
On Sun, 14 Jun 2026 17:23:11 +0800
liujie5@linkdatatechnology.com wrote:
> From: Jie Liu <liujie5@linkdatatechnology.com>
>
> This patch adds support for IPsec inline protocol offload for both
> inbound and outbound traffic.
>
> - Implement rte_security_ops: session_create, session_destroy.
> - Add hardware SA table management.
> - Update Rx/Tx data path to handle security offload flags.
>
> The hardware offloads the ESP encapsulation/decapsulation and
> cryptographic processing.
>
> Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
> ---
Git complains about this patch.
Applying: net/sxe2: support IPsec inline protocol offload
/home/shemminger/DPDK/main/.git/worktrees/sxe2/rebase-apply/patch:236: new blank line at EOF.
+
^ permalink raw reply
* Re: [PATCH v2 08/20] net/sxe2: support statistics and multi-process
From: Stephen Hemminger @ 2026-06-15 18:05 UTC (permalink / raw)
To: liujie5; +Cc: dev
In-Reply-To: <20260614092328.201826-11-liujie5@linkdatatechnology.com>
On Sun, 14 Jun 2026 17:23:12 +0800
liujie5@linkdatatechnology.com wrote:
> From: Jie Liu <liujie5@linkdatatechnology.com>
>
> - The statistics support includes:
> - Basic statistics (ipackets, opackets, ibytes, obytes, etc.)
> - Extended statistics (xstats) for detailed hardware counters.
> - Per-queue statistics for both RX and TX.
>
> The multi-process support allows secondary processes to retrieve
> statistics. Since secondary processes cannot access hardware registers
> directly, an IPC mechanism is implemented using the DPDK MP API.
>
> Atomic operations are used when reading 64-bit counters to ensure
> data consistency between processes.
>
> Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
> ---
The software stats do not need to be optional. You mentioned that they
have a performance cost, but that is because of the choice to use atomic counters.
Atomic operations are slow and not required for per-queue software statistics.
Even with memory order relaxed, the atomic operations cause a locked instruction
on x86. Thats what you are observing.
The DPDK follows the pattern of BSD and Linux kernel and does not use atomic
for software stats. When using per-queue statistics in some case, the point
in time measurement (summation) will be inaccurate but that is ok.
If you take off the atomic, I bet the cost of doing the conditional branch
outweighs the cost of simple basic arithmetic operation.
Please have them always on, drivers should only have options when
there is no other choice.
^ permalink raw reply
* Re: Question regarding duplicate fragment handling in DPDK IP reassembly library
From: Stephen Hemminger @ 2026-06-15 17:37 UTC (permalink / raw)
To: Samyak Jain; +Cc: dev@dpdk.org, Vikash kumar, Ankur Bharadwaj
In-Reply-To: <PN4PR01MB114326CC09306DA93ABA7C2ECEEE62@PN4PR01MB11432.INDPRD01.PROD.OUTLOOK.COM>
On Mon, 15 Jun 2026 12:39:48 +0000
Samyak Jain <samyak.jain@amantyatech.com> wrote:
> Hi DPDK Community,
>
> I am using DPDK 25.11 and evaluating the IP reassembly library
> (librte_ip_frag).
>
> During testing, I observed that duplicate fragments appear to cause reassembly failure and the fragment context gets invalidated.
>
> I would like to know:
>
> 1. Is duplicate fragment handling intentionally unsupported in
> rte_ipv4_frag_reassemble_packet() / rte_ipv6_frag_reassemble_packet()?
>
> 2. Has there been any upstream discussion or patch to support
> duplicate fragments while still rejecting conflicting
> fragments?
>
> 3. Are there any recommended approaches for applications that need
> Linux-like duplicate fragment tolerance?
>
> Any guidance would be appreciated.
>
> Thanks & Regards,
> Samyak Jain
>
Short answer: yes it is buggy, no it shouldn't be.
Looking into it but not a simple answer
^ permalink raw reply
* [PATCH v3 20/20] common/cnxk: fix TM link config selection in debug dump
From: Rahul Bhansali @ 2026-06-15 16:24 UTC (permalink / raw)
To: dev, Nithin Dabilpuram, Kiran Kumar K, Sunil Kumar Kori,
Satha Rao, Harman Kalra
Cc: jerinj, stable
In-Reply-To: <20260615162446.578336-1-rbhansali@marvell.com>
From: Satha Rao <skoteshwar@marvell.com>
Only emit the TM link configuration register when the configured TM
link level matches the hardware level being dumped, and use nix->tx_link
for the register and label so the dump reflects the active link.
Fixes: fcdef46b6698 ("common/cnxk: support NIX TM debug and misc utils")
Cc: stable@dpdk.org
Signed-off-by: Satha Rao <skoteshwar@marvell.com>
---
Changes in v3: No code change. FEC patches removed from series and patches reordered.
Changes in v2: No change.
drivers/common/cnxk/roc_nix_debug.c | 31 +++++++++++++++++++----------
1 file changed, 20 insertions(+), 11 deletions(-)
diff --git a/drivers/common/cnxk/roc_nix_debug.c b/drivers/common/cnxk/roc_nix_debug.c
index d4b2b86916..9c3bc8abe3 100644
--- a/drivers/common/cnxk/roc_nix_debug.c
+++ b/drivers/common/cnxk/roc_nix_debug.c
@@ -1150,7 +1150,7 @@ roc_nix_sq_dump(struct roc_nix_sq *sq, FILE *file)
};
static uint8_t
-nix_tm_reg_dump_prep(uint16_t hw_lvl, uint16_t schq, uint16_t link,
+nix_tm_reg_dump_prep(struct nix *nix, uint16_t hw_lvl, uint16_t schq,
uint64_t *reg, char regstr[][NIX_REG_NAME_SZ])
{
FILE *file = NULL;
@@ -1228,9 +1228,14 @@ nix_tm_reg_dump_prep(uint16_t hw_lvl, uint16_t schq, uint16_t link,
snprintf(regstr[k++], NIX_REG_NAME_SZ,
"NIX_AF_TL3[%u]_TOPOLOGY", schq);
- reg[k] = NIX_AF_TL3_TL2X_LINKX_CFG(schq, link);
- snprintf(regstr[k++], NIX_REG_NAME_SZ,
- "NIX_AF_TL3_TL2[%u]_LINK[%u]_CFG", schq, link);
+ /* Link configuration */
+ if (!nix->sdp_link &&
+ nix->tm_link_cfg_lvl == NIX_TXSCH_LVL_TL3) {
+ reg[k] = NIX_AF_TL3_TL2X_LINKX_CFG(schq, nix->tx_link);
+ snprintf(regstr[k++], NIX_REG_NAME_SZ,
+ "NIX_AF_TL3_TL2[%u]_LINK[%u]_CFG", schq,
+ nix->tx_link);
+ }
reg[k] = NIX_AF_TL3X_SCHEDULE(schq);
snprintf(regstr[k++], NIX_REG_NAME_SZ,
@@ -1261,9 +1266,14 @@ nix_tm_reg_dump_prep(uint16_t hw_lvl, uint16_t schq, uint16_t link,
snprintf(regstr[k++], NIX_REG_NAME_SZ,
"NIX_AF_TL2[%u]_TOPOLOGY", schq);
- reg[k] = NIX_AF_TL3_TL2X_LINKX_CFG(schq, link);
- snprintf(regstr[k++], NIX_REG_NAME_SZ,
- "NIX_AF_TL3_TL2[%u]_LINK[%u]_CFG", schq, link);
+ /* Link configuration */
+ if (!nix->sdp_link &&
+ nix->tm_link_cfg_lvl == NIX_TXSCH_LVL_TL2) {
+ reg[k] = NIX_AF_TL3_TL2X_LINKX_CFG(schq, nix->tx_link);
+ snprintf(regstr[k++], NIX_REG_NAME_SZ,
+ "NIX_AF_TL3_TL2[%u]_LINK[%u]_CFG", schq,
+ nix->tx_link);
+ }
reg[k] = NIX_AF_TL2X_SCHEDULE(schq);
snprintf(regstr[k++], NIX_REG_NAME_SZ,
@@ -1370,8 +1380,7 @@ nix_tm_dump_lvl(struct nix *nix, struct nix_tm_node_list *list, uint8_t hw_lvl)
root = node;
/* Dump registers only when HWRES is present */
- k = nix_tm_reg_dump_prep(node->hw_lvl, schq, nix->tx_link, reg,
- regstr);
+ k = nix_tm_reg_dump_prep(nix, node->hw_lvl, schq, reg, regstr);
if (!k)
continue;
@@ -1396,8 +1405,8 @@ nix_tm_dump_lvl(struct nix *nix, struct nix_tm_node_list *list, uint8_t hw_lvl)
/* Dump TL1 node data when root level is TL2 */
if (root && root->hw_lvl == NIX_TXSCH_LVL_TL2) {
- k = nix_tm_reg_dump_prep(NIX_TXSCH_LVL_TL1, root->parent_hw_id,
- nix->tx_link, reg, regstr);
+ k = nix_tm_reg_dump_prep(nix, NIX_TXSCH_LVL_TL1,
+ root->parent_hw_id, reg, regstr);
if (!k)
return;
--
2.34.1
^ permalink raw reply related
* [PATCH v3 19/20] crypto/cnxk: enforce DES/3DES cipher key length
From: Rahul Bhansali @ 2026-06-15 16:24 UTC (permalink / raw)
To: dev, Ankur Dwivedi, Anoob Joseph, Tejasree Kondoj,
Archana Muniganti, Akhil Goyal
Cc: jerinj, Aarnav JP, stable
In-Reply-To: <20260615162446.578336-1-rbhansali@marvell.com>
From: Aarnav JP <ajp@marvell.com>
Enforce exact key length match for DES/3DES algorithms
in fill_sess_cipher(), since these have fixed key sizes
(8 or 24 bytes). The existing check only enforced a lower
bound, allowing oversized keys to pass through.
Fixes: eb43e39851b8 ("crypto/cnxk: add cipher operation in session")
Cc: stable@dpdk.org
Signed-off-by: Aarnav JP <ajp@marvell.com>
---
Changes in v3: No code change. FEC patches removed from series and patches reordered.
Changes in v2: No change.
drivers/crypto/cnxk/cnxk_se.h | 11 ++++++++---
1 file changed, 8 insertions(+), 3 deletions(-)
diff --git a/drivers/crypto/cnxk/cnxk_se.h b/drivers/crypto/cnxk/cnxk_se.h
index 8dbf3e73c7..e2d7e10ec9 100644
--- a/drivers/crypto/cnxk/cnxk_se.h
+++ b/drivers/crypto/cnxk/cnxk_se.h
@@ -2297,9 +2297,14 @@ fill_sess_cipher(struct rte_crypto_sym_xform *xform, struct cnxk_se_sess *sess)
return -1;
}
- if (c_form->key.length < cipher_key_len) {
- plt_dp_err("Invalid cipher params keylen %u",
- c_form->key.length);
+ if (enc_type == ROC_SE_DES3_CBC || enc_type == ROC_SE_DES3_ECB ||
+ enc_type == ROC_SE_DES_DOCSISBPI) {
+ if (c_form->key.length != cipher_key_len) {
+ plt_dp_err("Invalid cipher params keylen %u", c_form->key.length);
+ return -1;
+ }
+ } else if (c_form->key.length < cipher_key_len) {
+ plt_dp_err("Invalid cipher params keylen %u", c_form->key.length);
return -1;
}
--
2.34.1
^ permalink raw reply related
* [PATCH v3 18/20] event/cnxk: fix Klocwork static analysis issues
From: Rahul Bhansali @ 2026-06-15 16:24 UTC (permalink / raw)
To: dev, Pavan Nikhilesh, Shijith Thotton, Rakesh Kudurumalla,
Rahul Bhansali
Cc: jerinj, Aarnav JP, stable
In-Reply-To: <20260615162446.578336-1-rbhansali@marvell.com>
From: Aarnav JP <ajp@marvell.com>
Cast uint16_t operands to uint64_t before bitwise OR with
uint64_t rx_offloads to fix operand size mismatches. Add NULL
check for bracket parser end pointer to prevent undefined
behavior from pointer comparison with NULL.
Fixes: 697883bcb0a8 ("event/cnxk: fix Rx timestamp handling")
Fixes: fe7ed2ebbf37 ("event/cnxk: set Rx offload flags")
Fixes: 38c2e3240ba8 ("event/cnxk: add option to control SSO HWGRP QoS")
Fixes: 8a3d58c189fd ("event/cnxk: add option to control timer adapters")
Cc: stable@dpdk.org
Signed-off-by: Aarnav JP <ajp@marvell.com>
---
Changes in v3: No code change. FEC patches removed from series and patches reordered.
Changes in v2: No change.
drivers/event/cnxk/cn10k_eventdev.c | 2 +-
drivers/event/cnxk/cnxk_eventdev.c | 2 +-
drivers/event/cnxk/cnxk_eventdev_adptr.c | 4 ++--
drivers/event/cnxk/cnxk_tim_evdev.c | 2 +-
4 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/drivers/event/cnxk/cn10k_eventdev.c b/drivers/event/cnxk/cn10k_eventdev.c
index 2e4b8aab92..62fea93b0b 100644
--- a/drivers/event/cnxk/cn10k_eventdev.c
+++ b/drivers/event/cnxk/cn10k_eventdev.c
@@ -660,7 +660,7 @@ cn10k_sso_tstamp_hdl_update(uint16_t port_id, uint16_t flags, bool ptp_en)
struct rte_eventdev *event_dev = cnxk_eth_dev->evdev_priv;
struct cnxk_sso_evdev *evdev = cnxk_sso_pmd_priv(event_dev);
- evdev->rx_offloads |= flags;
+ evdev->rx_offloads |= (uint64_t)flags;
if (ptp_en)
evdev->tstamp[port_id] = &cnxk_eth_dev->tstamp;
else
diff --git a/drivers/event/cnxk/cnxk_eventdev.c b/drivers/event/cnxk/cnxk_eventdev.c
index be6a487b59..4aa16f9026 100644
--- a/drivers/event/cnxk/cnxk_eventdev.c
+++ b/drivers/event/cnxk/cnxk_eventdev.c
@@ -566,7 +566,7 @@ parse_list(const char *value, void *opaque, param_parse_t fn)
else if (*s == ']')
end = s;
- if (start && start < end) {
+ if (start && end && start < end) {
*end = 0;
fn(start + 1, opaque);
s = end;
diff --git a/drivers/event/cnxk/cnxk_eventdev_adptr.c b/drivers/event/cnxk/cnxk_eventdev_adptr.c
index 8536dee5bf..5678e5d264 100644
--- a/drivers/event/cnxk/cnxk_eventdev_adptr.c
+++ b/drivers/event/cnxk/cnxk_eventdev_adptr.c
@@ -285,7 +285,7 @@ cnxk_sso_rx_adapter_queues_add(const struct rte_eventdev *event_dev,
/* Propagate force bp devarg */
cnxk_eth_dev->nix.force_rx_aura_bp = dev->force_ena_bp;
cnxk_sso_tstamp_cfg(eth_dev->data->port_id, eth_dev, dev);
- dev->rx_offloads |= cnxk_eth_dev->rx_offload_flags;
+ dev->rx_offloads |= (uint64_t)cnxk_eth_dev->rx_offload_flags;
return 0;
fail:
@@ -330,7 +330,7 @@ cnxk_sso_rx_adapter_start(const struct rte_eventdev *event_dev,
{
struct cnxk_eth_dev *cnxk_eth_dev = eth_dev->data->dev_private;
struct cnxk_sso_evdev *dev = cnxk_sso_pmd_priv(event_dev);
- dev->rx_offloads |= cnxk_eth_dev->rx_offload_flags;
+ dev->rx_offloads |= (uint64_t)cnxk_eth_dev->rx_offload_flags;
return 0;
}
diff --git a/drivers/event/cnxk/cnxk_tim_evdev.c b/drivers/event/cnxk/cnxk_tim_evdev.c
index 994d1d1090..8cdb8a72dd 100644
--- a/drivers/event/cnxk/cnxk_tim_evdev.c
+++ b/drivers/event/cnxk/cnxk_tim_evdev.c
@@ -508,7 +508,7 @@ cnxk_tim_parse_ring_ctl_list(const char *value, void *opaque)
else
continue;
- if (start && start < end) {
+ if (start && end && start < end) {
*end = 0;
cnxk_tim_parse_ring_param(start + 1, opaque);
start = end;
--
2.34.1
^ permalink raw reply related
* [PATCH v3 17/20] common/cnxk: add auth key len check in inbound SA
From: Rahul Bhansali @ 2026-06-15 16:24 UTC (permalink / raw)
To: dev, Nithin Dabilpuram, Kiran Kumar K, Sunil Kumar Kori,
Satha Rao, Harman Kalra, Archana Muniganti, Akhil Goyal,
Vidya Sagar Velumuri
Cc: jerinj, Aarnav JP, stable
In-Reply-To: <20260615162446.578336-1-rbhansali@marvell.com>
From: Aarnav JP <ajp@marvell.com>
Add auth key length validation before memcpy in
cnxk_on_ipsec_inb_sa_create() to prevent caller-provided
keys from overflowing fixed-size in-struct buffers and
corrupting adjacent fields.
Fixes: 532963b80707 ("crypto/cnxk: move IPsec SA creation to common")
Cc: stable@dpdk.org
Signed-off-by: Aarnav JP <ajp@marvell.com>
---
Changes in v3: No change.
Changes in v2: No change.
drivers/common/cnxk/cnxk_security.c | 27 +++++++++++++++++++--------
1 file changed, 19 insertions(+), 8 deletions(-)
diff --git a/drivers/common/cnxk/cnxk_security.c b/drivers/common/cnxk/cnxk_security.c
index 6f46ad3276..228ff2781d 100644
--- a/drivers/common/cnxk/cnxk_security.c
+++ b/drivers/common/cnxk/cnxk_security.c
@@ -1199,22 +1199,33 @@ cnxk_on_ipsec_inb_sa_create(struct rte_security_ipsec_xform *ipsec,
break;
case RTE_CRYPTO_AUTH_MD5_HMAC:
case RTE_CRYPTO_AUTH_SHA1_HMAC:
- memcpy(in_sa->sha1_or_gcm.hmac_key, auth_key,
- auth_key_len);
- ctx_len = offsetof(struct roc_ie_on_inb_sa,
- sha1_or_gcm.selector);
+ if (auth_key_len > (int)sizeof(in_sa->sha1_or_gcm.hmac_key)) {
+ plt_err("Auth key len %d exceeds max %zu for algo %u", auth_key_len,
+ sizeof(in_sa->sha1_or_gcm.hmac_key), auth_xform->auth.algo);
+ return -EINVAL;
+ }
+ memcpy(in_sa->sha1_or_gcm.hmac_key, auth_key, auth_key_len);
+ ctx_len = offsetof(struct roc_ie_on_inb_sa, sha1_or_gcm.selector);
break;
case RTE_CRYPTO_AUTH_SHA256_HMAC:
case RTE_CRYPTO_AUTH_SHA384_HMAC:
case RTE_CRYPTO_AUTH_SHA512_HMAC:
+ if (auth_key_len > (int)sizeof(in_sa->sha2.hmac_key)) {
+ plt_err("Auth key len %d exceeds max %zu for algo %u", auth_key_len,
+ sizeof(in_sa->sha2.hmac_key), auth_xform->auth.algo);
+ return -EINVAL;
+ }
memcpy(in_sa->sha2.hmac_key, auth_key, auth_key_len);
- ctx_len = offsetof(struct roc_ie_on_inb_sa,
- sha2.selector);
+ ctx_len = offsetof(struct roc_ie_on_inb_sa, sha2.selector);
break;
case RTE_CRYPTO_AUTH_AES_XCBC_MAC:
+ if (auth_key_len > (int)sizeof(in_sa->aes_xcbc.key)) {
+ plt_err("Auth key len %d exceeds max %zu for algo %u", auth_key_len,
+ sizeof(in_sa->aes_xcbc.key), auth_xform->auth.algo);
+ return -EINVAL;
+ }
memcpy(in_sa->aes_xcbc.key, auth_key, auth_key_len);
- ctx_len = offsetof(struct roc_ie_on_inb_sa,
- aes_xcbc.selector);
+ ctx_len = offsetof(struct roc_ie_on_inb_sa, aes_xcbc.selector);
break;
default:
plt_err("Unsupported auth algorithm %u", auth_xform->auth.algo);
--
2.34.1
^ permalink raw reply related
* [PATCH v3 16/20] common/cnxk: fix Klocwork static analysis issues
From: Rahul Bhansali @ 2026-06-15 16:24 UTC (permalink / raw)
To: dev, Nithin Dabilpuram, Kiran Kumar K, Sunil Kumar Kori,
Satha Rao, Harman Kalra, Satheesh Paul, Jerin Jacob,
Rakesh Kudurumalla
Cc: Aarnav JP, stable
In-Reply-To: <20260615162446.578336-1-rbhansali@marvell.com>
From: Aarnav JP <ajp@marvell.com>
Fix NULL pointer dereferences (roc_dev.c, roc_npa.c, roc_nix_inl.c),
resource leaks in error paths (roc_dev.c, roc_dpi.c, roc_ree.c,
roc_nix.c, roc_emdev.c), uninitialized variables (roc_npa_debug.c,
roc_emdev.c), array out-of-bounds access (roc_npc_utils.c, roc_emdev.c),
bitwise operand size mismatches (roc_mbox.h, roc_emdev_irq.c), and
format string type mismatches (roc_cpt_debug.c).
Fixes: 5d8ff275433a ("common/cnxk: fix race condition between up and down mailbox")
Fixes: 9a92937cf0c8 ("common/cnxk: fix possible out-of-bounds access")
Fixes: 7557e3f5b9fa ("common/cnxk: replace direct API usage in REE")
Fixes: 3fdf3e53f3c4 ("common/cnxk: enable CPT CQ for inline IPsec inbound")
Fixes: c758279fee32 ("common/cnxk: support debug dump to file")
Cc: stable@dpdk.org
Signed-off-by: Aarnav JP <ajp@marvell.com>
---
Changes in v3: No change.
Changes in v2: No change.
drivers/common/cnxk/roc_cpt_debug.c | 29 ++++++++++++++---------------
drivers/common/cnxk/roc_dev.c | 15 +++++++++++----
drivers/common/cnxk/roc_mbox.h | 4 ++--
drivers/common/cnxk/roc_nix_inl.c | 3 +--
drivers/common/cnxk/roc_npa.c | 3 +++
drivers/common/cnxk/roc_npa_debug.c | 8 +++++++-
drivers/common/cnxk/roc_npc_utils.c | 10 +++++++---
drivers/common/cnxk/roc_ree.c | 17 ++++++++++++-----
8 files changed, 57 insertions(+), 32 deletions(-)
diff --git a/drivers/common/cnxk/roc_cpt_debug.c b/drivers/common/cnxk/roc_cpt_debug.c
index 3b3e678c20..3c1c052e50 100644
--- a/drivers/common/cnxk/roc_cpt_debug.c
+++ b/drivers/common/cnxk/roc_cpt_debug.c
@@ -33,7 +33,7 @@ cpt_cnxk_parse_hdr_dump(FILE *file, const struct cpt_parse_hdr_s *cpth)
cpth->w0.num_frags, cpth->w0.pkt_out);
/* W1 */
- cpt_dump(file, "W1: wqe_ptr \t0x%016lx\t", cpth->wqe_ptr);
+ cpt_dump(file, "W1: wqe_ptr \t0x%016" PRIx64 "\t", cpth->wqe_ptr);
/* W2 */
cpt_dump(file, "W2: pkt_inline \t0x%x\t\torig_pkt_aura \t0x%x", cpth->w2.pkt_inline,
@@ -135,29 +135,28 @@ cpt_cn10k_parse_hdr_dump(FILE *file, const struct cpt_cn10k_parse_hdr_s *cpth)
cpt_dump(file, "W0: cookie \t0x%x\t\tmatch_id \t0x%04x \t",
cpth->w0.cookie, cpth->w0.match_id);
cpt_dump(file, "W0: err_sum \t%u \t", cpth->w0.err_sum);
- cpt_dump(file, "W0: reas_sts \t0x%x\t\tet_owr \t%u\t\tpkt_fmt \t%u \t",
- cpth->w0.reas_sts, cpth->w0.et_owr, cpth->w0.pkt_fmt);
- cpt_dump(file, "W0: pad_len \t%u\t\tnum_frags \t%u\t\tpkt_out \t%u \t",
- cpth->w0.pad_len, cpth->w0.num_frags, cpth->w0.pkt_out);
+ cpt_dump(file, "W0: reas_sts \t0x%x\t\tet_owr \t%u\t\tpkt_fmt \t%u \t", cpth->w0.reas_sts,
+ cpth->w0.et_owr, cpth->w0.pkt_fmt);
+ cpt_dump(file, "W0: pad_len \t%u\t\tnum_frags \t%u\t\tpkt_out \t%u \t", cpth->w0.pad_len,
+ cpth->w0.num_frags, cpth->w0.pkt_out);
/* W1 */
- cpt_dump(file, "W1: wqe_ptr \t0x%016lx\t",
- plt_be_to_cpu_64(cpth->wqe_ptr));
+ cpt_dump(file, "W1: wqe_ptr \t0x%016" PRIx64 "\t",
+ (uint64_t)plt_be_to_cpu_64(cpth->wqe_ptr));
/* W2 */
- cpt_dump(file, "W2: frag_age \t0x%x\t\torig_pf_func \t0x%04x",
- cpth->w2.frag_age, cpth->w2.orig_pf_func);
- cpt_dump(file, "W2: il3_off \t0x%x\t\tfi_pad \t0x%x \t",
- cpth->w2.il3_off, cpth->w2.fi_pad);
+ cpt_dump(file, "W2: frag_age \t0x%x\t\torig_pf_func \t0x%04x", cpth->w2.frag_age,
+ cpth->w2.orig_pf_func);
+ cpt_dump(file, "W2: il3_off \t0x%x\t\tfi_pad \t0x%x \t", cpth->w2.il3_off, cpth->w2.fi_pad);
cpt_dump(file, "W2: fi_offset \t0x%x \t", cpth->w2.fi_offset);
/* W3 */
- cpt_dump(file, "W3: hw_ccode \t0x%x\t\tuc_ccode \t0x%x\t\tspi \t0x%08x",
- cpth->w3.hw_ccode, cpth->w3.uc_ccode, cpth->w3.spi);
+ cpt_dump(file, "W3: hw_ccode \t0x%x\t\tuc_ccode \t0x%x\t\tspi \t0x%08x", cpth->w3.hw_ccode,
+ cpth->w3.uc_ccode, cpth->w3.spi);
/* W4 */
- cpt_dump(file, "W4: esn \t%" PRIx64 " \t OR frag1_wqe_ptr \t0x%" PRIx64,
- cpth->esn, plt_be_to_cpu_64(cpth->frag1_wqe_ptr));
+ cpt_dump(file, "W4: esn \t%" PRIx64 " \t OR frag1_wqe_ptr \t0x%" PRIx64, cpth->esn,
+ (uint64_t)plt_be_to_cpu_64(cpth->frag1_wqe_ptr));
/* offset of 0 implies 256B, otherwise it implies offset*8B */
offset = cpth->w2.fi_offset;
diff --git a/drivers/common/cnxk/roc_dev.c b/drivers/common/cnxk/roc_dev.c
index 32409f2ef3..61aa4b3075 100644
--- a/drivers/common/cnxk/roc_dev.c
+++ b/drivers/common/cnxk/roc_dev.c
@@ -1796,14 +1796,17 @@ dev_init(struct dev *dev, struct plt_pci_device *pci_dev)
rc = npa_lf_init(dev, pci_dev);
if (rc)
- goto stop_msg_thrd;
+ goto vf_flr_unregister;
/* Setup LMT line base */
rc = dev_lmt_setup(dev);
if (rc)
- goto stop_msg_thrd;
+ goto vf_flr_unregister;
return rc;
+vf_flr_unregister:
+ if (!is_vf)
+ dev_vf_flr_unregister_irqs(pci_dev, dev);
stop_msg_thrd:
/* Exiting the mbox sync thread */
if (dev->sync.start_thread) {
@@ -1812,10 +1815,14 @@ dev_init(struct dev *dev, struct plt_pci_device *pci_dev)
plt_thread_join(dev->sync.pfvf_msg_thread, NULL);
}
thread_fail:
- pthread_mutex_destroy(&dev->sync.mutex);
- pthread_cond_destroy(&dev->sync.pfvf_msg_cond);
+ if (pci_dev->max_vfs > 0) {
+ pthread_mutex_destroy(&dev->sync.mutex);
+ pthread_cond_destroy(&dev->sync.pfvf_msg_cond);
+ }
iounmap:
dev_vf_mbase_put(pci_dev, vf_mbase);
+ mbox_fini(&dev->mbox_vfpf);
+ mbox_fini(&dev->mbox_vfpf_up);
mbox_unregister:
dev_mbox_unregister_irq(pci_dev, dev);
if (dev->ops)
diff --git a/drivers/common/cnxk/roc_mbox.h b/drivers/common/cnxk/roc_mbox.h
index 1158ff50a7..52ecde6563 100644
--- a/drivers/common/cnxk/roc_mbox.h
+++ b/drivers/common/cnxk/roc_mbox.h
@@ -47,8 +47,8 @@ struct mbox_msghdr {
#define RVU_VF_VFPF_MBOX0 (0x0000)
#define RVU_VF_VFPF_MBOX1 (0x0008)
-#define MBOX_DOWN_MSG 1
-#define MBOX_UP_MSG 2
+#define MBOX_DOWN_MSG 1ULL
+#define MBOX_UP_MSG 2ULL
/* Mailbox message types */
#define MBOX_MSG_MASK 0xFFFF
diff --git a/drivers/common/cnxk/roc_nix_inl.c b/drivers/common/cnxk/roc_nix_inl.c
index b515d52534..db101e71a5 100644
--- a/drivers/common/cnxk/roc_nix_inl.c
+++ b/drivers/common/cnxk/roc_nix_inl.c
@@ -638,9 +638,8 @@ nix_inl_reass_inb_sa_tbl_setup(struct roc_nix *roc_nix)
res_addr_offset = (uint64_t)(inl_dev->res_addr_offset & 0xFF) << 48;
if (res_addr_offset)
res_addr_offset |= (1UL << 56);
+ cpt_cq_ena = (uint64_t)inl_dev->cpt_cq_ena << 63;
}
-
- cpt_cq_ena = (uint64_t)inl_dev->cpt_cq_ena << 63;
lf_cfg->enable = 1;
lf_cfg->profile_id = profile_id;
lf_cfg->rx_inline_sa_base = (uintptr_t)nix->inb_sa_base[profile_id] | cpt_cq_ena;
diff --git a/drivers/common/cnxk/roc_npa.c b/drivers/common/cnxk/roc_npa.c
index 88e328105a..4a3e96a97a 100644
--- a/drivers/common/cnxk/roc_npa.c
+++ b/drivers/common/cnxk/roc_npa.c
@@ -1113,6 +1113,9 @@ roc_npa_pool_destroy(uint64_t aura_handle)
struct npa_lf *lf = idev_npa_obj_get();
int rc = 0, aura_id;
+ if (lf == NULL)
+ return NPA_ERR_DEVICE_NOT_BOUNDED;
+
plt_npa_dbg("lf=%p aura_handle=0x%" PRIx64, lf, aura_handle);
aura_id = roc_npa_aura_handle_to_aura(aura_handle);
diff --git a/drivers/common/cnxk/roc_npa_debug.c b/drivers/common/cnxk/roc_npa_debug.c
index e64696730f..f978be9642 100644
--- a/drivers/common/cnxk/roc_npa_debug.c
+++ b/drivers/common/cnxk/roc_npa_debug.c
@@ -283,6 +283,9 @@ roc_npa_ctx_dump(void)
if (lf->aura_attr[q].halo) {
aq->ctype = NPA_AQ_CTYPE_HALO;
rc = mbox_process_msg(mbox, (void *)&rsp_cn20k);
+ } else if (roc_model_is_cn20k()) {
+ aq->ctype = NPA_AQ_CTYPE_AURA;
+ rc = mbox_process_msg(mbox, (void *)&rsp_cn20k);
} else {
aq->ctype = NPA_AQ_CTYPE_AURA;
rc = mbox_process_msg(mbox, (void *)&rsp);
@@ -323,7 +326,10 @@ roc_npa_ctx_dump(void)
aq->ctype = NPA_AQ_CTYPE_POOL;
aq->op = NPA_AQ_INSTOP_READ;
- rc = mbox_process_msg(mbox, (void *)&rsp);
+ if (roc_model_is_cn20k())
+ rc = mbox_process_msg(mbox, (void *)&rsp_cn20k);
+ else
+ rc = mbox_process_msg(mbox, (void *)&rsp);
if (rc) {
plt_err("Failed to get pool(%d) context", q);
goto exit;
diff --git a/drivers/common/cnxk/roc_npc_utils.c b/drivers/common/cnxk/roc_npc_utils.c
index 3c05e46e1b..8e83b8662d 100644
--- a/drivers/common/cnxk/roc_npc_utils.c
+++ b/drivers/common/cnxk/roc_npc_utils.c
@@ -486,7 +486,7 @@ npc_process_ipv6_field_hash_o20k(const struct roc_npc_flow_item_ipv6 *ipv6_spec,
uint8_t hash_field[ROC_IPV6_ADDR_LEN];
struct npc_xtract_info *xinfo;
uint32_t hash = 0, mask;
- int intf, i, rc = 0;
+ int intf, i, hash_idx = 0, rc = 0;
memset(hash_field, 0, sizeof(hash_field));
@@ -505,14 +505,18 @@ npc_process_ipv6_field_hash_o20k(const struct roc_npc_flow_item_ipv6 *ipv6_spec,
if (rc == 0)
continue;
- rc = npc_ipv6_field_hash_get(pst->npc, (const uint32_t *)hash_field, intf, i,
- &hash);
+ if (hash_idx >= NPC_MAX_HASH)
+ break;
+
+ rc = npc_ipv6_field_hash_get(pst->npc, (const uint32_t *)hash_field, intf,
+ hash_idx, &hash);
if (rc)
return rc;
mask = GENMASK(31, 0);
memcpy(pst->mcam_mask + xinfo->key_off, (uint8_t *)&mask, 4);
memcpy(pst->mcam_data + xinfo->key_off, (uint8_t *)&hash, 4);
+ hash_idx++;
}
return 0;
diff --git a/drivers/common/cnxk/roc_ree.c b/drivers/common/cnxk/roc_ree.c
index b6392658c3..923d9251ad 100644
--- a/drivers/common/cnxk/roc_ree.c
+++ b/drivers/common/cnxk/roc_ree.c
@@ -592,14 +592,15 @@ roc_ree_dev_init(struct roc_ree_vf *vf)
vf->block_address = ree_get_blkaddr(dev);
if (!vf->block_address) {
plt_err("Could not determine block PF number");
- goto fail;
+ rc = -ENODEV;
+ goto dev_fini;
}
/* Get number of queues available on the device */
rc = roc_ree_available_queues_get(vf, &nb_queues);
if (rc) {
plt_err("Could not determine the number of queues available");
- goto fail;
+ goto dev_fini;
}
/* Don't exceed the limits set per VF */
@@ -607,7 +608,8 @@ roc_ree_dev_init(struct roc_ree_vf *vf)
if (nb_queues == 0) {
plt_err("No free queues available on the device");
- goto fail;
+ rc = -ENOSPC;
+ goto dev_fini;
}
vf->max_queues = nb_queues;
@@ -618,18 +620,23 @@ roc_ree_dev_init(struct roc_ree_vf *vf)
rc = roc_ree_max_matches_get(vf, &max_matches);
if (rc) {
plt_err("Could not determine the maximum matches supported");
- goto fail;
+ goto dev_fini;
}
/* Don't exceed the limits set per VF */
max_matches = RTE_MIN(max_matches, REE_MAX_MATCHES_PER_VF);
if (max_matches == 0) {
plt_err("Could not determine the maximum matches supported");
- goto fail;
+ rc = -EIO;
+ goto dev_fini;
}
vf->max_matches = max_matches;
plt_ree_dbg("Max matches supported by device: %d", vf->max_matches);
+
+ return 0;
+dev_fini:
+ dev_fini(dev, pci_dev);
fail:
return rc;
}
--
2.34.1
^ permalink raw reply related
* [PATCH v3 15/20] common/cnxk: add cipher key length check in key set
From: Rahul Bhansali @ 2026-06-15 16:24 UTC (permalink / raw)
To: dev, Nithin Dabilpuram, Kiran Kumar K, Sunil Kumar Kori,
Satha Rao, Harman Kalra, Ankur Dwivedi, Akhil Goyal
Cc: jerinj, Aarnav JP, stable
In-Reply-To: <20260615162446.578336-1-rbhansali@marvell.com>
From: Aarnav JP <ajp@marvell.com>
Add upper-bound checks before memcpy into encr_key[32]
in roc_se_ciph_key_set() to prevent buffer overflow into
adjacent encr_iv[16]. Covers all write paths including
AES-DOCSISBPI and DES-DOCSISBPI branches that bypass
the generic copy via goto.
Fixes: 5e076b609f2a ("common/cnxk: add SE set key for crypto")
Cc: stable@dpdk.org
Signed-off-by: Aarnav JP <ajp@marvell.com>
---
Changes in v3: No change.
Changes in v2: No change.
drivers/common/cnxk/roc_se.c | 15 +++++++++++++++
1 file changed, 15 insertions(+)
diff --git a/drivers/common/cnxk/roc_se.c b/drivers/common/cnxk/roc_se.c
index d841a926a4..1cec536169 100644
--- a/drivers/common/cnxk/roc_se.c
+++ b/drivers/common/cnxk/roc_se.c
@@ -545,12 +545,22 @@ roc_se_ciph_key_set(struct roc_se_ctx *se_ctx, roc_se_cipher_type type, const ui
* less than 128. Pass it as regular AES-CBC cipher to CPT, but keep type in
* se_ctx as AES_DOCSISBPI to skip block size checks in instruction preparation.
*/
+ if (key_len > sizeof(fctx->enc.encr_key)) {
+ plt_err("Cipher key length %u exceeds max %zu", key_len,
+ sizeof(fctx->enc.encr_key));
+ return -1;
+ }
cpt_ciph_aes_key_type_set(fctx, key_len);
fctx->enc.enc_cipher = ROC_SE_AES_CBC;
memcpy(fctx->enc.encr_key, key, key_len);
goto success;
case ROC_SE_DES_DOCSISBPI:
/* See case ROC_SE_DES3_CBC: for explanation */
+ if (key_len * 3 > sizeof(fctx->enc.encr_key)) {
+ plt_err("DES-DOCSISBPI key length %u exceeds max %zu", key_len,
+ sizeof(fctx->enc.encr_key) / 3);
+ return -1;
+ }
for (i = 0; i < 3; i++)
memcpy(fctx->enc.encr_key + key_len * i, key, key_len);
/*
@@ -628,6 +638,11 @@ roc_se_ciph_key_set(struct roc_se_ctx *se_ctx, roc_se_cipher_type type, const ui
if (se_ctx->hash_type != ROC_SE_GMAC_TYPE)
fctx->enc.enc_cipher = type;
+ if (key_len > sizeof(fctx->enc.encr_key)) {
+ plt_err("Cipher key length %u exceeds max %zu", key_len,
+ sizeof(fctx->enc.encr_key));
+ return -1;
+ }
memcpy(fctx->enc.encr_key, key, key_len);
success:
--
2.34.1
^ permalink raw reply related
* [PATCH v3 14/20] net/cnxk: fix bitwise operand size mismatch in link mode
From: Rahul Bhansali @ 2026-06-15 16:24 UTC (permalink / raw)
To: dev, Nithin Dabilpuram, Kiran Kumar K, Sunil Kumar Kori,
Satha Rao, Harman Kalra
Cc: jerinj, Aarnav JP, stable
In-Reply-To: <20260615162446.578336-1-rbhansali@marvell.com>
From: Aarnav JP <ajp@marvell.com>
Cast enum roc_nix_link_mode values to uint64_t before bitwise
OR with uint64_t advertise variable to ensure consistent
operand sizes.
Fixes: 292fcbb3d290 ("net/cnxk: support link mode configuration")
Cc: stable@dpdk.org
Signed-off-by: Aarnav JP <ajp@marvell.com>
---
Changes in v3: No change.
Changes in v2: No change.
drivers/net/cnxk/cnxk_link.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/net/cnxk/cnxk_link.c b/drivers/net/cnxk/cnxk_link.c
index dde2c3a313..f6682b4697 100644
--- a/drivers/net/cnxk/cnxk_link.c
+++ b/drivers/net/cnxk/cnxk_link.c
@@ -61,13 +61,13 @@ nix_link_advertising_get(struct cnxk_eth_dev *dev, struct roc_nix_link_info *lin
} else {
for (bit = 0; bit < ROC_NIX_LINK_SPEED_MAX; bit++) {
if (link_info->speed_bitmask & BIT_ULL(bit))
- advertise |= rte_to_ethtool_mode[bit];
+ advertise |= (uint64_t)rte_to_ethtool_mode[bit];
}
goto exit;
}
}
- advertise |= mac_to_ethtool_mode[linfo.lmac_type_id][link_info->full_duplex];
+ advertise |= (uint64_t)mac_to_ethtool_mode[linfo.lmac_type_id][link_info->full_duplex];
exit:
return advertise;
}
--
2.34.1
^ permalink raw reply related
* [PATCH v3 13/20] net/cnxk: derive ethdev from SA for inbound CPT CQ events
From: Rahul Bhansali @ 2026-06-15 16:24 UTC (permalink / raw)
To: dev, Nithin Dabilpuram, Kiran Kumar K, Sunil Kumar Kori,
Satha Rao, Harman Kalra
Cc: jerinj, Aarnav JP
In-Reply-To: <20260615162446.578336-1-rbhansali@marvell.com>
From: Aarnav JP <ajp@marvell.com>
With inbound CPT CQ events, port_id is unavailable since the inline
device has no roc_nix. Resolve eth_dev for inbound CQ events in the
cn20k PMD callback via the SA private data chain instead of relying
on port_id.
Add an eth_dev back pointer to cnxk_eth_sec_sess, populated at
session creation, to complete the SA-to-ethdev lookup path
(inb_priv->eth_sec->eth_dev).
Signed-off-by: Aarnav JP <ajp@marvell.com>
---
Changes in v3: No change.
Changes in v2: No change.
drivers/net/cnxk/cn20k_ethdev_sec.c | 22 ++++++++++++++++++++--
drivers/net/cnxk/cnxk_ethdev.h | 3 +++
2 files changed, 23 insertions(+), 2 deletions(-)
diff --git a/drivers/net/cnxk/cn20k_ethdev_sec.c b/drivers/net/cnxk/cn20k_ethdev_sec.c
index 31f2518ea3..a5be85901f 100644
--- a/drivers/net/cnxk/cn20k_ethdev_sec.c
+++ b/drivers/net/cnxk/cn20k_ethdev_sec.c
@@ -541,7 +541,6 @@ cn20k_eth_sec_sso_work_cb(uint64_t *gw, void *args, enum nix_inl_event_type type
uintptr_t nixtx;
uint8_t port;
- RTE_SET_USED(args);
plt_nix_dbg("Received %s event", get_inl_event_type(type));
switch ((gw[0] >> 28) & 0xF) {
@@ -561,8 +560,26 @@ cn20k_eth_sec_sso_work_cb(uint64_t *gw, void *args, enum nix_inl_event_type type
/* Fall through */
default:
if (type) {
- eth_dev = &rte_eth_devices[port_id];
struct cpt_cq_s *cqs = (struct cpt_cq_s *)cq_s;
+
+ if (type == NIX_INL_INB_CPT_CQ) {
+ struct cn20k_inb_priv_data *inb_priv;
+
+ inb_priv = roc_nix_inl_ow_ipsec_inb_sa_sw_rsvd(args);
+ if (inb_priv->eth_sec && inb_priv->eth_sec->eth_dev) {
+ eth_dev = inb_priv->eth_sec->eth_dev;
+ } else {
+ plt_err("Inbound CPT CQ event: no eth_dev in SA priv");
+ return;
+ }
+ } else {
+ if (port_id >= RTE_MAX_ETHPORTS) {
+ plt_err("CPT CQ event: invalid port_id %u", port_id);
+ return;
+ }
+ eth_dev = &rte_eth_devices[port_id];
+ }
+
if (type < NIX_INL_SSO) {
cn20k_eth_sec_post_event(eth_dev, args, type,
(uint16_t)cqs->w0.s.uc_compcode,
@@ -804,6 +821,7 @@ cn20k_eth_sec_session_create(void *device, struct rte_security_session_conf *con
inl_dev = !!dev->inb.inl_dev;
memset(eth_sec, 0, sizeof(struct cnxk_eth_sec_sess));
+ eth_sec->eth_dev = eth_dev;
sess_priv.u64 = 0;
lock = inbound ? &dev->inb.lock : &dev->outb.lock;
diff --git a/drivers/net/cnxk/cnxk_ethdev.h b/drivers/net/cnxk/cnxk_ethdev.h
index ea6a2be30e..6686fdba31 100644
--- a/drivers/net/cnxk/cnxk_ethdev.h
+++ b/drivers/net/cnxk/cnxk_ethdev.h
@@ -225,6 +225,9 @@ struct cnxk_eth_sec_sess {
/* Out-Of-Place processing */
bool inb_oop;
+
+ /* Back pointer to eth_dev for port_id derivation in CQ callbacks */
+ struct rte_eth_dev *eth_dev;
};
TAILQ_HEAD(cnxk_eth_sec_sess_list, cnxk_eth_sec_sess);
--
2.34.1
^ permalink raw reply related
* [PATCH v3 12/20] net/cnxk: fix unsigned integer underflow in LSO calculation
From: Rahul Bhansali @ 2026-06-15 16:24 UTC (permalink / raw)
To: dev, Nithin Dabilpuram, Kiran Kumar K, Sunil Kumar Kori,
Satha Rao, Harman Kalra, Pavan Nikhilesh, Jerin Jacob,
Rahul Bhansali
Cc: Aarnav JP, stable
In-Reply-To: <20260615162446.578336-1-rbhansali@marvell.com>
From: Aarnav JP <ajp@marvell.com>
Replace branchless mask-based selection with a ternary operator
to resolve Coverity integer underflow warning. The expression
-(!w1.il3type) assigned -1 to a uint64_t variable, which is
well-defined but flagged as an unsigned integer underflow.
Coverity issue: 502004
Fixes: 19f3af2371a7 ("net/cnxk: add Tx burst for CN10K")
Fixes: 39dc567c1955 ("net/cnxk: add Tx burst for CN9K")
Fixes: 006c1daa89b9 ("net/cnxk: support Tx burst scalar for CN20K")
Cc: stable@dpdk.org
Signed-off-by: Aarnav JP <ajp@marvell.com>
---
Changes in v3: No change.
Changes in v2: No change.
drivers/net/cnxk/cn10k_tx.h | 8 ++------
drivers/net/cnxk/cn20k_tx.h | 8 ++------
drivers/net/cnxk/cn9k_tx.h | 8 ++------
3 files changed, 6 insertions(+), 18 deletions(-)
diff --git a/drivers/net/cnxk/cn10k_tx.h b/drivers/net/cnxk/cn10k_tx.h
index 8c912a1f35..d5cb2c3294 100644
--- a/drivers/net/cnxk/cn10k_tx.h
+++ b/drivers/net/cnxk/cn10k_tx.h
@@ -1138,10 +1138,8 @@ cn10k_nix_xmit_prepare(struct cn10k_eth_txq *txq,
if (flags & NIX_TX_NEED_EXT_HDR && flags & NIX_TX_OFFLOAD_TSO_F &&
(ol_flags & RTE_MBUF_F_TX_TCP_SEG)) {
uint16_t lso_sb;
- uint64_t mask;
- mask = -(!w1.il3type);
- lso_sb = (mask & w1.ol4ptr) + (~mask & w1.il4ptr) + m->l4_len;
+ lso_sb = (w1.il3type ? w1.il4ptr : w1.ol4ptr) + m->l4_len;
send_hdr_ext->w0.lso_sb = lso_sb;
send_hdr_ext->w0.lso = 1;
@@ -1766,13 +1764,11 @@ cn10k_nix_prepare_tso(struct rte_mbuf *m, union nix_send_hdr_w1_u *w1,
const uint64_t flags, const uint64_t lso_tun_fmt)
{
uint16_t lso_sb;
- uint64_t mask;
if (!(ol_flags & RTE_MBUF_F_TX_TCP_SEG))
return;
- mask = -(!w1->il3type);
- lso_sb = (mask & w1->ol4ptr) + (~mask & w1->il4ptr) + m->l4_len;
+ lso_sb = (w1->il3type ? w1->il4ptr : w1->ol4ptr) + m->l4_len;
w0->u |= BIT(14);
w0->lso_sb = lso_sb;
diff --git a/drivers/net/cnxk/cn20k_tx.h b/drivers/net/cnxk/cn20k_tx.h
index 8e64d2e352..a1c71f2761 100644
--- a/drivers/net/cnxk/cn20k_tx.h
+++ b/drivers/net/cnxk/cn20k_tx.h
@@ -1117,10 +1117,8 @@ cn20k_nix_xmit_prepare(struct cn20k_eth_txq *txq, struct rte_mbuf *m, struct rte
if (flags & NIX_TX_NEED_EXT_HDR && flags & NIX_TX_OFFLOAD_TSO_F &&
(ol_flags & RTE_MBUF_F_TX_TCP_SEG)) {
uint16_t lso_sb;
- uint64_t mask;
- mask = -(!w1.il3type);
- lso_sb = (mask & w1.ol4ptr) + (~mask & w1.il4ptr) + m->l4_len;
+ lso_sb = (w1.il3type ? w1.il4ptr : w1.ol4ptr) + m->l4_len;
send_hdr_ext->w0.lso_sb = lso_sb;
send_hdr_ext->w0.lso = 1;
@@ -1732,13 +1730,11 @@ cn20k_nix_prepare_tso(struct rte_mbuf *m, union nix_send_hdr_w1_u *w1, union nix
uint64_t ol_flags, const uint64_t flags, const uint64_t lso_tun_fmt)
{
uint16_t lso_sb;
- uint64_t mask;
if (!(ol_flags & RTE_MBUF_F_TX_TCP_SEG))
return;
- mask = -(!w1->il3type);
- lso_sb = (mask & w1->ol4ptr) + (~mask & w1->il4ptr) + m->l4_len;
+ lso_sb = (w1->il3type ? w1->il4ptr : w1->ol4ptr) + m->l4_len;
w0->u |= BIT(14);
w0->lso_sb = lso_sb;
diff --git a/drivers/net/cnxk/cn9k_tx.h b/drivers/net/cnxk/cn9k_tx.h
index 0ec448e36c..2f9b936d56 100644
--- a/drivers/net/cnxk/cn9k_tx.h
+++ b/drivers/net/cnxk/cn9k_tx.h
@@ -478,10 +478,8 @@ cn9k_nix_xmit_prepare(struct cn9k_eth_txq *txq, struct rte_mbuf *m, struct rte_m
if (flags & NIX_TX_OFFLOAD_TSO_F && (ol_flags & RTE_MBUF_F_TX_TCP_SEG)) {
uint16_t lso_sb;
- uint64_t mask;
- mask = -(!w1.il3type);
- lso_sb = (mask & w1.ol4ptr) + (~mask & w1.il4ptr) + m->l4_len;
+ lso_sb = (w1.il3type ? w1.il4ptr : w1.ol4ptr) + m->l4_len;
send_hdr_ext->w0.lso_sb = lso_sb;
send_hdr_ext->w0.lso = 1;
@@ -875,13 +873,11 @@ cn9k_nix_prepare_tso(struct rte_mbuf *m, union nix_send_hdr_w1_u *w1,
uint64_t flags)
{
uint16_t lso_sb;
- uint64_t mask;
if (!(ol_flags & RTE_MBUF_F_TX_TCP_SEG))
return;
- mask = -(!w1->il3type);
- lso_sb = (mask & w1->ol4ptr) + (~mask & w1->il4ptr) + m->l4_len;
+ lso_sb = (w1->il3type ? w1->il4ptr : w1->ol4ptr) + m->l4_len;
w0->u |= BIT(14);
w0->lso_sb = lso_sb;
--
2.34.1
^ permalink raw reply related
* [PATCH v3 11/20] net/cnxk: enable CPT CQ by default for inline IPsec
From: Rahul Bhansali @ 2026-06-15 16:24 UTC (permalink / raw)
To: dev, Nithin Dabilpuram, Kiran Kumar K, Sunil Kumar Kori,
Satha Rao, Harman Kalra
Cc: jerinj, Aarnav JP
In-Reply-To: <20260615162446.578336-1-rbhansali@marvell.com>
From: Aarnav JP <ajp@marvell.com>
CPT Completion Queue is supported on CN20K and provides
hardware-based completion notification, eliminating the
need for software polling. Change the default value of
cpt_cq_enable devarg from 0 to 1 so that CPT CQ is
enabled by default.
Signed-off-by: Aarnav JP <ajp@marvell.com>
---
Changes in v3: No change.
Changes in v2: No change.
doc/guides/nics/cnxk.rst | 13 +++++++++++++
drivers/net/cnxk/cnxk_ethdev_sec.c | 2 +-
2 files changed, 14 insertions(+), 1 deletion(-)
diff --git a/doc/guides/nics/cnxk.rst b/doc/guides/nics/cnxk.rst
index 239ebcd05c..c71029e1dc 100644
--- a/doc/guides/nics/cnxk.rst
+++ b/doc/guides/nics/cnxk.rst
@@ -745,6 +745,19 @@ Runtime Config Options for inline device
With the above configuration, inline inbound IPsec post-processing
should be done by the application.
+- ``Enable CPT Completion Queue for inline IPsec`` (default ``1`` for CN20K, ``0`` otherwise)
+
+ CPT Completion Queue for inline IPsec event delivery can be enabled or disabled
+ by ``cpt_cq_enable`` devargs parameter.
+ This option is supported on OCTEON CN20K SoC family.
+
+ For example::
+
+ -a 0002:1d:00.0,cpt_cq_enable=1
+
+ With the above configuration, driver would enable CPT completion queue
+ for inline IPsec event delivery instead of using the err-ring poll thread.
+
Port Representors
-----------------
diff --git a/drivers/net/cnxk/cnxk_ethdev_sec.c b/drivers/net/cnxk/cnxk_ethdev_sec.c
index fa7eacfbe4..61eb55ba43 100644
--- a/drivers/net/cnxk/cnxk_ethdev_sec.c
+++ b/drivers/net/cnxk/cnxk_ethdev_sec.c
@@ -742,7 +742,7 @@ nix_inl_parse_devargs(struct rte_devargs *devargs,
uint32_t meta_buf_sz = 0;
uint8_t rx_inj_ena = 0;
uint8_t selftest = 0;
- uint8_t cpt_cq_enable = 0;
+ uint8_t cpt_cq_enable = roc_feature_nix_has_cpt_cq_support() ? 1 : 0;
memset(&cpt_channel, 0, sizeof(cpt_channel));
--
2.34.1
^ permalink raw reply related
* [PATCH v3 10/20] common/cnxk: fix event type for soft expiry
From: Rahul Bhansali @ 2026-06-15 16:24 UTC (permalink / raw)
To: dev, Nithin Dabilpuram, Kiran Kumar K, Sunil Kumar Kori,
Satha Rao, Harman Kalra, Stephen Hemminger
Cc: jerinj, Rahul Bhansali
In-Reply-To: <20260615162446.578336-1-rbhansali@marvell.com>
Fix event type to default for inline soft expiry processing.
Fixes: 4a6154a7bd27 ("common/cnxk: fix array out-of-bounds")
Signed-off-by: Rahul Bhansali <rbhansali@marvell.com>
---
Changes in v3: No change.
Changes in v2: No change.
drivers/common/cnxk/roc_nix_inl_dev.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/common/cnxk/roc_nix_inl_dev.c b/drivers/common/cnxk/roc_nix_inl_dev.c
index 667209b8a0..bfdeef2688 100644
--- a/drivers/common/cnxk/roc_nix_inl_dev.c
+++ b/drivers/common/cnxk/roc_nix_inl_dev.c
@@ -1234,6 +1234,7 @@ inl_outb_soft_exp_poll(struct nix_inl_dev *inl_dev, uint32_t ring_idx)
if (sa != NULL) {
uint64_t tmp[2];
+ tmp[0] = ~0ULL;
inl_dev->work_cb(tmp, sa, NIX_INL_SOFT_EXPIRY_THRD, NULL, port_id);
__atomic_store_n(ring_base + tail_l + 1, 0ULL, __ATOMIC_RELAXED);
__atomic_fetch_add((uint32_t *)ring_base, 1, __ATOMIC_ACQ_REL);
--
2.34.1
^ permalink raw reply related
* [PATCH v3 09/20] common/cnxk: fix cnxk xstats names
From: Rahul Bhansali @ 2026-06-15 16:24 UTC (permalink / raw)
To: dev, Thomas Monjalon, Nithin Dabilpuram, Kiran Kumar K,
Sunil Kumar Kori, Satha Rao, Harman Kalra, Rakesh Kudurumalla
Cc: jerinj, Alok Mishra, stable
In-Reply-To: <20260615162446.578336-1-rbhansali@marvell.com>
From: Alok Mishra <almishra@marvell.com>
Prevent out of bounds writes when application provides a smaller
xstat name array. Return required count when xstats_names is NULL
or when the provided buffer is too small,
Fixes: 825bd1d9d8e6 ("common/cnxk: update extra stats for inline device")
Cc: stable@dpdk.org
Signed-off-by: Alok Mishra <almishra@marvell.com>
---
Changes in v3: No change.
Changes in v2: No change.
.mailmap | 1 +
drivers/common/cnxk/roc_nix_stats.c | 46 ++++++++++++++++-------------
2 files changed, 26 insertions(+), 21 deletions(-)
diff --git a/.mailmap b/.mailmap
index 0e0d83e1c6..efcb38b6bd 100644
--- a/.mailmap
+++ b/.mailmap
@@ -80,6 +80,7 @@ Alin Rauta <alin.rauta@intel.com>
Allain Legacy <allain.legacy@windriver.com>
Allen Hubbe <allen.hubbe@amd.com>
Alok Makhariya <alok.makhariya@nxp.com>
+Alok Mishra <almishra@marvell.com>
Alok Prasad <palok@marvell.com>
Alvaro Karsz <alvaro.karsz@solid-run.com>
Alvin Zhang <alvinx.zhang@intel.com>
diff --git a/drivers/common/cnxk/roc_nix_stats.c b/drivers/common/cnxk/roc_nix_stats.c
index 6f241c72de..ec2aca8164 100644
--- a/drivers/common/cnxk/roc_nix_stats.c
+++ b/drivers/common/cnxk/roc_nix_stats.c
@@ -503,46 +503,51 @@ roc_nix_xstats_names_get(struct roc_nix *roc_nix,
struct idev_cfg *idev = idev_get_cfg();
uint64_t i, count = 0;
- PLT_SET_USED(limit);
-
for (i = 0; i < CNXK_NIX_NUM_TX_XSTATS; i++) {
- NIX_XSTATS_NAME_PRINT(xstats_names, count, nix_tx_xstats, i);
+ if (xstats_names && count < limit)
+ NIX_XSTATS_NAME_PRINT(xstats_names, count, nix_tx_xstats, i);
count++;
}
for (i = 0; i < CNXK_NIX_NUM_RX_XSTATS; i++) {
- NIX_XSTATS_NAME_PRINT(xstats_names, count, nix_rx_xstats, i);
+ if (xstats_names && count < limit)
+ NIX_XSTATS_NAME_PRINT(xstats_names, count, nix_rx_xstats, i);
count++;
}
if (nix->inb_inl_dev && idev) {
if (idev->nix_inl_dev) {
for (i = 0; i < CNXK_INL_NIX_NUM_RX_XSTATS; i++) {
- NIX_XSTATS_NAME_PRINT(xstats_names, count,
- inl_nix_rx_xstats, i);
+ if (xstats_names && count < limit)
+ NIX_XSTATS_NAME_PRINT(xstats_names, count,
+ inl_nix_rx_xstats, i);
count++;
}
for (i = 0; i < CNXK_INL_NIX_RQ_XSTATS; i++) {
- NIX_XSTATS_NAME_PRINT(xstats_names, count,
- inl_nix_rq_xstats, i);
+ if (xstats_names && count < limit)
+ NIX_XSTATS_NAME_PRINT(xstats_names, count,
+ inl_nix_rq_xstats, i);
count++;
}
for (i = 0; i < PLT_DIM(inl_sw_xstats); i++) {
- NIX_XSTATS_NAME_PRINT(xstats_names, count, inl_sw_xstats, i);
+ if (xstats_names && count < limit)
+ NIX_XSTATS_NAME_PRINT(xstats_names, count, inl_sw_xstats,
+ i);
count++;
}
}
}
for (i = 0; i < CNXK_NIX_NUM_QUEUE_XSTATS; i++) {
- NIX_XSTATS_NAME_PRINT(xstats_names, count, nix_q_xstats, i);
+ if (xstats_names && count < limit)
+ NIX_XSTATS_NAME_PRINT(xstats_names, count, nix_q_xstats, i);
count++;
}
if (roc_model_is_cn10k() || roc_model_is_cn20k()) {
for (i = 0; i < CNXK_NIX_NUM_CN10K_RX_XSTATS; i++) {
- NIX_XSTATS_NAME_PRINT(xstats_names, count,
- nix_cn10k_rx_xstats, i);
+ if (xstats_names && count < limit)
+ NIX_XSTATS_NAME_PRINT(xstats_names, count, nix_cn10k_rx_xstats, i);
count++;
}
}
@@ -552,30 +557,29 @@ roc_nix_xstats_names_get(struct roc_nix *roc_nix,
if (roc_model_is_cn9k()) {
for (i = 0; i < CNXK_NIX_NUM_RX_XSTATS_CGX; i++) {
- NIX_XSTATS_NAME_PRINT(xstats_names, count,
- nix_rx_xstats_cgx, i);
+ if (xstats_names && count < limit)
+ NIX_XSTATS_NAME_PRINT(xstats_names, count, nix_rx_xstats_cgx, i);
count++;
}
for (i = 0; i < CNXK_NIX_NUM_TX_XSTATS_CGX; i++) {
- NIX_XSTATS_NAME_PRINT(xstats_names, count,
- nix_tx_xstats_cgx, i);
+ if (xstats_names && count < limit)
+ NIX_XSTATS_NAME_PRINT(xstats_names, count, nix_tx_xstats_cgx, i);
count++;
}
} else {
for (i = 0; i < CNXK_NIX_NUM_RX_XSTATS_RPM; i++) {
- NIX_XSTATS_NAME_PRINT(xstats_names, count,
- nix_rx_xstats_rpm, i);
+ if (xstats_names && count < limit)
+ NIX_XSTATS_NAME_PRINT(xstats_names, count, nix_rx_xstats_rpm, i);
count++;
}
for (i = 0; i < CNXK_NIX_NUM_TX_XSTATS_RPM; i++) {
- NIX_XSTATS_NAME_PRINT(xstats_names, count,
- nix_tx_xstats_rpm, i);
+ if (xstats_names && count < limit)
+ NIX_XSTATS_NAME_PRINT(xstats_names, count, nix_tx_xstats_rpm, i);
count++;
}
}
-
return count;
}
--
2.34.1
^ permalink raw reply related
* [PATCH v3 08/20] net/cnxk: update inbound SA pkind for skip size
From: Rahul Bhansali @ 2026-06-15 16:24 UTC (permalink / raw)
To: dev, Nithin Dabilpuram, Kiran Kumar K, Sunil Kumar Kori,
Satha Rao, Harman Kalra
Cc: jerinj, Rakesh Kudurumalla
In-Reply-To: <20260615162446.578336-1-rbhansali@marvell.com>
From: Rakesh Kudurumalla <rkudurumalla@marvell.com>
Update the inbound SA pkind using roc_npc_skip_size_pkind_get()
during session create and session update for both CN10K and CN20K.
This ensures the CPT second pass uses the correct pkind when
skip size is configured, retaining the default pkind otherwise.
Signed-off-by: Rakesh Kudurumalla <rkudurumalla@marvell.com>
---
Changes in v3: No change.
Changes in v2: No change.
drivers/net/cnxk/cn10k_ethdev_sec.c | 9 +++++++++
drivers/net/cnxk/cn20k_ethdev_sec.c | 8 ++++++++
2 files changed, 17 insertions(+)
diff --git a/drivers/net/cnxk/cn10k_ethdev_sec.c b/drivers/net/cnxk/cn10k_ethdev_sec.c
index 855bea1796..2f1fdf34fc 100644
--- a/drivers/net/cnxk/cn10k_ethdev_sec.c
+++ b/drivers/net/cnxk/cn10k_ethdev_sec.c
@@ -853,6 +853,10 @@ cn10k_eth_sec_session_create(void *device,
goto err;
}
+ rc = roc_npc_skip_size_pkind_get(&dev->npc);
+ if (rc >= 0)
+ inb_sa_dptr->w0.s.pkind = rc;
+
inb_priv = roc_nix_inl_ot_ipsec_inb_sa_sw_rsvd(inb_sa);
/* Back pointer to get eth_sec */
inb_priv->eth_sec = eth_sec;
@@ -1151,6 +1155,11 @@ cn10k_eth_sec_session_update(void *device, struct rte_security_session *sess,
rc = cnxk_ot_ipsec_inb_sa_fill(inb_sa_dptr, ipsec, crypto, 0);
if (rc)
goto err;
+
+ rc = roc_npc_skip_size_pkind_get(&dev->npc);
+ if (rc >= 0)
+ inb_sa_dptr->w0.s.pkind = rc;
+
/* Use cookie for original data */
inb_sa_dptr->w1.s.cookie = inb_sa->w1.s.cookie;
diff --git a/drivers/net/cnxk/cn20k_ethdev_sec.c b/drivers/net/cnxk/cn20k_ethdev_sec.c
index 5d0debb81d..31f2518ea3 100644
--- a/drivers/net/cnxk/cn20k_ethdev_sec.c
+++ b/drivers/net/cnxk/cn20k_ethdev_sec.c
@@ -865,6 +865,10 @@ cn20k_eth_sec_session_create(void *device, struct rte_security_session_conf *con
goto err;
}
+ rc = roc_npc_skip_size_pkind_get(&dev->npc);
+ if (rc >= 0)
+ inb_sa_dptr->w0.s.pkind = rc;
+
cn20k_eth_sec_inb_sa_misc_fill(inb_sa_dptr, ipsec);
inb_priv = roc_nix_inl_ow_ipsec_inb_sa_sw_rsvd(inb_sa);
@@ -1137,6 +1141,10 @@ cn20k_eth_sec_session_update(void *device, struct rte_security_session *sess,
if (rc)
return -EINVAL;
+ rc = roc_npc_skip_size_pkind_get(&dev->npc);
+ if (rc >= 0)
+ inb_sa_dptr->w0.s.pkind = rc;
+
cn20k_eth_sec_inb_sa_misc_fill(inb_sa_dptr, ipsec);
/* Use cookie for original data */
--
2.34.1
^ permalink raw reply related
* [PATCH v3 07/20] drivers: add support for devargs skip size
From: Rahul Bhansali @ 2026-06-15 16:24 UTC (permalink / raw)
To: dev, Nithin Dabilpuram, Kiran Kumar K, Sunil Kumar Kori,
Satha Rao, Harman Kalra
Cc: jerinj
In-Reply-To: <20260615162446.578336-1-rbhansali@marvell.com>
From: Kiran Kumar K <kirankumark@marvell.com>
Adding support for devargs skip_size to cnxk driver.
This allows users to specify the number of bytes to skip in the packet
parsing before L2.
Signed-off-by: Kiran Kumar K <kirankumark@marvell.com>
---
Changes in v3: Addressed review comments from Stephen Hemminger.
Changes in v2: No change.
doc/guides/nics/cnxk.rst | 19 ++++++-
drivers/common/cnxk/roc_mbox.h | 12 ++++-
drivers/common/cnxk/roc_nix.h | 14 ++---
drivers/common/cnxk/roc_nix_ops.c | 46 ++++++++++++++--
drivers/common/cnxk/roc_npc.c | 52 ++++++++++++++++++-
drivers/common/cnxk/roc_npc.h | 2 +
drivers/common/cnxk/roc_npc_priv.h | 11 ++++
.../common/cnxk/roc_platform_base_symbols.c | 1 +
drivers/net/cnxk/cnxk_eswitch.c | 2 +-
drivers/net/cnxk/cnxk_ethdev.c | 7 ++-
drivers/net/cnxk/cnxk_ethdev_devargs.c | 29 ++++++++++-
11 files changed, 171 insertions(+), 24 deletions(-)
diff --git a/doc/guides/nics/cnxk.rst b/doc/guides/nics/cnxk.rst
index b5bd50ceea..239ebcd05c 100644
--- a/doc/guides/nics/cnxk.rst
+++ b/doc/guides/nics/cnxk.rst
@@ -183,8 +183,8 @@ Runtime Config Options
With the above configuration, higig2 will be enabled on that port and the
traffic on this port should be higig2 traffic only. Supported switch header
- types are "chlen24b", "chlen90b", "dsa", "exdsa", "higig2", "vlan_exdsa" and
- "pre_l2".
+ types are "chlen24b", "chlen90b", "dsa", "exdsa", "higig2", "vlan_exdsa",
+ "pre_l2" and "skip_size".
- ``Flow pre_l2 info`` (default ``0x0/0x0/0x0``)
@@ -212,6 +212,21 @@ Runtime Config Options
is 0 (i.e., left shift) then the shift count will be 1, that is, (8 - n),
where n is the absolute position of leftmost set bit.
+- ``Skip size info`` (default ``0x0``)
+
+ When the switch header type is set to "skip_size", the number of bytes to
+ skip before the Ethernet header can be configured using ``skip_size_info``
+ ``devargs`` parameter. The value is in hexadecimal format and the valid
+ range is 0x0 to 0xff. This configures the PKIND so that the NPC parser
+ skips the specified number of bytes.
+
+ For example::
+
+ -a 0002:02:00.0,switch_header="skip_size",skip_size_info=0x2
+
+ With the above configuration, 2 bytes will be skipped before the Ethernet
+ header when parsing the incoming packets.
+
- ``RSS tag as XOR`` (default ``0``)
The HW gives two options to configure the RSS adder i.e
diff --git a/drivers/common/cnxk/roc_mbox.h b/drivers/common/cnxk/roc_mbox.h
index e31abf2234..1158ff50a7 100644
--- a/drivers/common/cnxk/roc_mbox.h
+++ b/drivers/common/cnxk/roc_mbox.h
@@ -462,8 +462,11 @@ struct ready_msg_rsp {
};
enum npc_pkind_type {
+ NPC_RX_SKIP_SIZE_PKIND = 46ULL,
+ NPC_RX_CPT_SKIP_SIZE_PKIND = 50ULL,
+ NPC_RX_CPT_HDR_PTP_PKIND = 54ULL,
NPC_RX_CUSTOM_PRE_L2_PKIND = 55ULL,
- NPC_RX_VLAN_EXDSA_PKIND = 56ULL,
+ NPC_RX_VLAN_EXDSA_PKIND,
NPC_RX_CHLEN24B_PKIND,
NPC_RX_CPT_HDR_PKIND,
NPC_RX_CHLEN90B_PKIND,
@@ -474,6 +477,8 @@ enum npc_pkind_type {
NPC_TX_DEF_PKIND,
};
+#define NPC_SKIP_SIZE_PKIND_MAX 4
+
/* Struct to set pkind */
struct npc_set_pkind {
struct mbox_msghdr hdr;
@@ -484,6 +489,7 @@ struct npc_set_pkind {
#define ROC_PRIV_FLAGS_EXDSA BIT_ULL(4)
#define ROC_PRIV_FLAGS_VLAN_EXDSA BIT_ULL(5)
#define ROC_PRIV_FLAGS_PRE_L2 BIT_ULL(6)
+#define ROC_PRIV_FLAGS_SKIP_SIZE BIT_ULL(7)
#define ROC_PRIV_FLAGS_CUSTOM BIT_ULL(63)
uint64_t __io mode;
#define PKIND_TX BIT_ULL(0)
@@ -499,6 +505,10 @@ struct npc_set_pkind {
/* Shift direction to get length of the
* header at var_len_off
*/
+ uint8_t __io skip_size;
+ /* Number of bytes to skip before the Ethernet header.
+ * Valid only in case custom flag.
+ */
};
/* Structure for requesting resource provisioning.
diff --git a/drivers/common/cnxk/roc_nix.h b/drivers/common/cnxk/roc_nix.h
index 8ba8b3e0b6..49ede85f9a 100644
--- a/drivers/common/cnxk/roc_nix.h
+++ b/drivers/common/cnxk/roc_nix.h
@@ -990,18 +990,14 @@ int __roc_api roc_nix_mac_stats_reset(struct roc_nix *roc_nix);
int __roc_api roc_nix_mac_fwdata_get(struct roc_nix *roc_nix, struct roc_nix_mac_fwdata *fwdata);
/* Ops */
-int __roc_api roc_nix_switch_hdr_set(struct roc_nix *roc_nix,
- uint64_t switch_header_type,
- uint8_t pre_l2_size_offset,
- uint8_t pre_l2_size_offset_mask,
- uint8_t pre_l2_size_shift_dir);
+int __roc_api roc_nix_switch_hdr_set(struct roc_nix *roc_nix, uint64_t switch_header_type,
+ uint8_t pre_l2_size_offset, uint8_t pre_l2_size_offset_mask,
+ uint8_t pre_l2_size_shift_dir, uint8_t skip_size);
int __roc_api roc_nix_lso_fmt_setup(struct roc_nix *roc_nix);
-int __roc_api roc_nix_lso_fmt_get(struct roc_nix *roc_nix,
- uint8_t udp_tun[ROC_NIX_LSO_TUN_MAX],
+int __roc_api roc_nix_lso_fmt_get(struct roc_nix *roc_nix, uint8_t udp_tun[ROC_NIX_LSO_TUN_MAX],
uint8_t tun[ROC_NIX_LSO_TUN_MAX]);
int __roc_api roc_nix_lso_fmt_ipv4_frag_get(struct roc_nix *roc_nix);
-int __roc_api roc_nix_lso_custom_fmt_setup(struct roc_nix *roc_nix,
- struct nix_lso_format *fields,
+int __roc_api roc_nix_lso_custom_fmt_setup(struct roc_nix *roc_nix, struct nix_lso_format *fields,
uint16_t nb_fields);
int __roc_api roc_nix_lso_alt_flags_profile_setup(struct roc_nix *roc_nix,
nix_lso_alt_flg_format_t *fmt);
diff --git a/drivers/common/cnxk/roc_nix_ops.c b/drivers/common/cnxk/roc_nix_ops.c
index 4653bb2049..13a548216b 100644
--- a/drivers/common/cnxk/roc_nix_ops.c
+++ b/drivers/common/cnxk/roc_nix_ops.c
@@ -501,17 +501,49 @@ roc_nix_lso_fmt_get(struct roc_nix *roc_nix,
return 0;
}
+static int
+skip_size_pkind_get(uint8_t skip_size, uint8_t *pkind)
+{
+ struct skip_size_pkind_cfg *cfg;
+ const struct plt_memzone *mz;
+ int i;
+
+ mz = plt_memzone_lookup(SKIP_SIZE_PKIND_MEMZONE);
+ if (!mz)
+ return -ENOMEM;
+ cfg = mz->addr;
+
+ for (i = 0; i < cfg->count; i++) {
+ if (cfg->entries[i].skip_size == skip_size) {
+ *pkind = cfg->entries[i].pkind;
+ return 0;
+ }
+ }
+
+ if (cfg->count >= NPC_SKIP_SIZE_PKIND_MAX) {
+ plt_err("skip_size PKIND limit (%d) reached", NPC_SKIP_SIZE_PKIND_MAX);
+ return -ENOSPC;
+ }
+
+ i = cfg->count;
+ cfg->entries[i].skip_size = skip_size;
+ cfg->entries[i].pkind = NPC_RX_SKIP_SIZE_PKIND + i;
+ *pkind = cfg->entries[i].pkind;
+ cfg->count++;
+ return 0;
+}
+
int
roc_nix_switch_hdr_set(struct roc_nix *roc_nix, uint64_t switch_header_type,
- uint8_t pre_l2_size_offset,
- uint8_t pre_l2_size_offset_mask,
- uint8_t pre_l2_size_shift_dir)
+ uint8_t pre_l2_size_offset, uint8_t pre_l2_size_offset_mask,
+ uint8_t pre_l2_size_shift_dir, uint8_t skip_size)
{
struct nix *nix = roc_nix_to_nix_priv(roc_nix);
struct dev *dev = &nix->dev;
struct mbox *mbox = mbox_get(dev->mbox);
struct npc_set_pkind *req;
struct msg_resp *rsp;
+ uint8_t pkind = 0;
int rc = -ENOSPC;
if (switch_header_type == 0)
@@ -524,6 +556,7 @@ roc_nix_switch_hdr_set(struct roc_nix *roc_nix, uint64_t switch_header_type,
switch_header_type != ROC_PRIV_FLAGS_EXDSA &&
switch_header_type != ROC_PRIV_FLAGS_VLAN_EXDSA &&
switch_header_type != ROC_PRIV_FLAGS_PRE_L2 &&
+ switch_header_type != ROC_PRIV_FLAGS_SKIP_SIZE &&
switch_header_type != ROC_PRIV_FLAGS_CUSTOM) {
plt_err("switch header type is not supported");
rc = NIX_ERR_PARAM;
@@ -564,6 +597,13 @@ roc_nix_switch_hdr_set(struct roc_nix *roc_nix, uint64_t switch_header_type,
req->var_len_off = pre_l2_size_offset;
req->var_len_off_mask = pre_l2_size_offset_mask;
req->shift_dir = pre_l2_size_shift_dir;
+ } else if (switch_header_type == ROC_PRIV_FLAGS_SKIP_SIZE) {
+ rc = skip_size_pkind_get(skip_size, &pkind);
+ if (rc)
+ goto exit;
+ req->mode = ROC_PRIV_FLAGS_CUSTOM;
+ req->pkind = pkind;
+ req->skip_size = skip_size;
}
req->dir = PKIND_RX;
diff --git a/drivers/common/cnxk/roc_npc.c b/drivers/common/cnxk/roc_npc.c
index a906fe0413..a8a31c7f6c 100644
--- a/drivers/common/cnxk/roc_npc.c
+++ b/drivers/common/cnxk/roc_npc.c
@@ -420,6 +420,16 @@ roc_npc_init(struct roc_npc *roc_npc)
roc_npc->flow_age.age_flow_refcnt = 0;
+ /* Create skip-size PKIND memzone if it doesn't exist */
+ if (!plt_memzone_lookup(SKIP_SIZE_PKIND_MEMZONE)) {
+ const struct plt_memzone *mz;
+
+ mz = plt_memzone_reserve_cache_align(SKIP_SIZE_PKIND_MEMZONE,
+ sizeof(struct skip_size_pkind_cfg));
+ if (mz != NULL)
+ memset(mz->addr, 0, sizeof(struct skip_size_pkind_cfg));
+ }
+
return rc;
done:
@@ -436,6 +446,9 @@ int
roc_npc_fini(struct roc_npc *roc_npc)
{
struct npc *npc = roc_npc_to_npc_priv(roc_npc);
+ struct skip_size_pkind_cfg *cfg;
+ const struct plt_memzone *mz;
+ uint16_t i, count = 0;
int rc;
if (!roc_npc->flow_age.aged_flows_get_thread_exit)
@@ -457,12 +470,47 @@ roc_npc_fini(struct roc_npc *roc_npc)
npc->prio_flow_list = NULL;
}
+ mz = plt_memzone_lookup(SKIP_SIZE_PKIND_MEMZONE);
+ if (mz) {
+ cfg = mz->addr;
+
+ for (i = 0; i < cfg->count; i++) {
+ if (cfg->entries[i].skip_size == 0)
+ count++;
+ }
+
+ if (count == cfg->count)
+ plt_memzone_free(mz);
+ }
+
return 0;
}
int
-roc_npc_validate_portid_action(struct roc_npc *roc_npc_src,
- struct roc_npc *roc_npc_dst)
+roc_npc_skip_size_pkind_get(struct roc_npc *roc_npc)
+{
+ struct skip_size_pkind_cfg *cfg;
+ const struct plt_memzone *mz;
+ int i;
+
+ if (roc_npc->switch_header_type != ROC_PRIV_FLAGS_SKIP_SIZE)
+ return -1;
+
+ mz = plt_memzone_lookup(SKIP_SIZE_PKIND_MEMZONE);
+ if (!mz)
+ return -1;
+ cfg = mz->addr;
+
+ for (i = 0; i < cfg->count; i++) {
+ if (cfg->entries[i].skip_size == roc_npc->skip_size)
+ return cfg->entries[i].pkind + NPC_SKIP_SIZE_PKIND_MAX;
+ }
+
+ return -1;
+}
+
+int
+roc_npc_validate_portid_action(struct roc_npc *roc_npc_src, struct roc_npc *roc_npc_dst)
{
struct roc_nix *roc_nix_src = roc_npc_src->roc_nix;
struct nix *nix_src = roc_nix_to_nix_priv(roc_nix_src);
diff --git a/drivers/common/cnxk/roc_npc.h b/drivers/common/cnxk/roc_npc.h
index 130990bda7..a7254f35ca 100644
--- a/drivers/common/cnxk/roc_npc.h
+++ b/drivers/common/cnxk/roc_npc.h
@@ -423,6 +423,7 @@ struct roc_npc {
*/
uint8_t pre_l2_size_shift_dir; /**< Shift direction to calculate size
*/
+ uint8_t skip_size; /**< Switch header skip size */
uint16_t flow_prealloc_size;
uint16_t flow_max_priority;
uint16_t channel;
@@ -506,4 +507,5 @@ void __roc_api roc_npc_sdp_channel_get(struct roc_npc *roc_npc, uint16_t *chan_b
uint16_t *chan_mask);
int __roc_api roc_npc_mcam_get_stats(struct roc_npc *roc_npc, struct roc_npc_flow *flow,
uint64_t *count);
+int __roc_api roc_npc_skip_size_pkind_get(struct roc_npc *roc_npc);
#endif /* _ROC_NPC_H_ */
diff --git a/drivers/common/cnxk/roc_npc_priv.h b/drivers/common/cnxk/roc_npc_priv.h
index f8f4489f06..6a27f0e0fa 100644
--- a/drivers/common/cnxk/roc_npc_priv.h
+++ b/drivers/common/cnxk/roc_npc_priv.h
@@ -554,4 +554,15 @@ int npc_aging_ctrl_thread_create(struct roc_npc *roc_npc, const struct roc_npc_a
struct roc_npc_flow *flow);
void npc_aging_ctrl_thread_destroy(struct roc_npc *roc_npc);
int npc_rss_free_grp_get(struct npc *npc, uint32_t *pos);
+
+#define SKIP_SIZE_PKIND_MEMZONE "roc_skip_size_pkind_cfg"
+
+struct skip_size_pkind_cfg {
+ uint8_t count;
+ struct {
+ uint8_t skip_size;
+ uint8_t pkind;
+ } entries[NPC_SKIP_SIZE_PKIND_MAX];
+};
+
#endif /* _ROC_NPC_PRIV_H_ */
diff --git a/drivers/common/cnxk/roc_platform_base_symbols.c b/drivers/common/cnxk/roc_platform_base_symbols.c
index ed34d4b05b..d1c9f2304d 100644
--- a/drivers/common/cnxk/roc_platform_base_symbols.c
+++ b/drivers/common/cnxk/roc_platform_base_symbols.c
@@ -492,6 +492,7 @@ RTE_EXPORT_INTERNAL_SYMBOL(roc_npc_fini)
RTE_EXPORT_INTERNAL_SYMBOL(roc_npc_validate_portid_action)
RTE_EXPORT_INTERNAL_SYMBOL(roc_npc_flow_parse)
RTE_EXPORT_INTERNAL_SYMBOL(roc_npc_sdp_channel_get)
+RTE_EXPORT_INTERNAL_SYMBOL(roc_npc_skip_size_pkind_get)
RTE_EXPORT_INTERNAL_SYMBOL(roc_npc_flow_create)
RTE_EXPORT_INTERNAL_SYMBOL(roc_npc_flow_destroy)
RTE_EXPORT_INTERNAL_SYMBOL(roc_npc_flow_dump)
diff --git a/drivers/net/cnxk/cnxk_eswitch.c b/drivers/net/cnxk/cnxk_eswitch.c
index e45c7dfd07..7e717a2fbf 100644
--- a/drivers/net/cnxk/cnxk_eswitch.c
+++ b/drivers/net/cnxk/cnxk_eswitch.c
@@ -553,7 +553,7 @@ nix_lf_setup(struct cnxk_eswitch_dev *eswitch_dev)
goto free_cqs;
}
- rc = roc_nix_switch_hdr_set(nix, 0, 0, 0, 0);
+ rc = roc_nix_switch_hdr_set(nix, 0, 0, 0, 0, 0);
if (rc) {
plt_err("switch hdr set failed = %s(%d)", roc_error_msg_get(rc), rc);
goto free_cqs;
diff --git a/drivers/net/cnxk/cnxk_ethdev.c b/drivers/net/cnxk/cnxk_ethdev.c
index edd9f09c4f..f7b66da3dc 100644
--- a/drivers/net/cnxk/cnxk_ethdev.c
+++ b/drivers/net/cnxk/cnxk_ethdev.c
@@ -1639,10 +1639,9 @@ cnxk_nix_configure(struct rte_eth_dev *eth_dev)
goto free_nix_lf;
}
- rc = roc_nix_switch_hdr_set(nix, dev->npc.switch_header_type,
- dev->npc.pre_l2_size_offset,
+ rc = roc_nix_switch_hdr_set(nix, dev->npc.switch_header_type, dev->npc.pre_l2_size_offset,
dev->npc.pre_l2_size_offset_mask,
- dev->npc.pre_l2_size_shift_dir);
+ dev->npc.pre_l2_size_shift_dir, dev->npc.skip_size);
if (rc) {
plt_err("Failed to enable switch type nix_lf rc=%d", rc);
goto free_nix_lf;
@@ -2365,7 +2364,7 @@ cnxk_eth_dev_uninit(struct rte_eth_dev *eth_dev, bool reset)
return 0;
/* Disable switch hdr pkind */
- roc_nix_switch_hdr_set(&dev->nix, 0, 0, 0, 0);
+ roc_nix_switch_hdr_set(&dev->nix, 0, 0, 0, 0, 0);
/* Clear the flag since we are closing down */
dev->configured = 0;
diff --git a/drivers/net/cnxk/cnxk_ethdev_devargs.c b/drivers/net/cnxk/cnxk_ethdev_devargs.c
index da8fc83f9d..ea18090919 100644
--- a/drivers/net/cnxk/cnxk_ethdev_devargs.c
+++ b/drivers/net/cnxk/cnxk_ethdev_devargs.c
@@ -239,6 +239,25 @@ parse_switch_header_type(const char *key, const char *value, void *extra_args)
if (strcmp(value, "pre_l2") == 0)
*(uint16_t *)extra_args = ROC_PRIV_FLAGS_PRE_L2;
+ if (strcmp(value, "skip_size") == 0)
+ *(uint16_t *)extra_args = ROC_PRIV_FLAGS_SKIP_SIZE;
+
+ return 0;
+}
+
+static int
+parse_skip_size_info(const char *key, const char *value, void *extra_args)
+{
+ RTE_SET_USED(key);
+ uint32_t val;
+
+ errno = 0;
+ val = strtoul(value, NULL, 0);
+ if (errno || val > 255)
+ return -EINVAL;
+
+ *(uint16_t *)extra_args = val;
+
return 0;
}
@@ -303,6 +322,7 @@ parse_val_u16(const char *key, const char *value, void *extra_args)
#define CNXK_FORCE_TAIL_DROP "force_tail_drop"
#define CNXK_DIS_XQE_DROP "disable_xqe_drop"
#define CNXK_RXC_STEP "rxc_step"
+#define CNXK_SKIP_SIZE_INFO "skip_size_info"
int
cnxk_ethdev_parse_devargs(struct rte_devargs *devargs, struct cnxk_eth_dev *dev)
@@ -317,6 +337,7 @@ cnxk_ethdev_parse_devargs(struct rte_devargs *devargs, struct cnxk_eth_dev *dev)
uint16_t custom_meta_aura_dis = 0;
uint16_t flow_prealloc_size = 1;
uint16_t switch_header_type = 0;
+ uint16_t skip_size_info = 0;
uint16_t flow_max_priority = 3;
uint16_t outb_nb_crypto_qs = 1;
uint32_t ipsec_in_min_spi = 0;
@@ -392,6 +413,8 @@ cnxk_ethdev_parse_devargs(struct rte_devargs *devargs, struct cnxk_eth_dev *dev)
rte_kvargs_process(kvlist, CNXK_FORCE_TAIL_DROP, &parse_flag, &force_tail_drop);
rte_kvargs_process(kvlist, CNXK_DIS_XQE_DROP, &parse_flag, &dis_xqe_drop);
rte_kvargs_process(kvlist, CNXK_RXC_STEP, &parse_rxc_step, &rxc_step);
+ rte_kvargs_process(kvlist, CNXK_SKIP_SIZE_INFO, &parse_skip_size_info,
+ &skip_size_info);
rte_kvargs_free(kvlist);
null_devargs:
@@ -424,6 +447,7 @@ cnxk_ethdev_parse_devargs(struct rte_devargs *devargs, struct cnxk_eth_dev *dev)
dev->npc.flow_max_priority = flow_max_priority;
dev->npc.switch_header_type = switch_header_type;
+ dev->npc.skip_size = skip_size_info;
dev->npc.sdp_channel = sdp_chan.channel;
dev->npc.sdp_channel_mask = sdp_chan.mask;
dev->npc.is_sdp_mask_set = sdp_chan.is_sdp_mask_set;
@@ -448,7 +472,7 @@ RTE_PMD_REGISTER_PARAM_STRING(net_cnxk,
CNXK_MAX_SQB_COUNT "=<8-512>"
CNXK_FLOW_PREALLOC_SIZE "=<1-32>"
CNXK_FLOW_MAX_PRIORITY "=<1-32>"
- CNXK_SWITCH_HEADER_TYPE "=<higig2|dsa|chlen90b>"
+ CNXK_SWITCH_HEADER_TYPE "=<higig2|dsa|chlen90b|skip_size>"
CNXK_RSS_TAG_AS_XOR "=1"
CNXK_IPSEC_IN_MAX_SPI "=<1-65535>"
CNXK_OUTB_NB_DESC "=<1-65535>"
@@ -463,4 +487,5 @@ RTE_PMD_REGISTER_PARAM_STRING(net_cnxk,
CNXK_CUSTOM_META_AURA_DIS "=1"
CNXK_FORCE_TAIL_DROP "=1"
CNXK_DIS_XQE_DROP "=1"
- CNXK_RXC_STEP "=<0-1048575>");
+ CNXK_RXC_STEP "=<0-1048575>"
+ CNXK_SKIP_SIZE_INFO "=<0x0-0xff>");
--
2.34.1
^ permalink raw reply related
* [PATCH v3 06/20] net/cnxk: reserve memory for lookup mem at probe
From: Rahul Bhansali @ 2026-06-15 16:24 UTC (permalink / raw)
To: dev, Nithin Dabilpuram, Kiran Kumar K, Sunil Kumar Kori,
Satha Rao, Harman Kalra
Cc: jerinj
In-Reply-To: <20260615162446.578336-1-rbhansali@marvell.com>
From: Nithin Dabilpuram <ndabilpuram@marvell.com>
Reserve memory for lookup mem at probe that is global for
all cnxk ethdev devices to avoid race at later stage.
Signed-off-by: Nithin Dabilpuram <ndabilpuram@marvell.com>
---
Changes in v3: Addressed review comments from Stephen Hemminger.
Changes in v2: No change.
drivers/net/cnxk/cnxk_ethdev.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/drivers/net/cnxk/cnxk_ethdev.c b/drivers/net/cnxk/cnxk_ethdev.c
index 06d1c9b362..edd9f09c4f 100644
--- a/drivers/net/cnxk/cnxk_ethdev.c
+++ b/drivers/net/cnxk/cnxk_ethdev.c
@@ -2220,6 +2220,13 @@ cnxk_eth_dev_init(struct rte_eth_dev *eth_dev)
/* Register callback for inline meta pool create 1:N pool:aura */
roc_nix_inl_custom_meta_pool_cb_register(cnxk_nix_inl_custom_meta_pool_cb);
+ /* Reserve memory for lookup_memory */
+ if (!cnxk_nix_fastpath_lookup_mem_get()) {
+ plt_err("Failed to reserve lookup memory");
+ rc = -ENOMEM;
+ goto dev_fini;
+ }
+
dev->eth_dev = eth_dev;
dev->configured = 0;
dev->ptype_disable = 0;
--
2.34.1
^ permalink raw reply related
* [PATCH v3 05/20] common/cnxk: configure LSO mask for single segments
From: Rahul Bhansali @ 2026-06-15 16:24 UTC (permalink / raw)
To: dev, Nithin Dabilpuram, Kiran Kumar K, Sunil Kumar Kori,
Satha Rao, Harman Kalra
Cc: jerinj, Rahul Bhansali
In-Reply-To: <20260615162446.578336-1-rbhansali@marvell.com>
Configures LSO flag mask for single packets.
Signed-off-by: Rahul Bhansali <rbhansali@marvell.com>
---
Changes in v3: No change.
Changes in v2: No change.
drivers/common/cnxk/roc_nix_ops.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/common/cnxk/roc_nix_ops.c b/drivers/common/cnxk/roc_nix_ops.c
index 12a12c6e35..4653bb2049 100644
--- a/drivers/common/cnxk/roc_nix_ops.c
+++ b/drivers/common/cnxk/roc_nix_ops.c
@@ -239,6 +239,8 @@ nix_lso_ipv4(struct roc_nix *roc_nix)
/* First get flags profile to update v4 flags */
memset(&alt_flags, 0, sizeof(alt_flags));
+ alt_flags.s.alt_ssf_set = 0;
+ alt_flags.s.alt_ssf_mask = 0xFFFF;
alt_flags.s.alt_fsf_set = 0x2000;
alt_flags.s.alt_fsf_mask = 0x5FFF;
alt_flags.s.alt_msf_set = 0x2000;
--
2.34.1
^ permalink raw reply related
* [PATCH v3 04/20] common/cnxk: update NIX irq handler
From: Rahul Bhansali @ 2026-06-15 16:24 UTC (permalink / raw)
To: dev, Nithin Dabilpuram, Kiran Kumar K, Sunil Kumar Kori,
Satha Rao, Harman Kalra
Cc: jerinj, Rahul Bhansali
In-Reply-To: <20260615162446.578336-1-rbhansali@marvell.com>
Move queue context dump and register print before interrupt
clear in NIX irq handler.
Signed-off-by: Rahul Bhansali <rbhansali@marvell.com>
---
Changes in v3: No change.
Changes in v2: No change.
drivers/common/cnxk/roc_nix_irq.c | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/drivers/common/cnxk/roc_nix_irq.c b/drivers/common/cnxk/roc_nix_irq.c
index 2b731302cd..6874435a4e 100644
--- a/drivers/common/cnxk/roc_nix_irq.c
+++ b/drivers/common/cnxk/roc_nix_irq.c
@@ -168,7 +168,7 @@ nix_lf_q_irq_get_and_clear(struct nix *nix, uint16_t q, uint32_t off,
reg = roc_atomic64_add_nosync(wdata, (int64_t *)(nix->base + off));
if (reg & BIT_ULL(42) /* OP_ERR */) {
- plt_err("Failed execute irq get off=0x%x", off);
+ plt_err("Failed execute irq get queue=%d off=0x%x", q, off);
return 0;
}
qint = reg & 0xff;
@@ -262,6 +262,10 @@ nix_lf_q_irq(void *param)
plt_err("Queue_intr=0x%" PRIx64 " qintx=%d pf=%d, vf=%d", intr, qintx,
dev->pf, dev->vf);
+ /* Dump registers to std out */
+ roc_nix_lf_reg_dump(nix_priv_to_roc_nix(nix), NULL);
+ roc_nix_queues_ctx_dump(nix_priv_to_roc_nix(nix), NULL);
+
/* Handle RQ interrupts */
for (q = 0; q < nix->nb_rx_queues; q++) {
rq = q % nix->qints;
@@ -323,10 +327,6 @@ nix_lf_q_irq(void *param)
/* Clear interrupt */
plt_write64(intr, nix->base + NIX_LF_QINTX_INT(qintx));
- /* Dump registers to std out */
- roc_nix_lf_reg_dump(nix_priv_to_roc_nix(nix), NULL);
- roc_nix_queues_ctx_dump(nix_priv_to_roc_nix(nix), NULL);
-
/* Call reset callback */
if (intr_cb && dev->ops->q_err_cb)
dev->ops->q_err_cb(nix_priv_to_roc_nix(nix), NULL);
--
2.34.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