Page MenuHomeFreeBSD

D56259.diff
No OneTemporary

D56259.diff

diff --git a/share/man/man4/rge.4 b/share/man/man4/rge.4
--- a/share/man/man4/rge.4
+++ b/share/man/man4/rge.4
@@ -3,7 +3,7 @@
.\"
.\" SPDX-License-Identifier: BSD-2-Clause
.\"
-.Dd December 18, 2025
+.Dd April 5, 2026
.Dt RGE 4
.Os
.Sh NAME
@@ -39,8 +39,8 @@
.Pp
All NICs supported by the
.Nm
-driver have TCP/IP checksum offload and hardware VLAN tagging/insertion
-features, and use a descriptor-based DMA mechanism.
+driver have TCP/IP checksum offload, hardware VLAN tagging/insertion
+features, Wake On Lan (WOL), and use a descriptor-based DMA mechanism.
They are also
capable of TCP large send (TCP segmentation offload).
.Pp
diff --git a/sys/dev/rge/if_rge.c b/sys/dev/rge/if_rge.c
--- a/sys/dev/rge/if_rge.c
+++ b/sys/dev/rge/if_rge.c
@@ -103,12 +103,7 @@
static void rge_txq_flush_mbufs(struct rge_softc *sc);
static void rge_tick(void *);
static void rge_link_state(struct rge_softc *);
-#if 0
-#ifndef SMALL_KERNEL
-int rge_wol(struct ifnet *, int);
-void rge_wol_power(struct rge_softc *);
-#endif
-#endif
+static void rge_setwol(struct rge_softc *);
struct rge_matchid {
uint16_t vendor;
@@ -161,7 +156,11 @@
if_setcapabilities(sc->sc_ifp, IFCAP_HWCSUM);
if_setcapenable(sc->sc_ifp, if_getcapabilities(sc->sc_ifp));
- /* TODO: set WOL */
+ /* Enable WOL if PM is supported. */
+ if (pci_has_pm(sc->sc_dev)) {
+ if_setcapabilitiesbit(sc->sc_ifp, IFCAP_WOL_MAGIC, 0);
+ if_setcapenablebit(sc->sc_ifp, IFCAP_WOL_MAGIC, 0);
+ }
/* Attach interface */
ether_ifattach(sc->sc_ifp, eaddr);
@@ -654,26 +653,6 @@
return (0);
}
-#if 0
-
-int
-rge_activate(struct device *self, int act)
-{
-#ifndef SMALL_KERNEL
- struct rge_softc *sc = (struct rge_softc *)self;
-#endif
-
- switch (act) {
- case DVACT_POWERDOWN:
-#ifndef SMALL_KERNEL
- rge_wol_power(sc);
-#endif
- break;
- }
- return (0);
-}
-#endif
-
static void
rge_intr_msi(void *arg)
{
@@ -1014,7 +993,9 @@
reinit = 1;
}
- /* TODO: WOL */
+ if ((mask & IFCAP_WOL_MAGIC) != 0 &&
+ (if_getcapabilities(ifp) & IFCAP_WOL_MAGIC) != 0)
+ if_togglecapenable(ifp, IFCAP_WOL_MAGIC);
if ((mask & IFCAP_RXCSUM) != 0 &&
(if_getcapabilities(ifp) & IFCAP_RXCSUM) != 0) {
@@ -2620,6 +2601,22 @@
}
}
+static void
+rge_setwol(struct rge_softc *sc)
+{
+ if_t ifp = sc->sc_ifp;
+ int enable;
+
+ mtx_assert(&sc->sc_mtx, MA_OWNED);
+
+ if (!pci_has_pm(sc->sc_dev))
+ return;
+
+ enable = (if_getcapenable(ifp) & IFCAP_WOL_MAGIC) != 0;
+
+ rge_wol_config(sc, enable);
+}
+
/**
* @brief Suspend
*/
@@ -2630,7 +2627,7 @@
RGE_LOCK(sc);
rge_stop_locked(sc);
- /* TODO: wake on lan */
+ rge_setwol(sc);
sc->sc_suspended = true;
RGE_UNLOCK(sc);
@@ -2646,7 +2643,6 @@
struct rge_softc *sc = device_get_softc(dev);
RGE_LOCK(sc);
- /* TODO: wake on lan */
/* reinit if required */
if (if_getflags(sc->sc_ifp) & IFF_UP)
@@ -2669,6 +2665,7 @@
RGE_LOCK(sc);
rge_stop_locked(sc);
+ rge_setwol(sc);
RGE_UNLOCK(sc);
return (0);
diff --git a/sys/dev/rge/if_rge_hw.h b/sys/dev/rge/if_rge_hw.h
--- a/sys/dev/rge/if_rge_hw.h
+++ b/sys/dev/rge/if_rge_hw.h
@@ -37,5 +37,6 @@
extern void rge_write_phy_ocp(struct rge_softc *, uint16_t, uint16_t);
extern uint16_t rge_read_phy_ocp(struct rge_softc *sc, uint16_t reg);
extern int rge_get_link_status(struct rge_softc *);
+extern void rge_wol_config(struct rge_softc *, int);
#endif /* __IF_RGE_HW_H__ */
diff --git a/sys/dev/rge/if_rge_hw.c b/sys/dev/rge/if_rge_hw.c
--- a/sys/dev/rge/if_rge_hw.c
+++ b/sys/dev/rge/if_rge_hw.c
@@ -2196,50 +2196,37 @@
return ((RGE_READ_2(sc, RGE_PHYSTAT) & RGE_PHYSTAT_LINK) ? 1 : 0);
}
-#if 0
-#ifndef SMALL_KERNEL
-int
-rge_wol(struct ifnet *ifp, int enable)
+void
+rge_wol_config(struct rge_softc *sc, int enable)
{
- struct rge_softc *sc = ifp->if_softc;
-
- if (enable) {
- if (!(RGE_READ_1(sc, RGE_CFG1) & RGE_CFG1_PM_EN)) {
- printf("%s: power management is disabled, "
- "cannot do WOL\n", sc->sc_dev.dv_xname);
- return (ENOTSUP);
- }
-
- }
-
- rge_iff(sc);
-
if (enable)
RGE_MAC_SETBIT(sc, 0xc0b6, 0x0001);
else
RGE_MAC_CLRBIT(sc, 0xc0b6, 0x0001);
+ /* Enable config register write. */
RGE_SETBIT_1(sc, RGE_EECMD, RGE_EECMD_WRITECFG);
- RGE_CLRBIT_1(sc, RGE_CFG5, RGE_CFG5_WOL_LANWAKE | RGE_CFG5_WOL_UCAST |
- RGE_CFG5_WOL_MCAST | RGE_CFG5_WOL_BCAST);
+
+ /* Clear all WOL bits, then set as requested. */
RGE_CLRBIT_1(sc, RGE_CFG3, RGE_CFG3_WOL_LINK | RGE_CFG3_WOL_MAGIC);
- if (enable)
+ RGE_CLRBIT_1(sc, RGE_CFG5, RGE_CFG5_WOL_LANWAKE |
+ RGE_CFG5_WOL_UCAST | RGE_CFG5_WOL_MCAST | RGE_CFG5_WOL_BCAST);
+ if (enable) {
+ RGE_SETBIT_1(sc, RGE_CFG3, RGE_CFG3_WOL_MAGIC);
RGE_SETBIT_1(sc, RGE_CFG5, RGE_CFG5_WOL_LANWAKE);
- RGE_CLRBIT_1(sc, RGE_EECMD, RGE_EECMD_WRITECFG);
+ }
- return (0);
-}
+ /* Config register write done. */
+ RGE_CLRBIT_1(sc, RGE_EECMD, RGE_EECMD_WRITECFG);
-void
-rge_wol_power(struct rge_softc *sc)
-{
- /* Disable RXDV gate. */
- RGE_CLRBIT_1(sc, RGE_PPSW, 0x08);
- DELAY(2000);
+ if (enable) {
+ /* Disable RXDV gate so WOL packets can reach the NIC. */
+ RGE_CLRBIT_1(sc, RGE_PPSW, 0x08);
+ DELAY(2000);
- RGE_SETBIT_1(sc, RGE_CFG1, RGE_CFG1_PM_EN);
- RGE_SETBIT_1(sc, RGE_CFG2, RGE_CFG2_PMSTS_EN);
+ /* Enable power management. */
+ RGE_SETBIT_1(sc, RGE_CFG1, RGE_CFG1_PM_EN);
+ RGE_SETBIT_1(sc, RGE_CFG2, RGE_CFG2_PMSTS_EN);
+ }
}
-#endif
-#endif

File Metadata

Mime Type
text/plain
Expires
Sun, Apr 12, 8:08 PM (12 h, 8 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
31335096
Default Alt Text
D56259.diff (5 KB)

Event Timeline