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