diff options
author | Michael Shalayeff <mickey@cvs.openbsd.org> | 2006-09-26 13:10:45 +0000 |
---|---|---|
committer | Michael Shalayeff <mickey@cvs.openbsd.org> | 2006-09-26 13:10:45 +0000 |
commit | 682237ddd2445accd36330968288990de1ef4de2 (patch) | |
tree | 63215f75514516b326bc363ed3750f1bec658564 /sys | |
parent | f436e67a7cb1b8184f336c3876b08ddbbcce4dad (diff) |
do not alloc jumbo buffers (3.5m per iface) and also do not allow card to receive large frames until mtu is set to higher value (later piece from brad); brad@ ok
Diffstat (limited to 'sys')
-rw-r--r-- | sys/dev/pci/if_bge.c | 54 |
1 files changed, 33 insertions, 21 deletions
diff --git a/sys/dev/pci/if_bge.c b/sys/dev/pci/if_bge.c index baf152c492d..a74efbe3ddd 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.180 2006/09/17 23:31:07 brad Exp $ */ +/* $OpenBSD: if_bge.c,v 1.181 2006/09/26 13:10:44 mickey Exp $ */ /* * Copyright (c) 2001 Wind River Systems @@ -581,6 +581,10 @@ bge_alloc_jumbo_mem(struct bge_softc *sc) int i, rseg, state, error; struct bge_jpool_entry *entry; + /* Check to see if Jumbo memory is already allocated */ + if (sc->bge_cdata.bge_jumbo_buf) + return (0); + state = error = 0; /* Grab a big chunk o' storage. */ @@ -633,6 +637,7 @@ bge_alloc_jumbo_mem(struct bge_softc *sc) entry = malloc(sizeof(struct bge_jpool_entry), M_DEVBUF, M_NOWAIT); if (entry == NULL) { + sc->bge_cdata.bge_jumbo_buf = NULL; printf("%s: no memory for jumbo buffer queue!\n", sc->bge_dev.dv_xname); error = ENOBUFS; @@ -1211,6 +1216,7 @@ int bge_blockinit(struct bge_softc *sc) { volatile struct bge_rcb *rcb; + struct ifnet *ifp = &sc->arpcom.ac_if; vaddr_t rcb_addr; int i; bge_hostaddr taddr; @@ -1246,9 +1252,16 @@ bge_blockinit(struct bge_softc *sc) /* Configure mbuf pool watermarks */ /* new Broadcom docs strongly recommend these: */ if (!(BGE_IS_5705_OR_BEYOND(sc))) { - CSR_WRITE_4(sc, BGE_BMAN_MBUFPOOL_READDMA_LOWAT, 0x50); - CSR_WRITE_4(sc, BGE_BMAN_MBUFPOOL_MACRX_LOWAT, 0x20); - CSR_WRITE_4(sc, BGE_BMAN_MBUFPOOL_HIWAT, 0x60); + if (ifp->if_mtu > ETHER_MAX_LEN) { + CSR_WRITE_4(sc, BGE_BMAN_MBUFPOOL_READDMA_LOWAT, 0x50); + CSR_WRITE_4(sc, BGE_BMAN_MBUFPOOL_MACRX_LOWAT, 0x20); + CSR_WRITE_4(sc, BGE_BMAN_MBUFPOOL_HIWAT, 0x60); + } else { + /* Values from Linux driver... */ + CSR_WRITE_4(sc, BGE_BMAN_MBUFPOOL_READDMA_LOWAT, 304); + CSR_WRITE_4(sc, BGE_BMAN_MBUFPOOL_MACRX_LOWAT, 152); + CSR_WRITE_4(sc, BGE_BMAN_MBUFPOOL_HIWAT, 380); + } } else { CSR_WRITE_4(sc, BGE_BMAN_MBUFPOOL_READDMA_LOWAT, 0x0); CSR_WRITE_4(sc, BGE_BMAN_MBUFPOOL_MACRX_LOWAT, 0x10); @@ -1868,16 +1881,6 @@ bge_attach(struct device *parent, struct device *self, void *aux) bzero(sc->bge_rdata, sizeof(struct bge_ring_data)); - /* - * Try to allocate memory for Jumbo buffers. - */ - if (BGE_IS_JUMBO_CAPABLE(sc)) { - if (bge_alloc_jumbo_mem(sc)) { - printf(": jumbo buffer allocation failed\n"); - goto fail_5; - } - } - /* Set default tuneable values. */ sc->bge_stat_ticks = BGE_TICKS_PER_SEC; sc->bge_rx_coal_ticks = 150; @@ -2827,6 +2830,17 @@ bge_init(void *xsc) bge_chipinit(sc); /* + * Try to allocate memory for Jumbo buffers. + */ + if (BGE_IS_JUMBO_CAPABLE(sc) && ifp->if_mtu > ETHERMTU && + bge_alloc_jumbo_mem(sc)) { + printf("%s: jumbo buffer allocation failed\n", + sc->bge_dev.dv_xname); + splx(s); + return; + } + + /* * Init the various state machines, ring * control blocks and firmware. */ @@ -2839,12 +2853,8 @@ bge_init(void *xsc) ifp = &sc->arpcom.ac_if; /* Specify MRU. */ - if (BGE_IS_JUMBO_CAPABLE(sc)) - CSR_WRITE_4(sc, BGE_RX_MTU, - BGE_JUMBO_FRAMELEN + ETHER_VLAN_ENCAP_LEN); - else - CSR_WRITE_4(sc, BGE_RX_MTU, - ETHER_MAX_LEN + ETHER_VLAN_ENCAP_LEN); + CSR_WRITE_4(sc, BGE_RX_MTU, ifp->if_mtu + + ETHER_HDR_LEN + ETHER_CRC_LEN + ETHER_VLAN_ENCAP_LEN); /* Load our MAC address. */ m = (u_int16_t *)&sc->arpcom.ac_enaddr[0]; @@ -3039,8 +3049,10 @@ bge_ioctl(struct ifnet *ifp, u_long command, caddr_t data) case SIOCSIFMTU: if (ifr->ifr_mtu < ETHERMIN || ifr->ifr_mtu > ifp->if_hardmtu) error = EINVAL; - else if (ifp->if_mtu != ifr->ifr_mtu) + else if (ifp->if_mtu != ifr->ifr_mtu) { ifp->if_mtu = ifr->ifr_mtu; + bge_init(sc); + } break; case SIOCSIFFLAGS: if (ifp->if_flags & IFF_UP) { |