Changeset View
Changeset View
Standalone View
Standalone View
sys/dev/rtwn/rtl8812a/r12a_tx.c
Show First 20 Lines • Show All 83 Lines • ▼ Show 20 Lines | txd->txdw5 |= htole32(SM(R12A_TXDW5_DATA_BW, | ||||
R12A_TXDW5_DATA_BW40)); | R12A_TXDW5_DATA_BW40)); | ||||
txd->txdw5 |= htole32(SM(R12A_TXDW5_DATA_PRIM_CHAN, | txd->txdw5 |= htole32(SM(R12A_TXDW5_DATA_PRIM_CHAN, | ||||
prim_chan)); | prim_chan)); | ||||
} | } | ||||
} | } | ||||
static void | static void | ||||
r12a_tx_protection(struct rtwn_softc *sc, struct r12a_tx_desc *txd, | r12a_tx_protection(struct rtwn_softc *sc, struct r12a_tx_desc *txd, | ||||
enum ieee80211_protmode mode, uint8_t ridx) | enum ieee80211_protmode mode, uint16_t rate_idx) | ||||
{ | { | ||||
const struct ieee80211_rate_t *rate; | |||||
struct ieee80211com *ic = &sc->sc_ic; | struct ieee80211com *ic = &sc->sc_ic; | ||||
uint8_t rate; | uint8_t ridx; | ||||
switch (mode) { | switch (mode) { | ||||
case IEEE80211_PROT_CTSONLY: | case IEEE80211_PROT_CTSONLY: | ||||
txd->txdw3 |= htole32(R12A_TXDW3_CTS2SELF); | txd->txdw3 |= htole32(R12A_TXDW3_CTS2SELF); | ||||
break; | break; | ||||
case IEEE80211_PROT_RTSCTS: | case IEEE80211_PROT_RTSCTS: | ||||
txd->txdw3 |= htole32(R12A_TXDW3_RTSEN); | txd->txdw3 |= htole32(R12A_TXDW3_RTSEN); | ||||
break; | break; | ||||
default: | default: | ||||
break; | break; | ||||
} | } | ||||
if (mode == IEEE80211_PROT_CTSONLY || | if (mode == IEEE80211_PROT_CTSONLY || | ||||
mode == IEEE80211_PROT_RTSCTS) { | mode == IEEE80211_PROT_RTSCTS) { | ||||
if (ridx >= RTWN_RIDX_HT_MCS(0)) | rate = ieee80211_ctl_rate(ic->ic_rt->ctl_rates, rate_idx); | ||||
rate = rtwn_ctl_mcsrate(ic->ic_rt, ridx); | |||||
else | |||||
rate = ieee80211_ctl_rate(ic->ic_rt, ridx2rate[ridx]); | |||||
ridx = rate2ridx(rate); | ridx = rate2ridx(rate); | ||||
txd->txdw4 |= htole32(SM(R12A_TXDW4_RTSRATE, ridx)); | txd->txdw4 |= htole32(SM(R12A_TXDW4_RTSRATE, ridx)); | ||||
/* RTS rate fallback limit (max). */ | /* RTS rate fallback limit (max). */ | ||||
txd->txdw4 |= htole32(SM(R12A_TXDW4_RTSRATE_FB_LMT, 0xf)); | txd->txdw4 |= htole32(SM(R12A_TXDW4_RTSRATE_FB_LMT, 0xf)); | ||||
if (RTWN_RATE_IS_CCK(ridx) && ridx != RTWN_RIDX_CCK1 && | if (rate->type == IEEE80211_T_CCK && | ||||
rate->props.cck.short_preamble && | |||||
(ic->ic_flags & IEEE80211_F_SHPREAMBLE)) | (ic->ic_flags & IEEE80211_F_SHPREAMBLE)) | ||||
txd->txdw5 |= htole32(R12A_TXDW5_RTS_SHORT); | txd->txdw5 |= htole32(R12A_TXDW5_RTS_SHORT); | ||||
} | } | ||||
} | } | ||||
static void | static void | ||||
r12a_tx_raid(struct rtwn_softc *sc, struct r12a_tx_desc *txd, | r12a_tx_raid(struct rtwn_softc *sc, struct r12a_tx_desc *txd, | ||||
struct ieee80211_node *ni, int ismcast) | struct ieee80211_node *ni, int ismcast) | ||||
▲ Show 20 Lines • Show All 93 Lines • ▼ Show 20 Lines | r12a_tx_set_ldpc(struct rtwn_softc *sc, struct r12a_tx_desc *txd, | ||||
if ((vap->iv_flags_ht & IEEE80211_FHT_LDPC_TX) && | if ((vap->iv_flags_ht & IEEE80211_FHT_LDPC_TX) && | ||||
(ni->ni_htcap & IEEE80211_HTCAP_LDPC)) | (ni->ni_htcap & IEEE80211_HTCAP_LDPC)) | ||||
txd->txdw5 |= htole32(R12A_TXDW5_DATA_LDPC); | txd->txdw5 |= htole32(R12A_TXDW5_DATA_LDPC); | ||||
} | } | ||||
void | void | ||||
r12a_fill_tx_desc(struct rtwn_softc *sc, struct ieee80211_node *ni, | r12a_fill_tx_desc(struct rtwn_softc *sc, struct ieee80211_node *ni, | ||||
struct mbuf *m, void *buf, uint8_t ridx, int maxretry) | struct mbuf *m, void *buf, uint16_t rate_idx, int maxretry) | ||||
{ | { | ||||
const struct ieee80211_rate_t *rate; | |||||
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 rtwn_vap *uvp = RTWN_VAP(vap); | struct rtwn_vap *uvp = RTWN_VAP(vap); | ||||
struct ieee80211_frame *wh; | struct ieee80211_frame *wh; | ||||
struct r12a_tx_desc *txd; | struct r12a_tx_desc *txd; | ||||
enum ieee80211_protmode prot; | enum ieee80211_protmode prot; | ||||
uint8_t type, tid, qos, qsel; | uint8_t type, tid, qos, qsel, ridx; | ||||
int hasqos, ismcast, macid; | int hasqos, ismcast, macid; | ||||
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; | ||||
hasqos = IEEE80211_QOS_HAS_SEQ(wh); | hasqos = IEEE80211_QOS_HAS_SEQ(wh); | ||||
ismcast = IEEE80211_IS_MULTICAST(wh->i_addr1); | ismcast = IEEE80211_IS_MULTICAST(wh->i_addr1); | ||||
rate = ieee80211_get_rate(rate_idx); | |||||
ridx = rate2ridx(rate); | |||||
/* Select TX ring for this frame. */ | /* Select TX ring for this frame. */ | ||||
if (hasqos) { | if (hasqos) { | ||||
qos = ((const struct ieee80211_qosframe *)wh)->i_qos[0]; | qos = ((const struct ieee80211_qosframe *)wh)->i_qos[0]; | ||||
tid = qos & IEEE80211_QOS_TID; | tid = qos & IEEE80211_QOS_TID; | ||||
} else { | } else { | ||||
qos = 0; | qos = 0; | ||||
tid = 0; | tid = 0; | ||||
} | } | ||||
Show All 28 Lines | if (type == IEEE80211_FC0_TYPE_DATA) { | ||||
} else | } else | ||||
txd->txdw2 |= htole32(R12A_TXDW2_AGGBK); | txd->txdw2 |= htole32(R12A_TXDW2_AGGBK); | ||||
if (sc->sc_ratectl == RTWN_RATECTL_NET80211) { | if (sc->sc_ratectl == RTWN_RATECTL_NET80211) { | ||||
txd->txdw2 |= htole32(R12A_TXDW2_SPE_RPT); | txd->txdw2 |= htole32(R12A_TXDW2_SPE_RPT); | ||||
sc->sc_tx_n_active++; | sc->sc_tx_n_active++; | ||||
} | } | ||||
if (RTWN_RATE_IS_CCK(ridx) && ridx != RTWN_RIDX_CCK1 && | if (rate->type == IEEE80211_T_CCK && | ||||
rate->props.cck.short_preamble && | |||||
(ic->ic_flags & IEEE80211_F_SHPREAMBLE)) | (ic->ic_flags & IEEE80211_F_SHPREAMBLE)) | ||||
txd->txdw5 |= htole32(R12A_TXDW5_DATA_SHORT); | txd->txdw5 |= htole32(R12A_TXDW5_DATA_SHORT); | ||||
prot = IEEE80211_PROT_NONE; | prot = IEEE80211_PROT_NONE; | ||||
if (ridx >= RTWN_RIDX_HT_MCS(0)) { | if (rate->type == IEEE80211_T_HT) { | ||||
r12a_tx_set_ht40(sc, txd, ni); | r12a_tx_set_ht40(sc, txd, ni); | ||||
r12a_tx_set_sgi(sc, txd, ni); | r12a_tx_set_sgi(sc, txd, ni); | ||||
r12a_tx_set_ldpc(sc, txd, ni); | r12a_tx_set_ldpc(sc, txd, ni); | ||||
prot = ic->ic_htprotmode; | prot = ic->ic_htprotmode; | ||||
} else if (ic->ic_flags & IEEE80211_F_USEPROT) | } else if (ic->ic_flags & IEEE80211_F_USEPROT) | ||||
prot = ic->ic_protmode; | prot = ic->ic_protmode; | ||||
/* XXX fix last comparison for A-MSDU (in net80211) */ | /* XXX fix last comparison for A-MSDU (in net80211) */ | ||||
/* XXX A-MPDU? */ | /* XXX A-MPDU? */ | ||||
if (m->m_pkthdr.len + IEEE80211_CRC_LEN > | if (m->m_pkthdr.len + IEEE80211_CRC_LEN > | ||||
vap->iv_rtsthreshold && | vap->iv_rtsthreshold && | ||||
vap->iv_rtsthreshold != IEEE80211_RTS_MAX) | vap->iv_rtsthreshold != IEEE80211_RTS_MAX) | ||||
prot = IEEE80211_PROT_RTSCTS; | prot = IEEE80211_PROT_RTSCTS; | ||||
if (prot != IEEE80211_PROT_NONE) | if (prot != IEEE80211_PROT_NONE) | ||||
r12a_tx_protection(sc, txd, prot, ridx); | r12a_tx_protection(sc, txd, prot, rate_idx); | ||||
} else /* IEEE80211_FC0_TYPE_MGT */ | } else /* IEEE80211_FC0_TYPE_MGT */ | ||||
qsel = R12A_TXDW1_QSEL_MGNT; | qsel = R12A_TXDW1_QSEL_MGNT; | ||||
} else { | } else { | ||||
macid = RTWN_MACID_BC; | macid = RTWN_MACID_BC; | ||||
qsel = R12A_TXDW1_QSEL_MGNT; | qsel = R12A_TXDW1_QSEL_MGNT; | ||||
} | } | ||||
txd->txdw1 |= htole32(SM(R12A_TXDW1_QSEL, qsel)); | txd->txdw1 |= htole32(SM(R12A_TXDW1_QSEL, qsel)); | ||||
Show All 37 Lines | r12a_fill_tx_desc_raw(struct rtwn_softc *sc, struct ieee80211_node *ni, | ||||
struct r12a_tx_desc *txd; | struct r12a_tx_desc *txd; | ||||
uint8_t ridx; | uint8_t ridx; | ||||
int ismcast; | int ismcast; | ||||
/* XXX TODO: 11n checks, matching rtwn_fill_tx_desc() */ | /* XXX TODO: 11n checks, matching rtwn_fill_tx_desc() */ | ||||
wh = mtod(m, struct ieee80211_frame *); | wh = mtod(m, struct ieee80211_frame *); | ||||
ismcast = IEEE80211_IS_MULTICAST(wh->i_addr1); | ismcast = IEEE80211_IS_MULTICAST(wh->i_addr1); | ||||
ridx = rate2ridx(params->ibp_rate0); | ridx = rate_idx2ridx(params->ibp_rate0); | ||||
/* Fill Tx descriptor. */ | /* Fill Tx descriptor. */ | ||||
txd = (struct r12a_tx_desc *)buf; | txd = (struct r12a_tx_desc *)buf; | ||||
txd->flags0 |= R12A_FLAGS0_LSG | R12A_FLAGS0_FSG; | txd->flags0 |= R12A_FLAGS0_LSG | R12A_FLAGS0_FSG; | ||||
if (ismcast) | if (ismcast) | ||||
txd->flags0 |= R12A_FLAGS0_BMCAST; | txd->flags0 |= R12A_FLAGS0_BMCAST; | ||||
if ((params->ibp_flags & IEEE80211_BPF_NOACK) == 0) { | if ((params->ibp_flags & IEEE80211_BPF_NOACK) == 0) { | ||||
txd->txdw4 = htole32(R12A_TXDW4_RETRY_LMT_ENA); | txd->txdw4 = htole32(R12A_TXDW4_RETRY_LMT_ENA); | ||||
txd->txdw4 |= htole32(SM(R12A_TXDW4_RETRY_LMT, | txd->txdw4 |= htole32(SM(R12A_TXDW4_RETRY_LMT, | ||||
params->ibp_try0)); | params->ibp_try0)); | ||||
} | } | ||||
if (params->ibp_flags & IEEE80211_BPF_RTS) | if (params->ibp_flags & IEEE80211_BPF_RTS) { | ||||
r12a_tx_protection(sc, txd, IEEE80211_PROT_RTSCTS, ridx); | r12a_tx_protection(sc, txd, IEEE80211_PROT_RTSCTS, | ||||
if (params->ibp_flags & IEEE80211_BPF_CTS) | params->ibp_rate0); | ||||
r12a_tx_protection(sc, txd, IEEE80211_PROT_CTSONLY, ridx); | } | ||||
if (params->ibp_flags & IEEE80211_BPF_CTS) { | |||||
r12a_tx_protection(sc, txd, IEEE80211_PROT_CTSONLY, | |||||
params->ibp_rate0); | |||||
} | |||||
txd->txdw1 |= htole32(SM(R12A_TXDW1_MACID, RTWN_MACID_BC)); | txd->txdw1 |= htole32(SM(R12A_TXDW1_MACID, RTWN_MACID_BC)); | ||||
txd->txdw1 |= htole32(SM(R12A_TXDW1_QSEL, R12A_TXDW1_QSEL_MGNT)); | txd->txdw1 |= htole32(SM(R12A_TXDW1_QSEL, R12A_TXDW1_QSEL_MGNT)); | ||||
/* Set TX rate index. */ | /* Set TX rate index. */ | ||||
txd->txdw4 |= htole32(SM(R12A_TXDW4_DATARATE, ridx)); | txd->txdw4 |= htole32(SM(R12A_TXDW4_DATARATE, ridx)); | ||||
txd->txdw4 |= htole32(SM(R12A_TXDW4_DATARATE_FB_LMT, 0x1f)); | txd->txdw4 |= htole32(SM(R12A_TXDW4_DATARATE_FB_LMT, 0x1f)); | ||||
txd->txdw6 |= htole32(SM(R21A_TXDW6_MBSSID, uvp->id)); | txd->txdw6 |= htole32(SM(R21A_TXDW6_MBSSID, uvp->id)); | ||||
▲ Show 20 Lines • Show All 57 Lines • Show Last 20 Lines |