i wrote this diff blind, so it may not compile or work.

the intention is to check for space before attempting to dequeue a
packet. the rest is largely cosmetic and makes it look more like
a decent driver.

could someone test please?

Index: sxie.c
===================================================================
RCS file: /cvs/src/sys/arch/armv7/sunxi/sxie.c,v
retrieving revision 1.25
diff -u -p -r1.25 sxie.c
--- sxie.c      22 Jan 2017 10:17:37 -0000      1.25
+++ sxie.c      31 May 2017 07:08:55 -0000
@@ -439,16 +439,15 @@ sxie_intr(void *arg)
        }
 
        if (pending & (SXIE_TX_FIFO0 | SXIE_TX_FIFO1)) {
-               ifq_clr_oactive(&ifp->if_snd);
                sc->txf_inuse &= ~pending;
                if (sc->txf_inuse == 0)
                        ifp->if_timer = 0;
                else
                        ifp->if_timer = 5;
-       }
 
-       if (ifp->if_flags & IFF_RUNNING && !IFQ_IS_EMPTY(&ifp->if_snd))
-               sxie_start(ifp);
+               if (ifq_is_oactive(&ifp->if_snd))
+                       ifq_restart(&ifp->if_snd);
+       }
 
        SXISET4(sc, SXIE_INTCR, SXIE_INTR_ENABLE);
 
@@ -468,65 +467,59 @@ sxie_start(struct ifnet *ifp)
        uint32_t fifo;
        uint32_t txbuf[SXIE_MAX_PKT_SIZE / sizeof(uint32_t)]; /* XXX !!! */
 
-       if (sc->txf_inuse == (SXIE_TX_FIFO0 | SXIE_TX_FIFO1))
-               ifq_set_oactive(&ifp->if_snd);
-
        if (!(ifp->if_flags & IFF_RUNNING) || ifq_is_oactive(&ifp->if_snd))
                return;
 
+
        td = (uint8_t *)&txbuf[0];
        m = NULL;
        head = NULL;
-trynext:
-       m = ifq_deq_begin(&ifp->if_snd);
-       if (m == NULL)
-               return;
-
-       if (m->m_pkthdr.len > SXIE_MAX_PKT_SIZE) {
-               ifq_deq_commit(&ifp->if_snd, m);
-               printf("sxie_start: packet too big\n");
-               m_freem(m);
-               return;
-       }
 
-       if (sc->txf_inuse == (SXIE_TX_FIFO0 | SXIE_TX_FIFO1)) {
-               ifq_deq_rollback(&ifp->if_snd, m);
-               printf("sxie_start: tx fifos in use.\n");
-               ifq_set_oactive(&ifp->if_snd);
-               return;
-       }
-
-       /* select fifo */
-       if (sc->txf_inuse & SXIE_TX_FIFO0) {
-               sc->txf_inuse |= SXIE_TX_FIFO1;
-               fifo = 1;
-       } else {
-               sc->txf_inuse |= SXIE_TX_FIFO0;
-               fifo = 0;
-       }
-       SXIWRITE4(sc, SXIE_TXINS, fifo);
-
-       /* set packet length */
-       SXIWRITE4(sc, SXIE_TXPKTLEN0 + (fifo * 4), m->m_pkthdr.len);
-
-       /* copy the actual packet to fifo XXX through 'align buffer'.. */
-       m_copydata(m, 0, m->m_pkthdr.len, (caddr_t)td);
-       bus_space_write_multi_4(sc->sc_iot, sc->sc_ioh,
-           SXIE_TXIO0 + (fifo * 4),
-           (uint32_t *)td, SXIE_ROUNDUP(m->m_pkthdr.len, 4) >> 2);
-
-       /* transmit to PHY from fifo */
-       SXISET4(sc, SXIE_TXCR0 + (fifo * 4), 1);
-       ifp->if_timer = 5;
-       ifq_deq_commit(&ifp->if_snd, m);
+       for (;;) {
+               if (sc->txf_inuse == (SXIE_TX_FIFO0 | SXIE_TX_FIFO1)) {
+                       ifq_set_oactive(&ifp->if_snd);
+                       break;
+               }
+
+               m = ifq_dequeue(&ifp->if_snd);
+               if (m == NULL)
+                       break;
+
+               if (m->m_pkthdr.len > SXIE_MAX_PKT_SIZE) {
+                       m_freem(m);
+                       continue;
+               }
 
 #if NBPFILTER > 0
-       if (ifp->if_bpf)
-               bpf_mtap(ifp->if_bpf, m, BPF_DIRECTION_OUT);
+               if (ifp->if_bpf)
+                       bpf_mtap(ifp->if_bpf, m, BPF_DIRECTION_OUT);
 #endif
-       m_freem(m);
 
-       goto trynext;
+               /* select fifo */
+               if (sc->txf_inuse & SXIE_TX_FIFO0) {
+                       sc->txf_inuse |= SXIE_TX_FIFO1;
+                       fifo = 1;
+               } else {
+                       sc->txf_inuse |= SXIE_TX_FIFO0;
+                       fifo = 0;
+               }
+               SXIWRITE4(sc, SXIE_TXINS, fifo);
+
+               /* set packet length */
+               SXIWRITE4(sc, SXIE_TXPKTLEN0 + (fifo * 4), m->m_pkthdr.len);
+
+               /* copy the actual packet to fifo XXX through 'align buffer' */
+               m_copydata(m, 0, m->m_pkthdr.len, (caddr_t)td);
+               bus_space_write_multi_4(sc->sc_iot, sc->sc_ioh,
+                   SXIE_TXIO0 + (fifo * 4),
+                   (uint32_t *)td, SXIE_ROUNDUP(m->m_pkthdr.len, 4) >> 2);
+
+               /* transmit to PHY from fifo */
+               SXISET4(sc, SXIE_TXCR0 + (fifo * 4), 1);
+               ifp->if_timer = 5;
+
+               m_freem(m);
+       }
 }
 
 void

Reply via email to