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

📄 wvlan_cs.c

📁 pcmcia source code
💻 C
📖 第 1 页 / 共 5 页
字号:
			else				wrq->u.mode = IW_MODE_ADHOC;			/* Check for compliant 802.11 IBSS Ad-Hoc mode */			if ((local->has_ibssid) &&			    (wvlan_hw_getallowibssflag(&local->ifb) == 1))				wrq->u.mode = IW_MODE_ADHOC;			break;		// Set the desired Power Management mode		case SIOCSIWPOWER:			// Disable it ?			if(wrq->u.power.disabled) {				local->pm_on = 0;				local->need_commit = 1;			} else {				// Check mode				switch(wrq->u.power.flags & IW_POWER_MODE)				{					case IW_POWER_UNICAST_R:						local->pm_multi = 0;						local->need_commit = 1;						break;					case IW_POWER_ALL_R:						local->pm_multi = 1;						local->need_commit = 1;						break;					case IW_POWER_ON:	// None = ok						break;					default:	// Invalid						rc = -EINVAL;				}				// Set period				if (wrq->u.power.flags & IW_POWER_PERIOD)				{					// Activate PM					local->pm_on = 1;					// Hum: check max/min values ?					local->pm_period = wrq->u.power.value/1000;					local->need_commit = 1;				}				if (wrq->u.power.flags & IW_POWER_TIMEOUT)					rc = -EINVAL;	// Invalid			}			break;		// Get the power management settings		case SIOCGIWPOWER:			wrq->u.power.disabled = !wvlan_hw_getpower(&local->ifb, CFG_CNF_PM_ENABLED);			wrq->u.power.flags = IW_POWER_PERIOD;			wrq->u.power.value = wvlan_hw_getpmsleep (&local->ifb) * 1000;			if (wvlan_hw_getpower(&local->ifb, CFG_CNF_MCAST_RX))				wrq->u.power.flags |= IW_POWER_ALL_R;			else				wrq->u.power.flags |= IW_POWER_UNICAST_R;			break;		// Set WEP keys and mode		case SIOCSIWENCODE:			// Is it supported?			if (!wvlan_hw_getprivacy(&local->ifb))			{				rc = -EOPNOTSUPP;				break;			}			// Basic checking: do we have a key to set?			if (wrq->u.encoding.pointer != (caddr_t) 0)			{				int index = (wrq->u.encoding.flags & IW_ENCODE_INDEX) - 1;				// Check the size of the key				if (wrq->u.encoding.length > MAX_KEY_SIZE)				{					rc = -EINVAL;					break;				}				// Check the index				if ((index < 0) || (index >= MAX_KEYS))					index = local->transmit_key;				// Cleanup				memset(local->key[index].key, 0, MAX_KEY_SIZE);				// Copy the key in the driver				wv_driver_unlock(local, &flags);				rc = copy_from_user(local->key[index].key, wrq->u.encoding.pointer, wrq->u.encoding.length);				wv_driver_lock(local, &flags);				if (rc) {					rc = -EFAULT;					local->key[index].len = 0;					break;				}				// Set the length				if (wrq->u.encoding.length > MIN_KEY_SIZE)					local->key[index].len = MAX_KEY_SIZE;				else					if (wrq->u.encoding.length > 0)						local->key[index].len = MIN_KEY_SIZE;					else						local->key[index].len = 0;				// Enable WEP (if possible)				if ((index == local->transmit_key) && (local->key[local->transmit_key].len > 0))					local->wep_on = 1;			}			else			{				int index = (wrq->u.encoding.flags & IW_ENCODE_INDEX) - 1;				// Do we want to just set the current transmit key?				if ((index >= 0) && (index < MAX_KEYS))				{					if (local->key[index].len > 0)					{						local->transmit_key = index;						local->wep_on = 1;					}					else						rc = -EINVAL;				}			}			// Read the flags			if (wrq->u.encoding.flags & IW_ENCODE_DISABLED)				local->wep_on = 0;	// disable encryption			if (wrq->u.encoding.flags & IW_ENCODE_RESTRICTED)				rc = -EINVAL;		// Invalid			// Commit the changes			if (rc == 0)				local->need_commit = 1;			break;		// Get the WEP keys and mode		case SIOCGIWENCODE:			// Is it supported?			if (!wvlan_hw_getprivacy(&local->ifb))			{				rc = -EOPNOTSUPP;				break;			}			// Only super-user can see WEP key			if (!capable(CAP_NET_ADMIN))			{				rc = -EPERM;				break;			}			// Basic checking...			if (wrq->u.encoding.pointer != (caddr_t) 0)			{				int index = (wrq->u.encoding.flags & IW_ENCODE_INDEX) - 1;				// Note: should read from adapter(?), and check if WEP capable				// Set the flags				wrq->u.encoding.flags = 0;				if (local->wep_on == 0)					wrq->u.encoding.flags |= IW_ENCODE_DISABLED;				// Which key do we want				if ((index < 0) || (index >= MAX_KEYS))					index = local->transmit_key;				wrq->u.encoding.flags |= index + 1;				// Copy the key to the user buffer				wrq->u.encoding.length = local->key[index].len;				wv_driver_unlock(local, &flags);				rc = copy_to_user(wrq->u.encoding.pointer, local->key[index].key, local->key[index].len);				wv_driver_lock(local, &flags);				if (rc)					rc = -EFAULT;							}			break;#endif /* WIRELESS_EXT > 8 */#if WIRELESS_EXT > 9		// Get the current Tx-Power		case SIOCGIWTXPOW:			wrq->u.txpower.value = 15;	/* 15 dBm */			wrq->u.txpower.fixed = 1;	/* No power control */			wrq->u.txpower.disabled = 0;	/* Can't turn off */			wrq->u.txpower.flags = IW_TXPOW_DBM;			break;#endif /* WIRELESS_EXT > 9 */		// Get range of parameters		case SIOCGIWRANGE:			if (wrq->u.data.pointer)			{				struct iw_range range;				rc = verify_area(VERIFY_WRITE, wrq->u.data.pointer, sizeof(struct iw_range));				if (rc)					break;				/* Set the length (very important for				 * backward compatibility) */				wrq->u.data.length = sizeof(range);				/* Set all the info we don't care or				 * don't know about to zero */				memset(&range, 0, sizeof(range));#if WIRELESS_EXT > 10				/* Set the Wireless Extension versions */				range.we_version_compiled = WIRELESS_EXT;				range.we_version_source = 10;#endif /* WIRELESS_EXT > 10 */				// Throughput is no way near 2 Mb/s !				// This value should be :				//	1.6 Mb/s for the 2 Mb/s card				//	~5 Mb/s for the 11 Mb/s card				// Jean II				range.throughput = 1.6 * 1024 * 1024;				range.min_nwid = 0x0000;				range.max_nwid = 0x0000;				range.num_channels = 14;				range.num_frequency = wvlan_hw_getfrequencylist(&local->ifb,						      range.freq,						      IW_MAX_FREQUENCIES);				range.sensitivity = 3;				if (local->port_type == 3 &&				    local->spy_number == 0)				{					range.max_qual.qual = 0;					range.max_qual.level = 0;					range.max_qual.noise = 0;				}				else				{					range.max_qual.qual = 0x8b - 0x2f;					range.max_qual.level = 0x2f - 0x95 - 1;					range.max_qual.noise = 0x2f - 0x95 - 1;				}#if WIRELESS_EXT > 7				range.num_bitrates = wvlan_getbitratelist(&local->ifb,							range.bitrate,							IW_MAX_BITRATES);				range.min_rts = 0;				range.max_rts = 2347;				range.min_frag = 256;				range.max_frag = 2346;#endif	/* WIRELESS_EXT > 7 */#if WIRELESS_EXT > 8				// Is WEP it supported?				if (wvlan_hw_getprivacy(&local->ifb))				{					// WEP: RC4 40 bits					range.encoding_size[0] = MIN_KEY_SIZE;					// RC4 ~128 bits					range.encoding_size[1] = MAX_KEY_SIZE;					range.num_encoding_sizes = 2;					range.max_encoding_tokens = 4;	// 4 keys				}				else				{					range.num_encoding_sizes = 0;					range.max_encoding_tokens = 0;				}#endif /* WIRELESS_EXT > 8 */#if WIRELESS_EXT > 9				/* Power Management */				range.min_pmp = 0;		/* ??? */				range.max_pmp = 65535000;	/* ??? */				range.pmp_flags = IW_POWER_PERIOD;				range.pmt_flags = 0;				range.pm_capa = IW_POWER_PERIOD |				  IW_POWER_UNICAST_R;				/* Transmit Power */				range.txpower[0] = 15;				range.num_txpower = 1;				range.txpower_capa = IW_TXPOW_DBM;#endif /* WIRELESS_EXT > 9 */				wv_driver_unlock(local, &flags);				rc = copy_to_user(wrq->u.data.pointer, &range, sizeof(struct iw_range));				wv_driver_lock(local, &flags);				if (rc)					rc = -EFAULT;			}			break;#ifdef WIRELESS_SPY		// Set the spy list		case SIOCSIWSPY:			if (wrq->u.data.length > IW_MAX_SPY)			{				rc = -E2BIG;				break;			}			local->spy_number = wrq->u.data.length;			if (local->spy_number > 0)			{				struct sockaddr address[IW_MAX_SPY];				int i;				rc = verify_area(VERIFY_READ, wrq->u.data.pointer, sizeof(struct sockaddr) * local->spy_number);				if (rc)					break;				wv_driver_unlock(local, &flags);				rc = copy_from_user(address, wrq->u.data.pointer, sizeof(struct sockaddr) * local->spy_number);				wv_driver_lock(local, &flags);				if (rc) {					rc = -EFAULT;					break;				}				for (i=0; i<local->spy_number; i++)					memcpy(local->spy_address[i], address[i].sa_data, MAC_ADDR_SIZE);				memset(local->spy_stat, 0, sizeof(struct iw_quality) * IW_MAX_SPY);				DEBUG(DEBUG_INFO, "%s: New spy list:\n", dev_info);				for (i=0; i<wrq->u.data.length; i++)					DEBUG(DEBUG_INFO, "%s: %d - %02x:%02x:%02x:%02x:%02x:%02x\n", dev_info, i+1,						local->spy_address[i][0], local->spy_address[i][1],						local->spy_address[i][2], local->spy_address[i][3],						local->spy_address[i][4], local->spy_address[i][5]);			}			break;		// Get the spy list		case SIOCGIWSPY:			wrq->u.data.length = local->spy_number;			if ((local->spy_number > 0) && (wrq->u.data.pointer))			{				struct sockaddr address[IW_MAX_SPY];				int i;				rc = verify_area(VERIFY_WRITE, wrq->u.data.pointer, (sizeof(struct iw_quality)+sizeof(struct sockaddr)) * IW_MAX_SPY);				if (rc)					break;				for (i=0; i<local->spy_number; i++)				{					memcpy(address[i].sa_data, local->spy_address[i], MAC_ADDR_SIZE);					address[i].sa_family = AF_UNIX;				}				wv_driver_unlock(local, &flags);				rc = copy_to_user(wrq->u.data.pointer, address, sizeof(struct sockaddr) * local->spy_number);				rc += copy_to_user(wrq->u.data.pointer + (sizeof(struct sockaddr)*local->spy_number), local->spy_stat, sizeof(struct iw_quality) * local->spy_number);				wv_driver_lock(local, &flags);				if (rc)					rc = -EFAULT;				for (i=0; i<local->spy_number; i++)					local->spy_stat[i].updated = 0;			}			break;#endif /* WIRELESS_SPY */#ifdef HISTOGRAM		// Set the histogram range		case SIOCDEVPRIVATE + 0xd:			// Only super-user can set histogram data			if (!capable(CAP_NET_ADMIN))			{				rc = -EPERM;				break;			}			if (wrq->u.data.length > 16)			{				rc = -E2BIG;				break;			}			local->his_number = wrq->u.data.length;			if (local->his_number > 0)			{				rc = verify_area(VERIFY_READ, wrq->u.data.pointer, sizeof(char) * local->his_number);				if (rc)					break;				wv_driver_unlock(local, &flags);				rc = copy_from_user(local->his_range, wrq->u.data.pointer, sizeof(char) * local->his_number);				wv_driver_lock(local, &flags);				if (rc) {					rc = -EFAULT;					break;				}				memset(local->his_sum, 0, sizeof(long) * 16);			}			break;		// Get the histogram statistic		case SIOCDEVPRIVATE + 0xe:			wrq->u.data.length = local->his_number;			if ((local->his_number > 0) && (wrq->u.data.pointer))			{				rc = verify_area(VERIFY_WRITE, wrq->u.data.pointer, sizeof(long) * 16);				if (rc)					break;				wv_driver_unlock(local, &flags);				rc = copy_to_user(wrq->u.data.pointer, local->his_sum, sizeof(long) * local->his_number);				wv_driver_lock(local, &flags);				if (rc)					rc = -EFAULT;			}			break;#endif /* HISTOGRAM */		// Get valid private ioctl calls		case SIOCGIWPRIV:			if (wrq->u.data.pointer)			{				struct iw_priv_args priv[] = {#ifdef HISTOGRAM					{ SIOCDEVPRIVATE + 0xd, IW_PRIV_TYPE_BYTE | 16, 0, "sethisto" },					{ SIOCDEVPRIVATE + 0xe, 0, IW_PRIV_TYPE_INT | 16, "gethisto" },#endif#ifdef PCMCIA_DEBUG					{ SIOCDEVPRIVATE + 0x0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "force_reset" },					{ SIOCDEVPRIVATE + 0x1, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "debug_getinfo" },#endif				};				rc = verify_area(VERIFY_WRITE, wrq->u.data.pointer, sizeof(priv));				if (rc)					break;				wrq->u.data.length = sizeof(priv) / sizeof(priv[0]);				wv_driver_unlock(local, &flags);				rc = copy_to_user(wrq->u.data.pointer, priv, sizeof(priv));				wv_driver_lock(local, &flags);				if (rc)					rc = -EFAULT;			}			break;#ifdef PCMCIA_DEBUG		// Force card reset (debug purpose only)		case SIOCDEVPRIVATE + 0x0:			// Only super-user can reset the card...			if (!capable(CAP_NET_ADMIN))			{				rc = -EPERM;				break;			}			if (*((int *) wrq->u.name) > 0)			{				// 'hard' reset				printk(KERN_DEBUG "%s: Forcing hard reset\n", dev_info);				/* IRQ already disabled, don't do it again */				wvlan_hw_shutdown(dev);				wvlan_hw_config(dev);			}			else			{				// 'soft' reset				printk(KERN_DEBUG "%s: Forc

⌨️ 快捷键说明

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