OpenCores
URL https://opencores.org/ocsvn/test_project/test_project/trunk

Subversion Repositories test_project

[/] [test_project/] [trunk/] [linux_sd_driver/] [drivers/] [net/] [wireless/] [airo_cs.c] - Blame information for rev 62

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 62 marcus.erl
/*======================================================================
2
 
3
    Aironet driver for 4500 and 4800 series cards
4
 
5
    This code is released under both the GPL version 2 and BSD licenses.
6
    Either license may be used.  The respective licenses are found at
7
    the end of this file.
8
 
9
    This code was developed by Benjamin Reed <breed@users.sourceforge.net>
10
    including portions of which come from the Aironet PC4500
11
    Developer's Reference Manual and used with permission.  Copyright
12
    (C) 1999 Benjamin Reed.  All Rights Reserved.  Permission to use
13
    code in the Developer's manual was granted for this driver by
14
    Aironet.
15
 
16
    In addition this module was derived from dummy_cs.
17
    The initial developer of dummy_cs is David A. Hinds
18
    <dahinds@users.sourceforge.net>.  Portions created by David A. Hinds
19
    are Copyright (C) 1999 David A. Hinds.  All Rights Reserved.
20
 
21
======================================================================*/
22
 
23
#ifdef __IN_PCMCIA_PACKAGE__
24
#include <pcmcia/k_compat.h>
25
#endif
26
#include <linux/init.h>
27
#include <linux/kernel.h>
28
#include <linux/module.h>
29
#include <linux/ptrace.h>
30
#include <linux/slab.h>
31
#include <linux/string.h>
32
#include <linux/timer.h>
33
#include <linux/netdevice.h>
34
 
35
#include <pcmcia/cs_types.h>
36
#include <pcmcia/cs.h>
37
#include <pcmcia/cistpl.h>
38
#include <pcmcia/cisreg.h>
39
#include <pcmcia/ds.h>
40
 
41
#include <asm/io.h>
42
#include <asm/system.h>
43
 
44
#include "airo.h"
45
 
46
/*
47
   All the PCMCIA modules use PCMCIA_DEBUG to control debugging.  If
48
   you do not define PCMCIA_DEBUG at all, all the debug code will be
49
   left out.  If you compile with PCMCIA_DEBUG=0, the debug code will
50
   be present but disabled -- but it can then be enabled for specific
51
   modules at load time with a 'pc_debug=#' option to insmod.
52
*/
53
#ifdef PCMCIA_DEBUG
54
static int pc_debug = PCMCIA_DEBUG;
55
module_param(pc_debug, int, 0);
56
static char *version = "$Revision: 1.2 $";
57
#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args);
58
#else
59
#define DEBUG(n, args...)
60
#endif
61
 
62
/*====================================================================*/
63
 
64
MODULE_AUTHOR("Benjamin Reed");
65
MODULE_DESCRIPTION("Support for Cisco/Aironet 802.11 wireless ethernet \
66
                   cards.  This is the module that links the PCMCIA card \
67
                   with the airo module.");
68
MODULE_LICENSE("Dual BSD/GPL");
69
MODULE_SUPPORTED_DEVICE("Aironet 4500, 4800 and Cisco 340 PCMCIA cards");
70
 
71
/*====================================================================*/
72
 
73
/*
74
   The event() function is this driver's Card Services event handler.
75
   It will be called by Card Services when an appropriate card status
76
   event is received.  The config() and release() entry points are
77
   used to configure or release a socket, in response to card
78
   insertion and ejection events.  They are invoked from the airo_cs
79
   event handler.
80
*/
81
 
82
static int airo_config(struct pcmcia_device *link);
83
static void airo_release(struct pcmcia_device *link);
84
 
85
/*
86
   The attach() and detach() entry points are used to create and destroy
87
   "instances" of the driver, where each instance represents everything
88
   needed to manage one actual PCMCIA card.
89
*/
90
 
91
static void airo_detach(struct pcmcia_device *p_dev);
92
 
93
/*
94
   You'll also need to prototype all the functions that will actually
95
   be used to talk to your device.  See 'pcmem_cs' for a good example
96
   of a fully self-sufficient driver; the other drivers rely more or
97
   less on other parts of the kernel.
98
*/
99
 
100
/*
101
   A linked list of "instances" of the  aironet device.  Each actual
102
   PCMCIA card corresponds to one device instance, and is described
103
   by one struct pcmcia_device structure (defined in ds.h).
104
 
105
   You may not want to use a linked list for this -- for example, the
106
   memory card driver uses an array of struct pcmcia_device pointers, where minor
107
   device numbers are used to derive the corresponding array index.
108
*/
109
 
110
/*
111
   A driver needs to provide a dev_node_t structure for each device
112
   on a card.  In some cases, there is only one device per card (for
113
   example, ethernet cards, modems).  In other cases, there may be
114
   many actual or logical devices (SCSI adapters, memory cards with
115
   multiple partitions).  The dev_node_t structures need to be kept
116
   in a linked list starting at the 'dev' field of a struct pcmcia_device
117
   structure.  We allocate them in the card's private data structure,
118
   because they generally shouldn't be allocated dynamically.
119
 
120
   In this case, we also provide a flag to indicate if a device is
121
   "stopped" due to a power management event, or card ejection.  The
122
   device IO routines can use a flag like this to throttle IO to a
123
   card that is not ready to accept it.
124
*/
125
 
126
typedef struct local_info_t {
127
        dev_node_t      node;
128
        struct net_device *eth_dev;
129
} local_info_t;
130
 
131
/*======================================================================
132
 
133
  airo_attach() creates an "instance" of the driver, allocating
134
  local data structures for one device.  The device is registered
135
  with Card Services.
136
 
137
  The dev_link structure is initialized, but we don't actually
138
  configure the card at this point -- we wait until we receive a
139
  card insertion event.
140
 
141
  ======================================================================*/
142
 
143
static int airo_probe(struct pcmcia_device *p_dev)
144
{
145
        local_info_t *local;
146
 
147
        DEBUG(0, "airo_attach()\n");
148
 
149
        /* Interrupt setup */
150
        p_dev->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
151
        p_dev->irq.IRQInfo1 = IRQ_LEVEL_ID;
152
        p_dev->irq.Handler = NULL;
153
 
154
        /*
155
          General socket configuration defaults can go here.  In this
156
          client, we assume very little, and rely on the CIS for almost
157
          everything.  In most clients, many details (i.e., number, sizes,
158
          and attributes of IO windows) are fixed by the nature of the
159
          device, and can be hard-wired here.
160
        */
161
        p_dev->conf.Attributes = 0;
162
        p_dev->conf.IntType = INT_MEMORY_AND_IO;
163
 
164
        /* Allocate space for private device-specific data */
165
        local = kzalloc(sizeof(local_info_t), GFP_KERNEL);
166
        if (!local) {
167
                printk(KERN_ERR "airo_cs: no memory for new device\n");
168
                return -ENOMEM;
169
        }
170
        p_dev->priv = local;
171
 
172
        return airo_config(p_dev);
173
} /* airo_attach */
174
 
175
/*======================================================================
176
 
177
  This deletes a driver "instance".  The device is de-registered
178
  with Card Services.  If it has been released, all local data
179
  structures are freed.  Otherwise, the structures will be freed
180
  when the device is released.
181
 
182
  ======================================================================*/
183
 
184
static void airo_detach(struct pcmcia_device *link)
185
{
186
        DEBUG(0, "airo_detach(0x%p)\n", link);
187
 
188
        airo_release(link);
189
 
190
        if ( ((local_info_t*)link->priv)->eth_dev ) {
191
                stop_airo_card( ((local_info_t*)link->priv)->eth_dev, 0 );
192
        }
193
        ((local_info_t*)link->priv)->eth_dev = NULL;
194
 
195
        kfree(link->priv);
196
} /* airo_detach */
197
 
198
/*======================================================================
199
 
200
  airo_config() is scheduled to run after a CARD_INSERTION event
201
  is received, to configure the PCMCIA socket, and to make the
202
  device available to the system.
203
 
204
  ======================================================================*/
205
 
206
#define CS_CHECK(fn, ret) \
207
do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
208
 
209
static int airo_config(struct pcmcia_device *link)
210
{
211
        tuple_t tuple;
212
        cisparse_t parse;
213
        local_info_t *dev;
214
        int last_fn, last_ret;
215
        u_char buf[64];
216
        win_req_t req;
217
        memreq_t map;
218
 
219
        dev = link->priv;
220
 
221
        DEBUG(0, "airo_config(0x%p)\n", link);
222
 
223
        /*
224
          In this loop, we scan the CIS for configuration table entries,
225
          each of which describes a valid card configuration, including
226
          voltage, IO window, memory window, and interrupt settings.
227
 
228
          We make no assumptions about the card to be configured: we use
229
          just the information available in the CIS.  In an ideal world,
230
          this would work for any PCMCIA card, but it requires a complete
231
          and accurate CIS.  In practice, a driver usually "knows" most of
232
          these things without consulting the CIS, and most client drivers
233
          will only use the CIS to fill in implementation-defined details.
234
        */
235
        tuple.Attributes = 0;
236
        tuple.TupleData = buf;
237
        tuple.TupleDataMax = sizeof(buf);
238
        tuple.TupleOffset = 0;
239
        tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
240
        CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
241
        while (1) {
242
                cistpl_cftable_entry_t dflt = { 0 };
243
                cistpl_cftable_entry_t *cfg = &(parse.cftable_entry);
244
                if (pcmcia_get_tuple_data(link, &tuple) != 0 ||
245
                                pcmcia_parse_tuple(link, &tuple, &parse) != 0)
246
                        goto next_entry;
247
 
248
                if (cfg->flags & CISTPL_CFTABLE_DEFAULT) dflt = *cfg;
249
                if (cfg->index == 0) goto next_entry;
250
                link->conf.ConfigIndex = cfg->index;
251
 
252
                /* Does this card need audio output? */
253
                if (cfg->flags & CISTPL_CFTABLE_AUDIO) {
254
                        link->conf.Attributes |= CONF_ENABLE_SPKR;
255
                        link->conf.Status = CCSR_AUDIO_ENA;
256
                }
257
 
258
                /* Use power settings for Vcc and Vpp if present */
259
                /*  Note that the CIS values need to be rescaled */
260
                if (cfg->vpp1.present & (1<<CISTPL_POWER_VNOM))
261
                        link->conf.Vpp =
262
                                cfg->vpp1.param[CISTPL_POWER_VNOM]/10000;
263
                else if (dflt.vpp1.present & (1<<CISTPL_POWER_VNOM))
264
                        link->conf.Vpp =
265
                                dflt.vpp1.param[CISTPL_POWER_VNOM]/10000;
266
 
267
                /* Do we need to allocate an interrupt? */
268
                if (cfg->irq.IRQInfo1 || dflt.irq.IRQInfo1)
269
                        link->conf.Attributes |= CONF_ENABLE_IRQ;
270
 
271
                /* IO window settings */
272
                link->io.NumPorts1 = link->io.NumPorts2 = 0;
273
                if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) {
274
                        cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt.io;
275
                        link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
276
                        if (!(io->flags & CISTPL_IO_8BIT))
277
                                link->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
278
                        if (!(io->flags & CISTPL_IO_16BIT))
279
                                link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
280
                        link->io.BasePort1 = io->win[0].base;
281
                        link->io.NumPorts1 = io->win[0].len;
282
                        if (io->nwin > 1) {
283
                                link->io.Attributes2 = link->io.Attributes1;
284
                                link->io.BasePort2 = io->win[1].base;
285
                                link->io.NumPorts2 = io->win[1].len;
286
                        }
287
                }
288
 
289
                /* This reserves IO space but doesn't actually enable it */
290
                if (pcmcia_request_io(link, &link->io) != 0)
291
                        goto next_entry;
292
 
293
                /*
294
                  Now set up a common memory window, if needed.  There is room
295
                  in the struct pcmcia_device structure for one memory window handle,
296
                  but if the base addresses need to be saved, or if multiple
297
                  windows are needed, the info should go in the private data
298
                  structure for this device.
299
 
300
                  Note that the memory window base is a physical address, and
301
                  needs to be mapped to virtual space with ioremap() before it
302
                  is used.
303
                */
304
                if ((cfg->mem.nwin > 0) || (dflt.mem.nwin > 0)) {
305
                        cistpl_mem_t *mem =
306
                                (cfg->mem.nwin) ? &cfg->mem : &dflt.mem;
307
                        req.Attributes = WIN_DATA_WIDTH_16|WIN_MEMORY_TYPE_CM;
308
                        req.Base = mem->win[0].host_addr;
309
                        req.Size = mem->win[0].len;
310
                        req.AccessSpeed = 0;
311
                        if (pcmcia_request_window(&link, &req, &link->win) != 0)
312
                                goto next_entry;
313
                        map.Page = 0; map.CardOffset = mem->win[0].card_addr;
314
                        if (pcmcia_map_mem_page(link->win, &map) != 0)
315
                                goto next_entry;
316
                }
317
                /* If we got this far, we're cool! */
318
                break;
319
 
320
        next_entry:
321
                CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(link, &tuple));
322
        }
323
 
324
    /*
325
      Allocate an interrupt line.  Note that this does not assign a
326
      handler to the interrupt, unless the 'Handler' member of the
327
      irq structure is initialized.
328
    */
329
        if (link->conf.Attributes & CONF_ENABLE_IRQ)
330
                CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
331
 
332
        /*
333
          This actually configures the PCMCIA socket -- setting up
334
          the I/O windows and the interrupt mapping, and putting the
335
          card and host interface into "Memory and IO" mode.
336
        */
337
        CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf));
338
        ((local_info_t*)link->priv)->eth_dev =
339
                init_airo_card( link->irq.AssignedIRQ,
340
                                link->io.BasePort1, 1, &handle_to_dev(link) );
341
        if (!((local_info_t*)link->priv)->eth_dev) goto cs_failed;
342
 
343
        /*
344
          At this point, the dev_node_t structure(s) need to be
345
          initialized and arranged in a linked list at link->dev_node.
346
        */
347
        strcpy(dev->node.dev_name, ((local_info_t*)link->priv)->eth_dev->name );
348
        dev->node.major = dev->node.minor = 0;
349
        link->dev_node = &dev->node;
350
 
351
        /* Finally, report what we've done */
352
        printk(KERN_INFO "%s: index 0x%02x: ",
353
               dev->node.dev_name, link->conf.ConfigIndex);
354
        if (link->conf.Vpp)
355
                printk(", Vpp %d.%d", link->conf.Vpp/10, link->conf.Vpp%10);
356
        if (link->conf.Attributes & CONF_ENABLE_IRQ)
357
                printk(", irq %d", link->irq.AssignedIRQ);
358
        if (link->io.NumPorts1)
359
                printk(", io 0x%04x-0x%04x", link->io.BasePort1,
360
                       link->io.BasePort1+link->io.NumPorts1-1);
361
        if (link->io.NumPorts2)
362
                printk(" & 0x%04x-0x%04x", link->io.BasePort2,
363
                       link->io.BasePort2+link->io.NumPorts2-1);
364
        if (link->win)
365
                printk(", mem 0x%06lx-0x%06lx", req.Base,
366
                       req.Base+req.Size-1);
367
        printk("\n");
368
        return 0;
369
 
370
 cs_failed:
371
        cs_error(link, last_fn, last_ret);
372
        airo_release(link);
373
        return -ENODEV;
374
} /* airo_config */
375
 
376
/*======================================================================
377
 
378
  After a card is removed, airo_release() will unregister the
379
  device, and release the PCMCIA configuration.  If the device is
380
  still open, this will be postponed until it is closed.
381
 
382
  ======================================================================*/
383
 
384
static void airo_release(struct pcmcia_device *link)
385
{
386
        DEBUG(0, "airo_release(0x%p)\n", link);
387
        pcmcia_disable_device(link);
388
}
389
 
390
static int airo_suspend(struct pcmcia_device *link)
391
{
392
        local_info_t *local = link->priv;
393
 
394
        netif_device_detach(local->eth_dev);
395
 
396
        return 0;
397
}
398
 
399
static int airo_resume(struct pcmcia_device *link)
400
{
401
        local_info_t *local = link->priv;
402
 
403
        if (link->open) {
404
                reset_airo_card(local->eth_dev);
405
                netif_device_attach(local->eth_dev);
406
        }
407
 
408
        return 0;
409
}
410
 
411
static struct pcmcia_device_id airo_ids[] = {
412
        PCMCIA_DEVICE_MANF_CARD(0x015f, 0x000a),
413
        PCMCIA_DEVICE_MANF_CARD(0x015f, 0x0005),
414
        PCMCIA_DEVICE_MANF_CARD(0x015f, 0x0007),
415
        PCMCIA_DEVICE_MANF_CARD(0x0105, 0x0007),
416
        PCMCIA_DEVICE_NULL,
417
};
418
MODULE_DEVICE_TABLE(pcmcia, airo_ids);
419
 
420
static struct pcmcia_driver airo_driver = {
421
        .owner          = THIS_MODULE,
422
        .drv            = {
423
                .name   = "airo_cs",
424
        },
425
        .probe          = airo_probe,
426
        .remove         = airo_detach,
427
        .id_table       = airo_ids,
428
        .suspend        = airo_suspend,
429
        .resume         = airo_resume,
430
};
431
 
432
static int airo_cs_init(void)
433
{
434
        return pcmcia_register_driver(&airo_driver);
435
}
436
 
437
static void airo_cs_cleanup(void)
438
{
439
        pcmcia_unregister_driver(&airo_driver);
440
}
441
 
442
/*
443
    This program is free software; you can redistribute it and/or
444
    modify it under the terms of the GNU General Public License
445
    as published by the Free Software Foundation; either version 2
446
    of the License, or (at your option) any later version.
447
 
448
    This program is distributed in the hope that it will be useful,
449
    but WITHOUT ANY WARRANTY; without even the implied warranty of
450
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
451
    GNU General Public License for more details.
452
 
453
    In addition:
454
 
455
    Redistribution and use in source and binary forms, with or without
456
    modification, are permitted provided that the following conditions
457
    are met:
458
 
459
    1. Redistributions of source code must retain the above copyright
460
       notice, this list of conditions and the following disclaimer.
461
    2. Redistributions in binary form must reproduce the above copyright
462
       notice, this list of conditions and the following disclaimer in the
463
       documentation and/or other materials provided with the distribution.
464
    3. The name of the author may not be used to endorse or promote
465
       products derived from this software without specific prior written
466
       permission.
467
 
468
    THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
469
    IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
470
    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
471
    ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
472
    INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
473
    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
474
    SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
475
    HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
476
    STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
477
    IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
478
    POSSIBILITY OF SUCH DAMAGE.
479
*/
480
 
481
module_init(airo_cs_init);
482
module_exit(airo_cs_cleanup);

powered by: WebSVN 2.1.0

© copyright 1999-2025 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.