Beispiel #1
0
/**
 * ath5k_ani_init() - Initialize ANI
 * @ah: The &struct ath5k_hw
 * @mode: One of enum ath5k_ani_mode
 *
 * Initialize ANI according to mode.
 */
void
ath5k_ani_init(struct ath5k_hw *ah, enum ath5k_ani_mode mode)
{
    /* ANI is only possible on 5212 and newer */
    if (ah->ah_version < AR5K_AR5212)
        return;

    if (mode < ATH5K_ANI_MODE_OFF || mode > ATH5K_ANI_MODE_AUTO) {
        ATH5K_ERR(ah, "ANI mode %d out of range", mode);
        return;
    }

    /* clear old state information */
    memset(&ah->ani_state, 0, sizeof(ah->ani_state));

    /* older hardware has more spur levels than newer */
    if (ah->ah_mac_srev < AR5K_SREV_AR2414)
        ah->ani_state.max_spur_level = 7;
    else
        ah->ani_state.max_spur_level = 2;

    /* initial values for our ani parameters */
    if (mode == ATH5K_ANI_MODE_OFF) {
        ATH5K_DBG_UNLIMIT(ah, ATH5K_DEBUG_ANI, "ANI off\n");
    } else if (mode == ATH5K_ANI_MODE_MANUAL_LOW) {
        ATH5K_DBG_UNLIMIT(ah, ATH5K_DEBUG_ANI,
                          "ANI manual low -> high sensitivity\n");
        ath5k_ani_set_noise_immunity_level(ah, 0);
        ath5k_ani_set_spur_immunity_level(ah, 0);
        ath5k_ani_set_firstep_level(ah, 0);
        ath5k_ani_set_ofdm_weak_signal_detection(ah, true);
        ath5k_ani_set_cck_weak_signal_detection(ah, true);
    } else if (mode == ATH5K_ANI_MODE_MANUAL_HIGH) {
        ATH5K_DBG_UNLIMIT(ah, ATH5K_DEBUG_ANI,
                          "ANI manual high -> low sensitivity\n");
        ath5k_ani_set_noise_immunity_level(ah,
                                           ATH5K_ANI_MAX_NOISE_IMM_LVL);
        ath5k_ani_set_spur_immunity_level(ah,
                                          ah->ani_state.max_spur_level);
        ath5k_ani_set_firstep_level(ah, ATH5K_ANI_MAX_FIRSTEP_LVL);
        ath5k_ani_set_ofdm_weak_signal_detection(ah, false);
        ath5k_ani_set_cck_weak_signal_detection(ah, false);
    } else if (mode == ATH5K_ANI_MODE_AUTO) {
        ATH5K_DBG_UNLIMIT(ah, ATH5K_DEBUG_ANI, "ANI auto\n");
        ath5k_ani_set_noise_immunity_level(ah, 0);
        ath5k_ani_set_spur_immunity_level(ah, 0);
        ath5k_ani_set_firstep_level(ah, 0);
        ath5k_ani_set_ofdm_weak_signal_detection(ah, true);
        ath5k_ani_set_cck_weak_signal_detection(ah, false);
    }

    /* newer hardware has PHY error counter registers which we can use to
     * get OFDM and CCK error counts. older hardware has to set rxfilter and
     * report every single PHY error by calling ath5k_ani_phy_error_report()
     */
    if (mode == ATH5K_ANI_MODE_AUTO) {
        if (ah->ah_capabilities.cap_has_phyerr_counters)
            ath5k_enable_phy_err_counters(ah);
        else
            ath5k_hw_set_rx_filter(ah, ath5k_hw_get_rx_filter(ah) |
                                   AR5K_RX_FILTER_PHYERR);
    } else {
        if (ah->ah_capabilities.cap_has_phyerr_counters)
            ath5k_disable_phy_err_counters(ah);
        else
            ath5k_hw_set_rx_filter(ah, ath5k_hw_get_rx_filter(ah) &
                                   ~AR5K_RX_FILTER_PHYERR);
    }

    ah->ani_state.ani_mode = mode;
}
void
ath5k_ani_init(struct ath5k_hw *ah, enum ath5k_ani_mode mode)
{
	
	if (ah->ah_version < AR5K_AR5212)
		return;

	if (mode < ATH5K_ANI_MODE_OFF || mode > ATH5K_ANI_MODE_AUTO) {
		ATH5K_ERR(ah, "ANI mode %d out of range", mode);
		return;
	}

	
	memset(&ah->ani_state, 0, sizeof(ah->ani_state));

	
	if (ah->ah_mac_srev < AR5K_SREV_AR2414)
		ah->ani_state.max_spur_level = 7;
	else
		ah->ani_state.max_spur_level = 2;

	
	if (mode == ATH5K_ANI_MODE_OFF) {
		ATH5K_DBG_UNLIMIT(ah, ATH5K_DEBUG_ANI, "ANI off\n");
	} else if (mode == ATH5K_ANI_MODE_MANUAL_LOW) {
		ATH5K_DBG_UNLIMIT(ah, ATH5K_DEBUG_ANI,
			"ANI manual low -> high sensitivity\n");
		ath5k_ani_set_noise_immunity_level(ah, 0);
		ath5k_ani_set_spur_immunity_level(ah, 0);
		ath5k_ani_set_firstep_level(ah, 0);
		ath5k_ani_set_ofdm_weak_signal_detection(ah, true);
		ath5k_ani_set_cck_weak_signal_detection(ah, true);
	} else if (mode == ATH5K_ANI_MODE_MANUAL_HIGH) {
		ATH5K_DBG_UNLIMIT(ah, ATH5K_DEBUG_ANI,
			"ANI manual high -> low sensitivity\n");
		ath5k_ani_set_noise_immunity_level(ah,
					ATH5K_ANI_MAX_NOISE_IMM_LVL);
		ath5k_ani_set_spur_immunity_level(ah,
					ah->ani_state.max_spur_level);
		ath5k_ani_set_firstep_level(ah, ATH5K_ANI_MAX_FIRSTEP_LVL);
		ath5k_ani_set_ofdm_weak_signal_detection(ah, false);
		ath5k_ani_set_cck_weak_signal_detection(ah, false);
	} else if (mode == ATH5K_ANI_MODE_AUTO) {
		ATH5K_DBG_UNLIMIT(ah, ATH5K_DEBUG_ANI, "ANI auto\n");
		ath5k_ani_set_noise_immunity_level(ah, 0);
		ath5k_ani_set_spur_immunity_level(ah, 0);
		ath5k_ani_set_firstep_level(ah, 0);
		ath5k_ani_set_ofdm_weak_signal_detection(ah, true);
		ath5k_ani_set_cck_weak_signal_detection(ah, false);
	}

	if (mode == ATH5K_ANI_MODE_AUTO) {
		if (ah->ah_capabilities.cap_has_phyerr_counters)
			ath5k_enable_phy_err_counters(ah);
		else
			ath5k_hw_set_rx_filter(ah, ath5k_hw_get_rx_filter(ah) |
						   AR5K_RX_FILTER_PHYERR);
	} else {
		if (ah->ah_capabilities.cap_has_phyerr_counters)
			ath5k_disable_phy_err_counters(ah);
		else
			ath5k_hw_set_rx_filter(ah, ath5k_hw_get_rx_filter(ah) &
						   ~AR5K_RX_FILTER_PHYERR);
	}

	ah->ani_state.ani_mode = mode;
}