vserver 2.0 rc7
[linux-2.6.git] / drivers / net / arcnet / com90xx.c
1 /*
2  * Linux ARCnet driver - COM90xx chipset (memory-mapped buffers)
3  * 
4  * Written 1994-1999 by Avery Pennarun.
5  * Written 1999 by Martin Mares <mj@ucw.cz>.
6  * Derived from skeleton.c by Donald Becker.
7  *
8  * Special thanks to Contemporary Controls, Inc. (www.ccontrols.com)
9  *  for sponsoring the further development of this driver.
10  *
11  * **********************
12  *
13  * The original copyright of skeleton.c was as follows:
14  *
15  * skeleton.c Written 1993 by Donald Becker.
16  * Copyright 1993 United States Government as represented by the
17  * Director, National Security Agency.  This software may only be used
18  * and distributed according to the terms of the GNU General Public License as
19  * modified by SRC, incorporated herein by reference.
20  *
21  * **********************
22  *
23  * For more details, see drivers/net/arcnet.c
24  *
25  * **********************
26  */
27 #include <linux/module.h>
28 #include <linux/moduleparam.h>
29 #include <linux/init.h>
30 #include <linux/ioport.h>
31 #include <linux/delay.h>
32 #include <linux/netdevice.h>
33 #include <asm/io.h>
34 #include <linux/arcdevice.h>
35
36
37 #define VERSION "arcnet: COM90xx chipset support\n"
38
39
40 /* Define this to speed up the autoprobe by assuming if only one io port and
41  * shmem are left in the list at Stage 5, they must correspond to each
42  * other.
43  *
44  * This is undefined by default because it might not always be true, and the
45  * extra check makes the autoprobe even more careful.  Speed demons can turn
46  * it on - I think it should be fine if you only have one ARCnet card
47  * installed.
48  *
49  * If no ARCnet cards are installed, this delay never happens anyway and thus
50  * the option has no effect.
51  */
52 #undef FAST_PROBE
53
54
55 /* Internal function declarations */
56 static int com90xx_found(int ioaddr, int airq, u_long shmem);
57 static void com90xx_command(struct net_device *dev, int command);
58 static int com90xx_status(struct net_device *dev);
59 static void com90xx_setmask(struct net_device *dev, int mask);
60 static int com90xx_reset(struct net_device *dev, int really_reset);
61 static void com90xx_copy_to_card(struct net_device *dev, int bufnum, int offset,
62                                  void *buf, int count);
63 static void com90xx_copy_from_card(struct net_device *dev, int bufnum, int offset,
64                                    void *buf, int count);
65
66 /* Known ARCnet cards */
67
68 static struct net_device *cards[16];
69 static int numcards;
70
71 /* Handy defines for ARCnet specific stuff */
72
73 /* The number of low I/O ports used by the card */
74 #define ARCNET_TOTAL_SIZE       16
75
76 /* Amount of I/O memory used by the card */
77 #define BUFFER_SIZE (512)
78 #define MIRROR_SIZE (BUFFER_SIZE*4)
79
80 /* COM 9026 controller chip --> ARCnet register addresses */
81 #define _INTMASK (ioaddr+0)     /* writable */
82 #define _STATUS  (ioaddr+0)     /* readable */
83 #define _COMMAND (ioaddr+1)     /* writable, returns random vals on read (?) */
84 #define _CONFIG  (ioaddr+2)     /* Configuration register */
85 #define _RESET   (ioaddr+8)     /* software reset (on read) */
86 #define _MEMDATA (ioaddr+12)    /* Data port for IO-mapped memory */
87 #define _ADDR_HI (ioaddr+15)    /* Control registers for said */
88 #define _ADDR_LO (ioaddr+14)
89
90 #undef ASTATUS
91 #undef ACOMMAND
92 #undef AINTMASK
93
94 #define ASTATUS()       inb(_STATUS)
95 #define ACOMMAND(cmd)   outb((cmd),_COMMAND)
96 #define AINTMASK(msk)   outb((msk),_INTMASK)
97
98
99 static int com90xx_skip_probe __initdata = 0;
100
101 /* Module parameters */
102
103 static int io;                  /* use the insmod io= irq= shmem= options */
104 static int irq;
105 static int shmem;
106 static char device[9];          /* use eg. device=arc1 to change name */
107
108 module_param(io, int, 0);
109 module_param(irq, int, 0);
110 module_param(shmem, int, 0);
111 module_param_string(device, device, sizeof(device), 0);
112
113 static void __init com90xx_probe(void)
114 {
115         int count, status, ioaddr, numprint, airq, openparen = 0;
116         unsigned long airqmask;
117         int ports[(0x3f0 - 0x200) / 16 + 1] =
118         {0};
119         u_long shmems[(0xFF800 - 0xA0000) / 2048 + 1] =
120         {0};
121         int numports, numshmems, *port;
122         u_long *p;
123
124         if (!io && !irq && !shmem && !*device && com90xx_skip_probe)
125                 return;
126
127         BUGLVL(D_NORMAL) printk(VERSION);
128
129         /* set up the arrays where we'll store the possible probe addresses */
130         numports = numshmems = 0;
131         if (io)
132                 ports[numports++] = io;
133         else
134                 for (count = 0x200; count <= 0x3f0; count += 16)
135                         ports[numports++] = count;
136         if (shmem)
137                 shmems[numshmems++] = shmem;
138         else
139                 for (count = 0xA0000; count <= 0xFF800; count += 2048)
140                         shmems[numshmems++] = count;
141
142         /* Stage 1: abandon any reserved ports, or ones with status==0xFF
143          * (empty), and reset any others by reading the reset port.
144          */
145         numprint = -1;
146         for (port = &ports[0]; port - ports < numports; port++) {
147                 numprint++;
148                 numprint %= 8;
149                 if (!numprint) {
150                         BUGMSG2(D_INIT, "\n");
151                         BUGMSG2(D_INIT, "S1: ");
152                 }
153                 BUGMSG2(D_INIT, "%Xh ", *port);
154
155                 ioaddr = *port;
156
157                 if (!request_region(*port, ARCNET_TOTAL_SIZE, "arcnet (90xx)")) {
158                         BUGMSG2(D_INIT_REASONS, "(request_region)\n");
159                         BUGMSG2(D_INIT_REASONS, "S1: ");
160                         BUGLVL(D_INIT_REASONS) numprint = 0;
161                         *port-- = ports[--numports];
162                         continue;
163                 }
164                 if (ASTATUS() == 0xFF) {
165                         BUGMSG2(D_INIT_REASONS, "(empty)\n");
166                         BUGMSG2(D_INIT_REASONS, "S1: ");
167                         BUGLVL(D_INIT_REASONS) numprint = 0;
168                         release_region(*port, ARCNET_TOTAL_SIZE);
169                         *port-- = ports[--numports];
170                         continue;
171                 }
172                 inb(_RESET);    /* begin resetting card */
173
174                 BUGMSG2(D_INIT_REASONS, "\n");
175                 BUGMSG2(D_INIT_REASONS, "S1: ");
176                 BUGLVL(D_INIT_REASONS) numprint = 0;
177         }
178         BUGMSG2(D_INIT, "\n");
179
180         if (!numports) {
181                 BUGMSG2(D_NORMAL, "S1: No ARCnet cards found.\n");
182                 return;
183         }
184         /* Stage 2: we have now reset any possible ARCnet cards, so we can't
185          * do anything until they finish.  If D_INIT, print the list of
186          * cards that are left.
187          */
188         numprint = -1;
189         for (port = &ports[0]; port < ports + numports; port++) {
190                 numprint++;
191                 numprint %= 8;
192                 if (!numprint) {
193                         BUGMSG2(D_INIT, "\n");
194                         BUGMSG2(D_INIT, "S2: ");
195                 }
196                 BUGMSG2(D_INIT, "%Xh ", *port);
197         }
198         BUGMSG2(D_INIT, "\n");
199         mdelay(RESETtime);
200
201         /* Stage 3: abandon any shmem addresses that don't have the signature
202          * 0xD1 byte in the right place, or are read-only.
203          */
204         numprint = -1;
205         for (p = &shmems[0]; p < shmems + numshmems; p++) {
206                 u_long ptr = *p;
207
208                 numprint++;
209                 numprint %= 8;
210                 if (!numprint) {
211                         BUGMSG2(D_INIT, "\n");
212                         BUGMSG2(D_INIT, "S3: ");
213                 }
214                 BUGMSG2(D_INIT, "%lXh ", *p);
215
216                 if (!request_mem_region(*p, BUFFER_SIZE, "arcnet (90xx)")) {
217                         BUGMSG2(D_INIT_REASONS, "(request_mem_region)\n");
218                         BUGMSG2(D_INIT_REASONS, "Stage 3: ");
219                         BUGLVL(D_INIT_REASONS) numprint = 0;
220                         *p-- = shmems[--numshmems];
221                         continue;
222                 }
223                 if (isa_readb(ptr) != TESTvalue) {
224                         BUGMSG2(D_INIT_REASONS, "(%02Xh != %02Xh)\n",
225                                 isa_readb(ptr), TESTvalue);
226                         BUGMSG2(D_INIT_REASONS, "S3: ");
227                         BUGLVL(D_INIT_REASONS) numprint = 0;
228                         release_mem_region(*p, BUFFER_SIZE);
229                         *p-- = shmems[--numshmems];
230                         continue;
231                 }
232                 /* By writing 0x42 to the TESTvalue location, we also make
233                  * sure no "mirror" shmem areas show up - if they occur
234                  * in another pass through this loop, they will be discarded
235                  * because *cptr != TESTvalue.
236                  */
237                 isa_writeb(0x42, ptr);
238                 if (isa_readb(ptr) != 0x42) {
239                         BUGMSG2(D_INIT_REASONS, "(read only)\n");
240                         BUGMSG2(D_INIT_REASONS, "S3: ");
241                         release_mem_region(*p, BUFFER_SIZE);
242                         *p-- = shmems[--numshmems];
243                         continue;
244                 }
245                 BUGMSG2(D_INIT_REASONS, "\n");
246                 BUGMSG2(D_INIT_REASONS, "S3: ");
247                 BUGLVL(D_INIT_REASONS) numprint = 0;
248         }
249         BUGMSG2(D_INIT, "\n");
250
251         if (!numshmems) {
252                 BUGMSG2(D_NORMAL, "S3: No ARCnet cards found.\n");
253                 for (port = &ports[0]; port < ports + numports; port++)
254                         release_region(*port, ARCNET_TOTAL_SIZE);
255                 return;
256         }
257         /* Stage 4: something of a dummy, to report the shmems that are
258          * still possible after stage 3.
259          */
260         numprint = -1;
261         for (p = &shmems[0]; p < shmems + numshmems; p++) {
262                 numprint++;
263                 numprint %= 8;
264                 if (!numprint) {
265                         BUGMSG2(D_INIT, "\n");
266                         BUGMSG2(D_INIT, "S4: ");
267                 }
268                 BUGMSG2(D_INIT, "%lXh ", *p);
269         }
270         BUGMSG2(D_INIT, "\n");
271
272         /* Stage 5: for any ports that have the correct status, can disable
273          * the RESET flag, and (if no irq is given) generate an autoirq,
274          * register an ARCnet device.
275          *
276          * Currently, we can only register one device per probe, so quit
277          * after the first one is found.
278          */
279         numprint = -1;
280         for (port = &ports[0]; port < ports + numports; port++) {
281                 int found = 0;
282                 numprint++;
283                 numprint %= 8;
284                 if (!numprint) {
285                         BUGMSG2(D_INIT, "\n");
286                         BUGMSG2(D_INIT, "S5: ");
287                 }
288                 BUGMSG2(D_INIT, "%Xh ", *port);
289
290                 ioaddr = *port;
291                 status = ASTATUS();
292
293                 if ((status & 0x9D)
294                     != (NORXflag | RECONflag | TXFREEflag | RESETflag)) {
295                         BUGMSG2(D_INIT_REASONS, "(status=%Xh)\n", status);
296                         BUGMSG2(D_INIT_REASONS, "S5: ");
297                         BUGLVL(D_INIT_REASONS) numprint = 0;
298                         release_region(*port, ARCNET_TOTAL_SIZE);
299                         *port-- = ports[--numports];
300                         continue;
301                 }
302                 ACOMMAND(CFLAGScmd | RESETclear | CONFIGclear);
303                 status = ASTATUS();
304                 if (status & RESETflag) {
305                         BUGMSG2(D_INIT_REASONS, " (eternal reset, status=%Xh)\n",
306                                 status);
307                         BUGMSG2(D_INIT_REASONS, "S5: ");
308                         BUGLVL(D_INIT_REASONS) numprint = 0;
309                         release_region(*port, ARCNET_TOTAL_SIZE);
310                         *port-- = ports[--numports];
311                         continue;
312                 }
313                 /* skip this completely if an IRQ was given, because maybe
314                  * we're on a machine that locks during autoirq!
315                  */
316                 if (!irq) {
317                         /* if we do this, we're sure to get an IRQ since the
318                          * card has just reset and the NORXflag is on until
319                          * we tell it to start receiving.
320                          */
321                         airqmask = probe_irq_on();
322                         AINTMASK(NORXflag);
323                         udelay(1);
324                         AINTMASK(0);
325                         airq = probe_irq_off(airqmask);
326
327                         if (airq <= 0) {
328                                 BUGMSG2(D_INIT_REASONS, "(airq=%d)\n", airq);
329                                 BUGMSG2(D_INIT_REASONS, "S5: ");
330                                 BUGLVL(D_INIT_REASONS) numprint = 0;
331                                 release_region(*port, ARCNET_TOTAL_SIZE);
332                                 *port-- = ports[--numports];
333                                 continue;
334                         }
335                 } else {
336                         airq = irq;
337                 }
338
339                 BUGMSG2(D_INIT, "(%d,", airq);
340                 openparen = 1;
341
342                 /* Everything seems okay.  But which shmem, if any, puts
343                  * back its signature byte when the card is reset?
344                  *
345                  * If there are multiple cards installed, there might be
346                  * multiple shmems still in the list.
347                  */
348 #ifdef FAST_PROBE
349                 if (numports > 1 || numshmems > 1) {
350                         inb(_RESET);
351                         mdelay(RESETtime);
352                 } else {
353                         /* just one shmem and port, assume they match */
354                         isa_writeb(TESTvalue, shmems[0]);
355                 }
356 #else
357                 inb(_RESET);
358                 mdelay(RESETtime);
359 #endif
360
361                 for (p = &shmems[0]; p < shmems + numshmems; p++) {
362                         u_long ptr = *p;
363
364                         if (isa_readb(ptr) == TESTvalue) {      /* found one */
365                                 BUGMSG2(D_INIT, "%lXh)\n", *p);
366                                 openparen = 0;
367
368                                 /* register the card */
369                                 if (com90xx_found(*port, airq, *p) == 0)
370                                         found = 1;
371                                 numprint = -1;
372
373                                 /* remove shmem from the list */
374                                 *p = shmems[--numshmems];
375                                 break;  /* go to the next I/O port */
376                         } else {
377                                 BUGMSG2(D_INIT_REASONS, "%Xh-", isa_readb(ptr));
378                         }
379                 }
380
381                 if (openparen) {
382                         BUGLVL(D_INIT) printk("no matching shmem)\n");
383                         BUGLVL(D_INIT_REASONS) printk("S5: ");
384                         BUGLVL(D_INIT_REASONS) numprint = 0;
385                 }
386                 if (!found)
387                         release_region(*port, ARCNET_TOTAL_SIZE);
388                 *port-- = ports[--numports];
389         }
390
391         BUGLVL(D_INIT_REASONS) printk("\n");
392
393         /* Now put back TESTvalue on all leftover shmems. */
394         for (p = &shmems[0]; p < shmems + numshmems; p++) {
395                 isa_writeb(TESTvalue, *p);
396                 release_mem_region(*p, BUFFER_SIZE);
397         }
398 }
399
400
401 /* Set up the struct net_device associated with this card.  Called after
402  * probing succeeds.
403  */
404 static int __init com90xx_found(int ioaddr, int airq, u_long shmem)
405 {
406         struct net_device *dev = NULL;
407         struct arcnet_local *lp;
408         u_long first_mirror, last_mirror;
409         int mirror_size;
410
411         /* allocate struct net_device */
412         dev = alloc_arcdev(device);
413         if (!dev) {
414                 BUGMSG2(D_NORMAL, "com90xx: Can't allocate device!\n");
415                 release_mem_region(shmem, BUFFER_SIZE);
416                 return -ENOMEM;
417         }
418         lp = dev->priv;
419         /* find the real shared memory start/end points, including mirrors */
420
421         /* guess the actual size of one "memory mirror" - the number of
422          * bytes between copies of the shared memory.  On most cards, it's
423          * 2k (or there are no mirrors at all) but on some, it's 4k.
424          */
425         mirror_size = MIRROR_SIZE;
426         if (isa_readb(shmem) == TESTvalue
427             && isa_readb(shmem - mirror_size) != TESTvalue
428             && isa_readb(shmem - 2 * mirror_size) == TESTvalue)
429                 mirror_size *= 2;
430
431         first_mirror = last_mirror = shmem;
432         while (isa_readb(first_mirror) == TESTvalue)
433                 first_mirror -= mirror_size;
434         first_mirror += mirror_size;
435
436         while (isa_readb(last_mirror) == TESTvalue)
437                 last_mirror += mirror_size;
438         last_mirror -= mirror_size;
439
440         dev->mem_start = first_mirror;
441         dev->mem_end = last_mirror + MIRROR_SIZE - 1;
442
443         release_mem_region(shmem, BUFFER_SIZE);
444         if (!request_mem_region(dev->mem_start, dev->mem_end - dev->mem_start + 1, "arcnet (90xx)"))
445                 goto err_free_dev;
446
447         /* reserve the irq */
448         if (request_irq(airq, &arcnet_interrupt, 0, "arcnet (90xx)", dev)) {
449                 BUGMSG(D_NORMAL, "Can't get IRQ %d!\n", airq);
450                 goto err_release_mem;
451         }
452         dev->irq = airq;
453
454         /* Initialize the rest of the device structure. */
455         lp->card_name = "COM90xx";
456         lp->hw.command = com90xx_command;
457         lp->hw.status = com90xx_status;
458         lp->hw.intmask = com90xx_setmask;
459         lp->hw.reset = com90xx_reset;
460         lp->hw.owner = THIS_MODULE;
461         lp->hw.copy_to_card = com90xx_copy_to_card;
462         lp->hw.copy_from_card = com90xx_copy_from_card;
463         lp->mem_start = ioremap(dev->mem_start, dev->mem_end - dev->mem_start + 1);
464         if (!lp->mem_start) {
465                 BUGMSG(D_NORMAL, "Can't remap device memory!\n");
466                 goto err_free_irq;
467         }
468
469         /* get and check the station ID from offset 1 in shmem */
470         dev->dev_addr[0] = readb(lp->mem_start + 1);
471
472         dev->base_addr = ioaddr;
473
474         BUGMSG(D_NORMAL, "COM90xx station %02Xh found at %03lXh, IRQ %d, "
475                "ShMem %lXh (%ld*%xh).\n",
476                dev->dev_addr[0],
477                dev->base_addr, dev->irq, dev->mem_start,
478          (dev->mem_end - dev->mem_start + 1) / mirror_size, mirror_size);
479
480         if (register_netdev(dev))
481                 goto err_unmap;
482
483         cards[numcards++] = dev;
484         return 0;
485
486 err_unmap:
487         iounmap(lp->mem_start);
488 err_free_irq:
489         free_irq(dev->irq, dev);
490 err_release_mem:
491         release_mem_region(dev->mem_start, dev->mem_end - dev->mem_start + 1);
492 err_free_dev:
493         free_netdev(dev);
494         return -EIO;
495 }
496
497
498 static void com90xx_command(struct net_device *dev, int cmd)
499 {
500         short ioaddr = dev->base_addr;
501
502         ACOMMAND(cmd);
503 }
504
505
506 static int com90xx_status(struct net_device *dev)
507 {
508         short ioaddr = dev->base_addr;
509
510         return ASTATUS();
511 }
512
513
514 static void com90xx_setmask(struct net_device *dev, int mask)
515 {
516         short ioaddr = dev->base_addr;
517
518         AINTMASK(mask);
519 }
520
521
522 /*
523  * Do a hardware reset on the card, and set up necessary registers.
524  * 
525  * This should be called as little as possible, because it disrupts the
526  * token on the network (causes a RECON) and requires a significant delay.
527  *
528  * However, it does make sure the card is in a defined state.
529  */
530 int com90xx_reset(struct net_device *dev, int really_reset)
531 {
532         struct arcnet_local *lp = dev->priv;
533         short ioaddr = dev->base_addr;
534
535         BUGMSG(D_INIT, "Resetting (status=%02Xh)\n", ASTATUS());
536
537         if (really_reset) {
538                 /* reset the card */
539                 inb(_RESET);
540                 mdelay(RESETtime);
541         }
542         ACOMMAND(CFLAGScmd | RESETclear);       /* clear flags & end reset */
543         ACOMMAND(CFLAGScmd | CONFIGclear);
544
545         /* don't do this until we verify that it doesn't hurt older cards! */
546         /* outb(inb(_CONFIG) | ENABLE16flag, _CONFIG); */
547
548         /* verify that the ARCnet signature byte is present */
549         if (readb(lp->mem_start) != TESTvalue) {
550                 if (really_reset)
551                         BUGMSG(D_NORMAL, "reset failed: TESTvalue not present.\n");
552                 return 1;
553         }
554         /* enable extended (512-byte) packets */
555         ACOMMAND(CONFIGcmd | EXTconf);
556
557         /* clean out all the memory to make debugging make more sense :) */
558         BUGLVL(D_DURING)
559             memset_io(lp->mem_start, 0x42, 2048);
560
561         /* done!  return success. */
562         return 0;
563 }
564
565 static void com90xx_copy_to_card(struct net_device *dev, int bufnum, int offset,
566                                  void *buf, int count)
567 {
568         struct arcnet_local *lp = dev->priv;
569         void __iomem *memaddr = lp->mem_start + bufnum * 512 + offset;
570         TIME("memcpy_toio", count, memcpy_toio(memaddr, buf, count));
571 }
572
573
574 static void com90xx_copy_from_card(struct net_device *dev, int bufnum, int offset,
575                                    void *buf, int count)
576 {
577         struct arcnet_local *lp = dev->priv;
578         void __iomem *memaddr = lp->mem_start + bufnum * 512 + offset;
579         TIME("memcpy_fromio", count, memcpy_fromio(buf, memaddr, count));
580 }
581
582
583 MODULE_LICENSE("GPL");
584
585 static int __init com90xx_init(void)
586 {
587         if (irq == 2)
588                 irq = 9;
589         com90xx_probe();
590         if (!numcards)
591                 return -EIO;
592         return 0;
593 }
594
595 static void __exit com90xx_exit(void)
596 {
597         struct net_device *dev;
598         struct arcnet_local *lp;
599         int count;
600
601         for (count = 0; count < numcards; count++) {
602                 dev = cards[count];
603                 lp = dev->priv;
604
605                 unregister_netdev(dev);
606                 free_irq(dev->irq, dev);
607                 iounmap(lp->mem_start);
608                 release_region(dev->base_addr, ARCNET_TOTAL_SIZE);
609                 release_mem_region(dev->mem_start, dev->mem_end - dev->mem_start + 1);
610                 free_netdev(dev);
611         }
612 }
613
614 module_init(com90xx_init);
615 module_exit(com90xx_exit);
616
617 #ifndef MODULE
618 static int __init com90xx_setup(char *s)
619 {
620         int ints[8];
621
622         s = get_options(s, 8, ints);
623         if (!ints[0] && !*s) {
624                 printk("com90xx: Disabled.\n");
625                 return 1;
626         }
627
628         switch (ints[0]) {
629         default:                /* ERROR */
630                 printk("com90xx: Too many arguments.\n");
631         case 3:         /* Mem address */
632                 shmem = ints[3];
633         case 2:         /* IRQ */
634                 irq = ints[2];
635         case 1:         /* IO address */
636                 io = ints[1];
637         }
638
639         if (*s)
640                 snprintf(device, sizeof(device), "%s", s);
641
642         return 1;
643 }
644
645 __setup("com90xx=", com90xx_setup);
646 #endif