Port over a new routine which grabs the percentage of time spent in TX frame, RX frame,

RX clear, RX extension clear.

This is useful for estimating channel business.

The same routines should be written for AR5210->AR5212 where appopriate.

Obtained from:	Atheros
This commit is contained in:
Adrian Chadd 2011-11-09 05:25:30 +00:00
parent 020d7846cb
commit a1dd224b99
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=227374
3 changed files with 60 additions and 1 deletions

View File

@ -1025,6 +1025,9 @@ struct ath_hal {
struct ath_desc *);
void __ahdecl(*ah_set11nBurstDuration)(struct ath_hal *,
struct ath_desc *, u_int);
uint32_t __ahdecl(*ah_get_mib_cycle_counts_pct) (struct ath_hal *,
uint32_t *, uint32_t *, uint32_t *, uint32_t *);
uint32_t __ahdecl(*ah_get11nExtBusy)(struct ath_hal *);
void __ahdecl(*ah_set11nMac2040)(struct ath_hal *,
HAL_HT_MACMODE);

View File

@ -112,11 +112,13 @@ struct ath_hal_5416 {
int ah_hangs; /* h/w hangs state */
uint8_t ah_keytype[AR5416_KEYTABLE_SIZE];
/*
* Extension Channel Rx Clear State
* Primary/Extension Channel Tx, Rx, Rx Clear State
*/
uint32_t ah_cycleCount;
uint32_t ah_ctlBusy;
uint32_t ah_extBusy;
uint32_t ah_rxBusy;
uint32_t ah_txBusy;
uint32_t ah_rx_chainmask;
uint32_t ah_tx_chainmask;
@ -194,6 +196,9 @@ 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 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);

View File

@ -171,6 +171,57 @@ ar5416SetCoverageClass(struct ath_hal *ah, uint8_t coverageclass, int now)
AH_PRIVATE(ah)->ah_coverageClass = coverageclass;
}
/*
* 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)
{
struct ath_hal_5416 *ahp = AH5416(ah);
u_int32_t good = 1;
/* XXX freeze/unfreeze mib counters */
uint32_t rc = OS_REG_READ(ah, AR_RCCNT);
uint32_t ec = OS_REG_READ(ah, AR_EXTRCCNT);
uint32_t rf = OS_REG_READ(ah, AR_RFCNT);
uint32_t tf = OS_REG_READ(ah, AR_TFCNT);
uint32_t cc = OS_REG_READ(ah, AR_CCCNT); /* read cycles last */
if (ahp->ah_cycleCount == 0 || ahp->ah_cycleCount > cc) {
/*
* Cycle counter wrap (or initial call); it's not possible
* to accurately calculate a value because the registers
* right shift rather than wrap--so punt and return 0.
*/
HALDEBUG(ah, HAL_DEBUG_ANY,
"%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;
}
}
ahp->ah_cycleCount = cc;
ahp->ah_rxBusy = rf;
ahp->ah_ctlBusy = rc;
ahp->ah_txBusy = tf;
ahp->ah_extBusy = ec;
return good;
}
/*
* Return approximation of extension channel busy over an time interval
* 0% (clear) -> 100% (busy)