On Wed, Aug 29, 2012 at 07:53:54AM -0700, russell wrote: > finally even though it did not work out for me. ( my nics were > nfe(4) which has no WOL bits in OBSD, I blame nvidia, those > secretive assholes.)
Yes, but they cannot hide their secrets forever ;) The nfe driver already knows the which register to poke, and in fact it currently attempts to enable WOL by default. However, it always shuts down the receive engine when the interface goes down which prevents wol from working. The diff below disables wol by default and makes it configurable. Works for me with: nfe0 at pci0 dev 5 function 0 "NVIDIA nForce3 LAN" rev 0xa2: apic 1 int 9, address 00:11:d8:90:b3:56 rlphy0 at nfe0 phy 1: IP101 10/100 PHY, rev. 4 Can you please test if this works for you, too? After applying the patch: cd /usr/src/sys/dev/pci patch < this-email and recompiling your kernel, try: 'ifconfig nfe0 wol' and you should see the WOL flag set: nfe0: flags=108843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST,WOL> mtu 1500 Then run 'shutdown -hp now' and try to wake the box remotely, for instance via 'arp -W <macaddr>'. Please make sure any relevant BIOS options are enabled. Thanks. (BTW, this patch should apply equally well to -current, 5.2, 5.1, and 5.0). Index: if_nfe.c =================================================================== RCS file: /cvs/src/sys/dev/pci/if_nfe.c,v retrieving revision 1.98 diff -u -p -r1.98 if_nfe.c --- if_nfe.c 5 Apr 2011 18:01:21 -0000 1.98 +++ if_nfe.c 30 Aug 2012 17:05:06 -0000 @@ -104,6 +104,9 @@ void nfe_setmulti(struct nfe_softc *); void nfe_get_macaddr(struct nfe_softc *, uint8_t *); void nfe_set_macaddr(struct nfe_softc *, const uint8_t *); void nfe_tick(void *); +#ifndef SMALL_KERNEL +int nfe_wol(struct ifnet*, int); +#endif struct cfattach nfe_ca = { sizeof (struct nfe_softc), nfe_match, nfe_attach, NULL, @@ -348,6 +351,12 @@ nfe_attach(struct device *parent, struct ifp->if_capabilities = IFCAP_VLAN_MTU; +#ifndef SMALL_KERNEL + ifp->if_capabilities |= IFCAP_WOL; + ifp->if_wol = nfe_wol; + nfe_wol(ifp, 0); +#endif + if (sc->sc_flags & NFE_USE_JUMBO) ifp->if_hardmtu = NFE_JUMBO_MTU; @@ -1155,7 +1164,6 @@ nfe_init(struct ifnet *ifp) NFE_WRITE(sc, NFE_STATUS, sc->mii_phyaddr << 24 | NFE_STATUS_MAGIC); NFE_WRITE(sc, NFE_SETUP_R4, NFE_R4_MAGIC); - NFE_WRITE(sc, NFE_WOL_CTL, NFE_WOL_ENABLE); sc->rxtxctl &= ~NFE_RXTX_BIT2; NFE_WRITE(sc, NFE_RXTX_CTL, sc->rxtxctl); @@ -1201,11 +1209,13 @@ nfe_stop(struct ifnet *ifp, int disable) /* abort Tx */ NFE_WRITE(sc, NFE_TX_CTL, 0); - /* disable Rx */ - NFE_WRITE(sc, NFE_RX_CTL, 0); + if ((sc->sc_flags & NFE_WOL) == 0) { + /* disable Rx */ + NFE_WRITE(sc, NFE_RX_CTL, 0); - /* disable interrupts */ - NFE_WRITE(sc, NFE_IRQ_MASK, 0); + /* disable interrupts */ + NFE_WRITE(sc, NFE_IRQ_MASK, 0); + } /* reset Tx and Rx rings */ nfe_reset_tx_ring(sc, &sc->txq); @@ -1803,3 +1813,21 @@ nfe_tick(void *arg) timeout_add_sec(&sc->sc_tick_ch, 1); } + +#ifndef SMALL_KERNEL +int +nfe_wol(struct ifnet *ifp, int enable) +{ + struct nfe_softc *sc = ifp->if_softc; + + if (enable) { + sc->sc_flags |= NFE_WOL; + NFE_WRITE(sc, NFE_WOL_CTL, NFE_WOL_ENABLE); + } else { + sc->sc_flags &= ~NFE_WOL; + NFE_WRITE(sc, NFE_WOL_CTL, 0); + } + + return 0; +} +#endif Index: if_nfevar.h =================================================================== RCS file: /cvs/src/sys/dev/pci/if_nfevar.h,v retrieving revision 1.14 diff -u -p -r1.14 if_nfevar.h --- if_nfevar.h 7 Sep 2010 16:21:45 -0000 1.14 +++ if_nfevar.h 30 Aug 2012 16:56:56 -0000 @@ -83,6 +83,7 @@ struct nfe_softc { #define NFE_USE_JUMBO 0x10 #define NFE_CORRECT_MACADDR 0x20 #define NFE_PWR_MGMT 0x40 +#define NFE_WOL 0x80 uint32_t rxtxctl; uint8_t mii_phyaddr;