diff options
author | Brad Smith <brad@cvs.openbsd.org> | 2014-09-02 10:14:56 +0000 |
---|---|---|
committer | Brad Smith <brad@cvs.openbsd.org> | 2014-09-02 10:14:56 +0000 |
commit | bac2e108929c270c1230ab140be13bddd46c25a4 (patch) | |
tree | f8afa9a901f4e5bdf29f6ecdd45900d9c218031b /sys/dev/pci/if_bge.c | |
parent | d31a63c2e89ebcec9fa967f81bc07c7fd837c2f8 (diff) |
Add Jumbo support for BCM5714 / BCM5780 and BCM5717 / BCM5719 / BCM5720 / BCM57765 / BCM57766
chipsets.
ok mikeb@ "i think it should go in" dlg@
Diffstat (limited to 'sys/dev/pci/if_bge.c')
-rw-r--r-- | sys/dev/pci/if_bge.c | 57 |
1 files changed, 41 insertions, 16 deletions
diff --git a/sys/dev/pci/if_bge.c b/sys/dev/pci/if_bge.c index 8ec4a8b1f42..da27a4bf94f 100644 --- a/sys/dev/pci/if_bge.c +++ b/sys/dev/pci/if_bge.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_bge.c,v 1.360 2014/08/26 11:01:21 mikeb Exp $ */ +/* $OpenBSD: if_bge.c,v 1.361 2014/09/02 10:14:55 brad Exp $ */ /* * Copyright (c) 2001 Wind River Systems @@ -1117,10 +1117,10 @@ bge_newbuf(struct bge_softc *sc, int i) struct mbuf *m; int error; - m = MCLGETI(NULL, M_DONTWAIT, NULL, MCLBYTES); + m = MCLGETI(NULL, M_DONTWAIT, NULL, sc->bge_rx_std_len); if (!m) return (ENOBUFS); - m->m_len = m->m_pkthdr.len = MCLBYTES; + m->m_len = m->m_pkthdr.len = sc->bge_rx_std_len; if (!(sc->bge_flags & BGE_RX_ALIGNBUG)) m_adj(m, ETHER_ALIGN); @@ -1241,8 +1241,8 @@ bge_init_rx_ring_std(struct bge_softc *sc) return (0); for (i = 0; i < BGE_STD_RX_RING_CNT; i++) { - if (bus_dmamap_create(sc->bge_dmatag, MCLBYTES, 1, MCLBYTES, 0, - BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW, + if (bus_dmamap_create(sc->bge_dmatag, sc->bge_rx_std_len, 1, + sc->bge_rx_std_len, 0, BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW, &sc->bge_cdata.bge_rx_std_map[i]) != 0) { printf("%s: unable to create dmamap for slot %d\n", sc->bge_dev.dv_xname, i); @@ -1485,6 +1485,7 @@ bge_init_tx_ring(struct bge_softc *sc) { int i; bus_dmamap_t dmamap; + bus_size_t txsegsz, txmaxsegsz; struct txdmamap_pool_entry *dma; if (sc->bge_flags & BGE_TXRING_VALID) @@ -1504,11 +1505,18 @@ bge_init_tx_ring(struct bge_softc *sc) if (BGE_CHIPREV(sc->bge_chipid) == BGE_CHIPREV_5700_BX) bge_writembx(sc, BGE_MBX_TX_NIC_PROD0_LO, 0); + if (BGE_IS_JUMBO_CAPABLE(sc)) { + txsegsz = 4096; + txmaxsegsz = BGE_JLEN; + } else { + txsegsz = MCLBYTES; + txmaxsegsz = MCLBYTES; + } + SLIST_INIT(&sc->txdma_list); for (i = 0; i < BGE_TX_RING_CNT; i++) { - if (bus_dmamap_create(sc->bge_dmatag, BGE_JLEN, - BGE_NTXSEG, BGE_JLEN, 0, BUS_DMA_NOWAIT, - &dmamap)) + if (bus_dmamap_create(sc->bge_dmatag, txmaxsegsz, + BGE_NTXSEG, txsegsz, 0, BUS_DMA_NOWAIT, &dmamap)) return (ENOBUFS); if (dmamap == NULL) panic("dmamap NULL in bge_init_tx_ring"); @@ -2001,7 +2009,7 @@ bge_blockinit(struct bge_softc *sc) * using this ring (i.e. once we set the MTU * high enough to require it). */ - if (BGE_IS_JUMBO_CAPABLE(sc)) { + if (sc->bge_flags & BGE_JUMBO_RING) { rcb = &sc->bge_rdata->bge_info.bge_jumbo_rx_rcb; BGE_HOSTADDR(rcb->bge_hostaddr, BGE_RING_DMA_ADDR(sc, bge_rx_jumbo_ring)); @@ -2065,7 +2073,7 @@ bge_blockinit(struct bge_softc *sc) * to work around HW bugs. */ CSR_WRITE_4(sc, BGE_RBDI_STD_REPL_THRESH, 8); - if (BGE_IS_JUMBO_CAPABLE(sc)) + if (sc->bge_flags & BGE_JUMBO_RING) CSR_WRITE_4(sc, BGE_RBDI_JUMBO_REPL_THRESH, 8); if (BGE_IS_5717_PLUS(sc)) { @@ -2699,7 +2707,8 @@ bge_attach(struct device *parent, struct device *self, void *aux) case BGE_ASICREV_BCM5719: case BGE_ASICREV_BCM5720: sc->bge_flags |= BGE_5717_PLUS | BGE_5755_PLUS | BGE_575X_PLUS | - BGE_5705_PLUS; + BGE_5705_PLUS | BGE_JUMBO_CAPABLE | BGE_JUMBO_RING | + BGE_JUMBO_FRAME; if (BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5719 || BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5720) { /* @@ -2707,6 +2716,13 @@ bge_attach(struct device *parent, struct device *self, void *aux) * of TXMBUF available space. */ sc->bge_flags |= BGE_RDMA_BUG; + + if (BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5719 && + sc->bge_chipid == BGE_CHIPID_BCM5719_A0) { + /* Jumbo frame on BCM5719 A0 does not work. */ + sc->bge_flags &= ~(BGE_JUMBO_CAPABLE | + BGE_JUMBO_RING | BGE_JUMBO_FRAME); + } } break; case BGE_ASICREV_BCM5755: @@ -2721,12 +2737,12 @@ bge_attach(struct device *parent, struct device *self, void *aux) case BGE_ASICREV_BCM5701: case BGE_ASICREV_BCM5703: case BGE_ASICREV_BCM5704: - sc->bge_flags |= BGE_5700_FAMILY | BGE_JUMBO_CAPABLE; + sc->bge_flags |= BGE_5700_FAMILY | BGE_JUMBO_CAPABLE | BGE_JUMBO_RING; break; case BGE_ASICREV_BCM5714_A0: case BGE_ASICREV_BCM5780: case BGE_ASICREV_BCM5714: - sc->bge_flags |= BGE_5714_FAMILY; + sc->bge_flags |= BGE_5714_FAMILY | BGE_JUMBO_CAPABLE | BGE_JUMBO_STD; /* FALLTHROUGH */ case BGE_ASICREV_BCM5750: case BGE_ASICREV_BCM5752: @@ -2738,6 +2754,11 @@ bge_attach(struct device *parent, struct device *self, void *aux) break; } + if (sc->bge_flags & BGE_JUMBO_STD) + sc->bge_rx_std_len = BGE_JLEN; + else + sc->bge_rx_std_len = MCLBYTES; + /* * When using the BCM5701 in PCI-X mode, data corruption has * been observed in the first few bytes of some received packets. @@ -4003,6 +4024,10 @@ bge_encap(struct bge_softc *sc, struct mbuf *m_head, u_int32_t *txidx) } } + if (sc->bge_flags & BGE_JUMBO_FRAME && + m_head->m_pkthdr.len > ETHER_MAX_LEN) + csum_flags |= BGE_TXBDFLAG_JUMBO_FRAME; + if (!(BGE_CHIPREV(sc->bge_chipid) == BGE_CHIPREV_5700_BX)) goto doit; @@ -4232,7 +4257,7 @@ bge_init(void *xsc) } /* Init Jumbo RX ring. */ - if (BGE_IS_JUMBO_CAPABLE(sc)) + if (sc->bge_flags & BGE_JUMBO_RING) bge_init_rx_ring_jumbo(sc); /* Init our RX return ring index */ @@ -4508,7 +4533,7 @@ bge_rxrinfo(struct bge_softc *sc, struct if_rxrinfo *ifri) memset(ifr, 0, sizeof(ifr)); if (ISSET(sc->bge_flags, BGE_RXRING_VALID)) { - ifr[n].ifr_size = MCLBYTES; + ifr[n].ifr_size = sc->bge_rx_std_len; strlcpy(ifr[n].ifr_name, "std", sizeof(ifr[n].ifr_name)); ifr[n].ifr_info = sc->bge_std_ring; @@ -4635,7 +4660,7 @@ bge_stop(struct bge_softc *sc) bge_free_rx_ring_std(sc); /* Free jumbo RX list. */ - if (BGE_IS_JUMBO_CAPABLE(sc)) + if (sc->bge_flags & BGE_JUMBO_RING) bge_free_rx_ring_jumbo(sc); /* Free TX buffers. */ |