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

📄 wl_iw.c

📁 wi-fi sources for asus wl138g v2 pci card
💻 C
📖 第 1 页 / 共 4 页
字号:
	struct net_device *dev,	struct iw_request_info *info,	struct sockaddr *awrq,	char *extra){	int error = -EINVAL;	WL_TRACE(("%s: SIOCSIWAP\n", dev->name));	if (awrq->sa_family != ARPHRD_ETHER) {		WL_ERROR(("Invalid Header...sa_family\n"));		return -EINVAL;	}	/* Ignore "auto" or "off" */	if (ETHER_ISBCAST(awrq->sa_data) || ETHER_ISNULLADDR(awrq->sa_data)) {		scb_val_t scbval;		WL_ASSOC(("disassociating \n"));		bzero(&scbval, sizeof (scb_val_t));		dev_wlc_ioctl(dev, WLC_DISASSOC, &scbval, sizeof(scb_val_t));		return 0;	}	WL_ASSOC(("Assoc to %s\n", bcm_ether_ntoa((struct ether_addr *)&(awrq->sa_data), eabuf)));	/* Reassociate to the specified AP */	if ((error = dev_wlc_ioctl(dev, WLC_REASSOC, awrq->sa_data, ETHER_ADDR_LEN))) {		WL_ERROR(("Invalid ioctl data.\n"));		return error;	}	return 0;}static intwl_iw_get_wap(	struct net_device *dev,	struct iw_request_info *info,	struct sockaddr *awrq,	char *extra){	WL_TRACE(("%s: SIOCGIWAP\n", dev->name));	awrq->sa_family = ARPHRD_ETHER;	memset(awrq->sa_data, 0, ETHER_ADDR_LEN);	/* Ignore error (may be down or disassociated) */	(void) dev_wlc_ioctl(dev, WLC_GET_BSSID, awrq->sa_data, ETHER_ADDR_LEN);	return 0;}#if WIRELESS_EXT > 17static intwl_iw_mlme(	struct net_device *dev,	struct iw_request_info *info,	struct sockaddr *awrq,	char *extra){	struct iw_mlme *mlme;	scb_val_t scbval;	int error  = -EINVAL;	WL_TRACE(("%s: SIOCSIWMLME\n", dev->name));	mlme = (struct iw_mlme *)extra;	if (mlme == NULL) {		WL_ERROR(("Invalid ioctl data.\n"));		return error;	}	scbval.val = mlme->reason_code;	bcopy(&mlme->addr.sa_data, &scbval.ea, ETHER_ADDR_LEN);	if (mlme->cmd == IW_MLME_DISASSOC)		error = dev_wlc_ioctl(dev, WLC_DISASSOC, &scbval, sizeof(scb_val_t));	else if (mlme->cmd == IW_MLME_DEAUTH)		error = dev_wlc_ioctl(dev, WLC_SCB_DEAUTHENTICATE_FOR_REASON, &scbval, sizeof(scb_val_t));	else {		WL_ERROR(("Invalid ioctl data.\n"));		return error;	}	return error;}#endifstatic intwl_iw_get_aplist(	struct net_device *dev,	struct iw_request_info *info,	struct iw_point *dwrq,	char *extra){	wl_scan_results_t *list;	struct sockaddr *addr = (struct sockaddr *) extra;	struct iw_quality qual[IW_MAX_AP];	wl_bss_info_t *bi = NULL;	int error, i;	WL_TRACE(("%s: SIOCGIWAPLIST\n", dev->name));	if (!extra)		return -EINVAL;	/* Get scan results (too large to put on the stack) */	list = kmalloc(WLC_IOCTL_MAXLEN, GFP_KERNEL);	if (!list)		return -ENOMEM;	memset(list, 0, WLC_IOCTL_MAXLEN);	list->buflen = WLC_IOCTL_MAXLEN;	if ((error = dev_wlc_ioctl(dev, WLC_SCAN_RESULTS, list, WLC_IOCTL_MAXLEN))) {		WL_ERROR(("%d: Scan results error %d\n", __LINE__, error));		kfree(list);		return error;	}	ASSERT(list->version == WL_BSS_INFO_VERSION);	for (i = 0, dwrq->length = 0; i < list->count && dwrq->length < IW_MAX_AP; i++) {		bi = bi ? (wl_bss_info_t *)((unsigned) bi + bi->length) : list->bss_info;		ASSERT(((unsigned) bi + bi->length) <= ((unsigned) list + WLC_IOCTL_MAXLEN));		/* Infrastructure only */		if (!(bi->capability & DOT11_CAP_ESS))			continue;		/* BSSID */		memcpy(addr[dwrq->length].sa_data, &bi->BSSID, ETHER_ADDR_LEN);		addr[dwrq->length].sa_family = ARPHRD_ETHER;		qual[dwrq->length].qual = rssi_to_qual(bi->RSSI);		qual[dwrq->length].level = 0x100 + bi->RSSI;		qual[dwrq->length].noise = 0x100 + bi->phy_noise;		/* Updated qual, level, and noise */		qual[dwrq->length].updated = 7;		dwrq->length++;	}	kfree(list);	if (dwrq->length) {		memcpy(&addr[dwrq->length], qual, sizeof(struct iw_quality) * dwrq->length);		/* Provided qual */		dwrq->flags = 1;	}	return 0;}#if WIRELESS_EXT > 13static intwl_iw_set_scan(	struct net_device *dev,	struct iw_request_info *info,	struct iw_param *vwrq,	char *extra){	wlc_ssid_t ssid;	WL_TRACE(("%s: SIOCSIWSCAN\n", dev->name));	/* Broadcast scan */	ssid.SSID_len = 0;	/* Ignore error (most likely scan in progress) */	(void) dev_wlc_ioctl(dev, WLC_SCAN, &ssid, sizeof(ssid));	return 0;}#if WIRELESS_EXT > 17static boolie_is_wpa_ie(uint8 **wpaie, uint8 **tlvs, int *tlvs_len){/* Is this body of this tlvs entry a WPA entry? If *//* not update the tlvs buffer pointer/length */	uint8 *ie = *wpaie;	/* If the contents match the WPA_OUI and type=1 */	if ((ie[1] >= 6) && 		!bcmp((const void *)&ie[2], (const void *)(WPA_OUI "\x01"), 4)) {		return TRUE;	}	/* point to the next ie */	ie += ie[1] + 2;	/* calculate the length of the rest of the buffer */	*tlvs_len -= (int)ie - (int)*tlvs;	/* update the pointer to the start of the buffer */	*tlvs = ie;	return FALSE;}#endifstatic intwl_iw_get_scan(	struct net_device *dev,	struct iw_request_info *info,	struct iw_point *dwrq,	char *extra){	wl_scan_results_t *list;	struct iw_event	iwe;	wl_bss_info_t *bi = NULL;	int error, i, j;	char *event = extra, *end = extra + IW_SCAN_MAX_DATA, *value;	WL_TRACE(("%s: SIOCGIWSCAN\n", dev->name));	if (!extra)		return -EINVAL;	/* Get scan results (too large to put on the stack) */	list = kmalloc(WLC_IOCTL_MAXLEN, GFP_KERNEL);	if (!list)		return -ENOMEM;	memset(list, 0, WLC_IOCTL_MAXLEN);	list->buflen = WLC_IOCTL_MAXLEN;	if ((error = dev_wlc_ioctl(dev, WLC_SCAN_RESULTS, list, WLC_IOCTL_MAXLEN))) {		kfree(list);		return error;	}	ASSERT(list->version == WL_BSS_INFO_VERSION);	for (i = 0; i < list->count && i < IW_MAX_AP; i++) {		bi = bi ? (wl_bss_info_t *)((unsigned) bi + bi->length) : list->bss_info;		ASSERT(((unsigned) bi + bi->length) <= ((unsigned) list + WLC_IOCTL_MAXLEN));		/* First entry must be the BSSID */		iwe.cmd = SIOCGIWAP;		iwe.u.ap_addr.sa_family = ARPHRD_ETHER;		memcpy(iwe.u.ap_addr.sa_data, &bi->BSSID, ETHER_ADDR_LEN);		event = iwe_stream_add_event(event, end, &iwe, IW_EV_ADDR_LEN);		/* SSID */		iwe.u.data.length = bi->SSID_len;		iwe.cmd = SIOCGIWESSID;		iwe.u.data.flags = 1;		event = iwe_stream_add_point(event, end, &iwe, bi->SSID);		/* Mode */		if (bi->capability & (DOT11_CAP_ESS | DOT11_CAP_IBSS)) {			iwe.cmd = SIOCGIWMODE;			if (bi->capability & DOT11_CAP_ESS)				iwe.u.mode = IW_MODE_INFRA;			else				iwe.u.mode = IW_MODE_ADHOC;			event = iwe_stream_add_event(event, end, &iwe, IW_EV_UINT_LEN);		}		/* Channel */		iwe.cmd = SIOCGIWFREQ;		iwe.u.freq.m = bi->channel;		iwe.u.freq.e = 0;		event = iwe_stream_add_event(event, end, &iwe, IW_EV_FREQ_LEN);		/* Channel quality */		iwe.cmd = IWEVQUAL;		iwe.u.qual.qual = rssi_to_qual(bi->RSSI);		iwe.u.qual.level = 0x100 + bi->RSSI;		iwe.u.qual.noise = 0x100 + bi->phy_noise;		event = iwe_stream_add_event(event, end, &iwe, IW_EV_QUAL_LEN);#if WIRELESS_EXT > 17		/* wpa_ie */		if (bi->ie_length) {			/* look for wpa/rsn ies in the ie list... */			bcm_tlv_t *ie;			uint8*ptr= ((uint8 *)bi) + sizeof(wl_bss_info_t);			int ptr_len = bi->ie_length;#ifdef BCMWPA2			if ((ie = bcm_parse_tlvs(ptr, ptr_len, DOT11_MNG_RSN_ID))) {				iwe.cmd = IWEVGENIE;				iwe.u.data.length = ie->len + 2;				event = iwe_stream_add_point(event, end, &iwe, (char *)ie);			}			ptr = ((uint8 *)bi) + sizeof(wl_bss_info_t);#endif /* BCMWPA2 */			while ((ie = bcm_parse_tlvs(ptr, ptr_len, DOT11_MNG_WPA_ID))) {				if (ie_is_wpa_ie(((uint8 **)&ie), &ptr, &ptr_len)) {					iwe.cmd = IWEVGENIE;					iwe.u.data.length = ie->len + 2;					event = iwe_stream_add_point(event, end, &iwe, (char *)ie);					goto done;				}			}		}done:#endif		/* Encryption */		iwe.cmd = SIOCGIWENCODE;		if (bi->capability & DOT11_CAP_PRIVACY)			iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;		else			iwe.u.data.flags = IW_ENCODE_DISABLED;		iwe.u.data.length = 0;		event = iwe_stream_add_point(event, end, &iwe, (char *)event);		/* Rates */		if (bi->rateset.count) {			value = event + IW_EV_LCP_LEN;			iwe.cmd = SIOCGIWRATE;			/* Those two flags are ignored... */			iwe.u.bitrate.fixed = iwe.u.bitrate.disabled = 0;			for (j = 0; j < bi->rateset.count && j < IW_MAX_BITRATES; j++) {				iwe.u.bitrate.value = (bi->rateset.rates[j] & 0x7f) * 500000;				value = iwe_stream_add_value(event, value, end, &iwe,					IW_EV_PARAM_LEN);			}			event = value;		}	}	kfree(list);	dwrq->length = event - extra;	dwrq->flags = 0;	/* todo */	return 0;}#endif /* WIRELESS_EXT > 13 */static intwl_iw_set_essid(	struct net_device *dev,	struct iw_request_info *info,	struct iw_point *dwrq,	char *extra){	wlc_ssid_t ssid;	int error;	WL_TRACE(("%s: SIOCSIWESSID\n", dev->name));	if (dwrq->length && extra) {		ssid.SSID_len = MIN(sizeof(ssid.SSID), dwrq->length - 1);		memcpy(ssid.SSID, extra, ssid.SSID_len);	} else {		/* Broadcast SSID */		ssid.SSID_len = 0;	}	if ((error = dev_wlc_ioctl(dev, WLC_SET_SSID, &ssid, sizeof(ssid))))		return error;	return 0;}static intwl_iw_get_essid(	struct net_device *dev,	struct iw_request_info *info,	struct iw_point *dwrq,	char *extra){	wlc_ssid_t ssid;	int error;	WL_TRACE(("%s: SIOCGIWESSID\n", dev->name));	if (!extra)		return -EINVAL;	if ((error = dev_wlc_ioctl(dev, WLC_GET_SSID, &ssid, sizeof(ssid)))) {		WL_ERROR(("Error getting the SSID\n"));		return error;	}	/* Get the current SSID */	memcpy(extra, ssid.SSID, ssid.SSID_len);	extra[ssid.SSID_len] = '\0';	dwrq->length = ssid.SSID_len ;	dwrq->flags = 1; /* active */	return 0;}static intwl_iw_set_nick(	struct net_device *dev,	struct iw_request_info *info,	struct iw_point *dwrq,	char *extra){	wl_iw_t *iw = dev->priv;	WL_TRACE(("%s: SIOCSIWNICKN\n", dev->name));	if (!extra)		return -EINVAL;	/* Check the size of the string */	if (dwrq->length > sizeof(iw->nickname))		return -E2BIG;	memcpy(iw->nickname, extra, dwrq->length);	iw->nickname[dwrq->length - 1] = '\0';	return 0;}static intwl_iw_get_nick(	struct net_device *dev,	struct iw_request_info *info,	struct iw_point *dwrq,	char *extra){	wl_iw_t *iw = dev->priv;	WL_TRACE(("%s: SIOCGIWNICKN\n", dev->name));	if (!extra)		return -EINVAL;	strcpy(extra, iw->nickname);	dwrq->length = strlen(extra) + 1;	return 0;}static int wl_iw_set_rate(	struct net_device *dev,	struct iw_request_info *info,	struct iw_param *vwrq,	char *extra){	wl_rateset_t rateset;	int error, rate, i, error_bg, error_a;	WL_TRACE(("%s: SIOCSIWRITE\n", dev->name));	/* Get current rateset */	if ((error = dev_wlc_ioctl(dev, WLC_GET_CURR_RATESET, &rateset, sizeof(rateset))))		return error;	if (vwrq->value < 0) {		/* Select maximum rate */		rate = rateset.rates[rateset.count - 1] & 0x7f;	} else if (vwrq->value < rateset.count) {		/* Select rate by rateset index */		rate = rateset.rates[vwrq->value] & 0x7f;	} else {		/* Specified rate in bps */		rate = vwrq->value / 500000;	}	if (vwrq->fixed) {		/*			Set rate override,			Since the is a/b/g-blind, both a/bg_rate are enforced.		*/		error_bg = dev_wlc_intvar_set(dev, "bg_rate", rate);		error_a = dev_wlc_intvar_set(dev, "a_rate", rate);		if (error_bg && error_a)			return (error_bg | error_a);	} else {		/*			clear rate override			Since the is a/b/g-blind, both a/bg_rate are enforced.		*/		/* 0 is for clearing rate override */		error_bg = dev_wlc_intvar_set(dev, "bg_rate", 0);		/* 0 is for clearing rate override */		error_a = dev_wlc_intvar_set(dev, "a_rate", 0);		if (error_bg && error_a)			return (error_bg | error_a);		/* Remove rates above selected rate */		for (i = 0; i < rateset.count; i++)			if ((rateset.rates[i] & 0x7f) > rate)				break;		rateset.count = i;		/* Set current rateset */		if ((error = dev_wlc_ioctl(dev, WLC_SET_RATESET, &rateset, sizeof(rateset))))			return error;	}	return 0;}static int wl_iw_get_rate(	struct net_device *dev,	struct iw_request_info *info,	struct iw_param *vwrq,	char *extra){	int error, rate;	WL_TRACE(("%s: SIOCGIWRATE\n", dev->name));	/* Report the current tx rate */	if ((error = dev_wlc_ioctl(dev, WLC_GET_RATE, &rate, sizeof(rate))))		return error;	vwrq->value = (rate & 0x7f) * 500000;	return 0;}static intwl_iw_set_rts(	struct net_device *dev,	struct iw_request_info *info,	struct iw_param *vwrq,	char *extra){	int error, rts;	WL_TRACE(("%s: SIOCSIWRTS\n", dev->name));	if (vwrq->disabled)

⌨️ 快捷键说明

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