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