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

📄 zd1201.c

📁 底层驱动开发
💻 C
📖 第 1 页 / 共 4 页
字号:
		return 0;	}	err = zd1201_setconfig16(zd, ZD1201_RID_PROMISCUOUSMODE, 0);	if (err)		return err;	zd->dev->type = ARPHRD_ETHER;	switch(*mode) {		case IW_MODE_MONITOR:			monitor = 1;			zd->dev->type = ARPHRD_IEEE80211;			/* Make sure we are no longer associated with by			   setting an 'impossible' essid.			   (otherwise we mess up firmware)			 */			zd1201_join(zd, "\0-*#\0", 5);			/* Put port in pIBSS */		case 8: /* No pseudo-IBSS in wireless extensions (yet) */			porttype = ZD1201_PORTTYPE_PSEUDOIBSS;			break;		case IW_MODE_ADHOC:			porttype = ZD1201_PORTTYPE_IBSS;			break;		case IW_MODE_INFRA:			porttype = ZD1201_PORTTYPE_BSS;			break;		default:			return -EINVAL;	}	err = zd1201_setconfig16(zd, ZD1201_RID_CNFPORTTYPE, porttype);	if (err)		return err;	if (zd->monitor && !monitor) {			zd1201_disable(zd);			*(__le16 *)buffer = cpu_to_le16(zd->essidlen);			memcpy(buffer+2, zd->essid, zd->essidlen);			err = zd1201_setconfig(zd, ZD1201_RID_CNFDESIREDSSID,			    buffer, IW_ESSID_MAX_SIZE+2, 1);			if (err)				return err;	}	zd->monitor=monitor;	/* If monitor mode is set we don't actually turn it on here since it	 * is done during mac reset anyway (see zd1201_mac_enable).	 */	zd1201_mac_reset(zd);	return 0;}static int zd1201_get_mode(struct net_device *dev,    struct iw_request_info *info, __u32 *mode, char *extra){	struct zd1201 *zd = (struct zd1201 *)dev->priv;	short porttype;	int err;	err = zd1201_getconfig16(zd, ZD1201_RID_CNFPORTTYPE, &porttype);	if (err)		return err;	switch(porttype) {		case ZD1201_PORTTYPE_IBSS:			*mode = IW_MODE_ADHOC;			break;		case ZD1201_PORTTYPE_BSS:			*mode = IW_MODE_INFRA;			break;		case ZD1201_PORTTYPE_WDS:			*mode = IW_MODE_REPEAT;			break;		case ZD1201_PORTTYPE_PSEUDOIBSS:			*mode = 8;/* No Pseudo-IBSS... */			break;		case ZD1201_PORTTYPE_AP:			*mode = IW_MODE_MASTER;			break;		default:			dev_dbg(&zd->usb->dev, "Unknown porttype: %d\n",			    porttype);			*mode = IW_MODE_AUTO;	}	if (zd->monitor)		*mode = IW_MODE_MONITOR;	return 0;}static int zd1201_get_range(struct net_device *dev,    struct iw_request_info *info, struct iw_point *wrq, char *extra){	struct iw_range *range = (struct iw_range *)extra;	wrq->length = sizeof(struct iw_range);	memset(range, 0, sizeof(struct iw_range));	range->we_version_compiled = WIRELESS_EXT;	range->we_version_source = WIRELESS_EXT;	range->max_qual.qual = 128;	range->max_qual.level = 128;	range->max_qual.noise = 128;	range->max_qual.updated = 7;	range->encoding_size[0] = 5;	range->encoding_size[1] = 13;	range->num_encoding_sizes = 2;	range->max_encoding_tokens = ZD1201_NUMKEYS;	range->num_bitrates = 4;	range->bitrate[0] = 1000000;	range->bitrate[1] = 2000000;	range->bitrate[2] = 5500000;	range->bitrate[3] = 11000000;	range->min_rts = 0;	range->min_frag = ZD1201_FRAGMIN;	range->max_rts = ZD1201_RTSMAX;	range->min_frag = ZD1201_FRAGMAX;	return 0;}/*	Little bit of magic here: we only get the quality if we poll *	for it, and we never get an actual request to trigger such *	a poll. Therefore we 'assume' that the user will soon ask for *	the stats after asking the bssid. */static int zd1201_get_wap(struct net_device *dev,    struct iw_request_info *info, struct sockaddr *ap_addr, char *extra){	struct zd1201 *zd = (struct zd1201 *)dev->priv;	unsigned char buffer[6];	if (!zd1201_getconfig(zd, ZD1201_RID_COMMSQUALITY, buffer, 6)) {		/* Unfortunately the quality and noise reported is useless.		   they seem to be accumulators that increase until you		   read them, unless we poll on a fixed interval we can't		   use them		 */		/*zd->iwstats.qual.qual = le16_to_cpu(((__le16 *)buffer)[0]);*/		zd->iwstats.qual.level = le16_to_cpu(((__le16 *)buffer)[1]);		/*zd->iwstats.qual.noise = le16_to_cpu(((__le16 *)buffer)[2]);*/		zd->iwstats.qual.updated = 2;	}	return zd1201_getconfig(zd,ZD1201_RID_CURRENTBSSID,ap_addr->sa_data,6);}static int zd1201_set_scan(struct net_device *dev,    struct iw_request_info *info, struct iw_point *srq, char *extra){	/* We do everything in get_scan */	return 0;}static int zd1201_get_scan(struct net_device *dev,    struct iw_request_info *info, struct iw_point *srq, char *extra){	struct zd1201 *zd = (struct zd1201 *)dev->priv;	int err, i, j, enabled_save;	struct iw_event iwe;	char *cev = extra;	char *end_buf = extra + IW_SCAN_MAX_DATA;	/* No scanning in AP mode */	if (zd->ap)		return -EOPNOTSUPP;	/* Scan doesn't seem to work if disabled */	enabled_save = zd->mac_enabled;	zd1201_enable(zd);	zd->rxdatas = 0;	err = zd1201_docmd(zd, ZD1201_CMDCODE_INQUIRE, 	     ZD1201_INQ_SCANRESULTS, 0, 0);	if (err)		return err;	wait_event_interruptible(zd->rxdataq, zd->rxdatas);	if (!zd->rxlen)		return -EIO;	if (le16_to_cpu(*(__le16*)&zd->rxdata[2]) != ZD1201_INQ_SCANRESULTS)		return -EIO;	for(i=8; i<zd->rxlen; i+=62) {		iwe.cmd = SIOCGIWAP;		iwe.u.ap_addr.sa_family = ARPHRD_ETHER;		memcpy(iwe.u.ap_addr.sa_data, zd->rxdata+i+6, 6);		cev = iwe_stream_add_event(cev, end_buf, &iwe, IW_EV_ADDR_LEN);		iwe.cmd = SIOCGIWESSID;		iwe.u.data.length = zd->rxdata[i+16];		iwe.u.data.flags = 1;		cev = iwe_stream_add_point(cev, end_buf, &iwe, zd->rxdata+i+18);		iwe.cmd = SIOCGIWMODE;		if (zd->rxdata[i+14]&0x01)			iwe.u.mode = IW_MODE_MASTER;		else			iwe.u.mode = IW_MODE_ADHOC;		cev = iwe_stream_add_event(cev, end_buf, &iwe, IW_EV_UINT_LEN);				iwe.cmd = SIOCGIWFREQ;		iwe.u.freq.m = zd->rxdata[i+0];		iwe.u.freq.e = 0;		cev = iwe_stream_add_event(cev, end_buf, &iwe, IW_EV_FREQ_LEN);				iwe.cmd = SIOCGIWRATE;		iwe.u.bitrate.fixed = 0;		iwe.u.bitrate.disabled = 0;		for (j=0; j<10; j++) if (zd->rxdata[i+50+j]) {			iwe.u.bitrate.value = (zd->rxdata[i+50+j]&0x7f)*500000;			cev=iwe_stream_add_event(cev, end_buf, &iwe,			    IW_EV_PARAM_LEN);		}				iwe.cmd = SIOCGIWENCODE;		iwe.u.data.length = 0;		if (zd->rxdata[i+14]&0x10)			iwe.u.data.flags = IW_ENCODE_ENABLED;		else			iwe.u.data.flags = IW_ENCODE_DISABLED;		cev = iwe_stream_add_point(cev, end_buf, &iwe, NULL);				iwe.cmd = IWEVQUAL;		iwe.u.qual.qual = zd->rxdata[i+4];		iwe.u.qual.noise= zd->rxdata[i+2]/10-100;		iwe.u.qual.level = (256+zd->rxdata[i+4]*100)/255-100;		iwe.u.qual.updated = 7;		cev = iwe_stream_add_event(cev, end_buf, &iwe, IW_EV_QUAL_LEN);	}	if (!enabled_save)		zd1201_disable(zd);	srq->length = cev - extra;	srq->flags = 0;	return 0;}static int zd1201_set_essid(struct net_device *dev,    struct iw_request_info *info, struct iw_point *data, char *essid){	struct zd1201 *zd = (struct zd1201 *)dev->priv;	if (data->length > IW_ESSID_MAX_SIZE)		return -EINVAL;	if (data->length < 1)		data->length = 1;	zd->essidlen = data->length-1;	memset(zd->essid, 0, IW_ESSID_MAX_SIZE+1);	memcpy(zd->essid, essid, data->length);	return zd1201_join(zd, zd->essid, zd->essidlen);}static int zd1201_get_essid(struct net_device *dev,    struct iw_request_info *info, struct iw_point *data, char *essid){	struct zd1201 *zd = (struct zd1201 *)dev->priv;	memcpy(essid, zd->essid, zd->essidlen);	data->flags = 1;	data->length = zd->essidlen;	return 0;}static int zd1201_get_nick(struct net_device *dev, struct iw_request_info *info,    struct iw_point *data, char *nick){	strcpy(nick, "zd1201");	data->flags = 1;	data->length = strlen(nick);	return 0;}static int zd1201_set_rate(struct net_device *dev,    struct iw_request_info *info, struct iw_param *rrq, char *extra){	struct zd1201 *zd = (struct zd1201 *)dev->priv;	short rate;	int err;	switch (rrq->value) {		case 1000000:			rate = ZD1201_RATEB1;			break;		case 2000000:			rate = ZD1201_RATEB2;			break;		case 5500000:			rate = ZD1201_RATEB5;			break;		case 11000000:		default:			rate = ZD1201_RATEB11;			break;	}	if (!rrq->fixed) { /* Also enable all lower bitrates */		rate |= rate-1;	}		err = zd1201_setconfig16(zd, ZD1201_RID_TXRATECNTL, rate);	if (err)		return err;	return zd1201_mac_reset(zd);}static int zd1201_get_rate(struct net_device *dev,    struct iw_request_info *info, struct iw_param *rrq, char *extra){	struct zd1201 *zd = (struct zd1201 *)dev->priv;	short rate;	int err;	err = zd1201_getconfig16(zd, ZD1201_RID_CURRENTTXRATE, &rate);	if (err)		return err;	switch(rate) {		case 1:			rrq->value = 1000000;			break;		case 2:			rrq->value = 2000000;			break;		case 5:			rrq->value = 5500000;			break;		case 11:			rrq->value = 11000000;			break;		default:			rrq->value = 0;	}	rrq->fixed = 0;	rrq->disabled = 0;	return 0;}static int zd1201_set_rts(struct net_device *dev, struct iw_request_info *info,    struct iw_param *rts, char *extra){	struct zd1201 *zd = (struct zd1201 *)dev->priv;	int err;	short val = rts->value;	if (rts->disabled || !rts->fixed)		val = ZD1201_RTSMAX;	if (val > ZD1201_RTSMAX)		return -EINVAL;	if (val < 0)		return -EINVAL;	err = zd1201_setconfig16(zd, ZD1201_RID_CNFRTSTHRESHOLD, val);	if (err)		return err;	return zd1201_mac_reset(zd);}static int zd1201_get_rts(struct net_device *dev, struct iw_request_info *info,    struct iw_param *rts, char *extra){	struct zd1201 *zd = (struct zd1201 *)dev->priv;	short rtst;	int err;	err = zd1201_getconfig16(zd, ZD1201_RID_CNFRTSTHRESHOLD, &rtst);	if (err)		return err;	rts->value = rtst;	rts->disabled = (rts->value == ZD1201_RTSMAX);	rts->fixed = 1;	return 0;}static int zd1201_set_frag(struct net_device *dev, struct iw_request_info *info,    struct iw_param *frag, char *extra){	struct zd1201 *zd = (struct zd1201 *)dev->priv;	int err;	short val = frag->value;	if (frag->disabled || !frag->fixed)		val = ZD1201_FRAGMAX;	if (val > ZD1201_FRAGMAX)		return -EINVAL;	if (val < ZD1201_FRAGMIN)		return -EINVAL;	if (val & 1)		return -EINVAL;	err = zd1201_setconfig16(zd, ZD1201_RID_CNFFRAGTHRESHOLD, val);	if (err)		return err;	return zd1201_mac_reset(zd);}static int zd1201_get_frag(struct net_device *dev, struct iw_request_info *info,    struct iw_param *frag, char *extra){	struct zd1201 *zd = (struct zd1201 *)dev->priv;	short fragt;	int err;	err = zd1201_getconfig16(zd, ZD1201_RID_CNFFRAGTHRESHOLD, &fragt);	if (err)		return err;	frag->value = fragt;	frag->disabled = (frag->value == ZD1201_FRAGMAX);	frag->fixed = 1;	return 0;}static int zd1201_set_retry(struct net_device *dev,    struct iw_request_info *info, struct iw_param *rrq, char *extra){	return 0;}static int zd1201_get_retry(struct net_device *dev,    struct iw_request_info *info, struct iw_param *rrq, char *extra){	return 0;}static int zd1201_set_encode(struct net_device *dev,    struct iw_request_info *info, struct iw_point *erq, char *key){	struct zd1201 *zd = (struct zd1201 *)dev->priv;	short i;	int err, rid;	if (erq->length > ZD1201_MAXKEYLEN)		return -EINVAL;	i = (erq->flags & IW_ENCODE_INDEX)-1;	if (i == -1) {		err = zd1201_getconfig16(zd,ZD1201_RID_CNFDEFAULTKEYID,&i);		if (err)			return err;	} else {		err = zd1201_setconfig16(zd, ZD1201_RID_CNFDEFAULTKEYID, i);		if (err)			return err;	}	if (i < 0 || i >= ZD1201_NUMKEYS)		return -EINVAL;	rid = ZD1201_RID_CNFDEFAULTKEY0 + i;	err = zd1201_setconfig(zd, rid, key, erq->length, 1);	if (err)		return err;	zd->encode_keylen[i] = erq->length;	memcpy(zd->encode_keys[i], key, erq->length);	i=0;	if (!(erq->flags & IW_ENCODE_DISABLED & IW_ENCODE_MODE)) {		i |= 0x01;		zd->encode_enabled = 1;	} else		zd->encode_enabled = 0;	if (erq->flags & IW_ENCODE_RESTRICTED & IW_ENCODE_MODE) {		i |= 0x02;		zd->encode_restricted = 1;	} else		zd->encode_restricted = 0;	err = zd1201_setconfig16(zd, ZD1201_RID_CNFWEBFLAGS, i);	if (err)		return err;	if (zd->encode_enabled)		i = ZD1201_CNFAUTHENTICATION_SHAREDKEY;	else		i = ZD1201_CNFAUTHENTICATION_OPENSYSTEM;	err = zd1201_setconfig16(zd, ZD1201_RID_CNFAUTHENTICATION, i);	if (err)		return err;	return zd1201_mac_reset(zd);

⌨️ 快捷键说明

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