[PATCH] pcmcia: remove dev_link_t and client_handle_t indirection
[linux-2.6-block.git] / drivers / net / pcmcia / ibmtr_cs.c
CommitLineData
1da177e4
LT
1/*======================================================================
2
3 A PCMCIA token-ring driver for IBM-based cards
4
5 This driver supports the IBM PCMCIA Token-Ring Card.
6 Written by Steve Kipisz, kipisz@vnet.ibm.com or
7 bungy@ibm.net
8
9 Written 1995,1996.
10
11 This code is based on pcnet_cs.c from David Hinds.
12
13 V2.2.0 February 1999 - Mike Phillips phillim@amtrak.com
14
15 Linux V2.2.x presented significant changes to the underlying
16 ibmtr.c code. Mainly the code became a lot more organized and
17 modular.
18
19 This caused the old PCMCIA Token Ring driver to give up and go
20 home early. Instead of just patching the old code to make it
21 work, the PCMCIA code has been streamlined, updated and possibly
22 improved.
23
24 This code now only contains code required for the Card Services.
25 All we do here is set the card up enough so that the real ibmtr.c
26 driver can find it and work with it properly.
27
28 i.e. We set up the io port, irq, mmio memory and shared ram
29 memory. This enables ibmtr_probe in ibmtr.c to find the card and
30 configure it as though it was a normal ISA and/or PnP card.
31
32 CHANGES
33
34 v2.2.5 April 1999 Mike Phillips (phillim@amtrak.com)
35 Obscure bug fix, required changed to ibmtr.c not ibmtr_cs.c
36
37 v2.2.7 May 1999 Mike Phillips (phillim@amtrak.com)
38 Updated to version 2.2.7 to match the first version of the kernel
39 that the modification to ibmtr.c were incorporated into.
40
41 v2.2.17 July 2000 Burt Silverman (burts@us.ibm.com)
42 Address translation feature of PCMCIA controller is usable so
43 memory windows can be placed in High memory (meaning above
44 0xFFFFF.)
45
46======================================================================*/
47
48#include <linux/kernel.h>
49#include <linux/init.h>
50#include <linux/ptrace.h>
51#include <linux/slab.h>
52#include <linux/string.h>
53#include <linux/timer.h>
54#include <linux/module.h>
55#include <linux/ethtool.h>
56#include <linux/netdevice.h>
57#include <linux/trdevice.h>
58#include <linux/ibmtr.h>
59
1da177e4
LT
60#include <pcmcia/cs_types.h>
61#include <pcmcia/cs.h>
62#include <pcmcia/cistpl.h>
63#include <pcmcia/ds.h>
64
65#include <asm/uaccess.h>
66#include <asm/io.h>
67#include <asm/system.h>
68
69#define PCMCIA
70#include "../tokenring/ibmtr.c"
71
72#ifdef PCMCIA_DEBUG
73static int pc_debug = PCMCIA_DEBUG;
74module_param(pc_debug, int, 0);
75#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
76static char *version =
77"ibmtr_cs.c 1.10 1996/01/06 05:19:00 (Steve Kipisz)\n"
78" 2.2.7 1999/05/03 12:00:00 (Mike Phillips)\n"
79" 2.4.2 2001/30/28 Midnight (Burt Silverman)\n";
80#else
81#define DEBUG(n, args...)
82#endif
83
84/*====================================================================*/
85
86/* Parameters that can be set with 'insmod' */
87
88/* MMIO base address */
89static u_long mmiobase = 0xce000;
90
91/* SRAM base address */
92static u_long srambase = 0xd0000;
93
94/* SRAM size 8,16,32,64 */
95static u_long sramsize = 64;
96
97/* Ringspeed 4,16 */
98static int ringspeed = 16;
99
100module_param(mmiobase, ulong, 0);
101module_param(srambase, ulong, 0);
102module_param(sramsize, ulong, 0);
103module_param(ringspeed, int, 0);
104MODULE_LICENSE("GPL");
105
106/*====================================================================*/
107
fba395ee 108static void ibmtr_config(struct pcmcia_device *link);
1da177e4 109static void ibmtr_hw_setup(struct net_device *dev, u_int mmiobase);
fba395ee 110static void ibmtr_release(struct pcmcia_device *link);
cc3b4866 111static void ibmtr_detach(struct pcmcia_device *p_dev);
1da177e4 112
1da177e4
LT
113/*====================================================================*/
114
115typedef struct ibmtr_dev_t {
fd238232 116 struct pcmcia_device *p_dev;
1da177e4
LT
117 struct net_device *dev;
118 dev_node_t node;
119 window_handle_t sram_win_handle;
120 struct tok_info *ti;
121} ibmtr_dev_t;
122
123static void netdev_get_drvinfo(struct net_device *dev,
124 struct ethtool_drvinfo *info)
125{
126 strcpy(info->driver, "ibmtr_cs");
127}
128
129static struct ethtool_ops netdev_ethtool_ops = {
130 .get_drvinfo = netdev_get_drvinfo,
131};
132
133/*======================================================================
134
135 ibmtr_attach() creates an "instance" of the driver, allocating
136 local data structures for one device. The device is registered
137 with Card Services.
138
139======================================================================*/
140
fba395ee 141static int ibmtr_attach(struct pcmcia_device *link)
1da177e4
LT
142{
143 ibmtr_dev_t *info;
1da177e4 144 struct net_device *dev;
fba395ee 145
1da177e4
LT
146 DEBUG(0, "ibmtr_attach()\n");
147
148 /* Create new token-ring device */
149 info = kmalloc(sizeof(*info), GFP_KERNEL);
f8cfa618 150 if (!info) return -ENOMEM;
1da177e4
LT
151 memset(info,0,sizeof(*info));
152 dev = alloc_trdev(sizeof(struct tok_info));
f8cfa618
DB
153 if (!dev) {
154 kfree(info);
155 return -ENOMEM;
156 }
1da177e4 157
fba395ee 158 info->p_dev = link;
1da177e4
LT
159 link->priv = info;
160 info->ti = netdev_priv(dev);
161
162 link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
163 link->io.NumPorts1 = 4;
164 link->io.IOAddrLines = 16;
165 link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT;
166 link->irq.IRQInfo1 = IRQ_LEVEL_ID;
167 link->irq.Handler = &tok_interrupt;
168 link->conf.Attributes = CONF_ENABLE_IRQ;
1da177e4
LT
169 link->conf.IntType = INT_MEMORY_AND_IO;
170 link->conf.Present = PRESENT_OPTION;
171
172 link->irq.Instance = info->dev = dev;
1da177e4 173
fd238232 174 SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops);
1da177e4 175
f8cfa618
DB
176 link->state |= DEV_PRESENT;
177 ibmtr_config(link);
1da177e4 178
f8cfa618 179 return 0;
1da177e4
LT
180} /* ibmtr_attach */
181
182/*======================================================================
183
184 This deletes a driver "instance". The device is de-registered
185 with Card Services. If it has been released, all local data
186 structures are freed. Otherwise, the structures will be freed
187 when the device is released.
188
189======================================================================*/
190
fba395ee 191static void ibmtr_detach(struct pcmcia_device *link)
1da177e4
LT
192{
193 struct ibmtr_dev_t *info = link->priv;
b4635811 194 struct net_device *dev = info->dev;
1da177e4
LT
195
196 DEBUG(0, "ibmtr_detach(0x%p)\n", link);
197
fd238232 198 if (link->dev_node)
1da177e4
LT
199 unregister_netdev(dev);
200
201 {
202 struct tok_info *ti = netdev_priv(dev);
203 del_timer_sync(&(ti->tr_timer));
204 }
205 if (link->state & DEV_CONFIG)
206 ibmtr_release(link);
207
1da177e4 208 free_netdev(dev);
b4635811 209 kfree(info);
1da177e4
LT
210} /* ibmtr_detach */
211
212/*======================================================================
213
214 ibmtr_config() is scheduled to run after a CARD_INSERTION event
215 is received, to configure the PCMCIA socket, and to make the
216 token-ring device available to the system.
217
218======================================================================*/
219
220#define CS_CHECK(fn, ret) \
221do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
222
fba395ee 223static void ibmtr_config(struct pcmcia_device *link)
1da177e4 224{
1da177e4
LT
225 ibmtr_dev_t *info = link->priv;
226 struct net_device *dev = info->dev;
227 struct tok_info *ti = netdev_priv(dev);
228 tuple_t tuple;
229 cisparse_t parse;
230 win_req_t req;
231 memreq_t mem;
232 int i, last_ret, last_fn;
233 u_char buf[64];
234
235 DEBUG(0, "ibmtr_config(0x%p)\n", link);
236
237 tuple.Attributes = 0;
238 tuple.TupleData = buf;
239 tuple.TupleDataMax = 64;
240 tuple.TupleOffset = 0;
241 tuple.DesiredTuple = CISTPL_CONFIG;
fba395ee
DB
242 CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
243 CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple));
244 CS_CHECK(ParseTuple, pcmcia_parse_tuple(link, &tuple, &parse));
1da177e4
LT
245 link->conf.ConfigBase = parse.config.base;
246
247 /* Configure card */
248 link->state |= DEV_CONFIG;
249
250 link->conf.ConfigIndex = 0x61;
251
252 /* Determine if this is PRIMARY or ALTERNATE. */
253
254 /* Try PRIMARY card at 0xA20-0xA23 */
255 link->io.BasePort1 = 0xA20;
fba395ee 256 i = pcmcia_request_io(link, &link->io);
1da177e4
LT
257 if (i != CS_SUCCESS) {
258 /* Couldn't get 0xA20-0xA23. Try ALTERNATE at 0xA24-0xA27. */
259 link->io.BasePort1 = 0xA24;
fba395ee 260 CS_CHECK(RequestIO, pcmcia_request_io(link, &link->io));
1da177e4
LT
261 }
262 dev->base_addr = link->io.BasePort1;
263
fba395ee 264 CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
1da177e4
LT
265 dev->irq = link->irq.AssignedIRQ;
266 ti->irq = link->irq.AssignedIRQ;
267 ti->global_int_enable=GLOBAL_INT_ENABLE+((dev->irq==9) ? 2 : dev->irq);
268
269 /* Allocate the MMIO memory window */
270 req.Attributes = WIN_DATA_WIDTH_16|WIN_MEMORY_TYPE_CM|WIN_ENABLE;
271 req.Attributes |= WIN_USE_WAIT;
272 req.Base = 0;
273 req.Size = 0x2000;
274 req.AccessSpeed = 250;
fba395ee 275 CS_CHECK(RequestWindow, pcmcia_request_window(&link, &req, &link->win));
1da177e4
LT
276
277 mem.CardOffset = mmiobase;
278 mem.Page = 0;
279 CS_CHECK(MapMemPage, pcmcia_map_mem_page(link->win, &mem));
280 ti->mmio = ioremap(req.Base, req.Size);
281
282 /* Allocate the SRAM memory window */
283 req.Attributes = WIN_DATA_WIDTH_16|WIN_MEMORY_TYPE_CM|WIN_ENABLE;
284 req.Attributes |= WIN_USE_WAIT;
285 req.Base = 0;
286 req.Size = sramsize * 1024;
287 req.AccessSpeed = 250;
fba395ee 288 CS_CHECK(RequestWindow, pcmcia_request_window(&link, &req, &info->sram_win_handle));
1da177e4
LT
289
290 mem.CardOffset = srambase;
291 mem.Page = 0;
292 CS_CHECK(MapMemPage, pcmcia_map_mem_page(info->sram_win_handle, &mem));
293
294 ti->sram_base = mem.CardOffset >> 12;
295 ti->sram_virt = ioremap(req.Base, req.Size);
296 ti->sram_phys = req.Base;
297
fba395ee 298 CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf));
1da177e4
LT
299
300 /* Set up the Token-Ring Controller Configuration Register and
301 turn on the card. Check the "Local Area Network Credit Card
302 Adapters Technical Reference" SC30-3585 for this info. */
303 ibmtr_hw_setup(dev, mmiobase);
304
fd238232 305 link->dev_node = &info->node;
1da177e4 306 link->state &= ~DEV_CONFIG_PENDING;
fba395ee 307 SET_NETDEV_DEV(dev, &handle_to_dev(link));
1da177e4
LT
308
309 i = ibmtr_probe_card(dev);
310 if (i != 0) {
311 printk(KERN_NOTICE "ibmtr_cs: register_netdev() failed\n");
fd238232 312 link->dev_node = NULL;
1da177e4
LT
313 goto failed;
314 }
315
316 strcpy(info->node.dev_name, dev->name);
317
318 printk(KERN_INFO "%s: port %#3lx, irq %d,",
319 dev->name, dev->base_addr, dev->irq);
320 printk (" mmio %#5lx,", (u_long)ti->mmio);
321 printk (" sram %#5lx,", (u_long)ti->sram_base << 12);
322 printk ("\n" KERN_INFO " hwaddr=");
323 for (i = 0; i < TR_ALEN; i++)
324 printk("%02X", dev->dev_addr[i]);
325 printk("\n");
326 return;
327
328cs_failed:
fba395ee 329 cs_error(link, last_fn, last_ret);
1da177e4
LT
330failed:
331 ibmtr_release(link);
332} /* ibmtr_config */
333
334/*======================================================================
335
336 After a card is removed, ibmtr_release() will unregister the net
337 device, and release the PCMCIA configuration. If the device is
338 still open, this will be postponed until it is closed.
339
340======================================================================*/
341
fba395ee 342static void ibmtr_release(struct pcmcia_device *link)
1da177e4 343{
5f2a71fc
DB
344 ibmtr_dev_t *info = link->priv;
345 struct net_device *dev = info->dev;
1da177e4 346
5f2a71fc 347 DEBUG(0, "ibmtr_release(0x%p)\n", link);
1da177e4 348
5f2a71fc
DB
349 if (link->win) {
350 struct tok_info *ti = netdev_priv(dev);
351 iounmap(ti->mmio);
352 pcmcia_release_window(info->sram_win_handle);
353 }
fba395ee 354 pcmcia_disable_device(link);
1da177e4
LT
355}
356
fba395ee 357static int ibmtr_suspend(struct pcmcia_device *link)
98e4c28b 358{
98e4c28b
DB
359 ibmtr_dev_t *info = link->priv;
360 struct net_device *dev = info->dev;
361
8661bb5b
DB
362 if ((link->state & DEV_CONFIG) && (link->open))
363 netif_device_detach(dev);
98e4c28b
DB
364
365 return 0;
366}
367
fba395ee 368static int ibmtr_resume(struct pcmcia_device *link)
98e4c28b 369{
98e4c28b
DB
370 ibmtr_dev_t *info = link->priv;
371 struct net_device *dev = info->dev;
372
8661bb5b
DB
373 if ((link->state & DEV_CONFIG) && (link->open)) {
374 ibmtr_probe(dev); /* really? */
375 netif_device_attach(dev);
376 }
98e4c28b
DB
377
378 return 0;
379}
380
381
1da177e4
LT
382/*====================================================================*/
383
384static void ibmtr_hw_setup(struct net_device *dev, u_int mmiobase)
385{
386 int i;
387
388 /* Bizarre IBM behavior, there are 16 bits of information we
389 need to set, but the card only allows us to send 4 bits at a
390 time. For each byte sent to base_addr, bits 7-4 tell the
391 card which part of the 16 bits we are setting, bits 3-0 contain
392 the actual information */
393
394 /* First nibble provides 4 bits of mmio */
395 i = (mmiobase >> 16) & 0x0F;
396 outb(i, dev->base_addr);
397
398 /* Second nibble provides 3 bits of mmio */
399 i = 0x10 | ((mmiobase >> 12) & 0x0E);
400 outb(i, dev->base_addr);
401
402 /* Third nibble, hard-coded values */
403 i = 0x26;
404 outb(i, dev->base_addr);
405
406 /* Fourth nibble sets shared ram page size */
407
408 /* 8 = 00, 16 = 01, 32 = 10, 64 = 11 */
409 i = (sramsize >> 4) & 0x07;
410 i = ((i == 4) ? 3 : i) << 2;
411 i |= 0x30;
412
413 if (ringspeed == 16)
414 i |= 2;
415 if (dev->base_addr == 0xA24)
416 i |= 1;
417 outb(i, dev->base_addr);
418
419 /* 0x40 will release the card for use */
420 outb(0x40, dev->base_addr);
421
422 return;
423}
424
469bf2b9
DB
425static struct pcmcia_device_id ibmtr_ids[] = {
426 PCMCIA_DEVICE_PROD_ID12("3Com", "TokenLink Velocity PC Card", 0x41240e5b, 0x82c3734e),
427 PCMCIA_DEVICE_PROD_ID12("IBM", "TOKEN RING", 0xb569a6e5, 0xbf8eed47),
428 PCMCIA_DEVICE_NULL,
429};
430MODULE_DEVICE_TABLE(pcmcia, ibmtr_ids);
431
1da177e4
LT
432static struct pcmcia_driver ibmtr_cs_driver = {
433 .owner = THIS_MODULE,
434 .drv = {
435 .name = "ibmtr_cs",
436 },
f8cfa618 437 .probe = ibmtr_attach,
cc3b4866 438 .remove = ibmtr_detach,
469bf2b9 439 .id_table = ibmtr_ids,
98e4c28b
DB
440 .suspend = ibmtr_suspend,
441 .resume = ibmtr_resume,
1da177e4
LT
442};
443
444static int __init init_ibmtr_cs(void)
445{
446 return pcmcia_register_driver(&ibmtr_cs_driver);
447}
448
449static void __exit exit_ibmtr_cs(void)
450{
451 pcmcia_unregister_driver(&ibmtr_cs_driver);
1da177e4
LT
452}
453
454module_init(init_ibmtr_cs);
455module_exit(exit_ibmtr_cs);