Date: Sat, 8 Nov 2008 16:59:29 +0900 From: Pyun YongHyeon <pyunyh@gmail.com> To: Alexey Shuvaev <shuvaev@physik.uni-wuerzburg.de> Cc: freebsd-current@freebsd.org Subject: Re: Call for testers: fxp(4) WOL Message-ID: <20081108075929.GE14970@cdnetworks.co.kr> In-Reply-To: <20081107194844.GA55053@localhost.my.domain> References: <20081015003745.GG14769@cdnetworks.co.kr> <20081103183556.GA2009@localhost.my.domain> <20081104014246.GA98154@cdnetworks.co.kr> <20081107194844.GA55053@localhost.my.domain>
next in thread | previous in thread | raw e-mail | index | archive | help
--GvXjxJ+pjyke8COw Content-Type: text/plain; charset=us-ascii Content-Disposition: inline On Fri, Nov 07, 2008 at 08:48:44PM +0100, Alexey Shuvaev wrote: > On Tue, Nov 04, 2008 at 10:42:46AM +0900, Pyun YongHyeon wrote: > > On Mon, Nov 03, 2008 at 07:35:56PM +0100, Alexey Shuvaev wrote: > > > Here are relevant messages from the verbose boot: > > > > > > fxp0: <Intel 82801CAM (ICH3) Pro/100 VE Ethernet> port 0xdf40-0xdf7f mem 0xfceff000-0xfcefffff irq 11 at device 8.0 on pci2 > > > > If it's based on ICH controller it would be 82559. > > > > > fxp0: Reserved 0x1000 bytes for rid 0x10 type 3 at 0xfceff000 > > > fxp0: using memory space register mapping > > > fxp0: PCI IDs: 8086 1031 1179 0001 0042 > > > fxp0: Dynamic Standby mode is disabled > > > miibus0: <MII bus> on fxp0 > > > fxp0: XXX: driver didn't set ifq_maxlen > > > ^^^ > > > Is this something to fix? > > > > > > > fxp(4) didn't set ifq_maxlen and if_attach corrected this with > > its default value. Normally network device drivers set this queue > > length to number of Tx descriptors but it's completely up to > > driver writers and I don't see compeling reason to change that. > > > Ok, I just was attracted by something with 'XXX'. > > > > However the system seems to honors only the BIOS settings, if I enable WOL in > > > the BIOS the system wakes up from power-down or suspend (to ram) states > > > regardless of fxp settings and with disabled WOL in BIOS it never > > > wakes up. > > > > > > > Yes that's an expected behaviour. BIOS option should be changed to > > enable WOL if you want to wake up your box from power down. If > > you don't want to wake up your box regardless of BIOS configuration > > you have to disable WOL with ifconfig before shutting down your > > box. Likewise even if you enable WOL with ifconfig(8) to wake up > > your system, BIOS WOL option also should be enabled to make it > > work. > > > > > The worse thing I have noticed is if I send WOL packet while the system is > > > running it reliably hangs. It does not panic and switching virtual > > > consoles works (and typing/deleting something in the shell prompt too), > > > but the cooler runs at full power and you can't do anything else. > > > This is both with patched fxp and that from -CURRENT. > > > > Hmm, I think that was old bebahviour of stock fxp(4). Previously > > fxp(4) was programmed to accept WOL packets regardless of running > > state of hardware. With my patch the WOL should be disabled for > > normal operation and WOL is enabled again when you shutdown your > > box. If sotck fxp(4) also show the same behaviour it's big security > > hole. > > ATM I have no idea how WOL packets can affect running box. :-( > > > I have tested more thoroughly and here are the results. > > FreeBSD-CURRENT (late oktober) without your patch > (is it what you call 'stock'?): Yes. > interface up or down, WOL disabled or enabled in the BIOS - > system hangs when receiving WOL packet. > Breaking to debugger shows kernel running, namely 3 acpi threads, > acpi_task_[0-2]. This is critical issue, your box is vulnerable to WOL attack. > FreeBSD-CURRENT from 4 Nov 2008 with your patch: > again, with WOL enabled in BIOS or not, system hangs with WOL packet, > but only if interface is down. > With interface (fxp0) up and running, nothing happens. > However, I failed to disable WOL with ifconfig, notebook boots > always when WOL enabled in the BIOS. Maybe BIOS doesn't honor preprogrammed PCI configuration data? Or the reset command in fxp_stop() might cleared some important configuration data. > Linux-Ubuntu uname: Linux ubuntu 2.6.22-14-generic #1 SMP > Sun Oct 14 23:05:12 GMT 2007 i686 GNU/Linux (booted live from CD) > The same results as with FreeBSD-CURRENT with your patch. > Disabling wol with ethtool does not produce the desired results. > Receiving WOL packet when interface is down does not hang the system, > but it (according to top) consumes 70% in system with > kacpid process consuming 98.5% of cpu. > Thanks a lot for your testing! > > Thanks for testing. I'll think again. > > By chance can you try Linux on your system and check whether it > > works? > > > So, it seems your patch is making FreeBSD on par with Linux. > If you need something more, you are welcome! I still have no clue yet but would you try attached one after backing out previous patch? -- Regards, Pyun YongHyeon --GvXjxJ+pjyke8COw Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="fxp.wol.patch2" Index: sys/dev/fxp/if_fxp.c =================================================================== --- sys/dev/fxp/if_fxp.c (revision 184742) +++ sys/dev/fxp/if_fxp.c (working copy) @@ -402,7 +402,7 @@ uint32_t val; uint16_t data, myea[ETHER_ADDR_LEN / 2]; u_char eaddr[ETHER_ADDR_LEN]; - int i, prefer_iomap; + int i, pmc, prefer_iomap; int error; error = 0; @@ -480,6 +480,16 @@ sc->revision = pci_get_revid(dev); /* + * Check availability of WOL. + */ + if (sc->revision >= FXP_REV_82558_A4) { + fxp_read_eeprom(sc, &data, 10, 1); + if ((data & 0x20) != 0 && + pci_find_extcap(sc->dev, PCIY_PMG, &pmc) == 0) + sc->flags |= FXP_FLAG_WOLCAP; + } + + /* * Determine whether we must use the 503 serial interface. */ fxp_read_eeprom(sc, &data, 6, 1); @@ -778,6 +788,11 @@ ifp->if_capenable |= IFCAP_HWCSUM; } + if (sc->flags & FXP_FLAG_WOLCAP) { + ifp->if_capabilities |= IFCAP_WOL_MAGIC; + ifp->if_capenable |= IFCAP_WOL_MAGIC; + } + #ifdef DEVICE_POLLING /* Inform the world we support polling. */ ifp->if_capabilities |= IFCAP_POLLING; @@ -938,17 +953,13 @@ static int fxp_shutdown(device_t dev) { - struct fxp_softc *sc = device_get_softc(dev); /* * Make sure that DMA is disabled prior to reboot. Not doing * do could allow DMA to corrupt kernel memory during the * reboot before the driver initializes. */ - FXP_LOCK(sc); - fxp_stop(sc); - FXP_UNLOCK(sc); - return (0); + return (fxp_suspend(dev)); } /* @@ -960,11 +971,27 @@ fxp_suspend(device_t dev) { struct fxp_softc *sc = device_get_softc(dev); + struct ifnet *ifp; + int pmc; + uint16_t pmstat; FXP_LOCK(sc); + ifp = sc->ifp; + if (pci_find_extcap(sc->dev, PCIY_PMG, &pmc) == 0) { + pmstat = pci_read_config(sc->dev, pmc + PCIR_POWER_STATUS, 2); + pmstat &= ~(PCIM_PSTAT_PME | PCIM_PSTAT_PMEENABLE); + if ((ifp->if_capenable & IFCAP_WOL_MAGIC) != 0) { + /* Request PME. */ + pmstat |= PCIM_PSTAT_PME | PCIM_PSTAT_PMEENABLE; + sc->flags |= FXP_FLAG_WOL; + /* Reconfigure hardware to accept magic frames. */ + fxp_init_body(sc); + } + pci_write_config(sc->dev, pmc + PCIR_POWER_STATUS, pmstat, 2); + } fxp_stop(sc); - + sc->suspended = 1; FXP_UNLOCK(sc); @@ -980,9 +1007,23 @@ { struct fxp_softc *sc = device_get_softc(dev); struct ifnet *ifp = sc->ifp; + int pmc; + uint16_t pmstat; FXP_LOCK(sc); + if (pci_find_extcap(sc->dev, PCIY_PMG, &pmc) == 0) { + sc->flags &= ~FXP_FLAG_WOL; + pmstat = pci_read_config(sc->dev, pmc + PCIR_POWER_STATUS, 2); + /* Disable PME and clear PME status. */ + pmstat &= ~PCIM_PSTAT_PMEENABLE; + pci_write_config(sc->dev, pmc + PCIR_POWER_STATUS, pmstat, 2); + if ((sc->flags & FXP_FLAG_WOL) != 0) { + /* Clear wakeup events. */ + CSR_READ_1(sc, FXP_CSR_PMDR); + } + } + CSR_WRITE_4(sc, FXP_CSR_PORT, FXP_PORT_SELECTIVE_RESET); DELAY(10); @@ -1848,11 +1889,13 @@ callout_stop(&sc->stat_ch); /* - * Issue software reset, which also unloads the microcode. + * Preserve PCI configuration, configure, IA/multicast + * setup and put RU and CU into idle state. */ - sc->flags &= ~FXP_FLAG_UCODE; - CSR_WRITE_4(sc, FXP_CSR_PORT, FXP_PORT_SOFTWARE_RESET); + CSR_WRITE_4(sc, FXP_CSR_PORT, FXP_PORT_SELECTIVE_RESET); DELAY(50); + /* Disable interrupts. */ + CSR_WRITE_1(sc, FXP_CSR_SCB_INTRCNTL, FXP_SCB_INTR_DISABLE); /* * Release any xmit buffers. @@ -1932,6 +1975,13 @@ */ fxp_stop(sc); + /* + * Issue software reset, which also unloads the microcode. + */ + sc->flags &= ~FXP_FLAG_UCODE; + CSR_WRITE_4(sc, FXP_CSR_PORT, FXP_PORT_SOFTWARE_RESET); + DELAY(50); + prm = (ifp->if_flags & IFF_PROMISC) ? 1 : 0; /* @@ -2047,8 +2097,7 @@ cbp->rcv_crc_xfer = 0; /* (don't) xfer CRC to host */ cbp->long_rx_en = sc->flags & FXP_FLAG_LONG_PKT_EN ? 1 : 0; cbp->ia_wake_en = 0; /* (don't) wake up on address match */ - cbp->magic_pkt_dis = 0; /* (don't) disable magic packet */ - /* must set wake_en in PMCSR also */ + cbp->magic_pkt_dis = sc->flags & FXP_FLAG_WOL ? 0 : 1; cbp->force_fdx = 0; /* (don't) force full duplex */ cbp->fdx_pin_en = 1; /* (enable) FDX# pin */ cbp->multi_ia = 0; /* (don't) accept multiple IAs */ @@ -2458,6 +2507,10 @@ } } #endif + if ((mask & IFCAP_WOL_MAGIC) != 0 && + (ifp->if_capabilities & IFCAP_WOL_MAGIC) != 0) + ifp->if_capenable ^= IFCAP_WOL_MAGIC; + if (mask & IFCAP_VLAN_MTU) { FXP_LOCK(sc); ifp->if_capenable ^= IFCAP_VLAN_MTU; Index: sys/dev/fxp/if_fxpreg.h =================================================================== --- sys/dev/fxp/if_fxpreg.h (revision 184742) +++ sys/dev/fxp/if_fxpreg.h (working copy) @@ -46,6 +46,7 @@ #define FXP_CSR_EEPROMCONTROL 14 /* eeprom control (2 bytes) */ #define FXP_CSR_MDICONTROL 16 /* mdi control (4 bytes) */ #define FXP_CSR_FLOWCONTROL 0x19 /* flow control (2 bytes) */ +#define FXP_CSR_PMDR 0x1B /* power management driver (1 byte) */ #define FXP_CSR_GENCONTROL 0x1C /* general control (1 byte) */ /* Index: sys/dev/fxp/if_fxpvar.h =================================================================== --- sys/dev/fxp/if_fxpvar.h (revision 184742) +++ sys/dev/fxp/if_fxpvar.h (working copy) @@ -193,6 +193,8 @@ #define FXP_FLAG_DEFERRED_RNR 0x0200 /* DEVICE_POLLING deferred RNR */ #define FXP_FLAG_EXT_RFA 0x0400 /* extended RFDs for csum offload */ #define FXP_FLAG_SAVE_BAD 0x0800 /* save bad pkts: bad size, CRC, etc */ +#define FXP_FLAG_WOLCAP 0x1000 /* WOL supported */ +#define FXP_FLAG_WOL 0x2000 /* WOL active */ /* Macros to ease CSR access. */ #define CSR_READ_1(sc, reg) bus_read_1(sc->fxp_res[0], reg) --GvXjxJ+pjyke8COw--
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20081108075929.GE14970>