From nobody Sun Aug 30 13:05:02 2026 X-Original-To: dev-commits-src-main@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 4hXsmH274Hz6qlsY for ; Sun, 30 Aug 2026 13:05:03 +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 4hXsmH1qCXz4CvB for ; Sun, 30 Aug 2026 13:05:03 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1788095103; 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=B9z5zLCdOeP7aZq1EirXoIr9rgC8ISK4nkvGgd4JxBk=; b=EOZzdNVoAO+ROUfttRgtWir83K0jlOoQRRsxG8CNXlj15Qt+tV3yVuT7ecWRGSJmogVZWY 6JgJRyIjsOXu6d2/I57LRSZQdufDP04kx7CbsaYFACi6GpAaYZNRyo9fc1wXkSRQqQBZ6e NJiCtuzV/e2+PL0obWO/ytjrUhjR1guKVwBPB7yrnJpoc42SzxQgMEVLsEnW0oreaEBe8w fJHPas8QPLUi8yFPZyIjzgrfDYwY+7eLbMhX21emxbf71m6kBLWmZuKBda2v3o9sP1x+rT z4hQvBccbdeyV2bSwdTenZXylqL4TxZH0dCae+L1F0RKlCcpyV01bfclrrZsLw== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1788095103; a=rsa-sha256; cv=none; b=WyVjc3s+nKlMFRfdNWEvJ49PRdNZsIrKwXVaMymLZ0GezswF2YtjtGnEBMCVyFjW5EAf9a kpkagDUGdAx+OqddgmOoIEz+OhZTos/iq/hdy3vObA6b7xSGZOIStr2rID3UBe2GmQtf08 baENcv5px7dwrs902p7DjuPnRZgNGIfW/HnXOUkO6d2fC+BF9NlEutC13BSgDqxMZKRn9Q vodahiKMqARHWcrxmSZCSHOAbduTXn9nKf59ce5h9FCBqOhI/y9f7ZSR2Kwx1jvXygB0GK XolD7nVtSotedZPyErJBUl3fGfVrwhPp87wBud+x4vrEBtgTTywCMxNPyIEFHA== 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=1788095103; 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=B9z5zLCdOeP7aZq1EirXoIr9rgC8ISK4nkvGgd4JxBk=; b=Xyzue7c/1W2jz9F4SH6fWIAmB7fI/rHsSSN7kD/LshsEgvSjYPA7Mvv/ydayutJHvO93TP /eDwdqo6lk5YIkK99DzqUO6eYycnylkC6CAJ8q2OxGw1X3Rgsw1wkp3gxoS2lh3p0RkN9T 4wuJ+JRht0o1xjiLhVf9pvSwCOTrerZrYRQ2QBD4bMd9FXsDwBUO7+DCsxtqQ5GKq+JCtJ E7MAkZiGix3cUvRDmRD6x23AHpz/KY6PJ9E/Mr5zAgazie10Daiiq0gO6kouKo4v3i1TmA tdOEkkmuAjn+rAwj6YK03DzFCn/z/0Rqirkh5CQFLbNk+GjM/oZwxrCe+K7npg== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) by mxrelay.nyi.freebsd.org (Postfix) with ESMTP id 4hXsmH0HTjzBL5 for ; Sun, 30 Aug 2026 13:05:03 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from git (uid 1279) (envelope-from git@FreeBSD.org) id 39011 by gitrepo.freebsd.org (DragonFly Mail Agent v0.13+ on gitrepo.freebsd.org); Sun, 30 Aug 2026 13:05:02 +0000 To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Kevin Bowling Subject: git: 90bee82638c3 - main - igc: Correct Wake-on-LAN filter programming List-Id: Commit messages for the main branch of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-main List-Help: List-Post: List-Subscribe: List-Unsubscribe: X-BeenThere: dev-commits-src-main@freebsd.org Sender: owner-dev-commits-src-main@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/main X-Git-Reftype: branch X-Git-Commit: 90bee82638c3f277f729aa5321aacd5d7333d512 Auto-Submitted: auto-generated Date: Sun, 30 Aug 2026 13:05:02 +0000 Message-Id: <6a942a7e.39011.7f11fd65@gitrepo.freebsd.org> The branch main has been updated by kbowling: URL: https://cgit.FreeBSD.org/src/commit/?id=90bee82638c3f277f729aa5321aacd5d7333d512 commit 90bee82638c3f277f729aa5321aacd5d7333d512 Author: Kevin Bowling AuthorDate: 2026-08-30 06:06:02 +0000 Commit: Kevin Bowling CommitDate: 2026-08-30 12:56:31 +0000 igc: Correct Wake-on-LAN filter programming The attach path translated WUC.APME into a saved link-change filter, then advertised magic-packet wake. Suspend removed unselected magic, unicast, and multicast bits from that saved value, commonly leaving no hardware wake filter at all. The destructive masking also made later capability changes ineffective. Advertise the I225/I226 wake filters whenever PCI power management is available and enable magic-packet wake by default. Build a fresh WUFC mask for every suspend, and explicitly clear WUC, WUFC, and PCI PME when wake is disabled. Require the PCI power-management capability to report D3hot PME support before advertising or arming wake. A PM capability alone does not mean the function can signal PME from the state used during system sleep. Reconstruct RAR0, the multicast table, and the receive filter after the stop-time reset so unicast and multicast wake use the current interface state. Keep the PHY powered while wake is armed, drain pending PCIe transactions, and disable bus mastering before D3. Clear the sticky base and extended wake status before arming filters. On resume, report the saved hardware wake cause, clear the device wake source, and then clear PCI PME. Run the DMA-fencing sequence even when wake programming fails, while allowing shutdown to continue after logging the failure. Explicitly restore PCI bus mastering during initialization so an iflib-local resume after another child rejects suspend can restart the device. Restore the Intel shared code PHY power down test from DPDK. The FreeBSD split inverted the reset-block condition, so its dormant hook would power down only when firmware explicitly vetoed the operation. Do not copy the generic legacy management test verbatim. The I225 and I226 define MANC bits 0 and 1 as flow-control and NC-SI discard controls, not SMBus and ASF enable bits. Preserve the link when the documented TCO receive path is enabled; the shared reset-block test separately honors the firmware keep-link-up veto. This follows section 8.21.1 of the Foxville Software User Manual. Evaluate management pass-through at each suspend. When neither a host wake filter nor management requires the link, invoke the shared-code power-down hook before D3. Leave a management-owned link untouched and restore a link previously powered down by the driver without another PHY reset. This follows DPDK's stop/start pairing without changing ordinary ifconfig down behavior. The implementation was checked against the Intel I225/I226 programming model, the Intel Linux igc lifecycle, and DPDK. On an I225-LM, a device-only D3 test observed PME for a valid magic packet and no PME with every host wake filter disabled. Both cases resumed to D0 with the link and configured addresses operational. The I225 system also completed a full ACPI S3 cycle and resumed with link, configured addresses, and traffic operational. On an I226-V, a device-only D3 test changed PMCSR accordingly after a magic packet. With dev.igc.0.wake enabled, a full ACPI S3 cycle remained asleep until a delayed magic packet and resumed with link, addresses, and traffic operational. PR: 282140 Obtained from: DPDK (shared-code power-down structure) MFC after: 2 weeks --- share/man/man4/igc.4 | 24 +++++- sys/dev/igc/if_igc.c | 209 ++++++++++++++++++++++++++++++++++------------ sys/dev/igc/if_igc.h | 4 +- sys/dev/igc/igc_base.c | 7 +- sys/dev/igc/igc_defines.h | 7 +- sys/dev/igc/igc_mac.c | 20 +++++ sys/dev/igc/igc_mac.h | 1 + sys/dev/igc/igc_regs.h | 2 +- 8 files changed, 204 insertions(+), 70 deletions(-) diff --git a/share/man/man4/igc.4 b/share/man/man4/igc.4 index 1fe87421738d..b7c3637ae7c0 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 August 11, 2026 +.Dd August 30, 2026 .Dt IGC 4 .Os .Sh NAME @@ -32,6 +32,24 @@ On Motherboard) based on the Intel I225 Multi Gigabit Controller. The driver supports Transmit/Receive checksum offload, Jumbo Frames, MSI/MSI-X, TSO, and RSS. .Pp +On systems that expose PCI power-management wake, the driver supports the +.Cm wol_magic , +.Cm wol_ucast , +and +.Cm wol_mcast +capabilities shown by +.Xr ifconfig 8 . +Magic-packet wake is enabled by default and any advertised wake mode can be +enabled or disabled with +.Xr ifconfig 8 . +Waking the system from an ACPI sleep state also requires enabling the +corresponding device wake source when it is exposed, for example: +.Bd -literal -offset indent +sysctl dev.igc.0.wake=1 +.Ed +The interface wake capabilities select the controller packet filters; they do +not enable the ACPI wake source. +.Pp Support for Jumbo Frames is provided via the interface MTU setting. Selecting an MTU larger than 1500 bytes with the .Xr ifconfig 8 @@ -154,8 +172,8 @@ A fatal initialization error has occurred. .It "igc%d: Unable to allocate bus resource: memory" A fatal initialization error has occurred. .It "igc%d: Invalid MAC address" -The MAC address programmed into the EEPROM is either empty or a multicast/broadcast -address. +The MAC address programmed into the EEPROM is either empty or a multicast or +broadcast address. .El .Sh SEE ALSO .Xr altq 4 , diff --git a/sys/dev/igc/if_igc.c b/sys/dev/igc/if_igc.c index 0ac2d2a7cc20..b07548821172 100644 --- a/sys/dev/igc/if_igc.c +++ b/sys/dev/igc/if_igc.c @@ -162,8 +162,10 @@ static int igc_sysctl_tso_tcp_flags_mask(SYSCTL_HANDLER_ARGS); /* Management and WOL Support */ static void igc_get_hw_control(struct igc_softc *); static void igc_release_hw_control(struct igc_softc *); -static void igc_get_wakeup(if_ctx_t); -static void igc_enable_wakeup(if_ctx_t); +static int igc_enable_pci_busmaster(struct igc_softc *); +static void igc_configure_wakeup(if_ctx_t); +static int igc_enable_wakeup(if_ctx_t); +static void igc_power_up_wakeup_link(struct igc_softc *); int igc_intr(void *); @@ -719,12 +721,7 @@ igc_if_attach_pre(if_ctx_t ctx) /* * Get Wake-on-Lan and Management info for later use */ - igc_get_wakeup(ctx); - - /* Enable only WOL MAGIC by default */ - scctx->isc_capenable &= ~IFCAP_WOL; - if (sc->wol != 0) - scctx->isc_capenable |= IFCAP_WOL_MAGIC; + igc_configure_wakeup(ctx); iflib_set_mac(ctx, hw->mac.addr); @@ -801,7 +798,13 @@ igc_if_detach(if_ctx_t ctx) static int igc_if_shutdown(if_ctx_t ctx) { - return igc_if_suspend(ctx); + int error; + + error = igc_if_suspend(ctx); + if (error != 0) + device_printf(iflib_get_dev(ctx), + "Wake configuration failed during shutdown: %d\n", error); + return (0); } /* @@ -811,22 +814,38 @@ static int igc_if_suspend(if_ctx_t ctx) { struct igc_softc *sc = iflib_get_softc(ctx); + int error; + error = igc_enable_wakeup(ctx); igc_release_hw_control(sc); - igc_enable_wakeup(ctx); - return (0); + return (error); } static int igc_if_resume(if_ctx_t ctx) { + struct igc_softc *sc = iflib_get_softc(ctx); + u32 wus, wus_ext; + /* * PCIe config space, and with it L1.2, may have been reset * across the suspend/resume cycle. */ igc_disable_broken_l1_2(ctx); + wus = IGC_READ_REG(&sc->hw, IGC_WUS); + wus_ext = IGC_READ_REG(&sc->hw, IGC_WUS_EXT); + if (wus != 0 || wus_ext != 0) + device_printf(sc->dev, + "Wakeup status: %#010x, extended %#010x\n", wus, wus_ext); + IGC_WRITE_REG(&sc->hw, IGC_WUFC, 0); + IGC_WRITE_REG(&sc->hw, IGC_WUFC_EXT, 0); + IGC_WRITE_REG(&sc->hw, IGC_WUC, 0); + IGC_WRITE_REG(&sc->hw, IGC_WUS, ~0U); + IGC_WRITE_REG(&sc->hw, IGC_WUS_EXT, ~0U); + /* Clear PME after its MAC wake source has been removed. */ + pci_clear_pme(sc->dev); - return(0); + return (0); } static int @@ -870,6 +889,14 @@ igc_if_init(if_ctx_t ctx) INIT_DEBUGOUT("igc_if_init: begin"); + if (igc_enable_pci_busmaster(sc) != 0) { + device_printf(sc->dev, "Could not enable PCI bus mastering\n"); + iflib_init_failed(ctx); + return; + } + if (sc->suspend_link_powered_down) + igc_power_up_wakeup_link(sc); + /* Get the latest mac address, User can use a LAA */ bcopy(if_getlladdr(ifp), sc->hw.mac.addr, ETHER_ADDR_LEN); @@ -2836,6 +2863,29 @@ igc_release_hw_control(struct igc_softc *sc) return; } +static int +igc_enable_pci_busmaster(struct igc_softc *sc) +{ + device_t dev; + u16 command; + int error; + + dev = sc->dev; + command = pci_read_config(dev, PCIR_COMMAND, 2); + if (command == 0xffff) + return (ENXIO); + if ((command & PCIM_CMD_BUSMASTEREN) != 0) + return (0); + + error = pci_enable_busmaster(dev); + command = pci_read_config(dev, PCIR_COMMAND, 2); + if (command == 0xffff) + return (ENXIO); + if ((command & PCIM_CMD_BUSMASTEREN) == 0) + return (error != 0 ? error : EIO); + return (0); +} + static int igc_is_valid_ether_addr(u8 *addr) { @@ -2848,75 +2898,124 @@ igc_is_valid_ether_addr(u8 *addr) return (true); } -/* -** Parse the interface capabilities with regard -** to both system management and wake-on-lan for -** later use. -*/ +/* Advertise the wake modes supported by I225/I226 physical functions. */ static void -igc_get_wakeup(if_ctx_t ctx) +igc_configure_wakeup(if_ctx_t ctx) { - struct igc_softc *sc = iflib_get_softc(ctx); - u16 eeprom_data = 0, apme_mask; - - apme_mask = IGC_WUC_APME; - eeprom_data = IGC_READ_REG(&sc->hw, IGC_WUC); + if_softc_ctx_t scctx = iflib_get_softc_ctx(ctx); + device_t dev = iflib_get_dev(ctx); + int capabilities; - if (eeprom_data & apme_mask) - sc->wol = IGC_WUFC_LNKC; + capabilities = pci_has_pme(dev, PCI_POWERSTATE_D3_HOT) ? + IFCAP_WOL : 0; + scctx->isc_capabilities &= ~IFCAP_WOL; + scctx->isc_capabilities |= capabilities; + scctx->isc_capenable &= ~IFCAP_WOL; + if (capabilities != 0) + scctx->isc_capenable |= IFCAP_WOL_MAGIC; } - -/* - * Enable PCI Wake On Lan capability - */ -static void +/* Configure the requested PCI Wake-on-LAN filters for suspend. */ +static int igc_enable_wakeup(if_ctx_t ctx) { struct igc_softc *sc = iflib_get_softc(ctx); device_t dev = iflib_get_dev(ctx); if_t ifp = iflib_get_ifp(ctx); - int error = 0; - u32 ctrl, rctl; - - if (!pci_has_pm(dev)) - return; + int enabled, error = 0, master_error, mcnt; + u32 ctrl, rctl, wufc; + bool manage; - /* - * Determine type of Wakeup: note that wol - * is set with all bits on by default. - */ - if ((if_getcapenable(ifp) & IFCAP_WOL_MAGIC) == 0) - sc->wol &= ~IGC_WUFC_MAG; - - if ((if_getcapenable(ifp) & IFCAP_WOL_UCAST) == 0) - sc->wol &= ~IGC_WUFC_EX; + if (!pci_has_pme(dev, PCI_POWERSTATE_D3_HOT)) + return (0); - if ((if_getcapenable(ifp) & IFCAP_WOL_MCAST) == 0) - sc->wol &= ~IGC_WUFC_MC; - else { - rctl = IGC_READ_REG(&sc->hw, IGC_RCTL); - rctl |= IGC_RCTL_MPE; - IGC_WRITE_REG(&sc->hw, IGC_RCTL, rctl); + enabled = if_getcapenable(ifp) & if_getcapabilities(ifp) & IFCAP_WOL; + manage = igc_enable_mng_pass_thru(&sc->hw); + wufc = 0; + if ((enabled & IFCAP_WOL_MAGIC) != 0) + wufc |= IGC_WUFC_MAG; + if ((enabled & IFCAP_WOL_UCAST) != 0) + wufc |= IGC_WUFC_EX; + if ((enabled & IFCAP_WOL_MCAST) != 0) { + wufc |= IGC_WUFC_MC; + bzero(sc->mta, ETHER_ADDR_LEN * + MAX_NUM_MULTICAST_ADDRESSES); + mcnt = if_foreach_llmaddr(ifp, igc_copy_maddr, sc->mta); + if (mcnt < MAX_NUM_MULTICAST_ADDRESSES) + igc_update_mc_addr_list(&sc->hw, sc->mta, mcnt); + } + + IGC_WRITE_REG(&sc->hw, IGC_WUFC, 0); + IGC_WRITE_REG(&sc->hw, IGC_WUFC_EXT, 0); + IGC_WRITE_REG(&sc->hw, IGC_WUC, 0); + IGC_WRITE_REG(&sc->hw, IGC_WUS, ~0U); + IGC_WRITE_REG(&sc->hw, IGC_WUS_EXT, ~0U); + + if (wufc == 0) { + if (manage) { + if (sc->suspend_link_powered_down) + igc_power_up_wakeup_link(sc); + pci_enable_pme(dev); + } else { + igc_power_down_phy(&sc->hw); + sc->suspend_link_powered_down = true; + pci_clear_pme(dev); + } + goto master_disable; } - - if (!(sc->wol & (IGC_WUFC_EX | IGC_WUFC_MAG | IGC_WUFC_MC))) + bcopy(if_getlladdr(ifp), sc->hw.mac.addr, ETHER_ADDR_LEN); + error = igc_rar_set(&sc->hw, sc->hw.mac.addr, 0); + if (error != IGC_SUCCESS) { + device_printf(dev, + "Could not restore unicast wake address: %d\n", error); goto pme; + } + rctl = IGC_READ_REG(&sc->hw, IGC_RCTL); + rctl &= ~(IGC_RCTL_UPE | IGC_RCTL_MPE | IGC_RCTL_MO_3); + rctl |= IGC_RCTL_EN | IGC_RCTL_BAM | + (sc->hw.mac.mc_filter_type << IGC_RCTL_MO_SHIFT); + if ((wufc & IGC_WUFC_MC) != 0) + rctl |= IGC_RCTL_MPE; + IGC_WRITE_REG(&sc->hw, IGC_RCTL, rctl); /* Advertise the wakeup capability */ ctrl = IGC_READ_REG(&sc->hw, IGC_CTRL); ctrl |= IGC_CTRL_ADVD3WUC; IGC_WRITE_REG(&sc->hw, IGC_CTRL, ctrl); + igc_power_up_wakeup_link(sc); /* Enable wakeup by the MAC */ IGC_WRITE_REG(&sc->hw, IGC_WUC, IGC_WUC_PME_EN); - IGC_WRITE_REG(&sc->hw, IGC_WUFC, sc->wol); + IGC_WRITE_REG(&sc->hw, IGC_WUFC, wufc); pme: - if (!error && (if_getcapenable(ifp) & IFCAP_WOL)) + if (error == IGC_SUCCESS) pci_enable_pme(dev); + else { + IGC_WRITE_REG(&sc->hw, IGC_WUFC, 0); + IGC_WRITE_REG(&sc->hw, IGC_WUFC_EXT, 0); + IGC_WRITE_REG(&sc->hw, IGC_WUC, 0); + pci_clear_pme(dev); + } - return; +master_disable: + master_error = igc_disable_pcie_master(&sc->hw); + if (master_error != IGC_SUCCESS) + device_printf(dev, "PCIe master disable timed out: %d\n", + master_error); + master_error = pci_disable_busmaster(dev); + if (master_error != 0) + device_printf(dev, "PCI bus-master disable failed: %d\n", + master_error); + + return (error == IGC_SUCCESS ? 0 : EIO); +} + +static void +igc_power_up_wakeup_link(struct igc_softc *sc) +{ + igc_power_up_phy(&sc->hw); + sc->suspend_link_powered_down = false; } /********************************************************************** diff --git a/sys/dev/igc/if_igc.h b/sys/dev/igc/if_igc.h index 3457f5e477ff..5b728b6b1193 100644 --- a/sys/dev/igc/if_igc.h +++ b/sys/dev/igc/if_igc.h @@ -380,9 +380,7 @@ struct igc_softc { u32 rx_mbuf_sz; int enable_aim; - - /* Management and WOL features */ - u32 wol; + bool suspend_link_powered_down; /* Multicast array memory */ u8 *mta; diff --git a/sys/dev/igc/igc_base.c b/sys/dev/igc/igc_base.c index 510f4c132b9a..cc8b4afbacd1 100644 --- a/sys/dev/igc/igc_base.c +++ b/sys/dev/igc/igc_base.c @@ -100,11 +100,10 @@ void igc_power_down_phy_copper_base(struct igc_hw *hw) if (!(phy->ops.check_reset_block)) return; - /* If the management interface is not enabled, then power down */ - if (phy->ops.check_reset_block(hw)) + /* If the management interface is not enabled, then power down. */ + if (!(igc_enable_mng_pass_thru(hw) || + phy->ops.check_reset_block(hw))) igc_power_down_phy_copper(hw); - - return; } /** diff --git a/sys/dev/igc/igc_defines.h b/sys/dev/igc/igc_defines.h index 1856c86b91a8..55d0cf8918c5 100644 --- a/sys/dev/igc/igc_defines.h +++ b/sys/dev/igc/igc_defines.h @@ -124,16 +124,15 @@ #define IGC_RXDPS_HDRSTAT_HDRSP 0x00008000 /* Management Control */ -#define IGC_MANC_SMBUS_EN 0x00000001 /* SMBus Enabled - RO */ -#define IGC_MANC_ASF_EN 0x00000002 /* ASF Enabled - RO */ +#define IGC_MANC_FC_DISCARD 0x00000001 /* Discard flow control */ +#define IGC_MANC_NCSI_DISCARD 0x00000002 /* Discard NC-SI */ #define IGC_MANC_ARP_EN 0x00002000 /* Enable ARP Request Filtering */ #define IGC_MANC_RCV_TCO_EN 0x00020000 /* Receive TCO Packets Enabled */ -#define IGC_MANC_BLK_PHY_RST_ON_IDE 0x00040000 /* Block phy resets */ +#define IGC_MANC_BLK_PHY_RST_ON_IDE 0x00040000 /* Keep PHY link up */ /* Enable MAC address filtering */ #define IGC_MANC_EN_MAC_ADDR_FILTER 0x00100000 /* Enable MNG packets to host memory */ #define IGC_MANC_EN_MNG2HOST 0x00200000 - #define IGC_MANC2H_PORT_623 0x00000020 /* Port 0x26f */ #define IGC_MANC2H_PORT_664 0x00000040 /* Port 0x298 */ #define IGC_MDEF_PORT_623 0x00000800 /* Port 0x26f */ diff --git a/sys/dev/igc/igc_mac.c b/sys/dev/igc/igc_mac.c index add6a7327ab6..722fb4e6864e 100644 --- a/sys/dev/igc/igc_mac.c +++ b/sys/dev/igc/igc_mac.c @@ -69,6 +69,26 @@ bool igc_null_mng_mode(struct igc_hw IGC_UNUSEDARG *hw) return false; } +/** + * igc_enable_mng_pass_thru - Check if management passthrough is needed + * @hw: pointer to the HW structure + * + * Verify that the I225/I226 management engine needs the external link. + **/ +bool +igc_enable_mng_pass_thru(struct igc_hw *hw) +{ + u32 manc; + + DEBUGFUNC("igc_enable_mng_pass_thru"); + + if (!hw->mac.asf_firmware_present) + return (false); + + manc = IGC_READ_REG(hw, IGC_MANC); + return ((manc & IGC_MANC_RCV_TCO_EN) != 0); +} + /** * igc_null_update_mc - No-op function, return void * @hw: pointer to the HW structure diff --git a/sys/dev/igc/igc_mac.h b/sys/dev/igc/igc_mac.h index 8349a45188b4..fac3712eac3a 100644 --- a/sys/dev/igc/igc_mac.h +++ b/sys/dev/igc/igc_mac.h @@ -12,6 +12,7 @@ void igc_null_mac_generic(struct igc_hw *hw); s32 igc_null_ops_generic(struct igc_hw *hw); s32 igc_null_link_info(struct igc_hw *hw, u16 *s, u16 *d); bool igc_null_mng_mode(struct igc_hw *hw); +bool igc_enable_mng_pass_thru(struct igc_hw *hw); void igc_null_update_mc(struct igc_hw *hw, u8 *h, u32 a); void igc_null_write_vfta(struct igc_hw *hw, u32 a, u32 b); int igc_null_rar_set(struct igc_hw *hw, u8 *h, u32 a); diff --git a/sys/dev/igc/igc_regs.h b/sys/dev/igc/igc_regs.h index 849b13b2adf2..0cc31eb158e5 100644 --- a/sys/dev/igc/igc_regs.h +++ b/sys/dev/igc/igc_regs.h @@ -231,7 +231,7 @@ #define IGC_VFTA 0x05600 /* VLAN Filter Table Array - RW Array */ #define IGC_WUC 0x05800 /* Wakeup Control - RW */ #define IGC_WUFC 0x05808 /* Wakeup Filter Control - RW */ -#define IGC_WUS 0x05810 /* Wakeup Status - RO */ +#define IGC_WUS 0x05810 /* Wakeup Status - RW1C */ /* Management registers */ #define IGC_MANC 0x05820 /* Management Control - RW */ #define IGC_IPAV 0x05838 /* IP Address Valid - RW */