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

📄 ieee80211_scan.c.svn-base

📁 最新之atheros芯片driver source code, 基于linux操作系统,內含atheros芯片HAL全部代码
💻 SVN-BASE
📖 第 1 页 / 共 3 页
字号:
/*- * Copyright (c) 2002-2005 Sam Leffler, Errno Consulting * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in the *    documentation and/or other materials provided with the distribution. * 3. The name of the author may not be used to endorse or promote products *    derived from this software without specific prior written permission. * * Alternatively, this software may be distributed under the terms of the * GNU General Public License ("GPL") version 2 as published by the Free * Software Foundation. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, 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 DAMAGE. * * $Id$ */#ifndef EXPORT_SYMTAB#define	EXPORT_SYMTAB#endif/* * IEEE 802.11 scanning support. */#ifndef AUTOCONF_INCLUDED#include <linux/config.h>#endif#include <linux/version.h>#include <linux/module.h>#include <linux/skbuff.h>#include <linux/netdevice.h>#include <linux/etherdevice.h>#include <linux/random.h>#include <linux/interrupt.h>#include <linux/delay.h>#include "if_media.h"#include <net80211/ieee80211_var.h>#include <net80211/if_athproto.h>struct scan_state {	struct ieee80211_scan_state base;	/* public state */	u_int ss_iflags;			/* flags used internally */#define	ISCAN_MINDWELL 	0x0001			/* min dwell time reached */#define	ISCAN_DISCARD	0x0002			/* discard rx'd frames */#define	ISCAN_CANCEL	0x0004			/* cancel current scan */#define	ISCAN_START	0x0008			/* 1st time through next_scan */	unsigned long ss_chanmindwell;		/* min dwell on curchan */	unsigned long ss_scanend;		/* time scan must stop */	u_int ss_duration;			/* duration for next scan */	struct tasklet_struct ss_pwrsav;	/* sta ps ena tasklet */	struct timer_list ss_scan_timer;	/* scan timer */};#define	SCAN_PRIVATE(_ss)	((struct scan_state *)(_ss))/* * Amount of time to go off-channel during a background * scan.  This value should be large enough to catch most * APs but short enough that we can return on-channel * before our listen interval expires. * * XXX tunable * XXX check against configured listen interval */#define	IEEE80211_SCAN_OFFCHANNEL	msecs_to_jiffies(150)/* * Roaming-related defaults.  RSSI thresholds are as returned by the * driver (dBm).  Transmit rate thresholds are IEEE rate codes (i.e * .5M units). */#define	SCAN_VALID_DEFAULT		60	/* scan cache valid age (secs) */#define	ROAM_RSSI_11A_DEFAULT		9	/* rssi threshold for 11a bss */#define	ROAM_RSSI_11G_DEFAULT		9	/* rssi threshold for 11g bss */#define	ROAM_RSSI_11BONLY_DEFAULT	9	/* rssi threshold for 11b-only bss */#define	ROAM_RATE_11A_DEFAULT		2 * 24	/* tx rate threshold for 11a bss */#define	ROAM_RATE_11G_DEFAULT		2 * 9	/* tx rate threshold for 11g bss */#define	ROAM_RATE_11BONLY_DEFAULT	2 * 5	/* tx rate threshold for 11b-only bss */static void scan_restart_pwrsav(unsigned long);static void scan_next(unsigned long);voidieee80211_scan_attach(struct ieee80211com *ic){	struct scan_state *ss;	ic->ic_roaming = IEEE80211_ROAMING_AUTO;	MALLOC(ss, struct scan_state *, sizeof(struct scan_state),		M_80211_SCAN, M_NOWAIT | M_ZERO);	if (ss != NULL) {		init_timer(&ss->ss_scan_timer);		ss->ss_scan_timer.function = scan_next;		ss->ss_scan_timer.data = (unsigned long) ss;		tasklet_init(&ss->ss_pwrsav, scan_restart_pwrsav,			(unsigned long) ss);		ic->ic_scan = &ss->base;	} else		ic->ic_scan = NULL;}voidieee80211_scan_detach(struct ieee80211com *ic){	struct ieee80211_scan_state *ss = ic->ic_scan;	if (ss != NULL) {		del_timer(&SCAN_PRIVATE(ss)->ss_scan_timer);		tasklet_kill(&SCAN_PRIVATE(ss)->ss_pwrsav);		if (ss->ss_ops != NULL) {			ss->ss_ops->scan_detach(ss);			ss->ss_ops = NULL;		}		ic->ic_flags &= ~IEEE80211_F_SCAN;		ic->ic_scan = NULL;		FREE(SCAN_PRIVATE(ss), M_80211_SCAN);	}}voidieee80211_scan_vattach(struct ieee80211vap *vap){	vap->iv_bgscanidle = msecs_to_jiffies(IEEE80211_BGSCAN_IDLE_DEFAULT);	vap->iv_bgscanintvl = IEEE80211_BGSCAN_INTVAL_DEFAULT * HZ;	vap->iv_scanvalid = SCAN_VALID_DEFAULT * HZ;	vap->iv_roam.rssi11a = ROAM_RSSI_11A_DEFAULT;	vap->iv_roam.rssi11g = ROAM_RSSI_11G_DEFAULT;	vap->iv_roam.rssi11bOnly = ROAM_RSSI_11BONLY_DEFAULT;	vap->iv_roam.rate11a = ROAM_RATE_11A_DEFAULT;	vap->iv_roam.rate11g = ROAM_RATE_11G_DEFAULT;	vap->iv_roam.rate11bOnly = ROAM_RATE_11BONLY_DEFAULT;}voidieee80211_scan_vdetach(struct ieee80211vap *vap){	struct ieee80211com *ic = vap->iv_ic;	struct ieee80211_scan_state *ss = ic->ic_scan;	IEEE80211_LOCK_IRQ(ic);	if (ss->ss_vap == vap) {		if (ic->ic_flags & IEEE80211_F_SCAN) {			del_timer(&SCAN_PRIVATE(ss)->ss_scan_timer);			ic->ic_flags &= ~IEEE80211_F_SCAN;		}		if (ss->ss_ops != NULL) {			ss->ss_ops->scan_detach(ss);			ss->ss_ops = NULL;		}	}	IEEE80211_UNLOCK_IRQ(ic);}/* * Simple-minded scanner module support. */#define	IEEE80211_SCANNER_MAX	(IEEE80211_M_MONITOR+1)static const char *scan_modnames[IEEE80211_SCANNER_MAX] = {	[IEEE80211_M_IBSS]	= "wlan_scan_sta",	[IEEE80211_M_STA]	= "wlan_scan_sta",	[IEEE80211_M_AHDEMO]	= "wlan_scan_sta",	[IEEE80211_M_HOSTAP]	= "wlan_scan_ap",};static const struct ieee80211_scanner *scanners[IEEE80211_SCANNER_MAX];/* If try load is set, this function will attempt to automatically load the * requested module if it is not present. This is on operation that may sleep. * Therefore: * if !!tryload, then Context: process */const struct ieee80211_scanner *ieee80211_scanner_get(enum ieee80211_opmode mode, int tryload){	int err;	if (mode >= IEEE80211_SCANNER_MAX)		return NULL;	if (scan_modnames[mode] == NULL)		return NULL;	if (scanners[mode] == NULL && tryload) {		err = ieee80211_load_module(scan_modnames[mode]);		if (scanners[mode] == NULL || err)			printk(KERN_WARNING "unable to load %s\n", scan_modnames[mode]);	}	return scanners[mode];}EXPORT_SYMBOL(ieee80211_scanner_get);voidieee80211_scanner_register(enum ieee80211_opmode mode,	const struct ieee80211_scanner *scan){	if (mode >= IEEE80211_SCANNER_MAX)		return;	scanners[mode] = scan;}EXPORT_SYMBOL(ieee80211_scanner_register);voidieee80211_scanner_unregister(enum ieee80211_opmode mode,	const struct ieee80211_scanner *scan){	if (mode >= IEEE80211_SCANNER_MAX)		return;	if (scanners[mode] == scan)		scanners[mode] = NULL;}EXPORT_SYMBOL(ieee80211_scanner_unregister);voidieee80211_scanner_unregister_all(const struct ieee80211_scanner *scan){	int m;	for (m = 0; m < IEEE80211_SCANNER_MAX; m++)		if (scanners[m] == scan)			scanners[m] = NULL;}EXPORT_SYMBOL(ieee80211_scanner_unregister_all);static voidchange_channel(struct ieee80211com *ic,	struct ieee80211_channel *chan){	ic->ic_curchan = chan;	ic->ic_set_channel(ic);}static charchannel_type(const struct ieee80211_channel *c){	if (IEEE80211_IS_CHAN_ST(c))		return 'S';	if (IEEE80211_IS_CHAN_108A(c))		return 'T';	if (IEEE80211_IS_CHAN_108G(c))		return 'G';	if (IEEE80211_IS_CHAN_A(c))		return 'a';	if (IEEE80211_IS_CHAN_ANYG(c))		return 'g';	if (IEEE80211_IS_CHAN_B(c))		return 'b';	return 'f';}voidieee80211_scan_dump_channels(const struct ieee80211_scan_state *ss){	struct ieee80211com *ic = ss->ss_vap->iv_ic;	const char *sep;	int i;	sep = "";	for (i = ss->ss_next; i < ss->ss_last; i++) {		const struct ieee80211_channel *c = ss->ss_chans[i];		printk("%s%u%c", sep, ieee80211_chan2ieee(ic, c),			channel_type(c));		sep = ", ";	}}EXPORT_SYMBOL(ieee80211_scan_dump_channels);/* * Enable station power save mode and start/restart the scanning thread. */static voidscan_restart_pwrsav(unsigned long arg){	struct scan_state *ss = (struct scan_state *)arg;	struct ieee80211vap *vap = ss->base.ss_vap;	struct ieee80211com *ic = vap->iv_ic;	int delay;	ieee80211_sta_pwrsave(vap, 1);	/*	 * Use an initial 1ms delay to ensure the null	 * data frame has a chance to go out.	 * XXX: 1ms is a lot, better to trigger scan	 * on TX complete.	 */	delay = msecs_to_jiffies(1);	if (delay < 1)		delay = 1;	ic->ic_scan_start(ic);			/* notify driver */	ss->ss_scanend = jiffies + delay + ss->ss_duration;	ss->ss_iflags |= ISCAN_START;	mod_timer(&ss->ss_scan_timer, jiffies + delay);}/* * Start/restart scanning.  If we're operating in station mode * and associated notify the ap we're going into power save mode * and schedule a callback to initiate the work (where there's a * better context for doing the work).  Otherwise, start the scan * directly. */static intscan_restart(struct scan_state *ss, u_int duration){	struct ieee80211vap *vap = ss->base.ss_vap;	struct ieee80211com *ic = vap->iv_ic;	if (ss->base.ss_next == ss->base.ss_last) {		IEEE80211_DPRINTF(vap, IEEE80211_MSG_SCAN,			"%s: no channels to scan\n", __func__);		return 0;	} else {		if ((vap->iv_opmode == IEEE80211_M_STA) &&			(vap->iv_state == IEEE80211_S_RUN) &&			!(IEEE80211_VAP_IS_SLEEPING(vap))) {			/*			 * Initiate power save before going off-channel.			 * Note that we cannot do this directly because			 * of locking issues; instead we defer it to a			 * tasklet.			 */			ss->ss_duration = duration;			tasklet_schedule(&ss->ss_pwrsav);		} else {			ic->ic_scan_start(ic);		/* notify driver */			ss->ss_scanend = jiffies + duration;			ss->ss_iflags |= ISCAN_START;			mod_timer(&ss->ss_scan_timer, jiffies);		}		return 1;	}}static voidcopy_ssid(struct ieee80211vap *vap, struct ieee80211_scan_state *ss,	int nssid, const struct ieee80211_scan_ssid ssids[]){	if (nssid > IEEE80211_SCAN_MAX_SSID) {		/* XXX printk */		IEEE80211_DPRINTF(vap, IEEE80211_MSG_SCAN,			"%s: too many ssid %d, ignoring all of them\n",			__func__, nssid);		return;	}	memcpy(ss->ss_ssid, ssids, nssid * sizeof(ssids[0]));	ss->ss_nssid = nssid;}/* * Start a scan unless one is already going. */intieee80211_start_scan(struct ieee80211vap *vap, int flags, u_int duration,	u_int nssid, const struct ieee80211_scan_ssid ssids[]){	struct ieee80211com *ic = vap->iv_ic;	const struct ieee80211_scanner *scan;	struct ieee80211_scan_state *ss = ic->ic_scan;

⌨️ 快捷键说明

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