Here is the combined diff from these sources:

http://www.mail-archive.com/tech@openbsd.org/msg01261.html
http://www.mail-archive.com/m...@openbsd.org/msg83528.html

Applied against most recent -current checkout:

--- rt2661.c.orig       Mon Jan 18 11:51:03 2010
+++ rt2661.c    Mon Jan 18 12:11:55 2010
@@ -97,9 +97,8 @@ void          rt2661_newassoc(struct ieee80211com *, struct ie
 int            rt2661_newstate(struct ieee80211com *, enum ieee80211_state,
                    int);
 uint16_t       rt2661_eeprom_read(struct rt2661_softc *, uint8_t);
+void           rt2661_free_tx_desc(struct rt2661_softc *, struct 
rt2661_tx_ring *);
 void           rt2661_tx_intr(struct rt2661_softc *);
-void           rt2661_tx_dma_intr(struct rt2661_softc *,
-                   struct rt2661_tx_ring *);
 void           rt2661_rx_intr(struct rt2661_softc *);
 #ifndef IEEE80211_STA_ONLY
 void           rt2661_mcu_beacon_expire(struct rt2661_softc *);
@@ -115,7 +114,7 @@ uint16_t    rt2661_txtime(int, int, uint32_t);
 uint8_t                rt2661_plcp_signal(int);
 void           rt2661_setup_tx_desc(struct rt2661_softc *,
                    struct rt2661_tx_desc *, uint32_t, uint16_t, int, int,
-                   const bus_dma_segment_t *, int, int);
+                   const bus_dma_segment_t *, int, int, int);
 int            rt2661_tx_mgt(struct rt2661_softc *, struct mbuf *,
                    struct ieee80211_node *);
 int            rt2661_tx_data(struct rt2661_softc *, struct mbuf *,
@@ -376,7 +375,7 @@ rt2661_alloc_tx_ring(struct rt2661_softc *sc, struct r
 
        ring->count = count;
        ring->queued = 0;
-       ring->cur = ring->next = ring->stat = 0;
+       ring->cur = ring->stat = 0;
 
        error = bus_dmamap_create(sc->sc_dmat, count * RT2661_TX_DESC_SIZE, 1,
            count * RT2661_TX_DESC_SIZE, 0, BUS_DMA_NOWAIT, &ring->map);
@@ -470,7 +469,7 @@ rt2661_reset_tx_ring(struct rt2661_softc *sc, struct r
            BUS_DMASYNC_PREWRITE);
 
        ring->queued = 0;
-       ring->cur = ring->next = ring->stat = 0;
+       ring->cur = ring->stat = 0;
 }
 
 void
@@ -881,6 +880,36 @@ rt2661_eeprom_read(struct rt2661_softc *sc, uint8_t ad
 }
 
 void
+rt2661_free_tx_desc(struct rt2661_softc *sc, struct rt2661_tx_ring *txq)
+{
+       struct rt2661_tx_desc *desc = &txq->desc[txq->stat];
+       struct rt2661_tx_data *data = &txq->data[txq->stat];
+       struct ieee80211com *ic = &sc->sc_ic;
+
+       bus_dmamap_sync(sc->sc_dmat, data->map, 0,
+                       data->map->dm_mapsize, BUS_DMASYNC_POSTWRITE);
+       bus_dmamap_unload(sc->sc_dmat, data->map);
+       m_freem(data->m);
+       data->m = NULL;
+
+       /* descriptor is no longer valid */
+       desc->flags &= ~htole32(RT2661_TX_VALID);
+
+       bus_dmamap_sync(sc->sc_dmat, txq->map,
+                       txq->stat * RT2661_TX_DESC_SIZE, RT2661_TX_DESC_SIZE,
+                       BUS_DMASYNC_PREWRITE);
+
+       if (data->ni) {
+               ieee80211_release_node(ic, data->ni);
+               data->ni = NULL;
+       }
+
+       txq->queued--;
+       if (++txq->stat >= txq->count)  /* faster than % count */
+               txq->stat = 0;
+}
+
+void
 rt2661_tx_intr(struct rt2661_softc *sc)
 {
        struct ieee80211com *ic = &sc->sc_ic;
@@ -888,7 +917,7 @@ rt2661_tx_intr(struct rt2661_softc *sc)
        struct rt2661_tx_ring *txq;
        struct rt2661_tx_data *data;
        struct rt2661_node *rn;
-       int qid, retrycnt;
+       int qid, ind, retrycnt;
 
        for (;;) {
                const uint32_t val = RAL_READ(sc, RT2661_STA_CSR4);
@@ -898,7 +927,14 @@ rt2661_tx_intr(struct rt2661_softc *sc)
                /* retrieve the queue in which this frame was sent */
                qid = RT2661_TX_QID(val);
                txq = (qid <= 3) ? &sc->txq[qid] : &sc->mgtq;
+               ind = RT2661_TX_INDEX(val);
 
+               if (txq->stat != ind)
+                       DPRINTFN(10, ("missed TX interrupt, catching up "
+                                "stat %d to index %d\n", txq->stat, ind, qid));
+                       while (txq->stat != ind)
+                               rt2661_free_tx_desc(sc, txq);
+
                /* retrieve rate control algorithm context */
                data = &txq->data[txq->stat];
                rn = (struct rt2661_node *)data->ni;
@@ -934,14 +970,7 @@ rt2661_tx_intr(struct rt2661_softc *sc)
                        ifp->if_oerrors++;
                }
 
-               ieee80211_release_node(ic, data->ni);
-               data->ni = NULL;
-
-               DPRINTFN(15, ("tx done q=%d idx=%u\n", qid, txq->stat));
-
-               txq->queued--;
-               if (++txq->stat >= txq->count)  /* faster than % count */
-                       txq->stat = 0;
+               rt2661_free_tx_desc(sc, txq);
        }
 
        sc->sc_tx_timer = 0;
@@ -950,42 +979,6 @@ rt2661_tx_intr(struct rt2661_softc *sc)
 }
 
 void
-rt2661_tx_dma_intr(struct rt2661_softc *sc, struct rt2661_tx_ring *txq)
-{
-       for (;;) {
-               struct rt2661_tx_desc *desc = &txq->desc[txq->next];
-               struct rt2661_tx_data *data = &txq->data[txq->next];
-
-               bus_dmamap_sync(sc->sc_dmat, txq->map,
-                   txq->next * RT2661_TX_DESC_SIZE, RT2661_TX_DESC_SIZE,
-                   BUS_DMASYNC_POSTREAD);
-
-               if ((letoh32(desc->flags) & RT2661_TX_BUSY) ||
-                   !(letoh32(desc->flags) & RT2661_TX_VALID))
-                       break;
-
-               bus_dmamap_sync(sc->sc_dmat, data->map, 0,
-                   data->map->dm_mapsize, BUS_DMASYNC_POSTWRITE);
-               bus_dmamap_unload(sc->sc_dmat, data->map);
-               m_freem(data->m);
-               data->m = NULL;
-               /* node reference is released in rt2661_tx_intr() */
-
-               /* descriptor is no longer valid */
-               desc->flags &= ~htole32(RT2661_TX_VALID);
-
-               bus_dmamap_sync(sc->sc_dmat, txq->map,
-                   txq->next * RT2661_TX_DESC_SIZE, RT2661_TX_DESC_SIZE,
-                   BUS_DMASYNC_PREWRITE);
-
-               DPRINTFN(15, ("tx dma done q=%p idx=%u\n", txq, txq->next));
-
-               if (++txq->next >= txq->count)  /* faster than % count */
-                       txq->next = 0;
-       }
-}
-
-void
 rt2661_rx_intr(struct rt2661_softc *sc)
 {
        struct ieee80211com *ic = &sc->sc_ic;
@@ -1212,24 +1205,9 @@ rt2661_intr(void *arg)
        if (!(ifp->if_flags & IFF_RUNNING))
                return 0;
 
-       if (r1 & RT2661_MGT_DONE)
-               rt2661_tx_dma_intr(sc, &sc->mgtq);
-
        if (r1 & RT2661_RX_DONE)
                rt2661_rx_intr(sc);
 
-       if (r1 & RT2661_TX0_DMA_DONE)
-               rt2661_tx_dma_intr(sc, &sc->txq[0]);
-
-       if (r1 & RT2661_TX1_DMA_DONE)
-               rt2661_tx_dma_intr(sc, &sc->txq[1]);
-
-       if (r1 & RT2661_TX2_DMA_DONE)
-               rt2661_tx_dma_intr(sc, &sc->txq[2]);
-
-       if (r1 & RT2661_TX3_DMA_DONE)
-               rt2661_tx_dma_intr(sc, &sc->txq[3]);
-
        if (r1 & RT2661_TX_DONE)
                rt2661_tx_intr(sc);
 
@@ -1377,7 +1355,7 @@ rt2661_plcp_signal(int rate)
 void
 rt2661_setup_tx_desc(struct rt2661_softc *sc, struct rt2661_tx_desc *desc,
     uint32_t flags, uint16_t xflags, int len, int rate,
-    const bus_dma_segment_t *segs, int nsegs, int ac)
+    const bus_dma_segment_t *segs, int nsegs, int ac, int ind)
 {
        struct ieee80211com *ic = &sc->sc_ic;
        uint16_t plcp_length;
@@ -1385,7 +1363,6 @@ rt2661_setup_tx_desc(struct rt2661_softc *sc, struct r
 
        desc->flags = htole32(flags);
        desc->flags |= htole32(len << 16);
-       desc->flags |= htole32(RT2661_TX_BUSY | RT2661_TX_VALID);
 
        desc->xflags = htole16(xflags);
        desc->xflags |= htole16(nsegs << 13);
@@ -1401,7 +1378,7 @@ rt2661_setup_tx_desc(struct rt2661_softc *sc, struct r
         * private data only. It will be made available by the NIC in STA_CSR4
         * on Tx interrupts.
         */
-       desc->qid = ac;
+       desc->qid = (ac <= 3 ? ac : 7) | (ind << 3);
 
        /* setup PLCP fields */
        desc->plcp_signal  = rt2661_plcp_signal(rate);
@@ -1433,6 +1410,8 @@ rt2661_setup_tx_desc(struct rt2661_softc *sc, struct r
                desc->addr[i] = htole32(segs[i].ds_addr);
                desc->len [i] = htole16(segs[i].ds_len);
        }
+
+       desc->flags |= htole32(RT2661_TX_BUSY | RT2661_TX_VALID);
 }
 
 int
@@ -1505,7 +1484,7 @@ rt2661_tx_mgt(struct rt2661_softc *sc, struct mbuf *m0
 
        rt2661_setup_tx_desc(sc, desc, flags, 0 /* XXX HWSEQ */,
            m0->m_pkthdr.len, rate, data->map->dm_segs, data->map->dm_nsegs,
-           RT2661_QID_MGT);
+           RT2661_QID_MGT, sc->mgtq.cur);
 
        bus_dmamap_sync(sc->sc_dmat, data->map, 0, data->map->dm_mapsize,
            BUS_DMASYNC_PREWRITE);
@@ -1633,7 +1612,7 @@ rt2661_tx_data(struct rt2661_softc *sc, struct mbuf *m
                rt2661_setup_tx_desc(sc, desc,
                    (needrts ? RT2661_TX_NEED_ACK : 0) | RT2661_TX_MORE_FRAG,
                    0, mprot->m_pkthdr.len, protrate, data->map->dm_segs,
-                   data->map->dm_nsegs, ac);
+                   data->map->dm_nsegs, ac, txq->cur);
 
                bus_dmamap_sync(sc->sc_dmat, data->map, 0,
                    data->map->dm_mapsize, BUS_DMASYNC_PREWRITE);
@@ -1723,7 +1702,7 @@ rt2661_tx_data(struct rt2661_softc *sc, struct mbuf *m
        }
 
        rt2661_setup_tx_desc(sc, desc, flags, 0, m0->m_pkthdr.len, rate,
-           data->map->dm_segs, data->map->dm_nsegs, ac);
+           data->map->dm_segs, data->map->dm_nsegs, ac, txq->cur);
 
        bus_dmamap_sync(sc->sc_dmat, data->map, 0, data->map->dm_mapsize,
            BUS_DMASYNC_PREWRITE);
@@ -2797,7 +2776,7 @@ rt2661_prepare_beacon(struct rt2661_softc *sc)
        rate = IEEE80211_IS_CHAN_5GHZ(ni->ni_chan) ? 12 : 2;
 
        rt2661_setup_tx_desc(sc, &desc, RT2661_TX_TIMESTAMP, RT2661_TX_HWSEQ,
-           m0->m_pkthdr.len, rate, NULL, 0, RT2661_QID_MGT);
+           m0->m_pkthdr.len, rate, NULL, 0, RT2661_QID_MGT, 0);
 
        /* copy the first 24 bytes of Tx descriptor into NIC memory */
        RAL_WRITE_REGION_1(sc, RT2661_HW_BEACON_BASE0, (uint8_t *)&desc, 24);
--- rt2661reg.h.orig    Mon Jan 18 12:08:57 2010
+++ rt2661reg.h Mon Jan 18 12:09:46 2010
@@ -189,7 +189,8 @@
 #define RT2661_TX_STAT_VALID   (1 << 0)
 #define RT2661_TX_RESULT(v)    (((v) >> 1) & 0x7)
 #define RT2661_TX_RETRYCNT(v)  (((v) >> 4) & 0xf)
-#define RT2661_TX_QID(v)       (((v) >> 8) & 0xf)
+#define RT2661_TX_QID(v)       (((v) >> 8) & 0x7)
+#define RT2661_TX_INDEX(v)     (((v) >>11) & 0x1f)
 #define RT2661_TX_SUCCESS      0
 #define RT2661_TX_RETRY_FAIL   6
 
--- rt2661var.h.orig    Mon Jan 18 12:09:54 2010
+++ rt2661var.h Mon Jan 18 12:10:12 2010
@@ -62,7 +62,6 @@ struct rt2661_tx_ring {
        int                     count;
        int                     queued;
        int                     cur;
-       int                     next;
        int                     stat;
 };

Reply via email to