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

📄 ieee80211.c.svn-base

📁 最新之atheros芯片driver source code, 基于linux操作系统,內含atheros芯片HAL全部代码
💻 SVN-BASE
📖 第 1 页 / 共 4 页
字号:
		vap->iv_ath_cap &= ~IEEE80211_ATHC_TURBOP;		if ((vap->iv_flags & IEEE80211_VAP_XR) == 0)			vap->iv_ath_cap &= ~IEEE80211_ATHC_XR;		break;	case IEEE80211_M_MONITOR:		vap->iv_caps |= IEEE80211_C_MONITOR;		vap->iv_ath_cap &= ~(IEEE80211_ATHC_XR | IEEE80211_ATHC_TURBOP);		break;	case IEEE80211_M_WDS:		vap->iv_caps |= IEEE80211_C_WDS;		vap->iv_ath_cap &= ~(IEEE80211_ATHC_XR | IEEE80211_ATHC_TURBOP);		vap->iv_flags_ext |= IEEE80211_FEXT_WDS;		break;	}	vap->iv_opmode = opmode;	IEEE80211_INIT_TQUEUE(&vap->iv_stajoin1tq, ieee80211_sta_join1_tasklet, vap);	vap->iv_chanchange_count = 0;	/* Enable various functionality by default, if we're capable. */#ifdef ATH_WME	/* Not yet the default */	if (vap->iv_caps & IEEE80211_C_WME)		vap->iv_flags |= IEEE80211_F_WME;#endif	if (vap->iv_caps & IEEE80211_C_FF)		vap->iv_flags |= IEEE80211_F_FF;	/* NB: Background scanning only makes sense for station mode right now */	if (ic->ic_opmode == IEEE80211_M_STA &&	    (vap->iv_caps & IEEE80211_C_BGSCAN))		vap->iv_flags |= IEEE80211_F_BGSCAN;	vap->iv_dtim_period = IEEE80211_DTIM_DEFAULT;	vap->iv_des_chan = IEEE80211_CHAN_ANYC;	/* any channel is OK */	vap->iv_monitor_crc_errors = 0;	vap->iv_monitor_phy_errors = 0;	IEEE80211_ADDR_COPY(vap->iv_myaddr, ic->ic_myaddr);	IEEE80211_ADDR_COPY(vap->iv_bssid, ic->ic_myaddr);	/* NB: Defer setting dev_addr so driver can override */	ieee80211_crypto_vattach(vap);	ieee80211_node_vattach(vap);	ieee80211_power_vattach(vap);	ieee80211_proto_vattach(vap);	ieee80211_scan_vattach(vap);	ieee80211_vlan_vattach(vap);	ieee80211_ioctl_vattach(vap);	return 1;#undef IEEE80211_C_OPMODE}EXPORT_SYMBOL(ieee80211_vap_setup);intieee80211_vap_attach(struct ieee80211vap *vap,	ifm_change_cb_t media_change, ifm_stat_cb_t media_status){	struct net_device *dev = vap->iv_dev;	struct ieee80211com *ic = vap->iv_ic;	struct ifmediareq imr;	ieee80211_node_latevattach(vap);	/* XXX: move into vattach */	ieee80211_power_latevattach(vap);	/* XXX: move into vattach */	memset(vap->wds_mac, 0x00, IEEE80211_ADDR_LEN);	(void) ieee80211_media_setup(ic, &vap->iv_media, vap->iv_caps,				     media_change, media_status);	ieee80211_media_status(dev, &imr);	ifmedia_set(&vap->iv_media, imr.ifm_active);	IEEE80211_LOCK_IRQ(ic);	TAILQ_INSERT_TAIL(&ic->ic_vaps, vap, iv_next);	IEEE80211_UNLOCK_IRQ(ic);	IEEE80211_ADDR_COPY(dev->dev_addr, vap->iv_myaddr);#ifdef ATH_SUPERG_XR	/* Do not register XR VAP device with OS. */	if (vap->iv_flags & IEEE80211_F_XR)		return 0;#endif	ieee80211_scanner_get(vap->iv_opmode, 1);	/* NB: rtnl_lock is held on entry, so don't use register_netdev */	if (register_netdevice(dev)) {		printk(KERN_ERR "%s: unable to register device\n", dev->name);		return 0;	}		/* SysFS needs to be initialised after the device, as it uses the 	 * device koject */	ieee80211_virtfs_latevattach(vap);	return 1;}EXPORT_SYMBOL(ieee80211_vap_attach);voidieee80211_vap_detach(struct ieee80211vap *vap){	struct ieee80211com *ic = vap->iv_ic;	struct net_device *dev = vap->iv_dev;	IEEE80211_CANCEL_TQUEUE(&vap->iv_stajoin1tq);	IEEE80211_LOCK_IRQ(ic);	TAILQ_REMOVE(&ic->ic_vaps, vap, iv_next);	if (TAILQ_EMPTY(&ic->ic_vaps))		/* reset to supported mode */		ic->ic_opmode = IEEE80211_M_STA;	IEEE80211_UNLOCK_IRQ(ic);	ifmedia_removeall(&vap->iv_media);	ieee80211_virtfs_vdetach(vap);	ieee80211_proc_cleanup(vap);	ieee80211_ioctl_vdetach(vap);	ieee80211_vlan_vdetach(vap);	ieee80211_scan_vdetach(vap);	ieee80211_proto_vdetach(vap);	ieee80211_crypto_vdetach(vap);	ieee80211_power_vdetach(vap);	ieee80211_node_vdetach(vap);#ifdef ATH_SUPERG_XR	/* XR VAP is not registered. */	if (!(vap->iv_flags & IEEE80211_F_XR))#endif	/* NB: rtnl_lock is held on entry so don't use unregister_netdev */	unregister_netdevice(dev);}EXPORT_SYMBOL(ieee80211_vap_detach);/* * Convert MHz frequency to IEEE channel number. */u_intieee80211_mhz2ieee(u_int freq, u_int flags){	if (flags & IEEE80211_CHAN_2GHZ) {	/* 2GHz band */		if (freq == 2484)		/* Japan */			return 14;		if ((freq >= 2412) && (freq < 2484)) /* don't number non-IEEE channels */			return (freq - 2407) / 5;		return 0;	} else if (flags & IEEE80211_CHAN_5GHZ)	{	/* 5Ghz band */		if ((freq >= 5150) && (freq <= 5825))	/* don't number non-IEEE channels */			return (freq - 5000) / 5;		return 0;	} else {		/* Something is fishy, don't do anything */		return 0;	}}EXPORT_SYMBOL(ieee80211_mhz2ieee);/* * Convert channel to IEEE channel number. */u_intieee80211_chan2ieee(struct ieee80211com *ic, const struct ieee80211_channel *c){	if (c == NULL) {		if_printf(ic->ic_dev, "invalid channel (NULL)\n");		return 0;		/* XXX */	}	return (c == IEEE80211_CHAN_ANYC ?  IEEE80211_CHAN_ANY : c->ic_ieee);}EXPORT_SYMBOL(ieee80211_chan2ieee);/* * Convert IEEE channel number to MHz frequency. */u_intieee80211_ieee2mhz(u_int chan, u_int flags){	if (flags & IEEE80211_CHAN_2GHZ) {	/* 2GHz band */		if (chan == 14)			return 2484;		if (chan < 14)			return 2407 + chan * 5;		else			return 2512 + ((chan - 15) * 20);	} else if (flags & IEEE80211_CHAN_5GHZ) /* 5Ghz band */		return 5000 + (chan * 5);	else {					/* either, guess */		if (chan == 14)			return 2484;		if (chan < 14)			/* 0-13 */			return 2407 + chan * 5;		if (chan < 27)			/* 15-26 */			return 2512 + ((chan - 15) * 20);		return 5000 + (chan * 5);	}}EXPORT_SYMBOL(ieee80211_ieee2mhz);/* * Locate a channel given a frequency+flags.  We cache * the previous lookup to optimize swithing between two * channels--as happens with dynamic turbo. */struct ieee80211_channel *ieee80211_find_channel(struct ieee80211com *ic, int freq, int flags){	struct ieee80211_channel *c;	int i;	/* Brute force search */	for (i = 0; i < ic->ic_nchans; i++) {		c = &ic->ic_channels[i];		if (c->ic_freq == freq &&		    (flags == 0 || 		     (c->ic_flags & IEEE80211_CHAN_ALLTURBO) == flags))			return c;	}	return NULL;}EXPORT_SYMBOL(ieee80211_find_channel);/* * Setup the media data structures according to the channel and * rate tables.  This must be called by the driver after * ieee80211_attach and before most anything else. */intieee80211_media_setup(struct ieee80211com *ic,	struct ifmedia *media, u_int32_t caps,	ifm_change_cb_t media_change, ifm_stat_cb_t media_stat){#define	ADD(_media, _s, _o) \	ifmedia_add(_media, IFM_MAKEWORD(IFM_IEEE80211, (_s), (_o), 0), 0, NULL)	int i, j, mode, rate, maxrate, mword, mopt, r;	struct ieee80211_rateset *rs;	struct ieee80211_rateset allrates;	/* Fill in media characteristics. */	ifmedia_init(media, 0, media_change, media_stat);	maxrate = 0;	memset(&allrates, 0, sizeof(allrates));	for (mode = IEEE80211_MODE_AUTO; mode < IEEE80211_MODE_MAX; mode++) {		static const u_int mopts[] = {			IFM_AUTO,			IFM_IEEE80211_11A,			IFM_IEEE80211_11B,			IFM_IEEE80211_11G,			IFM_IEEE80211_FH,			IFM_IEEE80211_11A | IFM_IEEE80211_TURBO,			IFM_IEEE80211_11G | IFM_IEEE80211_TURBO,		};		if ((ic->ic_modecaps & (1 << mode)) == 0)			continue;		mopt = mopts[mode];		ADD(media, IFM_AUTO, mopt);	/* e.g. 11a auto */		if (caps & IEEE80211_C_IBSS)			ADD(media, IFM_AUTO, mopt | IFM_IEEE80211_ADHOC);		if (caps & IEEE80211_C_HOSTAP)			ADD(media, IFM_AUTO, mopt | IFM_IEEE80211_HOSTAP);		if (caps & IEEE80211_C_AHDEMO)			ADD(media, IFM_AUTO, mopt | IFM_IEEE80211_ADHOC | IFM_FLAG0);		if (caps & IEEE80211_C_MONITOR)			ADD(media, IFM_AUTO, mopt | IFM_IEEE80211_MONITOR);		if (caps & IEEE80211_C_WDS)			ADD(media, IFM_AUTO, mopt | IFM_IEEE80211_WDS);		if (mode == IEEE80211_MODE_AUTO)			continue;		rs = &ic->ic_sup_rates[mode];		for (i = 0; i < rs->rs_nrates; i++) {			rate = rs->rs_rates[i];			mword = ieee80211_rate2media(ic, rate, mode);			if (mword == 0)				continue;			ADD(media, mword, mopt);			if (caps & IEEE80211_C_IBSS)				ADD(media, mword, mopt | IFM_IEEE80211_ADHOC);			if (caps & IEEE80211_C_HOSTAP)				ADD(media, mword, mopt | IFM_IEEE80211_HOSTAP);			if (caps & IEEE80211_C_AHDEMO)				ADD(media, mword, mopt | IFM_IEEE80211_ADHOC | IFM_FLAG0);			if (caps & IEEE80211_C_MONITOR)				ADD(media, mword, mopt | IFM_IEEE80211_MONITOR);			if (caps & IEEE80211_C_WDS)				ADD(media, mword, mopt | IFM_IEEE80211_WDS);			/* Add rate to the collection of all rates. */			r = rate & IEEE80211_RATE_VAL;			for (j = 0; j < allrates.rs_nrates; j++)				if (allrates.rs_rates[j] == r)					break;			if (j == allrates.rs_nrates) {				/* Unique, add to the set */				allrates.rs_rates[j] = r;				allrates.rs_nrates++;			}			rate = (rate & IEEE80211_RATE_VAL) / 2;			if (rate > maxrate)				maxrate = rate;		}	}	for (i = 0; i < allrates.rs_nrates; i++) {		mword = ieee80211_rate2media(ic, allrates.rs_rates[i],				IEEE80211_MODE_AUTO);		if (mword == 0)			continue;		mword = IFM_SUBTYPE(mword);	/* remove media options */		ADD(media, mword, 0);		if (caps & IEEE80211_C_IBSS)			ADD(media, mword, IFM_IEEE80211_ADHOC);		if (caps & IEEE80211_C_HOSTAP)			ADD(media, mword, IFM_IEEE80211_HOSTAP);		if (caps & IEEE80211_C_AHDEMO)			ADD(media, mword, IFM_IEEE80211_ADHOC | IFM_FLAG0);		if (caps & IEEE80211_C_MONITOR)			ADD(media, mword, IFM_IEEE80211_MONITOR);		if (caps & IEEE80211_C_WDS)			ADD(media, mword, IFM_IEEE80211_WDS);	}	return maxrate;#undef ADD}/* * Perform the DFS action (channel switch) using scan cache or a randomly * chosen channel. The choice of the random channel is done in * ieee80211_scan_dfs_action(). * * This was moved out of ieee80211_mark_dfs(), because the same functionality * is used also in ieee80211_ioctl_chanswitch(). */voidieee80211_dfs_action(struct ieee80211com *ic) {	struct ieee80211vap *vap;	/* Get an AP mode VAP */	TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next) {		if (vap->iv_state == IEEE80211_S_RUN) {			break;		}	}	if (vap == NULL) {		/*		 * No running VAP was found, check		 * if any one is scanning.		 */		TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next) {			if (vap->iv_state == IEEE80211_S_SCAN) {				break;			}		}		/* No running/scanning VAP was found, so they're all in		 * INIT state, no channel change needed. */		if (vap == NULL)			return;		/* Is it really Scanning */		/* XXX: Race condition? */		if (ic->ic_flags & IEEE80211_F_SCAN)			return;		/* It is not scanning, but waiting for ath driver to move the 		 * vap to RUN. */	}	/* Check the scan results using only cached results */	if (!(ieee80211_check_scan(vap, IEEE80211_SCAN_NOSSID |					IEEE80211_SCAN_KEEPMODE |					IEEE80211_SCAN_USECACHE, 0,				   vap->iv_des_nssid, vap->iv_des_ssid,				   ieee80211_scan_dfs_action))) {		/* No channel was found, so call the scan action with no		 * result. */		ieee80211_scan_dfs_action(vap, NULL);	}}voidieee80211_expire_excl_restrictions(struct ieee80211com *ic){	struct ieee80211_channel *c  = NULL;	struct net_device *dev = ic->ic_dev;	struct timeval tv_now;	int i;	do_gettimeofday(&tv_now);	for (i = 0; i < ic->ic_nchans; i++) {		c = &ic->ic_channels[i];		if (c->ic_flags & IEEE80211_CHAN_RADAR) {			if (timeval_compare(&ic->ic_chan_non_occupy[i],					    &tv_now) < 0) {				if_printf(dev,					  "Returning channel %3d (%4d MHz) "					  "radar avoidance marker expired.  "					  "Channel now available again. -- "					  "Time: %10ld.%06ld\n",					  c->ic_ieee, c->ic_freq, tv_now.tv_sec,					  tv_now.tv_usec);				c->ic_flags &= ~IEEE80211_CHAN_RADAR;			} else {				if_printf(dev,					  "Channel %3d (%4d MHz) is still "					  "marked for radar.  Channel will "					  "become usable in %u seconds at "					  "Time: %10ld.%06ld\n",					  c->ic_ieee, c->ic_freq,					  ic->ic_chan_non_occupy[i].tv_sec - 					   tv_now.tv_sec,					  ic->ic_chan_non_occupy[i].tv_sec,					  ic->ic_chan_non_occupy[i].tv_usec);			}		}	}}EXPORT_SYMBOL(ieee80211_expire_excl_restrictions);/* Update the Non-Occupancy Period timer with the first Non-Occupancy Period * that will expire */static voidieee80211_update_dfs_excl_timer(struct ieee80211com *ic){	struct ieee80211_channel * chan;	struct timeval tv_now, tv_next;	int i;	unsigned long jiffies_tmp;	do_gettimeofday(&tv_now);	jiffies_tmp = jiffies;	tv_next.tv_sec = 0;	tv_next.tv_usec = 0;	for (i = 0; i < ic->ic_nchans; i++) {		chan = &ic->ic_channels[i];		if (chan->ic_flags & IEEE80211_CHAN_RADAR) {			if ((tv_next.tv_sec == 0) &&			    (tv_next.tv_usec == 0)) {				tv_next = ic->ic_chan_non_occupy[i];			}			if (timeval_compare(&ic->ic_chan_non_occupy[i],					    &tv_next) < 0) {				tv_next = ic->ic_chan_non_occupy[i];			}		}	}	if ((tv_next.tv_sec == 0) &&	    (tv_next.tv_usec == 0)) {		del_timer(&ic->ic_dfs_excl_timer);	} else {		mod_timer(&ic->ic_dfs_excl_timer,			  jiffies_tmp + 			  (tv_next.tv_sec - tv_now.tv_sec + 1) * HZ);	}}/* Periodically expire radar avoidance marks. */static voidieee80211_expire_dfs_excl_timer(unsigned long data){	struct ieee80211com *ic = (struct ieee80211com *)data;	struct ieee80211vap *vap;	printk(KERN_INFO "%s: %s: expiring Non-Occupancy Period\n", 			DEV_NAME(ic->ic_dev), __func__);	if (ic->ic_flags_ext & IEEE80211_FEXT_MARKDFS) {		/* Make sure there are no channels that have just become 		 * available. */		ieee80211_expire_excl_restrictions(ic);		/* Go through and clear any interference flag we have, if we		 * just got it cleared up for us */		TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next) {		  /* We need to check for the special value		     IEEE80211_CHAN_ANYC before using vap->iv_des_chan		     since it will cause a kernel panic */			if ((vap->iv_state == IEEE80211_S_RUN) &&			    ((vap->iv_opmode == IEEE80211_M_HOSTAP) ||			     (vap->iv_opmode == IEEE80211_M_IBSS)) &&			    /* Operating on channel other than desired. */			    (vap->iv_des_chan != IEEE80211_CHAN_ANYC) &&			    (vap->iv_des_chan->ic_freq > 0) &&			    (vap->iv_des_chan->ic_freq !=

⌨️ 快捷键说明

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