Import 2.3.34
[davej-history.git] / drivers / net / aironet4500_card.c
blobb6a00e87549c58f932cb3d6fdb34ed7a6f3b6068
1 /*
2 * Aironet 4500 PCI-ISA-i365 driver
4 * Elmer Joandi, Januar 1999
5 * Copyright GPL
6 *
8 * Revision 0.1 ,started 30.12.1998
12 #ifdef MODULE
13 static const char *awc_version =
14 "aironet4500_cards.c v0.1 28/03/99 Elmer Joandi, elmer@ylenurme.ee.\n";
15 #endif
17 #include <linux/version.h>
18 #include <linux/config.h>
19 #include <linux/module.h>
21 #include <linux/kernel.h>
22 #include <linux/sched.h>
23 #include <linux/ptrace.h>
24 #include <linux/malloc.h>
25 #include <linux/string.h>
26 #include <linux/timer.h>
27 #include <linux/interrupt.h>
28 #include <linux/in.h>
29 #include <asm/io.h>
30 #include <asm/system.h>
31 #include <asm/bitops.h>
33 #include <linux/netdevice.h>
34 #include <linux/etherdevice.h>
35 #include <linux/skbuff.h>
36 #include <linux/if_arp.h>
37 #include <linux/ioport.h>
38 #include <linux/delay.h>
39 #if LINUX_VERSION_CODE < 0x20100
40 #include <linux/bios32.h>
41 #endif
43 #include "aironet4500.h"
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
53 #define AIRONET4500_PCI 1
54 #define AIRONET4500_PNP 2
55 #define AIRONET4500_ISA 3
56 #define AIRONET4500_365 4
59 #ifdef CONFIG_AIRONET4500_PCI
61 #include <linux/pci.h>
64 static int reverse_probe =0 ;
67 static int awc_pci_init(struct NET_DEVICE * dev, int pci_bus, int device_nr,
68 int ioaddr, int cis_addr, int mem_addr,u8 pci_irq_line) ;
71 int awc4500_pci_probe(struct NET_DEVICE *dev)
73 int cards_found = 0;
74 static int pci_index = 0; /* Static, for multiple probe calls. */
75 u8 pci_irq_line = 0;
76 // int p;
78 unsigned char awc_pci_dev, awc_pci_bus;
80 if (!pcibios_present())
81 return -1;
83 for (;pci_index < 0xff; pci_index++) {
84 u16 vendor, device, pci_command, new_command;
85 u32 pci_memaddr;
86 u32 pci_ioaddr;
87 u32 pci_cisaddr;
88 #if LINUX_VERSION_CODE < 0x20100
89 u16 pci_caps =0;
90 u8 pci_caps_ptr =0;
91 #endif
92 if (pcibios_find_class (PCI_CLASS_NETWORK_OTHER << 8,
93 reverse_probe ? 0xfe - pci_index : pci_index,
94 &awc_pci_bus, &awc_pci_dev) != PCIBIOS_SUCCESSFUL){
95 if (reverse_probe){
96 continue;
97 } else {
98 break;
101 pcibios_read_config_word(awc_pci_bus, awc_pci_dev,
102 PCI_VENDOR_ID, &vendor);
103 pcibios_read_config_word(awc_pci_bus, awc_pci_dev,
104 PCI_DEVICE_ID, &device);
105 #if LINUX_VERSION_CODE >= 0x20300
106 pci_irq_line = pci_find_slot(awc_pci_bus, awc_pci_dev)->irq;
107 pci_memaddr = pci_find_slot(awc_pci_bus, awc_pci_dev)->resource[0].start;
108 pci_cisaddr = pci_find_slot(awc_pci_bus, awc_pci_dev)->resource[1].start;
109 pci_ioaddr = pci_find_slot(awc_pci_bus, awc_pci_dev)->resource[2].start;
110 #else
111 #if LINUX_VERSION_CODE >= 0x20155
112 pci_irq_line = pci_find_slot(awc_pci_bus, awc_pci_dev)->irq;
113 pci_memaddr = pci_find_slot(awc_pci_bus, awc_pci_dev)->base_address[0];
114 pci_cisaddr = pci_find_slot(awc_pci_bus, awc_pci_dev)->base_address[1];
115 pci_ioaddr = pci_find_slot(awc_pci_bus, awc_pci_dev)->base_address[2];
116 #else
117 pcibios_read_config_dword(awc_pci_bus, awc_pci_dev,PCI_BASE_ADDRESS_0, &pci_memaddr);
118 pcibios_read_config_dword(awc_pci_bus, awc_pci_dev,PCI_BASE_ADDRESS_1, &pci_cisaddr);
119 pcibios_read_config_dword(awc_pci_bus, awc_pci_dev,PCI_BASE_ADDRESS_2, &pci_ioaddr);
120 pcibios_read_config_byte(awc_pci_bus, awc_pci_dev, PCI_INTERRUPT_LINE, &pci_irq_line);
121 pcibios_read_config_word(awc_pci_bus, awc_pci_dev,PCI_STATUS, &pci_caps);
122 pcibios_read_config_byte(awc_pci_bus, awc_pci_dev, 0x34, &pci_caps_ptr);
124 #endif // 2.2
125 #endif // 2.3
126 // printk("\n pci capabilities %x and ptr %x \n",pci_caps,pci_caps_ptr);
127 /* Remove I/O space marker in bit 0. */
129 if (vendor != PCI_VENDOR_ID_AIRONET)
130 continue;
131 if (device != PCI_DEVICE_AIRONET_4800_1 &&
132 device != PCI_DEVICE_AIRONET_4800 &&
133 device != PCI_DEVICE_AIRONET_4500 )
134 continue;
135 #if LINUX_VERSION_CODE < 0x20300
137 if (!(pci_ioaddr & 1)){
138 printk("awc4X00 ioaddr location mismatch \n");
139 return -1;
142 pci_ioaddr &= ~3;
143 pci_cisaddr &= ~0xf;
144 pci_memaddr &= ~0xf;
145 #endif
146 // if (check_region(pci_ioaddr, AIRONET4X00_IO_SIZE) ||
147 // check_region(pci_cisaddr, AIRONET4X00_CIS_SIZE) ||
148 // check_region(pci_memaddr, AIRONET4X00_MEM_SIZE)) {
149 // printk(KERN_ERR "aironet4X00 mem addrs not available for maping \n");
150 // continue;
151 // }
152 request_region(pci_ioaddr, AIRONET4X00_IO_SIZE, "aironet4x00 ioaddr");
153 // request_region(pci_cisaddr, AIRONET4X00_CIS_SIZE, "aironet4x00 cis");
154 // request_region(pci_memaddr, AIRONET4X00_MEM_SIZE, "aironet4x00 mem");
156 // pcibios_write_config_word(awc_pci_bus, awc_pci_dev,
157 // PCI_COMMAND, 0);
158 udelay(10000);
160 pcibios_read_config_word(awc_pci_bus, awc_pci_dev,
161 PCI_COMMAND, &pci_command);
162 new_command = pci_command |0x100 | PCI_COMMAND_MEMORY|PCI_COMMAND_IO;
163 if (pci_command != new_command) {
164 printk(KERN_INFO " The PCI BIOS has not enabled this"
165 " device! Updating PCI command %4.4x->%4.4x.\n",
166 pci_command, new_command);
167 pcibios_write_config_word(awc_pci_bus, awc_pci_dev,
168 PCI_COMMAND, new_command);
172 /* if (device == PCI_DEVICE_AIRONET_4800)
173 pcibios_write_config_dword(awc_pci_bus, awc_pci_dev,
174 0x40, 0x00000000);
176 udelay(1000);
178 if (device == PCI_DEVICE_AIRONET_4800)
179 pcibios_write_config_dword(awc_pci_bus, awc_pci_dev,
180 0x40, 0x40000000);
182 if (awc_pci_init(dev, awc_pci_bus, awc_pci_dev, pci_ioaddr,pci_cisaddr,pci_memaddr,pci_irq_line)){
183 printk(KERN_ERR "awc4800 pci init failed \n");
184 break;
186 dev = 0;
187 cards_found++;
190 return cards_found ? 0 : -ENODEV;
194 static int awc_pci_init(struct NET_DEVICE * dev, int pci_bus, int device_nr,
195 int ioaddr, int cis_addr, int mem_addr, u8 pci_irq_line) {
197 int i;
199 if (!dev) {
200 dev = init_etherdev(dev, 0 );
202 dev->priv = kmalloc(sizeof(struct awc_private),GFP_KERNEL );
203 memset(dev->priv,0,sizeof(struct awc_private));
204 if (!dev->priv) {
205 printk(KERN_CRIT "aironet4x00: could not allocate device private, some unstability may follow\n");
206 return -1;
209 // ether_setup(dev);
211 // dev->tx_queue_len = tx_queue_len;
213 dev->hard_start_xmit = &awc_start_xmit;
214 // dev->set_config = &awc_config_misiganes,aga mitte awc_config;
215 dev->get_stats = &awc_get_stats;
216 // dev->set_multicast_list = &awc_set_multicast_list;
217 dev->change_mtu = awc_change_mtu;
218 dev->init = &awc_init;
219 dev->open = &awc_open;
220 dev->stop = &awc_close;
221 dev->tbusy = 1;
222 dev->start = 0;
224 dev->base_addr = ioaddr;
227 dev->irq = pci_irq_line;
228 #if LINUX_VERSION_CODE > 0x20100
229 request_irq(dev->irq,awc_interrupt, SA_SHIRQ | SA_INTERRUPT ,"Aironet 4X00",dev);
230 #else
231 request_irq(dev->irq,awc_interrupt, SA_SHIRQ | SA_INTERRUPT ,"Aironet 4X00",dev);
232 #endif
233 awc_private_init( dev);
234 awc_init(dev);
236 i=0;
237 while (aironet4500_devices[i] && i < MAX_AWCS-1) i++;
238 if (!aironet4500_devices[i]){
239 aironet4500_devices[i]=dev;
240 ((struct awc_private *)
241 aironet4500_devices[i]->priv)->card_type = AIRONET4500_PCI;
243 if (awc_proc_set_fun)
244 awc_proc_set_fun(i);
247 dev->tbusy = 1;
248 dev->start = 0;
251 // if (register_netdev(dev) != 0) {
252 // printk(KERN_NOTICE "awc_cs: register_netdev() failed\n");
253 // goto failed;
254 // }
258 return 0;
259 // failed:
260 // return -1;
264 #ifdef MODULE
265 static void awc_pci_release(void) {
267 // long flags;
268 int i=0;
270 DEBUG(0, "awc_detach \n");
272 i=0;
273 while ( i < MAX_AWCS) {
274 if (!aironet4500_devices[i])
275 {i++; continue;};
276 if (((struct awc_private *)aironet4500_devices[i]->priv)->card_type != AIRONET4500_PCI)
277 {i++; continue;}
279 if (awc_proc_unset_fun)
280 awc_proc_unset_fun(i);
281 release_region(aironet4500_devices[i]->base_addr, AIRONET4X00_IO_SIZE);
282 // release_region(pci_cisaddr, AIRONET4X00_CIS_SIZE, "aironet4x00 cis");
283 // release_region(pci_memaddr, AIRONET4X00_MEM_SIZE, "aironet4x00 mem");
285 unregister_netdev(aironet4500_devices[i]);
286 free_irq(aironet4500_devices[i]->irq,aironet4500_devices[i]);
287 kfree_s(aironet4500_devices[i]->priv, sizeof(struct awc_private));
288 kfree_s(aironet4500_devices[i], sizeof(struct NET_DEVICE));
290 aironet4500_devices[i]=0;
293 i++;
300 #endif //MODULE
303 #endif /* CONFIG_AIRONET4500_PCI */
305 #ifdef CONFIG_AIRONET4500_PNP
307 #if LINUX_VERSION_CODE > 0x20300
308 #include <linux/isapnp.h>
309 #else
310 #include "isapnp.h"
311 #endif
312 #define AIRONET4X00_IO_SIZE 0x40
314 #if LINUX_VERSION_CODE > 0x20300
315 #define isapnp_logdev pci_dev
316 #define isapnp_dev pci_bus
317 #define isapnp_find_device isapnp_find_card
318 #define isapnp_find_logdev isapnp_find_dev
319 #define PNP_BUS bus
320 #define PNP_BUS_NUMBER number
321 #define PNP_DEV_NUMBER devfn
322 #else
323 #define PNP_BUS dev
324 #define PNP_BUS_NUMBER csn
325 #define PNP_DEV_NUMBER number
326 #endif
328 int awc4500_pnp_hw_reset(struct NET_DEVICE *dev){
329 struct isapnp_logdev *logdev;
330 #if LINUX_VERSION_CODE < 0x20300
331 struct isapnp_config cfg;
332 #endif
333 DEBUG(0, "awc_pnp_reset \n");
335 if (!dev->priv ) {
336 printk("awc4500 no dev->priv in hw_reset\n");
337 return -1;
340 logdev = ((struct isapnp_logdev *) ((struct awc_private *)dev->priv)->bus);
342 if (!logdev ) {
343 printk("awc4500 no pnp logdev in hw_reset\n");
344 return -1;
347 if (isapnp_cfg_begin(logdev->PNP_BUS->PNP_BUS_NUMBER, logdev->PNP_DEV_NUMBER)<0)
348 printk("isapnp cfg failed at release \n");
349 isapnp_deactivate(logdev->PNP_DEV_NUMBER);
350 isapnp_cfg_end();
352 udelay(100);
355 if (isapnp_cfg_begin(logdev->PNP_BUS->PNP_BUS_NUMBER, logdev->PNP_DEV_NUMBER) < 0) {
356 printk("%s cfg begin failed in hw_reset for csn %x devnum %x \n",
357 dev->name, logdev->PNP_BUS->PNP_BUS_NUMBER, logdev->PNP_DEV_NUMBER);
358 return -EAGAIN;
360 #if LINUX_VERSION_CODE < 0x20300
361 if (isapnp_config_init(&cfg, logdev)<0) {
362 printk("cfg init failed \n");
363 isapnp_cfg_end();
364 return -EAGAIN;
366 cfg.port[0] = dev->base_addr;
367 cfg.irq[0] = dev->irq;
369 if (isapnp_configure(&cfg)<0) {
370 printk("%s hw_reset, isapnp configure failed (out of resources?)\n",dev->name);
371 isapnp_cfg_end();
372 return -ENOMEM;
374 #else
376 #endif
377 isapnp_activate(logdev->PNP_DEV_NUMBER); /* activate device */
378 isapnp_cfg_end();
380 return 0;
383 int awc4500_pnp_probe(struct NET_DEVICE *dev)
385 int isa_index = 0;
386 int isa_irq_line = 0;
387 int isa_ioaddr = 0;
388 int card = 0;
389 int i=0;
390 struct isapnp_dev * pnp_dev ;
391 struct isapnp_logdev *logdev;
392 #if LINUX_VERSION_CODE < 0x20300
393 struct isapnp_config cfg;
394 #endif
396 while (1) {
398 pnp_dev = isapnp_find_device(
399 ISAPNP_VENDOR('A','W','L'),
400 ISAPNP_DEVICE(1),
401 #if LINUX_VERSION_CODE < 0x20300
402 isa_index
403 #else
405 #endif
408 if (!pnp_dev) break;
410 isa_index++;
412 logdev = isapnp_find_logdev(pnp_dev, ISAPNP_VENDOR('A','W','L'),
413 ISAPNP_FUNCTION(1),
415 if (!logdev){
416 printk("No logical device found on Aironet board \n");
417 return -ENODEV;
419 if (isapnp_cfg_begin(logdev->PNP_BUS->PNP_BUS_NUMBER, logdev->PNP_DEV_NUMBER) < 0) {
420 printk("cfg begin failed for csn %x devnum %x \n",
421 logdev->PNP_BUS->PNP_BUS_NUMBER, logdev->PNP_DEV_NUMBER);
422 return -EAGAIN;
424 #if LINUX_VERSION_CODE < 0x20300
425 if (isapnp_config_init(&cfg, logdev)<0) {
426 printk("cfg init failed \n");
427 isapnp_cfg_end();
428 return -EAGAIN;
430 if (isapnp_configure(&cfg)<0) {
431 printk("isapnp configure failed (out of resources?)\n");
432 isapnp_cfg_end();
433 return -ENOMEM;
435 #endif
436 isapnp_activate(logdev->PNP_DEV_NUMBER); /* activate device */
437 isapnp_cfg_end();
439 #if LINUX_VERSION_CODE < 0x20300
440 isa_ioaddr = cfg.port[0];
441 isa_irq_line = cfg.irq[0];
442 #else
443 isa_irq_line = logdev->irq;
444 isa_ioaddr = logdev->resource[0].start;
445 #endif
446 request_region(isa_ioaddr, AIRONET4X00_IO_SIZE, "aironet4x00 ioaddr");
448 if (!dev) {
449 dev = init_etherdev(dev, 0 );
451 dev->priv = kmalloc(sizeof(struct awc_private),GFP_KERNEL );
452 memset(dev->priv,0,sizeof(struct awc_private));
453 if (!dev->priv) {
454 printk(KERN_CRIT "aironet4x00: could not allocate device private, some unstability may follow\n");
455 return -1;
457 ((struct awc_private *)dev->priv)->bus = logdev;
459 // ether_setup(dev);
461 // dev->tx_queue_len = tx_queue_len;
463 dev->hard_start_xmit = &awc_start_xmit;
464 // dev->set_config = &awc_config_misiganes,aga mitte awc_config;
465 dev->get_stats = &awc_get_stats;
466 // dev->set_multicast_list = &awc_set_multicast_list;
467 dev->change_mtu = awc_change_mtu;
468 dev->init = &awc_init;
469 dev->open = &awc_open;
470 dev->stop = &awc_close;
471 dev->tbusy = 1;
472 dev->start = 0;
474 dev->base_addr = isa_ioaddr;
477 dev->irq = isa_irq_line;
478 #if LINUX_VERSION_CODE > 0x20100
479 request_irq(dev->irq,awc_interrupt , SA_SHIRQ | SA_INTERRUPT ,"Aironet 4X00",dev);
480 #else
481 request_irq(dev->irq,awc_interrupt, SA_SHIRQ ,"Aironet 4X00",dev);
482 #endif
484 awc_private_init( dev);
486 ((struct awc_private *)dev->priv)->bus = logdev;
488 cli();
489 if ( awc_init(dev) ){
490 printk("card not found at irq %x io %lx\n",dev->irq, dev->base_addr);
491 if (card==0){
492 sti();
493 return -1;
495 sti();
496 break;
498 udelay(10);
499 sti();
500 i=0;
501 while (aironet4500_devices[i] && i < MAX_AWCS-1) i++;
502 if (!aironet4500_devices[i] && i < MAX_AWCS-1 ){
503 aironet4500_devices[i]=dev;
505 ((struct awc_private *)
506 aironet4500_devices[i]->priv)->card_type = AIRONET4500_PNP;
508 if (awc_proc_set_fun)
509 awc_proc_set_fun(i);
510 } else {
511 printk(KERN_CRIT "Out of resources (MAX_AWCS) \n");
512 return -1;
515 dev->tbusy = 1;
516 dev->start = 0;
518 card++;
521 if (card == 0) return -ENODEV;
522 return 0;
525 #ifdef MODULE
526 static void awc_pnp_release(void) {
528 // long flags;
529 int i=0;
530 struct isapnp_logdev *logdev;
532 DEBUG(0, "awc_detach \n");
534 i=0;
535 while ( i < MAX_AWCS) {
536 if (!aironet4500_devices[i])
537 {i++; continue;}
538 if (((struct awc_private *)aironet4500_devices[i]->priv)->card_type != AIRONET4500_PNP)
539 {i++; continue;}
541 logdev = ((struct isapnp_logdev *) ((struct awc_private *)aironet4500_devices[i]->priv)->bus);
543 if (!logdev )
544 printk("awc4500 no pnp logdev in pnp_release\n");
546 if (awc_proc_unset_fun)
547 awc_proc_unset_fun(i);
548 if (isapnp_cfg_begin(logdev->PNP_BUS->PNP_BUS_NUMBER, logdev->PNP_DEV_NUMBER)<0)
549 printk("isapnp cfg failed at release \n");
550 isapnp_deactivate(logdev->PNP_DEV_NUMBER);
551 isapnp_cfg_end();
553 release_region(aironet4500_devices[i]->base_addr, AIRONET4X00_IO_SIZE);
554 // release_region(isa_cisaddr, AIRONET4X00_CIS_SIZE, "aironet4x00 cis");
555 // release_region(isa_memaddr, AIRONET4X00_MEM_SIZE, "aironet4x00 mem");
557 unregister_netdev(aironet4500_devices[i]);
558 free_irq(aironet4500_devices[i]->irq,aironet4500_devices[i]);
559 kfree_s(aironet4500_devices[i]->priv, sizeof(struct awc_private));
560 kfree_s(aironet4500_devices[i], sizeof(struct NET_DEVICE));
562 aironet4500_devices[i]=0;
565 i++;
571 #endif //MODULE
572 #endif /* CONFIG_AIRONET4500_PNP */
574 #ifdef CONFIG_AIRONET4500_ISA
576 static int irq[] = {0,0,0,0,0};
577 static int io[] = {0,0,0,0,0};
580 EXPORT_SYMBOL(irq);
581 EXPORT_SYMBOL(io);
583 #if LINUX_VERSION_CODE >= 0x20100
584 MODULE_PARM(irq,"i");
585 MODULE_PARM_DESC(irq,"Aironet 4x00 ISA non-PNP irqs,required");
586 MODULE_PARM(io,"i");
587 MODULE_PARM_DESC(io,"Aironet 4x00 ISA non-PNP ioports,required");
588 #endif
592 int awc4500_isa_probe(struct NET_DEVICE *dev)
594 // int cards_found = 0;
595 // static int isa_index = 0; /* Static, for multiple probe calls. */
596 int isa_irq_line = 0;
597 int isa_ioaddr = 0;
598 // int p;
599 int card = 0;
600 int i=0;
602 if (! io[0] || ! irq[0]){
604 printk(" Both irq and io params must be supplied for ISA mode !!!\n");
605 return -ENODEV;
608 printk(KERN_WARNING " Aironet ISA Card in non-PNP(ISA) mode sometimes feels bad on interrupt \n");
609 printk(KERN_WARNING " Use aironet4500_pnp if any problems(i.e. card malfunctioning). \n");
610 printk(KERN_WARNING " Note that this isa probe is not friendly... must give exact parameters \n");
612 while (irq[card] !=0){
614 isa_ioaddr = io[card];
615 isa_irq_line = irq[card];
617 request_region(isa_ioaddr, AIRONET4X00_IO_SIZE, "aironet4x00 ioaddr");
619 if (!dev) {
620 dev = init_etherdev(dev, 0 );
622 dev->priv = kmalloc(sizeof(struct awc_private),GFP_KERNEL );
623 memset(dev->priv,0,sizeof(struct awc_private));
624 if (!dev->priv) {
625 printk(KERN_CRIT "aironet4x00: could not allocate device private, some unstability may follow\n");
626 return -1;
629 // ether_setup(dev);
631 // dev->tx_queue_len = tx_queue_len;
633 dev->hard_start_xmit = &awc_start_xmit;
634 // dev->set_config = &awc_config_misiganes,aga mitte awc_config;
635 dev->get_stats = &awc_get_stats;
636 // dev->set_multicast_list = &awc_set_multicast_list;
637 dev->change_mtu = awc_change_mtu;
638 dev->init = &awc_init;
639 dev->open = &awc_open;
640 dev->stop = &awc_close;
641 dev->tbusy = 1;
642 dev->start = 0;
644 dev->base_addr = isa_ioaddr;
647 dev->irq = isa_irq_line;
649 #if LINUX_VERSION_CODE > 0x20100
650 request_irq(dev->irq,awc_interrupt ,SA_INTERRUPT ,"Aironet 4X00",dev);
651 #else
652 request_irq(dev->irq,awc_interrupt ,0 ,"Aironet 4X00",dev);
653 #endif
655 awc_private_init( dev);
656 if ( awc_init(dev) ){
657 printk("card not found at irq %x mem %x\n",irq[card],io[card]);
658 if (card==0)
659 return -1;
660 break;
663 i=0;
664 while (aironet4500_devices[i] && i < MAX_AWCS-1) i++;
665 if (!aironet4500_devices[i]){
666 aironet4500_devices[i]=dev;
667 ((struct awc_private *)
668 aironet4500_devices[i]->priv)->card_type = AIRONET4500_ISA;
670 if (awc_proc_set_fun)
671 awc_proc_set_fun(i);
674 dev->tbusy = 1;
675 dev->start = 0;
677 card++;
679 if (card == 0 ) {
680 return -ENODEV;
682 return 0;
685 #ifdef MODULE
686 static void awc_isa_release(void) {
688 // long flags;
689 int i=0;
691 DEBUG(0, "awc_detach \n");
693 i=0;
694 while ( i < MAX_AWCS) {
696 if (!aironet4500_devices[i])
697 {i++; continue;}
698 if (((struct awc_private *)aironet4500_devices[i]->priv)->card_type != AIRONET4500_ISA)
699 {i++; continue;}
701 if (awc_proc_unset_fun)
702 awc_proc_unset_fun(i);
703 release_region(aironet4500_devices[i]->base_addr, AIRONET4X00_IO_SIZE);
704 // release_region(isa_cisaddr, AIRONET4X00_CIS_SIZE, "aironet4x00 cis");
705 // release_region(isa_memaddr, AIRONET4X00_MEM_SIZE, "aironet4x00 mem");
707 unregister_netdev(aironet4500_devices[i]);
708 free_irq(aironet4500_devices[i]->irq,aironet4500_devices[i]);
709 kfree_s(aironet4500_devices[i]->priv, sizeof(struct awc_private));
710 kfree_s(aironet4500_devices[i], sizeof(struct NET_DEVICE));
712 aironet4500_devices[i]=0;
715 i++;
721 #endif //MODULE
723 #endif /* CONFIG_AIRONET4500_ISA */
725 #ifdef CONFIG_AIRONET4500_365
727 #define port_range 0x40
729 int awc_i365_offset_ports[] = {0x3e0,0x3e0,0x3e2,0x3e2};
730 int awc_i365_data_ports [] = {0x3e1,0x3e1,0x3e3,0x3e3};
731 int awc_i365_irq[] = {5,5,11,12};
732 int awc_i365_io[] = {0x140,0x100,0x400,0x440};
733 int awc_i365_sockets = 0;
735 struct i365_socket {
736 int offset_port ;
737 int data_port;
738 int socket;
739 int irq;
740 int io;
741 int manufacturer;
742 int product;
745 inline u8 i365_in (struct i365_socket * s, int offset) {
746 outb(offset + (s->socket % 2)* 0x40, s->offset_port);
747 return inb(s->data_port);
750 inline void i365_out (struct i365_socket * s, int offset,int data){
751 outb(offset + (s->socket % 2)* 0x40 ,s->offset_port);
752 outb((data & 0xff),s->data_port) ;
756 void awc_i365_card_release(struct i365_socket * s){
758 i365_out(s, 0x5, 0); // clearing ints
759 i365_out(s, 0x6, 0x20); // mem 16 bits
760 i365_out(s, 0x7, 0); // clear IO
761 i365_out(s, 0x3, 0); // gen ctrl reset + mem mode
762 i365_out(s, 0x2, 0); // reset power
763 i365_out(s, 0x2, i365_in(s, 0x2) & 0x7f ); // cardenable off
764 i365_out(s, 0x2, 0); // remove power
768 int awc_i365_probe_once(struct i365_socket * s ){
771 int caps=i365_in(s, 0);
772 int ret;
773 unsigned long jiff;
774 // short rev = 0x3000;
775 unsigned char cis [0x3e3];
776 unsigned char * mem = phys_to_virt(0xd000);
777 int i;
778 int port ;
780 DEBUG(1," i365 control ID %x \n", caps);
782 if (caps & 0xC){
783 return 1;
786 ret = i365_in(s, 0x1);
788 if ((ret & 0xC0) != 0xC0){
789 printk("card in socket %d port %x not in known state, %x \n",
790 s->socket, s->offset_port, ret );
791 return -1;
795 awc_i365_card_release(s);
798 udelay(100000);
800 i365_out(s, 0x2, 0x10 ); // power enable
801 udelay(200000);
803 i365_out(s, 0x2, 0x10 | 0x01 | 0x04 | 0x80); //power enable
805 udelay(250000);
807 if (!s->irq)
808 s->irq = 11;
810 i365_out(s, 0x3, 0x40 | 0x20 | s->irq);
812 jiff = jiffies;
814 while (jiffies-jiff < HZ )
815 if (i365_in(s,0x1) & 0x20)
816 break;
818 if (! (i365_in(s,0x1) & 0x20) ){
819 printk("irq enable timeout on socket %x \n", s->socket);
820 return -1;
823 i365_out(s,0x10,0xd0);
824 i365_out(s,0x11,0x0);
825 i365_out(s,0x12,0xd0);
826 i365_out(s,0x13,0x0);
827 i365_out(s,0x14,0x30 );
828 i365_out(s,0x15,0x3f | 0x40); // enab mem reg bit
829 i365_out(s,0x06,0x01); // enab mem
831 udelay(10000);
833 cis[0] = 0x45;
835 // memcpy_toio( 0xd3e0, &(cis[0]),0x1);
837 // mem[0x3e0] = 0x0;
838 // mem[0] = 0x45;
840 mem[0x3e0] = 0x45;
842 udelay(10000);
844 memcpy_fromio(cis,0xD000, 0x3e0);
846 for (i = 0; i <= 0x3e2; i++)
847 printk("%02x", mem[i]);
848 for (i = 0; i <= 0x3e2; i++)
849 printk("%c", mem[i]);
851 i=0;
852 while (i < 0x3e0){
853 if (cis[i] == 0xff)
854 break;
855 if (cis[i] != 0x20 ){
856 i = i + 2 + cis[i+1];
857 continue;
858 }else {
859 s->manufacturer = cis[i+2] | (cis[i+3]<<8);
860 s->product = cis[i+4] | (cis[i+5]<<8);
861 break;
863 i++;
866 DEBUG(1,"socket %x manufacturer %x product %x \n",
867 s->socket, s->manufacturer,s->product);
869 i365_out(s,0x07, 0x1 | 0x2); // enable io 16bit
870 udelay(1000);
871 port = s->io;
872 i365_out(s,0x08, port & 0xff);
873 i365_out(s,0x09, (port & 0xff00)/ 0x100);
874 i365_out(s,0x0A, (port+port_range) & 0xff);
875 i365_out(s,0x0B, ((port+port_range) & 0xff00) /0x100);
877 i365_out(s,0x06, 0x40); // enable io window
879 udelay(1000);
881 i365_out(s,0x3e0,0x45);
883 outw(0x10, s->io);
885 jiff = jiffies;
886 while (!(inw(s->io + 0x30) & 0x10)){
888 if (jiffies - jiff > HZ ){
890 printk("timed out waitin for command ack \n");
891 break;
896 outw(0x10, s->io + 0x34);
897 udelay(10000);
899 return 0;
907 static int awc_i365_init(struct i365_socket * s) {
909 struct NET_DEVICE * dev;
910 int i;
913 dev = init_etherdev(0, sizeof(struct awc_private) );
915 // dev->tx_queue_len = tx_queue_len;
916 ether_setup(dev);
918 dev->hard_start_xmit = &awc_start_xmit;
919 // dev->set_config = &awc_config_misiganes,aga mitte awc_config;
920 dev->get_stats = &awc_get_stats;
921 dev->set_multicast_list = &awc_set_multicast_list;
923 dev->init = &awc_init;
924 dev->open = &awc_open;
925 dev->stop = &awc_close;
926 dev->tbusy = 1;
927 dev->start = 0;
928 dev->irq = s->irq;
929 dev->base_addr = s->io;
932 awc_private_init( dev);
934 i=0;
935 while (aironet4500_devices[i] && i < MAX_AWCS-1) i++;
936 if (!aironet4500_devices[i]){
937 aironet4500_devices[i]=dev;
939 ((struct awc_private *)
940 aironet4500_devices[i]->priv)->card_type = AIRONET4500_365;
942 if (awc_proc_set_fun)
943 awc_proc_set_fun(i);
946 dev->tbusy = 1;
947 dev->start = 0;
950 if (register_netdev(dev) != 0) {
951 printk(KERN_NOTICE "awc_cs: register_netdev() failed\n");
952 goto failed;
957 return 0;
959 failed:
960 return -1;
964 static void awc_i365_release(void) {
966 // long flags;
967 int i=0;
969 DEBUG(0, "awc_detach \n");
971 i=0;
972 while ( i < MAX_AWCS) {
974 if (!aironet4500_devices[i])
975 {i++; continue;}
977 if (((struct awc_private *)aironet4500_devices[i]->priv)->card_type != AIRONET4500_365)
978 {i++; continue;}
980 if (awc_proc_unset_fun)
981 awc_proc_unset_fun(i);
983 unregister_netdev(aironet4500_devices[i]);
985 //kfree_s(aironet4500_devices[i]->priv, sizeof(struct awc_private));
986 kfree_s(aironet4500_devices[i], sizeof(struct NET_DEVICE));
988 aironet4500_devices[i]=0;
991 i++;
1003 int awc_i365_probe(void) {
1005 int i = 1;
1006 int k = 0;
1007 int ret = 0;
1008 int found=0;
1010 struct i365_socket s;
1011 /* Always emit the version, before any failure. */
1013 if (!awc_i365_sockets) {
1014 printk(" awc i82635 4x00: use bitfiel opts awc_i365_sockets=0x3 <- (1|2) to probe sockets 0 and 1\n");
1015 return -1;
1018 while (k < 4){
1019 if (i & awc_i365_sockets){
1021 s.offset_port = awc_i365_offset_ports[k];
1022 s.data_port = awc_i365_data_ports[k];
1023 s.socket = k;
1024 s.manufacturer = 0;
1025 s.product = 0;
1026 s.irq = awc_i365_irq[k];
1027 s.io = awc_i365_io[k];
1029 ret = awc_i365_probe_once(&s);
1030 if (!ret){
1031 if (awc_i365_init(&s))
1032 goto failed;
1033 else found++;
1034 } else if (ret == -1)
1035 goto failed;
1037 k++;
1038 i *=2;
1041 if (!found){
1042 printk("no aironet 4x00 cards found\n");
1043 return -1;
1045 return 0;
1047 failed:
1048 awc_i365_release();
1049 return -1;
1054 #endif /* CONFIG_AIRONET4500_365 */
1056 #ifdef MODULE
1057 int init_module(void)
1059 int found = 0;
1061 printk("%s\n ", awc_version);
1063 #ifdef CONFIG_AIRONET4500_PCI
1064 if (awc4500_pci_probe(NULL) == -ENODEV){
1065 printk("PCI 4X00 aironet cards not found\n");
1066 } else {
1067 found++;
1068 printk("PCI 4X00 found some cards \n");
1070 #endif
1071 #ifdef CONFIG_AIRONET4500_PNP
1072 if (awc4500_pnp_probe(NULL) == -ENODEV){
1073 printk("PNP 4X00 aironet cards not found\n");
1074 } else {
1075 found++;
1076 printk("PNP 4X00 found some cards \n");
1078 #endif
1079 #ifdef CONFIG_AIRONET4500_365
1080 if ( awc_i365_probe() == -1) {
1081 printk("PCMCIA 4X00 aironet cards not found for i365(without card services) initialization\n");
1082 } else {
1083 found++ ;
1084 printk("PCMCIA 4X00 found some cards, take care, this code is not supposed to work yet \n");
1086 #endif
1087 #ifdef CONFIG_AIRONET4500_ISA
1088 if (awc4500_isa_probe(NULL) == -ENODEV){
1089 printk("ISA 4X00 aironet ISA-bus non-PNP-mode cards not found\n");
1090 } else {
1091 found++;
1092 printk("ISA 4X00 found some cards \n");
1094 #endif
1095 if (!found) return -1;
1096 return 0;
1101 void cleanup_module(void)
1103 DEBUG(0, "awc_cs: unloading %c ",'\n');
1104 #ifdef CONFIG_AIRONET4500_PCI
1105 awc_pci_release();
1106 #endif
1107 #ifdef CONFIG_AIRONET4500_PNP
1108 awc_pnp_release();
1109 #endif
1110 #ifdef CONFIG_AIRONET4500_365
1111 awc_i365_release();
1112 #endif
1113 #ifdef CONFIG_AIRONET4500_ISA
1114 awc_isa_release();
1115 #endif
1118 #endif