Date: Wed, 17 Aug 2011 09:44:15 +0000 (UTC) From: Adrian Chadd <adrian@FreeBSD.org> To: src-committers@freebsd.org, svn-src-user@freebsd.org Subject: svn commit: r224933 - user/adrian/if_ath_tx/sys/dev/ath Message-ID: <201108170944.p7H9iFR3096619@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: adrian Date: Wed Aug 17 09:44:15 2011 New Revision: 224933 URL: http://svn.freebsd.org/changeset/base/224933 Log: Flesh out a completely untested aggregate completion handler. Modified: user/adrian/if_ath_tx/sys/dev/ath/if_ath_tx.c user/adrian/if_ath_tx/sys/dev/ath/if_ath_tx.h Modified: user/adrian/if_ath_tx/sys/dev/ath/if_ath_tx.c ============================================================================== --- user/adrian/if_ath_tx/sys/dev/ath/if_ath_tx.c Wed Aug 17 09:40:52 2011 (r224932) +++ user/adrian/if_ath_tx/sys/dev/ath/if_ath_tx.c Wed Aug 17 09:44:15 2011 (r224933) @@ -2344,20 +2344,28 @@ ath_tx_comp_cleanup_aggr(struct ath_soft * not the last descriptor in the first frame. */ static void -ath_tx_aggr_comp_aggr(struct ath_softc *sc, struct ath_buf *bf, int fail) +ath_tx_aggr_comp_aggr(struct ath_softc *sc, struct ath_buf *bf_first, int fail) { //struct ath_desc *ds = bf->bf_lastds; - struct ieee80211_node *ni = bf->bf_node; + struct ieee80211_node *ni = bf_first->bf_node; struct ath_node *an = ATH_NODE(ni); - int tid = bf->bf_state.bfs_tid; + int tid = bf_first->bf_state.bfs_tid; struct ath_tid *atid = &an->an_tid[tid]; - struct ath_tx_status *ts = &bf->bf_status.ds_txstat; + struct ath_tx_status *ts = &bf_first->bf_status.ds_txstat; + struct ieee80211_tx_ampdu *tap; + ath_bufhead bf_q; + int seq_st, tx_ok; + int hasba, isaggr; + uint32_t ba[2]; + struct ath_buf *bf, *bf_next; + int ba_index; + int drops = 0; /* * Punt cleanup to the relevant function, not our problem now */ if (atid->cleanup_inprogress) { - ath_tx_comp_cleanup_aggr(sc, bf); + ath_tx_comp_cleanup_aggr(sc, bf_first); return; } @@ -2365,15 +2373,83 @@ ath_tx_aggr_comp_aggr(struct ath_softc * * handle errors first */ if (ts->ts_status & HAL_TXERR_XRETRY) { - ath_tx_comp_aggr_error(sc, bf, atid); + ath_tx_comp_aggr_error(sc, bf_first, atid); return; } + STAILQ_INIT(&bf_q); + tap = ath_tx_get_tx_tid(an, tid); + /* * extract starting sequence and block-ack bitmap */ + /* XXX endian-ness of seq_st, ba? */ + seq_st = ts->ts_seqnum; + hasba = !! (ts->ts_flags & HAL_TX_BA); + tx_ok = (ts->ts_status == 0); + isaggr = bf_first->bf_state.bfs_aggr; + ba[0] = ts->ts_ba_low; + ba[1] = ts->ts_ba_high; + + /* Occasionally, the MAC sends a tx status for the wrong TID. */ + if (tid != ts->ts_tid) { + device_printf(sc->sc_dev, "%s: tid %d != hw tid %d\n", + __func__, tid, ts->ts_tid); + tx_ok = 0; + } + + /* AR5416 BA bug; this requires an interface reset */ + /* XXX TODO */ + + /* + * Walk the list of frames, figure out which ones were correctly + * sent and which weren't. + */ + bf = bf_first; - /* AR5416 BA bug; this requires re-TX of all frames */ + while (bf) { + ba_index = ATH_BA_INDEX(seq_st, SEQNO(bf->bf_state.bfs_seqno)); + bf_next = bf->bf_next; + + if (tx_ok && ATH_BA_ISSET(ba, ba_index)) { + ath_tx_update_baw(sc, an, atid, + SEQNO(bf->bf_state.bfs_seqno)); + ath_tx_default_comp(sc, bf, 0); + } else { + drops += ath_tx_retry_subframe(sc, bf, &bf_q); + } + bf = bf_next; + } + + /* update rate control module about aggregate status */ + /* XXX TODO */ + + /* + * send bar if we dropped any frames + */ + if (drops) { + if (ieee80211_send_bar(ni, tap, ni->ni_txseqs[tid]) == 0) { + /* + * Pause the TID if this was successful. + * An un-successful BAR TX would never call + * the BAR complete / timeout methods. + */ + ath_tx_tid_pause(sc, atid); + } else { + /* BAR TX failed */ + device_printf(sc->sc_dev, + "%s: TID %d: BAR TX failed\n", + __func__, tid); + } + } + + /* Prepend all frames to the beginning of the queue */ + ATH_TXQ_LOCK(atid); + while ((bf = STAILQ_FIRST(&bf_q)) != NULL) { + ATH_TXQ_INSERT_HEAD(atid, bf, bf_list); + STAILQ_REMOVE_HEAD(&bf_q, bf_list); + } + ATH_TXQ_UNLOCK(atid); } /* Modified: user/adrian/if_ath_tx/sys/dev/ath/if_ath_tx.h ============================================================================== --- user/adrian/if_ath_tx/sys/dev/ath/if_ath_tx.h Wed Aug 17 09:40:52 2011 (r224932) +++ user/adrian/if_ath_tx/sys/dev/ath/if_ath_tx.h Wed Aug 17 09:44:15 2011 (r224933) @@ -40,6 +40,17 @@ */ #define ATH_BA_INDEX(_st, _seq) (((_seq) - (_st)) & (IEEE80211_SEQ_RANGE - 1)) +#define WME_BA_BMP_SIZE 64 +#define WME_MAX_BA WME_BA_BMP_SIZE + +/* + * return whether a bit at index _n in bitmap _bm is set + * _sz is the size of the bitmap + */ +#define ATH_BA_ISSET(_bm, _n) (((_n) < (WME_BA_BMP_SIZE)) && \ + ((_bm)[(_n) >> 5] & (1 << ((_n) & 31)))) + + /* extracting the seqno from buffer seqno */ #define SEQNO(_a) ((_a) >> IEEE80211_SEQ_SEQ_SHIFT)
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201108170944.p7H9iFR3096619>