Merge /spare/repo/linux-2.6/
[deliverable/linux.git] / drivers / net / pcmcia / ibmtr_cs.c
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
60 #include <pcmcia/version.h>
61 #include <pcmcia/cs_types.h>
62 #include <pcmcia/cs.h>
63 #include <pcmcia/cistpl.h>
64 #include <pcmcia/ds.h>
65
66 #include <asm/uaccess.h>
67 #include <asm/io.h>
68 #include <asm/system.h>
69
70 #define PCMCIA
71 #include "../tokenring/ibmtr.c"
72
73 #ifdef PCMCIA_DEBUG
74 static int pc_debug = PCMCIA_DEBUG;
75 module_param(pc_debug, int, 0);
76 #define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
77 static char *version =
78 "ibmtr_cs.c 1.10 1996/01/06 05:19:00 (Steve Kipisz)\n"
79 " 2.2.7 1999/05/03 12:00:00 (Mike Phillips)\n"
80 " 2.4.2 2001/30/28 Midnight (Burt Silverman)\n";
81 #else
82 #define DEBUG(n, args...)
83 #endif
84
85 /*====================================================================*/
86
87 /* Parameters that can be set with 'insmod' */
88
89 /* MMIO base address */
90 static u_long mmiobase = 0xce000;
91
92 /* SRAM base address */
93 static u_long srambase = 0xd0000;
94
95 /* SRAM size 8,16,32,64 */
96 static u_long sramsize = 64;
97
98 /* Ringspeed 4,16 */
99 static int ringspeed = 16;
100
101 module_param(mmiobase, ulong, 0);
102 module_param(srambase, ulong, 0);
103 module_param(sramsize, ulong, 0);
104 module_param(ringspeed, int, 0);
105 MODULE_LICENSE("GPL");
106
107 /*====================================================================*/
108
109 static void ibmtr_config(dev_link_t *link);
110 static void ibmtr_hw_setup(struct net_device *dev, u_int mmiobase);
111 static void ibmtr_release(dev_link_t *link);
112 static int ibmtr_event(event_t event, int priority,
113 event_callback_args_t *args);
114
115 static dev_info_t dev_info = "ibmtr_cs";
116
117 static dev_link_t *ibmtr_attach(void);
118 static void ibmtr_detach(dev_link_t *);
119
120 static dev_link_t *dev_list;
121
122 /*====================================================================*/
123
124 typedef struct ibmtr_dev_t {
125 dev_link_t link;
126 struct net_device *dev;
127 dev_node_t node;
128 window_handle_t sram_win_handle;
129 struct tok_info *ti;
130 } ibmtr_dev_t;
131
132 static void netdev_get_drvinfo(struct net_device *dev,
133 struct ethtool_drvinfo *info)
134 {
135 strcpy(info->driver, "ibmtr_cs");
136 }
137
138 static struct ethtool_ops netdev_ethtool_ops = {
139 .get_drvinfo = netdev_get_drvinfo,
140 };
141
142 /*======================================================================
143
144 ibmtr_attach() creates an "instance" of the driver, allocating
145 local data structures for one device. The device is registered
146 with Card Services.
147
148 ======================================================================*/
149
150 static dev_link_t *ibmtr_attach(void)
151 {
152 ibmtr_dev_t *info;
153 dev_link_t *link;
154 struct net_device *dev;
155 client_reg_t client_reg;
156 int ret;
157
158 DEBUG(0, "ibmtr_attach()\n");
159
160 /* Create new token-ring device */
161 info = kmalloc(sizeof(*info), GFP_KERNEL);
162 if (!info) return NULL;
163 memset(info,0,sizeof(*info));
164 dev = alloc_trdev(sizeof(struct tok_info));
165 if (!dev) {
166 kfree(info);
167 return NULL;
168 }
169
170 link = &info->link;
171 link->priv = info;
172 info->ti = netdev_priv(dev);
173
174 link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
175 link->io.NumPorts1 = 4;
176 link->io.IOAddrLines = 16;
177 link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT;
178 link->irq.IRQInfo1 = IRQ_LEVEL_ID;
179 link->irq.Handler = &tok_interrupt;
180 link->conf.Attributes = CONF_ENABLE_IRQ;
181 link->conf.Vcc = 50;
182 link->conf.IntType = INT_MEMORY_AND_IO;
183 link->conf.Present = PRESENT_OPTION;
184
185 link->irq.Instance = info->dev = dev;
186
187 SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops);
188
189 /* Register with Card Services */
190 link->next = dev_list;
191 dev_list = link;
192 client_reg.dev_info = &dev_info;
193 client_reg.EventMask =
194 CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
195 CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
196 CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME;
197 client_reg.event_handler = &ibmtr_event;
198 client_reg.Version = 0x0210;
199 client_reg.event_callback_args.client_data = link;
200 ret = pcmcia_register_client(&link->handle, &client_reg);
201 if (ret != 0) {
202 cs_error(link->handle, RegisterClient, ret);
203 goto out_detach;
204 }
205
206 out:
207 return link;
208
209 out_detach:
210 ibmtr_detach(link);
211 link = NULL;
212 goto out;
213 } /* ibmtr_attach */
214
215 /*======================================================================
216
217 This deletes a driver "instance". The device is de-registered
218 with Card Services. If it has been released, all local data
219 structures are freed. Otherwise, the structures will be freed
220 when the device is released.
221
222 ======================================================================*/
223
224 static void ibmtr_detach(dev_link_t *link)
225 {
226 struct ibmtr_dev_t *info = link->priv;
227 dev_link_t **linkp;
228 struct net_device *dev;
229
230 DEBUG(0, "ibmtr_detach(0x%p)\n", link);
231
232 /* Locate device structure */
233 for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
234 if (*linkp == link) break;
235 if (*linkp == NULL)
236 return;
237
238 dev = info->dev;
239
240 if (link->dev)
241 unregister_netdev(dev);
242
243 {
244 struct tok_info *ti = netdev_priv(dev);
245 del_timer_sync(&(ti->tr_timer));
246 }
247 if (link->state & DEV_CONFIG)
248 ibmtr_release(link);
249
250 if (link->handle)
251 pcmcia_deregister_client(link->handle);
252
253 /* Unlink device structure, free bits */
254 *linkp = link->next;
255 free_netdev(dev);
256 kfree(info);
257 } /* ibmtr_detach */
258
259 /*======================================================================
260
261 ibmtr_config() is scheduled to run after a CARD_INSERTION event
262 is received, to configure the PCMCIA socket, and to make the
263 token-ring device available to the system.
264
265 ======================================================================*/
266
267 #define CS_CHECK(fn, ret) \
268 do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
269
270 static void ibmtr_config(dev_link_t *link)
271 {
272 client_handle_t handle = link->handle;
273 ibmtr_dev_t *info = link->priv;
274 struct net_device *dev = info->dev;
275 struct tok_info *ti = netdev_priv(dev);
276 tuple_t tuple;
277 cisparse_t parse;
278 win_req_t req;
279 memreq_t mem;
280 int i, last_ret, last_fn;
281 u_char buf[64];
282
283 DEBUG(0, "ibmtr_config(0x%p)\n", link);
284
285 tuple.Attributes = 0;
286 tuple.TupleData = buf;
287 tuple.TupleDataMax = 64;
288 tuple.TupleOffset = 0;
289 tuple.DesiredTuple = CISTPL_CONFIG;
290 CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple));
291 CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple));
292 CS_CHECK(ParseTuple, pcmcia_parse_tuple(handle, &tuple, &parse));
293 link->conf.ConfigBase = parse.config.base;
294
295 /* Configure card */
296 link->state |= DEV_CONFIG;
297
298 link->conf.ConfigIndex = 0x61;
299
300 /* Determine if this is PRIMARY or ALTERNATE. */
301
302 /* Try PRIMARY card at 0xA20-0xA23 */
303 link->io.BasePort1 = 0xA20;
304 i = pcmcia_request_io(link->handle, &link->io);
305 if (i != CS_SUCCESS) {
306 /* Couldn't get 0xA20-0xA23. Try ALTERNATE at 0xA24-0xA27. */
307 link->io.BasePort1 = 0xA24;
308 CS_CHECK(RequestIO, pcmcia_request_io(link->handle, &link->io));
309 }
310 dev->base_addr = link->io.BasePort1;
311
312 CS_CHECK(RequestIRQ, pcmcia_request_irq(link->handle, &link->irq));
313 dev->irq = link->irq.AssignedIRQ;
314 ti->irq = link->irq.AssignedIRQ;
315 ti->global_int_enable=GLOBAL_INT_ENABLE+((dev->irq==9) ? 2 : dev->irq);
316
317 /* Allocate the MMIO memory window */
318 req.Attributes = WIN_DATA_WIDTH_16|WIN_MEMORY_TYPE_CM|WIN_ENABLE;
319 req.Attributes |= WIN_USE_WAIT;
320 req.Base = 0;
321 req.Size = 0x2000;
322 req.AccessSpeed = 250;
323 CS_CHECK(RequestWindow, pcmcia_request_window(&link->handle, &req, &link->win));
324
325 mem.CardOffset = mmiobase;
326 mem.Page = 0;
327 CS_CHECK(MapMemPage, pcmcia_map_mem_page(link->win, &mem));
328 ti->mmio = ioremap(req.Base, req.Size);
329
330 /* Allocate the SRAM memory window */
331 req.Attributes = WIN_DATA_WIDTH_16|WIN_MEMORY_TYPE_CM|WIN_ENABLE;
332 req.Attributes |= WIN_USE_WAIT;
333 req.Base = 0;
334 req.Size = sramsize * 1024;
335 req.AccessSpeed = 250;
336 CS_CHECK(RequestWindow, pcmcia_request_window(&link->handle, &req, &info->sram_win_handle));
337
338 mem.CardOffset = srambase;
339 mem.Page = 0;
340 CS_CHECK(MapMemPage, pcmcia_map_mem_page(info->sram_win_handle, &mem));
341
342 ti->sram_base = mem.CardOffset >> 12;
343 ti->sram_virt = ioremap(req.Base, req.Size);
344 ti->sram_phys = req.Base;
345
346 CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link->handle, &link->conf));
347
348 /* Set up the Token-Ring Controller Configuration Register and
349 turn on the card. Check the "Local Area Network Credit Card
350 Adapters Technical Reference" SC30-3585 for this info. */
351 ibmtr_hw_setup(dev, mmiobase);
352
353 link->dev = &info->node;
354 link->state &= ~DEV_CONFIG_PENDING;
355 SET_NETDEV_DEV(dev, &handle_to_dev(handle));
356
357 i = ibmtr_probe_card(dev);
358 if (i != 0) {
359 printk(KERN_NOTICE "ibmtr_cs: register_netdev() failed\n");
360 link->dev = NULL;
361 goto failed;
362 }
363
364 strcpy(info->node.dev_name, dev->name);
365
366 printk(KERN_INFO "%s: port %#3lx, irq %d,",
367 dev->name, dev->base_addr, dev->irq);
368 printk (" mmio %#5lx,", (u_long)ti->mmio);
369 printk (" sram %#5lx,", (u_long)ti->sram_base << 12);
370 printk ("\n" KERN_INFO " hwaddr=");
371 for (i = 0; i < TR_ALEN; i++)
372 printk("%02X", dev->dev_addr[i]);
373 printk("\n");
374 return;
375
376 cs_failed:
377 cs_error(link->handle, last_fn, last_ret);
378 failed:
379 ibmtr_release(link);
380 } /* ibmtr_config */
381
382 /*======================================================================
383
384 After a card is removed, ibmtr_release() will unregister the net
385 device, and release the PCMCIA configuration. If the device is
386 still open, this will be postponed until it is closed.
387
388 ======================================================================*/
389
390 static void ibmtr_release(dev_link_t *link)
391 {
392 ibmtr_dev_t *info = link->priv;
393 struct net_device *dev = info->dev;
394
395 DEBUG(0, "ibmtr_release(0x%p)\n", link);
396
397 pcmcia_release_configuration(link->handle);
398 pcmcia_release_io(link->handle, &link->io);
399 pcmcia_release_irq(link->handle, &link->irq);
400 if (link->win) {
401 struct tok_info *ti = netdev_priv(dev);
402 iounmap(ti->mmio);
403 pcmcia_release_window(link->win);
404 pcmcia_release_window(info->sram_win_handle);
405 }
406
407 link->state &= ~DEV_CONFIG;
408 }
409
410 /*======================================================================
411
412 The card status event handler. Mostly, this schedules other
413 stuff to run after an event is received. A CARD_REMOVAL event
414 also sets some flags to discourage the net drivers from trying
415 to talk to the card any more.
416
417 ======================================================================*/
418
419 static int ibmtr_event(event_t event, int priority,
420 event_callback_args_t *args)
421 {
422 dev_link_t *link = args->client_data;
423 ibmtr_dev_t *info = link->priv;
424 struct net_device *dev = info->dev;
425
426 DEBUG(1, "ibmtr_event(0x%06x)\n", event);
427
428 switch (event) {
429 case CS_EVENT_CARD_REMOVAL:
430 link->state &= ~DEV_PRESENT;
431 if (link->state & DEV_CONFIG) {
432 /* set flag to bypass normal interrupt code */
433 struct tok_info *priv = netdev_priv(dev);
434 priv->sram_phys |= 1;
435 netif_device_detach(dev);
436 }
437 break;
438 case CS_EVENT_CARD_INSERTION:
439 link->state |= DEV_PRESENT;
440 ibmtr_config(link);
441 break;
442 case CS_EVENT_PM_SUSPEND:
443 link->state |= DEV_SUSPEND;
444 /* Fall through... */
445 case CS_EVENT_RESET_PHYSICAL:
446 if (link->state & DEV_CONFIG) {
447 if (link->open)
448 netif_device_detach(dev);
449 pcmcia_release_configuration(link->handle);
450 }
451 break;
452 case CS_EVENT_PM_RESUME:
453 link->state &= ~DEV_SUSPEND;
454 /* Fall through... */
455 case CS_EVENT_CARD_RESET:
456 if (link->state & DEV_CONFIG) {
457 pcmcia_request_configuration(link->handle, &link->conf);
458 if (link->open) {
459 ibmtr_probe(dev); /* really? */
460 netif_device_attach(dev);
461 }
462 }
463 break;
464 }
465 return 0;
466 } /* ibmtr_event */
467
468 /*====================================================================*/
469
470 static void ibmtr_hw_setup(struct net_device *dev, u_int mmiobase)
471 {
472 int i;
473
474 /* Bizarre IBM behavior, there are 16 bits of information we
475 need to set, but the card only allows us to send 4 bits at a
476 time. For each byte sent to base_addr, bits 7-4 tell the
477 card which part of the 16 bits we are setting, bits 3-0 contain
478 the actual information */
479
480 /* First nibble provides 4 bits of mmio */
481 i = (mmiobase >> 16) & 0x0F;
482 outb(i, dev->base_addr);
483
484 /* Second nibble provides 3 bits of mmio */
485 i = 0x10 | ((mmiobase >> 12) & 0x0E);
486 outb(i, dev->base_addr);
487
488 /* Third nibble, hard-coded values */
489 i = 0x26;
490 outb(i, dev->base_addr);
491
492 /* Fourth nibble sets shared ram page size */
493
494 /* 8 = 00, 16 = 01, 32 = 10, 64 = 11 */
495 i = (sramsize >> 4) & 0x07;
496 i = ((i == 4) ? 3 : i) << 2;
497 i |= 0x30;
498
499 if (ringspeed == 16)
500 i |= 2;
501 if (dev->base_addr == 0xA24)
502 i |= 1;
503 outb(i, dev->base_addr);
504
505 /* 0x40 will release the card for use */
506 outb(0x40, dev->base_addr);
507
508 return;
509 }
510
511 static struct pcmcia_device_id ibmtr_ids[] = {
512 PCMCIA_DEVICE_PROD_ID12("3Com", "TokenLink Velocity PC Card", 0x41240e5b, 0x82c3734e),
513 PCMCIA_DEVICE_PROD_ID12("IBM", "TOKEN RING", 0xb569a6e5, 0xbf8eed47),
514 PCMCIA_DEVICE_NULL,
515 };
516 MODULE_DEVICE_TABLE(pcmcia, ibmtr_ids);
517
518 static struct pcmcia_driver ibmtr_cs_driver = {
519 .owner = THIS_MODULE,
520 .drv = {
521 .name = "ibmtr_cs",
522 },
523 .attach = ibmtr_attach,
524 .detach = ibmtr_detach,
525 .id_table = ibmtr_ids,
526 };
527
528 static int __init init_ibmtr_cs(void)
529 {
530 return pcmcia_register_driver(&ibmtr_cs_driver);
531 }
532
533 static void __exit exit_ibmtr_cs(void)
534 {
535 pcmcia_unregister_driver(&ibmtr_cs_driver);
536 BUG_ON(dev_list != NULL);
537 }
538
539 module_init(init_ibmtr_cs);
540 module_exit(exit_ibmtr_cs);
This page took 0.043847 seconds and 6 git commands to generate.