root/drivers/net/3c507.c

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

DEFINITIONS

This source file includes following definitions.
  1. el16_probe
  2. el16_probe1
  3. el16_open
  4. el16_send_packet
  5. el16_interrupt
  6. el16_close
  7. el16_get_stats
  8. init_rx_bufs
  9. init_82586_mem
  10. hardware_send_packet
  11. el16_rx

   1 /* 3c507.c: An EtherLink16 device driver for Linux. */
   2 /*
   3         Written 1993 by Donald Becker.
   4         Copyright 1993 United States Government as represented by the Director,
   5         National Security Agency.  This software may only be used and distributed
   6         according to the terms of the GNU Public License as modified by SRC,
   7         incorported herein by reference.
   8 
   9         The author may be reached as becker@super.org or
  10         C/O Supercomputing Research Ctr., 17100 Science Dr., Bowie MD 20715
  11 
  12         Thanks go to jennings@Montrouge.SMR.slb.com ( Patrick Jennings)
  13         and jrs@world.std.com (Rick Sladkey) for testing and bugfixes.
  14 
  15         Things remaining to do:
  16         Verify that the tx and rx buffers don't have fencepost errors.
  17         Move the theory of operation and memory map documentation.
  18         The statistics need to be updated correctly.
  19 */
  20 
  21 static char *version =
  22         "3c507.c:v0.03 10/27/93 Donald Becker (becker@super.org)\n";
  23 
  24 #include <linux/config.h>
  25 
  26 /*
  27   Sources:
  28         This driver wouldn't have been written with the availability of the
  29         Crynwr driver source code.      It provided a known-working implementation
  30         that filled in the gaping holes of the Intel documention.  Three cheers
  31         for Russ Nelson.
  32 
  33         Intel Microcommunications Databook, Vol. 1, 1990. It provides just enough
  34         info that the casual reader might think that it documents the i82586.
  35 */
  36 
  37 #include <linux/kernel.h>
  38 #include <linux/sched.h>
  39 #include <linux/types.h>
  40 #include <linux/fcntl.h>
  41 #include <linux/interrupt.h>
  42 #include <linux/ptrace.h>
  43 #include <linux/ioport.h>
  44 #include <linux/in.h>
  45 #include <asm/system.h>
  46 #include <asm/bitops.h>
  47 #include <asm/io.h>
  48 #include <asm/dma.h>
  49 #include <errno.h>
  50 #include <memory.h>
  51 
  52 #include "dev.h"
  53 #include "eth.h"
  54 #include "skbuff.h"
  55 #include "arp.h"
  56 
  57 #ifndef HAVE_ALLOC_SKB
  58 #define alloc_skb(size, priority) (struct sk_buff *) kmalloc(size,priority)
  59 #define kfree_skbmem(addr, size) kfree_s(addr,size);
  60 #else
  61 #include <linux/malloc.h>
  62 #endif
  63 
  64 /* use 0 for production, 1 for verification, 2..7 for debug */
  65 #ifndef NET_DEBUG
  66 #define NET_DEBUG 1
  67 #endif
  68 static unsigned int net_debug = NET_DEBUG;
  69 
  70 /*
  71                         Details of the i82586.
  72 
  73    You'll really need the databook to understand the details of this part,
  74    but the outline is that the i82586 has two seperate processing units.
  75    Both are started from a list of three configuration tables, of which only
  76    the last, the System Control Block (SCB), is used after reset-time.  The SCB
  77    has the following fileds:
  78                 Status word
  79                 Command word
  80                 Tx/Command block addr.
  81                 Rx block addr.
  82    The command word accepts the following controls for the Tx and Rx units:
  83   */
  84 
  85 #define  CUC_START       0x0100
  86 #define  CUC_RESUME      0x0200
  87 #define  CUC_SUSPEND 0x0300
  88 #define  RX_START        0x0010
  89 #define  RX_RESUME       0x0020
  90 #define  RX_SUSPEND      0x0030
  91 
  92 /* The Rx unit uses a list of frame descriptors and a list of data buffer
  93    descriptors.  We use full-sized (1518 byte) data buffers, so there is
  94    a one-to-one pairing of frame descriptors to buffer descriptors.
  95 
  96    The Tx ("command") unit executes a list of commands that look like:
  97                 Status word             Written by the 82586 when the command is done.
  98                 Command word    Command in lower 3 bits, post-command action in upper 3
  99                 Link word               The address of the next command.
 100                 Parameters              (as needed).
 101 
 102         Some definitions related to the Command Word are:
 103  */
 104 #define CMD_EOL         0x8000                  /* The last command of the list, stop. */
 105 #define CMD_SUSP        0x4000                  /* Suspend after doing cmd. */
 106 #define CMD_INTR        0x2000                  /* Interrupt after doing cmd. */
 107 
 108 enum commands {
 109         CmdNOp = 0, CmdSASetup = 1, CmdConfigure = 2, CmdMulticastList = 3,
 110         CmdTx = 4, CmdTDR = 5, CmdDump = 6, CmdDiagnose = 7};
 111 
 112 /* Information that need to be kept for each board. */
 113 struct net_local {
 114         struct enet_statistics stats;
 115         int last_restart;
 116         ushort rx_head;
 117         ushort rx_tail;
 118         ushort tx_head;
 119         ushort tx_cmd_link;
 120         ushort tx_reap;
 121 };
 122 
 123 /*
 124                 Details of the EtherLink16 Implementation
 125   The 3c507 is a generic shared-memory i82586 implementation.
 126   The host can map 16K, 32K, 48K, or 64K of the 64K memory into
 127   0x0[CD][08]0000, or all 64K into 0xF[02468]0000.
 128   */
 129 
 130 /* Offsets from the base I/O address. */
 131 #define SA_DATA         0       /* Station address data, or 3Com signature. */
 132 #define MISC_CTRL       6       /* Switch the SA_DATA banks, and bus config bits. */
 133 #define RESET_IRQ       10      /* Reset the latched IRQ line. */
 134 #define SIGNAL_CA       11      /* Frob the 82586 Channel Attention line. */
 135 #define ROM_CONFIG      13
 136 #define MEM_CONFIG      14
 137 #define IRQ_CONFIG      15
 138 
 139 /* The ID port is used at boot-time to locate the ethercard. */
 140 #define ID_PORT         0x100
 141 
 142 /* Offsets to registers in the mailbox (SCB). */
 143 #define iSCB_STATUS     0x8
 144 #define iSCB_CMD                0xA
 145 #define iSCB_CBL                0xC     /* Command BLock offset. */
 146 #define iSCB_RFA                0xE     /* Rx Frame Area offset. */
 147 
 148 /*
 149   What follows in 'init_words[]' is the "program" that is downloaded to the
 150   82586 memory.  It's mostly tables and command blocks, and starts at the
 151   reset address 0xfffff6.  This is designed to be similar to the EtherExpress,
 152   thus the unusual location of the SCB at 0x0008.
 153 
 154   Even with the additional "don't care" values, doing it this way takes less
 155   program space than initializing the individual tables, and I feel it's much
 156   cleaner.
 157 
 158   The databook is particularly useless for the first two structures, I had
 159   to use the Crynwr driver as an example.
 160 
 161    The memory setup is as follows:
 162    */
 163 
 164 #define CONFIG_CMD      0x0018
 165 #define SET_SA_CMD      0x0024
 166 #define SA_OFFSET       0x002A
 167 #define IDLELOOP        0x30
 168 #define TDR_CMD         0x38
 169 #define TDR_TIME        0x3C
 170 #define DUMP_CMD        0x40
 171 #define DIAG_CMD        0x48
 172 #define SET_MC_CMD      0x4E
 173 #define DUMP_DATA       0x56    /* A 170 byte buffer for dump and Set-MC into. */
 174 
 175 #define TX_BUF_START    0x0100
 176 #define NUM_TX_BUFS     4
 177 #define TX_BUF_SIZE     (1518+14+20+16) /* packet+header+TBD */
 178 
 179 #define RX_BUF_START    0x2000
 180 #define RX_BUF_SIZE     (1518+14+18)    /* packet+header+RBD */
 181 #define RX_BUF_END              (dev->mem_end - dev->mem_start)
 182 
 183 /*
 184   That's it: only 86 bytes to set up the beast, including every extra
 185   command available.  The 170 byte buffer at DUMP_DATA is shared between the
 186   Dump command (called only by the diagnostic program) and the SetMulticastList
 187   command. 
 188 
 189   To complete the memory setup you only have to write the station address at
 190   SA_OFFSET and create the Tx & Rx buffer lists.
 191 
 192   The Tx command chain and buffer list is setup as follows:
 193   A Tx command table, with the data buffer pointing to...
 194   A Tx data buffer descriptor.  The packet is in a single buffer, rather than
 195      chaining together several smaller buffers.
 196   A NoOp command, which initially points to itself,
 197   And the packet data.
 198 
 199   A transmit is done by filling in the Tx command table and data buffer,
 200   re-writing the NoOp command, and finally changing the offset of the last
 201   command to point to the current Tx command.  When the Tx command is finished,
 202   it jumps to the NoOp, when it loops until the next Tx command changes the
 203   "link offset" in the NoOp.  This way the 82586 never has to go through the
 204   slow restart sequence.
 205 
 206   The Rx buffer list is set up in the obvious ring structure.  We have enough
 207   memory (and low enough interrupt latency) that we can avoid the complicated
 208   Rx buffer linked lists by alway associating a full-size Rx data buffer with
 209   each Rx data frame.
 210 
 211   I current use four transmit buffers starting at TX_BUF_START (0x0100), and
 212   use the rest of memory, from RX_BUF_START to RX_BUF_END, for Rx buffers.
 213 
 214   */
 215 
 216 short init_words[] = {
 217         0x0000,                                 /* Set bus size to 16 bits. */
 218         0x0000,0x0000,                  /* Set control mailbox (SCB) addr. */
 219         0,0,                                    /* pad to 0x000000. */
 220         0x0001,                                 /* Status word that's cleared when init is done. */
 221         0x0008,0,0,                             /* SCB offset, (skip, skip) */
 222 
 223         0,0xf000|RX_START|CUC_START,    /* SCB status and cmd. */
 224         CONFIG_CMD,                             /* Command list pointer, points to Configure. */
 225         RX_BUF_START,                           /* Rx block list. */
 226         0,0,0,0,                                /* Error count: CRC, align, buffer, overrun. */
 227 
 228         /* 0x0018: Configure command.  Change to put MAC data with packet. */
 229         0, CmdConfigure,                /* Status, command.             */
 230         SET_SA_CMD,                             /* Next command is Set Station Addr. */
 231         0x0804,                                 /* "4" bytes of config data, 8 byte FIFO. */
 232         0x2e40,                                 /* Magic values, including MAC data location. */
 233         0,                                              /* Unused pad word. */
 234 
 235         /* 0x0024: Setup station address command. */
 236         0, CmdSASetup,
 237         SET_MC_CMD,                             /* Next command. */
 238         0xaa00,0xb000,0x0bad,   /* Station address (to be filled in) */
 239 
 240         /* 0x0030: NOP, looping back to itself.  Point to first Tx buffer to Tx. */
 241         0, CmdNOp, IDLELOOP, 0 /* pad */,
 242 
 243         /* 0x0038: A unused Time-Domain Reflectometer command. */
 244         0, CmdTDR, IDLELOOP, 0,
 245 
 246         /* 0x0040: An unused Dump State command. */
 247         0, CmdDump, IDLELOOP, DUMP_DATA,
 248 
 249         /* 0x0048: An unused Diagnose command. */
 250         0, CmdDiagnose, IDLELOOP,
 251 
 252         /* 0x004E: An empty set-multicast-list command. */
 253         0, CmdMulticastList, IDLELOOP, 0,
 254 };
 255 
 256 /* Index to functions, as function prototypes. */
 257 
 258 extern int el16_probe(struct device *dev);      /* Called from Space.c */
 259 
 260 static int      el16_probe1(struct device *dev, short ioaddr);
 261 static int      el16_open(struct device *dev);
 262 static int      el16_send_packet(struct sk_buff *skb, struct device *dev);
 263 static void     el16_interrupt(int reg_ptr);
 264 static void el16_rx(struct device *dev);
 265 static int      el16_close(struct device *dev);
 266 static struct enet_statistics *el16_get_stats(struct device *dev);
 267 
 268 static void hardware_send_packet(struct device *dev, void *buf, short length);
 269 void init_82586_mem(struct device *dev);
 270 
 271 
 272 /* Check for a network adaptor of this type, and return '0' iff one exists.
 273    If dev->base_addr == 0, probe all likely locations.
 274    If dev->base_addr == 1, always return failure.
 275    If dev->base_addr == 2, (detachable devices only) alloate space for the
 276    device and return success.
 277    */
 278 int
 279 el16_probe(struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 280 {
 281         /* Don't probe all settable addresses, 0x[23][0-F]0, just common ones. */
 282         int *port, ports[] = {0x300, 0x320, 0x340, 0x280, 0};
 283         int base_addr = dev->base_addr;
 284         ushort lrs_state = 0xff, i;
 285 
 286         if (base_addr > 0x1ff)  /* Check a single specified location. */
 287                 return el16_probe1(dev, base_addr);
 288         else if (base_addr > 0)
 289                 return ENXIO;           /* Don't probe at all. */
 290 
 291         /* Send the ID sequence to the ID_PORT to enable the board. */
 292         outb(0x00, ID_PORT);
 293         for(i = 0; i < 255; i++) {
 294                 outb(lrs_state, ID_PORT);
 295                 lrs_state <<= 1;
 296                 if (lrs_state & 0x100)
 297                         lrs_state ^= 0xe7;
 298         }
 299         outb(0x00, ID_PORT);
 300 
 301         for (port = &ports[0]; *port; port++) {
 302                 short ioaddr = *port;
 303 #if 0
 304                 /* This is my original code. */
 305                 if (inb(ioaddr) == '*' && inb(ioaddr+1) == '3'
 306                         && inb(ioaddr+2) == 'C' && inb(ioaddr+3) == 'O'
 307                         && el16_probe1(dev, *port) == 0)
 308                         return 0;
 309 #else
 310         /* This is code from jennings@Montrouge.SMR.slb.com, done so that
 311            the string can be printed out. */
 312                 char res[5];
 313                 res[0] = inb(ioaddr); res[1] = inb(ioaddr+1);
 314                 res[2] = inb(ioaddr+2); res[3] = inb(ioaddr+3);
 315                 res[4] = 0;
 316                 if (res[0] == '*' && res[1] == '3'
 317                         && res[2] == 'C' && res[3] == 'O'
 318                         && el16_probe1(dev, *port) == 0)
 319                   return 0;
 320 #endif
 321         }
 322 
 323         return ENODEV;                  /* ENODEV would be more accurate. */
 324 }
 325 
 326 int el16_probe1(struct device *dev, short ioaddr)
     /* [previous][next][first][last][top][bottom][index][help] */
 327 {
 328         int i, irq, irqval;
 329 
 330         printk("%s: 3c507 at %#x,", dev->name, ioaddr);
 331 
 332         /* We should make a few more checks here, like the first three octets of
 333            the S.A. for the manufactor's code. */ 
 334 
 335         irq = inb(ioaddr + IRQ_CONFIG) & 0x0f;
 336 
 337         irqval = request_irq(irq, &el16_interrupt);
 338         if (irqval) {
 339                 printk ("unable to get IRQ %d (irqval=%d).\n", irq, irqval);
 340                 return EAGAIN;
 341         }
 342         
 343         /* We've committed to using the board, and can start filling in *dev. */
 344         snarf_region(ioaddr, 16);
 345         dev->base_addr = ioaddr;
 346 
 347         outb(0x01, ioaddr + MISC_CTRL);
 348         for (i = 0; i < 6; i++) {
 349                 dev->dev_addr[i] = inb(ioaddr + i);
 350                 printk(" %02x", dev->dev_addr[i]);
 351         }
 352 
 353         if ((dev->mem_start & 0xf) > 0)
 354                 net_debug = dev->mem_start & 7;
 355 
 356 #ifdef MEM_BASE
 357         dev->mem_start = MEM_BASE;
 358         dev->mem_end = dev->mem_start + 0x10000;
 359 #else
 360         {
 361                 int base;
 362                 int size;
 363                 char mem_config = inb(ioaddr + MEM_CONFIG);
 364                 if (mem_config & 0x20) {
 365                         size = 64*1024;
 366                         base = 0xf00000 + (mem_config & 0x08 ? 0x080000
 367                                                            : ((mem_config & 3) << 17));
 368                 } else {
 369                         size = ((mem_config & 3) + 1) << 14;
 370                         base = 0x0c0000 + ( (mem_config & 0x18) << 12);
 371                 }
 372                 if (size != 0x10000)
 373                         printk("%s: Warning, this version probably only works with 64K of"
 374                                    "shared memory.\n", dev->name);
 375                 dev->mem_start = base;
 376                 dev->mem_end = base + size;
 377         }
 378 #endif
 379 
 380         dev->if_port = (inb(ioaddr + ROM_CONFIG) & 0x80) ? 1 : 0;
 381         dev->irq = inb(ioaddr + IRQ_CONFIG) & 0x0f;
 382 
 383         printk(", IRQ %d, %sternal xcvr, memory %#x-%#x.\n", dev->irq,
 384                    dev->if_port ? "ex" : "in", dev->mem_start, dev->mem_end-1);
 385 
 386         if (net_debug)
 387                 printk(version);
 388 
 389         /* Initialize the device structure. */
 390         dev->priv = kmalloc(sizeof(struct net_local), GFP_KERNEL);
 391         memset(dev->priv, 0, sizeof(struct net_local));
 392 
 393         dev->open               = el16_open;
 394         dev->stop               = el16_close;
 395         dev->hard_start_xmit = el16_send_packet;
 396         dev->get_stats  = el16_get_stats;
 397 
 398         /* Fill in the fields of the device structure with ethernet-generic values.
 399            This should be in a common file instead of per-driver.  */
 400         for (i = 0; i < DEV_NUMBUFFS; i++)
 401                 dev->buffs[i] = NULL;
 402 
 403         dev->hard_header        = eth_header;
 404         dev->add_arp    = eth_add_arp;
 405         dev->queue_xmit = dev_queue_xmit;
 406         dev->rebuild_header = eth_rebuild_header;
 407         dev->type_trans = eth_type_trans;
 408 
 409         dev->type               = ARPHRD_ETHER;
 410         dev->hard_header_len = ETH_HLEN;
 411         dev->mtu                = 1500; /* eth_mtu */
 412         dev->addr_len   = ETH_ALEN;
 413         for (i = 0; i < ETH_ALEN; i++) {
 414                 dev->broadcast[i]=0xff;
 415         }
 416 
 417         /* New-style flags. */
 418         dev->flags              = IFF_BROADCAST;
 419         dev->family             = AF_INET;
 420         dev->pa_addr    = 0;
 421         dev->pa_brdaddr = 0;
 422         dev->pa_mask    = 0;
 423         dev->pa_alen    = sizeof(unsigned long);
 424 
 425         return 0;
 426 }
 427 
 428 
 429 
 430 static int
 431 el16_open(struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 432 {
 433         irq2dev_map[dev->irq] = dev;
 434 
 435         /* Initialize the 82586 memory and start it. */
 436         init_82586_mem(dev);
 437 
 438         dev->tbusy = 0;
 439         dev->interrupt = 0;
 440         dev->start = 1;
 441         return 0;
 442 }
 443 
 444 static int
 445 el16_send_packet(struct sk_buff *skb, struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 446 {
 447         struct net_local *lp = (struct net_local *)dev->priv;
 448         int ioaddr = dev->base_addr;
 449         short *shmem = (short*)dev->mem_start;
 450 
 451         if (dev->tbusy) {
 452                 /* If we get here, some higher level has decided we are broken.
 453                    There should really be a "kick me" function call instead. */
 454                 int tickssofar = jiffies - dev->trans_start;
 455                 if (tickssofar < 5)
 456                         return 1;
 457                 if (net_debug > 1)
 458                         printk("%s: transmit timed out, %s?  ", dev->name,
 459                                    shmem[iSCB_STATUS>>1] & 0x8000 ? "IRQ conflict" :
 460                                    "network cable problem");
 461                 /* Try to restart the adaptor. */
 462                 if (lp->last_restart == lp->stats.tx_packets) {
 463                         if (net_debug > 1) printk("Resetting board.\n");
 464                         /* Completely reset the adaptor. */
 465                         init_82586_mem(dev);
 466                 } else {
 467                         /* Issue the channel attention signal and hope it "gets better". */
 468                         if (net_debug > 1) printk("Kicking board.\n");
 469                         shmem[iSCB_CMD>>1] = 0xf000|CUC_START|RX_START;
 470                         outb(0, ioaddr + SIGNAL_CA);                    /* Issue channel-attn. */
 471                         lp->last_restart = lp->stats.tx_packets;
 472                 }
 473                 dev->tbusy=0;
 474                 dev->trans_start = jiffies;
 475         }
 476 
 477         /* If some higher layer thinks we've missed an tx-done interrupt
 478            we are passed NULL. Caution: dev_tint() handles the cli()/sti()
 479            itself. */
 480         if (skb == NULL) {
 481                 dev_tint(dev);
 482                 return 0;
 483         }
 484 
 485         /* For ethernet, fill in the header.  This should really be done by a
 486            higher level, rather than duplicated for each ethernet adaptor. */
 487         if (!skb->arp  &&  dev->rebuild_header(skb+1, dev)) {
 488                 skb->dev = dev;
 489                 arp_queue (skb);
 490                 return 0;
 491         }
 492         skb->arp=1;
 493 
 494         /* Block a timer-based transmit from overlapping. */
 495         if (set_bit(0, (void*)&dev->tbusy) != 0)
 496                 printk("%s: Transmitter access conflict.\n", dev->name);
 497         else {
 498                 short length = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN;
 499                 unsigned char *buf = (void *)(skb+1);
 500 
 501                 /* Disable the 82586's input to the interrupt line. */
 502                 outb(0x80, ioaddr + MISC_CTRL);
 503                 hardware_send_packet(dev, buf, length);
 504                 dev->trans_start = jiffies;
 505                 /* Enable the 82586 interrupt input. */
 506                 outb(0x84, ioaddr + MISC_CTRL);
 507         }
 508 
 509         if (skb->free)
 510                 kfree_skb (skb, FREE_WRITE);
 511 
 512         /* You might need to clean up and record Tx statistics here. */
 513 
 514         return 0;
 515 }
 516 
 517 /*      The typical workload of the driver:
 518         Handle the network interface interrupts. */
 519 static void
 520 el16_interrupt(int reg_ptr)
     /* [previous][next][first][last][top][bottom][index][help] */
 521 {
 522         int irq = -(((struct pt_regs *)reg_ptr)->orig_eax+2);
 523         struct device *dev = (struct device *)(irq2dev_map[irq]);
 524         struct net_local *lp;
 525         int ioaddr, status, boguscount = 0;
 526         ushort ack_cmd = 0;
 527         ushort *shmem;
 528         
 529         if (dev == NULL) {
 530                 printk ("net_interrupt(): irq %d for unknown device.\n", irq);
 531                 return;
 532         }
 533         dev->interrupt = 1;
 534         
 535         ioaddr = dev->base_addr;
 536         lp = (struct net_local *)dev->priv;
 537         shmem = ((ushort*)dev->mem_start);
 538         
 539         status = shmem[iSCB_STATUS>>1];
 540         
 541     if (net_debug > 4) {
 542                 printk("%s: 3c507 interrupt, status %4.4x.\n", dev->name, status);
 543     }
 544 
 545         /* Disable the 82586's input to the interrupt line. */
 546         outb(0x80, ioaddr + MISC_CTRL);
 547 
 548         /* Reap the Tx packet buffers. */
 549         while (lp->tx_reap != lp->tx_head) {
 550           unsigned short tx_status = shmem[lp->tx_reap>>1];
 551 
 552           if (tx_status == 0) {
 553                 if (net_debug > 5)  printk("Couldn't reap %#x.\n", lp->tx_reap);
 554                 break;
 555           }
 556           if (tx_status & 0x2000) {
 557                 lp->stats.tx_packets++;
 558                 lp->stats.collisions += tx_status & 0xf;
 559                 dev->tbusy = 0;
 560                 mark_bh(INET_BH);               /* Inform upper layers. */
 561           } else {
 562                 lp->stats.tx_errors++;
 563                 if (tx_status & 0x0600)  lp->stats.tx_carrier_errors++;
 564                 if (tx_status & 0x0100)  lp->stats.tx_fifo_errors++;
 565                 if (!(tx_status & 0x0040))  lp->stats.tx_heartbeat_errors++;
 566                 if (tx_status & 0x0020)  lp->stats.tx_aborted_errors++;
 567           }
 568           if (net_debug > 5)
 569                   printk("Reaped %x, Tx status %04x.\n" , lp->tx_reap, tx_status);
 570           lp->tx_reap += TX_BUF_SIZE;
 571           if (lp->tx_reap > RX_BUF_START - TX_BUF_SIZE)
 572                 lp->tx_reap = TX_BUF_START;
 573           if (++boguscount > 4)
 574                 break;
 575         }
 576 
 577         if (status & 0x4000) { /* Packet received. */
 578                 if (net_debug > 5)
 579                         printk("Received packet, rx_head %04x.\n", lp->rx_head);
 580                 el16_rx(dev);
 581         }
 582 
 583         /* Acknowledge the interrupt sources. */
 584         ack_cmd = status & 0xf000;
 585 
 586         if ((status & 0x0700) != 0x0200 && dev->start) {
 587                 if (net_debug)
 588                         printk("%s: Command unit stopped, status %04x, restarting.\n",
 589                                    dev->name, status);
 590                 /* If this ever occurs we should really re-write the idle loop, reset
 591                    the Tx list, and do a complete restart of the command unit.
 592                    For now we rely on the Tx timeout if the resume doesn't work. */
 593                 ack_cmd |= CUC_RESUME;
 594         }
 595 
 596         if ((status & 0x0070) != 0x0040  &&  dev->start) {
 597           static void init_rx_bufs(struct device *);
 598                 /* The Rx unit is not ready, it must be hung.  Restart the receiver by
 599                    initializing the rx buffers, and issuing an Rx start command. */
 600                 if (net_debug)
 601                         printk("%s: Rx unit stopped, status %04x, restarting.\n",
 602                                    dev->name, status);
 603                 init_rx_bufs(dev);
 604                 shmem[iSCB_RFA >> 1] = RX_BUF_START;
 605                 ack_cmd |= RX_START;
 606         }
 607 
 608         shmem[iSCB_CMD>>1] = ack_cmd;
 609         outb(0, ioaddr + SIGNAL_CA);                    /* Issue channel-attn. */
 610 
 611         /* Clear the latched interrupt. */
 612         outb(0, ioaddr + RESET_IRQ);
 613 
 614         /* Enable the 82586's interrupt input. */
 615         outb(0x84, ioaddr + MISC_CTRL);
 616 
 617         return;
 618 }
 619 
 620 static int
 621 el16_close(struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 622 {
 623         int ioaddr = dev->base_addr;
 624         ushort *shmem = (short*)dev->mem_start;
 625 
 626         dev->tbusy = 1;
 627         dev->start = 0;
 628 
 629         /* Flush the Tx and disable Rx. */
 630         shmem[iSCB_CMD >> 1] = RX_SUSPEND | CUC_SUSPEND;
 631         outb(0, ioaddr + SIGNAL_CA);
 632 
 633         /* Disable the 82586's input to the interrupt line. */
 634         outb(0x80, ioaddr + MISC_CTRL);
 635 
 636         /* We always physically use the IRQ line, so we don't do free_irq().
 637            We do remove ourselves from the map. */
 638 
 639         irq2dev_map[dev->irq] = 0;
 640 
 641         /* Update the statistics here. */
 642 
 643         return 0;
 644 }
 645 
 646 /* Get the current statistics.  This may be called with the card open or
 647    closed. */
 648 static struct enet_statistics *
 649 el16_get_stats(struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 650 {
 651         struct net_local *lp = (struct net_local *)dev->priv;
 652 
 653         /* ToDo: decide if there are any useful statistics from the SCB. */
 654 
 655         return &lp->stats;
 656 }
 657 
 658 /* Initialize the Rx-block list. */
 659 static void
 660 init_rx_bufs(struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 661 {
 662         struct net_local *lp = (struct net_local *)dev->priv;
 663         unsigned short *write_ptr;
 664 
 665         int cur_rxbuf = lp->rx_head = RX_BUF_START;
 666         
 667         /* Initialize each Rx frame + data buffer. */
 668         do {    /* While there is room for one more. */
 669 
 670           write_ptr = (unsigned short *)(dev->mem_start + cur_rxbuf);
 671 
 672                 *write_ptr++ = 0x0000;                          /* Status */
 673                 *write_ptr++ = 0x0000;                          /* Command */
 674                 *write_ptr++ = cur_rxbuf + RX_BUF_SIZE; /* Link */
 675                 *write_ptr++ = cur_rxbuf + 22;          /* Buffer offset */
 676                 *write_ptr++ = 0x0000;                          /* Pad for dest addr. */
 677                 *write_ptr++ = 0x0000;
 678                 *write_ptr++ = 0x0000;
 679                 *write_ptr++ = 0x0000;                          /* Pad for source addr. */
 680                 *write_ptr++ = 0x0000;
 681                 *write_ptr++ = 0x0000;
 682                 *write_ptr++ = 0x0000;                          /* Pad for protocol. */
 683                 
 684                 *write_ptr++ = 0x0000;                          /* Buffer: Actual count */
 685                 *write_ptr++ = -1;                                      /* Buffer: Next (none). */
 686                 *write_ptr++ = cur_rxbuf + 0x20;                /* Buffer: Address low */
 687                 *write_ptr++ = 0x0000;
 688                 /* Finally, the number of bytes in the buffer. */
 689                 *write_ptr++ = 0x8000 + RX_BUF_SIZE-0x20;
 690                 
 691                 lp->rx_tail = cur_rxbuf;
 692                 cur_rxbuf += RX_BUF_SIZE;
 693         } while (cur_rxbuf <= RX_BUF_END - RX_BUF_SIZE);
 694         
 695         /* Terminate the list by setting the EOL bit, and wrap the pointer to make
 696            the list a ring. */
 697         write_ptr = (unsigned short *)
 698           (dev->mem_start + lp->rx_tail + 2);
 699         *write_ptr++ = 0xC000;                                  /* Command, mark as last. */
 700         *write_ptr++ = lp->rx_head;                             /* Link */
 701 
 702 }
 703 
 704 void
 705 init_82586_mem(struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 706 {
 707         struct net_local *lp = (struct net_local *)dev->priv;
 708         short ioaddr = dev->base_addr;
 709         ushort *shmem = (short*)dev->mem_start;
 710 
 711         /* Enable loopback to protect the wire while starting up,
 712            and hold the 586 in reset during the memory initialization. */
 713         outb(0x20, ioaddr + MISC_CTRL);
 714 
 715         /* Write the words at 0xfff6 (address-aliased to 0xfffff6). */
 716 #ifdef old
 717         memcpy((void*)dev->mem_start+0xfff6, init_words, 10);
 718 #else
 719         memcpy((void*)dev->mem_end-10, init_words, 10);
 720 #endif
 721         /* Write the words at 0x0000. */
 722         memcpy((char*)dev->mem_start, init_words + 5, sizeof(init_words) - 10);
 723 
 724         /* Fill in the station address. */
 725         memcpy((char*)dev->mem_start+SA_OFFSET, dev->dev_addr,
 726                    sizeof(dev->dev_addr));
 727 
 728         /* The Tx-block list is written as needed.  We just set up the values. */
 729         lp->tx_cmd_link = IDLELOOP + 4;
 730         lp->tx_head = lp->tx_reap = TX_BUF_START;
 731 
 732         init_rx_bufs(dev);
 733 
 734         /* Start the 586 by releasing the reset line, but leave loopback. */
 735         outb(0xA0, ioaddr + MISC_CTRL);
 736 
 737         /* This was time consuming to track down: you need to give two channel
 738            attention signals to reliably start up the i82586. */
 739         outb(0, ioaddr + SIGNAL_CA);
 740 
 741         {
 742                 int boguscnt = 50;
 743                 while (shmem[iSCB_STATUS>>1] == 0)
 744                         if (--boguscnt == 0) {
 745                                 printk("%s: i82586 initialization timed out with status %04x,"
 746                                            "cmd %04x.\n", dev->name,
 747                                            shmem[iSCB_STATUS>>1], shmem[iSCB_CMD>>1]);
 748                                 break;
 749                         }
 750                 /* Issue channel-attn -- the 82586 won't start. */
 751                 outb(0, ioaddr + SIGNAL_CA);
 752         }
 753 
 754         /* Disable loopback and enable interrupts. */
 755         outb(0x84, ioaddr + MISC_CTRL);
 756         if (net_debug > 4)
 757                 printk("%s: Initialized 82586, status %04x.\n", dev->name,
 758                            shmem[iSCB_STATUS>>1]);
 759         return;
 760 }
 761 
 762 static void
 763 hardware_send_packet(struct device *dev, void *buf, short length)
     /* [previous][next][first][last][top][bottom][index][help] */
 764 {
 765         struct net_local *lp = (struct net_local *)dev->priv;
 766         short ioaddr = dev->base_addr;
 767         ushort tx_block = lp->tx_head;
 768         ushort *write_ptr =       (ushort *)(dev->mem_start + tx_block);
 769 
 770         /* Set the write pointer to the Tx block, and put out the header. */
 771         *write_ptr++ = 0x0000;                          /* Tx status */
 772         *write_ptr++ = CMD_INTR|CmdTx;          /* Tx command */
 773         *write_ptr++ = tx_block+16;                     /* Next command is a NoOp. */
 774         *write_ptr++ = tx_block+8;                      /* Data Buffer offset. */
 775 
 776         /* Output the data buffer descriptor. */
 777         *write_ptr++ = length | 0x8000;         /* Byte count parameter. */
 778         *write_ptr++ = -1;                                      /* No next data buffer. */
 779         *write_ptr++ = tx_block+22;                     /* Buffer follows the NoOp command. */
 780         *write_ptr++ = 0x0000;                          /* Buffer address high bits (always zero). */
 781 
 782         /* Output the Loop-back NoOp command. */
 783         *write_ptr++ = 0x0000;                          /* Tx status */
 784         *write_ptr++ = CmdNOp;                          /* Tx command */
 785         *write_ptr++ = tx_block+16;                     /* Next is myself. */
 786 
 787         /* Output the packet at the write pointer. */
 788         memcpy(write_ptr, buf, length);
 789 
 790         /* Set the old command link pointing to this send packet. */
 791         *(ushort*)(dev->mem_start + lp->tx_cmd_link) = tx_block;
 792         lp->tx_cmd_link = tx_block + 20;
 793 
 794         /* Set the next free tx region. */
 795         lp->tx_head = tx_block + TX_BUF_SIZE;
 796         if (lp->tx_head > RX_BUF_START - TX_BUF_SIZE)
 797                 lp->tx_head = TX_BUF_START;
 798 
 799     if (net_debug > 4) {
 800                 printk("%s: 3c507 @%x send length = %d, tx_block %3x, next %3x.\n",
 801                            dev->name, ioaddr, length, tx_block, lp->tx_head);
 802     }
 803 
 804         if (lp->tx_head != lp->tx_reap)
 805                 dev->tbusy = 0;
 806 }
 807 
 808 static void
 809 el16_rx(struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 810 {
 811         struct net_local *lp = (struct net_local *)dev->priv;
 812         short *shmem = (short*)dev->mem_start;
 813         ushort rx_head = lp->rx_head;
 814         ushort rx_tail = lp->rx_tail;
 815         ushort boguscount = 10;
 816         short frame_status;
 817 
 818         while ((frame_status = shmem[rx_head>>1]) < 0) {   /* Command complete */
 819                 ushort *read_frame =  (short *)(dev->mem_start + rx_head);
 820                 ushort rfd_cmd = read_frame[1];
 821                 ushort next_rx_frame = read_frame[2];
 822                 ushort data_buffer_addr = read_frame[3];
 823                 ushort *data_frame = (short *)(dev->mem_start + data_buffer_addr);
 824                 ushort pkt_len = data_frame[0];
 825 
 826                 if (rfd_cmd != 0 || data_buffer_addr != rx_head + 22
 827                         || pkt_len & 0xC000 != 0xC000) {
 828                         printk("%s: Rx frame at %#x corrupted, status %04x cmd %04x"
 829                                    "next %04x data-buf @%04x %04x.\n", dev->name, rx_head,
 830                                    frame_status, rfd_cmd, next_rx_frame, data_buffer_addr,
 831                                    pkt_len);
 832                 } else if ((frame_status & 0x2000) == 0) {
 833                         /* Frame Rxed, but with error. */
 834                         lp->stats.rx_errors++;
 835                         if (frame_status & 0x0800) lp->stats.rx_crc_errors++;
 836                         if (frame_status & 0x0400) lp->stats.rx_frame_errors++;
 837                         if (frame_status & 0x0200) lp->stats.rx_fifo_errors++;
 838                         if (frame_status & 0x0100) lp->stats.rx_over_errors++;
 839                         if (frame_status & 0x0080) lp->stats.rx_length_errors++;
 840                 } else {
 841                         /* Malloc up new buffer. */
 842                         int sksize;
 843                         struct sk_buff *skb;
 844 
 845                         pkt_len &= 0x3fff;
 846                         sksize = sizeof(struct sk_buff) + pkt_len;
 847                         skb = alloc_skb(sksize, GFP_ATOMIC);
 848                         if (skb == NULL) {
 849                                 printk("%s: Memory squeeze, dropping packet.\n", dev->name);
 850                                 lp->stats.rx_dropped++;
 851                                 break;
 852                         }
 853                         skb->mem_len = sksize;
 854                         skb->mem_addr = skb;
 855                         skb->len = pkt_len;
 856                         skb->dev = dev;
 857 
 858                         /* 'skb+1' points to the start of sk_buff data area. */
 859                         memcpy((unsigned char *) (skb + 1), data_frame + 5, pkt_len);
 860                 
 861 #ifdef HAVE_NETIF_RX
 862                         netif_rx(skb);
 863 #else
 864                         skb->lock = 0;
 865                         if (dev_rint((unsigned char*)skb, pkt_len, IN_SKBUFF, dev) != 0) {
 866                                 kfree_skbmem(skb, sksize);
 867                                 lp->stats.rx_dropped++;
 868                                 break;
 869                         }
 870 #endif
 871                         lp->stats.rx_packets++;
 872                 }
 873 
 874                 /* Clear the status word and set End-of-List on the rx frame. */
 875                 read_frame[0] = 0;
 876                 read_frame[1] = 0xC000;
 877                 /* Clear the end-of-list on the prev. RFD. */
 878                 *(short*)(dev->mem_start + rx_tail + 2) = 0x0000;
 879 
 880                 rx_tail = rx_head;
 881                 rx_head = next_rx_frame;
 882                 if (--boguscount == 0)
 883                         break;
 884         }
 885 
 886         lp->rx_head = rx_head;
 887         lp->rx_tail = rx_tail;
 888 }
 889 
 890 /*
 891  * Local variables:
 892  *  compile-command: "gcc -D__KERNEL__ -I/usr/src/linux/net/inet -I/usr/src/linux/drivers/net -Wall -Wstrict-prototypes -O6 -m486 -c 3c507.c"
 893  *  version-control: t
 894  *  kept-new-versions: 5
 895  *  tab-width: 4
 896  * End:
 897  */
 898 

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