FreeBSD Bugzilla – Attachment 248890 Details for
Bug 218579
bge(4): Wake on Lan (WoL) does not work
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
Latest version of patch for 14-STABLE
0001-bge-4-Add-WOL-support.patch (text/plain), 8.26 KB, created by
Cy Schubert
on 2024-03-03 08:25:36 UTC
(
hide
)
Description:
Latest version of patch for 14-STABLE
Filename:
MIME Type:
Creator:
Cy Schubert
Created:
2024-03-03 08:25:36 UTC
Size:
8.26 KB
patch
obsolete
>From 52e7f236d10fc651e679a116575dee97831bd3f8 Mon Sep 17 00:00:00 2001 >From: Cy Schubert <cy@FreeBSD.org> >Date: Sat, 4 Sep 2021 06:31:32 -0700 >Subject: [PATCH] bge(4): Add WOL support > >With this patch bge(4) receives WOL support. > >Like other NICs in FreeBSD when any of the WOL flags is set the NIC is >set to WOL upon NIC shutdown. > >PR: 218579, 171744, 177184, 184718 >Reported by: pozzugno@gmail.com >Reported by: Stephen Workman <workman_stephen _ gmail_com> >Reported by: Hielke Christian Braun <hcb _ unco_de> >Reported by: Simon Magrin <simon_magrin _ hotmail_com> >Reviewed by: >Tested by: Peter Libassi <peter _ libassi_se> on non-Acer machine >MFC after: 2 weeks >Relnotes: yes >Differential Revision: > >(cherry picked from commit 17c3c4975e266efbd98617c58d8293998fdd12df) >--- > sys/dev/bge/if_bge.c | 113 ++++++++++++++++++++++++++++++++++++++-- > sys/dev/bge/if_bgereg.h | 3 +- > 2 files changed, 110 insertions(+), 6 deletions(-) > >diff --git a/sys/dev/bge/if_bge.c b/sys/dev/bge/if_bge.c >index 77a4cb90d852..d06e0b90a291 100644 >--- a/sys/dev/bge/if_bge.c >+++ b/sys/dev/bge/if_bge.c >@@ -1,4 +1,4 @@ >-/*- >+/* > * SPDX-License-Identifier: BSD-4-Clause > * > * Copyright (c) 2001 Wind River Systems >@@ -479,6 +479,8 @@ static void bge_sig_pre_reset(struct bge_softc *, int); > static void bge_stop_fw(struct bge_softc *); > static int bge_reset(struct bge_softc *); > static void bge_link_upd(struct bge_softc *); >+static void bge_setwol(struct bge_softc *); >+static void bge_clrwol(struct bge_softc *); > > static void bge_ape_lock_init(struct bge_softc *); > static void bge_ape_read_fw_ver(struct bge_softc *); >@@ -888,6 +890,7 @@ bge_ape_send_event(struct bge_softc *sc, uint32_t event) > static void > bge_ape_driver_state_change(struct bge_softc *sc, int kind) > { >+ struct ifnet *ifp; > uint32_t apedata, event; > > if ((sc->bge_mfw_flags & BGE_MFW_ON_APE) == 0) >@@ -920,8 +923,24 @@ bge_ape_driver_state_change(struct bge_softc *sc, int kind) > event = BGE_APE_EVENT_STATUS_STATE_START; > break; > case BGE_RESET_SHUTDOWN: >- APE_WRITE_4(sc, BGE_APE_HOST_DRVR_STATE, >- BGE_APE_HOST_DRVR_STATE_UNLOAD); >+ /* XXX Needs rewording >+ * With the interface we are currently using, >+ * APE does not track driver state. Wiping >+ * out the HOST SEGMENT SIGNATURE forces >+ * the APE to assume OS absent status. >+ */ >+ APE_WRITE_4(sc, BGE_APE_HOST_SEG_SIG, 0); >+ >+ ifp = sc->bge_ifp; >+ if ((if_getcapenable(ifp) & IFCAP_WOL) != 0) { >+ APE_WRITE_4(sc, BGE_APE_HOST_WOL_SPEED, >+ BGE_APE_HOST_WOL_SPEED_AUTO); >+ APE_WRITE_4(sc, BGE_APE_HOST_DRVR_STATE, >+ BGE_APE_HOST_DRVR_STATE_WOL); >+ } else { >+ APE_WRITE_4(sc, BGE_APE_HOST_DRVR_STATE, >+ BGE_APE_HOST_DRVR_STATE_UNLOAD); >+ } > event = BGE_APE_EVENT_STATUS_STATE_UNLOAD; > break; > case BGE_RESET_SUSPEND: >@@ -3730,7 +3749,7 @@ bge_attach(device_t dev) > if_setsendqready(ifp); > if_sethwassist(ifp, sc->bge_csum_features); > if_setcapabilities(ifp, IFCAP_HWCSUM | IFCAP_VLAN_HWTAGGING | >- IFCAP_VLAN_MTU); >+ IFCAP_VLAN_MTU | IFCAP_WOL_MAGIC); > if ((sc->bge_flags & (BGE_FLAG_TSO | BGE_FLAG_TSO3)) != 0) { > if_sethwassistbits(ifp, CSUM_TSO, 0); > if_setcapabilitiesbit(ifp, IFCAP_TSO4 | IFCAP_VLAN_HWTSO, 0); >@@ -3738,6 +3757,8 @@ bge_attach(device_t dev) > #ifdef IFCAP_VLAN_HWCSUM > if_setcapabilitiesbit(ifp, IFCAP_VLAN_HWCSUM, 0); > #endif >+ if (pci_find_cap(dev, PCIY_PMG, ®) == 0) >+ if_setcapabilitiesbit(ifp, IFCAP_WOL_MAGIC, 0); > if_setcapenable(ifp, if_getcapabilities(ifp)); > #ifdef DEVICE_POLLING > if_setcapabilitiesbit(ifp, IFCAP_POLLING, 0); >@@ -3923,6 +3944,9 @@ bge_attach(device_t dev) > device_printf(sc->bge_dev, "couldn't set up irq\n"); > goto fail; > } >+ BGE_LOCK(sc); >+ bge_clrwol(sc); >+ BGE_UNLOCK(sc); > > /* Attach driver debugnet methods. */ > DEBUGNET_SET(ifp, bge); >@@ -3950,6 +3974,7 @@ bge_detach(device_t dev) > if (device_is_attached(dev)) { > ether_ifdetach(ifp); > BGE_LOCK(sc); >+ bge_setwol(sc); > bge_stop(sc); > BGE_UNLOCK(sc); > callout_drain(&sc->bge_stat_ch); >@@ -4137,7 +4162,8 @@ bge_reset(struct bge_softc *sc) > /* Reset some of the PCI state that got zapped by reset. */ > pci_write_config(dev, BGE_PCI_MISC_CTL, > BGE_PCIMISCCTL_INDIRECT_ACCESS | BGE_PCIMISCCTL_MASK_PCI_INTR | >- BGE_HIF_SWAP_OPTIONS | BGE_PCIMISCCTL_PCISTATE_RW, 4); >+ BGE_HIF_SWAP_OPTIONS | BGE_PCIMISCCTL_PCISTATE_RW | >+ BGE_PCIMISCCTL_CLOCKCTL_RW, 4); > val = BGE_PCISTATE_ROM_ENABLE | BGE_PCISTATE_ROM_RETRY_ENABLE; > if (sc->bge_chipid == BGE_CHIPID_BCM5704_A0 && > (sc->bge_flags & BGE_FLAG_PCIX) != 0) >@@ -5841,6 +5867,9 @@ bge_ioctl(if_t ifp, u_long command, caddr_t data) > } > } > #endif >+ if ((mask & IFCAP_WOL_MAGIC) != 0 && >+ (if_getcapabilities(ifp) & IFCAP_WOL_MAGIC) != 0) >+ if_togglecapenable(ifp, IFCAP_WOL_MAGIC); > if ((mask & IFCAP_TXCSUM) != 0 && > (if_getcapabilities(ifp) & IFCAP_TXCSUM) != 0) { > if_togglecapenable(ifp, IFCAP_TXCSUM); >@@ -6068,6 +6097,7 @@ bge_shutdown(device_t dev) > > sc = device_get_softc(dev); > BGE_LOCK(sc); >+ bge_setwol(sc); > bge_stop(sc); > BGE_UNLOCK(sc); > >@@ -6081,6 +6111,7 @@ bge_suspend(device_t dev) > > sc = device_get_softc(dev); > BGE_LOCK(sc); >+ bge_setwol(sc); > bge_stop(sc); > BGE_UNLOCK(sc); > >@@ -6096,11 +6127,13 @@ bge_resume(device_t dev) > sc = device_get_softc(dev); > BGE_LOCK(sc); > ifp = sc->bge_ifp; >+ bge_reset(sc); > if (if_getflags(ifp) & IFF_UP) { > bge_init_locked(sc); > if (if_getdrvflags(ifp) & IFF_DRV_RUNNING) > bge_start_locked(ifp); > } >+ bge_clrwol(sc); > BGE_UNLOCK(sc); > > return (0); >@@ -6850,3 +6883,73 @@ bge_debugnet_poll(if_t ifp, int count) > return (0); > } > #endif /* DEBUGNET */ >+ >+static void >+bge_setwol(struct bge_softc *sc) >+{ >+ struct ifnet *ifp; >+ uint32_t clk; >+ uint16_t pmstat; >+ int pmc; >+ >+#ifdef BGE_WOL_DEBUG >+ device_printf(sc->bge_dev, "Entering bge WOL\n"); >+#endif >+ ifp = sc->bge_ifp; >+ if ((if_getcapabilities(ifp) & IFCAP_WOL_MAGIC) == 0) >+ return; >+ if (pci_find_cap(sc->bge_dev, PCIY_PMG, &pmc) != 0) >+ return; >+ if ((if_getcapenable(ifp) & IFCAP_WOL) != 0) { >+#ifdef BGE_WOL_DEBUG >+ device_printf(sc->bge_dev, "Configuring bge WOL\n"); >+#endif >+ bge_reset(sc); >+ BGE_SETBIT(sc, BGE_MAC_MODE, BGE_MACMODE_MAGIC_PKT_ENB); >+ BGE_SETBIT(sc, BGE_MAC_MODE, BGE_MACMODE_ACPI_PWRON_ENB); >+ BGE_CLRBIT(sc, BGE_MAC_MODE, BGE_MACMODE_PORTMODE); >+ BGE_SETBIT(sc, BGE_MAC_MODE, BGE_PORTMODE_GMII); >+ BGE_SETBIT(sc, BGE_RX_MODE, BGE_RXMODE_ENABLE); >+ clk = CSR_READ_4(sc, BGE_PCI_CLKCTL) | >+ BGE_PCICLOCKCTL_RXCPU_CLK_DIS | >+ BGE_PCICLOCKCTL_ALTCLK | >+ BGE_PCICLOCKCTL_SYSPLL_DISABLE; >+ CSR_WRITE_4(sc, BGE_PCI_CLKCTL, clk); >+ } >+ else { >+#ifdef BGE_WOL_DEBUG >+ device_printf(sc->bge_dev, "Bypassing bge WOL\n"); >+#endif >+ BGE_CLRBIT(sc, BGE_MAC_MODE, BGE_MACMODE_MAGIC_PKT_ENB); >+ BGE_CLRBIT(sc, BGE_MAC_MODE, BGE_MACMODE_ACPI_PWRON_ENB); >+ } >+ >+ /* Request PME if WOL is requested. */ >+ pmstat = pci_read_config(sc->bge_dev, pmc + PCIR_POWER_STATUS, 2); >+ pmstat &= ~(PCIM_PSTAT_PME | PCIM_PSTAT_PMEENABLE); >+ if ((if_getcapenable(ifp) & IFCAP_WOL) != 0) >+ pmstat |= PCIM_PSTAT_PME | PCIM_PSTAT_PMEENABLE; >+ pci_write_config(sc->bge_dev, pmc + PCIR_POWER_STATUS, pmstat, 2); >+} >+ >+static void >+bge_clrwol(struct bge_softc *sc) >+{ >+ struct ifnet *ifp; >+ uint16_t pmstat; >+ int pmc; >+ >+ ifp = sc->bge_ifp; >+ if ((if_getcapabilities(ifp) & IFCAP_WOL) == 0) >+ return; >+ if (pci_find_cap(sc->bge_dev, PCIY_PMG, &pmc) != 0) >+ return; >+ if ((if_getcapenable(ifp) & IFCAP_WOL) == 0) >+ return; >+ BGE_CLRBIT(sc, BGE_MAC_MODE, BGE_MACMODE_MAGIC_PKT_ENB); >+ BGE_CLRBIT(sc, BGE_MAC_MODE, BGE_MACMODE_ACPI_PWRON_ENB); >+ >+ pmstat = pci_read_config(sc->bge_dev, pmc + PCIR_POWER_STATUS, 2); >+ pmstat &= ~(PCIM_PSTAT_PME | PCIM_PSTAT_PMEENABLE); >+ pci_write_config(sc->bge_dev, pmc + PCIR_POWER_STATUS, pmstat, 2); >+} >diff --git a/sys/dev/bge/if_bgereg.h b/sys/dev/bge/if_bgereg.h >index 8970a92c6a83..9a1bbba4411c 100644 >--- a/sys/dev/bge/if_bgereg.h >+++ b/sys/dev/bge/if_bgereg.h >@@ -456,7 +456,8 @@ > #define BGE_PCICLOCKCTL_ALTCLK 0x00001000 > #define BGE_PCICLOCKCTL_ALTCLK_SRC 0x00002000 > #define BGE_PCICLOCKCTL_PCIPLL_DISABLE 0x00004000 >-#define BGE_PCICLOCKCTL_SYSPLL_DISABLE 0x00008000 >+#define BGE_PCICLOCKCTL_SYSPLL_DISABLE 0x00008000 /* Disable the 133 MHz >+ * phase-locked loop */ > #define BGE_PCICLOCKCTL_BIST_ENABLE 0x00010000 > > #ifndef PCIM_CMD_MWIEN >-- >2.43.2 >
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 218579
:
186870
|
191147
|
197700
|
212388
|
248615
|
248888
| 248890 |
248891
|
249663
|
249664