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;