aboutsummaryrefslogtreecommitdiff
path: root/sys/dev/ath
diff options
context:
space:
mode:
authorAdrian Chadd <adrian@FreeBSD.org>2016-07-15 06:39:35 +0000
committerAdrian Chadd <adrian@FreeBSD.org>2016-07-15 06:39:35 +0000
commit7ff1939db0436c79d58549fd5bfc69b9ab233413 (patch)
treef0d2b53a5b84902f66197dc8f717e3322012d0f2 /sys/dev/ath
parent6199f16549898c1dcd3993918b86c964462dbdce (diff)
downloadsrc-7ff1939db0436c79d58549fd5bfc69b9ab233413.tar.gz
src-7ff1939db0436c79d58549fd5bfc69b9ab233413.zip
[ath] [ath_hal] break out the duration calculation to optionally include SIFS.
The pre-11n calculations include SIFS, but the 11n ones don't. The reason is that (mostly) the 11n hardware is doing the SIFS calculation for us but the pre-11n hardware isn't. This means that we're over-shooting the times in the duration field for non-11n frames on 11n hardware, which is OK, if not a little inefficient. Now, this is all fine for what the hardware needs for doing duration math for ACK, RTS/CTS, frame length, etc, but it isn't useful for doing PHY duration calculations. Ie, given a frame to TX and its timestamp, what would the end of the actual transmission time be; and similar for an RX timestamp and figuring out its original length. So, this adds a new field to the duration routines which requests SIFS or no SIFS to be included. All the callers currently will call it requesting SIFS, so this /should/ be a glorious no-op. I'm however planning some future work around airtime fairness and positioning which requires these routines to have SIFS be optional. Notably though, the 11n version doesn't do any SIFS addition at the moment. I'll go and tweak and verify all of the packet durations before I go and flip that part on. Tested: * AR9330, STA mode * AR9330, AP mode * AR9380, STA mode
Notes
Notes: svn path=/head/; revision=302877
Diffstat (limited to 'sys/dev/ath')
-rw-r--r--sys/dev/ath/ath_hal/ah.c40
-rw-r--r--sys/dev/ath/ath_hal/ah.h6
-rw-r--r--sys/dev/ath/ath_hal/ar5212/ar5212_reset.c7
-rw-r--r--sys/dev/ath/ath_rate/sample/sample.h8
-rw-r--r--sys/dev/ath/if_ath_beacon.c2
-rw-r--r--sys/dev/ath/if_ath_tdma.c6
-rw-r--r--sys/dev/ath/if_ath_tx.c7
-rw-r--r--sys/dev/ath/if_ath_tx_ht.c5
8 files changed, 48 insertions, 33 deletions
diff --git a/sys/dev/ath/ath_hal/ah.c b/sys/dev/ath/ath_hal/ah.c
index 7fff88b836b7..2d723bdae8d6 100644
--- a/sys/dev/ath/ath_hal/ah.c
+++ b/sys/dev/ath/ath_hal/ah.c
@@ -284,7 +284,8 @@ ath_hal_reverseBits(uint32_t val, uint32_t n)
*/
uint32_t
ath_hal_pkt_txtime(struct ath_hal *ah, const HAL_RATE_TABLE *rates, uint32_t frameLen,
- uint16_t rateix, HAL_BOOL isht40, HAL_BOOL shortPreamble)
+ uint16_t rateix, HAL_BOOL isht40, HAL_BOOL shortPreamble,
+ HAL_BOOL includeSifs)
{
uint8_t rc;
int numStreams;
@@ -293,7 +294,8 @@ ath_hal_pkt_txtime(struct ath_hal *ah, const HAL_RATE_TABLE *rates, uint32_t fra
/* Legacy rate? Return the old way */
if (! IS_HT_RATE(rc))
- return ath_hal_computetxtime(ah, rates, frameLen, rateix, shortPreamble);
+ return ath_hal_computetxtime(ah, rates, frameLen, rateix,
+ shortPreamble, includeSifs);
/* 11n frame - extract out the number of spatial streams */
numStreams = HT_RC_2_STREAMS(rc);
@@ -301,7 +303,9 @@ ath_hal_pkt_txtime(struct ath_hal *ah, const HAL_RATE_TABLE *rates, uint32_t fra
("number of spatial streams needs to be 1..3: MCS rate 0x%x!",
rateix));
- return ath_computedur_ht(frameLen, rc, numStreams, isht40, shortPreamble);
+ /* XXX TODO: Add SIFS */
+ return ath_computedur_ht(frameLen, rc, numStreams, isht40,
+ shortPreamble);
}
static const uint16_t ht20_bps[32] = {
@@ -350,7 +354,7 @@ ath_computedur_ht(uint32_t frameLen, uint16_t rate, int streams,
uint16_t
ath_hal_computetxtime(struct ath_hal *ah,
const HAL_RATE_TABLE *rates, uint32_t frameLen, uint16_t rateix,
- HAL_BOOL shortPreamble)
+ HAL_BOOL shortPreamble, HAL_BOOL includeSifs)
{
uint32_t bitsPerSymbol, numBits, numSymbols, phyTime, txTime;
uint32_t kbps;
@@ -373,8 +377,10 @@ ath_hal_computetxtime(struct ath_hal *ah,
if (shortPreamble && rates->info[rateix].shortPreamble)
phyTime >>= 1;
numBits = frameLen << 3;
- txTime = CCK_SIFS_TIME + phyTime
+ txTime = phyTime
+ ((numBits * 1000)/kbps);
+ if (includeSifs)
+ txTime += CCK_SIFS_TIME;
break;
case IEEE80211_T_OFDM:
bitsPerSymbol = (kbps * OFDM_SYMBOL_TIME) / 1000;
@@ -382,9 +388,10 @@ ath_hal_computetxtime(struct ath_hal *ah,
numBits = OFDM_PLCP_BITS + (frameLen << 3);
numSymbols = howmany(numBits, bitsPerSymbol);
- txTime = OFDM_SIFS_TIME
- + OFDM_PREAMBLE_TIME
+ txTime = OFDM_PREAMBLE_TIME
+ (numSymbols * OFDM_SYMBOL_TIME);
+ if (includeSifs)
+ txTime += OFDM_SIFS_TIME;
break;
case IEEE80211_T_OFDM_HALF:
bitsPerSymbol = (kbps * OFDM_HALF_SYMBOL_TIME) / 1000;
@@ -392,9 +399,10 @@ ath_hal_computetxtime(struct ath_hal *ah,
numBits = OFDM_HALF_PLCP_BITS + (frameLen << 3);
numSymbols = howmany(numBits, bitsPerSymbol);
- txTime = OFDM_HALF_SIFS_TIME
- + OFDM_HALF_PREAMBLE_TIME
+ txTime = OFDM_HALF_PREAMBLE_TIME
+ (numSymbols * OFDM_HALF_SYMBOL_TIME);
+ if (includeSifs)
+ txTime += OFDM_HALF_SIFS_TIME;
break;
case IEEE80211_T_OFDM_QUARTER:
bitsPerSymbol = (kbps * OFDM_QUARTER_SYMBOL_TIME) / 1000;
@@ -402,9 +410,10 @@ ath_hal_computetxtime(struct ath_hal *ah,
numBits = OFDM_QUARTER_PLCP_BITS + (frameLen << 3);
numSymbols = howmany(numBits, bitsPerSymbol);
- txTime = OFDM_QUARTER_SIFS_TIME
- + OFDM_QUARTER_PREAMBLE_TIME
+ txTime = OFDM_QUARTER_PREAMBLE_TIME
+ (numSymbols * OFDM_QUARTER_SYMBOL_TIME);
+ if (includeSifs)
+ txTime += OFDM_QUARTER_SIFS_TIME;
break;
case IEEE80211_T_TURBO:
bitsPerSymbol = (kbps * TURBO_SYMBOL_TIME) / 1000;
@@ -412,9 +421,10 @@ ath_hal_computetxtime(struct ath_hal *ah,
numBits = TURBO_PLCP_BITS + (frameLen << 3);
numSymbols = howmany(numBits, bitsPerSymbol);
- txTime = TURBO_SIFS_TIME
- + TURBO_PREAMBLE_TIME
+ txTime = TURBO_PREAMBLE_TIME
+ (numSymbols * TURBO_SYMBOL_TIME);
+ if (includeSifs)
+ txTime += TURBO_SIFS_TIME;
break;
default:
HALDEBUG(ah, HAL_DEBUG_PHYIO,
@@ -588,9 +598,9 @@ ath_hal_setupratetable(struct ath_hal *ah, HAL_RATE_TABLE *rt)
* 2Mb/s rate which will work but is suboptimal
*/
rt->info[i].lpAckDuration = ath_hal_computetxtime(ah, rt,
- WLAN_CTRL_FRAME_SIZE, cix, AH_FALSE);
+ WLAN_CTRL_FRAME_SIZE, cix, AH_FALSE, AH_TRUE);
rt->info[i].spAckDuration = ath_hal_computetxtime(ah, rt,
- WLAN_CTRL_FRAME_SIZE, cix, AH_TRUE);
+ WLAN_CTRL_FRAME_SIZE, cix, AH_TRUE, AH_TRUE);
}
#undef N
}
diff --git a/sys/dev/ath/ath_hal/ah.h b/sys/dev/ath/ath_hal/ah.h
index ab907658f1ed..519fcb8338df 100644
--- a/sys/dev/ath/ath_hal/ah.h
+++ b/sys/dev/ath/ath_hal/ah.h
@@ -1626,7 +1626,8 @@ extern int ath_hal_get_curmode(struct ath_hal *ah,
*/
extern uint32_t __ahdecl ath_hal_pkt_txtime(struct ath_hal *ah,
const HAL_RATE_TABLE *rates, uint32_t frameLen,
- uint16_t rateix, HAL_BOOL isht40, HAL_BOOL shortPreamble);
+ uint16_t rateix, HAL_BOOL isht40, HAL_BOOL shortPreamble,
+ HAL_BOOL includeSifs);
/*
* Calculate the duration of an 11n frame.
@@ -1639,7 +1640,8 @@ extern uint32_t __ahdecl ath_computedur_ht(uint32_t frameLen, uint16_t rate,
*/
extern uint16_t __ahdecl ath_hal_computetxtime(struct ath_hal *,
const HAL_RATE_TABLE *rates, uint32_t frameLen,
- uint16_t rateix, HAL_BOOL shortPreamble);
+ uint16_t rateix, HAL_BOOL shortPreamble,
+ HAL_BOOL includeSifs);
/*
* Adjust the TSF.
diff --git a/sys/dev/ath/ath_hal/ar5212/ar5212_reset.c b/sys/dev/ath/ath_hal/ar5212/ar5212_reset.c
index 6a76f4329fb2..7c9158e91d2b 100644
--- a/sys/dev/ath/ath_hal/ar5212/ar5212_reset.c
+++ b/sys/dev/ath/ath_hal/ar5212/ar5212_reset.c
@@ -2735,7 +2735,7 @@ ar5212SetRateDurationTable(struct ath_hal *ah,
AR_RATE_DURATION(rt->info[i].rateCode),
ath_hal_computetxtime(ah, rt,
WLAN_CTRL_FRAME_SIZE,
- rt->info[i].controlRate, AH_FALSE));
+ rt->info[i].controlRate, AH_FALSE, AH_TRUE));
if (!IEEE80211_IS_CHAN_TURBO(chan)) {
/* 11g Table is used to cover the CCK rates. */
rt = ar5212GetRateTable(ah, HAL_MODE_11G);
@@ -2748,7 +2748,8 @@ ar5212SetRateDurationTable(struct ath_hal *ah,
OS_REG_WRITE(ah, reg,
ath_hal_computetxtime(ah, rt,
WLAN_CTRL_FRAME_SIZE,
- rt->info[i].controlRate, AH_FALSE));
+ rt->info[i].controlRate, AH_FALSE,
+ AH_TRUE));
/* cck rates have short preamble option also */
if (rt->info[i].shortPreamble) {
reg += rt->info[i].shortPreamble << 2;
@@ -2756,7 +2757,7 @@ ar5212SetRateDurationTable(struct ath_hal *ah,
ath_hal_computetxtime(ah, rt,
WLAN_CTRL_FRAME_SIZE,
rt->info[i].controlRate,
- AH_TRUE));
+ AH_TRUE, AH_TRUE));
}
}
}
diff --git a/sys/dev/ath/ath_rate/sample/sample.h b/sys/dev/ath/ath_rate/sample/sample.h
index 5495141c60be..82037d7e935d 100644
--- a/sys/dev/ath/ath_rate/sample/sample.h
+++ b/sys/dev/ath/ath_rate/sample/sample.h
@@ -212,9 +212,9 @@ static unsigned calc_usecs_unicast_packet(struct ath_softc *sc,
if (rts) /* SIFS + CTS */
ctsduration += rt->info[cix].spAckDuration;
- /* XXX assumes short preamble */
+ /* XXX assumes short preamble, include SIFS */
ctsduration += ath_hal_pkt_txtime(sc->sc_ah, rt, length, rix,
- is_ht40, 0);
+ is_ht40, 0, 1);
if (cts) /* SIFS + ACK */
ctsduration += rt->info[cix].spAckDuration;
@@ -223,9 +223,9 @@ static unsigned calc_usecs_unicast_packet(struct ath_softc *sc,
}
tt += t_difs;
- /* XXX assumes short preamble */
+ /* XXX assumes short preamble, include SIFS */
tt += (long_retries+1)*ath_hal_pkt_txtime(sc->sc_ah, rt, length, rix,
- is_ht40, 0);
+ is_ht40, 0, 1);
tt += (long_retries+1)*(t_sifs + rt->info[rix].spAckDuration);
diff --git a/sys/dev/ath/if_ath_beacon.c b/sys/dev/ath/if_ath_beacon.c
index c700230149e5..1d1aa26831ce 100644
--- a/sys/dev/ath/if_ath_beacon.c
+++ b/sys/dev/ath/if_ath_beacon.c
@@ -347,7 +347,7 @@ ath_beacon_setup(struct ath_softc *sc, struct ath_buf *bf)
rc[0].tx_power_cap = 0x3f;
rc[0].PktDuration =
ath_hal_computetxtime(ah, rt, roundup(m->m_len, 4),
- rix, 0);
+ rix, 0, AH_TRUE);
ath_hal_set11nratescenario(ah, ds, 0, 0, rc, 4, flags);
}
diff --git a/sys/dev/ath/if_ath_tdma.c b/sys/dev/ath/if_ath_tdma.c
index e3460c6374c3..c29da1b1de89 100644
--- a/sys/dev/ath/if_ath_tdma.c
+++ b/sys/dev/ath/if_ath_tdma.c
@@ -288,7 +288,8 @@ ath_tdma_config(struct ath_softc *sc, struct ieee80211vap *vap)
/* XXX short preamble assumed */
/* XXX non-11n rate assumed */
sc->sc_tdmaguard = ath_hal_computetxtime(ah, sc->sc_currates,
- vap->iv_ifp->if_mtu + IEEE80211_MAXOVERHEAD, rix, AH_TRUE);
+ vap->iv_ifp->if_mtu + IEEE80211_MAXOVERHEAD, rix, AH_TRUE,
+ AH_TRUE);
}
ath_hal_intrset(ah, 0);
@@ -430,7 +431,8 @@ ath_tdma_update(struct ieee80211_node *ni,
rix,
!! (rs->rs_flags & HAL_RX_2040),
(rix & 0x80) ?
- (! (rs->rs_flags & HAL_RX_GI)) : rt->info[rix].shortPreamble);
+ (! (rs->rs_flags & HAL_RX_GI)) : rt->info[rix].shortPreamble,
+ AH_TRUE);
/* NB: << 9 is to cvt to TU and /2 */
nextslot = (rstamp - txtime) + (sc->sc_tdmabintval << 9);
diff --git a/sys/dev/ath/if_ath_tx.c b/sys/dev/ath/if_ath_tx.c
index d2b1d85ea9e3..fadfed3cc61f 100644
--- a/sys/dev/ath/if_ath_tx.c
+++ b/sys/dev/ath/if_ath_tx.c
@@ -1131,7 +1131,8 @@ ath_tx_calc_duration(struct ath_softc *sc, struct ath_buf *bf)
dur += ath_hal_computetxtime(ah,
rt,
bf->bf_nextfraglen,
- rix, shortPreamble);
+ rix, shortPreamble,
+ AH_TRUE);
}
if (isfrag) {
/*
@@ -1201,14 +1202,14 @@ ath_tx_calc_ctsduration(struct ath_hal *ah, int rix, int cix,
if (flags & HAL_TXDESC_RTSENA) /* SIFS + CTS */
ctsduration += rt->info[cix].spAckDuration;
ctsduration += ath_hal_computetxtime(ah,
- rt, pktlen, rix, AH_TRUE);
+ rt, pktlen, rix, AH_TRUE, AH_TRUE);
if ((flags & HAL_TXDESC_NOACK) == 0) /* SIFS + ACK */
ctsduration += rt->info[rix].spAckDuration;
} else {
if (flags & HAL_TXDESC_RTSENA) /* SIFS + CTS */
ctsduration += rt->info[cix].lpAckDuration;
ctsduration += ath_hal_computetxtime(ah,
- rt, pktlen, rix, AH_FALSE);
+ rt, pktlen, rix, AH_FALSE, AH_TRUE);
if ((flags & HAL_TXDESC_NOACK) == 0) /* SIFS + ACK */
ctsduration += rt->info[rix].lpAckDuration;
}
diff --git a/sys/dev/ath/if_ath_tx_ht.c b/sys/dev/ath/if_ath_tx_ht.c
index 5a55f60762df..c4d71301da98 100644
--- a/sys/dev/ath/if_ath_tx_ht.c
+++ b/sys/dev/ath/if_ath_tx_ht.c
@@ -296,8 +296,6 @@ ath_tx_rate_fill_rcflags(struct ath_softc *sc, struct ath_buf *bf)
* can receive (at least) 1 stream STBC, AND it's
* MCS 0-7, AND we have at least two chains enabled,
* enable STBC.
- *
- * XXX TODO: .. and the rate is an 11n rate?
*/
if (ic->ic_htcaps & IEEE80211_HTCAP_TXSTBC &&
ni->ni_vap->iv_flags_ht & IEEE80211_FHT_STBC_TX &&
@@ -621,8 +619,9 @@ ath_rateseries_setup(struct ath_softc *sc, struct ieee80211_node *ni,
if (shortPreamble)
series[i].Rate |=
rt->info[rc[i].rix].shortPreamble;
+ /* XXX TODO: don't include SIFS */
series[i].PktDuration = ath_hal_computetxtime(ah,
- rt, pktlen, rc[i].rix, shortPreamble);
+ rt, pktlen, rc[i].rix, shortPreamble, AH_TRUE);
}
}
}