Ejemplo n.º 1
0
/**
 * ath5k_ani_lower_immunity() - Decrease noise immunity
 * @ah: The &struct ath5k_hw
 * @as: The &struct ath5k_ani_state
 *
 * Try to lower noise immunity (=increase sensitivity) in several steps
 * depending on the average RSSI of the beacons we received.
 */
static void
ath5k_ani_lower_immunity(struct ath5k_hw *ah, struct ath5k_ani_state *as)
{
    int rssi = ewma_read(&ah->ah_beacon_rssi_avg);

    ATH5K_DBG_UNLIMIT(ah, ATH5K_DEBUG_ANI, "lower immunity");

    if (ah->opmode == NL80211_IFTYPE_AP) {
        /* AP mode */
        if (as->firstep_level > 0) {
            ath5k_ani_set_firstep_level(ah, as->firstep_level - 1);
            return;
        }
    } else {
        /* STA and IBSS mode (see TODO above) */
        if (rssi > ATH5K_ANI_RSSI_THR_HIGH) {
            /* beacon signal is high, leave OFDM weak signal
             * detection off or it may oscillate
             * TODO: who said it's off??? */
        } else if (rssi > ATH5K_ANI_RSSI_THR_LOW) {
            /* beacon RSSI is mid-range: turn on ODFM weak signal
             * detection and next, lower firstep level */
            if (as->ofdm_weak_sig == false) {
                ath5k_ani_set_ofdm_weak_signal_detection(ah,
                        true);
                return;
            }
            if (as->firstep_level > 0) {
                ath5k_ani_set_firstep_level(ah,
                                            as->firstep_level - 1);
                return;
            }
        } else {
            /* beacon signal is low: only reduce firstep level */
            if (as->firstep_level > 0) {
                ath5k_ani_set_firstep_level(ah,
                                            as->firstep_level - 1);
                return;
            }
        }
    }

    /* all modes */
    if (as->spur_level > 0) {
        ath5k_ani_set_spur_immunity_level(ah, as->spur_level - 1);
        return;
    }

    /* finally, reduce noise immunity */
    if (as->noise_imm_level > 0) {
        ath5k_ani_set_noise_immunity_level(ah, as->noise_imm_level - 1);
        return;
    }
}
Ejemplo n.º 2
0
static void
ath5k_ani_lower_immunity(struct ath5k_hw *ah, struct ath5k_ani_state *as)
{
	int rssi = ewma_read(&ah->ah_beacon_rssi_avg);

	ATH5K_DBG_UNLIMIT(ah, ATH5K_DEBUG_ANI, "lower immunity");

	if (ah->opmode == NL80211_IFTYPE_AP) {
		
		if (as->firstep_level > 0) {
			ath5k_ani_set_firstep_level(ah, as->firstep_level - 1);
			return;
		}
	} else {
		
		if (rssi > ATH5K_ANI_RSSI_THR_HIGH) {
		} else if (rssi > ATH5K_ANI_RSSI_THR_LOW) {
			if (!as->ofdm_weak_sig) {
				ath5k_ani_set_ofdm_weak_signal_detection(ah,
									 true);
				return;
			}
			if (as->firstep_level > 0) {
				ath5k_ani_set_firstep_level(ah,
							as->firstep_level - 1);
				return;
			}
		} else {
			
			if (as->firstep_level > 0) {
				ath5k_ani_set_firstep_level(ah,
							as->firstep_level - 1);
				return;
			}
		}
	}

	
	if (as->spur_level > 0) {
		ath5k_ani_set_spur_immunity_level(ah, as->spur_level - 1);
		return;
	}

	
	if (as->noise_imm_level > 0) {
		ath5k_ani_set_noise_immunity_level(ah, as->noise_imm_level - 1);
		return;
	}
}
Ejemplo n.º 3
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;
}
Ejemplo n.º 4
0
/**
 * ath5k_ani_raise_immunity() - Increase noise immunity
 * @ah: The &struct ath5k_hw
 * @as: The &struct ath5k_ani_state
 * @ofdm_trigger: If this is true we are called because of too many OFDM errors,
 * the algorithm will tune more parameters then.
 *
 * Try to raise noise immunity (=decrease sensitivity) in several steps
 * depending on the average RSSI of the beacons we received.
 */
static void
ath5k_ani_raise_immunity(struct ath5k_hw *ah, struct ath5k_ani_state *as,
                         bool ofdm_trigger)
{
    int rssi = ewma_read(&ah->ah_beacon_rssi_avg);

    ATH5K_DBG_UNLIMIT(ah, ATH5K_DEBUG_ANI, "raise immunity (%s)",
                      ofdm_trigger ? "ODFM" : "CCK");

    /* first: raise noise immunity */
    if (as->noise_imm_level < ATH5K_ANI_MAX_NOISE_IMM_LVL) {
        ath5k_ani_set_noise_immunity_level(ah, as->noise_imm_level + 1);
        return;
    }

    /* only OFDM: raise spur immunity level */
    if (ofdm_trigger &&
            as->spur_level < ah->ani_state.max_spur_level) {
        ath5k_ani_set_spur_immunity_level(ah, as->spur_level + 1);
        return;
    }

    /* AP mode */
    if (ah->opmode == NL80211_IFTYPE_AP) {
        if (as->firstep_level < ATH5K_ANI_MAX_FIRSTEP_LVL)
            ath5k_ani_set_firstep_level(ah, as->firstep_level + 1);
        return;
    }

    /* STA and IBSS mode */

    /* TODO: for IBSS mode it would be better to keep a beacon RSSI average
     * per each neighbour node and use the minimum of these, to make sure we
     * don't shut out a remote node by raising immunity too high. */

    if (rssi > ATH5K_ANI_RSSI_THR_HIGH) {
        ATH5K_DBG_UNLIMIT(ah, ATH5K_DEBUG_ANI,
                          "beacon RSSI high");
        /* only OFDM: beacon RSSI is high, we can disable ODFM weak
         * signal detection */
        if (ofdm_trigger && as->ofdm_weak_sig == true) {
            ath5k_ani_set_ofdm_weak_signal_detection(ah, false);
            ath5k_ani_set_spur_immunity_level(ah, 0);
            return;
        }
        /* as a last resort or CCK: raise firstep level */
        if (as->firstep_level < ATH5K_ANI_MAX_FIRSTEP_LVL) {
            ath5k_ani_set_firstep_level(ah, as->firstep_level + 1);
            return;
        }
    } else if (rssi > ATH5K_ANI_RSSI_THR_LOW) {
        /* beacon RSSI in mid range, we need OFDM weak signal detect,
         * but can raise firstep level */
        ATH5K_DBG_UNLIMIT(ah, ATH5K_DEBUG_ANI,
                          "beacon RSSI mid");
        if (ofdm_trigger && as->ofdm_weak_sig == false)
            ath5k_ani_set_ofdm_weak_signal_detection(ah, true);
        if (as->firstep_level < ATH5K_ANI_MAX_FIRSTEP_LVL)
            ath5k_ani_set_firstep_level(ah, as->firstep_level + 1);
        return;
    } else if (ah->ah_current_channel->band == IEEE80211_BAND_2GHZ) {
        /* beacon RSSI is low. in B/G mode turn of OFDM weak signal
         * detect and zero firstep level to maximize CCK sensitivity */
        ATH5K_DBG_UNLIMIT(ah, ATH5K_DEBUG_ANI,
                          "beacon RSSI low, 2GHz");
        if (ofdm_trigger && as->ofdm_weak_sig == true)
            ath5k_ani_set_ofdm_weak_signal_detection(ah, false);
        if (as->firstep_level > 0)
            ath5k_ani_set_firstep_level(ah, 0);
        return;
    }

    /* TODO: why not?:
    if (as->cck_weak_sig == true) {
    	ath5k_ani_set_cck_weak_signal_detection(ah, false);
    }
    */
}
Ejemplo n.º 5
0
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;
}
Ejemplo n.º 6
0
static void
ath5k_ani_raise_immunity(struct ath5k_hw *ah, struct ath5k_ani_state *as,
			 bool ofdm_trigger)
{
	int rssi = ewma_read(&ah->ah_beacon_rssi_avg);

	ATH5K_DBG_UNLIMIT(ah, ATH5K_DEBUG_ANI, "raise immunity (%s)",
		ofdm_trigger ? "ODFM" : "CCK");

	
	if (as->noise_imm_level < ATH5K_ANI_MAX_NOISE_IMM_LVL) {
		ath5k_ani_set_noise_immunity_level(ah, as->noise_imm_level + 1);
		return;
	}

	
	if (ofdm_trigger &&
	    as->spur_level < ah->ani_state.max_spur_level) {
		ath5k_ani_set_spur_immunity_level(ah, as->spur_level + 1);
		return;
	}

	
	if (ah->opmode == NL80211_IFTYPE_AP) {
		if (as->firstep_level < ATH5K_ANI_MAX_FIRSTEP_LVL)
			ath5k_ani_set_firstep_level(ah, as->firstep_level + 1);
		return;
	}

	


	if (rssi > ATH5K_ANI_RSSI_THR_HIGH) {
		ATH5K_DBG_UNLIMIT(ah, ATH5K_DEBUG_ANI,
				  "beacon RSSI high");
		if (ofdm_trigger && as->ofdm_weak_sig) {
			ath5k_ani_set_ofdm_weak_signal_detection(ah, false);
			ath5k_ani_set_spur_immunity_level(ah, 0);
			return;
		}
		
		if (as->firstep_level < ATH5K_ANI_MAX_FIRSTEP_LVL) {
			ath5k_ani_set_firstep_level(ah, as->firstep_level + 1);
			return;
		}
	} else if (rssi > ATH5K_ANI_RSSI_THR_LOW) {
		ATH5K_DBG_UNLIMIT(ah, ATH5K_DEBUG_ANI,
				  "beacon RSSI mid");
		if (ofdm_trigger && !as->ofdm_weak_sig)
			ath5k_ani_set_ofdm_weak_signal_detection(ah, true);
		if (as->firstep_level < ATH5K_ANI_MAX_FIRSTEP_LVL)
			ath5k_ani_set_firstep_level(ah, as->firstep_level + 1);
		return;
	} else if (ah->ah_current_channel->band == IEEE80211_BAND_2GHZ) {
		ATH5K_DBG_UNLIMIT(ah, ATH5K_DEBUG_ANI,
				  "beacon RSSI low, 2GHz");
		if (ofdm_trigger && as->ofdm_weak_sig)
			ath5k_ani_set_ofdm_weak_signal_detection(ah, false);
		if (as->firstep_level > 0)
			ath5k_ani_set_firstep_level(ah, 0);
		return;
	}

}