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

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