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

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