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