Greetings,

I've cleaned the diff a bit based on feedback from sthen@ & b...@.
Here it is:

? xl.diff
Index: xl.c
===================================================================
RCS file: /cvs/src/sys/dev/ic/xl.c,v
retrieving revision 1.96
diff -u -p -r1.96 xl.c
--- xl.c        7 Sep 2010 16:21:43 -0000       1.96
+++ xl.c        16 Sep 2010 09:59:41 -0000
@@ -153,7 +153,6 @@ void xl_stats_update(void *);
 int xl_encap(struct xl_softc *, struct xl_chain *,
     struct mbuf * );
 void xl_rxeof(struct xl_softc *);
-int xl_rx_resync(struct xl_softc *);
 void xl_txeof(struct xl_softc *);
 void xl_txeof_90xB(struct xl_softc *);
 void xl_txeoc(struct xl_softc *);
@@ -180,6 +179,7 @@ void xl_iff(struct xl_softc *);
 void xl_iff_90x(struct xl_softc *);
 void xl_iff_905b(struct xl_softc *);
 int xl_list_rx_init(struct xl_softc *);
+void xl_fill_rx_ring(struct xl_softc *);
 int xl_list_tx_init(struct xl_softc *);
 int xl_list_tx_init_90xB(struct xl_softc *);
 void xl_wait(struct xl_softc *);
@@ -1076,8 +1076,6 @@ xl_list_rx_init(struct xl_softc *sc)
        for (i = 0; i < XL_RX_LIST_CNT; i++) {
                cd->xl_rx_chain[i].xl_ptr =
                        (struct xl_list_onefrag *)&ld->xl_rx_list[i];
-               if (xl_newbuf(sc, &cd->xl_rx_chain[i]) == ENOBUFS)
-                       return(ENOBUFS);
                if (i == (XL_RX_LIST_CNT - 1))
                        n = 0;
                else
@@ -1088,11 +1086,30 @@ xl_list_rx_init(struct xl_softc *sc)
                ld->xl_rx_list[i].xl_next = htole32(next);
        }
 
-       cd->xl_rx_head = &cd->xl_rx_chain[0];
-
+       cd->xl_rx_prod = cd->xl_rx_cons = &cd->xl_rx_chain[0];
+       cd->xl_rx_cnt = 0;
+       xl_fill_rx_ring(sc);
        return (0);
 }
 
+void
+xl_fill_rx_ring(struct xl_softc *sc)
+{  
+        struct xl_chain_data    *cd;
+        struct xl_list_data     *ld;
+        
+        cd = &sc->xl_cdata;
+        ld = sc->xl_ldata;
+
+        while (cd->xl_rx_cnt < XL_RX_LIST_CNT) {
+                if (xl_newbuf(sc, cd->xl_rx_prod) == ENOBUFS)
+                        break;
+               cd->xl_rx_prod = cd->xl_rx_prod->xl_next;
+                cd->xl_rx_cnt++;
+        }
+}
+
+
 /*
  * Initialize an RX descriptor and attach an MBUF cluster.
  */
@@ -1102,13 +1119,9 @@ xl_newbuf(struct xl_softc *sc, struct xl
        struct mbuf     *m_new = NULL;
        bus_dmamap_t    map;
 
-       MGETHDR(m_new, M_DONTWAIT, MT_DATA);
-       if (m_new == NULL)
-               return (ENOBUFS);
-
-       MCLGET(m_new, M_DONTWAIT);
-       if (!(m_new->m_flags & M_EXT)) {
-               m_freem(m_new);
+       m_new = MCLGETI(NULL, M_DONTWAIT, &sc->sc_arpcom.ac_if, MCLBYTES);
+       
+       if (!m_new){
                return (ENOBUFS);
        }
 
@@ -1125,11 +1138,11 @@ xl_newbuf(struct xl_softc *sc, struct xl
                    0, c->map->dm_mapsize, BUS_DMASYNC_POSTREAD);
                bus_dmamap_unload(sc->sc_dmat, c->map);
        }
-
+       
        map = c->map;
        c->map = sc->sc_rx_sparemap;
        sc->sc_rx_sparemap = map;
-
+       
        /* Force longword alignment for packet payload. */
        m_adj(m_new, ETHER_ALIGN);
 
@@ -1150,32 +1163,6 @@ xl_newbuf(struct xl_softc *sc, struct xl
        return (0);
 }
 
-int
-xl_rx_resync(struct xl_softc *sc)
-{
-       struct xl_chain_onefrag *pos;
-       int i;
-
-       pos = sc->xl_cdata.xl_rx_head;
-
-       for (i = 0; i < XL_RX_LIST_CNT; i++) {
-               bus_dmamap_sync(sc->sc_dmat, sc->sc_listmap,
-                   ((caddr_t)pos->xl_ptr - sc->sc_listkva),
-                   sizeof(struct xl_list),
-                   BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
-
-               if (pos->xl_ptr->xl_status)
-                       break;
-               pos = pos->xl_next;
-       }
-
-       if (i == XL_RX_LIST_CNT)
-               return (0);
-
-       sc->xl_cdata.xl_rx_head = pos;
-
-       return (EAGAIN);
-}
 
 /*
  * A frame has been uploaded: pass the resulting mbuf chain up to
@@ -1195,12 +1182,14 @@ xl_rxeof(struct xl_softc *sc)
 
 again:
 
-       while ((rxstat = letoh32(sc->xl_cdata.xl_rx_head->xl_ptr->xl_status))
-           != 0) {
-               cur_rx = sc->xl_cdata.xl_rx_head;
-               sc->xl_cdata.xl_rx_head = cur_rx->xl_next;
+       while ((rxstat = letoh32(sc->xl_cdata.xl_rx_cons->xl_ptr->xl_status))
+           != 0 && sc->xl_cdata.xl_rx_cnt > 0) {
+               cur_rx = sc->xl_cdata.xl_rx_cons;
+                m = cur_rx->xl_mbuf;  
+                cur_rx->xl_mbuf = NULL;
+               sc->xl_cdata.xl_rx_cons = cur_rx->xl_next;
+               sc->xl_cdata.xl_rx_cnt--;
                total_len = rxstat & XL_RXSTAT_LENMASK;
-
                bus_dmamap_sync(sc->sc_dmat, sc->sc_listmap,
                    ((caddr_t)cur_rx->xl_ptr - sc->sc_listkva),
                    sizeof(struct xl_list),
@@ -1224,6 +1213,7 @@ again:
                if (rxstat & XL_RXSTAT_UP_ERROR) {
                        ifp->if_ierrors++;
                        cur_rx->xl_ptr->xl_status = htole32(0);
+                       m_freem(m);
                        continue;
                }
 
@@ -1237,22 +1227,7 @@ again:
                            "packet dropped\n", sc->sc_dev.dv_xname);
                        ifp->if_ierrors++;
                        cur_rx->xl_ptr->xl_status = htole32(0);
-                       continue;
-               }
-
-               /* No errors; receive the packet. */    
-               m = cur_rx->xl_mbuf;
-
-               /*
-                * Try to conjure up a new mbuf cluster. If that
-                * fails, it means we have an out of memory condition and
-                * should leave the buffer in place and continue. This will
-                * result in a lost packet, but there's little else we
-                * can do in this situation.
-                */
-               if (xl_newbuf(sc, cur_rx) == ENOBUFS) {
-                       ifp->if_ierrors++;
-                       cur_rx->xl_ptr->xl_status = htole32(0);
+                       m_freem(m);
                        continue;
                }
 
@@ -1286,7 +1261,7 @@ again:
 
                ether_input_mbuf(ifp, m);
        }
-
+       xl_fill_rx_ring(sc);
        /*
         * Handle the 'end of channel' condition. When the upload
         * engine hits the end of the RX ring, it will stall. This
@@ -1303,13 +1278,11 @@ again:
                CSR_READ_4(sc, XL_UPLIST_STATUS) & XL_PKTSTAT_UP_STALLED) {
                CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_UP_STALL);
                xl_wait(sc);
-               CSR_WRITE_4(sc, XL_UPLIST_PTR,
-                   sc->sc_listmap->dm_segs[0].ds_addr +
-                   offsetof(struct xl_list_data, xl_rx_list[0]));
-               sc->xl_cdata.xl_rx_head = &sc->xl_cdata.xl_rx_chain[0];
                CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_UP_UNSTALL);
+               xl_fill_rx_ring(sc);
                goto again;
        }
+
 }
 
 /*
@@ -1514,16 +1487,9 @@ xl_intr(void *arg)
                if (sc->intr_ack)
                        (*sc->intr_ack)(sc);
 
-               if (status & XL_STAT_UP_COMPLETE) {
-                       int curpkts;
-
-                       curpkts = ifp->if_ipackets;
+               if (status & XL_STAT_UP_COMPLETE)
                        xl_rxeof(sc);
-                       if (curpkts == ifp->if_ipackets) {
-                               while (xl_rx_resync(sc))
-                                       xl_rxeof(sc);
-                       }
-               }
+
 
                if (status & XL_STAT_DOWN_COMPLETE) {
                        if (sc->xl_type == XL_TYPE_905B)
@@ -2677,7 +2643,7 @@ xl_attach(struct xl_softc *sc)
         */
        if_attach(ifp);
        ether_ifattach(ifp);
-
+       m_clsetwms(ifp, MCLBYTES, 2, XL_RX_LIST_CNT - 1);
        sc->sc_sdhook = shutdownhook_establish(xl_shutdown, sc);
 }
 
Index: xlreg.h
===================================================================
RCS file: /cvs/src/sys/dev/ic/xlreg.h,v
retrieving revision 1.24
diff -u -p -r1.24 xlreg.h
--- xlreg.h     7 Sep 2010 16:21:43 -0000       1.24
+++ xlreg.h     16 Sep 2010 09:59:43 -0000
@@ -480,7 +480,10 @@ struct xl_chain_data {
        struct xl_chain_onefrag xl_rx_chain[XL_RX_LIST_CNT];
        struct xl_chain         xl_tx_chain[XL_TX_LIST_CNT];
 
-       struct xl_chain_onefrag *xl_rx_head;
+       struct xl_chain_onefrag *xl_rx_cons;
+        struct xl_chain_onefrag *xl_rx_prod;
+       int                     xl_rx_cnt;
+
 
        /* 3c90x "boomerang" queuing stuff */
        struct xl_chain         *xl_tx_head;


//Logan
C-x-C-c

Reply via email to