⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 if_ath_radar.c.svn-base

📁 最新之atheros芯片driver source code, 基于linux操作系统,內含atheros芯片HAL全部代码
💻 SVN-BASE
📖 第 1 页 / 共 4 页
字号:
/* * This software is distributed under the terms of the * GNU General Public License ("GPL") version 2 as published by the Free * Software Foundation. * * NO WARRANTY * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF * THE POSSIBILITY OF SUCH DAMAGES. * * $Id: if_ath_radar.c 2464 2007-06-15 22:51:56Z mtaylor $ */#include "opt_ah.h"#include "if_ath_debug.h"#ifndef AUTOCONF_INCLUDED#include <linux/config.h>#endif#include <linux/version.h>#include <linux/module.h>#include <linux/init.h>#include <linux/skbuff.h>#include <linux/netdevice.h>#include <linux/etherdevice.h>#include <linux/random.h>#include <linux/delay.h>#include <linux/cache.h>#include <linux/sysctl.h>#include <linux/proc_fs.h>#include <linux/if_arp.h>#include <linux/rtnetlink.h>#include <linux/time.h>#include <asm/uaccess.h>#include <linux/param.h>#include "if_ethersubr.h"	/* for ETHER_IS_MULTICAST */#include "if_media.h"#include "if_llc.h"#include <net80211/ieee80211_radiotap.h>#include <net80211/ieee80211_var.h>#include <net80211/ieee80211_monitor.h>#include <net80211/ieee80211_rate.h>#ifdef USE_HEADERLEN_RESV#include <net80211/if_llc.h>#endif#include "net80211/if_athproto.h"#include "if_athvar.h"#include "ah_desc.h"#include "ah_devid.h"		/* XXX to identify chipset */#ifdef ATH_PCI			/* PCI BUS */#include "if_ath_pci.h"#endif				/* PCI BUS */#ifdef ATH_AHB			/* AHB BUS */#include "if_ath_ahb.h"#endif				/* AHB BUS */#undef MAX#define MAX(a, b)  (((a) > (b)) ? (a) : (b))#undef MIN#define MIN(a, b)  (((a) < (b)) ? (a) : (b))#include "ah.h"#include "if_ath_hal.h"#ifdef ATH_TX99_DIAG#include "ath_tx99.h"#endif#include "ah_os.h"#include "if_ath_radar.h"#define sizetab(t) (sizeof(t)/sizeof(t[0]))#define nofloat_pct(_value, _pct) \	( (_value * (1000 + _pct)) / 1000 )struct radar_pattern_specification {	/* The name of the rule/specification (i.e. what did we detect) */	const char *name;	/* Interval MIN = 1000000 / FREQ - 2% 	 * (a.k.a. Pulse/Burst Repetition Interval) */	u_int32_t min_rep_int;	/* Interval MAX = 1000000 / FREQ + 2% 	 * (a.k.a. Pulse/Burst Repetition Interval) */	u_int32_t max_rep_int;	/* Do we adjust the min/max interval values dynamically 	 * based upon running mean interval? */	HAL_BOOL dyn_ints;	/* Fuzz factor dynamic matching, as unsigned integer percentage 	 * of variation (i.e. 2 for +/- 2% timing) */	u_int32_t fuzz_pct;	/* Match MIN (Minimum Pulse/Burst events required) */	u_int32_t min_pulse;	/* Match MIN duration (Minimum Pulse/Burst events 	 * required including missed) */	u_int32_t min_evts;	/* Match MAX duration (Maximum Pulse/Burst events 	 * required including missed) */	u_int32_t max_evts;	/* Maximum consecutive missing pulses */	u_int32_t max_consecutive_missing;	/* Maximum missing pulses */	u_int32_t max_missing;	/* Match on absolute distance to PRI/PRF midpoint */	HAL_BOOL match_midpoint;};static struct radar_pattern_specification radar_patterns[] = {#ifdef DFS_DOMAIN_ETSI	{"ETSI [ 200]", 4900, 5100, AH_FALSE, 20, 3, 4, 10, 4,  8, AH_TRUE},	{"ETSI [ 300]", 3267, 3399, AH_FALSE, 20, 3, 4, 10, 4,  6, AH_TRUE},	{"ETSI [ 500]", 1960, 2040, AH_FALSE, 20, 4, 4, 10, 4,  8, AH_TRUE},	{"ETSI [ 750]", 1307, 1359, AH_FALSE, 20, 5, 4, 15, 4, 13, AH_TRUE},	{"ETSI [ 800]", 1225, 1275, AH_FALSE, 20, 4, 4, 10, 4,  8, AH_TRUE},	{"ETSI [1000]",  980, 1020, AH_FALSE, 20, 4, 4, 10, 4,  8, AH_TRUE},	{"ETSI [1200]",  817,  849, AH_FALSE, 20, 5, 4, 15, 4, 13, AH_TRUE},	{"ETSI [1500]",  653,  679, AH_FALSE, 20, 5, 4, 15, 4,  6, AH_TRUE},	{"ETSI [1600]",  613,  637, AH_FALSE, 20, 5, 4, 15, 4,  7, AH_TRUE},	{"ETSI [2000]",  490,  510, AH_FALSE, 20, 7, 4, 20, 4, 10, AH_TRUE},	{"ETSI [2300]",  426,  442, AH_FALSE, 20, 9, 4, 25, 6, 20, AH_TRUE},	{"ETSI [3000]",  327,  339, AH_FALSE, 20, 7, 4, 20, 5, 20, AH_TRUE},	{"ETSI [3500]",  280,  290, AH_FALSE, 20, 9, 4, 25, 2, 20, AH_TRUE},	{"ETSI [4000]",  245,  255, AH_FALSE, 20, 7, 4, 20, 5, 20, AH_TRUE},#endif#ifdef DFS_DOMAIN_FCC	{"FCC [1,1399-1714]", 1399, 1714, AH_TRUE, 10, 5, 10, 18, 4,  6, AH_FALSE},	{"FCC [2,147-235]",    147,  235, AH_TRUE, 10, 8, 10, 29, 6, 12, AH_FALSE},	{"FCC [3-4,196-273]",  196,  273, AH_TRUE, 10, 8,  8, 18, 2, 16, AH_FALSE},	{"FCC [3-4,275-352]",  275,  352, AH_TRUE, 10, 8,  8, 18, 2, 16, AH_FALSE},	{"FCC [3-4,354-431]",  354,  431, AH_TRUE, 10, 8,  8, 18, 2, 16, AH_FALSE},	{"FCC [3-4,433-510]",  433,  510, AH_TRUE, 10, 8,  8, 18, 2, 16, AH_FALSE},	{"FCC [3-4,235-313]",  235,  313, AH_TRUE, 10, 8,  8, 18, 2, 16, AH_FALSE},	{"FCC [3-4,314-392]",  314,  392, AH_TRUE, 10, 8,  8, 18, 2, 16, AH_FALSE},	{"FCC [3-4,393-471]",  393,  471, AH_TRUE, 10, 8,  8, 18, 2, 16, AH_FALSE}#endif};#ifdef AR_DEBUGstatic u_int32_t interval_to_frequency(u_int32_t pri);#endif /* AR_DEBUG *//* Returns true if radar detection is enabled. */int ath_radar_is_enabled(struct ath_softc *sc){	struct ath_hal *ah = sc->sc_ah;	if (ar_device(sc->devid) >= 5211)		return ((OS_REG_READ(ah, AR5K_AR5212_PHY_ERR_FIL) & 			 AR5K_AR5212_PHY_ERR_FIL_RADAR) && 			(sc->sc_imask & HAL_INT_RXPHY) && 			(ath_hal_intrget(ah) & HAL_INT_RXPHY));	else		return ((sc->sc_imask & HAL_INT_RXPHY) && 			(ath_hal_intrget(ah) & HAL_INT_RXPHY));	return 0;}/* Read the radar pulse detection parameters. */void ath_radar_get_params(struct ath_softc *sc, RADAR_PARAM *rp){	u_int32_t radar = ath_reg_read(sc, AR5K_PHY_RADAR);	rp->rp_fir_filter_output_power_thr = 		(radar & AR5K_PHY_RADAR_FIRPWROUTTHR) >> 		AR5K_PHY_RADAR_FIRPWROUTTHR_S;	rp->rp_radar_rssi_thr = 		(radar & AR5K_PHY_RADAR_PULSERSSITHR) >> 		AR5K_PHY_RADAR_PULSERSSITHR_S;	rp->rp_pulse_height_thr = 		(radar & AR5K_PHY_RADAR_PULSEHEIGHTTHR) >> 		AR5K_PHY_RADAR_PULSEHEIGHTTHR_S;	rp->rp_pulse_rssi_thr = 		(radar & AR5K_PHY_RADAR_RADARRSSITHR) >> 		AR5K_PHY_RADAR_RADARRSSITHR_S;	rp->rp_inband_thr = 		(radar & AR5K_PHY_RADAR_INBANDTHR) >> 		AR5K_PHY_RADAR_INBANDTHR_S;}/* Update the radar pulse detection parameters.  * If rp is NULL, defaults are used for all fields. * If any member of rp is set to RADAR_PARAM_USE_DEFAULT, the default * is used for that field. */void ath_radar_set_params(struct ath_softc *sc, RADAR_PARAM *rp){#define BUILD_PHY_RADAR_FIELD(_MASK,_SHIFT,_FIELD) \	((NULL == rp || (rp->_FIELD == RADAR_PARAM_USE_DEFAULT)) ? \		((AR5K_PHY_RADAR_ENABLED_AR5213 & (_MASK))) : \		((rp->_FIELD << (_SHIFT)) & (_MASK)))	ath_reg_write(sc, AR5K_PHY_RADAR,	    BUILD_PHY_RADAR_FIELD(AR5K_PHY_RADAR_FIRPWROUTTHR,		AR5K_PHY_RADAR_FIRPWROUTTHR_S,		rp_fir_filter_output_power_thr) |	    BUILD_PHY_RADAR_FIELD(AR5K_PHY_RADAR_RADARRSSITHR,		AR5K_PHY_RADAR_RADARRSSITHR_S,		rp_pulse_rssi_thr) |	    BUILD_PHY_RADAR_FIELD(AR5K_PHY_RADAR_PULSEHEIGHTTHR,		AR5K_PHY_RADAR_PULSEHEIGHTTHR_S,		rp_pulse_height_thr) |	    BUILD_PHY_RADAR_FIELD(AR5K_PHY_RADAR_PULSERSSITHR,		AR5K_PHY_RADAR_PULSERSSITHR_S, rp_radar_rssi_thr) | 		      BUILD_PHY_RADAR_FIELD(AR5K_PHY_RADAR_INBANDTHR, 					    AR5K_PHY_RADAR_INBANDTHR_S, 					    rp_inband_thr)	    );#undef BUILD_PHY_RADAR_FIELD}/* This is called on channel change to enable radar detection for 5211+ chips.   * NOTE: AR5210 doesn't have radar pulse detection support. */int ath_radar_update(struct ath_softc *sc){	struct ath_hal *ah = sc->sc_ah;	struct ieee80211com *ic = &sc->sc_ic;	int required = 0;	/* Do not attempt to change radar state when bg scanning is	 * the cause */	if (ic->ic_flags & IEEE80211_F_SCAN)		return 1;	/* Update the DFS flags (as a sanity check) */	if (ath_radar_correct_dfs_flags(sc, &sc->sc_curchan))		DPRINTF(sc, ATH_DEBUG_DOTH, "%s: %s: channel required "			"corrections to private flags.\n",			SC_DEV_NAME(sc), __func__);	required = ath_radar_is_dfs_required(sc, &sc->sc_curchan) &&		    (ic->ic_flags & IEEE80211_F_DOTH);	/* configure radar pulse detector register using default values, but do	 * not toggle the enable bit.  XXX: allow tweaking?? */	ath_radar_set_params(sc, NULL);	if (ar_device(sc->devid) >= 5211) {		HAL_INT old_ier = ath_hal_intrget(ah);		HAL_INT new_ier = old_ier;		unsigned int old_radar = OS_REG_READ(ah, AR5K_PHY_RADAR);		unsigned int old_filter = 			OS_REG_READ(ah, AR5K_AR5212_PHY_ERR_FIL);		unsigned int old_rxfilt = ath_hal_getrxfilter(ah);		unsigned int old_mask = sc->sc_imask;		unsigned int new_radar = old_radar;		unsigned int new_filter = old_filter;		unsigned int new_mask = old_mask;		unsigned int new_rxfilt = old_rxfilt;		ath_hal_intrset(ah, old_ier & ~HAL_INT_GLOBAL);		if (required) {			new_radar |= AR5K_PHY_RADAR_ENABLE;			new_filter |= AR5K_AR5212_PHY_ERR_FIL_RADAR;			new_rxfilt |= (HAL_RX_FILTER_PHYERR |				       HAL_RX_FILTER_PHYRADAR);			new_mask |= HAL_INT_RXPHY;			new_ier |= HAL_INT_RXPHY;		} else {			new_radar &= ~AR5K_PHY_RADAR_ENABLE;			new_filter &= ~AR5K_AR5212_PHY_ERR_FIL_RADAR;			new_rxfilt &= ~HAL_RX_FILTER_PHYRADAR;			new_mask &= ~HAL_INT_RXPHY;			new_ier &= ~HAL_INT_RXPHY;		}		if (old_filter != new_filter)			OS_REG_WRITE(ah, AR5K_AR5212_PHY_ERR_FIL, new_filter);		if (old_radar != new_radar)			OS_REG_WRITE(ah, AR5K_PHY_RADAR, new_radar);		if (old_rxfilt != new_rxfilt)			ath_hal_setrxfilter(ah, new_rxfilt);		sc->sc_imask = new_mask;		if (DFLAG_ISSET(sc, ATH_DEBUG_DOTH) && 		    ((old_radar != new_radar) || 		     (old_filter != new_filter) || 		     (old_rxfilt != new_rxfilt) || 		     (old_mask != new_mask) || 		     (old_ier != new_ier))) {			DPRINTF(sc, ATH_DEBUG_DOTH, 				"%s: %s: Radar detection %s.\n", SC_DEV_NAME(sc),				__func__, required ? "enabled" : "disabled");		}		ath_hal_intrset(ah, new_ier);	}	return (required == ath_radar_is_enabled(sc));}/* Update channel's DFS flags based upon whether DFS is required.  Return * true if the value was repaired. */int ath_radar_correct_dfs_flags(struct ath_softc *sc, HAL_CHANNEL *hchan){	u_int32_t old_channelFlags = hchan->channelFlags;	u_int32_t old_privFlags = hchan->privFlags;	if (ath_radar_is_dfs_required(sc, hchan)) {		hchan->channelFlags |= CHANNEL_PASSIVE;		hchan->privFlags |= CHANNEL_DFS;	} else {		hchan->channelFlags &= ~CHANNEL_PASSIVE;		hchan->privFlags &= ~CHANNEL_DFS;	}	return ((old_privFlags != hchan->privFlags) ||		(old_channelFlags != hchan->channelFlags));}/* Returns true if DFS is required for the regulatory domain, country and  * combination in use.  * XXX: Need to add regulatory rules in here.  This is too conservative! */int ath_radar_is_dfs_required(struct ath_softc *sc, HAL_CHANNEL *hchan){	/* For FCC: 5250 to 5350MHz (channel 52 to 60) and for Europe added 	 * 5470 to 5725 MHz (channel 100 to 140). 	 * Being conservative, go with the entire band from 5250-5725 MHz. */	return ((hchan->channel >= 5250) && (hchan->channel <= 5725)) ? 1 : 0;}static struct ath_rp *pulse_head(struct ath_softc *sc){	return list_entry(sc->sc_rp_list.next, 			  struct ath_rp, list);}static struct ath_rp *pulse_tail(struct ath_softc *sc){	return list_entry(sc->sc_rp_list.prev, 			  struct ath_rp, list);}static struct ath_rp *pulse_prev(struct ath_rp *pulse){	return list_entry(pulse->list.prev, 			  struct ath_rp, list);}#define CR_FALLTHROUGH		0#define CR_NULL			1#define CR_EXCESS_INTERVALS	2#define CR_INTERVALS 		3#define CR_EXCESS_DURATION	4#define CR_DURATION		5#define CR_PULSES		6#define CR_MISSES		7#define CR_MIDPOINT_A		8#define CR_MIDPOINT_B		9#define CR_MIDPOINT_C		10#define CR_NOISE		11#define MR_MATCH 		0#define MR_FAIL_MIN_INTERVALS	1#define MR_FAIL_REQD_MATCHES	2#define MR_FAIL_MAX_MISSES	3#define MR_FAIL_MIN_PERIOD	4#define MR_FAIL_MAX_PERIOD	5#ifdef AR_DEBUGstatic const char *get_match_result_desc(u_int32_t code){	switch (code) {	case MR_MATCH:		return "MATCH";	case MR_FAIL_MIN_INTERVALS:		return "TOO-SHORT";	case MR_FAIL_REQD_MATCHES:		return "TOO-FEW";	case MR_FAIL_MAX_MISSES:		return "TOO-LOSSY";	case MR_FAIL_MIN_PERIOD:		return "PRI<MIN";	case MR_FAIL_MAX_PERIOD:		return "PRI>MAX";	default:		return "unknown";	}}#endif /* AR_DEBUG */static int32_t match_radar(	u_int32_t matched, 	u_int32_t missed, 	u_int32_t mean_period, 	u_int32_t noise,	u_int32_t min_evts,	u_int32_t max_evts,	u_int32_t min_rep_int,	u_int32_t max_rep_int,	u_int32_t min_pulse,	u_int32_t max_misses){	/* Not a match: insufficient overall burst length */	if ( (matched + missed) < min_evts)		return MR_FAIL_MIN_INTERVALS;	/* Not a match: insufficient match count */	if (matched < min_pulse)		return MR_FAIL_REQD_MATCHES;	/* Not a match: too many missies */	if (missed > max_misses)		return MR_FAIL_MAX_MISSES;	/* Not a match, PRI out of range */	if (mean_period < min_rep_int)		return MR_FAIL_MIN_PERIOD;	/* Not a match, PRI out of range */	if (mean_period > max_rep_int) 		return MR_FAIL_MAX_PERIOD;	return MR_MATCH;}static int32_t compare_radar_matches(	int32_t a_matched, 	int32_t a_missed, 	int32_t a_mean_period, 	int32_t a_noise,	int32_t a_min_evts,	int32_t a_max_evts,	int32_t a_min_rep_int,	int32_t a_max_rep_int,	int32_t a_min_pulse,

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -