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