net80211 drivers: fix rate setup for EAPOL frames, obtain Tx parameters

directly from the node.

- Use ni_txparms directly instead of calculating them manually every time
- Move M_EAPOL flag check upper; otherwise it may be skipped due to
'ucastrate' / 'mcastrate' check
- Use 'mgtrate' for control frames too (see ifconfig(8), mgtrate parameter)
- Add few more M_EAPOL checks where it was missing (zyd(4), ural(4),
urtw(4))
- Few unrelated cleanups

Tested with:
 - Intel 6205 (iwn(4)), STA mode;
 - WUSB54GC (rum(4)), HOSTAP mode + RTL8188EU (rtwn(4)), STA mode.

Reviewed by:	adrian
Differential Revision:	https://reviews.freebsd.org/D9811
This commit is contained in:
Andriy Voskoboinyk 2017-02-26 20:49:35 +00:00
parent 2fa6d2fe84
commit f631357540
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=314315
15 changed files with 56 additions and 92 deletions

View File

@ -2930,7 +2930,7 @@ bwi_encap(struct bwi_softc *sc, int idx, struct mbuf *m,
struct bwi_mac *mac;
struct bwi_txbuf_hdr *hdr;
struct ieee80211_frame *wh;
const struct ieee80211_txparam *tp;
const struct ieee80211_txparam *tp = ni->ni_txparms;
uint8_t rate, rate_fb;
uint32_t mac_ctrl;
uint16_t phy_ctrl;
@ -2955,7 +2955,6 @@ bwi_encap(struct bwi_softc *sc, int idx, struct mbuf *m,
/*
* Find TX rate
*/
tp = &vap->iv_txparms[ieee80211_chan2mode(ic->ic_curchan)];
if (type != IEEE80211_FC0_TYPE_DATA || (m->m_flags & M_EAPOL)) {
rate = rate_fb = tp->mgmtrate;
} else if (ismcast) {

View File

@ -6189,7 +6189,7 @@ bwn_set_txhdr(struct bwn_mac *mac, struct ieee80211_node *ni,
struct ieee80211_frame *protwh;
struct ieee80211_frame_cts *cts;
struct ieee80211_frame_rts *rts;
const struct ieee80211_txparam *tp;
const struct ieee80211_txparam *tp = ni->ni_txparms;
struct ieee80211vap *vap = ni->ni_vap;
struct ieee80211com *ic = &sc->sc_ic;
struct mbuf *mprot;
@ -6214,7 +6214,6 @@ bwn_set_txhdr(struct bwn_mac *mac, struct ieee80211_node *ni,
/*
* Find TX rate
*/
tp = &vap->iv_txparms[ieee80211_chan2mode(ic->ic_curchan)];
if (type != IEEE80211_FC0_TYPE_DATA || (m->m_flags & M_EAPOL))
rate = rate_fb = tp->mgmtrate;
else if (ismcast)

View File

@ -3549,7 +3549,9 @@ iwm_tx_fill_cmd(struct iwm_softc *sc, struct iwm_node *in,
tx->rts_retry_limit = IWM_RTS_DFAULT_RETRY_LIMIT;
tx->data_retry_limit = IWM_DEFAULT_TX_RETRY;
if (type == IEEE80211_FC0_TYPE_MGT) {
if (type == IEEE80211_FC0_TYPE_MGT ||
type == IEEE80211_FC0_TYPE_CTL ||
(m->m_flags & M_EAPOL) != 0) {
ridx = iwm_tx_rateidx_global_lookup(sc, tp->mgmtrate);
IWM_DPRINTF(sc, IWM_DEBUG_TXRATE,
"%s: MGT (%d)\n", __func__, tp->mgmtrate);
@ -3561,11 +3563,7 @@ iwm_tx_fill_cmd(struct iwm_softc *sc, struct iwm_node *in,
ridx = iwm_tx_rateidx_global_lookup(sc, tp->ucastrate);
IWM_DPRINTF(sc, IWM_DEBUG_TXRATE,
"%s: FIXED_RATE (%d)\n", __func__, tp->ucastrate);
} else if (m->m_flags & M_EAPOL) {
ridx = iwm_tx_rateidx_global_lookup(sc, tp->mgmtrate);
IWM_DPRINTF(sc, IWM_DEBUG_TXRATE,
"%s: EAPOL\n", __func__);
} else if (type == IEEE80211_FC0_TYPE_DATA) {
} else {
int i;
/* for data frames, use RS table */
@ -3582,10 +3580,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 {
ridx = iwm_tx_rateidx_global_lookup(sc, tp->mgmtrate);
IWM_DPRINTF(sc, IWM_DEBUG_TXRATE, "%s: DEFAULT (%d)\n",
__func__, tp->mgmtrate);
}
IWM_DPRINTF(sc, IWM_DEBUG_XMIT | IWM_DEBUG_TXRATE,

View File

@ -4370,7 +4370,7 @@ static int
iwn_tx_data(struct iwn_softc *sc, struct mbuf *m, struct ieee80211_node *ni)
{
struct iwn_ops *ops = &sc->ops;
const struct ieee80211_txparam *tp;
const struct ieee80211_txparam *tp = ni->ni_txparms;
struct ieee80211vap *vap = ni->ni_vap;
struct ieee80211com *ic = ni->ni_ic;
struct iwn_node *wn = (void *)ni;
@ -4449,15 +4449,14 @@ iwn_tx_data(struct iwn_softc *sc, struct mbuf *m, struct ieee80211_node *ni)
data = &ring->data[ring->cur];
/* Choose a TX rate index. */
tp = &vap->iv_txparms[ieee80211_chan2mode(ni->ni_chan)];
if (type == IEEE80211_FC0_TYPE_MGT)
if (type == IEEE80211_FC0_TYPE_MGT ||
type == IEEE80211_FC0_TYPE_CTL ||
(m->m_flags & M_EAPOL) != 0)
rate = tp->mgmtrate;
else if (IEEE80211_IS_MULTICAST(wh->i_addr1))
rate = tp->mcastrate;
else if (tp->ucastrate != IEEE80211_FIXED_RATE_NONE)
rate = tp->ucastrate;
else if (m->m_flags & M_EAPOL)
rate = tp->mgmtrate;
else {
/* XXX pass pktlen */
(void) ieee80211_ratectl_rate(ni, NULL, 0);

View File

@ -2231,11 +2231,11 @@ otus_tx(struct otus_softc *sc, struct ieee80211_node *ni, struct mbuf *m,
/* Pickup a rate index. */
if (params != NULL) {
rate = otus_rate_to_hw_rate(sc, params->ibp_rate0);
} else if (IEEE80211_IS_MULTICAST(wh->i_addr1) ||
(wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) != IEEE80211_FC0_TYPE_DATA) {
} else if (m->m_flags & M_EAPOL) {
/* Get lowest rate */
rate = otus_rate_to_hw_rate(sc, 0);
} else if (m->m_flags & M_EAPOL) {
} else if (IEEE80211_IS_MULTICAST(wh->i_addr1) ||
(wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) != IEEE80211_FC0_TYPE_DATA) {
/* Get lowest rate */
rate = otus_rate_to_hw_rate(sc, 0);
} else {

View File

@ -1518,7 +1518,7 @@ rt2560_tx_mgt(struct rt2560_softc *sc, struct mbuf *m0,
desc = &sc->prioq.desc[sc->prioq.cur];
data = &sc->prioq.data[sc->prioq.cur];
rate = vap->iv_txparms[ieee80211_chan2mode(ic->ic_curchan)].mgmtrate;
rate = ni->ni_txparms->mgmtrate;
wh = mtod(m0, struct ieee80211_frame *);
@ -1746,7 +1746,7 @@ rt2560_tx_data(struct rt2560_softc *sc, struct mbuf *m0,
struct rt2560_tx_desc *desc;
struct rt2560_tx_data *data;
struct ieee80211_frame *wh;
const struct ieee80211_txparam *tp;
const struct ieee80211_txparam *tp = ni->ni_txparms;
struct ieee80211_key *k;
struct mbuf *mnew;
bus_dma_segment_t segs[RT2560_MAX_SCATTER];
@ -1756,11 +1756,10 @@ rt2560_tx_data(struct rt2560_softc *sc, struct mbuf *m0,
wh = mtod(m0, struct ieee80211_frame *);
tp = &vap->iv_txparms[ieee80211_chan2mode(ni->ni_chan)];
if (IEEE80211_IS_MULTICAST(wh->i_addr1)) {
rate = tp->mcastrate;
} else if (m0->m_flags & M_EAPOL) {
if (m0->m_flags & M_EAPOL) {
rate = tp->mgmtrate;
} else if (IEEE80211_IS_MULTICAST(wh->i_addr1)) {
rate = tp->mcastrate;
} else if (tp->ucastrate != IEEE80211_FIXED_RATE_NONE) {
rate = tp->ucastrate;
} else {

View File

@ -1286,7 +1286,7 @@ rt2661_tx_mgt(struct rt2661_softc *sc, struct mbuf *m0,
desc = &sc->mgtq.desc[sc->mgtq.cur];
data = &sc->mgtq.data[sc->mgtq.cur];
rate = vap->iv_txparms[ieee80211_chan2mode(ic->ic_curchan)].mgmtrate;
rate = ni->ni_txparms->mgmtrate;
wh = mtod(m0, struct ieee80211_frame *);
@ -1435,7 +1435,7 @@ rt2661_tx_data(struct rt2661_softc *sc, struct mbuf *m0,
struct rt2661_tx_desc *desc;
struct rt2661_tx_data *data;
struct ieee80211_frame *wh;
const struct ieee80211_txparam *tp;
const struct ieee80211_txparam *tp = ni->ni_txparms;
struct ieee80211_key *k;
const struct chanAccParams *cap;
struct mbuf *mnew;
@ -1446,11 +1446,10 @@ rt2661_tx_data(struct rt2661_softc *sc, struct mbuf *m0,
wh = mtod(m0, struct ieee80211_frame *);
tp = &vap->iv_txparms[ieee80211_chan2mode(ni->ni_chan)];
if (IEEE80211_IS_MULTICAST(wh->i_addr1)) {
rate = tp->mcastrate;
} else if (m0->m_flags & M_EAPOL) {
if (m0->m_flags & M_EAPOL) {
rate = tp->mgmtrate;
} else if (IEEE80211_IS_MULTICAST(wh->i_addr1)) {
rate = tp->mcastrate;
} else if (tp->ucastrate != IEEE80211_FIXED_RATE_NONE) {
rate = tp->ucastrate;
} else {

View File

@ -1459,7 +1459,7 @@ rt2860_tx(struct rt2860_softc *sc, struct mbuf *m, struct ieee80211_node *ni)
struct rt2860_txd *txd;
struct rt2860_txwi *txwi;
struct ieee80211_frame *wh;
const struct ieee80211_txparam *tp;
const struct ieee80211_txparam *tp = ni->ni_txparms;
struct ieee80211_key *k;
struct mbuf *m1;
bus_dma_segment_t segs[RT2860_MAX_SCATTER];
@ -1488,11 +1488,10 @@ rt2860_tx(struct rt2860_softc *sc, struct mbuf *m, struct ieee80211_node *ni)
hdrlen = ieee80211_anyhdrsize(wh);
type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK;
tp = &vap->iv_txparms[ieee80211_chan2mode(ni->ni_chan)];
if (IEEE80211_IS_MULTICAST(wh->i_addr1)) {
rate = tp->mcastrate;
} else if (m->m_flags & M_EAPOL) {
if (m->m_flags & M_EAPOL) {
rate = tp->mgmtrate;
} else if (IEEE80211_IS_MULTICAST(wh->i_addr1)) {
rate = tp->mcastrate;
} else if (tp->ucastrate != IEEE80211_FIXED_RATE_NONE) {
rate = tp->ucastrate;
} else {

View File

@ -112,17 +112,16 @@ static int
rtwn_tx_data(struct rtwn_softc *sc, struct ieee80211_node *ni,
struct mbuf *m)
{
const struct ieee80211_txparam *tp;
const struct ieee80211_txparam *tp = ni->ni_txparms;
struct ieee80211com *ic = &sc->sc_ic;
struct ieee80211vap *vap = ni->ni_vap;
struct ieee80211_key *k = NULL;
struct ieee80211_channel *chan;
struct ieee80211_frame *wh;
struct rtwn_tx_desc_common *txd;
struct rtwn_tx_buf buf;
uint8_t rate, ridx, type;
u_int cipher;
int ismcast, maxretry;
int ismcast;
RTWN_ASSERT_LOCKED(sc);
@ -130,20 +129,15 @@ rtwn_tx_data(struct rtwn_softc *sc, struct ieee80211_node *ni,
type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK;
ismcast = IEEE80211_IS_MULTICAST(wh->i_addr1);
chan = (ni->ni_chan != IEEE80211_CHAN_ANYC) ?
ni->ni_chan : ic->ic_curchan;
tp = &vap->iv_txparms[ieee80211_chan2mode(chan)];
maxretry = tp->maxretry;
/* Choose a TX rate index. */
if (type == IEEE80211_FC0_TYPE_MGT)
if (type == IEEE80211_FC0_TYPE_MGT ||
type == IEEE80211_FC0_TYPE_CTL ||
(m->m_flags & M_EAPOL) != 0)
rate = tp->mgmtrate;
else if (ismcast)
rate = tp->mcastrate;
else if (tp->ucastrate != IEEE80211_FIXED_RATE_NONE)
rate = tp->ucastrate;
else if (m->m_flags & M_EAPOL)
rate = tp->mgmtrate;
else {
if (sc->sc_ratectl == RTWN_RATECTL_NET80211) {
/* XXX pass pktlen */
@ -181,7 +175,7 @@ rtwn_tx_data(struct rtwn_softc *sc, struct ieee80211_node *ni,
memset(txd, 0, sc->txdesc_len);
txd->txdw1 = htole32(SM(RTWN_TXDW1_CIPHER, rtwn_get_cipher(cipher)));
rtwn_fill_tx_desc(sc, ni, m, txd, ridx, maxretry);
rtwn_fill_tx_desc(sc, ni, m, txd, ridx, tp->maxretry);
if (ieee80211_radiotap_active_vap(vap)) {
struct rtwn_tx_radiotap_header *tap = &sc->sc_txtap;

View File

@ -1503,11 +1503,10 @@ rum_tx_crypto_flags(struct rum_softc *sc, struct ieee80211_node *ni,
static int
rum_tx_mgt(struct rum_softc *sc, struct mbuf *m0, struct ieee80211_node *ni)
{
struct ieee80211vap *vap = ni->ni_vap;
const struct ieee80211_txparam *tp = ni->ni_txparms;
struct ieee80211com *ic = &sc->sc_ic;
struct rum_tx_data *data;
struct ieee80211_frame *wh;
const struct ieee80211_txparam *tp;
struct ieee80211_key *k = NULL;
uint32_t flags = 0;
uint16_t dur;
@ -1537,8 +1536,6 @@ rum_tx_mgt(struct rum_softc *sc, struct mbuf *m0, struct ieee80211_node *ni)
wh = mtod(m0, struct ieee80211_frame *);
}
tp = &vap->iv_txparms[ieee80211_chan2mode(ic->ic_curchan)];
if (!IEEE80211_IS_MULTICAST(wh->i_addr1)) {
flags |= RT2573_TX_NEED_ACK;
@ -1642,7 +1639,7 @@ rum_tx_data(struct rum_softc *sc, struct mbuf *m0, struct ieee80211_node *ni)
struct ieee80211com *ic = &sc->sc_ic;
struct rum_tx_data *data;
struct ieee80211_frame *wh;
const struct ieee80211_txparam *tp;
const struct ieee80211_txparam *tp = ni->ni_txparms;
struct ieee80211_key *k = NULL;
uint32_t flags = 0;
uint16_t dur;
@ -1661,13 +1658,12 @@ rum_tx_data(struct rum_softc *sc, struct mbuf *m0, struct ieee80211_node *ni)
qos = 0;
ac = M_WME_GETAC(m0);
tp = &vap->iv_txparms[ieee80211_chan2mode(ni->ni_chan)];
if (IEEE80211_IS_MULTICAST(wh->i_addr1))
if (m0->m_flags & M_EAPOL)
rate = tp->mgmtrate;
else if (IEEE80211_IS_MULTICAST(wh->i_addr1))
rate = tp->mcastrate;
else if (tp->ucastrate != IEEE80211_FIXED_RATE_NONE)
rate = tp->ucastrate;
else if (m0->m_flags & M_EAPOL)
rate = tp->mgmtrate;
else {
(void) ieee80211_ratectl_rate(ni, NULL, 0);
rate = ni->ni_txrate;
@ -2190,12 +2186,11 @@ rum_set_chan(struct rum_softc *sc, struct ieee80211_channel *c)
static void
rum_set_maxretry(struct rum_softc *sc, struct ieee80211vap *vap)
{
const struct ieee80211_txparam *tp;
struct ieee80211_node *ni = vap->iv_bss;
const struct ieee80211_txparam *tp = ni->ni_txparms;
struct rum_vap *rvp = RUM_VAP(vap);
tp = &vap->iv_txparms[ieee80211_chan2mode(ni->ni_chan)];
rvp->maxretry = tp->maxretry < 0xf ? tp->maxretry : 0xf;
rvp->maxretry = MIN(tp->maxretry, 0xf);
rum_modbits(sc, RT2573_TXRX_CSR4, RT2573_SHORT_RETRY(rvp->maxretry) |
RT2573_LONG_RETRY(rvp->maxretry),

View File

@ -3310,8 +3310,7 @@ run_tx(struct run_softc *sc, struct mbuf *m, struct ieee80211_node *ni)
struct ieee80211com *ic = &sc->sc_ic;
struct ieee80211vap *vap = ni->ni_vap;
struct ieee80211_frame *wh;
struct ieee80211_channel *chan;
const struct ieee80211_txparam *tp;
const struct ieee80211_txparam *tp = ni->ni_txparms;
struct run_node *rn = RUN_NODE(ni);
struct run_tx_data *data;
struct rt2870_txd *txd;
@ -3360,9 +3359,6 @@ run_tx(struct run_softc *sc, struct mbuf *m, struct ieee80211_node *ni)
RUN_DPRINTF(sc, RUN_DEBUG_XMIT, "qos %d\tqid %d\ttid %d\tqflags %x\n",
qos, qid, tid, qflags);
chan = (ni->ni_chan != IEEE80211_CHAN_ANYC)?ni->ni_chan:ic->ic_curchan;
tp = &vap->iv_txparms[ieee80211_chan2mode(chan)];
/* pickup a rate index */
if (IEEE80211_IS_MULTICAST(wh->i_addr1) ||
type != IEEE80211_FC0_TYPE_DATA || m->m_flags & M_EAPOL) {

View File

@ -1070,9 +1070,8 @@ ural_tx_bcn(struct ural_softc *sc, struct mbuf *m0, struct ieee80211_node *ni)
static int
ural_tx_mgt(struct ural_softc *sc, struct mbuf *m0, struct ieee80211_node *ni)
{
struct ieee80211vap *vap = ni->ni_vap;
const struct ieee80211_txparam *tp = ni->ni_txparms;
struct ieee80211com *ic = ni->ni_ic;
const struct ieee80211_txparam *tp;
struct ural_tx_data *data;
struct ieee80211_frame *wh;
struct ieee80211_key *k;
@ -1085,8 +1084,6 @@ ural_tx_mgt(struct ural_softc *sc, struct mbuf *m0, struct ieee80211_node *ni)
STAILQ_REMOVE_HEAD(&sc->tx_free, next);
sc->tx_nfree--;
tp = &vap->iv_txparms[ieee80211_chan2mode(ic->ic_curchan)];
wh = mtod(m0, struct ieee80211_frame *);
if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED) {
k = ieee80211_crypto_encap(ni, m0);
@ -1239,7 +1236,7 @@ ural_tx_data(struct ural_softc *sc, struct mbuf *m0, struct ieee80211_node *ni)
struct ieee80211com *ic = ni->ni_ic;
struct ural_tx_data *data;
struct ieee80211_frame *wh;
const struct ieee80211_txparam *tp;
const struct ieee80211_txparam *tp = ni->ni_txparms;
struct ieee80211_key *k;
uint32_t flags = 0;
uint16_t dur;
@ -1249,8 +1246,9 @@ ural_tx_data(struct ural_softc *sc, struct mbuf *m0, struct ieee80211_node *ni)
wh = mtod(m0, struct ieee80211_frame *);
tp = &vap->iv_txparms[ieee80211_chan2mode(ni->ni_chan)];
if (IEEE80211_IS_MULTICAST(wh->i_addr1))
if (m0->m_flags & M_EAPOL)
rate = tp->mgmtrate;
else if (IEEE80211_IS_MULTICAST(wh->i_addr1))
rate = tp->mcastrate;
else if (tp->ucastrate != IEEE80211_FIXED_RATE_NONE)
rate = tp->ucastrate;

View File

@ -1643,7 +1643,7 @@ urtw_tx_start(struct urtw_softc *sc, struct ieee80211_node *ni, struct mbuf *m0,
{
struct ieee80211_frame *wh = mtod(m0, struct ieee80211_frame *);
struct ieee80211_key *k;
const struct ieee80211_txparam *tp;
const struct ieee80211_txparam *tp = ni->ni_txparms;
struct ieee80211com *ic = &sc->sc_ic;
struct ieee80211vap *vap = ni->ni_vap;
struct usb_xfer *rtl8187b_pipes[URTW_8187B_TXPIPE_MAX] = {
@ -1690,11 +1690,10 @@ urtw_tx_start(struct urtw_softc *sc, struct ieee80211_node *ni, struct mbuf *m0,
}
if ((wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) == IEEE80211_FC0_TYPE_MGT ||
(wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) == IEEE80211_FC0_TYPE_CTL) {
tp = &vap->iv_txparms[ieee80211_chan2mode(ic->ic_curchan)];
(wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) == IEEE80211_FC0_TYPE_CTL ||
(m0->m_flags & M_EAPOL) != 0) {
rate = tp->mgmtrate;
} else {
tp = &vap->iv_txparms[ieee80211_chan2mode(ni->ni_chan)];
/* for data frames */
if (IEEE80211_IS_MULTICAST(wh->i_addr1))
rate = tp->mcastrate;

View File

@ -2439,7 +2439,7 @@ zyd_tx_start(struct zyd_softc *sc, struct mbuf *m0, struct ieee80211_node *ni)
struct zyd_tx_desc *desc;
struct zyd_tx_data *data;
struct ieee80211_frame *wh;
const struct ieee80211_txparam *tp;
const struct ieee80211_txparam *tp = ni->ni_txparms;
struct ieee80211_key *k;
int rate, totlen;
static const uint8_t ratediv[] = ZYD_TX_RATEDIV;
@ -2453,11 +2453,10 @@ zyd_tx_start(struct zyd_softc *sc, struct mbuf *m0, struct ieee80211_node *ni)
sc->tx_nfree--;
if ((wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) == IEEE80211_FC0_TYPE_MGT ||
(wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) == IEEE80211_FC0_TYPE_CTL) {
tp = &vap->iv_txparms[ieee80211_chan2mode(ic->ic_curchan)];
(wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) == IEEE80211_FC0_TYPE_CTL ||
(m0->m_flags & M_EAPOL) != 0) {
rate = tp->mgmtrate;
} else {
tp = &vap->iv_txparms[ieee80211_chan2mode(ni->ni_chan)];
/* for data frames */
if (IEEE80211_IS_MULTICAST(wh->i_addr1))
rate = tp->mcastrate;

View File

@ -2784,11 +2784,10 @@ end: DPRINTF(sc, WPI_DEBUG_TRACE, error ? TRACE_STR_END_ERR : TRACE_STR_END,
static int
wpi_tx_data(struct wpi_softc *sc, struct mbuf *m, struct ieee80211_node *ni)
{
const struct ieee80211_txparam *tp;
const struct ieee80211_txparam *tp = ni->ni_txparms;
struct ieee80211vap *vap = ni->ni_vap;
struct ieee80211com *ic = ni->ni_ic;
struct wpi_node *wn = WPI_NODE(ni);
struct ieee80211_channel *chan;
struct ieee80211_frame *wh;
struct ieee80211_key *k = NULL;
struct wpi_buf tx_data;
@ -2813,19 +2812,15 @@ wpi_tx_data(struct wpi_softc *sc, struct mbuf *m, struct ieee80211_node *ni)
}
ac = M_WME_GETAC(m);
chan = (ni->ni_chan != IEEE80211_CHAN_ANYC) ?
ni->ni_chan : ic->ic_curchan;
tp = &vap->iv_txparms[ieee80211_chan2mode(chan)];
/* Choose a TX rate index. */
if (type == IEEE80211_FC0_TYPE_MGT)
if (type == IEEE80211_FC0_TYPE_MGT ||
type == IEEE80211_FC0_TYPE_CTL ||
(m->m_flags & M_EAPOL) != 0)
rate = tp->mgmtrate;
else if (ismcast)
rate = tp->mcastrate;
else if (tp->ucastrate != IEEE80211_FIXED_RATE_NONE)
rate = tp->ucastrate;
else if (m->m_flags & M_EAPOL)
rate = tp->mgmtrate;
else {
/* XXX pass pktlen */
(void) ieee80211_ratectl_rate(ni, NULL, 0);