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