root/drivers/net/ne.c

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

DEFINITIONS

This source file includes following definitions.
  1. ne_probe
  2. ne_probe1
  3. ne_reset_8390
  4. ne_block_input
  5. ne_block_output

   1 /* ne.c: A general non-shared-memory NS8390 ethernet driver for linux. */
   2 /*
   3     Written 1992-94 by Donald Becker.
   4 
   5     Copyright 1993 United States Government as represented by the
   6     Director, National Security Agency.
   7 
   8     This software may be used and distributed according to the terms
   9     of the GNU Public License, incorporated herein by reference.
  10 
  11     The author may be reached as becker@CESDIS.gsfc.nasa.gov, or C/O
  12     Center of Excellence in Space Data and Information Sciences
  13         Code 930.5, Goddard Space Flight Center, Greenbelt MD 20771
  14 
  15     This driver should work with many programmed-I/O 8390-based ethernet
  16     boards.  Currently it support the NE1000, NE2000, many clones,
  17     and some Cabletron products.
  18 */
  19 
  20 /* Routines for the NatSemi-based designs (NE[12]000). */
  21 
  22 static char *version =
  23     "ne.c:v1.10 9/23/94 Donald Becker (becker@cesdis.gsfc.nasa.gov)\n";
  24 
  25 #include <linux/config.h>
  26 #include <linux/kernel.h>
  27 #include <linux/sched.h>
  28 #include <linux/errno.h>
  29 #include <asm/system.h>
  30 #include <asm/io.h>
  31 
  32 #include <linux/netdevice.h>
  33 #include "8390.h"
  34 extern struct device *init_etherdev(struct device *dev, int sizeof_private,
  35                                     unsigned long *mem_startp);
  36 
  37 
  38 /* A zero-terminated list of I/O addresses to be probed. */
  39 static unsigned int netcard_portlist[] =
  40 { 0x300, 0x280, 0x320, 0x340, 0x360, 0};
  41 
  42 /* A list of bad clones that we none-the-less recognize. */
  43 static struct { char *name8, *name16; unsigned char SAprefix[4];}
  44 bad_clone_list[] = {
  45     {"DE100", "DE200", {0x00, 0xDE, 0x01,}},
  46     {"DE120", "DE220", {0x00, 0x80, 0xc8,}},
  47     {"DFI1000", "DFI2000", {'D', 'F', 'I',}}, /* Original, eh?  */
  48     {0,}
  49 };
  50 
  51 #define NE_BASE  (dev->base_addr)
  52 #define NE_CMD          0x00
  53 #define NE_DATAPORT     0x10    /* NatSemi-defined port window offset. */
  54 #define NE_RESET        0x1f    /* Issue a read to reset, a write to clear. */
  55 #define NE_IO_EXTENT    0x20
  56 
  57 #define NE1SM_START_PG  0x20    /* First page of TX buffer */
  58 #define NE1SM_STOP_PG   0x40    /* Last page +1 of RX ring */
  59 #define NESM_START_PG   0x40    /* First page of TX buffer */
  60 #define NESM_STOP_PG    0x80    /* Last page +1 of RX ring */
  61 
  62 int ne_probe(struct device *dev);
  63 static int ne_probe1(struct device *dev, int ioaddr);
  64 
  65 static void ne_reset_8390(struct device *dev);
  66 static int ne_block_input(struct device *dev, int count,
  67                           char *buf, int ring_offset);
  68 static void ne_block_output(struct device *dev, const int count,
  69                 const unsigned char *buf, const int start_page);
  70 
  71 
  72 /*  Probe for various non-shared-memory ethercards.
  73 
  74    NEx000-clone boards have a Station Address PROM (SAPROM) in the packet
  75    buffer memory space.  NE2000 clones have 0x57,0x57 in bytes 0x0e,0x0f of
  76    the SAPROM, while other supposed NE2000 clones must be detected by their
  77    SA prefix.
  78 
  79    Reading the SAPROM from a word-wide card with the 8390 set in byte-wide
  80    mode results in doubled values, which can be detected and compensated for.
  81 
  82    The probe is also responsible for initializing the card and filling
  83    in the 'dev' and 'ei_status' structures.
  84 
  85    We use the minimum memory size for some ethercard product lines, iff we can't
  86    distinguish models.  You can increase the packet buffer size by setting
  87    PACKETBUF_MEMSIZE.  Reported Cabletron packet buffer locations are:
  88         E1010   starts at 0x100 and ends at 0x2000.
  89         E1010-x starts at 0x100 and ends at 0x8000. ("-x" means "more memory")
  90         E2010    starts at 0x100 and ends at 0x4000.
  91         E2010-x starts at 0x100 and ends at 0xffff.  */
  92 
  93 #ifdef HAVE_DEVLIST
  94 struct netdev_entry netcard_drv =
  95 {"ne", ne_probe1, NE_IO_EXTENT, netcard_portlist};
  96 #else
  97 
  98 int ne_probe(struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
  99 {
 100     int i;
 101     int base_addr = dev ? dev->base_addr : 0;
 102 
 103     if (base_addr > 0x1ff)      /* Check a single specified location. */
 104         return ne_probe1(dev, base_addr);
 105     else if (base_addr != 0)    /* Don't probe at all. */
 106         return ENXIO;
 107 
 108     for (i = 0; netcard_portlist[i]; i++) {
 109         int ioaddr = netcard_portlist[i];
 110         if (check_region(ioaddr, NE_IO_EXTENT))
 111             continue;
 112         if (ne_probe1(dev, ioaddr) == 0)
 113             return 0;
 114     }
 115 
 116     return ENODEV;
 117 }
 118 #endif
 119 
 120 static int ne_probe1(struct device *dev, int ioaddr)
     /* [previous][next][first][last][top][bottom][index][help] */
 121 {
 122     int i;
 123     unsigned char SA_prom[32];
 124     int wordlength = 2;
 125     char *name = NULL;
 126     int start_page, stop_page;
 127     int neX000, ctron;
 128     int reg0 = inb(ioaddr);
 129 
 130     if ( reg0 == 0xFF)
 131         return ENODEV;
 132 
 133     /* Do a preliminary verification that we have a 8390. */
 134     {   int regd;
 135         outb_p(E8390_NODMA+E8390_PAGE1+E8390_STOP, ioaddr + E8390_CMD);
 136         regd = inb_p(ioaddr + 0x0d);
 137         outb_p(0xff, ioaddr + 0x0d);
 138         outb_p(E8390_NODMA+E8390_PAGE0, ioaddr + E8390_CMD);
 139         inb_p(ioaddr + EN0_COUNTER0); /* Clear the counter by reading. */
 140         if (inb_p(ioaddr + EN0_COUNTER0) != 0) {
 141             outb_p(reg0, ioaddr);
 142             outb(regd, ioaddr + 0x0d);  /* Restore the old values. */
 143             return ENODEV;
 144         }
 145     }
 146 
 147     printk("NE*000 ethercard probe at %#3x:", ioaddr);
 148 
 149     /* Read the 16 bytes of station address PROM.
 150        We must first initialize registers, similar to NS8390_init(eifdev, 0).
 151        We can't reliably read the SAPROM address without this.
 152        (I learned the hard way!). */
 153     {
 154         struct {unsigned char value, offset; } program_seq[] = {
 155             {E8390_NODMA+E8390_PAGE0+E8390_STOP, E8390_CMD}, /* Select page 0*/
 156             {0x48,      EN0_DCFG},      /* Set byte-wide (0x48) access. */
 157             {0x00,      EN0_RCNTLO},    /* Clear the count regs. */
 158             {0x00,      EN0_RCNTHI},
 159             {0x00,      EN0_IMR},       /* Mask completion irq. */
 160             {0xFF,      EN0_ISR},
 161             {E8390_RXOFF, EN0_RXCR},    /* 0x20  Set to monitor */
 162             {E8390_TXOFF, EN0_TXCR},    /* 0x02  and loopback mode. */
 163             {32,        EN0_RCNTLO},
 164             {0x00,      EN0_RCNTHI},
 165             {0x00,      EN0_RSARLO},    /* DMA starting at 0x0000. */
 166             {0x00,      EN0_RSARHI},
 167             {E8390_RREAD+E8390_START, E8390_CMD},
 168         };
 169         for (i = 0; i < sizeof(program_seq)/sizeof(program_seq[0]); i++)
 170             outb_p(program_seq[i].value, ioaddr + program_seq[i].offset);
 171     }
 172     for(i = 0; i < 32 /*sizeof(SA_prom)*/; i+=2) {
 173         SA_prom[i] = inb(ioaddr + NE_DATAPORT);
 174         SA_prom[i+1] = inb(ioaddr + NE_DATAPORT);
 175         if (SA_prom[i] != SA_prom[i+1])
 176             wordlength = 1;
 177     }
 178 
 179     if (wordlength == 2) {
 180         /* We must set the 8390 for word mode. */
 181         outb_p(0x49, ioaddr + EN0_DCFG);
 182         /* We used to reset the ethercard here, but it doesn't seem
 183            to be necessary. */
 184         /* Un-double the SA_prom values. */
 185         for (i = 0; i < 16; i++)
 186             SA_prom[i] = SA_prom[i+i];
 187         start_page = NESM_START_PG;
 188         stop_page = NESM_STOP_PG;
 189     } else {
 190         start_page = NE1SM_START_PG;
 191         stop_page = NE1SM_STOP_PG;
 192     }
 193 
 194     for(i = 0; i < ETHER_ADDR_LEN; i++) {
 195         dev->dev_addr[i] = SA_prom[i];
 196         printk(" %2.2x", SA_prom[i]);
 197     }
 198 
 199     neX000 = (SA_prom[14] == 0x57  &&  SA_prom[15] == 0x57);
 200     ctron =  (SA_prom[0] == 0x00 && SA_prom[1] == 0x00 && SA_prom[2] == 0x1d);
 201 
 202     /* Set up the rest of the parameters. */
 203     if (neX000) {
 204         name = (wordlength == 2) ? "NE2000" : "NE1000";
 205     } else if (ctron) {
 206         name = "Cabletron";
 207         start_page = 0x01;
 208         stop_page = (wordlength == 2) ? 0x40 : 0x20;
 209     } else {
 210         /* Ack!  Well, there might be a *bad* NE*000 clone there.
 211            Check for total bogus addresses. */
 212         for (i = 0; bad_clone_list[i].name8; i++) {
 213             if (SA_prom[0] == bad_clone_list[i].SAprefix[0] &&
 214                 SA_prom[1] == bad_clone_list[i].SAprefix[1] &&
 215                 SA_prom[2] == bad_clone_list[i].SAprefix[2]) {
 216                 if (wordlength == 2) {
 217                     name = bad_clone_list[i].name16;
 218                 } else {
 219                     name = bad_clone_list[i].name8;
 220                 }
 221                 break;
 222             }
 223         }
 224         if (bad_clone_list[i].name8 == NULL) {
 225             printk(" not found (invalid signature %2.2x %2.2x).\n",
 226                    SA_prom[14], SA_prom[15]);
 227             return ENXIO;
 228         }
 229     }
 230 
 231 
 232     if (dev == NULL)
 233         dev = init_etherdev(0, sizeof(struct ei_device), 0);
 234 
 235     if (dev->irq < 2) {
 236         autoirq_setup(0);
 237         outb_p(0x50, ioaddr + EN0_IMR); /* Enable one interrupt. */
 238         outb_p(0x00, ioaddr + EN0_RCNTLO);
 239         outb_p(0x00, ioaddr + EN0_RCNTHI);
 240         outb_p(E8390_RREAD+E8390_START, ioaddr); /* Trigger it... */
 241         outb_p(0x00, ioaddr + EN0_IMR);                 /* Mask it again. */
 242         dev->irq = autoirq_report(0);
 243         if (ei_debug > 2)
 244             printk(" autoirq is %d", dev->irq);
 245     } else if (dev->irq == 2)
 246         /* Fixup for users that don't know that IRQ 2 is really IRQ 9,
 247            or don't know which one to set. */
 248         dev->irq = 9;
 249     
 250     /* Snarf the interrupt now.  There's no point in waiting since we cannot
 251        share and the board will usually be enabled. */
 252     {
 253         int irqval = request_irq (dev->irq, ei_interrupt, 0, "ne");
 254         if (irqval) {
 255             printk (" unable to get IRQ %d (irqval=%d).\n", dev->irq, irqval);
 256             return EAGAIN;
 257         }
 258     }
 259 
 260     dev->base_addr = ioaddr;
 261 
 262     snarf_region(ioaddr, NE_IO_EXTENT);
 263 
 264     for(i = 0; i < ETHER_ADDR_LEN; i++)
 265         dev->dev_addr[i] = SA_prom[i];
 266 
 267     ethdev_init(dev);
 268     printk("\n%s: %s found at %#x, using IRQ %d.\n",
 269            dev->name, name, ioaddr, dev->irq);
 270 
 271     if (ei_debug > 0)
 272         printk(version);
 273 
 274     ei_status.name = name;
 275     ei_status.tx_start_page = start_page;
 276     ei_status.stop_page = stop_page;
 277     ei_status.word16 = (wordlength == 2);
 278 
 279     ei_status.rx_start_page = start_page + TX_PAGES;
 280 #ifdef PACKETBUF_MEMSIZE
 281     /* Allow the packet buffer size to be overridden by know-it-alls. */
 282     ei_status.stop_page = ei_status.tx_start_page + PACKETBUF_MEMSIZE;
 283 #endif
 284 
 285     ei_status.reset_8390 = &ne_reset_8390;
 286     ei_status.block_input = &ne_block_input;
 287     ei_status.block_output = &ne_block_output;
 288     NS8390_init(dev, 0);
 289     return 0;
 290 }
 291 
 292 /* Hard reset the card.  This used to pause for the same period that a
 293    8390 reset command required, but that shouldn't be necessary. */
 294 static void
 295 ne_reset_8390(struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 296 {
 297     int tmp = inb_p(NE_BASE + NE_RESET);
 298     int reset_start_time = jiffies;
 299 
 300     if (ei_debug > 1) printk("resetting the 8390 t=%ld...", jiffies);
 301     ei_status.txing = 0;
 302 
 303     outb_p(tmp, NE_BASE + NE_RESET);
 304     /* This check _should_not_ be necessary, omit eventually. */
 305     while ((inb_p(NE_BASE+EN0_ISR) & ENISR_RESET) == 0)
 306         if (jiffies - reset_start_time > 2) {
 307             printk("%s: ne_reset_8390() did not complete.\n", dev->name);
 308             break;
 309         }
 310 }
 311 
 312 /* Block input and output, similar to the Crynwr packet driver.  If you
 313    porting to a new ethercard look at the packet driver source for hints.
 314    The NEx000 doesn't share it on-board packet memory -- you have to put
 315    the packet out through the "remote DMA" dataport using outb. */
 316 
 317 static int
 318 ne_block_input(struct device *dev, int count, char *buf, int ring_offset)
     /* [previous][next][first][last][top][bottom][index][help] */
 319 {
 320     int xfer_count = count;
 321     int nic_base = dev->base_addr;
 322 
 323     if (ei_status.dmaing) {
 324         if (ei_debug > 0)
 325             printk("%s: DMAing conflict in ne_block_input "
 326                    "[DMAstat:%d][irqlock:%d][intr:%d].\n",
 327                    dev->name, ei_status.dmaing, ei_status.irqlock,
 328                    dev->interrupt);
 329         return 0;
 330     }
 331     ei_status.dmaing |= 0x01;
 332     outb_p(E8390_NODMA+E8390_PAGE0+E8390_START, nic_base+ NE_CMD);
 333     outb_p(count & 0xff, nic_base + EN0_RCNTLO);
 334     outb_p(count >> 8, nic_base + EN0_RCNTHI);
 335     outb_p(ring_offset & 0xff, nic_base + EN0_RSARLO);
 336     outb_p(ring_offset >> 8, nic_base + EN0_RSARHI);
 337     outb_p(E8390_RREAD+E8390_START, nic_base + NE_CMD);
 338     if (ei_status.word16) {
 339       insw(NE_BASE + NE_DATAPORT,buf,count>>1);
 340       if (count & 0x01)
 341         buf[count-1] = inb(NE_BASE + NE_DATAPORT), xfer_count++;
 342     } else {
 343         insb(NE_BASE + NE_DATAPORT, buf, count);
 344     }
 345 
 346     /* This was for the ALPHA version only, but enough people have
 347        encountering problems that it is still here.  If you see
 348        this message you either 1) have a slightly incompatible clone
 349        or 2) have noise/speed problems with your bus. */
 350     if (ei_debug > 1) {         /* DMA termination address check... */
 351         int addr, tries = 20;
 352         do {
 353             /* DON'T check for 'inb_p(EN0_ISR) & ENISR_RDC' here
 354                -- it's broken! Check the "DMA" address instead. */
 355             int high = inb_p(nic_base + EN0_RSARHI);
 356             int low = inb_p(nic_base + EN0_RSARLO);
 357             addr = (high << 8) + low;
 358             if (((ring_offset + xfer_count) & 0xff) == low)
 359                 break;
 360         } while (--tries > 0);
 361         if (tries <= 0)
 362             printk("%s: RX transfer address mismatch,"
 363                    "%#4.4x (expected) vs. %#4.4x (actual).\n",
 364                    dev->name, ring_offset + xfer_count, addr);
 365     }
 366     ei_status.dmaing &= ~0x01;
 367     return ring_offset + count;
 368 }
 369 
 370 static void
 371 ne_block_output(struct device *dev, int count,
     /* [previous][next][first][last][top][bottom][index][help] */
 372                 const unsigned char *buf, const int start_page)
 373 {
 374     int retries = 0;
 375     int nic_base = NE_BASE;
 376 
 377     /* Round the count up for word writes.  Do we need to do this?
 378        What effect will an odd byte count have on the 8390?
 379        I should check someday. */
 380     if (ei_status.word16 && (count & 0x01))
 381       count++;
 382     if (ei_status.dmaing) {
 383         if (ei_debug > 0)
 384             printk("%s: DMAing conflict in ne_block_output."
 385                    "[DMAstat:%d][irqlock:%d][intr:%d]\n",
 386                    dev->name, ei_status.dmaing, ei_status.irqlock,
 387                    dev->interrupt);
 388         return;
 389     }
 390     ei_status.dmaing |= 0x02;
 391     /* We should already be in page 0, but to be safe... */
 392     outb_p(E8390_PAGE0+E8390_START+E8390_NODMA, nic_base + NE_CMD);
 393 
 394  retry:
 395 #if defined(rw_bugfix)
 396     /* Handle the read-before-write bug the same way as the
 397        Crynwr packet driver -- the NatSemi method doesn't work.
 398        Actually this doesn't always work either, but if you have
 399        problems with your NEx000 this is better than nothing! */
 400     outb_p(0x42, nic_base + EN0_RCNTLO);
 401     outb_p(0x00,   nic_base + EN0_RCNTHI);
 402     outb_p(0x42, nic_base + EN0_RSARLO);
 403     outb_p(0x00, nic_base + EN0_RSARHI);
 404     outb_p(E8390_RREAD+E8390_START, nic_base + NE_CMD);
 405     /* Make certain that the dummy read has occured. */
 406     SLOW_DOWN_IO;
 407     SLOW_DOWN_IO;
 408     SLOW_DOWN_IO;
 409 #endif  /* rw_bugfix */
 410 
 411     /* Now the normal output. */
 412     outb_p(count & 0xff, nic_base + EN0_RCNTLO);
 413     outb_p(count >> 8,   nic_base + EN0_RCNTHI);
 414     outb_p(0x00, nic_base + EN0_RSARLO);
 415     outb_p(start_page, nic_base + EN0_RSARHI);
 416 
 417     outb_p(E8390_RWRITE+E8390_START, nic_base + NE_CMD);
 418     if (ei_status.word16) {
 419         outsw(NE_BASE + NE_DATAPORT, buf, count>>1);
 420     } else {
 421         outsb(NE_BASE + NE_DATAPORT, buf, count);
 422     }
 423 
 424     /* This was for the ALPHA version only, but enough people have
 425        encountering problems that it is still here. */
 426     if (ei_debug > 1) {         /* DMA termination address check... */
 427         int addr, tries = 20;
 428         do {
 429             /* DON'T check for 'inb_p(EN0_ISR) & ENISR_RDC' here
 430                -- it's broken! Check the "DMA" address instead. */
 431             int high = inb_p(nic_base + EN0_RSARHI);
 432             int low = inb_p(nic_base + EN0_RSARLO);
 433             addr = (high << 8) + low;
 434             if ((start_page << 8) + count == addr)
 435                 break;
 436         } while (--tries > 0);
 437         if (tries <= 0) {
 438             printk("%s: Tx packet transfer address mismatch,"
 439                    "%#4.4x (expected) vs. %#4.4x (actual).\n",
 440                    dev->name, (start_page << 8) + count, addr);
 441             if (retries++ == 0)
 442                 goto retry;
 443         }
 444     }
 445     ei_status.dmaing &= ~0x02;
 446     return;
 447 }
 448 
 449 
 450 /*
 451  * Local variables:
 452  *  compile-command: "gcc -DKERNEL -Wall -O6 -fomit-frame-pointer -I/usr/src/linux/net/tcp -c ne.c"
 453  *  version-control: t
 454  *  kept-new-versions: 5
 455  * End:
 456  */

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