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

📄 sm_drv_ioctl_umac.c

📁 cx3110 drivers for linux 2.6 (基于SPI)
💻 C
📖 第 1 页 / 共 4 页
字号:
	struct net_local *lp = dev->priv;	struct list_head *ptr;	struct sm_drv_bss_wpa_ie *bss = NULL;		if (down_trylock(&lp->wpa_sem))		return;		list_for_each(ptr, &lp->bss_wpa_list) {		bss = list_entry(ptr, struct sm_drv_bss_wpa_ie, list);		if (memcmp(bss->bssid, bssid, ETH_ALEN) == 0) {			/* AP is here, removing it...*/			DEBUG(DBG_WPA, "Removing " MACSTR " from wpa list...\n", MAC2STR(bssid));			list_del(&bss->list);			lp->num_bss_wpa--;			kfree(bss);			break;		}	}			up(&lp->wpa_sem);}void sm_drv_wpa_ie_clean(struct net_device *dev){	struct net_local *lp = dev->priv;	struct list_head *ptr, *n;	if (down_trylock(&lp->wpa_sem))		return;	list_for_each_safe(ptr, n, &lp->bss_wpa_list) {		struct  sm_drv_bss_wpa_ie *bss;		bss = list_entry(ptr, struct sm_drv_bss_wpa_ie, list);		list_del(&bss->list);		kfree(bss);	}	lp->num_bss_wpa = 0;	up(&lp->wpa_sem);}void sm_drv_update_stats(void * data){	struct net_device * dev = (struct net_device *)data;	struct net_local * lp = dev->priv;	struct obj_bss bss;	uint8_t bssid[ETH_ALEN];	uint32_t noise_floor, frame_stats;	sm_drv_oid_get(dev, DOT11_OID_NOISEFLOOR, (void*)&noise_floor, sizeof(uint32_t));	lp->iwstatistics.qual.noise = noise_floor;	/* copy this MAC to the bss */	bss.ext = 1;	if (sm_drv_oid_get(dev, DOT11_OID_BSSID, (void*)bssid, ETH_ALEN * sizeof(uint8_t)) < 0)		return;	memcpy(bss.address, bssid, ETH_ALEN);	/* now ask for the corresponding bss */	if (sm_drv_oid_get(dev, DOT11_OID_BSSFIND, (void *)&bss, sizeof(struct obj_bss)) < 0) {		bss.ext = 0;		if (sm_drv_oid_get(dev, DOT11_OID_BSSFIND, (void *)&bss, sizeof(struct obj_bss)) < 0)			return;	}	/* report the rssi and use it to calculate	 *  link quality through a signal-noise	 *  ratio 	 */	lp->iwstatistics.qual.level = bss.rssi;	lp->iwstatistics.qual.qual =		bss.rssi - lp->iwstatistics.qual.noise;	/* report that the stats are new */	lp->iwstatistics.qual.updated = 0x7;        /* Rx : unable to decrypt the MPDU */	sm_drv_oid_get(dev, DOT11_OID_PRIVRXFAILED, (void*)&frame_stats, sizeof(uint32_t));	lp->iwstatistics.discard.code = frame_stats;        /* Tx : Max MAC retries num reached */	sm_drv_oid_get(dev, DOT11_OID_MPDUTXFAILED, (void*)&frame_stats, sizeof(uint32_t));	lp->iwstatistics.discard.retries = frame_stats;	return;}struct iw_statistics * sm_drv_get_wireless_stats(struct net_device *dev){	struct net_local *lp = dev->priv;	if(!lp->sm_initialization) {		memset(&lp->iwstatistics, 0, sizeof(struct iw_statistics));		return &lp->iwstatistics;	}		lp->iwstatistics.qual.updated = 0;	/* 	 * Update our wireless stats, but do not schedule to often 	 * (max 1 HZ) 	 */	if ((lp->stats_timestamp == 0) ||	    time_after(jiffies, lp->stats_timestamp + 1 * HZ)) {		schedule_work(&lp->stats_work);		lp->stats_timestamp = jiffies;	}	return &lp->iwstatistics;}static int sm_drv_get_name(struct net_device *dev, struct iw_request_info *info,			   char *cwrq, char *extra){	struct net_local *lp = dev->priv;	char *capabilities;	uint32_t ret, profile;	DEBUG(DBG_IOCTL, "GET NAME\n");	if(!lp->sm_initialization) {		capabilities = "NOT READY";		ret = 0;		goto out;	}	ret = sm_drv_oid_get(dev, DOT11_OID_PROFILES, (void *)&profile, sizeof(uint32_t));		if (ret < 0) {		capabilities = "ERROR";		goto out;	}	DEBUG(DBG_IOCTL, "sm_drv_get_name: name-> 0x%x\n", profile);	switch (profile) {	case DOT11_PROFILE_B_ONLY:		capabilities = "IEEE 802.11b";		break;	case DOT11_PROFILE_MIXED:		capabilities = "IEEE 802.11b/g";		break;	case DOT11_PROFILE_MIXED_LONG:		capabilities = "IEEE 802.11b/g-long";		break;	case DOT11_PROFILE_G_ONLY:		capabilities = "IEEE 802.11g";		break;	case DOT11_PROFILE_TEST:		capabilities = "TEST profile";		break;	case DOT11_PROFILE_B_WIFI:		capabilities = "IEEE 802.11b wifi";		break;	case DOT11_PROFILE_MIXED_SHORT:		capabilities = "IEEE 802.1b/g-short";		break;	default:		capabilities = "Unknown profile";	/* Default */		break;	} out:	strncpy(cwrq, capabilities, IFNAMSIZ);	return ret;}static int sm_drv_set_freq(struct net_device *dev, struct iw_request_info *info,			   struct iw_freq *fwrq, char *extra){	int ret = 0;	uint32_t freq;	DEBUG(DBG_IOCTL, "SET FREQ: fwrq->m : %d fwrq->e : %d\n", fwrq->m, fwrq->e);	if (fwrq->m < 1000)		/* we have a channel number */		freq = freq_of_channel(fwrq->m);	else		freq = fwrq->m/1000;	DEBUG(DBG_IOCTL, "SET FREQ: freq is %d\n", freq);		if (!freq)		return -EINVAL;	else {				ret = sm_drv_oid_set(dev, DOT11_OID_FREQUENCY, (void *)&freq, sizeof(uint32_t));		if (ret < 0)			return ret;	}		return -EINPROGRESS;}static int sm_drv_get_freq(struct net_device *dev, struct iw_request_info *info,			   struct iw_freq *fwrq, char *extra){		uint32_t data[2];	DEBUG(DBG_IOCTL, "GET FREQ\n");	sm_drv_oid_get(dev, DOT11_OID_FREQUENCY, (void *)data, 2 * sizeof(uint32_t));			fwrq->m = channel_of_freq(data[0] / 1000);	fwrq->e = 0;	return 0;}static int sm_drv_set_mode(struct net_device *dev, struct iw_request_info *info,			   __u32 * uwrq, char *extra){	struct net_local * lp = dev->priv;	uint32_t sm_mode, mode, current_mode, err, bss_type, profile, ret, commit = 0;		DEBUG(DBG_IOCTL, "SET MODE\n");	mode = *(uint32_t *)uwrq;	switch (mode) {	case IW_MODE_INFRA:		mode = DOT11_MODE_CLIENT;		sm_mode = SM_MODE_CLIENT;		bss_type = DOT11_BSSTYPE_INFRA;		profile = DOT11_PROFILE_MIXED;		dev->type = ARPHRD_ETHER;		break;	case IW_MODE_ADHOC:		mode = DOT11_MODE_CLIENT;		sm_mode = SM_MODE_CLIENT;		bss_type = DOT11_BSSTYPE_IBSS;		/* When creating an Ad-Hoc network, we must be B only (wifi requirement) */		profile = DOT11_PROFILE_B_ONLY;		dev->type = ARPHRD_ETHER;		break;	case IW_MODE_MASTER:		return -1;#if 0 /* AP mode unsupported for now */		mode = DOT11_MODE_AP;		sm_mode = SM_MODE_AP;		bss_type = DOT11_BSSTYPE_INFRA;		profile = DOT11_PROFILE_MIXED;		break;#endif	case IW_MODE_MONITOR:		mode = MODE_PROMISCUOUS;		sm_mode = SM_MODE_PROMISCUOUS;		bss_type = DOT11_BSSTYPE_NONE;		dev->type = ARPHRD_IEEE80211;		break;			default:		return -EINVAL;	}		ret = sm_drv_oid_get(dev, GEN_OID_MODE, (void *)&current_mode, sizeof(uint32_t));	if (ret < 0)		return ret;		DEBUG(DBG_IOCTL, "sm_drv_ioctl: Setting Mode to %d (current: %d)\n", mode, current_mode);	if (mode != current_mode) {				spin_lock_bh(&lp->sm_lock);		lp->sm_mode = sm_mode;		spin_unlock_bh(&lp->sm_lock);				err = sm_drv_reset(dev, sm_mode);		if(err < 0)			return -EINVAL;	}		ret = sm_drv_oid_set(dev, DOT11_OID_PROFILES, (void*)&profile, sizeof(uint32_t));	if (ret < 0)		return ret;	if (bss_type == DOT11_BSSTYPE_IBSS) {		uint32_t preamble_settings = DOT11_PREAMBLESETTING_LONG;		ret = sm_drv_oid_set(dev, DOT11_OID_PREAMBLESETTINGS, 				     (void*)&preamble_settings,				     sizeof(uint32_t));		if (ret < 0)			return ret;	}	ret = sm_drv_oid_set(dev, DOT11_OID_BSSTYPE, (void*)&bss_type, sizeof(uint32_t));		if (ret < 0)		return ret;		lp->bss_type = bss_type;	ret = sm_drv_oid_set(dev, GEN_OID_COMMIT, (void*)&commit, sizeof(uint32_t));	if (ret < 0)		return ret;		return 0;}static int sm_drv_get_mode(struct net_device *dev, struct iw_request_info *info,			    __u32 * uwrq, char *extra){	uint32_t mode, ret, bss_type;		DEBUG(DBG_IOCTL, "GET MODE\n");	ret = sm_drv_oid_get(dev, GEN_OID_MODE, (void *)&mode, sizeof(uint32_t));	if (ret < 0)		return ret;	ret = sm_drv_oid_get(dev, DOT11_OID_BSSTYPE, (void *)&bss_type, sizeof(uint32_t));	if (ret < 0)		return ret;	DEBUG(DBG_IOCTL, "sm_drv_get_mode: mode-> 0x%x\n", mode);	switch (mode & 0xff) {	case DOT11_MODE_CLIENT:		if (bss_type == DOT11_BSSTYPE_INFRA)			mode = IW_MODE_INFRA; /* Client Mode */		else if (bss_type == DOT11_BSSTYPE_IBSS)			mode = IW_MODE_ADHOC; /* Ad-Hoc mode */		break;	case DOT11_MODE_AP:		mode = IW_MODE_MASTER; /* AP Mode */		break;	case MODE_PROMISCUOUS:		mode = IW_MODE_MONITOR; /* Listen only */		break;	default:		mode = IW_MODE_AUTO;	/* Default */		break;	}	*uwrq = mode;	return 0;}/*  * We use DOT11_OID_EDTHRESHOLD. From what I guess the card will not try to * emit data if (sensitivity > rssi - noise) (in dBm). */static int sm_drv_set_sens(struct net_device *dev, struct iw_request_info *info,			   struct iw_param *vwrq, char *extra){	uint32_t sens;	DEBUG(DBG_IOCTL, "SET SENS\n");	/* by default  the card sets this to 20. */	sens = vwrq->disabled ? 20 : vwrq->value;	/* set the ed threshold. */	return sm_drv_oid_set(dev, DOT11_OID_EDTHRESHOLD, (void*)&sens, sizeof(uint32_t));	}static int sm_drv_get_sens(struct net_device *dev, struct iw_request_info *info,			   struct iw_param *vwrq, char *extra){	int ret;	uint32_t sens;	DEBUG(DBG_IOCTL, "GET SENS\n");	ret = sm_drv_oid_get(dev, DOT11_OID_EDTHRESHOLD, (void*)&sens, sizeof(uint32_t));		if (ret < 0)		return ret;	vwrq->value = sens;	vwrq->disabled = (vwrq->value == 0);	vwrq->fixed = 1;	return 0;}static int sm_drv_get_range(struct net_device *dev, struct iw_request_info *info,			    struct iw_point *dwrq, char *extra){	struct iw_range *range = (struct iw_range *) extra;	uint8_t data[17];	int i, ret, freq_obj_size;		struct obj_frequencies * freq;	void * frequencies;	DEBUG(DBG_IOCTL, "GET RANGE\n");	freq_obj_size = (IW_MAX_FREQUENCIES + 1)* 2 * sizeof(uint8_t);	frequencies = kmalloc(freq_obj_size, GFP_ATOMIC);	memset(range, 0, sizeof (struct iw_range));	dwrq->length = sizeof (struct iw_range);	/* set the wireless extension version number */	range->we_version_source = SUPPORTED_WIRELESS_EXT;	range->we_version_compiled = WIRELESS_EXT;	/* Now the encoding capabilities */	range->num_encoding_sizes = 3;	/* 64(40) bits WEP */	range->encoding_size[0] = 5;	/* 128(104) bits WEP */	range->encoding_size[1] = 13;	/* 256 bits for WPA-PSK */	range->encoding_size[2] = 32;	/* 4 keys are allowed */	range->max_encoding_tokens = 4;	/* we don't know the quality range... */	range->max_qual.level = 0;	range->max_qual.noise = 0;	range->max_qual.qual = 0;	/* these value describe an average quality. Needs more tweaking... */	range->avg_qual.level = -80;	/* -80 dBm */	range->avg_qual.noise = 0;	/* don't know what to put here */	range->avg_qual.qual = 0;	range->sensitivity = 200;	/* retry limit capabilities */	range->retry_capa = IW_RETRY_LIMIT | IW_RETRY_LIFETIME;	range->retry_flags = IW_RETRY_LIMIT;	range->r_time_flags = IW_RETRY_LIFETIME;	/* I don't know the range. Put stupid things here */	range->min_retry = 1;	range->max_retry = 65535;	range->min_r_time = 1024;	range->max_r_time = 65535 * 1024;	/* txpower is supported in dBm's */	range->txpower_capa = IW_TXPOW_DBM;	/* 	 * Request the device for the supported frequencies	 * not really revelant since some devices will report the 5 GHz band	 * frequencies even if they don't support them.	 */	ret = sm_drv_oid_get(dev, DOT11_OID_SUPPORTEDFREQUENCIES, frequencies, freq_obj_size);	if (ret < 0)		return ret;	freq = (struct obj_frequencies *)frequencies;	range->num_channels = freq->nr;	range->num_frequency = freq->nr;	for (i = 0; i < (int)freq->nr; i++) {		range->freq[i].m = freq->mhz[i];		range->freq[i].e = 6;		range->freq[i].i = i + 1;	}#if 0	/* 	 * Frequencies are not listed in the right order. The reordering is probably	 * firmware dependant and thus should work for everyone.	 */	m = min(IW_MAX_FREQUENCIES, (int) freq->nr);	for (i = 0; i < m - 12; i++) {		range->freq[i].m = freq->mhz[12 + i];		range->freq[i].e = 6;		range->freq[i].i = i + 1;	}	for (i = m - 12; i < m; i++) {		range->freq[i].m = freq->mhz[i - m + 12];		range->freq[i].e = 6;		range->freq[i].i = i + 23;	}#endif	ret = sm_drv_oid_get(dev, DOT11_OID_SUPPORTEDRATES, (void *)data, 17 * sizeof(uint8_t));	if (ret < 0)		return ret;	/* We got an array of char. It is NULL terminated. */	i = 0;	while ((i < IW_MAX_BITRATES) && (data[i] != 0)) {		/*       the result must be in bps. The card gives us 500Kbps */		range->bitrate[i] = (__s32) (data[i] >> 1);		range->bitrate[i] *= 1000000;		i++;	}	range->num_bitrates = i;	return 0;}static int sm_drv_set_wap(struct net_device *dev, struct iw_request_info *info,			  struct sockaddr *awrq, char *extra){	uint8_t bssid[ETH_ALEN];	int ret;	DEBUG(DBG_IOCTL, "SET WAP\n");	if (awrq->sa_family != ARPHRD_ETHER)		return -EINVAL;	/* prepare the structure for the set object */	memcpy(bssid, awrq->sa_data, ETH_ALEN);	/* set the bssid -- does this make sense when in AP mode? */	ret = sm_drv_oid_set(dev, DOT11_OID_BSSID, (void*)bssid, ETH_ALEN * sizeof(uint8_t));	if (ret < 0)		return ret;	return -EINPROGRESS;	/* Call commit handler */}static int sm_drv_get_wap(struct net_device *dev, struct iw_request_info *info,			  struct sockaddr *awrq, char *extra){	uint8_t bssid[ETH_ALEN] = {0x0,0x0,0x0,0x0,0x0,0x0};	DEBUG(DBG_IOCTL, "GET WAP\n");	sm_drv_oid_get(dev, DOT11_OID_BSSID, (void*)bssid, ETH_ALEN * sizeof(uint8_t));		memcpy(awrq->sa_data, bssid, ETH_ALEN);	awrq->sa_family = ARPHRD_ETHER;	return 0;}static int sm_drv_set_scan(struct net_device *dev, struct iw_request_info *info,			   struct iw_point *vwrq, char *extra){	int ret = 0;	struct obj_ssid essid;	int16_t scan = -1;	uint32_t scan_mode, flush_bss_list = 1;	struct net_local *lp = dev->priv;	uint32_t bgr_scan_disable = 1;	if (vwrq == NULL)		return -EINVAL;	/* First we flush the UMAC's AP list*/	ret = sm_drv_oid_set(dev, DOT11_OID_BSSLISTFLUSH, (void*)&flush_bss_list, sizeof(uint32_t));	if (ret < 0)		return ret;	if (vwrq->flags & IW_SCAN_THIS_ESSID) {		if (vwrq->length > 0) {			essid.length = vwrq->length - 1;			memcpy(essid.octets, vwrq->pointer, essid.length + 1);		} else {			essid.length = 0;			memset(essid.octets, 0, sizeof(essid.octets));		}		scan_mode = SCAN_MODE_ACTIVE;	} else {

⌨️ 快捷键说明

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