This source file includes following definitions.
- ne_probe
 
- neprobe1
 
- ne_reset_8390
 
- ne_block_input
 
- ne_block_output
 
   1 
   2 
   3 
   4 
   5 
   6 
   7 
   8 
   9 
  10 
  11 
  12 
  13 
  14 
  15 
  16 
  17 
  18 
  19 static char *version =
  20     "ne.c:v0.99-15k 3/3/94 Donald Becker (becker@super.org)\n";
  21 
  22 #include <linux/config.h>
  23 #include <linux/kernel.h>
  24 #include <linux/sched.h>
  25 #include <linux/errno.h>
  26 #include <asm/system.h>
  27 #include <asm/io.h>
  28 
  29 #include <linux/netdevice.h>
  30 #include "8390.h"
  31 
  32 #define NE_BASE  (dev->base_addr)
  33 #define NE_CMD          0x00
  34 #define NE_DATAPORT     0x10    
  35 #define NE_RESET        0x1f    
  36 
  37 #define NE1SM_START_PG  0x20    
  38 #define NE1SM_STOP_PG   0x40    
  39 #define NESM_START_PG   0x40    
  40 #define NESM_STOP_PG    0x80    
  41 
  42 int ne_probe(struct device *dev);
  43 static int neprobe1(int ioaddr, struct device *dev, int verbose);
  44 
  45 static void ne_reset_8390(struct device *dev);
  46 static int ne_block_input(struct device *dev, int count,
  47                           char *buf, int ring_offset);
  48 static void ne_block_output(struct device *dev, const int count,
  49                 const unsigned char *buf, const int start_page);
  50 
  51 
  52 
  53 
  54 
  55 
  56 
  57 
  58 
  59 
  60 
  61 
  62 
  63 
  64 
  65 
  66 
  67 
  68 
  69 
  70 
  71 
  72 
  73 int ne_probe(struct device *dev)
     
  74 {
  75     int *port, ports[] = {0x300, 0x280, 0x320, 0x340, 0x360, 0};
  76     short ioaddr = dev->base_addr;
  77 
  78     if (ioaddr < 0)
  79         return ENXIO;           
  80     if (ioaddr > 0x100)
  81         return ! neprobe1(ioaddr, dev, 1);
  82 
  83     for (port = &ports[0]; *port; port++) {
  84 #ifdef HAVE_PORTRESERVE
  85         if (check_region(*port, 32))
  86             continue;
  87 #endif
  88         if (inb_p(*port) != 0xff && neprobe1(*port, dev, 0)) {
  89             dev->base_addr = *port;
  90             return 0;
  91         }
  92     }
  93     dev->base_addr = ioaddr;
  94     return ENODEV;
  95 }
  96 
  97 static int neprobe1(int ioaddr, struct device *dev, int verbose)
     
  98 {
  99     int i;
 100     unsigned char SA_prom[32];
 101     int wordlength = 2;
 102     char *name;
 103     int start_page, stop_page;
 104     int neX000, ctron, dlink, dfi;
 105     int reg0 = inb(ioaddr);
 106 
 107     if ( reg0 == 0xFF)
 108         return 0;
 109 
 110     
 111     {   int regd;
 112         outb_p(E8390_NODMA+E8390_PAGE1+E8390_STOP, ioaddr + E8390_CMD);
 113         regd = inb_p(ioaddr + 0x0d);
 114         outb_p(0xff, ioaddr + 0x0d);
 115         outb_p(E8390_NODMA+E8390_PAGE0, ioaddr + E8390_CMD);
 116         inb_p(ioaddr + EN0_COUNTER0); 
 117         if (inb_p(ioaddr + EN0_COUNTER0) != 0) {
 118             outb_p(reg0, ioaddr);
 119             outb(regd, ioaddr + 0x0d);  
 120             return 0;
 121         }
 122     }
 123 
 124     printk("NE*000 ethercard probe at %#3x:", ioaddr);
 125 
 126     
 127 
 128 
 129 
 130 
 131     {
 132         struct {unsigned char value, offset; } program_seq[] = {
 133             {E8390_NODMA+E8390_PAGE0+E8390_STOP, E8390_CMD}, 
 134             {0x48,      EN0_DCFG},      
 135             {0x00,      EN0_RCNTLO},    
 136             {0x00,      EN0_RCNTHI},
 137             {0x00,      EN0_IMR},       
 138             {0xFF,      EN0_ISR},
 139             {E8390_RXOFF, EN0_RXCR},    
 140             {E8390_TXOFF, EN0_TXCR},    
 141             {32,        EN0_RCNTLO},
 142             {0x00,      EN0_RCNTHI},
 143             {0x00,      EN0_RSARLO},    
 144             {0x00,      EN0_RSARHI},
 145             {E8390_RREAD+E8390_START, E8390_CMD},
 146         };
 147         for (i = 0; i < sizeof(program_seq)/sizeof(program_seq[0]); i++)
 148             outb_p(program_seq[i].value, ioaddr + program_seq[i].offset);
 149     }
 150     for(i = 0; i < 32 ; i+=2) {
 151         SA_prom[i] = inb(ioaddr + NE_DATAPORT);
 152         SA_prom[i+1] = inb(ioaddr + NE_DATAPORT);
 153         if (SA_prom[i] != SA_prom[i+1])
 154             wordlength = 1;
 155     }
 156 
 157     if (wordlength == 2) {
 158         
 159         outb_p(0x49, ioaddr + EN0_DCFG);
 160         
 161 
 162         
 163         for (i = 0; i < 16; i++)
 164             SA_prom[i] = SA_prom[i+i];
 165     }
 166 
 167 #if defined(show_all_SAPROM)
 168     
 169     for(i = 0; i < sizeof(SA_prom); i++)
 170         printk(" %2.2x", SA_prom[i]);
 171 #else
 172     for(i = 0; i < ETHER_ADDR_LEN; i++) {
 173         dev->dev_addr[i] = SA_prom[i];
 174         printk(" %2.2x", SA_prom[i]);
 175     }
 176 #endif
 177 
 178     neX000 = (SA_prom[14] == 0x57  &&  SA_prom[15] == 0x57);
 179     ctron =  (SA_prom[0] == 0x00 && SA_prom[1] == 0x00 && SA_prom[2] == 0x1d);
 180     dlink =  (SA_prom[0] == 0x00 && SA_prom[1] == 0xDE && SA_prom[2] == 0x01);
 181     dfi   =  (SA_prom[0] == 'D' && SA_prom[1] == 'F' && SA_prom[2] == 'I');
 182 
 183     
 184     if (neX000 || dlink || dfi) {
 185         if (wordlength == 2) {
 186             name = dlink ? "DE200" : "NE2000";
 187             start_page = NESM_START_PG;
 188             stop_page = NESM_STOP_PG;
 189         } else {
 190             name = dlink ? "DE100" : "NE1000";
 191             start_page = NE1SM_START_PG;
 192             stop_page = NE1SM_STOP_PG;
 193         }
 194     } else if (ctron) {
 195         name = "Cabletron";
 196         start_page = 0x01;
 197         stop_page = (wordlength == 2) ? 0x40 : 0x20;
 198     } else {
 199         printk(" not found.\n");
 200         return 0;
 201     }
 202 
 203     if (dev->irq < 2) {
 204         autoirq_setup(0);
 205         outb_p(0x50, ioaddr + EN0_IMR); 
 206         outb_p(0x00, ioaddr + EN0_RCNTLO);
 207         outb_p(0x00, ioaddr + EN0_RCNTHI);
 208         outb_p(E8390_RREAD+E8390_START, ioaddr); 
 209         outb_p(0x00, ioaddr + EN0_IMR);                 
 210         dev->irq = autoirq_report(0);
 211         if (ei_debug > 2)
 212             printk(" autoirq is %d", dev->irq);
 213     } else if (dev->irq == 2)
 214         
 215 
 216         dev->irq = 9;
 217     
 218     
 219 
 220     {
 221         int irqval = irqaction (dev->irq, &ei_sigaction);
 222         if (irqval) {
 223             printk (" unable to get IRQ %d (irqval=%d).\n", dev->irq, irqval);
 224             return 0;
 225         }
 226     }
 227 
 228     dev->base_addr = ioaddr;
 229 
 230 #ifdef HAVE_PORTRESERVE
 231     snarf_region(ioaddr, 32);
 232 #endif
 233 
 234     ethdev_init(dev);
 235     printk("\n%s: %s found at %#x, using IRQ %d.\n",
 236            dev->name, name, ioaddr, dev->irq);
 237 
 238     if (ei_debug > 0)
 239         printk(version);
 240 
 241     ei_status.name = name;
 242     ei_status.tx_start_page = start_page;
 243     ei_status.stop_page = stop_page;
 244     ei_status.word16 = (wordlength == 2);
 245 
 246     ei_status.rx_start_page = start_page + TX_PAGES;
 247 #ifdef PACKETBUF_MEMSIZE
 248     
 249     ei_status.stop_page = ei_status.tx_start_page + PACKETBUF_MEMSIZE;
 250 #endif
 251 
 252     ei_status.reset_8390 = &ne_reset_8390;
 253     ei_status.block_input = &ne_block_input;
 254     ei_status.block_output = &ne_block_output;
 255     NS8390_init(dev, 0);
 256     return dev->base_addr;
 257 }
 258 
 259 
 260 
 261 static void
 262 ne_reset_8390(struct device *dev)
     
 263 {
 264     int tmp = inb_p(NE_BASE + NE_RESET);
 265     int reset_start_time = jiffies;
 266 
 267     if (ei_debug > 1) printk("resetting the 8390 t=%ld...", jiffies);
 268     ei_status.txing = 0;
 269 
 270     outb_p(tmp, NE_BASE + NE_RESET);
 271     
 272     while ((inb_p(NE_BASE+EN0_ISR) & ENISR_RESET) == 0)
 273         if (jiffies - reset_start_time > 2) {
 274             printk("%s: ne_reset_8390() did not complete.\n", dev->name);
 275             break;
 276         }
 277 }
 278 
 279 
 280 
 281 
 282 
 283 
 284 static int
 285 ne_block_input(struct device *dev, int count, char *buf, int ring_offset)
     
 286 {
 287     int xfer_count = count;
 288     int nic_base = dev->base_addr;
 289 
 290     if (ei_status.dmaing) {
 291         if (ei_debug > 0)
 292             printk("%s: DMAing conflict in ne_block_input."
 293                    "[DMAstat:%1x][irqlock:%1x]\n",
 294                    dev->name, ei_status.dmaing, ei_status.irqlock);
 295         return 0;
 296     }
 297     ei_status.dmaing |= 0x01;
 298     outb_p(E8390_NODMA+E8390_PAGE0+E8390_START, nic_base+ NE_CMD);
 299     outb_p(count & 0xff, nic_base + EN0_RCNTLO);
 300     outb_p(count >> 8, nic_base + EN0_RCNTHI);
 301     outb_p(ring_offset & 0xff, nic_base + EN0_RSARLO);
 302     outb_p(ring_offset >> 8, nic_base + EN0_RSARHI);
 303     outb_p(E8390_RREAD+E8390_START, nic_base + NE_CMD);
 304     if (ei_status.word16) {
 305       insw(NE_BASE + NE_DATAPORT,buf,count>>1);
 306       if (count & 0x01)
 307         buf[count-1] = inb(NE_BASE + NE_DATAPORT), xfer_count++;
 308     } else {
 309         insb(NE_BASE + NE_DATAPORT, buf, count);
 310     }
 311 
 312     
 313 
 314 
 315 
 316     if (ei_debug > 1) {         
 317         int addr, tries = 20;
 318         do {
 319             
 320 
 321             int high = inb_p(nic_base + EN0_RSARHI);
 322             int low = inb_p(nic_base + EN0_RSARLO);
 323             addr = (high << 8) + low;
 324             if (((ring_offset + xfer_count) & 0xff) == low)
 325                 break;
 326         } while (--tries > 0);
 327         if (tries <= 0)
 328             printk("%s: RX transfer address mismatch,"
 329                    "%#4.4x (expected) vs. %#4.4x (actual).\n",
 330                    dev->name, ring_offset + xfer_count, addr);
 331     }
 332     ei_status.dmaing &= ~0x01;
 333     return ring_offset + count;
 334 }
 335 
 336 static void
 337 ne_block_output(struct device *dev, int count,
     
 338                 const unsigned char *buf, const int start_page)
 339 {
 340     int retries = 0;
 341     int nic_base = NE_BASE;
 342 
 343     
 344 
 345 
 346     if (ei_status.word16 && (count & 0x01))
 347       count++;
 348     if (ei_status.dmaing) {
 349         if (ei_debug > 0)
 350             printk("%s: DMAing conflict in ne_block_output."
 351                    "[DMAstat:%1x][irqlock:%1x]\n",
 352                    dev->name, ei_status.dmaing, ei_status.irqlock);
 353         return;
 354     }
 355     ei_status.dmaing |= 0x02;
 356     
 357     outb_p(E8390_PAGE0+E8390_START+E8390_NODMA, nic_base + NE_CMD);
 358 
 359  retry:
 360 #if defined(rw_bugfix)
 361     
 362 
 363 
 364 
 365     outb_p(0x42, nic_base + EN0_RCNTLO);
 366     outb_p(0x00,   nic_base + EN0_RCNTHI);
 367     outb_p(0x42, nic_base + EN0_RSARLO);
 368     outb_p(0x00, nic_base + EN0_RSARHI);
 369     outb_p(E8390_RREAD+E8390_START, nic_base + NE_CMD);
 370     
 371     SLOW_DOWN_IO;
 372     SLOW_DOWN_IO;
 373     SLOW_DOWN_IO;
 374 #endif  
 375 
 376     
 377     outb_p(count & 0xff, nic_base + EN0_RCNTLO);
 378     outb_p(count >> 8,   nic_base + EN0_RCNTHI);
 379     outb_p(0x00, nic_base + EN0_RSARLO);
 380     outb_p(start_page, nic_base + EN0_RSARHI);
 381 
 382     outb_p(E8390_RWRITE+E8390_START, nic_base + NE_CMD);
 383     if (ei_status.word16) {
 384         outsw(NE_BASE + NE_DATAPORT, buf, count>>1);
 385     } else {
 386         outsb(NE_BASE + NE_DATAPORT, buf, count);
 387     }
 388 
 389     
 390 
 391     if (ei_debug > 1) {         
 392         int addr, tries = 20;
 393         do {
 394             
 395 
 396             int high = inb_p(nic_base + EN0_RSARHI);
 397             int low = inb_p(nic_base + EN0_RSARLO);
 398             addr = (high << 8) + low;
 399             if ((start_page << 8) + count == addr)
 400                 break;
 401         } while (--tries > 0);
 402         if (tries <= 0) {
 403             printk("%s: Tx packet transfer address mismatch,"
 404                    "%#4.4x (expected) vs. %#4.4x (actual).\n",
 405                    dev->name, (start_page << 8) + count, addr);
 406             if (retries++ == 0)
 407                 goto retry;
 408         }
 409     }
 410     ei_status.dmaing &= ~0x02;
 411     return;
 412 }
 413 
 414 
 415 
 416 
 417 
 418 
 419 
 420 
 421