]> bbs.cooldavid.org Git - net-next-2.6.git/blame - drivers/net/pcmcia/ibmtr_cs.c
Merge branch 'master' of master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6
[net-next-2.6.git] / drivers / net / pcmcia / ibmtr_cs.c
CommitLineData
1da177e4
LT
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
636b8116
JP
48#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
49
1da177e4
LT
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>
1da177e4
LT
57#include <linux/netdevice.h>
58#include <linux/trdevice.h>
59#include <linux/ibmtr.h>
60
1da177e4
LT
61#include <pcmcia/cs.h>
62#include <pcmcia/cistpl.h>
63#include <pcmcia/ds.h>
64
65#include <asm/uaccess.h>
66#include <asm/io.h>
67#include <asm/system.h>
68
69#define PCMCIA
70#include "../tokenring/ibmtr.c"
71
1da177e4
LT
72
73/*====================================================================*/
74
75/* Parameters that can be set with 'insmod' */
76
77/* MMIO base address */
78static u_long mmiobase = 0xce000;
79
80/* SRAM base address */
81static u_long srambase = 0xd0000;
82
83/* SRAM size 8,16,32,64 */
84static u_long sramsize = 64;
85
86/* Ringspeed 4,16 */
87static int ringspeed = 16;
88
89module_param(mmiobase, ulong, 0);
90module_param(srambase, ulong, 0);
91module_param(sramsize, ulong, 0);
92module_param(ringspeed, int, 0);
93MODULE_LICENSE("GPL");
94
95/*====================================================================*/
96
15b99ac1 97static int ibmtr_config(struct pcmcia_device *link);
1da177e4 98static void ibmtr_hw_setup(struct net_device *dev, u_int mmiobase);
fba395ee 99static void ibmtr_release(struct pcmcia_device *link);
cc3b4866 100static void ibmtr_detach(struct pcmcia_device *p_dev);
1da177e4 101
1da177e4
LT
102/*====================================================================*/
103
104typedef struct ibmtr_dev_t {
fd238232 105 struct pcmcia_device *p_dev;
1da177e4 106 struct net_device *dev;
1da177e4
LT
107 window_handle_t sram_win_handle;
108 struct tok_info *ti;
109} ibmtr_dev_t;
110
5fa9167a
DB
111static irqreturn_t ibmtr_interrupt(int irq, void *dev_id) {
112 ibmtr_dev_t *info = dev_id;
113 struct net_device *dev = info->dev;
114 return tok_interrupt(irq, dev);
115};
116
1da177e4
LT
117/*======================================================================
118
119 ibmtr_attach() creates an "instance" of the driver, allocating
120 local data structures for one device. The device is registered
121 with Card Services.
122
123======================================================================*/
124
abf0437b 125static int __devinit ibmtr_attach(struct pcmcia_device *link)
1da177e4
LT
126{
127 ibmtr_dev_t *info;
1da177e4 128 struct net_device *dev;
fba395ee 129
dd0fab5b 130 dev_dbg(&link->dev, "ibmtr_attach()\n");
1da177e4
LT
131
132 /* Create new token-ring device */
dd00cc48 133 info = kzalloc(sizeof(*info), GFP_KERNEL);
f8cfa618 134 if (!info) return -ENOMEM;
1da177e4 135 dev = alloc_trdev(sizeof(struct tok_info));
f8cfa618
DB
136 if (!dev) {
137 kfree(info);
138 return -ENOMEM;
139 }
1da177e4 140
fba395ee 141 info->p_dev = link;
1da177e4
LT
142 link->priv = info;
143 info->ti = netdev_priv(dev);
144
90abdc3b
DB
145 link->resource[0]->flags |= IO_DATA_PATH_WIDTH_8;
146 link->resource[0]->end = 4;
1da177e4 147 link->conf.Attributes = CONF_ENABLE_IRQ;
1da177e4
LT
148 link->conf.IntType = INT_MEMORY_AND_IO;
149 link->conf.Present = PRESENT_OPTION;
150
5fa9167a 151 info->dev = dev;
1da177e4 152
15b99ac1 153 return ibmtr_config(link);
1da177e4
LT
154} /* ibmtr_attach */
155
156/*======================================================================
157
158 This deletes a driver "instance". The device is de-registered
159 with Card Services. If it has been released, all local data
160 structures are freed. Otherwise, the structures will be freed
161 when the device is released.
162
163======================================================================*/
164
fba395ee 165static void ibmtr_detach(struct pcmcia_device *link)
1da177e4
LT
166{
167 struct ibmtr_dev_t *info = link->priv;
b4635811 168 struct net_device *dev = info->dev;
5bebf82f 169 struct tok_info *ti = netdev_priv(dev);
1da177e4 170
dd0fab5b 171 dev_dbg(&link->dev, "ibmtr_detach\n");
5bebf82f
PW
172
173 /*
174 * When the card removal interrupt hits tok_interrupt(),
175 * bail out early, so we don't crash the machine
176 */
177 ti->sram_phys |= 1;
1da177e4 178
c7c2fa07 179 unregister_netdev(dev);
5bebf82f
PW
180
181 del_timer_sync(&(ti->tr_timer));
e2d40963
DB
182
183 ibmtr_release(link);
1da177e4 184
1da177e4 185 free_netdev(dev);
b4635811 186 kfree(info);
1da177e4
LT
187} /* ibmtr_detach */
188
189/*======================================================================
190
191 ibmtr_config() is scheduled to run after a CARD_INSERTION event
192 is received, to configure the PCMCIA socket, and to make the
193 token-ring device available to the system.
194
195======================================================================*/
196
abf0437b 197static int __devinit ibmtr_config(struct pcmcia_device *link)
1da177e4 198{
1da177e4
LT
199 ibmtr_dev_t *info = link->priv;
200 struct net_device *dev = info->dev;
201 struct tok_info *ti = netdev_priv(dev);
1da177e4 202 win_req_t req;
dd0fab5b 203 int i, ret;
1da177e4 204
dd0fab5b 205 dev_dbg(&link->dev, "ibmtr_config\n");
1da177e4 206
1da177e4 207 link->conf.ConfigIndex = 0x61;
90abdc3b 208 link->io_lines = 16;
1da177e4
LT
209
210 /* Determine if this is PRIMARY or ALTERNATE. */
211
212 /* Try PRIMARY card at 0xA20-0xA23 */
90abdc3b
DB
213 link->resource[0]->start = 0xA20;
214 i = pcmcia_request_io(link);
4c89e88b 215 if (i != 0) {
1da177e4 216 /* Couldn't get 0xA20-0xA23. Try ALTERNATE at 0xA24-0xA27. */
90abdc3b
DB
217 link->resource[0]->start = 0xA24;
218 ret = pcmcia_request_io(link);
dd0fab5b
DB
219 if (ret)
220 goto failed;
1da177e4 221 }
9a017a91 222 dev->base_addr = link->resource[0]->start;
1da177e4 223
eb14120f 224 ret = pcmcia_request_exclusive_irq(link, ibmtr_interrupt);
dd0fab5b
DB
225 if (ret)
226 goto failed;
eb14120f
DB
227 dev->irq = link->irq;
228 ti->irq = link->irq;
1da177e4
LT
229 ti->global_int_enable=GLOBAL_INT_ENABLE+((dev->irq==9) ? 2 : dev->irq);
230
231 /* Allocate the MMIO memory window */
232 req.Attributes = WIN_DATA_WIDTH_16|WIN_MEMORY_TYPE_CM|WIN_ENABLE;
233 req.Attributes |= WIN_USE_WAIT;
234 req.Base = 0;
235 req.Size = 0x2000;
236 req.AccessSpeed = 250;
6838b03f 237 ret = pcmcia_request_window(link, &req, &link->win);
dd0fab5b
DB
238 if (ret)
239 goto failed;
1da177e4 240
b5cb259e 241 ret = pcmcia_map_mem_page(link, link->win, mmiobase);
dd0fab5b
DB
242 if (ret)
243 goto failed;
1da177e4
LT
244 ti->mmio = ioremap(req.Base, req.Size);
245
246 /* Allocate the SRAM memory window */
247 req.Attributes = WIN_DATA_WIDTH_16|WIN_MEMORY_TYPE_CM|WIN_ENABLE;
248 req.Attributes |= WIN_USE_WAIT;
249 req.Base = 0;
250 req.Size = sramsize * 1024;
251 req.AccessSpeed = 250;
6838b03f 252 ret = pcmcia_request_window(link, &req, &info->sram_win_handle);
dd0fab5b
DB
253 if (ret)
254 goto failed;
1da177e4 255
b5cb259e 256 ret = pcmcia_map_mem_page(link, info->sram_win_handle, srambase);
dd0fab5b
DB
257 if (ret)
258 goto failed;
1da177e4 259
b5cb259e 260 ti->sram_base = srambase >> 12;
1da177e4
LT
261 ti->sram_virt = ioremap(req.Base, req.Size);
262 ti->sram_phys = req.Base;
263
dd0fab5b
DB
264 ret = pcmcia_request_configuration(link, &link->conf);
265 if (ret)
266 goto failed;
1da177e4
LT
267
268 /* Set up the Token-Ring Controller Configuration Register and
269 turn on the card. Check the "Local Area Network Credit Card
270 Adapters Technical Reference" SC30-3585 for this info. */
271 ibmtr_hw_setup(dev, mmiobase);
272
dd2e5a15 273 SET_NETDEV_DEV(dev, &link->dev);
1da177e4
LT
274
275 i = ibmtr_probe_card(dev);
276 if (i != 0) {
636b8116 277 pr_notice("register_netdev() failed\n");
1da177e4
LT
278 goto failed;
279 }
280
636b8116
JP
281 netdev_info(dev, "port %#3lx, irq %d, mmio %#5lx, sram %#5lx, hwaddr=%pM\n",
282 dev->base_addr, dev->irq,
283 (u_long)ti->mmio, (u_long)(ti->sram_base << 12),
284 dev->dev_addr);
15b99ac1 285 return 0;
1da177e4 286
1da177e4
LT
287failed:
288 ibmtr_release(link);
15b99ac1 289 return -ENODEV;
1da177e4
LT
290} /* ibmtr_config */
291
292/*======================================================================
293
294 After a card is removed, ibmtr_release() will unregister the net
295 device, and release the PCMCIA configuration. If the device is
296 still open, this will be postponed until it is closed.
297
298======================================================================*/
299
fba395ee 300static void ibmtr_release(struct pcmcia_device *link)
1da177e4 301{
5f2a71fc
DB
302 ibmtr_dev_t *info = link->priv;
303 struct net_device *dev = info->dev;
1da177e4 304
dd0fab5b 305 dev_dbg(&link->dev, "ibmtr_release\n");
1da177e4 306
5f2a71fc
DB
307 if (link->win) {
308 struct tok_info *ti = netdev_priv(dev);
309 iounmap(ti->mmio);
5f2a71fc 310 }
fba395ee 311 pcmcia_disable_device(link);
1da177e4
LT
312}
313
fba395ee 314static int ibmtr_suspend(struct pcmcia_device *link)
98e4c28b 315{
98e4c28b
DB
316 ibmtr_dev_t *info = link->priv;
317 struct net_device *dev = info->dev;
318
e2d40963 319 if (link->open)
8661bb5b 320 netif_device_detach(dev);
98e4c28b
DB
321
322 return 0;
323}
324
8814b505 325static int __devinit ibmtr_resume(struct pcmcia_device *link)
98e4c28b 326{
98e4c28b
DB
327 ibmtr_dev_t *info = link->priv;
328 struct net_device *dev = info->dev;
329
e2d40963 330 if (link->open) {
8661bb5b
DB
331 ibmtr_probe(dev); /* really? */
332 netif_device_attach(dev);
333 }
98e4c28b
DB
334
335 return 0;
336}
337
338
1da177e4
LT
339/*====================================================================*/
340
341static void ibmtr_hw_setup(struct net_device *dev, u_int mmiobase)
342{
343 int i;
344
345 /* Bizarre IBM behavior, there are 16 bits of information we
346 need to set, but the card only allows us to send 4 bits at a
347 time. For each byte sent to base_addr, bits 7-4 tell the
348 card which part of the 16 bits we are setting, bits 3-0 contain
349 the actual information */
350
351 /* First nibble provides 4 bits of mmio */
352 i = (mmiobase >> 16) & 0x0F;
353 outb(i, dev->base_addr);
354
355 /* Second nibble provides 3 bits of mmio */
356 i = 0x10 | ((mmiobase >> 12) & 0x0E);
357 outb(i, dev->base_addr);
358
359 /* Third nibble, hard-coded values */
360 i = 0x26;
361 outb(i, dev->base_addr);
362
363 /* Fourth nibble sets shared ram page size */
364
365 /* 8 = 00, 16 = 01, 32 = 10, 64 = 11 */
366 i = (sramsize >> 4) & 0x07;
367 i = ((i == 4) ? 3 : i) << 2;
368 i |= 0x30;
369
370 if (ringspeed == 16)
371 i |= 2;
372 if (dev->base_addr == 0xA24)
373 i |= 1;
374 outb(i, dev->base_addr);
375
376 /* 0x40 will release the card for use */
377 outb(0x40, dev->base_addr);
1da177e4
LT
378}
379
469bf2b9
DB
380static struct pcmcia_device_id ibmtr_ids[] = {
381 PCMCIA_DEVICE_PROD_ID12("3Com", "TokenLink Velocity PC Card", 0x41240e5b, 0x82c3734e),
382 PCMCIA_DEVICE_PROD_ID12("IBM", "TOKEN RING", 0xb569a6e5, 0xbf8eed47),
383 PCMCIA_DEVICE_NULL,
384};
385MODULE_DEVICE_TABLE(pcmcia, ibmtr_ids);
386
1da177e4
LT
387static struct pcmcia_driver ibmtr_cs_driver = {
388 .owner = THIS_MODULE,
389 .drv = {
390 .name = "ibmtr_cs",
391 },
f8cfa618 392 .probe = ibmtr_attach,
cc3b4866 393 .remove = ibmtr_detach,
469bf2b9 394 .id_table = ibmtr_ids,
98e4c28b
DB
395 .suspend = ibmtr_suspend,
396 .resume = ibmtr_resume,
1da177e4
LT
397};
398
399static int __init init_ibmtr_cs(void)
400{
401 return pcmcia_register_driver(&ibmtr_cs_driver);
402}
403
404static void __exit exit_ibmtr_cs(void)
405{
406 pcmcia_unregister_driver(&ibmtr_cs_driver);
1da177e4
LT
407}
408
409module_init(init_ibmtr_cs);
410module_exit(exit_ibmtr_cs);