Merge branches 'core-fixes-for-linus' and 'irq-fixes-for-linus' of git://git.kernel...
[pandora-kernel.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 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
49
50 #include <linux/kernel.h>
51 #include <linux/init.h>
52 #include <linux/ptrace.h>
53 #include <linux/slab.h>
54 #include <linux/string.h>
55 #include <linux/timer.h>
56 #include <linux/module.h>
57 #include <linux/netdevice.h>
58 #include <linux/trdevice.h>
59 #include <linux/ibmtr.h>
60
61 #include <pcmcia/cistpl.h>
62 #include <pcmcia/ds.h>
63
64 #include <asm/uaccess.h>
65 #include <asm/io.h>
66 #include <asm/system.h>
67
68 #define PCMCIA
69 #include "../tokenring/ibmtr.c"
70
71
72 /*====================================================================*/
73
74 /* Parameters that can be set with 'insmod' */
75
76 /* MMIO base address */
77 static u_long mmiobase = 0xce000;
78
79 /* SRAM base address */
80 static u_long srambase = 0xd0000;
81
82 /* SRAM size 8,16,32,64 */
83 static u_long sramsize = 64;
84
85 /* Ringspeed 4,16 */
86 static int ringspeed = 16;
87
88 module_param(mmiobase, ulong, 0);
89 module_param(srambase, ulong, 0);
90 module_param(sramsize, ulong, 0);
91 module_param(ringspeed, int, 0);
92 MODULE_LICENSE("GPL");
93
94 /*====================================================================*/
95
96 static int ibmtr_config(struct pcmcia_device *link);
97 static void ibmtr_hw_setup(struct net_device *dev, u_int mmiobase);
98 static void ibmtr_release(struct pcmcia_device *link);
99 static void ibmtr_detach(struct pcmcia_device *p_dev);
100
101 /*====================================================================*/
102
103 typedef struct ibmtr_dev_t {
104         struct pcmcia_device    *p_dev;
105         struct net_device       *dev;
106         struct tok_info         *ti;
107 } ibmtr_dev_t;
108
109 static irqreturn_t ibmtr_interrupt(int irq, void *dev_id) {
110         ibmtr_dev_t *info = dev_id;
111         struct net_device *dev = info->dev;
112         return tok_interrupt(irq, dev);
113 };
114
115 static int __devinit ibmtr_attach(struct pcmcia_device *link)
116 {
117     ibmtr_dev_t *info;
118     struct net_device *dev;
119
120     dev_dbg(&link->dev, "ibmtr_attach()\n");
121
122     /* Create new token-ring device */
123     info = kzalloc(sizeof(*info), GFP_KERNEL);
124     if (!info) return -ENOMEM;
125     dev = alloc_trdev(sizeof(struct tok_info));
126     if (!dev) {
127         kfree(info);
128         return -ENOMEM;
129     }
130
131     info->p_dev = link;
132     link->priv = info;
133     info->ti = netdev_priv(dev);
134
135     link->resource[0]->flags |= IO_DATA_PATH_WIDTH_8;
136     link->resource[0]->end = 4;
137     link->config_flags |= CONF_ENABLE_IRQ;
138     link->config_regs = PRESENT_OPTION;
139
140     info->dev = dev;
141
142     return ibmtr_config(link);
143 } /* ibmtr_attach */
144
145 static void ibmtr_detach(struct pcmcia_device *link)
146 {
147     struct ibmtr_dev_t *info = link->priv;
148     struct net_device *dev = info->dev;
149      struct tok_info *ti = netdev_priv(dev);
150
151     dev_dbg(&link->dev, "ibmtr_detach\n");
152     
153     /* 
154      * When the card removal interrupt hits tok_interrupt(), 
155      * bail out early, so we don't crash the machine 
156      */
157     ti->sram_phys |= 1;
158
159     unregister_netdev(dev);
160     
161     del_timer_sync(&(ti->tr_timer));
162
163     ibmtr_release(link);
164
165     free_netdev(dev);
166     kfree(info);
167 } /* ibmtr_detach */
168
169 static int __devinit ibmtr_config(struct pcmcia_device *link)
170 {
171     ibmtr_dev_t *info = link->priv;
172     struct net_device *dev = info->dev;
173     struct tok_info *ti = netdev_priv(dev);
174     int i, ret;
175
176     dev_dbg(&link->dev, "ibmtr_config\n");
177
178     link->io_lines = 16;
179     link->config_index = 0x61;
180
181     /* Determine if this is PRIMARY or ALTERNATE. */
182
183     /* Try PRIMARY card at 0xA20-0xA23 */
184     link->resource[0]->start = 0xA20;
185     i = pcmcia_request_io(link);
186     if (i != 0) {
187         /* Couldn't get 0xA20-0xA23.  Try ALTERNATE at 0xA24-0xA27. */
188         link->resource[0]->start = 0xA24;
189         ret = pcmcia_request_io(link);
190         if (ret)
191                 goto failed;
192     }
193     dev->base_addr = link->resource[0]->start;
194
195     ret = pcmcia_request_exclusive_irq(link, ibmtr_interrupt);
196     if (ret)
197             goto failed;
198     dev->irq = link->irq;
199     ti->irq = link->irq;
200     ti->global_int_enable=GLOBAL_INT_ENABLE+((dev->irq==9) ? 2 : dev->irq);
201
202     /* Allocate the MMIO memory window */
203     link->resource[2]->flags |= WIN_DATA_WIDTH_16|WIN_MEMORY_TYPE_CM|WIN_ENABLE;
204     link->resource[2]->flags |= WIN_USE_WAIT;
205     link->resource[2]->start = 0;
206     link->resource[2]->end = 0x2000;
207     ret = pcmcia_request_window(link, link->resource[2], 250);
208     if (ret)
209             goto failed;
210
211     ret = pcmcia_map_mem_page(link, link->resource[2], mmiobase);
212     if (ret)
213             goto failed;
214     ti->mmio = ioremap(link->resource[2]->start,
215                     resource_size(link->resource[2]));
216
217     /* Allocate the SRAM memory window */
218     link->resource[3]->flags = WIN_DATA_WIDTH_16|WIN_MEMORY_TYPE_CM|WIN_ENABLE;
219     link->resource[3]->flags |= WIN_USE_WAIT;
220     link->resource[3]->start = 0;
221     link->resource[3]->end = sramsize * 1024;
222     ret = pcmcia_request_window(link, link->resource[3], 250);
223     if (ret)
224             goto failed;
225
226     ret = pcmcia_map_mem_page(link, link->resource[3], srambase);
227     if (ret)
228             goto failed;
229
230     ti->sram_base = srambase >> 12;
231     ti->sram_virt = ioremap(link->resource[3]->start,
232                     resource_size(link->resource[3]));
233     ti->sram_phys = link->resource[3]->start;
234
235     ret = pcmcia_enable_device(link);
236     if (ret)
237             goto failed;
238
239     /*  Set up the Token-Ring Controller Configuration Register and
240         turn on the card.  Check the "Local Area Network Credit Card
241         Adapters Technical Reference"  SC30-3585 for this info.  */
242     ibmtr_hw_setup(dev, mmiobase);
243
244     SET_NETDEV_DEV(dev, &link->dev);
245
246     i = ibmtr_probe_card(dev);
247     if (i != 0) {
248         pr_notice("register_netdev() failed\n");
249         goto failed;
250     }
251
252     netdev_info(dev, "port %#3lx, irq %d, mmio %#5lx, sram %#5lx, hwaddr=%pM\n",
253                 dev->base_addr, dev->irq,
254                 (u_long)ti->mmio, (u_long)(ti->sram_base << 12),
255                 dev->dev_addr);
256     return 0;
257
258 failed:
259     ibmtr_release(link);
260     return -ENODEV;
261 } /* ibmtr_config */
262
263 static void ibmtr_release(struct pcmcia_device *link)
264 {
265         ibmtr_dev_t *info = link->priv;
266         struct net_device *dev = info->dev;
267
268         dev_dbg(&link->dev, "ibmtr_release\n");
269
270         if (link->resource[2]->end) {
271                 struct tok_info *ti = netdev_priv(dev);
272                 iounmap(ti->mmio);
273         }
274         pcmcia_disable_device(link);
275 }
276
277 static int ibmtr_suspend(struct pcmcia_device *link)
278 {
279         ibmtr_dev_t *info = link->priv;
280         struct net_device *dev = info->dev;
281
282         if (link->open)
283                 netif_device_detach(dev);
284
285         return 0;
286 }
287
288 static int __devinit ibmtr_resume(struct pcmcia_device *link)
289 {
290         ibmtr_dev_t *info = link->priv;
291         struct net_device *dev = info->dev;
292
293         if (link->open) {
294                 ibmtr_probe(dev);       /* really? */
295                 netif_device_attach(dev);
296         }
297
298         return 0;
299 }
300
301
302 /*====================================================================*/
303
304 static void ibmtr_hw_setup(struct net_device *dev, u_int mmiobase)
305 {
306     int i;
307
308     /* Bizarre IBM behavior, there are 16 bits of information we
309        need to set, but the card only allows us to send 4 bits at a 
310        time.  For each byte sent to base_addr, bits 7-4 tell the
311        card which part of the 16 bits we are setting, bits 3-0 contain 
312        the actual information */
313
314     /* First nibble provides 4 bits of mmio */
315     i = (mmiobase >> 16) & 0x0F;
316     outb(i, dev->base_addr);
317
318     /* Second nibble provides 3 bits of mmio */
319     i = 0x10 | ((mmiobase >> 12) & 0x0E);
320     outb(i, dev->base_addr);
321
322     /* Third nibble, hard-coded values */
323     i = 0x26;
324     outb(i, dev->base_addr);
325
326     /* Fourth nibble sets shared ram page size */
327
328     /* 8 = 00, 16 = 01, 32 = 10, 64 = 11 */          
329     i = (sramsize >> 4) & 0x07;
330     i = ((i == 4) ? 3 : i) << 2;
331     i |= 0x30;
332
333     if (ringspeed == 16)
334         i |= 2;
335     if (dev->base_addr == 0xA24)
336         i |= 1;
337     outb(i, dev->base_addr);
338
339     /* 0x40 will release the card for use */
340     outb(0x40, dev->base_addr);
341 }
342
343 static const struct pcmcia_device_id ibmtr_ids[] = {
344         PCMCIA_DEVICE_PROD_ID12("3Com", "TokenLink Velocity PC Card", 0x41240e5b, 0x82c3734e),
345         PCMCIA_DEVICE_PROD_ID12("IBM", "TOKEN RING", 0xb569a6e5, 0xbf8eed47),
346         PCMCIA_DEVICE_NULL,
347 };
348 MODULE_DEVICE_TABLE(pcmcia, ibmtr_ids);
349
350 static struct pcmcia_driver ibmtr_cs_driver = {
351         .owner          = THIS_MODULE,
352         .name           = "ibmtr_cs",
353         .probe          = ibmtr_attach,
354         .remove         = ibmtr_detach,
355         .id_table       = ibmtr_ids,
356         .suspend        = ibmtr_suspend,
357         .resume         = ibmtr_resume,
358 };
359
360 static int __init init_ibmtr_cs(void)
361 {
362         return pcmcia_register_driver(&ibmtr_cs_driver);
363 }
364
365 static void __exit exit_ibmtr_cs(void)
366 {
367         pcmcia_unregister_driver(&ibmtr_cs_driver);
368 }
369
370 module_init(init_ibmtr_cs);
371 module_exit(exit_ibmtr_cs);