summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoradrian <adrian@FreeBSD.org>2012-07-31 23:54:15 +0000
committeradrian <adrian@FreeBSD.org>2012-07-31 23:54:15 +0000
commit01f36653dbecf367fa3ced90e1d161320729802d (patch)
treeb977c8f00dc8abcb48618c84d59c3a6ab8dd1218
parent73fec218b58931ed8164f0f5054811095e817f58 (diff)
downloadFreeBSD-src-01f36653dbecf367fa3ced90e1d161320729802d.zip
FreeBSD-src-01f36653dbecf367fa3ced90e1d161320729802d.tar.gz
Allow 802.11n hardware to support multi-rate retry when RTS/CTS is
enabled. The legacy (pre-802.11n) hardware doesn't support this - although the AR5212 era hardware supports MRR, it doesn't have all the bits needed to support MRR + RTS/CTS. The AR5416 and later support a packet duration and RTS/CTS flags per rate scenario, so we should support it. Tested: * AR9280, STA PR: kern/170302
-rw-r--r--sys/dev/ath/ath_rate/sample/sample.c12
-rw-r--r--sys/dev/ath/if_ath.c9
-rw-r--r--sys/dev/ath/if_ath_tx.c9
-rw-r--r--sys/dev/ath/if_athvar.h1
4 files changed, 24 insertions, 7 deletions
diff --git a/sys/dev/ath/ath_rate/sample/sample.c b/sys/dev/ath/ath_rate/sample/sample.c
index cccf0e5..a69b306 100644
--- a/sys/dev/ath/ath_rate/sample/sample.c
+++ b/sys/dev/ath/ath_rate/sample/sample.c
@@ -502,8 +502,10 @@ ath_rate_findrate(struct ath_softc *sc, struct ath_node *an,
goto done;
}
- /* XXX TODO: this doesn't know about 11gn vs 11g protection; teach it */
- mrr = sc->sc_mrretry && !(ic->ic_flags & IEEE80211_F_USEPROT);
+ mrr = sc->sc_mrretry;
+ /* XXX check HT protmode too */
+ if (mrr && (ic->ic_flags & IEEE80211_F_USEPROT) && !sc->sc_mrrprot)
+ mrr = 0;
best_rix = pick_best_rate(an, rt, size_bin, !mrr);
if (best_rix >= 0) {
@@ -910,7 +912,11 @@ ath_rate_tx_complete(struct ath_softc *sc, struct ath_node *an,
short_tries, long_tries);
return;
}
- mrr = sc->sc_mrretry && !(ic->ic_flags & IEEE80211_F_USEPROT);
+ mrr = sc->sc_mrretry;
+ /* XXX check HT protmode too */
+ if (mrr && (ic->ic_flags & IEEE80211_F_USEPROT) && !sc->sc_mrrprot)
+ mrr = 0;
+
if (!mrr || ts->ts_finaltsi == 0) {
if (!IS_RATE_DEFINED(sn, final_rix)) {
badrate(ifp, 0, ts->ts_rate, long_tries, status);
diff --git a/sys/dev/ath/if_ath.c b/sys/dev/ath/if_ath.c
index 63ef2cf..caae6308 100644
--- a/sys/dev/ath/if_ath.c
+++ b/sys/dev/ath/if_ath.c
@@ -705,6 +705,12 @@ ath_attach(u_int16_t devid, struct ath_softc *sc)
(void) ath_hal_settxchainmask(sc->sc_ah, tx_chainmask);
}
+ /*
+ * Disable MRR with protected frames by default.
+ * Only 802.11n series NICs can handle this.
+ */
+ sc->sc_mrrprot = 0; /* XXX should be a capability */
+
#ifdef ATH_ENABLE_11N
/*
* Query HT capabilities
@@ -714,6 +720,9 @@ ath_attach(u_int16_t devid, struct ath_softc *sc)
int rxs, txs;
device_printf(sc->sc_dev, "[HT] enabling HT modes\n");
+
+ sc->sc_mrrprot = 1; /* XXX should be a capability */
+
ic->ic_htcaps = IEEE80211_HTC_HT /* HT operation */
| IEEE80211_HTC_AMPDU /* A-MPDU tx/rx */
| IEEE80211_HTC_AMSDU /* A-MSDU tx/rx */
diff --git a/sys/dev/ath/if_ath_tx.c b/sys/dev/ath/if_ath_tx.c
index 77be706..fe5be38 100644
--- a/sys/dev/ath/if_ath_tx.c
+++ b/sys/dev/ath/if_ath_tx.c
@@ -1051,11 +1051,12 @@ ath_tx_set_rtscts(struct ath_softc *sc, struct ath_buf *bf)
/*
* Must disable multi-rate retry when using RTS/CTS.
- * XXX TODO: only for pre-11n NICs.
*/
- bf->bf_state.bfs_ismrr = 0;
- bf->bf_state.bfs_try0 =
- bf->bf_state.bfs_rc[0].tries = ATH_TXMGTTRY; /* XXX ew */
+ if (!sc->sc_mrrprot) {
+ bf->bf_state.bfs_ismrr = 0;
+ bf->bf_state.bfs_try0 =
+ bf->bf_state.bfs_rc[0].tries = ATH_TXMGTTRY; /* XXX ew */
+ }
}
/*
diff --git a/sys/dev/ath/if_athvar.h b/sys/dev/ath/if_athvar.h
index b742ad8..94097ad 100644
--- a/sys/dev/ath/if_athvar.h
+++ b/sys/dev/ath/if_athvar.h
@@ -463,6 +463,7 @@ struct ath_softc {
void (*sc_setdefantenna)(struct ath_softc *, u_int);
unsigned int sc_invalid : 1,/* disable hardware accesses */
sc_mrretry : 1,/* multi-rate retry support */
+ sc_mrrprot : 1,/* MRR + protection support */
sc_softled : 1,/* enable LED gpio status */
sc_hardled : 1,/* enable MAC LED status */
sc_splitmic : 1,/* split TKIP MIC keys */
OpenPOWER on IntegriCloud