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, void *dev_id, 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", NULL);
 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         MOD_INC_USE_COUNT;
 446 
 447         return 0;
 448 }
 449 
 450 static int
 451 el16_send_packet(struct sk_buff *skb, struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 452 {
 453         struct net_local *lp = (struct net_local *)dev->priv;
 454         int ioaddr = dev->base_addr;
 455         short *shmem = (short*)dev->mem_start;
 456 
 457         if (dev->tbusy) {
 458                 /* If we get here, some higher level has decided we are broken.
 459                    There should really be a "kick me" function call instead. */
 460                 int tickssofar = jiffies - dev->trans_start;
 461                 if (tickssofar < 5)
 462                         return 1;
 463                 if (net_debug > 1)
 464                         printk("%s: transmit timed out, %s?  ", dev->name,
 465                                    shmem[iSCB_STATUS>>1] & 0x8000 ? "IRQ conflict" :
 466                                    "network cable problem");
 467                 /* Try to restart the adaptor. */
 468                 if (lp->last_restart == lp->stats.tx_packets) {
 469                         if (net_debug > 1) printk("Resetting board.\n");
 470                         /* Completely reset the adaptor. */
 471                         init_82586_mem(dev);
 472                 } else {
 473                         /* Issue the channel attention signal and hope it "gets better". */
 474                         if (net_debug > 1) printk("Kicking board.\n");
 475                         shmem[iSCB_CMD>>1] = 0xf000|CUC_START|RX_START;
 476                         outb(0, ioaddr + SIGNAL_CA);                    /* Issue channel-attn. */
 477                         lp->last_restart = lp->stats.tx_packets;
 478                 }
 479                 dev->tbusy=0;
 480                 dev->trans_start = jiffies;
 481         }
 482 
 483         /* If some higher layer thinks we've missed an tx-done interrupt
 484            we are passed NULL. Caution: dev_tint() handles the cli()/sti()
 485            itself. */
 486         if (skb == NULL) {
 487                 dev_tint(dev);
 488                 return 0;
 489         }
 490 
 491         /* Block a timer-based transmit from overlapping. */
 492         if (set_bit(0, (void*)&dev->tbusy) != 0)
 493                 printk("%s: Transmitter access conflict.\n", dev->name);
 494         else {
 495                 short length = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN;
 496                 unsigned char *buf = skb->data;
 497 
 498                 /* Disable the 82586's input to the interrupt line. */
 499                 outb(0x80, ioaddr + MISC_CTRL);
 500                 hardware_send_packet(dev, buf, length);
 501                 dev->trans_start = jiffies;
 502                 /* Enable the 82586 interrupt input. */
 503                 outb(0x84, ioaddr + MISC_CTRL);
 504         }
 505 
 506         dev_kfree_skb (skb, FREE_WRITE);
 507 
 508         /* You might need to clean up and record Tx statistics here. */
 509 
 510         return 0;
 511 }
 512 
 513 /*      The typical workload of the driver:
 514         Handle the network interface interrupts. */
 515 static void
 516 el16_interrupt(int irq, void *dev_id, struct pt_regs *regs)
     /* [previous][next][first][last][top][bottom][index][help] */
 517 {
 518         struct device *dev = (struct device *)(irq2dev_map[irq]);
 519         struct net_local *lp;
 520         int ioaddr, status, boguscount = 0;
 521         ushort ack_cmd = 0;
 522         ushort *shmem;
 523         
 524         if (dev == NULL) {
 525                 printk ("net_interrupt(): irq %d for unknown device.\n", irq);
 526                 return;
 527         }
 528         dev->interrupt = 1;
 529         
 530         ioaddr = dev->base_addr;
 531         lp = (struct net_local *)dev->priv;
 532         shmem = ((ushort*)dev->mem_start);
 533         
 534         status = shmem[iSCB_STATUS>>1];
 535         
 536         if (net_debug > 4) {
 537                 printk("%s: 3c507 interrupt, status %4.4x.\n", dev->name, status);
 538         }
 539 
 540         /* Disable the 82586's input to the interrupt line. */
 541         outb(0x80, ioaddr + MISC_CTRL);
 542 
 543         /* Reap the Tx packet buffers. */
 544         while (lp->tx_reap != lp->tx_head) {
 545           unsigned short tx_status = shmem[lp->tx_reap>>1];
 546 
 547           if (tx_status == 0) {
 548                 if (net_debug > 5)  printk("Couldn't reap %#x.\n", lp->tx_reap);
 549                 break;
 550           }
 551           if (tx_status & 0x2000) {
 552                 lp->stats.tx_packets++;
 553                 lp->stats.collisions += tx_status & 0xf;
 554                 dev->tbusy = 0;
 555                 mark_bh(NET_BH);                /* Inform upper layers. */
 556           } else {
 557                 lp->stats.tx_errors++;
 558                 if (tx_status & 0x0600)  lp->stats.tx_carrier_errors++;
 559                 if (tx_status & 0x0100)  lp->stats.tx_fifo_errors++;
 560                 if (!(tx_status & 0x0040))  lp->stats.tx_heartbeat_errors++;
 561                 if (tx_status & 0x0020)  lp->stats.tx_aborted_errors++;
 562           }
 563           if (net_debug > 5)
 564                   printk("Reaped %x, Tx status %04x.\n" , lp->tx_reap, tx_status);
 565           lp->tx_reap += TX_BUF_SIZE;
 566           if (lp->tx_reap > RX_BUF_START - TX_BUF_SIZE)
 567                 lp->tx_reap = TX_BUF_START;
 568           if (++boguscount > 4)
 569                 break;
 570         }
 571 
 572         if (status & 0x4000) { /* Packet received. */
 573                 if (net_debug > 5)
 574                         printk("Received packet, rx_head %04x.\n", lp->rx_head);
 575                 el16_rx(dev);
 576         }
 577 
 578         /* Acknowledge the interrupt sources. */
 579         ack_cmd = status & 0xf000;
 580 
 581         if ((status & 0x0700) != 0x0200 && dev->start) {
 582                 if (net_debug)
 583                         printk("%s: Command unit stopped, status %04x, restarting.\n",
 584                                    dev->name, status);
 585                 /* If this ever occurs we should really re-write the idle loop, reset
 586                    the Tx list, and do a complete restart of the command unit.
 587                    For now we rely on the Tx timeout if the resume doesn't work. */
 588                 ack_cmd |= CUC_RESUME;
 589         }
 590 
 591         if ((status & 0x0070) != 0x0040  &&  dev->start) {
 592           static void init_rx_bufs(struct device *);
 593                 /* The Rx unit is not ready, it must be hung.  Restart the receiver by
 594                    initializing the rx buffers, and issuing an Rx start command. */
 595                 if (net_debug)
 596                         printk("%s: Rx unit stopped, status %04x, restarting.\n",
 597                                    dev->name, status);
 598                 init_rx_bufs(dev);
 599                 shmem[iSCB_RFA >> 1] = RX_BUF_START;
 600                 ack_cmd |= RX_START;
 601         }
 602 
 603         shmem[iSCB_CMD>>1] = ack_cmd;
 604         outb(0, ioaddr + SIGNAL_CA);                    /* Issue channel-attn. */
 605 
 606         /* Clear the latched interrupt. */
 607         outb(0, ioaddr + RESET_IRQ);
 608 
 609         /* Enable the 82586's interrupt input. */
 610         outb(0x84, ioaddr + MISC_CTRL);
 611 
 612         return;
 613 }
 614 
 615 static int
 616 el16_close(struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 617 {
 618         int ioaddr = dev->base_addr;
 619         ushort *shmem = (short*)dev->mem_start;
 620 
 621         dev->tbusy = 1;
 622         dev->start = 0;
 623 
 624         /* Flush the Tx and disable Rx. */
 625         shmem[iSCB_CMD >> 1] = RX_SUSPEND | CUC_SUSPEND;
 626         outb(0, ioaddr + SIGNAL_CA);
 627 
 628         /* Disable the 82586's input to the interrupt line. */
 629         outb(0x80, ioaddr + MISC_CTRL);
 630 
 631         /* We always physically use the IRQ line, so we don't do free_irq().
 632            We do remove ourselves from the map. */
 633 
 634         irq2dev_map[dev->irq] = 0;
 635 
 636         /* Update the statistics here. */
 637 
 638         MOD_DEC_USE_COUNT;
 639 
 640         return 0;
 641 }
 642 
 643 /* Get the current statistics.  This may be called with the card open or
 644    closed. */
 645 static struct enet_statistics *
 646 el16_get_stats(struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 647 {
 648         struct net_local *lp = (struct net_local *)dev->priv;
 649 
 650         /* ToDo: decide if there are any useful statistics from the SCB. */
 651 
 652         return &lp->stats;
 653 }
 654 
 655 /* Initialize the Rx-block list. */
 656 static void
 657 init_rx_bufs(struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 658 {
 659         struct net_local *lp = (struct net_local *)dev->priv;
 660         unsigned short *write_ptr;
 661         unsigned short SCB_base = SCB_BASE;
 662 
 663         int cur_rxbuf = lp->rx_head = RX_BUF_START;
 664         
 665         /* Initialize each Rx frame + data buffer. */
 666         do {    /* While there is room for one more. */
 667 
 668           write_ptr = (unsigned short *)(dev->mem_start + cur_rxbuf);
 669 
 670                 *write_ptr++ = 0x0000;                          /* Status */
 671                 *write_ptr++ = 0x0000;                          /* Command */
 672                 *write_ptr++ = cur_rxbuf + RX_BUF_SIZE; /* Link */
 673                 *write_ptr++ = cur_rxbuf + 22;          /* Buffer offset */
 674                 *write_ptr++ = 0x0000;                          /* Pad for dest addr. */
 675                 *write_ptr++ = 0x0000;
 676                 *write_ptr++ = 0x0000;
 677                 *write_ptr++ = 0x0000;                          /* Pad for source addr. */
 678                 *write_ptr++ = 0x0000;
 679                 *write_ptr++ = 0x0000;
 680                 *write_ptr++ = 0x0000;                          /* Pad for protocol. */
 681                 
 682                 *write_ptr++ = 0x0000;                          /* Buffer: Actual count */
 683                 *write_ptr++ = -1;                                      /* Buffer: Next (none). */
 684                 *write_ptr++ = cur_rxbuf + 0x20 + SCB_base;     /* Buffer: Address low */
 685                 *write_ptr++ = 0x0000;
 686                 /* Finally, the number of bytes in the buffer. */
 687                 *write_ptr++ = 0x8000 + RX_BUF_SIZE-0x20;
 688                 
 689                 lp->rx_tail = cur_rxbuf;
 690                 cur_rxbuf += RX_BUF_SIZE;
 691         } while (cur_rxbuf <= RX_BUF_END - RX_BUF_SIZE);
 692         
 693         /* Terminate the list by setting the EOL bit, and wrap the pointer to make
 694            the list a ring. */
 695         write_ptr = (unsigned short *)
 696           (dev->mem_start + lp->rx_tail + 2);
 697         *write_ptr++ = 0xC000;                                  /* Command, mark as last. */
 698         *write_ptr++ = lp->rx_head;                             /* Link */
 699 
 700 }
 701 
 702 void
 703 init_82586_mem(struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 704 {
 705         struct net_local *lp = (struct net_local *)dev->priv;
 706         short ioaddr = dev->base_addr;
 707         ushort *shmem = (short*)dev->mem_start;
 708 
 709         /* Enable loopback to protect the wire while starting up,
 710            and hold the 586 in reset during the memory initialization. */
 711         outb(0x20, ioaddr + MISC_CTRL);
 712 
 713         /* Fix the ISCP address and base. */
 714         init_words[3] = SCB_BASE;
 715         init_words[7] = SCB_BASE;
 716 
 717         /* Write the words at 0xfff6 (address-aliased to 0xfffff6). */
 718         memcpy((void*)dev->mem_end-10, init_words, 10);
 719 
 720         /* Write the words at 0x0000. */
 721         memcpy((char*)dev->mem_start, init_words + 5, sizeof(init_words) - 10);
 722 
 723         /* Fill in the station address. */
 724         memcpy((char*)dev->mem_start+SA_OFFSET, dev->dev_addr,
 725                    sizeof(dev->dev_addr));
 726 
 727         /* The Tx-block list is written as needed.  We just set up the values. */
 728         lp->tx_cmd_link = IDLELOOP + 4;
 729         lp->tx_head = lp->tx_reap = TX_BUF_START;
 730 
 731         init_rx_bufs(dev);
 732 
 733         /* Start the 586 by releasing the reset line, but leave loopback. */
 734         outb(0xA0, ioaddr + MISC_CTRL);
 735 
 736         /* This was time consuming to track down: you need to give two channel
 737            attention signals to reliably start up the i82586. */
 738         outb(0, ioaddr + SIGNAL_CA);
 739 
 740         {
 741                 int boguscnt = 50;
 742                 while (shmem[iSCB_STATUS>>1] == 0)
 743                         if (--boguscnt == 0) {
 744                                 printk("%s: i82586 initialization timed out with status %04x,"
 745                                            "cmd %04x.\n", dev->name,
 746                                            shmem[iSCB_STATUS>>1], shmem[iSCB_CMD>>1]);
 747                                 break;
 748                         }
 749                 /* Issue channel-attn -- the 82586 won't start. */
 750                 outb(0, ioaddr + SIGNAL_CA);
 751         }
 752 
 753         /* Disable loopback and enable interrupts. */
 754         outb(0x84, ioaddr + MISC_CTRL);
 755         if (net_debug > 4)
 756                 printk("%s: Initialized 82586, status %04x.\n", dev->name,
 757                            shmem[iSCB_STATUS>>1]);
 758         return;
 759 }
 760 
 761 static void
 762 hardware_send_packet(struct device *dev, void *buf, short length)
     /* [previous][next][first][last][top][bottom][index][help] */
 763 {
 764         struct net_local *lp = (struct net_local *)dev->priv;
 765         short ioaddr = dev->base_addr;
 766         ushort tx_block = lp->tx_head;
 767         ushort *write_ptr =       (ushort *)(dev->mem_start + tx_block);
 768 
 769         /* Set the write pointer to the Tx block, and put out the header. */
 770         *write_ptr++ = 0x0000;                          /* Tx status */
 771         *write_ptr++ = CMD_INTR|CmdTx;          /* Tx command */
 772         *write_ptr++ = tx_block+16;                     /* Next command is a NoOp. */
 773         *write_ptr++ = tx_block+8;                      /* Data Buffer offset. */
 774 
 775         /* Output the data buffer descriptor. */
 776         *write_ptr++ = length | 0x8000;         /* Byte count parameter. */
 777         *write_ptr++ = -1;                                      /* No next data buffer. */
 778         *write_ptr++ = tx_block+22+SCB_BASE;/* Buffer follows the NoOp command. */
 779         *write_ptr++ = 0x0000;                          /* Buffer address high bits (always zero). */
 780 
 781         /* Output the Loop-back NoOp command. */
 782         *write_ptr++ = 0x0000;                          /* Tx status */
 783         *write_ptr++ = CmdNOp;                          /* Tx command */
 784         *write_ptr++ = tx_block+16;                     /* Next is myself. */
 785 
 786         /* Output the packet at the write pointer. */
 787         memcpy(write_ptr, buf, length);
 788 
 789         /* Set the old command link pointing to this send packet. */
 790         *(ushort*)(dev->mem_start + lp->tx_cmd_link) = tx_block;
 791         lp->tx_cmd_link = tx_block + 20;
 792 
 793         /* Set the next free tx region. */
 794         lp->tx_head = tx_block + TX_BUF_SIZE;
 795         if (lp->tx_head > RX_BUF_START - TX_BUF_SIZE)
 796                 lp->tx_head = TX_BUF_START;
 797 
 798         if (net_debug > 4) {
 799                 printk("%s: 3c507 @%x send length = %d, tx_block %3x, next %3x.\n",
 800                            dev->name, ioaddr, length, tx_block, lp->tx_head);
 801         }
 802 
 803         if (lp->tx_head != lp->tx_reap)
 804                 dev->tbusy = 0;
 805 }
 806 
 807 static void
 808 el16_rx(struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 809 {
 810         struct net_local *lp = (struct net_local *)dev->priv;
 811         short *shmem = (short*)dev->mem_start;
 812         ushort rx_head = lp->rx_head;
 813         ushort rx_tail = lp->rx_tail;
 814         ushort boguscount = 10;
 815         short frame_status;
 816 
 817         while ((frame_status = shmem[rx_head>>1]) < 0) {   /* Command complete */
 818                 ushort *read_frame =  (short *)(dev->mem_start + rx_head);
 819                 ushort rfd_cmd = read_frame[1];
 820                 ushort next_rx_frame = read_frame[2];
 821                 ushort data_buffer_addr = read_frame[3];
 822                 ushort *data_frame = (short *)(dev->mem_start + data_buffer_addr);
 823                 ushort pkt_len = data_frame[0];
 824 
 825                 if (rfd_cmd != 0 || data_buffer_addr != rx_head + 22
 826                         || (pkt_len & 0xC000) != 0xC000) {
 827                         printk("%s: Rx frame at %#x corrupted, status %04x cmd %04x"
 828                                    "next %04x data-buf @%04x %04x.\n", dev->name, rx_head,
 829                                    frame_status, rfd_cmd, next_rx_frame, data_buffer_addr,
 830                                    pkt_len);
 831                 } else if ((frame_status & 0x2000) == 0) {
 832                         /* Frame Rxed, but with error. */
 833                         lp->stats.rx_errors++;
 834                         if (frame_status & 0x0800) lp->stats.rx_crc_errors++;
 835                         if (frame_status & 0x0400) lp->stats.rx_frame_errors++;
 836                         if (frame_status & 0x0200) lp->stats.rx_fifo_errors++;
 837                         if (frame_status & 0x0100) lp->stats.rx_over_errors++;
 838                         if (frame_status & 0x0080) lp->stats.rx_length_errors++;
 839                 } else {
 840                         /* Malloc up new buffer. */
 841                         struct sk_buff *skb;
 842 
 843                         pkt_len &= 0x3fff;
 844                         skb = dev_alloc_skb(pkt_len+2);
 845                         if (skb == NULL) {
 846                                 printk("%s: Memory squeeze, dropping packet.\n", dev->name);
 847                                 lp->stats.rx_dropped++;
 848                                 break;
 849                         }
 850                         
 851                         skb_reserve(skb,2);
 852                         skb->dev = dev;
 853 
 854                         /* 'skb->data' points to the start of sk_buff data area. */
 855                         memcpy(skb_put(skb,pkt_len), data_frame + 5, pkt_len);
 856                 
 857                         skb->protocol=eth_type_trans(skb,dev);
 858                         netif_rx(skb);
 859                         lp->stats.rx_packets++;
 860                 }
 861 
 862                 /* Clear the status word and set End-of-List on the rx frame. */
 863                 read_frame[0] = 0;
 864                 read_frame[1] = 0xC000;
 865                 /* Clear the end-of-list on the prev. RFD. */
 866                 *(short*)(dev->mem_start + rx_tail + 2) = 0x0000;
 867 
 868                 rx_tail = rx_head;
 869                 rx_head = next_rx_frame;
 870                 if (--boguscount == 0)
 871                         break;
 872         }
 873 
 874         lp->rx_head = rx_head;
 875         lp->rx_tail = rx_tail;
 876 }
 877 #ifdef MODULE
 878 static char devicename[9] = { 0, };
 879 static struct device dev_3c507 = {
 880         devicename, /* device name is inserted by linux/drivers/net/net_init.c */
 881         0, 0, 0, 0,
 882         0, 0,
 883         0, 0, 0, NULL, el16_probe
 884 };
 885 
 886 static int io = 0x300;
 887 static int irq = 0;
 888 
 889 int init_module(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 890 {
 891         if (io == 0)
 892                 printk("3c507: You should not use auto-probing with insmod!\n");
 893         dev_3c507.base_addr = io;
 894         dev_3c507.irq       = irq;
 895         if (register_netdev(&dev_3c507) != 0) {
 896                 printk("3c507: register_netdev() returned non-zero.\n");
 897                 return -EIO;
 898         }
 899         return 0;
 900 }
 901 
 902 void
 903 cleanup_module(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 904 {
 905         unregister_netdev(&dev_3c507);
 906         kfree(dev_3c507.priv);
 907         dev_3c507.priv = NULL;
 908 
 909         /* If we don't do this, we can't re-insmod it later. */
 910         free_irq(dev_3c507.irq, NULL);
 911         release_region(dev_3c507.base_addr, EL16_IO_EXTENT);
 912 }
 913 #endif /* MODULE */
 914 
 915 /*
 916  * Local variables:
 917  *  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"
 918  *  version-control: t
 919  *  kept-new-versions: 5
 920  *  tab-width: 4
 921  *  c-indent-level: 4
 922  * End:
 923  */

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