Add initial support for the HAL channel survey support to the AR9300 HAL.

This is used by the 'athsurvey' command to print out channel survey
statistics - % busy times transmit, receive and airtime.

It's as buggy and incomplete as the rest of the HAL survey support -
notably, tying into the ANI code to read channel stats and occasionally
getting garbage counters isn't very nice.  It also doesn't (yet!) get
channel survey information during a scan.  But it's good enough for
basic air-time debugging, which is why I'm committing it in this state.

Tested:

* AR9380, STA mode
This commit is contained in:
adrian 2015-03-29 21:53:08 +00:00
parent 2bbb9a7275
commit 07bd0d0266
4 changed files with 50 additions and 6 deletions

View File

@ -185,6 +185,8 @@ struct ar9300_ani_state {
int32_t rssi; /* The current RSSI */
u_int32_t tx_frame_count; /* Last tx_frame_count */
u_int32_t rx_frame_count; /* Last rx Frame count */
u_int32_t rx_busy_count; /* Last rx busy count */
u_int32_t rx_ext_busy_count; /* Last rx busy count; extension channel */
u_int32_t cycle_count; /* Last cycle_count (can detect wrap-around) */
u_int32_t ofdm_phy_err_count;/* OFDM err count since last reset */
u_int32_t cck_phy_err_count; /* CCK err count since last reset */

View File

@ -1061,10 +1061,13 @@ ar9300_ani_get_listen_time(struct ath_hal *ah, HAL_ANISTATS *ani_stats)
struct ath_hal_9300 *ahp = AH9300(ah);
struct ar9300_ani_state *ani_state;
u_int32_t tx_frame_count, rx_frame_count, cycle_count;
u_int32_t rx_busy_count, rx_ext_busy_count;
int32_t listen_time;
tx_frame_count = OS_REG_READ(ah, AR_TFCNT);
rx_frame_count = OS_REG_READ(ah, AR_RFCNT);
rx_busy_count = OS_REG_READ(ah, AR_RCCNT);
rx_ext_busy_count = OS_REG_READ(ah, AR_EXTRCCNT);
cycle_count = OS_REG_READ(ah, AR_CCCNT);
ani_state = ahp->ah_curani;
@ -1085,17 +1088,30 @@ ar9300_ani_get_listen_time(struct ath_hal *ah, HAL_ANISTATS *ani_stats)
int32_t ccdelta = cycle_count - ani_state->cycle_count;
int32_t rfdelta = rx_frame_count - ani_state->rx_frame_count;
int32_t tfdelta = tx_frame_count - ani_state->tx_frame_count;
int32_t rcdelta = rx_busy_count - ani_state->rx_busy_count;
int32_t extrcdelta = rx_ext_busy_count - ani_state->rx_ext_busy_count;
listen_time = (ccdelta - rfdelta - tfdelta) / CLOCK_RATE(ah);
#if HAL_ANI_DEBUG
//#if HAL_ANI_DEBUG
HALDEBUG(ah, HAL_DEBUG_ANI,
"%s: cyclecount=%d, rfcount=%d, tfcount=%d, listen_time=%d "
"%s: cyclecount=%d, rfcount=%d, tfcount=%d, rcdelta=%d, extrcdelta=%d, listen_time=%d "
"CLOCK_RATE=%d\n",
__func__, ccdelta, rfdelta, tfdelta, listen_time, CLOCK_RATE(ah));
#endif
__func__, ccdelta, rfdelta, tfdelta, rcdelta, extrcdelta,
listen_time, CLOCK_RATE(ah));
//#endif
/* Populate as appropriate */
ani_stats->cyclecnt_diff = ccdelta;
ani_stats->rxclr_cnt = rcdelta;
ani_stats->txframecnt_diff = tfdelta;
ani_stats->rxframecnt_diff = rfdelta;
ani_stats->extrxclr_cnt = extrcdelta;
ani_stats->listen_time = listen_time;
ani_stats->valid = AH_TRUE;
}
ani_state->cycle_count = cycle_count;
ani_state->tx_frame_count = tx_frame_count;
ani_state->rx_frame_count = rx_frame_count;
ani_state->rx_busy_count = rx_busy_count;
ani_state->rx_ext_busy_count = rx_ext_busy_count;
return listen_time;
}
@ -1155,7 +1171,13 @@ ar9300_ani_ar_poll(struct ath_hal *ah, const HAL_NODE_STATS *stats,
ofdm_phy_err_cnt = OS_REG_READ(ah, AR_PHY_ERR_1);
cck_phy_err_cnt = OS_REG_READ(ah, AR_PHY_ERR_2);
/* Populate HAL_ANISTATS */
if (ani_stats) {
ani_stats->cckphyerr_cnt =
cck_phy_err_cnt - ani_state->cck_phy_err_count;
ani_stats->ofdmphyerrcnt_diff =
ofdm_phy_err_cnt - ani_state->ofdm_phy_err_count;
}
/* NB: only use ast_ani_*errs with AH_PRIVATE_DIAG */
ahp->ah_stats.ast_ani_ofdmerrs +=

View File

@ -366,11 +366,26 @@ ar9300_ani_poll_freebsd(struct ath_hal *ah,
HAL_NODE_STATS stats;
HAL_ANISTATS anistats;
HAL_SURVEY_SAMPLE survey;
OS_MEMZERO(&stats, sizeof(stats));
OS_MEMZERO(&anistats, sizeof(anistats));
OS_MEMZERO(&survey, sizeof(survey));
ar9300_ani_ar_poll(ah, &stats, chan, &anistats);
/*
* If ANI stats are valid, use them to update the
* channel survey.
*/
if (anistats.valid) {
survey.cycle_count = anistats.cyclecnt_diff;
survey.chan_busy = anistats.rxclr_cnt;
survey.ext_chan_busy = anistats.extrxclr_cnt;
survey.tx_busy = anistats.txframecnt_diff;
survey.rx_busy = anistats.rxframecnt_diff;
ath_hal_survey_add_sample(ah, &survey);
}
}
/*

View File

@ -4666,7 +4666,10 @@ ar9300_reset(struct ath_hal *ah, HAL_OPMODE opmode, struct ieee80211_channel *ch
#endif
ahp->ah_skip_rx_iq_cal = AH_FALSE;
}
/* FreeBSD: clear the channel survey data */
ath_hal_survey_clear(ah);
/*
* Fast channel change (Change synthesizer based on channel freq
* without resetting chip)
@ -6400,5 +6403,7 @@ ar9300_ant_ctrl_set_lna_div_use_bt_ant(struct ath_hal *ah, HAL_BOOL enable, cons
} else {
return AH_TRUE;
}
/* XXX TODO: Add AR9565 support? */
}
#endif /* ATH_ANT_DIV_COMB */