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

📄 airo.c

📁 linux-2.4.29操作系统的源码
💻 C
📖 第 1 页 / 共 5 页
字号:
}/*==============================================*//*========== EMMH ROUTINES  ====================*//*==============================================*//* mic accumulate */#define MIC_ACCUM(val)	\	context->accum += (u64)(val) * context->coeff[coeff_position++];static unsigned char aes_counter[16];/* expand the key to fill the MMH coefficient array */void emmh32_setseed(emmh32_context *context, u8 *pkey, int keylen, struct crypto_tfm *tfm){  /* take the keying material, expand if necessary, truncate at 16-bytes */  /* run through AES counter mode to generate context->coeff[] */  	int i,j;	u32 counter;	u8 *cipher, plain[16];	struct scatterlist sg[1];	crypto_cipher_setkey(tfm, pkey, 16);	counter = 0;	for (i = 0; i < (sizeof(context->coeff)/sizeof(context->coeff[0])); ) {		aes_counter[15] = (u8)(counter >> 0);		aes_counter[14] = (u8)(counter >> 8);		aes_counter[13] = (u8)(counter >> 16);		aes_counter[12] = (u8)(counter >> 24);		counter++;		memcpy (plain, aes_counter, 16);		sg[0].page = virt_to_page(plain);		sg[0].offset = ((long) plain & ~PAGE_MASK);		sg[0].length = 16;		crypto_cipher_encrypt(tfm, sg, sg, 16);		cipher = kmap(sg[0].page) + sg[0].offset;		for (j=0; (j<16) && (i< (sizeof(context->coeff)/sizeof(context->coeff[0]))); ) {			context->coeff[i++] = ntohl(*(u32 *)&cipher[j]);			j += 4;		}	}}/* prepare for calculation of a new mic */void emmh32_init(emmh32_context *context){	/* prepare for new mic calculation */	context->accum = 0;	context->position = 0;}/* add some bytes to the mic calculation */void emmh32_update(emmh32_context *context, u8 *pOctets, int len){	int	coeff_position, byte_position;  	if (len == 0) return;  	coeff_position = context->position >> 2;  	/* deal with partial 32-bit word left over from last update */	byte_position = context->position & 3;	if (byte_position) {		/* have a partial word in part to deal with */		do {			if (len == 0) return;			context->part.d8[byte_position++] = *pOctets++;			context->position++;			len--;		} while (byte_position < 4);		MIC_ACCUM(htonl(context->part.d32));	}	/* deal with full 32-bit words */	while (len >= 4) {		MIC_ACCUM(htonl(*(u32 *)pOctets));		context->position += 4;		pOctets += 4;		len -= 4;	}	/* deal with partial 32-bit word that will be left over from this update */	byte_position = 0;	while (len > 0) {		context->part.d8[byte_position++] = *pOctets++;		context->position++;		len--;	}}/* mask used to zero empty bytes for final partial word */static u32 mask32[4] = { 0x00000000L, 0xFF000000L, 0xFFFF0000L, 0xFFFFFF00L };/* calculate the mic */void emmh32_final(emmh32_context *context, u8 digest[4]){	int	coeff_position, byte_position;	u32	val;  	u64 sum, utmp;	s64 stmp;	coeff_position = context->position >> 2;  	/* deal with partial 32-bit word left over from last update */	byte_position = context->position & 3;	if (byte_position) {		/* have a partial word in part to deal with */		val = htonl(context->part.d32);		MIC_ACCUM(val & mask32[byte_position]);	/* zero empty bytes */	}	/* reduce the accumulated u64 to a 32-bit MIC */	sum = context->accum;	stmp = (sum  & 0xffffffffLL) - ((sum >> 32)  * 15);	utmp = (stmp & 0xffffffffLL) - ((stmp >> 32) * 15);	sum = utmp & 0xffffffffLL;	if (utmp > 0x10000000fLL)		sum -= 15;	val = (u32)sum;	digest[0] = (val>>24) & 0xFF;	digest[1] = (val>>16) & 0xFF;	digest[2] = (val>>8) & 0xFF;	digest[3] = val & 0xFF;}#endifstatic int readBSSListRid(struct airo_info *ai, int first,		      BSSListRid *list) {	int rc;			Cmd cmd;			Resp rsp;	if (first == 1) {			memset(&cmd, 0, sizeof(cmd));			cmd.cmd=CMD_LISTBSS;			if (down_interruptible(&ai->sem))				return -ERESTARTSYS;			issuecommand(ai, &cmd, &rsp);			up(&ai->sem);			/* Let the command take effect */			set_current_state (TASK_INTERRUPTIBLE);			ai->task = current;			schedule_timeout (3*HZ);			ai->task = NULL;		}	rc = PC4500_readrid(ai, first ? RID_BSSLISTFIRST : RID_BSSLISTNEXT,			    list, sizeof(*list), 1);	list->len = le16_to_cpu(list->len);	list->index = le16_to_cpu(list->index);	list->radioType = le16_to_cpu(list->radioType);	list->cap = le16_to_cpu(list->cap);	list->beaconInterval = le16_to_cpu(list->beaconInterval);	list->fh.dwell = le16_to_cpu(list->fh.dwell);	list->dsChannel = le16_to_cpu(list->dsChannel);	list->atimWindow = le16_to_cpu(list->atimWindow);	return rc;}static int readWepKeyRid(struct airo_info*ai, WepKeyRid *wkr, int temp) {	int rc = PC4500_readrid(ai, temp ? RID_WEP_TEMP : RID_WEP_PERM,				wkr, sizeof(*wkr), 1);	wkr->len = le16_to_cpu(wkr->len);	wkr->kindex = le16_to_cpu(wkr->kindex);	wkr->klen = le16_to_cpu(wkr->klen);	return rc;}/* In the writeXXXRid routines we copy the rids so that we don't screwup * the originals when we endian them... */static int writeWepKeyRid(struct airo_info*ai, WepKeyRid *pwkr, int perm, int lock) {	int rc;	WepKeyRid wkr = *pwkr;	wkr.len = cpu_to_le16(wkr.len);	wkr.kindex = cpu_to_le16(wkr.kindex);	wkr.klen = cpu_to_le16(wkr.klen);	rc = PC4500_writerid(ai, RID_WEP_TEMP, &wkr, sizeof(wkr), lock);	if (rc!=SUCCESS) printk(KERN_ERR "airo:  WEP_TEMP set %x\n", rc);	if (perm) {		rc = PC4500_writerid(ai, RID_WEP_PERM, &wkr, sizeof(wkr), lock);		if (rc!=SUCCESS) {			printk(KERN_ERR "airo:  WEP_PERM set %x\n", rc);		}	}	return rc;}static int readSsidRid(struct airo_info*ai, SsidRid *ssidr) {	int i;	int rc = PC4500_readrid(ai, RID_SSID, ssidr, sizeof(*ssidr), 1);	ssidr->len = le16_to_cpu(ssidr->len);	for(i = 0; i < 3; i++) {		ssidr->ssids[i].len = le16_to_cpu(ssidr->ssids[i].len);	}	return rc;}static int writeSsidRid(struct airo_info*ai, SsidRid *pssidr) {	int rc;	int i;	SsidRid ssidr = *pssidr;	ssidr.len = cpu_to_le16(ssidr.len);	for(i = 0; i < 3; i++) {		ssidr.ssids[i].len = cpu_to_le16(ssidr.ssids[i].len);	}	rc = PC4500_writerid(ai, RID_SSID, &ssidr, sizeof(ssidr), 1);	return rc;}static int readConfigRid(struct airo_info*ai, int lock) {	int rc;	u16 *s;	ConfigRid cfg;	if (ai->config.len)		return SUCCESS;	rc = PC4500_readrid(ai, RID_ACTUALCONFIG, &cfg, sizeof(cfg), lock);	if (rc != SUCCESS)		return rc;	for(s = &cfg.len; s <= &cfg.rtsThres; s++) *s = le16_to_cpu(*s);	for(s = &cfg.shortRetryLimit; s <= &cfg.radioType; s++)		*s = le16_to_cpu(*s);	for(s = &cfg.txPower; s <= &cfg.radioSpecific; s++)		*s = le16_to_cpu(*s);	for(s = &cfg.arlThreshold; s <= &cfg.autoWake; s++)		*s = le16_to_cpu(*s);	ai->config = cfg;	return SUCCESS;}static inline void checkThrottle(struct airo_info *ai) {	int i;/* Old hardware had a limit on encryption speed */	if (ai->config.authType != AUTH_OPEN && maxencrypt) {		for(i=0; i<8; i++) {			if (ai->config.rates[i] > maxencrypt) {				ai->config.rates[i] = 0;			}		}	}}static int writeConfigRid(struct airo_info*ai, int lock) {	u16 *s;	ConfigRid cfgr;	if (!ai->need_commit)		return SUCCESS;	ai->need_commit = 0;	checkThrottle(ai);	cfgr = ai->config;	if ((cfgr.opmode & 0xFF) == MODE_STA_IBSS)		set_bit(FLAG_ADHOC, &ai->flags);	else		clear_bit(FLAG_ADHOC, &ai->flags);	for(s = &cfgr.len; s <= &cfgr.rtsThres; s++) *s = cpu_to_le16(*s);	for(s = &cfgr.shortRetryLimit; s <= &cfgr.radioType; s++)		*s = cpu_to_le16(*s);	for(s = &cfgr.txPower; s <= &cfgr.radioSpecific; s++)		*s = cpu_to_le16(*s);	for(s = &cfgr.arlThreshold; s <= &cfgr.autoWake; s++)		*s = cpu_to_le16(*s);	return PC4500_writerid( ai, RID_CONFIG, &cfgr, sizeof(cfgr), lock);}static int readStatusRid(struct airo_info*ai, StatusRid *statr, int lock) {	int rc = PC4500_readrid(ai, RID_STATUS, statr, sizeof(*statr), lock);	u16 *s;	statr->len = le16_to_cpu(statr->len);	for(s = &statr->mode; s <= &statr->SSIDlen; s++) *s = le16_to_cpu(*s);	for(s = &statr->beaconPeriod; s <= &statr->shortPreamble; s++)		*s = le16_to_cpu(*s);	statr->load = le16_to_cpu(statr->load);	statr->assocStatus = le16_to_cpu(statr->assocStatus);	return rc;}static int readAPListRid(struct airo_info*ai, APListRid *aplr) {	int rc =  PC4500_readrid(ai, RID_APLIST, aplr, sizeof(*aplr), 1);	aplr->len = le16_to_cpu(aplr->len);	return rc;}static int writeAPListRid(struct airo_info*ai, APListRid *aplr) {	int rc;	aplr->len = cpu_to_le16(aplr->len);	rc = PC4500_writerid(ai, RID_APLIST, aplr, sizeof(*aplr), 1);	return rc;}static int readCapabilityRid(struct airo_info*ai, CapabilityRid *capr) {	int rc = PC4500_readrid(ai, RID_CAPABILITIES, capr, sizeof(*capr), 1);	u16 *s;	capr->len = le16_to_cpu(capr->len);	capr->prodNum = le16_to_cpu(capr->prodNum);	capr->radioType = le16_to_cpu(capr->radioType);	capr->country = le16_to_cpu(capr->country);	for(s = &capr->txPowerLevels[0]; s <= &capr->requiredHard; s++)		*s = le16_to_cpu(*s);	return rc;}static int readStatsRid(struct airo_info*ai, StatsRid *sr, int rid, int lock) {	int rc = PC4500_readrid(ai, rid, sr, sizeof(*sr), lock);	u32 *i;	sr->len = le16_to_cpu(sr->len);	for(i = &sr->vals[0]; i <= &sr->vals[99]; i++) *i = le32_to_cpu(*i);	return rc;}static int airo_open(struct net_device *dev) {	struct airo_info *info = dev->priv;	Resp rsp;	if (test_bit(FLAG_FLASHING, &info->flags))		return -EIO;	/* Make sure the card is configured.	 * Wireless Extensions may postpone config changes until the card	 * is open (to pipeline changes and speed-up card setup). If	 * those changes are not yet commited, do it now - Jean II */	if(info->need_commit) {		disable_MAC(info, 1);		writeConfigRid(info, 1);	}	if (info->wifidev != dev) {		/* Power on the MAC controller (which may have been disabled) */		clear_bit(FLAG_RADIO_DOWN, &info->flags);		enable_interrupts(info);	}	enable_MAC(info, &rsp, 1);	netif_start_queue(dev);	return 0;}static void get_tx_error(struct airo_info *ai, u32 fid){	u16 status;	if (bap_setup(ai, ai->fids[fid] & 0xffff, 4, BAP0) == SUCCESS) {		bap_read(ai, &status, 2, BAP0);		if (le16_to_cpu(status) & 2) /* Too many retries */			ai->stats.tx_aborted_errors++;		if (le16_to_cpu(status) & 4) /* Transmit lifetime exceeded */			ai->stats.tx_heartbeat_errors++;		if (le16_to_cpu(status) & 8) /* Aid fail */			{ }		if (le16_to_cpu(status) & 0x10) /* MAC disabled */			ai->stats.tx_carrier_errors++;		if (le16_to_cpu(status) & 0x20) /* Association lost */			{ }#if WIRELESS_EXT > 13		/* We produce a TXDROP event only for retry or lifetime		 * exceeded, because that's the only status that really mean		 * that this particular node went away.		 * Other errors means that *we* screwed up. - Jean II */		if ((le16_to_cpu(status) & 2) ||		     (le16_to_cpu(status) & 4)) {			union iwreq_data	wrqu;			char junk[0x18];			/* Faster to skip over useless data than to do			 * another bap_setup(). We are at offset 0x6 and			 * need to go to 0x18 and read 6 bytes - Jean II */			bap_read(ai, (u16 *) junk, 0x18, BAP0);			/* Copy 802.11 dest address.			 * We use the 802.11 header because the frame may			 * not be 802.3 or may be mangled...			 * In Ad-Hoc mode, it will be the node address.			 * In managed mode, it will be most likely the AP addr			 * User space will figure out how to convert it to			 * whatever it needs (IP address or else).			 * - Jean II */			memcpy(wrqu.addr.sa_data, junk + 0x12, ETH_ALEN);			wrqu.addr.sa_family = ARPHRD_ETHER;			/* Send event to user space */			wireless_send_event(ai->dev, IWEVTXDROP, &wrqu, NULL);		}#endif /* WIRELESS_EXT > 13 */	}}static void airo_end_xmit(struct net_device *dev) {	u16 status;	int i;	struct airo_info *priv = dev->priv;	struct sk_buff *skb = priv->xmit.skb;	int fid = priv->xmit.fid;	u32 *fids = priv->fids;	clear_bit(JOB_XMIT, &priv->flags);	clear_bit(FLAG_PENDING_XMIT, &priv->flags);	status = transmit_802_3_packet (priv, fids[fid], skb->data);	up(&priv->sem);	i = 0;	if ( status == SUCCESS ) {		dev->trans_start = jiffies;		for (; i < MAX_FIDS / 2 && (priv->fids[i] & 0xffff0000); i++);	} else {		priv->fids[fid] &= 0xffff;		priv->stats.tx_window_errors++;	}	if (i < MAX_FIDS / 2)		netif_wake_queue(dev);	dev_kfree_skb(skb);}static int airo_start_xmit(struct sk_buff *skb, struct net_device *dev) {	s16 len;	int i, j;	struct airo_info *priv = dev->priv;	u32 *fids = priv->fids;	if ( skb == NULL ) {		printk( KERN_ERR "airo:  skb == NULL!!!\n" );		return 0;	}	/* Find a vacant FID */	for( i = 0; i < MAX_FIDS / 2 && (fids[i] & 0xffff0000); i++ );	for( j = i + 1; j < MAX_FIDS / 2 && (fids[j] & 0xffff0000); j++ );	if ( j >= MAX_FIDS / 2 ) {		netif_stop_queue(dev);		if (i == MAX_FIDS / 2) {			priv->stats.tx_fifo_errors++;			return 1;		}	}	/* check min length*/	len = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN;        /* Mark fid as used & save length for later */	fids[i] |= (len << 16);	priv->xmit.skb = skb;	priv->xmit.fid = i;	if (down_trylock(&priv->sem) != 0) {		set_bit(FLAG_PENDING_XMIT, &priv->flags);		netif_stop_queue(dev);		set_bit(JOB_XMIT, &priv->flags);		wake_up_interruptible(&priv->thr_wait);	} else		airo_end_xmit(dev);	return 0;}static void airo_end_xmit11(struct net_device *dev) {	u16 status;	int i;	struct airo_info *priv = dev->priv;	struct sk_buff *skb = priv->xmit11.skb;	int fid = priv->xmit11.fid;	u32 *fids = priv->fids;

⌨️ 快捷键说明

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