RE: [PATCH v9-1 00/14] net/enetc: add new features for ENETC4 on i.MX95

Gagandeep Singh <[email protected]>
Newsgroups org.dpdk.dev
Message-ID <AMBPR04MB1228151E3124CC303F50909CCE1A72@AMBPR04MB12281.eurprd04.prod.outlook.com>
Hi,



NXP Confidential
> -----Original Message-----
> From: Stephen Hemminger <[email protected]>
> Sent: Saturday, August 15, 2026 8:47 PM
> To: Gagandeep Singh <[email protected]>
> Cc: [email protected]; Hemant Agrawal <[email protected]>
> Subject: Re: [PATCH v9-1 00/14] net/enetc: add new features for ENETC4 on
> i.MX95
>
> On Thu, 13 Aug 2026 17:43:44 +0530
> Gagandeep Singh <[email protected]> wrote:
>
> > V9-Changes:
> >  - Mid-body variable declaration moved to top of the function.
> >  - ret=0 dead code is removed.
> >  - Added check on return value of rte_intr_callback_unregister()
> >  - The pre-existing reply_msg leak fixed.
> >  - Added primary-process guard in enetc4_vf_dev_init
> >  - Removed Flow control from enetc4.ini
> >  - Fixed VF stats_reset baseline underflows on counter wrap
> >  - Fixed VF vlan_pvid_set fails on every successful command
> >
> > V8-changes:
> >  - Fixed Warning RBMR RMW races between threads by adding lock
> >  - Fixed `static const` arrays in `enetc.h`
> >  - Proper pthread_mutexattr_t initialization added as suggested by AI
> >  - VSIMSGSR stale re-read race is eliminated
> >
> > V7-changes:
> >  - added missing 14th patch.
> >
> > V6-changes:
> >  - fixed free() on memory allocated with rte_zmalloc().
> >  - fixed eventfd and vector-list leak on interrupt teardown
> >  - fixed Rx ring doubling still bypasses
> >  - fixed VSI-PSI transaction issued from the interrupt handler
> >  - fixed the free-and-reallocate of msg is unnecessary churn
> >  - fixed unsynchronized access to tx_pause_active and RBMR
> >  - fixed signed shift overflow in the register-dump version field
> >  - fixed the fw_size == 0 early return reports the length of "0.0"
> >  - unwanted blank lines removed.
> >  - parse_txq_prior() returns updated.
> >
> > V5-changes:
> >  - Patch 1 Build fixes which includes:
> >     'prev_seg' undeclared fixed.
> >     redefinition of 'dev_rx_offloads_sup' fixed.
> >     Error: duplicate rx_enable declaration fixed.
> >    PF loses Scattered Rx and Multi-segment Tx
> >  - mbuf leak in enetc_xmit_pkts_lso() fixed.
> >  - fixed conversion on ENETC4_TXBD_FLAGS_F issue.
> >  - fixed link speed decode has no upper bound.
> >  - fixed mailbox ops added to the no-VSI ops table.
> >  - new devargs documented.
> >
> > V4-changes:
> >  - fix doc build issue: WARNING: undefined label: pmd_build_and_test
> >
> > v3-changes:
> >  - fix doc build issue.
> >  - fix compilation issue on fedore:43-gcc-minsize
> >
> > V2-changes:
> >  - compilation fixes.
> >
> > V1-changes:
> > This series adds new PMD features to the ENETC4 driver targeting the
> > NXP i.MX95 NETC IP.
> >
> > The series covers:
> >
> >  - KEEP_CRC Rx offload: preserve the Ethernet FCS in the receive buffer.
> >  - TSO: TCP Segmentation Offload for the VF Tx path.
> >  - RSC/LRO: hardware Receive Segment Coalesce for PF and VF Rx paths.
> >  - Link speed code: extend the PF-to-VF mailbox field from 4-bit to
> >    8-bit to support speeds beyond 10G.
> >  - Firmware version: report the NETC IP version via fw_version_get.
> >  - Register dump: dump SI, port (PF) and BD ring registers.
> >  - Ring parameters: implement rxq_info_get / txq_info_get for the VF.
> >  - Link-up interrupt: refresh the cached link speed on each VF link-up
> >    interrupt so that link_update returns the current speed immediately.
> >  - Stats reset: software snapshot/delta approach for VF counter reset.
> >  - Per-queue Rx interrupt: MSI-X per-queue Rx interrupts for the VF,
> >    enabling interrupt-driven receive with l3fwd-power.
> >  - SI VLAN: hardware port VLAN insertion/removal for PF and VF.
> >  - VF link status bitmask: switch VF link status to bitmask encoding
> >    to align with the PF and newer kernel driver conventions.
> >  - TX PAUSE: VF sets Rx congestion mode when the PF signals TX PAUSE
> >    negotiated on the wire; adds Flow control = Y to enetc4.ini.
> >  - WRR Tx scheduler: per-ring WRR weights via enetc4_txq_wrr devarg.
> >
> > Gagandeep Singh (14):
> >   net/enetc: add keep-CRC Rx offload for ENETC4
> >   net/enetc: add TSO support for ENETC4 VF
> >   net/enetc: add RSC (hardware LRO) support for ENETC4
> >   net/enetc: extend PF-VF link speed field to 8 bits
> >   net/enetc: support firmware version get for VF
> >   net/enetc: support registers dump
> >   net/enetc: support ethtool ring parameters
> >   net/enetc: refresh link speed on VF link-up interrupt
> >   net/enetc: support stats reset for VF
> >   net/enetc4: add per-queue Rx interrupt support for VF
> >   net/enetc4: add SI-based port VLAN insertion and removal
> >   net/enetc4: update VF link status to bitmask encoding
> >   net/enetc4: enable Tx PAUSE via VF Rx congestion mode
> >   net/enetc4: add WRR Tx scheduler devarg for VF rings
> >
> >  doc/guides/nics/enetc4.rst             | 100 +++
> >  doc/guides/nics/features/enetc4.ini    |   7 +
> >  doc/guides/rel_notes/release_26_11.rst |  21 +
> >  drivers/net/enetc/base/enetc4_hw.h     | 137 +++-
> >  drivers/net/enetc/base/enetc_hw.h      |   6 +
> >  drivers/net/enetc/enetc.h              | 132 +++-
> >  drivers/net/enetc/enetc4_ethdev.c      | 459 +++++++++++--
> >  drivers/net/enetc/enetc4_vf.c          | 870 +++++++++++++++++++++----
> >  drivers/net/enetc/enetc_rxtx.c         | 530 ++++++++++++++-
> >  9 files changed, 2084 insertions(+), 178 deletions(-)
> >
>
> Still some AI review feedback items that need addressing.
> I say addressing because AI can and does spot things that are not a real problem.
>
> ENETC4 v9 series review - 14 patches
>
> No Reviewed-by.  The two v8 errors are fixed, but this revision introduces a
> regression in patch 14 that silently disables the existing enetc4_txq_prior devarg,
> and the patch 11 reply check looks inverted rather than fixed.  Applied cleanly
> onto c1a46b9; source review only, no builds.
>
>
> Fixed from v8
>
> enetc4_rd64() now reads the 64-bit SI counters as a high/low pair and oerrors is
> masked to 32 bits before the subtraction, so the stats_reset delta no longer
> underflows on counter wrap.  "Flow control = Y" is gone from enetc4.ini.  The
> ring-doubling paths validate the doubled count against MAX_BD_COUNT.
> enetc4_vf_link_update() frees reply_msg on both "Wrong reply message" paths.
> Interrupt teardown frees the vector list and disables the efds.  txq_prior moved to
> rte_zmalloc/rte_free consistently, with the old allocation released before re-
> parsing.
>
>
> Errors
>
> Patch 14 - enetc4_txq_prior and enetc4_txq_wrr have no effect at queue setup.
>
> In enetc4_tx_queue_setup() the hunk changed the target variable but not the
> register write:
>
>   uint32_t tx_en = ENETC_TBMR_EN;
>
>   if (priv->hw.txq_prior)
>           tx_data |= priv->hw.txq_prior[tx_ring->index];
>   if (priv->hw.txq_wrr)
>           tx_data |= priv->hw.txq_wrr[tx_ring->index];
>   /* enable ring */
>   enetc4_txbdr_wr(&priv->hw.hw, tx_ring->index, ENETC_TBMR, tx_en);
>
> tx_data is never read again, so both the priority and the WRR weight are dropped
> and only ENETC_TBMR_EN reaches TBaMR.  This is a regression: v8 had "tx_en
> |= priv->hw.txq_prior[...]", which worked.  The scheduler bits now only get
> programmed through enetc4_tx_queue_start(), which non-deferred queues never
> go through.  Either OR into tx_en, or drop tx_en and write tx_data |
> ENETC_TBMR_EN.
>
> Patch 11 - the vlan_pvid_set reply check is inverted, not fixed.
>
>   if (reply_msg->class_id != ENETC_CLASS_ID_SI_VLAN_ISO) {
>           ENETC_PMD_ERR("SI VLAN isolation command failed: ...");
>           err = -EINVAL;
>   }
>
> For the configuration command classes the driver already handles, class_id equal
> to the command class is the failure indication and
> ENETC_MSG_CLASS_ID_CMD_SUCCESS (0x1) is success.  Both MAC and VLAN
> filter follow that shape:
>
>   if (class_id == ENETC_CLASS_ID_MAC_FILTER) {
>           switch (status) { ... default: err = -EINVAL; }
>   }
>
> that is, every status under 0x20 is an error.  If 0x20 were also returned on success,
> set_mac_addr could never succeed.
>
> SI VLAN isolation (0x24) is a set-type command in the same 0x2x family, so
> success should arrive as 0x1 and 0x24 should carry a class-specific error status.
> As written the function still returns -EINVAL on every successful command, the
> same symptom as v8 with a different comparand.
> The shape to match is:
>
>   if (reply_msg->class_id == ENETC_CLASS_ID_SI_VLAN_ISO) {
>           /* class-specific failure: inspect reply_msg->status */
>           err = -EINVAL;
>   }
>
> The classes where class_id == command class *is* the success reply are the
> query classes - LINK_STATUS (0x80), LINK_SPEED (0x81), GET_IP_VER
> (0xF0) - which return data in the status byte.  If the PSI really does return 0x24 on
> success for this command, please say so in the commit message, since it
> contradicts the convention every other setter in the file uses.

I checked the kernel PF reply. The PSI reports command completion in the reply class_id: a
successful command returns ENETC_MSG_CLASS_ID_CMD_SUCCESS (0x1),
while any other class_id (e.g. CMD_NOT_SUPPORT 0x3) indicates a
failure. The command class value (0x24) is only used in the outgoing VF-to-PSI header and is never echoed back in the reply,
So treating class_id != CMD_SUCCESS as failure.

>
> Warnings
>
> Patch 11 - "VLAN offload = Y" added to enetc4.ini for a pvid change.
>
> doc/guides/nics/features.rst lists vlan_pvid_set under "Other dev ops not
> represented by a Feature"; pvid has no matrix entry.  The VLAN offload entry
> requires vlan_offload_set plus RTE_ETH_RX_OFFLOAD_VLAN_STRIP /
> RTE_ETH_TX_OFFLOAD_VLAN_INSERT in rx_offload_capa / tx_offload_capa.
> The PF ops table has no vlan_offload_set at all and neither offload flag is in
> dev_rx_offloads_sup / dev_tx_offloads_sup.  Drop the line.
>
> Patches 02 and 03 - the burst function is selected on enable but never restored.
>
> enetc4_rx_queue_setup() sets dev->rx_pkt_burst = &enetc_recv_pkts_rsc when
> LRO is requested and enetc4_tx_queue_setup() sets
> dev->tx_pkt_burst = &enetc_xmit_pkts_lso when TSO is requested; neither
> has an else branch.  The defaults are assigned once at probe in
> enetc4_dev_hw_init().  After a dev_stop plus rte_eth_dev_configure() without
> those offloads the pointers keep their previous values, and
> enetc_clean_rx_ring_rsc() then walks a 16B-descriptor ring as if it were 32B (i +=
> 2, bd_count not doubled, extension slot read from the neighbouring descriptor).
> The RSC assignment also happens before enetc4_alloc_rxbdr(), so it survives a
> failed setup.
>
>
> Info
>
> Patch 09 - enetc4_rd64() reads high and low with no re-read of the low word, so a
> carry between the two accesses yields a value 2^32 too large.  The window is tiny
> but the error is not; the usual form is read-high / read-low / read-high-again and
> retry if the high word moved.  Related: the operands of | have unspecified
> evaluation order, so which half is fetched first is up to the compiler.
>
> Patch 10 - enetc4_vf_rx_queue_intr_enable() writes RBICR1 = 0 and
> RBICR0 = ICEN | ICPT(1), overwriting the coalescing timer that patch 03 programs
> for RSC (ENETC4_RSC_DEF_ICTT).  An application enabling both LRO and
> intr_conf.rxq gets per-frame flushes and no coalescing, with no diagnostic.
>
> Patch 14 - ENETC_TBMR_WRR_MASK and ENETC_TBMR_PRIO_MASK use
> GENMASK, which is defined in ntmp.h, not in base/enetc_hw.h where the macros
> live.  It works only because enetc.h pulls in both and the expansion is deferred to
> the use site; enetc_rxtx.c includes base/enetc_hw.h directly and would break if it
> ever used them.
>
> Patch 14 - devargs are now parsed in both enetc4_dev_init() (priorities, nc) and
> enetc4_dev_configure() (priorities, wrr, nc).  The duplicate parse is harmless since
> parse_txq_prior() frees the previous array, but hw->nc_mode is reset and re-
> parsed in configure after the burst functions were already chosen in init, so an nc
> change there cannot take effect.

FALSE POSITIVE, no change. The claim that an nc change in dev_configure() "cannot take effect" does not hold:

nc_mode is derived from the device's devargs string, which is immutable after probe — re-parsing in configure always produces the exact value dev_init() computed. There is no possible "nc change" between the two calls.
The burst functions set in dev_init() (lines 1501-1503) are only a tentative default. The authoritative selection happens later in enetc4_tx_queue_setup() (lines 497-498) and enetc4_rx_queue_setup() (lines 728-730), which read hw->nc_mode and run after dev_configure(). So the configure-time value is fully honored at queue setup. The duplicate parse is redundant but harmless (as the comment itself concedes), and parse_txq_prior/wrr free the previous array each time, so no leak.

>
> Patch 01 - enetc_rx_crc_trim() decrements first_seg->pkt_len unconditionally; if
> a single-segment cluster ever arrived with data_len <= crc_len and prev_seg ==
> NULL, pkt_len would wrap.  Not reachable for valid Ethernet frames, but a
> data_len > crc_len guard on the pkt_len adjustment would make it total.

Its False positive, - `crc_len` is always `RTE_ETHER_CRC_LEN = 4`
ENETC hardware enforces the Ethernet minimum frame size (64 bytes including FCS)
Any frame delivered to the driver has `data_len >= 64`, so `last_seg->data_len > 4` is always true


I have sent V10 series with the fixes.
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.