summaryrefslogtreecommitdiff
path: root/sys/dev/pci
diff options
context:
space:
mode:
authorMichael Shalayeff <mickey@cvs.openbsd.org>2006-09-26 13:10:45 +0000
committerMichael Shalayeff <mickey@cvs.openbsd.org>2006-09-26 13:10:45 +0000
commit682237ddd2445accd36330968288990de1ef4de2 (patch)
tree63215f75514516b326bc363ed3750f1bec658564 /sys/dev/pci
parentf436e67a7cb1b8184f336c3876b08ddbbcce4dad (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/dev/pci')
-rw-r--r--sys/dev/pci/if_bge.c54
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) {