Hi,

I'd much appreciate testing with gigabit speed for this one. As usual,
Please do not hesitate to send feedback and comments.

Thanks,
Logan

Index: src/sys/dev/pci/if_stge.c
===================================================================
RCS file: /cvs/src/sys/dev/pci/if_stge.c,v
retrieving revision 1.52
diff -u -p -r1.52 if_stge.c
--- src/sys/dev/pci/if_stge.c   7 Dec 2009 15:31:07 -0000       1.52
+++ src/sys/dev/pci/if_stge.c   12 Dec 2010 18:15:21 -0000
@@ -93,6 +93,7 @@ void  stge_stop(struct ifnet *, int);
 
 void   stge_reset(struct stge_softc *);
 void   stge_rxdrain(struct stge_softc *);
+void   stge_fill_rx_ring(struct stge_softc *);
 int    stge_add_rxbuf(struct stge_softc *, int);
 void   stge_read_eeprom(struct stge_softc *, int, uint16_t *);
 void   stge_tick(void *);
@@ -291,7 +292,7 @@ stge_attach(struct device *parent, struc
        /*
         * Create the receive buffer DMA maps.
         */
-       for (i = 0; i < STGE_NRXDESC; i++) {
+       for (i = 0; i < STGE_NRXDESC ; i++) {
                if ((error = bus_dmamap_create(sc->sc_dmat, MCLBYTES, 1,
                    MCLBYTES, 0, 0, &sc->sc_rxsoft[i].ds_dmamap)) != 0) {
                        printf("%s: unable to create rx DMA map %d, "
@@ -385,7 +386,7 @@ stge_attach(struct device *parent, struc
 #endif
        IFQ_SET_MAXLEN(&ifp->if_snd, STGE_NTXDESC - 1);
        IFQ_SET_READY(&ifp->if_snd);
-
+       m_clsetwms(ifp, MCLBYTES, 4, STGE_NRXDESC - 1); 
        ifp->if_capabilities = IFCAP_VLAN_MTU;
 
 #if NVLAN > 0
@@ -763,13 +764,11 @@ stge_intr(void *arg)
                if (isr & (IS_RxDMAComplete|IS_RFDListEnd)) {
                        stge_rxintr(sc);
                        if (isr & IS_RFDListEnd) {
-                               printf("%s: receive ring overflow\n",
-                                   sc->sc_dev.dv_xname);
+                               ifp->if_ierrors++;
                                /*
                                 * XXX Should try to recover from this
                                 * XXX more gracefully.
                                 */
-                               wantinit = 1;
                        }
                }
 
@@ -878,7 +877,7 @@ stge_rxintr(struct stge_softc *sc)
        uint64_t status;
        int i, len;
 
-       for (i = sc->sc_rxptr;; i = STGE_NEXTRX(i)) {
+       for (i = sc->sc_rx_cons; sc->sc_rx_cnt > 0; i = STGE_NEXTRX(i)) {
                ds = &sc->sc_rxsoft[i];
 
                STGE_CDRXSYNC(sc, i,
@@ -889,8 +888,15 @@ stge_rxintr(struct stge_softc *sc)
                if ((status & RFD_RFDDone) == 0)
                        break;
 
+               bus_dmamap_sync(sc->sc_dmat, ds->ds_dmamap, 0,
+                       ds->ds_dmamap->dm_mapsize, BUS_DMASYNC_POSTREAD);
+               bus_dmamap_unload(sc->sc_dmat, ds->ds_dmamap);
+
+               m = ds->ds_mbuf;
+               ds->ds_mbuf = NULL;
+               sc->sc_rx_cnt--;
                if (__predict_false(sc->sc_rxdiscard)) {
-                       STGE_INIT_RXDESC(sc, i);
+                       m_freem(m);
                        if (status & RFD_FrameEnd) {
                                /* Reset our state. */
                                sc->sc_rxdiscard = 0;
@@ -898,30 +904,6 @@ stge_rxintr(struct stge_softc *sc)
                        continue;
                }
 
-               bus_dmamap_sync(sc->sc_dmat, ds->ds_dmamap, 0,
-                   ds->ds_dmamap->dm_mapsize, BUS_DMASYNC_POSTREAD);
-
-               m = ds->ds_mbuf;
-
-               /*
-                * Add a new receive buffer to the ring.
-                */
-               if (stge_add_rxbuf(sc, i) != 0) {
-                       /*
-                        * Failed, throw away what we've done so
-                        * far, and discard the rest of the packet.
-                        */
-                       ifp->if_ierrors++;
-                       bus_dmamap_sync(sc->sc_dmat, ds->ds_dmamap, 0,
-                           ds->ds_dmamap->dm_mapsize, BUS_DMASYNC_POSTREAD);
-                       STGE_INIT_RXDESC(sc, i);
-                       if ((status & RFD_FrameEnd) == 0)
-                               sc->sc_rxdiscard = 1;
-                       if (sc->sc_rxhead != NULL)
-                               m_freem(sc->sc_rxhead);
-                       STGE_RXCHAIN_RESET(sc);
-                       continue;
-               }
 
 #ifdef DIAGNOSTIC
                if (status & RFD_FrameStart) {
@@ -971,28 +953,6 @@ stge_rxintr(struct stge_softc *sc)
                tailm->m_len = len - sc->sc_rxlen;
 
                /*
-                * If the packet is small enough to fit in a
-                * single header mbuf, allocate one and copy
-                * the data into it.  This greatly reduces
-                * memory consumption when we receive lots
-                * of small packets.
-                */
-               if (stge_copy_small != 0 && len <= (MHLEN - 2)) {
-                       struct mbuf *nm;
-                       MGETHDR(nm, M_DONTWAIT, MT_DATA);
-                       if (nm == NULL) {
-                               ifp->if_ierrors++;
-                               m_freem(m);
-                               continue;
-                       }
-                       nm->m_data += 2;
-                       nm->m_pkthdr.len = nm->m_len = len;
-                       m_copydata(m, 0, len, mtod(nm, caddr_t));
-                       m_freem(m);
-                       m = nm;
-               }
-
-               /*
                 * Set the incoming checksum information for the packet.
                 */
                if ((status & RFD_IPDetected) &&
@@ -1030,7 +990,8 @@ stge_rxintr(struct stge_softc *sc)
        }
 
        /* Update the receive pointer. */
-       sc->sc_rxptr = i;
+       sc->sc_rx_cons = i;
+       stge_fill_rx_ring(sc);
 }
 
 /*
@@ -1131,8 +1092,7 @@ int
 stge_init(struct ifnet *ifp)
 {
        struct stge_softc *sc = ifp->if_softc;
-       struct stge_descsoft *ds;
-       int i, error = 0;
+       int i;
 
        /*
         * Cancel any pending I/O.
@@ -1161,26 +1121,12 @@ stge_init(struct ifnet *ifp)
         * Initialize the receive descriptor and receive job
         * descriptor rings.
         */
-       for (i = 0; i < STGE_NRXDESC; i++) {
-               ds = &sc->sc_rxsoft[i];
-               if (ds->ds_mbuf == NULL) {
-                       if ((error = stge_add_rxbuf(sc, i)) != 0) {
-                               printf("%s: unable to allocate or map rx "
-                                   "buffer %d, error = %d\n",
-                                   sc->sc_dev.dv_xname, i, error);
-                               /*
-                                * XXX Should attempt to run with fewer receive
-                                * XXX buffers instead of just failing.
-                                */
-                               stge_rxdrain(sc);
-                               goto out;
-                       }
-               } else
-                       STGE_INIT_RXDESC(sc, i);
-       }
-       sc->sc_rxptr = 0;
-       sc->sc_rxdiscard = 0;
+       sc->sc_rx_cons = sc->sc_rx_prod = sc->sc_rx_cnt = 0;
        STGE_RXCHAIN_RESET(sc);
+       for (i = 0; i < STGE_NRXDESC; i++)
+               STGE_INIT_RING_RXDESC(sc, i);
+       stge_fill_rx_ring(sc);
+       sc->sc_rxdiscard = 0;
 
        /* Set the station address. */
        if (sc->sc_stge1023) {
@@ -1219,7 +1165,7 @@ stge_init(struct ifnet *ifp)
 
        CSR_WRITE_4(sc, STGE_RFDListPtrHi, 0); /* NOTE: 32-bit DMA */
        CSR_WRITE_4(sc, STGE_RFDListPtrLo,
-           STGE_CDRXADDR(sc, sc->sc_rxptr));
+           STGE_CDRXADDR(sc, sc->sc_rx_cons));
 
        /*
         * Initialize the Tx auto-poll period.  It's OK to make this number
@@ -1332,10 +1278,7 @@ stge_init(struct ifnet *ifp)
        ifp->if_flags |= IFF_RUNNING;
        ifp->if_flags &= ~IFF_OACTIVE;
 
- out:
-       if (error)
-               printf("%s: interface not running\n", sc->sc_dev.dv_xname);
-       return (error);
+       return (0);
 }
 
 /*
@@ -1349,7 +1292,7 @@ stge_rxdrain(struct stge_softc *sc)
        struct stge_descsoft *ds;
        int i;
 
-       for (i = 0; i < STGE_NRXDESC; i++) {
+       for (i = 0; i < sc->sc_rx_cnt ; i++) {
                ds = &sc->sc_rxsoft[i];
                if (ds->ds_mbuf != NULL) {
                        bus_dmamap_unload(sc->sc_dmat, ds->ds_dmamap);
@@ -1358,8 +1301,18 @@ stge_rxdrain(struct stge_softc *sc)
                        ds->ds_mbuf = NULL;
                }
        }
+       sc->sc_rx_prod = sc->sc_rx_cons = sc->sc_rx_cnt = 0;
 }
 
+void
+stge_fill_rx_ring(struct stge_softc *sc)
+{
+       while(sc->sc_rx_cnt < STGE_NRXDESC) {
+               if(stge_add_rxbuf(sc, sc->sc_rx_prod) == ENOBUFS)
+                       break;
+       }
+}
+ 
 /*
  * stge_stop:          [ ifnet interface function ]
  *
@@ -1420,6 +1373,7 @@ stge_stop(struct ifnet *ifp, int disable
 
        if (disable)
                stge_rxdrain(sc);
+
 }
 
 static int
@@ -1468,16 +1422,10 @@ stge_add_rxbuf(struct stge_softc *sc, in
        struct mbuf *m;
        int error;
 
-       MGETHDR(m, M_DONTWAIT, MT_DATA);
-       if (m == NULL)
+       m = MCLGETI(NULL, M_DONTWAIT, &sc->sc_arpcom.ac_if, MCLBYTES);
+       if (!m)
                return (ENOBUFS);
 
-       MCLGET(m, M_DONTWAIT);
-       if ((m->m_flags & M_EXT) == 0) {
-               m_freem(m);
-               return (ENOBUFS);
-       }
-
        m->m_data = m->m_ext.ext_buf + 2;
        m->m_len = MCLBYTES - 2;
 
@@ -1487,7 +1435,7 @@ stge_add_rxbuf(struct stge_softc *sc, in
        ds->ds_mbuf = m;
 
        error = bus_dmamap_load(sc->sc_dmat, ds->ds_dmamap,
-           m->m_ext.ext_buf, m->m_ext.ext_size, NULL, BUS_DMA_NOWAIT);
+            m->m_ext.ext_buf, m->m_ext.ext_size, NULL, BUS_DMA_NOWAIT);
        if (error) {
                printf("%s: can't load rx DMA map %d, error = %d\n",
                    sc->sc_dev.dv_xname, idx, error);
@@ -1498,6 +1446,8 @@ stge_add_rxbuf(struct stge_softc *sc, in
            ds->ds_dmamap->dm_mapsize, BUS_DMASYNC_PREREAD);
 
        STGE_INIT_RXDESC(sc, idx);
+       sc->sc_rx_prod = STGE_NEXTRX(sc->sc_rx_prod);
+       sc->sc_rx_cnt++;
 
        return (0);
 }
Index: src/sys/dev/pci/if_stgereg.h
===================================================================
RCS file: /cvs/src/sys/dev/pci/if_stgereg.h,v
retrieving revision 1.11
diff -u -p -r1.11 if_stgereg.h
--- src/sys/dev/pci/if_stgereg.h        10 Aug 2009 19:41:05 -0000      1.11
+++ src/sys/dev/pci/if_stgereg.h        12 Dec 2010 18:15:22 -0000
@@ -478,6 +478,7 @@ struct stge_rfd {
  * Receive descriptor list size.
  */
 #define STGE_NRXDESC           256
+#define        STGE_NRXDESC_MIN        6
 #define STGE_NRXDESC_MASK      (STGE_NRXDESC - 1)
 #define STGE_NEXTRX(x)         (((x) + 1) & STGE_NRXDESC_MASK)
 
@@ -544,7 +545,7 @@ struct stge_softc {
        */
        struct stge_descsoft sc_txsoft[STGE_NTXDESC];
        struct stge_descsoft sc_rxsoft[STGE_NRXDESC];
-
+       u_int32_t sc_rx_cnt, sc_rx_prod, sc_rx_cons;
        /*
         * Control data structures.
        */
@@ -556,7 +557,6 @@ struct stge_softc {
        int     sc_txdirty;             /* first dirty Tx descriptor */
        int     sc_txlast;              /* last used Tx descriptor */
 
-       int     sc_rxptr;               /* next ready Rx descriptor/descsoft */
        int     sc_rxdiscard;
        int     sc_rxlen;
        struct mbuf *sc_rxhead;
@@ -610,10 +610,22 @@ do {                                                      
                \
        __rfd->rfd_frag.frag_word0 =                                    \
            htole64(FRAG_ADDR(__ds->ds_dmamap->dm_segs[0].ds_addr + 2) |\
            FRAG_LEN(MCLBYTES - 2));                                    \
-       __rfd->rfd_next =                                               \
-           htole64((uint64_t)STGE_CDRXADDR((sc), STGE_NEXTRX((x))));   \
        __rfd->rfd_status = 0;                                          \
        STGE_CDRXSYNC((sc), (x), BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE); \
+} while (/*CONSTCOND*/0)
+
+#define STGE_INIT_RING_RXDESC(sc, x)                                   \
+do {                                                                   \
+       struct stge_rfd *__rfd = &(sc)->sc_rxdescs[(x)];                \
+                                                                       \
+       if  (x < STGE_NRXDESC)                                          \
+               __rfd->rfd_next =                                       \
+               htole64((uint64_t)STGE_CDRXADDR((sc), STGE_NEXTRX((x))));\
+       else \
+               __rfd->rfd_next = \
+                htole64((uint64_t)STGE_CDRXADDR((sc), STGE_NEXTRX((-1))));\
+       __rfd->rfd_status = 0; \
+        STGE_CDRXSYNC((sc), (x), BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE); \
 } while (/*CONSTCOND*/0)
 
 #define STGE_TIMEOUT   1000

Reply via email to