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;

Reply via email to