Module Name: src Committed By: snj Date: Sun May 3 17:51:03 UTC 2009
Modified Files: src/sys/dev/pci [netbsd-5]: if_wm.c if_wmreg.h Log Message: Pull up following revision(s) (requested by spz in ticket #621): sys/dev/pci/if_wm.c: revisions 1.168, 1.169 via patch sys/dev/pci/if_wmreg.h: revision 1.26 via patch On i82563, the em driver says that the ready bit in the MDIC register may be incorrectly set. Insert delay(200) like the em driver. -- Examine the management mode and mark DRV_LOAD (for ICH{8,9,10},80003, 8257{1,2,3,4}). Add some error's printf(). Make the bank detect routine into the function. To generate a diff of this commit: cvs rdiff -u -r1.162.4.3 -r1.162.4.4 src/sys/dev/pci/if_wm.c cvs rdiff -u -r1.24 -r1.24.20.1 src/sys/dev/pci/if_wmreg.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/pci/if_wm.c diff -u src/sys/dev/pci/if_wm.c:1.162.4.3 src/sys/dev/pci/if_wm.c:1.162.4.4 --- src/sys/dev/pci/if_wm.c:1.162.4.3 Fri Mar 20 13:01:35 2009 +++ src/sys/dev/pci/if_wm.c Sun May 3 17:51:02 2009 @@ -1,4 +1,4 @@ -/* $NetBSD: if_wm.c,v 1.162.4.3 2009/03/20 13:01:35 msaitoh Exp $ */ +/* $NetBSD: if_wm.c,v 1.162.4.4 2009/05/03 17:51:02 snj Exp $ */ /* * Copyright (c) 2001, 2002, 2003, 2004 Wasabi Systems, Inc. @@ -79,7 +79,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: if_wm.c,v 1.162.4.3 2009/03/20 13:01:35 msaitoh Exp $"); +__KERNEL_RCSID(0, "$NetBSD: if_wm.c,v 1.162.4.4 2009/05/03 17:51:02 snj Exp $"); #include "bpfilter.h" #include "rnd.h" @@ -581,11 +581,16 @@ static int32_t wm_read_ich8_data(struct wm_softc *, uint32_t, uint32_t, uint16_t *); static int32_t wm_read_ich8_word(struct wm_softc *sc, uint32_t, uint16_t *); +static void wm_82547_txfifo_stall(void *); +static int wm_check_mng_mode(struct wm_softc *); +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 void wm_get_hw_control(struct wm_softc *); CFATTACH_DECL_NEW(wm, sizeof(struct wm_softc), wm_match, wm_attach, NULL, NULL); -static void wm_82547_txfifo_stall(void *); /* * Devices supported by this driver. @@ -1266,6 +1271,17 @@ */ wm_reset(sc); + switch (sc->sc_type) { + case WM_T_82573: + case WM_T_ICH8: + case WM_T_ICH9: + if (wm_check_mng_mode(sc) != 0) + wm_get_hw_control(sc); + break; + default: + break; + } + /* * Get some information about the EEPROM. */ @@ -1328,13 +1344,18 @@ * that no EEPROM is attached. */ - /* * Validate the EEPROM checksum. If the checksum fails, flag this for * later, so we can fail future reads from the EEPROM. */ - if (wm_validate_eeprom_checksum(sc)) - sc->sc_flags |= WM_F_EEPROM_INVALID; + if (wm_validate_eeprom_checksum(sc)) { + /* + * Read twice again because some PCI-e parts fail the first + * check due to the link being in sleep state. + */ + if (wm_validate_eeprom_checksum(sc)) + sc->sc_flags |= WM_F_EEPROM_INVALID; + } if (sc->sc_flags & WM_F_EEPROM_INVALID) aprint_verbose_dev(sc->sc_dev, "No EEPROM\n"); @@ -3048,6 +3069,17 @@ /* Reset the chip to a known state. */ wm_reset(sc); + switch (sc->sc_type) { + case WM_T_82573: + case WM_T_ICH8: + case WM_T_ICH9: + if (wm_check_mng_mode(sc) != 0) + wm_get_hw_control(sc); + break; + default: + break; + } + /* Initialize the transmit descriptor ring. */ memset(sc->sc_txdescs, 0, WM_TXDESCSIZE(sc)); WM_CDTXSYNC(sc, 0, WM_NTXDESC(sc), @@ -3463,8 +3495,11 @@ ret = wm_get_swsm_semaphore(sc); } - if (ret) + if (ret) { + aprint_error_dev(sc->sc_dev, "%s: failed to get semaphore\n", + __func__); return 1; + } if (sc->sc_flags & WM_F_EEPROM_HANDSHAKE) { reg = CSR_READ(sc, WMREG_EECD); @@ -4260,14 +4295,20 @@ int func = 0; /* XXX gcc */ if ((sc->sc_type == WM_T_ICH8) || (sc->sc_type == WM_T_ICH9)) { - if (wm_get_swfwhw_semaphore(sc)) + if (wm_get_swfwhw_semaphore(sc)) { + aprint_error_dev(sc->sc_dev, + "%s: failed to get semaphore\n", __func__); return; + } } if (sc->sc_type == WM_T_80003) { func = (CSR_READ(sc, WMREG_STATUS) >> STATUS_FUNCID_SHIFT) & 1; if (wm_get_swfw_semaphore(sc, - func ? SWFW_PHY1_SM : SWFW_PHY0_SM)) + func ? SWFW_PHY1_SM : SWFW_PHY0_SM)) { + aprint_error_dev(sc->sc_dev, + "%s: failed to get semaphore\n", __func__); return; + } } if (sc->sc_type >= WM_T_82544) { CSR_WRITE(sc, WMREG_CTRL, sc->sc_ctrl | CTRL_PHY_RESET); @@ -4622,8 +4663,11 @@ if (phy != 1) /* only one PHY on kumeran bus */ return 0; - if (wm_get_swfw_semaphore(sc, func ? SWFW_PHY1_SM : SWFW_PHY0_SM)) + if (wm_get_swfw_semaphore(sc, func ? SWFW_PHY1_SM : SWFW_PHY0_SM)) { + aprint_error_dev(sc->sc_dev, "%s: failed to get semaphore\n", + __func__); return 0; + } if ((reg & GG82563_MAX_REG_ADDRESS) < GG82563_MIN_ALT_REG) { wm_gmii_i82544_writereg(self, phy, GG82563_PHY_PAGE_SELECT, @@ -4633,7 +4677,11 @@ reg >> GG82563_PAGE_SHIFT); } + /* Wait more 200us for a bug of the ready bit in the MDIC register */ + delay(200); + rv = wm_gmii_i82544_readreg(self, phy, reg & GG82563_MAX_REG_ADDRESS); + delay(200); wm_put_swfw_semaphore(sc, func ? SWFW_PHY1_SM : SWFW_PHY0_SM); return (rv); } @@ -4654,8 +4702,11 @@ if (phy != 1) /* only one PHY on kumeran bus */ return; - if (wm_get_swfw_semaphore(sc, func ? SWFW_PHY1_SM : SWFW_PHY0_SM)) + if (wm_get_swfw_semaphore(sc, func ? SWFW_PHY1_SM : SWFW_PHY0_SM)) { + aprint_error_dev(sc->sc_dev, "%s: failed to get semaphore\n", + __func__); return; + } if ((reg & GG82563_MAX_REG_ADDRESS) < GG82563_MIN_ALT_REG) { wm_gmii_i82544_writereg(self, phy, GG82563_PHY_PAGE_SELECT, @@ -4665,7 +4716,11 @@ reg >> GG82563_PAGE_SHIFT); } + /* Wait more 200us for a bug of the ready bit in the MDIC register */ + delay(200); + wm_gmii_i82544_writereg(self, phy, reg & GG82563_MAX_REG_ADDRESS, val); + delay(200); wm_put_swfw_semaphore(sc, func ? SWFW_PHY1_SM : SWFW_PHY0_SM); } @@ -4744,8 +4799,11 @@ int func = ((CSR_READ(sc, WMREG_STATUS) >> STATUS_FUNCID_SHIFT) & 1); int rv; - if (wm_get_swfw_semaphore(sc, func ? SWFW_PHY1_SM : SWFW_PHY0_SM)) + if (wm_get_swfw_semaphore(sc, func ? SWFW_PHY1_SM : SWFW_PHY0_SM)) { + aprint_error_dev(sc->sc_dev, "%s: failed to get semaphore\n", + __func__); return 0; + } CSR_WRITE(sc, WMREG_KUMCTRLSTA, ((reg << KUMCTRLSTA_OFFSET_SHIFT) & KUMCTRLSTA_OFFSET) | @@ -4767,8 +4825,11 @@ { int func = ((CSR_READ(sc, WMREG_STATUS) >> STATUS_FUNCID_SHIFT) & 1); - if (wm_get_swfw_semaphore(sc, func ? SWFW_PHY1_SM : SWFW_PHY0_SM)) + if (wm_get_swfw_semaphore(sc, func ? SWFW_PHY1_SM : SWFW_PHY0_SM)) { + aprint_error_dev(sc->sc_dev, "%s: failed to get semaphore\n", + __func__); return; + } CSR_WRITE(sc, WMREG_KUMCTRLSTA, ((reg << KUMCTRLSTA_OFFSET_SHIFT) & KUMCTRLSTA_OFFSET) | @@ -4845,8 +4906,12 @@ for(timeout = 0; timeout < 200; timeout++) { if (sc->sc_flags & WM_F_EEPROM_SEMAPHORE) { - if (wm_get_swsm_semaphore(sc)) + if (wm_get_swsm_semaphore(sc)) { + aprint_error_dev(sc->sc_dev, + "%s: failed to get semaphore\n", + __func__); return 1; + } } swfw_sync = CSR_READ(sc, WMREG_SW_FW_SYNC); if ((swfw_sync & (swmask | fwmask)) == 0) { @@ -4942,15 +5007,21 @@ bank_offset = flash_bank * (sc->sc_ich8_flash_bank_size * 2); error = wm_get_swfwhw_semaphore(sc); - if (error) + if (error) { + aprint_error_dev(sc->sc_dev, "%s: failed to get semaphore\n", + __func__); return error; + } for (i = 0; i < words; i++) { /* The NVM part needs a byte offset, hence * 2 */ act_offset = bank_offset + ((offset + i) * 2); error = wm_read_ich8_word(sc, act_offset, &word); - if (error) + if (error) { + aprint_error_dev(sc->sc_dev, "%s: failed to read NVM\n", + __func__); break; + } data[i] = word; } @@ -5166,3 +5237,88 @@ status = wm_read_ich8_data(sc, index, 2, data); return status; } + +static int +wm_check_mng_mode(struct wm_softc *sc) +{ + int rv; + + switch (sc->sc_type) { + case WM_T_ICH8: + case WM_T_ICH9: + rv = wm_check_mng_mode_ich8lan(sc); + break; + case WM_T_82574: + rv = wm_check_mng_mode_82574(sc); + break; + default: + rv = wm_check_mng_mode_generic(sc); + break; + } + + printf("XXXXXXXXXXXXX mng=%d ===============\n", rv); + return rv; +} + +static int +wm_check_mng_mode_ich8lan(struct wm_softc *sc) +{ + uint32_t fwsm; + + fwsm = CSR_READ(sc, WMREG_FWSM); + + if ((fwsm & FWSM_MODE_MASK) == (MNG_ICH_IAMT_MODE << FWSM_MODE_SHIFT)) + return 1; + + return 0; +} + +static int +wm_check_mng_mode_82574(struct wm_softc *sc) +{ + uint16_t data; + + wm_read_eeprom(sc, NVM_INIT_CONTROL2_REG, 1, &data); + + if ((data & NVM_INIT_CTRL2_MNGM) != 0) + return 1; + + return 0; +} + +static int +wm_check_mng_mode_generic(struct wm_softc *sc) +{ + uint32_t fwsm; + + fwsm = CSR_READ(sc, WMREG_FWSM); + + if ((fwsm & FWSM_MODE_MASK) == (MNG_IAMT_MODE << FWSM_MODE_SHIFT)) + return 1; + + return 0; +} + +static void +wm_get_hw_control(struct wm_softc *sc) +{ + uint32_t reg; + + switch (sc->sc_type) { + case WM_T_82573: + 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_80003: + case WM_T_ICH8: + case WM_T_ICH9: + printf("YYYYYYYYYYYYYY load drv YYYYYYYYYYYYYYY\n"); + reg = CSR_READ(sc, WMREG_CTRL_EXT); + CSR_WRITE(sc, WMREG_CTRL_EXT, reg | CTRL_EXT_DRV_LOAD); + break; + default: + break; + } +} Index: src/sys/dev/pci/if_wmreg.h diff -u src/sys/dev/pci/if_wmreg.h:1.24 src/sys/dev/pci/if_wmreg.h:1.24.20.1 --- src/sys/dev/pci/if_wmreg.h:1.24 Tue Dec 25 18:33:41 2007 +++ src/sys/dev/pci/if_wmreg.h Sun May 3 17:51:02 2009 @@ -1,4 +1,4 @@ -/* $NetBSD: if_wmreg.h,v 1.24 2007/12/25 18:33:41 perry Exp $ */ +/* $NetBSD: if_wmreg.h,v 1.24.20.1 2009/05/03 17:51:02 snj Exp $ */ /* * Copyright (c) 2001 Wasabi Systems, Inc. @@ -334,6 +334,7 @@ #define CTRL_EXT_LINK_MODE_TBI 0x00C00000 #define CTRL_EXT_LINK_MODE_KMRN 0x00000000 #define CTRL_EXT_LINK_MODE_SERDES 0x00C00000 +#define CTRL_EXT_DRV_LOAD 0x10000000 #define WMREG_MDIC 0x0020 /* MDI Control Register */ @@ -664,6 +665,12 @@ #define SWSM_WMNG 0x00000004 /* Wake MNG Clock */ #define SWSM_DRV_LOAD 0x00000008 /* Driver Loaded Bit */ +#define WMREG_FWSM 0x5b54 /* FW Semaphore */ +#define FWSM_MODE_MASK 0xe +#define FWSM_MODE_SHIFT 0x1 +#define MNG_ICH_IAMT_MODE 0x2 +#define MNG_IAMT_MODE 0x3 + #define WMREG_SW_FW_SYNC 0x5b5c /* software-firmware semaphore */ #define SWFW_EEP_SM 0x0001 /* eeprom access */ #define SWFW_PHY0_SM 0x0002 /* first ctrl phy access */ @@ -731,3 +738,6 @@ #define ICH_FLASH_SECTOR_SIZE 4096 #define ICH_GFPREG_BASE_MASK 0x1FFF #define ICH_FLASH_LINEAR_ADDR_MASK 0x00FFFFFF + +#define NVM_INIT_CONTROL2_REG 0x000f +#define NVM_INIT_CTRL2_MNGM 0x6000