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

📄 hostap_ioctl.c

📁 IEEE 802.11a/b/g linux2.4/2.6 驱动程序源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
		}		data->length = val;		memcpy(essid, ssid + 2, IW_ESSID_MAX_SIZE);	}	return 0;}static int prism2_ioctl_giwrange(struct net_device *dev,				 struct iw_request_info *info,				 struct iw_point *data, char *extra){	struct hostap_interface *iface = dev->priv;	local_info_t *local = iface->local;	struct iw_range *range = (struct iw_range *) extra;	u8 rates[10];	u16 val;	int i, len, over2;	data->length = sizeof(struct iw_range);	memset(range, 0, sizeof(struct iw_range));	/* TODO: could fill num_txpower and txpower array with	 * something; however, there are 128 different values.. */	range->txpower_capa = IW_TXPOW_DBM;	if (local->iw_mode == IW_MODE_INFRA || local->iw_mode == IW_MODE_ADHOC)	{		range->min_pmp = 1 * 1024;		range->max_pmp = 65535 * 1024;		range->min_pmt = 1 * 1024;		range->max_pmt = 1000 * 1024;		range->pmp_flags = IW_POWER_PERIOD;		range->pmt_flags = IW_POWER_TIMEOUT;		range->pm_capa = IW_POWER_PERIOD | IW_POWER_TIMEOUT |			IW_POWER_UNICAST_R | IW_POWER_ALL_R;	}	range->we_version_compiled = WIRELESS_EXT;	range->we_version_source = 18;	range->retry_capa = IW_RETRY_LIMIT;	range->retry_flags = IW_RETRY_LIMIT;	range->min_retry = 0;	range->max_retry = 255;	range->num_channels = FREQ_COUNT;	val = 0;	for (i = 0; i < FREQ_COUNT; i++) {		if (local->channel_mask & (1 << i)) {			range->freq[val].i = i + 1;			range->freq[val].m = freq_list[i] * 100000;			range->freq[val].e = 1;			val++;		}		if (val == IW_MAX_FREQUENCIES)			break;	}	range->num_frequency = val;	if (local->sta_fw_ver >= PRISM2_FW_VER(1,3,1)) {		range->max_qual.qual = 70; /* what is correct max? This was not					    * documented exactly. At least					    * 69 has been observed. */		range->max_qual.level = 0; /* dB */		range->max_qual.noise = 0; /* dB */		/* What would be suitable values for "average/typical" qual? */		range->avg_qual.qual = 20;		range->avg_qual.level = -60;		range->avg_qual.noise = -95;	} else {		range->max_qual.qual = 92; /* 0 .. 92 */		range->max_qual.level = 154; /* 27 .. 154 */		range->max_qual.noise = 154; /* 27 .. 154 */	}	range->sensitivity = 3;	range->max_encoding_tokens = WEP_KEYS;	range->num_encoding_sizes = 2;	range->encoding_size[0] = 5;	range->encoding_size[1] = 13;	over2 = 0;	len = prism2_get_datarates(dev, rates);	range->num_bitrates = 0;	for (i = 0; i < len; i++) {		if (range->num_bitrates < IW_MAX_BITRATES) {			range->bitrate[range->num_bitrates] =				rates[i] * 500000;			range->num_bitrates++;		}		if (rates[i] == 0x0b || rates[i] == 0x16)			over2 = 1;	}	/* estimated maximum TCP throughput values (bps) */	range->throughput = over2 ? 5500000 : 1500000;	range->min_rts = 0;	range->max_rts = 2347;	range->min_frag = 256;	range->max_frag = 2346;#if WIRELESS_EXT > 16	/* Event capability (kernel + driver) */	range->event_capa[0] = (IW_EVENT_CAPA_K_0 |				IW_EVENT_CAPA_MASK(SIOCGIWTHRSPY) |				IW_EVENT_CAPA_MASK(SIOCGIWAP) |				IW_EVENT_CAPA_MASK(SIOCGIWSCAN));	range->event_capa[1] = IW_EVENT_CAPA_K_1;	range->event_capa[4] = (IW_EVENT_CAPA_MASK(IWEVTXDROP) |				IW_EVENT_CAPA_MASK(IWEVCUSTOM) |				IW_EVENT_CAPA_MASK(IWEVREGISTERED) |				IW_EVENT_CAPA_MASK(IWEVEXPIRED));#endif /* WIRELESS_EXT > 16 */#if WIRELESS_EXT > 17	range->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_WPA2 |		IW_ENC_CAPA_CIPHER_TKIP | IW_ENC_CAPA_CIPHER_CCMP;#endif /* WIRELESS_EXT > 17 */	return 0;}static int hostap_monitor_mode_enable(local_info_t *local){	struct net_device *dev = local->dev;	printk(KERN_DEBUG "Enabling monitor mode\n");	hostap_monitor_set_type(local);	if (hostap_set_word(dev, HFA384X_RID_CNFPORTTYPE,			    HFA384X_PORTTYPE_PSEUDO_IBSS)) {		printk(KERN_DEBUG "Port type setting for monitor mode "		       "failed\n");		return -EOPNOTSUPP;	}	/* Host decrypt is needed to get the IV and ICV fields;	 * however, monitor mode seems to remove WEP flag from frame	 * control field */	if (hostap_set_word(dev, HFA384X_RID_CNFWEPFLAGS,			    HFA384X_WEPFLAGS_HOSTENCRYPT |			    HFA384X_WEPFLAGS_HOSTDECRYPT)) {		printk(KERN_DEBUG "WEP flags setting failed\n");		return -EOPNOTSUPP;	}	if (local->func->reset_port(dev) ||	    local->func->cmd(dev, HFA384X_CMDCODE_TEST |			     (HFA384X_TEST_MONITOR << 8),			     0, NULL, NULL)) {		printk(KERN_DEBUG "Setting monitor mode failed\n");		return -EOPNOTSUPP;	}	return 0;}static int hostap_monitor_mode_disable(local_info_t *local){	struct net_device *dev = local->ddev;	if (dev == NULL)		return -1;	printk(KERN_DEBUG "%s: Disabling monitor mode\n", dev->name);	dev->type = ARPHRD_ETHER;	dev->hard_header_parse = local->saved_eth_header_parse;	if (local->func->cmd(dev, HFA384X_CMDCODE_TEST |			     (HFA384X_TEST_STOP << 8),			     0, NULL, NULL))		return -1;	return hostap_set_encryption(local);}static int prism2_ioctl_siwmode(struct net_device *dev,				struct iw_request_info *info,				__u32 *mode, char *extra){	struct hostap_interface *iface = dev->priv;	local_info_t *local = iface->local;	int double_reset = 0;	if (*mode != IW_MODE_ADHOC && *mode != IW_MODE_INFRA &&	    *mode != IW_MODE_MASTER && *mode != IW_MODE_REPEAT &&	    *mode != IW_MODE_MONITOR)		return -EOPNOTSUPP;#ifdef PRISM2_NO_STATION_MODES	if (*mode == IW_MODE_ADHOC || *mode == IW_MODE_INFRA)		return -EOPNOTSUPP;#endif /* PRISM2_NO_STATION_MODES */	if (*mode == local->iw_mode)		return 0;	if (*mode == IW_MODE_MASTER && local->essid[0] == '\0') {		printk(KERN_WARNING "%s: empty SSID not allowed in Master "		       "mode\n", dev->name);		return -EINVAL;	}	if (local->iw_mode == IW_MODE_MONITOR)		hostap_monitor_mode_disable(local);	if ((local->iw_mode == IW_MODE_ADHOC ||	     local->iw_mode == IW_MODE_MONITOR) && *mode == IW_MODE_MASTER) {		/* There seems to be a firmware bug in at least STA f/w v1.5.6		 * that leaves beacon frames to use IBSS type when moving from		 * IBSS to Host AP mode. Doing double Port0 reset seems to be		 * enough to workaround this. */		double_reset = 1;	}	printk(KERN_DEBUG "prism2: %s: operating mode changed "	       "%d -> %d\n", dev->name, local->iw_mode, *mode);	local->iw_mode = *mode;	if (local->iw_mode == IW_MODE_MONITOR)		hostap_monitor_mode_enable(local);	else if (local->iw_mode == IW_MODE_MASTER && !local->host_encrypt &&		 !local->fw_encrypt_ok) {		printk(KERN_DEBUG "%s: defaulting to host-based encryption as "		       "a workaround for firmware bug in Host AP mode WEP\n",		       dev->name);		local->host_encrypt = 1;	}	if (hostap_set_word(dev, HFA384X_RID_CNFPORTTYPE,			    hostap_get_porttype(local)))		return -EOPNOTSUPP;	if (local->func->reset_port(dev))		return -EINVAL;	if (double_reset && local->func->reset_port(dev))		return -EINVAL;	if (local->iw_mode != IW_MODE_INFRA && local->iw_mode != IW_MODE_ADHOC)	{		/* netif_carrier is used only in client modes for now, so make		 * sure carrier is on when moving to non-client modes. */		netif_carrier_on(local->dev);		netif_carrier_on(local->ddev);	}	return 0;}static int prism2_ioctl_giwmode(struct net_device *dev,				struct iw_request_info *info,				__u32 *mode, char *extra){	struct hostap_interface *iface = dev->priv;	local_info_t *local = iface->local;	switch (iface->type) {	case HOSTAP_INTERFACE_STA:		*mode = IW_MODE_INFRA;		break;	case HOSTAP_INTERFACE_WDS:		*mode = IW_MODE_REPEAT;		break;	default:		*mode = local->iw_mode;		break;	}	return 0;}static int prism2_ioctl_siwpower(struct net_device *dev,				 struct iw_request_info *info,				 struct iw_param *wrq, char *extra){#ifdef PRISM2_NO_STATION_MODES	return -EOPNOTSUPP;#else /* PRISM2_NO_STATION_MODES */	int ret = 0;	if (wrq->disabled)		return hostap_set_word(dev, HFA384X_RID_CNFPMENABLED, 0);	switch (wrq->flags & IW_POWER_MODE) {	case IW_POWER_UNICAST_R:		ret = hostap_set_word(dev, HFA384X_RID_CNFMULTICASTRECEIVE, 0);		if (ret)			return ret;		ret = hostap_set_word(dev, HFA384X_RID_CNFPMENABLED, 1);		if (ret)			return ret;		break;	case IW_POWER_ALL_R:		ret = hostap_set_word(dev, HFA384X_RID_CNFMULTICASTRECEIVE, 1);		if (ret)			return ret;		ret = hostap_set_word(dev, HFA384X_RID_CNFPMENABLED, 1);		if (ret)			return ret;		break;	case IW_POWER_ON:		break;	default:		return -EINVAL;	}	if (wrq->flags & IW_POWER_TIMEOUT) {		ret = hostap_set_word(dev, HFA384X_RID_CNFPMENABLED, 1);		if (ret)			return ret;		ret = hostap_set_word(dev, HFA384X_RID_CNFPMHOLDOVERDURATION,				      wrq->value / 1024);		if (ret)			return ret;	}	if (wrq->flags & IW_POWER_PERIOD) {		ret = hostap_set_word(dev, HFA384X_RID_CNFPMENABLED, 1);		if (ret)			return ret;		ret = hostap_set_word(dev, HFA384X_RID_CNFMAXSLEEPDURATION,				      wrq->value / 1024);		if (ret)			return ret;	}	return ret;#endif /* PRISM2_NO_STATION_MODES */}static int prism2_ioctl_giwpower(struct net_device *dev,				 struct iw_request_info *info,				 struct iw_param *rrq, char *extra){#ifdef PRISM2_NO_STATION_MODES	return -EOPNOTSUPP;#else /* PRISM2_NO_STATION_MODES */	struct hostap_interface *iface = dev->priv;	local_info_t *local = iface->local;	u16 enable, mcast;	if (local->func->get_rid(dev, HFA384X_RID_CNFPMENABLED, &enable, 2, 1)	    < 0)		return -EINVAL;	if (!__le16_to_cpu(enable)) {		rrq->disabled = 1;		return 0;	}	rrq->disabled = 0;	if ((rrq->flags & IW_POWER_TYPE) == IW_POWER_TIMEOUT) {		u16 timeout;		if (local->func->get_rid(dev,					 HFA384X_RID_CNFPMHOLDOVERDURATION,					 &timeout, 2, 1) < 0)			return -EINVAL;		rrq->flags = IW_POWER_TIMEOUT;		rrq->value = __le16_to_cpu(timeout) * 1024;	} else {		u16 period;		if (local->func->get_rid(dev, HFA384X_RID_CNFMAXSLEEPDURATION,					 &period, 2, 1) < 0)			return -EINVAL;		rrq->flags = IW_POWER_PERIOD;		rrq->value = __le16_to_cpu(period) * 1024;	}	if (local->func->get_rid(dev, HFA384X_RID_CNFMULTICASTRECEIVE, &mcast,				 2, 1) < 0)		return -EINVAL;	if (__le16_to_cpu(mcast))		rrq->flags |= IW_POWER_ALL_R;	else		rrq->flags |= IW_POWER_UNICAST_R;	return 0;#endif /* PRISM2_NO_STATION_MODES */}static int prism2_ioctl_siwretry(struct net_device *dev,				 struct iw_request_info *info,				 struct iw_param *rrq, char *extra){	struct hostap_interface *iface = dev->priv;	local_info_t *local = iface->local;	if (rrq->disabled)		return -EINVAL;	/* setting retry limits is not supported with the current station	 * firmware code; simulate this with alternative retry count for now */	if (rrq->flags == IW_RETRY_LIMIT) {		if (rrq->value < 0) {			/* disable manual retry count setting and use firmware			 * defaults */			local->manual_retry_count = -1;			local->tx_control &= ~HFA384X_TX_CTRL_ALT_RTRY;		} else {			if (hostap_set_word(dev, HFA384X_RID_CNFALTRETRYCOUNT,					    rrq->value)) {				printk(KERN_DEBUG "%s: Alternate retry count "				       "setting to %d failed\n",				       dev->name, rrq->value);				return -EOPNOTSUPP;			}			local->manual_retry_count = rrq->value;			local->tx_control |= HFA384X_TX_CTRL_ALT_RTRY;		}		return 0;	}	return -EOPNOTSUPP;#if 0	/* what could be done, if firmware would support this.. */	if (rrq->flags & IW_RETRY_LIMIT) {		if (rrq->flags & IW_RETRY_MAX)			HFA384X_RID_LONGRETRYLIMIT = rrq->value;		else if (rrq->flags & IW_RETRY_MIN)			HFA384X_RID_SHORTRETRYLIMIT = rrq->value;		else {			HFA384X_RID_LONGRETRYLIMIT = rrq->value;			HFA384X_RID_SHORTRETRYLIMIT = rrq->value;		}	}	if (rrq->flags & IW_RETRY_LIFETIME) {		HFA384X_RID_MAXTRANSMITLIFETIME = rrq->value / 1024;	}	return 0;#endif /* 0 */}static int prism2_ioctl_giwretry(struct net_device *dev,				 struct iw_request_info *info,				 struct iw_param *rrq, char *extra){	struct hostap_interface *iface = dev->priv;	local_info_t *local = iface->local;	u16 shortretry, longretry, lifetime, altretry;	if (local->func->get_rid(dev, HFA384X_RID_SHORTRETRYLIMIT, &shortretry,				 2, 1) < 0 ||	    local->func->get_rid(dev, HFA384X_RID_LONGRETRYLIMIT, &longretry,				 2, 1) < 0 ||	    local->func->get_rid(dev, HFA384X_RID_MAXTRANSMITLIFETIME,				 &lifetime, 2, 1) < 0)		return -EINVAL;	le16_to_cpus(&shortretry);	le16_to_cpus(&longretry);	le16_to_cpus(&lifetime);

⌨️ 快捷键说明

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