On Fri, Jan 18, 2013 at 09:00:25AM +1100, Darren Tucker wrote:
> Thanks to Mark Patruck for noticing that the previous patch didn't
> actually help, due to a bug I introduced in a last minute "obviously
> correct" clean up.

The turd polishing continues unabated.  This adds the interrupt disable
bit to descriptors where there's more than one mbuf in a packet.

Index: dev/pci/if_vr.c
===================================================================
RCS file: /cvs/src/sys/dev/pci/if_vr.c,v
retrieving revision 1.125
diff -u -p -r1.125 if_vr.c
--- dev/pci/if_vr.c     17 Jan 2013 21:49:48 -0000      1.125
+++ dev/pci/if_vr.c     18 Jan 2013 02:04:55 -0000
@@ -724,7 +724,7 @@ vr_list_tx_init(struct vr_softc *sc)
        cd = &sc->vr_cdata;
        ld = sc->vr_ldata;
 
-       cd->vr_tx_cnt = 0;
+       cd->vr_tx_cnt = cd->vr_tx_pkts = 0;
 
        for (i = 0; i < VR_TX_LIST_CNT; i++) {
                cd->vr_tx_chain[i].vr_ptr = &ld->vr_tx_list[i];
@@ -1198,7 +1198,7 @@ vr_encap(struct vr_softc *sc, struct vr_
        struct vr_chain         *c = *cp;
        struct vr_desc          *f = NULL;
        struct mbuf             *m_new = NULL;
-       u_int32_t               vr_ctl = 0, vr_status = 0;
+       u_int32_t               vr_ctl = 0, vr_status = 0, intdisable = 0;
        bus_dmamap_t            txmap;
        int                     i, runt = 0;
 
@@ -1259,6 +1259,15 @@ vr_encap(struct vr_softc *sc, struct vr_
        }
 #endif
 
+       /*
+        * We only want TX completion interrupts on every Nth packet.
+        * We need to set VR_TXNEXT_INTDISABLE on every descriptor except
+        * for the last discriptor of every Nth packet, where we set
+        * VR_TXCTL_FINT.
+        */
+       if (sc->vr_cdata.vr_tx_pkts++ % 8 != 0)
+               intdisable = VR_TXNEXT_INTDISABLE;
+
        if (m_new != NULL) {
                m_freem(m_head);
 
@@ -1276,7 +1285,7 @@ vr_encap(struct vr_softc *sc, struct vr_
                        f->vr_ctl |= htole32(VR_TXCTL_FIRSTFRAG);
                f->vr_status = htole32(vr_status);
                f->vr_data = htole32(txmap->dm_segs[i].ds_addr);
-               f->vr_next = htole32(c->vr_nextdesc->vr_paddr);
+               f->vr_next = htole32(c->vr_nextdesc->vr_paddr | intdisable);
                sc->vr_cdata.vr_tx_cnt++;
        }
 
@@ -1288,12 +1297,15 @@ vr_encap(struct vr_softc *sc, struct vr_
                    VR_TXCTL_TLINK | vr_ctl);
                f->vr_status = htole32(vr_status);
                f->vr_data = 
htole32(sc->sc_zeromap.vrm_map->dm_segs[0].ds_addr);
-               f->vr_next = htole32(c->vr_nextdesc->vr_paddr);
+               f->vr_next = htole32(c->vr_nextdesc->vr_paddr | intdisable);
                sc->vr_cdata.vr_tx_cnt++;
        }
 
        /* Set EOP on the last descriptor */
-       f->vr_ctl |= htole32(VR_TXCTL_LASTFRAG | VR_TXCTL_FINT);
+       f->vr_ctl |= htole32(VR_TXCTL_LASTFRAG);
+
+       if (!intdisable)
+               f->vr_ctl |= htole32(VR_TXCTL_FINT);
 
        return (0);
 }
@@ -1582,6 +1594,15 @@ vr_watchdog(struct ifnet *ifp)
        struct vr_softc         *sc;
 
        sc = ifp->if_softc;
+
+       /*
+        * Because we're only asking for completion interrupts only every
+        * few packets, occasionally the watchdog will fire when we have
+        * some TX descriptors to reclaim, so check for that first.
+        */
+       vr_txeof(sc);
+       if (sc->vr_cdata.vr_tx_cnt == 0);
+               return;
 
        ifp->if_oerrors++;
        printf("%s: watchdog timeout\n", sc->sc_dev.dv_xname);
Index: dev/pci/if_vrreg.h
===================================================================
RCS file: /cvs/src/sys/dev/pci/if_vrreg.h,v
retrieving revision 1.33
diff -u -p -r1.33 if_vrreg.h
--- dev/pci/if_vrreg.h  16 Jan 2013 05:25:57 -0000      1.33
+++ dev/pci/if_vrreg.h  18 Jan 2013 02:04:55 -0000
@@ -429,6 +429,9 @@ struct vr_desc {
 #define VR_TXCTL_LASTFRAG      0x00400000
 #define VR_TXCTL_FINT          0x00800000
 
+/* TDES3 aka vr_next */
+#define VR_TXNEXT_INTDISABLE   0x00000001
+
 #define VR_MAXFRAGS            8
 #define VR_RX_LIST_CNT         128
 #define VR_TX_LIST_CNT         128
@@ -467,6 +470,7 @@ struct vr_chain_data {
        struct vr_chain         *vr_tx_cons;
        struct vr_chain         *vr_tx_prod;
        int                     vr_tx_cnt;
+       int                     vr_tx_pkts;
 };
 
 struct vr_mii_frame {

-- 
Darren Tucker (dtucker at zip.com.au)
GPG key 8FF4FA69 / D9A3 86E9 7EEE AF4B B2D4  37C9 C982 80C7 8FF4 FA69
    Good judgement comes with experience. Unfortunately, the experience
usually comes from bad judgement.

Reply via email to