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

📄 ieee80211.c

📁 Linux下wifi实现
💻 C
📖 第 1 页 / 共 4 页
字号:
					 */					vap = TAILQ_FIRST(&ic->ic_vaps);					while ((vap->iv_state != IEEE80211_S_SCAN) && (vap != NULL) &&					       (vap->iv_ic != ic)) {						vap = TAILQ_NEXT(vap, iv_next);					}					/*					 * No running/scanning VAP was found, so they're all in					 * INIT state, no channel change needed					 */					if (!vap)						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_USECACHE | IEEE80211_SCAN_NOSSID | IEEE80211_SCAN_KEEPMODE, 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);				}			}		} else {			/* Change to a radar free 11a channel for dfstesttime seconds */			ic->ic_chanchange_chan = IEEE80211_RADAR_TEST_MUTE_CHAN;			ic->ic_chanchange_tbtt = IEEE80211_RADAR_11HCOUNT;			ic->ic_flags |= IEEE80211_F_CHANSWITCH;			/* A timer is setup in the radar task if markdfs is not set and			 * we are in hostap mode.			 */		}	} else {		/* Are we in sta mode? If so, send an action msg to ap saying we found a radar? */	}}EXPORT_SYMBOL(ieee80211_mark_dfs);voidieee80211_dfs_test_return(struct ieee80211com *ic, u_int8_t ieeeChan){	struct net_device *dev = ic->ic_dev;	/* Return to the original channel we were on before the test mute */	if_printf(dev, "Returning to channel %d\n", ieeeChan);	printk("Returning to chan %d\n", ieeeChan);	ic->ic_chanchange_chan = ieeeChan;	ic->ic_chanchange_tbtt = IEEE80211_RADAR_11HCOUNT;	ic->ic_flags |= IEEE80211_F_CHANSWITCH;}EXPORT_SYMBOL(ieee80211_dfs_test_return);voidieee80211_announce(struct ieee80211com *ic){	struct net_device *dev = ic->ic_dev;	int i, mode, rate, mword;	struct ieee80211_rateset *rs;	for (mode = IEEE80211_MODE_11A; mode < IEEE80211_MODE_MAX; mode++) {		if ((ic->ic_modecaps & (1<<mode)) == 0)			continue;		if_printf(dev, "%s rates: ", ieee80211_phymode_name[mode]);		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;			printf("%s%d%sMbps", (i != 0 ? " " : ""),			    (rate & IEEE80211_RATE_VAL) / 2,			    ((rate & 0x1) != 0 ? ".5" : ""));		}		printf("\n");	}	if_printf(dev, "H/W encryption support:");	if (ic->ic_caps & IEEE80211_C_WEP)		printk(" WEP");	if (ic->ic_caps & IEEE80211_C_AES)		printk(" AES");	if (ic->ic_caps & IEEE80211_C_AES_CCM)		printk(" AES_CCM");	if (ic->ic_caps & IEEE80211_C_CKIP)		printk(" CKIP");	if (ic->ic_caps & IEEE80211_C_TKIP)		printk(" TKIP");	printk("\n");}EXPORT_SYMBOL(ieee80211_announce);voidieee80211_announce_channels(struct ieee80211com *ic){	const struct ieee80211_channel *c;	char type;	int i;	printf("Chan  Freq  RegPwr  MinPwr  MaxPwr\n");	for (i = 0; i < ic->ic_nchans; i++) {		c = &ic->ic_channels[i];		if (IEEE80211_IS_CHAN_ST(c))			type = 'S';		else if (IEEE80211_IS_CHAN_108A(c))			type = 'T';		else if (IEEE80211_IS_CHAN_108G(c))			type = 'G';		else if (IEEE80211_IS_CHAN_A(c))			type = 'a';		else if (IEEE80211_IS_CHAN_ANYG(c))			type = 'g';		else if (IEEE80211_IS_CHAN_B(c))			type = 'b';		else			type = 'f';		printf("%4d  %4d%c %6d  %6d  %6d\n"			, c->ic_ieee, c->ic_freq, type			, c->ic_maxregpower			, c->ic_minpower, c->ic_maxpower		);	}}EXPORT_SYMBOL(ieee80211_announce_channels);/* * Common code to calculate the media status word * from the operating mode and channel state. */static intmedia_status(enum ieee80211_opmode opmode, const struct ieee80211_channel *chan){	int status;	status = IFM_IEEE80211;	switch (opmode) {	case IEEE80211_M_STA:		break;	case IEEE80211_M_AHDEMO:		status |= IFM_IEEE80211_ADHOC | IFM_FLAG0;		break;	case IEEE80211_M_IBSS:		status |= IFM_IEEE80211_ADHOC;		break;	case IEEE80211_M_HOSTAP:		status |= IFM_IEEE80211_HOSTAP;		break;	case IEEE80211_M_MONITOR:		status |= IFM_IEEE80211_MONITOR;		break;	case IEEE80211_M_WDS:		status |= IFM_IEEE80211_WDS;		break;	}	if (IEEE80211_IS_CHAN_A(chan)) {		status |= IFM_IEEE80211_11A;		if (IEEE80211_IS_CHAN_TURBO(chan))			status |= IFM_IEEE80211_TURBO;	} else if (IEEE80211_IS_CHAN_B(chan)) {		status |= IFM_IEEE80211_11B;	} else if (IEEE80211_IS_CHAN_ANYG(chan)) {		status |= IFM_IEEE80211_11G;		if (IEEE80211_IS_CHAN_TURBO(chan))			status |= IFM_IEEE80211_TURBO;	} else if (IEEE80211_IS_CHAN_FHSS(chan)) {		status |= IFM_IEEE80211_FH;	}	/* XXX else complain? */	return status;}/* * Handle a media requests on the base interface. */static voidieee80211com_media_status(struct net_device *dev, struct ifmediareq *imr){	struct ieee80211com *ic = dev->priv;	/*XXX*/	imr->ifm_status = IFM_AVALID;	if (!TAILQ_EMPTY(&ic->ic_vaps))		imr->ifm_status |= IFM_ACTIVE;	imr->ifm_active = media_status(ic->ic_opmode, ic->ic_curchan);}/* * Convert a media specification to an 802.11 phy mode. */static intmedia2mode(const struct ifmedia_entry *ime, enum ieee80211_phymode *mode){	switch (IFM_MODE(ime->ifm_media)) {	case IFM_IEEE80211_11A:		*mode = IEEE80211_MODE_11A;		break;	case IFM_IEEE80211_11B:		*mode = IEEE80211_MODE_11B;		break;	case IFM_IEEE80211_11G:		*mode = IEEE80211_MODE_11G;		break;	case IFM_IEEE80211_FH:		*mode = IEEE80211_MODE_FH;		break;	case IFM_AUTO:		*mode = IEEE80211_MODE_AUTO;		break;	default:		return 0;	}	/*	 * Turbo mode is an ``option''.  	 * XXX: Turbo currently does not apply to AUTO	 */	if (ime->ifm_media & IFM_IEEE80211_TURBO) {		if (*mode == IEEE80211_MODE_11A)			*mode = IEEE80211_MODE_TURBO_A;		else if (*mode == IEEE80211_MODE_11G)			*mode = IEEE80211_MODE_TURBO_G;		else			return 0;	}	return 1;}static intieee80211com_media_change(struct net_device *dev){	struct ieee80211com *ic = dev->priv;	/*XXX*/	struct ieee80211vap *vap;	struct ifmedia_entry *ime = ic->ic_media.ifm_cur;	enum ieee80211_phymode newphymode;	int j, error = 0;	/* XXX is rtnl held here? */	/*	 * First, identify the phy mode.	 */	if (!media2mode(ime, &newphymode))		return -EINVAL;	/* NB: mode must be supported, no need to check */	/*	 * Autoselect doesn't make sense when operating as an AP.	 * If no phy mode has been selected, pick one and lock it	 * down so rate tables can be used in forming beacon frames	 * and the like.	 */	if (ic->ic_opmode == IEEE80211_M_HOSTAP &&	    newphymode == IEEE80211_MODE_AUTO) {		for (j = IEEE80211_MODE_11A; j < IEEE80211_MODE_MAX; j++)			if (ic->ic_modecaps & (1 << j)) {				newphymode = j;				break;			}	}	/*	 * Handle phy mode change.	 */	IEEE80211_LOCK_IRQ(ic);	if (ic->ic_curmode != newphymode) {		/* change phy mode */		error = ieee80211_setmode(ic, newphymode);		if (error != 0) {			IEEE80211_UNLOCK_IRQ_EARLY(ic);			return error;		}		TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next) {			/* reset WME state */			ieee80211_wme_initparams_locked(vap);			/*			 * Setup an initial rate set according to the			 * current/default channel selected above.  This			 * will be changed when scanning but must exist			 * now so drivers have a consistent state.			 */			KASSERT(vap->iv_bss != NULL, ("no bss node"));			vap->iv_bss->ni_rates = ic->ic_sup_rates[newphymode];		}		error = ENETRESET;	}	IEEE80211_UNLOCK_IRQ(ic);#ifdef notdef	if (error == 0)		ifp->if_baudrate = ifmedia_baudrate(ime->ifm_media);#endif	return error;}static intfindrate(struct ieee80211com *ic, enum ieee80211_phymode mode, int rate){#define	IEEERATE(_ic,_m,_i) \	((_ic)->ic_sup_rates[_m].rs_rates[_i] & IEEE80211_RATE_VAL)	int i, nrates = ic->ic_sup_rates[mode].rs_nrates;	for (i = 0; i < nrates; i++)		if (IEEERATE(ic, mode, i) == rate)			return i;	return -1;#undef IEEERATE}/* * Convert a media specification to a rate index and possibly a mode * (if the rate is fixed and the mode is specified as ``auto'' then * we need to lock down the mode so the index is meanginful). */static intcheckrate(struct ieee80211com *ic, enum ieee80211_phymode mode, int rate){	/*	 * Check the rate table for the specified/current phy.	 */	if (mode == IEEE80211_MODE_AUTO) {		int i;		/*		 * In autoselect mode search for the rate.		 */		for (i = IEEE80211_MODE_11A; i < IEEE80211_MODE_MAX; i++) {			if ((ic->ic_modecaps & (1 << i)) &&			    findrate(ic, i, rate) != -1)				return 1;		}		return 0;	} else {		/*		 * Mode is fixed, check for rate.		 */		return (findrate(ic, mode, rate) != -1);	}}/* * Handle a media change request; the only per-vap * information that is meaningful is the fixed rate * and desired phy mode. */intieee80211_media_change(struct net_device *dev){	struct ieee80211vap *vap = dev->priv;	struct ieee80211com *ic = vap->iv_ic;	struct ifmedia_entry *ime = vap->iv_media.ifm_cur;	enum ieee80211_phymode newmode;	int newrate, error;	/*	 * First, identify the desired phy mode.	 */	if (!media2mode(ime, &newmode))		return -EINVAL;	/*	 * Check for fixed/variable rate.	 */	if (IFM_SUBTYPE(ime->ifm_media) != IFM_AUTO) {		/*		 * Convert media subtype to rate and potentially		 * lock down the mode.		 */		newrate = ieee80211_media2rate(ime->ifm_media);		if (newrate == 0 || !checkrate(ic, newmode, newrate))			return -EINVAL;	} else		newrate = IEEE80211_FIXED_RATE_NONE;	/*	 * Install the rate+mode settings.	 */	error = 0;	if (vap->iv_fixed_rate != newrate) {		vap->iv_fixed_rate = newrate;		/* fixed tx rate */		error = ENETRESET;	}	if (vap->iv_des_mode != newmode) {		vap->iv_des_mode = newmode;		/* desired phymode */		error = ENETRESET;	}	return error;}EXPORT_SYMBOL(ieee80211_media_change);voidieee80211_media_status(struct net_device *dev, struct ifmediareq *imr){	struct ieee80211vap *vap = dev->priv;	struct ieee80211com *ic = vap->iv_ic;	enum ieee80211_phymode mode;	struct ieee80211_rateset *rs;	imr->ifm_status = IFM_AVALID;	/*	 * NB: use the current channel's mode to lock down a xmit	 * rate only when running; otherwise we may have a mismatch	 * in which case the rate will not be convertible.	 */	if (vap->iv_state == IEEE80211_S_RUN) {		imr->ifm_status |= IFM_ACTIVE;		mode = ieee80211_chan2mode(ic->ic_curchan);	} else		mode = IEEE80211_MODE_AUTO;	imr->ifm_active = media_status(vap->iv_opmode, ic->ic_curchan);	/*	 * Calculate a current rate if possible.	 */	if (vap->iv_fixed_rate != IEEE80211_FIXED_RATE_NONE) {		/*		 * A fixed rate is set, report that.		 */		imr->ifm_active |= ieee80211_rate2media(ic,

⌨️ 快捷键说明

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