blob: 798b92c4d5f59422b6145c2b4139a7770d2e58bf [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
53/* Module parameters */
54
55#define INT_MODULE_PARM(n, v) static int n = v; MODULE_PARM(n, "i")
56
57MODULE_AUTHOR("Wai Chan");
58MODULE_DESCRIPTION("FT1000 PCMCIA driver");
59MODULE_LICENSE("GPL");
60
61/* Newer, simpler way of listing specific interrupts */
62
63/* The old way: bit map of interrupts to choose from */
64/* This means pick from 15, 14, 12, 11, 10, 9, 7, 5, 4, and 3 */
65
66/*
67 All the PCMCIA modules use PCMCIA_DEBUG to control debugging. If
68 you do not define PCMCIA_DEBUG at all, all the debug code will be
69 left out. If you compile with PCMCIA_DEBUG=0, the debug code will
70 be present but disabled.
71*/
72#ifdef FT_DEBUG
73#define DEBUG(n, args...) printk(KERN_DEBUG args)
74#else
75#define DEBUG(n, args...)
76#endif
77
78/*====================================================================*/
79
Marek Beliskoc331e762011-01-10 13:14:28 +010080struct net_device *init_ft1000_card(struct pcmcia_device *link,
81 void *ft1000_reset);
Marek Beliskof7c1be02010-09-22 07:56:27 +020082void stop_ft1000_card(struct net_device *);
83
84static int ft1000_config(struct pcmcia_device *link);
85static void ft1000_release(struct pcmcia_device *link);
86
87/*
88 The attach() and detach() entry points are used to create and destroy
89 "instances" of the driver, where each instance represents everything
90 needed to manage one actual PCMCIA card.
91*/
92
93static void ft1000_detach(struct pcmcia_device *link);
94static int ft1000_attach(struct pcmcia_device *link);
95
96typedef struct local_info_t {
97 struct pcmcia_device *link;
98 struct net_device *dev;
99} local_info_t;
100
101#define MAX_ASIC_RESET_CNT 10
102#define COR_DEFAULT 0x55
103
104/*====================================================================*/
105
106static void ft1000_reset(struct pcmcia_device * link)
107{
Marek Beliskoc331e762011-01-10 13:14:28 +0100108 pcmcia_reset_card(link->socket);
Marek Beliskof7c1be02010-09-22 07:56:27 +0200109}
110
111/*======================================================================
112
Greg Kroah-Hartmanbf3146c2010-09-22 08:34:49 -0700113
Marek Beliskof7c1be02010-09-22 07:56:27 +0200114======================================================================*/
115
116static int ft1000_attach(struct pcmcia_device *link)
117{
118
119 local_info_t *local;
120
121 DEBUG(0, "ft1000_cs: ft1000_attach()\n");
122
Alexander Beregalov2f481312011-03-09 03:53:37 +0300123 local = kzalloc(sizeof(local_info_t), GFP_KERNEL);
Marek Beliskof7c1be02010-09-22 07:56:27 +0200124 if (!local) {
125 return -ENOMEM;
126 }
Marek Beliskof7c1be02010-09-22 07:56:27 +0200127 local->link = link;
128
129 link->priv = local;
130 local->dev = NULL;
131
Marek Beliskoc331e762011-01-10 13:14:28 +0100132 link->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_SET_IO;
Marek Beliskof7c1be02010-09-22 07:56:27 +0200133
134 return ft1000_config(link);
Marek Beliskoc331e762011-01-10 13:14:28 +0100135
Marek Beliskof7c1be02010-09-22 07:56:27 +0200136} /* ft1000_attach */
137
138/*======================================================================
139
140 This deletes a driver "instance". The device is de-registered
141 with Card Services. If it has been released, all local data
142 structures are freed. Otherwise, the structures will be freed
143 when the device is released.
144
145======================================================================*/
146
147static void ft1000_detach(struct pcmcia_device *link)
148{
149 struct net_device *dev = ((local_info_t *) link->priv)->dev;
150
151 DEBUG(0, "ft1000_cs: ft1000_detach(0x%p)\n", link);
152
153 if (link == NULL) {
154 DEBUG(0,"ft1000_cs:ft1000_detach: Got a NULL pointer\n");
155 return;
156 }
157
158 if (dev) {
159 stop_ft1000_card(dev);
160 }
161
Marek Beliskoc331e762011-01-10 13:14:28 +0100162 pcmcia_disable_device(link);
Marek Beliskof7c1be02010-09-22 07:56:27 +0200163
164 /* This points to the parent local_info_t struct */
165 free_netdev(dev);
166
167} /* ft1000_detach */
168
169/*======================================================================
170
Marek Beliskoc331e762011-01-10 13:14:28 +0100171 Check if the io window is configured
172
173======================================================================*/
174int ft1000_confcheck(struct pcmcia_device *link, void *priv_data)
175{
176
177 return pcmcia_request_io(link);
178} /* ft1000_confcheck */
179
180/*======================================================================
181
Marek Beliskof7c1be02010-09-22 07:56:27 +0200182 ft1000_config() is scheduled to run after a CARD_INSERTION event
183 is received, to configure the PCMCIA socket, and to make the
184 device available to the system.
Greg Kroah-Hartmanbf3146c2010-09-22 08:34:49 -0700185
Marek Beliskof7c1be02010-09-22 07:56:27 +0200186======================================================================*/
187
Marek Beliskoc331e762011-01-10 13:14:28 +0100188static int ft1000_config(struct pcmcia_device *link)
Marek Beliskof7c1be02010-09-22 07:56:27 +0200189{
Marek Beliskoc331e762011-01-10 13:14:28 +0100190 int ret;
Marek Beliskof7c1be02010-09-22 07:56:27 +0200191
Marek Beliskoc331e762011-01-10 13:14:28 +0100192 dev_dbg(&link->dev, "ft1000_cs: ft1000_config(0x%p)\n", link);
Marek Beliskof7c1be02010-09-22 07:56:27 +0200193
Marek Beliskoc331e762011-01-10 13:14:28 +0100194 /* setup IO window */
195 ret = pcmcia_loop_config(link, ft1000_confcheck, NULL);
196 if (ret) {
197 printk(KERN_INFO "ft1000: Could not configure pcmcia\n");
198 return -ENODEV;
Marek Beliskof7c1be02010-09-22 07:56:27 +0200199 }
Marek Beliskoc331e762011-01-10 13:14:28 +0100200
201 /* configure device */
202 ret = pcmcia_enable_device(link);
203 if (ret) {
204 printk(KERN_INFO "ft1000: could not enable pcmcia\n");
Marek Beliskof7c1be02010-09-22 07:56:27 +0200205 goto failed;
Greg Kroah-Hartmanbf3146c2010-09-22 08:34:49 -0700206 }
Marek Beliskof7c1be02010-09-22 07:56:27 +0200207
Marek Beliskoc331e762011-01-10 13:14:28 +0100208 ((local_info_t *) link->priv)->dev = init_ft1000_card(link,
209 &ft1000_reset);
210 if (((local_info_t *) link->priv)->dev == NULL) {
211 printk(KERN_INFO "ft1000: Could not register as network device\n");
212 goto failed;
Marek Beliskof7c1be02010-09-22 07:56:27 +0200213 }
214
Marek Beliskof7c1be02010-09-22 07:56:27 +0200215 /* Finally, report what we've done */
216
217 return 0;
Marek Beliskof7c1be02010-09-22 07:56:27 +0200218failed:
219 ft1000_release(link);
220 return -ENODEV;
221
222} /* ft1000_config */
223
224/*======================================================================
225
226 After a card is removed, ft1000_release() will unregister the
227 device, and release the PCMCIA configuration. If the device is
228 still open, this will be postponed until it is closed.
Greg Kroah-Hartmanbf3146c2010-09-22 08:34:49 -0700229
Marek Beliskof7c1be02010-09-22 07:56:27 +0200230======================================================================*/
231
232static void ft1000_release(struct pcmcia_device * link)
233{
234
235 DEBUG(0, "ft1000_cs: ft1000_release(0x%p)\n", link);
236
237 /*
238 If the device is currently in use, we won't release until it
239 is actually closed, because until then, we can't be sure that
240 no one will try to access the device or its data structures.
241 */
242
Marek Beliskof7c1be02010-09-22 07:56:27 +0200243 /*
244 In a normal driver, additional code may be needed to release
Greg Kroah-Hartmanbf3146c2010-09-22 08:34:49 -0700245 other kernel data structures associated with this device.
Marek Beliskof7c1be02010-09-22 07:56:27 +0200246 */
Marek Beliskoc331e762011-01-10 13:14:28 +0100247 kfree((local_info_t *) link->priv);
Marek Beliskof7c1be02010-09-22 07:56:27 +0200248 /* Don't bother checking to see if these succeed or not */
249
250 pcmcia_disable_device(link);
251} /* ft1000_release */
252
253/*======================================================================
254
255 The card status event handler. Mostly, this schedules other
256 stuff to run after an event is received.
257
258 When a CARD_REMOVAL event is received, we immediately set a
259 private flag to block future accesses to this device. All the
260 functions that actually access the device should check this flag
261 to make sure the card is still present.
Greg Kroah-Hartmanbf3146c2010-09-22 08:34:49 -0700262
Marek Beliskof7c1be02010-09-22 07:56:27 +0200263======================================================================*/
264
265static int ft1000_suspend(struct pcmcia_device *link)
266{
267 struct net_device *dev = ((local_info_t *) link->priv)->dev;
268
Marek Beliskof7c1be02010-09-22 07:56:27 +0200269 if (link->open)
270 netif_device_detach(dev);
271 return 0;
272}
273
274static int ft1000_resume(struct pcmcia_device *link)
275{
276/* struct net_device *dev = link->priv;
277 */
278 return 0;
279}
280
281
282
283/*====================================================================*/
284
Joe Perches2202a5a2011-05-03 19:29:02 -0700285static const struct pcmcia_device_id ft1000_ids[] = {
Marek Beliskof7c1be02010-09-22 07:56:27 +0200286 PCMCIA_DEVICE_MANF_CARD(0x02cc, 0x0100),
287 PCMCIA_DEVICE_MANF_CARD(0x02cc, 0x1000),
288 PCMCIA_DEVICE_MANF_CARD(0x02cc, 0x1300),
289 PCMCIA_DEVICE_NULL,
290};
291
292MODULE_DEVICE_TABLE(pcmcia, ft1000_ids);
293
294static struct pcmcia_driver ft1000_cs_driver = {
295 .owner = THIS_MODULE,
Ondrej Zary01cafa52011-07-01 00:03:30 +0200296 .name = "ft1000_cs",
Marek Beliskof7c1be02010-09-22 07:56:27 +0200297 .probe = ft1000_attach,
298 .remove = ft1000_detach,
299 .id_table = ft1000_ids,
300 .suspend = ft1000_suspend,
301 .resume = ft1000_resume,
302};
303
304static int __init init_ft1000_cs(void)
305{
306 DEBUG(0, "ft1000_cs: loading\n");
307 return pcmcia_register_driver(&ft1000_cs_driver);
308}
309
310static void __exit exit_ft1000_cs(void)
311{
312 DEBUG(0, "ft1000_cs: unloading\n");
313 pcmcia_unregister_driver(&ft1000_cs_driver);
314}
315
316module_init(init_ft1000_cs);
317module_exit(exit_ft1000_cs);