Import 2.3.49pre2
[davej-history.git] / drivers / net / pcmcia / aironet4500_cs.c
blob5d72f7778fd2985cfb1f0e51e9ba7ab1ae67381a
1 /*
2 * Aironet 4500 Pcmcia driver
4 * Elmer Joandi, Januar 1999
5 * Copyright Elmer Joandi, all rights restricted
6 *
8 * Revision 0.1 ,started 30.12.1998
13 static const char *awc_version =
14 "aironet4500_cs.c v0.1 1/1/99 Elmer Joandi, elmer@ylenurme.ee.\n";
17 #include <linux/module.h>
18 //#include <pcmcia/config.h>
20 #include <linux/kernel.h>
21 #include <linux/sched.h>
22 #include <linux/ptrace.h>
23 #include <linux/malloc.h>
24 #include <linux/string.h>
25 #include <linux/timer.h>
26 #include <linux/interrupt.h>
27 #include <linux/in.h>
28 #include <asm/io.h>
29 #include <asm/system.h>
30 #include <asm/bitops.h>
32 #include <linux/netdevice.h>
33 #include <linux/etherdevice.h>
34 #include <linux/skbuff.h>
35 #include <linux/if_arp.h>
36 #include <linux/ioport.h>
39 #include <pcmcia/version.h>
40 #include <pcmcia/cs_types.h>
41 #include <pcmcia/cs.h>
42 #include <pcmcia/cistpl.h>
43 #include <pcmcia/cisreg.h>
44 #include <pcmcia/ciscode.h>
45 #if LINUX_VERSION_CODE < 0x20300
46 #ifdef MODULE
47 #include <pcmcia/k_compat.h>
48 #endif
49 #endif
50 #include <pcmcia/ds.h>
52 #include "../aironet4500.h"
55 static u_int irq_mask = 0x5eF8;
56 static int awc_ports[] = {0x140,0x100,0xc0, 0x80 };
57 #if LINUX_VERSION_CODE > 0x20100
58 MODULE_PARM(irq_mask, "i");
60 #endif
63 #define RUN_AT(x) (jiffies+(x))
65 #ifdef PCMCIA_DEBUG
66 static int pc_debug = PCMCIA_DEBUG;
67 MODULE_PARM(pc_debug, "i");
68 #define PC_DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
69 static char *version =
70 "aironet4500_cs.c v0.1 1/1/99 Elmer Joandi, elmer@ylenurme.ee.\n";
71 #else
72 #define PC_DEBUG(n, args...)
73 #endif
75 /* Index of functions. */
77 static dev_info_t dev_info = "aironet4500_cs";
79 static dev_link_t *awc_attach(void);
80 static void awc_detach(dev_link_t *);
81 static void awc_release(u_long arg);
82 static int awc_event(event_t event, int priority,
83 event_callback_args_t *args);
85 static dev_link_t *dev_list = NULL;
87 static void cs_error(client_handle_t handle, int func, int ret)
89 #if CS_RELEASE_CODE < 0x2911
90 CardServices(ReportError, dev_info, (void *)func, (void *)ret);
91 #else
92 error_info_t err = { func, ret };
93 CardServices(ReportError, handle, &err);
94 #endif
97 #define CFG_CHECK(fn, args...) if (CardServices(fn, args) != 0) goto next_entry
99 static void flush_stale_links(void)
101 dev_link_t *link, *next;
102 for (link = dev_list; link; link = next) {
103 next = link->next;
104 if (link->state & DEV_STALE_LINK)
105 awc_detach(link);
111 We never need to do anything when a awc device is "initialized"
112 by the net software, because we only register already-found cards.
115 static int awc_pcmcia_init(struct net_device *dev)
117 return awc_init(dev);
121 static int awc_pcmcia_open(struct net_device *dev)
123 dev_link_t *link;
124 int status;
126 for (link = dev_list; link; link = link->next)
127 if (link->priv == dev) break;
128 if (!DEV_OK(link))
129 return -ENODEV;
131 status = awc_open(dev);
133 if (!status )
134 link->open++;
136 return status;
139 static int awc_pcmcia_close(struct net_device *dev)
141 // int ioaddr = dev->base_addr;
142 dev_link_t *link;
143 int ret;
145 for (link = dev_list; link; link = link->next)
146 if (link->priv == dev) break;
147 if (link == NULL)
148 return -ENODEV;
150 PC_DEBUG(2, "%s: closing device.\n", dev->name);
152 link->open--;
153 ret = awc_close(dev);
155 if (link->state & DEV_STALE_CONFIG) {
156 link->release.expires = RUN_AT( HZ/20 );
157 link->state |= DEV_RELEASE_PENDING;
158 add_timer(&link->release);
160 return ret;
164 awc_attach() creates an "instance" of the driver, allocating
165 local data structures for one device. The device is registered
166 with Card Services.
169 static dev_link_t *awc_attach(void)
171 client_reg_t client_reg;
172 dev_link_t *link = NULL;
173 struct net_device *dev = NULL;
174 int ret;
176 PC_DEBUG(0, "awc_attach()\n");
177 flush_stale_links();
179 /* Create the PC card device object. */
180 link = kmalloc(sizeof(struct dev_link_t), GFP_KERNEL);
181 memset(link, 0, sizeof(struct dev_link_t));
182 link->dev = kmalloc(sizeof(struct dev_node_t), GFP_KERNEL);
183 memset(link->dev, 0, sizeof(struct dev_node_t));
185 link->release.function = &awc_release;
186 link->release.data = (u_long)link;
187 // link->io.NumPorts1 = 32;
188 link->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
189 // link->io.IOAddrLines = 5;
190 link->irq.Attributes = IRQ_HANDLE_PRESENT ; // |IRQ_TYPE_EXCLUSIVE ;
191 link->irq.IRQInfo1 = IRQ_INFO2_VALID|IRQ_LEVEL_ID;
192 link->irq.IRQInfo2 = irq_mask;
193 link->irq.Handler = &awc_interrupt;
194 link->conf.Attributes = CONF_ENABLE_IRQ;
195 link->conf.Vcc = 50;
196 link->conf.IntType = INT_MEMORY_AND_IO;
197 link->conf.ConfigIndex = 1;
198 link->conf.Present = PRESENT_OPTION;
200 /* Create the network device object. */
202 dev = kmalloc(sizeof(struct net_device ), GFP_KERNEL);
203 memset(dev,0,sizeof(struct net_device));
204 // dev = init_etherdev(0, sizeof(struct awc_private) );
205 if (!dev ) {
206 printk(KERN_CRIT "out of mem on dev alloc \n");
207 kfree(link->dev);
208 kfree(link);
209 return NULL;
211 dev->priv = kmalloc(sizeof(struct awc_private), GFP_KERNEL);
212 if (!dev->priv ) {printk(KERN_CRIT "out of mem on dev priv alloc \n"); return NULL;};
213 memset(dev->priv,0,sizeof(struct awc_private));
215 // link->dev->minor = dev->minor;
216 // link->dev->major = dev->major;
218 /* The 4500-specific entries in the device structure. */
220 // dev->tx_queue_len = tx_queue_len;
222 dev->hard_start_xmit = &awc_start_xmit;
223 // dev->set_config = &awc_config_misiganes,aga mitte awc_config;
224 dev->get_stats = &awc_get_stats;
225 // dev->set_multicast_list = &awc_set_multicast_list;
227 ether_setup(dev);
229 dev->name = ((struct awc_private *)dev->priv)->node.dev_name;
231 dev->init = &awc_pcmcia_init;
232 dev->open = &awc_pcmcia_open;
233 dev->stop = &awc_pcmcia_close;
234 netif_start_queue (dev);
236 link->priv = dev;
237 #if CS_RELEASE_CODE > 0x2911
238 link->irq.Instance = dev;
239 #endif
241 /* Register with Card Services */
242 link->next = dev_list;
243 dev_list = link;
246 client_reg.dev_info = &dev_info;
247 client_reg.Attributes = INFO_IO_CLIENT | INFO_CARD_SHARE;
248 client_reg.EventMask =
249 CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
250 CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
251 CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME;
252 client_reg.event_handler = &awc_event;
253 client_reg.Version = 0x0210;
254 client_reg.event_callback_args.client_data = link;
255 ret = CardServices(RegisterClient, &link->handle, &client_reg);
256 if (ret != 0) {
257 cs_error(link->handle, RegisterClient, ret);
258 awc_detach(link);
259 return NULL;
262 return link;
263 } /* awc_attach */
267 This deletes a driver "instance". The device is de-registered
268 with Card Services. If it has been released, all local data
269 structures are freed. Otherwise, the structures will be freed
270 when the device is released.
274 static void awc_detach(dev_link_t *link)
276 dev_link_t **linkp;
277 long flags;
278 int i=0;
280 DEBUG(0, "awc_detach(0x%p)\n", link);
282 /* Locate device structure */
283 for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
284 if (*linkp == link) break;
285 if (*linkp == NULL)
286 return;
288 save_flags(flags);
289 cli();
290 if (link->state & DEV_RELEASE_PENDING) {
291 del_timer(&link->release);
292 link->state &= ~DEV_RELEASE_PENDING;
294 restore_flags(flags);
296 if (link->state & DEV_CONFIG) {
297 awc_release((u_long)link);
298 if (link->state & DEV_STALE_CONFIG) {
299 link->state |= DEV_STALE_LINK;
300 return;
304 if (link->handle)
305 CardServices(DeregisterClient, link->handle);
307 /* Unlink device structure, free bits */
308 *linkp = link->next;
310 i=0;
311 while ( i < MAX_AWCS) {
312 if (!aironet4500_devices[i])
313 {i++; continue;}
314 if (aironet4500_devices[i] == link->priv){
315 if (awc_proc_unset_fun)
316 awc_proc_unset_fun(i);
318 aironet4500_devices[i]=0;
320 i++;
323 if (link->priv) {
324 //struct net_device *dev = link->priv;
325 // dam dam damn mif (dev->priv)
326 // kfree_s(dev->priv, sizeof(struct awc_private));
327 kfree_s(link->priv, sizeof(struct net_device));
329 kfree_s(link->dev, sizeof(struct dev_node_t));
330 kfree_s(link, sizeof(struct dev_link_t));
332 } /* awc_detach */
336 awc_pcmcia_config() is scheduled to run after a CARD_INSERTION event
337 is received, to configure the PCMCIA socket, and to make the
338 ethernet device available to the system.
342 #define CS_CHECK(fn, args...) \
343 while ((last_ret=CardServices(last_fn=(fn), args))!=0) goto cs_failed
345 static void awc_pcmcia_config(dev_link_t *link)
347 client_handle_t handle;
348 struct net_device *dev;
349 struct awc_private *lp;
350 tuple_t tuple;
351 int ii;
352 cisparse_t parse;
353 u_short buf[64];
354 int last_fn, last_ret, i = 0;
355 // int ioaddr;
356 u16 *phys_addr;
357 int retval;
359 handle = link->handle;
360 dev = link->priv;
361 phys_addr = (u16 *)dev->dev_addr;
363 PC_DEBUG(0, "awc_pcmcia_config(0x%p)\n", link);
365 tuple.Attributes = 0;
366 tuple.DesiredTuple = CISTPL_CONFIG;
367 CS_CHECK(GetFirstTuple, handle, &tuple);
368 tuple.TupleData = (cisdata_t *)buf;
369 tuple.TupleDataMax = 64;
370 tuple.TupleOffset = 0;
371 CS_CHECK(GetTupleData, handle, &tuple);
372 CS_CHECK(ParseTuple, handle, &tuple, &parse);
373 link->conf.ConfigBase = parse.config.base;
374 link->conf.Present = parse.config.rmask[0];
377 /* Configure card */
378 link->state |= DEV_CONFIG;
380 tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
381 CS_CHECK(GetFirstTuple, handle, &tuple);
383 while (1) {
384 cistpl_cftable_entry_t dflt = { 0 };
385 cistpl_cftable_entry_t *cfg = &(parse.cftable_entry);
386 CFG_CHECK(GetTupleData, handle, &tuple);
387 CFG_CHECK(ParseTuple, handle, &tuple, &parse);
389 if (cfg->flags & CISTPL_CFTABLE_DEFAULT) dflt = *cfg;
390 if (cfg->index == 0) goto next_entry;
391 link->conf.ConfigIndex = cfg->index;
393 /* Use power settings for Vcc and Vpp if present */
394 /* Note that the CIS values need to be rescaled */
395 if (cfg->vcc.present & (1<<CISTPL_POWER_VNOM))
396 link->conf.Vcc = cfg->vcc.param[CISTPL_POWER_VNOM]/10000;
397 else if (dflt.vcc.present & (1<<CISTPL_POWER_VNOM))
398 link->conf.Vcc = dflt.vcc.param[CISTPL_POWER_VNOM]/10000;
400 if (cfg->vpp1.present & (1<<CISTPL_POWER_VNOM))
401 link->conf.Vpp1 = link->conf.Vpp2 =
402 cfg->vpp1.param[CISTPL_POWER_VNOM]/10000;
403 else if (dflt.vpp1.present & (1<<CISTPL_POWER_VNOM))
404 link->conf.Vpp1 = link->conf.Vpp2 =
405 dflt.vpp1.param[CISTPL_POWER_VNOM]/10000;
407 /* Do we need to allocate an interrupt? */
408 if (cfg->irq.IRQInfo1 || dflt.irq.IRQInfo1)
409 link->conf.Attributes |= CONF_ENABLE_IRQ;
411 /* IO window settings */
412 link->io.NumPorts1 = link->io.NumPorts2 = 0;
413 if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) {
414 cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt.io;
415 link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
416 if (!(io->flags & CISTPL_IO_8BIT))
417 link->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
418 if (!(io->flags & CISTPL_IO_16BIT)) {
420 link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
421 printk(KERN_CRIT "8-bit IO not supported on this aironet 4500 driver \n");
423 link->io.BasePort1 = io->win[0].base;
425 link->io.NumPorts1 = io->win[0].len;
426 if (io->nwin > 1) {
427 link->io.Attributes2 = link->io.Attributes1;
428 link->io.BasePort2 = io->win[1].base;
429 link->io.NumPorts2 = io->win[1].len;
432 ii = 0;
433 last_fn = RequestIO;
434 while ((last_ret = CardServices(RequestIO, link->handle, &link->io)) ){
436 if (ii > 4)
437 goto cs_failed;
438 link->io.BasePort1 = awc_ports[ii];
439 ii++;
443 break;
445 next_entry:
446 if (CardServices(GetNextTuple, handle, &tuple))
447 break;
450 if (link->conf.Attributes & CONF_ENABLE_IRQ){
452 ii = 0; last_fn = RequestIRQ;
453 while ((last_ret = CardServices(RequestIRQ, link->handle, &link->irq)) ){
455 ii++;
456 while (!(irq_mask & (1 << ii) ) && ii < 15)
457 ii++;
458 link->irq.IRQInfo2 = 1 << ii;
460 if(ii > 15)
461 goto cs_failed;
462 printk("trying irq %d , mask %x \n",ii, link->irq.IRQInfo2);
467 CS_CHECK(RequestConfiguration, link->handle, &link->conf);
470 dev->irq = link->irq.AssignedIRQ;
471 dev->base_addr = link->io.BasePort1;
474 awc_private_init( dev);
478 retval = register_netdev(dev);
479 if (retval != 0) {
480 printk(KERN_NOTICE "awc_cs: register_netdev() failed for dev %x retval %x\n",(unsigned int)dev,retval);
481 goto failed;
484 if(awc_pcmcia_init(dev)) goto failed;
486 i=0;
487 while (aironet4500_devices[i] && i < MAX_AWCS-1) i++;
488 if (!aironet4500_devices[i]){
489 aironet4500_devices[i]=dev;
490 if (awc_proc_set_fun)
491 awc_proc_set_fun(i);
495 link->state &= ~DEV_CONFIG_PENDING;
497 lp = (struct awc_private *)dev->priv;
499 DEBUG(1,"pcmcia config complete on port %x \n",(unsigned int)dev->base_addr);
501 return;
503 cs_failed:
504 cs_error(link->handle, last_fn, last_ret);
505 link->dev=NULL;
506 failed:
508 awc_release((u_long)link);
509 return;
511 } /* awc_pcmcia_config */
514 After a card is removed, awc_release() will unregister the net
515 device, and release the PCMCIA configuration. If the device is
516 still open, this will be postponed until it is closed.
520 static void awc_release(u_long arg)
522 dev_link_t *link = (dev_link_t *)arg;
523 struct net_device *dev = link->priv;
525 DEBUG(0, "awc_release(0x%p)\n", link);
527 if (link->open) {
528 DEBUG(1, "awc_cs: release postponed, '%s' still open\n",
529 link->dev->dev_name);
530 link->state |= DEV_STALE_CONFIG;
531 return;
534 CardServices(ReleaseConfiguration, link->handle);
535 CardServices(ReleaseIO, link->handle, &link->io);
536 CardServices(ReleaseIRQ, link->handle, &link->irq);
538 CardServices(ReleaseWindow, link->win);
539 if (link->dev)
540 unregister_netdev(dev);
541 // link->dev = NULL;
543 link->state &= ~DEV_CONFIG;
544 if (link->state & DEV_STALE_LINK)
545 awc_detach(link);
547 } /* awc_release */
551 The card status event handler. Mostly, this schedules other
552 stuff to run after an event is received. A CARD_REMOVAL event
553 also sets some flags to discourage the net drivers from trying
554 to talk to the card any more.
557 static int awc_event(event_t event, int priority,
558 event_callback_args_t *args)
560 dev_link_t *link = args->client_data;
561 struct net_device *dev = link->priv;
563 PC_DEBUG(1, "awc_event(0x%06x)\n", event);
565 switch (event) {
566 case CS_EVENT_CARD_REMOVAL:
567 link->state &= ~DEV_PRESENT;
568 if (link->state & DEV_CONFIG) {
569 netif_device_detach(dev);
570 link->release.expires = RUN_AT( HZ/20 );
571 add_timer(&link->release);
573 break;
574 case CS_EVENT_CARD_INSERTION:
575 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
576 awc_pcmcia_config(link);
577 break;
578 case CS_EVENT_PM_SUSPEND:
579 link->state |= DEV_SUSPEND;
580 /* Fall through... */
581 case CS_EVENT_RESET_PHYSICAL:
582 if (link->state & DEV_CONFIG) {
583 if (link->open)
584 netif_device_detach(dev);
586 CardServices(ReleaseConfiguration, link->handle);
588 break;
589 case CS_EVENT_PM_RESUME:
590 link->state &= ~DEV_SUSPEND;
591 /* Fall through... */
592 case CS_EVENT_CARD_RESET:
593 if (link->state & DEV_CONFIG) {
594 CardServices(RequestConfiguration, link->handle, &link->conf);
595 if (link->open) {
596 // awc_reset(dev);
597 netif_device_attach(dev);
600 break;
602 return 0;
603 } /* awc_event */
607 int init_module(void)
609 servinfo_t serv;
611 /* Always emit the version, before any failure. */
612 printk(KERN_INFO"%s", awc_version);
613 PC_DEBUG(0, "%s\n", version);
614 CardServices(GetCardServicesInfo, &serv);
615 if (serv.Revision != CS_RELEASE_CODE) {
616 printk(KERN_NOTICE "awc_cs: Card Services release "
617 "does not match!\n");
618 return -1;
620 register_pcmcia_driver(&dev_info, &awc_attach, &awc_detach);
621 return 0;
624 void cleanup_module(void)
626 DEBUG(0, "awc_cs: unloading %c ",'\n');
627 unregister_pcmcia_driver(&dev_info);
629 while (dev_list != NULL) {
630 if (dev_list->state & DEV_CONFIG)
631 awc_release((u_long)dev_list);
632 awc_detach(dev_list);
635 // while (dev_list != NULL)
636 // awc_detach(dev_list);