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

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