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; };