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
15static 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
63static 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};
69MODULE_DEVICE_TABLE(pci, aironet4500_card_pci_tbl);
70MODULE_LICENSE("GPL");
71
72
73static int reverse_probe;
74
75
76static 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
80int 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
169static 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
253static 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
307int 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
344int 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
463static 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
508static 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
514MODULE_DEVICE_TABLE(isapnp, id_table);
515
516#endif //MODULE
517#endif /* CONFIG_AIRONET4500_PNP */
518
519#ifdef  CONFIG_AIRONET4500_ISA
520
521static int irq[] = {0,0,0,0,0};
522static int io[] = {0,0,0,0,0};
523
524/*
525	EXPORT_SYMBOL(irq);
526	EXPORT_SYMBOL(io);
527*/
528MODULE_PARM(irq,"i");
529MODULE_PARM_DESC(irq,"Aironet 4x00 ISA non-PNP irqs,required");
530MODULE_PARM(io,"i");
531MODULE_PARM_DESC(io,"Aironet 4x00 ISA non-PNP ioports,required");
532
533
534
535int 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
623static 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
666int awc_i365_offset_ports[] = {0x3e0,0x3e0,0x3e2,0x3e2};
667int awc_i365_data_ports [] = {0x3e1,0x3e1,0x3e3,0x3e3};
668int awc_i365_irq[]	= {5,5,11,12};
669int awc_i365_io[]	= {0x140,0x100,0x400,0x440};
670int awc_i365_sockets	= 0;
671
672struct 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
682inline 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
687inline 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
693void 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};
705int 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
841static 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
892static 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
931int 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
975failed:
976	awc_i365_release();
977	return -1;
978
979
980}
981
982#endif /* CONFIG_AIRONET4500_I365 */
983
984#ifdef MODULE
985int 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
1032void 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