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

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