diff --git a/sys/dev/ath/ath_rate/amrr/amrr.c b/sys/dev/ath/ath_rate/amrr/amrr.c index a946daef34ed..7877dab94fbc 100644 --- a/sys/dev/ath/ath_rate/amrr/amrr.c +++ b/sys/dev/ath/ath_rate/amrr/amrr.c @@ -104,8 +104,8 @@ ath_rate_node_cleanup(struct ath_softc *sc, struct ath_node *an) void ath_rate_findrate(struct ath_softc *sc, struct ath_node *an, - int shortPreamble, size_t frameLen, - u_int8_t *rix, int *try0, u_int8_t *txrate) + int shortPreamble, size_t frameLen, int tid, bool is_aggr, + u_int8_t *rix, int *try0, u_int8_t *txrate, int *maxdur) { struct amrr_node *amn = ATH_NODE_AMRR(an); @@ -115,6 +115,7 @@ ath_rate_findrate(struct ath_softc *sc, struct ath_node *an, *txrate = amn->amn_tx_rate0sp; else *txrate = amn->amn_tx_rate0; + maxdur = -1; } /* diff --git a/sys/dev/ath/ath_rate/onoe/onoe.c b/sys/dev/ath/ath_rate/onoe/onoe.c index 7e11d9d350cf..49a72b12af0d 100644 --- a/sys/dev/ath/ath_rate/onoe/onoe.c +++ b/sys/dev/ath/ath_rate/onoe/onoe.c @@ -112,8 +112,8 @@ ath_rate_node_cleanup(struct ath_softc *sc, struct ath_node *an) void ath_rate_findrate(struct ath_softc *sc, struct ath_node *an, - int shortPreamble, size_t frameLen, - u_int8_t *rix, int *try0, u_int8_t *txrate) + int shortPreamble, size_t frameLen, int tid, bool is_aggr, + u_int8_t *rix, int *try0, u_int8_t *txrate, int *maxdur) { struct onoe_node *on = ATH_NODE_ONOE(an); @@ -123,6 +123,7 @@ ath_rate_findrate(struct ath_softc *sc, struct ath_node *an, *txrate = on->on_tx_rate0sp; else *txrate = on->on_tx_rate0; + *maxdur = -1; } /* diff --git a/sys/dev/ath/ath_rate/sample/sample.c b/sys/dev/ath/ath_rate/sample/sample.c index ce22b36c539e..9d3136eaa1c1 100644 --- a/sys/dev/ath/ath_rate/sample/sample.c +++ b/sys/dev/ath/ath_rate/sample/sample.c @@ -482,8 +482,9 @@ ath_rate_pick_seed_rate_ht(struct ath_softc *sc, struct ath_node *an, void ath_rate_findrate(struct ath_softc *sc, struct ath_node *an, - int shortPreamble, size_t frameLen, - u_int8_t *rix0, int *try0, u_int8_t *txrate) + int shortPreamble, size_t frameLen, int tid, + bool is_aggr, u_int8_t *rix0, int *try0, + u_int8_t *txrate, int *maxdur) { #define DOT11RATE(ix) (rt->info[ix].dot11Rate & IEEE80211_RATE_VAL) #define MCS(ix) (rt->info[ix].dot11Rate | IEEE80211_RATE_MCS) @@ -498,6 +499,10 @@ ath_rate_findrate(struct ath_softc *sc, struct ath_node *an, ath_rate_update_static_rix(sc, &an->an_node); + /* For now don't take TID, is_aggr into account */ + /* Also for now don't calculate a max duration; that'll come later */ + *maxdur = -1; + if (sn->currates != sc->sc_currates) { device_printf(sc->sc_dev, "%s: currates != sc_currates!\n", __func__); diff --git a/sys/dev/ath/if_ath.c b/sys/dev/ath/if_ath.c index fa3081cff296..6d4ccd8f0ae3 100644 --- a/sys/dev/ath/if_ath.c +++ b/sys/dev/ath/if_ath.c @@ -4312,6 +4312,11 @@ ath_tx_update_ratectrl(struct ath_softc *sc, struct ieee80211_node *ni, an = ATH_NODE(ni); ATH_NODE_UNLOCK_ASSERT(an); + /* + * XXX TODO: teach the rate control about TXERR_FILT and + * see about handling it (eg see how many attempts were + * made before it got filtered and account for that.) + */ if ((ts->ts_status & HAL_TXERR_FILT) == 0) { ATH_NODE_LOCK(an); ath_rate_tx_complete(sc, an, rc, ts, frmlen, nframes, nbad); @@ -4355,6 +4360,9 @@ ath_tx_process_buf_completion(struct ath_softc *sc, struct ath_txq *txq, /* * XXX assume this isn't an aggregate * frame. + * + * XXX TODO: also do this for filtered frames? + * Once rate control knows about them? */ ath_tx_update_ratectrl(sc, ni, bf->bf_state.bfs_rc, ts, diff --git a/sys/dev/ath/if_ath_tx.c b/sys/dev/ath/if_ath_tx.c index 8d90a5d27fb1..43297cdd26c5 100644 --- a/sys/dev/ath/if_ath_tx.c +++ b/sys/dev/ath/if_ath_tx.c @@ -1376,10 +1376,12 @@ ath_tx_setds(struct ath_softc *sc, struct ath_buf *bf) * as they may depend upon the rate chosen. */ static void -ath_tx_do_ratelookup(struct ath_softc *sc, struct ath_buf *bf) +ath_tx_do_ratelookup(struct ath_softc *sc, struct ath_buf *bf, int tid, + bool is_aggr) { uint8_t rate, rix; int try0; + int maxdur; // Note: Unused for now if (! bf->bf_state.bfs_doratelookup) return; @@ -1389,7 +1391,7 @@ ath_tx_do_ratelookup(struct ath_softc *sc, struct ath_buf *bf) ATH_NODE_LOCK(ATH_NODE(bf->bf_node)); ath_rate_findrate(sc, ATH_NODE(bf->bf_node), bf->bf_state.bfs_shpream, - bf->bf_state.bfs_pktlen, &rix, &try0, &rate); + bf->bf_state.bfs_pktlen, tid, is_aggr, &rix, &try0, &rate, &maxdur); /* In case MRR is disabled, make sure rc[0] is setup correctly */ bf->bf_state.bfs_rc[0].rix = rix; @@ -1519,7 +1521,7 @@ ath_tx_xmit_normal(struct ath_softc *sc, struct ath_txq *txq, bf->bf_state.bfs_txflags |= HAL_TXDESC_CLRDMASK; /* Setup the descriptor before handoff */ - ath_tx_do_ratelookup(sc, bf); + ath_tx_do_ratelookup(sc, bf, tid->tid, false); ath_tx_calc_duration(sc, bf); ath_tx_calc_protection(sc, bf); ath_tx_set_rtscts(sc, bf); @@ -3094,7 +3096,7 @@ ath_tx_xmit_aggr(struct ath_softc *sc, struct ath_node *an, ath_tx_update_clrdmask(sc, tid, bf); /* Direct dispatch to hardware */ - ath_tx_do_ratelookup(sc, bf); + ath_tx_do_ratelookup(sc, bf, tid->tid, false); ath_tx_calc_duration(sc, bf); ath_tx_calc_protection(sc, bf); ath_tx_set_rtscts(sc, bf); @@ -4689,6 +4691,8 @@ ath_tx_comp_aggr_error(struct ath_softc *sc, struct ath_buf *bf_first, * * XXX use the length in the first frame in the series; * XXX just so things are consistent for now. + * + * XXX TODO: need to signal this is a large frame no matter what... */ ath_tx_update_ratectrl(sc, ni, bf_first->bf_state.bfs_rc, &bf_first->bf_status.ds_txstat, @@ -5088,9 +5092,11 @@ ath_tx_aggr_comp_aggr(struct ath_softc *sc, struct ath_buf *bf_first, * Now we know how many frames were bad, call the rate * control code. */ - if (fail == 0) + if (fail == 0) { + /* XXX TODO: what's pktlen here? */ ath_tx_update_ratectrl(sc, ni, rc, &ts, pktlen, nframes, nbad); + } /* * send bar if we dropped any frames @@ -5429,7 +5435,7 @@ ath_tx_tid_hw_queue_aggr(struct ath_softc *sc, struct ath_node *an, /* Update CLRDMASK just before this frame is queued */ ath_tx_update_clrdmask(sc, tid, bf); - ath_tx_do_ratelookup(sc, bf); + ath_tx_do_ratelookup(sc, bf, tid->tid, false); ath_tx_calc_duration(sc, bf); ath_tx_calc_protection(sc, bf); ath_tx_set_rtscts(sc, bf); @@ -5453,7 +5459,7 @@ ath_tx_tid_hw_queue_aggr(struct ath_softc *sc, struct ath_node *an, * really "do" aggregate lookups, so it only considers * the size of the first frame. */ - ath_tx_do_ratelookup(sc, bf); + ath_tx_do_ratelookup(sc, bf, tid->tid, true); bf->bf_state.bfs_rc[3].rix = 0; bf->bf_state.bfs_rc[3].tries = 0; @@ -5644,7 +5650,7 @@ ath_tx_tid_hw_queue_norm(struct ath_softc *sc, struct ath_node *an, ath_tx_update_clrdmask(sc, tid, bf); /* Program descriptors + rate control */ - ath_tx_do_ratelookup(sc, bf); + ath_tx_do_ratelookup(sc, bf, tid->tid, false); ath_tx_calc_duration(sc, bf); ath_tx_calc_protection(sc, bf); ath_tx_set_rtscts(sc, bf); diff --git a/sys/dev/ath/if_athrate.h b/sys/dev/ath/if_athrate.h index 8cf395c5d828..02b9e5ea5a58 100644 --- a/sys/dev/ath/if_athrate.h +++ b/sys/dev/ath/if_athrate.h @@ -132,10 +132,15 @@ void ath_rate_getxtxrates(struct ath_softc *sc, struct ath_node *an, * is to be setup then try0 should contain a value other than ATH_TXMATRY * and ath_rate_setupxtxdesc will be called after deciding if the frame * can be transmitted with multi-rate retry. + * + * maxdur is an optional return value (or -1 if not set) that defines + * the maximum frame duration in microseconds. This allows the rate + * control selection to override the maximum duration (normally 4ms) + * that the packet aggregation logic makes. */ void ath_rate_findrate(struct ath_softc *, struct ath_node *, - int shortPreamble, size_t frameLen, - u_int8_t *rix, int *try0, u_int8_t *txrate); + int shortPreamble, size_t frameLen, int tid, bool is_aggr, + u_int8_t *rix, int *try0, u_int8_t *txrate, int *maxdur); /* * Setup any extended (multi-rate) descriptor state for a data packet. * The rate index returned by ath_rate_findrate is passed back in.