root/net/inet/ne.c

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

DEFINITIONS

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

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