[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
This commit is contained in:
Adrian Chadd 2016-07-15 06:39:35 +00:00
parent 6199f16549
commit 7ff1939db0
8 changed files with 48 additions and 33 deletions

View File

@ -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
}

View File

@ -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.

View File

@ -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));
}
}
}

View File

@ -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);

View File

@ -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);
}

View File

@ -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);

View File

@ -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;
}

View File

@ -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);
}
}
}