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. */