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

📄 wl_iw.c

📁 wi-fi sources for asus wl138g v2 pci card
💻 C
📖 第 1 页 / 共 4 页
字号:
/* * Linux Wireless Extensions support * * Copyright 2005-2006, Broadcom Corporation * All Rights Reserved.                 *                                      * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. * $Id$ */#include <linux/if_arp.h>#include <asm/uaccess.h>#include <wlc_cfg.h>#include <typedefs.h>#include <linux/module.h>#include <osl.h>#include <bcmutils.h>#include <proto/ethernet.h>#include <proto/802.11.h>typedef void wlc_info_t;typedef void wl_info_t;typedef const struct sb_pub  sb_t;#include <wlioctl.h>#include <wlc_pub.h>#include <wl_dbg.h>#include <wl_iw.h>static intdev_wlc_ioctl(	struct net_device *dev,	int cmd,	void *arg,	int len){	struct ifreq ifr;	wl_ioctl_t ioc;	mm_segment_t fs;	int ret;	ioc.cmd = cmd;	ioc.buf = arg;	ioc.len = len;	strcpy(ifr.ifr_name, dev->name);	ifr.ifr_data = (caddr_t) &ioc;	/* Must be up for virtually all useful ioctls */	dev_open(dev);	fs = get_fs();	set_fs(get_ds());	ret = dev->do_ioctl(dev, &ifr, SIOCDEVPRIVATE);	set_fs(fs);	return ret;}/*set named driver variable to int value and return error indicationcalling example: dev_wlc_intvar_set(dev, "arate", rate)*/static intdev_wlc_intvar_set(	struct net_device *dev,	char *name,	int val){	char buf[WLC_IOCTL_SMLEN];	uint len;	len = bcm_mkiovar(name, (char *)(&val), sizeof(val), buf, sizeof(buf));	ASSERT(len);	return (dev_wlc_ioctl(dev, WLC_SET_VAR, buf, len));}#if WIRELESS_EXT > 17static intdev_wlc_bufvar_set(	struct net_device *dev,	char *name,	char *buf, int len){	char ioctlbuf[WLC_IOCTL_SMLEN];	uint buflen;	buflen = bcm_mkiovar(name, buf, len, ioctlbuf, sizeof(ioctlbuf));	ASSERT(buflen);	return (dev_wlc_ioctl(dev, WLC_SET_VAR, ioctlbuf, buflen));}/*get named driver variable to int value and return error indicationcalling example: dev_wlc_intvar_get(dev, "arate", &rate)*/static intdev_wlc_bufvar_get(	struct net_device *dev,	char *name,	char *buf, int buflen){	char ioctlbuf[WLC_IOCTL_SMLEN];	int error;	uint len;	len = bcm_mkiovar(name, NULL, 0, ioctlbuf, sizeof(ioctlbuf));	ASSERT(len);	error = dev_wlc_ioctl(dev, WLC_GET_VAR, (void *)ioctlbuf, len);	bcopy(ioctlbuf, buf, buflen);	return (error);}#endif/*get named driver variable to int value and return error indicationcalling example: dev_wlc_intvar_get(dev, "arate", &rate)*/static intdev_wlc_intvar_get(	struct net_device *dev,	char *name,	int *retval){	union {		char buf[WLC_IOCTL_SMLEN];		int val;	} var;	int error;	uint len;	uint data_null;	len = bcm_mkiovar(name, (char *)(&data_null), 0, (char *)(&var), sizeof(var.buf));	ASSERT(len);	error = dev_wlc_ioctl(dev, WLC_GET_VAR, (void *)&var, len);	*retval = var.val;	return (error);}/* Maintain backward compatibility */#if WIRELESS_EXT < 13struct iw_request_info{	__u16		cmd;		/* Wireless Extension command */	__u16		flags;		/* More to come ;-) */};typedef int (*iw_handler)(struct net_device *dev, struct iw_request_info *info,	void *wrqu, char *extra);#endif /* WIRELESS_EXT < 13 */static intwl_iw_config_commit(	struct net_device *dev,	struct iw_request_info *info,	void *zwrq,	char *extra){	wlc_ssid_t ssid;	int error;	struct sockaddr bssid;	WL_TRACE(("%s: SIOCSIWCOMMIT\n", dev->name));	if ((error = dev_wlc_ioctl(dev, WLC_GET_SSID, &ssid, sizeof(ssid))))		return error;	if (!ssid.SSID_len)		return 0;	bzero(&bssid, sizeof(struct sockaddr));	if ((error = dev_wlc_ioctl(dev, WLC_REASSOC, &bssid, ETHER_ADDR_LEN))) {		WL_ERROR(("Invalid ioctl data.\n"));		return error;	}	return 0;}static intwl_iw_get_name(	struct net_device *dev,	struct iw_request_info *info,	char *cwrq,	char *extra){	WL_TRACE(("%s: SIOCGIWNAME\n", dev->name));	strcpy(cwrq, "IEEE 802.11-DS");	return 0;}static intwl_iw_set_freq(	struct net_device *dev,	struct iw_request_info *info,	struct iw_freq *fwrq,	char *extra){	int error, chan;	WL_TRACE(("%s: SIOCSIWFREQ\n", dev->name));	/* Setting by channel number */	if (fwrq->e == 0 && fwrq->m < MAXCHANNEL) {		chan = fwrq->m;	}	/* Setting by frequency */	else {		/* Convert to MHz as best we can */		if (fwrq->e >= 6) {			fwrq->e -= 6;			while (fwrq->e--)				fwrq->m *= 10;		} else if (fwrq->e < 6) {			while (fwrq->e++ < 6)				fwrq->m /= 10;		}		chan = wlc_freq2channel(fwrq->m);	}	if ((error = dev_wlc_ioctl(dev, WLC_SET_CHANNEL, &chan, sizeof(chan))))		return error;	/* -EINPROGRESS: Call commit handler */	return -EINPROGRESS;}static intwl_iw_get_freq(	struct net_device *dev,	struct iw_request_info *info,	struct iw_freq *fwrq,	char *extra){	channel_info_t ci;	int error;	WL_TRACE(("%s: SIOCGIWFREQ\n", dev->name));	if ((error = dev_wlc_ioctl(dev, WLC_GET_CHANNEL, &ci, sizeof(ci))))		return error;	/* Return radio channel in channel form */	fwrq->m = ci.hw_channel;	fwrq->e = 0;	return 0;}static intwl_iw_set_mode(	struct net_device *dev,	struct iw_request_info *info,	__u32 *uwrq,	char *extra){	int infra = 0, ap = 0, error = 0;	WL_TRACE(("%s: SIOCSIWMODE\n", dev->name));	switch (*uwrq) {	case IW_MODE_MASTER:		infra = ap = 1;		break;	case IW_MODE_ADHOC:	case IW_MODE_AUTO:		break;	case IW_MODE_INFRA:		infra = 1;		break;	default:		return -EINVAL;	}	if ((error = dev_wlc_ioctl(dev, WLC_SET_INFRA, &infra, sizeof(infra))))		return error;	/* -EINPROGRESS: Call commit handler */	return -EINPROGRESS;}static intwl_iw_get_mode(	struct net_device *dev,	struct iw_request_info *info,	__u32 *uwrq,	char *extra){	int error, infra = 0, ap = 0;	WL_TRACE(("%s: SIOCGIWMODE\n", dev->name));	if ((error = dev_wlc_ioctl(dev, WLC_GET_INFRA, &infra, sizeof(infra))) ||	    (error = dev_wlc_ioctl(dev, WLC_GET_AP, &ap, sizeof(ap))))		return error;	*uwrq = infra ? ap ? IW_MODE_MASTER : IW_MODE_INFRA : IW_MODE_ADHOC;	return 0;}static intwl_iw_get_range(	struct net_device *dev,	struct iw_request_info *info,	struct iw_point *dwrq,	char *extra){	struct iw_range *range = (struct iw_range *) extra;	int channels[MAXCHANNEL];	wl_uint32_list_t *list = (wl_uint32_list_t *) channels;	wl_rateset_t rateset;	int error, i;	WL_TRACE(("%s: SIOCGIWRANGE\n", dev->name));	if (!extra)		return -EINVAL;	dwrq->length = sizeof(struct iw_range);	memset(range, 0, sizeof(range));	/* We don't use nwids */	range->min_nwid = range->max_nwid = 0;	/* Set available channels/frequencies */	list->count = MAXCHANNEL;	if ((error = dev_wlc_ioctl(dev, WLC_GET_VALID_CHANNELS, channels, sizeof(channels))))		return error;	for (i = 0; i < list->count && i < IW_MAX_FREQUENCIES; i++) {		range->freq[i].i = list->element[i];		range->freq[i].m = wlc_channel2freq(list->element[i]);		range->freq[i].e = 6;	}	range->num_frequency = range->num_channels = i;	/* Link quality (use NDIS cutoffs) */	range->max_qual.qual = 5;	/* Signal level (use RSSI) */	range->max_qual.level = 0x100 - 200;	/* -200 dBm */	/* Noise level (use noise) */	range->max_qual.noise = 0x100 - 200;	/* -200 dBm */	/* Signal level threshold range (?) */	range->sensitivity = 65535;#if WIRELESS_EXT > 11	/* Link quality (use NDIS cutoffs) */	range->avg_qual.qual = 3;	/* Signal level (use RSSI) */	range->avg_qual.level = 0x100 + WLC_RSSI_GOOD;	/* Noise level (use noise) */	range->avg_qual.noise = 0x100 - 75;	/* -75 dBm */#endif /* WIRELESS_EXT > 11 */	/* Set available bitrates */	if ((error = dev_wlc_ioctl(dev, WLC_GET_CURR_RATESET, &rateset, sizeof(rateset))))		return error;	range->num_bitrates = rateset.count;	for (i = 0; i < rateset.count && i < IW_MAX_BITRATES; i++)		range->bitrate[i] = (rateset.rates[i] & 0x7f) * 500000; /* convert to bps */	/* Set an indication of the max TCP throughput	 * in bit/s that we can expect using this interface.	 * May be use for QoS stuff... Jean II	 */	if ((error = dev_wlc_ioctl(dev, WLC_GET_PHYTYPE, &i, sizeof(i))))		return error;	if (i == PHY_TYPE_A)		range->throughput = 24000000;	/* 24 Mbits/s */	else		range->throughput = 1500000;	/* 1.5 Mbits/s */	/* RTS and fragmentation thresholds */	range->min_rts = 0;	range->max_rts = 2347;	range->min_frag = 256;	range->max_frag = 2346;	range->max_encoding_tokens = DOT11_MAX_DEFAULT_KEYS;	range->num_encoding_sizes = 4;	range->encoding_size[0] = WEP1_KEY_SIZE;	range->encoding_size[1] = WEP128_KEY_SIZE;#if WIRELESS_EXT > 17	range->encoding_size[2] = TKIP_KEY_SIZE;#else	range->encoding_size[2] = 0;#endif	range->encoding_size[3] = AES_KEY_SIZE;	/* Do not support power micro-management */	range->min_pmp = 0;	range->max_pmp = 0;	range->min_pmt = 0;	range->max_pmt = 0;	range->pmp_flags = 0;	range->pm_capa = 0;	/* Transmit Power - values are in mW */	range->num_txpower = 2;	range->txpower[0] = 1;	range->txpower[1] = 255;	range->txpower_capa = IW_TXPOW_MWATT;#if WIRELESS_EXT > 10	range->we_version_compiled = WIRELESS_EXT;	range->we_version_source = 18;	/* Only support retry limits */	range->retry_capa = IW_RETRY_LIMIT;	range->retry_flags = IW_RETRY_LIMIT;	range->r_time_flags = 0;	/* SRL and LRL limits */	range->min_retry = 1;	range->max_retry = 255;	/* Retry lifetime limits unsupported */	range->min_r_time = 0;	range->max_r_time = 0;#endif /* WIRELESS_EXT > 10 */#if WIRELESS_EXT > 17	range->enc_capa = IW_ENC_CAPA_WPA;	range->enc_capa |= IW_ENC_CAPA_CIPHER_TKIP;	range->enc_capa |= IW_ENC_CAPA_CIPHER_CCMP;#ifdef BCMWPA2	range->enc_capa |= IW_ENC_CAPA_WPA2;#endif#endif /* WIRELESS_EXT > 17 */	return 0;}static intrssi_to_qual(int rssi){	if (rssi <= WLC_RSSI_NO_SIGNAL)		return 0;	else if (rssi <= WLC_RSSI_VERY_LOW)		return 1;	else if (rssi <= WLC_RSSI_LOW)		return 2;	else if (rssi <= WLC_RSSI_GOOD)		return 3;	else if (rssi <= WLC_RSSI_VERY_GOOD)		return 4;	else		return 5;}static intwl_iw_set_spy(	struct net_device *dev,	struct iw_request_info *info,	struct iw_point *dwrq,	char *extra){	wl_iw_t *iw = dev->priv;	struct sockaddr *addr = (struct sockaddr *) extra;	int i;	WL_TRACE(("%s: SIOCSIWSPY\n", dev->name));	if (!extra)		return -EINVAL;	iw->spy_num = MIN(ARRAYSIZE(iw->spy_addr), dwrq->length);	for (i = 0; i < iw->spy_num; i++)		memcpy(&iw->spy_addr[i], addr[i].sa_data, ETHER_ADDR_LEN);	memset(iw->spy_qual, 0, sizeof(iw->spy_qual));	return 0;}static intwl_iw_get_spy(	struct net_device *dev,	struct iw_request_info *info,	struct iw_point *dwrq,	char *extra){	wl_iw_t *iw = dev->priv;	struct sockaddr *addr = (struct sockaddr *) extra;	struct iw_quality *qual = (struct iw_quality *) &addr[iw->spy_num];	int i;	WL_TRACE(("%s: SIOCGIWSPY\n", dev->name));	if (!extra)		return -EINVAL;	dwrq->length = iw->spy_num;	for (i = 0; i < iw->spy_num; i++) {		memcpy(addr[i].sa_data, &iw->spy_addr[i], ETHER_ADDR_LEN);		addr[i].sa_family = AF_UNIX;		memcpy(&qual[i], &iw->spy_qual[i], sizeof(struct iw_quality));		iw->spy_qual[i].updated = 0;	}	return 0;}static intwl_iw_set_wap(

⌨️ 快捷键说明

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