this is like the change i did for ix(4)...
Index: if_bnx.c
===================================================================
RCS file: /cvs/src/sys/dev/pci/if_bnx.c,v
retrieving revision 1.94
diff -u -p -r1.94 if_bnx.c
--- if_bnx.c 18 Apr 2011 04:27:31 -0000 1.94
+++ if_bnx.c 15 Jun 2011 04:05:28 -0000
@@ -363,7 +363,8 @@ int bnx_get_buf(struct bnx_softc *, u_in
int bnx_init_tx_chain(struct bnx_softc *);
void bnx_init_tx_context(struct bnx_softc *);
-void bnx_fill_rx_chain(struct bnx_softc *);
+void bnx_fill_rx_chain(struct bnx_softc *, int);
+void bnx_refill_rx_chain(void *);
void bnx_init_rx_context(struct bnx_softc *);
int bnx_init_rx_chain(struct bnx_softc *);
void bnx_free_rx_chain(struct bnx_softc *);
@@ -933,6 +934,7 @@ bnx_attachhook(void *xsc)
ether_ifattach(ifp);
timeout_set(&sc->bnx_timeout, bnx_tick, sc);
+ timeout_set(&sc->rx_refill, bnx_refill_rx_chain, sc);
/* Print some important debugging info. */
DBRUN(BNX_INFO, bnx_dump_driver_state(sc));
@@ -3233,6 +3235,7 @@ bnx_stop(struct bnx_softc *sc)
DBPRINT(sc, BNX_VERBOSE_RESET, "Entering %s()\n", __FUNCTION__);
timeout_del(&sc->bnx_timeout);
+ timeout_del(&sc->rx_refill);
ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
@@ -3706,6 +3709,7 @@ bnx_get_buf(struct bnx_softc *sc, u_int1
* last rx_bd entry so that rx_mbuf_ptr and rx_mbuf_map matches)
* and update our counter.
*/
+ sc->rx_mbuf_alloc++;
sc->rx_mbuf_ptr[*chain_prod] = m;
sc->rx_mbuf_map[first_chain_prod] = sc->rx_mbuf_map[*chain_prod];
sc->rx_mbuf_map[*chain_prod] = map;
@@ -3981,10 +3985,11 @@ bnx_init_rx_context(struct bnx_softc *sc
/* Nothing */
/****************************************************************************/
void
-bnx_fill_rx_chain(struct bnx_softc *sc)
+bnx_fill_rx_chain(struct bnx_softc *sc, int offset)
{
u_int16_t prod, chain_prod;
u_int32_t prod_bseq;
+ int refill = 0;
#ifdef BNX_DEBUG
int rx_mbuf_alloc_before, free_rx_bd_before;
#endif
@@ -4007,6 +4012,7 @@ bnx_fill_rx_chain(struct bnx_softc *sc)
break;
}
prod = NEXT_RX_BD(prod);
+ refill = 1;
}
#if 0
@@ -4016,17 +4022,33 @@ bnx_fill_rx_chain(struct bnx_softc *sc)
(free_rx_bd_before - sc->free_rx_bd)));
#endif
- /* Save the RX chain producer index. */
- sc->rx_prod = prod;
- sc->rx_prod_bseq = prod_bseq;
-
- /* Tell the chip about the waiting rx_bd's. */
- REG_WR16(sc, MB_RX_CID_ADDR + BNX_L2CTX_HOST_BDIDX, sc->rx_prod);
- REG_WR(sc, MB_RX_CID_ADDR + BNX_L2CTX_HOST_BSEQ, sc->rx_prod_bseq);
+ if (refill) {
+ /* Save the RX chain producer index. */
+ sc->rx_prod = prod;
+ sc->rx_prod_bseq = prod_bseq;
+
+ /* Tell the chip about the waiting rx_bd's. */
+ REG_WR16(sc, MB_RX_CID_ADDR + BNX_L2CTX_HOST_BDIDX,
+ sc->rx_prod);
+ REG_WR(sc, MB_RX_CID_ADDR + BNX_L2CTX_HOST_BSEQ,
+ sc->rx_prod_bseq);
+ } else if (sc->rx_mbuf_alloc < 2)
+ timeout_add(&sc->rx_refill, offset);
DBPRINT(sc, BNX_EXCESSIVE_RECV, "Exiting %s()\n", __FUNCTION__);
}
+void
+bnx_refill_rx_chain(void *xsc)
+{
+ struct bnx_softc *sc = xsc;
+ int s;
+
+ s = splnet();
+ bnx_fill_rx_chain(sc, 1);
+ splx(s);
+}
+
/****************************************************************************/
/* Allocate memory and initialize the RX data structures. */
/* */
@@ -4071,7 +4093,7 @@ bnx_init_rx_chain(struct bnx_softc *sc)
}
/* Fill up the RX chain. */
- bnx_fill_rx_chain(sc);
+ bnx_fill_rx_chain(sc, 1);
for (i = 0; i < RX_PAGES; i++)
bus_dmamap_sync(sc->bnx_dmatag, sc->rx_bd_chain_map[i], 0,
@@ -4120,7 +4142,7 @@ bnx_free_rx_chain(struct bnx_softc *sc)
}
m_freem(sc->rx_mbuf_ptr[i]);
sc->rx_mbuf_ptr[i] = NULL;
- DBRUNIF(1, sc->rx_mbuf_alloc--);
+ sc->rx_mbuf_alloc--;
}
}
@@ -4335,6 +4357,7 @@ bnx_rx_intr(struct bnx_softc *sc)
/* Remove the mbuf from RX chain. */
m = sc->rx_mbuf_ptr[sw_chain_cons];
sc->rx_mbuf_ptr[sw_chain_cons] = NULL;
+ sc->rx_mbuf_alloc--;
/*
* Frames received on the NetXteme II are prepended
@@ -4483,7 +4506,6 @@ bnx_rx_int_next_rx:
DBPRINT(sc, BNX_VERBOSE_RECV,
"%s(): Passing received frame up.\n", __FUNCTION__);
ether_input_mbuf(ifp, m);
- DBRUNIF(1, sc->rx_mbuf_alloc--);
sw_cons = sc->rx_cons;
}
@@ -4506,7 +4528,7 @@ bnx_rx_int_next_rx:
/* No new packets to process. Refill the RX chain and exit. */
sc->rx_cons = sw_cons;
- bnx_fill_rx_chain(sc);
+ bnx_fill_rx_chain(sc, 0);
for (i = 0; i < RX_PAGES; i++)
bus_dmamap_sync(sc->bnx_dmatag,