Merge git://git.kernel.org/pub/scm/linux/kernel/git/rusty/linux-2.6-for-linus
[pandora-kernel.git] / drivers / net / tokenring / abyss.c
1 /*
2  *  abyss.c: Network driver for the Madge Smart 16/4 PCI Mk2 token ring card.
3  *
4  *  Written 1999-2000 by Adam Fritzler
5  *
6  *  This software may be used and distributed according to the terms
7  *  of the GNU General Public License, incorporated herein by reference.
8  *
9  *  This driver module supports the following cards:
10  *      - Madge Smart 16/4 PCI Mk2
11  *
12  *  Maintainer(s):
13  *    AF        Adam Fritzler
14  *
15  *  Modification History:
16  *      30-Dec-99       AF      Split off from the tms380tr driver.
17  *      22-Jan-00       AF      Updated to use indirect read/writes 
18  *      23-Nov-00       JG      New PCI API, cleanups
19  *
20  *
21  *  TODO:
22  *      1. See if we can use MMIO instead of inb/outb/inw/outw
23  *      2. Add support for Mk1 (has AT24 attached to the PCI
24  *              config registers)
25  *
26  */
27
28 #include <linux/module.h>
29 #include <linux/kernel.h>
30 #include <linux/errno.h>
31 #include <linux/pci.h>
32 #include <linux/init.h>
33 #include <linux/netdevice.h>
34 #include <linux/trdevice.h>
35
36 #include <asm/system.h>
37 #include <asm/io.h>
38 #include <asm/irq.h>
39
40 #include "tms380tr.h"
41 #include "abyss.h"            /* Madge-specific constants */
42
43 static char version[] __devinitdata =
44 "abyss.c: v1.02 23/11/2000 by Adam Fritzler\n";
45
46 #define ABYSS_IO_EXTENT 64
47
48 static struct pci_device_id abyss_pci_tbl[] = {
49         { PCI_VENDOR_ID_MADGE, PCI_DEVICE_ID_MADGE_MK2,
50           PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_NETWORK_TOKEN_RING << 8, 0x00ffffff, },
51         { }                     /* Terminating entry */
52 };
53 MODULE_DEVICE_TABLE(pci, abyss_pci_tbl);
54
55 MODULE_LICENSE("GPL");
56
57 static int abyss_open(struct net_device *dev);
58 static int abyss_close(struct net_device *dev);
59 static void abyss_enable(struct net_device *dev);
60 static int abyss_chipset_init(struct net_device *dev);
61 static void abyss_read_eeprom(struct net_device *dev);
62 static unsigned short abyss_setnselout_pins(struct net_device *dev);
63
64 static void at24_writedatabyte(unsigned long regaddr, unsigned char byte);
65 static int at24_sendfullcmd(unsigned long regaddr, unsigned char cmd, unsigned char addr);
66 static int at24_sendcmd(unsigned long regaddr, unsigned char cmd);
67 static unsigned char at24_readdatabit(unsigned long regaddr);
68 static unsigned char at24_readdatabyte(unsigned long regaddr);
69 static int at24_waitforack(unsigned long regaddr);
70 static int at24_waitfornack(unsigned long regaddr);
71 static void at24_setlines(unsigned long regaddr, unsigned char clock, unsigned char data);
72 static void at24_start(unsigned long regaddr);
73 static unsigned char at24_readb(unsigned long regaddr, unsigned char addr);
74
75 static unsigned short abyss_sifreadb(struct net_device *dev, unsigned short reg)
76 {
77         return inb(dev->base_addr + reg);
78 }
79
80 static unsigned short abyss_sifreadw(struct net_device *dev, unsigned short reg)
81 {
82         return inw(dev->base_addr + reg);
83 }
84
85 static void abyss_sifwriteb(struct net_device *dev, unsigned short val, unsigned short reg)
86 {
87         outb(val, dev->base_addr + reg);
88 }
89
90 static void abyss_sifwritew(struct net_device *dev, unsigned short val, unsigned short reg)
91 {
92         outw(val, dev->base_addr + reg);
93 }
94
95 static int __devinit abyss_attach(struct pci_dev *pdev, const struct pci_device_id *ent)
96 {       
97         static int versionprinted;
98         struct net_device *dev;
99         struct net_local *tp;
100         int ret, pci_irq_line;
101         unsigned long pci_ioaddr;
102         DECLARE_MAC_BUF(mac);
103         
104         if (versionprinted++ == 0)
105                 printk("%s", version);
106
107         if (pci_enable_device(pdev))
108                 return -EIO;
109
110         /* Remove I/O space marker in bit 0. */
111         pci_irq_line = pdev->irq;
112         pci_ioaddr = pci_resource_start (pdev, 0);
113                 
114         /* At this point we have found a valid card. */
115                 
116         dev = alloc_trdev(sizeof(struct net_local));
117         if (!dev)
118                 return -ENOMEM;
119
120         if (!request_region(pci_ioaddr, ABYSS_IO_EXTENT, dev->name)) {
121                 ret = -EBUSY;
122                 goto err_out_trdev;
123         }
124                 
125         ret = request_irq(pdev->irq, tms380tr_interrupt, IRQF_SHARED,
126                           dev->name, dev);
127         if (ret)
128                 goto err_out_region;
129                 
130         dev->base_addr  = pci_ioaddr;
131         dev->irq        = pci_irq_line;
132                 
133         printk("%s: Madge Smart 16/4 PCI Mk2 (Abyss)\n", dev->name);
134         printk("%s:    IO: %#4lx  IRQ: %d\n",
135                dev->name, pci_ioaddr, dev->irq);
136         /*
137          * The TMS SIF registers lay 0x10 above the card base address.
138          */
139         dev->base_addr += 0x10;
140                 
141         ret = tmsdev_init(dev, &pdev->dev);
142         if (ret) {
143                 printk("%s: unable to get memory for dev->priv.\n", 
144                        dev->name);
145                 goto err_out_irq;
146         }
147
148         abyss_read_eeprom(dev);
149
150         printk("%s:    Ring Station Address: %s\n",
151                dev->name, print_mac(mac, dev->dev_addr));
152
153         tp = netdev_priv(dev);
154         tp->setnselout = abyss_setnselout_pins;
155         tp->sifreadb = abyss_sifreadb;
156         tp->sifreadw = abyss_sifreadw;
157         tp->sifwriteb = abyss_sifwriteb;
158         tp->sifwritew = abyss_sifwritew;
159
160         memcpy(tp->ProductID, "Madge PCI 16/4 Mk2", PROD_ID_SIZE + 1);
161                 
162         dev->open = abyss_open;
163         dev->stop = abyss_close;
164
165         pci_set_drvdata(pdev, dev);
166         SET_NETDEV_DEV(dev, &pdev->dev);
167
168         ret = register_netdev(dev);
169         if (ret)
170                 goto err_out_tmsdev;
171         return 0;
172
173 err_out_tmsdev:
174         pci_set_drvdata(pdev, NULL);
175         tmsdev_term(dev);
176 err_out_irq:
177         free_irq(pdev->irq, dev);
178 err_out_region:
179         release_region(pci_ioaddr, ABYSS_IO_EXTENT);
180 err_out_trdev:
181         free_netdev(dev);
182         return ret;
183 }
184
185 static unsigned short abyss_setnselout_pins(struct net_device *dev)
186 {
187         unsigned short val = 0;
188         struct net_local *tp = netdev_priv(dev);
189         
190         if(tp->DataRate == SPEED_4)
191                 val |= 0x01;  /* Set 4Mbps */
192         else
193                 val |= 0x00;  /* Set 16Mbps */
194         
195         return val;
196 }
197
198 /*
199  * The following Madge boards should use this code:
200  *   - Smart 16/4 PCI Mk2 (Abyss)
201  *   - Smart 16/4 PCI Mk1 (PCI T)
202  *   - Smart 16/4 Client Plus PnP (Big Apple)
203  *   - Smart 16/4 Cardbus Mk2
204  *
205  * These access an Atmel AT24 SEEPROM using their glue chip registers. 
206  *
207  */
208 static void at24_writedatabyte(unsigned long regaddr, unsigned char byte)
209 {
210         int i;
211         
212         for (i = 0; i < 8; i++) {
213                 at24_setlines(regaddr, 0, (byte >> (7-i))&0x01);
214                 at24_setlines(regaddr, 1, (byte >> (7-i))&0x01);
215                 at24_setlines(regaddr, 0, (byte >> (7-i))&0x01);
216         }
217 }
218
219 static int at24_sendfullcmd(unsigned long regaddr, unsigned char cmd, unsigned char addr)
220 {
221         if (at24_sendcmd(regaddr, cmd)) {
222                 at24_writedatabyte(regaddr, addr);
223                 return at24_waitforack(regaddr);
224         }
225         return 0;
226 }
227
228 static int at24_sendcmd(unsigned long regaddr, unsigned char cmd)
229 {
230         int i;
231         
232         for (i = 0; i < 10; i++) {
233                 at24_start(regaddr);
234                 at24_writedatabyte(regaddr, cmd);
235                 if (at24_waitforack(regaddr))
236                         return 1;
237         }
238         return 0;
239 }
240
241 static unsigned char at24_readdatabit(unsigned long regaddr)
242 {
243         unsigned char val;
244
245         at24_setlines(regaddr, 0, 1);
246         at24_setlines(regaddr, 1, 1);
247         val = (inb(regaddr) & AT24_DATA)?1:0;
248         at24_setlines(regaddr, 1, 1);
249         at24_setlines(regaddr, 0, 1);
250         return val;
251 }
252
253 static unsigned char at24_readdatabyte(unsigned long regaddr)
254 {
255         unsigned char data = 0;
256         int i;
257         
258         for (i = 0; i < 8; i++) {
259                 data <<= 1;
260                 data |= at24_readdatabit(regaddr);
261         }
262
263         return data;
264 }
265
266 static int at24_waitforack(unsigned long regaddr)
267 {
268         int i;
269         
270         for (i = 0; i < 10; i++) {
271                 if ((at24_readdatabit(regaddr) & 0x01) == 0x00)
272                         return 1;
273         }
274         return 0;
275 }
276
277 static int at24_waitfornack(unsigned long regaddr)
278 {
279         int i;
280         for (i = 0; i < 10; i++) {
281                 if ((at24_readdatabit(regaddr) & 0x01) == 0x01)
282                         return 1;
283         }
284         return 0;
285 }
286
287 static void at24_setlines(unsigned long regaddr, unsigned char clock, unsigned char data)
288 {
289         unsigned char val = AT24_ENABLE;
290         if (clock)
291                 val |= AT24_CLOCK;
292         if (data)
293                 val |= AT24_DATA;
294
295         outb(val, regaddr); 
296         tms380tr_wait(20); /* Very necessary. */
297 }
298
299 static void at24_start(unsigned long regaddr)
300 {
301         at24_setlines(regaddr, 0, 1);
302         at24_setlines(regaddr, 1, 1);
303         at24_setlines(regaddr, 1, 0);
304         at24_setlines(regaddr, 0, 1);
305 }
306
307 static unsigned char at24_readb(unsigned long regaddr, unsigned char addr)
308 {
309         unsigned char data = 0xff;
310         
311         if (at24_sendfullcmd(regaddr, AT24_WRITE, addr)) {
312                 if (at24_sendcmd(regaddr, AT24_READ)) {
313                         data = at24_readdatabyte(regaddr);
314                         if (!at24_waitfornack(regaddr))
315                                 data = 0xff;
316                 }
317         }
318         return data;
319 }
320
321
322 /*
323  * Enable basic functions of the Madge chipset needed
324  * for initialization.
325  */
326 static void abyss_enable(struct net_device *dev)
327 {
328         unsigned char reset_reg;
329         unsigned long ioaddr;
330         
331         ioaddr = dev->base_addr;
332         reset_reg = inb(ioaddr + PCIBM2_RESET_REG);
333         reset_reg |= PCIBM2_RESET_REG_CHIP_NRES;
334         outb(reset_reg, ioaddr + PCIBM2_RESET_REG);
335         tms380tr_wait(100);
336 }
337
338 /*
339  * Enable the functions of the Madge chipset needed for
340  * full working order. 
341  */
342 static int abyss_chipset_init(struct net_device *dev)
343 {
344         unsigned char reset_reg;
345         unsigned long ioaddr;
346         
347         ioaddr = dev->base_addr;
348         
349         reset_reg = inb(ioaddr + PCIBM2_RESET_REG);
350         
351         reset_reg |= PCIBM2_RESET_REG_CHIP_NRES;
352         outb(reset_reg, ioaddr + PCIBM2_RESET_REG);
353         
354         reset_reg &= ~(PCIBM2_RESET_REG_CHIP_NRES |
355                        PCIBM2_RESET_REG_FIFO_NRES | 
356                        PCIBM2_RESET_REG_SIF_NRES);
357         outb(reset_reg, ioaddr + PCIBM2_RESET_REG);
358         
359         tms380tr_wait(100);
360         
361         reset_reg |= PCIBM2_RESET_REG_CHIP_NRES;
362         outb(reset_reg, ioaddr + PCIBM2_RESET_REG);
363         
364         reset_reg |= PCIBM2_RESET_REG_SIF_NRES;
365         outb(reset_reg, ioaddr + PCIBM2_RESET_REG);
366
367         reset_reg |= PCIBM2_RESET_REG_FIFO_NRES;
368         outb(reset_reg, ioaddr + PCIBM2_RESET_REG);
369
370         outb(PCIBM2_INT_CONTROL_REG_SINTEN | 
371              PCIBM2_INT_CONTROL_REG_PCI_ERR_ENABLE, 
372              ioaddr + PCIBM2_INT_CONTROL_REG);
373   
374         outb(30, ioaddr + PCIBM2_FIFO_THRESHOLD);
375         
376         return 0;
377 }
378
379 static inline void abyss_chipset_close(struct net_device *dev)
380 {
381         unsigned long ioaddr;
382         
383         ioaddr = dev->base_addr;
384         outb(0, ioaddr + PCIBM2_RESET_REG);
385 }
386
387 /*
388  * Read configuration data from the AT24 SEEPROM on Madge cards.
389  *
390  */
391 static void abyss_read_eeprom(struct net_device *dev)
392 {
393         struct net_local *tp;
394         unsigned long ioaddr;
395         unsigned short val;
396         int i;
397         
398         tp = netdev_priv(dev);
399         ioaddr = dev->base_addr;
400         
401         /* Must enable glue chip first */
402         abyss_enable(dev);
403         
404         val = at24_readb(ioaddr + PCIBM2_SEEPROM_REG, 
405                          PCIBM2_SEEPROM_RING_SPEED);
406         tp->DataRate = val?SPEED_4:SPEED_16; /* set open speed */
407         printk("%s:    SEEPROM: ring speed: %dMb/sec\n", dev->name, tp->DataRate);
408         
409         val = at24_readb(ioaddr + PCIBM2_SEEPROM_REG,
410                          PCIBM2_SEEPROM_RAM_SIZE) * 128;
411         printk("%s:    SEEPROM: adapter RAM: %dkb\n", dev->name, val);
412         
413         dev->addr_len = 6;
414         for (i = 0; i < 6; i++) 
415                 dev->dev_addr[i] = at24_readb(ioaddr + PCIBM2_SEEPROM_REG, 
416                                               PCIBM2_SEEPROM_BIA+i);
417 }
418
419 static int abyss_open(struct net_device *dev)
420 {  
421         abyss_chipset_init(dev);
422         tms380tr_open(dev);
423         return 0;
424 }
425
426 static int abyss_close(struct net_device *dev)
427 {
428         tms380tr_close(dev);
429         abyss_chipset_close(dev);
430         return 0;
431 }
432
433 static void __devexit abyss_detach (struct pci_dev *pdev)
434 {
435         struct net_device *dev = pci_get_drvdata(pdev);
436         
437         BUG_ON(!dev);
438         unregister_netdev(dev);
439         release_region(dev->base_addr-0x10, ABYSS_IO_EXTENT);
440         free_irq(dev->irq, dev);
441         tmsdev_term(dev);
442         free_netdev(dev);
443         pci_set_drvdata(pdev, NULL);
444 }
445
446 static struct pci_driver abyss_driver = {
447         .name           = "abyss",
448         .id_table       = abyss_pci_tbl,
449         .probe          = abyss_attach,
450         .remove         = __devexit_p(abyss_detach),
451 };
452
453 static int __init abyss_init (void)
454 {
455         return pci_register_driver(&abyss_driver);
456 }
457
458 static void __exit abyss_rmmod (void)
459 {
460         pci_unregister_driver (&abyss_driver);
461 }
462
463 module_init(abyss_init);
464 module_exit(abyss_rmmod);
465