diff options
author | adrian <adrian@FreeBSD.org> | 2012-04-28 08:29:46 +0000 |
---|---|---|
committer | adrian <adrian@FreeBSD.org> | 2012-04-28 08:29:46 +0000 |
commit | 0d581e7a85f7b5fa60d74541897104ed606a47f8 (patch) | |
tree | 13d0f4e76cd37c97ad639fa72db3ba6849a2e968 /sys/dev | |
parent | ebcc237b86877ec440d76662899fecf13359e94f (diff) | |
download | FreeBSD-src-0d581e7a85f7b5fa60d74541897104ed606a47f8.zip FreeBSD-src-0d581e7a85f7b5fa60d74541897104ed606a47f8.tar.gz |
Extend the ANI code to implement basic channel survey support.
* Always call ar5416GetListenTime()
* Modify ar5416GetListenTime() to:
+ don't update the ANI state if there isn't any ANI state;
+ don't update the channel survey state if there's no active
channel - just to be paranoid
+ copy the channel survey results into the current sample slot
based on the current channel; then increment the sample counter
and sample history counter.
* Modify ar5416GetMIBCyclesPct() to simply return a HAL_SURVEY_SAMPLE,
rather than a set of percentages. The ANI code wasn't using the
percentages anyway.
TODO:
* Create a new function which fetches the survey results periodically
* .. then modify the ANI code to use the pre-fetched values rather than
fetching them again
* Roll the 11n ext busy function from ar5416_misc.c to update all the
counters, then do the result calculation
* .. then, modify the MIB counter routine to correctly fetch a snapshot -
freeze the counters, fetch the values, then reset the counters.
Diffstat (limited to 'sys/dev')
-rw-r--r-- | sys/dev/ath/ath_hal/ar5416/ar5416.h | 5 | ||||
-rw-r--r-- | sys/dev/ath/ath_hal/ar5416/ar5416_ani.c | 75 | ||||
-rw-r--r-- | sys/dev/ath/ath_hal/ar5416/ar5416_misc.c | 29 |
3 files changed, 73 insertions, 36 deletions
diff --git a/sys/dev/ath/ath_hal/ar5416/ar5416.h b/sys/dev/ath/ath_hal/ar5416/ar5416.h index 1483622..75f22b7 100644 --- a/sys/dev/ath/ath_hal/ar5416/ar5416.h +++ b/sys/dev/ath/ath_hal/ar5416/ar5416.h @@ -196,9 +196,8 @@ extern uint32_t ar5416GetCurRssi(struct ath_hal *ah); extern HAL_BOOL ar5416SetAntennaSwitch(struct ath_hal *, HAL_ANT_SETTING); extern HAL_BOOL ar5416SetDecompMask(struct ath_hal *, uint16_t, int); extern void ar5416SetCoverageClass(struct ath_hal *, uint8_t, int); -extern uint32_t ar5416GetMibCycleCountsPct(struct ath_hal *ah, - uint32_t *rxc_pcnt, uint32_t *rxextc_pcnt, uint32_t *rxf_pcnt, - uint32_t *txf_pcnt); +extern uint32_t ar5416GetMibCycleCounts(struct ath_hal *ah, + HAL_SURVEY_SAMPLE *hsample); extern uint32_t ar5416Get11nExtBusy(struct ath_hal *ah); extern void ar5416Set11nMac2040(struct ath_hal *ah, HAL_HT_MACMODE mode); extern HAL_HT_RXCLEAR ar5416Get11nRxClear(struct ath_hal *ah); diff --git a/sys/dev/ath/ath_hal/ar5416/ar5416_ani.c b/sys/dev/ath/ath_hal/ar5416/ar5416_ani.c index deaacd7..2e48473 100644 --- a/sys/dev/ath/ath_hal/ar5416/ar5416_ani.c +++ b/sys/dev/ath/ath_hal/ar5416/ar5416_ani.c @@ -804,20 +804,51 @@ ar5416AniLowerImmunity(struct ath_hal *ah) * deducting the cycles spent tx'ing and rx'ing from the total * cycle count since our last call. A return value <0 indicates * an invalid/inconsistent time. + * + * This may be called with ANI disabled; in which case simply keep + * the statistics and don't write to the aniState pointer. + * + * XXX TODO: Make this cleaner! */ static int32_t ar5416AniGetListenTime(struct ath_hal *ah) { struct ath_hal_5212 *ahp = AH5212(ah); - struct ar5212AniState *aniState; - uint32_t rxc_pct, extc_pct, rxf_pct, txf_pct; + struct ar5212AniState *aniState = NULL; int32_t listenTime; int good; + HAL_SURVEY_SAMPLE hs; + HAL_CHANNEL_SURVEY *cs = AH_NULL; + + /* + * We shouldn't see ah_curchan be NULL, but just in case.. + */ + if (AH_PRIVATE(ah)->ah_curchan == AH_NULL) { + ath_hal_printf(ah, "%s: ah_curchan = NULL?\n", __func__); + return (0); + } + /* XXX bounds check? */ + if (AH_PRIVATE(ah)->ah_curchan != AH_NULL) + cs = + &ahp->ah_chansurvey[AH_PRIVATE(ah)->ah_curchan->ic_devdata]; + + /* + * Fetch the current statistics, squirrel away the current + * sample, bump the sequence/sample counter. + */ + OS_MEMZERO(&hs, sizeof(hs)); + good = ar5416GetMibCycleCounts(ah, &hs); + if (cs != AH_NULL) { + OS_MEMCPY(&cs->samples[cs->cur_sample], &hs, sizeof(hs)); + cs->samples[cs->cur_sample].seq_num = cs->cur_seq; + cs->cur_sample = + (cs->cur_sample + 1) % CHANNEL_SURVEY_SAMPLE_COUNT; + cs->cur_seq++; + } - good = ar5416GetMibCycleCountsPct(ah, - &rxc_pct, &extc_pct, &rxf_pct, &txf_pct); + if (ANI_ENA(ah)) + aniState = ahp->ah_curani; - aniState = ahp->ah_curani; if (good == 0) { /* * Cycle counter wrap (or initial call); it's not possible @@ -826,18 +857,28 @@ ar5416AniGetListenTime(struct ath_hal *ah) */ listenTime = 0; ahp->ah_stats.ast_ani_lzero++; - } else { - int32_t ccdelta = AH5416(ah)->ah_cycleCount - aniState->cycleCount; - int32_t rfdelta = AH5416(ah)->ah_rxBusy - aniState->rxFrameCount; - int32_t tfdelta = AH5416(ah)->ah_txBusy - aniState->txFrameCount; + } else if (ANI_ENA(ah)) { + /* + * Only calculate and update the cycle count if we have + * an ANI state. + */ + int32_t ccdelta = + AH5416(ah)->ah_cycleCount - aniState->cycleCount; + int32_t rfdelta = + AH5416(ah)->ah_rxBusy - aniState->rxFrameCount; + int32_t tfdelta = + AH5416(ah)->ah_txBusy - aniState->txFrameCount; listenTime = (ccdelta - rfdelta - tfdelta) / CLOCK_RATE; } - aniState->cycleCount = AH5416(ah)->ah_cycleCount; - aniState->txFrameCount = AH5416(ah)->ah_rxBusy; - aniState->rxFrameCount = AH5416(ah)->ah_txBusy; - HALDEBUG(ah, HAL_DEBUG_ANI, "rxc=%d, extc=%d, rxf=%d, txf=%d\n", - rxc_pct, extc_pct, rxf_pct, txf_pct); + /* + * Again, only update ANI state if we have it. + */ + if (ANI_ENA(ah)) { + aniState->cycleCount = AH5416(ah)->ah_cycleCount; + aniState->txFrameCount = AH5416(ah)->ah_rxBusy; + aniState->rxFrameCount = AH5416(ah)->ah_txBusy; + } return listenTime; } @@ -902,13 +943,13 @@ ar5416AniPoll(struct ath_hal *ah, const struct ieee80211_channel *chan) const struct ar5212AniParams *params; int32_t listenTime; + /* Always update from the MIB, for statistics gathering */ + listenTime = ar5416AniGetListenTime(ah); + /* XXX can aniState be null? */ if (aniState == AH_NULL) return; - /* Always update from the MIB, for statistics gathering */ - listenTime = ar5416AniGetListenTime(ah); - if (!ANI_ENA(ah)) return; diff --git a/sys/dev/ath/ath_hal/ar5416/ar5416_misc.c b/sys/dev/ath/ath_hal/ar5416/ar5416_misc.c index 6807384..ff1dbd9 100644 --- a/sys/dev/ath/ath_hal/ar5416/ar5416_misc.c +++ b/sys/dev/ath/ath_hal/ar5416/ar5416_misc.c @@ -185,8 +185,7 @@ ar5416SetCoverageClass(struct ath_hal *ah, uint8_t coverageclass, int now) * Return the busy for rx_frame, rx_clear, and tx_frame */ uint32_t -ar5416GetMibCycleCountsPct(struct ath_hal *ah, uint32_t *rxc_pcnt, - uint32_t *extc_pcnt, uint32_t *rxf_pcnt, uint32_t *txf_pcnt) +ar5416GetMibCycleCounts(struct ath_hal *ah, HAL_SURVEY_SAMPLE *hsample) { struct ath_hal_5416 *ahp = AH5416(ah); u_int32_t good = 1; @@ -208,21 +207,17 @@ ar5416GetMibCycleCountsPct(struct ath_hal *ah, uint32_t *rxc_pcnt, "%s: cycle counter wrap. ExtBusy = 0\n", __func__); good = 0; } else { - uint32_t cc_d = cc - ahp->ah_cycleCount; - uint32_t rc_d = rc - ahp->ah_ctlBusy; - uint32_t ec_d = ec - ahp->ah_extBusy; - uint32_t rf_d = rf - ahp->ah_rxBusy; - uint32_t tf_d = tf - ahp->ah_txBusy; - - if (cc_d != 0) { - *rxc_pcnt = rc_d * 100 / cc_d; - *rxf_pcnt = rf_d * 100 / cc_d; - *txf_pcnt = tf_d * 100 / cc_d; - *extc_pcnt = ec_d * 100 / cc_d; - } else { - good = 0; - } + hsample->cycle_count = cc - ahp->ah_cycleCount; + hsample->chan_busy = rc - ahp->ah_ctlBusy; + hsample->ext_chan_busy = ec - ahp->ah_extBusy; + hsample->rx_busy = rf - ahp->ah_rxBusy; + hsample->tx_busy = tf - ahp->ah_txBusy; } + + /* + * Keep a copy of the MIB results so the next sample has something + * to work from. + */ ahp->ah_cycleCount = cc; ahp->ah_rxBusy = rf; ahp->ah_ctlBusy = rc; @@ -236,6 +231,8 @@ ar5416GetMibCycleCountsPct(struct ath_hal *ah, uint32_t *rxc_pcnt, * Return approximation of extension channel busy over an time interval * 0% (clear) -> 100% (busy) * + * XXX TODO: update this to correctly sample all the counters, + * rather than a subset of it. */ uint32_t ar5416Get11nExtBusy(struct ath_hal *ah) |