blob: 34fc21f82cbe8774f7c303a875e5e982e4aec110 [file] [log] [blame]
Marek Beliskof7c1be02010-09-22 07:56:27 +02001/*---------------------------------------------------------------------------
2 FT1000 driver for Flarion Flash OFDM NIC Device
3
4 Copyright (C) 1999 David A. Hinds. All Rights Reserved.
5 Copyright (C) 2002 Flarion Technologies, All rights reserved.
6 Copyright (C) 2006 Patrik Ostrihon, All rights reserved.
7 Copyright (C) 2006 ProWeb Consulting, a.s, All rights reserved.
8
9 The initial developer of the original code is David A. Hinds
10 <dahinds@users.sourceforge.net>. Portions created by David A. Hinds.
11
12 This file was modified to support the Flarion Flash OFDM NIC Device
13 by Wai Chan (w.chan@flarion.com).
14
15 Port for kernel 2.6 created by Patrik Ostrihon (patrik.ostrihon@pwc.sk)
Greg Kroah-Hartmanbf3146c2010-09-22 08:34:49 -070016
Marek Beliskof7c1be02010-09-22 07:56:27 +020017 This program is free software; you can redistribute it and/or modify it
18 under the terms of the GNU General Public License as published by the Free
19 Software Foundation; either version 2 of the License, or (at your option) any
20 later version. This program is distributed in the hope that it will be useful,
21 but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
22 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
23 more details. You should have received a copy of the GNU General Public
24 License along with this program; if not, write to the
25 Free Software Foundation, Inc., 59 Temple Place -
26 Suite 330, Boston, MA 02111-1307, USA.
27-----------------------------------------------------------------------------*/
28
29#include <linux/kernel.h>
30#include <linux/module.h>
31#include <linux/init.h>
32#include <linux/ptrace.h>
33#include <linux/slab.h>
34#include <linux/string.h>
35#include <linux/timer.h>
36#include <linux/ioport.h>
37#include <linux/delay.h>
38
39#include <linux/netdevice.h>
40#include <linux/etherdevice.h>
41
Marek Beliskof7c1be02010-09-22 07:56:27 +020042#include <pcmcia/cistpl.h>
43#include <pcmcia/cisreg.h>
44#include <pcmcia/ds.h>
45
46#include <asm/io.h>
47#include <asm/system.h>
48#include <asm/byteorder.h>
49#include <asm/uaccess.h>
50
Marek Beliskof7c1be02010-09-22 07:56:27 +020051/*====================================================================*/
52
Marek Beliskof7c1be02010-09-22 07:56:27 +020053MODULE_AUTHOR("Wai Chan");
54MODULE_DESCRIPTION("FT1000 PCMCIA driver");
55MODULE_LICENSE("GPL");
56
Marek Beliskof7c1be02010-09-22 07:56:27 +020057/*====================================================================*/
58
Marek Beliskoc331e762011-01-10 13:14:28 +010059struct net_device *init_ft1000_card(struct pcmcia_device *link,
60 void *ft1000_reset);
Marek Beliskof7c1be02010-09-22 07:56:27 +020061void stop_ft1000_card(struct net_device *);
62
63static int ft1000_config(struct pcmcia_device *link);
64static void ft1000_release(struct pcmcia_device *link);
Marek Beliskof7c1be02010-09-22 07:56:27 +020065static void ft1000_detach(struct pcmcia_device *link);
66static int ft1000_attach(struct pcmcia_device *link);
67
Marek Beliskof7c1be02010-09-22 07:56:27 +020068/*====================================================================*/
69
70static void ft1000_reset(struct pcmcia_device * link)
71{
Marek Beliskoc331e762011-01-10 13:14:28 +010072 pcmcia_reset_card(link->socket);
Marek Beliskof7c1be02010-09-22 07:56:27 +020073}
74
Marek Beliskof7c1be02010-09-22 07:56:27 +020075static int ft1000_attach(struct pcmcia_device *link)
76{
Ondrej Zary43707822011-07-01 00:03:44 +020077 link->priv = NULL;
Marek Beliskoc331e762011-01-10 13:14:28 +010078 link->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_SET_IO;
Marek Beliskof7c1be02010-09-22 07:56:27 +020079
80 return ft1000_config(link);
Marek Beliskoc331e762011-01-10 13:14:28 +010081
Ondrej Zary3061fab2011-07-01 00:03:50 +020082}
Marek Beliskof7c1be02010-09-22 07:56:27 +020083
84static void ft1000_detach(struct pcmcia_device *link)
85{
Ondrej Zary43707822011-07-01 00:03:44 +020086 struct net_device *dev = link->priv;
Marek Beliskof7c1be02010-09-22 07:56:27 +020087
Marek Beliskof7c1be02010-09-22 07:56:27 +020088 if (dev) {
89 stop_ft1000_card(dev);
90 }
91
Marek Beliskoc331e762011-01-10 13:14:28 +010092 pcmcia_disable_device(link);
Marek Beliskof7c1be02010-09-22 07:56:27 +020093
Marek Beliskof7c1be02010-09-22 07:56:27 +020094 free_netdev(dev);
95
Ondrej Zary3061fab2011-07-01 00:03:50 +020096}
Marek Beliskof7c1be02010-09-22 07:56:27 +020097
Marek Beliskoc331e762011-01-10 13:14:28 +010098int ft1000_confcheck(struct pcmcia_device *link, void *priv_data)
99{
Marek Beliskoc331e762011-01-10 13:14:28 +0100100 return pcmcia_request_io(link);
Ondrej Zary3061fab2011-07-01 00:03:50 +0200101}
Marek Beliskoc331e762011-01-10 13:14:28 +0100102
103/*======================================================================
104
Marek Beliskof7c1be02010-09-22 07:56:27 +0200105 ft1000_config() is scheduled to run after a CARD_INSERTION event
106 is received, to configure the PCMCIA socket, and to make the
107 device available to the system.
Greg Kroah-Hartmanbf3146c2010-09-22 08:34:49 -0700108
Marek Beliskof7c1be02010-09-22 07:56:27 +0200109======================================================================*/
110
Marek Beliskoc331e762011-01-10 13:14:28 +0100111static int ft1000_config(struct pcmcia_device *link)
Marek Beliskof7c1be02010-09-22 07:56:27 +0200112{
Marek Beliskoc331e762011-01-10 13:14:28 +0100113 int ret;
Marek Beliskof7c1be02010-09-22 07:56:27 +0200114
Marek Beliskoc331e762011-01-10 13:14:28 +0100115 dev_dbg(&link->dev, "ft1000_cs: ft1000_config(0x%p)\n", link);
Marek Beliskof7c1be02010-09-22 07:56:27 +0200116
Marek Beliskoc331e762011-01-10 13:14:28 +0100117 /* setup IO window */
118 ret = pcmcia_loop_config(link, ft1000_confcheck, NULL);
119 if (ret) {
120 printk(KERN_INFO "ft1000: Could not configure pcmcia\n");
121 return -ENODEV;
Marek Beliskof7c1be02010-09-22 07:56:27 +0200122 }
Marek Beliskoc331e762011-01-10 13:14:28 +0100123
124 /* configure device */
125 ret = pcmcia_enable_device(link);
126 if (ret) {
127 printk(KERN_INFO "ft1000: could not enable pcmcia\n");
Marek Beliskof7c1be02010-09-22 07:56:27 +0200128 goto failed;
Greg Kroah-Hartmanbf3146c2010-09-22 08:34:49 -0700129 }
Marek Beliskof7c1be02010-09-22 07:56:27 +0200130
Ondrej Zary43707822011-07-01 00:03:44 +0200131 link->priv = init_ft1000_card(link, &ft1000_reset);
132 if (link->priv == NULL) {
Marek Beliskoc331e762011-01-10 13:14:28 +0100133 printk(KERN_INFO "ft1000: Could not register as network device\n");
134 goto failed;
Marek Beliskof7c1be02010-09-22 07:56:27 +0200135 }
136
Marek Beliskof7c1be02010-09-22 07:56:27 +0200137 /* Finally, report what we've done */
138
139 return 0;
Marek Beliskof7c1be02010-09-22 07:56:27 +0200140failed:
141 ft1000_release(link);
142 return -ENODEV;
143
Ondrej Zary3061fab2011-07-01 00:03:50 +0200144}
Marek Beliskof7c1be02010-09-22 07:56:27 +0200145
146/*======================================================================
147
148 After a card is removed, ft1000_release() will unregister the
149 device, and release the PCMCIA configuration. If the device is
150 still open, this will be postponed until it is closed.
Greg Kroah-Hartmanbf3146c2010-09-22 08:34:49 -0700151
Marek Beliskof7c1be02010-09-22 07:56:27 +0200152======================================================================*/
153
154static void ft1000_release(struct pcmcia_device * link)
155{
Marek Beliskof7c1be02010-09-22 07:56:27 +0200156 pcmcia_disable_device(link);
Ondrej Zary3061fab2011-07-01 00:03:50 +0200157}
Marek Beliskof7c1be02010-09-22 07:56:27 +0200158
159static int ft1000_suspend(struct pcmcia_device *link)
160{
Ondrej Zary43707822011-07-01 00:03:44 +0200161 struct net_device *dev = link->priv;
Marek Beliskof7c1be02010-09-22 07:56:27 +0200162
Marek Beliskof7c1be02010-09-22 07:56:27 +0200163 if (link->open)
164 netif_device_detach(dev);
165 return 0;
166}
167
168static int ft1000_resume(struct pcmcia_device *link)
169{
Marek Beliskof7c1be02010-09-22 07:56:27 +0200170 return 0;
171}
172
Marek Beliskof7c1be02010-09-22 07:56:27 +0200173/*====================================================================*/
174
Joe Perches2202a5a2011-05-03 19:29:02 -0700175static const struct pcmcia_device_id ft1000_ids[] = {
Marek Beliskof7c1be02010-09-22 07:56:27 +0200176 PCMCIA_DEVICE_MANF_CARD(0x02cc, 0x0100),
177 PCMCIA_DEVICE_MANF_CARD(0x02cc, 0x1000),
178 PCMCIA_DEVICE_MANF_CARD(0x02cc, 0x1300),
179 PCMCIA_DEVICE_NULL,
180};
181
182MODULE_DEVICE_TABLE(pcmcia, ft1000_ids);
183
184static struct pcmcia_driver ft1000_cs_driver = {
185 .owner = THIS_MODULE,
Ondrej Zary01cafa52011-07-01 00:03:30 +0200186 .name = "ft1000_cs",
Marek Beliskof7c1be02010-09-22 07:56:27 +0200187 .probe = ft1000_attach,
188 .remove = ft1000_detach,
189 .id_table = ft1000_ids,
190 .suspend = ft1000_suspend,
191 .resume = ft1000_resume,
192};
193
194static int __init init_ft1000_cs(void)
195{
Marek Beliskof7c1be02010-09-22 07:56:27 +0200196 return pcmcia_register_driver(&ft1000_cs_driver);
197}
198
199static void __exit exit_ft1000_cs(void)
200{
Marek Beliskof7c1be02010-09-22 07:56:27 +0200201 pcmcia_unregister_driver(&ft1000_cs_driver);
202}
203
204module_init(init_ft1000_cs);
205module_exit(exit_ft1000_cs);