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_cleanup_cmd
  5. i596_reset
  6. i596_add_cmd
  7. i596_open
  8. i596_start_xmit
  9. print_eth
  10. apricot_init
  11. i596_interrupt
  12. i596_close
  13. i596_get_stats
  14. 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 flexible 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 print_eth(char *);
 192 #ifdef HAVE_MULTICAST
 193 static void set_multicast_list(struct device *dev, int num_addrs, void *addrs);
 194 #endif
 195 
 196 
 197 static inline void
 198 init_rx_bufs(struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 199 {
 200     struct i596_private *lp = (struct i596_private *)dev->priv;
 201     int i;
 202     int boguscnt = 100;
 203     short ioaddr = dev->base_addr;
 204 
 205     if (i596_debug > 1) printk ("%s: init_rx_bufs.\n", dev->name);
 206 
 207     for (i = 0; i < RX_RING_SIZE; i++)
 208     {
 209         if (i == 0)
 210         {
 211             lp->scb.rfd = &lp->rx[0];
 212         }
 213         if (i == (RX_RING_SIZE - 1))
 214         {
 215             lp->rx_tail = &(lp->rx[i]);
 216             lp->rx[i].next = &lp->rx[0];
 217             lp->rx[i].cmd = CMD_EOL;
 218         }
 219         else
 220         {
 221             lp->rx[i].next = &lp->rx[i+1];
 222             lp->rx[i].cmd = 0x0000;
 223         }
 224         lp->rx[i].stat = 0x0000;
 225         lp->rx[i].rbd = 0xffffffff;
 226         lp->rx[i].count = 0;
 227         lp->rx[i].size = 1532;
 228     }
 229 
 230     while (lp->scb.status, lp->scb.command)
 231         if (--boguscnt == 0)
 232         {
 233             printk("%s: init_rx_bufs timed out with status %4.4x, cmd %4.4x.\n",
 234                    dev->name, lp->scb.status, lp->scb.command);
 235             break;
 236         }
 237 
 238     lp->scb.command = RX_START;
 239     outw(0, ioaddr+4);
 240 
 241     return;
 242 
 243 }
 244 
 245 static inline void
 246 init_i596_mem(struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 247 {
 248     struct i596_private *lp = (struct i596_private *)dev->priv;
 249     short ioaddr = dev->base_addr;
 250     int boguscnt = 100;
 251 
 252     /* change the scp address */
 253     outw(0, ioaddr);
 254     outw(0, ioaddr);
 255     outb(4, ioaddr+0xf);
 256     outw(((((int)&lp->scp) & 0xffff) | 2), ioaddr);
 257     outw((((int)&lp->scp)>>16) & 0xffff, ioaddr);
 258 
 259     lp->last_cmd=jiffies;
 260 
 261     lp->scp.sysbus = 0x00440000;
 262     lp->scp.iscp = &(lp->iscp);
 263     lp->iscp.scb = &(lp->scb);
 264     lp->iscp.stat = 0x0001;
 265     lp->cmd_backlog = 0;
 266 
 267     lp->cmd_head = lp->scb.cmd = (struct i596_cmd *) -1;
 268 
 269     if (i596_debug > 2) printk("%s: starting i82596.\n", dev->name);
 270 
 271     (void) inb (ioaddr+0x10);
 272     outb(4, ioaddr+0xf);
 273     outw(0, ioaddr+4);
 274 
 275     while (lp->iscp.stat)
 276         if (--boguscnt == 0)
 277         {
 278             printk("%s: i82596 initialization timed out with status %4.4x, cmd %4.4x.\n",
 279                    dev->name, lp->scb.status, lp->scb.command);
 280             break;
 281         }
 282 
 283     memcpy (lp->i596_config, init_setup, 14);
 284     lp->set_conf.command = CmdConfigure;
 285     i596_add_cmd(dev, &lp->set_conf);
 286 
 287     memcpy (lp->eth_addr, dev->dev_addr, 6);
 288     lp->set_add.command = CmdSASetup;
 289     i596_add_cmd(dev, &lp->set_add);
 290 
 291     lp->tdr.command = CmdTDR;
 292     i596_add_cmd(dev, &lp->tdr);
 293 
 294     init_rx_bufs(dev);
 295 
 296     boguscnt=200;
 297     while (lp->scb.status, lp->scb.command)
 298         if (--boguscnt == 0)
 299         {
 300             printk("i82596 init timed out with status %4.4x, cmd %4.4x.\n",
 301                 lp->scb.status, lp->scb.command);
 302             break;
 303         }
 304 
 305     return;
 306 }
 307 
 308 static inline int
 309 i596_rx(struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 310 {
 311     struct i596_private *lp = (struct i596_private *)dev->priv;
 312     int frames=0;
 313 
 314     if (i596_debug > 3) printk ("i596_rx()\n");
 315 
 316     while ((lp->scb.rfd->stat) & STAT_C)
 317     {
 318         if (i596_debug >2) print_eth(lp->scb.rfd->data);
 319 
 320         if ((lp->scb.rfd->stat) & STAT_OK)
 321         {
 322             /* a good frame */
 323             int pkt_len = lp->scb.rfd->count & 0x3fff;
 324             struct sk_buff *skb = alloc_skb(pkt_len, GFP_ATOMIC);
 325 
 326             frames++;
 327 
 328             if (skb == NULL)
 329             {
 330                 printk ("%s: i596_rx Memory squeeze, dropping packet.\n", dev->name);
 331                 lp->stats.rx_dropped++;
 332                 break;
 333             }
 334 
 335             skb->len = pkt_len;
 336             skb->dev=dev;               
 337             memcpy(skb->data, lp->scb.rfd->data, pkt_len);
 338 
 339             netif_rx(skb);
 340             lp->stats.rx_packets++;
 341 
 342             if (i596_debug > 4) print_eth(skb->data);
 343         }
 344         else
 345         {
 346             lp->stats.rx_errors++;
 347             if ((lp->scb.rfd->stat) & 0x0001) lp->stats.collisions++;
 348             if ((lp->scb.rfd->stat) & 0x0080) lp->stats.rx_length_errors++;
 349             if ((lp->scb.rfd->stat) & 0x0100) lp->stats.rx_over_errors++;
 350             if ((lp->scb.rfd->stat) & 0x0200) lp->stats.rx_fifo_errors++;
 351             if ((lp->scb.rfd->stat) & 0x0400) lp->stats.rx_frame_errors++;
 352             if ((lp->scb.rfd->stat) & 0x0800) lp->stats.rx_crc_errors++;
 353             if ((lp->scb.rfd->stat) & 0x1000) lp->stats.rx_length_errors++;
 354         }
 355 
 356         lp->scb.rfd->stat=0;
 357         lp->rx_tail->cmd=0;
 358         lp->rx_tail=lp->scb.rfd;
 359         lp->scb.rfd=lp->scb.rfd->next;
 360         lp->rx_tail->count=0;
 361         lp->rx_tail->cmd=CMD_EOL;
 362 
 363     }
 364 
 365     if (i596_debug > 3) printk ("frames %d\n", frames);
 366 
 367     return 0;
 368 }
 369 
 370 static inline void
 371 i596_cleanup_cmd(struct i596_private *lp)
     /* [previous][next][first][last][top][bottom][index][help] */
 372 {
 373     struct i596_cmd *ptr;
 374     int boguscnt = 100;
 375 
 376     if (i596_debug > 4) printk ("i596_cleanup_cmd\n");
 377 
 378     while (lp->cmd_head != (struct i596_cmd *) -1)
 379     {
 380         ptr = lp->cmd_head;
 381 
 382         lp->cmd_head = lp->cmd_head->next;
 383         lp->cmd_backlog--;
 384 
 385         switch ((ptr->command) & 0x7)
 386         {
 387             case CmdTx:
 388             {
 389                 struct tx_cmd *tx_cmd = (struct tx_cmd *) ptr;
 390                 struct sk_buff *skb = ((struct sk_buff *)(tx_cmd->tbd->data)) -1;
 391 
 392                 dev_kfree_skb(skb, FREE_WRITE);
 393 
 394                 lp->stats.tx_errors++;
 395                 lp->stats.tx_aborted_errors++;
 396 
 397                 ptr->next = (struct i596_cmd * ) -1;
 398                 kfree_s((unsigned char *)tx_cmd, (sizeof (struct tx_cmd) + sizeof (struct i596_tbd)));
 399                 break;
 400             }
 401             case CmdMulticastList:
 402             {
 403                 unsigned short count = *((unsigned short *) (ptr + 1));
 404 
 405                 ptr->next = (struct i596_cmd * ) -1;
 406                 kfree_s((unsigned char *)ptr, (sizeof (struct i596_cmd) + count + 2));
 407                 break;
 408             }
 409             default:
 410                 ptr->next = (struct i596_cmd * ) -1;
 411         }
 412     }
 413 
 414     while (lp->scb.status, lp->scb.command)
 415         if (--boguscnt == 0)
 416         {
 417             printk("i596_cleanup_cmd timed out with status %4.4x, cmd %4.4x.\n",
 418                 lp->scb.status, lp->scb.command);
 419             break;
 420         }
 421 
 422     lp->scb.cmd = lp->cmd_head;
 423 }
 424 
 425 static inline void
 426 i596_reset(struct device *dev, struct i596_private *lp, int ioaddr)
     /* [previous][next][first][last][top][bottom][index][help] */
 427 {
 428     int boguscnt = 100;
 429 
 430     if (i596_debug > 4) printk ("i596_reset\n");
 431 
 432     while (lp->scb.status, lp->scb.command)
 433         if (--boguscnt == 0)
 434         {
 435             printk("i596_reset timed out with status %4.4x, cmd %4.4x.\n",
 436                 lp->scb.status, lp->scb.command);
 437             break;
 438         }
 439 
 440     dev->start=0;
 441     dev->tbusy=1;
 442 
 443     lp->scb.command=CUC_ABORT|RX_ABORT;
 444     outw(0, ioaddr+4);
 445 
 446     /* wait for shutdown */
 447     boguscnt = 400;
 448 
 449     while ((lp->scb.status, lp->scb.command) || lp->scb.command)
 450         if (--boguscnt == 0)
 451         {
 452             printk("i596_reset 2 timed out with status %4.4x, cmd %4.4x.\n",
 453                 lp->scb.status, lp->scb.command);
 454             break;
 455         }
 456 
 457     i596_cleanup_cmd(lp);
 458     i596_rx(dev);
 459 
 460     dev->start=1;
 461     dev->tbusy=0;
 462     dev->interrupt=0;
 463     init_i596_mem(dev);
 464 }
 465 
 466 static void i596_add_cmd(struct device *dev, struct i596_cmd *cmd)
     /* [previous][next][first][last][top][bottom][index][help] */
 467 {
 468     struct i596_private *lp = (struct i596_private *)dev->priv;
 469     int ioaddr = dev->base_addr;
 470     unsigned long flags;
 471     int boguscnt = 100;
 472 
 473     if (i596_debug > 4) printk ("i596_add_cmd\n");
 474 
 475     cmd->status = 0;
 476     cmd->command |= (CMD_EOL|CMD_INTR);
 477     cmd->next = (struct i596_cmd *) -1;
 478 
 479     save_flags(flags);
 480     cli();
 481     if (lp->cmd_head != (struct i596_cmd *) -1)
 482         lp->cmd_tail->next = cmd;
 483     else 
 484     {
 485         lp->cmd_head=cmd;
 486         while (lp->scb.status, lp->scb.command)
 487             if (--boguscnt == 0)
 488             {
 489                 printk("i596_add_cmd timed out with status %4.4x, cmd %4.4x.\n",
 490                    lp->scb.status, lp->scb.command);
 491                 break;
 492             }
 493 
 494         lp->scb.cmd = cmd;
 495         lp->scb.command = CUC_START;
 496         outw (0, ioaddr+4);
 497     }
 498     lp->cmd_tail=cmd;
 499     lp->cmd_backlog++;
 500 
 501     lp->cmd_head=lp->scb.cmd;
 502     restore_flags(flags);
 503 
 504     if (lp->cmd_backlog > 16) 
 505     {
 506         int tickssofar = jiffies - lp->last_cmd;
 507 
 508         if (tickssofar < 25) return;
 509 
 510         printk("%s: command unit timed out, status resetting.\n", dev->name);
 511 
 512         i596_reset(dev, lp, ioaddr);
 513     }
 514 }
 515 
 516 static int
 517 i596_open(struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 518 {
 519     if (request_irq(dev->irq, &i596_interrupt, 0, "apricot")) {
 520         return -EAGAIN;
 521     }
 522 
 523     irq2dev_map[dev->irq] = dev;
 524 
 525     if (i596_debug > 1)
 526         printk("%s: i596_open() irq %d.\n",
 527                dev->name, dev->irq);
 528 
 529     dev->tbusy = 0;
 530     dev->interrupt = 0;
 531     dev->start = 1;
 532 
 533     /* Initialize the 82596 memory */
 534     init_i596_mem(dev);
 535 
 536     return 0;                   /* Always succeed */
 537 }
 538 
 539 static int
 540 i596_start_xmit(struct sk_buff *skb, struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 541 {
 542     struct i596_private *lp = (struct i596_private *)dev->priv;
 543     int ioaddr = dev->base_addr;
 544     struct tx_cmd *tx_cmd;
 545 
 546     if (i596_debug > 2) printk ("%s: Apricot start xmit\n", dev->name);
 547 
 548     /* Transmitter timeout, serious problems. */
 549     if (dev->tbusy) {
 550         int tickssofar = jiffies - dev->trans_start;
 551         if (tickssofar < 5)
 552             return 1;
 553         printk("%s: transmit timed out, status resetting.\n",
 554                dev->name);
 555         lp->stats.tx_errors++;
 556         /* Try to restart the adaptor */
 557         if (lp->last_restart == lp->stats.tx_packets) {
 558             if (i596_debug > 1) printk ("Resetting board.\n");
 559 
 560             /* Shutdown and restart */
 561             i596_reset(dev,lp, ioaddr);
 562         } else {
 563             /* Issue a channel attention signal */
 564             if (i596_debug > 1) printk ("Kicking board.\n");
 565 
 566             lp->scb.command=CUC_START|RX_START;
 567             outw(0, ioaddr+4);
 568 
 569             lp->last_restart = lp->stats.tx_packets;
 570         }
 571         dev->tbusy = 0;
 572         dev->trans_start = jiffies;
 573     }
 574 
 575     /* If some higher level thinks we've misses a tx-done interrupt
 576        we are passed NULL. n.b. dev_tint handles the cli()/sti()
 577        itself. */
 578     if (skb == NULL) {
 579         dev_tint(dev);
 580         return 0;
 581     }
 582 
 583     /* shouldn't happen */
 584     if (skb->len <= 0) return 0;
 585 
 586     if (i596_debug > 3) printk("%s: i596_start_xmit() called\n", dev->name);
 587 
 588     /* Block a timer-based transmit from overlapping.  This could better be
 589        done with atomic_swap(1, dev->tbusy), but set_bit() works as well. */
 590     if (set_bit(0, (void*)&dev->tbusy) != 0)
 591         printk("%s: Transmitter access conflict.\n", dev->name);
 592     else
 593     {
 594         short length = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN;
 595         dev->trans_start=jiffies;
 596 
 597         tx_cmd = (struct tx_cmd *) kmalloc ((sizeof (struct tx_cmd) + sizeof (struct i596_tbd)), GFP_ATOMIC);
 598         if (tx_cmd == NULL)
 599         {
 600             printk ("%s: i596_xmit Memory squeeze, dropping packet.\n", dev->name);
 601             lp->stats.tx_dropped++;
 602 
 603             dev_kfree_skb(skb, FREE_WRITE);
 604         }
 605         else
 606         {
 607             tx_cmd->tbd = (struct i596_tbd *) (tx_cmd + 1);
 608             tx_cmd->tbd->next = (struct i596_tbd *) -1;
 609 
 610             tx_cmd->cmd.command = CMD_FLEX|CmdTx;
 611 
 612             tx_cmd->pad = 0;
 613             tx_cmd->size = 0;
 614             tx_cmd->tbd->pad = 0;
 615             tx_cmd->tbd->size = EOF | length;
 616 
 617             tx_cmd->tbd->data = skb->data;
 618 
 619             if (i596_debug > 3) print_eth(skb->data);
 620 
 621             i596_add_cmd(dev, (struct i596_cmd *)tx_cmd);
 622 
 623             lp->stats.tx_packets++;
 624         }
 625     }
 626 
 627     dev->tbusy = 0;
 628 
 629     return 0;
 630 }
 631 
 632 
 633 static void print_eth(char *add)
     /* [previous][next][first][last][top][bottom][index][help] */
 634 {
 635     int i;
 636 
 637     printk ("Dest  ");
 638     for (i = 0; i < 6; i++)
 639         printk(" %2.2X", (unsigned char)add[i]);
 640     printk ("\n");
 641 
 642     printk ("Source");
 643     for (i = 0; i < 6; i++)
 644         printk(" %2.2X", (unsigned char)add[i+6]);
 645     printk ("\n");
 646     printk ("type %2.2X%2.2X\n", (unsigned char)add[12], (unsigned char)add[13]);
 647 }
 648 
 649 unsigned long apricot_init(unsigned long mem_start, unsigned long mem_end)
     /* [previous][next][first][last][top][bottom][index][help] */
 650 {
 651     struct device *dev;
 652     int i;
 653     int checksum = 0;
 654     int ioaddr = 0x300;
 655     char eth_addr[6];
 656     
 657     /* this is easy the ethernet interface can only be at 0x300 */
 658     /* first check nothing is already registered here */
 659 
 660     if (check_region(ioaddr, APRICOT_TOTAL_SIZE))
 661         return mem_start;
 662 
 663     for (i = 0; i < 8; i++)
 664         checksum += inb(ioaddr + 8 + i);
 665 
 666     /* checksum is a multiple of 0x100, got this wrong first time
 667        some machines have 0x100, some 0x200. The DOS driver doesn't
 668        even bother with the checksum */
 669 
 670     if (checksum % 0x100) return mem_start;
 671 
 672 
 673     for(i = 0; i < 6 ; i++)
 674         eth_addr[i] = inb(ioaddr +8 +i));
 675     
 676     /* Some other boards trip the checksum.. but then appear as ether
 677        address 0. Trap these - AC */
 678        
 679     if(memcmp(eth_addr,"\x00\x00\x00\x00\x00\x00",6)==0)
 680         return mem_addr;
 681 
 682     dev = init_etherdev(0, (sizeof (struct i596_private) + 0xf), &mem_start);
 683     printk("%s: Apricot 82596 at %#3x,", dev->name, ioaddr);
 684 
 685     for (i = 0; i < 6; i++)
 686         printk(" %2.2X", dev->dev_addr[i] = eth_addr[i]);
 687 
 688     dev->base_addr = ioaddr;
 689     dev->irq = 10;
 690     printk(" IRQ %d.\n", dev->irq);
 691 
 692     snarf_region(ioaddr, APRICOT_TOTAL_SIZE);
 693 
 694     if (i596_debug > 0)
 695         printk(version);
 696 
 697     /* The APRICOT-specific entries in the device structure. */
 698     dev->open = &i596_open;
 699     dev->stop = &i596_close;
 700     dev->hard_start_xmit = &i596_start_xmit;
 701     dev->get_stats = &i596_get_stats;
 702 #ifdef HAVE_MULTICAST
 703     dev->set_multicast_list = &set_multicast_list;
 704 #endif
 705 
 706     /* align for scp */
 707     dev->priv = (void *)(((int) dev->priv + 0xf) & 0xfffffff0);
 708 
 709     return mem_start;
 710 }
 711 
 712 static void
 713 i596_interrupt(int reg_ptr)
     /* [previous][next][first][last][top][bottom][index][help] */
 714 {
 715     int irq = -(((struct pt_regs *)reg_ptr)->orig_eax+2);
 716     struct device *dev = (struct device *)(irq2dev_map[irq]);
 717     struct i596_private *lp;
 718     short ioaddr;
 719     int boguscnt = 200;
 720     unsigned short status, ack_cmd=0;
 721 
 722     if (dev == NULL) {
 723         printk ("i596_interrupt(): irq %d for unknown device.\n", irq);
 724         return;
 725     }
 726 
 727     if (i596_debug > 3) printk ("%s: i596_interrupt(): irq %d\n",dev->name, irq);
 728 
 729     if (dev->interrupt)
 730         printk("%s: Re-entering the interrupt handler.\n", dev->name);
 731 
 732     dev->interrupt = 1;
 733 
 734     ioaddr = dev->base_addr;
 735 
 736     lp = (struct i596_private *)dev->priv;
 737 
 738     while (lp->scb.status, lp->scb.command)
 739         if (--boguscnt == 0)
 740             {
 741                 printk("%s: i596 interrupt, timeout status %4.4x command %4.4x.\n", dev->name, lp->scb.status, lp->scb.command);
 742                 break;
 743             }
 744     status = lp->scb.status;
 745 
 746     if (i596_debug > 4)
 747         printk("%s: i596 interrupt, status %4.4x.\n", dev->name, status);
 748 
 749     ack_cmd = status & 0xf000;
 750 
 751     if ((status & 0x8000) || (status & 0x2000))
 752     {
 753         struct i596_cmd *ptr;
 754 
 755         if ((i596_debug > 4) && (status & 0x8000))
 756             printk("%s: i596 interrupt completed command.\n", dev->name);
 757         if ((i596_debug > 4) && (status & 0x2000))
 758             printk("%s: i596 interrupt command unit inactive %x.\n", dev->name, status & 0x0700);
 759 
 760         while ((lp->cmd_head != (struct i596_cmd *) -1) && (lp->cmd_head->status & STAT_C))
 761         {
 762             ptr = lp->cmd_head;
 763 
 764             lp->cmd_head = lp->cmd_head->next;
 765             lp->cmd_backlog--;
 766 
 767             switch ((ptr->command) & 0x7)
 768             {
 769                 case CmdTx:
 770                 {
 771                     struct tx_cmd *tx_cmd = (struct tx_cmd *) ptr;
 772                     struct sk_buff *skb = ((struct sk_buff *)(tx_cmd->tbd->data)) -1;
 773 
 774                     dev_kfree_skb(skb, FREE_WRITE);
 775 
 776                     if ((ptr->status) & STAT_OK)
 777                     {
 778                         if (i596_debug >2) print_eth(skb->data);
 779                     }
 780                     else
 781                     {
 782                         lp->stats.tx_errors++;
 783                         if ((ptr->status) & 0x0020) lp->stats.collisions++;
 784                         if (!((ptr->status) & 0x0040)) lp->stats.tx_heartbeat_errors++;
 785                         if ((ptr->status) & 0x0400) lp->stats.tx_carrier_errors++;
 786                         if ((ptr->status) & 0x0800) lp->stats.collisions++;
 787                         if ((ptr->status) & 0x1000) lp->stats.tx_aborted_errors++;
 788                     }
 789 
 790 
 791                     ptr->next = (struct i596_cmd * ) -1;
 792                     kfree_s((unsigned char *)tx_cmd, (sizeof (struct tx_cmd) + sizeof (struct i596_tbd)));
 793                     break;
 794                 }
 795                 case CmdMulticastList:
 796                 {
 797                     unsigned short count = *((unsigned short *) (ptr + 1));
 798 
 799                     ptr->next = (struct i596_cmd * ) -1;
 800                     kfree_s((unsigned char *)ptr, (sizeof (struct i596_cmd) + count + 2));
 801                     break;
 802                 }
 803                 case CmdTDR:
 804                 {
 805                     unsigned long status = *((unsigned long *) (ptr + 1));
 806 
 807                     if (status & 0x8000)
 808                     {
 809                         if (i596_debug > 3)
 810                             printk("%s: link ok.\n", dev->name);
 811                     }
 812                     else
 813                     {
 814                         if (status & 0x4000)
 815                             printk("%s: Transceiver problem.\n", dev->name);
 816                         if (status & 0x2000)
 817                             printk("%s: Termination problem.\n", dev->name);
 818                         if (status & 0x1000)
 819                             printk("%s: Short circuit.\n", dev->name);
 820 
 821                         printk("%s: Time %ld.\n", dev->name, status & 0x07ff);
 822                     }
 823                 }
 824                 default:
 825                     ptr->next = (struct i596_cmd * ) -1;
 826 
 827                 lp->last_cmd=jiffies;
 828             }
 829         }
 830 
 831         ptr = lp->cmd_head;
 832         while ((ptr != (struct i596_cmd *) -1) && (ptr != lp->cmd_tail))
 833         {
 834             ptr->command &= 0x1fff;
 835             ptr = ptr->next;
 836         }
 837 
 838         if ((lp->cmd_head != (struct i596_cmd *) -1) && (dev->start)) ack_cmd |= CUC_START;
 839         lp->scb.cmd = lp->cmd_head;
 840     }
 841 
 842     if ((status & 0x1000) || (status & 0x4000))
 843     {
 844         if ((i596_debug > 4) && (status & 0x4000))
 845             printk("%s: i596 interrupt received a frame.\n", dev->name);
 846         if ((i596_debug > 4) && (status & 0x1000))
 847             printk("%s: i596 interrupt receive unit inactive %x.\n", dev->name, status & 0x0070);
 848 
 849         i596_rx(dev);
 850 
 851         if (dev->start) ack_cmd |= RX_START;
 852     }
 853 
 854     /* acknowledge the interrupt */
 855 
 856 /*
 857     if ((lp->scb.cmd != (struct i596_cmd *) -1) && (dev->start)) ack_cmd |= CUC_START;
 858 */
 859     boguscnt = 100;
 860     while (lp->scb.status, lp->scb.command)
 861         if (--boguscnt == 0)
 862             {
 863                 printk("%s: i596 interrupt, timeout status %4.4x command %4.4x.\n", dev->name, lp->scb.status, lp->scb.command);
 864                 break;
 865             }
 866     lp->scb.command = ack_cmd;
 867 
 868     (void) inb (ioaddr+0x10);
 869     outb (4, ioaddr+0xf);
 870     outw (0, ioaddr+4);
 871 
 872     if (i596_debug > 4)
 873         printk("%s: exiting interrupt.\n", dev->name);
 874 
 875     dev->interrupt = 0;
 876     return;
 877 }
 878 
 879 static int
 880 i596_close(struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 881 {
 882     int ioaddr = dev->base_addr;
 883     struct i596_private *lp = (struct i596_private *)dev->priv;
 884 
 885     dev->start = 0;
 886     dev->tbusy = 1;
 887 
 888     if (i596_debug > 1)
 889         printk("%s: Shutting down ethercard, status was %4.4x.\n",
 890                dev->name, lp->scb.status);
 891 
 892     lp->scb.command = CUC_ABORT|RX_ABORT;
 893     outw(0, ioaddr+4);
 894 
 895     i596_cleanup_cmd(lp);
 896 
 897     free_irq(dev->irq);
 898     irq2dev_map[dev->irq] = 0;
 899 
 900     return 0;
 901 }
 902 
 903 static struct enet_statistics *
 904 i596_get_stats(struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 905 {
 906     struct i596_private *lp = (struct i596_private *)dev->priv;
 907 
 908     return &lp->stats;
 909 }
 910 
 911 #ifdef HAVE_MULTICAST
 912 /* Set or clear the multicast filter for this adaptor.
 913    num_addrs == -1      Promiscuous mode, receive all packets
 914    num_addrs == 0       Normal mode, clear multicast list
 915    num_addrs > 0        Multicast mode, receive normal and MC packets, and do
 916                         best-effort filtering.
 917  */
 918 static void
 919 set_multicast_list(struct device *dev, int num_addrs, void *addrs)
     /* [previous][next][first][last][top][bottom][index][help] */
 920 {
 921     struct i596_private *lp = (struct i596_private *)dev->priv;
 922     struct i596_cmd *cmd;
 923 
 924     if (i596_debug > 1)
 925         printk ("%s: set multicast list %d\n", dev->name, num_addrs);
 926 
 927     if (num_addrs > 0) {
 928         cmd = (struct i596_cmd *) kmalloc(sizeof(struct i596_cmd)+2+num_addrs*6, GFP_ATOMIC);
 929         if (cmd == NULL)
 930         {
 931             printk ("%s: set_multicast Memory squeeze.\n", dev->name);
 932             return;
 933         }
 934 
 935             cmd->command = CmdMulticastList;
 936             *((unsigned short *) (cmd + 1)) = num_addrs * 6;
 937             memcpy (((char *)(cmd + 1))+2, addrs, num_addrs * 6);
 938             print_eth (((char *)(cmd + 1)) + 2);
 939                 
 940             i596_add_cmd(dev, cmd);
 941     } else
 942     {
 943         if (lp->set_conf.next != (struct i596_cmd * ) -1) return;
 944         if (num_addrs == 0)
 945             lp->i596_config[8] &= ~0x01;
 946         else
 947             lp->i596_config[8] |= 0x01;
 948 
 949         i596_add_cmd(dev, &lp->set_conf);
 950     }
 951 
 952 }
 953 #endif
 954 
 955 #ifdef HAVE_DEVLIST
 956 static unsigned int apricot_portlist[] = {0x300, 0};
 957 struct netdev_entry apricot_drv =
 958 {"apricot", apricot_init, APRICOT_TOTAL_SIZE, apricot_portlist};
 959 #endif
 960 
 961 /*
 962  * Local variables:
 963  *  compile-command: "gcc -D__KERNEL__ -I/usr/src/linux/net/inet -Wall -Wstrict-prototypes -O6 -m486 -c apricot.c"
 964  * End:
 965  */

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