/** * ath5k_ani_calibration() - The main ANI calibration function * @ah: The &struct ath5k_hw * * We count OFDM and CCK errors relative to the time where we did not send or * receive ("listen" time) and raise or lower immunity accordingly. * This is called regularly (every second) from the calibration timer, but also * when an error threshold has been reached. * * In order to synchronize access from different contexts, this should be * called only indirectly by scheduling the ANI tasklet! */ void ath5k_ani_calibration(struct ath5k_hw *ah) { struct ath5k_ani_state *as = &ah->ani_state; int listen, ofdm_high, ofdm_low, cck_high, cck_low; /* get listen time since last call and add it to the counter because we * might not have restarted the "ani period" last time. * always do this to calculate the busy time also in manual mode */ listen = ath5k_hw_ani_get_listen_time(ah, as); as->listen_time += listen; if (as->ani_mode != ATH5K_ANI_MODE_AUTO) return; ath5k_ani_save_and_clear_phy_errors(ah, as); ofdm_high = as->listen_time * ATH5K_ANI_OFDM_TRIG_HIGH / 1000; cck_high = as->listen_time * ATH5K_ANI_CCK_TRIG_HIGH / 1000; ofdm_low = as->listen_time * ATH5K_ANI_OFDM_TRIG_LOW / 1000; cck_low = as->listen_time * ATH5K_ANI_CCK_TRIG_LOW / 1000; ATH5K_DBG_UNLIMIT(ah, ATH5K_DEBUG_ANI, "listen %d (now %d)", as->listen_time, listen); ATH5K_DBG_UNLIMIT(ah, ATH5K_DEBUG_ANI, "check high ofdm %d/%d cck %d/%d", as->ofdm_errors, ofdm_high, as->cck_errors, cck_high); if (as->ofdm_errors > ofdm_high || as->cck_errors > cck_high) { /* too many PHY errors - we have to raise immunity */ bool ofdm_flag = as->ofdm_errors > ofdm_high ? true : false; ath5k_ani_raise_immunity(ah, as, ofdm_flag); ath5k_ani_period_restart(as); } else if (as->listen_time > 5 * ATH5K_ANI_LISTEN_PERIOD) { /* If more than 5 (TODO: why 5?) periods have passed and we got * relatively little errors we can try to lower immunity */ ATH5K_DBG_UNLIMIT(ah, ATH5K_DEBUG_ANI, "check low ofdm %d/%d cck %d/%d", as->ofdm_errors, ofdm_low, as->cck_errors, cck_low); if (as->ofdm_errors <= ofdm_low && as->cck_errors <= cck_low) ath5k_ani_lower_immunity(ah, as); ath5k_ani_period_restart(as); } }
void ath5k_ani_calibration(struct ath5k_hw *ah) { struct ath5k_ani_state *as = &ah->ani_state; int listen, ofdm_high, ofdm_low, cck_high, cck_low; listen = ath5k_hw_ani_get_listen_time(ah, as); as->listen_time += listen; if (as->ani_mode != ATH5K_ANI_MODE_AUTO) return; ath5k_ani_save_and_clear_phy_errors(ah, as); ofdm_high = as->listen_time * ATH5K_ANI_OFDM_TRIG_HIGH / 1000; cck_high = as->listen_time * ATH5K_ANI_CCK_TRIG_HIGH / 1000; ofdm_low = as->listen_time * ATH5K_ANI_OFDM_TRIG_LOW / 1000; cck_low = as->listen_time * ATH5K_ANI_CCK_TRIG_LOW / 1000; ATH5K_DBG_UNLIMIT(ah, ATH5K_DEBUG_ANI, "listen %d (now %d)", as->listen_time, listen); ATH5K_DBG_UNLIMIT(ah, ATH5K_DEBUG_ANI, "check high ofdm %d/%d cck %d/%d", as->ofdm_errors, ofdm_high, as->cck_errors, cck_high); if (as->ofdm_errors > ofdm_high || as->cck_errors > cck_high) { bool ofdm_flag = as->ofdm_errors > ofdm_high ? true : false; ath5k_ani_raise_immunity(ah, as, ofdm_flag); ath5k_ani_period_restart(as); } else if (as->listen_time > 5 * ATH5K_ANI_LISTEN_PERIOD) { ATH5K_DBG_UNLIMIT(ah, ATH5K_DEBUG_ANI, "check low ofdm %d/%d cck %d/%d", as->ofdm_errors, ofdm_low, as->cck_errors, cck_low); if (as->ofdm_errors <= ofdm_low && as->cck_errors <= cck_low) ath5k_ani_lower_immunity(ah, as); ath5k_ani_period_restart(as); } }