as for the "pulling toghether", i would suggest something like this (draft, patches against latest -current files, _without_ stefan's recent patches):
# diff -u xl.c.orig xl.c > xl.c.patch1 --- xl.c.orig Sun Apr 17 22:52:43 2011 +++ xl.c Wed Jun 22 11:53:45 2011 @@ -2373,8 +2373,9 @@ xl_freetxrx(sc); #ifndef SMALL_KERNEL - /* Call upper layer WOL power routine if WOL is enabled. */ - if ((sc->xl_flags & XL_FLAG_WOL) && sc->wol_power) + /* Re-enable RX and call upper layer WOL power routine + * if WOL power callback is registered. */ + if (sc->wol_power) sc->wol_power(sc->wol_power_arg); #endif } @@ -2646,6 +2647,7 @@ CSR_WRITE_2(sc, XL_W0_MFG_ID, XL_NO_XCVR_PWR_MAGICBITS); } +#if 1 #ifndef SMALL_KERNEL /* Check availability of WOL. */ if ((sc->xl_caps & XL_CAPS_PWRMGMT) != 0) { @@ -2654,6 +2656,7 @@ xl_wol(ifp, 0); } #endif +#endif /* * Call MI attach routines. @@ -2693,12 +2696,9 @@ { struct xl_softc *sc = ifp->if_softc; - XL_SEL_WIN(7); if (enable) { - CSR_WRITE_2(sc, XL_W7_BM_PME, XL_BM_PME_MAGIC); sc->xl_flags |= XL_FLAG_WOL; } else { - CSR_WRITE_2(sc, XL_W7_BM_PME, 0); sc->xl_flags &= ~XL_FLAG_WOL; } return (0); # diff -u if_xl_pci.c.orig if_xl_pci.c > if_xl_pci.c.patch1 --- if_xl_pci.c.orig Sun Apr 17 22:52:43 2011 +++ if_xl_pci.c Wed Jun 22 11:53:06 2011 @@ -266,18 +266,6 @@ pci_conf_write(pc, pa->pa_tag, XL_PCI_LOMEM, mem); pci_conf_write(pc, pa->pa_tag, XL_PCI_INTLINE, irq); } - -#ifndef SMALL_KERNEL - /* The card is WOL-capable if it supports PME# assertion - * from D3hot power state. Install a callback to configure - * PCI power state for WOL. It will be invoked when the - * interface stops and WOL was enabled. */ - command = pci_conf_read(pc, pa->pa_tag, XL_PCI_PWRMGMTCAP); - if (command & XL_PME_CAP_D3_HOT) { - sc->wol_power = xl_pci_wol_power; - sc->wol_power_arg = psc; - } -#endif } /* @@ -335,6 +323,16 @@ printf(": %s", intrstr); xl_attach(sc); + +#ifndef SMALL_KERNEL + /* If the card is WOL-capable install a callback to configure + * PCI power state for WOL. It will be invoked when the + * interface stops and WOL was enabled. */ + if (sc->xl_caps & XL_CAPS_PWRMGMT) { + sc->wol_power = xl_pci_wol_power; + sc->wol_power_arg = psc; + } +#endif } int @@ -367,6 +365,22 @@ { u_int32_t command; struct xl_pci_softc *psc = (struct xl_pci_softc*)ppsc; + struct xl_softc *sc = &psc->psc_softc; + + XL_SEL_WIN(7); + + /* Clear any pending PME events. */ + CSR_READ_2(sc, XL_W7_BM_PME); + + /* If WOL flag is not set make sure PME is disabled, and + * return without doing anything. */ + if ((sc->xl_flags & XL_FLAG_WOL) == 0) { + CSR_WRITE_2(sc, XL_W7_BM_PME, 0); + return; + } + + CSR_WRITE_2(sc, XL_W7_BM_PME, XL_BM_PME_MAGIC); + CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_RX_ENABLE); /* Make sure power management is enabled, and set the card into * D3hot power state so it stays active after system shutdown. */