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