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