File: /usr/src/linux/drivers/net/aironet4500_core.c

1     /*
2      *	 Aironet 4500/4800 driver core
3      *
4      *		Elmer Joandi, Januar 1999
5      *		Copyright: 	GPL
6      *	
7      *
8      *	Revision 0.1 ,started  30.12.1998
9      *
10      *
11      */
12      /* CHANGELOG:
13      	march 99, stable version 2.0
14      	august 99, stable version 2.2
15      	november 99, integration with 2.3
16     	17.12.99: finally, got SMP near-correct. 
17     		timing issues remain- on SMP box its 15% slower on tcp	
18     	10.03.00 looks like softnet take us back to normal on SMP
19      */
20     
21     #include <linux/module.h>
22     #include <linux/init.h>
23     #include <linux/config.h>
24     #include <linux/kernel.h>
25     #include <linux/netdevice.h>
26     #include <linux/etherdevice.h>
27     #include <linux/skbuff.h>
28     #include <linux/if_arp.h>
29     #include <linux/ioport.h>
30     
31     #include <asm/io.h>
32     #include <asm/bitops.h>
33     #include <asm/system.h>
34     #include <asm/byteorder.h>
35     #include <asm/irq.h>
36     #include <linux/time.h>
37     #include <linux/sched.h>
38     #include <linux/delay.h>
39     #include "aironet4500.h"
40     #include <linux/ip.h>
41     
42     
43     int bap_sleep = 10 ;
44     int bap_sleep_after_setup = 1;
45     int sleep_before_command  = 1;
46     int bap_sleep_before_write= 1;
47     int sleep_in_command	  = 1;
48     int both_bap_lock;		/* activated at awc_init in this */
49     int bap_setup_spinlock;		/* file if numcpu >1 */
50     
51     EXPORT_SYMBOL(bap_sleep);
52     EXPORT_SYMBOL(bap_sleep_after_setup);
53     EXPORT_SYMBOL(sleep_before_command);
54     EXPORT_SYMBOL(bap_sleep_before_write);
55     EXPORT_SYMBOL(sleep_in_command);
56     EXPORT_SYMBOL(both_bap_lock);
57     EXPORT_SYMBOL(bap_setup_spinlock);
58     
59     struct awc_strings awc_status_error_codes[]=awc_reply_error_strings;
60     struct awc_strings awc_command_names[]=awc_command_name_strings;
61     struct awc_strings awc_link_status_names[]=awc_link_status_strings;
62     struct awc_strings awc_rid_names[]=aironet4500_RID_Select_strings;
63     struct awc_strings awc_link_failure_reason_names[]=IEEE_802_11_LINK_STATUS_FAILURE_REASON_STRINGS;
64     
65     const char *  awc_print_string( struct awc_strings* strings, int code){
66     	
67     	struct awc_strings * str = strings;
68     	int i = 0;
69     	while (str[i].string != NULL){
70     		if (str[i].par == (code & str[i].mask )){
71     			return str[i].string;
72     		};
73     		i++;
74     	};
75     	return "UNKNOWN";
76     };
77     
78     int awc_dump_registers(struct net_device * dev){
79     
80     #ifdef AWC_DEBUG
81     	int i;
82     #endif
83     	int status= inw(dev->base_addr +4*2);	
84     	int r1= inw(dev->base_addr +5*2);	
85     	int r2= inw(dev->base_addr +6*2);	
86     	int r3= inw(dev->base_addr +7*2);	
87     
88     	printk(KERN_ERR "Command %s , result: %s, at memblk %x(RID %s) , offset %x \n",
89     		awc_print_string(awc_command_names,status), 
90     		awc_print_string(awc_status_error_codes,r1),
91     		r2, awc_print_string(awc_rid_names,r2),
92     		r3);
93     
94     #ifdef AWC_DEBUG
95     	printk(KERN_ERR "%s aironet register dump ",dev->name );
96       
97     	                        
98     	for (i=0; i < 32; i++){
99     		printk("%4x ", inw(dev->base_addr + i*2 ) );
100     		if ( (i+1)%8 == 0){
101     			printk("\n");
102     			printk(KERN_ERR "%02x",(i+1)*2);
103     		}
104     	};
105     	printk(KERN_ERR " \n");
106     #endif
107     	return 0;                       
108     };
109               
110     /******************************		COMMAND 	******************/
111     
112     
113     inline 
114     int	awc_command_busy_clear_wait(struct net_device * dev){
115     //	long long jiff = jiffies;
116             u16  active_interrupts;
117             int  cnt= 0;
118             
119       	AWC_ENTRY_EXIT_DEBUG(" entry awc_command_busy_clear_wait ");
120       		     
121     	while (awc_command_busy(dev->base_addr)){
122     		if (cnt > 1000 ){
123     			printk(KERN_ERR "awc command busy too long, clearing\n");
124     			awc_dump_registers(dev);
125     			awc_event_ack_ClrStckCmdBsy(dev->base_addr);
126     			break;
127     		};
128     		if (((struct awc_private*) dev->priv)->ejected)
129     			return -1;
130     		cnt++;
131     		udelay(10);
132     	}
133     	
134     	cnt = 0;
135     	while (awc_command_busy(dev->base_addr)){
136     		//if (jiffies - jiff > (HZ/3)){
137     		if (cnt > 30000 ){
138     			printk(KERN_CRIT "awc command busy WAY too long, clearing\n");
139     			awc_dump_registers(dev);
140     			awc_event_ack_ClrStckCmdBsy(dev->base_addr);
141      			active_interrupts = awc_event_status(dev->base_addr);
142     			awc_event_ack(dev->base_addr, active_interrupts);
143     			                                
144     			AWC_ENTRY_EXIT_DEBUG("BAD exit\n ");
145     			return -1 ;
146     			
147     		};
148     		if (((struct awc_private*) dev->priv)->ejected)
149     			return -1;
150     		cnt++;
151     		udelay(10);
152     	}
153     
154     	
155     	AWC_ENTRY_EXIT_DEBUG(" exit\n ");
156     	     
157     	return 0;
158     	  
159     
160     };
161     
162     
163     
164     inline unsigned short 
165     awc_issue_command_and_block(struct awc_command * cmd){
166     
167     	int ticks;               
168          long long jiff;
169          u16	enabled_interrupts;
170          int cnt = 0;
171     //     unsigned long flags;
172          
173          jiff = jiffies; 
174               
175     
176       AWC_ENTRY_EXIT_DEBUG(" entry awc_issue_command_and_block ");
177                    
178          AWC_LOCK_COMMAND_ISSUING(cmd->priv);
179     
180          if (awc_command_busy_clear_wait(cmd->dev)) 		goto final;
181     
182          if (cmd->priv->sleeping_bap) udelay(sleep_before_command);               	
183     
184          awc4500wout(cmd->port,cmd->command,cmd->par0,cmd->par1,cmd->par2);
185     //     awc_dump_registers(cmd->dev);
186     
187     
188          if (cmd->priv->sleeping_bap) udelay(sleep_in_command);
189          
190          enabled_interrupts = awc_ints_enabled(cmd->dev->base_addr);
191          awc_ints_enable(cmd->dev->base_addr, enabled_interrupts & ~0x10);
192           if(cmd->priv->enabled_interrupts & 0x10)
193           	cmd->priv->enabled_interrupts &= ~0x10;
194     
195     	
196          while ( awc_command_read(cmd->port) == cmd->command) {
197            	  udelay(1);
198               awc_command_write(cmd->port, cmd->command);
199               //if ((jiffies - jiff) > 2){
200     	  if (cnt > 2000 ){
201               	printk(" long wait with commmand reg busy in blocking command \n");
202               	awc_dump_registers(cmd->dev);
203              	goto final;
204               };
205               if (cmd->priv->ejected)
206     		goto final;
207     	  cnt++;
208       	  udelay(10);
209     
210          };
211          AWC_ENTRY_EXIT_DEBUG(" issued " ); 
212     
213          ticks = 0;
214          while ( awc_event_status_Cmd(cmd->port) == 0) {
215     	  ticks++;
216               if (ticks > 100000){
217     		printk(" long wait with commmand reg busy \n");
218               	awc_dump_registers(cmd->dev);
219               		goto final;
220               };
221     	  if (ticks > 500){
222     	       DEBUG(1, " long wait after issue 10mks * %d ", ticks ); 
223              	//printk(" long wait with command reg busy about ticks\n");
224     	  	// sti();
225               }
226               if (cmd->priv->ejected)
227     		goto final;
228     	  udelay(10);
229          }            
230          if (cmd->priv->sleeping_bap) udelay(sleep_in_command);     
231     
232          awc_read_response(cmd);
233          AWC_ENTRY_EXIT_DEBUG(" resp read \n"); 
234     
235          if (awc_command_busy(cmd->port)) 
236          	awc_event_ack_ClrStckCmdBsy(cmd->port);
237     
238          awc_event_ack_Cmd(cmd->port);
239         if (cmd->priv->sleeping_bap) udelay(sleep_in_command);     
240      
241          if (cmd->status & 0xff00){
242          	printk(KERN_ERR " bad response to command %s, parameter %x \n",awc_print_string(awc_command_names, cmd->command),cmd->par0);
243          	awc_dump_registers(cmd->dev);
244       	goto final;   	 
245          }	
246     
247          AWC_UNLOCK_COMMAND_ISSUING(cmd->priv);
248          AWC_ENTRY_EXIT_DEBUG(" exit \n"); 
249         udelay(1);
250          return 0;
251     final: 
252          AWC_UNLOCK_COMMAND_ISSUING(cmd->priv);
253          AWC_ENTRY_EXIT_DEBUG("  BAD exit \n");
254          return -1; ;
255     };
256     
257     
258     inline 
259     unsigned short 
260     awc_issue_command(struct awc_command * cmd){
261     
262     
263     //     long long jiff = jiffies;          
264     //     unsigned short enabled_ints;               
265          int cnt = 0;
266     //	int i=0; 
267      
268          AWC_ENTRY_EXIT_DEBUG(" entry awc_issue_command");
269          
270          if (!cmd){
271          	printk(KERN_CRIT "cmd == NULL in awc_issue_command\n");
272          	return -1;
273          
274          }
275          if (!cmd->dev){
276          	printk(KERN_CRIT "cmd->dev == NULL in awc_issue_command\n");
277          	return -1;
278          
279          }
280     
281          AWC_LOCK_COMMAND_ISSUING(cmd->priv);	
282     
283          if(awc_command_busy_clear_wait(cmd->dev))		goto final;               	
284     
285           if(!cmd->priv->enabled_interrupts & 0x10){
286           	cmd->priv->enabled_interrupts |= 0x10;
287          	awc_ints_enable(cmd->port, cmd->priv->enabled_interrupts );
288           }
289     
290          cmd->priv->async_command_start = jiffies;
291          cmd->priv->command_semaphore_on++;
292     
293     
294          awc4500wout(cmd->port,cmd->command,cmd->par0,cmd->par1,cmd->par2);
295          
296          while ( awc_command_read(cmd->port) == cmd->command) {
297            
298               awc_command_write(cmd->port, cmd->command);
299               //if ((jiffies - jiff) > 2){
300               if (cnt > 2000) {  
301     		printk(" long wait with commmand reg busy in async command \n");
302               	awc_dump_registers(cmd->dev);
303              	goto final;
304               };
305               if (cmd->priv->ejected)
306     		goto final;
307     	   cnt++;
308     	  udelay(10);
309          };
310          
311          cmd->priv->cmd = *cmd;
312          
313          
314          AWC_ENTRY_EXIT_DEBUG(" exit \n"); 
315          return 0;
316      final:
317          AWC_UNLOCK_COMMAND_ISSUING(cmd->priv);
318          AWC_ENTRY_EXIT_DEBUG("  BAD exit \n");
319     	   return -1; ;
320     
321     };
322     
323     inline 
324     unsigned short 
325     awc_issue_command_no_ack(struct net_device * dev,
326     			u16 com, u16 par1, u16 par2, u16 par3){
327     
328          struct awc_private * priv = (struct awc_private *)dev->priv;
329          int cnt = 0;
330          long long jiff;
331          jiff = jiffies;          
332     
333          AWC_ENTRY_EXIT_DEBUG(" entry awc_issue_command_no_ack ");
334          
335                    
336          AWC_LOCK_COMMAND_ISSUING(priv);	
337     
338          if (awc_command_busy_clear_wait(dev)) {
339     		printk("aironet4x00 no_ack command (reset) with stuck card \n");
340          }
341     
342          awc4500wout(dev->base_addr,com, par1, par2,par3);
343     
344          udelay(10);     
345          while ( awc_event_status_Cmd(dev->base_addr) == 0) {
346               if (awc_command_read(dev->base_addr) == com) {                
347                    awc_command_write(dev->base_addr, com);
348               }
349               //if ((jiffies - jiff) > 2){
350               if (cnt > 2000) {  
351     		printk(" long wait with commmand reg busy in noack command %d par %d %d %d\n",com,par1,par2,par3);
352               	awc_dump_registers(dev);
353               		goto final;
354               };
355               if (priv->ejected)
356     		goto final;
357     	  udelay(10);
358     	  cnt++;
359          }            
360          
361          if (awc_command_busy(dev->base_addr)) 
362          	awc_event_ack_ClrStckCmdBsy(dev->base_addr);
363     
364          AWC_UNLOCK_COMMAND_ISSUING(priv);
365          AWC_ENTRY_EXIT_DEBUG(" exit \n"); 
366      return 0;
367     final: 
368          AWC_UNLOCK_COMMAND_ISSUING(priv);
369          AWC_ENTRY_EXIT_DEBUG("  BAD exit \n");
370     	   return -1; ;
371     };
372     
373     
374     /******************************** 	BAP	*************************/
375     
376     // inline // too long for inline
377     int awc_bap_setup(struct awc_command * cmd) {
378     
379     	int status;
380     	long long jiff;
381     	unsigned long flags;	
382     	int cleared = 0;
383     	int cycles = 0;
384     	
385          AWC_ENTRY_EXIT_DEBUG(" entry awc_bap_setup ");
386          	
387          if ( cmd->priv->sleeping_bap)
388     	udelay(bap_sleep);
389     	
390     	if (cmd->priv->ejected)
391     		return -1;
392               
393          if (!cmd->bap || !(cmd->lock_state & (AWC_BAP_SEMALOCKED |AWC_BAP_LOCKED)))
394          	DEBUG(1,"no bap or bap not locked cmd %d !!", cmd->command);
395     
396     	if (bap_setup_spinlock)
397     		spin_lock_irqsave(&cmd->priv->bap_setup_spinlock,cmd->priv->bap_setup_spinlock_flags);	  
398     	  status = AWC_IN(cmd->bap->offset);
399     	  
400     	  if (status & ~0x2000 ){
401     	  	WAIT61x3;
402     	  	status = AWC_IN(cmd->bap->offset);
403     	  }
404     
405     	  if (status & ~0x2000 ){
406                     WAIT61x3;
407     	        AWC_IN(cmd->dev->base_addr + 0x26);
408                     AWC_OUT(cmd->dev->base_addr + 0x26, 0);    
409     	  	WAIT61x3;
410     	  	udelay(60);
411     	  	#ifdef AWC_DEBUG
412     	  		printk("b");
413     	  	#endif
414     	  	status = AWC_IN(cmd->bap->offset);
415     	  }
416     
417     	  
418     	  if (status & 0xC000){
419     	  	printk(KERN_ERR "bap entered with err or busy bit set %x \n",status);
420     		if (cmd->bap->lock != 1) 
421     			printk(KERN_ERR "bap lock bad same time %x\n",cmd->bap->lock);
422     	  	awc_dump_registers(cmd->dev);
423     	  	//	AWC_OUT(cmd->bap->offset, 0x800);
424     	  }
425     
426     	  save_flags(flags);
427     	  cli();
428     	    
429               AWC_OUT(cmd->bap->select, cmd->rid);
430     	  WAIT61x3;
431               AWC_OUT(cmd->bap->offset, cmd->offset);
432      
433               restore_flags(flags);
434     
435     	  WAIT61x3;          
436               
437               jiff = jiffies;
438     
439               while (1) {
440                   cycles++;
441                   status = AWC_IN(cmd->bap->offset);
442                   if ( cmd->priv->sleeping_bap)
443                   		udelay(bap_sleep);
444                   if (cmd->priv->ejected)
445     			goto ejected_unlock;
446     	      udelay(1);
447     	      if (cycles > 10000) {
448     			printk(KERN_CRIT "deadlock in bap\n");
449     			goto return_AWC_ERROR;
450     	      };
451                   status = AWC_IN(cmd->bap->offset);
452                   if (status & AWC_BAP_BUSY) {
453                      if (cycles % 100 == 99 ) {
454                           save_flags(flags);
455                           cli();
456                           if (!cleared){
457                           	AWC_IN(cmd->dev->base_addr + 0x26);
458                           	AWC_OUT(cmd->dev->base_addr + 0x26, 0);
459                           	WAIT61x3;
460                           	cleared = 1;
461                           }  
462                           AWC_OUT(cmd->bap->select, cmd->rid);
463                           WAIT61x3;
464                           AWC_OUT(cmd->bap->offset, cmd->offset);
465                           restore_flags(flags);
466                     	#ifdef AWC_DEBUG
467     	  			printk("B");
468     	  		#endif      
469                           
470                           if ( cmd->priv->sleeping_bap)
471              		udelay(bap_sleep);
472              	      else udelay(30);
473                           //restart_timeout();
474                       }
475                       if (jiffies - jiff > 1 ) {
476                       	AWC_ENTRY_EXIT_DEBUG(" BAD BUSY  exit \n");
477                       	awc_dump_registers(cmd->dev);
478                       	goto return_AWC_ERROR;
479                       }
480                       continue;
481                   }
482                  if (status & AWC_BAP_DONE) {
483                       WAIT61x3; WAIT61x3; WAIT61x3;
484                       
485                     //  if ((status & 0xfff) != cmd->offset)
486                     //  	printk(KERN_ERR "awcPBD %x ",status);
487                        AWC_ENTRY_EXIT_DEBUG(" exit \n");
488                       if (cmd->priv->sleeping_bap)
489                       	udelay(bap_sleep_after_setup); 
490                        
491                       // success
492                       goto return_AWC_SUCCESS;
493                   }
494     
495                   if (status & AWC_BAP_ERR) {
496                  	  AWC_ENTRY_EXIT_DEBUG(" BAD  exit \n");
497                       // invalid rid or offset
498                       printk(KERN_ERR "bap setup error bit set for rid %x offset %x \n",cmd->rid,cmd->offset);
499                       awc_dump_registers(cmd->dev);
500                       goto return_AWC_ERROR;
501                   }
502                   if ( cmd->priv->sleeping_bap)
503              		udelay(bap_sleep);
504                   else udelay(1);
505                   // -- awc missed it, try again
506              
507                   save_flags(flags);
508                   cli();
509                   AWC_OUT(cmd->bap->select, cmd->rid);
510                   WAIT61x3;
511                   AWC_OUT(cmd->bap->offset, cmd->offset);
512                   WAIT61x3;
513                   restore_flags(flags);
514     		
515     	      if (jiffies - jiff > HZ)
516     	      if (! (status &(AWC_BAP_ERR |AWC_BAP_DONE |AWC_BAP_BUSY))){
517     		printk("aironet4500: bap setup lock without any status bits set");
518     		awc_dump_registers(cmd->dev);
519                     goto return_AWC_ERROR;
520     
521     	      };
522              
523               }
524     
525          AWC_ENTRY_EXIT_DEBUG(" WE MUST NOT BE HERE exit \n");
526     
527     ejected_unlock:
528          if (bap_setup_spinlock)
529     	spin_unlock_irqrestore(&cmd->priv->bap_setup_spinlock,cmd->priv->bap_setup_spinlock_flags);	  
530          AWC_ENTRY_EXIT_DEBUG(" ejected_unlock_exit \n");	
531          return -1;
532     
533     return_AWC_ERROR:
534          if (bap_setup_spinlock)
535     	spin_unlock_irqrestore(&cmd->priv->bap_setup_spinlock,cmd->priv->bap_setup_spinlock_flags);	  
536          AWC_ENTRY_EXIT_DEBUG(" AWC_ERROR_exit \n");
537          return AWC_ERROR;          
538     
539     return_AWC_SUCCESS:
540          if (bap_setup_spinlock)
541     	spin_unlock_irqrestore(&cmd->priv->bap_setup_spinlock,cmd->priv->bap_setup_spinlock_flags);	  
542          AWC_ENTRY_EXIT_DEBUG(" exit \n");
543          return AWC_SUCCESS;          
544     }
545     
546     
547     	// requires call to awc_bap_setup() first
548     inline 
549     int
550     awc_bap_read(struct awc_command * cmd) {
551     	register u16 len;
552     	register u16 * buff = (u16 *) cmd->buff;
553     	register u16 port= cmd->bap->data;
554     
555     
556             AWC_ENTRY_EXIT_DEBUG(" entry awc_bap_read ");
557          	if (!cmd->bap && !(cmd->lock_state & (AWC_BAP_SEMALOCKED |AWC_BAP_LOCKED)))
558          		DEBUG(0,"no bap or bap not locked %d !!", cmd->command);
559             cmd->len = (cmd->len + 1) & (~1);               // round up to even value
560             len = cmd->len / 2;
561     	if (cmd->priv->ejected)
562     			return -1;
563     
564     
565     	if (cmd->priv->sleeping_bap)
566     		udelay(bap_sleep_before_write);
567     		
568             if (!cmd->priv->sleeping_bap)
569             	while ( len-- > 0) 
570     			*buff++ = AWC_IN(port);
571     	else 
572     		while ( len-- > 0){
573     	                *buff++ = AWC_IN(port);
574     	        }
575     	AWC_ENTRY_EXIT_DEBUG(" exit  \n");
576       	if (cmd->priv->ejected)
577     			return -1;
578             	
579             return AWC_SUCCESS;
580     }
581     
582           // requires call to awc_bap_setup() first
583     inline 
584     int
585     awc_bap_write(struct awc_command * cmd){
586               register u16 len;
587               register u16 * buff = (u16 *) cmd->buff;
588               register u16 port= cmd->bap->data;
589               
590                
591           AWC_ENTRY_EXIT_DEBUG(" entry awc_bap_write ");
592           if (!cmd->bap && !(cmd->lock_state & (AWC_BAP_SEMALOCKED |AWC_BAP_LOCKED)))
593          		DEBUG(0,"no bap or bap not locked %d !!", cmd->command);
594          
595               cmd->len = (cmd->len + 1) & (~1);               // round up to even value
596               len = cmd->len / 2;
597     
598     	  if (cmd->priv->ejected)
599     			return -1;
600     
601     	  if (cmd->priv->sleeping_bap)
602     		udelay(bap_sleep_before_write);
603     
604     
605               if (!cmd->priv->sleeping_bap)
606               	while (len-- > 0) 
607                   		AWC_OUT(port, *buff++);
608               else
609               	while ( len-- > 0){
610               		AWC_OUT(port, *buff++);
611               	}
612     	  if (cmd->priv->ejected)
613     			return -1;
614     
615     
616           AWC_ENTRY_EXIT_DEBUG(" exit  \n");
617                   	
618               return AWC_SUCCESS;
619     }
620     
621     
622     
623     
624     /***************************** 	RID READ/WRITE	********************/
625     
626     const struct aironet4500_rid_selector  aironet4500_RID_Select_General_Config	=(const struct aironet4500_rid_selector){ 0xFF10, 1,0,0, "General Configuration" }; //        See notes General Configuration        Many configuration items.
627     const struct aironet4500_rid_selector  aironet4500_RID_Select_SSID_list		=(const struct aironet4500_rid_selector){ 0xFF11, 1,0,0, "Valid SSID list" }; //          See notes Valid SSID list              List of SSIDs which the station may associate to.
628     const struct aironet4500_rid_selector  aironet4500_RID_Select_AP_list		=(const struct aironet4500_rid_selector){ 0xFF12, 1,0,0, "Valid AP list" }; //          See notes Valid AP list                List of APs which the station may associate to.
629     const struct aironet4500_rid_selector  aironet4500_RID_Select_Driver_name	=(const struct aironet4500_rid_selector){ 0xFF13, 1,0,0, "Driver name" }; //          See notes Driver name                  The name and version of the driver (for debugging)
630     const struct aironet4500_rid_selector  aironet4500_RID_Select_Encapsulation	=(const struct aironet4500_rid_selector){ 0xFF14, 1,0,0, "Ethernet Protocol" }; //          See notes Ethernet Protocol            Rules for encapsulating ethernet payloads onto 802.11.
631     const struct aironet4500_rid_selector  aironet4500_RID_Select_WEP_volatile	=(const struct aironet4500_rid_selector){ 0xFF15, 1,0,0, "WEP key volatile" }; //          
632     const struct aironet4500_rid_selector  aironet4500_RID_Select_WEP_nonvolatile	=(const struct aironet4500_rid_selector){ 0xFF16, 1,0,0, "WEP key non-volatile" }; //
633     const struct aironet4500_rid_selector  aironet4500_RID_Select_Modulation	=(const struct aironet4500_rid_selector){ 0xFF17, 1,0,0, "Modulation" }; //
634     const struct aironet4500_rid_selector  aironet4500_RID_Select_Active_Config	=(const struct aironet4500_rid_selector){ 0xFF20, 0,1,1, "Actual Configuration" }; //          Read only      Actual Configuration    This has the same format as the General Configuration.
635     const struct aironet4500_rid_selector  aironet4500_RID_Select_Capabilities	=(const struct aironet4500_rid_selector){ 0xFF00, 0,1,0, "Capabilities" }; //          Read Only      Capabilities            PC4500 Information
636     const struct aironet4500_rid_selector  aironet4500_RID_Select_AP_Info		=(const struct aironet4500_rid_selector){ 0xFF01, 0,1,1, "AP Info" }; //          Read Only      AP Info                 Access Point Information
637     const struct aironet4500_rid_selector  aironet4500_RID_Select_Radio_Info	=(const struct aironet4500_rid_selector){ 0xFF02, 0,1,1, "Radio Info" }; //          Read Only      Radio Info              Radio Information -- note radio specific
638     const struct aironet4500_rid_selector  aironet4500_RID_Select_Status		=(const struct aironet4500_rid_selector){ 0xFF50, 0,1,1, "Status" }; //          Read Only      Status                  PC4500 Current Status Information
639     const struct aironet4500_rid_selector  aironet4500_RID_Select_16_stats		=(const struct aironet4500_rid_selector){ 0xFF60, 0,1,1, "Cumulative 16-bit Statistics" }; //          Read Only      16-bit Statistics       Cumulative 16-bit Statistics
640     const struct aironet4500_rid_selector  aironet4500_RID_Select_16_stats_delta	=(const struct aironet4500_rid_selector){ 0xFF61, 0,1,1, "Delta 16-bit Statistics" }; //          Read Only      16-bit Statistics       Delta 16-bit Statistics (since last clear)
641     const struct aironet4500_rid_selector  aironet4500_RID_Select_16_stats_clear	=(const struct aironet4500_rid_selector){ 0xFF62, 0,1,1, "Delta 16-bit Statistics and Clear" }; //          Read Only /    16-bit Statistics       Delta 16-bit Statistics and Clear
642     const struct aironet4500_rid_selector  aironet4500_RID_Select_32_stats      	=(const struct aironet4500_rid_selector){ 0xFF68, 0,1,1, "Cumulative 32-bit Statistics" }; //          Read Only      32-bit Statistics       Cumulative 32-bit Statistics
643     const struct aironet4500_rid_selector  aironet4500_RID_Select_32_stats_delta	=(const struct aironet4500_rid_selector){ 0xFF69, 0,1,1, "Delta 32-bit Statistics"  }; //          Read Only      32-bit Statistics       Delta 32-bit Statistics (since last clear)
644     const struct aironet4500_rid_selector  aironet4500_RID_Select_32_stats_clear	=(const struct aironet4500_rid_selector){ 0xFF6A, 0,1,1, "Delta 32-bit Statistics and Clear" }; //          Read Only /    32-bit Statistics       Delta 32-bit Statistics and Clear
645     
646     EXPORT_SYMBOL(aironet4500_RID_Select_General_Config); 
647     EXPORT_SYMBOL(aironet4500_RID_Select_SSID_list); 
648     EXPORT_SYMBOL(aironet4500_RID_Select_AP_list); 
649     EXPORT_SYMBOL(aironet4500_RID_Select_Driver_name); 
650     EXPORT_SYMBOL(aironet4500_RID_Select_Encapsulation); 
651     EXPORT_SYMBOL(aironet4500_RID_Select_WEP_volatile); 
652     EXPORT_SYMBOL(aironet4500_RID_Select_WEP_nonvolatile); 
653     EXPORT_SYMBOL(aironet4500_RID_Select_Modulation); 
654     EXPORT_SYMBOL(aironet4500_RID_Select_Active_Config); 
655     EXPORT_SYMBOL(aironet4500_RID_Select_Capabilities); 
656     EXPORT_SYMBOL(aironet4500_RID_Select_AP_Info); 
657     EXPORT_SYMBOL(aironet4500_RID_Select_Radio_Info); 
658     EXPORT_SYMBOL(aironet4500_RID_Select_Status); 
659     EXPORT_SYMBOL(aironet4500_RID_Select_16_stats); 
660     EXPORT_SYMBOL(aironet4500_RID_Select_16_stats_delta); 
661     EXPORT_SYMBOL(aironet4500_RID_Select_16_stats_clear); 
662     EXPORT_SYMBOL(aironet4500_RID_Select_32_stats); 
663     EXPORT_SYMBOL(aironet4500_RID_Select_32_stats_delta); 
664     EXPORT_SYMBOL(aironet4500_RID_Select_32_stats_clear); 
665     
666     
667     struct awc_rid_dir awc_rids_temp[]={
668     	// following MUST be consistent with awc_rids_setup !!!
669        {&aironet4500_RID_Select_General_Config,		0x100 , NULL, NULL, NULL,0 },
670        {&aironet4500_RID_Select_SSID_list, 			 0x68 , NULL, NULL, NULL,0 },
671        {&aironet4500_RID_Select_AP_list, 			 0x20 , NULL, NULL, NULL,0 },
672        {&aironet4500_RID_Select_Driver_name, 		 0x12 , NULL, NULL, NULL,0 },
673        {&aironet4500_RID_Select_Encapsulation, 		 0x22 , NULL, NULL, NULL,0 },
674        {&aironet4500_RID_Select_Active_Config, 		0x100 , NULL, NULL, NULL,0 },
675        {&aironet4500_RID_Select_Capabilities, 		 0x80 , NULL, NULL, NULL,0 },
676        {&aironet4500_RID_Select_Status, 			 0x6c , NULL, NULL, NULL,0 },
677        {&aironet4500_RID_Select_AP_Info, 			 0x06 , NULL, NULL, NULL,0 },
678        {&aironet4500_RID_Select_32_stats, 			0x184 , NULL, NULL, NULL,0 },
679        {&aironet4500_RID_Select_32_stats_delta, 		0x184 , NULL, NULL, NULL,0 },
680        {&aironet4500_RID_Select_32_stats_clear, 		0x184 , NULL, NULL, NULL,0 },
681        {&aironet4500_RID_Select_WEP_volatile,  		0x1c , NULL, NULL, NULL,0 },
682        {&aironet4500_RID_Select_WEP_nonvolatile,		0x1c , NULL, NULL, NULL,0 },
683        {&aironet4500_RID_Select_Modulation, 		0x04 , NULL, NULL, NULL,0 },
684     
685     #ifdef AWC_USE_16BIT_STATS
686        {&aironet4500_RID_Select_16_stats, 			0xC2 , NULL, NULL, NULL,0 },
687        {&aironet4500_RID_Select_16_stats_delta,		0xC2 , NULL, NULL, NULL,0 },
688        {&aironet4500_RID_Select_16_stats_clear, 		0xC2 , NULL, NULL, NULL,0 },
689     #else 
690        {NULL},{NULL},{NULL},
691     #endif	
692      
693        {0} 
694     
695     
696     };
697     
698     
699     
700     int 
701     awc_readrid(struct net_device * dev, struct aironet4500_RID * rid, void *pBuf ){
702     	  struct awc_command cmd;
703     
704     	  int sleep_state ;
705     
706            AWC_ENTRY_EXIT_DEBUG(" entry awc_readrid ");
707               if (!rid) return -1;
708               if (!rid->selector) return -1;
709               AWC_INIT_COMMAND(AWC_NOT_CLI,cmd,dev,0x21, rid->selector->selector,
710               	rid->selector->selector, rid->offset, (rid->bits / 8),pBuf);
711     
712     	  sleep_state = cmd.priv->sleeping_bap ;
713     	  cmd.priv->sleeping_bap = 1;
714     	  udelay(500);
715     	  AWC_BAP_LOCK_NOT_CLI(cmd);
716     	  if (awc_issue_command_and_block(&cmd))	goto final;
717     	  udelay(1);
718               if (awc_bap_setup(&cmd))			goto final;
719               udelay(1);
720               if (awc_bap_read(&cmd))			goto final;
721               cmd.priv->sleeping_bap = sleep_state;
722     
723     	  AWC_RELEASE_COMMAND(cmd);
724               AWC_ENTRY_EXIT_DEBUG(" exit \n"); 
725      	  return 0;
726          final:
727          	  cmd.priv->sleeping_bap = sleep_state;
728          	  AWC_RELEASE_COMMAND(cmd);
729          	  AWC_ENTRY_EXIT_DEBUG("  BAD exit \n");
730     	   return -1; ;
731     }
732     
733     int 
734     awc_writerid(struct net_device * dev, struct aironet4500_RID * rid, void *pBuf){
735     
736     	  struct awc_command cmd;
737     	  int sleep_state ;
738     
739          AWC_ENTRY_EXIT_DEBUG(" entry awc_writerid ");
740          
741     
742               AWC_INIT_COMMAND(AWC_NOT_CLI,cmd,dev,0x21, rid->selector->selector,
743               	rid->selector->selector,rid->offset, rid->bits/8,pBuf);
744     
745     	  sleep_state = cmd.priv->sleeping_bap ;
746     	  cmd.priv->sleeping_bap = 1;
747     
748     	  udelay(500);
749     	  AWC_BAP_LOCK_NOT_CLI(cmd);	  
750     	  if (awc_issue_command_and_block(&cmd))	goto final;
751     	  udelay(10);
752               if (awc_bap_setup(&cmd))			goto final;
753               udelay(10);
754               if (awc_bap_write(&cmd))			goto final;
755               udelay(10);	
756               cmd.command=0x121;
757     	  if (awc_issue_command_and_block(&cmd))	goto final;
758               cmd.priv->sleeping_bap = sleep_state;
759     
760     	  AWC_RELEASE_COMMAND(cmd);
761               AWC_ENTRY_EXIT_DEBUG(" exit \n"); 
762      	  return 0;
763          final:
764          	  cmd.priv->sleeping_bap = sleep_state;
765          	  AWC_RELEASE_COMMAND(cmd);
766          	  AWC_ENTRY_EXIT_DEBUG("  BAD exit \n");
767     	   return -1; ;
768     }
769     
770     int 
771     awc_readrid_dir(struct net_device * dev, struct awc_rid_dir * rid ){
772     	  struct awc_command cmd;
773     	  int sleep_state;
774     
775          AWC_ENTRY_EXIT_DEBUG(" entry awcreadrid_dir ");
776          
777     
778               AWC_INIT_COMMAND(AWC_NOT_CLI,cmd,dev,0x21, rid->selector->selector,
779               	rid->selector->selector,0, rid->bufflen,rid->buff);
780     
781     	  sleep_state = cmd.priv->sleeping_bap ;
782     	  cmd.priv->sleeping_bap = 1;
783     
784     	  udelay(500);
785     
786     	  AWC_BAP_LOCK_NOT_CLI(cmd);
787     	  if (awc_issue_command_and_block(&cmd))	goto final;
788     	  
789               if (awc_bap_setup(&cmd))			goto final;
790               if (awc_bap_read(&cmd))			goto final;
791               cmd.priv->sleeping_bap = sleep_state;
792     
793     	  AWC_RELEASE_COMMAND(cmd);
794               AWC_ENTRY_EXIT_DEBUG(" exit \n"); 
795      	  return 0;
796          final:
797          	  cmd.priv->sleeping_bap = sleep_state;
798          	  AWC_RELEASE_COMMAND(cmd);
799          	  AWC_ENTRY_EXIT_DEBUG("  BAD exit \n");
800     	   return -1; ;
801     }
802     
803     int 
804     awc_writerid_dir(struct net_device * dev, struct awc_rid_dir * rid){
805     
806     	  struct awc_command cmd;
807     	  int sleep_state ;
808     
809     
810          AWC_ENTRY_EXIT_DEBUG(" entry awc_writerid_dir ");
811          
812     
813     
814               AWC_INIT_COMMAND(AWC_NOT_CLI,cmd,dev,0x21, rid->selector->selector,
815               	rid->selector->selector,0, rid->bufflen,((char *)rid->buff));
816     
817     	  sleep_state = cmd.priv->sleeping_bap ;
818     	  cmd.priv->sleeping_bap = 1;
819     
820     	  udelay(500);
821     
822     	  AWC_BAP_LOCK_NOT_CLI(cmd);
823     
824     	  if (awc_issue_command_and_block(&cmd))	goto final;
825               if (awc_bap_setup(&cmd))			goto final;
826               if (awc_bap_write(&cmd))			goto final;
827               cmd.priv->sleeping_bap = sleep_state;
828     	            
829               cmd.command=0x121;
830               udelay(500);
831     	  if (awc_issue_command_and_block(&cmd))	goto final;
832     
833     	  AWC_RELEASE_COMMAND(cmd);
834               AWC_ENTRY_EXIT_DEBUG(" exit \n"); 
835      	  return 0;
836          final:
837          	  cmd.priv->sleeping_bap = sleep_state;
838          	  AWC_RELEASE_COMMAND(cmd);
839          	  AWC_ENTRY_EXIT_DEBUG("  BAD exit \n");
840     	   return -1; ;
841     }
842     
843     EXPORT_SYMBOL(awc_readrid);
844     EXPORT_SYMBOL(awc_writerid);
845     EXPORT_SYMBOL(awc_readrid_dir);
846     EXPORT_SYMBOL(awc_writerid_dir);
847     
848     /*****************************		STARTUP		*******************/
849     
850     
851     inline
852     int
853     awc_issue_blocking_command(struct net_device * dev,u16 comm){
854     
855     	  struct awc_command cmd;
856     //	  struct awc_private * priv = (struct awc_private *)dev->priv;
857     
858          AWC_ENTRY_EXIT_DEBUG(" entry awc_issue_blocking_command ");
859          
860               AWC_INIT_COMMAND(AWC_NOT_CLI,cmd,dev,comm,0, 0, 0, 0 ,0 );
861     
862               AWC_BAP_LOCK_NOT_CLI(cmd);
863     
864               if (awc_issue_command_and_block(&cmd))
865               	goto final;
866     
867     	  AWC_RELEASE_COMMAND(cmd);
868               AWC_ENTRY_EXIT_DEBUG(" exit \n"); 
869      	  return 0;
870          final:
871          	  AWC_RELEASE_COMMAND(cmd);
872          	  AWC_ENTRY_EXIT_DEBUG("  BAD exit \n");
873     	  return -1; ;
874     	  
875     };
876     
877     int 
878     awc_issue_soft_reset(struct net_device * dev){
879     
880     	u16 status ;
881     //	int i= 0;
882     
883     /*	outw(inw(dev->base_addr + 0x30), dev->base_addr + 0x32);
884     	udelay(10);
885     	outw(inw(dev->base_addr + 0x30), dev->base_addr + 0x34);
886     
887     	for (i=0; i< 32; i++)
888     		outw(0,dev->base_addr + i*2);
889     	udelay(100);
890     	outw(0x6,dev->base_addr + 0x34);
891     	udelay(100);
892     	outw(0x6,dev->base_addr + 0x34);
893     	outw(0x6,dev->base_addr + 0x34);
894                     WAIT61x3;
895     	        AWC_IN(dev->base_addr + 0x26);
896                     AWC_OUT(dev->base_addr + 0x26, 0);    
897     	  	WAIT61x3;
898     	  	udelay(60);
899     	
900     
901     	outw(0x4, dev->base_addr);
902     	udelay(1000);
903             WAIT61x3;
904             AWC_IN(dev->base_addr + 0x26);
905             AWC_OUT(dev->base_addr + 0x26, 0);    
906      	WAIT61x3;
907     	udelay(60);
908     */
909     
910     	status =  awc_issue_command_no_ack(dev, AWC_COMMAND_SOFT_RESET,0,0,0);
911     	
912     //	awc_command_busy_clear_wait(dev);
913     
914     	return status;
915     };
916     
917     int
918     awc_issue_noop(struct net_device * dev){
919     	int retval;
920     	AWC_OUT(dev->base_addr + 0x28, 0);
921     	AWC_OUT(dev->base_addr + 0x2A, 0);
922     	udelay(1000);
923     	retval= awc_issue_blocking_command(dev, AWC_COMMAND_NOOP);
924     	udelay(1000);
925     	return retval;
926     };
927     
928     EXPORT_SYMBOL(awc_enable_MAC);
929     
930     int
931     awc_enable_MAC(struct net_device * dev){
932             
933        struct awc_private * priv = (struct awc_private *)dev->priv;
934          AWC_ENTRY_EXIT_DEBUG(" entry awc_enable_MAC ");
935                 
936             if (priv->mac_enabled){
937             
938             	AWC_ENTRY_EXIT_DEBUG(" mac already enabled exit \n"); 
939      		return 0;
940             }
941             udelay(500);
942     	if (awc_issue_blocking_command(dev, AWC_COMMAND_ENABLE)){
943     		AWC_ENTRY_EXIT_DEBUG("  BAD exit \n");
944     	   return -1; ;
945     	}
946             udelay(500);
947     
948     	priv->mac_enabled = 1;
949          
950     	AWC_ENTRY_EXIT_DEBUG(" exit \n"); 
951      	return 0;
952     };
953     
954     EXPORT_SYMBOL(awc_disable_MAC);
955     int
956     awc_disable_MAC(struct net_device * dev){
957             
958        struct awc_private * priv = (struct awc_private *)dev->priv;
959          AWC_ENTRY_EXIT_DEBUG(" entry awc_disable_MAC ");
960                 
961             if (!priv->mac_enabled){
962             	AWC_ENTRY_EXIT_DEBUG(" mac allready disabled exit \n"); 
963      		return 0;
964             }
965             udelay(1000);
966     	if (awc_issue_blocking_command(dev, AWC_COMMAND_DISABLE)){
967     		AWC_ENTRY_EXIT_DEBUG("  BAD exit \n");
968     		return -1; ;
969     	}
970     	udelay(1000);
971     	priv->mac_enabled = 0;
972             AWC_ENTRY_EXIT_DEBUG(" exit \n");
973     	return 0;
974     };
975     
976     
977     
978     int
979     awc_read_all_rids(struct net_device * dev){
980     
981     	struct awc_private * priv = (struct awc_private *)dev->priv;
982     	int status,i;
983          AWC_ENTRY_EXIT_DEBUG(" entry awc_read_all_rids ");
984                                        
985       	for (i=0; i< AWC_NOF_RIDS && priv->rid_dir[i].selector  ; i++){
986       		status = awc_readrid_dir(dev,&priv->rid_dir[i]);
987       		udelay(50);
988       		if (status) return status;
989       		                
990       	}
991       	priv->rids_read = 1;
992       	
993          AWC_ENTRY_EXIT_DEBUG(" exit \n"); 
994          return 0;
995     }
996     
997     int
998     awc_write_all_rids(struct net_device * dev){
999     
1000     	struct awc_private * priv = (struct awc_private *)dev->priv;
1001       	int i,status ;
1002          AWC_ENTRY_EXIT_DEBUG(" entry awc_write_all_rids ");
1003                                        
1004       	for (i=0;i < 5 &&  i< AWC_NOF_RIDS && priv->rid_dir[i].selector  ; i++){
1005       	     status = awc_writerid_dir(dev,&priv->rid_dir[i]);
1006       	     udelay(10);
1007       	     if(status) return status;
1008       	}
1009          AWC_ENTRY_EXIT_DEBUG(" exit \n"); 
1010          return 0;
1011     }
1012     
1013     /**************************	FID QUEUES ****************************/
1014     /****************************	TX  ALLOC / DEALLOC 	***************/
1015     
1016     
1017     
1018     int  awc_tx_alloc(struct net_device * dev) {
1019     
1020     	  struct awc_command cmd;
1021     	  int k=0;
1022     	  int tot=0;
1023     	 struct awc_fid * fid = NULL;
1024     	 
1025          AWC_ENTRY_EXIT_DEBUG(" entry awc_tx_alloc ");
1026          	  
1027     
1028               AWC_INIT_COMMAND(AWC_NOT_CLI,cmd,dev,0x0A,0, 0,0,0,NULL);
1029     	  cmd.par0 = dev->mtu + AWC_TX_HEAD_SIZE + 8 ;
1030     
1031     	  DEBUG(32,"about to allocate %x bytes ",cmd.priv->large_buff_mem);
1032     	  DEBUG(32,"in %x large buffers ",cmd.priv->large_buff_mem / (dev->mtu + AWC_TX_HEAD_SIZE + 8) );
1033     	  	
1034     	  k=0;tot=0;
1035     	  AWC_BAP_LOCK_NOT_CLI(cmd);
1036     
1037     	  while (k < cmd.priv->large_buff_mem / (dev->mtu + AWC_TX_HEAD_SIZE + 8) ) {
1038     	  	
1039     	  	fid = kmalloc(sizeof(struct awc_fid),GFP_KERNEL );
1040     	  	if (!fid)	goto final;
1041     		memset(fid, 0, sizeof(struct awc_fid));
1042     
1043     		if (awc_issue_command_and_block(&cmd))		goto final;
1044     		
1045               	while ( awc_event_status_Alloc(cmd.port) == 0) ;
1046     		fid->u.tx.fid 		= awc_Tx_Allocated_Fid(cmd.port);
1047     		fid->u.tx.fid_size 	= dev->mtu + AWC_TX_HEAD_SIZE ;
1048     		
1049     		DEBUG(32,"allocated large tx fid %x ",fid->u.tx.fid);
1050     		if(fid->u.tx.fid == 0
1051     		   || cmd.status != 0xA){
1052     			printk(KERN_ERR "%s bad tx_alloc\n",dev->name);
1053     			fid->busy =1;
1054     			goto final;
1055     		} else {
1056     			fid->busy =0;
1057     			tot++;
1058     		}
1059     		awc_event_ack_Alloc(cmd.port);
1060     		
1061     		// shoudlnt goto final after that
1062     		awc_fid_queue_push_tail(&cmd.priv->tx_large_ready,fid);
1063     				
1064     		k++;
1065     	  }
1066     	  cmd.priv->tx_buffs_total = tot;
1067     	  DEBUG(32,"allocated %d large tx buffs\n",tot);
1068     
1069     	  cmd.par0 = AWC_TX_ALLOC_SMALL_SIZE ;
1070     	  k =0; tot = 0;
1071     
1072     	  while (k < cmd.priv->small_buff_no) {
1073     	  	
1074     	  	fid = kmalloc(sizeof(struct awc_fid),GFP_KERNEL );
1075     	  	if (!fid)	goto final;
1076     		memset(fid, 0, sizeof(struct awc_fid));
1077     
1078     	  	cmd.par0 = AWC_TX_ALLOC_SMALL_SIZE ;
1079     
1080     		if (awc_issue_command_and_block(&cmd))		goto final;
1081     		
1082               	while ( awc_event_status_Alloc(cmd.port) == 0) ;
1083     		fid->u.tx.fid 		= awc_Tx_Allocated_Fid(cmd.port);
1084     		fid->u.tx.fid_size 	= AWC_TX_ALLOC_SMALL_SIZE;
1085     		
1086     		DEBUG(32,"allocated large tx fid %x ",fid->u.tx.fid);
1087     		if(fid->u.tx.fid == 0
1088     		   || cmd.status != 0xA){
1089     			printk(KERN_ERR "%s bad tx_alloc\n",dev->name);
1090     			fid->busy =1;
1091     			goto final;
1092     		} else {
1093     			fid->busy =0;
1094     			tot++;
1095     		}
1096     		awc_event_ack_Alloc(cmd.port);
1097     		
1098     		// shoudlnt goto final after that
1099     		awc_fid_queue_push_tail(&cmd.priv->tx_small_ready,fid);
1100     				
1101     		k++;
1102     	  }
1103     
1104     	  cmd.priv->tx_small_buffs_total = tot;
1105     	  DEBUG(32,"allocated %d small tx buffs\n",tot);
1106     
1107     	  AWC_RELEASE_COMMAND(cmd);
1108               AWC_ENTRY_EXIT_DEBUG(" exit \n"); 
1109      	  return 0;
1110     
1111          final:
1112          	  if (fid ) 
1113          	  	kfree(fid);
1114          	  printk(KERN_CRIT "%s awc tx prealloc failed \n",dev->name);
1115          	  AWC_RELEASE_COMMAND(cmd);
1116          	  AWC_ENTRY_EXIT_DEBUG("  BAD exit \n");
1117     	  return -1; ;
1118     
1119     };
1120     
1121     int 
1122     awc_tx_dealloc_fid(struct net_device * dev,struct awc_fid * fid){
1123     
1124     	  struct awc_command cmd;
1125     	  int fid_handle = 0;
1126     	  
1127               AWC_INIT_COMMAND(AWC_NOT_CLI,cmd,dev,0x0C,0, 0,0,0,NULL);
1128     
1129     	  AWC_BAP_LOCK_NOT_CLI(cmd);
1130     
1131     	  if (fid->u.tx.fid){
1132     	  		fid_handle = cmd.par0 = fid->u.tx.fid;
1133     	  		fid->u.tx.fid = 0;
1134     			fid->busy =0;
1135     	  		kfree(fid);
1136     
1137     			if (!cmd.priv->ejected)
1138     				if (awc_issue_command_and_block(&cmd))	goto final;
1139     						//awc_event_ack_Alloc(cmd.port);
1140     	  }
1141     
1142     	  AWC_RELEASE_COMMAND(cmd);
1143               AWC_ENTRY_EXIT_DEBUG(" exit \n"); 
1144      	  return 0;
1145     
1146          	  final:
1147          	  	printk(KERN_ERR "awc_tx_dealloc failed for fid %x \n",fid_handle);
1148          	  	AWC_RELEASE_COMMAND(cmd);
1149          	  	AWC_ENTRY_EXIT_DEBUG("  BAD exit \n");
1150     	  return -1; ;
1151     
1152     
1153     };
1154     
1155     int
1156     awc_tx_dealloc(struct net_device * dev){
1157     
1158      	struct awc_private * priv = (struct awc_private *)dev->priv;
1159     
1160     
1161     
1162     //	  int k=0;
1163     	  struct awc_fid * fid;
1164     	  
1165               AWC_ENTRY_EXIT_DEBUG(" entry awc_tx_dealloc ");
1166          
1167     	  while (NULL != (fid = awc_fid_queue_pop_head(&priv->tx_large_ready)))
1168     		awc_tx_dealloc_fid(dev,fid);
1169     	  while (NULL != (fid = awc_fid_queue_pop_head(&priv->tx_small_ready)))
1170     		awc_tx_dealloc_fid(dev,fid);
1171     	  while (NULL != (fid = awc_fid_queue_pop_head(&priv->tx_post_process)))
1172     		awc_tx_dealloc_fid(dev,fid);
1173     	  while (NULL != (fid = awc_fid_queue_pop_head(&priv->tx_in_transmit)))
1174     		awc_tx_dealloc_fid(dev,fid);
1175     	
1176     	  return 0;
1177     
1178     };
1179     
1180     
1181     
1182     inline struct awc_fid *
1183     awc_tx_fid_lookup_and_remove(struct net_device * dev, u16 fid_handle){
1184     
1185      	struct awc_private * priv = (struct awc_private *)dev->priv;
1186     //	int k = 0;
1187     	unsigned long flags;
1188     	struct awc_fid * fid = NULL;
1189     	int cnt=0;
1190     	
1191          AWC_ENTRY_EXIT_DEBUG(" entry awc_tx_fid_lookup ");
1192     
1193     	spin_lock_irqsave(&(priv->queues_lock),flags);
1194     
1195     
1196     	fid = priv->tx_in_transmit.head;
1197     	cnt = 0;
1198     	while (fid){
1199     	  	if (fid->u.tx.fid == fid_handle){
1200     	  		awc_fid_queue_remove(&priv->tx_in_transmit, fid);
1201     	  		spin_unlock_irqrestore(&(priv->queues_lock),flags);
1202     	  		return fid;
1203     	  	}
1204     	  	fid = fid->next;
1205     	//	printk("iT\n");
1206     		if (cnt++ > 200) {
1207     	//		printk("bbb in awc_fid_queue\n");
1208     			spin_unlock_irqrestore(&(priv->queues_lock),flags);
1209     	  		return 0;
1210     		};
1211     	};
1212     
1213     	cnt=0;
1214     	fid = priv->tx_post_process.head;
1215     	while (fid){
1216     	  	if (fid->u.tx.fid == fid_handle){
1217     	  		awc_fid_queue_remove(&priv->tx_post_process, fid);
1218     	  		spin_unlock_irqrestore(&(priv->queues_lock),flags);
1219     	  		return fid;
1220     	  	}
1221     	  	fid = fid->next;
1222     	//	printk("pp\n");
1223     		if (cnt++ > 200) {
1224     	//		printk("bbb in awc_fid_queue\n");
1225     			spin_unlock_irqrestore(&(priv->queues_lock),flags);
1226     	  		return 0;
1227     		};
1228     
1229     	};
1230     
1231     	cnt=0;
1232     	fid = priv->tx_large_ready.head;
1233     	while (fid){
1234     	  	if (fid->u.tx.fid == fid_handle){
1235     	  		awc_fid_queue_remove(&priv->tx_large_ready, fid);
1236     	  		spin_unlock_irqrestore(&(priv->queues_lock),flags);
1237     	  		return fid;
1238     	  	}
1239     	  	fid = fid->next;
1240     	//	printk("lr\n");
1241     		if (cnt++ > 200) {
1242     	//		printk("bbb in awc_fid_queue\n");
1243     			spin_unlock_irqrestore(&(priv->queues_lock),flags);
1244     	  		return 0;
1245     		};
1246     
1247     	};
1248     	cnt=0;
1249     	fid = priv->tx_small_ready.head;
1250     	while (fid){
1251     	  	if (fid->u.tx.fid == fid_handle){
1252     	  		awc_fid_queue_remove(&priv->tx_small_ready, fid);
1253     	  		spin_unlock_irqrestore(&(priv->queues_lock),flags);
1254     	  		return fid;
1255     	  	}
1256     	  	fid = fid->next;
1257     	//	printk("sr\n");
1258     		if (cnt++ > 200) {
1259     	//		printk("bbb in awc_fid_queue\n");
1260     			spin_unlock_irqrestore(&(priv->queues_lock),flags);
1261     	  		return 0;
1262     		};
1263     
1264     	};
1265     
1266     	spin_unlock_irqrestore(&(priv->queues_lock),flags);
1267     	
1268     	printk(KERN_ERR "%s tx fid %x not found \n",dev->name, fid_handle);  
1269             AWC_ENTRY_EXIT_DEBUG(" BAD exit \n");   	  
1270     	return NULL;
1271     }
1272     
1273     
1274     
1275     
1276     
1277     int 
1278     awc_queues_init(struct net_device * dev){
1279      	struct awc_private * priv = (struct awc_private *)dev->priv;
1280     	struct awc_fid * fid = NULL;
1281     	int retv =0;
1282     	int k = 0;
1283     
1284     	awc_fid_queue_init(&priv->tx_in_transmit);
1285     	awc_fid_queue_init(&priv->tx_post_process);
1286     	awc_fid_queue_init(&priv->tx_large_ready);
1287     	awc_fid_queue_init(&priv->tx_small_ready);
1288     	awc_fid_queue_init(&priv->rx_ready);
1289     	awc_fid_queue_init(&priv->rx_post_process);
1290     
1291     	retv = awc_tx_alloc(dev);
1292     
1293     	k = 0;
1294     	while (k < AWC_RX_BUFFS){
1295     		fid = kmalloc(sizeof(struct awc_fid),GFP_KERNEL);
1296     		if (!fid) return -1;
1297     		awc_fid_queue_push_tail(&priv->rx_ready,fid);
1298     		k++;
1299     	};
1300     
1301     	if (retv) return retv;
1302     
1303     	return 0;	
1304     };
1305     
1306     
1307     int 
1308     awc_queues_destroy(struct net_device * dev){
1309      	struct awc_private * priv = (struct awc_private *)dev->priv;
1310     	struct awc_fid * fid = NULL;
1311     	int retv =0;
1312     	
1313     
1314     
1315     	while (NULL != (fid = awc_fid_queue_pop_head(&priv->rx_ready))){
1316     		kfree(fid);
1317     	}
1318     	while (NULL != (fid = awc_fid_queue_pop_head(&priv->rx_post_process))){
1319     		kfree(fid);
1320     	}
1321     
1322     	retv = awc_tx_dealloc(dev);
1323     
1324     	return retv;	
1325     };
1326     
1327     
1328     
1329     /****************************** 	802.11router	******************/
1330     inline int 
1331     awc_802_11_copy_path_skb(struct net_device * dev, struct awc_fid * rx_buff){
1332     
1333     	struct awc_private * priv = (struct awc_private * )dev->priv;
1334     
1335     	AWC_ENTRY_EXIT_DEBUG("awc_802_11_copy_path_skb");
1336     
1337             if (rx_buff->pkt_len < 22 ) rx_buff->pkt_len = 22;
1338             
1339     //	if (!rx_buff->skb)
1340     		rx_buff->skb =  dev_alloc_skb(rx_buff->pkt_len + 12 +2);
1341     	
1342     	
1343     	if (rx_buff->skb == NULL) {
1344     		printk(KERN_CRIT "couldnt alloc rx_buff->skb in rx event \n");
1345     		priv->stats.rx_dropped++;
1346     		return -1;
1347     	}
1348     	rx_buff->type |= p80211copy_path_skb;
1349     	
1350     	rx_buff->skb->dev = dev;
1351     
1352     //	skb_reserve(rx_buff->skb, rx_buff->pkt_len + 12 );
1353     
1354     	rx_buff->u.rx.payload = skb_put(rx_buff->skb, rx_buff->pkt_len + 12 ) ;
1355     	rx_buff->u.rx.payload  = ((char *)rx_buff->u.rx.payload ) +12;
1356     
1357     	AWC_ENTRY_EXIT_DEBUG("exit\n");
1358     
1359     	return 0;
1360     
1361     
1362     };
1363     
1364     
1365     int
1366     awc_802_11_find_copy_path(struct net_device * dev, struct awc_fid * rx_buff){
1367     
1368     //        struct awc_private * priv = (struct awc_private * )dev->priv;
1369     //        u8 is_802_3 = 0;
1370     //	int i = 0;
1371     
1372     	rx_buff->type =0;
1373     
1374     	return awc_802_11_copy_path_skb(dev,rx_buff);
1375     };
1376     
1377     
1378     /* 	called from INTERRUPT context,
1379     
1380     	must deliver the packet to where it was meant by 
1381     		awc_802_11_find_copy_path
1382     	
1383     	SHOULD be efficient and
1384     	queue the packet if operations take longer
1385     
1386     */ 
1387     
1388     
1389     int parse_not_8023;
1390            
1391     void
1392     awc_802_11_router_rx(struct net_device * dev,struct awc_fid * rx_buff){
1393     
1394             struct awc_private * priv = (struct awc_private * )dev->priv;
1395     	struct sk_buff * skb = rx_buff->skb;
1396     	u8 * payload = rx_buff->u.rx.payload;
1397     //	u8 * p802_3_macs_place = payload -12;
1398     	u16    pkt_len = rx_buff->pkt_len;	
1399     	struct ieee_802_11_802_1H_header * bridge = NULL;
1400     	struct ieee_802_11_snap_header * snap = NULL;
1401     	struct ieee_802_11_802_1H_header * bridge_tmp;
1402     	struct ieee_802_11_snap_header * snap_tmp;
1403     
1404     	u16	ptr = 0;
1405     	u16	len;
1406     
1407     	AWC_ENTRY_EXIT_DEBUG("awc_802_11_router_rx");
1408     
1409     //	if (rx_buff->type & p80211_8023)
1410     		rx_buff->mac = rx_buff->u.rx.ieee_802_3.dst_mac;
1411     //	else	
1412     //		rx_buff->mac = rx_buff->u.rx.ieee_802_11.mac1;	
1413     
1414     	if ( rx_buff->u.rx.ieee_802_11.frame_control == 0x8 )	
1415     		memcpy(priv->bssid,rx_buff->u.rx.ieee_802_11.mac3,6);
1416     	
1417     	while ((ptr < pkt_len - 1 ) && payload && parse_not_8023){
1418     
1419     		bridge_tmp 	= (struct ieee_802_11_802_1H_header*) &payload[ptr];
1420     		snap_tmp 	= (struct ieee_802_11_snap_header*) &payload[ptr];
1421     		len		= ntohs( *((u16*)&payload[ptr]) );
1422     
1423     		
1424     
1425     		if (  len < 0x5DC)	{ // not a protocol
1426     			
1427     			if ( len != pkt_len-2 - ptr){
1428     				printk(KERN_ERR "%s bad encapsulation lenght %x at pkt offset %x \n",dev->name,len,ptr);
1429     				goto bad_packet;
1430     			}
1431     			DEBUG(1,"parisng packet of size %x\n",len);
1432     			ptr +=2;
1433     			continue;
1434     		}	
1435     		
1436     		DEBUG(1,"parisng packet of proto %x\n",len);
1437     		
1438     		if (snap_tmp->dsap == 0xaa &&  snap_tmp->ssap == 0xaa &&
1439     		    pkt_len - ptr > sizeof(struct ieee_802_11_snap_header) ){
1440     			
1441     			DEBUG(0x200,"%s SNAP ",dev->name);
1442     			if (snap_tmp->ctrl != 0x03){
1443     				printk(KERN_ERR "%s unknown snap ctrl %x \n",dev->name,snap_tmp->ctrl);
1444     				goto bad_packet;
1445     			};
1446     			if (snap_tmp->oui[0] == 0 && // LLC RFC1042
1447     			    snap_tmp->oui[1] == 0 &&
1448     			    snap_tmp->oui[2] == 0 ){
1449     			    	snap = 	snap_tmp;
1450     			    	ptr +=	sizeof(struct ieee_802_11_snap_header);
1451     			    	DEBUG(0x200,"%s LLC RFC1042 \n",dev->name);
1452     			    	continue;
1453     			}
1454     			if (snap_tmp->oui[0] == 0 && // LLC 802.1H
1455     			    snap_tmp->oui[1] == 0 &&
1456     			    snap_tmp->oui[2] == 0x78){
1457     			    	snap = snap_tmp;
1458     			    	DEBUG(0x200,"%s LLC 802.1H \n",dev->name);
1459     			    	ptr +=	sizeof(struct ieee_802_11_snap_header);
1460     			    	continue;  
1461     			};
1462     			if (snap_tmp->oui[0] == 0x00 && // 802.1H itself
1463     			    snap_tmp->oui[1] == 0x40 &&
1464     			    snap_tmp->oui[2] == 0x96){
1465     			    	ptr +=	sizeof(struct ieee_802_11_802_1H_header);
1466     			    	if (ptr >= pkt_len){
1467     			    		goto bad_packet;
1468     			    		DEBUG(1,"%s invalid packet len in 802.1H SNAP OUI check \n",dev->name);
1469     			    	}
1470     			    	DEBUG(0x200,"%s OUI 004096  \n",dev->name);
1471     			    	DEBUG(0x200," 802.1H uknown1 %x  ",ntohs(bridge_tmp->unknown1));
1472     			    	DEBUG(0x200," 802.1H uknw type %x  \n",0xf000 & ntohs(bridge_tmp->unknown2));
1473     			    	DEBUG(0x200," 802.1H payloadsize %x  \n",0x0fff & ntohs(bridge_tmp->unknown2));
1474     			    	
1475     			    	//goto bad_packet; // TODO
1476     			    	
1477     			    	bridge = bridge_tmp;
1478     			    	if (bridge_tmp->unknown1 == 0x0000 &&
1479     			    	     ((ntohs(bridge_tmp->unknown2) & 0xf000) == 0x1000 ) ){
1480     			    	     rx_buff->type |= p80211_8021H;
1481     			    	     rx_buff->mac   = &payload[ptr];
1482     			    	     DEBUG(0x200," 802.1H DATA packet of size %x\n",0xf000 & ntohs(bridge_tmp->unknown2) );
1483     			    	     memcpy(priv->p2p,rx_buff->u.rx.ieee_802_11.mac2, 6);
1484     			    	     ptr +=12;
1485     			    	     continue;
1486     			    	};
1487     			    	DEBUG(0x200,"%s droping unknown  004096 packet \n ",dev->name);
1488     			    	goto bad_packet;
1489     			    	
1490     			 
1491     			}
1492     			goto bad_packet;
1493     		}
1494     		if ( len > 0x5DC){ 
1495     			// packet without linklevel header for us
1496     		
1497     			if (  len == 0x8000 ||  len == 0x8006){
1498     			
1499     				DEBUG(0x200,"Non IP packet %x \n",ntohs(len));
1500     			
1501     			};
1502     			goto good_packet;
1503     		
1504     		};
1505     		
1506     		goto good_packet;
1507     	}
1508     	
1509        good_packet:
1510     
1511     	if (ptr > pkt_len)	goto bad_packet;
1512     
1513     	if ( rx_buff->mac != (payload + ptr -12) )
1514     		memcpy( payload +ptr -12, rx_buff->mac , 12);
1515     
1516     	
1517     	
1518     	if (!payload || !skb || !rx_buff->skb || !rx_buff->u.rx.payload)
1519     		return ;
1520     	//skb->ip_summed = CHECKSUM_NONE;
1521     	skb->data = payload + ptr -12;
1522     	skb->len += ptr ;
1523     	
1524     	rx_buff->skb->protocol = eth_type_trans(rx_buff->skb,dev);
1525     	DEBUG(0x200,"eth_type_trans decided: %x\n",rx_buff->skb->protocol);
1526     	rx_buff->skb = NULL;
1527     	rx_buff->u.rx.payload = NULL;
1528     	priv->stats.rx_packets++;
1529     	priv->stats.rx_bytes += skb->len;
1530     	
1531     	netif_rx(skb);
1532     	dev->last_rx = jiffies;
1533     	AWC_ENTRY_EXIT_DEBUG("exit\n");
1534     	return ;
1535     
1536        bad_packet:
1537        	DEBUG(0x200,"%s packet dropped in packet hdr parse \n ",dev->name);
1538     	if (rx_buff->skb && (rx_buff->type & p80211copy_path_skb)){
1539     
1540     		dev_kfree_skb_irq(rx_buff->skb);		
1541     		rx_buff->skb = NULL;
1542     		rx_buff->u.rx.payload = NULL;
1543     	};
1544     
1545     	AWC_ENTRY_EXIT_DEBUG("exit\n");	
1546     
1547     };
1548     
1549     void
1550     awc_802_11_failed_rx_copy(struct net_device * dev,struct awc_fid * rx_buff){
1551     	struct awc_private * priv = (struct awc_private * )dev->priv;
1552     
1553     
1554     	AWC_ENTRY_EXIT_DEBUG("awc_802_11_failed_rx_copy");
1555     	if (rx_buff->skb)
1556                     dev_kfree_skb_irq(rx_buff->skb);
1557             rx_buff->skb = NULL;
1558             rx_buff->u.rx.payload = NULL;
1559     	priv->stats.rx_errors++;
1560     
1561     
1562     	AWC_ENTRY_EXIT_DEBUG("exit\n");
1563     };
1564     
1565     /*
1566     	called from kernel->driver tx routine
1567     	must decide where and how to post the packet 
1568     	must post the packet to wherever it decides
1569     	either copy to card or enqueue to destination queue
1570     
1571     */
1572     
1573     
1574     int
1575     awc_802_11_tx_find_path_and_post(struct net_device * dev,
1576     				 struct sk_buff * skb){
1577     
1578     
1579     	struct awc_private * priv = (struct awc_private * )dev->priv;
1580     	int i;
1581     	int len = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN; /* check min length*/
1582     	struct awc_fid * fid = NULL;
1583     //	u16 saved_fid ;
1584     	u16 p2p_direct =priv->p2p_found;
1585     	struct iphdr * ip_hdr;
1586     	//buffer = skb->data;
1587     
1588     	AWC_ENTRY_EXIT_DEBUG("awc_802_11_tx_find_path_and_post");	
1589     
1590     	// netif_stop_queue(dev);
1591     	DOWN(&priv->tx_buff_semaphore);
1592     	if (len  > dev->mtu + 16 ) {
1593     		printk(KERN_ERR "%s packet size too large %d \n",dev->name, len);
1594     		goto final;
1595     	}
1596     
1597     	if (len + AWC_TX_HEAD_SIZE < AWC_TX_ALLOC_SMALL_SIZE  )
1598     		fid = awc_fid_queue_pop_head(&priv->tx_small_ready);
1599     
1600     	if (!fid)
1601     		fid = awc_fid_queue_pop_head(&priv->tx_large_ready);
1602     			
1603     	if (!fid) {
1604     		DEBUG(32,"%s buffs in use \n",dev->name);
1605     		goto no_space;
1606     	}		
1607     /*
1608     	if (fid->u.tx.fid_size < len + AWC_TX_HEAD_SIZE){
1609     		awc_fid_queue_push_tail(&priv->tx_small_ready, fid);
1610     		fid = awc_fid_queue_pop_head(&priv->tx_large_ready);
1611     	}
1612     */
1613     	if (!fid) {
1614     	       DEBUG(32,"%s buffs in use \n",dev->name);
1615     	       goto no_space;
1616     	}
1617     	
1618     	if (fid->u.tx.fid_size < len + AWC_TX_HEAD_SIZE - 14){	
1619     		printk(KERN_ERR "found too small tx fid size %d, pktlen %d \n",fid->u.tx.fid_size, len);
1620     	}
1621     	memset(&fid->u.tx.radio_tx,		0,sizeof(struct aironet4500_radio_tx_header));
1622     	memset(&fid->u.tx.ieee_802_11,	0,sizeof(struct ieee_802_11_header));
1623     	memset(&fid->u.tx.ieee_802_3,	0,sizeof(struct ieee_802_3_header));
1624     	fid->u.tx.payload =NULL;
1625     	fid->u.tx.gap_length =0;
1626     	fid->busy = 1;
1627     	
1628     	
1629     	priv->tx_buffs_in_use++;
1630     	DEBUG(32,"found large buff %x \n",fid->u.tx.fid);
1631     
1632     /*
1633     	fid->type |= p80211_llc_snap;
1634     	fid->snap.dsap = 0xaa; 
1635     	fid->snap.ssap = 0xaa; 
1636     	fid->snap.ctrl = 0x03;	
1637     	fid->snap.oui[0] = 0x0;
1638     	fid->snap.oui[1] = 0x0;
1639     	fid->snap.oui[2] = 0x0;
1640     */
1641     	fid->skb = skb;
1642     
1643     
1644     	if (priv->p2p_uc && !priv->p2p_found){ // we go without encapsulation to neighbour;
1645     	
1646     		for (i=0; i < 6; i++)
1647     			if (priv->p2p[i] != skb->data[i]){
1648     				p2p_direct = 1;
1649     				break;
1650     			}	
1651     	};
1652     
1653     	if (priv->force_tx_rate == 2 || priv->force_tx_rate == 4 || 
1654     		priv->force_tx_rate== 11 || priv->force_tx_rate == 22){
1655     			fid->u.tx.radio_tx.tx_bit_rate  = priv->force_tx_rate;
1656     	} else if (priv->force_tx_rate != 0 ) {
1657     		printk(KERN_ERR "wrong force_tx_rate=%d changed to default \n",	priv->force_tx_rate);
1658     		priv->force_tx_rate = 0;
1659     	};
1660     	fid->u.tx.radio_tx.TX_Control = 
1661     		aironet4500_tx_control_tx_ok_event_enable |
1662     		aironet4500_tx_control_tx_fail_event_enable |
1663     		aironet4500_tx_control_no_release;
1664     
1665     	if (len < priv->force_rts_on_shorter){
1666     		fid->u.tx.radio_tx.TX_Control |=
1667     			aironet4500_tx_control_use_rts;
1668     	};
1669     
1670     	ip_hdr = (struct iphdr * ) ((( char * ) skb->data) + 14);
1671     	if (ip_hdr && skb->data[12] == 0x80 ){
1672     		if (ip_hdr->tos & IPTOS_RELIABILITY && priv->ip_tos_reliability_rts)
1673     			fid->u.tx.radio_tx.TX_Control |=
1674     			    aironet4500_tx_control_use_rts;
1675     		if (ip_hdr->tos & IPTOS_THROUGHPUT && priv->ip_tos_troughput_no_retries)
1676     			fid->u.tx.radio_tx.TX_Control |=
1677     			    aironet4500_tx_control_no_retries;
1678     	};
1679     
1680     	if (priv->p802_11_send ||  memcmp(dev->dev_addr, skb->data +6, 6)  ){
1681     		fid->u.tx.radio_tx.TX_Control |=
1682     			aironet4500_tx_control_header_type_802_11;	
1683     		DEBUG(0x200,"%s bridging, forcing 802_11 send \n ",dev->name);
1684     	}
1685     
1686     
1687     	if (!priv->p2p_uc || p2p_direct) {
1688     		if ((fid->u.tx.radio_tx.TX_Control &
1689     		                 aironet4500_tx_control_header_type_802_11 )){
1690     
1691     			// including 802.3 header into 802.11 packet
1692     			fid->u.tx.radio_tx.PayloadLength 	= len -12;
1693     			fid->u.tx.ieee_802_3.payload_length = len -12 ;
1694     			fid->pkt_len = len -12;
1695     			fid->u.tx.payload = skb->data +12;
1696     
1697     			if (priv->simple_bridge){	
1698     				memcpy(fid->u.tx.ieee_802_11.mac1,skb->data,6);
1699     				memcpy(fid->u.tx.ieee_802_11.mac2,skb->data +6,6);
1700     				memcpy(fid->u.tx.ieee_802_11.mac3,priv->status.CurrentBssid ,6);
1701     				memset(fid->u.tx.ieee_802_11.mac4,0,6);
1702     				fid->u.tx.ieee_802_11.frame_control = 0x8;
1703     				fid->u.tx.ieee_802_11.gapLen=6;
1704     			} else {
1705     				memcpy(fid->u.tx.ieee_802_11.mac1,skb->data,6);
1706     				memcpy(fid->u.tx.ieee_802_11.mac2,dev->dev_addr,6);
1707     				memcpy(fid->u.tx.ieee_802_11.mac3,skb->data +6 ,6);
1708     				memset(fid->u.tx.ieee_802_11.mac4,0 ,6);
1709     				fid->u.tx.ieee_802_11.frame_control = 0x108;
1710     				fid->u.tx.ieee_802_11.gapLen=6;                 
1711     			}
1712     		} else { // plain old 802.3, with hdr copied
1713     			fid->u.tx.radio_tx.PayloadLength 	= len -12;
1714     			fid->u.tx.ieee_802_3.payload_length = len -12;
1715     			fid->pkt_len = len - 12;
1716     			fid->u.tx.payload = skb->data +12;
1717     		};	
1718     		memcpy(fid->u.tx.ieee_802_3.dst_mac,skb->data, 12);
1719     		DEBUG(0x200,"%s tx simply 802.3 type \n ",dev->name);		
1720     
1721     	} else {// 802.1H bridgeing
1722     		fid->type 		|= p80211_8021H;
1723     		fid->bridge_size 	= len + sizeof(fid->bridge) ;
1724     		fid->bridge.dsap 	= 0xaa;
1725     		fid->bridge.ssap 	= 0xaa;
1726     		fid->bridge.ctrl 	= 0x03;
1727     		fid->bridge.oui[0] = 0x0;
1728     		fid->bridge.oui[1] = 0x40;
1729     		fid->bridge.oui[2] = 0x96;
1730     		fid->bridge.unknown1= 0x0000;
1731     		fid->bridge.unknown2= htons((len) & 0x1000);
1732     		fid->u.tx.radio_tx.PayloadLength 	= fid->bridge_size + 2;
1733     		fid->u.tx.ieee_802_3.payload_length = fid->u.tx.radio_tx.PayloadLength ;
1734     		
1735     
1736     		fid->u.tx.payload = skb->data +12;
1737     		if ((fid->u.tx.radio_tx.TX_Control &
1738     		                 aironet4500_tx_control_header_type_802_11 )){
1739     	
1740     			memcpy(fid->u.tx.ieee_802_11.mac1,priv->p2p,6);
1741     			memcpy(fid->u.tx.ieee_802_11.mac2,skb->data +6,6);
1742     			memcpy(fid->u.tx.ieee_802_11.mac3,priv->bssid ,6);
1743     			memset(fid->u.tx.ieee_802_11.mac4,0,6);
1744     			fid->u.tx.ieee_802_11.gapLen=6;
1745     
1746     			fid->u.tx.ieee_802_11.frame_control = 0x8;                 
1747     		}		
1748     		memcpy(fid->u.tx.ieee_802_3.dst_mac,priv->p2p, 6);
1749     		memcpy(fid->u.tx.ieee_802_3.src_mac,dev->dev_addr, 6);
1750     		fid->u.tx.payload = skb->data + 2 + sizeof(fid->bridge);
1751     		fid->pkt_len = len ;
1752     	
1753     		DEBUG(0x200,"%s tx simply 802.1H type \n ",dev->name);
1754     		
1755     	};
1756     	
1757     	priv->stats.tx_bytes += fid->u.tx.ieee_802_3.payload_length;
1758     	priv->stats.tx_packets++;
1759     	
1760     	
1761     	awc_fid_queue_push_tail(&priv->tx_in_transmit,fid);
1762     	udelay(1);
1763     	awc_transmit_packet(dev,fid);
1764     	if (priv->tx_large_ready.size <= 2 || priv->tx_small_ready.size <= 2 ){
1765     		if (netif_running(dev))
1766     			netif_stop_queue(dev);
1767     	} else {
1768     	  	if (netif_running(dev)) 
1769     			netif_wake_queue(dev);
1770     	}
1771     	UP(&priv->tx_buff_semaphore);
1772     	AWC_ENTRY_EXIT_DEBUG("exit\n");
1773     	return 0;
1774     
1775     	
1776        no_space:
1777     	DEBUG(32,"%s tx buffs not found \n ",dev->name);
1778     	#ifdef AWC_DEBUG
1779     //		printk("s");
1780     	#endif
1781        	netif_stop_queue (dev); //weell, here it must be set anyway and before
1782        	//priv->stats.tx_fifo_errors++;
1783        	UP(&priv->tx_buff_semaphore);
1784     	AWC_ENTRY_EXIT_DEBUG("NoSpaceExit\n");
1785        	return 1 ;
1786       final:
1787     	priv->stats.tx_errors++;
1788     	UP(&priv->tx_buff_semaphore);
1789     	if (!netif_running(dev)) 
1790     		netif_start_queue(dev);
1791     	dev_kfree_skb(skb);
1792     	AWC_ENTRY_EXIT_DEBUG("BADExit\n");
1793     	return -1;
1794       
1795     };
1796     
1797     /*
1798     	called from low level driver->card tx copy routine  
1799     	probably wants to free skbuf if failed transmits won't be
1800     	resubmitted to another device (if more than one path)
1801     	or tried again (if tx buffer in card needs to be filled again)
1802     */  
1803       
1804       
1805     void
1806     awc_802_11_after_tx_packet_to_card_write(struct net_device * dev,
1807     					 struct awc_fid * tx_buff){
1808     
1809     
1810     	AWC_ENTRY_EXIT_DEBUG("awc_802_11_after_tx_packet_to_card_write");
1811     
1812     	if (!tx_buff){
1813     		DEBUG(1,"%s no damn tx_buff in awc_802_11_after_tx_packet_to_card_write \n",dev->name);
1814     	};
1815     
1816     	if(tx_buff->skb){
1817     		dev_kfree_skb(tx_buff->skb);
1818     		tx_buff->skb = NULL;
1819     	}
1820     
1821     	AWC_ENTRY_EXIT_DEBUG("exit\n");
1822     };
1823     
1824     /*
1825             called from low level driver->card tx copy routine
1826             probably wants to free skbuf if failed writes won't be
1827             resubmitted to another device (if more than one path) 
1828             or tried again (if tx buffer in card needs to be filled again)
1829     */
1830                             
1831     void
1832     awc_802_11_after_failed_tx_packet_to_card_write(struct net_device * dev,
1833                                              struct awc_fid * tx_buff){
1834             struct awc_private * priv = (struct awc_private *)dev->priv;
1835     
1836     
1837     	AWC_ENTRY_EXIT_DEBUG("awc_802_11_after_failed_tx_packet_to_card_write");
1838     
1839     	if (!tx_buff){
1840     		DEBUG(1,"%s no damn tx_buff in awc_802_11_after_failed_tx_packet_to_card_write \n",dev->name);
1841     	};
1842     
1843     	if(tx_buff->skb){
1844     		dev_kfree_skb(tx_buff->skb);
1845     		tx_buff->skb = NULL;
1846     		tx_buff->busy =0;
1847     		printk(KERN_ERR "%s packet to card write failed \n",dev->name);
1848     	}
1849     	
1850     	awc_fid_queue_remove(&priv->tx_in_transmit,tx_buff);
1851     	
1852     	if (tx_buff->u.tx.fid_size <= AWC_TX_ALLOC_SMALL_SIZE)
1853     		awc_fid_queue_push_tail(&priv->tx_small_ready,tx_buff);
1854     	else 
1855     		awc_fid_queue_push_tail(&priv->tx_large_ready,tx_buff);
1856     
1857     	AWC_ENTRY_EXIT_DEBUG("exit\n");
1858     
1859     };
1860                                              
1861     inline void 
1862     awc_802_11_after_tx_complete(struct net_device * dev, struct awc_fid * tx_buff){
1863     
1864             struct awc_private * priv = (struct awc_private *)dev->priv;
1865     
1866     	AWC_ENTRY_EXIT_DEBUG("awc_802_11_after_tx_complete");                
1867     
1868     	DEBUG(32,"tx complete status %x \n ",tx_buff->u.tx.radio_tx.Status);
1869     
1870     	#ifdef AWC_DEBUG
1871     	 if (tx_buff->u.tx.radio_tx.Status)
1872     	 	printk("tf%x ",tx_buff->u.tx.radio_tx.Status);
1873     	#endif
1874     	if (tx_buff->u.tx.fid_size <= AWC_TX_ALLOC_SMALL_SIZE){
1875     		awc_fid_queue_push_tail(&priv->tx_small_ready,tx_buff);
1876     		priv->tx_small_buffs_in_use--;
1877     	} else { 
1878     		awc_fid_queue_push_tail(&priv->tx_large_ready,tx_buff);
1879     		priv->tx_buffs_in_use--;
1880     	}
1881     
1882     	tx_buff->busy = 0;
1883     //	netif_wake_queue (dev);
1884     
1885     	AWC_ENTRY_EXIT_DEBUG("exit\n");
1886     };
1887     
1888                                                      
1889     
1890     
1891     /********************************	R X	***********************/
1892     
1893     
1894     
1895     inline int
1896     awc_receive_packet(struct net_device * dev){
1897     	
1898         struct awc_command cmd;
1899         u16	Fid;
1900     //    struct sk_buff *skb = NULL;
1901         struct awc_fid * rx_buff;
1902     
1903     
1904         struct awc_private * priv ;
1905     	int i;    
1906         
1907         	priv= (struct awc_private *)dev->priv;
1908           	rx_buff = priv->rx_ready.head        ;
1909     
1910          AWC_ENTRY_EXIT_DEBUG(" entry awc_receive_packet ");
1911          
1912     	Fid = awc_Rx_Fid(dev->base_addr);
1913     	
1914     	DEBUG(128," RX FID  %x	\n",Fid);
1915     
1916     	if (!Fid){
1917     		printk(KERN_CRIT "No RxFid when rx event \n");
1918     		return -1;
1919     	}
1920     
1921     
1922     	
1923     	if (!rx_buff){
1924     		printk(KERN_CRIT "No rx_buff in rx event \n");
1925     		return -1;
1926     	}
1927     
1928     	rx_buff->type   = 0;
1929     
1930     	                
1931     	AWC_INIT_COMMAND(AWC_CLI,cmd,dev,0,0,
1932     			Fid, 0, 0x14 , &(rx_buff->u.rx.radio_rx));
1933     
1934     
1935     // header reading , order is important
1936     	AWC_BAP_LOCK_UNDER_CLI(cmd);
1937     
1938     	if (awc_bap_setup(&cmd))		goto final;
1939     	if (awc_bap_read(&cmd))		goto final;
1940     
1941     	DEBUG(128, "rx receive radio header, length %x \n",rx_buff->u.rx.radio_rx.PayloadLength);
1942     
1943     	cmd.buff 	= &(rx_buff->u.rx.ieee_802_11);
1944     	cmd.len		= 0x20;
1945     
1946     	if (awc_bap_read(&cmd))		goto final;
1947     
1948     	DEBUG(128, "rx receive 802_11 header, framecontrol %x \n",rx_buff->u.rx.ieee_802_11.frame_control);
1949     
1950     	if (rx_buff->u.rx.ieee_802_11.gapLen > 8) {
1951     		printk(KERN_ERR "%s: 802.11 gap lenght huge %d \n",dev->name,rx_buff->u.rx.ieee_802_11.gapLen);
1952     		goto final;
1953     	}
1954     	DEBUG(128,"SeqCtl %x, 802_11 macs: ",rx_buff->u.rx.ieee_802_11.SeqCtl);
1955     	if (awc_debug & 0x7000){
1956     		DEBUG(0x7000, " %s mac1 ",dev->name); for (i = 0; i < 6; i++) DEBUG(0x7000, "%02x:",((unsigned char)rx_buff->u.rx.ieee_802_11.mac1[i] )) ;
1957     		DEBUG(0x7000, " %s mac2 ",dev->name); for (i = 0; i < 6; i++) DEBUG(0x7000, "%02x:",((unsigned char)rx_buff->u.rx.ieee_802_11.mac2[i] )) ;
1958     		DEBUG(0x7000, " %s mac3 ",dev->name); for (i = 0; i < 6; i++) DEBUG(0x7000, "%02x:",((unsigned char)rx_buff->u.rx.ieee_802_11.mac3[i] )) ;
1959     		DEBUG(0x7000, " %s mac4 ",dev->name); for (i = 0; i < 6; i++) DEBUG(0x7000, "%02x:",((unsigned char)rx_buff->u.rx.ieee_802_11.mac4[i] )) ;
1960     	}	
1961     	DEBUG(128,"\n GapLen %d ",rx_buff->u.rx.ieee_802_11.gapLen );
1962     	
1963     	if (rx_buff->u.rx.ieee_802_11.gapLen > 0) {
1964     		cmd.buff     = rx_buff->u.rx.ieee_802_11.gap;
1965     		cmd.len      = rx_buff->u.rx.ieee_802_11.gapLen;
1966     		if (awc_bap_read(&cmd))	     goto final;
1967     		DEBUG(128, "rx receive gap header , gap length %x \n",rx_buff->u.rx.gap_length);
1968     	}
1969     	for (i = 0; i < rx_buff->u.rx.ieee_802_11.gapLen ; i++) DEBUG(128,"%x",((unsigned char)rx_buff->u.rx.ieee_802_11.gap[i] )) ;
1970     
1971             
1972     	if ( !(priv->config.ReceiveMode & RXMODE_DISABLE_802_3_HEADER ) 
1973     	     ){
1974     		cmd.buff     	 = &(rx_buff->u.rx.ieee_802_3);
1975     		cmd.len      	 = 0x10;
1976     		rx_buff->type 	|= p80211_8023;
1977     		if (awc_bap_read(&cmd))				goto final;
1978     		DEBUG(128, "rx receive 802_3 header, payload length %x \n",rx_buff->u.rx.ieee_802_3.payload_length);
1979             	DEBUG(128,"\n 802_3 status %x ",rx_buff->u.rx.ieee_802_3.status );
1980     		DEBUG(128," RX payloadLen %x, dst,src: ",rx_buff->u.rx.ieee_802_3.payload_length);
1981     		if (awc_debug & 0x7000){
1982     			for (i = 0; i < 6; i++) printk("%02x:",((unsigned char)rx_buff->u.rx.ieee_802_3.dst_mac[i] )) ;
1983     			for (i = 0; i < 6; i++) printk("%02x:",((unsigned char)rx_buff->u.rx.ieee_802_3.src_mac[i] )) ;
1984     		}
1985     	};
1986     
1987     	rx_buff->pkt_len = rx_buff->u.rx.radio_rx.PayloadLength;
1988     	
1989     	if (priv->config.OperatingMode & MODE_LLC_HOST)
1990     		rx_buff->type   |= p80211_llc_snap;
1991     
1992     	
1993     	if (awc_802_11_find_copy_path(dev,rx_buff))		goto final;
1994     
1995     
1996     	if (rx_buff->u.rx.payload ){	
1997     		cmd.buff = rx_buff->u.rx.payload;
1998     		cmd.len	 = rx_buff->pkt_len;
1999     		if (awc_bap_read(&cmd))				goto final;
2000     		DEBUG(128, "rx payload read %x \n",rx_buff->u.rx.ieee_802_3.payload_length);
2001     	};
2002     	
2003     	AWC_RELEASE_COMMAND(cmd);
2004     
2005             DEBUG(128,"\n payload hdr %x ",rx_buff->u.rx.ieee_802_3.status );
2006             if (awc_debug && rx_buff->u.rx.payload)
2007     		for (i = 0; i < 20; i++) DEBUG(128,"%x",((unsigned char)rx_buff->u.rx.payload[i] )) ;
2008     	DEBUG(128,"%c",'\n');
2009     
2010     	awc_802_11_router_rx(dev,rx_buff);
2011     
2012     	AWC_ENTRY_EXIT_DEBUG(" exit \n"); 
2013      	return 0;
2014          final:
2015          
2016             awc_802_11_failed_rx_copy(dev,rx_buff);
2017          	// if (skb) dev_kfree_skb(skb, FREE_WRITE);
2018          	AWC_RELEASE_COMMAND(cmd);
2019          	AWC_ENTRY_EXIT_DEBUG("  BAD exit \n");
2020     	return -1; ;
2021          	
2022     };
2023     
2024     
2025     int
2026     awc_transmit_packet(struct net_device * dev, struct awc_fid * tx_buff) {
2027     	
2028     	struct awc_command cmd;
2029     	u16 size ;
2030     //	unsigned long flags;
2031     	int i;
2032         struct awc_private * priv= (struct awc_private *)dev->priv;
2033     
2034          AWC_ENTRY_EXIT_DEBUG(" entry awc_transmit_packet ");
2035          
2036     	if (priv->link_status_changed ){
2037     		priv->link_status_changed =0;
2038       		awc_readrid_dir(dev,&priv->rid_dir[7]);
2039     	}
2040     	
2041     
2042             AWC_INIT_COMMAND(AWC_NOT_CLI,cmd,dev,0xB, tx_buff->u.tx.fid,
2043               	tx_buff->u.tx.fid, 0, 0x14 , &(tx_buff->u.tx.radio_tx));
2044     	
2045     	AWC_BAP_LOCK_NOT_CLI(cmd);
2046     
2047     #ifdef AWC_BY_BOOK
2048     #warning  By books is bad, AWC_BY_BOOK  
2049     #error cli sti bad here
2050     	if (    !(tx_buff->type &(p80211_llc_snap|p80211_8021H) ) 
2051     	     && !(tx_buff->u.tx.radio_tx.TX_Control &
2052     	                   aironet4500_tx_control_header_type_802_11 )){
2053     	
2054     		cmd.buff=&(tx_buff->u.tx.radio_tx.TX_Control);
2055     		cmd.len = 0x2 ;
2056             	cmd.offset = 0x8;
2057             	save_flags(flags);
2058             	cli();
2059             	if (awc_bap_setup(&cmd))		goto final;        
2060             	if (awc_bap_write(&cmd))		goto final;
2061     
2062     		cmd.buff=&(tx_buff->u.tx.ieee_802_3.payload_length);
2063     		cmd.len = 14;
2064             	cmd.offset = 0x36;
2065             	if (awc_bap_setup(&cmd))		goto final;        
2066          		if (awc_bap_write(&cmd))		goto final;
2067          		restore_flags(flags);
2068     
2069     	} else {
2070     #endif
2071     			
2072             	if (awc_bap_setup(&cmd))		goto final;        
2073             	if (awc_bap_write(&cmd))		goto final;
2074             
2075             	DEBUG(64," wrote radio tx header for fid %x \n",tx_buff->u.tx.fid);
2076     
2077     		// 802.11
2078             	cmd.buff=&(tx_buff->u.tx.ieee_802_11);
2079             	cmd.len = 0x20;
2080             	if (awc_bap_write(&cmd))                goto final;
2081     
2082     		// Gap
2083     		if (tx_buff->u.tx.ieee_802_11.gapLen) {
2084             		cmd.buff=&(tx_buff->u.tx.ieee_802_11.gap);
2085             		cmd.len = tx_buff->u.tx.ieee_802_11.gapLen;
2086             		if (awc_bap_write(&cmd))	goto final;
2087             	}
2088     	        // 802.3
2089     	        if ( !	(tx_buff->u.tx.radio_tx.TX_Control & 
2090     	      	 	aironet4500_tx_control_header_type_802_11 )){
2091     	       		 
2092            			cmd.buff=&(tx_buff->u.tx.ieee_802_3);
2093     			if (awc_debug & 0x7000){
2094     				printk("%s TX dst ",dev->name);
2095     				for (i=0; i < 6; i++) printk ("%02x:",(unsigned char) tx_buff->u.tx.ieee_802_3.dst_mac[i]);
2096     				printk(" src ");
2097     				for (i=0; i < 6; i++) printk ("%02x:",(unsigned char) tx_buff->u.tx.ieee_802_3.src_mac[i]);
2098     				printk(" \n ");
2099     			}
2100            			cmd.len = 0x10; 
2101            			if (awc_bap_write(&cmd))	goto final;
2102            		};
2103            	 	
2104            		if (tx_buff->type & p80211_llc_snap) {
2105            			cmd.buff=	& tx_buff->snap;
2106            			cmd.len =	sizeof(tx_buff->snap);
2107            			if (awc_bap_write(&cmd))		goto final;
2108             	};
2109     	 
2110     	  	if (tx_buff->type & p80211_8021H) {
2111            	 		size = htons(tx_buff->bridge_size);  
2112             	//	size = tx_buff->bridge_size;// to seasure raw speed of f** UC  
2113            			cmd.buff=	& size;
2114            			cmd.len =	2 ;
2115             		if (awc_bap_write(&cmd))                goto final;
2116             		
2117            			cmd.buff=	& tx_buff->bridge;
2118            			cmd.len =	sizeof(tx_buff->bridge);
2119            			if (awc_bap_write(&cmd))		goto final;
2120             	};
2121     	       	 
2122     #ifdef AWC_BY_BOOK	       	 
2123     	       	 
2124     	}
2125     #endif
2126            	cmd.buff=	tx_buff->u.tx.payload;
2127            	cmd.len =	tx_buff->pkt_len;
2128     
2129            	if (awc_bap_write(&cmd))			goto final;
2130     	AWC_RELEASE_COMMAND(cmd);
2131     // locking probs,  these two lines below and above, swithc order 
2132     	if (awc_issue_command_and_block(&cmd))		goto final_unlocked;      
2133     
2134     
2135     	tx_buff->transmit_start_time = jiffies;
2136     	awc_802_11_after_tx_packet_to_card_write(dev,tx_buff);         		
2137                // issue the transmit command
2138     
2139     
2140             AWC_ENTRY_EXIT_DEBUG(" exit \n"); 
2141     	return 0;
2142          final:
2143     	awc_802_11_after_failed_tx_packet_to_card_write(dev,tx_buff);     	        
2144          	printk(KERN_CRIT "%s awc tx command failed \n",dev->name);
2145          	AWC_RELEASE_COMMAND(cmd);
2146          	AWC_ENTRY_EXIT_DEBUG("  BAD exit \n");
2147     	return -1; ;
2148     
2149          final_unlocked:
2150     	awc_802_11_after_failed_tx_packet_to_card_write(dev,tx_buff);     	        
2151          	printk(KERN_CRIT "%s awc tx command failed \n",dev->name);
2152          	AWC_ENTRY_EXIT_DEBUG("  BAD exit \n");
2153     	return -1; ;
2154     
2155     }
2156     
2157     
2158     inline int
2159     awc_tx_complete_check(struct net_device * dev){
2160     
2161     	struct awc_fid	* fid;
2162     	struct awc_command cmd;
2163     
2164     
2165          AWC_ENTRY_EXIT_DEBUG(" entry awc_tx_complete_check ");
2166          
2167     		
2168     
2169     	fid = awc_fid_queue_pop_head(&((struct awc_private *)dev->priv)->tx_post_process);
2170     	
2171     	if (!fid) {
2172     		printk("awc_tx_complete_check with empty queue \n ");
2173     		return -1;
2174     	}
2175     
2176     	DEBUG(64," tx_complete fid %x \n",fid->u.tx.fid);
2177     	
2178             AWC_INIT_COMMAND(AWC_NOT_CLI,cmd,dev,0,0, fid->u.tx.fid,
2179               			0, 0x14 , &(fid->u.tx.radio_tx));
2180     
2181     	fid->state  |= awc_tx_fid_complete_read;
2182     
2183     	AWC_BAP_LOCK_NOT_CLI(cmd);
2184             if (awc_bap_setup(&cmd))		goto final;
2185             if (awc_bap_read(&cmd))			goto final;
2186     	AWC_RELEASE_COMMAND(cmd);
2187             
2188     	awc_802_11_after_tx_complete(dev,fid);         		
2189     
2190     	
2191             AWC_ENTRY_EXIT_DEBUG(" exit \n"); 
2192      	return 0;
2193             
2194          final:
2195             awc_802_11_after_tx_complete(dev,fid);
2196             printk(KERN_ERR "%s awc_tx_complete_check failed \n",dev->name);
2197          	AWC_RELEASE_COMMAND(cmd);
2198          	AWC_ENTRY_EXIT_DEBUG("  BAD exit \n");
2199     	return -1; ;
2200     }
2201     
2202     
2203     #define AWC_QUEUE_BH {\
2204     	if (!priv->bh_active && !priv->bh_running){\
2205     		priv->bh_active = 1;\
2206     		queue_task(&priv->immediate_bh, &tq_immediate);\
2207     		mark_bh(IMMEDIATE_BH);\
2208     	}\
2209     	}
2210     
2211     
2212     void
2213     awc_bh(struct net_device *dev){
2214     
2215             struct awc_private * priv = (struct awc_private *)dev->priv;
2216           	int  active_interrupts;
2217     	int enabled_interrupts;
2218     //	u16	tx_status;
2219     	int 	multi_ints = 0;
2220     //	u16	tx_fid = 0;
2221     //	unsigned long flags;
2222     
2223     	DEBUG(8, "awc_bh awoken on jiffie %ld \n",jiffies);
2224     
2225     	priv->bh_running = 1;
2226     	
2227     	active_interrupts = awc_event_status(dev->base_addr);
2228     	
2229             enabled_interrupts = awc_ints_enabled(dev->base_addr);
2230     
2231     	DEBUG(8, "awc_bh active ints %x \n",active_interrupts);
2232     
2233             if (test_and_set_bit( 0, (void *) &priv->tx_chain_active) ) {
2234     //		printk(KERN_ERR "tx chain active in bh \n");
2235     //		queue_task(&priv->immediate_bh, &tq_immediate);
2236     		goto bad_end;
2237     	}
2238     start:
2239     	if (active_interrupts == 0xffff){
2240     	
2241     		printk(KERN_CRIT "%s device ejected in interrupt, disabling\n",dev->name);
2242     		netif_device_detach (dev);
2243     		if (priv->command_semaphore_on){
2244     			priv->command_semaphore_on--;
2245     			AWC_UNLOCK_COMMAND_ISSUING(priv);
2246     		}
2247     		priv->tx_chain_active =0;
2248     		goto bad_end;
2249     		    
2250     	}
2251     
2252     	if (priv->unlock_command_postponed ){
2253     	
2254     	   priv->unlock_command_postponed-- ;
2255     	   if( priv->command_semaphore_on ){
2256     		
2257          		awc_read_response((&priv->cmd));
2258          		priv->async_command_start = 0;
2259          		if (priv->command_semaphore_on){
2260          		
2261          			priv->command_semaphore_on--;
2262     		        AWC_UNLOCK_COMMAND_ISSUING(priv);
2263     		}
2264          	    }
2265          	};
2266     
2267     /*        if ( active_interrupts & 0x1 ){
2268     	       		awc_receive_packet(dev) ;
2269     			awc_event_ack_Rx(dev->base_addr);
2270     			priv->waiting_interrupts &= ~0x1;
2271     	}
2272     */
2273     	while (priv->tx_post_process.size)
2274     		if (awc_tx_complete_check(dev)) break;
2275     	
2276     	active_interrupts = awc_event_status(dev->base_addr);
2277     
2278     	if (priv->command_semaphore_on || priv->tx_post_process.size){
2279     			if (multi_ints++ < 10000){
2280     				goto start;
2281     			}
2282     		};
2283     		priv->bh_active  = 0;
2284     		priv->bh_running = 0;
2285     
2286             priv->tx_chain_active = 0;
2287     
2288       	
2289     
2290       bad_end:
2291     //	if (!priv->tx_chain_active) 
2292     //		wake_up(&priv->tx_chain_wait_queue);
2293       
2294       	priv->bh_running = 0;
2295     	priv->bh_active = 0;
2296     	return ;
2297     };
2298     
2299     
2300     inline int
2301     awc_interrupt_process(struct net_device * dev){
2302     
2303     	struct awc_private * priv ;
2304           	int  active_interrupts;
2305     	int enabled_interrupts;
2306     	u16	tx_status;
2307     	int 	multi_ints = 0;
2308     	u16	tx_fid = 0;
2309     //	u16	ints_to_ack =0;
2310     	struct awc_fid	* fid = NULL;
2311     //	int interrupt_reenter = 0;
2312     //	unsigned long flags;	
2313     
2314     //	save_flags(flags);
2315     //	cli();
2316     	// here we need it, because on 2.3 SMP there are truly parallel irqs 	
2317     	disable_irq(dev->irq);
2318     
2319     	DEBUG(2," entering interrupt handler %s ",dev->name);
2320     
2321     	if (!dev) {
2322     		printk(KERN_ERR "No dev in interrupt   \n");
2323     		goto bad_end;
2324     	};
2325     
2326     	priv = (struct awc_private *)dev->priv;
2327     
2328     	if (!priv) {
2329     		printk(KERN_ERR "No PRIV in interrupt \n");
2330     		goto bad_end;
2331     	};
2332     
2333     
2334             enabled_interrupts = awc_ints_enabled(dev->base_addr);
2335     	active_interrupts = awc_event_status(dev->base_addr);
2336     
2337     	DEBUG(2,"entry: processing interrupts waiting %x \n",priv->waiting_interrupts);
2338     	DEBUG(2,"entry: processing interrupts active  %x \n",active_interrupts);
2339     	DEBUG(2,"entry: processing interrupts enabled %x \n",enabled_interrupts);
2340     //	printk("ikka interruptis\n");
2341     
2342     
2343     	priv->interrupt_count++;
2344     	if (priv->interrupt_count > 1 )
2345     		printk(" interrupt count on\n ");
2346     
2347     
2348     
2349     	if (priv->waiting_interrupts & active_interrupts)
2350     		printk(KERN_ERR "double interrupt waiting %x active %x \n",
2351     				priv->waiting_interrupts, active_interrupts);
2352     
2353      //       priv->waiting_interrupts |= active_interrupts;
2354     
2355     
2356     
2357     
2358     
2359     start:
2360     	DEBUG(2,"Start processing int, times %d\n",multi_ints);
2361     	
2362     	if (active_interrupts == 0xffff){
2363     	
2364     		printk(KERN_CRIT "%s device ejected, got interrupt, disabling\n",dev->name);
2365     		//priv->
2366     		netif_device_detach (dev);
2367     		priv->ejected = 1;
2368     		if (priv->bh_active || priv->bh_running){
2369     			priv->interrupt_count--;
2370     			goto bad_end;
2371     		} else if (priv->command_semaphore_on){
2372     			
2373     			printk(KERN_ERR "ejected, last BH fired \n");
2374     			
2375     			 AWC_QUEUE_BH;    
2376     		}
2377     		priv->interrupt_count--;
2378     		goto bad_end;
2379     	}
2380     
2381     	
2382     
2383     	if (active_interrupts & 0x100 ){
2384     		awc_event_ack_Awaken(dev->base_addr);
2385     		udelay(10);
2386     		DEBUG(1,"%s device awoke \n",dev->name);
2387     		priv->waiting_interrupts &= ~0x100;
2388     	};
2389     	if (active_interrupts & 0x80 ){
2390     	
2391     		priv->link_status = awc_Link_Status(dev->base_addr);
2392     		DEBUG(1,"link status changed %x \n",priv->link_status);
2393     		awc_event_ack_Link(dev->base_addr);
2394     		priv->waiting_interrupts &= ~0x80;
2395     	  	if(priv->link_status == 0x400)
2396     	  				printk(KERN_INFO "%s Associated\n",dev->name );
2397     	  	else { 
2398     	  		printk(KERN_INFO "%s Link status change : %s \n",dev->name, awc_print_string(awc_link_status_names, priv->link_status) );
2399     	  		if (	priv->link_status & 0x8100  ||
2400     	  			priv->link_status & 0x0100  ||
2401     	  			priv->link_status & 0x8200  ||
2402     	  			priv->link_status & 0x8400  ||
2403     	  			priv->link_status & 0x0300  )
2404     	  		printk(KERN_INFO "%s Link status change reason : %s \n",dev->name, awc_print_string(awc_link_failure_reason_names, priv->link_status & 0xff) );
2405     	  			
2406     	  	}
2407     	};
2408     
2409     
2410     	if (active_interrupts & 0x10 & enabled_interrupts ){
2411     
2412     //		printk(KERN_ERR "cmd int shouldnt be active in interrupt routine\n");
2413     
2414          		awc_event_ack_Cmd(priv->cmd.port);
2415          
2416          		if ( priv->enabled_interrupts & 0x10) 
2417          			priv->enabled_interrupts &= ~0x10;
2418     	     	
2419     	     	enabled_interrupts = awc_ints_enabled(dev->base_addr);
2420     
2421     		if (enabled_interrupts & 0x10){
2422     			awc_ints_enable(dev->base_addr, enabled_interrupts & ~0x10);
2423      	    	}
2424     
2425          		if (priv->command_semaphore_on){
2426          			priv->unlock_command_postponed++;
2427     
2428     			AWC_QUEUE_BH;
2429     		}
2430     	}
2431     	
2432     	if ((active_interrupts & 0x10) && !(0x10 & enabled_interrupts) ){
2433     
2434     //		printk(KERN_ERR "%s: aironet4500: cmd int shouldnt be active in interrupt routine\n",dev->name);
2435     
2436          		//awc_event_ack_Cmd(priv->cmd.port);
2437     	}     
2438     
2439     
2440     //	active_interrupts = awc_event_status(dev->base_addr);
2441     
2442     	tx_status = active_interrupts & 0x6 ;
2443     	
2444     
2445     
2446     	if (tx_status) {
2447     
2448     		tx_fid = awc_Tx_Compl_Fid(dev->base_addr);
2449     		if (!tx_fid){
2450     			udelay(10);
2451     			tx_fid = awc_Tx_Compl_Fid(dev->base_addr);
2452     		}
2453     		if (!tx_fid)
2454     			printk(KERN_ERR "No tx fid when tx int active\n");
2455     			
2456     		fid = awc_tx_fid_lookup_and_remove(dev, tx_fid);
2457     
2458     		if (fid) {
2459     			if (priv->process_tx_results) {
2460     				awc_fid_queue_push_tail(&priv->tx_post_process,fid);
2461     				AWC_QUEUE_BH;
2462     			}else {
2463     				if (fid->u.tx.fid_size <= AWC_TX_ALLOC_SMALL_SIZE)
2464         					awc_fid_queue_push_tail(&priv->tx_small_ready,fid);
2465               			else
2466           					awc_fid_queue_push_tail(&priv->tx_large_ready,fid);
2467     				netif_wake_queue (dev);
2468     			}
2469     		} else 
2470     			printk(KERN_ERR "awc fid %x not found\n",tx_fid);
2471     		
2472     
2473     		if (tx_status & 2){
2474     			awc_event_ack_Tx(dev->base_addr);
2475     			priv->stats.tx_packets++;
2476     			priv->waiting_interrupts  &= ~0x2;
2477     		}
2478     		if (tx_status & 4){
2479     			priv->stats.tx_errors++;
2480     			awc_event_ack_TxExc(dev->base_addr);
2481     			priv->waiting_interrupts  &= ~0x4;
2482     		}
2483     		if ((tx_status&6) == 6)
2484     			printk(KERN_NOTICE "%s: both tx and txExc up\n",dev->name);
2485     
2486     
2487     	}
2488     
2489     //	active_interrupts = awc_event_status(dev->base_addr);
2490     
2491             if ( active_interrupts & 0x1 ){
2492     	       		awc_receive_packet(dev);
2493     			awc_event_ack_Rx(dev->base_addr);
2494     			priv->waiting_interrupts &= ~0x1;
2495     	}
2496     
2497     	active_interrupts = awc_event_status(dev->base_addr);
2498     
2499     	if ((active_interrupts & 0x7) && 
2500     	     !priv->bh_active && 
2501     	     !priv->bh_running ){
2502     		if (multi_ints++ < 5)
2503     			goto start;
2504             }
2505     	if (multi_ints >=5 )
2506     		printk(KERN_ERR "%s multi_ints > 5 interrupts still active %x\n",dev->name,active_interrupts); 
2507     
2508      
2509     	priv->interrupt_count--;
2510     
2511     	awc_ints_enable(dev->base_addr, 0x0000);
2512     
2513     
2514     	DEBUG(0x8, " enabling ints in interrupt_process %x \n",
2515     		priv->enabled_interrupts & ~priv->waiting_interrupts);
2516      
2517     
2518     
2519             AWC_ENTRY_EXIT_DEBUG(" exit \n"); 
2520     
2521      	awc_ints_enable(dev->base_addr, 
2522      		priv->enabled_interrupts);
2523     
2524     //end_here:
2525     
2526     	enable_irq(dev->irq);
2527     //  	restore_flags(flags);
2528     
2529             return 0;
2530     
2531     bad_end:
2532             AWC_ENTRY_EXIT_DEBUG(" bad_end exit \n"); 	
2533     	enable_irq(dev->irq);
2534     //	restore_flags(flags);
2535     	return -1;
2536     
2537     
2538     };
2539     
2540     static const char *aironet4500_core_version =
2541     "aironet4500.c v0.1 1/1/99 Elmer Joandi, elmer@ylenurme.ee.\n";
2542     
2543     struct net_device * aironet4500_devices[MAX_AWCS];
2544     
2545     int awc_debug; //  0xffffff;
2546     static int p802_11_send; // 1
2547     
2548     static int awc_process_tx_results;
2549     int tx_queue_len = 10;
2550     int tx_rate;
2551     int channel = 5;
2552     //static int tx_full_rate;
2553     int max_mtu = 2312;
2554     int adhoc;
2555     int large_buff_mem = 1700 * 10;
2556     int small_buff_no	= 20;
2557     int awc_full_stats;
2558     char SSID[33];
2559     int master;
2560     int slave;
2561     int awc_simple_bridge;
2562     // int debug =0;
2563     
2564     #if LINUX_VERSION_CODE >= 0x20100
2565     
2566     MODULE_PARM(awc_debug,"i");
2567     MODULE_PARM(tx_rate,"i");
2568     MODULE_PARM(channel,"i");
2569     //MODULE_PARM(tx_full_rate,"i");
2570     MODULE_PARM(adhoc,"i");
2571     MODULE_PARM(master,"i");
2572     MODULE_PARM(slave,"i");
2573     MODULE_PARM(awc_simple_bridge,"i");
2574     MODULE_PARM(max_mtu,"i");
2575     MODULE_PARM(large_buff_mem,"i");
2576     MODULE_PARM(small_buff_no,"i");
2577     MODULE_PARM(SSID,"c33");
2578     MODULE_PARM_DESC(awc_debug,"Aironet debug mask");
2579     MODULE_PARM_DESC(channel,"Aironet ");
2580     MODULE_PARM_DESC(adhoc,"Aironet Access Points not available (0-1)");
2581     MODULE_PARM_DESC(master,"Aironet is Adhoc master (creates network sync) (0-1)");
2582     MODULE_PARM_DESC(slave,"Aironet is Adhoc slave (0-1)");
2583     MODULE_PARM_DESC(max_mtu,"Aironet MTU limit (256-2312)");
2584     #endif
2585     
2586     /*EXPORT_SYMBOL(tx_queue_len);
2587     EXPORT_SYMBOL(awc_debug);
2588      */
2589     EXPORT_SYMBOL(awc_init);
2590     EXPORT_SYMBOL(awc_open);
2591     EXPORT_SYMBOL(awc_close);
2592     EXPORT_SYMBOL(awc_reset);
2593     EXPORT_SYMBOL(awc_config);
2594     
2595     EXPORT_SYMBOL(aironet4500_devices);
2596     EXPORT_SYMBOL(awc_debug);
2597     //EXPORT_SYMBOL();
2598     
2599     EXPORT_SYMBOL(awc_private_init);
2600     EXPORT_SYMBOL(awc_tx_timeout);
2601     EXPORT_SYMBOL(awc_start_xmit);
2602     EXPORT_SYMBOL(awc_interrupt);
2603     EXPORT_SYMBOL(awc_get_stats);
2604     EXPORT_SYMBOL(awc_change_mtu);
2605     EXPORT_SYMBOL(awc_set_multicast_list);
2606     
2607     EXPORT_SYMBOL(awc_proc_set_fun);
2608     EXPORT_SYMBOL(awc_proc_unset_fun);
2609     EXPORT_SYMBOL(awc_register_proc);
2610     EXPORT_SYMBOL(awc_unregister_proc);
2611     
2612     
2613     /***************************  RESET INIT CONFIG ***********************/
2614     
2615     
2616      void awc_reset(struct net_device *dev)
2617     {
2618     
2619     	long long jiff;
2620     
2621     	DEBUG(2, " awc_reset dev %p \n", dev);
2622     	DEBUG(2, "%s: awc_reset \n",  dev->name);
2623     	
2624     	awc_issue_soft_reset(dev);
2625     	
2626     	jiff = jiffies;
2627     	udelay(1000);
2628     	while (awc_command_read(dev->base_addr)){
2629     		udelay(1000);
2630     		if (jiffies - jiff > 5*HZ){
2631     			printk(KERN_CRIT "%s bad reset\n",dev->name);
2632     			break;
2633     		}
2634     	};
2635     
2636     }
2637     
2638      int awc_config(struct net_device *dev)
2639     {
2640     //	struct awc_private *priv = (struct awc_private *)dev->priv;
2641     
2642     	DEBUG(2, "%s: awc_config \n",  dev->name);
2643     
2644     	
2645             if( awc_disable_MAC(dev))		goto final;
2646     	udelay(100);        
2647     	if( awc_write_all_rids(dev) )		goto final;
2648     	udelay(100);
2649             if( awc_enable_MAC(dev))		goto final;
2650     
2651     	return 0;
2652        final: 
2653        	return -1;
2654     }
2655     
2656     
2657     char name[] = "ElmerLinux";
2658     
2659      int awc_init(struct net_device *dev){
2660             struct awc_private *priv = (struct awc_private *)dev->priv;
2661     	int i;        
2662     	const char * radioType;
2663      
2664     	DEBUG(2, "%s: awc_init \n",  dev->name);
2665     
2666     	/* both_bap_lock decreases performance about 15% 
2667     	 * but without it card gets screwed up 
2668     	 */ 
2669     #ifdef CONFIG_SMP
2670     	if(smp_num_cpus > 1){
2671     		both_bap_lock = 1;
2672     		bap_setup_spinlock = 1;
2673     	}
2674     #endif
2675     	//awc_dump_registers(dev);
2676     
2677     	if (adhoc & !max_mtu)
2678     		max_mtu= 2250;
2679     	else if (!max_mtu)
2680     		max_mtu= 1500;
2681     			
2682             priv->sleeping_bap = 1;
2683             	
2684     
2685     	priv->enabled_interrupts = awc_ints_enabled(dev->base_addr);
2686             
2687      	if( awc_issue_noop(dev) ) 	goto final;
2688     
2689     	awc_ints_enable(dev->base_addr,0);
2690     
2691      	if( awc_disable_MAC(dev) )	goto final;
2692     
2693     		
2694     //	awc_rids_setup(dev);
2695     	i=0;
2696     	while ( i < AWC_NOF_RIDS){
2697     		if (awc_rids_temp[i].selector)
2698     			memcpy(&priv->rid_dir[i],&awc_rids_temp[i],sizeof(priv->rid_dir[0]) );
2699     		else priv->rid_dir[i].selector = NULL;
2700     		i++;
2701     	}
2702     	
2703     	// following MUST be consistent with awc_rids in count and ordrering !!!
2704      	priv->rid_dir[0].buff = &priv->config; // card RID mirrors
2705     	priv->rid_dir[1].buff = &priv->SSIDs;
2706     	priv->rid_dir[2].buff = &priv->fixed_APs;
2707          	priv->rid_dir[3].buff = &priv->driver_name;
2708           	priv->rid_dir[4].buff = &priv->enc_trans;
2709     	priv->rid_dir[5].buff = &priv->general_config; //      	
2710     	priv->rid_dir[6].buff = &priv->capabilities;
2711      	priv->rid_dir[7].buff = &priv->status;
2712       	priv->rid_dir[8].buff = &priv->AP;
2713        	priv->rid_dir[9].buff = &priv->statistics;
2714         	priv->rid_dir[10].buff = &priv->statistics_delta;
2715          	priv->rid_dir[11].buff = &priv->statistics_delta_clear;
2716     	priv->rid_dir[12].buff = &priv->wep_volatile;
2717     	priv->rid_dir[13].buff = &priv->wep_nonvolatile;
2718     	priv->rid_dir[14].buff = &priv->modulation;
2719     
2720           	priv->rid_dir[15].buff = &priv->statistics16;
2721     	priv->rid_dir[16].buff = &priv->statistics16_delta;
2722      	priv->rid_dir[17].buff = &priv->statistics16_delta_clear;
2723                            	
2724      	priv->rid_dir[0].bufflen = sizeof(priv->config); // card RID mirrors
2725     	priv->rid_dir[1].bufflen = sizeof(priv->SSIDs);
2726     	priv->rid_dir[2].bufflen = sizeof(priv->fixed_APs);
2727          	priv->rid_dir[3].bufflen = sizeof(priv->driver_name);
2728           	priv->rid_dir[4].bufflen = sizeof(priv->enc_trans);
2729     	priv->rid_dir[5].bufflen = sizeof(priv->general_config); //
2730     	priv->rid_dir[6].bufflen = sizeof(priv->capabilities);
2731      	priv->rid_dir[7].bufflen = sizeof(priv->status);
2732       	priv->rid_dir[8].bufflen = sizeof(priv->AP);
2733        	priv->rid_dir[9].bufflen = sizeof(priv->statistics);
2734         	priv->rid_dir[10].bufflen = sizeof(priv->statistics_delta);
2735          	priv->rid_dir[11].bufflen = sizeof(priv->statistics_delta_clear);
2736     	priv->rid_dir[12].bufflen = sizeof(priv->wep_volatile);
2737     	priv->rid_dir[13].bufflen = sizeof(priv->wep_nonvolatile);
2738     	priv->rid_dir[14].bufflen = sizeof(priv->modulation);
2739     
2740           	priv->rid_dir[15].bufflen = sizeof(priv->statistics16);
2741     	priv->rid_dir[16].bufflen = sizeof(priv->statistics16_delta);
2742      	priv->rid_dir[17].bufflen = sizeof(priv->statistics16_delta_clear);
2743     
2744     
2745      	if( awc_read_all_rids(dev) )	goto final;
2746      
2747     
2748      	priv->config.OperatingMode = 0;// MODE_LLC_HOST;
2749      	DEBUG(1,"ReceiveMode %x \n",priv->config.ReceiveMode);
2750      //	priv->config.ReceiveMode	=  RXMODE_DISABLE_802_3_HEADER;
2751      	
2752     	if (!adhoc)
2753     	        priv->config.OperatingMode = MODE_STA_ESS;
2754     //        priv->config.OperatingMode = MODE_AP;
2755     // Setting rates does not work with new hardware, use force_tx_rate via proc
2756     //	priv->config.Rates[0]	=0x82;
2757     //	priv->config.Rates[1]	=0x4;
2758     //	priv->config.Rates[2]	=tx_full_rate;
2759     //	priv->config.Rates[3]	=0;
2760     //	priv->config.Rates[4]	=0;
2761     //	priv->config.Rates[5]	=0;
2762     //	priv->config.Rates[6]	=0;
2763     //	priv->config.Rates[7]	=0;
2764     	priv->config.Channel	= channel;
2765     	if (adhoc && master){
2766     		priv->config.JoinNetTimeout	= 0x1;//0 is facotry default
2767     	} else if (adhoc && slave){
2768     		// by spec 0xffff, but, this causes immediate bad behaviour
2769     		// firmware behvaiour changed somehere around ver 2??
2770     		priv->config.JoinNetTimeout	= 0x7fff;
2771     	};	
2772     //	priv->config.AuthenticationType = 1;
2773     	priv->config.Stationary	=1;
2774     //	priv->config.ScanMode	= 1;
2775     //	priv->config.LinkLossDelay	= 100;
2776     	priv->config.FragmentThreshold = 1700;
2777     	priv->config.RtsThreshold	= 1700;
2778     	memcpy(priv->config.NodeName, name, 10);
2779     
2780     	DEBUG(1,"%s supported Rates \n",dev->name);
2781     	for (i=0; i< 8; i++)
2782     		DEBUG(1,"%x ",priv->capabilities.SupportedRates[i]);
2783     	DEBUG(1,"%c",'\n');
2784     	DEBUG(1,"%s default Rates \n",dev->name);
2785     	for (i=0; i< 8; i++)
2786     		DEBUG(1,"%x ",priv->config.Rates[i]);
2787     	DEBUG(1,"%c",'\n');
2788     			
2789     
2790     	// here we go, bad aironet
2791     	memset(&priv->SSIDs,0,sizeof(priv->SSIDs));
2792     
2793     	spin_lock_init(&priv->queues_lock);
2794             priv->SSIDs.ridLen		=0;
2795             if (!SSID) {
2796     	        priv->SSIDs.SSID[0].SSID[0] 	='a';
2797     	        priv->SSIDs.SSID[0].SSID[1] 	='b';
2798     	        priv->SSIDs.SSID[0].SSID[2] 	='c';
2799             	priv->SSIDs.SSID[0].lenght 	=3;
2800             } else {
2801             	int sidlen = strlen(SSID);
2802             	memcpy(priv->SSIDs.SSID[0].SSID,SSID,sidlen);
2803             	priv->SSIDs.SSID[0].lenght = sidlen;
2804             };
2805             
2806             priv->SSIDs.SSID[1].lenght 	=0;
2807             priv->SSIDs.SSID[1].SSID[0] 	=0;
2808             priv->SSIDs.SSID[1].SSID[1] 	=0;        
2809             priv->SSIDs.SSID[2].lenght 	=0;
2810             priv->SSIDs.SSID[2].SSID[0] 	=0;
2811             priv->SSIDs.SSID[2].SSID[1] 	=0;
2812     
2813     
2814     //	priv->enc_trans.rules[0].etherType= 0x0008;
2815     //	priv->enc_trans.rules[0].Action   = 1;        
2816              	
2817      	memcpy(	priv->config.StationMacAddress,
2818      		priv->capabilities.FactoryAddress,	6	);
2819     
2820             memcpy(dev->dev_addr, priv->config.StationMacAddress, 6);
2821     
2822     	DEBUG(2, "%s: awc_init success \n",  dev->name);
2823     	
2824     	if (priv->capabilities.RadioType == 1) radioType = "802.11 Frequency Hoping";
2825     	else if (priv->capabilities.RadioType == 2) radioType = "802.11 Direct Sequence";
2826     	else if (priv->capabilities.RadioType == 4) radioType = "LM2000";
2827     	else radioType = "Multiple Radio Types";
2828     
2829     	printk("%s: %s %s found @ 0x%lx irq %d firmwareVersion %d \n",dev->name,
2830     		priv->capabilities.ProductName,radioType,
2831     		dev->base_addr,dev->irq,
2832     		priv->capabilities.SoftwareVersion);
2833      
2834      	return 0; 
2835        final:
2836        	printk(KERN_ERR "aironet init failed \n");
2837        	return NODEV;
2838        	
2839      };
2840     
2841     int awc_private_init(struct net_device * dev){
2842     	struct awc_private * priv = (struct awc_private *) dev->priv;
2843     	int i = 0;
2844     
2845     	DEBUG(2, "%s: awc_private_init \n",  dev->name);
2846     	
2847     	
2848     	memset(priv, 0, sizeof(struct awc_private)); 
2849     	
2850     	spin_lock_init(&priv->queues_lock);
2851     	
2852     	priv->bap0.select 	= dev->base_addr + awc_Select0_register;
2853     	priv->bap0.offset 	= dev->base_addr + awc_Offset0_register;
2854     	priv->bap0.data		= dev->base_addr + awc_Data0_register;
2855     	priv->bap0.lock 	= 0;
2856     	priv->bap0.status	= 0;
2857     	spin_lock_init(&priv->bap0.spinlock);
2858     	init_MUTEX(&priv->bap0.sem);
2859     	priv->bap1.select 	= dev->base_addr + awc_Select1_register;
2860     	priv->bap1.offset 	= dev->base_addr + awc_Offset1_register;
2861     	priv->bap1.data		= dev->base_addr + awc_Data1_register;
2862     	priv->bap1.lock 	= 0;
2863     	priv->bap1.status	= 0;
2864     	spin_lock_init(&priv->bap1.spinlock);
2865     	init_MUTEX(&priv->bap1.sem);
2866     	priv->sleeping_bap	= 1;
2867     	
2868     //spinlock now	init_MUTEX(&priv->command_semaphore);
2869     	spin_lock_init(&priv->command_issuing_spinlock);
2870     	spin_lock_init(&priv->both_bap_spinlock);
2871     	spin_lock_init(&priv->bap_setup_spinlock);
2872     	spin_lock_init(&priv->interrupt_spinlock);
2873     	
2874     	priv->command_semaphore_on = 0;
2875     	priv->unlock_command_postponed = 0;
2876     	INIT_LIST_HEAD(&priv->immediate_bh.list);
2877     	priv->immediate_bh.sync 	= 0;
2878     	priv->immediate_bh.routine 	= (void *)(void *)awc_bh;
2879     	priv->immediate_bh.data 	= dev;
2880     	priv->bh_running	= 0;
2881     	priv->bh_active		= 0;
2882     	priv->tx_chain_active	= 0;
2883     	priv->enabled_interrupts= 0x00;
2884     	priv->waiting_interrupts= 0x00;
2885     	
2886     	
2887     	init_MUTEX(&priv->tx_buff_semaphore);
2888     	priv->tx_buffs_in_use	= 0;
2889     	priv->tx_small_buffs_in_use = 0;
2890     	priv->mac_enabled 	=0;
2891     	priv->link_status	=0;
2892     	priv->large_buff_mem	= large_buff_mem;
2893     	if (priv->large_buff_mem < max_mtu + AWC_TX_HEAD_SIZE + 10 )
2894     		priv->large_buff_mem = max_mtu + AWC_TX_HEAD_SIZE + 10;
2895     	priv->small_buff_no	= small_buff_no;
2896     	if (priv->small_buff_no  < 1 )
2897     		priv->small_buff_no = 1 ;
2898     
2899     	priv->process_tx_results = awc_process_tx_results;
2900     
2901     	//init_waitqueue(&priv->tx_chain_wait_queue);
2902     
2903     	for (i=0; i< 6 ; i++ ) {
2904     		priv->p2p[i] = 0xff;
2905     		priv->bssid[i] =0;
2906     	}
2907     //	priv->p2p_uc 		=1;
2908     	priv->p2p_found		=0;
2909     
2910     	priv->p802_11_send	=p802_11_send;
2911     	priv->full_stats	= awc_full_stats;
2912     	priv->simple_bridge	= awc_simple_bridge;
2913     	priv->force_rts_on_shorter = 0;
2914     	priv->force_tx_rate	= tx_rate;
2915     	priv->ip_tos_reliability_rts = 0;
2916     	priv->ip_tos_troughput_no_retries = 0 ;	
2917     
2918     	priv->ejected		=0;	
2919     	priv->interrupt_count	=0;
2920     	
2921     	return 0;
2922     	
2923     };
2924     
2925     /****************************	OPEN	CLOSE	**********************/
2926     
2927      
2928      int awc_open(struct net_device *dev)
2929     {
2930     	struct awc_private *priv = (struct awc_private *)dev->priv;
2931     
2932     
2933     
2934     	DEBUG(2, "%s: awc_open \n",  dev->name);
2935     
2936     	if( awc_queues_init(dev) )		goto final;
2937     	if( awc_config(dev) )		goto final;
2938     	
2939     	memcpy(dev->dev_addr, priv->config.StationMacAddress, 6);
2940     	 
2941     	priv->enabled_interrupts = 0x87;
2942     	awc_ints_enable(dev->base_addr,priv->enabled_interrupts);
2943     
2944     //	priv->p8022_client 	= register_8022_client;
2945     //	priv->snap_client	= register_snap_client;	
2946     	DEBUG(2, "%s: opened \n", dev->name);
2947     
2948     	priv->sleeping_bap  = 0;
2949     	
2950     	
2951     	MOD_INC_USE_COUNT;
2952     //	kernel_thread(awc_thread,dev,0);
2953     
2954     	netif_start_queue (dev);
2955     	return 0;					/* Always succeed */
2956     
2957        final:
2958        	netif_device_detach (dev);
2959        	printk(KERN_ERR "aironet open failed \n");
2960        	return -1;
2961     }
2962     
2963     
2964      int awc_close(struct net_device *dev)
2965     {
2966     	struct awc_private * priv = (struct awc_private *) dev->priv;
2967     
2968     	DEBUG(2, "%s: closing device.\n", dev->name);
2969     
2970     	netif_stop_queue (dev);
2971     	
2972     	awc_disable_MAC(dev);
2973     	awc_queues_destroy(dev);
2974     	
2975     	awc_reset(dev);
2976     	
2977     	mdelay(10);
2978     	
2979     	AWC_LOCK_COMMAND_ISSUING(priv);
2980     
2981     	MOD_DEC_USE_COUNT;
2982     
2983     	AWC_UNLOCK_COMMAND_ISSUING(priv);
2984     	 
2985     	return 0;
2986     }
2987     
2988     
2989     
2990     /******************************		TX  RX STUFF	******************/
2991     
2992     
2993     
2994     void awc_tx_timeout (struct net_device *dev)
2995     {
2996     	struct awc_private *priv = (struct awc_private *) dev->priv;
2997     	struct awc_fid * fid;
2998     	int cnt;
2999     	unsigned long flags;
3000     
3001     	DEBUG (2, "%s: awc_tx_timeout \n", dev->name);
3002     
3003     	printk (KERN_NOTICE "%s: Transmit timed out , buffs %d %d, queues tx %d pp %d lrg %d sm %d  \n ",
3004     	     dev->name, priv->tx_small_buffs_total, priv->tx_buffs_total,
3005     		priv->tx_in_transmit.size, priv->tx_post_process.size,
3006     		priv->tx_large_ready.size, priv->tx_small_ready.size);
3007     	priv->stats.tx_errors++;
3008     
3009     	save_flags(flags);
3010     	cli();
3011     	fid = priv->tx_in_transmit.head;
3012     	cnt = 0;
3013     	while (fid) { // removing all fids older that that
3014     		if (jiffies - fid->transmit_start_time > (HZ)) {
3015     			//      printk(KERN_ERR "%s staled tx_buff found, age %uld jiffies\n",dev->name,
3016     			//              jiffies - fid->transmit_start_time );
3017     			awc_fid_queue_remove (&priv->tx_in_transmit, fid);
3018     			if (fid->u.tx.fid_size <= AWC_TX_ALLOC_SMALL_SIZE)
3019     				awc_fid_queue_push_tail (&priv->tx_small_ready, fid);
3020     			else
3021     				awc_fid_queue_push_tail (&priv->tx_large_ready, fid);
3022     		}
3023     		fid = fid->next;
3024     		if (cnt++ > 200) {
3025     			printk ("bbb in awc_fid_queue\n");
3026     			restore_flags(flags);
3027     			return;
3028     		};
3029     
3030     	}
3031     	restore_flags(flags);
3032     	dev->trans_start = jiffies;
3033     	netif_wake_queue (dev);
3034     }
3035     
3036     
3037     long long last_tx_q_hack;
3038     int direction = 1;
3039     
3040     int awc_start_xmit(struct sk_buff *skb, struct net_device *dev) {
3041     
3042     	struct awc_private *priv = (struct awc_private *)dev->priv;
3043     	int retval = 0;
3044     //	unsigned long flags;
3045     
3046     	DEBUG(2, "%s: awc_start_xmit \n",  dev->name);
3047     
3048     
3049     	if (!dev) {
3050     		DEBUG(1, " xmit dev=NULL, jiffie %ld \n",jiffies);
3051     		return -1;
3052     	};
3053     
3054     	if (!skb) {
3055     		DEBUG(1, " xmit skb=NULL, jiffie %ld \n",jiffies);
3056     		return -1;
3057     	};
3058     	
3059     //	if (test_and_set_bit( 0, (void *) &priv->tx_chain_active) ) {
3060     //		netif_start_queue (dev);
3061     //		return 1;
3062     //	}
3063     
3064     	dev->trans_start = jiffies;
3065     	retval = awc_802_11_tx_find_path_and_post(dev,skb);
3066     	priv->tx_chain_active = 0;
3067     //	wake_up_interruptible(&priv->tx_chain_wait_queue);	
3068     
3069     //	if (!dev->tbusy) dev_tint(dev);
3070     	return retval;
3071     }
3072     
3073     void awc_interrupt(int irq, void *dev_id, struct pt_regs *regs)
3074     {
3075     	struct net_device *dev = dev_id;
3076     	struct awc_private *priv;
3077     	unsigned long flags;
3078     
3079     //	if ((dev == NULL)) return;
3080     
3081     	priv = (struct awc_private *)dev->priv;
3082     
3083     
3084     	
3085     
3086     	DEBUG(2, "%s: awc_interrupt \n",  dev->name);
3087     	spin_lock_irqsave(&priv->interrupt_spinlock, flags);	  
3088     
3089     	awc_interrupt_process(dev);
3090     
3091     	spin_unlock_irqrestore(&priv->interrupt_spinlock, flags);	  
3092     }
3093     
3094     
3095     
3096     /************************	STATS, MULTICAST & STUFF  ****************/
3097     
3098     
3099     
3100      struct net_device_stats *awc_get_stats(struct net_device *dev)
3101     {
3102     	struct awc_private *priv = (struct awc_private *)dev->priv;
3103     //        unsigned long flags;
3104     //	int cnt = 0;
3105     //	int unlocked_stats_in_interrupt=0;
3106     	
3107     	DEBUG(2, "%s: awc_get_stats \n",  dev->name);
3108     
3109     	if (!netif_running(dev)) {
3110     		return 0;			
3111     	}
3112     //	save_flags(flags);
3113     //	cli();
3114     	if (awc_full_stats)
3115     		awc_readrid_dir(dev, &priv->rid_dir[9]);
3116     //	restore_flags(flags);
3117     
3118     	// the very following is the very wrong very probably
3119     	if (awc_full_stats){
3120     		priv->stats.rx_bytes		= priv->statistics.HostRxBytes;
3121     		priv->stats.tx_bytes		= priv->statistics.HostTxBytes;
3122     		priv->stats.rx_fifo_errors 	= priv->statistics.RxOverrunErr ;
3123     		priv->stats.rx_crc_errors 	= priv->statistics.RxPlcpCrcErr + priv->statistics.RxMacCrcErr ;
3124     		priv->stats.rx_frame_errors 	= priv->statistics.RxPlcpFormat ;
3125     		priv->stats.rx_length_errors	=  priv->statistics.RxPlcpLength   ;
3126     		priv->stats.rx_missed_errors	= priv->statistics.RxAged ;
3127     		priv->stats.rx_over_errors	= priv->statistics.RxOverrunErr ;
3128     			
3129     		priv->stats.collisions 		= priv->statistics.TxSinColl;
3130     		priv->stats.tx_aborted_errors 	= priv->statistics.TxAged ;
3131     		priv->stats.tx_fifo_errors	= priv->statistics.HostTxFail ;
3132     		priv->stats.tx_window_errors 	= priv->statistics.TxMulColl  ;
3133     		priv->stats.tx_heartbeat_errors	= priv->statistics.DefersProt +priv->statistics.DefersEngy ;
3134     		priv->stats.tx_carrier_errors	= priv->statistics.RetryLong +priv->statistics.RetryShort  ;
3135     		priv->stats.multicast		= priv->statistics.HostRxMc;
3136     	}
3137     
3138     
3139     //	printk("rx_packets %d\n",priv->stats.rx_packets);
3140     	return &(priv->stats);
3141     }
3142     
3143     
3144     int awc_change_mtu(struct net_device *dev, int new_mtu){
3145     
3146     //	struct awc_private *priv = (struct awc_private *)dev->priv;
3147             unsigned long flags;
3148     
3149            if ((new_mtu < 256 ) || (new_mtu > 2312) || (max_mtu && new_mtu > max_mtu) )
3150                     return -EINVAL;
3151     
3152     	if (netif_running(dev)) {
3153     		printk("PLEASE, ifconfig %s down for mtu change\n",dev->name);
3154     
3155     	};
3156     	if (dev->mtu != new_mtu) {
3157     		save_flags(flags);
3158     		cli();
3159     		 netif_stop_queue(dev);
3160     		 awc_disable_MAC(dev);
3161     		restore_flags(flags); 
3162     				
3163     		awc_tx_dealloc(dev);
3164     		dev->mtu = new_mtu;
3165     		awc_tx_alloc(dev);
3166     		awc_enable_MAC(dev);
3167     		netif_start_queue(dev);
3168     
3169     		printk("%s mtu has been changed to %d \n ",dev->name,dev->mtu);
3170     
3171     	}
3172     
3173     	return 0;
3174     
3175     };
3176     
3177     
3178      void
3179     awc_set_multicast_list(struct net_device *dev) {
3180     //	int ioaddr = dev->base_addr;
3181     
3182     /*	if (dev->flags & IFF_PROMISC)
3183     		promisc
3184     	else if (dev->mc_count || (dev->flags & IFF_ALLMULTI))
3185     		allmulti
3186     	else
3187     		normal
3188     		*/
3189     
3190     
3191     }
3192     
3193     
3194     
3195     int (* awc_proc_set_fun) (int);
3196     int (* awc_proc_unset_fun) (int);
3197     
3198     
3199     int awc_register_proc(int (*awc_proc_set_device)(int),int (*awc_proc_unset_device)(int)){
3200     
3201     	AWC_ENTRY_EXIT_DEBUG("awc_register_proc");
3202     	awc_proc_set_fun 	= awc_proc_set_device;
3203     	awc_proc_unset_fun 	= awc_proc_unset_device;
3204     	AWC_ENTRY_EXIT_DEBUG("exit");
3205     	return 0;
3206     };
3207     
3208     int awc_unregister_proc(void){
3209     
3210     	AWC_ENTRY_EXIT_DEBUG("awc_unregister_proc");
3211     	
3212     	awc_proc_set_fun        = NULL;
3213     	awc_proc_unset_fun      = NULL;	                
3214     	AWC_ENTRY_EXIT_DEBUG("exit");
3215     	return 0;
3216     };
3217     
3218     static int aironet_core_init(void)
3219     {
3220     //	unsigned long flags;
3221     
3222     		
3223     	printk(KERN_INFO"%s", aironet4500_core_version);
3224     	return 0;
3225     	
3226     
3227     }
3228     
3229     static void aironet_core_exit(void)
3230     {
3231     	printk(KERN_INFO "aironet4500 unloading core module \n");
3232     
3233     }
3234             
3235     module_init(aironet_core_init);
3236     module_exit(aironet_core_exit);
3237     
3238