1 /*======================================================================
3 A PCMCIA token-ring driver for IBM-based cards
5 This driver supports the IBM PCMCIA Token-Ring Card.
6 Written by Steve Kipisz, kipisz@vnet.ibm.com or
11 This code is based on pcnet_cs.c from David Hinds.
13 V2.2.0 February 1999 - Mike Phillips phillim@amtrak.com
15 Linux V2.2.x presented significant changes to the underlying
16 ibmtr.c code. Mainly the code became a lot more organized and
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
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.
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.
34 v2.2.5 April 1999 Mike Phillips (phillim@amtrak.com)
35 Obscure bug fix, required changed to ibmtr.c not ibmtr_cs.c
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.
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
46 ======================================================================*/
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>
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>
66 #include <asm/uaccess.h>
68 #include <asm/system.h>
71 #include "../tokenring/ibmtr.c"
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";
82 #define DEBUG(n, args...)
85 /*====================================================================*/
87 /* Parameters that can be set with 'insmod' */
89 /* MMIO base address */
90 static u_long mmiobase = 0xce000;
92 /* SRAM base address */
93 static u_long srambase = 0xd0000;
95 /* SRAM size 8,16,32,64 */
96 static u_long sramsize = 64;
99 static int ringspeed = 16;
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");
107 /*====================================================================*/
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);
115 static dev_info_t dev_info = "ibmtr_cs";
117 static dev_link_t *ibmtr_attach(void);
118 static void ibmtr_detach(dev_link_t *);
120 static dev_link_t *dev_list;
122 /*====================================================================*/
124 typedef struct ibmtr_dev_t {
126 struct net_device *dev;
128 window_handle_t sram_win_handle;
132 static void netdev_get_drvinfo(struct net_device *dev,
133 struct ethtool_drvinfo *info)
135 strcpy(info->driver, "ibmtr_cs");
138 static struct ethtool_ops netdev_ethtool_ops = {
139 .get_drvinfo = netdev_get_drvinfo,
142 /*======================================================================
144 ibmtr_attach() creates an "instance" of the driver, allocating
145 local data structures for one device. The device is registered
148 ======================================================================*/
150 static dev_link_t *ibmtr_attach(void)
154 struct net_device *dev;
155 client_reg_t client_reg;
158 DEBUG(0, "ibmtr_attach()\n");
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));
172 info->ti = netdev_priv(dev);
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;
182 link->conf.IntType = INT_MEMORY_AND_IO;
183 link->conf.Present = PRESENT_OPTION;
185 link->irq.Instance = info->dev = dev;
187 SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops);
189 /* Register with Card Services */
190 link->next = dev_list;
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);
202 cs_error(link->handle, RegisterClient, ret);
215 /*======================================================================
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.
222 ======================================================================*/
224 static void ibmtr_detach(dev_link_t *link)
226 struct ibmtr_dev_t *info = link->priv;
228 struct net_device *dev;
230 DEBUG(0, "ibmtr_detach(0x%p)\n", link);
232 /* Locate device structure */
233 for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
234 if (*linkp == link) break;
241 unregister_netdev(dev);
244 struct tok_info *ti = netdev_priv(dev);
245 del_timer_sync(&(ti->tr_timer));
247 if (link->state & DEV_CONFIG)
251 pcmcia_deregister_client(link->handle);
253 /* Unlink device structure, free bits */
259 /*======================================================================
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.
265 ======================================================================*/
267 #define CS_CHECK(fn, ret) \
268 do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
270 static void ibmtr_config(dev_link_t *link)
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);
280 int i, last_ret, last_fn;
283 DEBUG(0, "ibmtr_config(0x%p)\n", link);
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;
296 link->state |= DEV_CONFIG;
298 link->conf.ConfigIndex = 0x61;
300 /* Determine if this is PRIMARY or ALTERNATE. */
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));
310 dev->base_addr = link->io.BasePort1;
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);
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;
322 req.AccessSpeed = 250;
323 CS_CHECK(RequestWindow, pcmcia_request_window(&link->handle, &req, &link->win));
325 mem.CardOffset = mmiobase;
327 CS_CHECK(MapMemPage, pcmcia_map_mem_page(link->win, &mem));
328 ti->mmio = ioremap(req.Base, req.Size);
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;
334 req.Size = sramsize * 1024;
335 req.AccessSpeed = 250;
336 CS_CHECK(RequestWindow, pcmcia_request_window(&link->handle, &req, &info->sram_win_handle));
338 mem.CardOffset = srambase;
340 CS_CHECK(MapMemPage, pcmcia_map_mem_page(info->sram_win_handle, &mem));
342 ti->sram_base = mem.CardOffset >> 12;
343 ti->sram_virt = ioremap(req.Base, req.Size);
344 ti->sram_phys = req.Base;
346 CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link->handle, &link->conf));
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);
353 link->dev = &info->node;
354 link->state &= ~DEV_CONFIG_PENDING;
355 SET_NETDEV_DEV(dev, &handle_to_dev(handle));
357 i = ibmtr_probe_card(dev);
359 printk(KERN_NOTICE "ibmtr_cs: register_netdev() failed\n");
364 strcpy(info->node.dev_name, dev->name);
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]);
377 cs_error(link->handle, last_fn, last_ret);
382 /*======================================================================
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.
388 ======================================================================*/
390 static void ibmtr_release(dev_link_t *link)
392 ibmtr_dev_t *info = link->priv;
393 struct net_device *dev = info->dev;
395 DEBUG(0, "ibmtr_release(0x%p)\n", link);
397 pcmcia_release_configuration(link->handle);
398 pcmcia_release_io(link->handle, &link->io);
399 pcmcia_release_irq(link->handle, &link->irq);
401 struct tok_info *ti = netdev_priv(dev);
403 pcmcia_release_window(link->win);
404 pcmcia_release_window(info->sram_win_handle);
407 link->state &= ~DEV_CONFIG;
410 /*======================================================================
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.
417 ======================================================================*/
419 static int ibmtr_event(event_t event, int priority,
420 event_callback_args_t *args)
422 dev_link_t *link = args->client_data;
423 ibmtr_dev_t *info = link->priv;
424 struct net_device *dev = info->dev;
426 DEBUG(1, "ibmtr_event(0x%06x)\n", 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);
438 case CS_EVENT_CARD_INSERTION:
439 link->state |= DEV_PRESENT;
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) {
448 netif_device_detach(dev);
449 pcmcia_release_configuration(link->handle);
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);
459 ibmtr_probe(dev); /* really? */
460 netif_device_attach(dev);
468 /*====================================================================*/
470 static void ibmtr_hw_setup(struct net_device *dev, u_int mmiobase)
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 */
480 /* First nibble provides 4 bits of mmio */
481 i = (mmiobase >> 16) & 0x0F;
482 outb(i, dev->base_addr);
484 /* Second nibble provides 3 bits of mmio */
485 i = 0x10 | ((mmiobase >> 12) & 0x0E);
486 outb(i, dev->base_addr);
488 /* Third nibble, hard-coded values */
490 outb(i, dev->base_addr);
492 /* Fourth nibble sets shared ram page size */
494 /* 8 = 00, 16 = 01, 32 = 10, 64 = 11 */
495 i = (sramsize >> 4) & 0x07;
496 i = ((i == 4) ? 3 : i) << 2;
501 if (dev->base_addr == 0xA24)
503 outb(i, dev->base_addr);
505 /* 0x40 will release the card for use */
506 outb(0x40, dev->base_addr);
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),
516 MODULE_DEVICE_TABLE(pcmcia, ibmtr_ids);
518 static struct pcmcia_driver ibmtr_cs_driver = {
519 .owner = THIS_MODULE,
523 .attach = ibmtr_attach,
524 .detach = ibmtr_detach,
525 .id_table = ibmtr_ids,
528 static int __init init_ibmtr_cs(void)
530 return pcmcia_register_driver(&ibmtr_cs_driver);
533 static void __exit exit_ibmtr_cs(void)
535 pcmcia_unregister_driver(&ibmtr_cs_driver);
536 BUG_ON(dev_list != NULL);
539 module_init(init_ibmtr_cs);
540 module_exit(exit_ibmtr_cs);