Page MenuHomeFreeBSD

D48142.id149109.diff
No OneTemporary

D48142.id149109.diff

diff --git a/sys/dev/rtwn/rtl8192c/r92c_tx.c b/sys/dev/rtwn/rtl8192c/r92c_tx.c
--- a/sys/dev/rtwn/rtl8192c/r92c_tx.c
+++ b/sys/dev/rtwn/rtl8192c/r92c_tx.c
@@ -77,10 +77,14 @@
static void
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;
uint8_t rate;
+ bool use_fw_ratectl;
+
+ use_fw_ratectl =
+ (sc->sc_ratectl == RTWN_RATECTL_FW && !force_rate);
switch (mode) {
case IEEE80211_PROT_CTSONLY:
@@ -95,17 +99,27 @@
if (mode == IEEE80211_PROT_CTSONLY ||
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);
- else
+ ridx = rate2ridx(IEEE80211_RV(rate));
+ } else {
rate = ieee80211_ctl_rate(ic->ic_rt, ridx2rate[ridx]);
- ridx = rate2ridx(IEEE80211_RV(rate));
+ ridx = rate2ridx(IEEE80211_RV(rate));
+ }
txd->txdw4 |= htole32(SM(R92C_TXDW4_RTSRATE, ridx));
/* RTS rate fallback limit (max). */
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))
txd->txdw4 |= htole32(R92C_TXDW4_RTS_SHORT);
}
@@ -285,6 +299,51 @@
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) {
+ 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;
+
+ prot = IEEE80211_PROT_RTSCTS;
+ } else {
+ if (RTWN_RATE_IS_HT(ridx))
+ 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);
+}
+
void
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)
@@ -292,7 +351,6 @@
#ifndef RTWN_WITHOUT_UCODE
struct r92c_softc *rs = sc->sc_priv;
#endif
- struct ieee80211com *ic = &sc->sc_ic;
struct ieee80211vap *vap = ni->ni_vap;
struct rtwn_vap *uvp = RTWN_VAP(vap);
struct ieee80211_frame *wh;
@@ -357,24 +415,22 @@
r92c_fill_tx_desc_shpreamble(sc, txd, ridx, force_rate);
- prot = IEEE80211_PROT_NONE;
- if (RTWN_RATE_IS_HT(ridx)) {
+ prot = r92c_tx_get_protmode(sc, vap, ni, m, 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_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). */
- if (prot != IEEE80211_PROT_NONE)
- r92c_tx_protection(sc, txd, prot, ridx);
+ r92c_tx_protection(sc, txd, prot, ridx, force_rate);
} else /* IEEE80211_FC0_TYPE_MGT */
qsel = R92C_TXDW1_QSEL_MGNT;
} else {
@@ -438,9 +494,11 @@
params->ibp_try0));
}
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)
- 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);
txd->txdw1 |= htole32(SM(R92C_TXDW1_QSEL, R92C_TXDW1_QSEL_MGNT));

File Metadata

Mime Type
text/plain
Expires
Mon, Feb 9, 1:37 AM (19 h, 35 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
28522090
Default Alt Text
D48142.id149109.diff (5 KB)

Event Timeline