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

📄 ieee80211.c

📁 madwifi上的atheros无线网卡驱动源码
💻 C
📖 第 1 页 / 共 4 页
字号:
	vap->iv_dev = dev;			/* back pointer */#ifdef ATH_SUPERG_XR	/*	 * setup XR vap specific flags.	 * link the XR vap to its normal val.	 */	if (flags & IEEE80211_VAP_XR) {		struct ieee80211vap *vapparent = NULL;		vap->iv_unit = -1;		vap->iv_flags = ic->ic_flags | IEEE80211_F_XR;	/* propagate common flags and add XR flag */		vap->iv_flags_ext = ic->ic_flags_ext;		TAILQ_FOREACH(vapparent, &ic->ic_vaps, iv_next)			if (vapparent->iv_unit == unit)				break;		vap->iv_xrvap = vapparent;		vap->iv_ath_cap = vapparent->iv_ath_cap;		/* Default multicast rate to lowest possible 256 Kbps */		vap->iv_mcast_rate = 256;	} else {		vap->iv_unit = unit;		vap->iv_flags = ic->ic_flags;		/* propagate common flags */		vap->iv_flags_ext = ic->ic_flags_ext;		vap->iv_xrvap = NULL;		vap->iv_ath_cap = ic->ic_ath_cap;		/* Default Multicast traffic to lowest rate of 1 Mbps*/		vap->iv_mcast_rate = 1000;	}#else	vap->iv_unit = unit;	vap->iv_flags = ic->ic_flags;		/* propagate common flags */	vap->iv_flags_ext = ic->ic_flags_ext;	vap->iv_xrvap = NULL;	vap->iv_ath_cap = ic->ic_ath_cap;	/* Default Multicast traffic to lowest rate of 1000 Kbps*/	vap->iv_mcast_rate = 1000;#endif	vap->iv_caps = ic->ic_caps &~ IEEE80211_C_OPMODE;	switch (opmode) {	case IEEE80211_M_STA:		/* WDS/Repeater */		if (flags & IEEE80211_NO_STABEACONS)			vap->iv_flags_ext |= IEEE80211_FEXT_SWBMISS;		break;	case IEEE80211_M_IBSS:		vap->iv_caps |= IEEE80211_C_IBSS;		vap->iv_ath_cap &= ~IEEE80211_ATHC_XR;		break;	case IEEE80211_M_AHDEMO:		vap->iv_caps |= IEEE80211_C_AHDEMO;		vap->iv_ath_cap &= ~IEEE80211_ATHC_XR;		break;	case IEEE80211_M_HOSTAP:		vap->iv_caps |= IEEE80211_C_HOSTAP;		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 notyet	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: bg 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);	/* 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);	ieee80211_sysctl_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 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;	} else		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_sysctl_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 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;	flags &= IEEE80211_CHAN_ALLTURBO;	c = ic->ic_prevchan;	if (c != NULL && c->ic_freq == freq &&	    (c->ic_flags & IEEE80211_CHAN_ALLTURBO) == flags)		return c;	/* brute force search */	for (i = 0; i < ic->ic_nchans; i++) {		c = &ic->ic_channels[i];		if (c->ic_freq == freq &&		    (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}voidieee80211_mark_dfs(struct ieee80211com *ic, struct ieee80211_channel *ichan){	struct ieee80211_channel *c=NULL;	struct net_device *dev = ic->ic_dev;	struct ieee80211vap *vap;	int i;	if_printf(dev, "Radar found on channel %d (%d MHz)\n",		ichan->ic_ieee, ichan->ic_freq);	if (ic->ic_opmode == IEEE80211_M_HOSTAP) {		/* Mark the channel in the ic_chan list */		if (ic->ic_flags_ext & IEEE80211_FEXT_MARKDFS) {			for (i = 0; i < ic->ic_nchans; i++) {				c = &ic->ic_channels[i];				if (c->ic_freq != ichan->ic_freq)					continue;				c->ic_flags |= IEEE80211_CHAN_RADAR;			}						c = ieee80211_find_channel(ic, ichan->ic_freq, ichan->ic_flags);			if (c == NULL) {				if_printf(dev,"%s: Couldn't find matching channel for dfs mark (%d, 0x%x)\n",					  __func__, ichan->ic_freq, ichan->ic_flags);				return;			}			if  (ic->ic_curchan->ic_freq == c->ic_freq) {				/* get an AP vap */				vap = TAILQ_FIRST(&ic->ic_vaps);				while ((vap != NULL) && (vap->iv_state != IEEE80211_S_RUN) &&				       (vap->iv_ic != ic)) {					vap = TAILQ_NEXT(vap, iv_next);				}				

⌨️ 快捷键说明

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