From owner-svn-src-all@FreeBSD.ORG Sat Apr 28 08:29:47 2012 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 24B5C106566B; Sat, 28 Apr 2012 08:29:47 +0000 (UTC) (envelope-from adrian@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 0F93C8FC0A; Sat, 28 Apr 2012 08:29:47 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.4/8.14.4) with ESMTP id q3S8TkEi050156; Sat, 28 Apr 2012 08:29:46 GMT (envelope-from adrian@svn.freebsd.org) Received: (from adrian@localhost) by svn.freebsd.org (8.14.4/8.14.4/Submit) id q3S8TkFB050152; Sat, 28 Apr 2012 08:29:46 GMT (envelope-from adrian@svn.freebsd.org) Message-Id: <201204280829.q3S8TkFB050152@svn.freebsd.org> From: Adrian Chadd Date: Sat, 28 Apr 2012 08:29:46 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r234752 - head/sys/dev/ath/ath_hal/ar5416 X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 28 Apr 2012 08:29:47 -0000 Author: adrian Date: Sat Apr 28 08:29:46 2012 New Revision: 234752 URL: http://svn.freebsd.org/changeset/base/234752 Log: 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. Modified: head/sys/dev/ath/ath_hal/ar5416/ar5416.h head/sys/dev/ath/ath_hal/ar5416/ar5416_ani.c head/sys/dev/ath/ath_hal/ar5416/ar5416_misc.c Modified: head/sys/dev/ath/ath_hal/ar5416/ar5416.h ============================================================================== --- head/sys/dev/ath/ath_hal/ar5416/ar5416.h Sat Apr 28 08:17:19 2012 (r234751) +++ head/sys/dev/ath/ath_hal/ar5416/ar5416.h Sat Apr 28 08:29:46 2012 (r234752) @@ -196,9 +196,8 @@ extern uint32_t ar5416GetCurRssi(struct 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); Modified: head/sys/dev/ath/ath_hal/ar5416/ar5416_ani.c ============================================================================== --- head/sys/dev/ath/ath_hal/ar5416/ar5416_ani.c Sat Apr 28 08:17:19 2012 (r234751) +++ head/sys/dev/ath/ath_hal/ar5416/ar5416_ani.c Sat Apr 28 08:29:46 2012 (r234752) @@ -804,20 +804,51 @@ ar5416AniLowerImmunity(struct ath_hal *a * 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; - good = ar5416GetMibCycleCountsPct(ah, - &rxc_pct, &extc_pct, &rxf_pct, &txf_pct); + /* + * 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++; + } + + 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 *a */ 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 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; Modified: head/sys/dev/ath/ath_hal/ar5416/ar5416_misc.c ============================================================================== --- head/sys/dev/ath/ath_hal/ar5416/ar5416_misc.c Sat Apr 28 08:17:19 2012 (r234751) +++ head/sys/dev/ath/ath_hal/ar5416/ar5416_misc.c Sat Apr 28 08:29:46 2012 (r234752) @@ -185,8 +185,7 @@ ar5416SetCoverageClass(struct ath_hal *a * 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_ha "%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_ha * 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)