root/net/inet/el.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. el2autoprobe
  2. el2probe
  3. el2_reset_8390
  4. el2_init_card
  5. el2_block_output
  6. el2_block_input

   1 /* el.c: A shared-memory NS8390 ethernet driver for linux. */
   2 /*
   3     Written 1992,1993 by Donald Becker. This is alpha test code.
   4     Copyright 1993 United States Government as represented by the
   5     Director, National Security Agency.  This software may be used and
   6     distributed according to the terms of the GNU Public License,
   7     incorporated herein by reference.
   8 
   9     This driver should work with the 3c503 and 3c503/16.  It must be used
  10     in shared memory mode.
  11 
  12     The Author may be reached as becker@super.org or
  13     C/O Supercomputing Research Ctr., 17100 Science Dr., Bowie MD 20715
  14 */
  15 
  16 static char *version = "el.c:v0.99-10 5/28/93 Donald Becker (becker@super.org)\n";
  17 
  18 #include <linux/config.h>
  19 #include <linux/kernel.h>
  20 #include <linux/sched.h>
  21 #include <linux/errno.h>
  22 #include <asm/io.h>
  23 #include <asm/system.h>
  24 
  25 #include "dev.h"
  26 
  27 #include "8390.h"
  28 #include "elreg.h"
  29 
  30 extern void NS8390_init(struct device *dev, int startp);
  31 extern int ei_debug;
  32 extern struct sigaction ei_sigaction;
  33 
  34 int el2autoprobe(int ioaddr, struct device *dev);
  35 int el2probe(int ioaddr, struct device *dev);
  36 
  37 static void el2_reset_8390(struct device *dev);
  38 static void el2_init_card(struct device *dev);
  39 static void el2_block_output(struct device *dev, int count,
  40                              const unsigned char *buf, const start_page);
  41 static int el2_block_input(struct device *dev, int count, char *buf,
  42                            int ring_offset);
  43 
  44 
  45 int
  46 el2autoprobe(int ioaddr, struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
  47 {
  48     int *addr, addrs[] = { 0xddffe, 0xd9ffe, 0xcdffe, 0xc9ffe, 0};
  49     int ports[] = {0x300,0x310,0x330,0x350,0x250,0x280,0x2a0,0x2e0,0};
  50 
  51     /* Non-autoprobe case first: */
  52     if (ioaddr > 0)
  53         return el2probe(ioaddr, dev);
  54 
  55     /* We check for a memory-mapped 3c503 board by looking at the
  56        port location bitmap at the end of the jumpered boot PROM space.
  57        This works even if a PROM isn't there. */
  58     for (addr = addrs; *addr; addr++) {
  59         int i;
  60         unsigned int base_bits = *(unsigned char *)*addr;
  61         /* Find first set bit. */
  62         for(i = 7; i >= 0; i--, base_bits >>= 1)
  63             if (base_bits & 0x1)
  64                 break;
  65         if (base_bits == 1 &&  el2probe(ports[i], dev))
  66             return dev->base_addr;
  67     }
  68 #ifndef ignore_nonshared_memory
  69     /* It's not memory mapped, bummer.  Try all of the locations
  70        that aren't obviously empty. */
  71     {   int i;
  72         for (i = 0; i < 8; i++) {
  73             inb_p(ports[i] + 0x40F); /* Reset any lurking NE2000 */
  74             if (inb(ports[i] + 0x403) == (0x80 >> i) /* Preliminary check */
  75                 && el2probe(ports[i], dev))
  76                 return dev->base_addr;
  77         }
  78     }
  79 #endif  /* probe_nonshared_memory */
  80     return 0;
  81 }
  82 
  83 /* Probe for the Etherlink II card at I/O port base IOADDR,
  84    returning non-zero on sucess.  If found, set the station
  85    address and memory parameters in DEVICE. */
  86 int
  87 el2probe(int ioaddr, struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
  88 {
  89     int i, iobase_reg, membase_reg, saved_406;
  90     unsigned char *station_addr = dev->dev_addr;
  91 
  92     /* We verify that it's a 3C503 board by checking the first three octets
  93        of its ethernet address. */
  94     printk("3c503 probe at %#3x:", ioaddr);
  95     iobase_reg = inb(ioaddr+0x403);
  96     membase_reg = inb(ioaddr+0x404);
  97     /* Verify ASIC register that should be 0 or have a single bit set. */
  98     if (   (iobase_reg  & (iobase_reg - 1))
  99         || (membase_reg & (membase_reg - 1))) {
 100         printk("  not found.\n");
 101         return 0;
 102     }
 103     saved_406 = inb_p(ioaddr + 0x406);
 104     outb_p(ECNTRL_RESET|ECNTRL_THIN, ioaddr + 0x406); /* Reset it... */
 105     outb_p(ECNTRL_THIN, ioaddr + 0x406);
 106     /* Map the station addr PROM into the lower I/O ports. */
 107     outb(ECNTRL_SAPROM|ECNTRL_THIN, ioaddr + 0x406);
 108     for (i = 0; i < ETHER_ADDR_LEN; i++) {
 109         printk(" %2.2X", (station_addr[i] = inb(ioaddr + i)));
 110     }
 111     if ( station_addr[0] != 0x02
 112         || station_addr[1] != 0x60
 113         || station_addr[2] != 0x8c) {
 114         printk("  3C503 not found.\n");
 115         /* Restore the register we frobbed. */
 116         outb_p(saved_406, ioaddr + 0x406);
 117         return 0;
 118     }
 119     /* Map the 8390 back into the window. */
 120     outb(ECNTRL_THIN, ioaddr + 0x406);
 121     dev->base_addr = ioaddr;
 122     /* Probe for, turn on and clear the board's shared memory. */
 123     if (ei_debug > 2) printk(" memory jumpers %2.2x ", membase_reg);
 124     outb(EGACFR_NORM, ioaddr + 0x405);  /* Enable RAM */
 125     if ((membase_reg & 0xf0) == 0) {
 126         dev->mem_start = 0;
 127     } else {
 128         dev->mem_start = ((membase_reg & 0xc0) ? 0xD8000 : 0xC8000) +
 129             ((membase_reg & 0xA0) ? 0x4000 : 0);
 130 
 131 #define EL2_MEMSIZE (EL2SM_STOP_PG - EL2SM_START_PG)*256
 132 #ifdef EL2MEMTEST
 133         /* This has never found an error, but someone might care. */
 134         {                       /* Check the card's memory. */
 135             int *mem_base = (int *)dev->mem_start;
 136             int memtest_value = 0xbbadf00d;
 137             mem_base[0] = 0xba5eba5e;
 138             for (i = 1; i < EL2_MEMSIZE/sizeof(mem_base[0]); i++) {
 139                 mem_base[i] = memtest_value;
 140                 if (mem_base[0] != 0xba5eba5e
 141                     || mem_base[i] != memtest_value) {
 142                     printk(" memory failure or memory address conflict.\n");
 143                     dev->mem_start = 0;
 144                     break;
 145                 }
 146                 memtest_value += 0x55555555;
 147                 mem_base[i] = 0;
 148             }
 149         }
 150 #endif  /* EL2MEMTEST */
 151         /* Divide the on-board memory into a single maximum-sized transmit
 152            (double-sized for ping-pong transmit) buffer at the base, and
 153            use the rest as a receive ring. */
 154         dev->mem_end = dev->rmem_end = dev->mem_start + EL2_MEMSIZE;
 155         dev->rmem_start = TX_PAGES*256 + dev->mem_start;
 156     }
 157     if (ei_debug > 2)
 158         printk("\n3c503: memory params start=%#5x rstart=%#5x end=%#5x rend=%#5x.\n",
 159                dev->mem_start, dev->rmem_start, dev->mem_end, dev->rmem_end);
 160 
 161     /* Finish setting the board's parameters. */
 162     ei_status.name = "3C503";
 163     ei_status.tx_start_page = EL2SM_START_PG;
 164     ei_status.rx_start_page = EL2SM_START_PG + TX_PAGES;
 165     ei_status.stop_page = EL2SM_STOP_PG;
 166     ei_status.reset_8390 = &el2_reset_8390;
 167     ei_status.block_input = &el2_block_input;
 168     ei_status.block_output = &el2_block_output;
 169 /* This should be probed for (or set via an ioctl()) at run-time someday. */
 170 #if defined(EI8390_THICK) || defined(EL2_AUI)
 171     ei_status.interface_num = 1;
 172 #else
 173     ei_status.interface_num = 0;
 174 #endif
 175 
 176     if (dev->irq < 2) {
 177         int irqlist[] = {5, 9, 3, 4, 0};
 178         int *irqp = irqlist;
 179         do {
 180             if (request_irq (dev->irq = *irqp, NULL) != -EBUSY) {
 181                 /* Twinkle the interrupt, and check if it's seen. */
 182                 autoirq_setup(0);
 183                 outb_p((0x04 << (dev->irq == 9 ? 2 : dev->irq)), E33G_IDCFR);
 184                 outb_p(0x00, E33G_IDCFR);
 185                 if (dev->irq == autoirq_report(0)        /* It's a good IRQ line! */
 186                     && request_irq (dev->irq, &ei_interrupt) == 0) {
 187                     printk(" got IRQ %d", dev->irq);
 188                     break;
 189                 } else
 190                     printk(" IRQ%d busy..", dev->irq);
 191             }
 192         } while (*++irqp);
 193         if (*irqp == 0) {
 194             printk(" unable to find an free IRQ line.\n");
 195             return 0;
 196         }
 197     } else {
 198         if (dev->irq == 2)
 199             dev->irq = 9;
 200         else if (dev->irq > 5 && dev->irq != 9) {
 201             printk("\n3c503: configured interrupt number %d out of range.\n",
 202                    dev->irq);
 203             return 0;
 204         }
 205         if (request_irq(dev->irq, &ei_interrupt)) {
 206             printk (" unable to get IRQ%d.\n", dev->irq);
 207             return 0;
 208         }
 209     }
 210 
 211     dev->start = 0;
 212     el2_init_card(dev);
 213 
 214     if (dev->mem_start)
 215         printk("\n%s: %s using IRQ %d with shared memory at %#6x-%#6x,\n",
 216                dev->name, ei_status.name, dev->irq,
 217                dev->mem_start, dev->mem_end-1);
 218     else
 219         printk("\n%s: %s using IRQ %d with programmed I/O.\n",
 220                dev->name, ei_status.name, dev->irq);
 221     if (ei_debug > 1)
 222         printk(version);
 223 
 224     return ioaddr;
 225 }
 226 
 227 /* This is called whenever we have a unrecoverable failure:
 228        transmit timeout
 229        Bad ring buffer packet header
 230  */
 231 static void
 232 el2_reset_8390(struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 233 {
 234     if (ei_debug > 1) {
 235         printk("%s: Resetting the 3c503 board...", dev->name);
 236         printk("%#x=%#02x %#x=%#02x %#x=%#02x...", E33G_IDCFR, inb(E33G_IDCFR),
 237                E33G_CNTRL, inb(E33G_CNTRL), E33G_GACFR, inb(E33G_GACFR));
 238     }
 239     outb_p(ECNTRL_RESET|ECNTRL_THIN, E33G_CNTRL);
 240     ei_status.txing = 0;
 241     outb_p(ei_status.interface_num==0 ? ECNTRL_THIN : ECNTRL_AUI, E33G_CNTRL);
 242     el2_init_card(dev);
 243     if (ei_debug > 1) printk("done\n");
 244 }
 245 
 246 /* Initialize the 3c503 GA registers after a reset. */
 247 static void
 248 el2_init_card(struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 249 {
 250     /* Unmap the station PROM and select the DIX or BNC connector. */
 251     outb_p(ei_status.interface_num==0 ? ECNTRL_THIN : ECNTRL_AUI, E33G_CNTRL);
 252 
 253     /* Set ASIC copy of rx's first and last+1 buffer pages */
 254     /* These must be the same as in the 8390. */
 255     outb(ei_status.rx_start_page, E33G_STARTPG);
 256     outb(ei_status.stop_page,  E33G_STOPPG);
 257 
 258     /* Point the vector pointer registers somewhere ?harmless?. */
 259     outb(0xff, E33G_VP2);       /* Point at the ROM restart location 0xffff0 */
 260     outb(0xff, E33G_VP1);
 261     outb(0x00, E33G_VP0);
 262     /* Turn off all interrupts until we're opened. */
 263     outb_p(0x00,  dev->base_addr + EN0_IMR);
 264     /* Enable IRQs iff started. */
 265     outb(EGACFR_NORM, E33G_GACFR);
 266 
 267     /* Set the interrupt line. */
 268     outb_p((0x04 << (dev->irq == 9 ? 2 : dev->irq)), E33G_IDCFR);
 269     outb_p(8, E33G_DRQCNT);             /* Set burst size to 8 */
 270     outb_p(0x20, E33G_DMAAH);   /* Put a valid addr in the GA DMA */
 271     outb_p(0x00, E33G_DMAAL);
 272     return;                     /* We always succeed */
 273 }
 274 
 275 /* Either use the shared memory (if enabled on the board) or put the packet
 276    out through the ASIC FIFO.  The latter is probably much slower. */
 277 static void
 278 el2_block_output(struct device *dev, int count,
     /* [previous][next][first][last][top][bottom][index][help] */
 279                  const unsigned char *buf, const start_page)
 280 {
 281     int i;                              /* Buffer index */
 282     int boguscount = 0;         /* timeout counter */
 283 
 284     /* This should really be set with during an open(). */
 285     outb(EGACFR_NORM, E33G_GACFR);      /* Enable RAM and interrupts. */
 286 
 287     if (dev->mem_start) {       /* Shared memory transfer */
 288         void *dest_addr = (void *)(dev->mem_start +
 289             ((start_page - ei_status.tx_start_page) << 8));
 290         memcpy(dest_addr, buf, count);
 291         if (ei_debug > 2  &&  memcmp(dest_addr, buf, count))
 292             printk("%s: 3c503 send_packet() bad memory copy @ %#5x.\n",
 293                    dev->name, dest_addr);
 294         else if (ei_debug > 4)
 295             printk("%s: 3c503 send_packet() good memory copy @ %#5x.\n",
 296                    dev->name, dest_addr);
 297         return;
 298     }
 299     /* No shared memory, put the packet out the slow way. */
 300     /* Set up then start the internal memory transfer to Tx Start Page */
 301     outb(0x00, E33G_DMAAL);
 302     outb_p(start_page, E33G_DMAAH);
 303     outb_p((ei_status.interface_num ? ECNTRL_AUI : ECNTRL_THIN ) | ECNTRL_OUTPUT
 304            | ECNTRL_START, E33G_CNTRL);
 305 
 306     /* This is the byte copy loop: it should probably be tuned for
 307        for speed once everything is working.  I think it is possible
 308        to output 8 bytes between each check of the status bit. */
 309     for(i = 0; i < count; i++) {
 310         if (i % 8 == 0)
 311             while ((inb(E33G_STATUS) & ESTAT_DPRDY) == 0)
 312                 if (++boguscount > (i<<3) + 32) {
 313                     printk("%s: FIFO blocked in el2_block_output (at %d of %d, bc=%d).\n",
 314                            dev->name, i, count, boguscount);
 315                     return;
 316                 }
 317         outb(buf[i], E33G_FIFOH);
 318     }
 319     outb_p(ei_status.interface_num==0 ? ECNTRL_THIN : ECNTRL_AUI, E33G_CNTRL);
 320     return;
 321 }
 322 
 323 /* Returns the new ring pointer. */
 324 static int
 325 el2_block_input(struct device *dev, int count, char *buf, int ring_offset)
     /* [previous][next][first][last][top][bottom][index][help] */
 326 {
 327     int boguscount = 0;
 328     int end_of_ring = dev->rmem_end;
 329     unsigned int i;
 330 
 331     /* Maybe enable shared memory just be to be safe... nahh.*/
 332     if (dev->mem_start) {       /* Use the shared memory. */
 333         ring_offset -= (EL2SM_START_PG<<8);
 334         if (dev->mem_start + ring_offset + count > end_of_ring) {
 335             /* We must wrap the input move. */
 336             int semi_count = end_of_ring - (dev->mem_start + ring_offset);
 337             if (ei_debug > 4)
 338                 printk("%s: 3c503 block_input() @ %#5x+%x=%5x.\n",
 339                        dev->name, dev->mem_start, ring_offset,
 340                        (char *)dev->mem_start + ring_offset);
 341             memcpy(buf, (char *)dev->mem_start + ring_offset, semi_count);
 342             count -= semi_count;
 343             memcpy(buf + semi_count, (char *)dev->rmem_start, count);
 344             return dev->rmem_start + count;
 345         }
 346         if (ei_debug > 4)
 347             printk("%s: 3c503 block_input() @ %#5x+%x=%5x.\n",
 348                    dev->name, dev->mem_start, ring_offset,
 349                    (char *)dev->mem_start + ring_offset);
 350         memcpy(buf, (char *)dev->mem_start + ring_offset, count);
 351         return ring_offset + count;
 352     }
 353     /* No shared memory, use programmed I/O. */
 354     outb(ring_offset & 0xff, E33G_DMAAL);
 355     outb_p((ring_offset >> 8) & 0xff, E33G_DMAAH);
 356     outb_p((ei_status.interface_num == 0 ? ECNTRL_THIN : ECNTRL_AUI) | ECNTRL_INPUT
 357            | ECNTRL_START, E33G_CNTRL);
 358 
 359     /* This is the byte copy loop: it should probably be tuned for
 360        for speed once everything is working. */
 361     for(i = 0; i < count; i++) {
 362         if (i % 8 == 0)
 363             while ((inb(E33G_STATUS) & ESTAT_DPRDY) == 0)
 364                 if (++boguscount > (i<<3) + 32) {
 365                     printk("%s: FIFO blocked in el2_block_input() (at %d of %d, bc=%d).\n",
 366                            dev->name, i, count, boguscount);
 367                     boguscount = 0;
 368                     break;
 369                 }
 370         buf[i] = inb_p(E33G_FIFOH);
 371     }
 372     outb_p(ei_status.interface_num == 0 ? ECNTRL_THIN : ECNTRL_AUI, E33G_CNTRL);
 373     return 0;
 374 }
 375 
 376 /*
 377  * Local variables:
 378  *  compile-command: "gcc -DKERNEL -Wall -O6 -fomit-frame-pointer -I/usr/src/linux/net/tcp -c 3c503.c"
 379  *  version-control: t
 380  *  kept-new-versions: 5
 381  * End:
 382  */

/* [previous][next][first][last][top][bottom][index][help] */