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

📄 isl_ioctl.c

📁 linux内核源码
💻 C
📖 第 1 页 / 共 5 页
字号:
	return rvalue;}/* Set AP address*/static intprism54_set_wap(struct net_device *ndev, struct iw_request_info *info,		struct sockaddr *awrq, char *extra){	islpci_private *priv = netdev_priv(ndev);	char bssid[6];	int rvalue;	if (awrq->sa_family != ARPHRD_ETHER)		return -EINVAL;	/* prepare the structure for the set object */	memcpy(&bssid[0], awrq->sa_data, 6);	/* set the bssid -- does this make sense when in AP mode? */	rvalue = mgt_set_request(priv, DOT11_OID_BSSID, 0, &bssid);	return (rvalue ? rvalue : -EINPROGRESS);	/* Call commit handler */}/* get AP address*/static intprism54_get_wap(struct net_device *ndev, struct iw_request_info *info,		struct sockaddr *awrq, char *extra){	islpci_private *priv = netdev_priv(ndev);	union oid_res_t r;	int rvalue;	rvalue = mgt_get_request(priv, DOT11_OID_BSSID, 0, NULL, &r);	memcpy(awrq->sa_data, r.ptr, 6);	awrq->sa_family = ARPHRD_ETHER;	kfree(r.ptr);	return rvalue;}static intprism54_set_scan(struct net_device *dev, struct iw_request_info *info,		 struct iw_param *vwrq, char *extra){	/* hehe the device does this automagicaly */	return 0;}/* a little helper that will translate our data into a card independent * format that the Wireless Tools will understand. This was inspired by * the "Aironet driver for 4500 and 4800 series cards" (GPL) */static char *prism54_translate_bss(struct net_device *ndev, char *current_ev,		      char *end_buf, struct obj_bss *bss, char noise){	struct iw_event iwe;	/* Temporary buffer */	short cap;	islpci_private *priv = netdev_priv(ndev);	u8 wpa_ie[MAX_WPA_IE_LEN];	size_t wpa_ie_len;	/* The first entry must be the MAC address */	memcpy(iwe.u.ap_addr.sa_data, bss->address, 6);	iwe.u.ap_addr.sa_family = ARPHRD_ETHER;	iwe.cmd = SIOCGIWAP;	current_ev =	    iwe_stream_add_event(current_ev, end_buf, &iwe, IW_EV_ADDR_LEN);	/* The following entries will be displayed in the same order we give them */	/* The ESSID. */	iwe.u.data.length = bss->ssid.length;	iwe.u.data.flags = 1;	iwe.cmd = SIOCGIWESSID;	current_ev = iwe_stream_add_point(current_ev, end_buf,					  &iwe, bss->ssid.octets);	/* Capabilities */#define CAP_ESS 0x01#define CAP_IBSS 0x02#define CAP_CRYPT 0x10	/* Mode */	cap = bss->capinfo;	iwe.u.mode = 0;	if (cap & CAP_ESS)		iwe.u.mode = IW_MODE_MASTER;	else if (cap & CAP_IBSS)		iwe.u.mode = IW_MODE_ADHOC;	iwe.cmd = SIOCGIWMODE;	if (iwe.u.mode)		current_ev =		    iwe_stream_add_event(current_ev, end_buf, &iwe,					 IW_EV_UINT_LEN);	/* Encryption capability */	if (cap & CAP_CRYPT)		iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;	else		iwe.u.data.flags = IW_ENCODE_DISABLED;	iwe.u.data.length = 0;	iwe.cmd = SIOCGIWENCODE;	current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, NULL);	/* Add frequency. (short) bss->channel is the frequency in MHz */	iwe.u.freq.m = bss->channel;	iwe.u.freq.e = 6;	iwe.cmd = SIOCGIWFREQ;	current_ev =	    iwe_stream_add_event(current_ev, end_buf, &iwe, IW_EV_FREQ_LEN);	/* Add quality statistics */	iwe.u.qual.level = bss->rssi;	iwe.u.qual.noise = noise;	/* do a simple SNR for quality */	iwe.u.qual.qual = bss->rssi - noise;	iwe.cmd = IWEVQUAL;	current_ev =	    iwe_stream_add_event(current_ev, end_buf, &iwe, IW_EV_QUAL_LEN);	/* Add WPA/RSN Information Element, if any */	wpa_ie_len = prism54_wpa_bss_ie_get(priv, bss->address, wpa_ie);	if (wpa_ie_len > 0) {		iwe.cmd = IWEVGENIE;		iwe.u.data.length = min(wpa_ie_len, (size_t)MAX_WPA_IE_LEN);		current_ev = iwe_stream_add_point(current_ev, end_buf,				&iwe, wpa_ie);	}	/* Do the bitrates */	{		char *	current_val = current_ev + IW_EV_LCP_LEN;		int i;		int mask;		iwe.cmd = SIOCGIWRATE;		/* Those two flags are ignored... */		iwe.u.bitrate.fixed = iwe.u.bitrate.disabled = 0;		/* Parse the bitmask */		mask = 0x1;		for(i = 0; i < sizeof(scan_rate_list); i++) {			if(bss->rates & mask) {				iwe.u.bitrate.value = (scan_rate_list[i] * 500000);				current_val = iwe_stream_add_value(current_ev, current_val,								   end_buf, &iwe,								   IW_EV_PARAM_LEN);			}			mask <<= 1;		}		/* Check if we added any event */		if ((current_val - current_ev) > IW_EV_LCP_LEN)			current_ev = current_val;	}	return current_ev;}static intprism54_get_scan(struct net_device *ndev, struct iw_request_info *info,		 struct iw_point *dwrq, char *extra){	islpci_private *priv = netdev_priv(ndev);	int i, rvalue;	struct obj_bsslist *bsslist;	u32 noise = 0;	char *current_ev = extra;	union oid_res_t r;	if (islpci_get_state(priv) < PRV_STATE_INIT) {		/* device is not ready, fail gently */		dwrq->length = 0;		return 0;	}	/* first get the noise value. We will use it to report the link quality */	rvalue = mgt_get_request(priv, DOT11_OID_NOISEFLOOR, 0, NULL, &r);	noise = r.u;	/* Ask the device for a list of known bss.	* The old API, using SIOCGIWAPLIST, had a hard limit of IW_MAX_AP=64.	* The new API, using SIOCGIWSCAN, is only limited by the buffer size.	* WE-14->WE-16, the buffer is limited to IW_SCAN_MAX_DATA bytes.	* Starting with WE-17, the buffer can be as big as needed.	* But the device won't repport anything if you change the value	* of IWMAX_BSS=24. */	rvalue |= mgt_get_request(priv, DOT11_OID_BSSLIST, 0, NULL, &r);	bsslist = r.ptr;	/* ok now, scan the list and translate its info */	for (i = 0; i < (int) bsslist->nr; i++) {		current_ev = prism54_translate_bss(ndev, current_ev,						   extra + dwrq->length,						   &(bsslist->bsslist[i]),						   noise);		/* Check if there is space for one more entry */		if((extra + dwrq->length - current_ev) <= IW_EV_ADDR_LEN) {			/* Ask user space to try again with a bigger buffer */			rvalue = -E2BIG;			break;		}	}	kfree(bsslist);	dwrq->length = (current_ev - extra);	dwrq->flags = 0;	/* todo */	return rvalue;}static intprism54_set_essid(struct net_device *ndev, struct iw_request_info *info,		  struct iw_point *dwrq, char *extra){	islpci_private *priv = netdev_priv(ndev);	struct obj_ssid essid;	memset(essid.octets, 0, 33);	/* Check if we were asked for `any' */	if (dwrq->flags && dwrq->length) {		if (dwrq->length > 32)			return -E2BIG;		essid.length = dwrq->length;		memcpy(essid.octets, extra, dwrq->length);	} else		essid.length = 0;	if (priv->iw_mode != IW_MODE_MONITOR)		return mgt_set_request(priv, DOT11_OID_SSID, 0, &essid);	/* If in monitor mode, just save to mib */	mgt_set(priv, DOT11_OID_SSID, &essid);	return 0;}static intprism54_get_essid(struct net_device *ndev, struct iw_request_info *info,		  struct iw_point *dwrq, char *extra){	islpci_private *priv = netdev_priv(ndev);	struct obj_ssid *essid;	union oid_res_t r;	int rvalue;	rvalue = mgt_get_request(priv, DOT11_OID_SSID, 0, NULL, &r);	essid = r.ptr;	if (essid->length) {		dwrq->flags = 1;	/* set ESSID to ON for Wireless Extensions */		/* if it is too big, trunk it */		dwrq->length = min((u8)IW_ESSID_MAX_SIZE, essid->length);	} else {		dwrq->flags = 0;		dwrq->length = 0;	}	essid->octets[essid->length] = '\0';	memcpy(extra, essid->octets, dwrq->length);	kfree(essid);	return rvalue;}/* Provides no functionality, just completes the ioctl. In essence this is a * just a cosmetic ioctl. */static intprism54_set_nick(struct net_device *ndev, struct iw_request_info *info,		 struct iw_point *dwrq, char *extra){	islpci_private *priv = netdev_priv(ndev);	if (dwrq->length > IW_ESSID_MAX_SIZE)		return -E2BIG;	down_write(&priv->mib_sem);	memset(priv->nickname, 0, sizeof (priv->nickname));	memcpy(priv->nickname, extra, dwrq->length);	up_write(&priv->mib_sem);	return 0;}static intprism54_get_nick(struct net_device *ndev, struct iw_request_info *info,		 struct iw_point *dwrq, char *extra){	islpci_private *priv = netdev_priv(ndev);	dwrq->length = 0;	down_read(&priv->mib_sem);	dwrq->length = strlen(priv->nickname);	memcpy(extra, priv->nickname, dwrq->length);	up_read(&priv->mib_sem);	return 0;}/* Set the allowed Bitrates */static intprism54_set_rate(struct net_device *ndev,		 struct iw_request_info *info,		 struct iw_param *vwrq, char *extra){	islpci_private *priv = netdev_priv(ndev);	u32 rate, profile;	char *data;	int ret, i;	union oid_res_t r;	if (vwrq->value == -1) {		/* auto mode. No limit. */		profile = 1;		return mgt_set_request(priv, DOT11_OID_PROFILES, 0, &profile);	}	ret = mgt_get_request(priv, DOT11_OID_SUPPORTEDRATES, 0, NULL, &r);	if (ret) {		kfree(r.ptr);		return ret;	}	rate = (u32) (vwrq->value / 500000);	data = r.ptr;	i = 0;	while (data[i]) {		if (rate && (data[i] == rate)) {			break;		}		if (vwrq->value == i) {			break;		}		data[i] |= 0x80;		i++;	}	if (!data[i]) {		kfree(r.ptr);		return -EINVAL;	}	data[i] |= 0x80;	data[i + 1] = 0;	/* Now, check if we want a fixed or auto value */	if (vwrq->fixed) {		data[0] = data[i];		data[1] = 0;	}/*	i = 0;	printk("prism54 rate: ");	while(data[i]) {		printk("%u ", data[i]);		i++;	}	printk("0\n");*/	profile = -1;	ret = mgt_set_request(priv, DOT11_OID_PROFILES, 0, &profile);	ret |= mgt_set_request(priv, DOT11_OID_EXTENDEDRATES, 0, data);	ret |= mgt_set_request(priv, DOT11_OID_RATES, 0, data);	kfree(r.ptr);	return ret;}/* Get the current bit rate */static intprism54_get_rate(struct net_device *ndev,		 struct iw_request_info *info,		 struct iw_param *vwrq, char *extra){	islpci_private *priv = netdev_priv(ndev);	int rvalue;	char *data;	union oid_res_t r;	/* Get the current bit rate */	if ((rvalue = mgt_get_request(priv, GEN_OID_LINKSTATE, 0, NULL, &r)))		return rvalue;	vwrq->value = r.u * 500000;	/* request the device for the enabled rates */	rvalue = mgt_get_request(priv, DOT11_OID_RATES, 0, NULL, &r);	if (rvalue) {		kfree(r.ptr);		return rvalue;	}	data = r.ptr;	vwrq->fixed = (data[0] != 0) && (data[1] == 0);	kfree(r.ptr);	return 0;}static intprism54_set_rts(struct net_device *ndev, struct iw_request_info *info,		struct iw_param *vwrq, char *extra){	islpci_private *priv = netdev_priv(ndev);	return mgt_set_request(priv, DOT11_OID_RTSTHRESH, 0, &vwrq->value);}static intprism54_get_rts(struct net_device *ndev, struct iw_request_info *info,		struct iw_param *vwrq, char *extra){	islpci_private *priv = netdev_priv(ndev);	union oid_res_t r;	int rvalue;	/* get the rts threshold */	rvalue = mgt_get_request(priv, DOT11_OID_RTSTHRESH, 0, NULL, &r);	vwrq->value = r.u;	return rvalue;}static intprism54_set_frag(struct net_device *ndev, struct iw_request_info *info,		 struct iw_param *vwrq, char *extra){	islpci_private *priv = netdev_priv(ndev);	return mgt_set_request(priv, DOT11_OID_FRAGTHRESH, 0, &vwrq->value);}static intprism54_get_frag(struct net_device *ndev, struct iw_request_info *info,		 struct iw_param *vwrq, char *extra){	islpci_private *priv = netdev_priv(ndev);	union oid_res_t r;	int rvalue;	rvalue = mgt_get_request(priv, DOT11_OID_FRAGTHRESH, 0, NULL, &r);	vwrq->value = r.u;	return rvalue;}/* Here we have (min,max) = max retries for (small frames, big frames). Where * big frame <=>  bigger than the rts threshold * small frame <=>  smaller than the rts threshold * This is not really the behavior expected by the wireless tool but it seems * to be a common behavior in other drivers. */static intprism54_set_retry(struct net_device *ndev, struct iw_request_info *info,		  struct iw_param *vwrq, char *extra){	islpci_private *priv = netdev_priv(ndev);	u32 slimit = 0, llimit = 0;	/* short and long limit */	u32 lifetime = 0;	int rvalue = 0;	if (vwrq->disabled)		/* we cannot disable this feature */		return -EINVAL;	if (vwrq->flags & IW_RETRY_LIMIT) {		if (vwrq->flags & IW_RETRY_SHORT)			slimit = vwrq->value;		else if (vwrq->flags & IW_RETRY_LONG)			llimit = vwrq->value;		else {			/* we are asked to set both */			slimit = vwrq->value;			llimit = vwrq->value;		}	}	if (vwrq->flags & IW_RETRY_LIFETIME)		/* Wireless tools use us unit while the device uses 1024 us unit */		lifetime = vwrq->value / 1024;	/* now set what is requested */	if (slimit)		rvalue =		    mgt_set_request(priv, DOT11_OID_SHORTRETRIES, 0, &slimit);	if (llimit)		rvalue |=		    mgt_set_request(priv, DOT11_OID_LONGRETRIES, 0, &llimit);	if (lifetime)		rvalue |=		    mgt_set_request(priv, DOT11_OID_MAXTXLIFETIME, 0,				    &lifetime);	return rvalue;}static intprism54_get_retry(struct net_device *ndev, struct iw_request_info *info,		  struct iw_param *vwrq, char *extra){	islpci_private *priv = netdev_priv(ndev);	union oid_res_t r;	int rvalue = 0;	vwrq->disabled = 0;	/* It cannot be disabled */	if ((vwrq->flags & IW_RETRY_TYPE) == IW_RETRY_LIFETIME) {

⌨️ 快捷键说明

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