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

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