1 /*---------------------------------------------------------------------------
2 FT1000 driver for Flarion Flash OFDM NIC Device
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.
9 The initial developer of the original code is David A. Hinds
10 <dahinds@users.sourceforge.net>. Portions created by David A. Hinds.
12 This file was modified to support the Flarion Flash OFDM NIC Device
13 by Wai Chan (w.chan@flarion.com).
15 Port for kernel 2.6 created by Patrik Ostrihon (patrik.ostrihon@pwc.sk)
17 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 -----------------------------------------------------------------------------*/
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>
39 #include <linux/netdevice.h>
40 #include <linux/etherdevice.h>
42 //#include <pcmcia/version.h> // Slavius 21.10.2009 removed from kernel
43 #include <pcmcia/cs_types.h>
44 #include <pcmcia/cs.h>
45 #include <pcmcia/cistpl.h>
46 #include <pcmcia/cisreg.h>
47 #include <pcmcia/ds.h>
50 #include <asm/system.h>
51 #include <asm/byteorder.h>
52 #include <asm/uaccess.h>
54 #include "ft1000_cs.h" // Slavius 21.10.2009 because CS_SUCCESS constant is missing due to removed pcmcia/version.h
56 /*====================================================================*/
58 /* Module parameters */
60 #define INT_MODULE_PARM(n, v) static int n = v; MODULE_PARM(n, "i")
62 MODULE_AUTHOR("Wai Chan");
63 MODULE_DESCRIPTION("FT1000 PCMCIA driver");
64 MODULE_LICENSE("GPL");
66 /* Newer, simpler way of listing specific interrupts */
68 /* The old way: bit map of interrupts to choose from */
69 /* This means pick from 15, 14, 12, 11, 10, 9, 7, 5, 4, and 3 */
72 All the PCMCIA modules use PCMCIA_DEBUG to control debugging. If
73 you do not define PCMCIA_DEBUG at all, all the debug code will be
74 left out. If you compile with PCMCIA_DEBUG=0, the debug code will
75 be present but disabled.
78 #define DEBUG(n, args...) printk(KERN_DEBUG args)
80 #define DEBUG(n, args...)
83 /*====================================================================*/
85 struct net_device
*init_ft1000_card(int, int, unsigned char *,
86 void *ft1000_reset
, struct pcmcia_device
* link
,
88 void stop_ft1000_card(struct net_device
*);
90 static int ft1000_config(struct pcmcia_device
*link
);
91 static void ft1000_release(struct pcmcia_device
*link
);
94 The attach() and detach() entry points are used to create and destroy
95 "instances" of the driver, where each instance represents everything
96 needed to manage one actual PCMCIA card.
99 static void ft1000_detach(struct pcmcia_device
*link
);
100 static int ft1000_attach(struct pcmcia_device
*link
);
102 typedef struct local_info_t
{
103 struct pcmcia_device
*link
;
104 struct net_device
*dev
;
107 #define MAX_ASIC_RESET_CNT 10
108 #define COR_DEFAULT 0x55
110 /*====================================================================*/
112 static void ft1000_reset(struct pcmcia_device
* link
)
116 DEBUG(0, "ft1000_cs:ft1000_reset is called................\n");
118 /* Soft-Reset card */
119 reg
.Action
= CS_WRITE
;
120 reg
.Offset
= CISREG_COR
;
121 reg
.Value
= COR_SOFT_RESET
;
122 pcmcia_access_configuration_register(link
, ®
);
124 /* Wait until the card has acknowledged our reset */
127 /* Restore original COR configuration index */
128 /* Need at least 2 write to respond */
129 reg
.Action
= CS_WRITE
;
130 reg
.Offset
= CISREG_COR
;
131 reg
.Value
= COR_DEFAULT
;
132 pcmcia_access_configuration_register(link
, ®
);
134 /* Wait until the card has finished restarting */
137 reg
.Action
= CS_WRITE
;
138 reg
.Offset
= CISREG_COR
;
139 reg
.Value
= COR_DEFAULT
;
140 pcmcia_access_configuration_register(link
, ®
);
142 /* Wait until the card has finished restarting */
145 reg
.Action
= CS_WRITE
;
146 reg
.Offset
= CISREG_COR
;
147 reg
.Value
= COR_DEFAULT
;
148 pcmcia_access_configuration_register(link
, ®
);
150 /* Wait until the card has finished restarting */
155 /*====================================================================*/
157 static int get_tuple_first(struct pcmcia_device
*link
, tuple_t
* tuple
,
161 i
= pcmcia_get_first_tuple(link
, tuple
);
164 i
= pcmcia_get_tuple_data(link
, tuple
);
167 return pcmcia_parse_tuple(tuple
, parse
); // Slavius 21.10.2009 removed unused link parameter
170 static int get_tuple_next(struct pcmcia_device
*link
, tuple_t
* tuple
,
174 i
= pcmcia_get_next_tuple(link
, tuple
);
177 i
= pcmcia_get_tuple_data(link
, tuple
);
180 return pcmcia_parse_tuple(tuple
, parse
); // Slavius 21.10.2009 removed unused link parameter
183 /*======================================================================
186 ======================================================================*/
188 static int ft1000_attach(struct pcmcia_device
*link
)
193 DEBUG(0, "ft1000_cs: ft1000_attach()\n");
195 local
= kmalloc(sizeof(local_info_t
), GFP_KERNEL
);
199 memset(local
, 0, sizeof(local_info_t
));
205 link
->irq
.Attributes
= IRQ_TYPE_EXCLUSIVE
;
206 link
->irq
.IRQInfo1
= IRQ_LEVEL_ID
;
207 link
->conf
.Attributes
= CONF_ENABLE_IRQ
;
208 link
->conf
.IntType
= INT_MEMORY_AND_IO
;
209 link
->irq
.Handler
= NULL
;
211 return ft1000_config(link
);
212 } /* ft1000_attach */
214 /*======================================================================
216 This deletes a driver "instance". The device is de-registered
217 with Card Services. If it has been released, all local data
218 structures are freed. Otherwise, the structures will be freed
219 when the device is released.
221 ======================================================================*/
223 static void ft1000_detach(struct pcmcia_device
*link
)
225 struct net_device
*dev
= ((local_info_t
*) link
->priv
)->dev
;
227 DEBUG(0, "ft1000_cs: ft1000_detach(0x%p)\n", link
);
230 DEBUG(0,"ft1000_cs:ft1000_detach: Got a NULL pointer\n");
235 stop_ft1000_card(dev
);
238 ft1000_release(link
);
240 /* This points to the parent local_info_t struct */
243 } /* ft1000_detach */
245 /*======================================================================
247 ft1000_config() is scheduled to run after a CARD_INSERTION event
248 is received, to configure the PCMCIA socket, and to make the
249 device available to the system.
251 ======================================================================*/
253 #define CS_CHECK(fn, ret) \
254 do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
256 #define CFG_CHECK(fn, ret) \
257 last_fn = (fn); if ((last_ret = (ret)) != 0) goto next_entry
259 static int ft1000_config(struct pcmcia_device
* link
)
263 int last_fn
, last_ret
, i
;
265 cistpl_lan_node_id_t
*node_id
;
266 cistpl_cftable_entry_t dflt
= { 0 };
267 cistpl_cftable_entry_t
*cfg
;
268 unsigned char mac_address
[6];
270 DEBUG(0, "ft1000_cs: ft1000_config(0x%p)\n", link
);
273 This reads the card's CONFIG tuple to find its configuration
276 // tuple.DesiredTuple = CISTPL_CONFIG;
277 // tuple.Attributes = 0;
278 tuple
.TupleData
= buf
;
279 tuple
.TupleDataMax
= sizeof(buf
);
280 tuple
.TupleOffset
= 0;
281 // CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
282 // CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple));
283 // CS_CHECK(ParseTuple, pcmcia_parse_tuple(link, &tuple, &parse));
284 // link->conf.ConfigBase = parse.config.base;
285 // link->conf.Present = parse.config.rmask[0];
288 In this loop, we scan the CIS for configuration table entries,
289 each of which describes a valid card configuration, including
290 voltage, IO window, memory window, and interrupt settings.
292 We make no assumptions about the card to be configured: we use
293 just the information available in the CIS. In an ideal world,
294 this would work for any PCMCIA card, but it requires a complete
295 and accurate CIS. In practice, a driver usually "knows" most of
296 these things without consulting the CIS, and most client drivers
297 will only use the CIS to fill in implementation-defined details.
299 tuple
.DesiredTuple
= CISTPL_CFTABLE_ENTRY
;
300 tuple
.Attributes
= 0;
301 CS_CHECK(GetFirstTuple
, pcmcia_get_first_tuple(link
, &tuple
));
303 cfg
= &(parse
.cftable_entry
);
304 CFG_CHECK(GetTupleData
, pcmcia_get_tuple_data(link
, &tuple
));
305 CFG_CHECK(ParseTuple
,
306 pcmcia_parse_tuple(&tuple
, &parse
)); // Slavius 21.10.2009 removed unused link parameter
308 if (cfg
->flags
& CISTPL_CFTABLE_DEFAULT
)
312 link
->conf
.ConfigIndex
= cfg
->index
;
314 /* Do we need to allocate an interrupt? */
315 if (cfg
->irq
.IRQInfo1
|| dflt
.irq
.IRQInfo1
)
316 link
->conf
.Attributes
|= CONF_ENABLE_IRQ
;
318 /* IO window settings */
319 link
->io
.NumPorts1
= link
->io
.NumPorts2
= 0;
320 if ((cfg
->io
.nwin
> 0) || (dflt
.io
.nwin
> 0)) {
321 cistpl_io_t
*io
= (cfg
->io
.nwin
) ? &cfg
->io
: &dflt
.io
;
322 link
->io
.Attributes1
= IO_DATA_PATH_WIDTH_AUTO
;
323 if (!(io
->flags
& CISTPL_IO_8BIT
)) {
324 DEBUG(0, "ft1000_cs: IO_DATA_PATH_WIDTH_16\n");
325 link
->io
.Attributes1
= IO_DATA_PATH_WIDTH_16
;
327 if (!(io
->flags
& CISTPL_IO_16BIT
)) {
328 DEBUG(0, "ft1000_cs: IO_DATA_PATH_WIDTH_8\n");
329 link
->io
.Attributes1
= IO_DATA_PATH_WIDTH_8
;
331 link
->io
.IOAddrLines
= io
->flags
& CISTPL_IO_LINES_MASK
;
332 link
->io
.BasePort1
= io
->win
[0].base
;
333 link
->io
.NumPorts1
= io
->win
[0].len
;
335 link
->io
.Attributes2
= link
->io
.Attributes1
;
336 link
->io
.BasePort2
= io
->win
[1].base
;
337 link
->io
.NumPorts2
= io
->win
[1].len
;
339 /* This reserves IO space but doesn't actually enable it */
340 pcmcia_request_io(link
, &link
->io
);
346 last_ret
= pcmcia_get_next_tuple(link
, &tuple
);
348 if (last_ret
!= CS_SUCCESS
) {
349 cs_error(link
, RequestIO
, last_ret
);
354 Allocate an interrupt line. Note that this does not assign a
355 handler to the interrupt, unless the 'Handler' member of the
356 irq structure is initialized.
358 CS_CHECK(RequestIRQ
, pcmcia_request_irq(link
, &link
->irq
));
361 This actually configures the PCMCIA socket -- setting up
362 the I/O windows and the interrupt mapping, and putting the
363 card and host interface into "Memory and IO" mode.
365 CS_CHECK(RequestConfiguration
,
366 pcmcia_request_configuration(link
, &link
->conf
));
368 /* Get MAC address from tuples */
370 tuple
.Attributes
= tuple
.TupleOffset
= 0;
371 tuple
.TupleData
= buf
;
372 tuple
.TupleDataMax
= sizeof(buf
);
374 /* Check for a LAN function extension tuple */
375 tuple
.DesiredTuple
= CISTPL_FUNCE
;
376 i
= get_tuple_first(link
, &tuple
, &parse
);
377 while (i
== CS_SUCCESS
) {
378 if (parse
.funce
.type
== CISTPL_FUNCE_LAN_NODE_ID
)
380 i
= get_tuple_next(link
, &tuple
, &parse
);
383 if (i
== CS_SUCCESS
) {
384 node_id
= (cistpl_lan_node_id_t
*) parse
.funce
.data
;
385 if (node_id
->nb
== 6) {
386 for (i
= 0; i
< 6; i
++)
387 mac_address
[i
] = node_id
->id
[i
];
391 ((local_info_t
*) link
->priv
)->dev
=
392 init_ft1000_card(link
->irq
.AssignedIRQ
, link
->io
.BasePort1
,
393 &mac_address
[0], ft1000_reset
, link
,
394 &handle_to_dev(link
));
397 At this point, the dev_node_t structure(s) need to be
398 initialized and arranged in a linked list at link->dev.
401 /* Finally, report what we've done */
406 cs_error(link
, last_fn
, last_ret
);
408 ft1000_release(link
);
411 } /* ft1000_config */
413 /*======================================================================
415 After a card is removed, ft1000_release() will unregister the
416 device, and release the PCMCIA configuration. If the device is
417 still open, this will be postponed until it is closed.
419 ======================================================================*/
421 static void ft1000_release(struct pcmcia_device
* link
)
424 DEBUG(0, "ft1000_cs: ft1000_release(0x%p)\n", link
);
427 If the device is currently in use, we won't release until it
428 is actually closed, because until then, we can't be sure that
429 no one will try to access the device or its data structures.
432 /* Unlink the device chain */
433 link
->dev_node
= NULL
;
436 In a normal driver, additional code may be needed to release
437 other kernel data structures associated with this device.
440 /* Don't bother checking to see if these succeed or not */
442 pcmcia_disable_device(link
);
443 } /* ft1000_release */
445 /*======================================================================
447 The card status event handler. Mostly, this schedules other
448 stuff to run after an event is received.
450 When a CARD_REMOVAL event is received, we immediately set a
451 private flag to block future accesses to this device. All the
452 functions that actually access the device should check this flag
453 to make sure the card is still present.
455 ======================================================================*/
457 static int ft1000_suspend(struct pcmcia_device
*link
)
459 struct net_device
*dev
= ((local_info_t
*) link
->priv
)->dev
;
461 DEBUG(1, "ft1000_cs: ft1000_event(0x%06x)\n", event
);
464 netif_device_detach(dev
);
468 static int ft1000_resume(struct pcmcia_device
*link
)
470 /* struct net_device *dev = link->priv;
477 /*====================================================================*/
479 static struct pcmcia_device_id ft1000_ids
[] = {
480 PCMCIA_DEVICE_MANF_CARD(0x02cc, 0x0100),
481 PCMCIA_DEVICE_MANF_CARD(0x02cc, 0x1000),
482 PCMCIA_DEVICE_MANF_CARD(0x02cc, 0x1300),
486 MODULE_DEVICE_TABLE(pcmcia
, ft1000_ids
);
488 static struct pcmcia_driver ft1000_cs_driver
= {
489 .owner
= THIS_MODULE
,
493 .probe
= ft1000_attach
,
494 .remove
= ft1000_detach
,
495 .id_table
= ft1000_ids
,
496 .suspend
= ft1000_suspend
,
497 .resume
= ft1000_resume
,
500 static int __init
init_ft1000_cs(void)
502 DEBUG(0, "ft1000_cs: loading\n");
503 return pcmcia_register_driver(&ft1000_cs_driver
);
506 static void __exit
exit_ft1000_cs(void)
508 DEBUG(0, "ft1000_cs: unloading\n");
509 pcmcia_unregister_driver(&ft1000_cs_driver
);
512 module_init(init_ft1000_cs
);
513 module_exit(exit_ft1000_cs
);