OSDN Git Service

[PATCH] PPP: fix crash using usb-serial on high speed devices
[linux-kernel-docs/linux-2.4.36.git] / 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 MODULE_LICENSE("GPL");
2586
2587
2588 /*EXPORT_SYMBOL(tx_queue_len);
2589 EXPORT_SYMBOL(awc_debug);
2590  */
2591 EXPORT_SYMBOL(awc_init);
2592 EXPORT_SYMBOL(awc_open);
2593 EXPORT_SYMBOL(awc_close);
2594 EXPORT_SYMBOL(awc_reset);
2595 EXPORT_SYMBOL(awc_config);
2596
2597 EXPORT_SYMBOL(aironet4500_devices);
2598 EXPORT_SYMBOL(awc_debug);
2599 //EXPORT_SYMBOL();
2600
2601 EXPORT_SYMBOL(awc_private_init);
2602 EXPORT_SYMBOL(awc_tx_timeout);
2603 EXPORT_SYMBOL(awc_start_xmit);
2604 EXPORT_SYMBOL(awc_interrupt);
2605 EXPORT_SYMBOL(awc_get_stats);
2606 EXPORT_SYMBOL(awc_change_mtu);
2607 EXPORT_SYMBOL(awc_set_multicast_list);
2608
2609 EXPORT_SYMBOL(awc_proc_set_fun);
2610 EXPORT_SYMBOL(awc_proc_unset_fun);
2611 EXPORT_SYMBOL(awc_register_proc);
2612 EXPORT_SYMBOL(awc_unregister_proc);
2613
2614
2615 /***************************  RESET INIT CONFIG ***********************/
2616
2617
2618  void awc_reset(struct net_device *dev)
2619 {
2620
2621         long long jiff;
2622
2623         DEBUG(2, " awc_reset dev %p \n", dev);
2624         DEBUG(2, "%s: awc_reset \n",  dev->name);
2625         
2626         awc_issue_soft_reset(dev);
2627         
2628         jiff = jiffies;
2629         udelay(1000);
2630         while (awc_command_read(dev->base_addr)){
2631                 udelay(1000);
2632                 if (jiffies - jiff > 5*HZ){
2633                         printk(KERN_CRIT "%s bad reset\n",dev->name);
2634                         break;
2635                 }
2636         };
2637
2638 }
2639
2640  int awc_config(struct net_device *dev)
2641 {
2642 //      struct awc_private *priv = (struct awc_private *)dev->priv;
2643
2644         DEBUG(2, "%s: awc_config \n",  dev->name);
2645
2646         
2647         if( awc_disable_MAC(dev))               goto final;
2648         udelay(100);        
2649         if( awc_write_all_rids(dev) )           goto final;
2650         udelay(100);
2651         if( awc_enable_MAC(dev))                goto final;
2652
2653         return 0;
2654    final: 
2655         return -1;
2656 }
2657
2658
2659 char name[] = "ElmerLinux";
2660
2661  int awc_init(struct net_device *dev){
2662         struct awc_private *priv = (struct awc_private *)dev->priv;
2663         int i;        
2664         const char * radioType;
2665  
2666         DEBUG(2, "%s: awc_init \n",  dev->name);
2667
2668         /* both_bap_lock decreases performance about 15% 
2669          * but without it card gets screwed up 
2670          */ 
2671 #ifdef CONFIG_SMP
2672         if(smp_num_cpus > 1){
2673                 both_bap_lock = 1;
2674                 bap_setup_spinlock = 1;
2675         }
2676 #endif
2677         //awc_dump_registers(dev);
2678
2679         if (adhoc & !max_mtu)
2680                 max_mtu= 2250;
2681         else if (!max_mtu)
2682                 max_mtu= 1500;
2683                         
2684         priv->sleeping_bap = 1;
2685                 
2686
2687         priv->enabled_interrupts = awc_ints_enabled(dev->base_addr);
2688         
2689         if( awc_issue_noop(dev) )       goto final;
2690
2691         awc_ints_enable(dev->base_addr,0);
2692
2693         if( awc_disable_MAC(dev) )      goto final;
2694
2695                 
2696 //      awc_rids_setup(dev);
2697         i=0;
2698         while ( i < AWC_NOF_RIDS){
2699                 if (awc_rids_temp[i].selector)
2700                         memcpy(&priv->rid_dir[i],&awc_rids_temp[i],sizeof(priv->rid_dir[0]) );
2701                 else priv->rid_dir[i].selector = NULL;
2702                 i++;
2703         }
2704         
2705         // following MUST be consistent with awc_rids in count and ordrering !!!
2706         priv->rid_dir[0].buff = &priv->config; // card RID mirrors
2707         priv->rid_dir[1].buff = &priv->SSIDs;
2708         priv->rid_dir[2].buff = &priv->fixed_APs;
2709         priv->rid_dir[3].buff = &priv->driver_name;
2710         priv->rid_dir[4].buff = &priv->enc_trans;
2711         priv->rid_dir[5].buff = &priv->general_config; //       
2712         priv->rid_dir[6].buff = &priv->capabilities;
2713         priv->rid_dir[7].buff = &priv->status;
2714         priv->rid_dir[8].buff = &priv->AP;
2715         priv->rid_dir[9].buff = &priv->statistics;
2716         priv->rid_dir[10].buff = &priv->statistics_delta;
2717         priv->rid_dir[11].buff = &priv->statistics_delta_clear;
2718         priv->rid_dir[12].buff = &priv->wep_volatile;
2719         priv->rid_dir[13].buff = &priv->wep_nonvolatile;
2720         priv->rid_dir[14].buff = &priv->modulation;
2721
2722         priv->rid_dir[15].buff = &priv->statistics16;
2723         priv->rid_dir[16].buff = &priv->statistics16_delta;
2724         priv->rid_dir[17].buff = &priv->statistics16_delta_clear;
2725                         
2726         priv->rid_dir[0].bufflen = sizeof(priv->config); // card RID mirrors
2727         priv->rid_dir[1].bufflen = sizeof(priv->SSIDs);
2728         priv->rid_dir[2].bufflen = sizeof(priv->fixed_APs);
2729         priv->rid_dir[3].bufflen = sizeof(priv->driver_name);
2730         priv->rid_dir[4].bufflen = sizeof(priv->enc_trans);
2731         priv->rid_dir[5].bufflen = sizeof(priv->general_config); //
2732         priv->rid_dir[6].bufflen = sizeof(priv->capabilities);
2733         priv->rid_dir[7].bufflen = sizeof(priv->status);
2734         priv->rid_dir[8].bufflen = sizeof(priv->AP);
2735         priv->rid_dir[9].bufflen = sizeof(priv->statistics);
2736         priv->rid_dir[10].bufflen = sizeof(priv->statistics_delta);
2737         priv->rid_dir[11].bufflen = sizeof(priv->statistics_delta_clear);
2738         priv->rid_dir[12].bufflen = sizeof(priv->wep_volatile);
2739         priv->rid_dir[13].bufflen = sizeof(priv->wep_nonvolatile);
2740         priv->rid_dir[14].bufflen = sizeof(priv->modulation);
2741
2742         priv->rid_dir[15].bufflen = sizeof(priv->statistics16);
2743         priv->rid_dir[16].bufflen = sizeof(priv->statistics16_delta);
2744         priv->rid_dir[17].bufflen = sizeof(priv->statistics16_delta_clear);
2745
2746
2747         if( awc_read_all_rids(dev) )    goto final;
2748  
2749
2750         priv->config.OperatingMode = 0;// MODE_LLC_HOST;
2751         DEBUG(1,"ReceiveMode %x \n",priv->config.ReceiveMode);
2752  //     priv->config.ReceiveMode        =  RXMODE_DISABLE_802_3_HEADER;
2753         
2754         if (!adhoc)
2755                 priv->config.OperatingMode = MODE_STA_ESS;
2756 //        priv->config.OperatingMode = MODE_AP;
2757 // Setting rates does not work with new hardware, use force_tx_rate via proc
2758 //      priv->config.Rates[0]   =0x82;
2759 //      priv->config.Rates[1]   =0x4;
2760 //      priv->config.Rates[2]   =tx_full_rate;
2761 //      priv->config.Rates[3]   =0;
2762 //      priv->config.Rates[4]   =0;
2763 //      priv->config.Rates[5]   =0;
2764 //      priv->config.Rates[6]   =0;
2765 //      priv->config.Rates[7]   =0;
2766         priv->config.Channel    = channel;
2767         if (adhoc && master){
2768                 priv->config.JoinNetTimeout     = 0x1;//0 is facotry default
2769         } else if (adhoc && slave){
2770                 // by spec 0xffff, but, this causes immediate bad behaviour
2771                 // firmware behvaiour changed somehere around ver 2??
2772                 priv->config.JoinNetTimeout     = 0x7fff;
2773         };      
2774 //      priv->config.AuthenticationType = 1;
2775         priv->config.Stationary =1;
2776 //      priv->config.ScanMode   = 1;
2777 //      priv->config.LinkLossDelay      = 100;
2778         priv->config.FragmentThreshold = 1700;
2779         priv->config.RtsThreshold       = 1700;
2780         memcpy(priv->config.NodeName, name, 10);
2781
2782         DEBUG(1,"%s supported Rates \n",dev->name);
2783         for (i=0; i< 8; i++)
2784                 DEBUG(1,"%x ",priv->capabilities.SupportedRates[i]);
2785         DEBUG(1,"%c",'\n');
2786         DEBUG(1,"%s default Rates \n",dev->name);
2787         for (i=0; i< 8; i++)
2788                 DEBUG(1,"%x ",priv->config.Rates[i]);
2789         DEBUG(1,"%c",'\n');
2790                         
2791
2792         // here we go, bad aironet
2793         memset(&priv->SSIDs,0,sizeof(priv->SSIDs));
2794
2795         spin_lock_init(&priv->queues_lock);
2796         priv->SSIDs.ridLen              =0;
2797         if (!SSID) {
2798                 priv->SSIDs.SSID[0].SSID[0]     ='a';
2799                 priv->SSIDs.SSID[0].SSID[1]     ='b';
2800                 priv->SSIDs.SSID[0].SSID[2]     ='c';
2801                 priv->SSIDs.SSID[0].lenght      =3;
2802         } else {
2803                 int sidlen = strlen(SSID);
2804                 memcpy(priv->SSIDs.SSID[0].SSID,SSID,sidlen);
2805                 priv->SSIDs.SSID[0].lenght = sidlen;
2806         };
2807         
2808         priv->SSIDs.SSID[1].lenght      =0;
2809         priv->SSIDs.SSID[1].SSID[0]     =0;
2810         priv->SSIDs.SSID[1].SSID[1]     =0;        
2811         priv->SSIDs.SSID[2].lenght      =0;
2812         priv->SSIDs.SSID[2].SSID[0]     =0;
2813         priv->SSIDs.SSID[2].SSID[1]     =0;
2814
2815
2816 //      priv->enc_trans.rules[0].etherType= 0x0008;
2817 //      priv->enc_trans.rules[0].Action   = 1;        
2818                 
2819         memcpy( priv->config.StationMacAddress,
2820                 priv->capabilities.FactoryAddress,      6       );
2821
2822         memcpy(dev->dev_addr, priv->config.StationMacAddress, 6);
2823
2824         DEBUG(2, "%s: awc_init success \n",  dev->name);
2825         
2826         if (priv->capabilities.RadioType == 1) radioType = "802.11 Frequency Hoping";
2827         else if (priv->capabilities.RadioType == 2) radioType = "802.11 Direct Sequence";
2828         else if (priv->capabilities.RadioType == 4) radioType = "LM2000";
2829         else radioType = "Multiple Radio Types";
2830
2831         printk("%s: %s %s found @ 0x%lx irq %d firmwareVersion %d \n",dev->name,
2832                 priv->capabilities.ProductName,radioType,
2833                 dev->base_addr,dev->irq,
2834                 priv->capabilities.SoftwareVersion);
2835  
2836         return 0; 
2837    final:
2838         printk(KERN_ERR "aironet init failed \n");
2839         return ENODEV;
2840         
2841  };
2842
2843 int awc_private_init(struct net_device * dev){
2844         struct awc_private * priv = (struct awc_private *) dev->priv;
2845         int i = 0;
2846
2847         DEBUG(2, "%s: awc_private_init \n",  dev->name);
2848         
2849         
2850         memset(priv, 0, sizeof(struct awc_private)); 
2851         
2852         spin_lock_init(&priv->queues_lock);
2853         
2854         priv->bap0.select       = dev->base_addr + awc_Select0_register;
2855         priv->bap0.offset       = dev->base_addr + awc_Offset0_register;
2856         priv->bap0.data         = dev->base_addr + awc_Data0_register;
2857         priv->bap0.lock         = 0;
2858         priv->bap0.status       = 0;
2859         spin_lock_init(&priv->bap0.spinlock);
2860         init_MUTEX(&priv->bap0.sem);
2861         priv->bap1.select       = dev->base_addr + awc_Select1_register;
2862         priv->bap1.offset       = dev->base_addr + awc_Offset1_register;
2863         priv->bap1.data         = dev->base_addr + awc_Data1_register;
2864         priv->bap1.lock         = 0;
2865         priv->bap1.status       = 0;
2866         spin_lock_init(&priv->bap1.spinlock);
2867         init_MUTEX(&priv->bap1.sem);
2868         priv->sleeping_bap      = 1;
2869         
2870 //spinlock now  init_MUTEX(&priv->command_semaphore);
2871         spin_lock_init(&priv->command_issuing_spinlock);
2872         spin_lock_init(&priv->both_bap_spinlock);
2873         spin_lock_init(&priv->bap_setup_spinlock);
2874         spin_lock_init(&priv->interrupt_spinlock);
2875         
2876         priv->command_semaphore_on = 0;
2877         priv->unlock_command_postponed = 0;
2878         INIT_LIST_HEAD(&priv->immediate_bh.list);
2879         priv->immediate_bh.sync         = 0;
2880         priv->immediate_bh.routine      = (void *)(void *)awc_bh;
2881         priv->immediate_bh.data         = dev;
2882         priv->bh_running        = 0;
2883         priv->bh_active         = 0;
2884         priv->tx_chain_active   = 0;
2885         priv->enabled_interrupts= 0x00;
2886         priv->waiting_interrupts= 0x00;
2887         
2888         
2889         init_MUTEX(&priv->tx_buff_semaphore);
2890         priv->tx_buffs_in_use   = 0;
2891         priv->tx_small_buffs_in_use = 0;
2892         priv->mac_enabled       =0;
2893         priv->link_status       =0;
2894         priv->large_buff_mem    = large_buff_mem;
2895         if (priv->large_buff_mem < max_mtu + AWC_TX_HEAD_SIZE + 10 )
2896                 priv->large_buff_mem = max_mtu + AWC_TX_HEAD_SIZE + 10;
2897         priv->small_buff_no     = small_buff_no;
2898         if (priv->small_buff_no  < 1 )
2899                 priv->small_buff_no = 1 ;
2900
2901         priv->process_tx_results = awc_process_tx_results;
2902
2903         //init_waitqueue(&priv->tx_chain_wait_queue);
2904
2905         for (i=0; i< 6 ; i++ ) {
2906                 priv->p2p[i] = 0xff;
2907                 priv->bssid[i] =0;
2908         }
2909 //      priv->p2p_uc            =1;
2910         priv->p2p_found         =0;
2911
2912         priv->p802_11_send      =p802_11_send;
2913         priv->full_stats        = awc_full_stats;
2914         priv->simple_bridge     = awc_simple_bridge;
2915         priv->force_rts_on_shorter = 0;
2916         priv->force_tx_rate     = tx_rate;
2917         priv->ip_tos_reliability_rts = 0;
2918         priv->ip_tos_troughput_no_retries = 0 ; 
2919
2920         priv->ejected           =0;     
2921         priv->interrupt_count   =0;
2922         
2923         return 0;
2924         
2925 };
2926
2927 /****************************   OPEN    CLOSE   **********************/
2928
2929  
2930  int awc_open(struct net_device *dev)
2931 {
2932         struct awc_private *priv = (struct awc_private *)dev->priv;
2933
2934
2935
2936         DEBUG(2, "%s: awc_open \n",  dev->name);
2937
2938         if( awc_queues_init(dev) )              goto final;
2939         if( awc_config(dev) )           goto final;
2940         
2941         memcpy(dev->dev_addr, priv->config.StationMacAddress, 6);
2942          
2943         priv->enabled_interrupts = 0x87;
2944         awc_ints_enable(dev->base_addr,priv->enabled_interrupts);
2945
2946 //      priv->p8022_client      = register_8022_client;
2947 //      priv->snap_client       = register_snap_client; 
2948         DEBUG(2, "%s: opened \n", dev->name);
2949
2950         priv->sleeping_bap  = 0;
2951         
2952         
2953         MOD_INC_USE_COUNT;
2954 //      kernel_thread(awc_thread,dev,0);
2955
2956         netif_start_queue (dev);
2957         return 0;                                       /* Always succeed */
2958
2959    final:
2960         netif_device_detach (dev);
2961         printk(KERN_ERR "aironet open failed \n");
2962         return -1;
2963 }
2964
2965
2966  int awc_close(struct net_device *dev)
2967 {
2968         struct awc_private * priv = (struct awc_private *) dev->priv;
2969
2970         DEBUG(2, "%s: closing device.\n", dev->name);
2971
2972         netif_stop_queue (dev);
2973         
2974         awc_disable_MAC(dev);
2975         awc_queues_destroy(dev);
2976         
2977         awc_reset(dev);
2978         
2979         mdelay(10);
2980         
2981         AWC_LOCK_COMMAND_ISSUING(priv);
2982
2983         MOD_DEC_USE_COUNT;
2984
2985         AWC_UNLOCK_COMMAND_ISSUING(priv);
2986          
2987         return 0;
2988 }
2989
2990
2991
2992 /******************************         TX  RX STUFF    ******************/
2993
2994
2995
2996 void awc_tx_timeout (struct net_device *dev)
2997 {
2998         struct awc_private *priv = (struct awc_private *) dev->priv;
2999         struct awc_fid * fid;
3000         int cnt;
3001         unsigned long flags;
3002
3003         DEBUG (2, "%s: awc_tx_timeout \n", dev->name);
3004
3005         printk (KERN_NOTICE "%s: Transmit timed out , buffs %d %d, queues tx %d pp %d lrg %d sm %d  \n ",
3006              dev->name, priv->tx_small_buffs_total, priv->tx_buffs_total,
3007                 priv->tx_in_transmit.size, priv->tx_post_process.size,
3008                 priv->tx_large_ready.size, priv->tx_small_ready.size);
3009         priv->stats.tx_errors++;
3010
3011         save_flags(flags);
3012         cli();
3013         fid = priv->tx_in_transmit.head;
3014         cnt = 0;
3015         while (fid) { // removing all fids older that that
3016                 if (jiffies - fid->transmit_start_time > (HZ)) {
3017                         //      printk(KERN_ERR "%s staled tx_buff found, age %uld jiffies\n",dev->name,
3018                         //              jiffies - fid->transmit_start_time );
3019                         awc_fid_queue_remove (&priv->tx_in_transmit, fid);
3020                         if (fid->u.tx.fid_size <= AWC_TX_ALLOC_SMALL_SIZE)
3021                                 awc_fid_queue_push_tail (&priv->tx_small_ready, fid);
3022                         else
3023                                 awc_fid_queue_push_tail (&priv->tx_large_ready, fid);
3024                 }
3025                 fid = fid->next;
3026                 if (cnt++ > 200) {
3027                         printk ("bbb in awc_fid_queue\n");
3028                         restore_flags(flags);
3029                         return;
3030                 };
3031
3032         }
3033         restore_flags(flags);
3034         dev->trans_start = jiffies;
3035         netif_wake_queue (dev);
3036 }
3037
3038
3039 long long last_tx_q_hack;
3040 int direction = 1;
3041
3042 int awc_start_xmit(struct sk_buff *skb, struct net_device *dev) {
3043
3044         struct awc_private *priv = (struct awc_private *)dev->priv;
3045         int retval = 0;
3046 //      unsigned long flags;
3047
3048         DEBUG(2, "%s: awc_start_xmit \n",  dev->name);
3049
3050
3051         if (!dev) {
3052                 DEBUG(1, " xmit dev=NULL, jiffie %ld \n",jiffies);
3053                 return -1;
3054         };
3055
3056         if (!skb) {
3057                 DEBUG(1, " xmit skb=NULL, jiffie %ld \n",jiffies);
3058                 return -1;
3059         };
3060         
3061 //      if (test_and_set_bit( 0, (void *) &priv->tx_chain_active) ) {
3062 //              netif_start_queue (dev);
3063 //              return 1;
3064 //      }
3065
3066         dev->trans_start = jiffies;
3067         retval = awc_802_11_tx_find_path_and_post(dev,skb);
3068         priv->tx_chain_active = 0;
3069 //      wake_up_interruptible(&priv->tx_chain_wait_queue);      
3070
3071 //      if (!dev->tbusy) dev_tint(dev);
3072         return retval;
3073 }
3074
3075 void awc_interrupt(int irq, void *dev_id, struct pt_regs *regs)
3076 {
3077         struct net_device *dev = dev_id;
3078         struct awc_private *priv;
3079         unsigned long flags;
3080
3081 //      if ((dev == NULL)) return;
3082
3083         priv = (struct awc_private *)dev->priv;
3084
3085
3086         
3087
3088         DEBUG(2, "%s: awc_interrupt \n",  dev->name);
3089         spin_lock_irqsave(&priv->interrupt_spinlock, flags);      
3090
3091         awc_interrupt_process(dev);
3092
3093         spin_unlock_irqrestore(&priv->interrupt_spinlock, flags);         
3094 }
3095
3096
3097
3098 /************************       STATS, MULTICAST & STUFF  ****************/
3099
3100
3101
3102  struct net_device_stats *awc_get_stats(struct net_device *dev)
3103 {
3104         struct awc_private *priv = (struct awc_private *)dev->priv;
3105 //        unsigned long flags;
3106 //      int cnt = 0;
3107 //      int unlocked_stats_in_interrupt=0;
3108         
3109         DEBUG(2, "%s: awc_get_stats \n",  dev->name);
3110
3111         if (!netif_running(dev)) {
3112                 return 0;                       
3113         }
3114 //      save_flags(flags);
3115 //      cli();
3116         if (awc_full_stats)
3117                 awc_readrid_dir(dev, &priv->rid_dir[9]);
3118 //      restore_flags(flags);
3119
3120         // the very following is the very wrong very probably
3121         if (awc_full_stats){
3122                 priv->stats.rx_bytes            = priv->statistics.HostRxBytes;
3123                 priv->stats.tx_bytes            = priv->statistics.HostTxBytes;
3124                 priv->stats.rx_fifo_errors      = priv->statistics.RxOverrunErr ;
3125                 priv->stats.rx_crc_errors       = priv->statistics.RxPlcpCrcErr + priv->statistics.RxMacCrcErr ;
3126                 priv->stats.rx_frame_errors     = priv->statistics.RxPlcpFormat ;
3127                 priv->stats.rx_length_errors    =  priv->statistics.RxPlcpLength   ;
3128                 priv->stats.rx_missed_errors    = priv->statistics.RxAged ;
3129                 priv->stats.rx_over_errors      = priv->statistics.RxOverrunErr ;
3130                         
3131                 priv->stats.collisions          = priv->statistics.TxSinColl;
3132                 priv->stats.tx_aborted_errors   = priv->statistics.TxAged ;
3133                 priv->stats.tx_fifo_errors      = priv->statistics.HostTxFail ;
3134                 priv->stats.tx_window_errors    = priv->statistics.TxMulColl  ;
3135                 priv->stats.tx_heartbeat_errors = priv->statistics.DefersProt +priv->statistics.DefersEngy ;
3136                 priv->stats.tx_carrier_errors   = priv->statistics.RetryLong +priv->statistics.RetryShort  ;
3137                 priv->stats.multicast           = priv->statistics.HostRxMc;
3138         }
3139
3140
3141 //      printk("rx_packets %d\n",priv->stats.rx_packets);
3142         return &(priv->stats);
3143 }
3144
3145
3146 int awc_change_mtu(struct net_device *dev, int new_mtu){
3147
3148 //      struct awc_private *priv = (struct awc_private *)dev->priv;
3149         unsigned long flags;
3150
3151        if ((new_mtu < 256 ) || (new_mtu > 2312) || (max_mtu && new_mtu > max_mtu) )
3152                 return -EINVAL;
3153
3154         if (netif_running(dev)) {
3155                 printk("PLEASE, ifconfig %s down for mtu change\n",dev->name);
3156
3157         };
3158         if (dev->mtu != new_mtu) {
3159                 save_flags(flags);
3160                 cli();
3161                  netif_stop_queue(dev);
3162                  awc_disable_MAC(dev);
3163                 restore_flags(flags); 
3164                                 
3165                 awc_tx_dealloc(dev);
3166                 dev->mtu = new_mtu;
3167                 awc_tx_alloc(dev);
3168                 awc_enable_MAC(dev);
3169                 netif_start_queue(dev);
3170
3171                 printk("%s mtu has been changed to %d \n ",dev->name,dev->mtu);
3172
3173         }
3174
3175         return 0;
3176
3177 };
3178
3179
3180  void
3181 awc_set_multicast_list(struct net_device *dev) {
3182 //      int ioaddr = dev->base_addr;
3183
3184 /*      if (dev->flags & IFF_PROMISC)
3185                 promisc
3186         else if (dev->mc_count || (dev->flags & IFF_ALLMULTI))
3187                 allmulti
3188         else
3189                 normal
3190                 */
3191
3192
3193 }
3194
3195
3196
3197 int (* awc_proc_set_fun) (int);
3198 int (* awc_proc_unset_fun) (int);
3199
3200
3201 int awc_register_proc(int (*awc_proc_set_device)(int),int (*awc_proc_unset_device)(int)){
3202
3203         AWC_ENTRY_EXIT_DEBUG("awc_register_proc");
3204         awc_proc_set_fun        = awc_proc_set_device;
3205         awc_proc_unset_fun      = awc_proc_unset_device;
3206         AWC_ENTRY_EXIT_DEBUG("exit");
3207         return 0;
3208 };
3209
3210 int awc_unregister_proc(void){
3211
3212         AWC_ENTRY_EXIT_DEBUG("awc_unregister_proc");
3213         
3214         awc_proc_set_fun        = NULL;
3215         awc_proc_unset_fun      = NULL;                 
3216         AWC_ENTRY_EXIT_DEBUG("exit");
3217         return 0;
3218 };
3219
3220 static int aironet_core_init(void)
3221 {
3222 //      unsigned long flags;
3223
3224                 
3225         printk(KERN_INFO"%s", aironet4500_core_version);
3226         return 0;
3227         
3228
3229 }
3230
3231 static void aironet_core_exit(void)
3232 {
3233         printk(KERN_INFO "aironet4500 unloading core module \n");
3234
3235 }
3236         
3237 module_init(aironet_core_init);
3238 module_exit(aironet_core_exit);
3239