proper ring size check when runt segment is added

Index: if_vr.c
===================================================================
RCS file: /cvs/src/sys/dev/pci/if_vr.c,v
retrieving revision 1.115
diff -u -r1.115 if_vr.c
--- if_vr.c     18 Sep 2012 14:49:44 -0000      1.115
+++ if_vr.c     5 Oct 2012 18:22:36 -0000
@@ -113,13 +113,16 @@
        NULL, "vr", DV_IFNET
 };
 
-int vr_encap(struct vr_softc *, struct vr_chain *, struct mbuf *);
+int vr_encap(struct vr_softc *, struct vr_chain **, struct mbuf *);
 void vr_rxeof(struct vr_softc *);
 void vr_rxeoc(struct vr_softc *);
 void vr_txeof(struct vr_softc *);
 void vr_tick(void *);
 void vr_rxtick(void *);
 int vr_intr(void *);
+int vr_dmamem_alloc(struct vr_softc *, struct vr_dmamem *,
+    bus_size_t, u_int);
+void vr_dmamem_free(struct vr_softc *, struct vr_dmamem *);
 void vr_start(struct ifnet *);
 int vr_ioctl(struct ifnet *, u_long, caddr_t);
 void vr_chipinit(struct vr_softc *);
@@ -481,6 +484,46 @@
        return(0);
 }
 
+int
+vr_dmamem_alloc(struct vr_softc *sc, struct vr_dmamem *vrm,
+    bus_size_t size, u_int align)
+{
+       vrm->vrm_size = size;
+
+       if (bus_dmamap_create(sc->sc_dmat, vrm->vrm_size, 1,
+           vrm->vrm_size, 0, BUS_DMA_WAITOK | BUS_DMA_ALLOCNOW,
+           &vrm->vrm_map) != 0)
+               return (1);
+       if (bus_dmamem_alloc(sc->sc_dmat, vrm->vrm_size,
+           align, 0, &vrm->vrm_seg, 1, &vrm->vrm_nsegs,
+           BUS_DMA_WAITOK | BUS_DMA_ZERO) != 0)
+               goto destroy;
+       if (bus_dmamem_map(sc->sc_dmat, &vrm->vrm_seg, vrm->vrm_nsegs,
+           vrm->vrm_size, &vrm->vrm_kva, BUS_DMA_WAITOK) != 0)
+               goto free;
+       if (bus_dmamap_load(sc->sc_dmat, vrm->vrm_map, vrm->vrm_kva,
+           vrm->vrm_size, NULL, BUS_DMA_WAITOK) != 0)
+               goto unmap;
+
+       return (0);
+ unmap:
+       bus_dmamem_unmap(sc->sc_dmat, vrm->vrm_kva, vrm->vrm_size);
+ free:
+       bus_dmamem_free(sc->sc_dmat, &vrm->vrm_seg, 1);
+ destroy:
+       bus_dmamap_destroy(sc->sc_dmat, vrm->vrm_map);
+       return (1);
+}
+
+void
+vr_dmamem_free(struct vr_softc *sc, struct vr_dmamem *vrm)
+{
+       bus_dmamap_unload(sc->sc_dmat, vrm->vrm_map);
+       bus_dmamem_unmap(sc->sc_dmat, vrm->vrm_kva, vrm->vrm_size);
+       bus_dmamem_free(sc->sc_dmat, &vrm->vrm_seg, 1);
+       bus_dmamap_destroy(sc->sc_dmat, vrm->vrm_map);
+}
+
 /*
  * Attach the interface. Allocate softc structures, do ifmedia
  * setup and ethernet/BPF attach.
@@ -497,8 +540,6 @@
        const char              *intrstr = NULL;
        struct ifnet            *ifp = &sc->arpcom.ac_if;
        bus_size_t              size;
-       int rseg;
-       caddr_t kva;
 
        /*
         * Handle power management nonsense.
@@ -555,7 +596,7 @@
        /* Allocate interrupt */
        if (pci_intr_map(pa, &ih)) {
                printf(": can't map interrupt\n");
-               goto fail_1;
+               goto fail;
        }
        intrstr = pci_intr_string(pc, ih);
        sc->sc_ih = pci_intr_establish(pc, ih, IPL_NET, vr_intr, sc,
@@ -565,7 +606,7 @@
                if (intrstr != NULL)
                        printf(" at %s", intrstr);
                printf("\n");
-               goto fail_1;
+               goto fail;
        }
        printf(": %s", intrstr);
 
@@ -593,29 +634,20 @@
        printf(", address %s\n", ether_sprintf(sc->arpcom.ac_enaddr));
 
        sc->sc_dmat = pa->pa_dmat;
-       if (bus_dmamem_alloc(sc->sc_dmat, sizeof(struct vr_list_data),
-           PAGE_SIZE, 0, &sc->sc_listseg, 1, &rseg,
-           BUS_DMA_NOWAIT | BUS_DMA_ZERO)) {
-               printf(": can't alloc list\n");
-               goto fail_2;
-       }
-       if (bus_dmamem_map(sc->sc_dmat, &sc->sc_listseg, rseg,
-           sizeof(struct vr_list_data), &kva, BUS_DMA_NOWAIT)) {
-               printf(": can't map dma buffers (%d bytes)\n",
-                   sizeof(struct vr_list_data));
-               goto fail_3;
-       }
-       if (bus_dmamap_create(sc->sc_dmat, sizeof(struct vr_list_data), 1,
-           sizeof(struct vr_list_data), 0, BUS_DMA_NOWAIT, &sc->sc_listmap)) {
-               printf(": can't create dma map\n");
-               goto fail_4;
-       }
-       if (bus_dmamap_load(sc->sc_dmat, sc->sc_listmap, kva,
-           sizeof(struct vr_list_data), NULL, BUS_DMA_NOWAIT)) {
-               printf(": can't load dma map\n");
-               goto fail_5;
+       if (vr_dmamem_alloc(sc, &sc->sc_zeromap, 64, PAGE_SIZE) != 0) {
+               printf(": failed to allocate zero pad memory\n");
+               return;
+       }
+       bzero(sc->sc_zeromap.vrm_kva, 64);
+       bus_dmamap_sync(sc->sc_dmat, sc->sc_zeromap.vrm_map, 0,
+           sc->sc_zeromap.vrm_map->dm_mapsize, BUS_DMASYNC_PREREAD);
+       if (vr_dmamem_alloc(sc, &sc->sc_listmap, sizeof(struct vr_list_data),
+           PAGE_SIZE) != 0) {
+               printf(": failed to allocate dma map\n");
+               goto free_zero;
        }
-       sc->vr_ldata = (struct vr_list_data *)kva;
+
+       sc->vr_ldata = (struct vr_list_data *)sc->sc_listmap.vrm_kva;
        sc->vr_quirks = vr_quirks(pa);
 
        ifp = &sc->arpcom.ac_if;
@@ -667,19 +699,11 @@
        ether_ifattach(ifp);
        return;
 
-fail_5:
-       bus_dmamap_destroy(sc->sc_dmat, sc->sc_listmap);
-
-fail_4:
-       bus_dmamem_unmap(sc->sc_dmat, kva, sizeof(struct vr_list_data));
-
-fail_3:
-       bus_dmamem_free(sc->sc_dmat, &sc->sc_listseg, rseg);
-
-fail_2:
-       pci_intr_disestablish(pc, sc->sc_ih);
-
-fail_1:
+free_zero:
+       bus_dmamap_sync(sc->sc_dmat, sc->sc_zeromap.vrm_map, 0,
+           sc->sc_zeromap.vrm_map->dm_mapsize, BUS_DMASYNC_POSTREAD);
+       vr_dmamem_free(sc, &sc->sc_zeromap);
+fail:
        bus_space_unmap(sc->vr_btag, sc->vr_bhandle, size);
 }
 
@@ -720,13 +744,17 @@
 
        cd = &sc->vr_cdata;
        ld = sc->vr_ldata;
+
+       cd->vr_tx_pkts = 0;
+       cd->vr_tx_cnt = 0;
+
        for (i = 0; i < VR_TX_LIST_CNT; i++) {
                cd->vr_tx_chain[i].vr_ptr = &ld->vr_tx_list[i];
                cd->vr_tx_chain[i].vr_paddr =
-                   sc->sc_listmap->dm_segs[0].ds_addr +
+                   sc->sc_listmap.vrm_map->dm_segs[0].ds_addr +
                    offsetof(struct vr_list_data, vr_tx_list[i]);
 
-               if (bus_dmamap_create(sc->sc_dmat, MCLBYTES, 1,
+               if (bus_dmamap_create(sc->sc_dmat, MCLBYTES * VR_MAXFRAGS, 
VR_MAXFRAGS,
                    MCLBYTES, 0, BUS_DMA_NOWAIT, &cd->vr_tx_chain[i].vr_map))
                        return (ENOBUFS);
 
@@ -769,7 +797,7 @@
                d = (struct vr_desc *)&ld->vr_rx_list[i];
                cd->vr_rx_chain[i].vr_ptr = d;
                cd->vr_rx_chain[i].vr_paddr =
-                   sc->sc_listmap->dm_segs[0].ds_addr +
+                   sc->sc_listmap.vrm_map->dm_segs[0].ds_addr +
                    offsetof(struct vr_list_data, vr_rx_list[i]);
 
                if (i == (VR_RX_LIST_CNT - 1))
@@ -779,7 +807,7 @@
 
                cd->vr_rx_chain[i].vr_nextdesc = &cd->vr_rx_chain[nexti];
                ld->vr_rx_list[i].vr_next =
-                   htole32(sc->sc_listmap->dm_segs[0].ds_addr +
+                   htole32(sc->sc_listmap.vrm_map->dm_segs[0].ds_addr +
                    offsetof(struct vr_list_data, vr_rx_list[nexti]));
        }
 
@@ -826,8 +854,8 @@
        ifp = &sc->arpcom.ac_if;
 
        while(sc->vr_cdata.vr_rx_cnt > 0) {
-               bus_dmamap_sync(sc->sc_dmat, sc->sc_listmap,
-                   0, sc->sc_listmap->dm_mapsize,
+               bus_dmamap_sync(sc->sc_dmat, sc->sc_listmap.vrm_map,
+                   0, sc->sc_listmap.vrm_map->dm_mapsize,
                    BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
                rxstat = letoh32(sc->vr_cdata.vr_rx_cons->vr_ptr->vr_status);
                if (rxstat & VR_RXSTAT_OWN)
@@ -930,8 +958,8 @@
 
        vr_fill_rx_ring(sc);
 
-       bus_dmamap_sync(sc->sc_dmat, sc->sc_listmap,
-           0, sc->sc_listmap->dm_mapsize,
+       bus_dmamap_sync(sc->sc_dmat, sc->sc_listmap.vrm_map,
+           0, sc->sc_listmap.vrm_map->dm_mapsize,
            BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
 }
 
@@ -984,11 +1012,13 @@
         * frames that have been transmitted.
         */
        cur_tx = sc->vr_cdata.vr_tx_cons;
-       while(cur_tx->vr_mbuf != NULL) {
-               u_int32_t               txstat;
+       while (cur_tx != sc->vr_cdata.vr_tx_prod) {
+           
+               u_int32_t               txstat, txctl;
                int                     i;
 
                txstat = letoh32(cur_tx->vr_ptr->vr_status);
+               txctl = letoh32(cur_tx->vr_ptr->vr_ctl);
 
                if ((txstat & VR_TXSTAT_ABRT) ||
                    (txstat & VR_TXSTAT_UDF)) {
@@ -1002,7 +1032,7 @@
                                sc->vr_flags |= VR_F_RESTART;
                                break;
                        }
-                       VR_TXOWN(cur_tx) = htole32(VR_TXSTAT_OWN);
+                       cur_tx->vr_ptr->vr_status = htole32(VR_TXSTAT_OWN);
                        CSR_WRITE_4(sc, VR_TXADDR, cur_tx->vr_paddr);
                        break;
                }
@@ -1010,6 +1040,11 @@
                if (txstat & VR_TXSTAT_OWN)
                        break;
 
+               sc->vr_cdata.vr_tx_cnt--;
+               /* Only the first descriptor in the chain is valid. */
+               if ((txctl & VR_TXCTL_FIRSTFRAG) == 0)
+                       goto next;
+
                if (txstat & VR_TXSTAT_ERRSUM) {
                        ifp->if_oerrors++;
                        if (txstat & VR_TXSTAT_DEFER)
@@ -1028,11 +1063,12 @@
                cur_tx->vr_mbuf = NULL;
                ifp->if_flags &= ~IFF_OACTIVE;
 
+next:
                cur_tx = cur_tx->vr_nextdesc;
        }
 
        sc->vr_cdata.vr_tx_cons = cur_tx;
-       if (cur_tx->vr_mbuf == NULL)
+       if (sc->vr_cdata.vr_tx_cnt == 0)
                ifp->if_timer = 0;
 }
 
@@ -1164,23 +1200,26 @@
  * pointers to the fragment pointers.
  */
 int
-vr_encap(struct vr_softc *sc, struct vr_chain *c, struct mbuf *m_head)
+vr_encap(struct vr_softc *sc, struct vr_chain **cp, struct mbuf *m_head)
 {
+       struct vr_chain         *c = *cp;
        struct vr_desc          *f = NULL;
        struct mbuf             *m_new = NULL;
-       u_int32_t               vr_flags = 0, vr_status = 0;
+       u_int32_t               vr_ctl = 0, vr_status = 0;
+       bus_dmamap_t            txmap;
+       int                     i, runt = 0;
 
        if (sc->vr_quirks & VR_Q_CSUM) {
                if (m_head->m_pkthdr.csum_flags & M_IPV4_CSUM_OUT)
-                       vr_flags |= VR_TXCTL_IPCSUM;
+                       vr_ctl |= VR_TXCTL_IPCSUM;
                if (m_head->m_pkthdr.csum_flags & M_TCP_CSUM_OUT)
-                       vr_flags |= VR_TXCTL_TCPCSUM;
+                       vr_ctl |= VR_TXCTL_TCPCSUM;
                if (m_head->m_pkthdr.csum_flags & M_UDP_CSUM_OUT)
-                       vr_flags |= VR_TXCTL_UDPCSUM;
+                       vr_ctl |= VR_TXCTL_UDPCSUM;
        }
 
+       /* Deep copy for chips that need alignment, or too many segments */
        if (sc->vr_quirks & VR_Q_NEEDALIGN ||
-           m_head->m_pkthdr.len < VR_MIN_FRAMELEN ||
            bus_dmamap_load_mbuf(sc->sc_dmat, c->vr_map, m_head,
                                 BUS_DMA_NOWAIT | BUS_DMA_WRITE)) {
                MGETHDR(m_new, M_DONTWAIT, MT_DATA);
@@ -1197,44 +1236,69 @@
                    mtod(m_new, caddr_t));
                m_new->m_pkthdr.len = m_new->m_len = m_head->m_pkthdr.len;
 
-               /*
-                * The Rhine chip doesn't auto-pad, so we have to make
-                * sure to pad short frames out to the minimum frame length
-                * ourselves.
-                */
-               if (m_head->m_pkthdr.len < VR_MIN_FRAMELEN) {
-                       /* data field should be padded with octets of zero */
-                       bzero(&m_new->m_data[m_new->m_len],
-                           VR_MIN_FRAMELEN-m_new->m_len);
-                       m_new->m_pkthdr.len += VR_MIN_FRAMELEN - m_new->m_len;
-                       m_new->m_len = m_new->m_pkthdr.len;
-               }
-
                if (bus_dmamap_load_mbuf(sc->sc_dmat, c->vr_map, m_new,
                    BUS_DMA_NOWAIT | BUS_DMA_WRITE)) {
                        m_freem(m_new);
-                       return (1);
+                       return(ENOBUFS);
                }
+               c->vr_mbuf = m_new;
+       } else {
+               c->vr_mbuf = m_head;
        }
 
        bus_dmamap_sync(sc->sc_dmat, c->vr_map, 0, c->vr_map->dm_mapsize,
            BUS_DMASYNC_PREWRITE);
 
-       if (m_new != NULL) {
+       if (c->vr_map->dm_mapsize < VR_MIN_FRAMELEN)
+               runt = 1;
+       /* Check number of available descriptors */
+       if (sc->vr_cdata.vr_tx_cnt + c->vr_map->dm_nsegs + runt >=
+           (VR_TX_LIST_CNT - 1)) {
+               printf("vr_tx_cnt %i dm_nsegs %i\n", sc->vr_cdata.vr_tx_cnt, 
c->vr_map->dm_nsegs);
+               bus_dmamap_unload(sc->sc_dmat, c->vr_map);
+               if (m_new)
+                       m_freem(m_new);
+               return(ENOBUFS);
+       }
+       if (m_new)
                m_freem(m_head);
 
-               c->vr_mbuf = m_new;
-       } else
-               c->vr_mbuf = m_head;
-
-       f = c->vr_ptr;
-       f->vr_data = htole32(c->vr_map->dm_segs[0].ds_addr);
-       f->vr_ctl = htole32(c->vr_map->dm_mapsize);
-       f->vr_ctl |= htole32(vr_flags|VR_TXCTL_TLINK|VR_TXCTL_FIRSTFRAG);
-       f->vr_status = htole32(vr_status);
+       txmap = c->vr_map;
+       for (i = 0; i < txmap->dm_nsegs; i++) {
+               if (i != 0)
+                       *cp = c = c->vr_nextdesc;
+               f = c->vr_ptr;
+               f->vr_ctl = htole32(txmap->dm_segs[i].ds_len | VR_TXCTL_TLINK |
+                   vr_ctl);
+               if (i == 0)
+                       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);
+               sc->vr_cdata.vr_tx_cnt++;
+       }
+
+       /* Pad runt frames */
+       if (runt) {
+               *cp = c = c->vr_nextdesc;
+               f = c->vr_ptr;
+               f->vr_ctl = htole32((VR_MIN_FRAMELEN - txmap->dm_mapsize) |
+                   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);
+               sc->vr_cdata.vr_tx_cnt++;
+       }
 
-       f->vr_ctl |= htole32(VR_TXCTL_LASTFRAG|VR_TXCTL_FINT);
-       f->vr_next = htole32(c->vr_nextdesc->vr_paddr);
+       /*
+        * Set EOP on the last desciptor and request Tx completion
+        * interrupt for every VR_TX_INTR_THRESH-th frames
+        */
+       VR_INC(sc->vr_cdata.vr_tx_pkts, VR_TX_INTR_THRESH);
+       if (sc->vr_cdata.vr_tx_pkts == 0)
+               f->vr_ctl |= htole32(VR_TXCTL_LASTFRAG | VR_TXCTL_FINT);
+       else
+               f->vr_ctl |= htole32(VR_TXCTL_LASTFRAG);
 
        return (0);
 }
@@ -1251,7 +1315,7 @@
 {
        struct vr_softc         *sc;
        struct mbuf             *m_head;
-       struct vr_chain         *cur_tx;
+       struct vr_chain         *cur_tx, *head_tx;
 
        sc = ifp->if_softc;
 
@@ -1265,7 +1329,8 @@
                        break;
 
                /* Pack the data into the descriptor. */
-               if (vr_encap(sc, cur_tx, m_head)) {
+               head_tx = cur_tx;
+               if (vr_encap(sc, &cur_tx, m_head)) {
                        /* Rollback, send what we were able to encap. */
                        if (ALTQ_IS_ENABLED(&ifp->if_snd))
                                m_freem(m_head);
@@ -1274,7 +1339,8 @@
                        break;
                }
 
-               VR_TXOWN(cur_tx) = htole32(VR_TXSTAT_OWN);
+               /* Only set ownership bit on first descriptor */
+               head_tx->vr_ptr->vr_status |= htole32(VR_TXSTAT_OWN);
 
 #if NBPFILTER > 0
                /*
@@ -1282,16 +1348,16 @@
                 * to him.
                 */
                if (ifp->if_bpf)
-                       bpf_mtap_ether(ifp->if_bpf, cur_tx->vr_mbuf,
+                       bpf_mtap_ether(ifp->if_bpf, head_tx->vr_mbuf,
                        BPF_DIRECTION_OUT);
 #endif
                cur_tx = cur_tx->vr_nextdesc;
        }
-       if (cur_tx != sc->vr_cdata.vr_tx_prod || cur_tx->vr_mbuf != NULL) {
+       if (sc->vr_cdata.vr_tx_cnt != 0) {
                sc->vr_cdata.vr_tx_prod = cur_tx;
 
-               bus_dmamap_sync(sc->sc_dmat, sc->sc_listmap, 0,
-                   sc->sc_listmap->dm_mapsize,
+               bus_dmamap_sync(sc->sc_dmat, sc->sc_listmap.vrm_map, 0,
+                   sc->sc_listmap.vrm_map->dm_mapsize,
                    BUS_DMASYNC_PREWRITE|BUS_DMASYNC_PREREAD);
 
                /* Tell the chip to start transmitting. */
@@ -1405,7 +1471,7 @@
                                    VR_CMD_TX_ON|VR_CMD_RX_ON|
                                    VR_CMD_RX_GO);
 
-       CSR_WRITE_4(sc, VR_TXADDR, sc->sc_listmap->dm_segs[0].ds_addr +
+       CSR_WRITE_4(sc, VR_TXADDR, sc->sc_listmap.vrm_map->dm_segs[0].ds_addr +
            offsetof(struct vr_list_data, vr_tx_list[0]));
 
        /*
@@ -1514,6 +1580,15 @@
 
        sc = ifp->if_softc;
 
+       /*
+        * Reclaim first as we don't request interrupt for every packet.
+        */
+       printf("vr_watchdog vr_tx_cnt %i\n",sc->vr_cdata.vr_tx_cnt);
+       vr_txeof(sc);
+       printf("vr_watchdog vr_tx_cnt %i (after 
txeof)\n",sc->vr_cdata.vr_tx_cnt);
+       if (sc->vr_cdata.vr_tx_cnt == 0)
+               return;
+
        ifp->if_oerrors++;
        printf("%s: watchdog timeout\n", sc->sc_dev.dv_xname);
        vr_init(sc);
@@ -1653,13 +1728,13 @@
        d->vr_data = htole32(r->vr_map->dm_segs[0].ds_addr);
        d->vr_ctl = htole32(VR_RXCTL | VR_RXLEN);
 
-       bus_dmamap_sync(sc->sc_dmat, sc->sc_listmap, 0,
-           sc->sc_listmap->dm_mapsize, BUS_DMASYNC_PREWRITE);
+       bus_dmamap_sync(sc->sc_dmat, sc->sc_listmap.vrm_map, 0,
+           sc->sc_listmap.vrm_map->dm_mapsize, BUS_DMASYNC_PREWRITE);
 
        d->vr_status = htole32(VR_RXSTAT);
 
-       bus_dmamap_sync(sc->sc_dmat, sc->sc_listmap, 0,
-           sc->sc_listmap->dm_mapsize,
+       bus_dmamap_sync(sc->sc_dmat, sc->sc_listmap.vrm_map, 0,
+           sc->sc_listmap.vrm_map->dm_mapsize,
            BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
 
        return (0);
Index: if_vrreg.h
===================================================================
RCS file: /cvs/src/sys/dev/pci/if_vrreg.h,v
retrieving revision 1.30
diff -u -r1.30 if_vrreg.h
--- if_vrreg.h  5 Jan 2012 19:08:25 -0000       1.30
+++ if_vrreg.h  5 Oct 2012 18:22:36 -0000
@@ -417,13 +417,14 @@
 #define VR_TXCTL_LASTFRAG      0x00400000
 #define VR_TXCTL_FINT          0x00800000
 
-#define VR_MAXFRAGS            16
-#define VR_RX_LIST_CNT         64
+#define VR_MAXFRAGS            8
+#define VR_TX_INTR_THRESH      8
+#define VR_RX_LIST_CNT         128
 #define VR_TX_LIST_CNT         128
 #define VR_MIN_FRAMELEN                60
 #define VR_RXLEN               1524
 
-#define VR_TXOWN(x)            x->vr_ptr->vr_status
+#define VR_INC(x,y)            (x) = (((x) + 1) % y)
 
 struct vr_list_data {
        struct vr_desc          vr_rx_list[VR_RX_LIST_CNT];
@@ -456,6 +457,8 @@
 
        struct vr_chain         *vr_tx_cons;
        struct vr_chain         *vr_tx_prod;
+       int                     vr_tx_cnt;
+       int                     vr_tx_pkts;
 };
 
 struct vr_mii_frame {
@@ -479,6 +482,14 @@
 #define VR_FLAG_SCHEDDELAY     2
 #define VR_FLAG_DELAYTIMEO     3       
 
+struct vr_dmamem {
+       bus_dmamap_t            vrm_map;
+       bus_dma_segment_t       vrm_seg;
+       int                     vrm_nsegs;
+       size_t                  vrm_size;
+       caddr_t                 vrm_kva;
+};
+
 struct vr_softc {
        struct device           sc_dev;         /* generic device structure */
        pci_chipset_tag_t       sc_pc;          /* PCI registers info */
@@ -496,8 +507,8 @@
        struct mii_data         sc_mii;
        struct timeout          sc_to;
        struct timeout          sc_rxto;
-       bus_dmamap_t            sc_listmap;     /* descriptor list map */
-       bus_dma_segment_t       sc_listseg;
+       struct vr_dmamem        sc_listmap;     /* descriptor list map */
+       struct vr_dmamem        sc_zeromap;     /* zero pad map */
        int                     sc_rxbufs;
        int                     vr_link;
        int                     vr_quirks;

Reply via email to