On Mon, Jun 27, 2011 at 09:31:26AM +0000, Thomas Gerlach wrote:
> Tobias Ulmer <tobiasu <at> tmux.org> writes:
> 
> > 
> > I've lost track which patches need to be applied or not, but once a
> > complete patch appears, I'm willing to test it on a machine that has
> > three different xl's.
> > 
> > 
> 
> 
> hi tobias,
> 
> sorry for any confusion. i think, the recent patches that should work are the
> following:

After spending some time with xl hardware, I fixed several issues and
got WOL to work even without the tiny WOL cable I thought was required.
It seems to send the signal via the PME pin on the PCI connector.

This diff works fine for me, against -current. Testing and OKs welcome.

Index: ic/xl.c
===================================================================
RCS file: /cvs/src/sys/dev/ic/xl.c,v
retrieving revision 1.102
diff -u -p -r1.102 xl.c
--- ic/xl.c     21 Jun 2011 16:52:45 -0000      1.102
+++ ic/xl.c     8 Jul 2011 12:46:21 -0000
@@ -193,6 +193,7 @@ void xl_miibus_writereg(struct device *,
 void xl_miibus_statchg(struct device *);
 #ifndef SMALL_KERNEL
 int xl_wol(struct ifnet *, int);
+void xl_wol_power(struct xl_softc *);
 #endif
 
 int
@@ -204,6 +205,9 @@ xl_activate(struct device *self, int act
 
        switch (act) {
        case DVACT_QUIESCE:
+#ifndef SMALL_KERNEL
+               xl_wol_power(sc);
+#endif
                rv = config_activate_children(self, act);
                break;
        case DVACT_SUSPEND:
@@ -2371,11 +2375,22 @@ xl_stop(struct xl_softc *sc)
        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)
-               sc->wol_power(sc->wol_power_arg);
+       xl_wol_power(sc);
 #endif
 }
+
+#ifndef SMALL_KERNEL
+void
+xl_wol_power(struct xl_softc *sc)
+{
+       /* Re-enable RX and call upper layer WOL power routine
+        * if WOL is enabled. */
+       if ((sc->xl_flags & XL_FLAG_WOL) && sc->wol_power) {
+               CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_RX_ENABLE);
+               sc->wol_power(sc->wol_power_arg);
+       }
+}
+#endif
 
 void
 xl_attach(struct xl_softc *sc)
Index: pci/if_xl_pci.c
===================================================================
RCS file: /cvs/src/sys/dev/pci/if_xl_pci.c,v
retrieving revision 1.36
diff -u -p -r1.36 if_xl_pci.c
--- pci/if_xl_pci.c     17 Apr 2011 20:52:43 -0000      1.36
+++ pci/if_xl_pci.c     8 Jul 2011 12:49:22 -0000
@@ -273,7 +273,7 @@ xl_pci_attach(struct device *parent, str
                 * 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) {
+               if ((command >> 16) & XL_PME_CAP_D3_HOT) {
                        sc->wol_power = xl_pci_wol_power;
                        sc->wol_power_arg = psc; 
                }
@@ -365,13 +365,8 @@ xl_pci_intr_ack(struct xl_softc *sc)
 void
 xl_pci_wol_power(void *ppsc)
 {
-       u_int32_t       command;
        struct xl_pci_softc *psc = (struct xl_pci_softc*)ppsc;
 
-       /* Make sure power management is enabled, and set the card into
-        * D3hot power state so it stays active after system shutdown. */
-       command = pci_conf_read(psc->psc_pc, psc->psc_tag, XL_PCI_PWRMGMTCTRL);
-       command |= XL_PME_EN | XL_PSTATE_D3;
-       pci_conf_write(psc->psc_pc, psc->psc_tag, XL_PCI_PWRMGMTCTRL, command);
+       pci_set_powerstate(psc->psc_pc, psc->psc_tag, PCI_PMCSR_STATE_D3);
 }
 #endif

Reply via email to