summaryrefslogtreecommitdiffstats
path: root/sys/dev
diff options
context:
space:
mode:
authoradrian <adrian@FreeBSD.org>2012-04-28 08:29:46 +0000
committeradrian <adrian@FreeBSD.org>2012-04-28 08:29:46 +0000
commit0d581e7a85f7b5fa60d74541897104ed606a47f8 (patch)
tree13d0f4e76cd37c97ad639fa72db3ba6849a2e968 /sys/dev
parentebcc237b86877ec440d76662899fecf13359e94f (diff)
downloadFreeBSD-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.h5
-rw-r--r--sys/dev/ath/ath_hal/ar5416/ar5416_ani.c75
-rw-r--r--sys/dev/ath/ath_hal/ar5416/ar5416_misc.c29
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)
OpenPOWER on IntegriCloud