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

📄 wext.c

📁 linux内核源码
💻 C
📖 第 1 页 / 共 4 页
字号:
   Infra 	     		    	B(4)	G(12)   Adhoc 	      		    	B(4)	B(4) *//** *  @brief Get Range Info * *  @param dev                  A pointer to net_device structure *  @param info			A pointer to iw_request_info structure *  @param vwrq 		A pointer to iw_param structure *  @param extra		A pointer to extra data buf *  @return 	   		0 --success, otherwise fail */static int wlan_get_range(struct net_device *dev, struct iw_request_info *info,			  struct iw_point *dwrq, char *extra){	int i, j;	wlan_private *priv = dev->priv;	wlan_adapter *adapter = priv->adapter;	struct iw_range *range = (struct iw_range *)extra;	struct chan_freq_power *cfp;	u8 rates[MAX_RATES + 1];	u8 flag = 0;	lbs_deb_enter(LBS_DEB_WEXT);	dwrq->length = sizeof(struct iw_range);	memset(range, 0, sizeof(struct iw_range));	range->min_nwid = 0;	range->max_nwid = 0;	memset(rates, 0, sizeof(rates));	copy_active_data_rates(adapter, rates);	range->num_bitrates = strnlen(rates, IW_MAX_BITRATES);	for (i = 0; i < range->num_bitrates; i++)		range->bitrate[i] = rates[i] * 500000;	range->num_bitrates = i;	lbs_deb_wext("IW_MAX_BITRATES %d, num_bitrates %d\n", IW_MAX_BITRATES,	       range->num_bitrates);	range->num_frequency = 0;	if (priv->adapter->enable11d &&	    adapter->connect_status == LIBERTAS_CONNECTED) {		u8 chan_no;		u8 band;		struct parsed_region_chan_11d *parsed_region_chan =		    &adapter->parsed_region_chan;		if (parsed_region_chan == NULL) {			lbs_deb_wext("11d: parsed_region_chan is NULL\n");			goto out;		}		band = parsed_region_chan->band;		lbs_deb_wext("band %d, nr_char %d\n", band,		       parsed_region_chan->nr_chan);		for (i = 0; (range->num_frequency < IW_MAX_FREQUENCIES)		     && (i < parsed_region_chan->nr_chan); i++) {			chan_no = parsed_region_chan->chanpwr[i].chan;			lbs_deb_wext("chan_no %d\n", chan_no);			range->freq[range->num_frequency].i = (long)chan_no;			range->freq[range->num_frequency].m =			    (long)libertas_chan_2_freq(chan_no, band) * 100000;			range->freq[range->num_frequency].e = 1;			range->num_frequency++;		}		flag = 1;	}	if (!flag) {		for (j = 0; (range->num_frequency < IW_MAX_FREQUENCIES)		     && (j < sizeof(adapter->region_channel)			 / sizeof(adapter->region_channel[0])); j++) {			cfp = adapter->region_channel[j].CFP;			for (i = 0; (range->num_frequency < IW_MAX_FREQUENCIES)			     && adapter->region_channel[j].valid			     && cfp			     && (i < adapter->region_channel[j].nrcfp); i++) {				range->freq[range->num_frequency].i =				    (long)cfp->channel;				range->freq[range->num_frequency].m =				    (long)cfp->freq * 100000;				range->freq[range->num_frequency].e = 1;				cfp++;				range->num_frequency++;			}		}	}	lbs_deb_wext("IW_MAX_FREQUENCIES %d, num_frequency %d\n",	       IW_MAX_FREQUENCIES, range->num_frequency);	range->num_channels = range->num_frequency;	sort_channels(&range->freq[0], range->num_frequency);	/*	 * Set an indication of the max TCP throughput in bit/s that we can	 * expect using this interface	 */	if (i > 2)		range->throughput = 5000 * 1000;	else		range->throughput = 1500 * 1000;	range->min_rts = MRVDRV_RTS_MIN_VALUE;	range->max_rts = MRVDRV_RTS_MAX_VALUE;	range->min_frag = MRVDRV_FRAG_MIN_VALUE;	range->max_frag = MRVDRV_FRAG_MAX_VALUE;	range->encoding_size[0] = 5;	range->encoding_size[1] = 13;	range->num_encoding_sizes = 2;	range->max_encoding_tokens = 4;	range->min_pmp = 1000000;	range->max_pmp = 120000000;	range->min_pmt = 1000;	range->max_pmt = 1000000;	range->pmp_flags = IW_POWER_PERIOD;	range->pmt_flags = IW_POWER_TIMEOUT;	range->pm_capa = IW_POWER_PERIOD | IW_POWER_TIMEOUT | IW_POWER_ALL_R;	/*	 * Minimum version we recommend	 */	range->we_version_source = 15;	/*	 * Version we are compiled with	 */	range->we_version_compiled = WIRELESS_EXT;	range->retry_capa = IW_RETRY_LIMIT;	range->retry_flags = IW_RETRY_LIMIT | IW_RETRY_MAX;	range->min_retry = TX_RETRY_MIN;	range->max_retry = TX_RETRY_MAX;	/*	 * Set the qual, level and noise range values	 */	range->max_qual.qual = 100;	range->max_qual.level = 0;	range->max_qual.noise = 0;	range->max_qual.updated = IW_QUAL_ALL_UPDATED | IW_QUAL_DBM;	range->avg_qual.qual = 70;	/* TODO: Find real 'good' to 'bad' threshold value for RSSI */	range->avg_qual.level = 0;	range->avg_qual.noise = 0;	range->avg_qual.updated = IW_QUAL_ALL_UPDATED | IW_QUAL_DBM;	range->sensitivity = 0;	/*	 * Setup the supported power level ranges	 */	memset(range->txpower, 0, sizeof(range->txpower));	range->txpower[0] = 5;	range->txpower[1] = 7;	range->txpower[2] = 9;	range->txpower[3] = 11;	range->txpower[4] = 13;	range->txpower[5] = 15;	range->txpower[6] = 17;	range->txpower[7] = 19;	range->num_txpower = 8;	range->txpower_capa = IW_TXPOW_DBM;	range->txpower_capa |= IW_TXPOW_RANGE;	range->event_capa[0] = (IW_EVENT_CAPA_K_0 |				IW_EVENT_CAPA_MASK(SIOCGIWAP) |				IW_EVENT_CAPA_MASK(SIOCGIWSCAN));	range->event_capa[1] = IW_EVENT_CAPA_K_1;	if (adapter->fwcapinfo & FW_CAPINFO_WPA) {		range->enc_capa =   IW_ENC_CAPA_WPA		                  | IW_ENC_CAPA_WPA2		                  | IW_ENC_CAPA_CIPHER_TKIP		                  | IW_ENC_CAPA_CIPHER_CCMP;	}out:	lbs_deb_leave(LBS_DEB_WEXT);	return 0;}static int wlan_set_power(struct net_device *dev, struct iw_request_info *info,			  struct iw_param *vwrq, char *extra){	wlan_private *priv = dev->priv;	wlan_adapter *adapter = priv->adapter;	lbs_deb_enter(LBS_DEB_WEXT);	/* PS is currently supported only in Infrastructure mode	 * Remove this check if it is to be supported in IBSS mode also	 */	if (vwrq->disabled) {		adapter->psmode = WLAN802_11POWERMODECAM;		if (adapter->psstate != PS_STATE_FULL_POWER) {			libertas_ps_wakeup(priv, CMD_OPTION_WAITFORRSP);		}		return 0;	}	if ((vwrq->flags & IW_POWER_TYPE) == IW_POWER_TIMEOUT) {		lbs_deb_wext(		       "setting power timeout is not supported\n");		return -EINVAL;	} else if ((vwrq->flags & IW_POWER_TYPE) == IW_POWER_PERIOD) {		lbs_deb_wext("setting power period not supported\n");		return -EINVAL;	}	if (adapter->psmode != WLAN802_11POWERMODECAM) {		return 0;	}	adapter->psmode = WLAN802_11POWERMODEMAX_PSP;	if (adapter->connect_status == LIBERTAS_CONNECTED) {		libertas_ps_sleep(priv, CMD_OPTION_WAITFORRSP);	}	lbs_deb_leave(LBS_DEB_WEXT);	return 0;}static int wlan_get_power(struct net_device *dev, struct iw_request_info *info,			  struct iw_param *vwrq, char *extra){	wlan_private *priv = dev->priv;	wlan_adapter *adapter = priv->adapter;	int mode;	lbs_deb_enter(LBS_DEB_WEXT);	mode = adapter->psmode;	if ((vwrq->disabled = (mode == WLAN802_11POWERMODECAM))	    || adapter->connect_status == LIBERTAS_DISCONNECTED)	{		goto out;	}	vwrq->value = 0;out:	lbs_deb_leave(LBS_DEB_WEXT);	return 0;}static struct iw_statistics *wlan_get_wireless_stats(struct net_device *dev){	enum {		POOR = 30,		FAIR = 60,		GOOD = 80,		VERY_GOOD = 90,		EXCELLENT = 95,		PERFECT = 100	};	wlan_private *priv = dev->priv;	wlan_adapter *adapter = priv->adapter;	u32 rssi_qual;	u32 tx_qual;	u32 quality = 0;	int stats_valid = 0;	u8 rssi;	u32 tx_retries;	lbs_deb_enter(LBS_DEB_WEXT);	priv->wstats.status = adapter->mode;	/* If we're not associated, all quality values are meaningless */	if (adapter->connect_status != LIBERTAS_CONNECTED)		goto out;	/* Quality by RSSI */	priv->wstats.qual.level =	    CAL_RSSI(adapter->SNR[TYPE_BEACON][TYPE_NOAVG],	     adapter->NF[TYPE_BEACON][TYPE_NOAVG]);	if (adapter->NF[TYPE_BEACON][TYPE_NOAVG] == 0) {		priv->wstats.qual.noise = MRVDRV_NF_DEFAULT_SCAN_VALUE;	} else {		priv->wstats.qual.noise =		    CAL_NF(adapter->NF[TYPE_BEACON][TYPE_NOAVG]);	}	lbs_deb_wext("signal level %#x\n", priv->wstats.qual.level);	lbs_deb_wext("noise %#x\n", priv->wstats.qual.noise);	rssi = priv->wstats.qual.level - priv->wstats.qual.noise;	if (rssi < 15)		rssi_qual = rssi * POOR / 10;	else if (rssi < 20)		rssi_qual = (rssi - 15) * (FAIR - POOR) / 5 + POOR;	else if (rssi < 30)		rssi_qual = (rssi - 20) * (GOOD - FAIR) / 5 + FAIR;	else if (rssi < 40)		rssi_qual = (rssi - 30) * (VERY_GOOD - GOOD) /		    10 + GOOD;	else		rssi_qual = (rssi - 40) * (PERFECT - VERY_GOOD) /		    10 + VERY_GOOD;	quality = rssi_qual;	/* Quality by TX errors */	priv->wstats.discard.retries = priv->stats.tx_errors;	tx_retries = le32_to_cpu(adapter->logmsg.retry);	if (tx_retries > 75)		tx_qual = (90 - tx_retries) * POOR / 15;	else if (tx_retries > 70)		tx_qual = (75 - tx_retries) * (FAIR - POOR) / 5 + POOR;	else if (tx_retries > 65)		tx_qual = (70 - tx_retries) * (GOOD - FAIR) / 5 + FAIR;	else if (tx_retries > 50)		tx_qual = (65 - tx_retries) * (VERY_GOOD - GOOD) /		    15 + GOOD;	else		tx_qual = (50 - tx_retries) *		    (PERFECT - VERY_GOOD) / 50 + VERY_GOOD;	quality = min(quality, tx_qual);	priv->wstats.discard.code = le32_to_cpu(adapter->logmsg.wepundecryptable);	priv->wstats.discard.fragment = le32_to_cpu(adapter->logmsg.rxfrag);	priv->wstats.discard.retries = tx_retries;	priv->wstats.discard.misc = le32_to_cpu(adapter->logmsg.ackfailure);	/* Calculate quality */	priv->wstats.qual.qual = min_t(u8, quality, 100);	priv->wstats.qual.updated = IW_QUAL_ALL_UPDATED | IW_QUAL_DBM;	stats_valid = 1;	/* update stats asynchronously for future calls */	libertas_prepare_and_send_command(priv, CMD_802_11_RSSI, 0,					0, 0, NULL);	libertas_prepare_and_send_command(priv, CMD_802_11_GET_LOG, 0,					0, 0, NULL);out:	if (!stats_valid) {		priv->wstats.miss.beacon = 0;		priv->wstats.discard.retries = 0;		priv->wstats.qual.qual = 0;		priv->wstats.qual.level = 0;		priv->wstats.qual.noise = 0;		priv->wstats.qual.updated = IW_QUAL_ALL_UPDATED;		priv->wstats.qual.updated |= IW_QUAL_NOISE_INVALID |		    IW_QUAL_QUAL_INVALID | IW_QUAL_LEVEL_INVALID;	}	lbs_deb_leave(LBS_DEB_WEXT);	return &priv->wstats;}static int wlan_set_freq(struct net_device *dev, struct iw_request_info *info,		  struct iw_freq *fwrq, char *extra){	int ret = -EINVAL;	wlan_private *priv = dev->priv;	wlan_adapter *adapter = priv->adapter;	struct chan_freq_power *cfp;	struct assoc_request * assoc_req;	lbs_deb_enter(LBS_DEB_WEXT);	mutex_lock(&adapter->lock);	assoc_req = wlan_get_association_request(adapter);	if (!assoc_req) {		ret = -ENOMEM;		goto out;	}	/* If setting by frequency, convert to a channel */	if (fwrq->e == 1) {		long f = fwrq->m / 100000;		cfp = find_cfp_by_band_and_freq(adapter, 0, f);		if (!cfp) {			lbs_deb_wext("invalid freq %ld\n", f);			goto out;		}		fwrq->e = 0;		fwrq->m = (int) cfp->channel;	}	/* Setting by channel number */	if (fwrq->m > 1000 || fwrq->e > 0) {		goto out;	}	cfp = libertas_find_cfp_by_band_and_channel(adapter, 0, fwrq->m);	if (!cfp) {		goto out;	}	assoc_req->channel = fwrq->m;	ret = 0;out:	if (ret == 0) {		set_bit(ASSOC_FLAG_CHANNEL, &assoc_req->flags);		wlan_postpone_association_work(priv);	} else {		wlan_cancel_association_work(priv);	}	mutex_unlock(&adapter->lock);	lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret);	return ret;}static int wlan_set_rate(struct net_device *dev, struct iw_request_info *info,		  struct iw_param *vwrq, char *extra){	wlan_private *priv = dev->priv;	wlan_adapter *adapter = priv->adapter;	u32 new_rate;	u16 action;	int ret = -EINVAL;	u8 rates[MAX_RATES + 1];	lbs_deb_enter(LBS_DEB_WEXT);	lbs_deb_wext("vwrq->value %d\n", vwrq->value);	/* Auto rate? */	if (vwrq->value == -1) {		action = CMD_ACT_SET_TX_AUTO;		adapter->auto_rate = 1;		adapter->cur_rate = 0;	} else {		if (vwrq->value % 100000)			goto out;		memset(rates, 0, sizeof(rates));		copy_active_data_rates(adapter, rates);		new_rate = vwrq->value / 500000;		if (!memchr(rates, new_rate, sizeof(rates))) {			lbs_pr_alert("fixed data rate 0x%X out of range\n",				new_rate);			goto out;		}		adapter->cur_rate = new_rate;		action = CMD_ACT_SET_TX_FIX_RATE;		adapter->auto_rate = 0;	}	ret = libertas_prepare_and_send_command(priv, CMD_802_11_DATA_RATE,				    action, CMD_OPTION_WAITFORRSP, 0, NULL);out:	lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret);	return ret;}static int wlan_get_rate(struct net_device *dev, struct iw_request_info *info,		  struct iw_param *vwrq, char *extra){	wlan_private *priv = dev->priv;	wlan_adapter *adapter = priv->adapter;	lbs_deb_enter(LBS_DEB_WEXT);	if (adapter->connect_status == LIBERTAS_CONNECTED) {		vwrq->value = adapter->cur_rate * 500000;		if (adapter->auto_rate)			vwrq->fixed = 0;		else			vwrq->fixed = 1;	} else {		vwrq->fixed = 0;		vwrq->value = 0;	}	lbs_deb_leave(LBS_DEB_WEXT);	return 0;}static int wlan_set_mode(struct net_device *dev,		  struct iw_request_info *info, u32 * uwrq, char *extra){	int ret = 0;	wlan_private *priv = dev->priv;	wlan_adapter *adapter = priv->adapter;	struct assoc_request * assoc_req;	lbs_deb_enter(LBS_DEB_WEXT);	if (   (*uwrq != IW_MODE_ADHOC)	    && (*uwrq != IW_MODE_INFRA)	    && (*uwrq != IW_MODE_AUTO)) {		lbs_deb_wext("Invalid mode: 0x%x\n", *uwrq);		ret = -EINVAL;		goto out;	}	mutex_lock(&adapter->lock);	assoc_req = wlan_get_association_request(adapter);	if (!assoc_req) {		ret = -ENOMEM;		wlan_cancel_association_work(priv);	} else {		assoc_req->mode = *uwrq;		set_bit(ASSOC_FLAG_MODE, &assoc_req->flags);		wlan_postpone_association_work(priv);		lbs_deb_wext("Switching to mode: 0x%x\n", *uwrq);	}	mutex_unlock(&adapter->lock);out:	lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret);	return ret;}/** *  @brief Get Encryption key * *  @param dev                  A pointer to net_device structure *  @param info			A pointer to iw_request_info structure

⌨️ 快捷键说明

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