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