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 
awc_print_string(struct awc_strings * strings,int code)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 
awc_dump_registers(struct net_device * dev)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
awc_command_busy_clear_wait(struct net_device * dev)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
awc_issue_command_and_block(struct awc_command * cmd)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
awc_issue_command(struct awc_command * cmd)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
awc_issue_command_no_ack(struct net_device * dev,u16 com,u16 par1,u16 par2,u16 par3)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
awc_bap_setup(struct awc_command * cmd)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
awc_bap_read(struct awc_command * cmd)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
awc_bap_write(struct awc_command * cmd)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
awc_readrid(struct net_device * dev,struct aironet4500_RID * rid,void * pBuf)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
awc_writerid(struct net_device * dev,struct aironet4500_RID * rid,void * pBuf)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
awc_readrid_dir(struct net_device * dev,struct awc_rid_dir * rid)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
awc_writerid_dir(struct net_device * dev,struct awc_rid_dir * rid)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
awc_issue_blocking_command(struct net_device * dev,u16 comm)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
awc_issue_soft_reset(struct net_device * dev)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
awc_issue_noop(struct net_device * dev)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
awc_enable_MAC(struct net_device * dev)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
awc_disable_MAC(struct net_device * dev)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
awc_read_all_rids(struct net_device * dev)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
awc_write_all_rids(struct net_device * dev)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 
awc_tx_alloc(struct net_device * dev)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
awc_tx_dealloc_fid(struct net_device * dev,struct awc_fid * fid)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
awc_tx_dealloc(struct net_device * dev)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 *
awc_tx_fid_lookup_and_remove(struct net_device * dev,u16 fid_handle)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
awc_queues_init(struct net_device * dev)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
awc_queues_destroy(struct net_device * dev)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
awc_802_11_copy_path_skb(struct net_device * dev,struct awc_fid * rx_buff)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
awc_802_11_find_copy_path(struct net_device * dev,struct awc_fid * rx_buff)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
awc_802_11_router_rx(struct net_device * dev,struct awc_fid * rx_buff)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
awc_802_11_failed_rx_copy(struct net_device * dev,struct awc_fid * rx_buff)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
awc_802_11_tx_find_path_and_post(struct net_device * dev,struct sk_buff * skb)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
awc_802_11_after_tx_packet_to_card_write(struct net_device * dev,struct awc_fid * tx_buff)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
awc_802_11_after_failed_tx_packet_to_card_write(struct net_device * dev,struct awc_fid * tx_buff)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
awc_802_11_after_tx_complete(struct net_device * dev,struct awc_fid * tx_buff)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
awc_receive_packet(struct net_device * dev)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
awc_transmit_packet(struct net_device * dev,struct awc_fid * tx_buff)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
awc_tx_complete_check(struct net_device * dev)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
awc_bh(struct net_device * dev)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
awc_interrupt_process(struct net_device * dev)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 
awc_reset(struct net_device * dev)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 
awc_config(struct net_device * dev)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 
awc_init(struct net_device * dev)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 
awc_private_init(struct net_device * dev)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 
awc_open(struct net_device * dev)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 
awc_close(struct net_device * dev)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 
awc_tx_timeout(struct net_device * dev)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 
awc_start_xmit(struct sk_buff * skb,struct net_device * dev)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 
awc_interrupt(int irq,void * dev_id,struct pt_regs * regs)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 
awc_get_stats(struct net_device * dev)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 
awc_change_mtu(struct net_device * dev,int new_mtu)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
awc_set_multicast_list(struct net_device * dev)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 
awc_register_proc(int (* awc_proc_set_device)(int),int (* awc_proc_unset_device)(int))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 
awc_unregister_proc(void)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 
aironet_core_init(void)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 
aironet_core_exit(void)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 
3240