linux/drivers/net/wireless/ath/ath5k/ani.c

/*
 * Copyright (C) 2010 Bruno Randolf <[email protected]>
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

#define pr_fmt(fmt)

#include "ath5k.h"
#include "reg.h"
#include "debug.h"
#include "ani.h"

/**
 * DOC: Basic ANI Operation
 *
 * Adaptive Noise Immunity (ANI) controls five noise immunity parameters
 * depending on the amount of interference in the environment, increasing
 * or reducing sensitivity as necessary.
 *
 * The parameters are:
 *
 *   - "noise immunity"
 *
 *   - "spur immunity"
 *
 *   - "firstep level"
 *
 *   - "OFDM weak signal detection"
 *
 *   - "CCK weak signal detection"
 *
 * Basically we look at the amount of ODFM and CCK timing errors we get and then
 * raise or lower immunity accordingly by setting one or more of these
 * parameters.
 *
 * Newer chipsets have PHY error counters in hardware which will generate a MIB
 * interrupt when they overflow. Older hardware has too enable PHY error frames
 * by setting a RX flag and then count every single PHY error. When a specified
 * threshold of errors has been reached we will raise immunity.
 * Also we regularly check the amount of errors and lower or raise immunity as
 * necessary.
 */


/***********************\
* ANI parameter control *
\***********************/

/**
 * ath5k_ani_set_noise_immunity_level() - Set noise immunity level
 * @ah: The &struct ath5k_hw
 * @level: level between 0 and @ATH5K_ANI_MAX_NOISE_IMM_LVL
 */
void
ath5k_ani_set_noise_immunity_level(struct ath5k_hw *ah, int level)
{}

/**
 * ath5k_ani_set_spur_immunity_level() - Set spur immunity level
 * @ah: The &struct ath5k_hw
 * @level: level between 0 and @max_spur_level (the maximum level is dependent
 * on the chip revision).
 */
void
ath5k_ani_set_spur_immunity_level(struct ath5k_hw *ah, int level)
{}

/**
 * ath5k_ani_set_firstep_level() - Set "firstep" level
 * @ah: The &struct ath5k_hw
 * @level: level between 0 and @ATH5K_ANI_MAX_FIRSTEP_LVL
 */
void
ath5k_ani_set_firstep_level(struct ath5k_hw *ah, int level)
{}

/**
 * ath5k_ani_set_ofdm_weak_signal_detection() - Set OFDM weak signal detection
 * @ah: The &struct ath5k_hw
 * @on: turn on or off
 */
void
ath5k_ani_set_ofdm_weak_signal_detection(struct ath5k_hw *ah, bool on)
{}

/**
 * ath5k_ani_set_cck_weak_signal_detection() - Set CCK weak signal detection
 * @ah: The &struct ath5k_hw
 * @on: turn on or off
 */
void
ath5k_ani_set_cck_weak_signal_detection(struct ath5k_hw *ah, bool on)
{}


/***************\
* ANI algorithm *
\***************/

/**
 * 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)
{}

/**
 * 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)
{}

/**
 * ath5k_hw_ani_get_listen_time() - Update counters and return listening time
 * @ah: The &struct ath5k_hw
 * @as: The &struct ath5k_ani_state
 *
 * Return an approximation of the time spent "listening" in milliseconds (ms)
 * since the last call of this function.
 * Save a snapshot of the counter values for debugging/statistics.
 */
static int
ath5k_hw_ani_get_listen_time(struct ath5k_hw *ah, struct ath5k_ani_state *as)
{}

/**
 * ath5k_ani_save_and_clear_phy_errors() - Clear and save PHY error counters
 * @ah: The &struct ath5k_hw
 * @as: The &struct ath5k_ani_state
 *
 * Clear the PHY error counters as soon as possible, since this might be called
 * from a MIB interrupt and we want to make sure we don't get interrupted again.
 * Add the count of CCK and OFDM errors to our internal state, so it can be used
 * by the algorithm later.
 *
 * Will be called from interrupt and tasklet context.
 * Returns 0 if both counters are zero.
 */
static int
ath5k_ani_save_and_clear_phy_errors(struct ath5k_hw *ah,
				    struct ath5k_ani_state *as)
{}

/**
 * ath5k_ani_period_restart() - Restart ANI period
 * @as: The &struct ath5k_ani_state
 *
 * Just reset counters, so they are clear for the next "ani period".
 */
static void
ath5k_ani_period_restart(struct ath5k_ani_state *as)
{}

/**
 * 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)
{}


/*******************\
* Interrupt handler *
\*******************/

/**
 * ath5k_ani_mib_intr() - Interrupt handler for ANI MIB counters
 * @ah: The &struct ath5k_hw
 *
 * Just read & reset the registers quickly, so they don't generate more
 * interrupts, save the counters and schedule the tasklet to decide whether
 * to raise immunity or not.
 *
 * We just need to handle PHY error counters, ath5k_hw_update_mib_counters()
 * should take care of all "normal" MIB interrupts.
 */
void
ath5k_ani_mib_intr(struct ath5k_hw *ah)
{}

/**
 * ath5k_ani_phy_error_report - Used by older HW to report PHY errors
 *
 * @ah: The &struct ath5k_hw
 * @phyerr: One of enum ath5k_phy_error_code
 *
 * This is used by hardware without PHY error counters to report PHY errors
 * on a frame-by-frame basis, instead of the interrupt.
 */
void
ath5k_ani_phy_error_report(struct ath5k_hw *ah,
			   enum ath5k_phy_error_code phyerr)
{}


/****************\
* Initialization *
\****************/

/**
 * ath5k_enable_phy_err_counters() - Enable PHY error counters
 * @ah: The &struct ath5k_hw
 *
 * Enable PHY error counters for OFDM and CCK timing errors.
 */
static void
ath5k_enable_phy_err_counters(struct ath5k_hw *ah)
{}

/**
 * ath5k_disable_phy_err_counters() - Disable PHY error counters
 * @ah: The &struct ath5k_hw
 *
 * Disable PHY error counters for OFDM and CCK timing errors.
 */
static void
ath5k_disable_phy_err_counters(struct ath5k_hw *ah)
{}

/**
 * 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)
{}


/**************\
* Debug output *
\**************/

#ifdef CONFIG_ATH5K_DEBUG

/**
 * ath5k_ani_print_counters() - Print ANI counters
 * @ah: The &struct ath5k_hw
 *
 * Used for debugging ANI
 */
void
ath5k_ani_print_counters(struct ath5k_hw *ah)
{}

#endif