2005-04-16 15:20:36 -07:00
/*======================================================================
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
2009-03-06 07:09:41 -08:00
are Copyright ( C ) 1999 David A . Hinds . All Rights Reserved .
2005-04-16 15:20:36 -07:00
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */
# 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>
2009-03-06 07:09:41 -08:00
# include <linux/io.h>
2005-04-16 15:20:36 -07:00
2005-11-05 17:42:27 +01:00
# include "airo.h"
2005-04-16 15:20:36 -07:00
/*====================================================================*/
MODULE_AUTHOR ( " Benjamin Reed " ) ;
2009-03-06 07:09:41 -08:00
MODULE_DESCRIPTION ( " Support for Cisco/Aironet 802.11 wireless ethernet "
" cards. This is the module that links the PCMCIA card "
" with the airo module. " ) ;
2005-04-16 15:20:36 -07:00
MODULE_LICENSE ( " Dual BSD/GPL " ) ;
MODULE_SUPPORTED_DEVICE ( " Aironet 4500, 4800 and Cisco 340 PCMCIA cards " ) ;
/*====================================================================*/
2006-03-31 17:26:06 +02:00
static int airo_config ( struct pcmcia_device * link ) ;
2006-03-31 17:21:06 +02:00
static void airo_release ( struct pcmcia_device * link ) ;
2005-04-16 15:20:36 -07:00
2005-11-14 21:23:14 +01:00
static void airo_detach ( struct pcmcia_device * p_dev ) ;
2005-04-16 15:20:36 -07:00
2014-08-09 22:16:23 +05:30
struct local_info {
2005-04-16 15:20:36 -07:00
struct net_device * eth_dev ;
2014-08-09 22:16:23 +05:30
} ;
2005-04-16 15:20:36 -07:00
2006-03-31 17:26:06 +02:00
static int airo_probe ( struct pcmcia_device * p_dev )
2005-04-16 15:20:36 -07:00
{
2014-08-09 22:16:23 +05:30
struct local_info * local ;
2005-11-14 21:25:51 +01:00
2009-10-24 15:53:36 +02:00
dev_dbg ( & p_dev - > dev , " airo_attach() \n " ) ;
2005-04-16 15:20:36 -07:00
/* Allocate space for private device-specific data */
2014-08-09 22:16:23 +05:30
local = kzalloc ( sizeof ( * local ) , GFP_KERNEL ) ;
2013-02-03 17:28:14 +00:00
if ( ! local )
2005-11-14 21:25:51 +01:00
return - ENOMEM ;
2013-02-03 17:28:14 +00:00
2006-03-05 10:45:09 +01:00
p_dev - > priv = local ;
2005-11-14 21:25:51 +01:00
2006-03-31 17:26:06 +02:00
return airo_config ( p_dev ) ;
2005-04-16 15:20:36 -07:00
} /* airo_attach */
2006-03-31 17:21:06 +02:00
static void airo_detach ( struct pcmcia_device * link )
2005-04-16 15:20:36 -07:00
{
2009-10-24 15:53:36 +02:00
dev_dbg ( & link - > dev , " airo_detach \n " ) ;
2005-11-14 21:25:35 +01:00
2006-03-02 00:09:29 +01:00
airo_release ( link ) ;
2005-11-14 21:25:35 +01:00
2014-08-09 22:16:23 +05:30
if ( ( ( struct local_info * ) link - > priv ) - > eth_dev ) {
stop_airo_card ( ( ( struct local_info * ) link - > priv ) - > eth_dev ,
0 ) ;
2005-04-16 15:20:36 -07:00
}
2014-08-09 22:16:23 +05:30
( ( struct local_info * ) link - > priv ) - > eth_dev = NULL ;
2005-11-14 21:23:14 +01:00
2005-10-28 16:53:13 -04:00
kfree ( link - > priv ) ;
2005-04-16 15:20:36 -07:00
} /* airo_detach */
2010-07-30 13:13:46 +02:00
static int airo_cs_config_check ( struct pcmcia_device * p_dev , void * priv_data )
2008-08-02 14:28:43 +02:00
{
2010-07-30 13:13:46 +02:00
if ( p_dev - > config_index = = 0 )
return - EINVAL ;
2008-08-02 14:28:43 +02:00
2010-07-30 13:13:46 +02:00
return pcmcia_request_io ( p_dev ) ;
2008-08-02 14:28:43 +02:00
}
2006-03-31 17:26:06 +02:00
static int airo_config ( struct pcmcia_device * link )
2005-04-16 15:20:36 -07:00
{
2014-08-09 22:16:23 +05:30
struct local_info * dev ;
2009-10-24 15:53:36 +02:00
int ret ;
2006-03-31 17:21:06 +02:00
2005-04-16 15:20:36 -07:00
dev = link - > priv ;
2009-10-24 15:53:36 +02:00
dev_dbg ( & link - > dev , " airo_config \n " ) ;
2006-03-02 00:09:29 +01:00
2010-07-30 09:51:52 +02:00
link - > config_flags | = CONF_ENABLE_IRQ | CONF_AUTO_SET_VPP |
2010-07-30 13:13:46 +02:00
CONF_AUTO_AUDIO | CONF_AUTO_SET_IO ;
2010-07-30 09:51:52 +02:00
2010-07-28 09:32:02 +02:00
ret = pcmcia_loop_config ( link , airo_cs_config_check , NULL ) ;
2009-10-24 15:53:36 +02:00
if ( ret )
2008-08-02 14:28:43 +02:00
goto failed ;
2010-03-07 12:21:16 +01:00
if ( ! link - > irq )
goto failed ;
2009-03-06 07:09:41 -08:00
2010-07-29 19:27:09 +02:00
ret = pcmcia_enable_device ( link ) ;
2009-10-24 15:53:36 +02:00
if ( ret )
goto failed ;
2014-08-09 22:16:23 +05:30
( ( struct local_info * ) link - > priv ) - > eth_dev =
2010-03-07 12:21:16 +01:00
init_airo_card ( link - > irq ,
2010-07-24 15:58:54 +02:00
link - > resource [ 0 ] - > start , 1 , & link - > dev ) ;
2014-08-09 22:16:23 +05:30
if ( ! ( ( struct local_info * ) link - > priv ) - > eth_dev )
2009-10-24 15:53:36 +02:00
goto failed ;
2009-03-06 07:09:41 -08:00
2006-03-31 17:26:06 +02:00
return 0 ;
2008-08-02 14:28:43 +02:00
failed :
2005-04-16 15:20:36 -07:00
airo_release ( link ) ;
2006-03-31 17:26:06 +02:00
return - ENODEV ;
2005-04-16 15:20:36 -07:00
} /* airo_config */
2006-03-31 17:21:06 +02:00
static void airo_release ( struct pcmcia_device * link )
2005-04-16 15:20:36 -07:00
{
2009-10-24 15:53:36 +02:00
dev_dbg ( & link - > dev , " airo_release \n " ) ;
2006-03-31 17:21:06 +02:00
pcmcia_disable_device ( link ) ;
2005-04-16 15:20:36 -07:00
}
2006-03-31 17:21:06 +02:00
static int airo_suspend ( struct pcmcia_device * link )
2005-11-14 21:21:18 +01:00
{
2014-08-09 22:16:23 +05:30
struct local_info * local = link - > priv ;
2005-11-14 21:21:18 +01:00
2006-03-02 00:09:29 +01:00
netif_device_detach ( local - > eth_dev ) ;
2005-11-14 21:21:18 +01:00
return 0 ;
}
2006-03-31 17:21:06 +02:00
static int airo_resume ( struct pcmcia_device * link )
2005-11-14 21:21:18 +01:00
{
2014-08-09 22:16:23 +05:30
struct local_info * local = link - > priv ;
2005-11-14 21:21:18 +01:00
2006-03-02 00:09:29 +01:00
if ( link - > open ) {
2005-11-14 21:21:18 +01:00
reset_airo_card ( local - > eth_dev ) ;
netif_device_attach ( local - > eth_dev ) ;
}
return 0 ;
}
2011-05-03 19:29:01 -07:00
static const struct pcmcia_device_id airo_ids [ ] = {
2005-06-27 16:28:20 -07:00
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 ) ;
2005-04-16 15:20:36 -07:00
static struct pcmcia_driver airo_driver = {
. owner = THIS_MODULE ,
2010-08-08 11:36:26 +02:00
. name = " airo_cs " ,
2006-03-31 17:26:06 +02:00
. probe = airo_probe ,
2005-11-14 21:23:14 +01:00
. remove = airo_detach ,
2005-06-27 16:28:20 -07:00
. id_table = airo_ids ,
2005-11-14 21:21:18 +01:00
. suspend = airo_suspend ,
. resume = airo_resume ,
2005-04-16 15:20:36 -07:00
} ;
2013-03-06 11:27:43 -07:00
module_pcmcia_driver ( airo_driver ) ;
2005-04-16 15:20:36 -07:00
/*
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
2009-03-06 07:09:41 -08:00
POSSIBILITY OF SUCH DAMAGE .
2005-04-16 15:20:36 -07:00
*/