From nobody Mon Aug 31 17:18:36 2026 X-Original-To: dev-commits-src-all@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4hYbLP1GDkz6r5yq for ; Mon, 31 Aug 2026 17:18:37 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "YR2" (not verified)) by mx1.freebsd.org (Postfix) with ESMTPS id 4hYbLN5R6xz3Hx5 for ; Mon, 31 Aug 2026 17:18:36 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1788196716; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=yNx1UGOcH5Jb+C9VrDa8yHYQ7kWSVv3C8wtaxy5qjWM=; b=TvwbTRdSGaOeEzmP60DWuStXh2m/Ob/nN0iLS+z4nS9c5F8/RalnHWUuhAVm5Lvw2JLlDl ymfaw0p5nUkTo9boypiabPRaSYpC+S8hFimXc7oY6eWUUA+vZcWsa/7uIpamheVf+TtQkA zs6Nji4YOLO/B/gzzgvGyTfGl81RqX3c2cropvZINgbLeLv34UWSdEGGlrK5NKwsIQOxwb sEfCKR1wvIzvQ7jDkMCLSv/uGKNbzx1SJXYMGsSTSb7FmZKHkXcs5tG0rGieFpTHWjC1Nm xr/eQdR7/tRKX3gGgvCbs4xrm8+9rsiOZMrJpKDZ15MuC7uGr5TRnlpylu6Uig== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1788196716; a=rsa-sha256; cv=none; b=KsD7qHEcVZ92JmI/XDDLxxumMos+qy8P0pi8PKzUz2xeFZkTHv/MS+ODTZ8c+h57X3OtVX I8SuQIP7F72TXurSZ8V0TJkQoAPDTBMnVSA1J2TlAwK8w7gjtc5NvaZKp9z4jDtsSge5nc X2Vke64Epgqq16fsfHmC23cdVofMgfLf6K8pXqyDpfce81l0dnLIu9YEFgsjwSpNjSCPd9 sFCbsTnFWXtQ5vKVu9pO/YB0QPMkRKV22akhSuTWBaUeeWwmflL8wxx3BrydNkRey3UaAK VWYsLGP/OxFxQZ2xue2l3B/yiTTosxTNC8BOrPdKvmUiR8anHk8Cz+Z7dweACw== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1788196716; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=yNx1UGOcH5Jb+C9VrDa8yHYQ7kWSVv3C8wtaxy5qjWM=; b=HXoDu2vusarOHRHv64ZqNoAwLaQq7nigsT6v6+tA23xmgQxY9/sWOsXdgqaPzAW1FlFWR7 1eW0P/Vy29MFFqrBPPnRQ93AgHeD+VY+VPd1xK1yvxINNlz6aW2LfJSdmMplpCnwAhbQ27 NZKeMO7t+c8QmU7O9J3UNU1Lqcx8M3wz89RfRvmfscvRasuUOuK6YsJG6ZRTTkLqpAbh1N DrSQmL3tHtRmheIIjpztaTG0hxBIi3I7tylZydRh/4SgJo2AfOKeYSOI7TpGZCUBs1+X1t +BAnrmpjAuNlANySI9Tny3FupTWOdm3aEYh8jd/m7cHvQH2hSH5cq9IhVU0Fvg== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) by mxrelay.nyi.freebsd.org (Postfix) with ESMTP id 4hYbLN32r0z53S for ; Mon, 31 Aug 2026 17:18:36 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from git (uid 1279) (envelope-from git@FreeBSD.org) id 36ffe by gitrepo.freebsd.org (DragonFly Mail Agent v0.13+ on gitrepo.freebsd.org); Mon, 31 Aug 2026 17:18:36 +0000 To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org Cc: Nick Price From: Ed Maste Subject: git: 1a8240f5524b - stable/15 - aq(4): expand and correct offloads, fix VLAN/multicast filtering List-Id: Commit messages for all branches of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-all List-Help: List-Post: List-Subscribe: List-Unsubscribe: X-BeenThere: dev-commits-src-all@freebsd.org Sender: owner-dev-commits-src-all@FreeBSD.org List-Id: List-Post: List-Help: List-Subscribe: List-Unsubscribe: List-Owner: Precedence: list MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: emaste X-Git-Repository: src X-Git-Refname: refs/heads/stable/15 X-Git-Reftype: branch X-Git-Commit: 1a8240f5524b9fbc035e5aa11e4a9419e5c56380 Auto-Submitted: auto-generated Date: Mon, 31 Aug 2026 17:18:36 +0000 Message-Id: <6a95b76c.36ffe.4bab9e9e@gitrepo.freebsd.org> The branch stable/15 has been updated by emaste: URL: https://cgit.FreeBSD.org/src/commit/?id=1a8240f5524b9fbc035e5aa11e4a9419e5c56380 commit 1a8240f5524b9fbc035e5aa11e4a9419e5c56380 Author: Nick Price AuthorDate: 2026-07-19 16:40:36 +0000 Commit: Ed Maste CommitDate: 2026-08-31 17:17:12 +0000 aq(4): expand and correct offloads, fix VLAN/multicast filtering Advertise the offloads the hardware already performs, correct the TX descriptor's L3 family selection, and correct the VLAN and multicast receive-filter paths. Offloads: advertise IFCAP_HWCSUM_IPV6 (adding CSUM_IP6_TCP/UDP/TSO to isc_tx_csum_flags) and IFCAP_VLAN_HWTSO, and enable the RX outer (S-VLAN) tag parse mode in aq_hw_offload_set(). TX descriptor L3 family: aq_setup_offloads() derived tx_desc_cmd_ipv4 from CSUM_IP|CSUM_TSO, but CSUM_TSO is (CSUM_IP_TSO|CSUM_IP6_TSO) and tcp_output() sets both bits without regard to address family, so an IPv6 TSO frame matched on CSUM_IP_TSO and went out with the IPv4 header-checksum command set on a frame that carries no IPv4 header. The checksum flags cannot distinguish the family; key the bit off IPI_TX_IPV4 instead, which iflib derives from the parsed ethertype, as the IPI_TX_INTR test below it already does. Plain IPv6 checksum offload was unaffected, as CSUM_IP6_TCP alone never matched the mask. RX VLAN tag stripping: ring init hardwired hardware tag stripping off while the RX path still set M_VLANTAG and the writeback tag for every tagged frame, so a tagged frame arrived with the tag in line while the mbuf claimed it stripped and ether_demux() parsed four bytes short of the payload. Program per-ring stripping from IFCAP_VLAN_HWTAGGING and set M_VLANTAG only under the same capability, so the two states stay coherent. VLAN filter and promiscuous edge cases: filter only when 1..16 VLANs are registered -- with none (or more than the 16 the table holds) fall back to VLAN-promiscuous and pass all tags, rather than dropping every tagged frame against an empty filter table; and keep VLAN-promiscuous set whenever the interface is IFF_PROMISC, so adding or removing a VLAN under promisc does not clear it and start dropping tagged frames. Multicast reconcile: ifdi_multi_set is declarative, but aq_if_multi_set() only added -- shrinking the list left accept-all-multicast latched or stale exact slots enabled, defeating hardware multicast filtering until a reinit. Clear the exact slots before reprogramming the current list, and always drive accept-all-multicast from the current state so a shrink clears it. Reviewed by: adrian Differential Revision: https://reviews.freebsd.org/D58145 (cherry picked from commit dcede1ec9de3b24fc9fbeeebc99ca34d226995f9) --- sys/dev/aq/aq_hw.c | 3 +++ sys/dev/aq/aq_hw_llh.c | 8 ++++++++ sys/dev/aq/aq_hw_llh.h | 4 ++++ sys/dev/aq/aq_hw_llh_internal.h | 13 +++++++++++++ sys/dev/aq/aq_main.c | 43 ++++++++++++++++++++++++++--------------- sys/dev/aq/aq_ring.c | 10 +++++++--- 6 files changed, 62 insertions(+), 19 deletions(-) diff --git a/sys/dev/aq/aq_hw.c b/sys/dev/aq/aq_hw.c index da07c876b959..1ad9d2e15ed7 100644 --- a/sys/dev/aq/aq_hw.c +++ b/sys/dev/aq/aq_hw.c @@ -459,6 +459,9 @@ aq_hw_offload_set(struct aq_hw *hw) /* LSO offloads*/ tdm_large_send_offload_en_set(hw, 0xFFFFFFFFU); + /* Outer (S-VLAN) tag parse mode */ + rpo_outer_vlan_tag_mode_set(hw, 1U); + { uint32_t i = 0; uint32_t val = (8U < HW_ATL_B0_LRO_RXD_MAX) ? 0x3U : diff --git a/sys/dev/aq/aq_hw_llh.c b/sys/dev/aq/aq_hw_llh.c index eb053a4bdce6..dba02c467e55 100644 --- a/sys/dev/aq/aq_hw_llh.c +++ b/sys/dev/aq/aq_hw_llh.c @@ -1441,6 +1441,14 @@ rpo_tcp_udp_crc_offload_en_set(struct aq_hw *aq_hw, rpol4chk_en_shift, tcp_udp_crc_offload_en); } +void +rpo_outer_vlan_tag_mode_set(struct aq_hw *aq_hw, uint32_t outer_vlan_tag_mode) +{ + AQ_WRITE_REG_BIT(aq_hw, rpo_outer_vl_ins_mode_adr, + rpo_outer_vl_ins_mode_msk, rpo_outer_vl_ins_mode_shift, + outer_vlan_tag_mode); +} + void rpo_lro_en_set(struct aq_hw *aq_hw, uint32_t lro_en) { diff --git a/sys/dev/aq/aq_hw_llh.h b/sys/dev/aq/aq_hw_llh.h index 68cc666be1a3..47011295aa4c 100644 --- a/sys/dev/aq/aq_hw_llh.h +++ b/sys/dev/aq/aq_hw_llh.h @@ -808,6 +808,10 @@ void rpo_rx_desc_vlan_stripping_set(struct aq_hw *aq_hw, void rpo_tcp_udp_crc_offload_en_set(struct aq_hw *aq_hw, uint32_t tcp_udp_crc_offload_en); +/* set RX outer (S-VLAN) tag parse mode */ +void rpo_outer_vlan_tag_mode_set(struct aq_hw *aq_hw, + uint32_t outer_vlan_tag_mode); + /* Set LRO Patch Optimization Enable. */ void rpo_lro_patch_optimization_en_set(struct aq_hw *aq_hw, uint32_t lro_patch_optimization_en); diff --git a/sys/dev/aq/aq_hw_llh_internal.h b/sys/dev/aq/aq_hw_llh_internal.h index bad3c1640cf8..fa1c9a83985b 100644 --- a/sys/dev/aq/aq_hw_llh_internal.h +++ b/sys/dev/aq/aq_hw_llh_internal.h @@ -2145,6 +2145,19 @@ /* default value of bitfield ipv4_chk_en */ #define rpo_ipv4chk_en_default 0x0 +/* register address for bitfield outer_vl_ins_mode */ +#define rpo_outer_vl_ins_mode_adr 0x00005580 +/* bitmask for bitfield outer_vl_ins_mode */ +#define rpo_outer_vl_ins_mode_msk 0x00000004 +/* inverted bitmask for bitfield outer_vl_ins_mode */ +#define rpo_outer_vl_ins_mode_mskn 0xfffffffb +/* lower bit position of bitfield outer_vl_ins_mode */ +#define rpo_outer_vl_ins_mode_shift 2 +/* width of bitfield outer_vl_ins_mode */ +#define rpo_outer_vl_ins_mode_width 1 +/* default value of bitfield outer_vl_ins_mode */ +#define rpo_outer_vl_ins_mode_default 0x0 + /* rx desc{d}_vl_strip bitfield definitions * preprocessor definitions for the bitfield "desc{d}_vl_strip". * parameter: descriptor {d} | stride size 0x20 | range [0, 31] diff --git a/sys/dev/aq/aq_main.c b/sys/dev/aq/aq_main.c index d4f687fee8f1..5d2d9061c548 100644 --- a/sys/dev/aq/aq_main.c +++ b/sys/dev/aq/aq_main.c @@ -371,10 +371,12 @@ aq_if_attach_pre(if_ctx_t ctx) softc->admin_ticks = 0; iflib_set_mac(ctx, hw->mac_addr); - scctx->isc_tx_csum_flags = CSUM_IP | CSUM_TCP | CSUM_UDP | CSUM_TSO; + scctx->isc_tx_csum_flags = CSUM_IP | CSUM_TCP | CSUM_UDP | CSUM_TSO | + CSUM_IP6_TCP | CSUM_IP6_UDP | CSUM_IP6_TSO; scctx->isc_capabilities = IFCAP_RXCSUM | IFCAP_TXCSUM | IFCAP_HWCSUM | - IFCAP_TSO | IFCAP_LRO | IFCAP_JUMBO_MTU | IFCAP_VLAN_HWFILTER | - IFCAP_VLAN_MTU | IFCAP_VLAN_HWTAGGING | IFCAP_VLAN_HWCSUM; + IFCAP_HWCSUM_IPV6 | IFCAP_TSO | IFCAP_LRO | IFCAP_JUMBO_MTU | + IFCAP_VLAN_HWFILTER | IFCAP_VLAN_MTU | IFCAP_VLAN_HWTAGGING | + IFCAP_VLAN_HWCSUM | IFCAP_VLAN_HWTSO; scctx->isc_capenable = scctx->isc_capabilities; scctx->isc_tx_nsegments = 31; scctx->isc_tx_tso_segments_max = 31; @@ -739,6 +741,11 @@ aq_if_init(if_ctx_t ctx) aq_hw_udp_rss_enable(hw, aq_enable_rss_udp); aq_hw_set_link_speed(hw, hw->link_rate); + /* iflib does not replay filter state after init; aq_hw_init() clears it. */ + aq_if_multi_set(ctx); + if (aq_if_promisc_set(ctx, if_getflags(iflib_get_ifp(ctx))) != 0) + device_printf(softc->dev, "could not restore promiscuous mode\n"); + AQ_DBG_EXIT(0); } @@ -822,14 +829,18 @@ aq_if_multi_set(if_ctx_t ctx) if_t ifp = iflib_get_ifp(ctx); struct aq_hw *hw = &softc->hw; AQ_DBG_ENTER(); - softc->mcnt = if_llmaddr_count(iflib_get_ifp(ctx)); - if (softc->mcnt >= AQ_HW_MAC_MAX) { - aq_hw_set_promisc(hw, !!(if_getflags(ifp) & IFF_PROMISC), - aq_is_vlan_promisc_required(softc), - !!(if_getflags(ifp) & IFF_ALLMULTI) || aq_is_mc_promisc_required(softc)); - } else { - if_foreach_llmaddr(iflib_get_ifp(ctx), &aq_mc_filter_apply, softc); + softc->mcnt = if_llmaddr_count(ifp); + + /* Reconcile HW to the current list: clear stale slots, reprogram. */ + if (softc->mcnt < AQ_HW_MAC_MAX) { + for (int i = 1; i < AQ_HW_MAC_MAX; i++) + rpfl2_uc_flr_en_set(hw, 0U, i); + if_foreach_llmaddr(ifp, &aq_mc_filter_apply, softc); } + + aq_hw_set_promisc(hw, !!(if_getflags(ifp) & IFF_PROMISC), + aq_is_vlan_promisc_required(softc), + !!(if_getflags(ifp) & IFF_ALLMULTI) || aq_is_mc_promisc_required(softc)); AQ_DBG_EXIT(0); } @@ -1056,11 +1067,9 @@ aq_is_vlan_promisc_required(struct aq_dev *softc) bit_count(softc->vlan_tags, 0, 4096, &vlan_tag_count); - if (vlan_tag_count <= AQ_HW_VLAN_MAX_FILTERS) - return (false); - else - return (true); - + /* Filter only with 1..16 VLANs; 0 or >16 pass all tags. */ + return (vlan_tag_count == 0 || + vlan_tag_count > AQ_HW_VLAN_MAX_FILTERS); } static void @@ -1087,7 +1096,9 @@ aq_update_vlan_filters(struct aq_dev *softc) } hw_atl_b0_hw_vlan_set(hw, aq_vlans); - hw_atl_b0_hw_vlan_promisc_set(hw, aq_is_vlan_promisc_required(softc)); + hw_atl_b0_hw_vlan_promisc_set(hw, + aq_is_vlan_promisc_required(softc) || + (if_getflags(iflib_get_ifp(softc->ctx)) & IFF_PROMISC) != 0); } /* VLAN support */ diff --git a/sys/dev/aq/aq_ring.c b/sys/dev/aq/aq_ring.c index 311a5c9abf28..8307fb0b3474 100644 --- a/sys/dev/aq/aq_ring.c +++ b/sys/dev/aq/aq_ring.c @@ -110,7 +110,9 @@ aq_ring_rx_init(struct aq_hw *hw, struct aq_ring *ring) rdm_rx_desc_head_buff_size_set(hw, 0U, ring->index); rdm_rx_desc_head_splitting_set(hw, 0U, ring->index); - rpo_rx_desc_vlan_stripping_set(hw, 0U, ring->index); + rpo_rx_desc_vlan_stripping_set(hw, + (if_getcapenable(iflib_get_ifp(ring->dev->ctx)) & + IFCAP_VLAN_HWTAGGING) != 0 ? 1U : 0U, ring->index); /* Rx ring set mode */ @@ -363,7 +365,8 @@ aq_isc_rxd_pkt_get(void *arg, if_rxd_info_t ri) ri->iri_frags[i].irf_idx = cidx; ri->iri_frags[i].irf_len = len; - if ((rx_desc->wb.pkt_type & 0x60) != 0) { + if ((if_getcapenable(ifp) & IFCAP_VLAN_HWTAGGING) != 0 && + (rx_desc->wb.pkt_type & 0x60) != 0) { ri->iri_flags |= M_VLANTAG; ri->iri_vtag = le32toh(rx_desc->wb.vlan); } @@ -405,7 +408,8 @@ aq_setup_offloads(struct aq_dev *aq_dev, if_pkt_info_t pi, volatile struct aq_tx { AQ_DBG_ENTER(); txd->cmd |= tx_desc_cmd_fcs; - txd->cmd |= (pi->ipi_csum_flags & (CSUM_IP|CSUM_TSO)) ? + txd->cmd |= ((pi->ipi_flags & IPI_TX_IPV4) && + (pi->ipi_csum_flags & (CSUM_IP | CSUM_IP_TSO))) ? tx_desc_cmd_ipv4 : 0; txd->cmd |= (pi->ipi_csum_flags & (CSUM_IP_TCP | CSUM_IP6_TCP | CSUM_IP_UDP | CSUM_IP6_UDP)) ? tx_desc_cmd_l4cs : 0;