Migrate the net80211 TX aggregation state to be from per-AC to per-TID.

TODO:

* Test mwl(4) more thoroughly!

Reviewed by:	bschmidt (for iwn)
This commit is contained in:
Adrian Chadd 2012-04-15 20:29:39 +00:00
parent 82d05362e6
commit 2aa563dfeb
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=234324
10 changed files with 69 additions and 67 deletions

View File

@ -4214,14 +4214,11 @@ ath_tx_get_tx_tid(struct ath_node *an, int tid)
{
struct ieee80211_node *ni = &an->an_node;
struct ieee80211_tx_ampdu *tap;
int ac;
if (tid == IEEE80211_NONQOS_TID)
return NULL;
ac = TID_TO_WME_AC(tid);
tap = &ni->ni_tx_ampdu[ac];
tap = &ni->ni_tx_ampdu[tid];
return tap;
}
@ -4279,7 +4276,7 @@ ath_addba_request(struct ieee80211_node *ni, struct ieee80211_tx_ampdu *tap,
int dialogtoken, int baparamset, int batimeout)
{
struct ath_softc *sc = ni->ni_ic->ic_ifp->if_softc;
int tid = WME_AC_TO_TID(tap->txa_ac);
int tid = tap->txa_tid;
struct ath_node *an = ATH_NODE(ni);
struct ath_tid *atid = &an->an_tid[tid];
@ -4346,7 +4343,7 @@ ath_addba_response(struct ieee80211_node *ni, struct ieee80211_tx_ampdu *tap,
int status, int code, int batimeout)
{
struct ath_softc *sc = ni->ni_ic->ic_ifp->if_softc;
int tid = WME_AC_TO_TID(tap->txa_ac);
int tid = tap->txa_tid;
struct ath_node *an = ATH_NODE(ni);
struct ath_tid *atid = &an->an_tid[tid];
int r;
@ -4387,7 +4384,7 @@ void
ath_addba_stop(struct ieee80211_node *ni, struct ieee80211_tx_ampdu *tap)
{
struct ath_softc *sc = ni->ni_ic->ic_ifp->if_softc;
int tid = WME_AC_TO_TID(tap->txa_ac);
int tid = tap->txa_tid;
struct ath_node *an = ATH_NODE(ni);
struct ath_tid *atid = &an->an_tid[tid];
@ -4424,7 +4421,7 @@ ath_bar_response(struct ieee80211_node *ni, struct ieee80211_tx_ampdu *tap,
int status)
{
struct ath_softc *sc = ni->ni_ic->ic_ifp->if_softc;
int tid = WME_AC_TO_TID(tap->txa_ac);
int tid = tap->txa_tid;
struct ath_node *an = ATH_NODE(ni);
struct ath_tid *atid = &an->an_tid[tid];
int attempts = tap->txa_attempts;
@ -4457,7 +4454,7 @@ ath_addba_response_timeout(struct ieee80211_node *ni,
struct ieee80211_tx_ampdu *tap)
{
struct ath_softc *sc = ni->ni_ic->ic_ifp->if_softc;
int tid = WME_AC_TO_TID(tap->txa_ac);
int tid = tap->txa_tid;
struct ath_node *an = ATH_NODE(ni);
struct ath_tid *atid = &an->an_tid[tid];

View File

@ -2445,7 +2445,7 @@ iwn_rx_compressed_ba(struct iwn_softc *sc, struct iwn_rx_desc *desc,
txq = &sc->txq[le16toh(ba->qid)];
tap = sc->qid2tap[le16toh(ba->qid)];
tid = WME_AC_TO_TID(tap->txa_ac);
tid = tap->txa_tid;
ni = tap->txa_ni;
wn = (void *)ni;
@ -2804,7 +2804,7 @@ iwn_ampdu_tx_done(struct iwn_softc *sc, int qid, int idx, int nframes,
}
tap = sc->qid2tap[qid];
if (tap != NULL) {
tid = WME_AC_TO_TID(tap->txa_ac);
tid = tap->txa_tid;
wn = (void *)tap->txa_ni;
wn->agg[tid].bitmap = bitmap;
wn->agg[tid].startidx = start;
@ -5585,7 +5585,7 @@ iwn_addba_response(struct ieee80211_node *ni, struct ieee80211_tx_ampdu *tap,
{
struct iwn_softc *sc = ni->ni_ic->ic_ifp->if_softc;
int qid = *(int *)tap->txa_private;
uint8_t tid = WME_AC_TO_TID(tap->txa_ac);
uint8_t tid = tap->txa_tid;
int ret;
if (code == IEEE80211_STATUS_SUCCESS) {
@ -5609,7 +5609,7 @@ static int
iwn_ampdu_tx_start(struct ieee80211com *ic, struct ieee80211_node *ni,
uint8_t tid)
{
struct ieee80211_tx_ampdu *tap = &ni->ni_tx_ampdu[TID_TO_WME_AC(tid)];
struct ieee80211_tx_ampdu *tap = &ni->ni_tx_ampdu[tid];
struct iwn_softc *sc = ni->ni_ic->ic_ifp->if_softc;
struct iwn_ops *ops = &sc->ops;
struct iwn_node *wn = (void *)ni;
@ -5642,7 +5642,7 @@ iwn_ampdu_tx_stop(struct ieee80211_node *ni, struct ieee80211_tx_ampdu *tap)
{
struct iwn_softc *sc = ni->ni_ic->ic_ifp->if_softc;
struct iwn_ops *ops = &sc->ops;
uint8_t tid = WME_AC_TO_TID(tap->txa_ac);
uint8_t tid = tap->txa_tid;
int qid;
if (tap->txa_private == NULL)

View File

@ -3739,7 +3739,7 @@ mwl_addba_request(struct ieee80211_node *ni, struct ieee80211_tx_ampdu *tap,
/* NB: no held reference to ni */
sp = mwl_hal_bastream_alloc(MWL_VAP(vap)->mv_hvap,
(baparamset & IEEE80211_BAPS_POLICY_IMMEDIATE) != 0,
ni->ni_macaddr, WME_AC_TO_TID(tap->txa_ac), ni->ni_htparam,
ni->ni_macaddr, tap->txa_tid, ni->ni_htparam,
ni, tap);
if (sp == NULL) {
/*
@ -3776,8 +3776,8 @@ mwl_addba_response(struct ieee80211_node *ni, struct ieee80211_tx_ampdu *tap,
if (bas == NULL) {
/* XXX should not happen */
DPRINTF(sc, MWL_DEBUG_AMPDU,
"%s: no BA stream allocated, AC %d\n",
__func__, tap->txa_ac);
"%s: no BA stream allocated, TID %d\n",
__func__, tap->txa_tid);
sc->sc_stats.mst_addba_nostream++;
return 0;
}
@ -3805,18 +3805,18 @@ mwl_addba_response(struct ieee80211_node *ni, struct ieee80211_tx_ampdu *tap,
tap->txa_private = NULL;
DPRINTF(sc, MWL_DEBUG_AMPDU,
"%s: create failed, error %d, bufsiz %d AC %d "
"%s: create failed, error %d, bufsiz %d TID %d "
"htparam 0x%x\n", __func__, error, bufsiz,
tap->txa_ac, ni->ni_htparam);
tap->txa_tid, ni->ni_htparam);
sc->sc_stats.mst_bacreate_failed++;
return 0;
}
/* NB: cache txq to avoid ptr indirect */
mwl_bastream_setup(bas, tap->txa_ac, bas->bastream->txq);
mwl_bastream_setup(bas, tap->txa_tid, bas->bastream->txq);
DPRINTF(sc, MWL_DEBUG_AMPDU,
"%s: bastream %p assigned to txq %d AC %d bufsiz %d "
"%s: bastream %p assigned to txq %d TID %d bufsiz %d "
"htparam 0x%x\n", __func__, bas->bastream,
bas->txq, tap->txa_ac, bufsiz, ni->ni_htparam);
bas->txq, tap->txa_tid, bufsiz, ni->ni_htparam);
} else {
/*
* Other side NAK'd us; return the resources.

View File

@ -187,10 +187,10 @@ struct mwl_bastate {
};
static __inline__ void
mwl_bastream_setup(struct mwl_bastate *bas, int ac, int txq)
mwl_bastream_setup(struct mwl_bastate *bas, int tid, int txq)
{
bas->txq = txq;
bas->qos = htole16(WME_AC_TO_TID(ac) | IEEE80211_QOS_ACKPOLICY_BA);
bas->qos = htole16(tid | IEEE80211_QOS_ACKPOLICY_BA);
}
static __inline__ void

View File

@ -202,7 +202,7 @@ _db_show_txampdu(const char *sep, int ix, const struct ieee80211_tx_ampdu *tap)
{
db_printf("%stxampdu[%d]: %p flags %b %s\n",
sep, ix, tap, tap->txa_flags, IEEE80211_AGGR_BITS,
ieee80211_wme_acnames[tap->txa_ac]);
ieee80211_wme_acnames[TID_TO_WME_AC(tap->txa_tid)]);
db_printf("%s token %u lastsample %d pkts %d avgpps %d qbytes %d qframes %d\n",
sep, tap->txa_token, tap->txa_lastsample, tap->txa_pkts,
tap->txa_avgpps, tap->txa_qbytes, tap->txa_qframes);
@ -293,7 +293,7 @@ _db_show_sta(const struct ieee80211_node *ni)
ni->ni_htopmode, ni->ni_htstbc, ni->ni_chw);
/* XXX ampdu state */
for (i = 0; i < WME_NUM_AC; i++)
for (i = 0; i < WME_NUM_TID; i++)
if (ni->ni_tx_ampdu[i].txa_flags & IEEE80211_AGGR_SETUP)
_db_show_txampdu("\t", i, &ni->ni_tx_ampdu[i]);
for (i = 0; i < WME_NUM_TID; i++)

View File

@ -1023,7 +1023,7 @@ void
ieee80211_ht_node_init(struct ieee80211_node *ni)
{
struct ieee80211_tx_ampdu *tap;
int ac;
int tid;
if (ni->ni_flags & IEEE80211_NODE_HT) {
/*
@ -1033,9 +1033,9 @@ ieee80211_ht_node_init(struct ieee80211_node *ni)
*/
ieee80211_ht_node_cleanup(ni);
}
for (ac = 0; ac < WME_NUM_AC; ac++) {
tap = &ni->ni_tx_ampdu[ac];
tap->txa_ac = ac;
for (tid = 0; tid < WME_NUM_TID; tid++) {
tap = &ni->ni_tx_ampdu[tid];
tap->txa_tid = tid;
tap->txa_ni = ni;
/* NB: further initialization deferred */
}
@ -1055,7 +1055,7 @@ ieee80211_ht_node_cleanup(struct ieee80211_node *ni)
KASSERT(ni->ni_flags & IEEE80211_NODE_HT, ("not an HT node"));
/* XXX optimize this */
for (i = 0; i < WME_NUM_AC; i++) {
for (i = 0; i < WME_NUM_TID; i++) {
struct ieee80211_tx_ampdu *tap = &ni->ni_tx_ampdu[i];
if (tap->txa_flags & IEEE80211_AGGR_SETUP)
ampdu_tx_stop(tap);
@ -1160,7 +1160,7 @@ ieee80211_ht_wds_init(struct ieee80211_node *ni)
{
struct ieee80211vap *vap = ni->ni_vap;
struct ieee80211_tx_ampdu *tap;
int ac;
int tid;
KASSERT(vap->iv_flags_ht & IEEE80211_FHT_HT, ("no HT requested"));
@ -1198,9 +1198,9 @@ ieee80211_ht_wds_init(struct ieee80211_node *ni)
ni->ni_htopmode = 0; /* XXX need protection state */
ni->ni_htstbc = 0; /* XXX need info */
for (ac = 0; ac < WME_NUM_AC; ac++) {
tap = &ni->ni_tx_ampdu[ac];
tap->txa_ac = ac;
for (tid = 0; tid < WME_NUM_TID; tid++) {
tap = &ni->ni_tx_ampdu[tid];
tap->txa_tid = tid;
}
/* NB: AMPDU tx/rx governed by IEEE80211_FHT_AMPDU_{TX,RX} */
ni->ni_flags |= IEEE80211_NODE_HT | IEEE80211_NODE_AMPDU;
@ -1685,7 +1685,8 @@ ampdu_tx_stop(struct ieee80211_tx_ampdu *tap)
struct ieee80211com *ic = ni->ni_ic;
KASSERT(tap->txa_flags & IEEE80211_AGGR_SETUP,
("txa_flags 0x%x ac %d", tap->txa_flags, tap->txa_ac));
("txa_flags 0x%x tid %d ac %d", tap->txa_flags, tap->txa_tid,
TID_TO_WME_AC(tap->txa_tid)));
/*
* Stop BA stream if setup so driver has a chance
@ -1898,7 +1899,7 @@ ht_recv_action_ba_addba_response(struct ieee80211_node *ni,
struct ieee80211_tx_ampdu *tap;
uint8_t dialogtoken, policy;
uint16_t baparamset, batimeout, code;
int tid, ac, bufsiz;
int tid, bufsiz;
dialogtoken = frm[2];
code = LE_READ_2(frm+3);
@ -1908,8 +1909,7 @@ ht_recv_action_ba_addba_response(struct ieee80211_node *ni,
policy = MS(baparamset, IEEE80211_BAPS_POLICY);
batimeout = LE_READ_2(frm+7);
ac = TID_TO_WME_AC(tid);
tap = &ni->ni_tx_ampdu[ac];
tap = &ni->ni_tx_ampdu[tid];
if ((tap->txa_flags & IEEE80211_AGGR_XCHGPEND) == 0) {
IEEE80211_DISCARD_MAC(vap,
IEEE80211_MSG_ACTION | IEEE80211_MSG_11N,
@ -1972,7 +1972,7 @@ ht_recv_action_ba_delba(struct ieee80211_node *ni,
struct ieee80211_rx_ampdu *rap;
struct ieee80211_tx_ampdu *tap;
uint16_t baparamset, code;
int tid, ac;
int tid;
baparamset = LE_READ_2(frm+2);
code = LE_READ_2(frm+4);
@ -1985,8 +1985,7 @@ ht_recv_action_ba_delba(struct ieee80211_node *ni,
MS(baparamset, IEEE80211_DELBAPS_INIT), code);
if ((baparamset & IEEE80211_DELBAPS_INIT) == 0) {
ac = TID_TO_WME_AC(tid);
tap = &ni->ni_tx_ampdu[ac];
tap = &ni->ni_tx_ampdu[tid];
ic->ic_addba_stop(ni, tap);
} else {
rap = &ni->ni_rx_ampdu[tid];
@ -2058,7 +2057,8 @@ ieee80211_ampdu_enable(struct ieee80211_node *ni,
{
struct ieee80211vap *vap = ni->ni_vap;
if (tap->txa_avgpps < vap->iv_ampdu_mintraffic[tap->txa_ac])
if (tap->txa_avgpps <
vap->iv_ampdu_mintraffic[TID_TO_WME_AC(tap->txa_tid)])
return 0;
/* XXX check rssi? */
if (tap->txa_attempts >= ieee80211_addba_maxtries &&
@ -2071,8 +2071,9 @@ ieee80211_ampdu_enable(struct ieee80211_node *ni,
return 0;
}
IEEE80211_NOTE(vap, IEEE80211_MSG_11N, ni,
"enable AMPDU on %s, avgpps %d pkts %d",
ieee80211_wme_acnames[tap->txa_ac], tap->txa_avgpps, tap->txa_pkts);
"enable AMPDU on tid %d (%s), avgpps %d pkts %d",
tap->txa_tid, ieee80211_wme_acnames[TID_TO_WME_AC(tap->txa_tid)],
tap->txa_avgpps, tap->txa_pkts);
return 1;
}
@ -2099,7 +2100,7 @@ ieee80211_ampdu_request(struct ieee80211_node *ni,
tap->txa_flags &= ~IEEE80211_AGGR_NAK;
dialogtoken = (tokens+1) % 63; /* XXX */
tid = WME_AC_TO_TID(tap->txa_ac);
tid = tap->txa_tid;
tap->txa_start = ni->ni_txseqs[tid];
args[0] = dialogtoken;
@ -2113,8 +2114,8 @@ ieee80211_ampdu_request(struct ieee80211_node *ni,
if (!ic->ic_addba_request(ni, tap, dialogtoken, args[2], args[3])) {
/* unable to setup state, don't make request */
IEEE80211_NOTE(ni->ni_vap, IEEE80211_MSG_11N,
ni, "%s: could not setup BA stream for AC %d",
__func__, tap->txa_ac);
ni, "%s: could not setup BA stream for TID %d AC %d",
__func__, tap->txa_tid, TID_TO_WME_AC(tap->txa_tid));
/* defer next try so we don't slam the driver with requests */
tap->txa_attempts = ieee80211_addba_maxtries;
/* NB: check in case driver wants to override */
@ -2147,20 +2148,20 @@ ieee80211_ampdu_stop(struct ieee80211_node *ni, struct ieee80211_tx_ampdu *tap,
tap->txa_flags &= ~IEEE80211_AGGR_BARPEND;
if (IEEE80211_AMPDU_RUNNING(tap)) {
IEEE80211_NOTE(vap, IEEE80211_MSG_ACTION | IEEE80211_MSG_11N,
ni, "%s: stop BA stream for AC %d (reason %d)",
__func__, tap->txa_ac, reason);
ni, "%s: stop BA stream for TID %d (reason %d)",
__func__, tap->txa_tid, reason);
vap->iv_stats.is_ampdu_stop++;
ic->ic_addba_stop(ni, tap);
args[0] = WME_AC_TO_TID(tap->txa_ac);
args[0] = tap->txa_tid;
args[1] = IEEE80211_DELBAPS_INIT;
args[2] = reason; /* XXX reason code */
ic->ic_send_action(ni, IEEE80211_ACTION_CAT_BA,
IEEE80211_ACTION_BA_DELBA, args);
} else {
IEEE80211_NOTE(vap, IEEE80211_MSG_ACTION | IEEE80211_MSG_11N,
ni, "%s: BA stream for AC %d not running (reason %d)",
__func__, tap->txa_ac, reason);
ni, "%s: BA stream for TID %d not running (reason %d)",
__func__, tap->txa_tid, reason);
vap->iv_stats.is_ampdu_stop_failed++;
}
}
@ -2176,7 +2177,7 @@ bar_timeout(void *arg)
IEEE80211_NOTE(ni->ni_vap, IEEE80211_MSG_11N,
ni, "%s: tid %u flags 0x%x attempts %d", __func__,
tap->txa_ac, tap->txa_flags, tap->txa_attempts);
tap->txa_tid, tap->txa_flags, tap->txa_attempts);
/* guard against race with bar_tx_complete */
if ((tap->txa_flags & IEEE80211_AGGR_BARPEND) == 0)
@ -2210,7 +2211,7 @@ bar_tx_complete(struct ieee80211_node *ni, void *arg, int status)
IEEE80211_NOTE(ni->ni_vap, IEEE80211_MSG_11N,
ni, "%s: tid %u flags 0x%x pending %d status %d",
__func__, tap->txa_ac, tap->txa_flags,
__func__, tap->txa_tid, tap->txa_flags,
callout_pending(&tap->txa_timer), status);
ni->ni_vap->iv_stats.is_ampdu_bar_tx++;
@ -2237,7 +2238,7 @@ ieee80211_bar_response(struct ieee80211_node *ni,
tap->txa_start,
IEEE80211_SEQ_ADD(tap->txa_start, tap->txa_wnd-1),
tap->txa_qframes, tap->txa_seqpending,
WME_AC_TO_TID(tap->txa_ac));
tap->txa_tid);
/* NB: timer already stopped in bar_tx_complete */
tap->txa_start = tap->txa_seqpending;
@ -2292,7 +2293,7 @@ ieee80211_send_bar(struct ieee80211_node *ni,
IEEE80211_ADDR_COPY(bar->i_ra, ni->ni_macaddr);
IEEE80211_ADDR_COPY(bar->i_ta, vap->iv_myaddr);
tid = WME_AC_TO_TID(tap->txa_ac);
tid = tap->txa_tid;
barctl = (tap->txa_flags & IEEE80211_AGGR_IMMEDIATE ?
0 : IEEE80211_BAR_NOACK)
| IEEE80211_BAR_COMP

View File

@ -44,7 +44,7 @@ struct ieee80211_tx_ampdu {
#define IEEE80211_AGGR_SETUP 0x0008 /* deferred state setup */
#define IEEE80211_AGGR_NAK 0x0010 /* peer NAK'd ADDBA request */
#define IEEE80211_AGGR_BARPEND 0x0020 /* BAR response pending */
uint8_t txa_ac;
uint8_t txa_tid;
uint8_t txa_token; /* dialog token */
int txa_lastsample; /* ticks @ last traffic sample */
int txa_pkts; /* packets over last sample interval */

View File

@ -214,7 +214,7 @@ struct ieee80211_node {
uint8_t ni_htstbc; /* HT */
uint8_t ni_chw; /* negotiated channel width */
struct ieee80211_htrateset ni_htrates; /* negotiated ht rate set */
struct ieee80211_tx_ampdu ni_tx_ampdu[WME_NUM_AC];
struct ieee80211_tx_ampdu ni_tx_ampdu[WME_NUM_TID];
struct ieee80211_rx_ampdu ni_rx_ampdu[WME_NUM_TID];
/* others */

View File

@ -323,8 +323,8 @@ ieee80211_start(struct ifnet *ifp)
if ((ni->ni_flags & IEEE80211_NODE_AMPDU_TX) &&
(vap->iv_flags_ht & IEEE80211_FHT_AMPDU_TX) &&
(m->m_flags & M_EAPOL) == 0) {
const int ac = M_WME_GETAC(m);
struct ieee80211_tx_ampdu *tap = &ni->ni_tx_ampdu[ac];
int tid = WME_AC_TO_TID(M_WME_GETAC(m));
struct ieee80211_tx_ampdu *tap = &ni->ni_tx_ampdu[tid];
ieee80211_txampdu_count_packet(tap);
if (IEEE80211_AMPDU_RUNNING(tap)) {
@ -589,7 +589,7 @@ ieee80211_send_setup(
}
*(uint16_t *)&wh->i_dur[0] = 0;
tap = &ni->ni_tx_ampdu[TID_TO_WME_AC(tid)];
tap = &ni->ni_tx_ampdu[tid];
if (tid != IEEE80211_NONQOS_TID && IEEE80211_AMPDU_RUNNING(tap))
m->m_flags |= M_AMPDU_MPDU;
else {

View File

@ -562,9 +562,11 @@ ieee80211_ff_age(struct ieee80211com *ic, struct ieee80211_stageq *sq,
IEEE80211_LOCK(ic);
head = sq->head;
while ((m = sq->head) != NULL && M_AGE_GET(m) < quanta) {
int tid = WME_AC_TO_TID(M_WME_GETAC(m));
/* clear tap ref to frame */
ni = (struct ieee80211_node *) m->m_pkthdr.rcvif;
tap = &ni->ni_tx_ampdu[M_WME_GETAC(m)];
tap = &ni->ni_tx_ampdu[tid];
KASSERT(tap->txa_private == m, ("staging queue empty"));
tap->txa_private = NULL;
@ -670,7 +672,7 @@ ieee80211_ff_check(struct ieee80211_node *ni, struct mbuf *m)
* be aggregated with other types of frames when encryption is on?
*/
IEEE80211_LOCK(ic);
tap = &ni->ni_tx_ampdu[pri];
tap = &ni->ni_tx_ampdu[WME_AC_TO_TID(pri)];
mstaged = tap->txa_private; /* NB: we reuse AMPDU state */
ieee80211_txampdu_count_packet(tap);
@ -783,12 +785,14 @@ ieee80211_ff_node_cleanup(struct ieee80211_node *ni)
struct ieee80211_superg *sg = ic->ic_superg;
struct ieee80211_tx_ampdu *tap;
struct mbuf *m, *head;
int ac;
int tid;
IEEE80211_LOCK(ic);
head = NULL;
for (ac = 0; ac < WME_NUM_AC; ac++) {
tap = &ni->ni_tx_ampdu[ac];
for (tid = 0; tid < WME_NUM_TID; tid++) {
int ac = TID_TO_WME_AC(tid);
tap = &ni->ni_tx_ampdu[tid];
m = tap->txa_private;
if (m != NULL) {
tap->txa_private = NULL;