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

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