i dont have this hardware, so i can only test that it hasnt broken this chip:
bge0 at pci3 dev 4 function 0 "Broadcom BCM5714" rev 0xa3, BCM5715 A3 (0x9003): ivec 0x795, address 00:14:4f:a9:34:90 brgphy0 at bge0 phy 1: BCM5714 10/100/1000baseT/SX PHY, rev. 0 i need tests from any bge users willing to give it a spin to make sure it hasnt broken support for previous chips, in particular i need a BCM5717 test since this driver touches the conditionals around that one a lot. this is an intermediate diff on the way to BCM5720 support. Index: if_bge.c =================================================================== RCS file: /cvs/src/sys/dev/pci/if_bge.c,v retrieving revision 1.311 diff -u -p -r1.311 if_bge.c --- if_bge.c 4 Jul 2012 13:24:41 -0000 1.311 +++ if_bge.c 10 Sep 2012 12:53:31 -0000 @@ -305,6 +305,7 @@ const struct pci_matchid bge_devices[] = #define BGE_IS_5755_PLUS(sc) ((sc)->bge_flags & BGE_5755_PLUS) #define BGE_IS_5700_FAMILY(sc) ((sc)->bge_flags & BGE_5700_FAMILY) #define BGE_IS_5714_FAMILY(sc) ((sc)->bge_flags & BGE_5714_FAMILY) +#define BGE_IS_5717_PLUS(sc) ((sc)->bge_flags & BGE_5717_PLUS) #define BGE_IS_JUMBO_CAPABLE(sc) ((sc)->bge_flags & BGE_JUMBO_CAPABLE) static const struct bge_revision { @@ -400,6 +401,7 @@ static const struct bge_revision bge_maj { BGE_ASICREV_BCM5906, "unknown BCM5906" }, { BGE_ASICREV_BCM57780, "unknown BCM57780" }, { BGE_ASICREV_BCM5717, "unknown BCM5717" }, + { BGE_ASICREV_BCM5719, "unknown BCM5719" }, { BGE_ASICREV_BCM57765, "unknown BCM57765" }, { 0, NULL } @@ -1260,7 +1262,19 @@ bge_chipinit(struct bge_softc *sc) if (BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5703 || BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5704) dma_rw_ctl &= ~BGE_PCIDMARWCTL_MINDMA; - + if (BGE_IS_5717_PLUS(sc)) { + dma_rw_ctl &= ~BGE_PCIDMARWCTL_DIS_CACHE_ALIGNMENT; + if (sc->bge_chipid == BGE_CHIPID_BCM57765_A0) + dma_rw_ctl &= ~BGE_PCIDMARWCTL_CRDRDR_RDMA_MRRS_MSK; + /* + * Enable HW workaround for controllers that misinterpret + * a status tag update and leave interrupts permanently + * disabled. + */ + if (BGE_ASICREV(sc->bge_chipid) != BGE_ASICREV_BCM5717 && + BGE_ASICREV(sc->bge_chipid) != BGE_ASICREV_BCM57765) + dma_rw_ctl |= BGE_PCIDMARWCTL_TAGGED_STATUS_WA; + } pci_conf_write(pa->pa_pc, pa->pa_tag, BGE_PCI_DMA_RW_CTL, dma_rw_ctl); /* @@ -1318,7 +1332,7 @@ bge_blockinit(struct bge_softc *sc) vaddr_t rcb_addr; int i; bge_hostaddr taddr; - u_int32_t val; + u_int32_t dmactl, val; /* * Initialize the memory window pointer register so that @@ -1346,8 +1360,7 @@ bge_blockinit(struct bge_softc *sc) /* Configure mbuf pool watermarks */ /* new Broadcom docs strongly recommend these: */ - if (BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5717 || - BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM57765) { + if (BGE_IS_5717_PLUS(sc)) { CSR_WRITE_4(sc, BGE_BMAN_MBUFPOOL_READDMA_LOWAT, 0x0); CSR_WRITE_4(sc, BGE_BMAN_MBUFPOOL_MACRX_LOWAT, 0x2a); CSR_WRITE_4(sc, BGE_BMAN_MBUFPOOL_HIWAT, 0xa0); @@ -1372,8 +1385,16 @@ bge_blockinit(struct bge_softc *sc) CSR_WRITE_4(sc, BGE_BMAN_DMA_DESCPOOL_HIWAT, 10); /* Enable buffer manager */ - CSR_WRITE_4(sc, BGE_BMAN_MODE, - BGE_BMANMODE_ENABLE|BGE_BMANMODE_LOMBUF_ATTN); + val = BGE_BMANMODE_ENABLE | BGE_BMANMODE_LOMBUF_ATTN; + /* + * Change the arbitration algorithm of TXMBUF read request to + * round-robin instead of priority based for BCM5719. When + * TXFIFO is almost empty, RDMA will hold its request until + * TXFIFO is not almost empty. + */ + if (BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5719) + val |= BGE_BMANMODE_NO_TX_UNDERRUN; + CSR_WRITE_4(sc, BGE_BMAN_MODE, val); /* Poll for buffer manager start indication */ for (i = 0; i < 2000; i++) { @@ -1408,8 +1429,7 @@ bge_blockinit(struct bge_softc *sc) /* Initialize the standard RX ring control block */ rcb = &sc->bge_rdata->bge_info.bge_std_rx_rcb; BGE_HOSTADDR(rcb->bge_hostaddr, BGE_RING_DMA_ADDR(sc, bge_rx_std_ring)); - if (BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5717 || - BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM57765) + if (BGE_IS_5717_PLUS(sc)) rcb->bge_maxlen_flags = (BGE_RCB_MAXLEN_FLAGS(512, 0) | (ETHER_MAX_DIX_LEN << 2)); else if (BGE_IS_5705_PLUS(sc)) @@ -1417,7 +1437,11 @@ bge_blockinit(struct bge_softc *sc) else rcb->bge_maxlen_flags = BGE_RCB_MAXLEN_FLAGS(ETHER_MAX_DIX_LEN, 0); - rcb->bge_nicaddr = BGE_STD_RX_RINGS; + if (BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5717 || + BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5719) + rcb->bge_nicaddr = BGE_STD_RX_RINGS_5717; + else + rcb->bge_nicaddr = BGE_STD_RX_RINGS; CSR_WRITE_4(sc, BGE_RX_STD_RCB_HADDR_HI, rcb->bge_hostaddr.bge_addr_hi); CSR_WRITE_4(sc, BGE_RX_STD_RCB_HADDR_LO, rcb->bge_hostaddr.bge_addr_lo); CSR_WRITE_4(sc, BGE_RX_STD_RCB_MAXLEN_FLAGS, rcb->bge_maxlen_flags); @@ -1436,7 +1460,11 @@ bge_blockinit(struct bge_softc *sc) BGE_RING_DMA_ADDR(sc, bge_rx_jumbo_ring)); rcb->bge_maxlen_flags = BGE_RCB_MAXLEN_FLAGS(0, BGE_RCB_FLAG_USE_EXT_RX_BD | BGE_RCB_FLAG_RING_DISABLED); - rcb->bge_nicaddr = BGE_JUMBO_RX_RINGS; + if (BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5717 || + BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5719) + rcb->bge_nicaddr = BGE_JUMBO_RX_RINGS_5717; + else + rcb->bge_nicaddr = BGE_JUMBO_RX_RINGS; CSR_WRITE_4(sc, BGE_RX_JUMBO_RCB_HADDR_HI, rcb->bge_hostaddr.bge_addr_hi); @@ -1479,8 +1507,7 @@ bge_blockinit(struct bge_softc *sc) CSR_WRITE_4(sc, BGE_RBDI_STD_REPL_THRESH, 8); CSR_WRITE_4(sc, BGE_RBDI_JUMBO_REPL_THRESH, 8); - if (BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5717 || - BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM57765) { + if (BGE_IS_5717_PLUS(sc)) { CSR_WRITE_4(sc, BGE_STD_REPL_LWM, 4); CSR_WRITE_4(sc, BGE_JUMBO_REPL_LWM, 4); } @@ -1503,7 +1530,11 @@ bge_blockinit(struct bge_softc *sc) BGE_HOSTADDR(taddr, BGE_RING_DMA_ADDR(sc, bge_tx_ring)); RCB_WRITE_4(sc, rcb_addr, bge_hostaddr.bge_addr_hi, taddr.bge_addr_hi); RCB_WRITE_4(sc, rcb_addr, bge_hostaddr.bge_addr_lo, taddr.bge_addr_lo); - RCB_WRITE_4(sc, rcb_addr, bge_nicaddr, + if (BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5717 || + BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5719) + RCB_WRITE_4(sc, rcb_addr, bge_nicaddr, BGE_SEND_RING_5717); + else + RCB_WRITE_4(sc, rcb_addr, bge_nicaddr, BGE_NIC_TXRING_ADDR(0, BGE_TX_RING_CNT)); if (BGE_IS_5700_FAMILY(sc)) RCB_WRITE_4(sc, rcb_addr, bge_maxlen_flags, @@ -1686,6 +1717,40 @@ bge_blockinit(struct bge_softc *sc) if (sc->bge_flags & BGE_PCIE) val |= BGE_RDMAMODE_FIFO_LONG_BURST; + if (BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5761 || + BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5784 || + BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5785 || + BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM57780 || + BGE_IS_5717_PLUS(sc)) { + dmactl = CSR_READ_4(sc, BGE_RDMA_RSRVCTRL); + /* + * Adjust tx margin to prevent TX data corruption and + * fix internal FIFO overflow. + */ + if (BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5719) { + dmactl &= ~(BGE_RDMA_RSRVCTRL_FIFO_LWM_MASK | + BGE_RDMA_RSRVCTRL_FIFO_HWM_MASK | + BGE_RDMA_RSRVCTRL_TXMRGN_MASK); + dmactl |= BGE_RDMA_RSRVCTRL_FIFO_LWM_1_5K | + BGE_RDMA_RSRVCTRL_FIFO_HWM_1_5K | + BGE_RDMA_RSRVCTRL_TXMRGN_320B; + } + /* + * Enable fix for read DMA FIFO overruns. + * The fix is to limit the number of RX BDs + * the hardware would fetch at a fime. + */ + CSR_WRITE_4(sc, BGE_RDMA_RSRVCTRL, dmactl | + BGE_RDMA_RSRVCTRL_FIFO_OFLW_FIX); + } + + if (BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5719) { + CSR_WRITE_4(sc, BGE_RDMA_LSO_CRPTEN_CTRL, + CSR_READ_4(sc, BGE_RDMA_LSO_CRPTEN_CTRL) | + BGE_RDMA_LSO_CRPTEN_CTRL_BLEN_BD_4K | + BGE_RDMA_LSO_CRPTEN_CTRL_BLEN_LSO_4K); + } + /* Turn on read DMA state machine */ CSR_WRITE_4(sc, BGE_RDMA_MODE, val); @@ -1861,7 +1926,8 @@ bge_attach(struct device *parent, struct if (BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_USE_PRODID_REG) { if (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_BROADCOM_BCM5717 || - PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_BROADCOM_BCM5718) + PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_BROADCOM_BCM5718 || + PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_BROADCOM_BCM5719) sc->bge_chipid = pci_conf_read(pc, pa->pa_tag, BGE_PCI_GEN2_PRODID_ASICREV); else if (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_BROADCOM_BCM57761 || @@ -1918,6 +1984,11 @@ bge_attach(struct device *parent, struct sizeof(name)) > 0 && strcmp(name, "network") == 0) sc->bge_flags |= BGE_NO_EEPROM; #endif + if (BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5717 || + BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5719 || + BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM57765) + sc->bge_flags |= BGE_5717_PLUS; + if (BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5700 || BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5701 || BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5703 || @@ -1930,14 +2001,13 @@ bge_attach(struct device *parent, struct sc->bge_flags |= BGE_5714_FAMILY; /* Intentionally exclude BGE_ASICREV_BCM5906 */ - if (BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5717 || - BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5755 || + if (BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5755 || BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5761 || BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5784 || BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5785 || BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5787 || - BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM57765 || - BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM57780) + BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM57780 || + BGE_IS_5717_PLUS(sc)) sc->bge_flags |= BGE_5755_PLUS; if (BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5750 || @@ -2134,12 +2204,12 @@ bge_attach(struct device *parent, struct sc->bge_tx_max_coal_bds = 400; /* 5705 limits RX return ring to 512 entries. */ - if (BGE_IS_5700_FAMILY(sc) || - BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5717 || - BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM57765) + if (BGE_IS_5717_PLUS(sc)) sc->bge_return_ring_cnt = BGE_RETURN_RING_CNT; - else + else if (BGE_IS_5705_PLUS(sc)) sc->bge_return_ring_cnt = BGE_RETURN_RING_CNT_5705; + else + sc->bge_return_ring_cnt = BGE_RETURN_RING_CNT; /* Set up ifnet structure */ ifp = &sc->arpcom.ac_if; @@ -2493,10 +2563,9 @@ bge_reset(struct bge_softc *sc) } if (sc->bge_flags & BGE_PCIE && + !BGE_IS_5717_PLUS(sc) && sc->bge_chipid != BGE_CHIPID_BCM5750_A0 && - BGE_ASICREV(sc->bge_chipid) != BGE_ASICREV_BCM5717 && - BGE_ASICREV(sc->bge_chipid) != BGE_ASICREV_BCM5785 && - BGE_ASICREV(sc->bge_chipid) != BGE_ASICREV_BCM57765) { + BGE_ASICREV(sc->bge_chipid) != BGE_ASICREV_BCM5785) { u_int32_t v; /* Enable PCI Express bug fix */ Index: if_bgereg.h =================================================================== RCS file: /cvs/src/sys/dev/pci/if_bgereg.h,v retrieving revision 1.104 diff -u -p -r1.104 if_bgereg.h --- if_bgereg.h 15 Feb 2011 19:49:47 -0000 1.104 +++ if_bgereg.h 10 Sep 2012 12:53:31 -0000 @@ -92,6 +92,7 @@ #define BGE_UNMAPPED_END 0x00001FFF #define BGE_DMA_DESCRIPTORS 0x00002000 #define BGE_DMA_DESCRIPTORS_END 0x00003FFF +#define BGE_SEND_RING_5717 0x00004000 #define BGE_SEND_RING_1_TO_4 0x00004000 #define BGE_SEND_RING_1_TO_4_END 0x00005FFF @@ -106,6 +107,8 @@ #define BGE_BUFFPOOL_2_END 0x00017FFF #define BGE_BUFFPOOL_3 0x00018000 /* or expansion ROM */ #define BGE_BUFFPOOL_3_END 0x0001FFFF +#define BGE_STD_RX_RINGS_5717 0x00040000 +#define BGE_JUMBO_RX_RINGS_5717 0x00044400 /* Mappings for external SSRAM configurations */ #define BGE_SEND_RING_5_TO_6 0x00006000 @@ -306,6 +309,12 @@ #define BGE_CHIPID_BCM5906_A2 0xc002 #define BGE_CHIPID_BCM57780_A0 0x57780000 #define BGE_CHIPID_BCM57780_A1 0x57780001 +#define BGE_CHIPID_BCM5717_A0 0x05717000 +#define BGE_CHIPID_BCM5717_B0 0x05717100 +#define BGE_CHIPID_BCM5719_A0 0x05719000 +#define BGE_CHIPID_BCM5720_A0 0x05720000 +#define BGE_CHIPID_BCM57765_A0 0x57785000 +#define BGE_CHIPID_BCM57765_B0 0x57785100 /* shorthand one */ #define BGE_ASICREV(x) ((x) >> 12) @@ -328,6 +337,7 @@ #define BGE_ASICREV_BCM5785 0x5785 #define BGE_ASICREV_BCM57780 0x57780 #define BGE_ASICREV_BCM5717 0x5717 +#define BGE_ASICREV_BCM5719 0x5719 #define BGE_ASICREV_BCM57765 0x57785 /* chip revisions */ @@ -346,6 +356,7 @@ /* PCI DMA Read/Write Control register */ #define BGE_PCIDMARWCTL_MINDMA 0x000000FF +#define BGE_PCIDMARWCTL_DIS_CACHE_ALIGNMENT 0x00000001 #define BGE_PCIDMARWCTL_RDADRR_BNDRY 0x00000700 #define BGE_PCIDMARWCTL_WRADDR_BNDRY 0x00003800 #define BGE_PCIDMARWCTL_ONEDMA_ATONCE 0x0000C000 @@ -363,6 +374,9 @@ #define BGE_PCIDMARWCTL_RD_CMD_SHIFT(x) ((x) << 24) #define BGE_PCIDMARWCTL_WR_CMD_SHIFT(x) ((x) << 28) +#define BGE_PCIDMARWCTL_TAGGED_STATUS_WA 0x00000080 +#define BGE_PCIDMARWCTL_CRDRDR_RDMA_MRRS_MSK 0x00000380 + #define BGE_PCI_READ_BNDRY_DISABLE 0x00000000 #define BGE_PCI_READ_BNDRY_16BYTES 0x00000100 #define BGE_PCI_READ_BNDRY_32BYTES 0x00000200 @@ -1490,6 +1504,7 @@ #define BGE_BMANMODE_ATTN 0x00000004 #define BGE_BMANMODE_TESTMODE 0x00000008 #define BGE_BMANMODE_LOMBUF_ATTN 0x00000010 +#define BGE_BMANMODE_NO_TX_UNDERRUN 0x80000000 /* Buffer manager status register */ #define BGE_BMANSTAT_ERRO 0x00000004 @@ -1501,6 +1516,8 @@ */ #define BGE_RDMA_MODE 0x4800 #define BGE_RDMA_STATUS 0x4804 +#define BGE_RDMA_RSRVCTRL 0x4900 +#define BGE_RDMA_LSO_CRPTEN_CTRL 0x4910 /* Read DMA mode register */ #define BGE_RDMAMODE_RESET 0x00000001 @@ -1531,6 +1548,19 @@ #define BGE_RDMASTAT_PCI_FIFOOREAD_ATTN 0x00000100 #define BGE_RDMASTAT_LOCWRITE_TOOBIG 0x00000200 +/* Read DMA Reserved Control register */ +#define BGE_RDMA_RSRVCTRL_FIFO_OFLW_FIX 0x00000004 +#define BGE_RDMA_RSRVCTRL_FIFO_LWM_1_5K 0x00000C00 +#define BGE_RDMA_RSRVCTRL_FIFO_HWM_1_5K 0x000C0000 +#define BGE_RDMA_RSRVCTRL_TXMRGN_320B 0x28000000 +#define BGE_RDMA_RSRVCTRL_FIFO_LWM_MASK 0x00000FF0 +#define BGE_RDMA_RSRVCTRL_FIFO_HWM_MASK 0x000FF000 +#define BGE_RDMA_RSRVCTRL_TXMRGN_MASK 0xFFE00000 + +#define BGE_RDMA_LSO_CRPTEN_CTRL_BLEN_BD_512 0x00020000 +#define BGE_RDMA_LSO_CRPTEN_CTRL_BLEN_BD_4K 0x00030000 +#define BGE_RDMA_LSO_CRPTEN_CTRL_BLEN_LSO_4K 0x000C0000 + /* * Write DMA control registers */ @@ -2611,6 +2641,7 @@ struct bge_softc { #define BGE_5755_PLUS 0x00800000 #define BGE_5714_FAMILY 0x01000000 #define BGE_5700_FAMILY 0x02000000 +#define BGE_5717_PLUS 0x04000000 bus_dma_tag_t bge_dmatag; u_int32_t bge_chipid;