summaryrefslogtreecommitdiff
path: root/sys/dev/pci/if_bge.c
diff options
context:
space:
mode:
authorBrad Smith <brad@cvs.openbsd.org>2014-09-02 10:14:56 +0000
committerBrad Smith <brad@cvs.openbsd.org>2014-09-02 10:14:56 +0000
commitbac2e108929c270c1230ab140be13bddd46c25a4 (patch)
treef8afa9a901f4e5bdf29f6ecdd45900d9c218031b /sys/dev/pci/if_bge.c
parentd31a63c2e89ebcec9fa967f81bc07c7fd837c2f8 (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.c57
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. */