Changeset View
Changeset View
Standalone View
Standalone View
sys/dev/rtwn/rtl8192c/r92c_tx.c
| Show First 20 Lines • Show All 71 Lines • ▼ Show 20 Lines | if (ieee80211_ht_check_tx_ht40(ni)) { | |||||||||
| extc_offset = r92c_tx_get_sco(sc, ni->ni_chan); | extc_offset = r92c_tx_get_sco(sc, ni->ni_chan); | |||||||||
| txd->txdw4 |= htole32(R92C_TXDW4_DATA_BW40); | txd->txdw4 |= htole32(R92C_TXDW4_DATA_BW40); | |||||||||
| txd->txdw4 |= htole32(SM(R92C_TXDW4_DATA_SCO, extc_offset)); | txd->txdw4 |= htole32(SM(R92C_TXDW4_DATA_SCO, extc_offset)); | |||||||||
| } | } | |||||||||
| } | } | |||||||||
| static void | static void | |||||||||
| r92c_tx_protection(struct rtwn_softc *sc, struct r92c_tx_desc *txd, | r92c_tx_protection(struct rtwn_softc *sc, struct r92c_tx_desc *txd, | |||||||||
| enum ieee80211_protmode mode, uint8_t ridx) | enum ieee80211_protmode mode, uint8_t ridx, bool force_rate) | |||||||||
| { | { | |||||||||
| struct ieee80211com *ic = &sc->sc_ic; | struct ieee80211com *ic = &sc->sc_ic; | |||||||||
| uint8_t rate; | uint8_t rate; | |||||||||
| bool use_fw_ratectl; | ||||||||||
| use_fw_ratectl = | ||||||||||
| (sc->sc_ratectl == RTWN_RATECTL_FW && !force_rate); | ||||||||||
| switch (mode) { | switch (mode) { | |||||||||
| case IEEE80211_PROT_CTSONLY: | case IEEE80211_PROT_CTSONLY: | |||||||||
| txd->txdw4 |= htole32(R92C_TXDW4_CTS2SELF); | txd->txdw4 |= htole32(R92C_TXDW4_CTS2SELF); | |||||||||
| break; | break; | |||||||||
| case IEEE80211_PROT_RTSCTS: | case IEEE80211_PROT_RTSCTS: | |||||||||
| txd->txdw4 |= htole32(R92C_TXDW4_RTSEN); | txd->txdw4 |= htole32(R92C_TXDW4_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 (RTWN_RATE_IS_HT(ridx)) | if (use_fw_ratectl) { | |||||||||
| /* | ||||||||||
| * If we're not forcing the driver rate then this | ||||||||||
| * field actually doesn't matter; what matters is | ||||||||||
| * the RRSR and INIRTS configuration. | ||||||||||
| */ | ||||||||||
| ridx = RTWN_RIDX_OFDM24; | ||||||||||
| } else if (RTWN_RATE_IS_HT(ridx)) { | ||||||||||
| rate = rtwn_ctl_mcsrate(ic->ic_rt, ridx); | rate = rtwn_ctl_mcsrate(ic->ic_rt, ridx); | |||||||||
| else | ridx = rate2ridx(IEEE80211_RV(rate)); | |||||||||
| } else { | ||||||||||
| rate = ieee80211_ctl_rate(ic->ic_rt, ridx2rate[ridx]); | rate = ieee80211_ctl_rate(ic->ic_rt, ridx2rate[ridx]); | |||||||||
| ridx = rate2ridx(IEEE80211_RV(rate)); | ridx = rate2ridx(IEEE80211_RV(rate)); | |||||||||
| } | ||||||||||
fuz: Avoid code duplication of the common `ridx` assignment. | ||||||||||
Done Inline Actions? : go at he end of the line ; also there is an extra ; in there somewhere... bz: ? : go at he end of the line ; also there is an extra ; in there somewhere... | ||||||||||
| txd->txdw4 |= htole32(SM(R92C_TXDW4_RTSRATE, ridx)); | txd->txdw4 |= htole32(SM(R92C_TXDW4_RTSRATE, ridx)); | |||||||||
| /* RTS rate fallback limit (max). */ | /* RTS rate fallback limit (max). */ | |||||||||
| txd->txdw5 |= htole32(SM(R92C_TXDW5_RTSRATE_FB_LMT, 0xf)); | txd->txdw5 |= htole32(SM(R92C_TXDW5_RTSRATE_FB_LMT, 0xf)); | |||||||||
| if (RTWN_RATE_IS_CCK(ridx) && ridx != RTWN_RIDX_CCK1 && | if (!use_fw_ratectl && RTWN_RATE_IS_CCK(ridx) && | |||||||||
| ridx != RTWN_RIDX_CCK1 && | ||||||||||
| (ic->ic_flags & IEEE80211_F_SHPREAMBLE)) | (ic->ic_flags & IEEE80211_F_SHPREAMBLE)) | |||||||||
| txd->txdw4 |= htole32(R92C_TXDW4_RTS_SHORT); | txd->txdw4 |= htole32(R92C_TXDW4_RTS_SHORT); | |||||||||
| } | } | |||||||||
| } | } | |||||||||
| static void | static void | |||||||||
| r92c_tx_raid(struct rtwn_softc *sc, struct r92c_tx_desc *txd, | r92c_tx_raid(struct rtwn_softc *sc, struct r92c_tx_desc *txd, | |||||||||
| struct ieee80211_node *ni, int ismcast) | struct ieee80211_node *ni, int ismcast) | |||||||||
| ▲ Show 20 Lines • Show All 163 Lines • ▼ Show 20 Lines | ||||||||||
| { | { | |||||||||
| const struct ieee80211com *ic = &sc->sc_ic; | const struct ieee80211com *ic = &sc->sc_ic; | |||||||||
| if (RTWN_RATE_IS_CCK(ridx) && ridx != RTWN_RIDX_CCK1 && | if (RTWN_RATE_IS_CCK(ridx) && ridx != RTWN_RIDX_CCK1 && | |||||||||
| (ic->ic_flags & IEEE80211_F_SHPREAMBLE)) | (ic->ic_flags & IEEE80211_F_SHPREAMBLE)) | |||||||||
| txd->txdw4 |= htole32(R92C_TXDW4_DATA_SHPRE); | txd->txdw4 |= htole32(R92C_TXDW4_DATA_SHPRE); | |||||||||
| } | } | |||||||||
| static enum ieee80211_protmode | ||||||||||
| r92c_tx_get_protmode(struct rtwn_softc *sc, const struct ieee80211vap *vap, | ||||||||||
| const struct ieee80211_node *ni, const struct mbuf *m, | ||||||||||
| uint8_t ridx, bool force_rate) | ||||||||||
| { | ||||||||||
| const struct ieee80211com *ic = &sc->sc_ic; | ||||||||||
| enum ieee80211_protmode prot; | ||||||||||
| prot = IEEE80211_PROT_NONE; | ||||||||||
| /* | ||||||||||
| * If doing firmware rate control, base it the configured channel. | ||||||||||
| * This ensures that for HT operation the RTS/CTS or CTS-to-self | ||||||||||
| * configuration is obeyed. | ||||||||||
| */ | ||||||||||
| if (sc->sc_ratectl == RTWN_RATECTL_FW && !force_rate) { | ||||||||||
Done Inline Actions
Booleans should not be compared against true/false, use boolean operators instead. fuz: Booleans should not be compared against true/false, use boolean operators instead. | ||||||||||
| struct ieee80211_channel *chan; | ||||||||||
| enum ieee80211_phymode mode; | ||||||||||
| chan = (ni->ni_chan != IEEE80211_CHAN_ANYC) ? | ||||||||||
| ni->ni_chan : ic->ic_curchan; | ||||||||||
| mode = ieee80211_chan2mode(chan); | ||||||||||
| if (mode == IEEE80211_MODE_11NG) | ||||||||||
| prot = ic->ic_htprotmode; | ||||||||||
| else if (ic->ic_flags & IEEE80211_F_USEPROT) | ||||||||||
| prot = ic->ic_protmode; | ||||||||||
| } else { | ||||||||||
| if (RTWN_RATE_IS_HT(ridx)) | ||||||||||
Done Inline ActionsThis seems wrong. prot is unconditionally overwritten at this point. What is the point of the previous if statements? Is perhaps an else missing? fuz: This seems wrong. `prot` is unconditionally overwritten at this point. What is the point of… | ||||||||||
Done Inline Actions
oops, left in debugging. :-) I'll remove it. adrian: > This seems wrong. `prot` is unconditionally overwritten at this point. What is the point of… | ||||||||||
| prot = ic->ic_htprotmode; | ||||||||||
| else if (ic->ic_flags & IEEE80211_F_USEPROT) | ||||||||||
| prot = ic->ic_protmode; | ||||||||||
| } | ||||||||||
| /* XXX fix last comparison for A-MSDU (in net80211) */ | ||||||||||
| /* XXX A-MPDU? */ | ||||||||||
| if (m->m_pkthdr.len + IEEE80211_CRC_LEN > | ||||||||||
| vap->iv_rtsthreshold && | ||||||||||
| vap->iv_rtsthreshold != IEEE80211_RTS_MAX) | ||||||||||
| prot = IEEE80211_PROT_RTSCTS; | ||||||||||
| return (prot); | ||||||||||
| } | ||||||||||
Done Inline ActionsThe control flow of this function is confusing and not obvious. Could you perhaps use an early return pattern instead of repeatedly assigning to prot? fuz: The control flow of this function is confusing and not obvious. Could you perhaps use an early… | ||||||||||
Done Inline ActionsI can't because the last check (rts/cts threshold) needs to override the others. adrian: I can't because the last check (rts/cts threshold) needs to override the others. | ||||||||||
| void | void | |||||||||
| r92c_fill_tx_desc(struct rtwn_softc *sc, struct ieee80211_node *ni, | r92c_fill_tx_desc(struct rtwn_softc *sc, struct ieee80211_node *ni, | |||||||||
| struct mbuf *m, void *buf, uint8_t ridx, bool force_rate, int maxretry) | struct mbuf *m, void *buf, uint8_t ridx, bool force_rate, int maxretry) | |||||||||
| { | { | |||||||||
| #ifndef RTWN_WITHOUT_UCODE | #ifndef RTWN_WITHOUT_UCODE | |||||||||
| struct r92c_softc *rs = sc->sc_priv; | struct r92c_softc *rs = sc->sc_priv; | |||||||||
| #endif | #endif | |||||||||
| 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 r92c_tx_desc *txd; | struct r92c_tx_desc *txd; | |||||||||
| enum ieee80211_protmode prot; | enum ieee80211_protmode prot; | |||||||||
| uint8_t type, tid, qos, qsel; | uint8_t type, tid, qos, qsel; | |||||||||
| int hasqos, ismcast, macid; | int hasqos, ismcast, macid; | |||||||||
| ▲ Show 20 Lines • Show All 48 Lines • ▼ Show 20 Lines | if (type == IEEE80211_FC0_TYPE_DATA) { | |||||||||
| sc->sc_tx_n_active++; | sc->sc_tx_n_active++; | |||||||||
| #ifndef RTWN_WITHOUT_UCODE | #ifndef RTWN_WITHOUT_UCODE | |||||||||
| rs->rs_c2h_pending++; | rs->rs_c2h_pending++; | |||||||||
| #endif | #endif | |||||||||
| } | } | |||||||||
| r92c_fill_tx_desc_shpreamble(sc, txd, ridx, force_rate); | r92c_fill_tx_desc_shpreamble(sc, txd, ridx, force_rate); | |||||||||
| prot = IEEE80211_PROT_NONE; | prot = r92c_tx_get_protmode(sc, vap, ni, m, ridx, | |||||||||
| if (RTWN_RATE_IS_HT(ridx)) { | force_rate); | |||||||||
| /* | ||||||||||
| * Note: Firmware rate control will enable short-GI | ||||||||||
| * based on the configured rate mask, however HT40 | ||||||||||
| * may not be enabled. | ||||||||||
| */ | ||||||||||
| if (sc->sc_ratectl != RTWN_RATECTL_FW && | ||||||||||
| RTWN_RATE_IS_HT(ridx)) { | ||||||||||
| r92c_tx_set_ht40(sc, txd, ni); | r92c_tx_set_ht40(sc, txd, ni); | |||||||||
| r92c_tx_set_sgi(sc, txd, ni); | r92c_tx_set_sgi(sc, txd, ni); | |||||||||
| prot = ic->ic_htprotmode; | } | |||||||||
| } else if (ic->ic_flags & IEEE80211_F_USEPROT) | ||||||||||
| prot = ic->ic_protmode; | ||||||||||
| /* XXX fix last comparison for A-MSDU (in net80211) */ | ||||||||||
| /* XXX A-MPDU? */ | ||||||||||
| if (m->m_pkthdr.len + IEEE80211_CRC_LEN > | ||||||||||
| vap->iv_rtsthreshold && | ||||||||||
| vap->iv_rtsthreshold != IEEE80211_RTS_MAX) | ||||||||||
| prot = IEEE80211_PROT_RTSCTS; | ||||||||||
| /* NB: checks for ht40 / short bits (set above). */ | /* NB: checks for ht40 / short bits (set above). */ | |||||||||
| if (prot != IEEE80211_PROT_NONE) | r92c_tx_protection(sc, txd, prot, ridx, force_rate); | |||||||||
| r92c_tx_protection(sc, txd, prot, ridx); | ||||||||||
| } else /* IEEE80211_FC0_TYPE_MGT */ | } else /* IEEE80211_FC0_TYPE_MGT */ | |||||||||
| qsel = R92C_TXDW1_QSEL_MGNT; | qsel = R92C_TXDW1_QSEL_MGNT; | |||||||||
| } else { | } else { | |||||||||
| macid = RTWN_MACID_BC; | macid = RTWN_MACID_BC; | |||||||||
| qsel = R92C_TXDW1_QSEL_MGNT; | qsel = R92C_TXDW1_QSEL_MGNT; | |||||||||
| } | } | |||||||||
| txd->txdw1 |= htole32(SM(R92C_TXDW1_QSEL, qsel)); | txd->txdw1 |= htole32(SM(R92C_TXDW1_QSEL, qsel)); | |||||||||
| ▲ Show 20 Lines • Show All 47 Lines • ▼ Show 20 Lines | if (ismcast) | |||||||||
| txd->flags0 |= R92C_FLAGS0_BMCAST; | txd->flags0 |= R92C_FLAGS0_BMCAST; | |||||||||
| if ((params->ibp_flags & IEEE80211_BPF_NOACK) == 0) { | if ((params->ibp_flags & IEEE80211_BPF_NOACK) == 0) { | |||||||||
| txd->txdw5 |= htole32(R92C_TXDW5_RTY_LMT_ENA); | txd->txdw5 |= htole32(R92C_TXDW5_RTY_LMT_ENA); | |||||||||
| txd->txdw5 |= htole32(SM(R92C_TXDW5_RTY_LMT, | txd->txdw5 |= htole32(SM(R92C_TXDW5_RTY_LMT, | |||||||||
| params->ibp_try0)); | params->ibp_try0)); | |||||||||
| } | } | |||||||||
| if (params->ibp_flags & IEEE80211_BPF_RTS) | if (params->ibp_flags & IEEE80211_BPF_RTS) | |||||||||
| r92c_tx_protection(sc, txd, IEEE80211_PROT_RTSCTS, ridx); | r92c_tx_protection(sc, txd, IEEE80211_PROT_RTSCTS, ridx, | |||||||||
| true); | ||||||||||
| if (params->ibp_flags & IEEE80211_BPF_CTS) | if (params->ibp_flags & IEEE80211_BPF_CTS) | |||||||||
| r92c_tx_protection(sc, txd, IEEE80211_PROT_CTSONLY, ridx); | r92c_tx_protection(sc, txd, IEEE80211_PROT_CTSONLY, ridx, | |||||||||
| true); | ||||||||||
| rtwn_r92c_tx_setup_macid(sc, txd, RTWN_MACID_BC); | rtwn_r92c_tx_setup_macid(sc, txd, RTWN_MACID_BC); | |||||||||
| txd->txdw1 |= htole32(SM(R92C_TXDW1_QSEL, R92C_TXDW1_QSEL_MGNT)); | txd->txdw1 |= htole32(SM(R92C_TXDW1_QSEL, R92C_TXDW1_QSEL_MGNT)); | |||||||||
| /* Set TX rate index. */ | /* Set TX rate index. */ | |||||||||
| r92c_fill_tx_desc_datarate(sc, txd, ridx, true); /* force rate */ | r92c_fill_tx_desc_datarate(sc, txd, ridx, true); /* force rate */ | |||||||||
| txd->txdw4 |= htole32(SM(R92C_TXDW4_PORT_ID, uvp->id)); | txd->txdw4 |= htole32(SM(R92C_TXDW4_PORT_ID, uvp->id)); | |||||||||
| r92c_tx_raid(sc, txd, ni, ismcast); | r92c_tx_raid(sc, txd, ni, ismcast); | |||||||||
| ▲ Show 20 Lines • Show All 48 Lines • Show Last 20 Lines | ||||||||||
Avoid code duplication of the common ridx assignment.