summaryrefslogtreecommitdiffstats
path: root/sys/dev
diff options
context:
space:
mode:
authoradrian <adrian@FreeBSD.org>2011-02-03 20:30:17 +0000
committeradrian <adrian@FreeBSD.org>2011-02-03 20:30:17 +0000
commit977ce16e849f71f47591f1d929eaef77ced04092 (patch)
treea6b0aa3e3dc83744ae54c776c5afad459c02e835 /sys/dev
parent721d089943d51eeed81e964668e1d27193259350 (diff)
downloadFreeBSD-src-977ce16e849f71f47591f1d929eaef77ced04092.zip
FreeBSD-src-977ce16e849f71f47591f1d929eaef77ced04092.tar.gz
Modify the TX path to set and use the 11n rate scenario bits.
This isn't strictly required to TX (at least non-agg and non-HT40, non-short-GI) frames; but as it needs to be done anyway, just get it done. Linux ath9k uses the rate scenario style path for -all- packets, legacy or otherwise. This code does much the same. Beacon TX still uses the legacy, non-rate-scenario TX descriptor setup. Ath9k also does this. This 11n rate scenario path is only called for chips in the AR5416 HAL; legacy chips use the previous interface for TX'ing.
Diffstat (limited to 'sys/dev')
-rw-r--r--sys/dev/ath/if_ath_tx.c100
1 files changed, 75 insertions, 25 deletions
diff --git a/sys/dev/ath/if_ath_tx.c b/sys/dev/ath/if_ath_tx.c
index eb60a23..3a18433 100644
--- a/sys/dev/ath/if_ath_tx.c
+++ b/sys/dev/ath/if_ath_tx.c
@@ -97,6 +97,7 @@ __FBSDID("$FreeBSD$");
#include <dev/ath/if_ath_misc.h>
#include <dev/ath/if_ath_tx.h>
+#include <dev/ath/if_ath_tx_ht.h>
/*
* Whether to use the 11n rate scenario functions or not
@@ -482,6 +483,10 @@ ath_tx_start(struct ath_softc *sc, struct ieee80211_node *ni, struct ath_buf *bf
HAL_BOOL shortPreamble;
struct ath_node *an;
u_int pri;
+ uint8_t try[4], rate[4];
+
+ bzero(try, sizeof(try));
+ bzero(rate, sizeof(rate));
wh = mtod(m0, struct ieee80211_frame *);
iswep = wh->i_fc[1] & IEEE80211_FC1_WEP;
@@ -768,10 +773,17 @@ ath_tx_start(struct ath_softc *sc, struct ieee80211_node *ni, struct ath_buf *bf
txq->axq_intrcnt = 0;
}
+ if (ath_tx_is_11n(sc)) {
+ rate[0] = rix;
+ try[0] = try0;
+ }
+
/*
* Formulate first tx descriptor with tx controls.
*/
/* XXX check return value? */
+ /* XXX is this ok to call for 11n descriptors? */
+ /* XXX or should it go through the first, next, last 11n calls? */
ath_hal_setuptxdesc(ah, ds
, pktlen /* packet length */
, hdrlen /* header length */
@@ -792,8 +804,16 @@ ath_tx_start(struct ath_softc *sc, struct ieee80211_node *ni, struct ath_buf *bf
* when the hardware supports multi-rate retry and
* we don't use it.
*/
- if (ismrr)
- ath_rate_setupxtxdesc(sc, an, ds, shortPreamble, rix);
+ if (ismrr) {
+ if (ath_tx_is_11n(sc))
+ ath_rate_getxtxrates(sc, an, rix, rate, try);
+ else
+ ath_rate_setupxtxdesc(sc, an, ds, shortPreamble, rix);
+ }
+
+ if (ath_tx_is_11n(sc)) {
+ ath_buf_set_rate(sc, ni, bf, pktlen, flags, ctsrate, rate, try);
+ }
ath_tx_handoff(sc, txq, bf);
return 0;
@@ -817,6 +837,10 @@ ath_tx_raw_start(struct ath_softc *sc, struct ieee80211_node *ni,
const HAL_RATE_TABLE *rt;
struct ath_desc *ds;
u_int pri;
+ uint8_t try[4], rate[4];
+
+ bzero(try, sizeof(try));
+ bzero(rate, sizeof(rate));
wh = mtod(m0, struct ieee80211_frame *);
ismcast = IEEE80211_IS_MULTICAST(wh->i_addr1);
@@ -925,30 +949,56 @@ ath_tx_raw_start(struct ath_softc *sc, struct ieee80211_node *ni,
);
bf->bf_txflags = flags;
- if (ismrr) {
- rix = ath_tx_findrix(sc, params->ibp_rate1);
- rate1 = rt->info[rix].rateCode;
- if (params->ibp_flags & IEEE80211_BPF_SHORTPRE)
- rate1 |= rt->info[rix].shortPreamble;
- if (params->ibp_try2) {
- rix = ath_tx_findrix(sc, params->ibp_rate2);
- rate2 = rt->info[rix].rateCode;
- if (params->ibp_flags & IEEE80211_BPF_SHORTPRE)
- rate2 |= rt->info[rix].shortPreamble;
- } else
- rate2 = 0;
- if (params->ibp_try3) {
- rix = ath_tx_findrix(sc, params->ibp_rate3);
- rate3 = rt->info[rix].rateCode;
+ if (ath_tx_is_11n(sc)) {
+ rate[0] = ath_tx_findrix(sc, params->ibp_rate0);
+ try[0] = params->ibp_try0;
+
+ if (ismrr) {
+ /* Remember, rate[] is actually an array of rix's -adrian */
+ rate[0] = ath_tx_findrix(sc, params->ibp_rate0);
+ rate[1] = ath_tx_findrix(sc, params->ibp_rate1);
+ rate[2] = ath_tx_findrix(sc, params->ibp_rate2);
+ rate[3] = ath_tx_findrix(sc, params->ibp_rate3);
+
+ try[0] = params->ibp_try0;
+ try[1] = params->ibp_try1;
+ try[2] = params->ibp_try2;
+ try[3] = params->ibp_try3;
+ }
+ } else {
+ if (ismrr) {
+ rix = ath_tx_findrix(sc, params->ibp_rate1);
+ rate1 = rt->info[rix].rateCode;
if (params->ibp_flags & IEEE80211_BPF_SHORTPRE)
- rate3 |= rt->info[rix].shortPreamble;
- } else
- rate3 = 0;
- ath_hal_setupxtxdesc(ah, ds
- , rate1, params->ibp_try1 /* series 1 */
- , rate2, params->ibp_try2 /* series 2 */
- , rate3, params->ibp_try3 /* series 3 */
- );
+ rate1 |= rt->info[rix].shortPreamble;
+ if (params->ibp_try2) {
+ rix = ath_tx_findrix(sc, params->ibp_rate2);
+ rate2 = rt->info[rix].rateCode;
+ if (params->ibp_flags & IEEE80211_BPF_SHORTPRE)
+ rate2 |= rt->info[rix].shortPreamble;
+ } else
+ rate2 = 0;
+ if (params->ibp_try3) {
+ rix = ath_tx_findrix(sc, params->ibp_rate3);
+ rate3 = rt->info[rix].rateCode;
+ if (params->ibp_flags & IEEE80211_BPF_SHORTPRE)
+ rate3 |= rt->info[rix].shortPreamble;
+ } else
+ rate3 = 0;
+ ath_hal_setupxtxdesc(ah, ds
+ , rate1, params->ibp_try1 /* series 1 */
+ , rate2, params->ibp_try2 /* series 2 */
+ , rate3, params->ibp_try3 /* series 3 */
+ );
+ }
+ }
+
+ if (ath_tx_is_11n(sc)) {
+ /*
+ * notice that rix doesn't include any of the "magic" flags txrate
+ * does for communicating "other stuff" to the HAL.
+ */
+ ath_buf_set_rate(sc, ni, bf, pktlen, flags, ctsrate, rate, try);
}
/* NB: no buffered multicast in power save support */
OpenPOWER on IntegriCloud