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

📄 sm_drv_ioctl_umac.c

📁 cx3110 drivers for linux 2.6 (基于SPI)
💻 C
📖 第 1 页 / 共 4 页
字号:
		essid.length = 0;		scan_mode = SCAN_MODE_PASSIVE;	}	ret = sm_drv_oid_set(dev, DOT11_OID_SCANMODE, (void*)&scan_mode, sizeof(uint32_t));	if (ret < 0)		return ret;	ret = sm_drv_oid_set(dev, DOT11_OID_SCANSSID, (void*)&essid, sizeof(struct obj_ssid));	if (ret < 0)		return ret;		/* We let the background scanning work a bit...*/	if (scan_mode == SCAN_MODE_PASSIVE && lp->link_state != DOT11_STATE_ASSOC)		msleep(2000);	/* Let's start the scan timer in case UMAC doesn't trap the scan event */	mod_timer(&lp->scan_timer, jiffies + 4 * HZ);		if (lp->link_state != DOT11_STATE_ASSOC && 	    lp->bss_type != DOT11_BSSTYPE_IBSS) {		ret = sm_drv_oid_set(dev, DOT11_OID_AUTOSCANDISABLE,				     (void*)&bgr_scan_disable,				     sizeof(uint32_t));		if (ret < 0)			return ret;	}	/* And finally we send the scan request */	ret = sm_drv_oid_set(dev, DOT11_OID_SCAN, (void*)&scan, sizeof(int16_t));	if (ret < 0) {		/* 		 * If we're associated, we haven't disable bgr scan,		 * so we don't need to go there.		 */		if (lp->link_state != DOT11_STATE_ASSOC &&		    lp->bss_type != DOT11_BSSTYPE_IBSS)			goto scan_err_out;	}		return 0; scan_err_out:	DEBUG(DBG_ALL, "Scanning failed (err: %d), turning background scanning on\n", ret);	bgr_scan_disable = 0;	sm_drv_oid_set(dev, DOT11_OID_AUTOSCANDISABLE, (void*)&bgr_scan_disable, sizeof(uint32_t));		return ret;}int sm_drv_get_scan(struct net_device *dev, struct iw_request_info *info,		    struct iw_point *dwrq, char *extra){	int ret;	char *current_ev = extra;		DEBUG(DBG_IOCTL, "GET SCAN\n");	ret = sm_drv_parse_bssid(dev, NULL, 0, &current_ev);	if (ret < 0)		return ret;	dwrq->length = (current_ev - extra);	dwrq->flags = 0;			return 0;}static int set_auth_order(struct net_device *dev, uint16_t flags){	uint8_t auth_order[4];		DEBUG(DBG_WPA, "AUTHORDER flags: 0x%x\n", flags);	switch (flags) {	case IW_AUTH_NOWPA:				auth_order[0] = DOT11_AUTHALG_OS; 		auth_order[1] = DOT11_AUTHALG_SK;		auth_order[2] = DOT11_AUTHALG_NONE;		break;	case IW_AUTH_WPA:		DEBUG(DBG_WPA, "WPA authorder\n");		auth_order[0] = DOT11_AUTHALG_WPA;		auth_order[1] = DOT11_AUTHALG_NONE;		break;	case IW_AUTH_WPA_PSK:		DEBUG(DBG_WPA, "WPA_PSK authorder\n");		auth_order[0] = DOT11_AUTHALG_WPAPSK;		auth_order[1] = DOT11_AUTHALG_NONE;		break;	case IW_AUTH_WPA2:		DEBUG(DBG_WPA, "WPA2 authorder\n");		auth_order[0] = DOT11_AUTHALG_WPA2;		auth_order[1] = DOT11_AUTHALG_NONE;		break;	case IW_AUTH_WPA2_PSK:		DEBUG(DBG_WPA, "WPA2_PSK authorder\n");		auth_order[0] = DOT11_AUTHALG_WPA2PSK;		auth_order[1] = DOT11_AUTHALG_NONE;		break;	default:		printk("Using default authentication order\n");		auth_order[0] = DOT11_AUTHALG_OS; 		auth_order[1] = DOT11_AUTHALG_SK;		auth_order[2] = DOT11_AUTHALG_NONE;		break;	}	return sm_drv_oid_set(dev, DOT11_OID_AUTHORDER, (void*)auth_order, 4 * sizeof(uint8_t));}static int sm_drv_set_essid(struct net_device *dev, struct iw_request_info *info,			    struct iw_point *dwrq, char *extra){	uint32_t ret;	struct obj_ssid essid;	DEBUG(DBG_IOCTL, "SET ESSID\n");	memset(essid.octets, 0, 33);		/* Check if we were asked for `any' */	if (dwrq->flags && dwrq->length) {		if (dwrq->length > min(33, IW_ESSID_MAX_SIZE + 1))			return -E2BIG;		essid.length = dwrq->length - 1;		DEBUG(DBG_IOCTL, "New ESSID name: %s\n", extra);		memcpy(essid.octets, extra, dwrq->length);	} else		essid.length = 0;		ret = set_auth_order(dev, dwrq->flags & IW_AUTH_MASK);	if (ret < 0)		return ret;	return sm_drv_oid_set(dev, DOT11_OID_SSID, (void*)&essid, sizeof(struct obj_ssid));}static int sm_drv_get_essid(struct net_device *dev, struct iw_request_info *info,			    struct iw_point *dwrq, char *extra){	struct obj_ssid essid;	int ret;	DEBUG(DBG_IOCTL, "GET ESSID\n");	ret = sm_drv_oid_get(dev, DOT11_OID_SSID, (void*)&essid, sizeof(struct obj_ssid));		if (ret < 0) {		extra = "\0";		return 0;	}	if (essid.length) {		/* set ESSID to ON for Wireless Extensions */		dwrq->flags = 1;		/* if it is to big, trunk it */		dwrq->length = min(IW_ESSID_MAX_SIZE, essid.length + 1);	} else {		dwrq->flags = 0;		dwrq->length = 0;	}		essid.octets[essid.length] = '\0';	memcpy(extra, essid.octets, dwrq->length);		return 0;}static int sm_drv_set_rate(struct net_device *dev,			   struct iw_request_info *info,			   struct iw_param *vwrq, char *extra){	u32 rate;	uint8_t data[17];	int ret, i;		DEBUG(DBG_IOCTL, "SET RATE\n");	/*	 * First we need to get the supported rates	 */	ret = sm_drv_oid_get(dev, DOT11_OID_SUPPORTEDRATES, (void *)data, 17 * sizeof(uint8_t));	if (ret < 0)		return ret;	rate = (u32) (vwrq->value / 500000);	i = 0;	while (data[i]) {		DEBUG(DBG_IOCTL, "rate[%d]->%d\n", i, data[i]);		if (rate && (data[i] == rate)) {			break;		}		if (vwrq->value == i) {			break;		}		data[i] |= 0x80;		i++;	}			if (!data[i])		return -EINVAL;		data[i] |= 0x80;	data[i + 1] = 0;		/* Now, check if we want a fixed or auto value */	if (vwrq->fixed) {		data[0] = data[i];		data[1] = 0;	}	ret = sm_drv_oid_set(dev, DOT11_OID_EXTENDEDRATES, (void *)data, 17 * sizeof(uint8_t));	if (ret < 0)		return ret;		ret = sm_drv_oid_set(dev, DOT11_OID_RATES, (void *)data, 17 * sizeof(uint8_t));	if (ret < 0)		return ret;		return -EINPROGRESS;}/* Get the current bit rate */static int sm_drv_get_rate(struct net_device *dev,			   struct iw_request_info *info,			   struct iw_param *vwrq, char *extra){	int ret;	uint32_t state;	DEBUG(DBG_IOCTL, "GET RATE\n");		/* Get the current bit rate */	ret = sm_drv_oid_get(dev, GEN_OID_LINKSTATE, (void *)&state, sizeof(uint32_t));	if (ret < 0)		return ret;	vwrq->value = state * 500000;	vwrq->fixed = 1;	 	return 0;}static int sm_drv_set_rts(struct net_device *dev, struct iw_request_info *info,			  struct iw_param *vwrq, char *extra){	DEBUG(DBG_IOCTL, "SET RTS\n");		return sm_drv_oid_set(dev, DOT11_OID_RTSTHRESH, (void*)&vwrq->value, sizeof(uint32_t));}static int sm_drv_get_rts(struct net_device *dev, struct iw_request_info *info,			  struct iw_param *vwrq, char *extra){	uint32_t rts, ret;		DEBUG(DBG_IOCTL, "SET RTS\n");	/* get the rts threshold */	ret = sm_drv_oid_get(dev, DOT11_OID_RTSTHRESH, (void *)&rts, sizeof(uint32_t));	if (ret < 0)		return ret;		vwrq->value = rts;		return ret;}static int sm_drv_set_frag(struct net_device *dev, struct iw_request_info *info,			  struct iw_param *vwrq, char *extra){	DEBUG(DBG_IOCTL, "SET RTS\n");		return sm_drv_oid_set(dev, DOT11_OID_FRAGTHRESH, (void*)&vwrq->value, sizeof(uint32_t));}static int sm_drv_get_frag(struct net_device *dev, struct iw_request_info *info,			  struct iw_param *vwrq, char *extra){	uint32_t frag, ret;		DEBUG(DBG_IOCTL, "SET RTS\n");	/* get the rts threshold */	ret = sm_drv_oid_get(dev, DOT11_OID_FRAGTHRESH, (void *)&frag, sizeof(uint32_t));	if (ret < 0)		return ret;		vwrq->value = frag;		return ret;}static int sm_drv_set_txpower(struct net_device *dev, struct iw_request_info *info,			      struct iw_param *vwrq, char *extra){		uint32_t output_power = vwrq->value;	DEBUG(DBG_IOCTL, "SET TXPOWER\n");		/* Conexant firmware operates in 1/4 dBm */	output_power *= 4;	if (vwrq->disabled) {		DEBUG(DBG_ALL, "Radio OFF not supported\n");		return 0;		//return sm_drv_oid_set(dev, GEN_OID_HIBERNATE, (void*)&radio_on, sizeof(uint32_t));	} else if (vwrq->fixed) {//		printk("Setting TX output power to %d dBm\n", output_power/4);		return sm_drv_oid_set(dev, DOT11_OID_OUTPUTPOWER, (void *)&output_power, sizeof(uint32_t));	} else {		DEBUG(DBG_IOCTL, "Radio is ON\n");		return 0;		//return sm_drv_oid_set(dev, GEN_OID_HIBERNATE, (void*)&radio_on, sizeof(uint32_t));	}}static int sm_drv_get_txpower(struct net_device *dev, struct iw_request_info *info,			      struct iw_param *vwrq, char *extra){	int ret;	uint32_t output_power;		DEBUG(DBG_IOCTL, "GET TXPOWER\n");	ret = sm_drv_oid_get(dev, DOT11_OID_OUTPUTPOWER, (void *)&output_power, sizeof(uint32_t));	if (ret < 0)		return ret;        /* Conexant firmware operates in 0.25 dBm (1/4 dBm) */		vwrq->value = output_power/4;	vwrq->fixed = 1;	        /* 	 * Radio is not turned off	 * btw: how is possible to turn off only the radio 	 */	vwrq->disabled = 0;	return ret;}static int sm_drv_set_encode(struct net_device *dev, struct iw_request_info *info,			     struct iw_point *dwrq, char *extra){	int ret = 0, force = 0;	int invoke = 0, exunencrypt = 0;		DEBUG(DBG_IOCTL, "SET ENCODE\n");		/* 	 * With the new API, it's impossible to get a NULL pointer.	 * New version of iwconfig set the IW_ENCODE_NOKEY flag	 * when no key is given, but older versions don't. 	 */	if (dwrq->length > 0) {		/* we have a key to set */		int index = (dwrq->flags & IW_ENCODE_INDEX) - 1;		int current_index;		struct obj_key key = {DOT11_PRIV_WEP, 0, ""};		/* 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 (!(dwrq->flags & IW_ENCODE_NOKEY)) {			key.length = dwrq->length > sizeof (key.key) ?			    sizeof (key.key) : dwrq->length;			memcpy(key.key, extra, key.length);			if ((index < 0) || (index > 3))				/* no index provided use the current one */				index = current_index;			/* now send the key to the card  */			ret = sm_drv_oid_set(dev, DOT11_OID_DEFKEYID + index + 1, (void *)&key, sizeof(struct obj_key));			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 = (dwrq->flags & IW_ENCODE_INDEX) - 1;		struct obj_key key = {DOT11_PRIV_WEP, 0, ""};				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;			ret = sm_drv_oid_get(dev, DOT11_OID_DEFKEYID + index + 1, (void *)&key, sizeof(struct obj_key)); 			if (ret < 0)				return ret;			/* We have a key there, let's turn encryption on */			if (key.length > 0)				force = 1;		} else {			if (!dwrq->flags & IW_ENCODE_MODE) {				/* we cannot do anything. Complain. */				return -EINVAL;			}		}	}	/* now read the flags     */	if (dwrq->flags & IW_ENCODE_DISABLED) {		/* Encoding disabled, 		 * authen = DOT11_AUTH_OS;		 * invoke = 0;		 * exunencrypt = 0; */	}	if (dwrq->flags & IW_ENCODE_OPEN)		/* Encode but accept non-encoded packets. No auth */		invoke = 1;	if ((dwrq->flags & IW_ENCODE_RESTRICTED) || force) {		/* Refuse non-encoded packets. Auth */		invoke = 1;		exunencrypt = 1;	}	/* do the change if requested  */	if ((dwrq->flags & IW_ENCODE_MODE) || force) {		ret = sm_drv_oid_set(dev, DOT11_OID_PRIVACYINVOKED, (void *)&invoke, sizeof(uint32_t));		ret |= sm_drv_oid_set(dev, DOT11_OID_EXUNENCRYPTED, (void *)&exunencrypt, sizeof(uint32_t));	}	return ret;}static int sm_drv_get_encode(struct net_device *dev, struct iw_request_info *info,			     struct iw_point *dwrq, char *extra){	struct obj_key key;	u32 devindex, index = (dwrq->flags & IW_ENCODE_INDEX) - 1;	uint32_t authen = 0, invoke = 0, exunencrypt = 0;	int ret;	DEBUG(DBG_IOCTL, "GET ENCODE\n");		/* first get the flags */	ret = sm_drv_oid_get(dev, DOT11_OID_AUTHENABLE, (void *)&authen, sizeof(uint32_t));	ret |= sm_drv_oid_get(dev, DOT11_OID_PRIVACYINVOKED, (void *)&invoke, sizeof(uint32_t));	ret |= sm_drv_oid_get(dev, DOT11_OID_EXUNENCRYPTED, (void *)&exunencrypt, sizeof(uint32_t));		if (ret < 0)		return ret;	if (invoke 	    && ((authen == DOT11_AUTH_OS) || (authen == DOT11_AUTH_BOTH)) 	    && exunencrypt) {		switch (invoke) {		case DOT11_PRIV_INV_WEP:			dwrq->flags = IW_ENCODE_RESTRICTED;			break;		case DOT11_PRIV_INV_TKIP:			dwrq->flags |= IW_ENCODE_TKIP;			break;		case DOT11_PRIV_INV_AES_CCMP:			dwrq->flags |= IW_ENCODE_AES;			break;					}	}	else if (((authen == DOT11_AUTH_OS) || (authen == DOT11_AUTH_BOTH)) 		 && !exunencrypt) {		/* If we set it to DISABLED, we won't see the keys */		dwrq->flags = IW_ENCODE_OPEN;	} else		/* The card should not work in this state */		dwrq->flags = 0;	/* get the current device key index */	ret = sm_drv_oid_get(dev, DOT11_OID_DEFKEYID, (void *)&devindex, sizeof(uint32_t)); 	if (ret < 0)		return ret;	if ((index < 0) || (index > 3))		/* no index provided, use the current one */		index = devindex;		ret = sm_drv_oid_get(dev, DOT11_OID_DEFKEYID + index + 1, (void *)&key, sizeof(struct obj_key)); 	if (ret < 0)		return ret;	dwrq->length = key.length;	memcpy(extra, key.key, dwrq->length);	/* return the used key index */	dwrq->flags |= devindex + 1;	return ret;}static int sm_drv_set_ps(struct net_device *dev, struct iw_request_info *info,			  struct iw_param *prq, char * extra){	uint32_t psm;	DEBUG(DBG_IOCTL, "SET PSM\n");		if (prq->disabled) {		printk("No power saving\n");		psm = DOT11_PSM_ACTIVE;	} else {		switch (prq->flags & IW_POWER_MODE) {		case IW_POWER_ALL_R:			psm = DOT11_PSM_POWERSAVE;			printk("Full PSM\n");			break;		default:						psm = DOT11_PSM_DYNAMIC;			printk("Dynamic PSM\n");		}				if (prq->value) {			uint32_t cam_timeout = prq->value;			int ret;			ret = sm_drv_oid_set(dev, DOT11_OID_CAMTIMEOUT, 					     (void *)&cam_timeout, 					     sizeof(uint32_t));			if (ret < 0)				return ret;						printk("PSM timeout %d ms\n", cam_timeout);		}		}				return sm_drv_oid_set(dev, DOT11_OID_PSM, (void *)&psm, sizeof(uint32_t));}static int sm_drv_get_ps(struct net_device *dev, struct iw_request_info *info,			 struct iw_param *prq, char * extra){	int ret = 0;	uint32_t psm, cam_timeout;	DEBUG(DBG_IOCTL, "GET PSM\n");	ret = sm_drv_oid_get(dev, DOT11_OID_PSM, (void *)&psm, sizeof(uint32_t));	if (ret < 0)		return ret;	ret = sm_drv_oid_get(dev, DOT11_OID_CAMTIMEOUT, (void *)&cam_timeout, sizeof(uint32_t));

⌨️ 快捷键说明

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