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

📄 ieee80211.c

📁 Linux下wifi实现
💻 C
📖 第 1 页 / 共 4 页
字号:
			vap->iv_fixed_rate, mode);	} else if (vap->iv_opmode == IEEE80211_M_STA) {		/*		 * In station mode report the current transmit rate.		 */		rs = &vap->iv_bss->ni_rates;		imr->ifm_active |= ieee80211_rate2media(ic,			rs->rs_rates[vap->iv_bss->ni_txrate], mode);	} else		imr->ifm_active |= IFM_AUTO;}EXPORT_SYMBOL(ieee80211_media_status);/* * Set the current phy mode. */intieee80211_setmode(struct ieee80211com *ic, enum ieee80211_phymode mode){#if 0	/*	 * Potentially invalidate the bss channel.	 */	/* XXX not right/too conservative */	if (ic->ic_bsschan != IEEE80211_CHAN_ANYC &&	    mode != ieee80211_chan2mode(ic->ic_bsschan))		ic->ic_bsschan = IEEE80211_CHAN_ANYC;	/* invalidate */#endif	ieee80211_reset_erp(ic, mode);	/* reset ERP state */	ic->ic_curmode = mode;		/* NB: must do post reset_erp */	return 0;}EXPORT_SYMBOL(ieee80211_setmode);/* * Return the phy mode for with the specified channel. */enum ieee80211_phymodeieee80211_chan2mode(const struct ieee80211_channel *chan){	/*	 * Callers should handle this case properly, rather than	 * just relying that this function returns a sane value.	 * XXX Probably needs to be revised.	 */	KASSERT(chan != IEEE80211_CHAN_ANYC, ("channel not setup"));		if (IEEE80211_IS_CHAN_108G(chan))		return IEEE80211_MODE_TURBO_G;	else if (IEEE80211_IS_CHAN_TURBO(chan))		return IEEE80211_MODE_TURBO_A;	else if (IEEE80211_IS_CHAN_A(chan))		return IEEE80211_MODE_11A;	else if (IEEE80211_IS_CHAN_ANYG(chan))		return IEEE80211_MODE_11G;	else if (IEEE80211_IS_CHAN_B(chan))		return IEEE80211_MODE_11B;	else if (IEEE80211_IS_CHAN_FHSS(chan))		return IEEE80211_MODE_FH;	/* NB: should not get here */	printk("%s: cannot map channel to mode; freq %u flags 0x%x\n",		__func__, chan->ic_freq, chan->ic_flags);	return IEEE80211_MODE_11B;}EXPORT_SYMBOL(ieee80211_chan2mode);/* * convert IEEE80211 rate value to ifmedia subtype. * ieee80211 rate is in unit of 0.5Mbps. */intieee80211_rate2media(struct ieee80211com *ic, int rate, enum ieee80211_phymode mode){#define	N(a)	(sizeof(a) / sizeof(a[0]))	static const struct {		u_int	m;	/* rate + mode */		u_int	r;	/* if_media rate */	} rates[] = {		{   2 | IFM_IEEE80211_FH, IFM_IEEE80211_FH1 },		{   4 | IFM_IEEE80211_FH, IFM_IEEE80211_FH2 },		{   2 | IFM_IEEE80211_11B, IFM_IEEE80211_DS1 },		{   4 | IFM_IEEE80211_11B, IFM_IEEE80211_DS2 },		{  11 | IFM_IEEE80211_11B, IFM_IEEE80211_DS5 },		{  22 | IFM_IEEE80211_11B, IFM_IEEE80211_DS11 },		{  44 | IFM_IEEE80211_11B, IFM_IEEE80211_DS22 },		{   3 | IFM_IEEE80211_11A, IFM_IEEE80211_OFDM1_50 },		{   4 | IFM_IEEE80211_11A, IFM_IEEE80211_OFDM2_25 },		{   6 | IFM_IEEE80211_11A, IFM_IEEE80211_OFDM3 },		{   9 | IFM_IEEE80211_11A, IFM_IEEE80211_OFDM4_50 },		{  12 | IFM_IEEE80211_11A, IFM_IEEE80211_OFDM6 },		{  18 | IFM_IEEE80211_11A, IFM_IEEE80211_OFDM9 },		{  24 | IFM_IEEE80211_11A, IFM_IEEE80211_OFDM12 },		{  27 | IFM_IEEE80211_11A, IFM_IEEE80211_OFDM13_5 },		{  36 | IFM_IEEE80211_11A, IFM_IEEE80211_OFDM18 },		{  48 | IFM_IEEE80211_11A, IFM_IEEE80211_OFDM24 },		{  54 | IFM_IEEE80211_11A, IFM_IEEE80211_OFDM27 },		{  72 | IFM_IEEE80211_11A, IFM_IEEE80211_OFDM36 },		{  96 | IFM_IEEE80211_11A, IFM_IEEE80211_OFDM48 },		{ 108 | IFM_IEEE80211_11A, IFM_IEEE80211_OFDM54 },		{   2 | IFM_IEEE80211_11G, IFM_IEEE80211_DS1 },		{   4 | IFM_IEEE80211_11G, IFM_IEEE80211_DS2 },		{  11 | IFM_IEEE80211_11G, IFM_IEEE80211_DS5 },		{  22 | IFM_IEEE80211_11G, IFM_IEEE80211_DS11 },		{  12 | IFM_IEEE80211_11G, IFM_IEEE80211_OFDM6 },		{  18 | IFM_IEEE80211_11G, IFM_IEEE80211_OFDM9 },		{  24 | IFM_IEEE80211_11G, IFM_IEEE80211_OFDM12 },		{  36 | IFM_IEEE80211_11G, IFM_IEEE80211_OFDM18 },		{  48 | IFM_IEEE80211_11G, IFM_IEEE80211_OFDM24 },		{  72 | IFM_IEEE80211_11G, IFM_IEEE80211_OFDM36 },		{  96 | IFM_IEEE80211_11G, IFM_IEEE80211_OFDM48 },		{ 108 | IFM_IEEE80211_11G, IFM_IEEE80211_OFDM54 },		/* NB: OFDM72 doesn't really exist so we don't handle it */	};	u_int mask, i;	mask = rate & IEEE80211_RATE_VAL;	switch (mode) {	case IEEE80211_MODE_11A:	case IEEE80211_MODE_TURBO_A:		mask |= IFM_IEEE80211_11A;		break;	case IEEE80211_MODE_11B:		mask |= IFM_IEEE80211_11B;		break;	case IEEE80211_MODE_FH:		mask |= IFM_IEEE80211_FH;		break;	case IEEE80211_MODE_AUTO:		/* NB: ic may be NULL for some drivers */		if (ic && ic->ic_phytype == IEEE80211_T_FH) {			mask |= IFM_IEEE80211_FH;			break;		}		/* NB: hack, 11g matches both 11b+11a rates */		/* fall thru... */	case IEEE80211_MODE_11G:	case IEEE80211_MODE_TURBO_G:		mask |= IFM_IEEE80211_11G;		break;	}	for (i = 0; i < N(rates); i++)		if (rates[i].m == mask)			return rates[i].r;	return IFM_AUTO;#undef N}EXPORT_SYMBOL(ieee80211_rate2media);intieee80211_media2rate(int mword){#define	N(a)	(sizeof(a) / sizeof(a[0]))	static const int ieeerates[] = {		-1,		/* IFM_AUTO */		0,		/* IFM_MANUAL */		0,		/* IFM_NONE */		2,		/* IFM_IEEE80211_FH1 */		4,		/* IFM_IEEE80211_FH2 */		2,		/* IFM_IEEE80211_DS1 */		4,		/* IFM_IEEE80211_DS2 */		11,		/* IFM_IEEE80211_DS5 */		22,		/* IFM_IEEE80211_DS11 */		44,		/* IFM_IEEE80211_DS22 */		3,		/* IFM_IEEE80211_OFDM1_50 */		4,		/* IFM_IEEE80211_OFDM2_25 */		6,		/* IFM_IEEE80211_OFDM3 */		9,		/* IFM_IEEE80211_OFDM4_50 */		12,		/* IFM_IEEE80211_OFDM6 */		18,		/* IFM_IEEE80211_OFDM9 */		24,		/* IFM_IEEE80211_OFDM12 */		27,		/* IFM_IEEE80211_OFDM13_5 */		36,		/* IFM_IEEE80211_OFDM18 */		48,		/* IFM_IEEE80211_OFDM24 */		54,		/* IFM_IEEE80211_OFDM27 */		72,		/* IFM_IEEE80211_OFDM36 */		96,		/* IFM_IEEE80211_OFDM48 */		108,		/* IFM_IEEE80211_OFDM54 */		144,		/* IFM_IEEE80211_OFDM72 */	};	return IFM_SUBTYPE(mword) < N(ieeerates) ?		ieeerates[IFM_SUBTYPE(mword)] : 0;#undef N}EXPORT_SYMBOL(ieee80211_media2rate);/* * Return netdevice statistics. */static struct net_device_stats *ieee80211_getstats(struct net_device *dev){	struct ieee80211vap *vap = dev->priv;	struct net_device_stats *stats = &vap->iv_devstats;	/* XXX total guess as to what to count where */	/* update according to private statistics */	stats->tx_errors = vap->iv_stats.is_tx_nodefkey			 + vap->iv_stats.is_tx_noheadroom			 + vap->iv_stats.is_crypto_enmicfail;	stats->tx_dropped = vap->iv_stats.is_tx_nobuf			+ vap->iv_stats.is_tx_nonode			+ vap->iv_stats.is_tx_unknownmgt			+ vap->iv_stats.is_tx_badcipher			+ vap->iv_stats.is_tx_nodefkey;	stats->rx_errors = vap->iv_stats.is_rx_tooshort			+ vap->iv_stats.is_rx_wepfail			+ vap->iv_stats.is_rx_decap			+ vap->iv_stats.is_rx_nobuf			+ vap->iv_stats.is_rx_decryptcrc			+ vap->iv_stats.is_rx_ccmpmic			+ vap->iv_stats.is_rx_tkipmic			+ vap->iv_stats.is_rx_tkipicv;	stats->rx_crc_errors = 0;	return stats;}static intieee80211_change_mtu(struct net_device *dev, int mtu){	if (!(IEEE80211_MTU_MIN < mtu && mtu <= IEEE80211_MTU_MAX))		return -EINVAL;	dev->mtu = mtu;	/* XXX coordinate with parent device */	return 0;}static voidieee80211_set_multicast_list(struct net_device *dev){	struct ieee80211vap *vap = dev->priv;	struct ieee80211com *ic = vap->iv_ic;	struct net_device *parent = ic->ic_dev;	IEEE80211_LOCK_IRQ(ic);	if (dev->flags & IFF_PROMISC) {		if ((vap->iv_flags & IEEE80211_F_PROMISC) == 0) {			vap->iv_flags |= IEEE80211_F_PROMISC;			ic->ic_promisc++;			parent->flags |= IFF_PROMISC;		}	} else {		if (vap->iv_flags & IEEE80211_F_PROMISC) {			vap->iv_flags &= ~IEEE80211_F_PROMISC;			ic->ic_promisc--;			parent->flags &= ~IFF_PROMISC;		}	}	if (dev->flags & IFF_ALLMULTI) {		if ((vap->iv_flags & IEEE80211_F_ALLMULTI) == 0) {			vap->iv_flags |= IEEE80211_F_ALLMULTI;			ic->ic_allmulti++;			parent->flags |= IFF_ALLMULTI;		}	} else {		if (vap->iv_flags & IEEE80211_F_ALLMULTI) {			vap->iv_flags &= ~IEEE80211_F_ALLMULTI;			ic->ic_allmulti--;			parent->flags &= ~IFF_ALLMULTI;		}	}	IEEE80211_UNLOCK_IRQ(ic);	/* XXX merge multicast list into parent device */	parent->set_multicast_list(ic->ic_dev);}voidieee80211_build_countryie(struct ieee80211com *ic){#define	N(a)	(sizeof (a) / sizeof (a[0]))	int i, j, chanflags, found;	struct net_device *dev = ic->ic_dev;	struct ieee80211_channel *c;	u_int8_t chanlist[IEEE80211_CHAN_MAX + 1];	u_int8_t chancnt = 0;	u_int8_t *cur_runlen, *cur_chan, *cur_pow, prevchan;	/*	 * Fill in country IE.	 */	memset(&ic->ic_country_ie, 0, sizeof(ic->ic_country_ie));  	ic->ic_country_ie.country_id = IEEE80211_ELEMID_COUNTRY;	ic->ic_country_ie.country_len = 0; /* init needed by following code */	/* initialize country IE */	found = 0;	for (i = 0; i < N(country_strings); i++) {		if (country_strings[i].iso_code == ic->ic_country_code) {			ic->ic_country_ie.country_str[0] = country_strings[i].iso_name[0];			ic->ic_country_ie.country_str[1] = country_strings[i].iso_name[1];			found = 1;			break;		}	}	if (!found) {		if_printf(dev, "bad country string ignored: %d\n",			ic->ic_country_code);		ic->ic_country_ie.country_str[0] = ' ';		ic->ic_country_ie.country_str[1] = ' ';				}	/* 	 * indoor/outdoor portion if country string.	 * NB: this is not quite right, since we should have one of:	 *     'I' indoor only	 *     'O' outdoor only	 *     ' ' all enviroments	 *  we currently can only provide 'I' or ' '.	 */	ic->ic_country_ie.country_str[2] = 'I';	if (ic->ic_country_outdoor)		ic->ic_country_ie.country_str[2] = ' ';	/* 	 * runlength encoded channel max tx power info.	 */	cur_runlen = &ic->ic_country_ie.country_triplet[1];	cur_chan = &ic->ic_country_ie.country_triplet[0];	cur_pow = &ic->ic_country_ie.country_triplet[2];	prevchan = 0;	ic->ic_country_ie.country_len = 3; /* invalid, but just initialize */	if ((ic->ic_flags_ext & IEEE80211_FEXT_REGCLASS) && ic->ic_nregclass) {		/* Add regulatory triplets.	 	* chan/no_of_chans/tx power triplet is overridden as	 	* as follows:	 	* cur_chan == REGULATORY EXTENSION ID.	 	* cur_runlen = Regulatory class.	 	* cur_pow = coverage class.	 	*/		for (i=0; i < ic->ic_nregclass; i++) {			*cur_chan = IEEE80211_REG_EXT_ID;			*cur_runlen = ic->ic_regclassids[i];			*cur_pow = ic->ic_coverageclass;				cur_runlen +=3;			cur_chan += 3;			cur_pow += 3;			ic->ic_country_ie.country_len += 3;		}	} else {		if ((ic->ic_curmode == IEEE80211_MODE_11A) || 		    (ic->ic_curmode == IEEE80211_MODE_TURBO_A))			chanflags = IEEE80211_CHAN_5GHZ;		else 			chanflags = IEEE80211_CHAN_2GHZ;			memset(&chanlist[0], 0, sizeof(chanlist));  		/* XXX not right due to duplicate entries */		for (i = 0; i < ic->ic_nchans; i++) {			c = &ic->ic_channels[i];				/* Does channel belong to current operation mode */			if (!(c->ic_flags & chanflags))				continue;			/* Skip previously reported channels */			for (j = 0; j < chancnt; j++)				if (c->ic_ieee == chanlist[j])					break;						if (j != chancnt) /* found a match */				continue;			chanlist[chancnt] = c->ic_ieee;			chancnt++;				/* Skip turbo channels */			if (IEEE80211_IS_CHAN_TURBO(c))				continue;				/* Skip half/quarter rate channels */			if (IEEE80211_IS_CHAN_HALF(c) || 			    IEEE80211_IS_CHAN_QUARTER(c))				continue;				if (*cur_runlen == 0) {				(*cur_runlen)++;				*cur_pow = c->ic_maxregpower;				*cur_chan = c->ic_ieee;				prevchan = c->ic_ieee;				ic->ic_country_ie.country_len += 3;			} else if (*cur_pow == c->ic_maxregpower &&			    c->ic_ieee == prevchan + 1) {				(*cur_runlen)++;				prevchan = c->ic_ieee;			} else {				cur_runlen +=3;				cur_chan += 3;				cur_pow += 3;				(*cur_runlen)++;				*cur_pow = c->ic_maxregpower;				*cur_chan = c->ic_ieee;				prevchan = c->ic_ieee;				ic->ic_country_ie.country_len += 3;			}		}	}	/* pad */	if (ic->ic_country_ie.country_len & 1)		ic->ic_country_ie.country_len++;#if 0	ic->ic_country_ie.country_len=8;	ic->ic_country_ie.country_triplet[0] = 10;	ic->ic_country_ie.country_triplet[1] = 11;	ic->ic_country_ie.country_triplet[2] = 12;#endif#undef N}

⌨️ 快捷键说明

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