root/drivers/net/apricot.c

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

DEFINITIONS

This source file includes following definitions.
  1. init_rx_bufs
  2. init_i596_mem
  3. i596_rx
  4. i596_add_cmd
  5. i596_cleanup_cmd
  6. i596_open
  7. i596_start_xmit
  8. print_eth
  9. apricot_init
  10. i596_interrupt
  11. i596_close
  12. i596_get_stats
  13. set_multicast_list

   1 /* apricot.c: An Apricot 82596 ethernet driver for linux. */
   2 /*
   3     Apricot
   4         Written 1994 by Mark Evans.
   5         This driver is for the Apricot 82596 bus-master interface
   6     
   7     Driver skeleton 
   8         Written 1993 by Donald Becker.
   9         Copyright 1993 United States Government as represented by the Director,
  10         National Security Agency.  This software may only be used and distributed
  11         according to the terms of the GNU Public License as modified by SRC,
  12         incorporated herein by reference.
  13 
  14         The author may be reached as becker@super.org or
  15         C/O Supercomputing Research Ctr., 17100 Science Dr., Bowie MD 20715
  16     
  17 
  18 */
  19 
  20 static char *version = "apricot.c:v0.02 19/05/94\n";
  21 
  22 #include <linux/config.h>
  23 #include <linux/kernel.h>
  24 #include <linux/sched.h>
  25 #include <linux/string.h>
  26 #include <linux/ptrace.h>
  27 #include <linux/errno.h>
  28 #include <linux/ioport.h>
  29 #include <linux/malloc.h>
  30 #include <linux/interrupt.h>
  31 #include <asm/bitops.h>
  32 #include <asm/io.h>
  33 #include <asm/dma.h>
  34 
  35 #include <linux/netdevice.h>
  36 #include <linux/etherdevice.h>
  37 #include <linux/skbuff.h>
  38 
  39 #ifndef HAVE_PORTRESERVE
  40 #define check_region(addr, size)        0
  41 #define snarf_region(addr, size)        do ; while(0)
  42 #endif
  43 
  44 #ifndef HAVE_ALLOC_SKB
  45 #define alloc_skb(size, priority) (struct sk_buff *) kmalloc(size,priority)
  46 #define kfree_skbmem(buff, size) kfree_s(buff,size)
  47 #endif
  48 
  49 struct device *init_etherdev(struct device *dev, int sizeof_private,
  50                              unsigned long *mem_start);
  51 
  52 #define APRICOT_DEBUG 1
  53 
  54 #ifdef APRICOT_DEBUG
  55 int i596_debug = APRICOT_DEBUG;
  56 #else
  57 int i596_debug = 1;
  58 #endif
  59 
  60 #define APRICOT_TOTAL_SIZE 17
  61 
  62 #define CMD_EOL         0x8000  /* The last command of the list, stop. */
  63 #define CMD_SUSP        0x4000  /* Suspend after doing cmd. */
  64 #define CMD_INTR        0x2000  /* Interrupt after doing cmd. */
  65 
  66 #define CMD_FLEX        0x0008  /* Enable flexable memory model */
  67 
  68 enum commands {
  69         CmdNOp = 0, CmdSASetup = 1, CmdConfigure = 2, CmdMulticastList = 3,
  70         CmdTx = 4, CmdTDR = 5, CmdDump = 6, CmdDiagnose = 7};
  71 
  72 #define STAT_C          0x8000  /* Set to 0 after execution */
  73 #define STAT_B          0x4000  /* Command being executed */
  74 #define STAT_OK         0x2000  /* Command executed ok */
  75 #define STAT_A          0x1000  /* Command aborted */
  76 
  77 #define  CUC_START      0x0100
  78 #define  CUC_RESUME     0x0200
  79 #define  CUC_SUSPEND    0x0300
  80 #define  CUC_ABORT      0x0400
  81 #define  RX_START       0x0010
  82 #define  RX_RESUME      0x0020
  83 #define  RX_SUSPEND     0x0030
  84 #define  RX_ABORT       0x0040
  85 
  86 struct i596_cmd {
  87     unsigned short status;
  88     unsigned short command;
  89     struct i596_cmd *next;
  90 };
  91 
  92 #define EOF             0x8000
  93 #define SIZE_MASK       0x3fff
  94 
  95 struct i596_tbd {
  96     unsigned short size;
  97     unsigned short pad;
  98     struct i596_tbd *next;
  99     char *data;
 100 };
 101 
 102 struct tx_cmd {
 103     struct i596_cmd cmd;
 104     struct i596_tbd *tbd;
 105     unsigned short size;
 106     unsigned short pad;
 107 };
 108 
 109 struct i596_rfd {
 110     unsigned short stat;
 111     unsigned short cmd;
 112     struct i596_rfd *next;
 113     long rbd; 
 114     unsigned short count;
 115     unsigned short size;
 116     char data[1532];
 117 };
 118 
 119 #define RX_RING_SIZE 16
 120 
 121 struct i596_scb {
 122     unsigned short status;
 123     unsigned short command;
 124     struct i596_cmd *cmd;
 125     struct i596_rfd *rfd;
 126     unsigned long crc_err;
 127     unsigned long align_err;
 128     unsigned long resource_err;
 129     unsigned long over_err;
 130     unsigned long rcvdt_err;
 131     unsigned long short_err;
 132     unsigned short t_on;
 133     unsigned short t_off;
 134 };
 135 
 136 struct i596_iscp {
 137     unsigned long stat;
 138     struct i596_scb *scb;
 139 };
 140 
 141 struct i596_scp {
 142     unsigned long sysbus;
 143     unsigned long pad;
 144     struct i596_iscp *iscp;
 145 };
 146 
 147 struct i596_private {
 148     struct i596_scp scp;
 149     struct i596_iscp iscp;
 150     struct i596_scb scb;
 151     struct i596_cmd set_add;
 152     char eth_addr[8];
 153     struct i596_cmd set_conf;
 154     char i596_config[16];
 155     struct i596_cmd tdr;
 156     unsigned long stat;
 157     struct i596_rfd rx[RX_RING_SIZE];
 158     int last_restart;
 159     struct i596_rfd *rx_tail;
 160     struct i596_cmd *cmd_tail;
 161     struct i596_cmd *cmd_head;
 162     int cmd_backlog;
 163     unsigned long last_cmd;
 164     struct enet_statistics stats;
 165 };
 166 
 167 char init_setup[] = {
 168         0x8E,   /* length, prefetch on */
 169         0xC8,   /* fifo to 8, monitor off */
 170         0x80,   /* don't save bad frames */
 171         0x2E,   /* No source address insertion, 8 byte preamble */
 172         0x00,   /* priority and backoff defaults */
 173         0x60,   /* interframe spacing */
 174         0x00,   /* slot time LSB */
 175         0xf2,   /* slot time and retries */
 176         0x00,   /* promiscuous mode */
 177         0x00,   /* collision detect */
 178         0x40,   /* minimum frame length */
 179         0xff,   
 180         0x00,
 181         0x7f    /*  *multi IA */ };
 182 
 183 char adds[] = {0x00, 0x00, 0x49, 0x20, 0x54, 0xDA, 0x80, 0x00, 0x4e, 0x02, 0xb7, 0xb8};
 184 
 185 static int i596_open(struct device *dev);
 186 static int i596_start_xmit(struct sk_buff *skb, struct device *dev);
 187 static void i596_interrupt(int reg_ptr);
 188 static int i596_close(struct device *dev);
 189 static struct enet_statistics *i596_get_stats(struct device *dev);
 190 static void i596_add_cmd(struct device *dev, struct i596_cmd *cmd);
 191 static void i596_cleanup_cmd(struct i596_private *lp);
 192 static void print_eth(char *);
 193 #ifdef HAVE_MULTICAST
 194 static void set_multicast_list(struct device *dev, int num_addrs, void *addrs);
 195 #endif
 196 
 197 
 198 
 199 static inline void
 200 init_rx_bufs(struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 201 {
 202     struct i596_private *lp = (struct i596_private *)dev->priv;
 203     int i;
 204     int boguscnt = 50;
 205     short ioaddr = dev->base_addr;
 206 
 207     if (i596_debug > 1) printk ("%s: init_rx_bufs.\n", dev->name);
 208 
 209     for (i = 0; i < RX_RING_SIZE; i++)
 210     {
 211         if (i == 0)
 212         {
 213             lp->scb.rfd = &lp->rx[0];
 214         }
 215         if (i == (RX_RING_SIZE - 1))
 216         {
 217             lp->rx_tail = &(lp->rx[i]);
 218             lp->rx[i].next = &lp->rx[0];
 219             lp->rx[i].cmd = CMD_EOL;
 220         }
 221         else
 222         {
 223             lp->rx[i].next = &lp->rx[i+1];
 224             lp->rx[i].cmd = 0x0000;
 225         }
 226         lp->rx[i].stat = 0x0000;
 227         lp->rx[i].rbd = 0xffffffff;
 228         lp->rx[i].count = 0;
 229         lp->rx[i].size = 1532;
 230     }
 231 
 232     while (lp->scb.status, lp->scb.command)
 233         if (--boguscnt == 0)
 234         {
 235             printk("%s: init_rx_bufs timed out with status %4.4x, cmd %4.4x.\n",
 236                    dev->name, lp->scb.status, lp->scb.command);
 237             break;
 238         }
 239 
 240     lp->scb.command = RX_START;
 241     outw(0, ioaddr+4);
 242 
 243     return;
 244 
 245 }
 246 
 247 static inline void
 248 init_i596_mem(struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 249 {
 250     struct i596_private *lp = (struct i596_private *)dev->priv;
 251     short ioaddr = dev->base_addr;
 252     int boguscnt = 50;
 253 
 254     /* change the scp address */
 255     outw(0, ioaddr);
 256     outw(0, ioaddr);
 257     outb(4, ioaddr+0xf);
 258     outw(((((int)&lp->scp) & 0xffff) | 2), ioaddr);
 259     outw((((int)&lp->scp)>>16) & 0xffff, ioaddr);
 260 
 261     lp->last_cmd=jiffies;
 262 
 263     lp->scp.sysbus = 0x00440000;
 264     lp->scp.iscp = &(lp->iscp);
 265     lp->iscp.scb = &(lp->scb);
 266     lp->iscp.stat = 0x0001;
 267     lp->cmd_backlog = 0;
 268 
 269     lp->cmd_head = lp->scb.cmd = (struct i596_cmd *) -1;
 270 
 271     if (i596_debug > 2) printk("%s: starting i82596.\n", dev->name);
 272 
 273     (void) inb (ioaddr+0x10);
 274     outb(4, ioaddr+0xf);
 275     outw(0, ioaddr+4);
 276 
 277     while (lp->iscp.stat)
 278         if (--boguscnt == 0)
 279         {
 280             printk("%s: i82596 initialization timed out with status %4.4x, cmd %4.4x.\n",
 281                    dev->name, lp->scb.status, lp->scb.command);
 282             break;
 283         }
 284 
 285     memcpy (lp->i596_config, init_setup, 14);
 286     lp->set_conf.command = CmdConfigure;
 287     i596_add_cmd(dev, &lp->set_conf);
 288 
 289     memcpy (lp->eth_addr, dev->dev_addr, 6);
 290     lp->set_add.command = CmdSASetup;
 291     i596_add_cmd(dev, &lp->set_add);
 292 
 293     lp->tdr.command = CmdTDR;
 294     i596_add_cmd(dev, &lp->tdr);
 295 
 296     init_rx_bufs(dev);
 297 
 298     return;
 299 
 300 }
 301 
 302 static inline int
 303 i596_rx(struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 304 {
 305     struct i596_private *lp = (struct i596_private *)dev->priv;
 306     int frames=0;
 307 
 308     if (i596_debug > 3) printk ("i596_rx()\n");
 309 
 310     while ((lp->scb.rfd->stat) & STAT_C)
 311     {
 312         if (i596_debug >2) print_eth(lp->scb.rfd->data);
 313 
 314         if ((lp->scb.rfd->stat) & STAT_OK)
 315         {
 316             /* a good frame */
 317             int pkt_len = lp->scb.rfd->count & 0x3fff;
 318             struct sk_buff *skb = alloc_skb(pkt_len, GFP_ATOMIC);
 319 
 320             frames++;
 321 
 322             if (skb == NULL)
 323             {
 324                 printk ("%s: i596_rx Memory squeeze, dropping packet.\n", dev->name);
 325                 lp->stats.rx_dropped++;
 326                 break;
 327             }
 328 
 329             skb->len = pkt_len;
 330             skb->dev=dev;               
 331             memcpy(skb->data, lp->scb.rfd->data, pkt_len);
 332 
 333             netif_rx(skb);
 334             lp->stats.rx_packets++;
 335 
 336             if (i596_debug > 4) print_eth(skb->data);
 337         }
 338         else
 339         {
 340             lp->stats.rx_errors++;
 341             if ((lp->scb.rfd->stat) & 0x0001) lp->stats.collisions++;
 342             if ((lp->scb.rfd->stat) & 0x0080) lp->stats.rx_length_errors++;
 343             if ((lp->scb.rfd->stat) & 0x0100) lp->stats.rx_over_errors++;
 344             if ((lp->scb.rfd->stat) & 0x0200) lp->stats.rx_fifo_errors++;
 345             if ((lp->scb.rfd->stat) & 0x0400) lp->stats.rx_frame_errors++;
 346             if ((lp->scb.rfd->stat) & 0x0800) lp->stats.rx_crc_errors++;
 347             if ((lp->scb.rfd->stat) & 0x1000) lp->stats.rx_length_errors++;
 348         }
 349 
 350         lp->scb.rfd->stat=0;
 351         lp->rx_tail->cmd=0;
 352         lp->rx_tail=lp->scb.rfd;
 353         lp->scb.rfd=lp->scb.rfd->next;
 354         lp->rx_tail->count=0;
 355         lp->rx_tail->cmd=CMD_EOL;
 356 
 357     }
 358 
 359     if (i596_debug > 3) printk ("frames %d\n", frames);
 360 
 361     return 0;
 362 }
 363 
 364 
 365 static void i596_add_cmd(struct device *dev, struct i596_cmd *cmd)
     /* [previous][next][first][last][top][bottom][index][help] */
 366 {
 367     struct i596_private *lp = (struct i596_private *)dev->priv;
 368     int ioaddr = dev->base_addr;
 369     unsigned long flags;
 370     int boguscnt = 50;
 371 
 372     if (i596_debug > 4) printk ("i596_add_cmd\n");
 373 
 374     cmd->status = 0;
 375     cmd->command |= (CMD_EOL|CMD_INTR);
 376     cmd->next = (struct i596_cmd *) -1;
 377 
 378     save_flags(flags);
 379     cli();
 380     if (lp->cmd_head != (struct i596_cmd *) -1)
 381         lp->cmd_tail->next = cmd;
 382     else 
 383     {
 384         lp->cmd_head=cmd;
 385         while (lp->scb.status, lp->scb.command)
 386             if (--boguscnt == 0)
 387             {
 388                 printk("i596_add_cmd timed out with status %4.4x, cmd %4.4x.\n",
 389                    lp->scb.status, lp->scb.command);
 390                 break;
 391             }
 392 
 393         lp->scb.cmd = cmd;
 394         lp->scb.command = CUC_START;
 395         outw (0, ioaddr+4);
 396     }
 397     lp->cmd_tail=cmd;
 398     lp->cmd_backlog++;
 399 
 400     lp->cmd_head=lp->scb.cmd;
 401     restore_flags(flags);
 402 
 403     if (lp->cmd_backlog > 8) 
 404     {
 405         int tickssofar = jiffies - lp->last_cmd;
 406         if (tickssofar < 10)
 407             return;
 408         printk("%s: command unit timed out, status resetting.\n",
 409                dev->name);
 410 
 411         boguscnt = 50;
 412         while (lp->scb.status, lp->scb.command)
 413             if (--boguscnt == 0)
 414             {
 415                 printk("i596_add_cmd timed out with status %4.4x, cmd %4.4x.\n",
 416                     lp->scb.status, lp->scb.command);
 417                 break;
 418             }
 419         lp->scb.command=CUC_ABORT|RX_ABORT;
 420         outw(0, ioaddr+4);
 421 
 422         i596_cleanup_cmd(lp);
 423         i596_rx(dev);
 424         init_i596_mem(dev);
 425     }
 426 
 427 }
 428 
 429 
 430 
 431 static void i596_cleanup_cmd(struct i596_private *lp)
     /* [previous][next][first][last][top][bottom][index][help] */
 432 {
 433     struct i596_cmd *ptr;
 434     int boguscnt = 50;
 435 
 436     if (i596_debug > 4) printk ("i596_cleanup_cmd\n");
 437 
 438     while (lp->cmd_head != (struct i596_cmd *) -1)
 439     {
 440         ptr = lp->cmd_head;
 441 
 442         lp->cmd_head = lp->cmd_head->next;
 443         lp->cmd_backlog--;
 444 
 445         switch ((ptr->command) & 0x7)
 446         {
 447             case CmdTx:
 448             {
 449                 struct tx_cmd *tx_cmd = (struct tx_cmd *) ptr;
 450                 struct sk_buff *skb = ((struct sk_buff *)(tx_cmd->tbd->data)) -1;
 451 
 452                 dev_kfree_skb(skb, FREE_WRITE);
 453 
 454                 lp->stats.tx_errors++;
 455                 lp->stats.tx_aborted_errors++;
 456 
 457                 ptr->next = (struct i596_cmd * ) -1;
 458                 kfree_s((unsigned char *)tx_cmd, (sizeof (struct tx_cmd) + sizeof (struct i596_tbd)));
 459                 break;
 460             }
 461             case CmdMulticastList:
 462             {
 463                 unsigned short count = *((unsigned short *) (ptr + 1));
 464 
 465                 ptr->next = (struct i596_cmd * ) -1;
 466                 kfree_s((unsigned char *)ptr, (sizeof (struct i596_cmd) + count + 2));
 467                 break;
 468             }
 469             default:
 470                 ptr->next = (struct i596_cmd * ) -1;
 471         }
 472     }
 473 
 474     while (lp->scb.status, lp->scb.command)
 475         if (--boguscnt == 0)
 476         {
 477             printk("i596_cleanup_cmd timed out with status %4.4x, cmd %4.4x.\n",
 478                 lp->scb.status, lp->scb.command);
 479             break;
 480         }
 481 
 482     lp->scb.cmd = lp->cmd_head;
 483 }
 484 
 485 
 486 
 487 
 488 static int
 489 i596_open(struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 490 {
 491     if (request_irq(dev->irq, &i596_interrupt)) {
 492         return -EAGAIN;
 493     }
 494 
 495     irq2dev_map[dev->irq] = dev;
 496 
 497     if (i596_debug > 1)
 498         printk("%s: i596_open() irq %d.\n",
 499                dev->name, dev->irq);
 500 
 501     dev->tbusy = 0;
 502     dev->interrupt = 0;
 503     dev->start = 1;
 504 
 505     /* Initialize the 82596 memory */
 506     init_i596_mem(dev);
 507 
 508     return 0;                   /* Always succeed */
 509 }
 510 
 511 static int
 512 i596_start_xmit(struct sk_buff *skb, struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 513 {
 514     struct i596_private *lp = (struct i596_private *)dev->priv;
 515     int ioaddr = dev->base_addr;
 516     struct tx_cmd *tx_cmd;
 517 
 518     if (i596_debug > 2) printk ("%s: Apricot start xmit\n", dev->name);
 519 
 520     /* Transmitter timeout, serious problems. */
 521     if (dev->tbusy) {
 522         int tickssofar = jiffies - dev->trans_start;
 523         if (tickssofar < 5)
 524             return 1;
 525         printk("%s: transmit timed out, status resetting.\n",
 526                dev->name);
 527         lp->stats.tx_errors++;
 528         /* Try to restart the adaptor */
 529         if (lp->last_restart == lp->stats.tx_packets) {
 530             if (i596_debug > 1) printk ("Resetting board.\n");
 531             /* Shutdown and restart */
 532             
 533             lp->scb.command=CUC_ABORT|RX_ABORT;
 534             outw(0, ioaddr+4);
 535 
 536             i596_cleanup_cmd(lp);
 537             init_i596_mem(dev);
 538         } else {
 539             /* Issue a channel attention signal */
 540             if (i596_debug > 1) printk ("Kicking board.\n");
 541 
 542             lp->scb.command=CUC_START|RX_START;
 543             outw(0, ioaddr+4);
 544 
 545             lp->last_restart = lp->stats.tx_packets;
 546         }
 547         dev->tbusy = 0;
 548         dev->trans_start = jiffies;
 549     }
 550 
 551     /* If some higher level thinks we've misses a tx-done interrupt
 552        we are passed NULL. n.b. dev_tint handles the cli()/sti()
 553        itself. */
 554     if (skb == NULL) {
 555         dev_tint(dev);
 556         return 0;
 557     }
 558 
 559     /* shouldn't happen */
 560     if (skb->len <= 0) return 0;
 561 
 562     if (i596_debug > 3) printk("%s: i596_start_xmit() called\n", dev->name);
 563 
 564     /* Block a timer-based transmit from overlapping.  This could better be
 565        done with atomic_swap(1, dev->tbusy), but set_bit() works as well. */
 566     if (set_bit(0, (void*)&dev->tbusy) != 0)
 567         printk("%s: Transmitter access conflict.\n", dev->name);
 568     else
 569     {
 570         short length = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN;
 571         dev->trans_start=jiffies;
 572 
 573         tx_cmd = (struct tx_cmd *) kmalloc ((sizeof (struct tx_cmd) + sizeof (struct i596_tbd)), GFP_ATOMIC);
 574         if (tx_cmd == NULL)
 575         {
 576             printk ("%s: i596_xmit Memory squeeze, dropping packet.\n", dev->name);
 577             lp->stats.tx_dropped++;
 578 
 579             dev_kfree_skb(skb, FREE_WRITE);
 580         }
 581         else
 582         {
 583             tx_cmd->tbd = (struct i596_tbd *) (tx_cmd + 1);
 584             tx_cmd->tbd->next = (struct i596_tbd *) -1;
 585 
 586             tx_cmd->cmd.command = CMD_FLEX|CmdTx;
 587 
 588             tx_cmd->pad = 0;
 589             tx_cmd->size = 0;
 590             tx_cmd->tbd->pad = 0;
 591             tx_cmd->tbd->size = EOF | length;
 592 
 593             tx_cmd->tbd->data = skb->data;
 594 
 595             if (i596_debug > 3) print_eth(skb->data);
 596 
 597             i596_add_cmd(dev, (struct i596_cmd *)tx_cmd);
 598 
 599             lp->stats.tx_packets++;
 600         }
 601     }
 602 
 603     dev->tbusy = 0;
 604 
 605     return 0;
 606 }
 607 
 608 
 609 
 610 static void print_eth(char *add)
     /* [previous][next][first][last][top][bottom][index][help] */
 611 {
 612     int i;
 613 
 614     printk ("Dest  ");
 615     for (i = 0; i < 6; i++)
 616         printk(" %2.2X", (unsigned char)add[i]);
 617     printk ("\n");
 618 
 619     printk ("Source");
 620     for (i = 0; i < 6; i++)
 621         printk(" %2.2X", (unsigned char)add[i+6]);
 622     printk ("\n");
 623     printk ("type %2.2X%2.2X\n", (unsigned char)add[12], (unsigned char)add[13]);
 624 }
 625 
 626 unsigned long apricot_init(unsigned long mem_start, unsigned long mem_end)
     /* [previous][next][first][last][top][bottom][index][help] */
 627 {
 628     struct device *dev;
 629     int i;
 630     int checksum = 0;
 631     int ioaddr = 0x300;
 632 
 633     /* this is easy the ethernet interface can only be at 0x300 */
 634     /* first check nothing is already registered here */
 635 
 636     if (check_region(ioaddr, APRICOT_TOTAL_SIZE))
 637         return mem_start;
 638 
 639     /* very similar to the SMC card except that the checksum is 0x200 */
 640     for (i = 0; i < 8; i++)
 641         checksum += inb(ioaddr + 8 + i);
 642 
 643     if (checksum != 0x200) return mem_start;
 644 
 645     dev = init_etherdev(0, (sizeof (struct i596_private) + 0xf), &mem_start);
 646 
 647     printk("%s: Apricot 82596 at %#3x,", dev->name, ioaddr);
 648 
 649     for (i = 0; i < 6; i++)
 650         printk(" %2.2X", dev->dev_addr[i] = inb(ioaddr +8 + i));
 651 
 652     dev->base_addr = ioaddr;
 653     dev->irq = 10;
 654     printk(" IRQ %d.\n", dev->irq);
 655 
 656     snarf_region(ioaddr, APRICOT_TOTAL_SIZE);
 657 
 658     if (i596_debug > 0)
 659         printk(version);
 660 
 661     /* The APRICOT-specific entries in the device structure. */
 662     dev->open = &i596_open;
 663     dev->stop = &i596_close;
 664     dev->hard_start_xmit = &i596_start_xmit;
 665     dev->get_stats = &i596_get_stats;
 666 #ifdef HAVE_MULTICAST
 667     dev->set_multicast_list = &set_multicast_list;
 668 #endif
 669 
 670     /* align for scp */
 671     dev->priv = (void *)(((int) dev->priv + 0xf) & 0xfffffff0);
 672 
 673     return mem_start;
 674 }
 675 
 676 
 677 static void
 678 i596_interrupt(int reg_ptr)
     /* [previous][next][first][last][top][bottom][index][help] */
 679 {
 680     int irq = -(((struct pt_regs *)reg_ptr)->orig_eax+2);
 681     struct device *dev = (struct device *)(irq2dev_map[irq]);
 682     struct i596_private *lp;
 683     short ioaddr;
 684     int boguscnt = 100;
 685     unsigned short status, ack_cmd=0;
 686 
 687     if (dev == NULL) {
 688         printk ("i596_interrupt(): irq %d for unknown device.\n", irq);
 689         return;
 690     }
 691 
 692     if (i596_debug > 3) printk ("%s: i596_interrupt(): irq %d\n",dev->name, irq);
 693 
 694     if (dev->interrupt)
 695         printk("%s: Re-entering the interrupt handler.\n", dev->name);
 696 
 697     dev->interrupt = 1;
 698 
 699     ioaddr = dev->base_addr;
 700 
 701     lp = (struct i596_private *)dev->priv;
 702 
 703     while (lp->scb.status, lp->scb.command)
 704         if (--boguscnt == 0)
 705             {
 706                 printk("%s: i596 interrupt, timeout status %4.4x command %4.4x.\n", dev->name, lp->scb.status, lp->scb.command);
 707                 break;
 708             }
 709     status = lp->scb.status;
 710 
 711     if (i596_debug > 4)
 712         printk("%s: i596 interrupt, status %4.4x.\n", dev->name, status);
 713 
 714     ack_cmd = status & 0xf000;
 715 
 716     if ((status & 0x8000) || (status & 0x2000))
 717     {
 718         struct i596_cmd *ptr;
 719 
 720         if ((i596_debug > 4) && (status & 0x8000))
 721             printk("%s: i596 interrupt completed command.\n", dev->name);
 722         if ((i596_debug > 4) && (status & 0x2000))
 723             printk("%s: i596 interrupt command unit inactive %x.\n", dev->name, status & 0x0700);
 724 
 725         while ((lp->cmd_head != (struct i596_cmd *) -1) && (lp->cmd_head->status & STAT_C))
 726         {
 727             ptr = lp->cmd_head;
 728 
 729             lp->cmd_head = lp->cmd_head->next;
 730             lp->cmd_backlog--;
 731 
 732             switch ((ptr->command) & 0x7)
 733             {
 734                 case CmdTx:
 735                 {
 736                     struct tx_cmd *tx_cmd = (struct tx_cmd *) ptr;
 737                     struct sk_buff *skb = ((struct sk_buff *)(tx_cmd->tbd->data)) -1;
 738 
 739                     dev_kfree_skb(skb, FREE_WRITE);
 740 
 741                     if ((ptr->status) & STAT_OK)
 742                     {
 743                         if (i596_debug >2) print_eth(skb->data);
 744                     }
 745                     else
 746                     {
 747                         lp->stats.tx_errors++;
 748                         if ((ptr->status) & 0x0020) lp->stats.collisions++;
 749                         if (!((ptr->status) & 0x0040)) lp->stats.tx_heartbeat_errors++;
 750                         if ((ptr->status) & 0x0400) lp->stats.tx_carrier_errors++;
 751                         if ((ptr->status) & 0x0800) lp->stats.collisions++;
 752                         if ((ptr->status) & 0x1000) lp->stats.tx_aborted_errors++;
 753                     }
 754 
 755 
 756                     ptr->next = (struct i596_cmd * ) -1;
 757                     kfree_s((unsigned char *)tx_cmd, (sizeof (struct tx_cmd) + sizeof (struct i596_tbd)));
 758                     break;
 759                 }
 760                 case CmdMulticastList:
 761                 {
 762                     unsigned short count = *((unsigned short *) (ptr + 1));
 763 
 764                     ptr->next = (struct i596_cmd * ) -1;
 765                     kfree_s((unsigned char *)ptr, (sizeof (struct i596_cmd) + count + 2));
 766                     break;
 767                 }
 768                 case CmdTDR:
 769                 {
 770                     unsigned long status = *((unsigned long *) (ptr + 1));
 771 
 772                     if (status & 0x8000)
 773                     {
 774                         if (i596_debug > 3)
 775                             printk("%s: link ok.\n", dev->name);
 776                     }
 777                     else
 778                     {
 779                         if (status & 0x4000)
 780                             printk("%s: Transceiver problem.\n", dev->name);
 781                         if (status & 0x2000)
 782                             printk("%s: Termination problem.\n", dev->name);
 783                         if (status & 0x1000)
 784                             printk("%s: Short circuit.\n", dev->name);
 785 
 786                         printk("%s: Time %ld.\n", dev->name, status & 0x07ff);
 787                     }
 788                 }
 789                 default:
 790                     ptr->next = (struct i596_cmd * ) -1;
 791 
 792                 lp->last_cmd=jiffies;
 793             }
 794         }
 795 
 796         ptr = lp->cmd_head;
 797         while ((ptr != (struct i596_cmd *) -1) && (ptr != lp->cmd_tail))
 798         {
 799             ptr->command &= 0x1fff;
 800             ptr = ptr->next;
 801         }
 802 
 803         if ((lp->cmd_head != (struct i596_cmd *) -1) && (dev->start)) ack_cmd |= CUC_START;
 804         lp->scb.cmd = lp->cmd_head;
 805     }
 806 
 807     if ((status & 0x1000) || (status & 0x4000))
 808     {
 809         if ((i596_debug > 4) && (status & 0x4000))
 810             printk("%s: i596 interrupt received a frame.\n", dev->name);
 811         if ((i596_debug > 4) && (status & 0x1000))
 812             printk("%s: i596 interrupt receive unit inactive %x.\n", dev->name, status & 0x0070);
 813 
 814         i596_rx(dev);
 815 
 816         if (dev->start) ack_cmd |= RX_START;
 817     }
 818 
 819     /* acknowlage the interrupt */
 820 
 821 /*
 822     if ((lp->scb.cmd != (struct i596_cmd *) -1) && (dev->start)) ack_cmd |= CUC_START;
 823 */
 824     boguscnt = 100;
 825     while (lp->scb.status, lp->scb.command)
 826         if (--boguscnt == 0)
 827             {
 828                 printk("%s: i596 interrupt, timeout status %4.4x command %4.4x.\n", dev->name, lp->scb.status, lp->scb.command);
 829                 break;
 830             }
 831     lp->scb.command = ack_cmd;
 832 
 833     (void) inb (ioaddr+0x10);
 834     outb (4, ioaddr+0xf);
 835     outw (0, ioaddr+4);
 836 
 837     if (i596_debug > 4)
 838         printk("%s: exiting interrupt.\n", dev->name);
 839 
 840     dev->interrupt = 0;
 841     return;
 842 }
 843 
 844 static int
 845 i596_close(struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 846 {
 847     int ioaddr = dev->base_addr;
 848     struct i596_private *lp = (struct i596_private *)dev->priv;
 849 
 850     dev->start = 0;
 851     dev->tbusy = 1;
 852 
 853     if (i596_debug > 1)
 854         printk("%s: Shutting down ethercard, status was %4.4x.\n",
 855                dev->name, lp->scb.status);
 856 
 857     lp->scb.command = CUC_ABORT|RX_ABORT;
 858     outw(0, ioaddr+4);
 859 
 860     i596_cleanup_cmd(lp);
 861 
 862     free_irq(dev->irq);
 863     irq2dev_map[dev->irq] = 0;
 864 
 865     return 0;
 866 }
 867 
 868 static struct enet_statistics *
 869 i596_get_stats(struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 870 {
 871     struct i596_private *lp = (struct i596_private *)dev->priv;
 872 
 873     return &lp->stats;
 874 }
 875 
 876 #ifdef HAVE_MULTICAST
 877 /* Set or clear the multicast filter for this adaptor.
 878    num_addrs == -1      Promiscuous mode, receive all packets
 879    num_addrs == 0       Normal mode, clear multicast list
 880    num_addrs > 0        Multicast mode, receive normal and MC packets, and do
 881                         best-effort filtering.
 882  */
 883 static void
 884 set_multicast_list(struct device *dev, int num_addrs, void *addrs)
     /* [previous][next][first][last][top][bottom][index][help] */
 885 {
 886     struct i596_private *lp = (struct i596_private *)dev->priv;
 887     struct i596_cmd *cmd;
 888 
 889     if (i596_debug > 1)
 890         printk ("%s: set multicast list %d\n", dev->name, num_addrs);
 891 
 892     if (num_addrs > 0) {
 893         cmd = (struct i596_cmd *) kmalloc(sizeof(struct i596_cmd)+2+num_addrs*6, GFP_ATOMIC);
 894         if (cmd == NULL)
 895         {
 896             printk ("%s: set_multicast Memory squeeze.\n", dev->name);
 897             return;
 898         }
 899 
 900             cmd->command = CmdMulticastList;
 901             *((unsigned short *) (cmd + 1)) = num_addrs * 6;
 902             memcpy (((char *)(cmd + 1))+2, addrs, num_addrs * 6);
 903             print_eth (((char *)(cmd + 1)) + 2);
 904                 
 905             i596_add_cmd(dev, cmd);
 906     } else
 907     {
 908         if (lp->set_conf.next != (struct i596_cmd * ) -1) return;
 909         if (num_addrs == 0)
 910             lp->i596_config[8] &= ~0x01;
 911         else
 912             lp->i596_config[8] |= 0x01;
 913 
 914         i596_add_cmd(dev, &lp->set_conf);
 915     }
 916 
 917 }
 918 #endif
 919 
 920 #ifdef HAVE_DEVLIST
 921 static unsigned int apricot_portlist[] = {0x300, 0};
 922 struct netdev_entry apricot_drv =
 923 {"apricot", apricot_init, APRICOT_TOTAL_SIZE, apricot_portlist};
 924 #endif
 925 
 926 /*
 927  * Local variables:
 928  *  compile-command: "gcc -D__KERNEL__ -I/usr/src/linux/net/inet -Wall -Wstrict-prototypes -O6 -m486 -c apricot.c"
 929  * End:
 930  */

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