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 memory.
29 This enables ibmtr_probe in ibmtr.c to find the card and configure it
30 as though it was a normal ISA and/or PnP card.
31
32 There is some confusion with the difference between available shared
33 ram and the amount actually reserved from memory. ibmtr.c sets up
34 several offsets depending upon the actual on-board memory, not the
35 reserved memory. We need to get around this to allow the cards to
36 work with other cards in restricted memory space. Therefore the
37 pcmcia_reality_check function.
38
39 TODO
40 - Write the suspend / resume functions.
41 - Fix Kernel Oops when removing card before ifconfig down
42
43 CHANGES
44
45 v2.2.5 April 1999 Mike Phillips (phillim@amtrak.com)
46 Obscure bug fix, required changed to ibmtr.c not ibmtr_cs.c
47
48 v2.2.7 May 1999 Mike Phillips (phillim@amtrak.com)
49 Updated to version 2.2.7 to match the first version of the kernel
50 that the modification to ibmtr.c were incorporated into.
51
52 ======================================================================*/
53
54 #include <linux/kernel.h>
55 #include <linux/init.h>
56 #include <linux/sched.h>
57 #include <linux/ptrace.h>
58 #include <linux/malloc.h>
59 #include <linux/string.h>
60 #include <linux/timer.h>
61 #include <linux/delay.h>
62 #include <linux/module.h>
63 #include <asm/io.h>
64 #include <asm/system.h>
65
66 #include <linux/netdevice.h>
67 #include <linux/trdevice.h>
68 #include <linux/ibmtr.h>
69
70 #include <pcmcia/version.h>
71 #include <pcmcia/cs_types.h>
72 #include <pcmcia/cs.h>
73 #include <pcmcia/cistpl.h>
74 #include <pcmcia/ds.h>
75
76 #ifdef PCMCIA_DEBUG
77 static int pc_debug = PCMCIA_DEBUG;
78 MODULE_PARM(pc_debug, "i");
79 #define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
80 static char *version =
81 "ibmtr_cs.c 1.10 1996/01/06 05:19:00 (Steve Kipisz)\n"
82 " 2.2.7 1999/05/03 12:00:00 (Mike Phillips)\n" ;
83 #else
84 #define DEBUG(n, args...)
85 #endif
86
87 /*====================================================================*/
88
89 /* Parameters that can be set with 'insmod' */
90
91 /* Bit map of interrupts to choose from */
92 static u_int irq_mask = 0xdeb8;
93 static int irq_list[4] = { -1 };
94
95 /* MMIO base address */
96 static u_long mmiobase = 0;
97
98 /* SRAM base address */
99 static u_long srambase = 0;
100
101 /* SRAM size 8,16,32,64 */
102 static u_long sramsize = 16;
103
104 /* Ringspeed 4,16 */
105 static int ringspeed = 16;
106
107 MODULE_PARM(irq_mask, "i");
108 MODULE_PARM(irq_list, "1-4i");
109 MODULE_PARM(mmiobase, "i");
110 MODULE_PARM(srambase, "i");
111 MODULE_PARM(sramsize, "i");
112 MODULE_PARM(ringspeed, "i");
113
114 /*====================================================================*/
115
116 static void ibmtr_config(dev_link_t *link);
117 static void ibmtr_hw_setup(struct net_device *dev);
118 static void ibmtr_release(u_long arg);
119 static int ibmtr_event(event_t event, int priority,
120 event_callback_args_t *args);
121
122 static dev_info_t dev_info = "ibmtr_cs";
123
124 static dev_link_t *ibmtr_attach(void);
125 static void ibmtr_detach(dev_link_t *);
126
127 static dev_link_t *dev_list = NULL;
128
129 extern int ibmtr_probe(struct net_device *dev);
130 unsigned char pcmcia_reality_check(unsigned char gss);
131
132 extern int trdev_init(struct net_device *dev);
133 extern void tok_interrupt(int irq, struct pt_regs *regs);
134 extern int tok_init_card(struct net_device *dev);
135 extern unsigned char get_sram_size(struct tok_info *ti);
136
137 /*====================================================================*/
138
139 typedef struct ibmtr_dev_t {
140 dev_link_t link;
141 struct net_device *dev; /* Changed for 2.2.0 */
142 dev_node_t node;
143 window_handle_t sram_win_handle;
144 struct tok_info ti;
145 } ibmtr_dev_t;
146
147 /*======================================================================
148
149 This bit of code is used to avoid unregistering network devices
150 at inappropriate times. 2.2 and later kernels are fairly picky
151 about when this can happen.
152
153 ======================================================================*/
154
155 static void flush_stale_links(void)
156 {
157 dev_link_t *link, *next;
158 for (link = dev_list; link; link = next) {
159 next = link->next;
160 if (link->state & DEV_STALE_LINK)
161 ibmtr_detach(link);
162 }
163 }
164
165 /*====================================================================*/
166
167 static void cs_error(client_handle_t handle, int func, int ret)
168 {
169 error_info_t err = { func, ret };
170 CardServices(ReportError, handle, &err);
171 }
172
173 /*======================================================================
174
175 ibmtr_attach() creates an "instance" of the driver, allocating
176 local data structures for one device. The device is registered
177 with Card Services.
178
179 ======================================================================*/
180
181 static dev_link_t *ibmtr_attach(void)
182 {
183 ibmtr_dev_t *info;
184 dev_link_t *link;
185 struct net_device *dev;
186 client_reg_t client_reg;
187 int i, ret;
188
189 DEBUG(0, "ibmtr_attach()\n");
190 flush_stale_links();
191
192 /* Create new token-ring device */
193 info = kmalloc(sizeof(*info), GFP_KERNEL);
194 if (!info) return NULL;
195 memset(info, 0, sizeof(*info));
196 link = &info->link; link->priv = info;
197
198 link->release.function = &ibmtr_release;
199 link->release.data = (u_long)link;
200 link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
201 link->io.NumPorts1 = 4;
202 link->io.IOAddrLines = 16;
203 link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT;
204 link->irq.IRQInfo1 = IRQ_INFO2_VALID|IRQ_LEVEL_ID;
205 if (irq_list[0] == -1)
206 link->irq.IRQInfo2 = irq_mask;
207 else
208 for (i = 0; i < 4; i++)
209 link->irq.IRQInfo2 |= 1 << irq_list[i];
210 link->irq.Handler = &tok_interrupt;
211 link->conf.Attributes = CONF_ENABLE_IRQ;
212 link->conf.Vcc = 50;
213 link->conf.IntType = INT_MEMORY_AND_IO;
214 link->conf.Present = PRESENT_OPTION;
215
216 dev = init_trdev(NULL,0);
217 dev->priv = &info->ti;
218 link->irq.Instance = info->dev = dev;
219
220 if (dev == NULL) {
221 ibmtr_detach(link);
222 return NULL;
223 }
224
225 dev->init = &ibmtr_probe;
226
227 /* Register with Card Services */
228 link->next = dev_list;
229 dev_list = link;
230 client_reg.dev_info = &dev_info;
231 client_reg.Attributes = INFO_IO_CLIENT | INFO_CARD_SHARE;
232 client_reg.EventMask =
233 CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
234 CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
235 CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME;
236 client_reg.event_handler = &ibmtr_event;
237 client_reg.Version = 0x0210;
238 client_reg.event_callback_args.client_data = link;
239 ret = CardServices(RegisterClient, &link->handle, &client_reg);
240 if (ret != 0) {
241 cs_error(link->handle, RegisterClient, ret);
242 ibmtr_detach(link);
243 return NULL;
244 }
245
246 return link;
247 } /* ibmtr_attach */
248
249 /*======================================================================
250
251 This deletes a driver "instance". The device is de-registered
252 with Card Services. If it has been released, all local data
253 structures are freed. Otherwise, the structures will be freed
254 when the device is released.
255
256 ======================================================================*/
257
258 static void ibmtr_detach(dev_link_t *link)
259 {
260 struct ibmtr_dev_t *info = link->priv;
261 dev_link_t **linkp;
262 struct net_device *dev;
263
264 DEBUG(0, "ibmtr_detach(0x%p)\n", link);
265
266 /* Locate device structure */
267 for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
268 if (*linkp == link) break;
269 if (*linkp == NULL)
270 return;
271
272 dev = info->dev;
273 {
274 struct tok_info *ti = (struct tok_info *)dev->priv;
275 del_timer(&(ti->tr_timer));
276 }
277 del_timer(&link->release);
278 if (link->state & DEV_CONFIG) {
279 ibmtr_release((u_long)link);
280 if (link->state & DEV_STALE_CONFIG) {
281 link->state |= DEV_STALE_LINK;
282 return;
283 }
284 }
285
286 if (link->handle)
287 CardServices(DeregisterClient, link->handle);
288
289 /* Unlink device structure, free bits */
290 *linkp = link->next;
291 if (link->dev)
292 unregister_trdev(info->dev);
293 kfree(info);
294
295 } /* ibmtr_detach */
296
297 /*======================================================================
298
299 ibmtr_config() is scheduled to run after a CARD_INSERTION event
300 is received, to configure the PCMCIA socket, and to make the
301 token-ring device available to the system.
302
303 ======================================================================*/
304
305 #define CS_CHECK(fn, args...) \
306 while ((last_ret=CardServices(last_fn=(fn), args))!=0) goto cs_failed
307
308 static void ibmtr_config(dev_link_t *link)
309 {
310 client_handle_t handle = link->handle;
311 ibmtr_dev_t *info = link->priv;
312 struct net_device *dev = info->dev;
313 struct tok_info *ti = dev->priv;
314 tuple_t tuple;
315 cisparse_t parse;
316 win_req_t req;
317 memreq_t mem;
318 int i, last_ret, last_fn;
319 u_char buf[64];
320 unsigned char Shared_Ram_Base;
321
322 DEBUG(0, "ibmtr_config(0x%p)\n", link);
323
324 tuple.Attributes = 0;
325 tuple.TupleData = buf;
326 tuple.TupleDataMax = 64;
327 tuple.TupleOffset = 0;
328 tuple.DesiredTuple = CISTPL_CONFIG;
329 CS_CHECK(GetFirstTuple, handle, &tuple);
330 CS_CHECK(GetTupleData, handle, &tuple);
331 CS_CHECK(ParseTuple, handle, &tuple, &parse);
332 link->conf.ConfigBase = parse.config.base;
333
334 /* Configure card */
335 link->state |= DEV_CONFIG;
336
337 link->conf.ConfigIndex = 0x61;
338
339 /* Determine if this is PRIMARY or ALTERNATE. */
340
341 /* Try PRIMARY card at 0xA20-0xA23 */
342 link->io.BasePort1 = 0xA20;
343 i = CardServices(RequestIO, link->handle, &link->io);
344 if (i == CS_SUCCESS) {
345 memcpy(info->node.dev_name, "tr0\0", 4);
346 } else {
347 /* Couldn't get 0xA20-0xA23. Try ALTERNATE at 0xA24-0xA27. */
348 link->io.BasePort1 = 0xA24;
349 CS_CHECK(RequestIO, link->handle, &link->io);
350 memcpy(info->node.dev_name, "tr1\0", 4);
351 }
352 dev->base_addr = link->io.BasePort1;
353
354 CS_CHECK(RequestIRQ, link->handle, &link->irq);
355 dev->irq = link->irq.AssignedIRQ;
356 ti->irq = link->irq.AssignedIRQ;
357 ti->global_int_enable=GLOBAL_INT_ENABLE+((dev->irq==9) ? 2 : dev->irq);
358
359 /* Allocate the MMIO memory window */
360 req.Attributes = WIN_DATA_WIDTH_16|WIN_MEMORY_TYPE_CM|WIN_ENABLE;
361 req.Attributes |= WIN_USE_WAIT|WIN_STRICT_ALIGN;
362 req.Base = mmiobase;
363 req.Size = 0x2000;
364 req.AccessSpeed = 250;
365 link->win = (window_handle_t)link->handle;
366 CS_CHECK(RequestWindow, &link->win, &req);
367
368 mem.CardOffset = req.Base;
369 mem.Page = 0;
370 CS_CHECK(MapMemPage, link->win, &mem);
371 ti->mmio = (u_long)ioremap(req.Base, req.Size);
372
373 /* Allocate the SRAM memory window */
374 req.Attributes = WIN_DATA_WIDTH_16|WIN_MEMORY_TYPE_CM|WIN_ENABLE;
375 req.Attributes |= WIN_USE_WAIT|WIN_MAP_BELOW_1MB;
376 req.Base = srambase;
377 req.Size = sramsize * 1024;
378 req.AccessSpeed = 250;
379 info->sram_win_handle = (window_handle_t)link->handle;
380 CS_CHECK(RequestWindow, &info->sram_win_handle, &req);
381
382 mem.CardOffset = req.Base;
383 mem.Page = 0;
384 CS_CHECK(MapMemPage, info->sram_win_handle, &mem);
385 Shared_Ram_Base = req.Base >> 12;
386
387 ti->sram = 0;
388 ti->sram_base = Shared_Ram_Base;
389
390 CS_CHECK(RequestConfiguration, link->handle, &link->conf);
391
392 /* Set up the Token-Ring Controller Configuration Register and
393 turn on the card. Check the "Local Area Network Credit Card
394 Adapters Technical Reference" SC30-3585 for this info. */
395 ibmtr_hw_setup(dev);
396
397 i = register_trdev(dev);
398
399 if (i != 0) {
400 printk(KERN_NOTICE "ibmtr_cs: register_trdev() failed\n");
401 goto failed;
402 }
403
404 link->dev = &info->node;
405 link->state &= ~DEV_CONFIG_PENDING;
406
407 printk(KERN_INFO "%s: port %#3lx, irq %d,",
408 dev->name, dev->base_addr, dev->irq);
409 printk (" mmio %#5lx,", (u_long)ti->mmio);
410 printk (" sram %#5lx,", (u_long)ti->sram_base << 12);
411 printk ("\n" KERN_INFO " hwaddr=");
412 for (i = 0; i < TR_ALEN; i++)
413 printk("%02X", dev->dev_addr[i]);
414 printk("\n");
415 return;
416
417 cs_failed:
418 cs_error(link->handle, last_fn, last_ret);
419 failed:
420 ibmtr_release((u_long)link);
421 } /* ibmtr_config */
422
423 /*======================================================================
424
425 After a card is removed, ibmtr_release() will unregister the net
426 device, and release the PCMCIA configuration. If the device is
427 still open, this will be postponed until it is closed.
428
429 ======================================================================*/
430
431 static void ibmtr_release(u_long arg)
432 {
433 dev_link_t *link = (dev_link_t *)arg;
434 ibmtr_dev_t *info = link->priv;
435 struct net_device *dev = info->dev;
436
437 DEBUG(0, "ibmtr_release(0x%p)\n", link);
438
439 if (link->open) {
440 DEBUG(1, "ibmtr_cs: release postponed, '%s' "
441 "still open\n", info->node.dev_name);
442 link->state |= DEV_STALE_CONFIG;
443 return;
444 }
445
446 CardServices(ReleaseConfiguration, link->handle);
447 CardServices(ReleaseIO, link->handle, &link->io);
448 CardServices(ReleaseIRQ, link->handle, &link->irq);
449 if (link->win) {
450 struct tok_info *ti = dev->priv;
451 iounmap((void *)ti->mmio);
452 CardServices(ReleaseWindow, link->win);
453 CardServices(ReleaseWindow, info->sram_win_handle);
454 }
455
456 link->state &= ~DEV_CONFIG;
457
458 } /* ibmtr_release */
459
460 /*======================================================================
461
462 The card status event handler. Mostly, this schedules other
463 stuff to run after an event is received. A CARD_REMOVAL event
464 also sets some flags to discourage the net drivers from trying
465 to talk to the card any more.
466
467 ======================================================================*/
468
469 static int ibmtr_event(event_t event, int priority,
470 event_callback_args_t *args)
471 {
472 dev_link_t *link = args->client_data;
473 ibmtr_dev_t *info = link->priv;
474 struct net_device *dev = info->dev;
475
476 DEBUG(1, "ibmtr_event(0x%06x)\n", event);
477
478 switch (event) {
479 case CS_EVENT_CARD_REMOVAL:
480 link->state &= ~DEV_PRESENT;
481 if (link->state & DEV_CONFIG) {
482 netif_device_detach(dev);
483 mod_timer(&link->release, jiffies + HZ/20);
484 }
485 break;
486 case CS_EVENT_CARD_INSERTION:
487 link->state |= DEV_PRESENT;
488 ibmtr_config(link);
489 break;
490 case CS_EVENT_PM_SUSPEND:
491 link->state |= DEV_SUSPEND;
492 /* Fall through... */
493 case CS_EVENT_RESET_PHYSICAL:
494 if (link->state & DEV_CONFIG) {
495 if (link->open)
496 netif_device_detach(dev);
497 CardServices(ReleaseConfiguration, link->handle);
498 }
499 break;
500 case CS_EVENT_PM_RESUME:
501 link->state &= ~DEV_SUSPEND;
502 /* Fall through... */
503 case CS_EVENT_CARD_RESET:
504 if (link->state & DEV_CONFIG) {
505 CardServices(RequestConfiguration, link->handle, &link->conf);
506 if (link->open) {
507 (dev->init)(dev);
508 netif_device_attach(dev);
509 }
510 }
511 break;
512 }
513 return 0;
514 } /* ibmtr_event */
515
516 /*====================================================================*/
517
518 static void ibmtr_hw_setup(struct net_device *dev)
519 {
520 struct tok_info *ti = dev->priv;
521 int i;
522
523 /* Bizarre IBM behavior, there are 16 bits of information we
524 need to set, but the card only allows us to send 4 bits at a
525 time. For each byte sent to base_addr, bits 7-4 tell the
526 card which part of the 16 bits we are setting, bits 3-0 contain
527 the actual information */
528
529 /* First nibble provides 4 bits of mmio */
530 i = ((int)ti->mmio >> 16) & 0x0F;
531 outb(i, dev->base_addr);
532
533 /* Second nibble provides 3 bits of mmio */
534 i = 0x10 | (((int)ti->mmio >> 12) & 0x0E);
535 outb(i, dev->base_addr);
536
537 /* Third nibble, hard-coded values */
538 i = 0x26;
539 outb(i, dev->base_addr);
540
541 /* Fourth nibble sets shared ram page size */
542
543 /* 8 = 00, 16 = 01, 32 = 10, 64 = 11 */
544
545 i = (sramsize >> 4) & 0x07;
546 i = ((i == 4) ? 3 : i) << 2;
547 i |= 0x30;
548
549 if (ringspeed == 16)
550 i |= 2;
551 if (dev->base_addr == 0xA24)
552 i |= 1;
553 outb(i, dev->base_addr);
554
555 /* X40 will release the card for use */
556
557 outb(0x40, dev->base_addr);
558
559 return;
560 }
561
562 /*======================================================================
563
564 A sweet little function that circumvents the problem with
565 ibmtr.c trying to use more memory than we can allocate for
566 the PCMCIA card. ibmtr.c just assumes that if a card has
567 64K of shared ram, the entire 64K must be mapped into memory,
568 whereas resources are sometimes a little tight in card services
569 so we fool ibmtr.c into thinking the card has less memory on
570 it than it has.
571
572 ======================================================================*/
573
574 unsigned char pcmcia_reality_check(unsigned char gss)
575 {
576 return (gss < sramsize) ? sramsize : gss;
577 }
578
579 /*====================================================================*/
580
581 static int __init init_ibmtr_cs(void)
582 {
583 servinfo_t serv;
584 DEBUG(0, "%s\n", version);
585 CardServices(GetCardServicesInfo, &serv);
586 if (serv.Revision != CS_RELEASE_CODE) {
587 printk(KERN_NOTICE "ibmtr_cs: Card Services release "
588 "does not match!\n");
589 return -1;
590 }
591 register_pccard_driver(&dev_info, &ibmtr_attach, &ibmtr_detach);
592 return 0;
593 }
594
595 static void __exit exit_ibmtr_cs(void)
596 {
597 DEBUG(0, "ibmtr_cs: unloading\n");
598 unregister_pccard_driver(&dev_info);
599 while (dev_list != NULL)
600 ibmtr_detach(dev_list);
601 }
602
603 module_init(init_ibmtr_cs);
604 module_exit(exit_ibmtr_cs);
605
This page was automatically generated by the
LXR engine.
Visit the LXR main site for more
information.