Module Name: src Committed By: msaitoh Date: Sun Mar 7 09:05:19 UTC 2010
Modified Files: src/sys/dev/mii: igphyreg.h src/sys/dev/pci: if_wm.c if_wmreg.h if_wmvar.h Log Message: - Add code for WOL, ASF, IPMI and Intel AMT. - wm_enable_wakeup() is disabled by default. If you want to use WOL with the Magic Packet, define WM_WOL. - Add the following flags: WM_F_ASF_FIRMWARE_PRESENT WM_F_ARC_SUBSYSTEM_VALID WM_F_HAS_AMT WM_F_HAS_MANAGE WM_F_WOL - Add wm_suspend() and wm_resume(). Give/get the control to/from the firmware. - Need more work for PCH. See wm_enable_phy_wakeup(). - Enable wm_get_hw_control() for 82574 and 82583. - Add Yet another workaround for ICH8. - Add wm_igp3_phy_powerdown_workaround_ich8lan() for power down problem on D3. To generate a diff of this commit: cvs rdiff -u -r1.5 -r1.6 src/sys/dev/mii/igphyreg.h cvs rdiff -u -r1.202 -r1.203 src/sys/dev/pci/if_wm.c cvs rdiff -u -r1.39 -r1.40 src/sys/dev/pci/if_wmreg.h cvs rdiff -u -r1.10 -r1.11 src/sys/dev/pci/if_wmvar.h Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/dev/mii/igphyreg.h diff -u src/sys/dev/mii/igphyreg.h:1.5 src/sys/dev/mii/igphyreg.h:1.6 --- src/sys/dev/mii/igphyreg.h:1.5 Tue Jan 12 21:48:26 2010 +++ src/sys/dev/mii/igphyreg.h Sun Mar 7 09:05:19 2010 @@ -1,4 +1,4 @@ -/* $NetBSD: igphyreg.h,v 1.5 2010/01/12 21:48:26 msaitoh Exp $ */ +/* $NetBSD: igphyreg.h,v 1.6 2010/03/07 09:05:19 msaitoh Exp $ */ /******************************************************************************* @@ -154,6 +154,22 @@ #define ANALOG_FUSE_FINE_1 0x0080 #define ANALOG_FUSE_FINE_10 0x0500 +/* + * IGP3 regs + */ +#define IGP3_PAGE_SHIFT 5 +#define IGP3_MAX_REG_ADDRESS 0x1f /* 5 bit address bus (0-0x1f) */ +#define IGP3_REG(page, reg) \ + (((page) << IGP3_PAGE_SHIFT) | ((reg) & IGP3_MAX_REG_ADDRESS)) + +#define IGP3_VR_CTRL IGP3_REG(776, 18) +#define IGP3_VR_CTRL_DEV_POWERDOWN_MODE_MASK 0x0300 +#define IGP3_VR_CTRL_MODE_SHUTDOWN 0x0200 + +#define IGP3_PM_CTRL IGP3_REG(769, 20) +#define IGP3_PM_CTRL_FORCE_PWR_DOWN 0x0020 + + #define IGPHY_READ(sc, reg) \ (PHY_WRITE(sc, MII_IGPHY_PAGE_SELECT, (reg) & ~0x1f), \ PHY_READ(sc, (reg) & 0x1f)) Index: src/sys/dev/pci/if_wm.c diff -u src/sys/dev/pci/if_wm.c:1.202 src/sys/dev/pci/if_wm.c:1.203 --- src/sys/dev/pci/if_wm.c:1.202 Sun Mar 7 07:53:37 2010 +++ src/sys/dev/pci/if_wm.c Sun Mar 7 09:05:19 2010 @@ -1,4 +1,4 @@ -/* $NetBSD: if_wm.c,v 1.202 2010/03/07 07:53:37 msaitoh Exp $ */ +/* $NetBSD: if_wm.c,v 1.203 2010/03/07 09:05:19 msaitoh Exp $ */ /* * Copyright (c) 2001, 2002, 2003, 2004 Wasabi Systems, Inc. @@ -76,7 +76,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: if_wm.c,v 1.202 2010/03/07 07:53:37 msaitoh Exp $"); +__KERNEL_RCSID(0, "$NetBSD: if_wm.c,v 1.203 2010/03/07 09:05:19 msaitoh Exp $"); #include "rnd.h" @@ -137,7 +137,9 @@ #define WM_DEBUG_TX 0x02 #define WM_DEBUG_RX 0x04 #define WM_DEBUG_GMII 0x08 -int wm_debug = WM_DEBUG_TX|WM_DEBUG_RX|WM_DEBUG_LINK|WM_DEBUG_GMII; +#define WM_DEBUG_MANAGE 0x10 +int wm_debug = WM_DEBUG_TX | WM_DEBUG_RX | WM_DEBUG_LINK | WM_DEBUG_GMII + | WM_DEBUG_MANAGE; #define DPRINTF(x, y) if (wm_debug & (x)) printf y #else @@ -262,6 +264,7 @@ int sc_bus_speed; /* PCI/PCIX bus speed */ int sc_pcixe_capoff; /* PCI[Xe] capability register offset */ + const struct wm_product *sc_wmp; /* Pointer to the wm_product entry */ wm_chip_type sc_type; /* MAC type */ int sc_rev; /* MAC revision */ wm_phy_type sc_phytype; /* PHY type */ @@ -282,9 +285,9 @@ /* * Software state for the transmit and receive descriptors. */ - int sc_txnum; /* must be a power of two */ - struct wm_txsoft sc_txsoft[WM_TXQUEUELEN_MAX]; - struct wm_rxsoft sc_rxsoft[WM_NRXDESC]; + int sc_txnum; /* must be a power of two */ + struct wm_txsoft sc_txsoft[WM_TXQUEUELEN_MAX]; + struct wm_rxsoft sc_rxsoft[WM_NRXDESC]; /* * Control data structures. @@ -498,6 +501,8 @@ static int wm_ioctl(struct ifnet *, u_long, void *); static int wm_init(struct ifnet *); static void wm_stop(struct ifnet *, int); +static bool wm_suspend(device_t, const pmf_qual_t *); +static bool wm_resume(device_t, const pmf_qual_t *); static void wm_reset(struct wm_softc *); static void wm_rxdrain(struct wm_softc *); @@ -575,16 +580,28 @@ static int wm_check_mng_mode_ich8lan(struct wm_softc *); static int wm_check_mng_mode_82574(struct wm_softc *); static int wm_check_mng_mode_generic(struct wm_softc *); +static int wm_enable_mng_pass_thru(struct wm_softc *); static int wm_check_reset_block(struct wm_softc *); static void wm_get_hw_control(struct wm_softc *); static int wm_check_for_link(struct wm_softc *); static void wm_kmrn_lock_loss_workaround_ich8lan(struct wm_softc *); static void wm_gig_downshift_workaround_ich8lan(struct wm_softc *); +#ifdef WM_WOL +static void wm_igp3_phy_powerdown_workaround_ich8lan(struct wm_softc *); +#endif static void wm_hv_phy_workaround_ich8lan(struct wm_softc *); static void wm_k1_gig_workaround_hv(struct wm_softc *, int); static void wm_configure_k1_ich8lan(struct wm_softc *, int); static void wm_set_pcie_completion_timeout(struct wm_softc *); static void wm_reset_init_script_82575(struct wm_softc *); +static void wm_release_manageability(struct wm_softc *); +static void wm_release_hw_control(struct wm_softc *); +static void wm_get_wakeup(struct wm_softc *); +#ifdef WM_WOL +static void wm_enable_phy_wakeup(struct wm_softc *); +static void wm_enable_wakeup(struct wm_softc *); +#endif +static void wm_init_manageability(struct wm_softc *); CFATTACH_DECL3_NEW(wm, sizeof(struct wm_softc), wm_match, wm_attach, wm_detach, NULL, NULL, NULL, DVF_DETACH_SHUTDOWN); @@ -600,6 +617,7 @@ int wmp_flags; #define WMP_F_1000X 0x01 #define WMP_F_1000T 0x02 +#define WMP_F_SERDES 0x04 } wm_products[] = { { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82542, "Intel i82542 1000BASE-X Ethernet", @@ -1082,12 +1100,13 @@ uint8_t enaddr[ETHER_ADDR_LEN]; uint16_t myea[ETHER_ADDR_LEN / 2], cfg1, cfg2, swdpin, io3; pcireg_t preg, memtype; + uint16_t eeprom_data, apme_mask; uint32_t reg; sc->sc_dev = self; callout_init(&sc->sc_tick_ch, 0); - wmp = wm_lookup(pa); + sc->sc_wmp = wmp = wm_lookup(pa); if (wmp == NULL) { printf("\n"); panic("wm_attach: impossible"); @@ -1118,7 +1137,7 @@ if ((sc->sc_type == WM_T_82575) || (sc->sc_type == WM_T_82576) || (sc->sc_type == WM_T_82580) || (sc->sc_type == WM_T_82580ER)) - sc->sc_flags |= WM_F_NEWQUEUE; + sc->sc_flags |= WM_F_NEWQUEUE; /* Set device properties (mactype) */ dict = device_properties(sc->sc_dev); @@ -1150,6 +1169,8 @@ return; } + wm_get_wakeup(sc); + /* * In addition, i82544 and later support I/O mapped indirect * register access. It is not desirable (nor supported in @@ -1638,6 +1659,58 @@ } } + /* check for WM_F_WOL */ + switch (sc->sc_type) { + case WM_T_82542_2_0: + case WM_T_82542_2_1: + case WM_T_82543: + /* dummy? */ + eeprom_data = 0; + apme_mask = EEPROM_CFG3_APME; + break; + case WM_T_82544: + apme_mask = EEPROM_CFG2_82544_APM_EN; + eeprom_data = cfg2; + break; + case WM_T_82546: + case WM_T_82546_3: + case WM_T_82571: + case WM_T_82572: + case WM_T_82573: + case WM_T_82574: + case WM_T_82583: + case WM_T_80003: + default: + apme_mask = EEPROM_CFG3_APME; + wm_read_eeprom(sc, (sc->sc_funcid == 1) ? EEPROM_OFF_CFG3_PORTB + : EEPROM_OFF_CFG3_PORTA, 1, &eeprom_data); + break; + case WM_T_82575: + case WM_T_82576: + case WM_T_82580: + case WM_T_82580ER: + case WM_T_ICH8: + case WM_T_ICH9: + case WM_T_ICH10: + case WM_T_PCH: + apme_mask = WUC_APME; + eeprom_data = CSR_READ(sc, WMREG_WUC); + break; + } + + /* Check for WM_F_WOL flag after the setting of the EEPROM stuff */ + if ((eeprom_data & apme_mask) != 0) + sc->sc_flags |= WM_F_WOL; +#ifdef WM_DEBUG + if ((sc->sc_flags & WM_F_WOL) != 0) + printf("WOL\n"); +#endif + + /* + * XXX need special handling for some multiple port cards + * to disable a paticular port. + */ + if (sc->sc_type >= WM_T_82544) { pn = prop_dictionary_get(dict, "i82543-swdpin"); if (pn != NULL) { @@ -1930,7 +2003,7 @@ NULL, xname, "rx_macctl"); #endif /* WM_EVENT_COUNTERS */ - if (pmf_device_register(self, NULL, NULL)) + if (pmf_device_register(self, wm_suspend, wm_resume)) pmf_class_network_register(self, ifp); else aprint_error_dev(self, "couldn't establish power handler\n"); @@ -1980,9 +2053,7 @@ pmf_device_deregister(self); /* Tell the firmware about the release */ -#if 0 wm_release_manageability(sc); -#endif mii_detach(&sc->sc_mii, MII_PHY_ANY, MII_OFFSET_ANY); @@ -2025,9 +2096,7 @@ sc->sc_ss = 0; } -#if 0 wm_release_hw_control(sc); -#endif return 0; } @@ -3990,6 +4059,9 @@ if ((error = mii_ifmedia_change(&sc->sc_mii)) != 0) goto out; + /* Configure for OS presence */ + wm_init_manageability(sc); + /* * Set up the receive control register; we actually program * the register when we set the receive filter. Use multicast @@ -6729,6 +6801,36 @@ } static int +wm_enable_mng_pass_thru(struct wm_softc *sc) +{ + uint32_t manc, fwsm, factps; + + if ((sc->sc_flags & WM_F_ASF_FIRMWARE_PRES) == 0) + return 0; + + manc = CSR_READ(sc, WMREG_MANC); + + DPRINTF(WM_DEBUG_MANAGE, ("%s: MANC (%08x)\n", + device_xname(sc->sc_dev), manc)); + if (((manc & MANC_RECV_TCO_EN) == 0) + || ((manc & MANC_EN_MAC_ADDR_FILTER) == 0)) + return 0; + + if ((sc->sc_flags & WM_F_ARC_SUBSYS_VALID) != 0) { + fwsm = CSR_READ(sc, WMREG_FWSM); + factps = CSR_READ(sc, WMREG_FACTPS); + if (((factps & FACTPS_MNGCG) == 0) + && ((fwsm & FWSM_MODE_MASK) + == (MNG_ICH_IAMT_MODE << FWSM_MODE_SHIFT))) + return 1; + } else if (((manc & MANC_SMBUS_EN) != 0) + && ((manc & MANC_ASF_EN) == 0)) + return 1; + + return 0; +} + +static int wm_check_reset_block(struct wm_softc *sc) { uint32_t reg; @@ -6771,19 +6873,13 @@ switch (sc->sc_type) { case WM_T_82573: -#if 0 - case WM_T_82574: - case WM_T_82583: - /* - * FreeBSD's em driver has the function for 82574 to checks - * the management mode, but it's not used. Why? - */ -#endif reg = CSR_READ(sc, WMREG_SWSM); CSR_WRITE(sc, WMREG_SWSM, reg | SWSM_DRV_LOAD); break; case WM_T_82571: case WM_T_82572: + case WM_T_82574: + case WM_T_82583: case WM_T_80003: case WM_T_ICH8: case WM_T_ICH9: @@ -6797,6 +6893,24 @@ } } +static void +wm_release_hw_control(struct wm_softc *sc) +{ + uint32_t reg; + + if ((sc->sc_flags & WM_F_HAS_MANAGE) == 0) + return; + + if (sc->sc_type == WM_T_82573) { + reg = CSR_READ(sc, WMREG_SWSM); + reg &= ~SWSM_DRV_LOAD; + CSR_WRITE(sc, WMREG_SWSM, reg & ~SWSM_DRV_LOAD); + } else { + reg = CSR_READ(sc, WMREG_CTRL_EXT); + CSR_WRITE(sc, WMREG_CTRL_EXT, reg & ~CTRL_EXT_DRV_LOAD); + } +} + /* XXX Currently TBI only */ static int wm_check_for_link(struct wm_softc *sc) @@ -6930,6 +7044,45 @@ } } +#ifdef WM_WOL +/* Power down workaround on D3 */ +static void +wm_igp3_phy_powerdown_workaround_ich8lan(struct wm_softc *sc) +{ + uint32_t reg; + int i; + + for (i = 0; i < 2; i++) { + /* Disable link */ + reg = CSR_READ(sc, WMREG_PHY_CTRL); + reg |= PHY_CTRL_GBE_DIS | PHY_CTRL_NOND0A_GBE_DIS; + CSR_WRITE(sc, WMREG_PHY_CTRL, reg); + + /* + * Call gig speed drop workaround on Gig disable before + * accessing any PHY registers + */ + if (sc->sc_type == WM_T_ICH8) + wm_gig_downshift_workaround_ich8lan(sc); + + /* Write VR power-down enable */ + reg = sc->sc_mii.mii_readreg(sc->sc_dev, 1, IGP3_VR_CTRL); + reg &= ~IGP3_VR_CTRL_DEV_POWERDOWN_MODE_MASK; + reg |= IGP3_VR_CTRL_MODE_SHUTDOWN; + sc->sc_mii.mii_writereg(sc->sc_dev, 1, IGP3_VR_CTRL, reg); + + /* Read it back and test */ + reg = sc->sc_mii.mii_readreg(sc->sc_dev, 1, IGP3_VR_CTRL); + reg &= IGP3_VR_CTRL_DEV_POWERDOWN_MODE_MASK; + if ((reg == IGP3_VR_CTRL_MODE_SHUTDOWN) || (i != 0)) + break; + + /* Issue PHY reset and repeat at most one more time */ + CSR_WRITE(sc, WMREG_CTRL, sc->sc_ctrl | CTRL_PHY_RESET); + } +} +#endif /* WM_WOL */ + /* * Workaround for pch's PHYs * XXX should be moved to new PHY driver? @@ -7083,3 +7236,225 @@ wm_82575_write_8bit_ctlr_reg(sc, WMREG_SCCTL, 0x14, 0x00); wm_82575_write_8bit_ctlr_reg(sc, WMREG_SCCTL, 0x10, 0x00); } + +static void +wm_init_manageability(struct wm_softc *sc) +{ + + if (sc->sc_flags & WM_F_HAS_MANAGE) { + uint32_t manc2h = CSR_READ(sc, WMREG_MANC2H); + uint32_t manc = CSR_READ(sc, WMREG_MANC); + + /* disabl hardware interception of ARP */ + manc &= ~MANC_ARP_EN; + + /* enable receiving management packets to the host */ + if (sc->sc_type >= WM_T_82571) { + manc |= MANC_EN_MNG2HOST; + manc2h |= MANC2H_PORT_623| MANC2H_PORT_624; + CSR_WRITE(sc, WMREG_MANC2H, manc2h); + + } + + CSR_WRITE(sc, WMREG_MANC, manc); + } +} + +static void +wm_release_manageability(struct wm_softc *sc) +{ + + if (sc->sc_flags & WM_F_HAS_MANAGE) { + uint32_t manc = CSR_READ(sc, WMREG_MANC); + + if (sc->sc_type >= WM_T_82571) + manc &= ~MANC_EN_MNG2HOST; + + CSR_WRITE(sc, WMREG_MANC, manc); + } +} + +static void +wm_get_wakeup(struct wm_softc *sc) +{ + + /* 0: HAS_AMT, ARC_SUBSYS_VALID, ASF_FIRMWARE_PRES */ + switch (sc->sc_type) { + case WM_T_82573: + case WM_T_82583: + sc->sc_flags |= WM_F_HAS_AMT; + /* FALLTHROUGH */ + case WM_T_80003: + case WM_T_82541: + case WM_T_82547: + case WM_T_82571: + case WM_T_82572: + case WM_T_82574: + case WM_T_82575: + case WM_T_82576: + if ((CSR_READ(sc, WMREG_FWSM) & FWSM_MODE_MASK) != 0) + sc->sc_flags |= WM_F_ARC_SUBSYS_VALID; + sc->sc_flags |= WM_F_ASF_FIRMWARE_PRES; + break; + case WM_T_ICH8: + case WM_T_ICH9: + case WM_T_ICH10: + case WM_T_PCH: + sc->sc_flags |= WM_F_HAS_AMT; + sc->sc_flags |= WM_F_ASF_FIRMWARE_PRES; + break; + default: + break; + } + + /* 1: HAS_MANAGE */ + if (wm_enable_mng_pass_thru(sc) != 0) + sc->sc_flags |= WM_F_HAS_MANAGE; + +#ifdef WM_DEBUG + printf("\n"); + if ((sc->sc_flags & WM_F_HAS_AMT) != 0) + printf("HAS_AMT,"); + if ((sc->sc_flags & WM_F_ARC_SUBSYS_VALID) != 0) + printf("ARC_SUBSYS_VALID,"); + if ((sc->sc_flags & WM_F_ASF_FIRMWARE_PRES) != 0) + printf("ASF_FIRMWARE_PRES,"); + if ((sc->sc_flags & WM_F_HAS_MANAGE) != 0) + printf("HAS_MANAGE,"); + printf("\n"); +#endif + /* + * Note that the WOL flags is set after the resetting of the eeprom + * stuff + */ +} + +#ifdef WM_WOL +/* WOL in the newer chipset interfaces (pchlan) */ +static void +wm_enable_phy_wakeup(struct wm_softc *sc) +{ +#if 0 + uint16_t preg; + + /* Copy MAC RARs to PHY RARs */ + + /* Copy MAC MTA to PHY MTA */ + + /* Configure PHY Rx Control register */ + + /* Enable PHY wakeup in MAC register */ + + /* Configure and enable PHY wakeup in PHY registers */ + + /* Activate PHY wakeup */ + + /* XXX */ +#endif +} + +static void +wm_enable_wakeup(struct wm_softc *sc) +{ + uint32_t reg, pmreg; + pcireg_t pmode; + + if (pci_get_capability(sc->sc_pc, sc->sc_pcitag, PCI_CAP_PWRMGMT, + &pmreg, NULL) == 0) + return; + + /* Advertise the wakeup capability */ + CSR_WRITE(sc, WMREG_CTRL, sc->sc_ctrl | CTRL_SWDPIN(2) + | CTRL_SWDPIN(3)); + CSR_WRITE(sc, WMREG_WUC, WUC_APME); + + /* ICH workaround */ + switch (sc->sc_type) { + case WM_T_ICH8: + case WM_T_ICH9: + case WM_T_ICH10: + case WM_T_PCH: + /* Disable gig during WOL */ + reg = CSR_READ(sc, WMREG_PHY_CTRL); + reg |= PHY_CTRL_D0A_LPLU | PHY_CTRL_GBE_DIS; + CSR_WRITE(sc, WMREG_PHY_CTRL, reg); + if (sc->sc_type == WM_T_PCH) + wm_gmii_reset(sc); + + /* Power down workaround */ + if (sc->sc_phytype == WMPHY_82577) { + struct mii_softc *child; + + /* Assume that the PHY is copper */ + child = LIST_FIRST(&sc->sc_mii.mii_phys); + if (child->mii_mpd_rev <= 2) + sc->sc_mii.mii_writereg(sc->sc_dev, 1, + (768 << 5) | 25, 0x0444); /* magic num */ + } + break; + default: + break; + } + + /* Keep the laser running on fiber adapters */ + if (((sc->sc_wmp->wmp_flags & WMP_F_1000X) != 0) + || (sc->sc_wmp->wmp_flags & WMP_F_SERDES) != 0) { + reg = CSR_READ(sc, WMREG_CTRL_EXT); + reg |= CTRL_EXT_SWDPIN(3); + CSR_WRITE(sc, WMREG_CTRL_EXT, reg); + } + + reg = CSR_READ(sc, WMREG_WUFC) | WUFC_MAG; +#if 0 /* for the multicast packet */ + reg |= WUFC_MC; + CSR_WRITE(sc, WMREG_RCTL, CSR_READ(sc, WMREG_RCTL) | RCTL_MPE); +#endif + + if (sc->sc_type == WM_T_PCH) { + wm_enable_phy_wakeup(sc); + } else { + CSR_WRITE(sc, WMREG_WUC, WUC_PME_EN); + CSR_WRITE(sc, WMREG_WUFC, reg); + } + + if (((sc->sc_type == WM_T_ICH8) || (sc->sc_type == WM_T_ICH9) + || (sc->sc_type == WM_T_ICH10) || (sc->sc_type == WM_T_PCH)) + && (sc->sc_phytype == WMPHY_IGP_3)) + wm_igp3_phy_powerdown_workaround_ich8lan(sc); + + /* Request PME */ + pmode = pci_conf_read(sc->sc_pc, sc->sc_pcitag, pmreg + PCI_PMCSR); +#if 0 + /* Disable WOL */ + pmode &= ~(PCI_PMCSR_PME_STS | PCI_PMCSR_PME_EN); +#else + /* For WOL */ + pmode |= PCI_PMCSR_PME_STS | PCI_PMCSR_PME_EN; +#endif + pci_conf_write(sc->sc_pc, sc->sc_pcitag, pmreg + PCI_PMCSR, pmode); +} +#endif /* WM_WOL */ + +static bool +wm_suspend(device_t self, const pmf_qual_t *qual) +{ + struct wm_softc *sc = device_private(self); + + wm_release_manageability(sc); + wm_release_hw_control(sc); +#ifdef WM_WOL + wm_enable_wakeup(sc); +#endif + + return true; +} + +static bool +wm_resume(device_t self, const pmf_qual_t *qual) +{ + struct wm_softc *sc = device_private(self); + + wm_init_manageability(sc); + + return true; +} Index: src/sys/dev/pci/if_wmreg.h diff -u src/sys/dev/pci/if_wmreg.h:1.39 src/sys/dev/pci/if_wmreg.h:1.40 --- src/sys/dev/pci/if_wmreg.h:1.39 Sun Mar 7 07:53:37 2010 +++ src/sys/dev/pci/if_wmreg.h Sun Mar 7 09:05:19 2010 @@ -1,4 +1,4 @@ -/* $NetBSD: if_wmreg.h,v 1.39 2010/03/07 07:53:37 msaitoh Exp $ */ +/* $NetBSD: if_wmreg.h,v 1.40 2010/03/07 09:05:19 msaitoh Exp $ */ /* * Copyright (c) 2001 Wasabi Systems, Inc. @@ -275,9 +275,11 @@ #define EEPROM_OFF_MACADDR 0x00 /* MAC address offset */ #define EEPROM_OFF_CFG1 0x0a /* config word 1 */ #define EEPROM_OFF_CFG2 0x0f /* config word 2 */ +#define EEPROM_OFF_CFG3_PORTB 0x14 /* config word 3 */ #define EEPROM_INIT_3GIO_3 0x1a /* PCIe Initial Configuration Word 3 */ #define EEPROM_OFF_K1_CONFIG 0x1b /* NVM K1 Config */ #define EEPROM_OFF_SWDPIN 0x20 /* SWD Pins (Cordova) */ +#define EEPROM_OFF_CFG3_PORTA 0x24 /* config word 3 */ #define EEPROM_CFG1_LVDID (1U << 0) #define EEPROM_CFG1_LSSID (1U << 1) @@ -294,7 +296,7 @@ #define EEPROM_CFG1_64_32_BAR (1U << 13) #define EEPROM_CFG2_CSR_RD_SPLIT (1U << 1) -#define EEPROM_CFG2_APM_EN (1U << 2) +#define EEPROM_CFG2_82544_APM_EN (1U << 2) #define EEPROM_CFG2_64_BIT (1U << 3) #define EEPROM_CFG2_MAX_READ (1U << 4) #define EEPROM_CFG2_DMCR_MAP (1U << 5) @@ -302,6 +304,7 @@ #define EEPROM_CFG2_MSI_DIS (1U << 7) #define EEPROM_CFG2_FLASH_DIS (1U << 8) #define EEPROM_CFG2_FLASH_SIZE(x) (((x) & 3) >> 9) +#define EEPROM_CFG2_APM_EN (1U << 10) #define EEPROM_CFG2_ANE (1U << 11) #define EEPROM_CFG2_PAUSE(x) (((x) & 3) >> 12) #define EEPROM_CFG2_ASDE (1U << 14) @@ -318,6 +321,8 @@ #define EEPROM_3GIO_3_ASPM_MASK (0x3 << 2) /* Active State PM Support */ +#define EEPROM_CFG3_APME (1U << 10) + #define WMREG_EERD 0x0014 /* EEPROM read */ #define EERD_DONE 0x02 /* done bit */ #define EERD_START 0x01 /* First bit for telling part to start operation */ @@ -778,11 +783,30 @@ #define WMREG_RLPML 0x5004 /* Rx Long Packet Max Length */ #define WMREG_WUC 0x5800 /* Wakeup Control */ +#define WUC_APME 0x00000001 /* APM Enable */ +#define WUC_PME_EN 0x00000002 /* PME Enable */ + +#define WMREG_WUFC 0x5808 /* Wakeup Filter COntrol */ +#define WUFC_MAG 0x00000002 /* Magic Packet Wakeup Enable */ +#define WUFC_EX 0x00000004 /* Directed Exact Wakeup Enable */ +#define WUFC_MC 0x00000008 /* Directed Multicast Wakeup En */ +#define WUFC_BC 0x00000010 /* Broadcast Wakeup Enable */ +#define WUFC_ARP 0x00000020 /* ARP Request Packet Wakeup En */ +#define WUFC_IPV4 0x00000040 /* Directed IPv4 Packet Wakeup En */ +#define WUFC_IPV6 0x00000080 /* Directed IPv6 Packet Wakeup En */ #define WMREG_MANC 0x5820 /* Management Control */ +#define MANC_SMBUS_EN 0x00000001 +#define MANC_ASF_EN 0x00000002 +#define MANC_ARP_EN 0x00002000 +#define MANC_RECV_TCO_EN 0x00020000 #define MANC_BLK_PHY_RST_ON_IDE 0x00040000 +#define MANC_EN_MAC_ADDR_FILTER 0x00100000 +#define MANC_EN_MNG2HOST 0x00200000 #define WMREG_MANC2H 0x5860 /* Manaegment Control To Host - RW */ +#define MANC2H_PORT_623 (1 << 5) +#define MANC2H_PORT_624 (1 << 6) #define WMREG_GCR 0x5b00 /* PCIe Control */ #define GCR_RXD_NO_SNOOP 0x00000001 @@ -795,6 +819,11 @@ #define GCR_CMPL_TMOUT_10MS 0x00001000 #define GCR_CMPL_TMOUT_RESEND 0x00010000 #define GCR_CAP_VER2 0x00040000 + +#define WMREG_FACTPS 0x5b30 /* Function Active and Power State to MNG */ +#define FACTPS_MNGCG 0x20000000 +#define FACTPS_LFS 0x40000000 /* LAN Function Select */ + #define WMREG_GIOCTL 0x5b44 /* GIO Analog Control Register */ #define WMREG_CCMCTL 0x5b48 /* CCM Control Register */ #define WMREG_SCCTL 0x5b4c /* PCIc PLL Configuration Register */ @@ -808,7 +837,7 @@ #define WMREG_FWSM 0x5b54 /* FW Semaphore */ #define FWSM_MODE_MASK 0xe #define FWSM_MODE_SHIFT 0x1 -#define MNG_ICH_IAMT_MODE 0x2 +#define MNG_ICH_IAMT_MODE 0x2 /* PT mode? */ #define MNG_IAMT_MODE 0x3 #define FWSM_RSPCIPHY 0x00000040 /* Reset PHY on PCI reset */ Index: src/sys/dev/pci/if_wmvar.h diff -u src/sys/dev/pci/if_wmvar.h:1.10 src/sys/dev/pci/if_wmvar.h:1.11 --- src/sys/dev/pci/if_wmvar.h:1.10 Thu Feb 25 15:07:06 2010 +++ src/sys/dev/pci/if_wmvar.h Sun Mar 7 09:05:19 2010 @@ -1,4 +1,4 @@ -/* $NetBSD: if_wmvar.h,v 1.10 2010/02/25 15:07:06 msaitoh Exp $ */ +/* $NetBSD: if_wmvar.h,v 1.11 2010/03/07 09:05:19 msaitoh Exp $ */ /* * Copyright (c) 2001, 2002, 2003, 2004 Wasabi Systems, Inc. @@ -72,22 +72,27 @@ #define _DEV_PCI_IF_WMVAR_H_ /* sc_flags */ -#define WM_F_HAS_MII 0x0001 /* has MII */ -#define WM_F_EEPROM_HANDSHAKE 0x0002 /* requires EEPROM handshake */ -#define WM_F_EEPROM_SEMAPHORE 0x0004 /* EEPROM with semaphore */ -#define WM_F_EEPROM_EERDEEWR 0x0008 /* EEPROM access via EERD/EEWR */ -#define WM_F_EEPROM_SPI 0x0010 /* EEPROM is SPI */ -#define WM_F_EEPROM_FLASH 0x0020 /* EEPROM is FLASH */ -#define WM_F_EEPROM_INVALID 0x0040 /* EEPROM not present (bad checksum) */ -#define WM_F_IOH_VALID 0x0080 /* I/O handle is valid */ -#define WM_F_BUS64 0x0100 /* bus is 64-bit */ -#define WM_F_PCIX 0x0200 /* bus is PCI-X */ -#define WM_F_CSA 0x0400 /* bus is CSA */ -#define WM_F_PCIE 0x0800 /* bus is PCI-Express */ -#define WM_F_SWFW_SYNC 0x1000 /* Software-Firmware synchronisation */ -#define WM_F_SWFWHW_SYNC 0x2000 /* Software-Firmware synchronisation */ -#define WM_F_SGMII 0x4000 /* use SGMII */ -#define WM_F_NEWQUEUE 0x8000 /* chips which has the new queue system */ +#define WM_F_HAS_MII 0x00000001 /* has MII */ +#define WM_F_EEPROM_HANDSHAKE 0x00000002 /* requires EEPROM handshake */ +#define WM_F_EEPROM_SEMAPHORE 0x00000004 /* EEPROM with semaphore */ +#define WM_F_EEPROM_EERDEEWR 0x00000008 /* EEPROM access via EERD/EEWR */ +#define WM_F_EEPROM_SPI 0x00000010 /* EEPROM is SPI */ +#define WM_F_EEPROM_FLASH 0x00000020 /* EEPROM is FLASH */ +#define WM_F_EEPROM_INVALID 0x00000040 /* EEPROM not present (bad checksum) */ +#define WM_F_IOH_VALID 0x00000080 /* I/O handle is valid */ +#define WM_F_BUS64 0x00000100 /* bus is 64-bit */ +#define WM_F_PCIX 0x00000200 /* bus is PCI-X */ +#define WM_F_CSA 0x00000400 /* bus is CSA */ +#define WM_F_PCIE 0x00000800 /* bus is PCI-Express */ +#define WM_F_SWFW_SYNC 0x00001000 /* Software-Firmware synchronisation */ +#define WM_F_SWFWHW_SYNC 0x00002000 /* Software-Firmware synchronisation */ +#define WM_F_SGMII 0x00004000 /* use SGMII */ +#define WM_F_NEWQUEUE 0x00008000 /* chips which has the new queue system */ +#define WM_F_ASF_FIRMWARE_PRES 0x00010000 +#define WM_F_ARC_SUBSYS_VALID 0x00020000 +#define WM_F_HAS_AMT 0x00040000 +#define WM_F_HAS_MANAGE 0x00080000 +#define WM_F_WOL 0x00100000 typedef enum { WM_T_unknown = 0,