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

📄 wext.c

📁 linux内核源码
💻 C
📖 第 1 页 / 共 4 页
字号:
/**  * This file contains ioctl functions  */#include <linux/ctype.h>#include <linux/delay.h>#include <linux/if.h>#include <linux/if_arp.h>#include <linux/wireless.h>#include <linux/bitops.h>#include <net/ieee80211.h>#include <net/iw_handler.h>#include "host.h"#include "radiotap.h"#include "decl.h"#include "defs.h"#include "dev.h"#include "join.h"#include "wext.h"#include "assoc.h"/** *  @brief Find the channel frequency power info with specific channel * *  @param adapter 	A pointer to wlan_adapter structure *  @param band		it can be BAND_A, BAND_G or BAND_B *  @param channel      the channel for looking *  @return 	   	A pointer to struct chan_freq_power structure or NULL if not find. */struct chan_freq_power *libertas_find_cfp_by_band_and_channel(wlan_adapter * adapter,						 u8 band, u16 channel){	struct chan_freq_power *cfp = NULL;	struct region_channel *rc;	int count = sizeof(adapter->region_channel) /	    sizeof(adapter->region_channel[0]);	int i, j;	for (j = 0; !cfp && (j < count); j++) {		rc = &adapter->region_channel[j];		if (adapter->enable11d)			rc = &adapter->universal_channel[j];		if (!rc->valid || !rc->CFP)			continue;		if (rc->band != band)			continue;		for (i = 0; i < rc->nrcfp; i++) {			if (rc->CFP[i].channel == channel) {				cfp = &rc->CFP[i];				break;			}		}	}	if (!cfp && channel)		lbs_deb_wext("libertas_find_cfp_by_band_and_channel: can't find "		       "cfp by band %d / channel %d\n", band, channel);	return cfp;}/** *  @brief Find the channel frequency power info with specific frequency * *  @param adapter 	A pointer to wlan_adapter structure *  @param band		it can be BAND_A, BAND_G or BAND_B *  @param freq	        the frequency for looking *  @return 	   	A pointer to struct chan_freq_power structure or NULL if not find. */static struct chan_freq_power *find_cfp_by_band_and_freq(wlan_adapter * adapter,						     u8 band, u32 freq){	struct chan_freq_power *cfp = NULL;	struct region_channel *rc;	int count = sizeof(adapter->region_channel) /	    sizeof(adapter->region_channel[0]);	int i, j;	for (j = 0; !cfp && (j < count); j++) {		rc = &adapter->region_channel[j];		if (adapter->enable11d)			rc = &adapter->universal_channel[j];		if (!rc->valid || !rc->CFP)			continue;		if (rc->band != band)			continue;		for (i = 0; i < rc->nrcfp; i++) {			if (rc->CFP[i].freq == freq) {				cfp = &rc->CFP[i];				break;			}		}	}	if (!cfp && freq)		lbs_deb_wext("find_cfp_by_band_and_freql: can't find cfp by "		       "band %d / freq %d\n", band, freq);	return cfp;}/** *  @brief Set Radio On/OFF * *  @param priv                 A pointer to wlan_private structure *  @option 			Radio Option *  @return 	   		0 --success, otherwise fail */static int wlan_radio_ioctl(wlan_private * priv, u8 option){	int ret = 0;	wlan_adapter *adapter = priv->adapter;	lbs_deb_enter(LBS_DEB_WEXT);	if (adapter->radioon != option) {		lbs_deb_wext("switching radio %s\n", option ? "on" : "off");		adapter->radioon = option;		ret = libertas_prepare_and_send_command(priv,					    CMD_802_11_RADIO_CONTROL,					    CMD_ACT_SET,					    CMD_OPTION_WAITFORRSP, 0, NULL);	}	lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret);	return ret;}/** *  @brief Copy active data rates based on adapter mode and status * *  @param adapter              A pointer to wlan_adapter structure *  @param rate		        The buf to return the active rates */static void copy_active_data_rates(wlan_adapter * adapter, u8 * rates){	lbs_deb_enter(LBS_DEB_WEXT);	if (adapter->connect_status != LIBERTAS_CONNECTED)		memcpy(rates, libertas_bg_rates, MAX_RATES);	else		memcpy(rates, adapter->curbssparams.rates, MAX_RATES);	lbs_deb_leave(LBS_DEB_WEXT);}static int wlan_get_name(struct net_device *dev, struct iw_request_info *info,			 char *cwrq, char *extra){	lbs_deb_enter(LBS_DEB_WEXT);	/* We could add support for 802.11n here as needed. Jean II */	snprintf(cwrq, IFNAMSIZ, "IEEE 802.11b/g");	lbs_deb_leave(LBS_DEB_WEXT);	return 0;}static int wlan_get_freq(struct net_device *dev, struct iw_request_info *info,			 struct iw_freq *fwrq, char *extra){	wlan_private *priv = dev->priv;	wlan_adapter *adapter = priv->adapter;	struct chan_freq_power *cfp;	lbs_deb_enter(LBS_DEB_WEXT);	cfp = libertas_find_cfp_by_band_and_channel(adapter, 0,					   adapter->curbssparams.channel);	if (!cfp) {		if (adapter->curbssparams.channel)			lbs_deb_wext("invalid channel %d\n",			       adapter->curbssparams.channel);		return -EINVAL;	}	fwrq->m = (long)cfp->freq * 100000;	fwrq->e = 1;	lbs_deb_wext("freq %u\n", fwrq->m);	lbs_deb_leave(LBS_DEB_WEXT);	return 0;}static int wlan_get_wap(struct net_device *dev, struct iw_request_info *info,			struct sockaddr *awrq, char *extra){	wlan_private *priv = dev->priv;	wlan_adapter *adapter = priv->adapter;	lbs_deb_enter(LBS_DEB_WEXT);	if (adapter->connect_status == LIBERTAS_CONNECTED) {		memcpy(awrq->sa_data, adapter->curbssparams.bssid, ETH_ALEN);	} else {		memset(awrq->sa_data, 0, ETH_ALEN);	}	awrq->sa_family = ARPHRD_ETHER;	lbs_deb_leave(LBS_DEB_WEXT);	return 0;}static int wlan_set_nick(struct net_device *dev, struct iw_request_info *info,			 struct iw_point *dwrq, char *extra){	wlan_private *priv = dev->priv;	wlan_adapter *adapter = priv->adapter;	lbs_deb_enter(LBS_DEB_WEXT);	/*	 * Check the size of the string	 */	if (dwrq->length > 16) {		return -E2BIG;	}	mutex_lock(&adapter->lock);	memset(adapter->nodename, 0, sizeof(adapter->nodename));	memcpy(adapter->nodename, extra, dwrq->length);	mutex_unlock(&adapter->lock);	lbs_deb_leave(LBS_DEB_WEXT);	return 0;}static int wlan_get_nick(struct net_device *dev, struct iw_request_info *info,			 struct iw_point *dwrq, char *extra){	wlan_private *priv = dev->priv;	wlan_adapter *adapter = priv->adapter;	lbs_deb_enter(LBS_DEB_WEXT);	dwrq->length = strlen(adapter->nodename);	memcpy(extra, adapter->nodename, dwrq->length);	extra[dwrq->length] = '\0';	dwrq->flags = 1;	/* active */	lbs_deb_leave(LBS_DEB_WEXT);	return 0;}static int mesh_get_nick(struct net_device *dev, struct iw_request_info *info,			 struct iw_point *dwrq, char *extra){	wlan_private *priv = dev->priv;	wlan_adapter *adapter = priv->adapter;	lbs_deb_enter(LBS_DEB_WEXT);	/* Use nickname to indicate that mesh is on */	if (adapter->connect_status == LIBERTAS_CONNECTED) {		strncpy(extra, "Mesh", 12);		extra[12] = '\0';		dwrq->length = strlen(extra);	}	else {		extra[0] = '\0';		dwrq->length = 0;	}	lbs_deb_leave(LBS_DEB_WEXT);	return 0;}static int wlan_set_rts(struct net_device *dev, struct iw_request_info *info,			struct iw_param *vwrq, char *extra){	int ret = 0;	wlan_private *priv = dev->priv;	wlan_adapter *adapter = priv->adapter;	u32 rthr = vwrq->value;	lbs_deb_enter(LBS_DEB_WEXT);	if (vwrq->disabled) {		adapter->rtsthsd = rthr = MRVDRV_RTS_MAX_VALUE;	} else {		if (rthr < MRVDRV_RTS_MIN_VALUE || rthr > MRVDRV_RTS_MAX_VALUE)			return -EINVAL;		adapter->rtsthsd = rthr;	}	ret = libertas_prepare_and_send_command(priv, CMD_802_11_SNMP_MIB,				    CMD_ACT_SET, CMD_OPTION_WAITFORRSP,				    OID_802_11_RTS_THRESHOLD, &rthr);	lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret);	return ret;}static int wlan_get_rts(struct net_device *dev, struct iw_request_info *info,			struct iw_param *vwrq, char *extra){	int ret = 0;	wlan_private *priv = dev->priv;	wlan_adapter *adapter = priv->adapter;	lbs_deb_enter(LBS_DEB_WEXT);	adapter->rtsthsd = 0;	ret = libertas_prepare_and_send_command(priv, CMD_802_11_SNMP_MIB,				    CMD_ACT_GET, CMD_OPTION_WAITFORRSP,				    OID_802_11_RTS_THRESHOLD, NULL);	if (ret)		goto out;	vwrq->value = adapter->rtsthsd;	vwrq->disabled = ((vwrq->value < MRVDRV_RTS_MIN_VALUE)			  || (vwrq->value > MRVDRV_RTS_MAX_VALUE));	vwrq->fixed = 1;out:	lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret);	return ret;}static int wlan_set_frag(struct net_device *dev, struct iw_request_info *info,			 struct iw_param *vwrq, char *extra){	int ret = 0;	u32 fthr = vwrq->value;	wlan_private *priv = dev->priv;	wlan_adapter *adapter = priv->adapter;	lbs_deb_enter(LBS_DEB_WEXT);	if (vwrq->disabled) {		adapter->fragthsd = fthr = MRVDRV_FRAG_MAX_VALUE;	} else {		if (fthr < MRVDRV_FRAG_MIN_VALUE		    || fthr > MRVDRV_FRAG_MAX_VALUE)			return -EINVAL;		adapter->fragthsd = fthr;	}	ret = libertas_prepare_and_send_command(priv, CMD_802_11_SNMP_MIB,				    CMD_ACT_SET, CMD_OPTION_WAITFORRSP,				    OID_802_11_FRAGMENTATION_THRESHOLD, &fthr);	lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret);	return ret;}static int wlan_get_frag(struct net_device *dev, struct iw_request_info *info,			 struct iw_param *vwrq, char *extra){	int ret = 0;	wlan_private *priv = dev->priv;	wlan_adapter *adapter = priv->adapter;	lbs_deb_enter(LBS_DEB_WEXT);	adapter->fragthsd = 0;	ret = libertas_prepare_and_send_command(priv,				    CMD_802_11_SNMP_MIB,				    CMD_ACT_GET, CMD_OPTION_WAITFORRSP,				    OID_802_11_FRAGMENTATION_THRESHOLD, NULL);	if (ret)		goto out;	vwrq->value = adapter->fragthsd;	vwrq->disabled = ((vwrq->value < MRVDRV_FRAG_MIN_VALUE)			  || (vwrq->value > MRVDRV_FRAG_MAX_VALUE));	vwrq->fixed = 1;out:	lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret);	return ret;}static int wlan_get_mode(struct net_device *dev,			 struct iw_request_info *info, u32 * uwrq, char *extra){	wlan_private *priv = dev->priv;	wlan_adapter *adapter = priv->adapter;	lbs_deb_enter(LBS_DEB_WEXT);	*uwrq = adapter->mode;	lbs_deb_leave(LBS_DEB_WEXT);	return 0;}static int mesh_wlan_get_mode(struct net_device *dev,		              struct iw_request_info *info, u32 * uwrq,			      char *extra){	lbs_deb_enter(LBS_DEB_WEXT);	*uwrq = IW_MODE_REPEAT ;	lbs_deb_leave(LBS_DEB_WEXT);	return 0;}static int wlan_get_txpow(struct net_device *dev,			  struct iw_request_info *info,			  struct iw_param *vwrq, char *extra){	int ret = 0;	wlan_private *priv = dev->priv;	wlan_adapter *adapter = priv->adapter;	lbs_deb_enter(LBS_DEB_WEXT);	ret = libertas_prepare_and_send_command(priv,				    CMD_802_11_RF_TX_POWER,				    CMD_ACT_TX_POWER_OPT_GET,				    CMD_OPTION_WAITFORRSP, 0, NULL);	if (ret)		goto out;	lbs_deb_wext("tx power level %d dbm\n", adapter->txpowerlevel);	vwrq->value = adapter->txpowerlevel;	vwrq->fixed = 1;	if (adapter->radioon) {		vwrq->disabled = 0;		vwrq->flags = IW_TXPOW_DBM;	} else {		vwrq->disabled = 1;	}out:	lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret);	return ret;}static int wlan_set_retry(struct net_device *dev, struct iw_request_info *info,			  struct iw_param *vwrq, char *extra){	int ret = 0;	wlan_private *priv = dev->priv;	wlan_adapter *adapter = priv->adapter;	lbs_deb_enter(LBS_DEB_WEXT);	if (vwrq->flags == IW_RETRY_LIMIT) {		/* The MAC has a 4-bit Total_Tx_Count register		   Total_Tx_Count = 1 + Tx_Retry_Count */#define TX_RETRY_MIN 0#define TX_RETRY_MAX 14		if (vwrq->value < TX_RETRY_MIN || vwrq->value > TX_RETRY_MAX)			return -EINVAL;		/* Adding 1 to convert retry count to try count */		adapter->txretrycount = vwrq->value + 1;		ret = libertas_prepare_and_send_command(priv, CMD_802_11_SNMP_MIB,					    CMD_ACT_SET,					    CMD_OPTION_WAITFORRSP,					    OID_802_11_TX_RETRYCOUNT, NULL);		if (ret)			goto out;	} else {		return -EOPNOTSUPP;	}out:	lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret);	return ret;}static int wlan_get_retry(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 ret = 0;	lbs_deb_enter(LBS_DEB_WEXT);	adapter->txretrycount = 0;	ret = libertas_prepare_and_send_command(priv,				    CMD_802_11_SNMP_MIB,				    CMD_ACT_GET, CMD_OPTION_WAITFORRSP,				    OID_802_11_TX_RETRYCOUNT, NULL);	if (ret)		goto out;	vwrq->disabled = 0;	if (!vwrq->flags) {		vwrq->flags = IW_RETRY_LIMIT;		/* Subtract 1 to convert try count to retry count */		vwrq->value = adapter->txretrycount - 1;	}out:	lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret);	return ret;}static inline void sort_channels(struct iw_freq *freq, int num){	int i, j;	struct iw_freq temp;	for (i = 0; i < num; i++)		for (j = i + 1; j < num; j++)			if (freq[i].i > freq[j].i) {				temp.i = freq[i].i;				temp.m = freq[i].m;				freq[i].i = freq[j].i;				freq[i].m = freq[j].m;				freq[j].i = temp.i;				freq[j].m = temp.m;			}}/* data rate listing	MULTI_BANDS:		abg		a	b	b/g   Infra 	G(12)		A(8)	B(4)	G(12)   Adhoc 	A+B(12)		A(8)	B(4)	B(4)	non-MULTI_BANDS:					b	b/g

⌨️ 快捷键说明

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