From nobody Mon Aug 17 00:27:26 2026 X-Original-To: dev-commits-src-branches@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 4hNYZ66CcTz6X1cw for ; Mon, 17 Aug 2026 00:27:26 +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 4hNYZ638Wyz3gDh for ; Mon, 17 Aug 2026 00:27:26 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1786926446; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=HZ2oRJncdQTzPbGOijJcRcfgg+/hwC/HWZy9uKeIDGQ=; b=nqdtZloJnq08lFShlizfzL6riLKgZ2SZ+HoBWrwDgAUqebqK1INzxURM/e5aydeaz6Jy9b ec+td2XqsLTFHLlPCGxeex2fMQ63xxiPYWliaizSgkIFDpWzPAtjoiTJqTg7gqp70tAyjh w+GBjs31c0qU1FiCLdJfD1CiNCriCK68y+E9wHdZwWxUVSDPLrFor0MWBAM/VoIKiIY4QM SnhHgPv4DnMkrWZVppAuKS317qvbY39mgqgFsk5sYWHCvstEDQTUuwpUHbyawAumv3/TNq pRUo3LRCXyK22lpAmM5Tq4oqVjoAikeiIBr6675A+F/RNG4YWNEDj+hBE2b+IQ== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1786926446; a=rsa-sha256; cv=none; b=u1CySGh8Vi/WXgorsvdD3ZAscU5mRFjlL6dLzP3Qho9WaPDvVKtWJkBGanJzvvXVfKZlD5 NMdwOGLqTXRETNOxfb4QOOHudwBWU7hbQezcNzzGS9tpoHA22DEx4YAsLIlvmhdiBqztXY 1X+bMZ6R3YMWzJVkmP/eB0SqxXSpASTcEFoKcGHBKv8h+/LvA0ZDDdQ3YQwTtstE6SxvW1 UkG1+kt9y8slXjhmfvSX5IU3kpb3MjsxnNr+M/ei1k9cCoqHn47curN7UEwnS8QMG/TYeL F9n+ebg4eHKNlsKAmCu53WxNkaUn1NJiI7RDUWwEI6+VwBkqfAM5w+f7B+FnLA== 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=1786926446; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=HZ2oRJncdQTzPbGOijJcRcfgg+/hwC/HWZy9uKeIDGQ=; b=bF1IpFgFoRtTU1lF5SgNKZF6QuDJ+975ktm9H9BOG/i5UKCLgyDB7VkL1lzNu3e/WcGF5H 7GmSHZm6ryoUsBlesXV930MJLxuHeuJHawx3wfkXBSO/I+5anYT5bgwTuXQtJPkZVAQWj/ U9TqLWo+euPzxTFozpkS5SJWQ6aPiqhU167m8w6Ky81XDB/smVizFMrGwIhAsH5T4lsR98 K2AjGspScRVbrTZV4NSieSnZu80D8m5n2ivGo4ytS3dROCTZyjKiMnuzVHEih3vsr+M9K8 wjbMC6yQhVErJECVMbPanygD2aq/Gal34U+cHHFxfIN12ICNoPkqvTC7R/cZkQ== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) by mxrelay.nyi.freebsd.org (Postfix) with ESMTP id 4hNYZ61FBdzrRW for ; Mon, 17 Aug 2026 00:27:26 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from git (uid 1279) (envelope-from git@FreeBSD.org) id 37662 by gitrepo.freebsd.org (DragonFly Mail Agent v0.13+ on gitrepo.freebsd.org); Mon, 17 Aug 2026 00:27:26 +0000 To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org From: Kevin Bowling Subject: git: 1c8363854095 - stable/14 - igc: Add VLAN hardware filtering List-Id: Commits to the stable branches of the FreeBSD src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-branches List-Help: List-Post: List-Subscribe: List-Unsubscribe: X-BeenThere: dev-commits-src-branches@freebsd.org Sender: owner-dev-commits-src-branches@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: kbowling X-Git-Repository: src X-Git-Refname: refs/heads/stable/14 X-Git-Reftype: branch X-Git-Commit: 1c8363854095fa2c7ebeff6e7b6980244ba829f7 Auto-Submitted: auto-generated Date: Mon, 17 Aug 2026 00:27:26 +0000 Message-Id: <6a82556e.37662.4aff21cb@gitrepo.freebsd.org> The branch stable/14 has been updated by kbowling: URL: https://cgit.FreeBSD.org/src/commit/?id=1c8363854095fa2c7ebeff6e7b6980244ba829f7 commit 1c8363854095fa2c7ebeff6e7b6980244ba829f7 Author: Kevin Bowling AuthorDate: 2026-08-03 10:57:39 +0000 Commit: Kevin Bowling CommitDate: 2026-08-17 00:26:28 +0000 igc: Add VLAN hardware filtering Borrow the e1000 VLAN filter table Ambiguous presence of the feature by Intel was settled by DPDK and emperical testing. Relnotes: yes (cherry picked from commit 8f779f159e2198c85b4fcb8685989879a9330104) --- share/man/man4/igc.4 | 6 +-- sys/dev/igc/if_igc.c | 116 +++++++++++++++++++++++++++++++++++++++++++++++---- sys/dev/igc/if_igc.h | 3 ++ 3 files changed, 113 insertions(+), 12 deletions(-) diff --git a/share/man/man4/igc.4 b/share/man/man4/igc.4 index 3b92472e8355..521a36531208 100644 --- a/share/man/man4/igc.4 +++ b/share/man/man4/igc.4 @@ -3,7 +3,7 @@ .\" Copyright 2021 Rubicon Communications, LLC (Netgate) .\" SPDX-License-Identifier: BSD-3-Clause .\" -.Dd March 9, 2026 +.Dd August 3, 2026 .Dt IGC 4 .Os .Sh NAME @@ -39,8 +39,8 @@ utility configures the adapter to receive and transmit Jumbo Frames. The maximum MTU size for Jumbo Frames is 9216 bytes. .Pp -This driver version supports VLAN hardware insertion / extraction, and -VLAN checksum offload. +This driver version supports VLAN hardware insertion / extraction, +VLAN checksum offload, and VLAN hardware filtering. For information on enabling VLANs, see .Xr ifconfig 8 . The diff --git a/sys/dev/igc/if_igc.c b/sys/dev/igc/if_igc.c index 17784f5f5f43..2c276533026e 100644 --- a/sys/dev/igc/if_igc.c +++ b/sys/dev/igc/if_igc.c @@ -109,6 +109,8 @@ static void igc_if_media_status(if_ctx_t, struct ifmediareq *); static int igc_if_media_change(if_ctx_t); static int igc_if_mtu_set(if_ctx_t, uint32_t); static void igc_if_timer(if_ctx_t, uint16_t); +static void igc_if_vlan_register(if_ctx_t, u16); +static void igc_if_vlan_unregister(if_ctx_t, u16); static void igc_if_watchdog_reset(if_ctx_t); static bool igc_if_needs_restart(if_ctx_t, enum iflib_restart_event); @@ -134,6 +136,10 @@ static void igc_if_debug(if_ctx_t); static void igc_update_stats_counters(struct igc_softc *); static void igc_add_hw_stats(struct igc_softc *); static int igc_if_set_promisc(if_ctx_t, int); +static bool igc_if_vlan_filter_capable(if_ctx_t); +static bool igc_if_vlan_filter_used(if_ctx_t); +static void igc_if_vlan_filter_enable(struct igc_softc *); +static void igc_if_vlan_filter_disable(struct igc_softc *); static void igc_setup_vlan_hw_support(if_ctx_t); static void igc_fw_version(struct igc_softc *); static void igc_sbuf_fw_version(struct igc_fw_version *, struct sbuf *); @@ -221,6 +227,8 @@ static device_method_t igc_if_methods[] = { DEVMETHOD(ifdi_promisc_set, igc_if_set_promisc), DEVMETHOD(ifdi_timer, igc_if_timer), DEVMETHOD(ifdi_watchdog_reset, igc_if_watchdog_reset), + DEVMETHOD(ifdi_vlan_register, igc_if_vlan_register), + DEVMETHOD(ifdi_vlan_unregister, igc_if_vlan_unregister), DEVMETHOD(ifdi_get_counter, igc_if_get_counter), DEVMETHOD(ifdi_rx_queue_intr_enable, igc_if_rx_queue_intr_enable), DEVMETHOD(ifdi_tx_queue_intr_enable, igc_if_tx_queue_intr_enable), @@ -448,8 +456,9 @@ igc_set_num_queues(if_ctx_t ctx) #define IGC_CAPS \ IFCAP_HWCSUM | IFCAP_VLAN_MTU | IFCAP_VLAN_HWTAGGING | \ - IFCAP_VLAN_HWCSUM | IFCAP_WOL | IFCAP_TSO4 | IFCAP_LRO | \ - IFCAP_VLAN_HWTSO | IFCAP_JUMBO_MTU | IFCAP_HWCSUM_IPV6 | IFCAP_TSO6 + IFCAP_VLAN_HWCSUM | IFCAP_VLAN_HWFILTER | IFCAP_WOL | IFCAP_TSO4 | \ + IFCAP_LRO | IFCAP_VLAN_HWTSO | IFCAP_JUMBO_MTU | \ + IFCAP_HWCSUM_IPV6 | IFCAP_TSO6 /********************************************************************* * Device initialization routine @@ -1307,20 +1316,24 @@ igc_if_set_promisc(if_ctx_t ctx, int flags) /* Don't disable if in MAX groups */ if (mcnt < MAX_NUM_MULTICAST_ADDRESSES) - reg_rctl &= (~IGC_RCTL_MPE); - IGC_WRITE_REG(&sc->hw, IGC_RCTL, reg_rctl); + reg_rctl &= ~IGC_RCTL_MPE; if (flags & IFF_PROMISC) { reg_rctl |= (IGC_RCTL_UPE | IGC_RCTL_MPE); /* Turn this on if you want to see bad packets */ if (igc_debug_sbp) reg_rctl |= IGC_RCTL_SBP; - IGC_WRITE_REG(&sc->hw, IGC_RCTL, reg_rctl); } else if (flags & IFF_ALLMULTI) { reg_rctl |= IGC_RCTL_MPE; reg_rctl &= ~IGC_RCTL_UPE; - IGC_WRITE_REG(&sc->hw, IGC_RCTL, reg_rctl); } + + if ((flags & IFF_PROMISC) || !igc_if_vlan_filter_used(ctx)) + reg_rctl &= ~IGC_RCTL_VFE; + else + reg_rctl |= IGC_RCTL_VFE; + IGC_WRITE_REG(&sc->hw, IGC_RCTL, reg_rctl); + return (0); } @@ -2416,16 +2429,87 @@ igc_initialize_receive_unit(if_ctx_t ctx) return; } +static void +igc_if_vlan_register(if_ctx_t ctx, u16 vtag) +{ + struct igc_softc *sc = iflib_get_softc(ctx); + u32 index, mask; + + index = (vtag >> 5) & 0x7f; + mask = 1U << (vtag & 0x1f); + if ((sc->shadow_vfta[index] & mask) != 0) + return; + sc->shadow_vfta[index] |= mask; + igc_write_vfta(&sc->hw, index, sc->shadow_vfta[index]); +} + +static void +igc_if_vlan_unregister(if_ctx_t ctx, u16 vtag) +{ + struct igc_softc *sc = iflib_get_softc(ctx); + u32 index, mask; + + index = (vtag >> 5) & 0x7f; + mask = 1U << (vtag & 0x1f); + if ((sc->shadow_vfta[index] & mask) == 0) + return; + sc->shadow_vfta[index] &= ~mask; + igc_write_vfta(&sc->hw, index, sc->shadow_vfta[index]); +} + +static bool +igc_if_vlan_filter_capable(if_ctx_t ctx) +{ + if_t ifp = iflib_get_ifp(ctx); + + return ((if_getcapenable(ifp) & IFCAP_VLAN_HWFILTER) != 0 && + !igc_disable_crc_stripping); +} + +static bool +igc_if_vlan_filter_used(if_ctx_t ctx) +{ + struct igc_softc *sc = iflib_get_softc(ctx); + + if (!igc_if_vlan_filter_capable(ctx)) + return (false); + + for (int i = 0; i < IGC_VFTA_SIZE; i++) + if (sc->shadow_vfta[i] != 0) + return (true); + + return (false); +} + +static void +igc_if_vlan_filter_enable(struct igc_softc *sc) +{ + u32 reg; + + reg = IGC_READ_REG(&sc->hw, IGC_RCTL); + reg &= ~IGC_RCTL_CFIEN; + reg |= IGC_RCTL_VFE; + IGC_WRITE_REG(&sc->hw, IGC_RCTL, reg); +} + +static void +igc_if_vlan_filter_disable(struct igc_softc *sc) +{ + u32 reg; + + reg = IGC_READ_REG(&sc->hw, IGC_RCTL); + reg &= ~(IGC_RCTL_VFE | IGC_RCTL_CFIEN); + IGC_WRITE_REG(&sc->hw, IGC_RCTL, reg); +} + static void igc_setup_vlan_hw_support(if_ctx_t ctx) { struct igc_softc *sc = iflib_get_softc(ctx); struct igc_hw *hw = &sc->hw; - struct ifnet *ifp = iflib_get_ifp(ctx); + if_t ifp = iflib_get_ifp(ctx); u32 reg; - /* igc hardware doesn't seem to implement VFTA for HWFILTER */ - if (if_getcapenable(ifp) & IFCAP_VLAN_HWTAGGING && !igc_disable_crc_stripping) { reg = IGC_READ_REG(hw, IGC_CTRL); @@ -2436,6 +2520,20 @@ igc_setup_vlan_hw_support(if_ctx_t ctx) reg &= ~IGC_CTRL_VME; IGC_WRITE_REG(hw, IGC_CTRL, reg); } + + if (!igc_if_vlan_filter_capable(ctx)) { + igc_if_vlan_filter_disable(sc); + return; + } + + /* Always admit priority-tagged frames. */ + sc->shadow_vfta[0] |= 1U; + + /* A reset may clear the VFTA, so restore the complete desired table. */ + for (int i = 0; i < IGC_VFTA_SIZE; i++) + igc_write_vfta(hw, i, sc->shadow_vfta[i]); + + igc_if_vlan_filter_enable(sc); } static void diff --git a/sys/dev/igc/if_igc.h b/sys/dev/igc/if_igc.h index a090eeb12247..d9834212fee8 100644 --- a/sys/dev/igc/if_igc.h +++ b/sys/dev/igc/if_igc.h @@ -387,6 +387,9 @@ struct igc_softc { /* Multicast array memory */ u8 *mta; + /* Retained across resets to restore the hardware VLAN filter table. */ + u32 shadow_vfta[IGC_VFTA_SIZE]; + /* Info about the interface */ u16 link_active; u16 fc;