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

📄 hostap_ioctl.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 5 页
字号:
				rrq->value = local->manual_retry_count;		} else if ((rrq->flags & IW_RETRY_MAX)) {			rrq->flags = IW_RETRY_LIMIT | IW_RETRY_MAX;			rrq->value = longretry;		} else {			rrq->flags = IW_RETRY_LIMIT;			rrq->value = shortretry;			if (shortretry != longretry)				rrq->flags |= IW_RETRY_MIN;		}	}	return 0;}/* Note! This TX power controlling is experimental and should not be used in * production use. It just sets raw power register and does not use any kind of * feedback information from the measured TX power (CR58). This is now * commented out to make sure that it is not used by accident. TX power * configuration will be enabled again after proper algorithm using feedback * has been implemented. */#ifdef RAW_TXPOWER_SETTING/* Map HFA386x's CR31 to and from dBm with some sort of ad hoc mapping.. * This version assumes following mapping: * CR31 is 7-bit value with -64 to +63 range. * -64 is mapped into +20dBm and +63 into -43dBm. * This is certainly not an exact mapping for every card, but at least * increasing dBm value should correspond to increasing TX power. */static int prism2_txpower_hfa386x_to_dBm(u16 val){	signed char tmp;	if (val > 255)		val = 255;	tmp = val;	tmp >>= 2;	return -12 - tmp;}static u16 prism2_txpower_dBm_to_hfa386x(int val){	signed char tmp;	if (val > 20)		return 128;	else if (val < -43)		return 127;	tmp = val;	tmp = -12 - tmp;	tmp <<= 2;	return (unsigned char) tmp;}#endif /* RAW_TXPOWER_SETTING */static int prism2_ioctl_siwtxpow(struct net_device *dev,				 struct iw_request_info *info,				 struct iw_param *rrq, char *extra){	struct hostap_interface *iface;	local_info_t *local;#ifdef RAW_TXPOWER_SETTING	char *tmp;#endif	u16 val;	int ret = 0;	iface = netdev_priv(dev);	local = iface->local;	if (rrq->disabled) {		if (local->txpower_type != PRISM2_TXPOWER_OFF) {			val = 0xff; /* use all standby and sleep modes */			ret = local->func->cmd(dev, HFA384X_CMDCODE_WRITEMIF,					       HFA386X_CR_A_D_TEST_MODES2,					       &val, NULL);			printk(KERN_DEBUG "%s: Turning radio off: %s\n",			       dev->name, ret ? "failed" : "OK");			local->txpower_type = PRISM2_TXPOWER_OFF;		}		return (ret ? -EOPNOTSUPP : 0);	}	if (local->txpower_type == PRISM2_TXPOWER_OFF) {		val = 0; /* disable all standby and sleep modes */		ret = local->func->cmd(dev, HFA384X_CMDCODE_WRITEMIF,				       HFA386X_CR_A_D_TEST_MODES2, &val, NULL);		printk(KERN_DEBUG "%s: Turning radio on: %s\n",		       dev->name, ret ? "failed" : "OK");		local->txpower_type = PRISM2_TXPOWER_UNKNOWN;	}#ifdef RAW_TXPOWER_SETTING	if (!rrq->fixed && local->txpower_type != PRISM2_TXPOWER_AUTO) {		printk(KERN_DEBUG "Setting ALC on\n");		val = HFA384X_TEST_CFG_BIT_ALC;		local->func->cmd(dev, HFA384X_CMDCODE_TEST |				 (HFA384X_TEST_CFG_BITS << 8), 1, &val, NULL);		local->txpower_type = PRISM2_TXPOWER_AUTO;		return 0;	}	if (local->txpower_type != PRISM2_TXPOWER_FIXED) {		printk(KERN_DEBUG "Setting ALC off\n");		val = HFA384X_TEST_CFG_BIT_ALC;		local->func->cmd(dev, HFA384X_CMDCODE_TEST |				 (HFA384X_TEST_CFG_BITS << 8), 0, &val, NULL);			local->txpower_type = PRISM2_TXPOWER_FIXED;	}	if (rrq->flags == IW_TXPOW_DBM)		tmp = "dBm";	else if (rrq->flags == IW_TXPOW_MWATT)		tmp = "mW";	else		tmp = "UNKNOWN";	printk(KERN_DEBUG "Setting TX power to %d %s\n", rrq->value, tmp);	if (rrq->flags != IW_TXPOW_DBM) {		printk("SIOCSIWTXPOW with mW is not supported; use dBm\n");		return -EOPNOTSUPP;	}	local->txpower = rrq->value;	val = prism2_txpower_dBm_to_hfa386x(local->txpower);	if (local->func->cmd(dev, HFA384X_CMDCODE_WRITEMIF,			     HFA386X_CR_MANUAL_TX_POWER, &val, NULL))		ret = -EOPNOTSUPP;#else /* RAW_TXPOWER_SETTING */	if (rrq->fixed)		ret = -EOPNOTSUPP;#endif /* RAW_TXPOWER_SETTING */	return ret;}static int prism2_ioctl_giwtxpow(struct net_device *dev,				 struct iw_request_info *info,				 struct iw_param *rrq, char *extra){#ifdef RAW_TXPOWER_SETTING	struct hostap_interface *iface;	local_info_t *local;	u16 resp0;	iface = netdev_priv(dev);	local = iface->local;	rrq->flags = IW_TXPOW_DBM;	rrq->disabled = 0;	rrq->fixed = 0;	if (local->txpower_type == PRISM2_TXPOWER_AUTO) {		if (local->func->cmd(dev, HFA384X_CMDCODE_READMIF,				     HFA386X_CR_MANUAL_TX_POWER,				     NULL, &resp0) == 0) {			rrq->value = prism2_txpower_hfa386x_to_dBm(resp0);		} else {			/* Could not get real txpower; guess 15 dBm */			rrq->value = 15;		}	} else if (local->txpower_type == PRISM2_TXPOWER_OFF) {		rrq->value = 0;		rrq->disabled = 1;	} else if (local->txpower_type == PRISM2_TXPOWER_FIXED) {		rrq->value = local->txpower;		rrq->fixed = 1;	} else {		printk("SIOCGIWTXPOW - unknown txpower_type=%d\n",		       local->txpower_type);	}	return 0;#else /* RAW_TXPOWER_SETTING */	return -EOPNOTSUPP;#endif /* RAW_TXPOWER_SETTING */}#ifndef PRISM2_NO_STATION_MODES/* HostScan request works with and without host_roaming mode. In addition, it * does not break current association. However, it requires newer station * firmware version (>= 1.3.1) than scan request. */static int prism2_request_hostscan(struct net_device *dev,				   u8 *ssid, u8 ssid_len){	struct hostap_interface *iface;	local_info_t *local;	struct hfa384x_hostscan_request scan_req;	iface = netdev_priv(dev);	local = iface->local;	memset(&scan_req, 0, sizeof(scan_req));	scan_req.channel_list = cpu_to_le16(local->channel_mask &					    local->scan_channel_mask);	scan_req.txrate = __constant_cpu_to_le16(HFA384X_RATES_1MBPS);	if (ssid) {		if (ssid_len > 32)			return -EINVAL;		scan_req.target_ssid_len = cpu_to_le16(ssid_len);		memcpy(scan_req.target_ssid, ssid, ssid_len);	}	if (local->func->set_rid(dev, HFA384X_RID_HOSTSCAN, &scan_req,				 sizeof(scan_req))) {		printk(KERN_DEBUG "%s: HOSTSCAN failed\n", dev->name);		return -EINVAL;	}	return 0;}static int prism2_request_scan(struct net_device *dev){	struct hostap_interface *iface;	local_info_t *local;	struct hfa384x_scan_request scan_req;	int ret = 0;	iface = netdev_priv(dev);	local = iface->local;	memset(&scan_req, 0, sizeof(scan_req));	scan_req.channel_list = cpu_to_le16(local->channel_mask &					    local->scan_channel_mask);	scan_req.txrate = __constant_cpu_to_le16(HFA384X_RATES_1MBPS);	/* FIX:	 * It seems to be enough to set roaming mode for a short moment to	 * host-based and then setup scanrequest data and return the mode to	 * firmware-based.	 *	 * Master mode would need to drop to Managed mode for a short while	 * to make scanning work.. Or sweep through the different channels and	 * use passive scan based on beacons. */	if (!local->host_roaming)		hostap_set_word(dev, HFA384X_RID_CNFROAMINGMODE,				HFA384X_ROAMING_HOST);	if (local->func->set_rid(dev, HFA384X_RID_SCANREQUEST, &scan_req,				 sizeof(scan_req))) {		printk(KERN_DEBUG "SCANREQUEST failed\n");		ret = -EINVAL;	}	if (!local->host_roaming)		hostap_set_word(dev, HFA384X_RID_CNFROAMINGMODE,				HFA384X_ROAMING_FIRMWARE);	return 0;}#else /* !PRISM2_NO_STATION_MODES */static inline int prism2_request_hostscan(struct net_device *dev,					  u8 *ssid, u8 ssid_len){	return -EOPNOTSUPP;}static inline int prism2_request_scan(struct net_device *dev){	return -EOPNOTSUPP;}#endif /* !PRISM2_NO_STATION_MODES */static int prism2_ioctl_siwscan(struct net_device *dev,				struct iw_request_info *info,				struct iw_point *data, char *extra){	struct hostap_interface *iface;	local_info_t *local;	int ret;	u8 *ssid = NULL, ssid_len = 0;	struct iw_scan_req *req = (struct iw_scan_req *) extra;	iface = netdev_priv(dev);	local = iface->local;	if (data->length < sizeof(struct iw_scan_req))		req = NULL;	if (local->iw_mode == IW_MODE_MASTER) {		/* In master mode, we just return the results of our local		 * tables, so we don't need to start anything...		 * Jean II */		data->length = 0;		return 0;	}	if (!local->dev_enabled)		return -ENETDOWN;	if (req && data->flags & IW_SCAN_THIS_ESSID) {		ssid = req->essid;		ssid_len = req->essid_len;		if (ssid_len &&		    ((local->iw_mode != IW_MODE_INFRA &&		      local->iw_mode != IW_MODE_ADHOC) ||		     (local->sta_fw_ver < PRISM2_FW_VER(1,3,1))))			return -EOPNOTSUPP;	}	if (local->sta_fw_ver >= PRISM2_FW_VER(1,3,1))		ret = prism2_request_hostscan(dev, ssid, ssid_len);	else		ret = prism2_request_scan(dev);	if (ret == 0)		local->scan_timestamp = jiffies;	/* Could inquire F101, F103 or wait for SIOCGIWSCAN and read RID */	return ret;}#ifndef PRISM2_NO_STATION_MODESstatic char * __prism2_translate_scan(local_info_t *local,				      struct hfa384x_hostscan_result *scan,				      struct hostap_bss_info *bss,				      char *current_ev, char *end_buf){	int i, chan;	struct iw_event iwe;	char *current_val;	u16 capabilities;	u8 *pos;	u8 *ssid, *bssid;	size_t ssid_len;	char *buf;	if (bss) {		ssid = bss->ssid;		ssid_len = bss->ssid_len;		bssid = bss->bssid;	} else {		ssid = scan->ssid;		ssid_len = le16_to_cpu(scan->ssid_len);		bssid = scan->bssid;	}	if (ssid_len > 32)		ssid_len = 32;	/* First entry *MUST* be the AP MAC address */	memset(&iwe, 0, sizeof(iwe));	iwe.cmd = SIOCGIWAP;	iwe.u.ap_addr.sa_family = ARPHRD_ETHER;	memcpy(iwe.u.ap_addr.sa_data, bssid, ETH_ALEN);	current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe,					  IW_EV_ADDR_LEN);	/* Other entries will be displayed in the order we give them */	memset(&iwe, 0, sizeof(iwe));	iwe.cmd = SIOCGIWESSID;	iwe.u.data.length = ssid_len;	iwe.u.data.flags = 1;	current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, ssid);	memset(&iwe, 0, sizeof(iwe));	iwe.cmd = SIOCGIWMODE;	if (bss) {		capabilities = bss->capab_info;	} else {		capabilities = le16_to_cpu(scan->capability);	}	if (capabilities & (WLAN_CAPABILITY_ESS |			    WLAN_CAPABILITY_IBSS)) {		if (capabilities & WLAN_CAPABILITY_ESS)			iwe.u.mode = IW_MODE_MASTER;		else			iwe.u.mode = IW_MODE_ADHOC;		current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe,						  IW_EV_UINT_LEN);	}	memset(&iwe, 0, sizeof(iwe));	iwe.cmd = SIOCGIWFREQ;	if (scan) {		chan = scan->chid;	} else if (bss) {		chan = bss->chan;	} else {		chan = 0;	}	if (chan > 0) {		iwe.u.freq.m = freq_list[le16_to_cpu(chan - 1)] * 100000;		iwe.u.freq.e = 1;		current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe,						  IW_EV_FREQ_LEN);	}	if (scan) {		memset(&iwe, 0, sizeof(iwe));		iwe.cmd = IWEVQUAL;		if (local->last_scan_type == PRISM2_HOSTSCAN) {			iwe.u.qual.level = le16_to_cpu(scan->sl);			iwe.u.qual.noise = le16_to_cpu(scan->anl);		} else {			iwe.u.qual.level =				HFA384X_LEVEL_TO_dBm(le16_to_cpu(scan->sl));			iwe.u.qual.noise =				HFA384X_LEVEL_TO_dBm(le16_to_cpu(scan->anl));		}		iwe.u.qual.updated = IW_QUAL_LEVEL_UPDATED			| IW_QUAL_NOISE_UPDATED			| IW_QUAL_QUAL_INVALID			| IW_QUAL_DBM;		current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe,						  IW_EV_QUAL_LEN);	}	memset(&iwe, 0, sizeof(iwe));	iwe.cmd = SIOCGIWENCODE;	if (capabilities & WLAN_CAPABILITY_PRIVACY)		iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;	else		iwe.u.data.flags = IW_ENCODE_DISABLED;	iwe.u.data.length = 0;	current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, "");	/* TODO: add SuppRates into BSS table */	if (scan) {		memset(&iwe, 0, sizeof(iwe));		iwe.cmd = SIOCGIWRATE;		current_val = current_ev + IW_EV_LCP_LEN;		pos = scan->sup_rates;		for (i = 0; i < sizeof(scan->sup_rates); i++) {			if (pos[i] == 0)				break;			/* Bit rate given in 500 kb/s units (+ 0x80) */			iwe.u.bitrate.value = ((pos[i] & 0x7f) * 500000);			current_val = iwe_stream_add_value(				current_ev, current_val, end_buf, &iwe,				IW_EV_PARAM_LEN);		}		/* Check if we added any event */		if ((current_val - current_ev) > IW_EV_LCP_LEN)			current_ev = current_val;	}	/* TODO: add BeaconInt,resp_rate,atim into BSS table */	buf = kmalloc(MAX_WPA_IE_LEN * 2 + 30, GFP_ATOMIC);	if (buf && scan) {		memset(&iwe, 0, sizeof(iwe));		iwe.cmd = IWEVCUSTOM;		sprintf(buf, "bcn_int=%d", le16_to_cpu(scan->beacon_interval));		iwe.u.data.length = strlen(buf);		current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe,						  buf);		memset(&iwe, 0, sizeof(iwe));		iwe.cmd = IWEVCUSTOM;		sprintf(buf, "resp_rate=%d", le16_to_cpu(scan->rate));		iwe.u.data.length = strlen(buf);		current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe,						  buf);		if (local->last_scan_type == PRISM2_HOSTSCAN &&		    (capabilities & WLAN_CAPABILITY_IBSS)) {			memset(&iwe, 0, sizeof(iwe));			iwe.cmd = IWEVCUSTOM;			sprintf(buf, "atim=%d", le16_to_cpu(scan->atim));			iwe.u.data.length = strlen(buf);			current_ev = iwe_stream_add_point(current_ev, end_buf,							  &iwe, buf);		}	}	kfree(buf);	if (bss && bss->wpa_ie_len > 0 && bss->wpa_ie_len <= MAX_WPA_IE_LEN) {		memset(&iwe, 0, sizeof(iwe));		iwe.cmd = IWEVGENIE;		iwe.u.data.length = bss->wpa_ie_len;

⌨️ 快捷键说明

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