diff --git a/src/add-ons/kernel/drivers/network/broadcom570x/dev/bge/if_bge.c b/src/add-ons/kernel/drivers/network/broadcom570x/dev/bge/if_bge.c index 928bd0fe50..9fdbcc6954 100644 --- a/src/add-ons/kernel/drivers/network/broadcom570x/dev/bge/if_bge.c +++ b/src/add-ons/kernel/drivers/network/broadcom570x/dev/bge/if_bge.c @@ -32,7 +32,7 @@ */ #include -__FBSDID("$FreeBSD: src/sys/dev/bge/if_bge.c,v 1.198 2007/09/30 11:05:14 marius Exp $"); +__FBSDID("$FreeBSD: src/sys/dev/bge/if_bge.c,v 1.215 2008/10/27 22:10:01 marius Exp $"); /* * Broadcom BCM570x family gigabit ethernet driver for FreeBSD. @@ -134,7 +134,7 @@ MODULE_DEPEND(bge, miibus, 1, 1, 1); * ID burned into it, though it will always be overriden by the vendor * ID in the EEPROM. Just to be safe, we cover all possibilities. */ -static struct bge_type { +static const struct bge_type { uint16_t bge_vid; uint16_t bge_did; } bge_devs[] = { @@ -169,6 +169,7 @@ static struct bge_type { { BCOM_VENDORID, BCOM_DEVICEID_BCM5715S }, { BCOM_VENDORID, BCOM_DEVICEID_BCM5720 }, { BCOM_VENDORID, BCOM_DEVICEID_BCM5721 }, + { BCOM_VENDORID, BCOM_DEVICEID_BCM5722 }, { BCOM_VENDORID, BCOM_DEVICEID_BCM5750 }, { BCOM_VENDORID, BCOM_DEVICEID_BCM5750M }, { BCOM_VENDORID, BCOM_DEVICEID_BCM5751 }, @@ -195,6 +196,8 @@ static struct bge_type { { BCOM_VENDORID, BCOM_DEVICEID_BCM5901 }, { BCOM_VENDORID, BCOM_DEVICEID_BCM5901A2 }, { BCOM_VENDORID, BCOM_DEVICEID_BCM5903M }, + { BCOM_VENDORID, BCOM_DEVICEID_BCM5906 }, + { BCOM_VENDORID, BCOM_DEVICEID_BCM5906M }, { SK_VENDORID, SK_DEVICEID_ALTIMA }, @@ -267,10 +270,13 @@ static const struct bge_revision { { BGE_CHIPID_BCM5755_A0, "BCM5755 A0" }, { BGE_CHIPID_BCM5755_A1, "BCM5755 A1" }, { BGE_CHIPID_BCM5755_A2, "BCM5755 A2" }, + { BGE_CHIPID_BCM5722_A0, "BCM5722 A0" }, /* 5754 and 5787 share the same ASIC ID */ { BGE_CHIPID_BCM5787_A0, "BCM5754/5787 A0" }, { BGE_CHIPID_BCM5787_A1, "BCM5754/5787 A1" }, { BGE_CHIPID_BCM5787_A2, "BCM5754/5787 A2" }, + { BGE_CHIPID_BCM5906_A1, "BCM5906 A1" }, + { BGE_CHIPID_BCM5906_A2, "BCM5906 A2" }, { 0, NULL } }; @@ -293,6 +299,7 @@ static const struct bge_revision bge_majorrevs[] = { { BGE_ASICREV_BCM5755, "unknown BCM5755" }, /* 5754 and 5787 share the same ASIC ID */ { BGE_ASICREV_BCM5787, "unknown BCM5754/5787" }, + { BGE_ASICREV_BCM5906, "unknown BCM5906" }, { 0, NULL } }; @@ -305,6 +312,9 @@ static const struct bge_revision bge_majorrevs[] = { const struct bge_revision * bge_lookup_rev(uint32_t); const struct bge_vendor * bge_lookup_vendor(uint16_t); + +typedef int (*bge_eaddr_fcn_t)(struct bge_softc *, uint8_t[]); + static int bge_probe(device_t); static int bge_attach(device_t); static int bge_detach(device_t); @@ -315,6 +325,12 @@ static void bge_dma_map_addr(void *, bus_dma_segment_t *, int, int); static int bge_dma_alloc(device_t); static void bge_dma_free(struct bge_softc *); +static int bge_get_eaddr_fw(struct bge_softc *sc, uint8_t ether_addr[]); +static int bge_get_eaddr_mem(struct bge_softc *, uint8_t[]); +static int bge_get_eaddr_nvram(struct bge_softc *, uint8_t[]); +static int bge_get_eaddr_eeprom(struct bge_softc *, uint8_t[]); +static int bge_get_eaddr(struct bge_softc *, uint8_t[]); + static void bge_txeof(struct bge_softc *); static void bge_rxeof(struct bge_softc *); @@ -337,6 +353,9 @@ static int bge_ifmedia_upd_locked(struct ifnet *); static int bge_ifmedia_upd(struct ifnet *); static void bge_ifmedia_sts(struct ifnet *, struct ifmediareq *); +static uint8_t bge_nvram_getbyte(struct bge_softc *, int, uint8_t *); +static int bge_read_nvram(struct bge_softc *, caddr_t, int, int); + static uint8_t bge_eeprom_getbyte(struct bge_softc *, int, uint8_t *); static int bge_read_eeprom(struct bge_softc *, caddr_t, int, int); @@ -356,9 +375,10 @@ static int bge_init_tx_ring(struct bge_softc *); static int bge_chipinit(struct bge_softc *); static int bge_blockinit(struct bge_softc *); -static int bge_has_eeprom(struct bge_softc *); +static int bge_has_eaddr(struct bge_softc *); static uint32_t bge_readmem_ind(struct bge_softc *, int); static void bge_writemem_ind(struct bge_softc *, int, int); +static void bge_writembx(struct bge_softc *, int, int); #ifdef notdef static uint32_t bge_readreg_ind(struct bge_softc *, int); #endif @@ -440,7 +460,7 @@ SYSCTL_INT(_hw_bge, OID_AUTO, allow_asf, CTLFLAG_RD, &bge_allow_asf, 0, #define SPARC64_OFW_SUBVENDOR "subsystem-vendor-id" static int -bge_has_eeprom(struct bge_softc *sc) +bge_has_eaddr(struct bge_softc *sc) { #ifdef __sparc64__ char buf[sizeof(SPARC64_BLADE_1500_PATH_BGE)]; @@ -452,7 +472,7 @@ bge_has_eeprom(struct bge_softc *sc) /* * The on-board BGEs found in sun4u machines aren't fitted with * an EEPROM which means that we have to obtain the MAC address - * via OFW and that some tests will always fail. We distinguish + * via OFW and that some tests will always fail. We distinguish * such BGEs by the subvendor ID, which also has to be obtained * from OFW instead of the PCI configuration space as the latter * indicates Broadcom as the subvendor of the netboot interface. @@ -533,6 +553,15 @@ bge_writemem_direct(struct bge_softc *sc, int off, int val) CSR_WRITE_4(sc, off, val); } +static void +bge_writembx(struct bge_softc *sc, int off, int val) +{ + if (sc->bge_asicrev == BGE_ASICREV_BCM5906) + off += BGE_LPMBX_IRQ0_HI - BGE_MBX_IRQ0_HI; + + CSR_WRITE_4(sc, off, val); +} + /* * Map a single buffer address. */ @@ -555,6 +584,78 @@ bge_dma_map_addr(void *arg, bus_dma_segment_t *segs, int nseg, int error) ctx->bge_busaddr = segs->ds_addr; } +static uint8_t +bge_nvram_getbyte(struct bge_softc *sc, int addr, uint8_t *dest) +{ + uint32_t access, byte = 0; + int i; + + /* Lock. */ + CSR_WRITE_4(sc, BGE_NVRAM_SWARB, BGE_NVRAMSWARB_SET1); + for (i = 0; i < 8000; i++) { + if (CSR_READ_4(sc, BGE_NVRAM_SWARB) & BGE_NVRAMSWARB_GNT1) + break; + DELAY(20); + } + if (i == 8000) + return (1); + + /* Enable access. */ + access = CSR_READ_4(sc, BGE_NVRAM_ACCESS); + CSR_WRITE_4(sc, BGE_NVRAM_ACCESS, access | BGE_NVRAMACC_ENABLE); + + CSR_WRITE_4(sc, BGE_NVRAM_ADDR, addr & 0xfffffffc); + CSR_WRITE_4(sc, BGE_NVRAM_CMD, BGE_NVRAM_READCMD); + for (i = 0; i < BGE_TIMEOUT * 10; i++) { + DELAY(10); + if (CSR_READ_4(sc, BGE_NVRAM_CMD) & BGE_NVRAMCMD_DONE) { + DELAY(10); + break; + } + } + + if (i == BGE_TIMEOUT * 10) { + if_printf(sc->bge_ifp, "nvram read timed out\n"); + return (1); + } + + /* Get result. */ + byte = CSR_READ_4(sc, BGE_NVRAM_RDDATA); + + *dest = (bswap32(byte) >> ((addr % 4) * 8)) & 0xFF; + + /* Disable access. */ + CSR_WRITE_4(sc, BGE_NVRAM_ACCESS, access); + + /* Unlock. */ + CSR_WRITE_4(sc, BGE_NVRAM_SWARB, BGE_NVRAMSWARB_CLR1); + CSR_READ_4(sc, BGE_NVRAM_SWARB); + + return (0); +} + +/* + * Read a sequence of bytes from NVRAM. + */ +static int +bge_read_nvram(struct bge_softc *sc, caddr_t dest, int off, int cnt) +{ + int err = 0, i; + uint8_t byte = 0; + + if (sc->bge_asicrev != BGE_ASICREV_BCM5906) + return (1); + + for (i = 0; i < cnt; i++) { + err = bge_nvram_getbyte(sc, off + i, &byte); + if (err) + break; + *(dest + i) = byte; + } + + return (err ? 1 : 0); +} + /* * Read a byte of data stored in the EEPROM at address 'addr.' The * BCM570x supports both the traditional bitbang interface and an @@ -659,11 +760,14 @@ bge_miibus_readreg(device_t dev, int phy, int reg) } if (i == BGE_TIMEOUT) { - device_printf(sc->bge_dev, "PHY read timed out\n"); + device_printf(sc->bge_dev, + "PHY read timed out (phy %d, reg %d, val 0x%08x)\n", + phy, reg, val); val = 0; goto done; } + DELAY(5); val = CSR_READ_4(sc, BGE_MI_COMM); done: @@ -687,6 +791,10 @@ bge_miibus_writereg(device_t dev, int phy, int reg, int val) sc = device_get_softc(dev); + if (sc->bge_asicrev == BGE_ASICREV_BCM5906 && + (reg == BRGPHY_MII_1000CTL || reg == BRGPHY_MII_AUXCTL)) + return(0); + /* Reading with autopolling on may trigger PCI errors */ autopoll = CSR_READ_4(sc, BGE_MI_MODE); if (autopoll & BGE_MIMODE_AUTOPOLL) { @@ -699,12 +807,17 @@ bge_miibus_writereg(device_t dev, int phy, int reg, int val) for (i = 0; i < BGE_TIMEOUT; i++) { DELAY(10); - if (!(CSR_READ_4(sc, BGE_MI_COMM) & BGE_MICOMM_BUSY)) + if (!(CSR_READ_4(sc, BGE_MI_COMM) & BGE_MICOMM_BUSY)) { + DELAY(5); + CSR_READ_4(sc, BGE_MI_COMM); /* dummy read */ break; + } } if (i == BGE_TIMEOUT) { - device_printf(sc->bge_dev, "PHY write timed out\n"); + device_printf(sc->bge_dev, + "PHY write timed out (phy %d, reg %d, val %d)\n", + phy, reg, val); return (0); } @@ -887,7 +1000,7 @@ bge_init_rx_ring_std(struct bge_softc *sc) BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); sc->bge_std = i - 1; - CSR_WRITE_4(sc, BGE_MBX_RX_STD_PROD_LO, sc->bge_std); + bge_writembx(sc, BGE_MBX_RX_STD_PROD_LO, sc->bge_std); return (0); } @@ -934,7 +1047,7 @@ bge_init_rx_ring_jumbo(struct bge_softc *sc) BGE_RCB_FLAG_USE_EXT_RX_BD); CSR_WRITE_4(sc, BGE_RX_JUMBO_RCB_MAXLEN_FLAGS, rcb->bge_maxlen_flags); - CSR_WRITE_4(sc, BGE_MBX_RX_JUMBO_PROD_LO, sc->bge_jumbo); + bge_writembx(sc, BGE_MBX_RX_JUMBO_PROD_LO, sc->bge_jumbo); return (0); } @@ -990,17 +1103,17 @@ bge_init_tx_ring(struct bge_softc *sc) /* Initialize transmit producer index for host-memory send ring. */ sc->bge_tx_prodidx = 0; - CSR_WRITE_4(sc, BGE_MBX_TX_HOST_PROD0_LO, sc->bge_tx_prodidx); + bge_writembx(sc, BGE_MBX_TX_HOST_PROD0_LO, sc->bge_tx_prodidx); /* 5700 b2 errata */ if (sc->bge_chiprev == BGE_CHIPREV_5700_BX) - CSR_WRITE_4(sc, BGE_MBX_TX_HOST_PROD0_LO, sc->bge_tx_prodidx); + bge_writembx(sc, BGE_MBX_TX_HOST_PROD0_LO, sc->bge_tx_prodidx); /* NIC-memory send ring not used; initialize to zero. */ - CSR_WRITE_4(sc, BGE_MBX_TX_NIC_PROD0_LO, 0); + bge_writembx(sc, BGE_MBX_TX_NIC_PROD0_LO, 0); /* 5700 b2 errata */ if (sc->bge_chiprev == BGE_CHIPREV_5700_BX) - CSR_WRITE_4(sc, BGE_MBX_TX_NIC_PROD0_LO, 0); + bge_writembx(sc, BGE_MBX_TX_NIC_PROD0_LO, 0); return (0); } @@ -1168,10 +1281,10 @@ bge_chipinit(struct bge_softc *sc) /* * Check the 'ROM failed' bit on the RX CPU to see if * self-tests passed. Skip this check when there's no - * EEPROM fitted, since in that case it will always - * fail. + * chip containing the Ethernet address fitted, since + * in that case it will always fail. */ - if ((sc->bge_flags & BGE_FLAG_EEPROM) && + if ((sc->bge_flags & BGE_FLAG_EADDR) && CSR_READ_4(sc, BGE_RXCPU_MODE) & BGE_RXCPUMODE_ROMFAIL) { device_printf(sc->bge_dev, "RX CPU self-diagnostics failed!\n"); return (ENODEV); @@ -1271,6 +1384,16 @@ bge_chipinit(struct bge_softc *sc) /* Set the timer prescaler (always 66Mhz) */ CSR_WRITE_4(sc, BGE_MISC_CFG, BGE_32BITTIME_66MHZ); + /* XXX: The Linux tg3 driver does this at the start of brgphy_reset. */ + if (sc->bge_asicrev == BGE_ASICREV_BCM5906) { + DELAY(40); /* XXX */ + + /* Put PHY into ready state */ + BGE_CLRBIT(sc, BGE_MISC_CFG, BGE_MISCCFG_EPHY_IDDQ); + CSR_READ_4(sc, BGE_MISC_CFG); /* Flush */ + DELAY(40); + } + return (0); } @@ -1308,14 +1431,19 @@ bge_blockinit(struct bge_softc *sc) } /* Configure mbuf pool watermarks */ - if (!(BGE_IS_5705_PLUS(sc))) { - CSR_WRITE_4(sc, BGE_BMAN_MBUFPOOL_READDMA_LOWAT, 0x0); - CSR_WRITE_4(sc, BGE_BMAN_MBUFPOOL_MACRX_LOWAT, 0x10); - } else { + if (!BGE_IS_5705_PLUS(sc)) { CSR_WRITE_4(sc, BGE_BMAN_MBUFPOOL_READDMA_LOWAT, 0x50); CSR_WRITE_4(sc, BGE_BMAN_MBUFPOOL_MACRX_LOWAT, 0x20); + CSR_WRITE_4(sc, BGE_BMAN_MBUFPOOL_HIWAT, 0x60); + } else if (sc->bge_asicrev == BGE_ASICREV_BCM5906) { + CSR_WRITE_4(sc, BGE_BMAN_MBUFPOOL_READDMA_LOWAT, 0x0); + CSR_WRITE_4(sc, BGE_BMAN_MBUFPOOL_MACRX_LOWAT, 0x04); + CSR_WRITE_4(sc, BGE_BMAN_MBUFPOOL_HIWAT, 0x10); + } else { + CSR_WRITE_4(sc, BGE_BMAN_MBUFPOOL_READDMA_LOWAT, 0x0); + CSR_WRITE_4(sc, BGE_BMAN_MBUFPOOL_MACRX_LOWAT, 0x10); + CSR_WRITE_4(sc, BGE_BMAN_MBUFPOOL_HIWAT, 0x60); } - CSR_WRITE_4(sc, BGE_BMAN_MBUFPOOL_HIWAT, 0x60); /* Configure DMA resource watermarks */ CSR_WRITE_4(sc, BGE_BMAN_DMA_DESCPOOL_LOWAT, 5); @@ -1421,6 +1549,9 @@ bge_blockinit(struct bge_softc *sc) * requirement of all 575x family chips. The Linux driver sets * the lower threshold for all 5705 family chips as well, but there * are reports that it might not need to be so strict. + * + * XXX Linux does some extra fiddling here for the 5906 parts as + * well. */ if (BGE_IS_5705_PLUS(sc)) val = 8; @@ -1462,15 +1593,15 @@ bge_blockinit(struct bge_softc *sc) BGE_RCB_MAXLEN_FLAGS(sc->bge_return_ring_cnt, BGE_RCB_FLAG_RING_DISABLED)); RCB_WRITE_4(sc, vrcb, bge_nicaddr, 0); - CSR_WRITE_4(sc, BGE_MBX_RX_CONS0_LO + + bge_writembx(sc, BGE_MBX_RX_CONS0_LO + (i * (sizeof(uint64_t))), 0); vrcb += sizeof(struct bge_rcb); } /* Initialize RX ring indexes */ - CSR_WRITE_4(sc, BGE_MBX_RX_STD_PROD_LO, 0); - CSR_WRITE_4(sc, BGE_MBX_RX_JUMBO_PROD_LO, 0); - CSR_WRITE_4(sc, BGE_MBX_RX_MINI_PROD_LO, 0); + bge_writembx(sc, BGE_MBX_RX_STD_PROD_LO, 0); + bge_writembx(sc, BGE_MBX_RX_JUMBO_PROD_LO, 0); + bge_writembx(sc, BGE_MBX_RX_MINI_PROD_LO, 0); /* * Set up RX return ring 0 @@ -1720,7 +1851,7 @@ bge_lookup_vendor(uint16_t vid) static int bge_probe(device_t dev) { - struct bge_type *t = bge_devs; + const struct bge_type *t = bge_devs; struct bge_softc *sc = device_get_softc(dev); uint16_t vid, did; @@ -1742,7 +1873,8 @@ bge_probe(device_t dev) #if __FreeBSD_version > 700024 const char *pname; - if (pci_get_vpd_ident(dev, &pname) == 0) + if (bge_has_eaddr(sc) && + pci_get_vpd_ident(dev, &pname) == 0) snprintf(model, 64, "%s", pname); else #endif @@ -1892,16 +2024,10 @@ bge_dma_alloc(device_t dev) /* * Allocate the parent bus DMA tag appropriate for PCI. */ - error = bus_dma_tag_create(bus_get_dma_tag(sc->bge_dev), /* parent */ - 1, 0, /* alignment, boundary */ - BUS_SPACE_MAXADDR, /* lowaddr */ - BUS_SPACE_MAXADDR, /* highaddr */ - NULL, NULL, /* filter, filterarg */ - MAXBSIZE, BGE_NSEG_NEW, /* maxsize, nsegments */ - BUS_SPACE_MAXSIZE_32BIT, /* maxsegsize */ - 0, /* flags */ - NULL, NULL, /* lockfunc, lockarg */ - &sc->bge_cdata.bge_parent_tag); + error = bus_dma_tag_create(bus_get_dma_tag(sc->bge_dev), + 1, 0, BUS_SPACE_MAXADDR, BUS_SPACE_MAXADDR, NULL, + NULL, BUS_SPACE_MAXSIZE_32BIT, 0, BUS_SPACE_MAXSIZE_32BIT, + 0, NULL, NULL, &sc->bge_cdata.bge_parent_tag); if (error != 0) { device_printf(sc->bge_dev, @@ -1910,7 +2036,7 @@ bge_dma_alloc(device_t dev) } /* - * Create tag for RX mbufs. + * Create tag for mbufs. */ error = bus_dma_tag_create(sc->bge_cdata.bge_parent_tag, 1, 0, BUS_SPACE_MAXADDR, BUS_SPACE_MAXADDR, NULL, @@ -2202,10 +2328,11 @@ bge_can_use_msi(struct bge_softc *sc) int can_use_msi = 0; switch (sc->bge_asicrev) { + case BGE_ASICREV_BCM5714_A0: case BGE_ASICREV_BCM5714: /* - * Apparently, MSI doesn't work when this chip is configured - * in single-port mode. + * Apparently, MSI doesn't work when these chips are + * configured in single-port mode. */ if (bge_has_multiple_ports(sc)) can_use_msi = 1; @@ -2215,10 +2342,9 @@ bge_can_use_msi(struct bge_softc *sc) sc->bge_chiprev != BGE_CHIPREV_5750_BX) can_use_msi = 1; break; - case BGE_ASICREV_BCM5752: - case BGE_ASICREV_BCM5780: - can_use_msi = 1; - break; + default: + if (BGE_IS_575X_PLUS(sc)) + can_use_msi = 1; } return (can_use_msi); } @@ -2229,8 +2355,7 @@ bge_attach(device_t dev) { struct ifnet *ifp; struct bge_softc *sc; - uint32_t hwcfg = 0; - uint32_t mac_tmp = 0; + uint32_t hwcfg = 0, misccfg; u_char eaddr[ETHER_ADDR_LEN]; int error, reg, rid, trys; @@ -2244,7 +2369,7 @@ bge_attach(device_t dev) rid = BGE_PCI_BAR0; sc->bge_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, - RF_ACTIVE | PCI_RF_DENSE); + RF_ACTIVE); if (sc->bge_res == NULL) { device_printf (sc->bge_dev, "couldn't map memory\n"); @@ -2252,19 +2377,25 @@ bge_attach(device_t dev) goto fail; } - sc->bge_btag = rman_get_bustag(sc->bge_res); - sc->bge_bhandle = rman_get_bushandle(sc->bge_res); - /* Save ASIC rev. */ - sc->bge_chipid = pci_read_config(dev, BGE_PCI_MISC_CTL, 4) & BGE_PCIMISCCTL_ASICREV; sc->bge_asicrev = BGE_ASICREV(sc->bge_chipid); sc->bge_chiprev = BGE_CHIPREV(sc->bge_chipid); - if (bge_has_eeprom(sc)) - sc->bge_flags |= BGE_FLAG_EEPROM; + /* + * Don't enable Ethernet@WireSpeed for the 5700, 5906, or the + * 5705 A0 and A1 chips. + */ + if (sc->bge_asicrev != BGE_ASICREV_BCM5700 && + sc->bge_asicrev != BGE_ASICREV_BCM5906 && + sc->bge_chipid != BGE_CHIPID_BCM5705_A0 && + sc->bge_chipid != BGE_CHIPID_BCM5705_A1) + sc->bge_flags |= BGE_FLAG_WIRESPEED; + + if (bge_has_eaddr(sc)) + sc->bge_flags |= BGE_FLAG_EADDR; /* Save chipset family. */ switch (sc->bge_asicrev) { @@ -2283,6 +2414,7 @@ bge_attach(device_t dev) case BGE_ASICREV_BCM5752: case BGE_ASICREV_BCM5755: case BGE_ASICREV_BCM5787: + case BGE_ASICREV_BCM5906: sc->bge_flags |= BGE_FLAG_575X_PLUS; /* FALLTHRU */ case BGE_ASICREV_BCM5705: @@ -2302,12 +2434,23 @@ bge_attach(device_t dev) if (BGE_IS_5705_PLUS(sc) && !(sc->bge_flags & BGE_FLAG_ADJUST_TRIM)) { if (sc->bge_asicrev == BGE_ASICREV_BCM5755 || - sc->bge_asicrev == BGE_ASICREV_BCM5787) - sc->bge_flags |= BGE_FLAG_JITTER_BUG; - else + sc->bge_asicrev == BGE_ASICREV_BCM5787) { + if (sc->bge_chipid != BGE_CHIPID_BCM5722_A0) + sc->bge_flags |= BGE_FLAG_JITTER_BUG; + } else if (sc->bge_asicrev != BGE_ASICREV_BCM5906) sc->bge_flags |= BGE_FLAG_BER_BUG; } + + /* + * We could possibly check for BCOM_DEVICEID_BCM5788 in bge_probe() + * but I do not know the DEVICEID for the 5788M. + */ + misccfg = CSR_READ_4(sc, BGE_MISC_CFG) & BGE_MISCCFG_BOARD_ID; + if (misccfg == BGE_MISCCFG_BOARD_ID_5788 || + misccfg == BGE_MISCCFG_BOARD_ID_5788M) + sc->bge_flags |= BGE_FLAG_5788; + /* * Check if this is a PCI-X or PCI Express device. */ @@ -2414,28 +2557,12 @@ bge_attach(device_t dev) goto fail; } -#ifdef __sparc64__ - if ((sc->bge_flags & BGE_FLAG_EEPROM) == 0) - OF_getetheraddr(dev, eaddr); - else -#endif - { - mac_tmp = bge_readmem_ind(sc, 0x0C14); - if ((mac_tmp >> 16) == 0x484B) { - eaddr[0] = (u_char)(mac_tmp >> 8); - eaddr[1] = (u_char)mac_tmp; - mac_tmp = bge_readmem_ind(sc, 0x0C18); - eaddr[2] = (u_char)(mac_tmp >> 24); - eaddr[3] = (u_char)(mac_tmp >> 16); - eaddr[4] = (u_char)(mac_tmp >> 8); - eaddr[5] = (u_char)mac_tmp; - } else if (bge_read_eeprom(sc, eaddr, - BGE_EE_MAC_OFFSET + 2, ETHER_ADDR_LEN)) { - device_printf(sc->bge_dev, - "failed to read station address\n"); - error = ENXIO; - goto fail; - } + error = bge_get_eaddr(sc, eaddr); + if (error) { + device_printf(sc->bge_dev, + "failed to read station address\n"); + error = ENXIO; + goto fail; } /* 5705 limits RX return ring to 512 entries. */ @@ -2507,7 +2634,8 @@ bge_attach(device_t dev) */ if (bge_readmem_ind(sc, BGE_SOFTWARE_GENCOMM_SIG) == BGE_MAGIC_NUMBER) hwcfg = bge_readmem_ind(sc, BGE_SOFTWARE_GENCOMM_NICCFG); - else if (sc->bge_flags & BGE_FLAG_EEPROM) { + else if ((sc->bge_flags & BGE_FLAG_EADDR) && + (sc->bge_asicrev != BGE_ASICREV_BCM5906)) { if (bge_read_eeprom(sc, (caddr_t)&hwcfg, BGE_EE_HWCFG_OFFSET, sizeof(hwcfg))) { device_printf(sc->bge_dev, "failed to read EEPROM\n"); @@ -2682,13 +2810,14 @@ static int bge_reset(struct bge_softc *sc) { device_t dev; - uint32_t cachesize, command, pcistate, reset; + uint32_t cachesize, command, pcistate, reset, val; void (*write_op)(struct bge_softc *, int, int); - int i, val = 0; + int i; dev = sc->bge_dev; - if (BGE_IS_575X_PLUS(sc) && !BGE_IS_5714_FAMILY(sc)) { + if (BGE_IS_575X_PLUS(sc) && !BGE_IS_5714_FAMILY(sc) && + (sc->bge_asicrev != BGE_ASICREV_BCM5906)) { if (sc->bge_flags & BGE_FLAG_PCIE) write_op = bge_writemem_direct; else @@ -2744,16 +2873,23 @@ bge_reset(struct bge_softc *sc) /* Issue global reset */ write_op(sc, BGE_MISC_CFG, reset); + if (sc->bge_asicrev == BGE_ASICREV_BCM5906) { + val = CSR_READ_4(sc, BGE_VCPU_STATUS); + CSR_WRITE_4(sc, BGE_VCPU_STATUS, + val | BGE_VCPU_STATUS_DRV_RESET); + val = CSR_READ_4(sc, BGE_VCPU_EXT_CTRL); + CSR_WRITE_4(sc, BGE_VCPU_EXT_CTRL, + val & ~BGE_VCPU_EXT_CTRL_HALT_CPU); + } + DELAY(1000); /* XXX: Broadcom Linux driver. */ if (sc->bge_flags & BGE_FLAG_PCIE) { if (sc->bge_chipid == BGE_CHIPID_BCM5750_A0) { - uint32_t v; - DELAY(500000); /* wait for link training to complete */ - v = pci_read_config(dev, 0xC4, 4); - pci_write_config(dev, 0xC4, v | (1 << 15), 4); + val = pci_read_config(dev, 0xC4, 4); + pci_write_config(dev, 0xC4, val | (1 << 15), 4); } /* * Set PCIE max payload size to 128 bytes and clear error @@ -2772,8 +2908,6 @@ bge_reset(struct bge_softc *sc) /* Re-enable MSI, if neccesary, and enable the memory arbiter. */ if (BGE_IS_5714_FAMILY(sc)) { - uint32_t val; - /* This chip disables MSI on reset. */ if (sc->bge_flags & BGE_FLAG_MSI) { val = pci_read_config(dev, BGE_PCI_MSI_CTL, 2); @@ -2788,21 +2922,35 @@ bge_reset(struct bge_softc *sc) } else CSR_WRITE_4(sc, BGE_MARB_MODE, BGE_MARBMODE_ENABLE); - /* - * Poll until we see the 1's complement of the magic number. - * This indicates that the firmware initialization is complete. - * We expect this to fail if no EEPROM is fitted though. - */ - for (i = 0; i < BGE_TIMEOUT; i++) { - DELAY(10); - val = bge_readmem_ind(sc, BGE_SOFTWARE_GENCOMM); - if (val == ~BGE_MAGIC_NUMBER) - break; - } + if (sc->bge_asicrev == BGE_ASICREV_BCM5906) { + for (i = 0; i < BGE_TIMEOUT; i++) { + val = CSR_READ_4(sc, BGE_VCPU_STATUS); + if (val & BGE_VCPU_STATUS_INIT_DONE) + break; + DELAY(100); + } + if (i == BGE_TIMEOUT) { + device_printf(sc->bge_dev, "reset timed out\n"); + return (1); + } + } else { + /* + * Poll until we see the 1's complement of the magic number. + * This indicates that the firmware initialization is complete. + * We expect this to fail if no chip containing the Ethernet + * address is fitted though. + */ + for (i = 0; i < BGE_TIMEOUT; i++) { + DELAY(10); + val = bge_readmem_ind(sc, BGE_SOFTWARE_GENCOMM); + if (val == ~BGE_MAGIC_NUMBER) + break; + } - if ((sc->bge_flags & BGE_FLAG_EEPROM) && i == BGE_TIMEOUT) - device_printf(sc->bge_dev, "firmware handshake timed out, " - "found 0x%08x\n", val); + if ((sc->bge_flags & BGE_FLAG_EADDR) && i == BGE_TIMEOUT) + device_printf(sc->bge_dev, "firmware handshake timed out, " + "found 0x%08x\n", val); + } /* * XXX Wait for the value of the PCISTATE register to @@ -2840,20 +2988,16 @@ bge_reset(struct bge_softc *sc) */ if (sc->bge_asicrev == BGE_ASICREV_BCM5704 && sc->bge_flags & BGE_FLAG_TBI) { - uint32_t serdescfg; - - serdescfg = CSR_READ_4(sc, BGE_SERDES_CFG); - serdescfg = (serdescfg & ~0xFFF) | 0x880; - CSR_WRITE_4(sc, BGE_SERDES_CFG, serdescfg); + val = CSR_READ_4(sc, BGE_SERDES_CFG); + val = (val & ~0xFFF) | 0x880; + CSR_WRITE_4(sc, BGE_SERDES_CFG, val); } /* XXX: Broadcom Linux driver. */ if (sc->bge_flags & BGE_FLAG_PCIE && sc->bge_chipid != BGE_CHIPID_BCM5750_A0) { - uint32_t v; - - v = CSR_READ_4(sc, 0x7C00); - CSR_WRITE_4(sc, 0x7C00, v | (1 << 25)); + val = CSR_READ_4(sc, 0x7C00); + CSR_WRITE_4(sc, 0x7C00, val | (1 << 25)); } DELAY(10000); @@ -3022,11 +3166,11 @@ bge_rxeof(struct bge_softc *sc) bus_dmamap_sync(sc->bge_cdata.bge_rx_jumbo_ring_tag, sc->bge_cdata.bge_rx_jumbo_ring_map, BUS_DMASYNC_PREWRITE); - CSR_WRITE_4(sc, BGE_MBX_RX_CONS0_LO, sc->bge_rx_saved_considx); + bge_writembx(sc, BGE_MBX_RX_CONS0_LO, sc->bge_rx_saved_considx); if (stdcnt) - CSR_WRITE_4(sc, BGE_MBX_RX_STD_PROD_LO, sc->bge_std); + bge_writembx(sc, BGE_MBX_RX_STD_PROD_LO, sc->bge_std); if (jumbocnt) - CSR_WRITE_4(sc, BGE_MBX_RX_JUMBO_PROD_LO, sc->bge_jumbo); + bge_writembx(sc, BGE_MBX_RX_JUMBO_PROD_LO, sc->bge_jumbo); #ifdef notyet /* * This register wraps very quickly under heavy packet drops. @@ -3168,7 +3312,7 @@ bge_intr(void *xsc) * the status check). So toggling would probably be a pessimization * even with MSI. It would only be needed for using a task queue. */ - CSR_WRITE_4(sc, BGE_MBX_IRQ0_LO, 0); + bge_writembx(sc, BGE_MBX_IRQ0_LO, 0); /* * Do the mandatory PCI flush as well as get the link status. @@ -3240,8 +3384,12 @@ bge_tick(void *xsc) if ((sc->bge_flags & BGE_FLAG_TBI) == 0) { mii = device_get_softc(sc->bge_miibus); - /* Don't mess with the PHY in IPMI/ASF mode */ - if (!((sc->bge_asf_mode & ASF_STACKUP) && (sc->bge_link))) + /* + * Do not touch PHY if we have link up. This could break + * IPMI/ASF mode or produce extra input errors + * (extra errors was reported for bcm5701 & bcm5704). + */ + if (!sc->bge_link) mii_tick(mii); } else { /* @@ -3255,7 +3403,11 @@ bge_tick(void *xsc) #endif { sc->bge_link_evt++; - BGE_SETBIT(sc, BGE_MISC_LOCAL_CTL, BGE_MLC_INTR_SET); + if (sc->bge_asicrev == BGE_ASICREV_BCM5700 || + sc->bge_flags & BGE_FLAG_5788) + BGE_SETBIT(sc, BGE_MISC_LOCAL_CTL, BGE_MLC_INTR_SET); + else + BGE_SETBIT(sc, BGE_HCC_MODE, BGE_HCCMODE_COAL_NOW); } } @@ -3390,7 +3542,7 @@ bge_encap(struct bge_softc *sc, struct mbuf **m_head, uint32_t *txidx) error = bus_dmamap_load_mbuf_sg(sc->bge_cdata.bge_mtag, map, m, segs, &nsegs, BUS_DMA_NOWAIT); if (error == EFBIG) { - m = m_defrag(m, M_DONTWAIT); + m = m_collapse(m, M_DONTWAIT, BGE_NSEG_NEW); if (m == NULL) { m_freem(*m_head); *m_head = NULL; @@ -3545,10 +3697,10 @@ bge_start_locked(struct ifnet *ifp) return; /* Transmit. */ - CSR_WRITE_4(sc, BGE_MBX_TX_HOST_PROD0_LO, prodidx); + bge_writembx(sc, BGE_MBX_TX_HOST_PROD0_LO, prodidx); /* 5700 b2 errata */ if (sc->bge_chiprev == BGE_CHIPREV_5700_BX) - CSR_WRITE_4(sc, BGE_MBX_TX_HOST_PROD0_LO, prodidx); + bge_writembx(sc, BGE_MBX_TX_HOST_PROD0_LO, prodidx); sc->bge_tx_prodidx = prodidx; @@ -3675,7 +3827,7 @@ bge_init_locked(struct bge_softc *sc) if (ifp->if_capenable & IFCAP_POLLING) { BGE_SETBIT(sc, BGE_PCI_MISC_CTL, BGE_PCIMISCCTL_MASK_PCI_INTR); - CSR_WRITE_4(sc, BGE_MBX_IRQ0_LO, 1); + bge_writembx(sc, BGE_MBX_IRQ0_LO, 1); } else #endif @@ -3683,7 +3835,7 @@ bge_init_locked(struct bge_softc *sc) { BGE_SETBIT(sc, BGE_PCI_MISC_CTL, BGE_PCIMISCCTL_CLEAR_INTA); BGE_CLRBIT(sc, BGE_PCI_MISC_CTL, BGE_PCIMISCCTL_MASK_PCI_INTR); - CSR_WRITE_4(sc, BGE_MBX_IRQ0_LO, 0); + bge_writembx(sc, BGE_MBX_IRQ0_LO, 0); } bge_ifmedia_upd_locked(ifp); @@ -3783,6 +3935,24 @@ bge_ifmedia_upd_locked(struct ifnet *ifp) } mii_mediachg(mii); + /* + * Force an interrupt so that we will call bge_link_upd + * if needed and clear any pending link state attention. + * Without this we are not getting any further interrupts + * for link state changes and thus will not UP the link and + * not be able to send in bge_start_locked. The only + * way to get things working was to receive a packet and + * get an RX intr. + * bge_tick should help for fiber cards and we might not + * need to do this here if BGE_FLAG_TBI is set but as + * we poll for fiber anyway it should not harm. + */ + if (sc->bge_asicrev == BGE_ASICREV_BCM5700 || + sc->bge_flags & BGE_FLAG_5788) + BGE_SETBIT(sc, BGE_MISC_LOCAL_CTL, BGE_MLC_INTR_SET); + else + BGE_SETBIT(sc, BGE_HCC_MODE, BGE_HCCMODE_COAL_NOW); + return (0); } @@ -3906,7 +4076,7 @@ bge_ioctl(struct ifnet *ifp, u_long command, caddr_t data) BGE_LOCK(sc); BGE_SETBIT(sc, BGE_PCI_MISC_CTL, BGE_PCIMISCCTL_MASK_PCI_INTR); - CSR_WRITE_4(sc, BGE_MBX_IRQ0_LO, 1); + bge_writembx(sc, BGE_MBX_IRQ0_LO, 1); ifp->if_capenable |= IFCAP_POLLING; BGE_UNLOCK(sc); } else { @@ -3915,7 +4085,7 @@ bge_ioctl(struct ifnet *ifp, u_long command, caddr_t data) BGE_LOCK(sc); BGE_CLRBIT(sc, BGE_PCI_MISC_CTL, BGE_PCIMISCCTL_MASK_PCI_INTR); - CSR_WRITE_4(sc, BGE_MBX_IRQ0_LO, 0); + bge_writembx(sc, BGE_MBX_IRQ0_LO, 0); ifp->if_capenable &= ~IFCAP_POLLING; BGE_UNLOCK(sc); } @@ -4040,7 +4210,7 @@ bge_stop(struct bge_softc *sc) /* Disable host interrupts. */ BGE_SETBIT(sc, BGE_PCI_MISC_CTL, BGE_PCIMISCCTL_MASK_PCI_INTR); - CSR_WRITE_4(sc, BGE_MBX_IRQ0_LO, 1); + bge_writembx(sc, BGE_MBX_IRQ0_LO, 1); /* * Tell firmware we're shutting down. @@ -4295,6 +4465,9 @@ bge_add_sysctls(struct bge_softc *sc) #endif + if (BGE_IS_5705_PLUS(sc)) + return; + tree = SYSCTL_ADD_NODE(ctx, children, OID_AUTO, "stats", CTLFLAG_RD, NULL, "BGE Statistics"); schildren = children = SYSCTL_CHILDREN(tree); @@ -4417,16 +4590,12 @@ bge_sysctl_stats(SYSCTL_HANDLER_ARGS) { struct bge_softc *sc; uint32_t result; - int base, offset; + int offset; sc = (struct bge_softc *)arg1; offset = arg2; - if (BGE_IS_5705_PLUS(sc)) - base = BGE_MAC_STATS; - else - base = BGE_MEMWIN_START + BGE_STATS_BLOCK; - result = CSR_READ_4(sc, base + offset + offsetof(bge_hostaddr, - bge_addr_lo)); + result = CSR_READ_4(sc, BGE_MEMWIN_START + BGE_STATS_BLOCK + offset + + offsetof(bge_hostaddr, bge_addr_lo)); return (sysctl_handle_int(oidp, &result, 0, req)); } @@ -4537,3 +4706,79 @@ bge_sysctl_mem_read(SYSCTL_HANDLER_ARGS) return (error); } #endif + +static int +bge_get_eaddr_fw(struct bge_softc *sc, uint8_t ether_addr[]) +{ + + if (sc->bge_flags & BGE_FLAG_EADDR) + return (1); + +#ifdef __sparc64__ + OF_getetheraddr(sc->bge_dev, ether_addr); + return (0); +#endif + return (1); +} + +static int +bge_get_eaddr_mem(struct bge_softc *sc, uint8_t ether_addr[]) +{ + uint32_t mac_addr; + + mac_addr = bge_readmem_ind(sc, 0x0c14); + if ((mac_addr >> 16) == 0x484b) { + ether_addr[0] = (uint8_t)(mac_addr >> 8); + ether_addr[1] = (uint8_t)mac_addr; + mac_addr = bge_readmem_ind(sc, 0x0c18); + ether_addr[2] = (uint8_t)(mac_addr >> 24); + ether_addr[3] = (uint8_t)(mac_addr >> 16); + ether_addr[4] = (uint8_t)(mac_addr >> 8); + ether_addr[5] = (uint8_t)mac_addr; + return (0); + } + return (1); +} + +static int +bge_get_eaddr_nvram(struct bge_softc *sc, uint8_t ether_addr[]) +{ + int mac_offset = BGE_EE_MAC_OFFSET; + + if (sc->bge_asicrev == BGE_ASICREV_BCM5906) + mac_offset = BGE_EE_MAC_OFFSET_5906; + + return (bge_read_nvram(sc, ether_addr, mac_offset + 2, + ETHER_ADDR_LEN)); +} + +static int +bge_get_eaddr_eeprom(struct bge_softc *sc, uint8_t ether_addr[]) +{ + + if (sc->bge_asicrev == BGE_ASICREV_BCM5906) + return (1); + + return (bge_read_eeprom(sc, ether_addr, BGE_EE_MAC_OFFSET + 2, + ETHER_ADDR_LEN)); +} + +static int +bge_get_eaddr(struct bge_softc *sc, uint8_t eaddr[]) +{ + static const bge_eaddr_fcn_t bge_eaddr_funcs[] = { + /* NOTE: Order is critical */ + bge_get_eaddr_fw, + bge_get_eaddr_mem, + bge_get_eaddr_nvram, + bge_get_eaddr_eeprom, + NULL + }; + const bge_eaddr_fcn_t *func; + + for (func = bge_eaddr_funcs; *func != NULL; ++func) { + if ((*func)(sc, eaddr) == 0) + break; + } + return (*func == NULL ? ENXIO : 0); +} diff --git a/src/add-ons/kernel/drivers/network/broadcom570x/dev/bge/if_bgereg.h b/src/add-ons/kernel/drivers/network/broadcom570x/dev/bge/if_bgereg.h index 8566489de3..9753d81d44 100644 --- a/src/add-ons/kernel/drivers/network/broadcom570x/dev/bge/if_bgereg.h +++ b/src/add-ons/kernel/drivers/network/broadcom570x/dev/bge/if_bgereg.h @@ -30,7 +30,7 @@ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF * THE POSSIBILITY OF SUCH DAMAGE. * - * $FreeBSD: src/sys/dev/bge/if_bgereg.h,v 1.73 2007/05/22 19:22:58 jkim Exp $ + * $FreeBSD: src/sys/dev/bge/if_bgereg.h,v 1.81 2008/10/14 20:28:42 marius Exp $ */ /* @@ -277,12 +277,15 @@ #define BGE_CHIPID_BCM5755_A0 0xa0000000 #define BGE_CHIPID_BCM5755_A1 0xa0010000 #define BGE_CHIPID_BCM5755_A2 0xa0020000 +#define BGE_CHIPID_BCM5722_A0 0xa2000000 #define BGE_CHIPID_BCM5754_A0 0xb0000000 #define BGE_CHIPID_BCM5754_A1 0xb0010000 #define BGE_CHIPID_BCM5754_A2 0xb0020000 #define BGE_CHIPID_BCM5787_A0 0xb0000000 #define BGE_CHIPID_BCM5787_A1 0xb0010000 #define BGE_CHIPID_BCM5787_A2 0xb0020000 +#define BGE_CHIPID_BCM5906_A1 0xc0010000 +#define BGE_CHIPID_BCM5906_A2 0xc0020000 /* shorthand one */ #define BGE_ASICREV(x) ((x) >> 28) @@ -299,6 +302,7 @@ #define BGE_ASICREV_BCM5755 0x0a #define BGE_ASICREV_BCM5754 0x0b #define BGE_ASICREV_BCM5787 0x0b +#define BGE_ASICREV_BCM5906 0x0c /* chip revisions */ #define BGE_CHIPREV(x) ((x) >> 24) @@ -1438,6 +1442,17 @@ #define BGE_RXCPUSTAT_MA_REQ_FIFOOFLOW 0x40000000 #define BGE_RXCPUSTAT_BLOCKING_READ 0x80000000 +/* + * V? CPU registers + */ +#define BGE_VCPU_STATUS 0x5100 +#define BGE_VCPU_EXT_CTRL 0x6890 + +#define BGE_VCPU_STATUS_INIT_DONE 0x04000000 +#define BGE_VCPU_STATUS_DRV_RESET 0x08000000 + +#define BGE_VCPU_EXT_CTRL_HALT_CPU 0x00400000 +#define BGE_VCPU_EXT_CTRL_DISABLE_WOL 0x20000000 /* * TX CPU registers @@ -1684,6 +1699,56 @@ #define BGE_EE_DELAY 0x6848 #define BGE_FASTBOOT_PC 0x6894 +/* + * NVRAM Control registers + */ +#define BGE_NVRAM_CMD 0x7000 +#define BGE_NVRAM_STAT 0x7004 +#define BGE_NVRAM_WRDATA 0x7008 +#define BGE_NVRAM_ADDR 0x700c +#define BGE_NVRAM_RDDATA 0x7010 +#define BGE_NVRAM_CFG1 0x7014 +#define BGE_NVRAM_CFG2 0x7018 +#define BGE_NVRAM_CFG3 0x701c +#define BGE_NVRAM_SWARB 0x7020 +#define BGE_NVRAM_ACCESS 0x7024 +#define BGE_NVRAM_WRITE1 0x7028 + +#define BGE_NVRAMCMD_RESET 0x00000001 +#define BGE_NVRAMCMD_DONE 0x00000008 +#define BGE_NVRAMCMD_START 0x00000010 +#define BGE_NVRAMCMD_WR 0x00000020 /* 1 = wr, 0 = rd */ +#define BGE_NVRAMCMD_ERASE 0x00000040 +#define BGE_NVRAMCMD_FIRST 0x00000080 +#define BGE_NVRAMCMD_LAST 0x00000100 + +#define BGE_NVRAM_READCMD \ + (BGE_NVRAMCMD_FIRST|BGE_NVRAMCMD_LAST| \ + BGE_NVRAMCMD_START|BGE_NVRAMCMD_DONE) +#define BGE_NVRAM_WRITECMD \ + (BGE_NVRAMCMD_FIRST|BGE_NVRAMCMD_LAST| \ + BGE_NVRAMCMD_START|BGE_NVRAMCMD_DONE|BGE_NVRAMCMD_WR) + +#define BGE_NVRAMSWARB_SET0 0x00000001 +#define BGE_NVRAMSWARB_SET1 0x00000002 +#define BGE_NVRAMSWARB_SET2 0x00000003 +#define BGE_NVRAMSWARB_SET3 0x00000004 +#define BGE_NVRAMSWARB_CLR0 0x00000010 +#define BGE_NVRAMSWARB_CLR1 0x00000020 +#define BGE_NVRAMSWARB_CLR2 0x00000040 +#define BGE_NVRAMSWARB_CLR3 0x00000080 +#define BGE_NVRAMSWARB_GNT0 0x00000100 +#define BGE_NVRAMSWARB_GNT1 0x00000200 +#define BGE_NVRAMSWARB_GNT2 0x00000400 +#define BGE_NVRAMSWARB_GNT3 0x00000800 +#define BGE_NVRAMSWARB_REQ0 0x00001000 +#define BGE_NVRAMSWARB_REQ1 0x00002000 +#define BGE_NVRAMSWARB_REQ2 0x00004000 +#define BGE_NVRAMSWARB_REQ3 0x00008000 + +#define BGE_NVRAMACC_ENABLE 0x00000001 +#define BGE_NVRAMACC_WRENABLE 0x00000002 + /* Mode control register */ #define BGE_MODECTL_INT_SNDCOAL_ONLY 0x00000001 #define BGE_MODECTL_BYTESWAP_NONFRAME 0x00000002 @@ -1711,6 +1776,10 @@ /* Misc. config register */ #define BGE_MISCCFG_RESET_CORE_CLOCKS 0x00000001 #define BGE_MISCCFG_TIMER_PRESCALER 0x000000FE +#define BGE_MISCCFG_BOARD_ID 0x0001E000 +#define BGE_MISCCFG_BOARD_ID_5788 0x00010000 +#define BGE_MISCCFG_BOARD_ID_5788M 0x00018000 +#define BGE_MISCCFG_EPHY_IDDQ 0x00200000 #define BGE_32BITTIME_66MHZ (0x41 << 1) @@ -1827,8 +1896,7 @@ struct bge_rcb { }; #define RCB_WRITE_4(sc, rcb, offset, val) \ - bus_space_write_4(sc->bge_btag, sc->bge_bhandle, \ - rcb + offsetof(struct bge_rcb, offset), val) + bus_write_4(sc->bge_res, rcb + offsetof(struct bge_rcb, offset), val) #define BGE_RCB_MAXLEN_FLAGS(maxlen, flags) ((maxlen) << 16 | (flags)) #define BGE_RCB_FLAG_USE_EXT_RX_BD 0x0001 @@ -2011,6 +2079,7 @@ struct bge_status_block { #define BCOM_DEVICEID_BCM5715S 0x1679 #define BCOM_DEVICEID_BCM5720 0x1658 #define BCOM_DEVICEID_BCM5721 0x1659 +#define BCOM_DEVICEID_BCM5722 0x165A #define BCOM_DEVICEID_BCM5750 0x1676 #define BCOM_DEVICEID_BCM5750M 0x167C #define BCOM_DEVICEID_BCM5751 0x1677 @@ -2037,6 +2106,8 @@ struct bge_status_block { #define BCOM_DEVICEID_BCM5901 0x170D #define BCOM_DEVICEID_BCM5901A2 0x170E #define BCOM_DEVICEID_BCM5903M 0x16FF +#define BCOM_DEVICEID_BCM5906 0x1712 +#define BCOM_DEVICEID_BCM5906M 0x1713 /* * Alteon AceNIC PCI vendor/device ID. @@ -2090,6 +2161,7 @@ struct bge_status_block { * Offset of MAC address inside EEPROM. */ #define BGE_EE_MAC_OFFSET 0x7C +#define BGE_EE_MAC_OFFSET_5906 0x10 #define BGE_EE_HWCFG_OFFSET 0xC8 #define BGE_HWCFG_VOLTAGE 0x00000003 @@ -2321,10 +2393,10 @@ struct bge_gib { */ #define CSR_WRITE_4(sc, reg, val) \ - bus_space_write_4(sc->bge_btag, sc->bge_bhandle, reg, val) + bus_write_4(sc->bge_res, reg, val) #define CSR_READ_4(sc, reg) \ - bus_space_read_4(sc->bge_btag, sc->bge_bhandle, reg) + bus_read_4(sc->bge_res, reg) #define BGE_SETBIT(sc, reg, x) \ CSR_WRITE_4(sc, reg, (CSR_READ_4(sc, reg) | (x))) @@ -2449,8 +2521,6 @@ struct bge_softc { device_t bge_dev; struct mtx bge_mtx; device_t bge_miibus; - bus_space_handle_t bge_bhandle; - bus_space_tag_t bge_btag; void *bge_intrhand; struct resource *bge_irq; struct resource *bge_res; @@ -2458,7 +2528,8 @@ struct bge_softc { uint32_t bge_flags; #define BGE_FLAG_TBI 0x00000001 #define BGE_FLAG_JUMBO 0x00000002 -#define BGE_FLAG_EEPROM 0x00000004 +#define BGE_FLAG_WIRESPEED 0x00000004 +#define BGE_FLAG_EADDR 0x00000008 #define BGE_FLAG_MSI 0x00000100 #define BGE_FLAG_PCIX 0x00000200 #define BGE_FLAG_PCIE 0x00000400 @@ -2474,6 +2545,7 @@ struct bge_softc { #define BGE_FLAG_BER_BUG 0x02000000 #define BGE_FLAG_ADJUST_TRIM 0x04000000 #define BGE_FLAG_CRC_BUG 0x08000000 +#define BGE_FLAG_5788 0x20000000 uint32_t bge_chipid; uint8_t bge_asicrev; uint8_t bge_chiprev; diff --git a/src/add-ons/kernel/drivers/network/broadcom570x/dev/mii/brgphyreg.h b/src/add-ons/kernel/drivers/network/broadcom570x/dev/mii/brgphyreg.h index 87d0a456a9..9b7d474bcb 100644 --- a/src/add-ons/kernel/drivers/network/broadcom570x/dev/mii/brgphyreg.h +++ b/src/add-ons/kernel/drivers/network/broadcom570x/dev/mii/brgphyreg.h @@ -29,7 +29,7 @@ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF * THE POSSIBILITY OF SUCH DAMAGE. * - * $FreeBSD: src/sys/dev/mii/brgphyreg.h,v 1.10 2007/06/07 02:21:38 davidch Exp $ + * $FreeBSD: src/sys/dev/mii/brgphyreg.h,v 1.11 2008/04/29 19:47:13 jhb Exp $ */ #ifndef _DEV_MII_BRGPHYREG_H_ @@ -161,6 +161,7 @@ #define BRGPHY_MII_DSP_RW_PORT 0x15 /* DSP coefficient r/w port */ #define BRGPHY_MII_DSP_ADDR_REG 0x17 /* DSP coefficient addr register */ +#define BRGPHY_MII_EPHY_PTEST 0x17 /* 5906 PHY register */ #define BRGPHY_DSP_TAP_NUMBER_MASK 0x00 #define BRGPHY_DSP_AGC_A 0x00