rearrange txeof so it processes slots up to the index given in the
authorjmatthew <jmatthew@openbsd.org>
Thu, 23 Aug 2018 01:06:06 +0000 (01:06 +0000)
committerjmatthew <jmatthew@openbsd.org>
Thu, 23 Aug 2018 01:06:06 +0000 (01:06 +0000)
completion event, and only request completion events for the last packet
we place on the ring in bnxt_start, which doesn't do anything now but
will make tx faster when we get tx mitigation working.

sys/dev/pci/if_bnxt.c

index 3920c8b..ecf090d 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: if_bnxt.c,v 1.5 2018/08/23 00:22:53 jmatthew Exp $    */
+/*     $OpenBSD: if_bnxt.c,v 1.6 2018/08/23 01:06:06 jmatthew Exp $    */
 /*-
  * Broadcom NetXtreme-C/E network driver.
  *
@@ -1036,7 +1036,7 @@ bnxt_start(struct ifqueue *ifq)
        struct bnxt_slot *bs;
        bus_dmamap_t map;
        struct mbuf *m;
-       u_int idx, free, used;
+       u_int idx, free, used, laststart;
        uint16_t txflags;
        int i;
 
@@ -1086,7 +1086,9 @@ bnxt_start(struct ifqueue *ifq)
                        txflags = TX_BD_SHORT_FLAGS_LHINT_GTE2K;
 
                txflags |= TX_BD_SHORT_TYPE_TX_BD_SHORT |
+                   TX_BD_SHORT_FLAGS_NO_CMPL |
                    (map->dm_nsegs << TX_BD_SHORT_FLAGS_BD_CNT_SFT);
+               laststart = idx;
 
                for (i = 0; i < map->dm_nsegs; i++) {
                        txring[idx].flags_type = htole16(txflags);
@@ -1110,6 +1112,12 @@ bnxt_start(struct ifqueue *ifq)
                        sc->sc_tx_prod = 0;
        }
 
+       /* unset NO_CMPL on the first bd of the last packet */
+       if (used != 0) {
+               txring[laststart].flags_type &=
+                   ~htole16(TX_BD_SHORT_FLAGS_NO_CMPL);
+       }
+
        bnxt_write_tx_doorbell(sc, &sc->sc_tx_ring, idx);
        sc->sc_tx_ring_prod = idx;
 }
@@ -1784,31 +1792,34 @@ bnxt_txeof(struct bnxt_softc *sc, struct cmpl_base *cmpl)
        struct tx_cmpl *txcmpl = (struct tx_cmpl *)cmpl;
        struct bnxt_slot *bs;
        bus_dmamap_t map;
-       u_int idx, freed;
+       u_int idx, freed, segs, last;
 
-       if (txcmpl->opaque != sc->sc_tx_cons)
-               printf("%s: txeof for %d, expected %d?\n",
-                   DEVNAME(sc), txcmpl->opaque, sc->sc_tx_cons);
        idx = sc->sc_tx_ring_cons;
+       last = sc->sc_tx_cons;
+       freed = 0;
+       do {
+               bs = &sc->sc_tx_slots[sc->sc_tx_cons];
+               map = bs->bs_map;
+
+               segs = map->dm_nsegs;
+               bus_dmamap_sync(sc->sc_dmat, map, 0, map->dm_mapsize,
+                   BUS_DMASYNC_POSTWRITE);
+               bus_dmamap_unload(sc->sc_dmat, map);
+               m_freem(bs->bs_m);
+               bs->bs_m = NULL;
 
-       bs = &sc->sc_tx_slots[sc->sc_tx_cons];
-       map = bs->bs_map;
+               idx += segs;
+               freed += segs;
+               if (idx >= sc->sc_tx_ring.ring_size)
+                       idx -= sc->sc_tx_ring.ring_size;
 
-       freed = map->dm_nsegs;
-       bus_dmamap_sync(sc->sc_dmat, map, 0, map->dm_mapsize,
-           BUS_DMASYNC_POSTWRITE);
-       bus_dmamap_unload(sc->sc_dmat, map);
-       m_freem(bs->bs_m);
-       bs->bs_m = NULL;
+               last = sc->sc_tx_cons;
+               if (++sc->sc_tx_cons >= sc->sc_tx_ring.ring_size)
+                       sc->sc_tx_cons = 0;
 
-       idx += freed;
-       if (idx >= sc->sc_tx_ring.ring_size)
-               idx -= sc->sc_tx_ring.ring_size;
+       } while (last != txcmpl->opaque);
        sc->sc_tx_ring_cons = idx;
 
-       if (++sc->sc_tx_cons >= sc->sc_tx_ring.ring_size)
-               sc->sc_tx_cons = 0;
-
        return (freed);
 }