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
  12. init_module
  13. cleanup_module

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

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