wstats.updated = 3; 
wstats.noise = apriv->wstats.qual.noise; wstats.updated = IW_QUAL_LEVEL_UPDATED | IW_QUAL_QUAL_UPDATED | IW_QUAL_NOISE_UPDATED; 
static irqreturn_t airo_interrupt ( int irq, void* dev_id, struct pt_regs *regs) {	struct net_device *dev = (struct net_device *)dev_id;	u16 status;	u16 fid;	struct airo_info *apriv = dev->priv;	u16 savedInterrupts = 0;	int handled = 0;	if (!netif_device_present(dev))		return IRQ_NONE;	for (;;) {		status = IN4500( apriv, EVSTAT );		if ( !(status & STATUS_INTS) || status == 0xffff ) break;		handled = 1;		if ( status & EV_AWAKE ) {			OUT4500( apriv, EVACK, EV_AWAKE );			OUT4500( apriv, EVACK, EV_AWAKE );		}		if (!savedInterrupts) {			savedInterrupts = IN4500( apriv, EVINTEN );			OUT4500( apriv, EVINTEN, 0 );		}		if ( status & EV_MIC ) {			OUT4500( apriv, EVACK, EV_MIC );#ifdef MICSUPPORT			if (test_bit(FLAG_MIC_CAPABLE, &apriv->flags)) {				set_bit(JOB_MIC, &apriv->flags);				wake_up_interruptible(&apriv->thr_wait);			}#endif		}		if ( status & EV_LINK ) {			union iwreq_data	wrqu;			/* The link status has changed, if you want to put a			   monitor hook in, do it here.  (Remember that			   interrupts are still disabled!)			*/			u16 newStatus = IN4500(apriv, LINKSTAT);			OUT4500( apriv, EVACK, EV_LINK);			/* Here is what newStatus means: */#define NOBEACON 0x8000 /* Loss of sync - missed beacons */#define MAXRETRIES 0x8001 /* Loss of sync - max retries */#define MAXARL 0x8002 /* Loss of sync - average retry level exceeded*/#define FORCELOSS 0x8003 /* Loss of sync - host request */#define TSFSYNC 0x8004 /* Loss of sync - TSF synchronization */#define DEAUTH 0x8100 /* Deauthentication (low byte is reason code) */#define DISASS 0x8200 /* Disassociation (low byte is reason code) */#define ASSFAIL 0x8400 /* Association failure (low byte is reason			  code) */#define AUTHFAIL 0x0300 /* Authentication failure (low byte is reason			   code) */#define ASSOCIATED 0x0400 /* Assocatied */#define RC_RESERVED 0 /* Reserved return code */#define RC_NOREASON 1 /* Unspecified reason */#define RC_AUTHINV 2 /* Previous authentication invalid */#define RC_DEAUTH 3 /* Deauthenticated because sending station is		       leaving */#define RC_NOACT 4 /* Disassociated due to inactivity */#define RC_MAXLOAD 5 /* Disassociated because AP is unable to handle			all currently associated stations */#define RC_BADCLASS2 6 /* Class 2 frame received from			  non-Authenticated station */#define RC_BADCLASS3 7 /* Class 3 frame received from			  non-Associated station */#define RC_STATLEAVE 8 /* Disassociated because sending station is			  leaving BSS */#define RC_NOAUTH 9 /* Station requesting (Re)Association is not		       Authenticated with the responding station */			if (newStatus != ASSOCIATED) {				if (auto_wep && !apriv->expires) {					apriv->expires = RUN_AT(3*HZ);					wake_up_interruptible(&apriv->thr_wait);				}			} else {				struct task_struct *task = apriv->task;				if (auto_wep)					apriv->expires = 0;				if (task)					wake_up_process (task);				set_bit(FLAG_UPDATE_UNI, &apriv->flags);				set_bit(FLAG_UPDATE_MULTI, &apriv->flags);			}			/* Question : is ASSOCIATED the only status			 * that is valid ? We want to catch handover			 * and reassociations as valid status			 * Jean II */			if(newStatus == ASSOCIATED) {				if (apriv->scan_timestamp) {					/* Send an empty event to user space.					 * We don't send the received data on					 * the event because it would require					 * us to do complex transcoding, and					 * we want to minimise the work done in					 * the irq handler. Use a request to					 * extract the data - Jean II */					wrqu.data.length = 0;					wrqu.data.flags = 0;					wireless_send_event(dev, SIOCGIWSCAN, &wrqu, NULL);					apriv->scan_timestamp = 0;				}				if (down_trylock(&apriv->sem) != 0) {					set_bit(JOB_EVENT, &apriv->flags);					wake_up_interruptible(&apriv->thr_wait);				} else					airo_send_event(dev);			} else {				memset(wrqu.ap_addr.sa_data, '\0', ETH_ALEN);				wrqu.ap_addr.sa_family = ARPHRD_ETHER;				/* Send event to user space */				wireless_send_event(dev, SIOCGIWAP, &wrqu,NULL);			}		}		/* Check to see if there is something to receive */		if ( status & EV_RX  ) {			struct sk_buff *skb = NULL;			u16 fc, len, hdrlen = 0;#pragma pack(1)			struct {				u16 status, len;				u8 rssi[2];				u8 rate;				u8 freq;				u16 tmp[4];			} hdr;#pragma pack()			u16 gap;			u16 tmpbuf[4];			u16 *buffer;			if (test_bit(FLAG_MPI,&apriv->flags)) {				if (test_bit(FLAG_802_11, &apriv->flags))					mpi_receive_802_11(apriv);				else					mpi_receive_802_3(apriv);				OUT4500(apriv, EVACK, EV_RX);				goto exitrx;			}			fid = IN4500( apriv, RXFID );			/* Get the packet length */			if (test_bit(FLAG_802_11, &apriv->flags)) {				bap_setup (apriv, fid, 4, BAP0);				bap_read (apriv, (u16*)&hdr, sizeof(hdr), BAP0);				/* Bad CRC. Ignore packet */				if (le16_to_cpu(hdr.status) & 2)					hdr.len = 0;				if (apriv->wifidev == NULL)					hdr.len = 0;			} else {				bap_setup (apriv, fid, 0x36, BAP0);				bap_read (apriv, (u16*)&hdr.len, 2, BAP0);			}			len = le16_to_cpu(hdr.len);			if (len > 2312) {				printk( KERN_ERR "airo: Bad size %d\n", len );				goto badrx;			}			if (len == 0)				goto badrx;			if (test_bit(FLAG_802_11, &apriv->flags)) {				bap_read (apriv, (u16*)&fc, sizeof(fc), BAP0);				fc = le16_to_cpu(fc);				switch (fc & 0xc) {					case 4:						if ((fc & 0xe0) == 0xc0)							hdrlen = 10;						else							hdrlen = 16;						break;					case 8:						if ((fc&0x300)==0x300){							hdrlen = 30;							break;						}					default:						hdrlen = 24;				}			} else				hdrlen = ETH_ALEN * 2;			skb = dev_alloc_skb( len + hdrlen + 2 + 2 );			if ( !skb ) {				apriv->stats.rx_dropped++;				goto badrx;			}			skb_reserve(skb, 2); /* This way the IP header is aligned */			buffer = (u16*)skb_put (skb, len + hdrlen);			if (test_bit(FLAG_802_11, &apriv->flags)) {				buffer[0] = fc;				bap_read (apriv, buffer + 1, hdrlen - 2, BAP0);				if (hdrlen == 24)					bap_read (apriv, tmpbuf, 6, BAP0);				bap_read (apriv, &gap, sizeof(gap), BAP0);				gap = le16_to_cpu(gap);				if (gap) {					if (gap <= 8)						bap_read (apriv, tmpbuf, gap, BAP0);					else						printk(KERN_ERR "airo: gaplen too big. Problems will follow...\n");				}				bap_read (apriv, buffer + hdrlen/2, len, BAP0);			} else {#ifdef MICSUPPORT				MICBuffer micbuf;#endif				bap_read (apriv, buffer, ETH_ALEN*2, BAP0);#ifdef MICSUPPORT				if (apriv->micstats.enabled) {					bap_read (apriv,(u16*)&micbuf,sizeof(micbuf),BAP0);					if (ntohs(micbuf.typelen) > 0x05DC)						bap_setup (apriv, fid, 0x44, BAP0);					else {						if (len <= sizeof(micbuf))							goto badmic;						len -= sizeof(micbuf);						skb_trim (skb, len + hdrlen);					}				}#endif				bap_read(apriv,buffer+ETH_ALEN,len,BAP0);#ifdef MICSUPPORT				if (decapsulate(apriv,&micbuf,(etherHead*)buffer,len)) {badmic:					dev_kfree_skb_irq (skb);#else				if (0) {#endifbadrx:					OUT4500( apriv, EVACK, EV_RX);					goto exitrx;				}			}#ifdef WIRELESS_SPY			if (apriv->spy_data.spy_number > 0) {				char *sa;				struct iw_quality wstats;				/* Prepare spy data : addr + qual */				if (!test_bit(FLAG_802_11, &apriv->flags)) {					sa = (char*)buffer + 6;					bap_setup (apriv, fid, 8, BAP0);					bap_read (apriv, (u16*)hdr.rssi, 2, BAP0);				} else					sa = (char*)buffer + 10;				wstats.qual = hdr.rssi[0];				if (apriv->rssi)					wstats.level = 0x100 - apriv->rssi[hdr.rssi[1]].rssidBm;				else					wstats.level = (hdr.rssi[1] + 321) / 2;				wstats.updated = 3;					/* Update spy records */				wireless_spy_update(dev, sa, &wstats);			}#endif /* WIRELESS_SPY */			OUT4500( apriv, EVACK, EV_RX);			if (test_bit(FLAG_802_11, &apriv->flags)) {				skb->mac.raw = skb->data;				skb->pkt_type = PACKET_OTHERHOST;				skb->dev = apriv->wifidev;				skb->protocol = htons(ETH_P_802_2);			} else {				skb->dev = dev;				skb->protocol = eth_type_trans(skb,dev);			}			skb->dev->last_rx = jiffies;			skb->ip_summed = CHECKSUM_NONE;			netif_rx( skb );		}exitrx:		/* Check to see if a packet has been transmitted */		if (  status & ( EV_TX|EV_TXCPY|EV_TXEXC ) ) {			int i;			int len = 0;			int index = -1;			if (test_bit(FLAG_MPI,&apriv->flags)) {				unsigned long flags;				if (status & EV_TXEXC)					get_tx_error(apriv, -1);				spin_lock_irqsave(&apriv->aux_lock, flags);				if (skb_queue_len (&apriv->txq)) {					spin_unlock_irqrestore(&apriv->aux_lock,flags);					mpi_send_packet (dev);				} else {					clear_bit(FLAG_PENDING_XMIT, &apriv->flags);					spin_unlock_irqrestore(&apriv->aux_lock,flags);					netif_wake_queue (dev);				}				OUT4500( apriv, EVACK,					status & (EV_TX|EV_TXCPY|EV_TXEXC));				goto exittx;			}			fid = IN4500(apriv, TXCOMPLFID);			for( i = 0; i < MAX_FIDS; i++ ) {				if ( ( apriv->fids[i] & 0xffff ) == fid ) {					len = apriv->fids[i] >> 16;					index = i;				}			}			if (index != -1) {				if (status & EV_TXEXC)					get_tx_error(apriv, index);				OUT4500( apriv, EVACK, status & (EV_TX | EV_TXEXC));				/* Set up to be used again */				apriv->fids[index] &= 0xffff;				if (index < MAX_FIDS / 2) {					if (!test_bit(FLAG_PENDING_XMIT, &apriv->flags))						netif_wake_queue(dev);				} else {					if (!test_bit(FLAG_PENDING_XMIT11, &apriv->flags))						netif_wake_queue(apriv->wifidev);				}			} else {				OUT4500( apriv, EVACK, status & (EV_TX | EV_TXCPY | EV_TXEXC));				printk( KERN_ERR "airo: Unallocated FID was used to xmit\n" );			}		}exittx:		if ( status & ~STATUS_INTS & ~IGNORE_INTS )			printk( KERN_WARNING "airo: Got weird status %x\n",				status & ~STATUS_INTS & ~IGNORE_INTS );	}	if (savedInterrupts)		OUT4500( apriv, EVINTEN, savedInterrupts );	/* done.. */	return IRQ_RETVAL(handled);}
4520	/local/tlutelli/issta_data/temp/c/2005_temp/2005/4520/41480af27a85d6008d9e11db8bc2730407c25e1d/airo.c/clean/drivers/net/wireless/airo.c