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

📄 ieee80211_wireless.c.svn-base

📁 最新之atheros芯片driver source code, 基于linux操作系统,內含atheros芯片HAL全部代码
💻 SVN-BASE
📖 第 1 页 / 共 5 页
字号:
		range->pmp_flags = IW_POWER_PERIOD;		range->pmt_flags = IW_POWER_TIMEOUT;		range->pm_capa = IW_POWER_PERIOD | IW_POWER_TIMEOUT |			IW_POWER_UNICAST_R | IW_POWER_ALL_R;	}	range->we_version_compiled = WIRELESS_EXT;	range->we_version_source = 18;	range->retry_capa = IW_RETRY_LIMIT;	range->retry_flags = IW_RETRY_LIMIT;	range->min_retry = 0;	range->max_retry = 255;	range->num_channels = ic->ic_nchans;	range->num_frequency = 0;	memset(reported, 0, sizeof(reported));	for (i = 0; i < ic->ic_nchans; i++) {		const struct ieee80211_channel *c = &ic->ic_channels[i];		/* discard if previously reported (e.g. b/g) */		if (isclr(reported, c->ic_ieee)) {			setbit(reported, c->ic_ieee);			range->freq[range->num_frequency].i = c->ic_ieee;			range->freq[range->num_frequency].m =				ic->ic_channels[i].ic_freq * 100000;			range->freq[range->num_frequency].e = 1;			if (++range->num_frequency == IW_MAX_FREQUENCIES)				break;		}	}	/* Atheros' RSSI value is SNR: 0 -> 60 for old chipsets. Range 	 * for newer chipsets is unknown. This value is arbitarily chosen 	 * to give an indication that full rate will be available and to be 	 * a practicable maximum. */	range->max_qual.qual  = 70;#if WIRELESS_EXT >= 19	/* XXX: This should be updated to use the current noise floor. */	/* These are negative full bytes.	 * Min. quality is noise + 1 */	range->max_qual.updated |= IW_QUAL_DBM;	range->max_qual.level = ATH_DEFAULT_NOISE + 1;	range->max_qual.noise = ATH_DEFAULT_NOISE;#else	/* Values larger than the maximum are assumed to be absolute */	range->max_qual.level = 0;	range->max_qual.noise = 0;#endif	range->sensitivity = 1;	range->max_encoding_tokens = IEEE80211_WEP_NKID;	/* XXX query driver to find out supported key sizes */	range->num_encoding_sizes = 3;	range->encoding_size[0] = 5;		/* 40-bit */	range->encoding_size[1] = 13;		/* 104-bit */	range->encoding_size[2] = 16;		/* 128-bit */	/* XXX this only works for station mode */	rs = &ni->ni_rates;	range->num_bitrates = rs->rs_nrates;	if (range->num_bitrates > IW_MAX_BITRATES)		range->num_bitrates = IW_MAX_BITRATES;	for (i = 0; i < range->num_bitrates; i++) {		r = rs->rs_rates[i] & IEEE80211_RATE_VAL;		range->bitrate[i] = (r * 1000000) / 2;	}	/* estimated maximum TCP throughput values (bps) */	range->throughput = 5500000;	range->min_rts = 0;	range->max_rts = 2347;	range->min_frag = 256;	range->max_frag = 2346;#if WIRELESS_EXT >= 17	/* Event capability (kernel) */	IW_EVENT_CAPA_SET_KERNEL(range->event_capa);	/* Event capability (driver) */	if (vap->iv_opmode == IEEE80211_M_STA ||		 vap->iv_opmode == IEEE80211_M_IBSS ||		 vap->iv_opmode == IEEE80211_M_AHDEMO) {		/* for now, only ibss, ahdemo, sta has this cap */		IW_EVENT_CAPA_SET(range->event_capa, SIOCGIWSCAN);	}	if (vap->iv_opmode == IEEE80211_M_STA) {		/* for sta only */		IW_EVENT_CAPA_SET(range->event_capa, SIOCGIWAP);		IW_EVENT_CAPA_SET(range->event_capa, IWEVREGISTERED);		IW_EVENT_CAPA_SET(range->event_capa, IWEVEXPIRED);	}	/* this is used for reporting replay failure, which is used by the different encoding schemes */	IW_EVENT_CAPA_SET(range->event_capa, IWEVCUSTOM);#endif#if WIRELESS_EXT >= 18	/* report supported WPA/WPA2 capabilities to userspace */	range->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_WPA2 |		IW_ENC_CAPA_CIPHER_TKIP | IW_ENC_CAPA_CIPHER_CCMP;#endif	return 0;}static intieee80211_ioctl_setspy(struct net_device *dev, struct iw_request_info *info,	struct iw_point *data, char *extra){	/* save the list of node addresses */	struct ieee80211vap *vap = netdev_priv(dev);	struct sockaddr address[IW_MAX_SPY];	unsigned int number = data->length;	int i;	if (number > IW_MAX_SPY)		return -E2BIG;	/* get the addresses into the driver */	if (data->pointer) {		if (copy_from_user(address, data->pointer,		    sizeof(struct sockaddr) * number))			return -EFAULT;	} else		return -EINVAL;	/* copy the MAC addresses into a list */	if (number > 0) {		/* extract the MAC addresses */		for (i = 0; i < number; i++)			memcpy(&vap->iv_spy.mac[i * IEEE80211_ADDR_LEN],				address[i].sa_data, IEEE80211_ADDR_LEN);		/* init rssi timestamps to 0 */		memset(vap->iv_spy.ts_rssi, 0, sizeof(vap->iv_spy.ts_rssi));	}	vap->iv_spy.num = number;	return 0;}static intieee80211_ioctl_getspy(struct net_device *dev, struct iw_request_info *info,	struct iw_point *data, char *extra){	/*	 * locate nodes by mac (ieee80211_find_node()),	 * copy out rssi, set updated flag appropriately	 */	struct ieee80211vap *vap = netdev_priv(dev);	struct ieee80211_node_table *nt = &vap->iv_ic->ic_sta;	struct ieee80211_node *ni;	struct ieee80211com *ic = vap->iv_ic;	struct sockaddr *address;	struct iw_quality *spy_stat;	unsigned int number = vap->iv_spy.num;	int i;	address = (struct sockaddr *)extra;	spy_stat = (struct iw_quality *)(extra + number * sizeof(struct sockaddr));	for (i = 0; i < number; i++) {		memcpy(address[i].sa_data, &vap->iv_spy.mac[i * IEEE80211_ADDR_LEN],			IEEE80211_ADDR_LEN);		address[i].sa_family = AF_PACKET;	}	/* locate a node, read its rssi, check if updated, convert to dBm */	for (i = 0; i < number; i++) {		ni = ieee80211_find_node(nt, &vap->iv_spy.mac[i * IEEE80211_ADDR_LEN]);		/* check we are associated w/ this vap */		if (ni) {			if (ni->ni_vap == vap) {				set_quality(&spy_stat[i], 					ic->ic_rssi_ewma ? 					 ic->ic_node_getrssi(ni) : ni->ni_rssi,					ic->ic_channoise);				if (ni->ni_rtsf != vap->iv_spy.ts_rssi[i]) {					vap->iv_spy.ts_rssi[i] = ni->ni_rtsf;				} else {					spy_stat[i].updated = 0;				}			}			ieee80211_unref_node(&ni);		} else {			spy_stat[i].updated = IW_QUAL_ALL_INVALID;		}	}	/* copy results to userspace */	data->length = number;	return 0;}#if WIRELESS_EXT >= 16/* Enhanced iwspy support */static intieee80211_ioctl_setthrspy(struct net_device *dev, struct iw_request_info *info,	struct iw_point *data, char *extra){	struct ieee80211vap *vap = netdev_priv(dev);	struct iw_thrspy threshold;	if (data->length != 1)		return -EINVAL;	/* get the threshold values into the driver */	if (data->pointer) {		if (copy_from_user(&threshold, data->pointer,		    sizeof(struct iw_thrspy)))			return -EFAULT;	} else		return -EINVAL;	if (threshold.low.level == 0) {		/* disable threshold */		vap->iv_spy.thr_low = 0;		vap->iv_spy.thr_high = 0;		IEEE80211_DPRINTF(vap, IEEE80211_MSG_DEBUG,			"%s: disabled iw_spy threshold\n", __func__);	} else {		/* We are passed a signal level/strength - calculate 		 * corresponding RSSI values */		/* XXX: We should use current noise value. */		vap->iv_spy.thr_low = threshold.low.level + ATH_DEFAULT_NOISE;		vap->iv_spy.thr_high = threshold.high.level + ATH_DEFAULT_NOISE;		IEEE80211_DPRINTF(vap, IEEE80211_MSG_DEBUG,			"%s: enabled iw_spy threshold\n", __func__);	}	return 0;}static intieee80211_ioctl_getthrspy(struct net_device *dev, struct iw_request_info *info,	struct iw_point *data, char *extra){	struct ieee80211vap *vap = netdev_priv(dev);	struct ieee80211com *ic = vap->iv_ic;	struct iw_thrspy *threshold;	threshold = (struct iw_thrspy *)extra;	/* set threshold values */	set_quality(&(threshold->low), vap->iv_spy.thr_low, ic->ic_channoise);	set_quality(&(threshold->high), vap->iv_spy.thr_high, ic->ic_channoise);	/* copy results to userspace */	data->length = 1;	return 0;}#endifstatic intieee80211_ioctl_siwmode(struct net_device *dev, struct iw_request_info *info,	__u32 *mode, char *extra){	struct ieee80211vap *vap = netdev_priv(dev);	struct ifmediareq imr;	int valid = 0;	memset(&imr, 0, sizeof(imr));	vap->iv_media.ifm_status(vap->iv_dev, &imr);	if (imr.ifm_active & IFM_IEEE80211_HOSTAP)		valid = (*mode == IW_MODE_MASTER);	else if (imr.ifm_active & IFM_IEEE80211_MONITOR)		valid = (*mode == IW_MODE_MONITOR);	else if (imr.ifm_active & IFM_IEEE80211_ADHOC)		valid = (*mode == IW_MODE_ADHOC);	else if (imr.ifm_active & IFM_IEEE80211_WDS)		valid = (*mode == IW_MODE_REPEAT);	else		valid = (*mode == IW_MODE_INFRA);	return valid ? 0 : -EINVAL;}static intieee80211_ioctl_giwmode(struct net_device *dev,	struct iw_request_info *info,	__u32 *mode, char *extra){	struct ieee80211vap *vap = netdev_priv(dev);	struct ifmediareq imr;	memset(&imr, 0, sizeof(imr));	vap->iv_media.ifm_status(vap->iv_dev, &imr);	if (imr.ifm_active & IFM_IEEE80211_HOSTAP)		*mode = IW_MODE_MASTER;	else if (imr.ifm_active & IFM_IEEE80211_MONITOR)		*mode = IW_MODE_MONITOR;	else if (imr.ifm_active & IFM_IEEE80211_ADHOC)		*mode = IW_MODE_ADHOC;	else if (imr.ifm_active & IFM_IEEE80211_WDS)		*mode = IW_MODE_REPEAT;	else		*mode = IW_MODE_INFRA;	return 0;}static intieee80211_ioctl_siwpower(struct net_device *dev, struct iw_request_info *info,	struct iw_param *wrq, char *extra){	struct ieee80211vap *vap = netdev_priv(dev);	struct ieee80211com *ic = vap->iv_ic;	/* XXX: These values, flags, and caps do not seem to be used elsewhere 	 * at all? */	if ((ic->ic_caps & IEEE80211_C_PMGT) == 0)		return -EOPNOTSUPP;	if (wrq->disabled) {		ic->ic_flags &= ~IEEE80211_F_PMGTON;	} else {		switch (wrq->flags & IW_POWER_MODE) {		case IW_POWER_UNICAST_R:		case IW_POWER_ALL_R:		case IW_POWER_ON:			if (wrq->flags & IW_POWER_PERIOD) {				if (IEEE80211_BINTVAL_VALID(wrq->value))					ic->ic_lintval = IEEE80211_MS_TO_TU(wrq->value);				else					return -EINVAL;			}			if (wrq->flags & IW_POWER_TIMEOUT)				ic->ic_holdover = IEEE80211_MS_TO_TU(wrq->value);			ic->ic_flags |= IEEE80211_F_PMGTON;			break;		default:			return -EINVAL;		}	}	return IS_UP(ic->ic_dev) ? ic->ic_reset(ic->ic_dev) : 0;}static intieee80211_ioctl_giwpower(struct net_device *dev, struct iw_request_info *info,	struct iw_param *rrq, char *extra){	struct ieee80211vap *vap = netdev_priv(dev);	struct ieee80211com *ic = vap->iv_ic;	rrq->disabled = (ic->ic_flags & IEEE80211_F_PMGTON) == 0;	if (!rrq->disabled) {		switch (rrq->flags & IW_POWER_TYPE) {		case IW_POWER_TIMEOUT:			rrq->flags = IW_POWER_TIMEOUT;			rrq->value = IEEE80211_TU_TO_MS(ic->ic_holdover);			break;		case IW_POWER_PERIOD:			rrq->flags = IW_POWER_PERIOD;			rrq->value = IEEE80211_TU_TO_MS(ic->ic_lintval);			break;		}		rrq->flags |= IW_POWER_ALL_R;	}	return 0;}static intieee80211_ioctl_siwretry(struct net_device *dev, struct iw_request_info *info,	struct iw_param *rrq, char *extra){	struct ieee80211vap *vap = netdev_priv(dev);	struct ieee80211com *ic = vap->iv_ic;	if (rrq->disabled) {		if (vap->iv_flags & IEEE80211_F_SWRETRY) {			vap->iv_flags &= ~IEEE80211_F_SWRETRY;			goto done;		}		return 0;	}	if ((vap->iv_caps & IEEE80211_C_SWRETRY) == 0)		return -EOPNOTSUPP;	if (rrq->flags == IW_RETRY_LIMIT) {		if (rrq->value >= 0) {			vap->iv_txmin = rrq->value;			vap->iv_txmax = rrq->value;	/* XXX */			vap->iv_txlifetime = 0;		/* XXX */			vap->iv_flags |= IEEE80211_F_SWRETRY;		} else {			vap->iv_flags &= ~IEEE80211_F_SWRETRY;		}		return 0;	}done:	return IS_UP(vap->iv_dev) ? ic->ic_reset(vap->iv_dev) : 0;}static intieee80211_ioctl_giwretry(struct net_device *dev, struct iw_request_info *info,	struct iw_param *rrq, char *extra){	struct ieee80211vap *vap = netdev_priv(dev);	rrq->disabled = (vap->iv_flags & IEEE80211_F_SWRETRY) == 0;	if (!rrq->disabled) {		switch (rrq->flags & IW_RETRY_TYPE) {		case IW_RETRY_LIFETIME:			rrq->flags = IW_RETRY_LIFETIME;			rrq->value = IEEE80211_TU_TO_MS(vap->iv_txlifetime);			break;		case IW_RETRY_LIMIT:			rrq->flags = IW_RETRY_LIMIT;			switch (rrq->flags & IW_RETRY_MODIFIER) {			case IW_RETRY_MIN:				rrq->flags |= IW_RETRY_MAX;				rrq->value = vap->iv_txmin;				break;			case IW_RETRY_MAX:				rrq->flags |= IW_RETRY_MAX;				rrq->value = vap->iv_txmax;				break;			}			break;		}	}	return 0;}static intieee80211_ioctl_siwtxpow(struct net_device *dev, struct iw_request_info *info,	struct iw_param *rrq, char *extra){	struct ieee80211vap *vap = netdev_priv(dev);	struct ieee80211com *ic = vap->iv_ic;	int fixed, disabled;	fixed = (ic->ic_flags & IEEE80211_F_TXPOW_FIXED);	disabled = (fixed && vap->iv_bss->ni_txpower == 0);	if (rrq->disabled) {		if (!disabled) {			if ((ic->ic_caps & IEEE80211_C_TXPMGT) == 0)				return -EOPNOTSUPP;			ic->ic_flags |= IEEE80211_F_TXPOW_FIXED;			vap->iv_bss->ni_txpower = 0;			goto done;		}		return 0;	}	if (rrq->fixed) {		if ((ic->ic_caps & IEEE80211_C_TXPMGT) == 0)			return -EOPNOTSUPP;		if (rrq->flags != IW_TXPOW_DBM)			return -EINVAL;		if (ic->ic_bsschan != IEEE80211_CHAN_ANYC) {			if ((ic->ic_bsschan->ic_maxregpower >= rrq->value) &&			    (ic->ic_txpowlimit/2 >= rrq->value)) {				vap->iv_bss->ni_txpower = 2 * rrq->value;				ic->ic_newtxpowlimit = 2 * rrq->value;				ic->ic_flags |= IEEE80211_F_TXPOW_FIXED;			} else				return -EINVAL;		} else {			/*			 * No channel set yet

⌨️ 快捷键说明

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