On Wed, Jun 15, 2011 at 07:39:12PM +0100, Stuart Henderson wrote: > On 2011/06/15 14:06, David Gwynne wrote: > > this is like the change i did for ix(4)... > > > Index: if_bnx.c > > can i have the if_bnxreg.h part too, please? :)
yes... 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 21:36:46 -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, Index: if_bnxreg.h =================================================================== RCS file: /cvs/src/sys/dev/pci/if_bnxreg.h,v retrieving revision 1.37 diff -u -p -r1.37 if_bnxreg.h --- if_bnxreg.h 20 Sep 2010 07:40:38 -0000 1.37 +++ if_bnxreg.h 15 Jun 2011 21:36:46 -0000 @@ -4867,6 +4867,7 @@ struct bnx_softc { int bnx_link; struct timeout bnx_timeout; + struct timeout rx_refill; /* Frame size and mbuf allocation size for RX frames. */ u_int32_t max_frame_size; @@ -5007,7 +5008,9 @@ struct bnx_softc { #ifdef BNX_DEBUG /* Track the number of enqueued mbufs. */ int tx_mbuf_alloc; +#endif int rx_mbuf_alloc; +#ifdef BNX_DEBUG /* Track the distribution buffer segments. */ u_int32_t rx_mbuf_segs[BNX_MAX_SEGMENTS+1];