Hi Stephen,
Thanks for the review. Replies below; the [PATCH nn/28] numbers refer to the v5 series. At 2026-11-09 21:14:11, "Stephen Hemminger" <[email protected]> wrote: >On Fri, 30 Oct 2026 22:47:04 +0800 >Jiacheng Ye <[email protected]> wrote: > >> This series fixes offload capability advertisement, cmdq/compact CQE >> configuration, and several defects found during review, and adds NIC >> type identification, FEC, CIR drop statistics, VF LAG/link state, COS >> mask/map, mbox recording, RSS hash configuration, compact CQE Rx/Tx >> paths, TSO segment expansion, Tx burst mode reporting, queue statistics, >> pseudo-header checksum, per-tile cmdq ops, SP560 NIC support, and device >> kvargs tunables. >> >> Thanks to Stephen Hemminger for the review. The review comments are addressed >> in this version, and the changes are listed below. >> >> v5: > >Lots of open items from AI review > >Subject: Re: [PATCH v5 00/28] net/hinic3: fixes and new features > >Applies to main (release notes conflict aside) and every commit builds >with -Dwerror=true. The v4 items are addressed: tx_pkt_prepare is >installed in 09, and the SP560 CEQ EN bit is explained. > >There is still no cover letter or changelog. Please add one; at 28 >patches it is hard to see what changed between versions. [Jiacheng] Thanks for the note. The 00/28 cover letter was sent with the series (Message-ID [email protected]) and includes the v5 changelog; it is about 10.8 KB because it also carries the v2-v5 history, so it may have been truncated on the way. I have repeated the v5 changelog below for convenience. Changes in v5: - Register hinic3_prep_pkts() in the pseudo-header checksum patch instead of the compact CQE Rx patch. - Mention only SP620 in that commit message. - Document the RQ CEQ EN bit and the INTR field for SW compact CQE. - Drop the per-packet ERR log for a zero tso_segsz. - Keep log and error messages on a single line. - Check the non-TSO packet length before the early SGE-count return. - Scale the coalescing parameters by their unit in the log. - Clear the stale Rx hardware CI write-back memory on queue reset. > >Errors >====== > >[PATCH 18/28] net/hinic3: update RSS hash type configuration > >nic_dev->rss_type is set, but never cleared: > > cqe_info->rss_type = (rxq->nic_dev->rss_type.val != 0) ? 1 : 0; > >hinic3_remove_rxtx_configure() sets rss_state to DISABLE and leaves >rss_type alone, and so does the init_rss_fail path. After stop and >reconfigure without RSS (mq_mode NONE, or a single queue), the compact >CQE path still sets RTE_MBUF_F_RX_RSS_HASH on every mbuf, with a >garbage hash. Clear rss_type.val wherever rss_state goes to DISABLE. >Better, cache an rss_en flag in struct hinic3_rxq at queue start, so >the fast path does not dereference nic_dev for every packet. [Jiacheng] Accepted. The fast path now uses rxq->rss_en, cached when the queue starts, cleared on queue stop and reset. rss_type.val is cleared on every path that disables RSS (remove_rxtx_configure and the init RSS failure path), so no stale hash leaks into the compact CQE path. > > >[PATCH 19/28] net/hinic3: refactor flow rule parsing > >The new IP-in-IP pattern accepts an outer IPv6 with an inner L3: > > case RTE_FLOW_ITEM_TYPE_IPV4: > case RTE_FLOW_ITEM_TYPE_IPV6: > /* Ip-in-ip: a second L3 with an optional L4 (or ANY). */ > hinic3_flow_take(item, next); > >The parser then sets outer_ip_type = IPV6 and ip_type = IPV4/IPV6. >hinic3_fdir_tcam_ipv6_vxlan_init() programs addresses only when >ip_type == HINIC3_FDIR_IP_TYPE_ANY, so the rule is accepted with no >address match and steers all IPv6 IP-in-IP traffic. classify_inner() >already rejects outer IPv6 plus inner L3 for this reason. Do the same >here: > > case RTE_FLOW_ITEM_TYPE_IPV4: > case RTE_FLOW_ITEM_TYPE_IPV6: > if (ip_type == RTE_FLOW_ITEM_TYPE_IPV6) > return HINIC3_FLOW_KIND_INVALID; > hinic3_flow_take(item, next); [Jiacheng] Accepted. hinic3_flow_classify_ip() returns HINIC3_FLOW_KIND_INVALID when a second L3 follows an outer IPv6, so an outer IPv6 plus inner L3 rule is rejected by the parser. > > >[PATCH 24/28] net/hinic3: expand TSO from 127 to 255 segments > >A Tx WQEBB is 16 bytes, one per SGE, so a 255-SGE TSO packet needs >wqebb_cnt = sge_cnt + 1 = 256. hinic3_get_sq_free_wqebbs() never >returns more than q_depth - 1, and setup accepts depths 128 and 256. >On those rings the packet never fits: the burst hits > > if (wqe_info.wqebb_cnt > free_wqebb_cnt) { > txq->txq_stats.tx_busy += (nb_pkts - nb_tx); > goto end; > >every time, and the queue stalls at that packet forever. Before this >patch only depth 128 was affected. In hinic3_get_tx_offload(), reject >(free and count) a packet whose WQEBB count exceeds q_depth - 1, or >raise the Tx minimum depth to 512 in both setup and tx_desc_lim. Also >set tx_desc_lim.nb_seg_max and nb_mtu_seg_max. [Jiacheng] Accepted. hinic3_get_tx_offload() rejects the packet when wqe_info->sge_cnt >= q_depth - 1, i.e. when the WQEBB count cannot fit in a ring that never reports more than q_depth - 1 free WQEBBs; the packet is freed and counted in offload_errors. tx_desc_lim.nb_seg_max and nb_mtu_seg_max are set to HINIC3_TSO_PKT_MAX_SGE. An extended WQE needs one WQEBB per SGE plus one for the task section, so the usable SGE count is q_depth - 2: 126 segments at depth 128, 254 at depth 256, and the hardware maximum of 255 is reachable only from depth 512 up. nb_seg_max stays 255 (the hardware limit) and the Tx minimum depth stays 128; a packet that does not fit is rejected and counted rather than stalling the queue. > > >Warnings >======== > >[PATCH 03/28] net/hinic3: fix TCAM index leak on ethertype flow set > >Wrong Fixes tag. efa3b9b36fc7 has no TCAM allocation in >hinic3_set_fdir_ethertype_filter(); that came with b2d4933b80ec, >which first shipped in 26.03. Not in 25.11, so drop Cc: stable. > > Fixes: b2d4933b80ec ("net/hinic3: support htn FDIR for new SPx series NIC") [Jiacheng] Accepted. > > >[PATCH 05/28] net/hinic3: fix vport enable null dereference > >Same problem. The nic_dev dereference in hinic3_set_vport_enable() was >added by 9204b6b7bb1a (26.03), not de490215f74a. Drop Cc: stable. > > Fixes: 9204b6b7bb1a ("net/hinic3: split new/old command queue operations") > >The new check cannot fire: hinic3_func_init() sets hwdev->dev_handle >right after allocating hwdev, before any vport command. > > nic_dev = hwdev->dev_handle; > if (!nic_dev) > return -EINVAL; > >The real fix is moving the dereference below the hwdev check. Drop >the nic_dev check and fix the commit message. [Jiacheng] Accepted. > > >[PATCH 09/28] net/hinic3: fix pseudo-header checksum calculation > >hinic3_prep_pkts() writes headers through rte_pktmbuf_mtod_offset() >without checking that they are in the first segment. A multi-segment >mbuf with split headers gets an out-of-bounds write. Do what >rte_net_intel_cksum_flags_prepare() does: > > if (unlikely(rte_pktmbuf_data_len(mbuf) < > inner_l3_offset + mbuf->l3_len + mbuf->l4_len)) { > rte_errno = ENOTSUP; > return i; > } > >The shared mbuf check is too broad: > > if (unlikely(rte_mbuf_refcnt_read(mbuf) > 1 || RTE_MBUF_CLONED(mbuf))) { > >HINIC3_TX_OFFLOAD_MASK includes VLAN and IP checksum, which write >nothing. A cloned mbuf asking only for VLAN insert now fails >tx_prepare on SP620, which breaks flooding and multicast. Do the check >only when ol_flags has HINIC3_PKT_TX_L4_MASK, HINIC3_PKT_TX_TCP_SEG or >HINIC3_PKT_TX_OUTER_UDP_CKSUM. > >The patch also starts advertising RTE_ETH_TX_OFFLOAD_OUTER_UDP_CKSUM. >That is a new capability in a stable-tagged fix, and the commit >message does not mention it. Move it to its own patch and add "Outer >L3 checksum" and "Outer L4 checksum" to hinic3.ini. [Jiacheng] Accepted for the contiguity check (it now mirrors rte_net_intel_cksum_flags_prepare()) and for narrowing the shared-mbuf check to the L4/TSO/outer-UDP flags. The OUTER_UDP_CKSUM advertisement was moved out of this fix into its own offload patch. For the ini rows: the feature matrix has no separate outer checksum rows, and the drivers that advertise OUTER_IPV4_CKSUM/OUTER_UDP_CKSUM (hns3, bnxt, enic) only mark "L3/L4 checksum offload". Should I add "Outer L3 checksum" / "Outer L4 checksum" to default.ini and list them in hinic3.ini? > > >[PATCH 10/28] net/hinic3: add SP230 Rx queue interrupt handling > >The comment and commit message say the SP230 vectors are masked: > > if (HINIC3_IS_SP230_NIC(nic_dev)) > return hinic3_sp230_mask_rxq_msix(dev); > >hinic3_sp230_mask_rxq_msix() only calls hinic3_init_rxq_msix_attr(), >which sets pending limit, coalesce timer and resend timer. Nothing >calls hinic3_set_msix_state(..., HINIC3_MSIX_DISABLE) or sets the >auto-mask state. Either mask the vectors, or rename the function and >fix the text to say coalescing only. [Jiacheng] Accepted. > > >[PATCH 13/28] net/hinic3: add FEC mode get/set and capability support > > if (num < HINIC3_FEC_CAPA_NUM_PER_SPEED) { > ... > return -EINVAL; > >rte_eth_fec_get_capability() requires a too-small array to return the >needed count, not an error. Return HINIC3_FEC_CAPA_NUM_PER_SPEED. > >When firmware reports HINIC3_PORT_FEC_NOT_SET, fec_get returns 0, >which is not a valid mode mask. Since set rejects AUTO, once a mode is >forced the user can't go back to the default. Map NOT_SET to and from >RTE_ETH_FEC_MODE_CAPA_MASK(AUTO), and accept AUTO in >hinic3_fec_param_valid(). > >The get/set helpers do not check out_size, unlike the rest of the mgmt >helpers in that file: > > if (fec_msg.head.status != 0 || err) { > >Use "if (err || !out_size || fec_msg.head.status)". [Jiacheng] Accepted for the needed-count return and the out_size checks in all FEC mgmt helpers. For AUTO I kept it read-only. A forced FEC mode can only be configured after auto-negotiation is disabled with the hinicadm5 tool; while auto-negotiation is enabled the firmware rejects the SET request (mgmt status 0x10), and the PMD cannot toggle the auto-negotiation state. So NOT_SET is mapped to AUTO in fec_get() and in the reported capabilities, AUTO is masked out of the advertised capabilities, and fec_set() rejects it. To configure rs/base/nofec/llrs, disable auto-negotiation with hinicadm5 first; to return to auto, re-enable it there. An application that saves the mode from fec_get() and restores it later will get -EINVAL for AUTO, which is intentional. > > >[PATCH 14/28] net/hinic3: add mbox message recording and debug dump > >eth_dev_priv_dump is also registered for secondary processes, for >example dpdk-proc-info --show-port-private, but the dump does > > pci_dev = hwdev->pci_dev; > >hwdev is in shared memory, but pci_dev points into the primary's heap, >so a secondary reads a bad pointer. Pass RTE_ETH_DEV_TO_PCI(dev) down >from hinic3_eth_dev_priv_dump(). [Jiacheng] Accepted. > > >[PATCH 15/28] net/hinic3: add COS mask and COS map support > >The patch drops the existing COS clamps, and the commit message does >not say so: > > - *cos_id = vf_dcb.state.default_cos % HINIC3_COS_NUM_MAX_HTN; > + *cos_id = vf_dcb.state.default_cos; > >The PF HTN limit of 4 is removed as well. cos_map is only applied on >SP230, so SP620 VFs can now get COS 4-7. Keep the clamp on paths that >don't use cos_map, or explain in the commit message why it is safe. [Jiacheng] The commit message will explain it: the four-COS clamp existed for the HTN tile, where the COS may be split between the NIC and RoCE; cos_map[] folds any COS outside the firmware cos_mask into default_cos, so the clamp is no longer needed on SP230. On SP620 and SP560 all eight COS belong to the NIC, so the clamp is dropped there as well. > > >[PATCH 16/28] net/hinic3: add VF link state and promiscuous support > >dev_set_link_down only disables the vport. The next PF link-up event >goes through hinic3_set_vport_state(), which re-enables the vport >whenever HINIC3_DEV_START is set: > > if (hinic3_get_bit(HINIC3_DEV_START, &nic_dev->dev_status)) > err = hinic3_set_vport_enable(hwdev, true); > >That sets vf_valid_status back to 1 and reports the link up again, so >an administrative link down does not stick. Keep a separate admin-down >flag, set only by set_link_up/down, and check it in >hinic3_set_vport_state() and in the link status calculation. [Jiacheng] Accepted. > > >[PATCH 19/28] net/hinic3: refactor flow rule parsing > >The commit message says IPv4 and VXLAN keys no longer set the >vlan_flag mask. The lines removed were duplicates. >hinic3_fdir_tcam_notunnel_init() and >hinic3_fdir_tcam_vxlan_geneve_init() still do > > tcam_key->key_mask.vlan_flag = 1; > >so those rules still match only untagged packets. Fix the commit >message, or the code if the change was intended. [Jiacheng] The vlan_flag field is only used by bifur, which this driver does not support, so the setters are dropped. > > >[PATCH 20/28] net/hinic3: add SP560 NIC type identification and > handling > >The new HTN ops change the SP230 queue context values. Before this >patch, SP230 used the common values: drop OFF 0, prefetch 1/6/256, no >PFH_TH. Now it gets: > > #define HINIC3_DEFAULT_DROP_THD_OFF 0xFFFF > #define SQ_PREFETCH_MAX 5 > #define SQ_PREFETCH_MIN 4 > #define SQ_PREFETCH_THRESHOLD 48 > ... > #define RQ_PFH_TH 7 > >The commit message only talks about SP560. Either keep the old SP230 >values, or put the change in a separate patch with the reason. [Jiacheng] This patch also switches the HTN tile (SP230) queue context from the generic values inherited from the shared code to the tile-recommended ones: drop threshold off 0xFFFF, SQ prefetch 4/5/48, RQ prefetch 2/4/32 and PFH_TH 7. The generic values were not tuned for the HTN tile. This will be described in the commit message. > > >[PATCH 23/28] net/hinic3: ensure queue depth and state consistency > >The depth cache is cleared only in dev_configure: > > nic_dev->rxq_depth = 0; > nic_dev->txq_depth = 0; > >ethdev allows queue setup again while stopped, without reconfigure. >testpmd "port config all rxd 2048" does this. Queue 0 then fails with >-EINVAL against the stale depth. Instead of the cache, compare against >q_depth of the other non-NULL dev->data->{rx,tx}_queues[]. > >dev_stop marks queues STOPPED in ethdev but leaves txq->status at >START. A deferred-start queue started at runtime keeps transmitting >after stop/start, and rte_eth_dev_tx_queue_stop() then returns early >without calling the driver. Call HINIC3_SET_TXQ_STOPPED() in the same >loop. [Jiacheng] The cache is now reset in dev_configure() and in dev_stop(), and dev_start() validates that every configured queue is present and shares queue 0's depth. A reconfiguration while stopped, including "port config all rxd 2048" without a new dev_configure(), therefore works; a partial reconfiguration is refused at dev_start() instead of running with rings that do not match the root context. HINIC3_SET_TXQ_STOPPED() is called in the dev_stop loop. > > >[PATCH 24/28], [PATCH 25/28] Tx path logging > >These are new per-packet logs in the Tx path, at WARNING and ERR: > > PMD_DRV_LOG(WARNING, "illegal pkt, payload offset (%u) > data len (%u).", > PMD_DRV_LOG(WARNING, "TSO payload over hardware limit."); > PMD_DRV_LOG(ERR, "IPinIP not support TSO"); > PMD_DRV_LOG(ERR, "VXLAN_GPE not support TSO"); > >A bad packet stream floods the log, and the drops are already counted >in offload_errors. Remove them, or use a rate-limited data path log. [Jiacheng] Accepted. > > >[PATCH 25/28] net/hinic3: split Tx burst function for compact CQE > support > >hinic3_mbuf_dma_map_sge() is shared by both bursts and does this for >every segment: > > if (txq->nic_dev->nic_type == NIC_SP620) > wqe_desc->queue_info = 0; > >In the compact burst, a single-WQEBB WQE keeps its task in >hdr->queue_info, and hinic3_set_tx_offload_compact_cqe() has already >written it. On an SP620 that reports NIC_F_TX_WQE_COMPACT_TASK, the >checksum and VLAN offload are wiped. The commit message says the burst >is chosen by feature bit, not NIC model, so this check is inconsistent. >Do the zeroing in hinic3_xmit_pkts() only, for SQ_WQE_COMPACT_TYPE, >once per packet. > >The compact burst declares wqe_info once per burst: > > struct hinic3_wqe_info wqe_info = { 0 }; > >hinic3_set_tx_offload_compact_cqe() sets vlan_valid, tso, mss and >payload_offset but never clears them. A VLAN or TSO packet leaks >those values into later packets in the same burst, for example a >plain checksum packet sent as TSO with a stale MSS. The old combined >burst had the same bug, and the normal path is fixed here, but the new >compact path copies it. Clear wqe_info.offload_info and >wqe_info.queue_info for each packet. [Jiacheng] Accepted. The zeroing moved to hinic3_xmit_pkts() and is done once per packet only for SQ_WQE_COMPACT_TYPE; hinic3_mbuf_dma_map_sge() no longer writes queue_info. The compact burst clears wqe_info.queue_info and wqe_info.offload_info for every packet in hinic3_get_tx_offload(), so VLAN/TSO state cannot leak into the next packet. > > >[PATCH 27/28] net/hinic3: add Tx burst mode get > > (nic_dev->config.rx_cqe_compact_en == HINIC3_RX_CQE_COMPACT_EN) ? > "compact CQE" : "scalar", > >Tx burst selection uses HINIC3_SUPPORT_TX_WQE_COMPACT_TASK(), not the >Rx compact CQE setting, so this can name the wrong function. Use > > dev->tx_pkt_burst == hinic3_xmit_pkts_compact_cqe [Jiacheng] Accepted. > >Info >==== > >[PATCH 09/28] Tunnel type is an enumerated field, not a bitmask: > > if ((ol_flags & HINIC3_PKT_TX_TUNNEL_IPIP) == HINIC3_PKT_TX_TUNNEL_IPIP) { > >This also matches GTP (0x7) and other values. Use >(ol_flags & HINIC3_PKT_TX_TUNNEL_MASK) == HINIC3_PKT_TX_TUNNEL_IPIP. >The VXLAN and GENEVE support tests have the same problem. [Jiacheng] Accepted. > >[PATCH 11/28] The tunnel TSO gating fixed here came from c1537bf6c033 >("net/hinic3: support Compact CQE in init"). Add a second Fixes tag. [Jiacheng] Accepted. > >[PATCH 12/28] rx_discard_phy is counted and named on every NIC type >but only filled in on SP620, so SP230/SP560 show a counter that is >always 0. Use the same HINIC3_IS_SP620_NIC() condition in calc_num, >get_names and get. [Jiacheng] Accepted. > >[PATCH 21/28] rx_cqe_coalesce_num and rx_cqe_timer_loop only take >effect with HW compact CQE. hinic3.rst should say so. [Jiacheng] Accepted. hinic3.rst now says the two RX CQE coalescing parameters only take effect with HW compact CQE and are ignored with SW compact and split CQE. > >[PATCH 22/28] HINIC3_RX_COMPACT_L3_L4_CSUM_ERROR goes to the default >case and keeps value 1, which is HINIC3_RX_CSUM_IP_CSUM_ERR. A bad >L4 checksum is then reported as RTE_MBUF_F_RX_IP_CKSUM_BAD. Also, >the ptype table produces RTE_PTYPE_INNER_L4_FRAG, _ICMP and _ESP, >which are missing from dev_supported_ptypes_get. [Jiacheng] Fixed: HINIC3_RX_COMPACT_L3_L4_CSUM_ERROR maps to HINIC3_RX_CSUM_LAYER_UNKNOWN_ERR instead of the default value. The inner FRAG/ICMP/ESP encodings are reserved firmware values that the current hardware does not produce; those cases are not emitted, so the table and dev_supported_ptypes_get() stay in sync. > >[PATCH 25/28] rte_prefetch0(tx_pkts[0]) runs before the loop, so with >nb_pkts == 0 it reads past the array. [Jiacheng] Accepted. > >Pre-existing, not introduced by this series: >- hinic3_dev_stats_get() does > dev->data->rx_mbuf_alloc_failed += rxq->rxq_stats.rx_nombuf; > on every call, so rx_nombuf grows each time stats are read. >- hinic3_start_rq()/hinic3_stop_rq() call hinic3_set_vport_enable(), > a blocking mgmt message, while holding the queue_list_lock spinlock. [Jiacheng] Both are pre-existing. I will send them as separate patches rather than mixing them into this series, together with the unaligned mbox-header read. Thanks again for the review. Regards, Jiacheng

