Module Name: src Committed By: msaitoh Date: Tue Dec 29 16:01:22 UTC 2009
Modified Files: src/sys/dev/pci: if_wm.c if_wmreg.h if_wmvar.h Log Message: - Fix an incorrect test for WM_F_EEPROM_INALID since rev. 1.183. Some old chips don't set EECD_EE_PRES. - Fix a bug that WM_F_EEPROM_SPI and WM_F_FLASH are set. - Add an missing decrement for a timeout reported by Wolfgang Stukenbrock in PR#42422. - Add support for i82583V. - PBA setting for i82574 is not 12K but 20K. - Enable checking the management mode on 82574. To generate a diff of this commit: cvs rdiff -u -r1.184 -r1.185 src/sys/dev/pci/if_wm.c cvs rdiff -u -r1.28 -r1.29 src/sys/dev/pci/if_wmreg.h cvs rdiff -u -r1.4 -r1.5 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/pci/if_wm.c diff -u src/sys/dev/pci/if_wm.c:1.184 src/sys/dev/pci/if_wm.c:1.185 --- src/sys/dev/pci/if_wm.c:1.184 Sun Dec 27 20:36:38 2009 +++ src/sys/dev/pci/if_wm.c Tue Dec 29 16:01:21 2009 @@ -1,4 +1,4 @@ -/* $NetBSD: if_wm.c,v 1.184 2009/12/27 20:36:38 msaitoh Exp $ */ +/* $NetBSD: if_wm.c,v 1.185 2009/12/29 16:01:21 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.184 2009/12/27 20:36:38 msaitoh Exp $"); +__KERNEL_RCSID(0, "$NetBSD: if_wm.c,v 1.185 2009/12/29 16:01:21 msaitoh Exp $"); #include "bpfilter.h" #include "rnd.h" @@ -530,6 +530,7 @@ static int wm_kmrn_readreg(struct wm_softc *, int); static void wm_kmrn_writereg(struct wm_softc *, int, int); +static void wm_set_spiaddrsize(struct wm_softc *); static int wm_match(device_t, cfdata_t, void *); static void wm_attach(device_t, device_t, void *); static int wm_is_onboard_nvm_eeprom(struct wm_softc *); @@ -547,14 +548,12 @@ static int32_t wm_ich8_flash_cycle(struct wm_softc *, uint32_t); static int32_t wm_read_ich8_data(struct wm_softc *, uint32_t, uint32_t, uint16_t *); -static int32_t wm_read_ich8_byte(struct wm_softc *sc, uint32_t, uint8_t *); -static int32_t wm_read_ich8_word(struct wm_softc *sc, uint32_t, uint16_t *); +static int32_t wm_read_ich8_byte(struct wm_softc *, uint32_t, uint8_t *); +static int32_t wm_read_ich8_word(struct wm_softc *, 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 *); -#if 0 static int wm_check_mng_mode_82574(struct wm_softc *); -#endif static int wm_check_mng_mode_generic(struct wm_softc *); static void wm_get_hw_control(struct wm_softc *); static int wm_check_for_link(struct wm_softc *); @@ -562,7 +561,6 @@ CFATTACH_DECL_NEW(wm, sizeof(struct wm_softc), wm_match, wm_attach, NULL, NULL); - /* * Devices supported by this driver. */ @@ -772,6 +770,10 @@ "Intel i82574L", WM_T_82574, WMP_F_1000T }, + { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82583V, + "Intel i82583V", + WM_T_82583, WMP_F_1000T }, + { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_80K3LAN_CPR_DPT, "i80003 dual 1000baseT Ethernet", WM_T_80003, WMP_F_1000T }, @@ -884,6 +886,16 @@ wa->wa_high = 0; } +static void +wm_set_spiaddrsize(struct wm_softc *sc) +{ + uint32_t reg; + + sc->sc_flags |= WM_F_EEPROM_SPI; + reg = CSR_READ(sc, WMREG_EECD); + sc->sc_ee_addrbits = (reg & EECD_EE_ABITS) ? 16 : 8; +} + static const struct wm_product * wm_lookup(const struct pci_attach_args *pa) { @@ -1214,7 +1226,6 @@ goto fail_3; } - /* * Create the transmit buffer DMA maps. */ @@ -1261,6 +1272,7 @@ case WM_T_82572: case WM_T_82573: case WM_T_82574: + case WM_T_82583: case WM_T_80003: case WM_T_ICH8: case WM_T_ICH9: @@ -1275,10 +1287,75 @@ /* * Get some information about the EEPROM. */ - if ((sc->sc_type == WM_T_ICH8) || (sc->sc_type == WM_T_ICH9) - || (sc->sc_type == WM_T_ICH10)) { - uint32_t flash_size; - sc->sc_flags |= WM_F_SWFWHW_SYNC | WM_F_EEPROM_FLASH; + switch (sc->sc_type) { + case WM_T_82542_2_0: + case WM_T_82542_2_1: + case WM_T_82543: + case WM_T_82544: + /* Microwire */ + sc->sc_ee_addrbits = 6; + break; + case WM_T_82540: + case WM_T_82545: + case WM_T_82545_3: + case WM_T_82546: + case WM_T_82546_3: + /* Microwire */ + reg = CSR_READ(sc, WMREG_EECD); + if (reg & EECD_EE_SIZE) + sc->sc_ee_addrbits = 8; + else + sc->sc_ee_addrbits = 6; + sc->sc_flags |= WM_F_EEPROM_HANDSHAKE; + break; + case WM_T_82541: + case WM_T_82541_2: + case WM_T_82547: + case WM_T_82547_2: + reg = CSR_READ(sc, WMREG_EECD); + if (reg & EECD_EE_TYPE) { + /* SPI */ + wm_set_spiaddrsize(sc); + } else + /* Microwire */ + sc->sc_ee_addrbits = (reg & EECD_EE_ABITS) ? 8 : 6; + sc->sc_flags |= WM_F_EEPROM_HANDSHAKE; + break; + case WM_T_82571: + case WM_T_82572: + /* SPI */ + wm_set_spiaddrsize(sc); + sc->sc_flags |= WM_F_EEPROM_HANDSHAKE; + break; + case WM_T_82573: + case WM_T_82574: + case WM_T_82583: + if (wm_is_onboard_nvm_eeprom(sc) == 0) + sc->sc_flags |= WM_F_EEPROM_FLASH; + else { + /* SPI */ + wm_set_spiaddrsize(sc); + } + sc->sc_flags |= WM_F_EEPROM_EERDEEWR; + break; + case WM_T_80003: + /* SPI */ + wm_set_spiaddrsize(sc); + sc->sc_flags |= WM_F_EEPROM_EERDEEWR | WM_F_SWFW_SYNC; + break; + case WM_T_ICH8: + case WM_T_ICH9: + /* Check whether EEPROM is present or not */ + if ((CSR_READ(sc, WMREG_EECD) & EECD_EE_PRES) == 0) { + /* Not found */ + aprint_error_dev(sc->sc_dev, + "EEPROM PRESENT bit isn't set\n"); + sc->sc_flags |= WM_F_EEPROM_INVALID; + } + /* FALLTHROUGH */ + case WM_T_ICH10: + /* FLASH */ + sc->sc_flags |= WM_F_EEPROM_FLASH | WM_F_SWFWHW_SYNC; memtype = pci_mapreg_type(pa->pa_pc, pa->pa_tag, WM_ICH8_FLASH); if (pci_mapreg_map(pa, WM_ICH8_FLASH, memtype, 0, &sc->sc_flasht, &sc->sc_flashh, NULL, NULL)) { @@ -1286,47 +1363,18 @@ "can't map FLASH registers\n"); return; } - flash_size = ICH8_FLASH_READ32(sc, ICH_FLASH_GFPREG); - sc->sc_ich8_flash_base = (flash_size & ICH_GFPREG_BASE_MASK) * + reg = ICH8_FLASH_READ32(sc, ICH_FLASH_GFPREG); + sc->sc_ich8_flash_base = (reg & ICH_GFPREG_BASE_MASK) * ICH_FLASH_SECTOR_SIZE; sc->sc_ich8_flash_bank_size = - ((flash_size >> 16) & ICH_GFPREG_BASE_MASK) + 1; + ((reg >> 16) & ICH_GFPREG_BASE_MASK) + 1; sc->sc_ich8_flash_bank_size -= - (flash_size & ICH_GFPREG_BASE_MASK); + (reg & ICH_GFPREG_BASE_MASK); sc->sc_ich8_flash_bank_size *= ICH_FLASH_SECTOR_SIZE; sc->sc_ich8_flash_bank_size /= 2 * sizeof(uint16_t); - } else if (sc->sc_type == WM_T_80003) - sc->sc_flags |= WM_F_EEPROM_EERDEEWR | WM_F_SWFW_SYNC; - else if (sc->sc_type == WM_T_82573) - sc->sc_flags |= WM_F_EEPROM_EERDEEWR; - else if (sc->sc_type == WM_T_82574) - sc->sc_flags |= WM_F_EEPROM_EERDEEWR; - else if (sc->sc_type > WM_T_82544) - sc->sc_flags |= WM_F_EEPROM_HANDSHAKE; - - if (sc->sc_type <= WM_T_82544) - sc->sc_ee_addrbits = 6; - else if (sc->sc_type <= WM_T_82546_3) { - reg = CSR_READ(sc, WMREG_EECD); - if (reg & EECD_EE_SIZE) - sc->sc_ee_addrbits = 8; - else - sc->sc_ee_addrbits = 6; - } else if (sc->sc_type <= WM_T_82547_2) { - reg = CSR_READ(sc, WMREG_EECD); - if (reg & EECD_EE_TYPE) { - sc->sc_flags |= WM_F_EEPROM_SPI; - sc->sc_ee_addrbits = (reg & EECD_EE_ABITS) ? 16 : 8; - } else - sc->sc_ee_addrbits = (reg & EECD_EE_ABITS) ? 8 : 6; - } else if ((sc->sc_type == WM_T_82573 || sc->sc_type == WM_T_82574) && - (wm_is_onboard_nvm_eeprom(sc) == 0)) { - sc->sc_flags |= WM_F_EEPROM_FLASH; - } else { - /* Assume everything else is SPI. */ - reg = CSR_READ(sc, WMREG_EECD); - sc->sc_flags |= WM_F_EEPROM_SPI; - sc->sc_ee_addrbits = (reg & EECD_EE_ABITS) ? 16 : 8; + break; + default: + break; } /* @@ -1334,25 +1382,19 @@ * This allows the EEPROM type to be printed correctly in the case * that no EEPROM is attached. */ - - /* Check whether EEPROM is present or not */ - if ((CSR_READ(sc, WMREG_EECD) & EECD_EE_PRES) == 0) { - /* Not found */ - sc->sc_flags |= WM_F_EEPROM_INVALID; - } else { + /* + * 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)) { /* - * Validate the EEPROM checksum. If the checksum fails, flag - * this for later, so we can fail future reads from the EEPROM. + * 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)) { - /* - * 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 (wm_validate_eeprom_checksum(sc)) + sc->sc_flags |= WM_F_EEPROM_INVALID; } + /* Set device properties (macflags) */ prop_dictionary_set_uint32(dict, "macflags", sc->sc_flags); @@ -1505,7 +1547,7 @@ */ if (sc->sc_type == WM_T_ICH8 || sc->sc_type == WM_T_ICH9 || sc->sc_type == WM_T_ICH10 || sc->sc_type == WM_T_82573 - || sc->sc_type == WM_T_82574) { + || sc->sc_type == WM_T_82574 || sc->sc_type == WM_T_82583) { /* STATUS_TBIMODE reserved/reused, can't rely on it */ wm_gmii_mediainit(sc); } else if (sc->sc_type < WM_T_82543 || @@ -1535,7 +1577,7 @@ IFQ_SET_READY(&ifp->if_snd); if (sc->sc_type != WM_T_82573 && sc->sc_type != WM_T_82574 && - sc->sc_type != WM_T_ICH8) + sc->sc_type != WM_T_82583 && sc->sc_type != WM_T_ICH8) sc->sc_ethercom.ec_capabilities |= ETHERCAP_JUMBO_MTU; /* @@ -2928,7 +2970,6 @@ ifp->if_collisions += CSR_READ(sc, WMREG_COLC); ifp->if_ierrors += CSR_READ(sc, WMREG_RXERRC); - if (sc->sc_flags & WM_F_HAS_MII) mii_tick(&sc->sc_mii); else @@ -2971,9 +3012,12 @@ sc->sc_pba = PBA_32K; break; case WM_T_82573: - case WM_T_82574: sc->sc_pba = PBA_12K; break; + case WM_T_82574: + case WM_T_82583: + sc->sc_pba = PBA_20K; + break; case WM_T_ICH8: sc->sc_pba = PBA_8K; CSR_WRITE(sc, WMREG_PBS, PBA_16K); @@ -2995,7 +3039,7 @@ sc->sc_ctrl |= CTRL_GIO_M_DIS; CSR_WRITE(sc, WMREG_CTRL, sc->sc_ctrl); - while (timeout) { + while (timeout--) { if ((CSR_READ(sc, WMREG_STATUS) & STATUS_GIO_M_ENA) == 0) break; delay(100); @@ -3079,6 +3123,7 @@ break; case WM_T_82573: case WM_T_82574: + case WM_T_82583: if (sc->sc_flags & WM_F_EEPROM_FLASH) { delay(10); reg = CSR_READ(sc, WMREG_CTRL_EXT) | CTRL_EXT_EE_RST; @@ -3155,6 +3200,7 @@ case WM_T_82572: case WM_T_82573: case WM_T_82574: + case WM_T_82583: case WM_T_80003: case WM_T_ICH8: case WM_T_ICH9: @@ -3439,7 +3485,7 @@ /* 82573 doesn't support jumbo frame */ if (sc->sc_type != WM_T_82573 && sc->sc_type != WM_T_82574 && - sc->sc_type != WM_T_ICH8) + sc->sc_type != WM_T_82583 && sc->sc_type != WM_T_ICH8) sc->sc_rctl |= RCTL_LPE; if (MCLBYTES == 2048) { @@ -3573,6 +3619,7 @@ case WM_T_82572: case WM_T_82573: case WM_T_82574: + case WM_T_82583: case WM_T_80003: case WM_T_ICH8: case WM_T_ICH9: @@ -3593,7 +3640,8 @@ } /* Phy configuration starts after EECD_AUTO_RD is set */ - if (sc->sc_type == WM_T_82573 || sc->sc_type == WM_T_82574) + if (sc->sc_type == WM_T_82573 || sc->sc_type == WM_T_82574 + || sc->sc_type == WM_T_82574) delay(25000); } @@ -5115,16 +5163,16 @@ { uint32_t eecd = 0; - if (sc->sc_type == WM_T_82573 || sc->sc_type == WM_T_82574) { + if (sc->sc_type == WM_T_82573 || sc->sc_type == WM_T_82574 + || sc->sc_type == WM_T_82583) { eecd = CSR_READ(sc, WMREG_EECD); /* Isolate bits 15 & 16 */ eecd = ((eecd >> 15) & 0x03); /* If both bits are set, device is Flash type */ - if (eecd == 0x03) { + if (eecd == 0x03) return 0; - } } return 1; } @@ -5554,15 +5602,10 @@ case WM_T_ICH10: rv = wm_check_mng_mode_ich8lan(sc); break; -#if 0 case WM_T_82574: - /* - * The function is provided in em driver, but it's not - * used. Why? - */ + case WM_T_82583: rv = wm_check_mng_mode_82574(sc); break; -#endif case WM_T_82571: case WM_T_82572: case WM_T_82573: @@ -5591,7 +5634,6 @@ return 0; } -#if 0 static int wm_check_mng_mode_82574(struct wm_softc *sc) { @@ -5604,7 +5646,6 @@ return 0; } -#endif static int wm_check_mng_mode_generic(struct wm_softc *sc) @@ -5628,6 +5669,7 @@ 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? Index: src/sys/dev/pci/if_wmreg.h diff -u src/sys/dev/pci/if_wmreg.h:1.28 src/sys/dev/pci/if_wmreg.h:1.29 --- src/sys/dev/pci/if_wmreg.h:1.28 Tue Jul 14 00:00:44 2009 +++ src/sys/dev/pci/if_wmreg.h Tue Dec 29 16:01:21 2009 @@ -1,4 +1,4 @@ -/* $NetBSD: if_wmreg.h,v 1.28 2009/07/14 00:00:44 msaitoh Exp $ */ +/* $NetBSD: if_wmreg.h,v 1.29 2009/12/29 16:01:21 msaitoh Exp $ */ /* * Copyright (c) 2001 Wasabi Systems, Inc. @@ -598,6 +598,7 @@ #define PBA_10K 0x000a #define PBA_12K 0x000c #define PBA_16K 0x0010 /* 16K, default Tx allocation */ +#define PBA_20K 0x0014 #define PBA_22K 0x0016 #define PBA_24K 0x0018 #define PBA_30K 0x001e Index: src/sys/dev/pci/if_wmvar.h diff -u src/sys/dev/pci/if_wmvar.h:1.4 src/sys/dev/pci/if_wmvar.h:1.5 --- src/sys/dev/pci/if_wmvar.h:1.4 Wed Dec 16 14:37:26 2009 +++ src/sys/dev/pci/if_wmvar.h Tue Dec 29 16:01:21 2009 @@ -1,4 +1,4 @@ -/* $NetBSD: if_wmvar.h,v 1.4 2009/12/16 14:37:26 msaitoh Exp $ */ +/* $NetBSD: if_wmvar.h,v 1.5 2009/12/29 16:01:21 msaitoh Exp $ */ /* * Copyright (c) 2001, 2002, 2003, 2004 Wasabi Systems, Inc. @@ -106,6 +106,7 @@ WM_T_82572, /* i82572 */ WM_T_82573, /* i82573 */ WM_T_82574, /* i82574 */ + WM_T_82583, /* i82583 */ WM_T_80003, /* i80003 */ WM_T_ICH8, /* ICH8 LAN */ WM_T_ICH9, /* ICH9 LAN */