1
2
3
4
5
6
7
8
9
10
11
12
13
14#ifdef MODULE
15static const char *awc_version =
16"aironet4500_cards.c v0.2 Feb 27, 2000 Elmer Joandi, elmer@ylenurme.ee.\n";
17#endif
18
19#include <linux/version.h>
20#include <linux/config.h>
21#include <linux/module.h>
22
23#include <linux/kernel.h>
24#include <linux/sched.h>
25#include <linux/tqueue.h>
26#include <linux/slab.h>
27#include <linux/string.h>
28#include <linux/timer.h>
29#include <linux/interrupt.h>
30#include <linux/in.h>
31#include <asm/io.h>
32#include <asm/system.h>
33#include <asm/bitops.h>
34
35#include <linux/netdevice.h>
36#include <linux/etherdevice.h>
37#include <linux/skbuff.h>
38#include <linux/if_arp.h>
39#include <linux/ioport.h>
40#include <linux/delay.h>
41#include <linux/init.h>
42
43#include "aironet4500.h"
44
45#define PCI_VENDOR_ID_AIRONET 0x14b9
46#define PCI_DEVICE_AIRONET_4800_1 0x1
47#define PCI_DEVICE_AIRONET_4800 0x4500
48#define PCI_DEVICE_AIRONET_4500 0x4800
49#define AIRONET4X00_IO_SIZE 0x40
50#define AIRONET4X00_CIS_SIZE 0x300
51#define AIRONET4X00_MEM_SIZE 0x300
52
53#define AIRONET4500_PCI 1
54#define AIRONET4500_PNP 2
55#define AIRONET4500_ISA 3
56#define AIRONET4500_365 4
57
58
59#ifdef CONFIG_AIRONET4500_PCI
60
61#include <linux/pci.h>
62
63static struct pci_device_id aironet4500_card_pci_tbl[] __devinitdata = {
64 { PCI_VENDOR_ID_AIRONET, PCI_DEVICE_AIRONET_4800_1, PCI_ANY_ID, PCI_ANY_ID, },
65 { PCI_VENDOR_ID_AIRONET, PCI_DEVICE_AIRONET_4800, PCI_ANY_ID, PCI_ANY_ID, },
66 { PCI_VENDOR_ID_AIRONET, PCI_DEVICE_AIRONET_4500, PCI_ANY_ID, PCI_ANY_ID, },
67 { }
68};
69MODULE_DEVICE_TABLE(pci, aironet4500_card_pci_tbl);
70MODULE_LICENSE("GPL");
71
72
73static int reverse_probe;
74
75
76static int awc_pci_init(struct net_device * dev, struct pci_dev *pdev,
77 int ioaddr, int cis_addr, int mem_addr,u8 pci_irq_line) ;
78
79
80int awc4500_pci_probe(struct net_device *dev)
81{
82 int cards_found = 0;
83 static int pci_index;
84 u8 pci_irq_line = 0;
85
86
87 unsigned char awc_pci_dev, awc_pci_bus;
88
89 if (!pci_present())
90 return -1;
91
92 for (;pci_index < 0xff; pci_index++) {
93 u16 vendor, device, pci_command, new_command;
94 u32 pci_memaddr;
95 u32 pci_ioaddr;
96 u32 pci_cisaddr;
97 struct pci_dev *pdev;
98
99 if (pcibios_find_class (PCI_CLASS_NETWORK_OTHER << 8,
100 reverse_probe ? 0xfe - pci_index : pci_index,
101 &awc_pci_bus, &awc_pci_dev) != PCIBIOS_SUCCESSFUL){
102 if (reverse_probe){
103 continue;
104 } else {
105 break;
106 }
107 }
108 pdev = pci_find_slot(awc_pci_bus, awc_pci_dev);
109 if (!pdev)
110 continue;
111 if (pci_enable_device(pdev))
112 continue;
113 vendor = pdev->vendor;
114 device = pdev->device;
115 pci_irq_line = pdev->irq;
116 pci_memaddr = pci_resource_start (pdev, 0);
117 pci_cisaddr = pci_resource_start (pdev, 1);
118 pci_ioaddr = pci_resource_start (pdev, 2);
119
120
121
122
123 if (vendor != PCI_VENDOR_ID_AIRONET)
124 continue;
125 if (device != PCI_DEVICE_AIRONET_4800_1 &&
126 device != PCI_DEVICE_AIRONET_4800 &&
127 device != PCI_DEVICE_AIRONET_4500 )
128 continue;
129
130
131
132
133
134
135
136 if (!request_region(pci_ioaddr, AIRONET4X00_IO_SIZE, "aironet4x00 ioaddr"))
137 continue;
138
139
140
141 mdelay(10);
142
143 pci_read_config_word(pdev, PCI_COMMAND, &pci_command);
144 new_command = pci_command | PCI_COMMAND_SERR;
145 if (pci_command != new_command)
146 pci_write_config_word(pdev, PCI_COMMAND, new_command);
147
148
149
150
151
152
153
154 if (device == PCI_DEVICE_AIRONET_4800)
155 pci_write_config_dword(pdev, 0x40, 0x40000000);
156
157 if (awc_pci_init(dev, pdev, pci_ioaddr,pci_cisaddr,pci_memaddr,pci_irq_line)){
158 printk(KERN_ERR "awc4800 pci init failed \n");
159 break;
160 }
161 dev = 0;
162 cards_found++;
163 }
164
165 return cards_found ? 0 : -ENODEV;
166}
167
168
169static int awc_pci_init(struct net_device * dev, struct pci_dev *pdev,
170 int ioaddr, int cis_addr, int mem_addr, u8 pci_irq_line) {
171
172 int i, allocd_dev = 0;
173
174 if (!dev) {
175 dev = init_etherdev(NULL, 0);
176 if (!dev)
177 return -ENOMEM;
178 allocd_dev = 1;
179 }
180 dev->priv = kmalloc(sizeof(struct awc_private),GFP_KERNEL );
181 if (!dev->priv) {
182 if (allocd_dev) {
183 unregister_netdev(dev);
184 kfree(dev);
185 }
186 return -ENOMEM;
187 }
188 memset(dev->priv,0,sizeof(struct awc_private));
189 if (!dev->priv) {
190 printk(KERN_CRIT "aironet4x00: could not allocate device private, some unstability may follow\n");
191 if (allocd_dev) {
192 unregister_netdev(dev);
193 kfree(dev);
194 }
195 return -ENOMEM;
196 };
197
198
199
200
201
202 dev->hard_start_xmit = &awc_start_xmit;
203
204 dev->get_stats = &awc_get_stats;
205
206 dev->change_mtu = awc_change_mtu;
207 dev->init = &awc_init;
208 dev->open = &awc_open;
209 dev->stop = &awc_close;
210 dev->base_addr = ioaddr;
211 dev->irq = pci_irq_line;
212 dev->tx_timeout = &awc_tx_timeout;
213 dev->watchdog_timeo = AWC_TX_TIMEOUT;
214
215
216 i = request_irq(dev->irq,awc_interrupt, SA_SHIRQ | SA_INTERRUPT, dev->name, dev);
217 if (i) {
218 kfree(dev->priv);
219 dev->priv = NULL;
220 if (allocd_dev) {
221 unregister_netdev(dev);
222 kfree(dev);
223 }
224 return i;
225 }
226
227 awc_private_init( dev);
228 awc_init(dev);
229
230 i=0;
231 while (aironet4500_devices[i] && i < MAX_AWCS-1) i++;
232 if (!aironet4500_devices[i]){
233 aironet4500_devices[i]=dev;
234 ((struct awc_private *)
235 aironet4500_devices[i]->priv)->card_type = AIRONET4500_PCI;
236
237 if (awc_proc_set_fun)
238 awc_proc_set_fun(i);
239 }
240
241
242
243
244
245
246 return 0;
247
248
249
250}
251
252#ifdef MODULE
253static void awc_pci_release(void) {
254
255
256 int i=0;
257
258 DEBUG(0, "awc_detach \n");
259
260 i=0;
261 while ( i < MAX_AWCS) {
262 if (!aironet4500_devices[i])
263 {i++; continue;};
264 if (((struct awc_private *)aironet4500_devices[i]->priv)->card_type != AIRONET4500_PCI)
265 {i++; continue;}
266
267 if (awc_proc_unset_fun)
268 awc_proc_unset_fun(i);
269 release_region(aironet4500_devices[i]->base_addr, AIRONET4X00_IO_SIZE);
270
271
272
273 unregister_netdev(aironet4500_devices[i]);
274 free_irq(aironet4500_devices[i]->irq,aironet4500_devices[i]);
275 kfree(aironet4500_devices[i]->priv);
276 kfree(aironet4500_devices[i]);
277
278 aironet4500_devices[i]=0;
279
280
281 i++;
282 }
283
284
285}
286
287
288#endif
289
290
291#endif
292
293#ifdef CONFIG_AIRONET4500_PNP
294
295#include <linux/isapnp.h>
296#define AIRONET4X00_IO_SIZE 0x40
297
298#define isapnp_logdev pci_dev
299#define isapnp_dev pci_bus
300#define isapnp_find_device isapnp_find_card
301#define isapnp_find_logdev isapnp_find_dev
302#define PNP_BUS bus
303#define PNP_BUS_NUMBER number
304#define PNP_DEV_NUMBER devfn
305
306
307int awc4500_pnp_hw_reset(struct net_device *dev){
308 struct isapnp_logdev *logdev;
309
310 DEBUG(0, "awc_pnp_reset \n");
311
312 if (!dev->priv ) {
313 printk("awc4500 no dev->priv in hw_reset\n");
314 return -1;
315 };
316
317 logdev = ((struct isapnp_logdev *) ((struct awc_private *)dev->priv)->bus);
318
319 if (!logdev ) {
320 printk("awc4500 no pnp logdev in hw_reset\n");
321 return -1;
322 };
323
324 if (isapnp_cfg_begin(logdev->PNP_BUS->PNP_BUS_NUMBER, logdev->PNP_DEV_NUMBER)<0)
325 printk("isapnp cfg failed at release \n");
326 isapnp_deactivate(logdev->PNP_DEV_NUMBER);
327 isapnp_cfg_end();
328
329 udelay(100);
330
331
332 if (isapnp_cfg_begin(logdev->PNP_BUS->PNP_BUS_NUMBER, logdev->PNP_DEV_NUMBER) < 0) {
333 printk("%s cfg begin failed in hw_reset for csn %x devnum %x \n",
334 dev->name, logdev->PNP_BUS->PNP_BUS_NUMBER, logdev->PNP_DEV_NUMBER);
335 return -EAGAIN;
336 }
337
338 isapnp_activate(logdev->PNP_DEV_NUMBER);
339 isapnp_cfg_end();
340
341 return 0;
342}
343
344int awc4500_pnp_probe(struct net_device *dev)
345{
346 int isa_index = 0;
347 int isa_irq_line = 0;
348 int isa_ioaddr = 0;
349 int card = 0;
350 int i=0;
351 struct isapnp_dev * pnp_dev ;
352 struct isapnp_logdev *logdev;
353
354 while (1) {
355
356 pnp_dev = isapnp_find_device(
357 ISAPNP_VENDOR('A','W','L'),
358 ISAPNP_DEVICE(1),
359 0);
360
361 if (!pnp_dev) break;
362
363 isa_index++;
364
365 logdev = isapnp_find_logdev(pnp_dev, ISAPNP_VENDOR('A','W','L'),
366 ISAPNP_FUNCTION(1),
367 0);
368 if (!logdev){
369 printk("No logical device found on Aironet board \n");
370 return -ENODEV;
371 }
372 if (isapnp_cfg_begin(logdev->PNP_BUS->PNP_BUS_NUMBER, logdev->PNP_DEV_NUMBER) < 0) {
373 printk("cfg begin failed for csn %x devnum %x \n",
374 logdev->PNP_BUS->PNP_BUS_NUMBER, logdev->PNP_DEV_NUMBER);
375 return -EAGAIN;
376 }
377 isapnp_activate(logdev->PNP_DEV_NUMBER);
378 isapnp_cfg_end();
379
380 isa_irq_line = logdev->irq;
381 isa_ioaddr = logdev->resource[0].start;
382 request_region(isa_ioaddr, AIRONET4X00_IO_SIZE, "aironet4x00 ioaddr");
383
384 if (!dev) {
385 dev = init_etherdev(NULL, 0);
386 if (!dev) {
387 release_region(isa_ioaddr, AIRONET4X00_IO_SIZE);
388 isapnp_cfg_begin(logdev->PNP_BUS->PNP_BUS_NUMBER,
389 logdev->PNP_DEV_NUMBER);
390 isapnp_deactivate(logdev->PNP_DEV_NUMBER);
391 isapnp_cfg_end();
392 return -ENOMEM;
393 }
394 }
395 dev->priv = kmalloc(sizeof(struct awc_private),GFP_KERNEL );
396 memset(dev->priv,0,sizeof(struct awc_private));
397 if (!dev->priv) {
398 printk(KERN_CRIT "aironet4x00: could not allocate device private, some unstability may follow\n");
399 return -1;
400 };
401 ((struct awc_private *)dev->priv)->bus = logdev;
402
403
404
405
406
407 dev->hard_start_xmit = &awc_start_xmit;
408
409 dev->get_stats = &awc_get_stats;
410
411 dev->change_mtu = awc_change_mtu;
412 dev->init = &awc_init;
413 dev->open = &awc_open;
414 dev->stop = &awc_close;
415 dev->base_addr = isa_ioaddr;
416 dev->irq = isa_irq_line;
417 dev->tx_timeout = &awc_tx_timeout;
418 dev->watchdog_timeo = AWC_TX_TIMEOUT;
419
420 netif_start_queue (dev);
421
422 request_irq(dev->irq,awc_interrupt , SA_SHIRQ | SA_INTERRUPT ,"Aironet 4X00",dev);
423
424 awc_private_init( dev);
425
426 ((struct awc_private *)dev->priv)->bus = logdev;
427
428 cli();
429 if ( awc_init(dev) ){
430 printk("card not found at irq %x io %lx\n",dev->irq, dev->base_addr);
431 if (card==0){
432 sti();
433 return -1;
434 }
435 sti();
436 break;
437 }
438 udelay(10);
439 sti();
440 i=0;
441 while (aironet4500_devices[i] && i < MAX_AWCS-1) i++;
442 if (!aironet4500_devices[i] && i < MAX_AWCS-1 ){
443 aironet4500_devices[i]=dev;
444
445 ((struct awc_private *)
446 aironet4500_devices[i]->priv)->card_type = AIRONET4500_PNP;
447
448 if (awc_proc_set_fun)
449 awc_proc_set_fun(i);
450 } else {
451 printk(KERN_CRIT "Out of resources (MAX_AWCS) \n");
452 return -1;
453 }
454
455 card++;
456 }
457
458 if (card == 0) return -ENODEV;
459 return 0;
460}
461
462#ifdef MODULE
463static void awc_pnp_release(void) {
464
465
466 int i=0;
467 struct isapnp_logdev *logdev;
468
469 DEBUG(0, "awc_detach \n");
470
471 i=0;
472 while ( i < MAX_AWCS) {
473 if (!aironet4500_devices[i])
474 {i++; continue;}
475 if (((struct awc_private *)aironet4500_devices[i]->priv)->card_type != AIRONET4500_PNP)
476 {i++; continue;}
477
478 logdev = ((struct isapnp_logdev *) ((struct awc_private *)aironet4500_devices[i]->priv)->bus);
479
480 if (!logdev )
481 printk("awc4500 no pnp logdev in pnp_release\n");
482
483 if (awc_proc_unset_fun)
484 awc_proc_unset_fun(i);
485 if (isapnp_cfg_begin(logdev->PNP_BUS->PNP_BUS_NUMBER, logdev->PNP_DEV_NUMBER)<0)
486 printk("isapnp cfg failed at release \n");
487 isapnp_deactivate(logdev->PNP_DEV_NUMBER);
488 isapnp_cfg_end();
489
490 release_region(aironet4500_devices[i]->base_addr, AIRONET4X00_IO_SIZE);
491
492
493
494 unregister_netdev(aironet4500_devices[i]);
495 free_irq(aironet4500_devices[i]->irq,aironet4500_devices[i]);
496 kfree(aironet4500_devices[i]->priv);
497 kfree(aironet4500_devices[i]);
498
499 aironet4500_devices[i]=0;
500
501
502 i++;
503 }
504
505
506}
507
508static struct isapnp_device_id id_table[] = {
509 { ISAPNP_ANY_ID, ISAPNP_ANY_ID,
510 ISAPNP_VENDOR('A','W','L'), ISAPNP_DEVICE(1), 0 },
511 {0}
512};
513
514MODULE_DEVICE_TABLE(isapnp, id_table);
515
516#endif
517#endif
518
519#ifdef CONFIG_AIRONET4500_ISA
520
521static int irq[] = {0,0,0,0,0};
522static int io[] = {0,0,0,0,0};
523
524
525
526
527
528MODULE_PARM(irq,"i");
529MODULE_PARM_DESC(irq,"Aironet 4x00 ISA non-PNP irqs,required");
530MODULE_PARM(io,"i");
531MODULE_PARM_DESC(io,"Aironet 4x00 ISA non-PNP ioports,required");
532
533
534
535int awc4500_isa_probe(struct net_device *dev)
536{
537
538
539 int isa_irq_line = 0;
540 int isa_ioaddr = 0;
541
542 int card = 0;
543 int i=0;
544
545 if (! io[0] || ! irq[0]){
546
547
548 return -ENODEV;
549 }
550
551 printk(KERN_WARNING " Aironet ISA Card in non-PNP(ISA) mode sometimes feels bad on interrupt \n");
552 printk(KERN_WARNING " Use aironet4500_pnp if any problems(i.e. card malfunctioning). \n");
553 printk(KERN_WARNING " Note that this isa probe is not friendly... must give exact parameters \n");
554
555 while (irq[card] != 0){
556
557 isa_ioaddr = io[card];
558 isa_irq_line = irq[card];
559
560 request_region(isa_ioaddr, AIRONET4X00_IO_SIZE, "aironet4x00 ioaddr");
561
562 if (!dev) {
563 dev = init_etherdev(NULL, 0);
564 if (!dev) {
565 release_region(isa_ioaddr, AIRONET4X00_IO_SIZE);
566 return (card == 0) ? -ENOMEM : 0;
567 }
568 }
569 dev->priv = kmalloc(sizeof(struct awc_private),GFP_KERNEL );
570 memset(dev->priv,0,sizeof(struct awc_private));
571 if (!dev->priv) {
572 printk(KERN_CRIT "aironet4x00: could not allocate device private, some unstability may follow\n");
573 return -1;
574 };
575
576
577
578
579
580 dev->hard_start_xmit = &awc_start_xmit;
581
582 dev->get_stats = &awc_get_stats;
583
584 dev->change_mtu = awc_change_mtu;
585 dev->init = &awc_init;
586 dev->open = &awc_open;
587 dev->stop = &awc_close;
588 dev->base_addr = isa_ioaddr;
589 dev->irq = isa_irq_line;
590 dev->tx_timeout = &awc_tx_timeout;
591 dev->watchdog_timeo = AWC_TX_TIMEOUT;
592
593 request_irq(dev->irq,awc_interrupt ,SA_INTERRUPT ,"Aironet 4X00",dev);
594
595 awc_private_init( dev);
596 if ( awc_init(dev) ){
597 printk("card not found at irq %x mem %x\n",irq[card],io[card]);
598 if (card==0)
599 return -1;
600 break;
601 }
602
603 i=0;
604 while (aironet4500_devices[i] && i < MAX_AWCS-1) i++;
605 if (!aironet4500_devices[i]){
606 aironet4500_devices[i]=dev;
607 ((struct awc_private *)
608 aironet4500_devices[i]->priv)->card_type = AIRONET4500_ISA;
609
610 if (awc_proc_set_fun)
611 awc_proc_set_fun(i);
612 }
613
614 card++;
615 }
616 if (card == 0 ) {
617 return -ENODEV;
618 };
619 return 0;
620}
621
622#ifdef MODULE
623static void awc_isa_release(void) {
624
625
626 int i=0;
627
628 DEBUG(0, "awc_detach \n");
629
630 i=0;
631 while ( i < MAX_AWCS) {
632
633 if (!aironet4500_devices[i])
634 {i++; continue;}
635 if (((struct awc_private *)aironet4500_devices[i]->priv)->card_type != AIRONET4500_ISA)
636 {i++; continue;}
637
638 if (awc_proc_unset_fun)
639 awc_proc_unset_fun(i);
640 release_region(aironet4500_devices[i]->base_addr, AIRONET4X00_IO_SIZE);
641
642
643
644 unregister_netdev(aironet4500_devices[i]);
645 free_irq(aironet4500_devices[i]->irq,aironet4500_devices[i]);
646 kfree(aironet4500_devices[i]->priv);
647 kfree(aironet4500_devices[i]);
648
649 aironet4500_devices[i]=0;
650
651
652 i++;
653 }
654
655
656}
657
658#endif
659
660#endif
661
662#ifdef CONFIG_AIRONET4500_I365
663
664#define port_range 0x40
665
666int awc_i365_offset_ports[] = {0x3e0,0x3e0,0x3e2,0x3e2};
667int awc_i365_data_ports [] = {0x3e1,0x3e1,0x3e3,0x3e3};
668int awc_i365_irq[] = {5,5,11,12};
669int awc_i365_io[] = {0x140,0x100,0x400,0x440};
670int awc_i365_sockets = 0;
671
672struct i365_socket {
673 int offset_port ;
674 int data_port;
675 int socket;
676 int irq;
677 int io;
678 int manufacturer;
679 int product;
680};
681
682inline u8 i365_in (struct i365_socket * s, int offset) {
683 outb(offset + (s->socket % 2)* 0x40, s->offset_port);
684 return inb(s->data_port);
685};
686
687inline void i365_out (struct i365_socket * s, int offset,int data){
688 outb(offset + (s->socket % 2)* 0x40 ,s->offset_port);
689 outb((data & 0xff),s->data_port) ;
690
691};
692
693void awc_i365_card_release(struct i365_socket * s){
694
695 i365_out(s, 0x5, 0);
696 i365_out(s, 0x6, 0x20);
697 i365_out(s, 0x7, 0);
698 i365_out(s, 0x3, 0);
699 i365_out(s, 0x2, 0);
700 i365_out(s, 0x2, i365_in(s, 0x2) & 0x7f );
701 i365_out(s, 0x2, 0);
702
703
704};
705int awc_i365_probe_once(struct i365_socket * s ){
706
707
708 int caps=i365_in(s, 0);
709 int ret;
710 unsigned long jiff;
711
712 unsigned char cis [0x3e3];
713 unsigned char * mem = phys_to_virt(0xd000);
714 int i;
715 int port ;
716
717 DEBUG(1," i365 control ID %x \n", caps);
718
719 if (caps & 0xC){
720 return 1;
721 };
722
723 ret = i365_in(s, 0x1);
724
725 if ((ret & 0xC0) != 0xC0){
726 printk("card in socket %d port %x not in known state, %x \n",
727 s->socket, s->offset_port, ret );
728 return -1;
729 };
730
731
732 awc_i365_card_release(s);
733
734
735 mdelay(100);
736
737 i365_out(s, 0x2, 0x10 );
738 mdelay(200);
739
740 i365_out(s, 0x2, 0x10 | 0x01 | 0x04 | 0x80);
741
742 mdelay(250);
743
744 if (!s->irq)
745 s->irq = 11;
746
747 i365_out(s, 0x3, 0x40 | 0x20 | s->irq);
748
749 jiff = jiffies;
750
751 while (jiffies-jiff < HZ )
752 if (i365_in(s,0x1) & 0x20)
753 break;
754
755 if (! (i365_in(s,0x1) & 0x20) ){
756 printk("irq enable timeout on socket %x \n", s->socket);
757 return -1;
758 };
759
760 i365_out(s,0x10,0xd0);
761 i365_out(s,0x11,0x0);
762 i365_out(s,0x12,0xd0);
763 i365_out(s,0x13,0x0);
764 i365_out(s,0x14,0x30 );
765 i365_out(s,0x15,0x3f | 0x40);
766 i365_out(s,0x06,0x01);
767
768 mdelay(10);
769
770 cis[0] = 0x45;
771
772
773
774
775
776
777 mem[0x3e0] = 0x45;
778
779 mdelay(10);
780
781 memcpy_fromio(cis,0xD000, 0x3e0);
782
783 for (i = 0; i <= 0x3e2; i++)
784 printk("%02x", mem[i]);
785 for (i = 0; i <= 0x3e2; i++)
786 printk("%c", mem[i]);
787
788 i=0;
789 while (i < 0x3e0){
790 if (cis[i] == 0xff)
791 break;
792 if (cis[i] != 0x20 ){
793 i = i + 2 + cis[i+1];
794 continue;
795 }else {
796 s->manufacturer = cis[i+2] | (cis[i+3]<<8);
797 s->product = cis[i+4] | (cis[i+5]<<8);
798 break;
799 };
800 i++;
801 };
802
803 DEBUG(1,"socket %x manufacturer %x product %x \n",
804 s->socket, s->manufacturer,s->product);
805
806 i365_out(s,0x07, 0x1 | 0x2);
807 mdelay(1);
808 port = s->io;
809 i365_out(s,0x08, port & 0xff);
810 i365_out(s,0x09, (port & 0xff00)/ 0x100);
811 i365_out(s,0x0A, (port+port_range) & 0xff);
812 i365_out(s,0x0B, ((port+port_range) & 0xff00) /0x100);
813
814 i365_out(s,0x06, 0x40);
815
816 mdelay(1);
817
818 i365_out(s,0x3e0,0x45);
819
820 outw(0x10, s->io);
821
822 jiff = jiffies;
823 while (!(inw(s->io + 0x30) & 0x10)){
824
825 if (jiffies - jiff > HZ ){
826
827 printk("timed out waitin for command ack \n");
828 break;
829 }
830 };
831
832
833 outw(0x10, s->io + 0x34);
834 mdelay(10);
835
836 return 0;
837
838};
839
840
841static int awc_i365_init(struct i365_socket * s) {
842
843 struct net_device * dev;
844 int i;
845
846
847 dev = init_etherdev(0, sizeof(struct awc_private) );
848
849
850 ether_setup(dev);
851
852 dev->hard_start_xmit = &awc_start_xmit;
853
854 dev->get_stats = &awc_get_stats;
855 dev->set_multicast_list = &awc_set_multicast_list;
856
857 dev->init = &awc_init;
858 dev->open = &awc_open;
859 dev->stop = &awc_close;
860 dev->irq = s->irq;
861 dev->base_addr = s->io;
862 dev->tx_timeout = &awc_tx_timeout;
863 dev->watchdog_timeo = AWC_TX_TIMEOUT;
864
865
866 awc_private_init( dev);
867
868 i=0;
869 while (aironet4500_devices[i] && i < MAX_AWCS-1) i++;
870 if (!aironet4500_devices[i]){
871 aironet4500_devices[i]=dev;
872
873 ((struct awc_private *)
874 aironet4500_devices[i]->priv)->card_type = AIRONET4500_365;
875
876 if (awc_proc_set_fun)
877 awc_proc_set_fun(i);
878 }
879
880 if (register_netdev(dev) != 0) {
881 printk(KERN_NOTICE "awc_cs: register_netdev() failed\n");
882 goto failed;
883 }
884
885 return 0;
886
887 failed:
888 return -1;
889}
890
891
892static void awc_i365_release(void) {
893
894
895 int i=0;
896
897 DEBUG(0, "awc_detach \n");
898
899 i=0;
900 while ( i < MAX_AWCS) {
901
902 if (!aironet4500_devices[i])
903 {i++; continue;}
904
905 if (((struct awc_private *)aironet4500_devices[i]->priv)->card_type != AIRONET4500_365)
906 {i++; continue;}
907
908 if (awc_proc_unset_fun)
909 awc_proc_unset_fun(i);
910
911 unregister_netdev(aironet4500_devices[i]);
912
913
914 kfree(aironet4500_devices[i]);
915
916 aironet4500_devices[i]=0;
917
918
919 i++;
920 }
921
922
923}
924
925
926
927
928
929
930
931int awc_i365_probe(void) {
932
933 int i = 1;
934 int k = 0;
935 int ret = 0;
936 int found=0;
937
938 struct i365_socket s;
939
940
941 if (!awc_i365_sockets) {
942 printk(" awc i82635 4x00: use bitfiel opts awc_i365_sockets=0x3 <- (1|2) to probe sockets 0 and 1\n");
943 return -1;
944 };
945
946 while (k < 4){
947 if (i & awc_i365_sockets){
948
949 s.offset_port = awc_i365_offset_ports[k];
950 s.data_port = awc_i365_data_ports[k];
951 s.socket = k;
952 s.manufacturer = 0;
953 s.product = 0;
954 s.irq = awc_i365_irq[k];
955 s.io = awc_i365_io[k];
956
957 ret = awc_i365_probe_once(&s);
958 if (!ret){
959 if (awc_i365_init(&s))
960 goto failed;
961 else found++;
962 } else if (ret == -1)
963 goto failed;
964 };
965 k++;
966 i *=2;
967 };
968
969 if (!found){
970 printk("no aironet 4x00 cards found\n");
971 return -1;
972 }
973 return 0;
974
975failed:
976 awc_i365_release();
977 return -1;
978
979
980}
981
982#endif
983
984#ifdef MODULE
985int init_module(void)
986{
987 int found = 0;
988
989 printk("%s\n ", awc_version);
990
991#ifdef CONFIG_AIRONET4500_PCI
992 if (awc4500_pci_probe(NULL) == -ENODEV){
993
994 } else {
995 found++;
996
997 }
998#endif
999#ifdef CONFIG_AIRONET4500_PNP
1000 if (awc4500_pnp_probe(NULL) == -ENODEV){
1001
1002 } else {
1003 found++;
1004
1005 }
1006#endif
1007#ifdef CONFIG_AIRONET4500_365
1008 if ( awc_i365_probe() == -1) {
1009
1010 } else {
1011 found++ ;
1012
1013 }
1014#endif
1015#ifdef CONFIG_AIRONET4500_ISA
1016 if (awc4500_isa_probe(NULL) == -ENODEV){
1017
1018 } else {
1019 found++;
1020
1021 }
1022#endif
1023 if (!found) {
1024 printk(KERN_ERR "No Aironet 4X00 cards were found. Note that for ISA \n cards you should use either automatic PNP mode or \n ISA mode with both io and irq param \n Aironet is also afraid of: being second PNP controller(by slot), having anything(brandname bios weirdnesses) in range 0x100-0x180 and maybe around 0xd0000\n If you PNP type card does not get found, try non-PNP switch before complainig. \n");
1025 return -1;
1026 }
1027 return 0;
1028
1029
1030}
1031
1032void cleanup_module(void)
1033{
1034 DEBUG(0, "awc_cs: unloading %c ",'\n');
1035#ifdef CONFIG_AIRONET4500_PCI
1036 awc_pci_release();
1037#endif
1038#ifdef CONFIG_AIRONET4500_PNP
1039 awc_pnp_release();
1040#endif
1041#ifdef CONFIG_AIRONET4500_365
1042 awc_i365_release();
1043#endif
1044#ifdef CONFIG_AIRONET4500_ISA
1045 awc_isa_release();
1046#endif
1047
1048}
1049#endif
1050