diff options
| author | Paul Saab <ps@FreeBSD.org> | 2004-09-29 14:31:49 +0000 |
|---|---|---|
| committer | Paul Saab <ps@FreeBSD.org> | 2004-09-29 14:31:49 +0000 |
| commit | d03c7f123603b4db0c96049abb501669c0eabe92 (patch) | |
| tree | 07d92ffb1d718e2f1a27046320e430e1ef025bb3 /sys/dev/bge | |
| parent | 1c9205d5b1a0c68c645a6e26e6c944452ce0255d (diff) | |
Notes
Diffstat (limited to 'sys/dev/bge')
| -rw-r--r-- | sys/dev/bge/if_bge.c | 159 | ||||
| -rw-r--r-- | sys/dev/bge/if_bgereg.h | 11 |
2 files changed, 132 insertions, 38 deletions
diff --git a/sys/dev/bge/if_bge.c b/sys/dev/bge/if_bge.c index 71ad6ab36938..34341caf79f0 100644 --- a/sys/dev/bge/if_bge.c +++ b/sys/dev/bge/if_bge.c @@ -155,6 +155,12 @@ static struct bge_type bge_devs[] = { "Broadcom BCM5705M Gigabit Ethernet" }, { BCOM_VENDORID, BCOM_DEVICEID_BCM5705M_ALT, "Broadcom BCM5705M Gigabit Ethernet" }, + { BCOM_VENDORID, BCOM_DEVICEID_BCM5750, + "Broadcom BCM5750 Gigabit Ethernet" }, + { BCOM_VENDORID, BCOM_DEVICEID_BCM5750M, + "Broadcom BCM5750M Gigabit Ethernet" }, + { BCOM_VENDORID, BCOM_DEVICEID_BCM5751, + "Broadcom BCM5751 Gigabit Ethernet" }, { BCOM_VENDORID, BCOM_DEVICEID_BCM5782, "Broadcom BCM5782 Gigabit Ethernet" }, { BCOM_VENDORID, BCOM_DEVICEID_BCM5788, @@ -1216,7 +1222,11 @@ bge_chipinit(sc) BGE_MEMWIN_WRITE(sc, i, 0); /* Set up the PCI DMA control register. */ - if (pci_read_config(sc->bge_dev, BGE_PCI_PCISTATE, 4) & + if (sc->bge_pcie) { + dma_rw_ctl = BGE_PCI_READ_CMD|BGE_PCI_WRITE_CMD | + (0xf << BGE_PCIDMARWCTL_RD_WAT_SHIFT) | + (0x2 << BGE_PCIDMARWCTL_WR_WAT_SHIFT); + } else if (pci_read_config(sc->bge_dev, BGE_PCI_PCISTATE, 4) & BGE_PCISTATE_PCI_BUSMODE) { /* Conventional PCI bus */ dma_rw_ctl = BGE_PCI_READ_CMD|BGE_PCI_WRITE_CMD | @@ -1255,7 +1265,8 @@ bge_chipinit(sc) if (sc->bge_asicrev == BGE_ASICREV_BCM5703 || sc->bge_asicrev == BGE_ASICREV_BCM5704 || - sc->bge_asicrev == BGE_ASICREV_BCM5705) + sc->bge_asicrev == BGE_ASICREV_BCM5705 || + sc->bge_asicrev == BGE_ASICREV_BCM5750) dma_rw_ctl &= ~BGE_PCIDMARWCTL_MINDMA; pci_write_config(sc->bge_dev, BGE_PCI_DMA_RW_CTL, dma_rw_ctl, 4); @@ -1308,7 +1319,8 @@ bge_blockinit(sc) /* Note: the BCM5704 has a smaller mbuf space than other chips. */ - if (sc->bge_asicrev != BGE_ASICREV_BCM5705) { + if (sc->bge_asicrev != BGE_ASICREV_BCM5705 && + sc->bge_asicrev != BGE_ASICREV_BCM5750) { /* Configure mbuf memory pool */ if (sc->bge_extram) { CSR_WRITE_4(sc, BGE_BMAN_MBUFPOOL_BASEADDR, @@ -1333,7 +1345,8 @@ bge_blockinit(sc) } /* Configure mbuf pool watermarks */ - if (sc->bge_asicrev == BGE_ASICREV_BCM5705) { + if (sc->bge_asicrev == BGE_ASICREV_BCM5705 || + sc->bge_asicrev == BGE_ASICREV_BCM5750) { CSR_WRITE_4(sc, BGE_BMAN_MBUFPOOL_READDMA_LOWAT, 0x0); CSR_WRITE_4(sc, BGE_BMAN_MBUFPOOL_MACRX_LOWAT, 0x10); } else { @@ -1347,7 +1360,8 @@ bge_blockinit(sc) CSR_WRITE_4(sc, BGE_BMAN_DMA_DESCPOOL_HIWAT, 10); /* Enable buffer manager */ - if (sc->bge_asicrev != BGE_ASICREV_BCM5705) { + if (sc->bge_asicrev != BGE_ASICREV_BCM5705 && + sc->bge_asicrev != BGE_ASICREV_BCM5750) { CSR_WRITE_4(sc, BGE_BMAN_MODE, BGE_BMANMODE_ENABLE|BGE_BMANMODE_LOMBUF_ATTN); @@ -1390,7 +1404,8 @@ bge_blockinit(sc) BGE_ADDR_HI(sc->bge_ldata.bge_rx_std_ring_paddr); bus_dmamap_sync(sc->bge_cdata.bge_rx_std_ring_tag, sc->bge_cdata.bge_rx_std_ring_map, BUS_DMASYNC_PREREAD); - if (sc->bge_asicrev == BGE_ASICREV_BCM5705) + if (sc->bge_asicrev == BGE_ASICREV_BCM5705 || + sc->bge_asicrev == BGE_ASICREV_BCM5750) rcb->bge_maxlen_flags = BGE_RCB_MAXLEN_FLAGS(512, 0); else rcb->bge_maxlen_flags = @@ -1412,7 +1427,8 @@ bge_blockinit(sc) * using this ring (i.e. once we set the MTU * high enough to require it). */ - if (sc->bge_asicrev != BGE_ASICREV_BCM5705) { + if (sc->bge_asicrev != BGE_ASICREV_BCM5705 && + sc->bge_asicrev != BGE_ASICREV_BCM5750) { rcb = &sc->bge_ldata.bge_info.bge_jumbo_rx_rcb; rcb->bge_hostaddr.bge_addr_lo = @@ -1476,7 +1492,8 @@ bge_blockinit(sc) vrcb->bge_hostaddr.bge_addr_hi = htole32(BGE_ADDR_HI(sc->bge_ldata.bge_tx_ring_paddr)); vrcb->bge_nicaddr = BGE_NIC_TXRING_ADDR(0, BGE_TX_RING_CNT); - if (sc->bge_asicrev != BGE_ASICREV_BCM5705) + if (sc->bge_asicrev != BGE_ASICREV_BCM5705 && + sc->bge_asicrev != BGE_ASICREV_BCM5750) vrcb->bge_maxlen_flags = BGE_RCB_MAXLEN_FLAGS(BGE_TX_RING_CNT, 0); @@ -1565,7 +1582,8 @@ bge_blockinit(sc) CSR_WRITE_4(sc, BGE_HCC_TX_COAL_TICKS, sc->bge_tx_coal_ticks); CSR_WRITE_4(sc, BGE_HCC_RX_MAX_COAL_BDS, sc->bge_rx_max_coal_bds); CSR_WRITE_4(sc, BGE_HCC_TX_MAX_COAL_BDS, sc->bge_tx_max_coal_bds); - if (sc->bge_asicrev != BGE_ASICREV_BCM5705) { + if (sc->bge_asicrev != BGE_ASICREV_BCM5705 && + sc->bge_asicrev != BGE_ASICREV_BCM5750) { CSR_WRITE_4(sc, BGE_HCC_RX_COAL_TICKS_INT, 0); CSR_WRITE_4(sc, BGE_HCC_TX_COAL_TICKS_INT, 0); } @@ -1573,7 +1591,8 @@ bge_blockinit(sc) CSR_WRITE_4(sc, BGE_HCC_TX_MAX_COAL_BDS_INT, 0); /* Set up address of statistics block */ - if (sc->bge_asicrev != BGE_ASICREV_BCM5705) { + if (sc->bge_asicrev != BGE_ASICREV_BCM5705 && + sc->bge_asicrev != BGE_ASICREV_BCM5750) { CSR_WRITE_4(sc, BGE_HCC_STATS_ADDR_HI, BGE_ADDR_HI(sc->bge_ldata.bge_stats_paddr)); CSR_WRITE_4(sc, BGE_HCC_STATS_ADDR_LO, @@ -1604,7 +1623,8 @@ bge_blockinit(sc) CSR_WRITE_4(sc, BGE_RXLP_MODE, BGE_RXLPMODE_ENABLE); /* Turn on RX list selector state machine. */ - if (sc->bge_asicrev != BGE_ASICREV_BCM5705) + if (sc->bge_asicrev != BGE_ASICREV_BCM5705 && + sc->bge_asicrev != BGE_ASICREV_BCM5750) CSR_WRITE_4(sc, BGE_RXLS_MODE, BGE_RXLSMODE_ENABLE); /* Turn on DMA, clear stats */ @@ -1626,7 +1646,8 @@ bge_blockinit(sc) #endif /* Turn on DMA completion state machine */ - if (sc->bge_asicrev != BGE_ASICREV_BCM5705) + if (sc->bge_asicrev != BGE_ASICREV_BCM5705 && + sc->bge_asicrev != BGE_ASICREV_BCM5750) CSR_WRITE_4(sc, BGE_DMAC_MODE, BGE_DMACMODE_ENABLE); /* Turn on write DMA state machine */ @@ -1647,7 +1668,8 @@ bge_blockinit(sc) CSR_WRITE_4(sc, BGE_RDBDI_MODE, BGE_RDBDIMODE_ENABLE); /* Turn on Mbuf cluster free state machine */ - if (sc->bge_asicrev != BGE_ASICREV_BCM5705) + if (sc->bge_asicrev != BGE_ASICREV_BCM5705 && + sc->bge_asicrev != BGE_ASICREV_BCM5750) CSR_WRITE_4(sc, BGE_MBCF_MODE, BGE_MBCFMODE_ENABLE); /* Turn on send BD completion state machine */ @@ -1981,7 +2003,8 @@ bge_dma_alloc(dev) sc->bge_ldata.bge_rx_std_ring_paddr = ctx.bge_busaddr; - if (sc->bge_asicrev != BGE_ASICREV_BCM5705) { + if (sc->bge_asicrev != BGE_ASICREV_BCM5705 && + sc->bge_asicrev != BGE_ASICREV_BCM5750) { /* * Create tag for jumbo mbufs. @@ -2261,6 +2284,29 @@ bge_attach(dev) BGE_LOCK_INIT(sc, device_get_nameunit(dev)); + /* 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); + + /* + * XXX: Broadcom Linux driver. Not in specs or eratta. + * PCI-Express? + */ + if (sc->bge_asicrev == BGE_ASICREV_BCM5750) { + u_int32_t v; + + v = pci_read_config(dev, BGE_PCI_MSI_CAPID, 4); + if (((v >> 8) & 0xff) == BGE_PCIE_CAPID_REG) { + v = pci_read_config(dev, BGE_PCIE_CAPID_REG, 4); + if ((v & 0xff) == BGE_PCIE_CAPID) + sc->bge_pcie = 1; + } + } + /* Try to reset the chip. */ bge_reset(sc); @@ -2291,16 +2337,9 @@ bge_attach(dev) goto fail; } - /* 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); - /* 5705 limits RX return ring to 512 entries. */ - if (sc->bge_asicrev == BGE_ASICREV_BCM5705) + if (sc->bge_asicrev == BGE_ASICREV_BCM5705 || + sc->bge_asicrev == BGE_ASICREV_BCM5750) sc->bge_return_ring_cnt = BGE_RETURN_RING_CNT_5705; else sc->bge_return_ring_cnt = BGE_RETURN_RING_CNT; @@ -2317,7 +2356,8 @@ bge_attach(dev) * Try to allocate memory for jumbo buffers. * The 5705 does not appear to support jumbo frames. */ - if (sc->bge_asicrev != BGE_ASICREV_BCM5705) { + if (sc->bge_asicrev != BGE_ASICREV_BCM5705 && + sc->bge_asicrev != BGE_ASICREV_BCM5750) { if (bge_alloc_jumbo_mem(sc)) { printf("bge%d: jumbo buffer allocation " "failed\n", sc->bge_unit); @@ -2465,7 +2505,8 @@ bge_detach(dev) } bge_release_resources(sc); - if (sc->bge_asicrev != BGE_ASICREV_BCM5705) + if (sc->bge_asicrev != BGE_ASICREV_BCM5705 && + sc->bge_asicrev != BGE_ASICREV_BCM5750) bge_free_jumbo_mem(sc); return(0); @@ -2508,7 +2549,7 @@ bge_reset(sc) struct bge_softc *sc; { device_t dev; - u_int32_t cachesize, command, pcistate; + u_int32_t cachesize, command, pcistate, reset; int i, val = 0; dev = sc->bge_dev; @@ -2522,12 +2563,37 @@ bge_reset(sc) BGE_PCIMISCCTL_INDIRECT_ACCESS|BGE_PCIMISCCTL_MASK_PCI_INTR| BGE_PCIMISCCTL_ENDIAN_WORDSWAP|BGE_PCIMISCCTL_PCISTATE_RW, 4); + reset = BGE_MISCCFG_RESET_CORE_CLOCKS|(65<<1); + + /* XXX: Broadcom Linux driver. */ + if (sc->bge_pcie) { + if (CSR_READ_4(sc, 0x7e2c) == 0x60) /* PCIE 1.0 */ + CSR_WRITE_4(sc, 0x7e2c, 0x20); + if (sc->bge_chipid != BGE_CHIPID_BCM5750_A0) { + /* Prevent PCIE link training during global reset */ + CSR_WRITE_4(sc, BGE_MISC_CFG, (1<<29)); + reset |= (1<<29); + } + } + /* Issue global reset */ - bge_writereg_ind(sc, BGE_MISC_CFG, - BGE_MISCCFG_RESET_CORE_CLOCKS|(65<<1)); + bge_writereg_ind(sc, BGE_MISC_CFG, reset); DELAY(1000); + /* XXX: Broadcom Linux driver. */ + if (sc->bge_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); + } + /* Set PCIE max payload size and clear error status. */ + pci_write_config(dev, 0xd8, 0xf5000, 4); + } + /* Reset some of the PCI state that got zapped by reset */ pci_write_config(dev, BGE_PCI_MISC_CTL, BGE_PCIMISCCTL_INDIRECT_ACCESS|BGE_PCIMISCCTL_MASK_PCI_INTR| @@ -2537,7 +2603,8 @@ bge_reset(sc) bge_writereg_ind(sc, BGE_MISC_CFG, (65 << 1)); /* Enable memory arbiter. */ - if (sc->bge_asicrev != BGE_ASICREV_BCM5705) + if (sc->bge_asicrev != BGE_ASICREV_BCM5705 && + sc->bge_asicrev != BGE_ASICREV_BCM5750) CSR_WRITE_4(sc, BGE_MARB_MODE, BGE_MARBMODE_ENABLE); /* @@ -2595,6 +2662,13 @@ bge_reset(sc) CSR_WRITE_4(sc, BGE_SERDES_CFG, serdescfg); } + /* XXX: Broadcom Linux driver. */ + if (sc->bge_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)); + } DELAY(10000); return; @@ -2624,7 +2698,8 @@ bge_rxeof(sc) sc->bge_cdata.bge_rx_return_ring_map, BUS_DMASYNC_POSTWRITE); bus_dmamap_sync(sc->bge_cdata.bge_rx_std_ring_tag, sc->bge_cdata.bge_rx_std_ring_map, BUS_DMASYNC_POSTREAD); - if (sc->bge_asicrev != BGE_ASICREV_BCM5705) { + if (sc->bge_asicrev != BGE_ASICREV_BCM5705 && + sc->bge_asicrev != BGE_ASICREV_BCM5750) { bus_dmamap_sync(sc->bge_cdata.bge_rx_jumbo_ring_tag, sc->bge_cdata.bge_rx_jumbo_ring_map, BUS_DMASYNC_POSTREAD); @@ -2740,7 +2815,8 @@ bge_rxeof(sc) bus_dmamap_sync(sc->bge_cdata.bge_rx_std_ring_tag, sc->bge_cdata.bge_rx_std_ring_map, BUS_DMASYNC_POSTREAD|BUS_DMASYNC_PREWRITE); - if (sc->bge_asicrev != BGE_ASICREV_BCM5705) { + if (sc->bge_asicrev != BGE_ASICREV_BCM5705 && + sc->bge_asicrev != BGE_ASICREV_BCM5750) { bus_dmamap_sync(sc->bge_cdata.bge_rx_jumbo_ring_tag, sc->bge_cdata.bge_rx_jumbo_ring_map, BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE); @@ -2926,7 +3002,8 @@ bge_tick_locked(sc) BGE_LOCK_ASSERT(sc); - if (sc->bge_asicrev == BGE_ASICREV_BCM5705) + if (sc->bge_asicrev == BGE_ASICREV_BCM5705 || + sc->bge_asicrev == BGE_ASICREV_BCM5750) bge_stats_update_regs(sc); else bge_stats_update(sc); @@ -3438,7 +3515,8 @@ bge_ioctl(ifp, command, data) switch(command) { case SIOCSIFMTU: /* Disallow jumbo frames on 5705. */ - if ((sc->bge_asicrev == BGE_ASICREV_BCM5705 && + if (((sc->bge_asicrev == BGE_ASICREV_BCM5705 || + sc->bge_asicrev == BGE_ASICREV_BCM5750) && ifr->ifr_mtu > ETHERMTU) || ifr->ifr_mtu > BGE_JUMBO_MTU) error = EINVAL; else { @@ -3565,7 +3643,8 @@ bge_stop(sc) BGE_CLRBIT(sc, BGE_RX_MODE, BGE_RXMODE_ENABLE); BGE_CLRBIT(sc, BGE_RBDI_MODE, BGE_RBDIMODE_ENABLE); BGE_CLRBIT(sc, BGE_RXLP_MODE, BGE_RXLPMODE_ENABLE); - if (sc->bge_asicrev != BGE_ASICREV_BCM5705) + if (sc->bge_asicrev != BGE_ASICREV_BCM5705 && + sc->bge_asicrev != BGE_ASICREV_BCM5750) BGE_CLRBIT(sc, BGE_RXLS_MODE, BGE_RXLSMODE_ENABLE); BGE_CLRBIT(sc, BGE_RDBDI_MODE, BGE_RBDIMODE_ENABLE); BGE_CLRBIT(sc, BGE_RDC_MODE, BGE_RDCMODE_ENABLE); @@ -3579,7 +3658,8 @@ bge_stop(sc) BGE_CLRBIT(sc, BGE_SDI_MODE, BGE_SDIMODE_ENABLE); BGE_CLRBIT(sc, BGE_RDMA_MODE, BGE_RDMAMODE_ENABLE); BGE_CLRBIT(sc, BGE_SDC_MODE, BGE_SDCMODE_ENABLE); - if (sc->bge_asicrev != BGE_ASICREV_BCM5705) + if (sc->bge_asicrev != BGE_ASICREV_BCM5705 && + sc->bge_asicrev != BGE_ASICREV_BCM5750) BGE_CLRBIT(sc, BGE_DMAC_MODE, BGE_DMACMODE_ENABLE); BGE_CLRBIT(sc, BGE_SBDC_MODE, BGE_SBDCMODE_ENABLE); @@ -3589,11 +3669,13 @@ bge_stop(sc) */ BGE_CLRBIT(sc, BGE_HCC_MODE, BGE_HCCMODE_ENABLE); BGE_CLRBIT(sc, BGE_WDMA_MODE, BGE_WDMAMODE_ENABLE); - if (sc->bge_asicrev != BGE_ASICREV_BCM5705) + if (sc->bge_asicrev != BGE_ASICREV_BCM5705 && + sc->bge_asicrev != BGE_ASICREV_BCM5750) BGE_CLRBIT(sc, BGE_MBCF_MODE, BGE_MBCFMODE_ENABLE); CSR_WRITE_4(sc, BGE_FTQ_RESET, 0xFFFFFFFF); CSR_WRITE_4(sc, BGE_FTQ_RESET, 0); - if (sc->bge_asicrev != BGE_ASICREV_BCM5705) { + if (sc->bge_asicrev != BGE_ASICREV_BCM5705 && + sc->bge_asicrev != BGE_ASICREV_BCM5750) { BGE_CLRBIT(sc, BGE_BMAN_MODE, BGE_BMANMODE_ENABLE); BGE_CLRBIT(sc, BGE_MARB_MODE, BGE_MARBMODE_ENABLE); } @@ -3611,7 +3693,8 @@ bge_stop(sc) bge_free_rx_ring_std(sc); /* Free jumbo RX list. */ - if (sc->bge_asicrev != BGE_ASICREV_BCM5705) + if (sc->bge_asicrev != BGE_ASICREV_BCM5705 && + sc->bge_asicrev != BGE_ASICREV_BCM5750) bge_free_rx_ring_jumbo(sc); /* Free TX buffers. */ diff --git a/sys/dev/bge/if_bgereg.h b/sys/dev/bge/if_bgereg.h index 66e103c3da57..e75a3bff114f 100644 --- a/sys/dev/bge/if_bgereg.h +++ b/sys/dev/bge/if_bgereg.h @@ -169,6 +169,10 @@ #define BGE_PCI_MSI_ADDR_LO 0x60 #define BGE_PCI_MSI_DATA 0x64 +/* PCI MSI. ??? */ +#define BGE_PCIE_CAPID_REG 0xD0 +#define BGE_PCIE_CAPID 0x10 + /* * PCI registers specific to the BCM570x family. */ @@ -233,6 +237,8 @@ #define BGE_CHIPID_BCM5705_A1 0x30010000 #define BGE_CHIPID_BCM5705_A2 0x30020000 #define BGE_CHIPID_BCM5705_A3 0x30030000 +#define BGE_CHIPID_BCM5750_A0 0x40000000 +#define BGE_CHIPID_BCM5750_A1 0x40010000 /* shorthand one */ #define BGE_ASICREV(x) ((x) >> 28) @@ -241,6 +247,7 @@ #define BGE_ASICREV_BCM5703 0x01 #define BGE_ASICREV_BCM5704 0x02 #define BGE_ASICREV_BCM5705 0x03 +#define BGE_ASICREV_BCM5750 0x04 /* chip revisions */ #define BGE_CHIPREV(x) ((x) >> 24) @@ -1860,6 +1867,9 @@ struct bge_status_block { #define BCOM_DEVICEID_BCM5705K 0x1654 #define BCOM_DEVICEID_BCM5705M 0x165D #define BCOM_DEVICEID_BCM5705M_ALT 0x165E +#define BCOM_DEVICEID_BCM5750 0x1676 +#define BCOM_DEVICEID_BCM5750M 0x167C +#define BCOM_DEVICEID_BCM5751 0x1677 #define BCOM_DEVICEID_BCM5782 0x1696 #define BCOM_DEVICEID_BCM5788 0x169C #define BCOM_DEVICEID_BCM5901 0x170D @@ -2316,6 +2326,7 @@ struct bge_softc { u_int8_t bge_asicrev; u_int8_t bge_chiprev; u_int8_t bge_no_3_led; + u_int8_t bge_pcie; struct bge_ring_data bge_ldata; /* rings */ struct bge_chain_data bge_cdata; /* mbufs */ u_int16_t bge_tx_saved_considx; |
