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     for (i = 0; i < 8; i++)
 640         checksum += inb(ioaddr + 8 + i);
 641 
 642     /* checksum is a multiple of 0x100, got this wrong first time
 643        some machines have 0x100, some 0x200. The DOS driver doesn't
 644        even bother with the checksum */
 645 
 646     if (checksum % 0x100) return mem_start;
 647 
 648     dev = init_etherdev(0, (sizeof (struct i596_private) + 0xf), &mem_start);
 649 
 650     printk("%s: Apricot 82596 at %#3x,", dev->name, ioaddr);
 651 
 652     for (i = 0; i < 6; i++)
 653         printk(" %2.2X", dev->dev_addr[i] = inb(ioaddr +8 + i));
 654 
 655     dev->base_addr = ioaddr;
 656     dev->irq = 10;
 657     printk(" IRQ %d.\n", dev->irq);
 658 
 659     snarf_region(ioaddr, APRICOT_TOTAL_SIZE);
 660 
 661     if (i596_debug > 0)
 662         printk(version);
 663 
 664     /* The APRICOT-specific entries in the device structure. */
 665     dev->open = &i596_open;
 666     dev->stop = &i596_close;
 667     dev->hard_start_xmit = &i596_start_xmit;
 668     dev->get_stats = &i596_get_stats;
 669 #ifdef HAVE_MULTICAST
 670     dev->set_multicast_list = &set_multicast_list;
 671 #endif
 672 
 673     /* align for scp */
 674     dev->priv = (void *)(((int) dev->priv + 0xf) & 0xfffffff0);
 675 
 676     return mem_start;
 677 }
 678 
 679 
 680 static void
 681 i596_interrupt(int reg_ptr)
     /* [previous][next][first][last][top][bottom][index][help] */
 682 {
 683     int irq = -(((struct pt_regs *)reg_ptr)->orig_eax+2);
 684     struct device *dev = (struct device *)(irq2dev_map[irq]);
 685     struct i596_private *lp;
 686     short ioaddr;
 687     int boguscnt = 100;
 688     unsigned short status, ack_cmd=0;
 689 
 690     if (dev == NULL) {
 691         printk ("i596_interrupt(): irq %d for unknown device.\n", irq);
 692         return;
 693     }
 694 
 695     if (i596_debug > 3) printk ("%s: i596_interrupt(): irq %d\n",dev->name, irq);
 696 
 697     if (dev->interrupt)
 698         printk("%s: Re-entering the interrupt handler.\n", dev->name);
 699 
 700     dev->interrupt = 1;
 701 
 702     ioaddr = dev->base_addr;
 703 
 704     lp = (struct i596_private *)dev->priv;
 705 
 706     while (lp->scb.status, lp->scb.command)
 707         if (--boguscnt == 0)
 708             {
 709                 printk("%s: i596 interrupt, timeout status %4.4x command %4.4x.\n", dev->name, lp->scb.status, lp->scb.command);
 710                 break;
 711             }
 712     status = lp->scb.status;
 713 
 714     if (i596_debug > 4)
 715         printk("%s: i596 interrupt, status %4.4x.\n", dev->name, status);
 716 
 717     ack_cmd = status & 0xf000;
 718 
 719     if ((status & 0x8000) || (status & 0x2000))
 720     {
 721         struct i596_cmd *ptr;
 722 
 723         if ((i596_debug > 4) && (status & 0x8000))
 724             printk("%s: i596 interrupt completed command.\n", dev->name);
 725         if ((i596_debug > 4) && (status & 0x2000))
 726             printk("%s: i596 interrupt command unit inactive %x.\n", dev->name, status & 0x0700);
 727 
 728         while ((lp->cmd_head != (struct i596_cmd *) -1) && (lp->cmd_head->status & STAT_C))
 729         {
 730             ptr = lp->cmd_head;
 731 
 732             lp->cmd_head = lp->cmd_head->next;
 733             lp->cmd_backlog--;
 734 
 735             switch ((ptr->command) & 0x7)
 736             {
 737                 case CmdTx:
 738                 {
 739                     struct tx_cmd *tx_cmd = (struct tx_cmd *) ptr;
 740                     struct sk_buff *skb = ((struct sk_buff *)(tx_cmd->tbd->data)) -1;
 741 
 742                     dev_kfree_skb(skb, FREE_WRITE);
 743 
 744                     if ((ptr->status) & STAT_OK)
 745                     {
 746                         if (i596_debug >2) print_eth(skb->data);
 747                     }
 748                     else
 749                     {
 750                         lp->stats.tx_errors++;
 751                         if ((ptr->status) & 0x0020) lp->stats.collisions++;
 752                         if (!((ptr->status) & 0x0040)) lp->stats.tx_heartbeat_errors++;
 753                         if ((ptr->status) & 0x0400) lp->stats.tx_carrier_errors++;
 754                         if ((ptr->status) & 0x0800) lp->stats.collisions++;
 755                         if ((ptr->status) & 0x1000) lp->stats.tx_aborted_errors++;
 756                     }
 757 
 758 
 759                     ptr->next = (struct i596_cmd * ) -1;
 760                     kfree_s((unsigned char *)tx_cmd, (sizeof (struct tx_cmd) + sizeof (struct i596_tbd)));
 761                     break;
 762                 }
 763                 case CmdMulticastList:
 764                 {
 765                     unsigned short count = *((unsigned short *) (ptr + 1));
 766 
 767                     ptr->next = (struct i596_cmd * ) -1;
 768                     kfree_s((unsigned char *)ptr, (sizeof (struct i596_cmd) + count + 2));
 769                     break;
 770                 }
 771                 case CmdTDR:
 772                 {
 773                     unsigned long status = *((unsigned long *) (ptr + 1));
 774 
 775                     if (status & 0x8000)
 776                     {
 777                         if (i596_debug > 3)
 778                             printk("%s: link ok.\n", dev->name);
 779                     }
 780                     else
 781                     {
 782                         if (status & 0x4000)
 783                             printk("%s: Transceiver problem.\n", dev->name);
 784                         if (status & 0x2000)
 785                             printk("%s: Termination problem.\n", dev->name);
 786                         if (status & 0x1000)
 787                             printk("%s: Short circuit.\n", dev->name);
 788 
 789                         printk("%s: Time %ld.\n", dev->name, status & 0x07ff);
 790                     }
 791                 }
 792                 default:
 793                     ptr->next = (struct i596_cmd * ) -1;
 794 
 795                 lp->last_cmd=jiffies;
 796             }
 797         }
 798 
 799         ptr = lp->cmd_head;
 800         while ((ptr != (struct i596_cmd *) -1) && (ptr != lp->cmd_tail))
 801         {
 802             ptr->command &= 0x1fff;
 803             ptr = ptr->next;
 804         }
 805 
 806         if ((lp->cmd_head != (struct i596_cmd *) -1) && (dev->start)) ack_cmd |= CUC_START;
 807         lp->scb.cmd = lp->cmd_head;
 808     }
 809 
 810     if ((status & 0x1000) || (status & 0x4000))
 811     {
 812         if ((i596_debug > 4) && (status & 0x4000))
 813             printk("%s: i596 interrupt received a frame.\n", dev->name);
 814         if ((i596_debug > 4) && (status & 0x1000))
 815             printk("%s: i596 interrupt receive unit inactive %x.\n", dev->name, status & 0x0070);
 816 
 817         i596_rx(dev);
 818 
 819         if (dev->start) ack_cmd |= RX_START;
 820     }
 821 
 822     /* acknowlage the interrupt */
 823 
 824 /*
 825     if ((lp->scb.cmd != (struct i596_cmd *) -1) && (dev->start)) ack_cmd |= CUC_START;
 826 */
 827     boguscnt = 100;
 828     while (lp->scb.status, lp->scb.command)
 829         if (--boguscnt == 0)
 830             {
 831                 printk("%s: i596 interrupt, timeout status %4.4x command %4.4x.\n", dev->name, lp->scb.status, lp->scb.command);
 832                 break;
 833             }
 834     lp->scb.command = ack_cmd;
 835 
 836     (void) inb (ioaddr+0x10);
 837     outb (4, ioaddr+0xf);
 838     outw (0, ioaddr+4);
 839 
 840     if (i596_debug > 4)
 841         printk("%s: exiting interrupt.\n", dev->name);
 842 
 843     dev->interrupt = 0;
 844     return;
 845 }
 846 
 847 static int
 848 i596_close(struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 849 {
 850     int ioaddr = dev->base_addr;
 851     struct i596_private *lp = (struct i596_private *)dev->priv;
 852 
 853     dev->start = 0;
 854     dev->tbusy = 1;
 855 
 856     if (i596_debug > 1)
 857         printk("%s: Shutting down ethercard, status was %4.4x.\n",
 858                dev->name, lp->scb.status);
 859 
 860     lp->scb.command = CUC_ABORT|RX_ABORT;
 861     outw(0, ioaddr+4);
 862 
 863     i596_cleanup_cmd(lp);
 864 
 865     free_irq(dev->irq);
 866     irq2dev_map[dev->irq] = 0;
 867 
 868     return 0;
 869 }
 870 
 871 static struct enet_statistics *
 872 i596_get_stats(struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 873 {
 874     struct i596_private *lp = (struct i596_private *)dev->priv;
 875 
 876     return &lp->stats;
 877 }
 878 
 879 #ifdef HAVE_MULTICAST
 880 /* Set or clear the multicast filter for this adaptor.
 881    num_addrs == -1      Promiscuous mode, receive all packets
 882    num_addrs == 0       Normal mode, clear multicast list
 883    num_addrs > 0        Multicast mode, receive normal and MC packets, and do
 884                         best-effort filtering.
 885  */
 886 static void
 887 set_multicast_list(struct device *dev, int num_addrs, void *addrs)
     /* [previous][next][first][last][top][bottom][index][help] */
 888 {
 889     struct i596_private *lp = (struct i596_private *)dev->priv;
 890     struct i596_cmd *cmd;
 891 
 892     if (i596_debug > 1)
 893         printk ("%s: set multicast list %d\n", dev->name, num_addrs);
 894 
 895     if (num_addrs > 0) {
 896         cmd = (struct i596_cmd *) kmalloc(sizeof(struct i596_cmd)+2+num_addrs*6, GFP_ATOMIC);
 897         if (cmd == NULL)
 898         {
 899             printk ("%s: set_multicast Memory squeeze.\n", dev->name);
 900             return;
 901         }
 902 
 903             cmd->command = CmdMulticastList;
 904             *((unsigned short *) (cmd + 1)) = num_addrs * 6;
 905             memcpy (((char *)(cmd + 1))+2, addrs, num_addrs * 6);
 906             print_eth (((char *)(cmd + 1)) + 2);
 907                 
 908             i596_add_cmd(dev, cmd);
 909     } else
 910     {
 911         if (lp->set_conf.next != (struct i596_cmd * ) -1) return;
 912         if (num_addrs == 0)
 913             lp->i596_config[8] &= ~0x01;
 914         else
 915             lp->i596_config[8] |= 0x01;
 916 
 917         i596_add_cmd(dev, &lp->set_conf);
 918     }
 919 
 920 }
 921 #endif
 922 
 923 #ifdef HAVE_DEVLIST
 924 static unsigned int apricot_portlist[] = {0x300, 0};
 925 struct netdev_entry apricot_drv =
 926 {"apricot", apricot_init, APRICOT_TOTAL_SIZE, apricot_portlist};
 927 #endif
 928 
 929 /*
 930  * Local variables:
 931  *  compile-command: "gcc -D__KERNEL__ -I/usr/src/linux/net/inet -Wall -Wstrict-prototypes -O6 -m486 -c apricot.c"
 932  * End:
 933  */

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