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

📄 ieee80211.c.svn-base

📁 最新之atheros芯片driver source code, 基于linux操作系统,內含atheros芯片HAL全部代码
💻 SVN-BASE
📖 第 1 页 / 共 4 页
字号:
		 * 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 PHY mode */		error = -ENETRESET;	}	return error;}EXPORT_SYMBOL(ieee80211_media_change);voidieee80211_media_status(struct net_device *dev, struct ifmediareq *imr){	struct ieee80211vap *vap = netdev_priv(dev);	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,			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(KERN_ERR "%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){	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 through* */	case IEEE80211_MODE_11G:	case IEEE80211_MODE_TURBO_G:		mask |= IFM_IEEE80211_11G;		break;	}	for (i = 0; i < ARRAY_SIZE(rates); i++)		if (rates[i].m == mask)			return rates[i].r;	return IFM_AUTO;}EXPORT_SYMBOL(ieee80211_rate2media);intieee80211_media2rate(int mword){	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) < ARRAY_SIZE(ieeerates) ?		ieeerates[IFM_SUBTYPE(mword)] : 0;}EXPORT_SYMBOL(ieee80211_media2rate);/* * Return netdevice statistics. */static struct net_device_stats *ieee80211_getstats(struct net_device *dev){	struct ieee80211vap *vap = netdev_priv(dev);	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 = netdev_priv(dev);	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){	int i, found;	struct net_device *dev = ic->ic_dev;	struct ieee80211_channel *c;	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;	/* Initialize country IE */	found = 0;	for (i = 0; i < ARRAY_SIZE(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 {		u_int16_t curmode_noturbo = ic->ic_curmode;		/* advertise only non-turbo channels */		/* XXX: shouldn't turbo channels be included as well? */		switch (curmode_noturbo) {		case IEEE80211_MODE_TURBO_A:			curmode_noturbo = IEEE80211_MODE_11A;			break;		case IEEE80211_MODE_TURBO_G:			curmode_noturbo = IEEE80211_MODE_11G;			break;		}		for (i = 0; i < ic->ic_nchans; i++) {			c = &ic->ic_channels[i];			/* Does channel belong to current operation mode */			if (ieee80211_chan2mode(c) != curmode_noturbo)				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 +					(IEEE80211_IS_CHAN_5GHZ(c) ? 4 : 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++;}voidieee80211_build_sc_ie(struct ieee80211com *ic){	struct ieee80211_ie_sc *ie = &ic->ic_sc_ie;	int i, j;	struct ieee80211_channel *c;	u_int8_t prevchan;	/* Fill in Supported Channels IE. */	memset(ie, 0, sizeof(*ie));	ie->sc_id = IEEE80211_ELEMID_SUPPCHAN;	prevchan = 0;	j = 0;	for (i = 0; i < ic->ic_nchans; i++) {		c = &ic->ic_channels[i];		/* Skip disabled channels */		if (isclr(ic->ic_chan_active, c->ic_ieee))			continue;		/* XXX 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;		/* Skip duplicate frequencies (separate b/g channels) */		if (c->ic_ieee == prevchan)			continue;		if (ie->sc_subband[j].sc_number == 0) {			ie->sc_subband[j].sc_first = c->ic_ieee;		} else if (c->ic_ieee != prevchan +				/* XXX: see 802.11d-2001-4-05-03-interp,				 * but what about .11j, turbo, etc.? */				(IEEE80211_IS_CHAN_5GHZ(c) ? 4 : 1)) {			j++;			ie->sc_subband[j].sc_first = c->ic_ieee;		}		ie->sc_subband[j].sc_number++;		prevchan = c->ic_ieee;	}	ie->sc_len = (j+1) * 2;}int ath_debug_global = 0;EXPORT_SYMBOL(ath_debug_global);

⌨️ 快捷键说明

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