Index: head/sys/dev/iwm/if_iwm.c =================================================================== --- head/sys/dev/iwm/if_iwm.c +++ head/sys/dev/iwm/if_iwm.c @@ -324,7 +324,7 @@ #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 @@ */ 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_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 @@ 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) {