Index: src/sys/dev/age/if_age.c =================================================================== RCS file: /home/ncvs/src/sys/dev/age/if_age.c,v retrieving revision 1.2.2.6 diff -u -r1.2.2.6 if_age.c --- src/sys/dev/age/if_age.c 12 Jan 2009 04:23:47 -0000 1.2.2.6 +++ src/sys/dev/age/if_age.c 29 Mar 2009 12:04:42 -0000 @@ -106,8 +106,6 @@ static void age_miibus_statchg(device_t); static void age_mediastatus(struct ifnet *, struct ifmediareq *); static int age_mediachange(struct ifnet *); -static int age_read_vpd_word(struct age_softc *, uint32_t, uint32_t, - uint32_t *); static int age_probe(device_t); static void age_get_macaddr(struct age_softc *); static void age_phy_reset(struct age_softc *); @@ -321,29 +319,6 @@ } static int -age_read_vpd_word(struct age_softc *sc, uint32_t vpdc, uint32_t offset, - uint32_t *word) -{ - int i; - - pci_write_config(sc->age_dev, vpdc + PCIR_VPD_ADDR, offset, 2); - for (i = AGE_TIMEOUT; i > 0; i--) { - DELAY(10); - if ((pci_read_config(sc->age_dev, vpdc + PCIR_VPD_ADDR, 2) & - 0x8000) == 0x8000) - break; - } - if (i == 0) { - device_printf(sc->age_dev, "VPD read timeout!\n"); - *word = 0; - return (ETIMEDOUT); - } - - *word = pci_read_config(sc->age_dev, vpdc + PCIR_VPD_DATA, 4); - return (0); -} - -static int age_probe(device_t dev) { struct age_dev *sp; @@ -368,8 +343,8 @@ static void age_get_macaddr(struct age_softc *sc) { - uint32_t ea[2], off, reg, word; - int vpd_error, match, vpdc; + uint32_t ea[2], reg; + int i, vpdc; reg = CSR_READ_4(sc, AGE_SPI_CTRL); if ((reg & SPI_VPD_ENB) != 0) { @@ -378,112 +353,36 @@ CSR_WRITE_4(sc, AGE_SPI_CTRL, reg); } - vpd_error = 0; - ea[0] = ea[1] = 0; - if ((vpd_error = pci_find_extcap(sc->age_dev, PCIY_VPD, &vpdc)) == 0) { + if (pci_find_extcap(sc->age_dev, PCIY_VPD, &vpdc) == 0) { /* - * PCI VPD capability exists, but it seems that it's - * not in the standard form as stated in PCI VPD - * specification such that driver could not use - * pci_get_vpd_readonly(9) with keyword 'NA'. - * Search VPD data starting at address 0x0100. The data - * should be used as initializers to set AGE_PAR0, - * AGE_PAR1 register including other PCI configuration - * registers. + * PCI VPD capability found, let TWSI reload EEPROM. + * This will set ethernet address of controller. */ - word = 0; - match = 0; - reg = 0; - for (off = AGE_VPD_REG_CONF_START; off < AGE_VPD_REG_CONF_END; - off += sizeof(uint32_t)) { - vpd_error = age_read_vpd_word(sc, vpdc, off, &word); - if (vpd_error != 0) - break; - if (match != 0) { - switch (reg) { - case AGE_PAR0: - ea[0] = word; - break; - case AGE_PAR1: - ea[1] = word; - break; - default: - break; - } - match = 0; - } else if ((word & 0xFF) == AGE_VPD_REG_CONF_SIG) { - match = 1; - reg = word >> 16; - } else + CSR_WRITE_4(sc, AGE_TWSI_CTRL, CSR_READ_4(sc, AGE_TWSI_CTRL) | + TWSI_CTRL_SW_LD_START); + for (i = 100; i > 0; i--) { + DELAY(1000); + reg = CSR_READ_4(sc, AGE_TWSI_CTRL); + if ((reg & TWSI_CTRL_SW_LD_START) == 0) break; } - if (off >= AGE_VPD_REG_CONF_END) - vpd_error = ENOENT; - if (vpd_error == 0) { - /* - * Don't blindly trust ethernet address obtained - * from VPD. Check whether ethernet address is - * valid one. Otherwise fall-back to reading - * PAR register. - */ - ea[1] &= 0xFFFF; - if ((ea[0] == 0 && ea[1] == 0) || - (ea[0] == 0xFFFFFFFF && ea[1] == 0xFFFF)) { - if (bootverbose) - device_printf(sc->age_dev, - "invalid ethernet address " - "returned from VPD.\n"); - vpd_error = EINVAL; - } - } - if (vpd_error != 0 && (bootverbose)) - device_printf(sc->age_dev, "VPD access failure!\n"); + if (i == 0) + device_printf(sc->age_dev, + "reloading EEPROM timeout!\n"); } else { if (bootverbose) device_printf(sc->age_dev, "PCI VPD capability not found!\n"); } - /* - * It seems that L1 also provides a way to extract ethernet - * address via SPI flash interface. Because SPI flash memory - * device of different vendors vary in their instruction - * codes for read ID instruction, it's very hard to get - * instructions codes without detailed information for the - * flash memory device used on ethernet controller. To simplify - * code, just read AGE_PAR0/AGE_PAR1 register to get ethernet - * address which is supposed to be set by hardware during - * power on reset. - */ - if (vpd_error != 0) { - /* - * VPD is mapped to SPI flash memory or BIOS set it. - */ - ea[0] = CSR_READ_4(sc, AGE_PAR0); - ea[1] = CSR_READ_4(sc, AGE_PAR1); - } - - ea[1] &= 0xFFFF; - if ((ea[0] == 0 && ea[1] == 0) || - (ea[0] == 0xFFFFFFFF && ea[1] == 0xFFFF)) { - device_printf(sc->age_dev, - "generating fake ethernet address.\n"); - ea[0] = arc4random(); - /* Set OUI to ASUSTek COMPUTER INC. */ - sc->age_eaddr[0] = 0x00; - sc->age_eaddr[1] = 0x1B; - sc->age_eaddr[2] = 0xFC; - sc->age_eaddr[3] = (ea[0] >> 16) & 0xFF; - sc->age_eaddr[4] = (ea[0] >> 8) & 0xFF; - sc->age_eaddr[5] = (ea[0] >> 0) & 0xFF; - } else { - sc->age_eaddr[0] = (ea[1] >> 8) & 0xFF; - sc->age_eaddr[1] = (ea[1] >> 0) & 0xFF; - sc->age_eaddr[2] = (ea[0] >> 24) & 0xFF; - sc->age_eaddr[3] = (ea[0] >> 16) & 0xFF; - sc->age_eaddr[4] = (ea[0] >> 8) & 0xFF; - sc->age_eaddr[5] = (ea[0] >> 0) & 0xFF; - } + ea[0] = CSR_READ_4(sc, AGE_PAR0); + ea[1] = CSR_READ_4(sc, AGE_PAR1); + sc->age_eaddr[0] = (ea[1] >> 8) & 0xFF; + sc->age_eaddr[1] = (ea[1] >> 0) & 0xFF; + sc->age_eaddr[2] = (ea[0] >> 24) & 0xFF; + sc->age_eaddr[3] = (ea[0] >> 16) & 0xFF; + sc->age_eaddr[4] = (ea[0] >> 8) & 0xFF; + sc->age_eaddr[5] = (ea[0] >> 0) & 0xFF; } static void