Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/dev/ic - use IFQ_POLL/DEQUEUE rather than IF_DEQUEUE/PRE...



details:   https://anonhg.NetBSD.org/src/rev/2985c178a6e7
branches:  trunk
changeset: 579877:2985c178a6e7
user:      yamt <yamt%NetBSD.org@localhost>
date:      Wed Mar 30 11:38:06 2005 +0000

description:
- use IFQ_POLL/DEQUEUE rather than IF_DEQUEUE/PREPEND.
- handle tx queue full correctly.

diffstat:

 sys/dev/ic/rtl8169.c |  47 ++++++++++++++++++++++++++++++++---------------
 1 files changed, 32 insertions(+), 15 deletions(-)

diffs (114 lines):

diff -r 51cda4d16be7 -r 2985c178a6e7 sys/dev/ic/rtl8169.c
--- a/sys/dev/ic/rtl8169.c      Wed Mar 30 11:09:16 2005 +0000
+++ b/sys/dev/ic/rtl8169.c      Wed Mar 30 11:38:06 2005 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: rtl8169.c,v 1.16 2005/03/29 09:52:31 yamt Exp $        */
+/*     $NetBSD: rtl8169.c,v 1.17 2005/03/30 11:38:06 yamt Exp $        */
 
 /*
  * Copyright (c) 1997, 1998-2003
@@ -1308,13 +1308,17 @@
            0, sc->rtk_ldata.rtk_tx_list_map->dm_mapsize,
            BUS_DMASYNC_POSTREAD);
 
-       while (idx != sc->rtk_ldata.rtk_txq_prodidx) {
+       while (/* CONSTCOND */ 1) {
                struct rtk_txq *txq = &sc->rtk_ldata.rtk_txq[idx];
-               int descidx = txq->txq_descidx;
+               int descidx;
                u_int32_t txstat;
 
-               KASSERT(txq->txq_mbuf != NULL);
+               if (txq->txq_mbuf == NULL) {
+                       KASSERT(idx == sc->rtk_ldata.rtk_txq_prodidx);
+                       break;
+               }
 
+               descidx = txq->txq_descidx;
                txstat =
                    le32toh(sc->rtk_ldata.rtk_tx_list[descidx].rtk_cmdstat);
                KASSERT((txstat & RTK_TDESC_CMD_EOF) != 0);
@@ -1511,8 +1515,9 @@
        u_int32_t               cmdstat, rtk_flags;
        struct rtk_txq          *txq;
 
-       if (sc->rtk_ldata.rtk_tx_free <= 4)
+       if (sc->rtk_ldata.rtk_tx_free <= 4) {
                return EFBIG;
+       }
 
        /*
         * Set up checksum offload. Note: checksum offload bits must
@@ -1653,41 +1658,55 @@
 re_start(struct ifnet *ifp)
 {
        struct rtk_softc        *sc;
-       struct mbuf             *m_head = NULL;
        int                     idx;
 
        sc = ifp->if_softc;
 
        idx = sc->rtk_ldata.rtk_txq_prodidx;
-       while (sc->rtk_ldata.rtk_txq[idx].txq_mbuf == NULL) {
+       while (/* CONSTCOND */ 1) {
+               struct mbuf *m;
                int error;
 
-               IF_DEQUEUE(&ifp->if_snd, m_head);
-               if (m_head == NULL)
+               IFQ_POLL(&ifp->if_snd, m);
+               if (m == NULL)
                        break;
 
-               error = re_encap(sc, m_head, &idx);
+               if (sc->rtk_ldata.rtk_txq[idx].txq_mbuf != NULL) {
+                       KASSERT(idx == sc->rtk_ldata.rtk_txq_considx);
+                       ifp->if_flags |= IFF_OACTIVE;
+                       break;
+               }
+
+               error = re_encap(sc, m, &idx);
                if (error == EFBIG &&
                    sc->rtk_ldata.rtk_tx_free == RTK_TX_DESC_CNT(sc)) {
+                       IFQ_DEQUEUE(&ifp->if_snd, m);
+                       m_freem(m);
                        ifp->if_oerrors++;
-                       m_freem(m_head);
                        continue;
                }
                if (error) {
-                       IF_PREPEND(&ifp->if_snd, m_head);
                        ifp->if_flags |= IFF_OACTIVE;
                        break;
                }
+
+               IFQ_DEQUEUE(&ifp->if_snd, m);
+
 #if NBPFILTER > 0
                /*
                 * If there's a BPF listener, bounce a copy of this frame
                 * to him.
                 */
                if (ifp->if_bpf)
-                       bpf_mtap(ifp->if_bpf, m_head);
+                       bpf_mtap(ifp->if_bpf, m);
 #endif
        }
 
+       if (sc->rtk_ldata.rtk_txq_prodidx == idx) {
+               return;
+       }
+       sc->rtk_ldata.rtk_txq_prodidx = idx;
+
        /* Flush the TX descriptors */
 
        bus_dmamap_sync(sc->sc_dmat,
@@ -1695,8 +1714,6 @@
            0, sc->rtk_ldata.rtk_tx_list_map->dm_mapsize,
            BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
 
-       sc->rtk_ldata.rtk_txq_prodidx = idx;
-
        /*
         * RealTek put the TX poll request register in a different
         * location on the 8169 gigE chip. I don't know why.



Home | Main Index | Thread Index | Old Index