root/drivers/net/ni52.c

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

DEFINITIONS

This source file includes following definitions.
  1. ni52_close
  2. ni52_open
  3. check586
  4. alloc586
  5. ni52_probe
  6. ni52_probe1
  7. init586
  8. alloc_rfa
  9. ni52_interrupt
  10. ni52_rcv_int
  11. ni52_rnr_int
  12. ni52_xmt_int
  13. startrecv586
  14. ni52_send_packet
  15. ni52_get_stats
  16. set_multicast_list

   1 /* 
   2  * net-3-driver for the NI5210 card (i82586 Ethernet chip)
   3  *
   4  * This is an extension to the Linux operating system, and is covered by the
   5  * same Gnu Public License that covers that work.
   6  * 
   7  * Alphacode 0.62 (95/01/19) for Linux 1.1.82 (or later)
   8  * Copyrights (c) 1994,1995 by M.Hipp (Michael.Hipp@student.uni-tuebingen.de)
   9  *    [feel free to mail ....]
  10  *
  11  * CAN YOU PLEASE REPORT ME YOUR PERFORMANCE EXPERIENCES !!.
  12  * 
  13  * If you find a bug, please report me:
  14  *   The kernel panic output and any kmsg from the ni52 driver
  15  *   the ni5210-driver-version and the linux-kernel version 
  16  *   how many shared memory (memsize) on the netcard, 
  17  *   bootprom: yes/no, base_addr, mem_start
  18  *   maybe the ni5210-card revision and the i82586 version
  19  *
  20  * autoprobe for: base_addr: 0x300,0x280,0x360,0x320,0x340
  21  *                mem_start: 0xc8000,0xd0000,0xd4000,0xd8000 (8K and 16K)
  22  *
  23  * sources:
  24  *   skeleton.c from Donald Becker
  25  *
  26  * I have also done a look in the following sources: (mail me if you need them)
  27  *   crynwr-packet-driver by Russ Nelson
  28  *   Garret A. Wollman's (fourth) i82586-driver for BSD
  29  *   (before getting an i82596 (yes 596 not 586) manual, the existing drivers helped
  30  *    me a lot to understand this tricky chip.)
  31  *
  32  * Known Problems:
  33  *   The internal sysbus seems to be slow. So we often lose packets because of
  34  *   overruns while receiving from a fast remote host. 
  35  *   This can slow down TCP connections. Maybe the newer ni5210 cards are better.
  36  * 
  37  * IMPORTANT NOTE:
  38  *   On fast networks, it's a (very) good idea to have 16K shared memory. With
  39  *   8K, we can store only 4 receive frames, so it can (easily) happen that a remote 
  40  *   machine 'overruns' our system.
  41  *
  42  * Known i82586 bugs (I'm sure, there are many more!):
  43  *   Running the NOP-mode, the i82586 sometimes seems to forget to report
  44  *   every xmit-interrupt until we restart the CU.
  45  *   Another MAJOR bug is, that the RU sometimes seems to ignore the EL-Bit 
  46  *   in the RBD-Struct which indicates an end of the RBD queue. 
  47  *   Instead, the RU fetches another (randomly selected and 
  48  *   usually used) RBD and begins to fill it. (Maybe, this happens only if 
  49  *   the last buffer from the previous RFD fits exact into the queue and
  50  *   the next RFD can't fetch an initial RBD. Anyone knows more? )
  51  */
  52 
  53 /*
  54  * 18.Nov.95: Mcast changes (AC).
  55  *
  56  * 19.Jan.95: verified (MH)
  57  *
  58  * 19.Sep.94: Added Multicast support (not tested yet) (MH)
  59  * 
  60  * 18.Sep.94: Workaround for 'EL-Bug'. Removed flexible RBD-handling. 
  61  *            Now, every RFD has exact one RBD. (MH)
  62  *
  63  * 14.Sep.94: added promiscuous mode, a few cleanups (MH)
  64  *
  65  * 19.Aug.94: changed request_irq() parameter (MH)
  66  * 
  67  * 20.July.94: removed cleanup bugs, removed a 16K-mem-probe-bug (MH)
  68  *
  69  * 19.July.94: lotsa cleanups .. (MH)
  70  *
  71  * 17.July.94: some patches ... verified to run with 1.1.29 (MH)
  72  *
  73  * 4.July.94: patches for Linux 1.1.24  (MH)
  74  *
  75  * 26.March.94: patches for Linux 1.0 and iomem-auto-probe (MH)
  76  *
  77  * 30.Sep.93: Added nop-chain .. driver now runs with only one Xmit-Buff, too (MH)
  78  *
  79  * < 30.Sep.93: first versions 
  80  */
  81  
  82 #include <linux/kernel.h>
  83 #include <linux/sched.h>
  84 #include <linux/string.h>
  85 #include <linux/errno.h>
  86 #include <linux/ioport.h>
  87 #include <linux/malloc.h>
  88 #include <linux/interrupt.h>
  89 #include <linux/delay.h>
  90 #include <asm/bitops.h>
  91 #include <asm/io.h>
  92 
  93 #include <linux/netdevice.h>
  94 #include <linux/etherdevice.h>
  95 #include <linux/skbuff.h>
  96 
  97 #include "ni52.h"
  98 
  99 #define DEBUG       /* debug on */
 100 #define SYSBUSVAL 1 /* 8 Bit */
 101 
 102 #define ni_attn586()  {outb(0,dev->base_addr+NI52_ATTENTION);}
 103 #define ni_reset586() {outb(0,dev->base_addr+NI52_RESET);}
 104 
 105 #define make32(ptr16) (p->memtop + (short) (ptr16) )
 106 #define make24(ptr32) ((char *) (ptr32) - p->base)
 107 #define make16(ptr32) ((unsigned short) ((unsigned long) (ptr32) - (unsigned long) p->memtop ))
 108 
 109 /******************* how to calculate the buffers *****************************
 110 
 111   * IMPORTANT NOTE: if you configure only one NUM_XMIT_BUFFS, the driver works
 112   * --------------- in a different (more stable?) mode. Only in this mode it's
 113   *                 possible to configure the driver with 'NO_NOPCOMMANDS'
 114 
 115 sizeof(scp)=12; sizeof(scb)=16; sizeof(iscp)=8;
 116 sizeof(scp)+sizeof(iscp)+sizeof(scb) = 36 = INIT
 117 sizeof(rfd) = 24; sizeof(rbd) = 12; 
 118 sizeof(tbd) = 8; sizeof(transmit_cmd) = 16;
 119 sizeof(nop_cmd) = 8; 
 120 
 121   * if you don't know the driver, better do not change this values: */
 122 
 123 #define RECV_BUFF_SIZE 1524 /* slightly oversized */
 124 #define XMIT_BUFF_SIZE 1524 /* slightly oversized */
 125 #define NUM_XMIT_BUFFS 1    /* config for both, 8K and 16K shmem */
 126 #define NUM_RECV_BUFFS_8  4 /* config for 8K shared mem */
 127 #define NUM_RECV_BUFFS_16 9 /* config for 16K shared mem */
 128 #define NO_NOPCOMMANDS      /* only possible with NUM_XMIT_BUFFS=1 */
 129 
 130 /**************************************************************************/
 131 
 132 #define DELAY(x) {int i=jiffies; \
 133                   if(loops_per_sec == 1) \
 134                      while(i+(x)>jiffies); \
 135                   else \
 136                      __delay((loops_per_sec>>5)*x); \
 137                  }
 138 
 139 /* a much shorter delay: */
 140 #define DELAY_16(); { __delay( (loops_per_sec>>16)+1 ); }
 141 
 142 /* wait for command with timeout: */
 143 #define WAIT_4_SCB_CMD() { int i; \
 144   for(i=0;i<1024;i++) { \
 145     if(!p->scb->cmd) break; \
 146     DELAY_16(); \
 147     if(i == 1023) { \
 148       printk("%s: scb_cmd timed out .. resetting i82586\n",dev->name); \
 149       ni_reset586(); } } }
 150 
 151 
 152 #define NI52_TOTAL_SIZE 16
 153 #define NI52_ADDR0 0x02
 154 #define NI52_ADDR1 0x07
 155 #define NI52_ADDR2 0x01
 156 
 157 #ifndef HAVE_PORTRESERVE
 158 #define check_region(ioaddr, size)              0
 159 #define request_region(ioaddr, size,name)    do ; while (0)
 160 #endif
 161 
 162 static int     ni52_probe1(struct device *dev,int ioaddr);
 163 static void    ni52_interrupt(int irq,struct pt_regs *reg_ptr);
 164 static int     ni52_open(struct device *dev);
 165 static int     ni52_close(struct device *dev);
 166 static int     ni52_send_packet(struct sk_buff *,struct device *);
 167 static struct  enet_statistics *ni52_get_stats(struct device *dev);
 168 static void    set_multicast_list(struct device *dev);
 169 
 170 /* helper-functions */
 171 static int     init586(struct device *dev);
 172 static int     check586(struct device *dev,char *where,unsigned size);
 173 static void    alloc586(struct device *dev);
 174 static void    startrecv586(struct device *dev);
 175 static void   *alloc_rfa(struct device *dev,void *ptr);
 176 static void    ni52_rcv_int(struct device *dev);
 177 static void    ni52_xmt_int(struct device *dev);
 178 static void    ni52_rnr_int(struct device *dev);
 179 
 180 struct priv
 181 {
 182   struct enet_statistics stats;
 183   unsigned long base;
 184   char *memtop;
 185   volatile struct rfd_struct  *rfd_last,*rfd_top,*rfd_first;
 186   volatile struct scp_struct  *scp;  /* volatile is important */
 187   volatile struct iscp_struct *iscp; /* volatile is important */
 188   volatile struct scb_struct  *scb;  /* volatile is important */
 189   volatile struct tbd_struct  *xmit_buffs[NUM_XMIT_BUFFS];
 190   volatile struct transmit_cmd_struct *xmit_cmds[NUM_XMIT_BUFFS];
 191 #if (NUM_XMIT_BUFFS == 1)
 192   volatile struct nop_cmd_struct *nop_cmds[2];
 193 #else
 194   volatile struct nop_cmd_struct *nop_cmds[NUM_XMIT_BUFFS];
 195 #endif
 196   volatile int    nop_point,num_recv_buffs;
 197   volatile char  *xmit_cbuffs[NUM_XMIT_BUFFS];
 198   volatile int    xmit_count,xmit_last;
 199 };
 200 
 201 
 202 /**********************************************
 203  * close device 
 204  */
 205 
 206 static int ni52_close(struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 207 {
 208   free_irq(dev->irq);
 209   irq2dev_map[dev->irq] = 0;
 210 
 211   ni_reset586(); /* the hard way to stop the receiver */
 212 
 213   dev->start = 0;
 214   dev->tbusy = 0;
 215 
 216   return 0;
 217 }
 218 
 219 /**********************************************
 220  * open device 
 221  */
 222 
 223 static int ni52_open(struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 224 {
 225   alloc586(dev);
 226   init586(dev);  
 227   startrecv586(dev);
 228 
 229   if(request_irq(dev->irq, &ni52_interrupt,0,"ni52")) 
 230   {    
 231     ni_reset586();
 232     return -EAGAIN;
 233   }  
 234   irq2dev_map[dev->irq] = dev;
 235 
 236   dev->interrupt = 0;
 237   dev->tbusy = 0;
 238   dev->start = 1;
 239 
 240   return 0; /* most done by init */
 241 }
 242 
 243 /**********************************************
 244  * Check to see if there's an 82586 out there. 
 245  */
 246 
 247 static int check586(struct device *dev,char *where,unsigned size)
     /* [previous][next][first][last][top][bottom][index][help] */
 248 {
 249   struct priv *p = (struct priv *) dev->priv;
 250   char *iscp_addrs[2];
 251   int i;
 252 
 253   p->base = (unsigned long) where + size - 0x01000000;
 254   p->memtop = where + size;
 255   p->scp = (struct scp_struct *)(p->base + SCP_DEFAULT_ADDRESS);
 256   memset((char *)p->scp,0, sizeof(struct scp_struct));
 257   p->scp->sysbus = SYSBUSVAL;        /* 1 = 8Bit-Bus, 0 = 16 Bit */
 258   
 259   iscp_addrs[0] = where;
 260   iscp_addrs[1]= (char *) p->scp - sizeof(struct iscp_struct);
 261 
 262   for(i=0;i<2;i++)
 263   {
 264     p->iscp = (struct iscp_struct *) iscp_addrs[i];
 265     memset((char *)p->iscp,0, sizeof(struct iscp_struct));
 266 
 267     p->scp->iscp = make24(p->iscp);
 268     p->iscp->busy = 1;
 269 
 270     ni_reset586();
 271     ni_attn586();
 272     DELAY(2);   /* wait a while... */
 273 
 274     if(p->iscp->busy) /* i82586 clears 'busy' after successful init */
 275       return 0;
 276   }
 277   return 1;
 278 }
 279 
 280 /******************************************************************
 281  * set iscp at the right place, called by ni52_probe1 and open586. 
 282  */
 283 
 284 void alloc586(struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 285 {
 286   struct priv *p =  (struct priv *) dev->priv; 
 287 
 288   ni_reset586();
 289   DELAY(2);
 290 
 291   p->scp  = (struct scp_struct *)  (p->base + SCP_DEFAULT_ADDRESS);
 292   p->scb  = (struct scb_struct *)  (dev->mem_start);
 293   p->iscp = (struct iscp_struct *) ((char *)p->scp - sizeof(struct iscp_struct));
 294 
 295   memset((char *) p->iscp,0,sizeof(struct iscp_struct));
 296   memset((char *) p->scp ,0,sizeof(struct scp_struct));
 297 
 298   p->scp->iscp = make24(p->iscp);
 299   p->scp->sysbus = SYSBUSVAL;
 300   p->iscp->scb_offset = make16(p->scb);
 301 
 302   p->iscp->busy = 1;
 303   ni_reset586();
 304   ni_attn586();
 305 
 306   DELAY(2); 
 307 
 308   if(p->iscp->busy)
 309     printk("%s: Init-Problems (alloc).\n",dev->name);
 310 
 311   memset((char *)p->scb,0,sizeof(struct scb_struct));
 312 }
 313 
 314 /**********************************************
 315  * probe the ni5210-card
 316  */
 317 
 318 int ni52_probe(struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 319 {
 320   int *port, ports[] = {0x300, 0x280, 0x360 , 0x320 , 0x340, 0};
 321   int base_addr = dev->base_addr;
 322 
 323   if (base_addr > 0x1ff)                /* Check a single specified location. */
 324     if( (inb(base_addr+NI52_MAGIC1) == NI52_MAGICVAL1) &&
 325         (inb(base_addr+NI52_MAGIC2) == NI52_MAGICVAL2))
 326       return ni52_probe1(dev, base_addr);
 327   else if (base_addr > 0)               /* Don't probe at all. */
 328     return ENXIO;
 329 
 330   for (port = ports; *port; port++) {
 331     int ioaddr = *port;
 332     if (check_region(ioaddr, NI52_TOTAL_SIZE))
 333       continue;
 334     if( !(inb(ioaddr+NI52_MAGIC1) == NI52_MAGICVAL1) || 
 335         !(inb(ioaddr+NI52_MAGIC2) == NI52_MAGICVAL2))
 336       continue;
 337 
 338     dev->base_addr = ioaddr;
 339     if (ni52_probe1(dev, ioaddr) == 0)
 340       return 0;
 341   }
 342 
 343   dev->base_addr = base_addr;
 344   return ENODEV;
 345 }
 346 
 347 static int ni52_probe1(struct device *dev,int ioaddr)
     /* [previous][next][first][last][top][bottom][index][help] */
 348 {
 349   long memaddrs[] = { 0xd0000,0xd2000,0xc8000,0xca000,0xd4000,0xd6000,0xd8000, 0 };
 350   int i,size;
 351 
 352   for(i=0;i<ETH_ALEN;i++)
 353     dev->dev_addr[i] = inb(dev->base_addr+i);
 354 
 355   if(dev->dev_addr[0] != NI52_ADDR0 || dev->dev_addr[1] != NI52_ADDR1
 356                                     || dev->dev_addr[2] != NI52_ADDR2)
 357     return ENODEV;
 358 
 359   printk("%s: Ni52 found at %#3lx, ",dev->name,dev->base_addr);
 360 
 361   request_region(ioaddr,NI52_TOTAL_SIZE,"ni52");
 362 
 363   dev->priv = (void *) kmalloc(sizeof(struct priv),GFP_KERNEL); 
 364                                   /* warning: we don't free it on errors */
 365   if (dev->priv == NULL)
 366      return -ENOMEM;
 367   memset((char *) dev->priv,0,sizeof(struct priv));
 368 
 369   /* 
 370    * check (or search) IO-Memory, 8K and 16K
 371    */
 372   if(dev->mem_start != 0) /* no auto-mem-probe */
 373   {
 374     size = 0x4000; /* check for 16K mem */
 375     if(!check586(dev,(char *) dev->mem_start,size)) {
 376       size = 0x2000; /* check for 8K mem */
 377       if(!check586(dev,(char *) dev->mem_start,size)) {
 378         printk("?memprobe, Can't find memory at 0x%lx!\n",dev->mem_start);
 379         return ENODEV;
 380       }
 381     }
 382   }
 383   else  
 384   {
 385     for(i=0;;i++)
 386     {
 387       if(!memaddrs[i]) {
 388         printk("?memprobe, Can't find io-memory!\n");
 389         return ENODEV;
 390       }
 391       dev->mem_start = memaddrs[i];
 392       size = 0x2000; /* check for 8K mem */
 393       if(check586(dev,(char *)dev->mem_start,size)) /* 8K-check */
 394         break;
 395       size = 0x4000; /* check for 16K mem */
 396       if(check586(dev,(char *)dev->mem_start,size)) /* 16K-check */
 397         break;
 398     }
 399   }
 400   dev->mem_end = dev->mem_start + size; /* set mem_end showed by 'ifconfig' */
 401   
 402   ((struct priv *) (dev->priv))->base =  dev->mem_start + size - 0x01000000;
 403   alloc586(dev);
 404 
 405   /* set number of receive-buffs according to memsize */
 406   if(size == 0x2000)
 407     ((struct priv *) dev->priv)->num_recv_buffs = NUM_RECV_BUFFS_8;
 408   else
 409     ((struct priv *) dev->priv)->num_recv_buffs = NUM_RECV_BUFFS_16;
 410 
 411   printk("Memaddr: 0x%lx, Memsize: %d, ",dev->mem_start,size);
 412 
 413   if(dev->irq < 2)
 414   {
 415     autoirq_setup(0);
 416     ni_reset586();
 417     ni_attn586();
 418     if(!(dev->irq = autoirq_report(2)))
 419     {
 420       printk("?autoirq, Failed to detect IRQ line!\n"); 
 421       return 1;
 422     }
 423   }
 424   else if(dev->irq == 2) 
 425     dev->irq = 9;
 426 
 427   printk("IRQ %d.\n",dev->irq);
 428 
 429   dev->open            = &ni52_open;
 430   dev->stop            = &ni52_close;
 431   dev->get_stats       = &ni52_get_stats;
 432   dev->hard_start_xmit = &ni52_send_packet;
 433   dev->set_multicast_list = &set_multicast_list;
 434 
 435   dev->if_port         = 0;
 436 
 437   ether_setup(dev);
 438 
 439   dev->tbusy = 0;
 440   dev->interrupt = 0;
 441   dev->start = 0;
 442   
 443   return 0;
 444 }
 445 
 446 /********************************************** 
 447  * init the chip (ni52-interrupt should be disabled?!)
 448  * needs a correct 'allocated' memory
 449  */
 450 
 451 static int init586(struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 452 {
 453   void *ptr;
 454   unsigned long s;
 455   int i,result=0;
 456   struct priv *p = (struct priv *) dev->priv;
 457   volatile struct configure_cmd_struct  *cfg_cmd;
 458   volatile struct iasetup_cmd_struct *ias_cmd;
 459   volatile struct tdr_cmd_struct *tdr_cmd;
 460   volatile struct mcsetup_cmd_struct *mc_cmd;
 461   struct dev_mc_list *dmi=dev->mc_list;
 462   int num_addrs=dev->mc_count;
 463 
 464   ptr = (void *) ((char *)p->scb + sizeof(struct scb_struct));
 465 
 466   cfg_cmd = (struct configure_cmd_struct *)ptr; /* configure-command */
 467   cfg_cmd->cmd_status = 0;
 468   cfg_cmd->cmd_cmd    = CMD_CONFIGURE | CMD_LAST;
 469   cfg_cmd->cmd_link   = 0xffff;
 470 
 471   cfg_cmd->byte_cnt   = 0x0a; /* number of cfg bytes */
 472   cfg_cmd->fifo       = 0x08; /* fifo-limit (8=tx:32/rx:64) */
 473   cfg_cmd->sav_bf     = 0x40; /* hold or discard bad recv frames (bit 7) */
 474   cfg_cmd->adr_len    = 0x2e; /* addr_len |!src_insert |pre-len |loopback */
 475   cfg_cmd->priority   = 0x00;
 476   cfg_cmd->ifs        = 0x60;
 477   cfg_cmd->time_low   = 0x00;
 478   cfg_cmd->time_high  = 0xf2;
 479   cfg_cmd->promisc    = 0;
 480   if(dev->flags&(IFF_ALLMULTI|IFF_PROMISC))
 481   {
 482         cfg_cmd->promisc=1;
 483         dev->flags|=IFF_PROMISC;
 484   }
 485   cfg_cmd->carr_coll  = 0x00;
 486  
 487   p->scb->cbl_offset = make16(cfg_cmd);
 488 
 489   p->scb->cmd = CUC_START; /* cmd.-unit start */
 490   ni_attn586();
 491  
 492   s = jiffies; /* warning: only active with interrupts on !! */
 493   while(!(cfg_cmd->cmd_status & STAT_COMPL)) 
 494     if(jiffies-s > 30) break;
 495 
 496   if((cfg_cmd->cmd_status & (STAT_OK|STAT_COMPL)) != (STAT_COMPL|STAT_OK))
 497   {
 498     printk("%s (ni52): configure command failed: %x\n",dev->name,cfg_cmd->cmd_status);
 499     return 1; 
 500   }
 501 
 502     /*
 503      * individual address setup
 504      */
 505   ias_cmd = (struct iasetup_cmd_struct *)ptr;
 506 
 507   ias_cmd->cmd_status = 0;
 508   ias_cmd->cmd_cmd    = CMD_IASETUP | CMD_LAST;
 509   ias_cmd->cmd_link   = 0xffff;
 510 
 511   memcpy((char *)&ias_cmd->iaddr,(char *) dev->dev_addr,ETH_ALEN);
 512 
 513   p->scb->cbl_offset = make16(ias_cmd);
 514 
 515   p->scb->cmd = CUC_START; /* cmd.-unit start */
 516   ni_attn586();
 517 
 518   s = jiffies;
 519   while(!(ias_cmd->cmd_status & STAT_COMPL)) 
 520     if(jiffies-s > 30) break;
 521 
 522   if((ias_cmd->cmd_status & (STAT_OK|STAT_COMPL)) != (STAT_OK|STAT_COMPL)) {
 523     printk("%s (ni52): individual address setup command failed: %04x\n",dev->name,ias_cmd->cmd_status);
 524     return 1; 
 525   }
 526 
 527    /* 
 528     * TDR, wire check .. e.g. no resistor e.t.c 
 529     */
 530   tdr_cmd = (struct tdr_cmd_struct *)ptr;
 531 
 532   tdr_cmd->cmd_status  = 0;
 533   tdr_cmd->cmd_cmd     = CMD_TDR | CMD_LAST;
 534   tdr_cmd->cmd_link    = 0xffff;
 535   tdr_cmd->status      = 0;
 536 
 537   p->scb->cbl_offset = make16(tdr_cmd);
 538 
 539   p->scb->cmd = CUC_START; /* cmd.-unit start */
 540   ni_attn586();
 541 
 542   s = jiffies; 
 543   while(!(tdr_cmd->cmd_status & STAT_COMPL))
 544     if(jiffies - s > 30) {
 545       printk("%s: Problems while running the TDR.\n",dev->name);
 546       result = 1;
 547     }
 548 
 549   if(!result)
 550   {
 551     DELAY(2); /* wait for result */
 552     result = tdr_cmd->status;
 553 
 554     p->scb->cmd = p->scb->status & STAT_MASK;
 555     ni_attn586(); /* ack the interrupts */
 556 
 557     if(result & TDR_LNK_OK) ;
 558     else if(result & TDR_XCVR_PRB)
 559       printk("%s: TDR: Transceiver problem!\n",dev->name);
 560     else if(result & TDR_ET_OPN)
 561       printk("%s: TDR: No correct termination %d clocks away.\n",dev->name,result & TDR_TIMEMASK);
 562     else if(result & TDR_ET_SRT) 
 563     {
 564       if (result & TDR_TIMEMASK) /* time == 0 -> strange :-) */
 565         printk("%s: TDR: Detected a short circuit %d clocks away.\n",dev->name,result & TDR_TIMEMASK);
 566     }
 567     else
 568       printk("%s: TDR: Unknown status %04x\n",dev->name,result);
 569   }
 570  
 571    /* 
 572     * ack interrupts 
 573     */
 574   p->scb->cmd = p->scb->status & STAT_MASK;
 575   ni_attn586();
 576 
 577    /*
 578     * alloc nop/xmit-cmds
 579     */
 580 #if (NUM_XMIT_BUFFS == 1)
 581   for(i=0;i<2;i++)
 582   {
 583     p->nop_cmds[i] = (struct nop_cmd_struct *)ptr;
 584     p->nop_cmds[i]->cmd_cmd    = CMD_NOP;
 585     p->nop_cmds[i]->cmd_status = 0;
 586     p->nop_cmds[i]->cmd_link   = make16((p->nop_cmds[i]));
 587     ptr = (char *) ptr + sizeof(struct nop_cmd_struct);
 588   }
 589   p->xmit_cmds[0] = (struct transmit_cmd_struct *)ptr; /* transmit cmd/buff 0 */
 590   ptr = (char *) ptr + sizeof(struct transmit_cmd_struct);
 591 #else
 592   for(i=0;i<NUM_XMIT_BUFFS;i++)
 593   {
 594     p->nop_cmds[i] = (struct nop_cmd_struct *)ptr;
 595     p->nop_cmds[i]->cmd_cmd    = CMD_NOP;
 596     p->nop_cmds[i]->cmd_status = 0;
 597     p->nop_cmds[i]->cmd_link   = make16((p->nop_cmds[i]));
 598     ptr = (char *) ptr + sizeof(struct nop_cmd_struct);
 599     p->xmit_cmds[i] = (struct transmit_cmd_struct *)ptr; /*transmit cmd/buff 0*/
 600     ptr = (char *) ptr + sizeof(struct transmit_cmd_struct);
 601   }
 602 #endif
 603 
 604   ptr = alloc_rfa(dev,(void *)ptr); /* init receive-frame-area */ 
 605 
 606   /* 
 607    * Multicast setup
 608    */
 609   
 610   if(dev->mc_count)
 611   { /* I don't understand this: do we really need memory after the init? */
 612     int len = ((char *) p->iscp - (char *) ptr - 8) / 6;
 613     if(len <= 0)
 614     {
 615       printk("%s: Ooooops, no memory for MC-Setup!\n",dev->name);
 616     }
 617     else
 618     {
 619       if(len < num_addrs)
 620       {
 621         /* BUG - should go ALLMULTI in this case */
 622         num_addrs = len;
 623         printk("%s: Sorry, can only apply %d MC-Address(es).\n",dev->name,num_addrs);
 624       }
 625       mc_cmd = (struct mcsetup_cmd_struct *) ptr;
 626       mc_cmd->cmd_status = 0;
 627       mc_cmd->cmd_cmd = CMD_MCSETUP | CMD_LAST;
 628       mc_cmd->cmd_link = 0xffff;
 629       mc_cmd->mc_cnt = num_addrs * 6;
 630       for(i=0;i<num_addrs;i++)
 631       {
 632                 memcpy((char *) mc_cmd->mc_list[i], dmi->dmi_addr,6);
 633                 dmi=dmi->next;
 634       }
 635       p->scb->cbl_offset = make16(mc_cmd);
 636       p->scb->cmd = CUC_START;
 637       ni_attn586();
 638       s = jiffies;
 639       while(!(mc_cmd->cmd_status & STAT_COMPL))
 640         if(jiffies - s > 30)
 641           break;
 642       if(!(mc_cmd->cmd_status & STAT_COMPL))
 643         printk("%s: Can't apply multicast-address-list.\n",dev->name);
 644     }
 645   }
 646 
 647   /*
 648    * alloc xmit-buffs / init xmit_cmds
 649    */
 650   for(i=0;i<NUM_XMIT_BUFFS;i++)
 651   {
 652     p->xmit_cbuffs[i] = (char *)ptr; /* char-buffs */
 653     ptr = (char *) ptr + XMIT_BUFF_SIZE;
 654     p->xmit_buffs[i] = (struct tbd_struct *)ptr; /* TBD */
 655     ptr = (char *) ptr + sizeof(struct tbd_struct);
 656     if((void *)ptr > (void *)p->iscp) 
 657     {
 658       printk("%s: not enough shared-mem for your configuration!\n",dev->name);
 659       return 1;
 660     }   
 661     memset((char *)(p->xmit_cmds[i]) ,0, sizeof(struct transmit_cmd_struct));
 662     memset((char *)(p->xmit_buffs[i]),0, sizeof(struct tbd_struct));
 663     p->xmit_cmds[i]->cmd_status = STAT_COMPL;
 664     p->xmit_cmds[i]->cmd_cmd = CMD_XMIT | CMD_INT;
 665     p->xmit_cmds[i]->tbd_offset = make16((p->xmit_buffs[i]));
 666     p->xmit_buffs[i]->next = 0xffff;
 667     p->xmit_buffs[i]->buffer = make24((p->xmit_cbuffs[i]));
 668   }
 669 
 670   p->xmit_count = 0; 
 671   p->xmit_last  = 0;
 672 #ifndef NO_NOPCOMMANDS
 673   p->nop_point  = 0;
 674 #endif
 675 
 676    /*
 677     * 'start transmitter' (nop-loop)
 678     */
 679 #ifndef NO_NOPCOMMANDS
 680   p->scb->cbl_offset = make16(p->nop_cmds[0]);
 681   p->scb->cmd = CUC_START;
 682   ni_attn586();
 683   WAIT_4_SCB_CMD();
 684 #else
 685   p->xmit_cmds[0]->cmd_link = 0xffff;
 686   p->xmit_cmds[0]->cmd_cmd  = CMD_XMIT | CMD_LAST | CMD_INT;
 687 #endif
 688 
 689   return 0;
 690 }
 691 
 692 /******************************************************
 693  * This is a helper routine for ni52_rnr_int() and init586(). 
 694  * It sets up the Receive Frame Area (RFA).
 695  */
 696 
 697 static void *alloc_rfa(struct device *dev,void *ptr) 
     /* [previous][next][first][last][top][bottom][index][help] */
 698 {
 699   volatile struct rfd_struct *rfd = (struct rfd_struct *)ptr;
 700   volatile struct rbd_struct *rbd;
 701   int i;
 702   struct priv *p = (struct priv *) dev->priv;
 703 
 704   memset((char *) rfd,0,sizeof(struct rfd_struct)*p->num_recv_buffs);
 705   p->rfd_first = rfd;
 706 
 707   for(i = 0; i < p->num_recv_buffs; i++)
 708     rfd[i].next = make16(rfd + (i+1) % p->num_recv_buffs);
 709   rfd[p->num_recv_buffs-1].last = RFD_SUSP;   /* RU suspend */
 710 
 711   ptr = (void *) (rfd + p->num_recv_buffs);
 712 
 713   rbd = (struct rbd_struct *) ptr;
 714   ptr = (void *) (rbd + p->num_recv_buffs);
 715 
 716    /* clr descriptors */
 717   memset((char *) rbd,0,sizeof(struct rbd_struct)*p->num_recv_buffs);
 718 
 719   for(i=0;i<p->num_recv_buffs;i++)
 720   {
 721     rbd[i].next = make16((rbd + (i+1) % p->num_recv_buffs));
 722     rbd[i].size = RECV_BUFF_SIZE;
 723     rbd[i].buffer = make24(ptr);
 724     ptr = (char *) ptr + RECV_BUFF_SIZE;
 725   }
 726 
 727   p->rfd_top  = p->rfd_first;
 728   p->rfd_last = p->rfd_first + p->num_recv_buffs - 1;
 729 
 730   p->scb->rfa_offset            = make16(p->rfd_first);
 731   p->rfd_first->rbd_offset      = make16(rbd);
 732 
 733   return ptr;
 734 }
 735 
 736 
 737 /**************************************************
 738  * Interrupt Handler ...
 739  */
 740 
 741 static void ni52_interrupt(int irq,struct pt_regs *reg_ptr)
     /* [previous][next][first][last][top][bottom][index][help] */
 742 {
 743   struct device *dev = (struct device *) irq2dev_map[irq];
 744   unsigned short stat;
 745   struct priv *p;
 746 
 747   if (dev == NULL) {
 748     printk ("ni52-interrupt: irq %d for unknown device.\n",(int) -(((struct pt_regs *)reg_ptr)->orig_eax+2));
 749     return;
 750   }
 751   p = (struct priv *) dev->priv;
 752 
 753   dev->interrupt = 1;
 754 
 755   while((stat=p->scb->status & STAT_MASK))
 756   {
 757     p->scb->cmd = stat;
 758     ni_attn586(); /* ack inter. */
 759 
 760    if(stat & STAT_CX)    /* command with I-bit set complete */
 761       ni52_xmt_int(dev);
 762 
 763     if(stat & STAT_FR)   /* received a frame */
 764       ni52_rcv_int(dev);
 765 
 766 #ifndef NO_NOPCOMMANDS
 767     if(stat & STAT_CNA)  /* CU went 'not ready' */
 768     {
 769       if(dev->start)
 770         printk("%s: oops! CU has left active state. stat: %04x/%04x.\n",dev->name,(int) stat,(int) p->scb->status);
 771     }
 772 #endif
 773 
 774     if(stat & STAT_RNR) /* RU went 'not ready' */
 775     {
 776       if(p->scb->status & RU_SUSPEND) /* special case: RU_SUSPEND */
 777       {
 778         WAIT_4_SCB_CMD();
 779         p->scb->cmd = RUC_RESUME;
 780         ni_attn586();
 781       }
 782       else
 783       {
 784         printk("%s: Receiver-Unit went 'NOT READY': %04x/%04x.\n",dev->name,(int) stat,(int) p->scb->status);
 785         ni52_rnr_int(dev); 
 786       }
 787     }
 788     WAIT_4_SCB_CMD(); /* wait for ack. (ni52_xmt_int can be faster than ack!!) */
 789     if(p->scb->cmd)   /* timed out? */
 790       break;
 791   }
 792 
 793   dev->interrupt = 0;
 794 }
 795 
 796 /*******************************************************
 797  * receive-interrupt
 798  */
 799 
 800 static void ni52_rcv_int(struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 801 {
 802   int status;
 803   unsigned short totlen;
 804   struct sk_buff *skb;
 805   struct rbd_struct *rbd;
 806   struct priv *p = (struct priv *) dev->priv;
 807 
 808   for(;(status = p->rfd_top->status) & STAT_COMPL;)
 809   {
 810       rbd = (struct rbd_struct *) make32(p->rfd_top->rbd_offset);
 811 
 812       if(status & STAT_OK) /* frame received without error? */
 813       {
 814         if( (totlen = rbd->status) & RBD_LAST) /* the first and the last buffer? */
 815         {
 816           totlen &= RBD_MASK; /* length of this frame */
 817           rbd->status = 0;
 818           skb = (struct sk_buff *) dev_alloc_skb(totlen+2);
 819           if(skb != NULL)
 820           {
 821             skb->dev = dev;
 822             skb_reserve(skb,2);         /* 16 byte alignment */
 823             memcpy(skb_put(skb,totlen),(char *) p->base+(unsigned long) rbd->buffer, totlen);
 824             skb->protocol=eth_type_trans(skb,dev);
 825             netif_rx(skb);
 826             p->stats.rx_packets++;
 827           }
 828           else
 829             p->stats.rx_dropped++;
 830         }
 831         else
 832         {
 833           printk("%s: received oversized frame.\n",dev->name);
 834           p->stats.rx_dropped++;
 835         }
 836       }
 837       else /* frame !(ok), only with 'save-bad-frames' */
 838       {
 839         printk("%s: oops! rfd-error-status: %04x\n",dev->name,status);
 840         p->stats.rx_errors++;
 841       }
 842       p->rfd_top->status = 0;
 843       p->rfd_top->last = RFD_SUSP;
 844       p->rfd_last->last = 0;        /* delete RU_SUSP  */
 845       p->rfd_last = p->rfd_top;
 846       p->rfd_top = (struct rfd_struct *) make32(p->rfd_top->next); /* step to next RFD */
 847   }
 848 }
 849 
 850 /**********************************************************
 851  * handle 'Receiver went not ready'. 
 852  */
 853 
 854 static void ni52_rnr_int(struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 855 {
 856   struct priv *p = (struct priv *) dev->priv;
 857 
 858   p->stats.rx_errors++;
 859 
 860   WAIT_4_SCB_CMD();    /* wait for the last cmd */
 861   p->scb->cmd = RUC_ABORT; /* usually the RU is in the 'no resource'-state .. abort it now. */
 862   ni_attn586(); 
 863   WAIT_4_SCB_CMD();    /* wait for accept cmd. */
 864 
 865   alloc_rfa(dev,(char *)p->rfd_first);
 866   startrecv586(dev); /* restart RU */
 867 
 868   printk("%s: Receive-Unit restarted. Status: %04x\n",dev->name,p->scb->status);
 869 
 870 }
 871 
 872 /**********************************************************
 873  * handle xmit - interrupt
 874  */
 875 
 876 static void ni52_xmt_int(struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 877 {
 878   int status;
 879   struct priv *p = (struct priv *) dev->priv;
 880 
 881   status = p->xmit_cmds[p->xmit_last]->cmd_status;
 882   if(!(status & STAT_COMPL))
 883     printk("%s: strange .. xmit-int without a 'COMPLETE'\n",dev->name);
 884 
 885   if(status & STAT_OK)
 886   {
 887     p->stats.tx_packets++;
 888     p->stats.collisions += (status & TCMD_MAXCOLLMASK);
 889   }
 890   else 
 891   {
 892     p->stats.tx_errors++;
 893     if(status & TCMD_LATECOLL) {
 894       printk("%s: late collision detected.\n",dev->name);
 895       p->stats.collisions++;
 896     } 
 897     else if(status & TCMD_NOCARRIER) {
 898       p->stats.tx_carrier_errors++;
 899       printk("%s: no carrier detected.\n",dev->name);
 900     } 
 901     else if(status & TCMD_LOSTCTS) 
 902       printk("%s: loss of CTS detected.\n",dev->name);
 903     else if(status & TCMD_UNDERRUN) {
 904       p->stats.tx_fifo_errors++;
 905       printk("%s: DMA underrun detected.\n",dev->name);
 906     }
 907     else if(status & TCMD_MAXCOLL) {
 908       printk("%s: Max. collisions exceeded.\n",dev->name);
 909       p->stats.collisions += 16;
 910     } 
 911   }
 912 
 913 #if (NUM_XMIT_BUFFS != 1)
 914   if( (++p->xmit_last) == NUM_XMIT_BUFFS) 
 915     p->xmit_last = 0;
 916 #endif
 917 
 918   dev->tbusy = 0;
 919   mark_bh(NET_BH);
 920 }
 921 
 922 /***********************************************************
 923  * (re)start the receiver
 924  */ 
 925 
 926 static void startrecv586(struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 927 {
 928   struct priv *p = (struct priv *) dev->priv;
 929 
 930   p->scb->rfa_offset = make16(p->rfd_first);
 931   p->scb->cmd = RUC_START;
 932   ni_attn586();         /* start cmd. */
 933   WAIT_4_SCB_CMD();     /* wait for accept cmd. (no timeout!!) */
 934 }
 935 
 936 /******************************************************
 937  * send frame 
 938  */
 939 
 940 static int ni52_send_packet(struct sk_buff *skb, struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 941 {
 942   int len,i;
 943 #ifndef NO_NOPCOMMANDS
 944   int next_nop;
 945 #endif
 946   struct priv *p = (struct priv *) dev->priv;
 947 
 948   if(dev->tbusy)
 949   {
 950     int tickssofar = jiffies - dev->trans_start;
 951     if (tickssofar < 5)
 952       return 1;
 953 
 954     if(p->scb->status & CU_ACTIVE) /* COMMAND-UNIT active? */
 955     {
 956       dev->tbusy = 0;
 957 #ifdef DEBUG
 958       printk("%s: strange ... timeout with CU active?!?\n",dev->name);
 959       printk("%s: X0: %04x N0: %04x N1: %04x %d\n",dev->name,(int)p->xmit_cmds[0]->cmd_status,(int)p->nop_cmds[0]->cmd_status,(int)p->nop_cmds[1]->cmd_status,(int)p->nop_point);
 960 #endif
 961       p->scb->cmd = CUC_ABORT;
 962       ni_attn586();
 963       WAIT_4_SCB_CMD();
 964       p->scb->cbl_offset = make16(p->nop_cmds[p->nop_point]);
 965       p->scb->cmd = CUC_START;
 966       ni_attn586();
 967       WAIT_4_SCB_CMD();
 968       dev->trans_start = jiffies;
 969       return 0;
 970     }
 971     else
 972     {
 973 #ifdef DEBUG
 974       printk("%s: xmitter timed out, try to restart! stat: %04x\n",dev->name,p->scb->status);
 975       printk("%s: command-stats: %04x %04x\n",dev->name,p->xmit_cmds[0]->cmd_status,p->xmit_cmds[1]->cmd_status);
 976 #endif
 977       ni52_close(dev);
 978       ni52_open(dev);
 979     }
 980     dev->trans_start = jiffies;
 981     return 0;
 982   }
 983 
 984   if(skb == NULL)
 985   {
 986     dev_tint(dev);
 987     return 0;
 988   }
 989 
 990   if (skb->len <= 0)
 991     return 0;
 992   if(skb->len > XMIT_BUFF_SIZE)
 993   {
 994     printk("%s: Sorry, max. framelength is %d bytes. The length of your frame is %ld bytes.\n",dev->name,XMIT_BUFF_SIZE,skb->len);
 995     return 0;
 996   }
 997 
 998   if (set_bit(0, (void*)&dev->tbusy) != 0)
 999      printk("%s: Transmitter access conflict.\n", dev->name);
1000   else
1001   {
1002     memcpy((char *)p->xmit_cbuffs[p->xmit_count],(char *)(skb->data),skb->len);
1003     len = (ETH_ZLEN < skb->len) ? skb->len : ETH_ZLEN;
1004 
1005 #if (NUM_XMIT_BUFFS == 1)
1006 #  ifdef NO_NOPCOMMANDS
1007     p->xmit_buffs[0]->size = TBD_LAST | len;
1008     for(i=0;i<16;i++)
1009     {
1010       p->scb->cbl_offset = make16(p->xmit_cmds[0]);
1011       p->scb->cmd = CUC_START;
1012       p->xmit_cmds[0]->cmd_status = 0;
1013 
1014       ni_attn586();
1015       dev->trans_start = jiffies;
1016       if(!i)
1017         dev_kfree_skb(skb,FREE_WRITE);
1018       WAIT_4_SCB_CMD();
1019       if( (p->scb->status & CU_ACTIVE)) /* test it, because CU sometimes doesn't start immediately */
1020         break;
1021       if(p->xmit_cmds[0]->cmd_status)
1022         break;
1023       if(i==15)
1024         printk("%s: Can't start transmit-command.\n",dev->name);
1025     }
1026 #  else
1027     next_nop = (p->nop_point + 1) & 0x1;
1028     p->xmit_buffs[0]->size = TBD_LAST | len;
1029 
1030     p->xmit_cmds[0]->cmd_link   = p->nop_cmds[next_nop]->cmd_link 
1031                                 = make16((p->nop_cmds[next_nop]));
1032     p->xmit_cmds[0]->cmd_status = p->nop_cmds[next_nop]->cmd_status = 0;
1033 
1034     p->nop_cmds[p->nop_point]->cmd_link = make16((p->xmit_cmds[0]));
1035     dev->trans_start = jiffies;
1036     p->nop_point = next_nop;
1037     dev_kfree_skb(skb,FREE_WRITE);
1038 #  endif
1039 #else
1040     p->xmit_buffs[p->xmit_count]->size = TBD_LAST | len;
1041     if( (next_nop = p->xmit_count + 1) == NUM_XMIT_BUFFS ) 
1042       next_nop = 0;
1043 
1044     p->xmit_cmds[p->xmit_count]->cmd_status  = 0;
1045     p->xmit_cmds[p->xmit_count]->cmd_link = p->nop_cmds[next_nop]->cmd_link 
1046                                           = make16((p->nop_cmds[next_nop]));
1047     p->nop_cmds[next_nop]->cmd_status = 0;
1048 
1049     p->nop_cmds[p->xmit_count]->cmd_link = make16((p->xmit_cmds[p->xmit_count]));
1050     dev->trans_start = jiffies;
1051     p->xmit_count = next_nop;
1052   
1053     cli();
1054     if(p->xmit_count != p->xmit_last)
1055       dev->tbusy = 0;
1056     sti();
1057     dev_kfree_skb(skb,FREE_WRITE);
1058 #endif
1059   }
1060   return 0;
1061 }
1062 
1063 /*******************************************
1064  * Someone wanna have the statistics 
1065  */
1066 
1067 static struct enet_statistics *ni52_get_stats(struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
1068 {
1069   struct priv *p = (struct priv *) dev->priv;
1070   unsigned short crc,aln,rsc,ovrn;
1071 
1072   crc = p->scb->crc_errs; /* get error-statistic from the ni82586 */
1073   p->scb->crc_errs -= crc;
1074   aln = p->scb->aln_errs;
1075   p->scb->aln_errs -= aln;
1076   rsc = p->scb->rsc_errs;
1077   p->scb->rsc_errs -= rsc;
1078   ovrn = p->scb->ovrn_errs;
1079   p->scb->ovrn_errs -= ovrn;
1080 
1081   p->stats.rx_crc_errors += crc;
1082   p->stats.rx_fifo_errors += ovrn;
1083   p->stats.rx_frame_errors += aln;
1084   p->stats.rx_dropped += rsc;
1085 
1086   return &p->stats;
1087 }
1088 
1089 /********************************************************
1090  * Set MC list ..  
1091  */
1092 
1093 static void set_multicast_list(struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
1094 {
1095   if(!dev->start)
1096   {
1097     printk("%s: Can't apply promiscuous/multicastmode to a not running interface.\n",dev->name);
1098     return;
1099   }
1100 
1101   dev->start = 0;
1102   alloc586(dev);
1103   init586(dev);  
1104   startrecv586(dev);
1105   dev->start = 1;
1106 }
1107 
1108 /*
1109  * END: linux/drivers/net/ni52.c 
1110  */

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