[iwm] use rate control info from the node txrates; use mgmtrate for EAPOL frames

This changes the transmit rate control code to do a few things:

* use fixed rates (mcast, ucast, mgmt) where required.
* Don't use a hard-coded 11a or 11bg rate for non-data frames -
  use what net80211 says we should use.
* use mgmtrate for EAPOL frames.

Reviewed by:	avos
Differential Revision:	https://reviews.freebsd.org/D7994
This commit is contained in:
Adrian Chadd 2016-09-21 20:56:10 +00:00
parent 172b009aef
commit cf4f71f1e5

View File

@ -324,7 +324,7 @@ static void iwm_update_sched(struct iwm_softc *, int, int, uint8_t,
#endif
static const struct iwm_rate *
iwm_tx_fill_cmd(struct iwm_softc *, struct iwm_node *,
struct ieee80211_frame *, struct iwm_tx_cmd *);
struct mbuf *, struct iwm_tx_cmd *);
static int iwm_tx(struct iwm_softc *, struct mbuf *,
struct ieee80211_node *, int);
static int iwm_raw_xmit(struct ieee80211_node *, struct mbuf *,
@ -3197,24 +3197,36 @@ iwm_tx_rateidx_lookup(struct iwm_softc *sc, struct iwm_node *in,
*/
static const struct iwm_rate *
iwm_tx_fill_cmd(struct iwm_softc *sc, struct iwm_node *in,
struct ieee80211_frame *wh, struct iwm_tx_cmd *tx)
struct mbuf *m, struct iwm_tx_cmd *tx)
{
struct ieee80211com *ic = &sc->sc_ic;
struct ieee80211_node *ni = &in->in_ni;
struct ieee80211_frame *wh;
const struct ieee80211_txparam *tp = ni->ni_txparms;
const struct iwm_rate *rinfo;
int type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK;
int ridx, rate_flags;
int type;
int ridx, rate_flags, i;
wh = mtod(m, struct ieee80211_frame *);
type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK;
tx->rts_retry_limit = IWM_RTS_DFAULT_RETRY_LIMIT;
tx->data_retry_limit = IWM_DEFAULT_TX_RETRY;
/*
* XXX TODO: everything about the rate selection here is terrible!
*/
if (type == IEEE80211_FC0_TYPE_DATA) {
int i;
if (type == IEEE80211_FC0_TYPE_MGT) {
i = iwm_tx_rateidx_lookup(sc, in, tp->mgmtrate);
ridx = in->in_ridx[i];
} else if (IEEE80211_IS_MULTICAST(wh->i_addr1)) {
i = iwm_tx_rateidx_lookup(sc, in, tp->mcastrate);
ridx = in->in_ridx[i];
} else if (tp->ucastrate != IEEE80211_FIXED_RATE_NONE) {
i = iwm_tx_rateidx_lookup(sc, in, tp->ucastrate);
ridx = in->in_ridx[i];
} else if (m->m_flags & M_EAPOL) {
i = iwm_tx_rateidx_lookup(sc, in, tp->mgmtrate);
ridx = in->in_ridx[i];
} else {
/* for data frames, use RS table */
/* XXX pass pktlen */
(void) ieee80211_ratectl_rate(ni, NULL, 0);
i = iwm_tx_rateidx_lookup(sc, in, ni->ni_txrate);
ridx = in->in_ridx[i];
@ -3225,28 +3237,6 @@ iwm_tx_fill_cmd(struct iwm_softc *sc, struct iwm_node *in,
IWM_DPRINTF(sc, IWM_DEBUG_XMIT | IWM_DEBUG_TXRATE,
"%s: start with i=%d, txrate %d\n",
__func__, i, iwm_rates[ridx].rate);
} else {
/*
* For non-data, use the lowest supported rate for the given
* operational mode.
*
* Note: there may not be any rate control information available.
* This driver currently assumes if we're transmitting data
* frames, use the rate control table. Grr.
*
* XXX TODO: use the configured rate for the traffic type!
* XXX TODO: this should be per-vap, not curmode; as we later
* on we'll want to handle off-channel stuff (eg TDLS).
*/
if (ic->ic_curmode == IEEE80211_MODE_11A) {
/*
* XXX this assumes the mode is either 11a or not 11a;
* definitely won't work for 11n.
*/
ridx = IWM_RIDX_OFDM;
} else {
ridx = IWM_RIDX_CCK;
}
}
rinfo = &iwm_rates[ridx];
@ -3308,7 +3298,7 @@ iwm_tx(struct iwm_softc *sc, struct mbuf *m, struct ieee80211_node *ni, int ac)
tx = (void *)cmd->data;
memset(tx, 0, sizeof(*tx));
rinfo = iwm_tx_fill_cmd(sc, in, wh, tx);
rinfo = iwm_tx_fill_cmd(sc, in, m, tx);
/* Encrypt the frame if need be. */
if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED) {