Changeset View
Changeset View
Standalone View
Standalone View
sys/dev/rtwn/if_rtwn_tx.c
Show First 20 Lines • Show All 106 Lines • ▼ Show 20 Lines | rtwn_get_cipher(u_int ic_cipher) | ||||
return (cipher); | return (cipher); | ||||
} | } | ||||
static int | static int | ||||
rtwn_tx_data(struct rtwn_softc *sc, struct ieee80211_node *ni, | rtwn_tx_data(struct rtwn_softc *sc, struct ieee80211_node *ni, | ||||
struct mbuf *m) | struct mbuf *m) | ||||
{ | { | ||||
const struct ieee80211_txparam *tp = ni->ni_txparms; | const struct ieee80211_txparam_vht *tp = ni->ni_txparms; | ||||
struct ieee80211com *ic = &sc->sc_ic; | struct ieee80211com *ic = &sc->sc_ic; | ||||
struct ieee80211vap *vap = ni->ni_vap; | struct ieee80211vap *vap = ni->ni_vap; | ||||
struct ieee80211_key *k = NULL; | struct ieee80211_key *k = NULL; | ||||
struct ieee80211_frame *wh; | struct ieee80211_frame *wh; | ||||
struct rtwn_tx_desc_common *txd; | struct rtwn_tx_desc_common *txd; | ||||
struct rtwn_tx_buf buf; | struct rtwn_tx_buf buf; | ||||
uint8_t rate, ridx, type; | uint16_t rate_idx; | ||||
uint8_t type; | |||||
u_int cipher; | u_int cipher; | ||||
int ismcast; | int ismcast; | ||||
RTWN_ASSERT_LOCKED(sc); | RTWN_ASSERT_LOCKED(sc); | ||||
wh = mtod(m, struct ieee80211_frame *); | wh = mtod(m, struct ieee80211_frame *); | ||||
type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK; | type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK; | ||||
ismcast = IEEE80211_IS_MULTICAST(wh->i_addr1); | ismcast = IEEE80211_IS_MULTICAST(wh->i_addr1); | ||||
/* Choose a TX rate index. */ | /* Choose a TX rate index. */ | ||||
if (type == IEEE80211_FC0_TYPE_MGT || | if (type == IEEE80211_FC0_TYPE_MGT || | ||||
type == IEEE80211_FC0_TYPE_CTL || | type == IEEE80211_FC0_TYPE_CTL || | ||||
(m->m_flags & M_EAPOL) != 0) | (m->m_flags & M_EAPOL) != 0) | ||||
rate = tp->mgmtrate; | rate_idx = tp->mgmtrate; | ||||
else if (ismcast) | else if (ismcast) | ||||
rate = tp->mcastrate; | rate_idx = tp->mcastrate; | ||||
else if (tp->ucastrate != IEEE80211_FIXED_RATE_NONE) | else if (tp->ucastrate != IEEE80211_RATE_NONEXISTENT) | ||||
rate = tp->ucastrate; | rate_idx = tp->ucastrate; | ||||
else { | else { | ||||
if (sc->sc_ratectl == RTWN_RATECTL_NET80211) { | if (sc->sc_ratectl == RTWN_RATECTL_NET80211) { | ||||
/* XXX pass pktlen */ | /* XXX pass pktlen */ | ||||
(void) ieee80211_ratectl_rate(ni, NULL, 0); | (void) ieee80211_ratectl_rate(ni, NULL, 0); | ||||
rate = ni->ni_txrate; | rate_idx = ni->ni_txrate; | ||||
} else { | } else { | ||||
if (ni->ni_flags & IEEE80211_NODE_VHT) | |||||
rate_idx = IEEE80211_RATE_INDEX_VHT(4, 1); | |||||
if (ni->ni_flags & IEEE80211_NODE_HT) | if (ni->ni_flags & IEEE80211_NODE_HT) | ||||
rate = IEEE80211_RATE_MCS | 0x4; /* MCS4 */ | rate_idx = IEEE80211_RATE_INDEX_HT(4); | ||||
else if (ic->ic_curmode != IEEE80211_MODE_11B) | else if (ic->ic_curmode != IEEE80211_MODE_11B) | ||||
rate = ridx2rate[RTWN_RIDX_OFDM36]; | rate_idx = IEEE80211_RATE_INDEX_OFDM36; | ||||
else | else | ||||
rate = ridx2rate[RTWN_RIDX_CCK55]; | rate_idx = IEEE80211_RATE_INDEX_CCK5; | ||||
} | } | ||||
} | } | ||||
ridx = rate2ridx(rate); | |||||
cipher = IEEE80211_CIPHER_NONE; | cipher = IEEE80211_CIPHER_NONE; | ||||
if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED) { | if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED) { | ||||
k = ieee80211_crypto_encap(ni, m); | k = ieee80211_crypto_encap(ni, m); | ||||
if (k == NULL) { | if (k == NULL) { | ||||
device_printf(sc->sc_dev, | device_printf(sc->sc_dev, | ||||
"ieee80211_crypto_encap returns NULL.\n"); | "ieee80211_crypto_encap returns NULL.\n"); | ||||
return (ENOBUFS); | return (ENOBUFS); | ||||
} | } | ||||
if (!(k->wk_flags & IEEE80211_KEY_SWCRYPT)) | if (!(k->wk_flags & IEEE80211_KEY_SWCRYPT)) | ||||
cipher = k->wk_cipher->ic_cipher; | cipher = k->wk_cipher->ic_cipher; | ||||
/* in case packet header moved, reset pointer */ | /* in case packet header moved, reset pointer */ | ||||
wh = mtod(m, struct ieee80211_frame *); | wh = mtod(m, struct ieee80211_frame *); | ||||
} | } | ||||
/* Fill Tx descriptor. */ | /* Fill Tx descriptor. */ | ||||
txd = (struct rtwn_tx_desc_common *)&buf; | txd = (struct rtwn_tx_desc_common *)&buf; | ||||
memset(txd, 0, sc->txdesc_len); | memset(txd, 0, sc->txdesc_len); | ||||
txd->txdw1 = htole32(SM(RTWN_TXDW1_CIPHER, rtwn_get_cipher(cipher))); | txd->txdw1 = htole32(SM(RTWN_TXDW1_CIPHER, rtwn_get_cipher(cipher))); | ||||
rtwn_fill_tx_desc(sc, ni, m, txd, ridx, tp->maxretry); | rtwn_fill_tx_desc(sc, ni, m, txd, rate_idx, tp->maxretry); | ||||
if (ieee80211_radiotap_active_vap(vap)) { | if (ieee80211_radiotap_active_vap(vap)) { | ||||
struct rtwn_tx_radiotap_header *tap = &sc->sc_txtap; | struct rtwn_tx_radiotap_header *tap = &sc->sc_txtap; | ||||
tap->wt_flags = rtwn_tx_radiotap_flags(sc, txd); | tap->wt_flags = rtwn_tx_radiotap_flags(sc, txd); | ||||
if (k != NULL) | if (k != NULL) | ||||
tap->wt_flags |= IEEE80211_RADIOTAP_F_WEP; | tap->wt_flags |= IEEE80211_RADIOTAP_F_WEP; | ||||
ieee80211_radiotap_tx(vap, m); | ieee80211_radiotap_tx(vap, m); | ||||
▲ Show 20 Lines • Show All 154 Lines • Show Last 20 Lines |