| /*====================================================================== | |
| Aironet driver for 4500 and 4800 series cards | |
| This code is released under both the GPL version 2 and BSD licenses. | |
| Either license may be used. The respective licenses are found at | |
| the end of this file. | |
| This code was developed by Benjamin Reed <breed@users.sourceforge.net> | |
| including portions of which come from the Aironet PC4500 | |
| Developer's Reference Manual and used with permission. Copyright | |
| (C) 1999 Benjamin Reed. All Rights Reserved. Permission to use | |
| code in the Developer's manual was granted for this driver by | |
| Aironet. | |
| In addition this module was derived from dummy_cs. | |
| The initial developer of dummy_cs is David A. Hinds | |
| <dahinds@users.sourceforge.net>. Portions created by David A. Hinds | |
| are Copyright (C) 1999 David A. Hinds. All Rights Reserved. | |
| ======================================================================*/ | |
| #ifdef __IN_PCMCIA_PACKAGE__ | |
| #include <pcmcia/k_compat.h> | |
| #endif | |
| #include <linux/kernel.h> | |
| #include <linux/module.h> | |
| #include <linux/ptrace.h> | |
| #include <linux/slab.h> | |
| #include <linux/string.h> | |
| #include <linux/timer.h> | |
| #include <linux/netdevice.h> | |
| #include <pcmcia/cistpl.h> | |
| #include <pcmcia/cisreg.h> | |
| #include <pcmcia/ds.h> | |
| #include <linux/io.h> | |
| #include "airo.h" | |
| /*====================================================================*/ | |
| MODULE_AUTHOR("Benjamin Reed"); | |
| MODULE_DESCRIPTION("Support for Cisco/Aironet 802.11 wireless ethernet " | |
| "cards. This is the module that links the PCMCIA card " | |
| "with the airo module."); | |
| MODULE_LICENSE("Dual BSD/GPL"); | |
| MODULE_SUPPORTED_DEVICE("Aironet 4500, 4800 and Cisco 340 PCMCIA cards"); | |
| /*====================================================================*/ | |
| static int airo_config(struct pcmcia_device *link); | |
| static void airo_release(struct pcmcia_device *link); | |
| static void airo_detach(struct pcmcia_device *p_dev); | |
| struct local_info { | |
| struct net_device *eth_dev; | |
| }; | |
| static int airo_probe(struct pcmcia_device *p_dev) | |
| { | |
| struct local_info *local; | |
| dev_dbg(&p_dev->dev, "airo_attach()\n"); | |
| /* Allocate space for private device-specific data */ | |
| local = kzalloc(sizeof(*local), GFP_KERNEL); | |
| if (!local) | |
| return -ENOMEM; | |
| p_dev->priv = local; | |
| return airo_config(p_dev); | |
| } /* airo_attach */ | |
| static void airo_detach(struct pcmcia_device *link) | |
| { | |
| dev_dbg(&link->dev, "airo_detach\n"); | |
| airo_release(link); | |
| if (((struct local_info *)link->priv)->eth_dev) { | |
| stop_airo_card(((struct local_info *)link->priv)->eth_dev, | |
| 0); | |
| } | |
| ((struct local_info *)link->priv)->eth_dev = NULL; | |
| kfree(link->priv); | |
| } /* airo_detach */ | |
| static int airo_cs_config_check(struct pcmcia_device *p_dev, void *priv_data) | |
| { | |
| if (p_dev->config_index == 0) | |
| return -EINVAL; | |
| return pcmcia_request_io(p_dev); | |
| } | |
| static int airo_config(struct pcmcia_device *link) | |
| { | |
| struct local_info *dev; | |
| int ret; | |
| dev = link->priv; | |
| dev_dbg(&link->dev, "airo_config\n"); | |
| link->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_SET_VPP | | |
| CONF_AUTO_AUDIO | CONF_AUTO_SET_IO; | |
| ret = pcmcia_loop_config(link, airo_cs_config_check, NULL); | |
| if (ret) | |
| goto failed; | |
| if (!link->irq) | |
| goto failed; | |
| ret = pcmcia_enable_device(link); | |
| if (ret) | |
| goto failed; | |
| ((struct local_info *)link->priv)->eth_dev = | |
| init_airo_card(link->irq, | |
| link->resource[0]->start, 1, &link->dev); | |
| if (!((struct local_info *)link->priv)->eth_dev) | |
| goto failed; | |
| return 0; | |
| failed: | |
| airo_release(link); | |
| return -ENODEV; | |
| } /* airo_config */ | |
| static void airo_release(struct pcmcia_device *link) | |
| { | |
| dev_dbg(&link->dev, "airo_release\n"); | |
| pcmcia_disable_device(link); | |
| } | |
| static int airo_suspend(struct pcmcia_device *link) | |
| { | |
| struct local_info *local = link->priv; | |
| netif_device_detach(local->eth_dev); | |
| return 0; | |
| } | |
| static int airo_resume(struct pcmcia_device *link) | |
| { | |
| struct local_info *local = link->priv; | |
| if (link->open) { | |
| reset_airo_card(local->eth_dev); | |
| netif_device_attach(local->eth_dev); | |
| } | |
| return 0; | |
| } | |
| static const struct pcmcia_device_id airo_ids[] = { | |
| PCMCIA_DEVICE_MANF_CARD(0x015f, 0x000a), | |
| PCMCIA_DEVICE_MANF_CARD(0x015f, 0x0005), | |
| PCMCIA_DEVICE_MANF_CARD(0x015f, 0x0007), | |
| PCMCIA_DEVICE_MANF_CARD(0x0105, 0x0007), | |
| PCMCIA_DEVICE_NULL, | |
| }; | |
| MODULE_DEVICE_TABLE(pcmcia, airo_ids); | |
| static struct pcmcia_driver airo_driver = { | |
| .owner = THIS_MODULE, | |
| .name = "airo_cs", | |
| .probe = airo_probe, | |
| .remove = airo_detach, | |
| .id_table = airo_ids, | |
| .suspend = airo_suspend, | |
| .resume = airo_resume, | |
| }; | |
| module_pcmcia_driver(airo_driver); | |
| /* | |
| This program is free software; you can redistribute it and/or | |
| modify it under the terms of the GNU General Public License | |
| as published by the Free Software Foundation; either version 2 | |
| of the License, or (at your option) any later version. | |
| This program is distributed in the hope that it will be useful, | |
| but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
| GNU General Public License for more details. | |
| In addition: | |
| Redistribution and use in source and binary forms, with or without | |
| modification, are permitted provided that the following conditions | |
| are met: | |
| 1. Redistributions of source code must retain the above copyright | |
| notice, this list of conditions and the following disclaimer. | |
| 2. Redistributions in binary form must reproduce the above copyright | |
| notice, this list of conditions and the following disclaimer in the | |
| documentation and/or other materials provided with the distribution. | |
| 3. The name of the author may not be used to endorse or promote | |
| products derived from this software without specific prior written | |
| permission. | |
| THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR | |
| IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | |
| WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |
| ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, | |
| INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | |
| (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR | |
| SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |
| HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | |
| STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING | |
| IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | |
| POSSIBILITY OF SUCH DAMAGE. | |
| */ |