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 #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
63 static 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 { } /* Terminating entry */
68 };
69 MODULE_DEVICE_TABLE(pci, aironet4500_card_pci_tbl);
70 MODULE_LICENSE("GPL");
71
72
73 static int reverse_probe;
74
75
76 static 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
awc4500_pci_probe(struct net_device * dev)80 int awc4500_pci_probe(struct net_device *dev)
81 {
82 int cards_found = 0;
83 static int pci_index; /* Static, for multiple probe calls. */
84 u8 pci_irq_line = 0;
85 // int p;
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 // printk("\n pci capabilities %x and ptr %x \n",pci_caps,pci_caps_ptr);
121 /* Remove I/O space marker in bit 0. */
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 // if (check_region(pci_ioaddr, AIRONET4X00_IO_SIZE) ||
131 // check_region(pci_cisaddr, AIRONET4X00_CIS_SIZE) ||
132 // check_region(pci_memaddr, AIRONET4X00_MEM_SIZE)) {
133 // printk(KERN_ERR "aironet4X00 mem addrs not available for maping \n");
134 // continue;
135 // }
136 if (!request_region(pci_ioaddr, AIRONET4X00_IO_SIZE, "aironet4x00 ioaddr"))
137 continue;
138 // request_region(pci_cisaddr, AIRONET4X00_CIS_SIZE, "aironet4x00 cis");
139 // request_region(pci_memaddr, AIRONET4X00_MEM_SIZE, "aironet4x00 mem");
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 /* if (device == PCI_DEVICE_AIRONET_4800)
150 pci_write_config_dword(pdev, 0x40, 0x00000000);
151
152 udelay(1000);
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
awc_pci_init(struct net_device * dev,struct pci_dev * pdev,int ioaddr,int cis_addr,int mem_addr,u8 pci_irq_line)169 static 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 // ether_setup(dev);
199
200 // dev->tx_queue_len = tx_queue_len;
201
202 dev->hard_start_xmit = &awc_start_xmit;
203 // dev->set_config = &awc_config_misiganes,aga mitte awc_config;
204 dev->get_stats = &awc_get_stats;
205 // dev->set_multicast_list = &awc_set_multicast_list;
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 // if (register_netdev(dev) != 0) {
242 // printk(KERN_NOTICE "awc_cs: register_netdev() failed\n");
243 // goto failed;
244 // }
245
246 return 0;
247 // failed:
248 // return -1;
249
250 }
251
252 #ifdef MODULE
awc_pci_release(void)253 static void awc_pci_release(void) {
254
255 // long flags;
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 // release_region(pci_cisaddr, AIRONET4X00_CIS_SIZE, "aironet4x00 cis");
271 // release_region(pci_memaddr, AIRONET4X00_MEM_SIZE, "aironet4x00 mem");
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 //MODULE
289
290
291 #endif /* CONFIG_AIRONET4500_PCI */
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
awc4500_pnp_hw_reset(struct net_device * dev)307 int 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); /* activate device */
339 isapnp_cfg_end();
340
341 return 0;
342 }
343
awc4500_pnp_probe(struct net_device * dev)344 int 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); /* activate device */
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 // ether_setup(dev);
404
405 // dev->tx_queue_len = tx_queue_len;
406
407 dev->hard_start_xmit = &awc_start_xmit;
408 // dev->set_config = &awc_config_misiganes,aga mitte awc_config;
409 dev->get_stats = &awc_get_stats;
410 // dev->set_multicast_list = &awc_set_multicast_list;
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
awc_pnp_release(void)463 static void awc_pnp_release(void) {
464
465 // long flags;
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 // release_region(isa_cisaddr, AIRONET4X00_CIS_SIZE, "aironet4x00 cis");
492 // release_region(isa_memaddr, AIRONET4X00_MEM_SIZE, "aironet4x00 mem");
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
508 static 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
514 MODULE_DEVICE_TABLE(isapnp, id_table);
515
516 #endif //MODULE
517 #endif /* CONFIG_AIRONET4500_PNP */
518
519 #ifdef CONFIG_AIRONET4500_ISA
520
521 static int irq[] = {0,0,0,0,0};
522 static int io[] = {0,0,0,0,0};
523
524 /*
525 EXPORT_SYMBOL(irq);
526 EXPORT_SYMBOL(io);
527 */
528 MODULE_PARM(irq,"i");
529 MODULE_PARM_DESC(irq,"Aironet 4x00 ISA non-PNP irqs,required");
530 MODULE_PARM(io,"i");
531 MODULE_PARM_DESC(io,"Aironet 4x00 ISA non-PNP ioports,required");
532
533
534
awc4500_isa_probe(struct net_device * dev)535 int awc4500_isa_probe(struct net_device *dev)
536 {
537 // int cards_found = 0;
538 // static int isa_index; /* Static, for multiple probe calls. */
539 int isa_irq_line = 0;
540 int isa_ioaddr = 0;
541 // int p;
542 int card = 0;
543 int i=0;
544
545 if (! io[0] || ! irq[0]){
546
547 // printk(" Both irq and io params must be supplied for ISA mode !!!\n");
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 // ether_setup(dev);
577
578 // dev->tx_queue_len = tx_queue_len;
579
580 dev->hard_start_xmit = &awc_start_xmit;
581 // dev->set_config = &awc_config_misiganes,aga mitte awc_config;
582 dev->get_stats = &awc_get_stats;
583 // dev->set_multicast_list = &awc_set_multicast_list;
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
awc_isa_release(void)623 static void awc_isa_release(void) {
624
625 // long flags;
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 // release_region(isa_cisaddr, AIRONET4X00_CIS_SIZE, "aironet4x00 cis");
642 // release_region(isa_memaddr, AIRONET4X00_MEM_SIZE, "aironet4x00 mem");
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 //MODULE
659
660 #endif /* CONFIG_AIRONET4500_ISA */
661
662 #ifdef CONFIG_AIRONET4500_I365
663
664 #define port_range 0x40
665
666 int awc_i365_offset_ports[] = {0x3e0,0x3e0,0x3e2,0x3e2};
667 int awc_i365_data_ports [] = {0x3e1,0x3e1,0x3e3,0x3e3};
668 int awc_i365_irq[] = {5,5,11,12};
669 int awc_i365_io[] = {0x140,0x100,0x400,0x440};
670 int awc_i365_sockets = 0;
671
672 struct 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
i365_in(struct i365_socket * s,int offset)682 inline 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
i365_out(struct i365_socket * s,int offset,int data)687 inline 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
awc_i365_card_release(struct i365_socket * s)693 void awc_i365_card_release(struct i365_socket * s){
694
695 i365_out(s, 0x5, 0); // clearing ints
696 i365_out(s, 0x6, 0x20); // mem 16 bits
697 i365_out(s, 0x7, 0); // clear IO
698 i365_out(s, 0x3, 0); // gen ctrl reset + mem mode
699 i365_out(s, 0x2, 0); // reset power
700 i365_out(s, 0x2, i365_in(s, 0x2) & 0x7f ); // cardenable off
701 i365_out(s, 0x2, 0); // remove power
702
703
704 };
awc_i365_probe_once(struct i365_socket * s)705 int 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 // short rev = 0x3000;
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 ); // power enable
738 mdelay(200);
739
740 i365_out(s, 0x2, 0x10 | 0x01 | 0x04 | 0x80); //power enable
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); // enab mem reg bit
766 i365_out(s,0x06,0x01); // enab mem
767
768 mdelay(10);
769
770 cis[0] = 0x45;
771
772 // memcpy_toio( 0xd3e0, &(cis[0]),0x1);
773
774 // mem[0x3e0] = 0x0;
775 // mem[0] = 0x45;
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); // enable io 16bit
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); // enable io window
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
awc_i365_init(struct i365_socket * s)841 static 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 // dev->tx_queue_len = tx_queue_len;
850 ether_setup(dev);
851
852 dev->hard_start_xmit = &awc_start_xmit;
853 // dev->set_config = &awc_config_misiganes,aga mitte awc_config;
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
awc_i365_release(void)892 static void awc_i365_release(void) {
893
894 // long flags;
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 //kfree(aironet4500_devices[i]->priv);
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
awc_i365_probe(void)931 int 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 /* Always emit the version, before any failure. */
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
975 failed:
976 awc_i365_release();
977 return -1;
978
979
980 }
981
982 #endif /* CONFIG_AIRONET4500_I365 */
983
984 #ifdef MODULE
init_module(void)985 int 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 // printk("PCI 4X00 aironet cards not found\n");
994 } else {
995 found++;
996 // printk("PCI 4X00 found some cards \n");
997 }
998 #endif
999 #ifdef CONFIG_AIRONET4500_PNP
1000 if (awc4500_pnp_probe(NULL) == -ENODEV){
1001 // printk("PNP 4X00 aironet cards not found\n");
1002 } else {
1003 found++;
1004 // printk("PNP 4X00 found some cards \n");
1005 }
1006 #endif
1007 #ifdef CONFIG_AIRONET4500_365
1008 if ( awc_i365_probe() == -1) {
1009 // printk("PCMCIA 4X00 aironet cards not found for i365(without card services) initialization\n");
1010 } else {
1011 found++ ;
1012 // printk("PCMCIA 4X00 found some cards, take care, this code is not supposed to work yet \n");
1013 }
1014 #endif
1015 #ifdef CONFIG_AIRONET4500_ISA
1016 if (awc4500_isa_probe(NULL) == -ENODEV){
1017 // printk("ISA 4X00 aironet ISA-bus non-PNP-mode cards not found\n");
1018 } else {
1019 found++;
1020 // printk("ISA 4X00 found some cards \n");
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
cleanup_module(void)1032 void 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