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

📄 sm_drv_ioctl_umac.c

📁 cx3110 drivers for linux 2.6 (基于SPI)
💻 C
📖 第 1 页 / 共 4 页
字号:
	if (ret < 0)		return ret;	if (psm == DOT11_PSM_ACTIVE) 		prq->disabled = 1;	else		prq->disabled = 0;	/* Note : by default, display the period */	if ((prq->flags & IW_POWER_TYPE) == IW_POWER_TIMEOUT) {		prq->flags = IW_POWER_TIMEOUT;		prq->value = cam_timeout;	} 	return ret;}#define WLAN_FC_TYPE_MGMT 0#define WLAN_FC_STYPE_ASSOC_REQ 0#define WLAN_FC_STYPE_REASSOC_REQ 2static int sm_drv_set_genie(struct net_device *dev,			    struct iw_request_info *info,			    union iwreq_data *wrqu, char *extra){	int alen, ret=0, i;	struct iw_point *dwrq;	struct obj_attachment *attach;		dwrq = &wrqu->data;	if (dwrq == NULL)		return -EINVAL;		if (dwrq->length) {				DEBUG(DBG_WPA, "IE:\n");		for (i = 0; i < dwrq->length; i++) {			DEBUG(DBG_WPA, "0x%02x ", *((char*)(dwrq->pointer) + i));		}		DEBUG(DBG_WPA, "\n");		alen = sizeof(struct obj_attachment) + dwrq->length;		attach = (struct obj_attachment *)kzalloc(alen, GFP_ATOMIC);		if (attach == NULL) 			return -ENOMEM;				memcpy(attach->data, dwrq->pointer, dwrq->length);					} else {		/* If length is set to 0, we remove the generic element from the frame */		alen = sizeof(struct obj_attachment);		attach = (struct obj_attachment *)kmalloc(alen, GFP_ATOMIC);	}		/* We attach the IE for association and re-association. This is neede for roaming */	attach->type = (WLAN_FC_TYPE_MGMT << 2) |		(WLAN_FC_STYPE_ASSOC_REQ << 4);	attach->id = -1;		attach->size = dwrq->length;		ret = sm_drv_oid_set(dev, DOT11_OID_ATTACHMENT, (void*)attach, alen);	if (ret < 0)		return ret;	attach->type = (WLAN_FC_TYPE_MGMT << 2) |		(WLAN_FC_STYPE_REASSOC_REQ << 4);	ret = sm_drv_oid_set(dev, DOT11_OID_ATTACHMENT, (void*)attach, alen);	kfree(attach);	return ret;	}static int sm_drv_set_pmk(struct net_device *dev, struct iw_request_info *info,			  struct iw_point *dwrq, char *extra){	struct iw_pmksa * pmk;	struct obj_stakey key;		if (dwrq == NULL)		return -EINVAL;		if (!dwrq->length)		return -EINVAL;	pmk = (struct iw_pmksa *)dwrq->pointer;		memset(&key, 0, sizeof(struct obj_stakey));	switch (pmk->cmd) {	case IW_PMKSA_ADD:		key.type = DOT11_PRIV_PMKID;		memcpy(key.address, pmk->bssid.sa_data, ETH_ALEN);				key.length = IW_PMKID_LEN;		memcpy(key.key, pmk->pmkid, IW_PMKID_LEN);				break;	case IW_PMKSA_REMOVE:		key.type = DOT11_PRIV_PMKID; 		memcpy(key.address, pmk->bssid.sa_data, ETH_ALEN);				break;	case IW_PMKSA_FLUSH:		break;	default:		DEBUG(DBG_WPA, "Invalid PMK command: %d\n", pmk->cmd);		return -EINVAL;	}		return sm_drv_oid_set(dev, DOT11_OID_STAKEY, (void *)&key, sizeof(struct obj_stakey));}/* Private handlers *//* First private ioctl after the WPA ones */#define SIOCIFWFIRST_SMPRIV                       SIOCIWFIRSTPRIV + 12/* Preamble settings */#define SM_DRV_SET_PREAMBLE                       SIOCIFWFIRST_SMPRIV#define SM_DRV_GET_PREAMBLE                       SIOCIFWFIRST_SMPRIV + 1static int sm_drv_set_preamble(struct net_device *dev, struct iw_request_info *info,			       __u32 * uwrq, char *extra){	DEBUG(DBG_IOCTL, "SET PREAMBLE\n");		if (uwrq == NULL)		return -EINVAL;	return sm_drv_oid_set(dev, DOT11_OID_PREAMBLESETTINGS, uwrq, sizeof(uint32_t));}static int sm_drv_get_preamble(struct net_device *dev, struct iw_request_info *info,			   __u32 * uwrq, char *extra){	uint32_t preamble, ret;		DEBUG(DBG_IOCTL, "GET PREAMBLE\n");	/* get the rts threshold */	ret = sm_drv_oid_get(dev, DOT11_OID_PREAMBLESETTINGS, (void *)&preamble, sizeof(uint32_t));	if (ret < 0)		return ret;	memcpy(extra, &preamble, sizeof(preamble));		return ret;}#define SM_DRV_SET_HIBERNATE                    SIOCIFWFIRST_SMPRIV + 2static int sm_drv_set_hibernate(struct net_device *dev, struct iw_request_info *info,				__u32 * uwrq, char *extra){	DEBUG(DBG_IOCTL, "SET HIBERNATE\n");		if (uwrq == NULL)		return -EINVAL;	return sm_drv_oid_set(dev, GEN_OID_HIBERNATE, uwrq, sizeof(uint32_t));}#define SM_DRV_SET_BGRSCAN                      SIOCIFWFIRST_SMPRIV + 4static int sm_drv_set_bgrscan(struct net_device *dev, struct iw_request_info *info,				  __u32 * uwrq, char *extra){	DEBUG(DBG_IOCTL, "SET BACKGROUND SCANNING\n");	return sm_drv_oid_set(dev, DOT11_OID_AUTOSCANDISABLE, uwrq, sizeof(uint32_t));}#define SM_DRV_SET_BEACONPERIOD                  SIOCIFWFIRST_SMPRIV + 6#define SM_DRV_GET_BEACONPERIOD                  SIOCIFWFIRST_SMPRIV + 7static int sm_drv_set_beaconperiod(struct net_device *dev, struct iw_request_info *info,				   __u32 * uwrq, char *extra){	DEBUG(DBG_IOCTL, "SET BEACON PERIOD\n");	if (uwrq == NULL)		return -EINVAL;	return sm_drv_oid_set(dev, DOT11_OID_BEACONPERIOD, uwrq, sizeof(uint32_t));}static int sm_drv_get_beaconperiod(struct net_device *dev, struct iw_request_info *info,				   __u32 * uwrq, char *extra){	uint32_t period, ret;		DEBUG(DBG_IOCTL, "GET BEACON PERIOD\n");	ret = sm_drv_oid_get(dev, DOT11_OID_BEACONPERIOD, (void *)&period, sizeof(uint32_t));	if (ret < 0)		return ret;		memcpy(extra, &period, sizeof(period));		return ret;}/* WPA related handlers */int sm_drv_process_bss_data(struct net_device* dev,  u8 *addr, 			     u8 *payload, size_t len, uint32_t event){	struct ieee80211_beacon_phdr *hdr;	u8 *pos, *end, *wpa1_ie_pos = NULL;	int i;	DEBUG(DBG_WPA, "Dumping frame for " MACSTR "\n", MAC2STR(addr));	for (i = 0; i < len; i++)		DEBUG(DBG_WPA, "0x%02x ",payload[i]);	DEBUG(DBG_WPA, "\n");	hdr = (struct ieee80211_beacon_phdr *) payload;	pos = (u8 *) (hdr + 1);	end = payload + len;	while (pos < end) {		/* If we find an RSN IE, we're done, we can send the IE event */		if (pos[0] == WPA2_EID_GENERIC && pos[1] >= 2 &&		    memcmp(pos + 2, wpa2_oid, 2) == 0) {			DEBUG(DBG_WPA, "Found WPA2 OID in beacon frame for " MACSTR "\n\n", MAC2STR(addr));			sm_drv_wpa_ie_add(dev, addr, pos, pos[1] + 2, event);							return 0;		}			/* 		 * If we find a WPA IE, we should continue to check if there's no RSN IE.		 * We just keep track of the WPA1 IE position. 		 */		if (pos[0] == WPA_EID_GENERIC && pos[1] >= 4 &&		    memcmp(pos + 2, wpa_oid, 4) == 0) {			DEBUG(DBG_WPA, "Found WPA OID in beacon frame for " MACSTR "\n\n", MAC2STR(addr));			wpa1_ie_pos = pos;		}		pos++;	}		if (wpa1_ie_pos != NULL) {		sm_drv_wpa_ie_add(dev, addr, wpa1_ie_pos, wpa1_ie_pos[1] + 2, event);						return 0;				}		/* 	 * We didn't find any WPA OID in the beacon,	 * let's remove the AP from the WPA list, if it's	 * there.	 */	sm_drv_wpa_ie_remove(dev, addr);	return -1;}static int sm_drv_set_encryption(struct net_device *dev, struct iw_request_info *info,				 struct iw_point *dwrq, char *extra){	int ret = 0, force = 0, i;	int invoke = 0, exunencrypt = 0;	struct wlan_crypt * crypt_info;	struct net_local *lp = dev->priv;	const char multicast_address[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};		DEBUG(DBG_WPA, "Calling set_encryption\n");	if (dwrq == NULL)		return -EINVAL;		if (!dwrq->length)		return -EINVAL;	crypt_info = (struct wlan_crypt *)dwrq->pointer;			DEBUG(DBG_WPA, "Key dumping:\n");	DEBUG(DBG_WPA, "  alg:   %s\n", crypt_info->alg);	DEBUG(DBG_WPA, "  flags: 0x%x\n", crypt_info->flags);	DEBUG(DBG_WPA, "  index: %d\n", crypt_info->idx);	DEBUG(DBG_WPA, "  key length: %d\n", crypt_info->key_len);	DEBUG(DBG_WPA, "  key:\n");	for (i = 0; i < crypt_info->key_len; i++)		DEBUG(DBG_WPA, "  0x%x\n", *((uint8_t *)crypt_info->key + i));	if (crypt_info->key_len > 0) {		int index = crypt_info->idx;		int current_index;		struct obj_stakey key;		/* get the current key index */		ret = sm_drv_oid_get(dev, DOT11_OID_DEFKEYID, (void *)&current_index, sizeof(uint32_t));		if (ret < 0)			return ret;		/* Verify that the key is not marked as invalid */		if (!(crypt_info->flags & IW_ENCODE_NOKEY)) {			key.length = dwrq->length > sizeof (key.key) ?			    sizeof (key.key) : dwrq->length;						if (crypt_info->flags & IW_ENCODE_TKIP) {				DEBUG(DBG_WPA, "TKIP encryption\n");								/* 				 * UMAC expects the key in AP mode: RX mic at the				 * end, and TX at byte 16.				 * This is 802.11i AP compliant, but not STA.				 * Conexant doesn't seem to care.				 */				memcpy(key.key, crypt_info->key, key.length -16);				memcpy(key.key+16, crypt_info->key+24, 8);				memcpy(key.key+24, crypt_info->key+16, 8);								key.type = DOT11_PRIV_TKIP;				invoke =  DOT11_PRIV_INV_TKIP;			}			else if (crypt_info->flags & IW_ENCODE_AES) {				DEBUG(DBG_WPA, "AES encryption\n");				memcpy(key.key, crypt_info->key, key.length);				key.type = DOT11_PRIV_AES_CCMP;				invoke =  DOT11_PRIV_INV_AES_CCMP;			}			if ((index < 0) || (index > 3)) {				/* no index provided use the current one */				index = current_index;			}			/* 			 * We can now send the key to the UMAC.			 * Flags tell us which key it is.			 */			if (crypt_info->flags & IW_ENCODE_UNICAST) {				DEBUG(DBG_WPA, "Setting key with Mac: " MACSTR "\n", MAC2STR(lp->ap_mac_address));				memcpy(key.address, lp->ap_mac_address, ETH_ALEN);			}			else if (crypt_info->flags & IW_ENCODE_MULTICAST)				memcpy(key.address, multicast_address, ETH_ALEN);			key.keyid = index;			key.ext = 0;						ret = sm_drv_oid_set(dev, DOT11_OID_STAKEY, (void *)&key, sizeof(struct obj_stakey));			if (ret < 0)				return ret;		}		/*		 * If a valid key is set, encryption should be enabled 		 * (user may turn it off later).		 * This is also how "iwconfig ethX key on" works		 */		if ((index == current_index) && (key.length > 0))			force = 1;	} else {		int index = (crypt_info->flags & IW_ENCODE_INDEX) - 1;		if ((index >= 0) && (index <= 3)) {			/* we want to set the key index */			ret = sm_drv_oid_set(dev, DOT11_OID_DEFKEYID, (void *)&index, sizeof(uint32_t));			if (ret < 0)				return ret;		} else {			if (!crypt_info->flags & IW_ENCODE_MODE) {				/* we cannot do anything. Complain. */				return -EINVAL;			}		}	}		/* now read the flags */	if (crypt_info->flags & IW_ENCODE_OPEN) {		/* Encode but accept non-encoded packets. No auth */		DEBUG(DBG_WPA, "Encode but accept non-encoded packets\n");	}	if ((crypt_info->flags & IW_ENCODE_RESTRICTED) || force) {		/* Refuse non-encoded packets. Auth */		DEBUG(DBG_WPA, "Refuse non-encoded packets\n");		exunencrypt = 1;	}	/* do the change if requested  */	if ((crypt_info->flags & IW_ENCODE_MODE) || force) {		uint32_t dot1x_enable = 1;		DEBUG(DBG_WPA, "PRIVACY INVOKED\n");		ret = sm_drv_oid_set(dev, DOT11_OID_PRIVACYINVOKED, (void *)&invoke, sizeof(uint32_t));		DEBUG(DBG_WPA, "EXUNENCRYPTED\n");		ret |= sm_drv_oid_set(dev, DOT11_OID_EXUNENCRYPTED, (void *)&exunencrypt, sizeof(uint32_t));		DEBUG(DBG_WPA, "Enabling 802.1x\n");		ret |= sm_drv_oid_set(dev, DOT11_OID_DOT1XENABLE, (void *)&dot1x_enable, sizeof(uint32_t));	}	return ret;}int sm_drv_set_wpa(struct net_device *dev, struct iw_request_info *info,		   __u32 * uwrq, char *extra){	struct net_local *lp = dev->priv;	int ret = 0;	uint32_t filter, dot1x_enable = 1;		if (uwrq == NULL)		return -EINVAL;	DEBUG(DBG_WPA, "Calling set_wpa\n");		filter = 1; /* Filter out all unencrypted frames */	dot1x_enable = 1;	lp->wpa = *uwrq;		switch (lp->wpa) {	case DOT11_PRIV_INV_NONE: /* Clears/disables WPA and friends */		filter = 0; /* Do not filter un-encrypted data */		break;	case DOT11_PRIV_INV_WEP:		dot1x_enable = 0;		break;	case DOT11_PRIV_INV_TKIP:		break;	case DOT11_PRIV_INV_AES_CCMP:		break;	default:		return -EINVAL;	}	ret = sm_drv_oid_set(dev, DOT11_OID_PRIVACYINVOKED, (void *)&(lp->wpa), sizeof(uint32_t));	ret |= sm_drv_oid_set(dev, DOT11_OID_EXUNENCRYPTED, (void *)&filter, sizeof(uint32_t));	ret |= sm_drv_oid_set(dev, DOT11_OID_DOT1XENABLE, (void *)&dot1x_enable, sizeof(uint32_t));	return ret;}int sm_drv_get_wpa(struct net_device *dev, struct iw_request_info *info,		__u32 * uwrq, char *extra){	struct net_local *lp = dev->priv;		*uwrq = lp->wpa;	return 0;}const iw_handler sm_drv_we_handler[] = {	(iw_handler) sm_drv_commit,	        /* SIOCSIWCOMMIT */	(iw_handler) sm_drv_get_name,	        /* SIOCGIWNAME */	(iw_handler) NULL,	                /* SIOCSIWNWID */	(iw_handler) NULL,	                /* SIOCGIWNWID */	(iw_handler) sm_drv_set_freq,	        /* SIOCSIWFREQ */	(iw_handler) sm_drv_get_freq,	        /* SIOCGIWFREQ */	(iw_handler) sm_drv_set_mode,	        /* SIOCSIWMODE */	(iw_handler) sm_drv_get_mode,	        /* SIOCGIWMODE */	(iw_handler) sm_drv_set_sens,	        /* SIOCSIWSENS */	(iw_handler) sm_drv_get_sens,	        /* SIOCGIWSENS */	(iw_handler) NULL,	                /* SIOCSIWRANGE */	(iw_handler) sm_drv_get_range,	        /* SIOCGIWRANGE */	(iw_handler) NULL,	                /* SIOCSIWPRIV */	(iw_handler) NULL,	                /* SIOCGIWPRIV */	(iw_handler) NULL,	                /* SIOCSIWSTATS */	(iw_handler) sm_drv_get_wireless_stats,	/* SIOCGIWSTATS */	(iw_handler) NULL,	                /* SIOCSIWSPY */	iw_handler_get_spy,	                /* SIOCGIWSPY */	iw_handler_set_thrspy,	                /* SIOCSIWTHRSPY */	iw_handler_get_thrspy,	                /* SIOCGIWTHRSPY */	(iw_handler) sm_drv_set_wap,	        /* SIOCSIWAP */	(iw_handler) sm_drv_get_wap,	        /* SIOCGIWAP */	(iw_handler) NULL,	                /* -- hole -- */	(iw_handler) NULL,	                /* SIOCGIWAPLIST deprecated */	(iw_handler) sm_drv_set_scan,	        /* SIOCSIWSCAN */	(iw_handler) sm_drv_get_scan,	        /* SIOCGIWSCAN */	(iw_handler) sm_drv_set_essid,	        /* SIOCSIWESSID */	(iw_handler) sm_drv_get_essid,	        /* SIOCGIWESSID */	(iw_handler) NULL,	                /* SIOCSIWNICKN */	(iw_handler) NULL,	                /* SIOCGIWNICKN */	(iw_handler) NULL,	                /* -- hole -- */	(iw_handler) NULL,	                /* -- hole -- */	(iw_handler) sm_drv_set_rate,	        /* SIOCSIWRATE */	(iw_handler) sm_drv_get_rate,	        /* SIOCGIWRATE */	(iw_handler) sm_drv_set_rts,	        /* SIOCSIWRTS */	(iw_handler) sm_drv_get_rts,	        /* SIOCGIWRTS */	(iw_handler) sm_drv_set_frag,	        /* SIOCSIWFRAG */	(iw_handler) sm_drv_get_frag,	        /* SIOCGIWFRAG */	(iw_handler) sm_drv_set_txpower,	/* SIOCSIWTXPOW */	(iw_handler) sm_drv_get_txpower,	/* SIOCGIWTXPOW */	(iw_handler) NULL,	                /* SIOCSIWRETRY */	(iw_handler) NULL,	                /* SIOCGIWRETRY */	(iw_handler) sm_drv_set_encode,	        /* SIOCSIWENCODE */	(iw_handler) sm_drv_get_encode,	        /* SIOCGIWENCODE */	(iw_handler) sm_drv_set_ps,	        /* SIOCSIWPOWER */	(iw_handler) sm_drv_get_ps,	        /* SIOCGIWPOWER */	(iw_handler) NULL,			/* -- hole -- */	(iw_handler) NULL,			/* -- hole -- */	(iw_handler) sm_drv_set_genie,          /* SIOCSIWGENIE*/	(iw_handler) NULL,	                /* SIOCGIWGENIE */	(iw_handler) NULL,	                /* SIOCSIWAUTH */	(iw_handler) NULL,	                /* SIOCGIWAUTH */	(iw_handler) NULL,	                /* SIOCSIWENCODEEXT */	(iw_handler) NULL,	                /* SIOCGIWENCODEEXT */	(iw_handler) sm_drv_set_pmk,		/* SIOCSIWPMKSA */};#define SM_DRV_SET_DEBUG                       SIOCIWFIRSTPRIVconst struct iw_priv_args sm_drv_we_private_args[] = {	{SM_DRV_SET_DEBUG, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "set_debug"},	{SM_DRV_WPA_SCAN, IW_PRIV_TYPE_NONE, IW_PRIV_TYPE_NONE, "wpa_scan"},	{SM_DRV_WPA_GEN_ELT, IW_PRIV_TYPE_BYTE | 256, 0, "gen_ie"},	{SM_DRV_SET_PREAMBLE, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "set_preamble"},	{SM_DRV_GET_PREAMBLE, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "get_preamble"},	{SM_DRV_SET_HIBERNATE, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "set_hibernate"},	{SM_DRV_SET_BGRSCAN, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "set_backscan"},	{SM_DRV_SET_BEACONPERIOD, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "set_bperiod"},	{SM_DRV_GET_BEACONPERIOD, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "get_bperiod"},};static const iw_handler sm_drv_we_private_handler[] = {	(iw_handler) sm_drv_set_debug,	(iw_handler) NULL,	(iw_handler) sm_drv_set_scan,	(iw_handler) NULL,	(iw_handler) sm_drv_set_genie,	(iw_handler) NULL,	(iw_handler) sm_drv_set_wpa,	(iw_handler) sm_drv_get_wpa,	(iw_handler) sm_drv_set_encryption,	(iw_handler) sm_drv_set_encryption,	(iw_handler) sm_drv_set_pmk,	(iw_handler) NULL,	(iw_handler) sm_drv_set_preamble,	(iw_handler) sm_drv_get_preamble,	(iw_handler) sm_drv_set_hibernate,	(iw_handler) NULL,	(iw_handler) sm_drv_set_bgrscan,	(iw_handler) NULL,	(iw_handler) sm_drv_set_beaconperiod,	(iw_handler) sm_drv_get_beaconperiod,};const struct iw_handler_def sm_drv_we_handler_def = {	.num_standard = sizeof(sm_drv_we_handler) / sizeof(iw_handler),	.num_private = sizeof(sm_drv_we_private_handler) / sizeof(iw_handler),	.num_private_args =	  sizeof(sm_drv_we_private_args) / sizeof(struct iw_priv_args),	.standard = (iw_handler *) sm_drv_we_handler,	.private = (iw_handler *) sm_drv_we_private_handler,	.private_args = (struct iw_priv_args *) sm_drv_we_private_args,	.get_wireless_stats = sm_drv_get_wireless_stats,};

⌨️ 快捷键说明

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