seeq8005.c revision 1.4 1 /* $NetBSD: seeq8005.c,v 1.4 2000/10/01 23:32:42 thorpej Exp $ */
2
3 /*
4 * Copyright (c) 2000 Ben Harris
5 * Copyright (c) 1995 Mark Brinicombe
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. All advertising materials mentioning features or use of this software
17 * must display the following acknowledgement:
18 * This product includes software developed by Mark Brinicombe.
19 * 4. The name of the company nor the name of the author may be used to
20 * endorse or promote products derived from this software without specific
21 * prior written permission.
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
24 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
25 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
26 * IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
27 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
28 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
29 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 * SUCH DAMAGE.
34 */
35 /*
36 * seeq8005.c - SEEQ 8005 device driver
37 */
38 /*
39 * This driver currently supports the following chip:
40 * SEEQ 8005 Advanced Ethernet Data Link Controller
41 */
42 /*
43 * This driver is based on the arm32 ea(4) driver, hence the names of many
44 * of the functions.
45 */
46 /*
47 * Bugs/possible improvements:
48 * - Does not currently support DMA
49 * - Does not currently support multicasts
50 * - Does not transmit multiple packets in one go
51 * - Does not support big-endian hosts
52 * - Does not support 8-bit busses
53 */
54
55 #include "opt_inet.h"
56 #include "opt_ns.h"
57
58 #include <sys/types.h>
59 #include <sys/param.h>
60
61 __RCSID("$NetBSD: seeq8005.c,v 1.4 2000/10/01 23:32:42 thorpej Exp $");
62
63 #include <sys/systm.h>
64 #include <sys/endian.h>
65 #include <sys/errno.h>
66 #include <sys/ioctl.h>
67 #include <sys/mbuf.h>
68 #include <sys/socket.h>
69 #include <sys/syslog.h>
70 #include <sys/device.h>
71
72 #include <net/if.h>
73 #include <net/if_dl.h>
74 #include <net/if_types.h>
75 #include <net/if_ether.h>
76
77 #ifdef INET
78 #include <netinet/in.h>
79 #include <netinet/in_systm.h>
80 #include <netinet/in_var.h>
81 #include <netinet/ip.h>
82 #include <netinet/if_inarp.h>
83 #endif
84
85 #ifdef NS
86 #include <netns/ns.h>
87 #include <netns/ns_if.h>
88 #endif
89
90 #include "bpfilter.h"
91 #if NBPFILTER > 0
92 #include <net/bpf.h>
93 #include <net/bpfdesc.h>
94 #endif
95
96 #include <machine/bus.h>
97 #include <machine/intr.h>
98
99 #include <dev/ic/seeq8005reg.h>
100 #include <dev/ic/seeq8005var.h>
101
102 #ifndef EA_TIMEOUT
103 #define EA_TIMEOUT 60
104 #endif
105
106 #define EA_TX_BUFFER_SIZE 0x4000
107 #define EA_RX_BUFFER_SIZE 0xC000
108
109 /*#define EA_TX_DEBUG*/
110 /*#define EA_RX_DEBUG*/
111 /*#define EA_DEBUG*/
112 /*#define EA_PACKET_DEBUG*/
113
114 /* for debugging convenience */
115 #ifdef EA_DEBUG
116 #define dprintf(x) printf x
117 #else
118 #define dprintf(x)
119 #endif
120
121 /*
122 * prototypes
123 */
124
125 static int ea_init(struct seeq8005_softc *);
126 static int ea_ioctl(struct ifnet *, u_long, caddr_t);
127 static void ea_start(struct ifnet *);
128 static void ea_watchdog(struct ifnet *);
129 static void ea_chipreset(struct seeq8005_softc *);
130 static void ea_ramtest(struct seeq8005_softc *);
131 static int ea_stoptx(struct seeq8005_softc *);
132 static int ea_stoprx(struct seeq8005_softc *);
133 static void ea_stop(struct seeq8005_softc *);
134 static void ea_await_fifo_empty(struct seeq8005_softc *);
135 static void ea_await_fifo_full(struct seeq8005_softc *);
136 static void ea_writebuf(struct seeq8005_softc *, u_char *, u_int, size_t);
137 static void ea_readbuf(struct seeq8005_softc *, u_char *, u_int, size_t);
138 static void ea_select_buffer(struct seeq8005_softc *, int);
139 static void earead(struct seeq8005_softc *, int, int);
140 static struct mbuf *eaget(struct seeq8005_softc *, int, int, struct ifnet *);
141 static void eagetpackets(struct seeq8005_softc *);
142 static void eatxpacket(struct seeq8005_softc *);
143
144
145 #ifdef EA_PACKET_DEBUG
146 void ea_dump_buffer(struct seeq8005_softc *, int);
147 #endif
148
149
150 #ifdef EA_PACKET_DEBUG
151 /*
152 * Dump the interface buffer
153 */
154
155 void
156 ea_dump_buffer(struct seeq8005_softc *sc, u_int offset)
157 {
158 bus_space_tag_t iot = sc->sc_iot;
159 bus_space_handle_t ioh = sc->sc_ioh;
160 u_int addr;
161 int loop;
162 size_t size;
163 int ctrl;
164 int ptr;
165
166 addr = offset;
167
168 do {
169 bus_space_write_2(iot, ioh, EA_8005_COMMAND,
170 sc->sc_command | EA_CMD_FIFO_READ);
171 bus_space_write_2(iot, ioh, EA_8005_CONFIG1,
172 sc->sc_config1 | EA_BUFCODE_LOCAL_MEM);
173 bus_space_write_2(iot, ioh, EA_8005_DMA_ADDR, addr);
174
175 ptr = bus_space_read_2(iot, ioh, EA_8005_BUFWIN);
176 ctrl = bus_space_read_2(iot, ioh, EA_8005_BUFWIN);
177 ptr = ((ptr & 0xff) << 8) | ((ptr >> 8) & 0xff);
178
179 if (ptr == 0) break;
180 size = ptr - addr;
181
182 printf("addr=%04x size=%04x ", addr, size);
183 printf("cmd=%02x st=%02x\n", ctrl & 0xff, ctrl >> 8);
184
185 for (loop = 0; loop < size - 4; loop += 2)
186 printf("%04x ",
187 bus_space_read_2(iot, ioh, EA_8005_BUFWIN));
188 printf("\n");
189 addr = ptr;
190 } while (size != 0);
191 }
192 #endif
193
194 /*
195 * Attach chip.
196 */
197
198 void
199 seeq8005_attach(struct seeq8005_softc *sc, const u_int8_t *myaddr)
200 {
201 struct ifnet *ifp = &sc->sc_ethercom.ec_if;
202 u_int id;
203
204 printf(" address %s", ether_sprintf(myaddr));
205
206 /* Stop the board. */
207
208 ea_chipreset(sc);
209
210 /* Get the product ID */
211
212 ea_select_buffer(sc, EA_BUFCODE_PRODUCTID);
213 id = bus_space_read_2(sc->sc_iot, sc->sc_ioh, EA_8005_BUFWIN);
214
215 if ((id & 0xf0) == 0xa0) {
216 sc->sc_flags |= SEEQ8005_80C04;
217 printf(", SEEQ 80C04 rev %02x", id);
218 } else
219 printf(", SEEQ 8005");
220
221 /* Initialise ifnet structure. */
222
223 bcopy(sc->sc_dev.dv_xname, ifp->if_xname, IFNAMSIZ);
224 ifp->if_softc = sc;
225 ifp->if_start = ea_start;
226 ifp->if_ioctl = ea_ioctl;
227 ifp->if_watchdog = ea_watchdog;
228 ifp->if_flags = IFF_BROADCAST | IFF_NOTRAILERS;
229
230 /* Now we can attach the interface. */
231
232 if_attach(ifp);
233 ether_ifattach(ifp, myaddr);
234
235 /* Finally, attach to bpf filter if it is present. */
236
237 #if NBPFILTER > 0
238 bpfattach(&ifp->if_bpf, ifp, DLT_EN10MB, sizeof(struct ether_header));
239 #endif
240
241 printf("\n");
242
243 /* Test the RAM */
244 ea_ramtest(sc);
245 }
246
247
248 /*
249 * Test the RAM on the ethernet card.
250 */
251
252 void
253 ea_ramtest(struct seeq8005_softc *sc)
254 {
255 bus_space_tag_t iot = sc->sc_iot;
256 bus_space_handle_t ioh = sc->sc_ioh;
257 int loop;
258 u_int sum = 0;
259
260 /* dprintf(("ea_ramtest()\n"));*/
261
262 /*
263 * Test the buffer memory on the board.
264 * Write simple pattens to it and read them back.
265 */
266
267 /* Set up the whole buffer RAM for writing */
268
269 ea_select_buffer(sc, EA_BUFCODE_TX_EAP);
270 bus_space_write_2(iot, ioh, EA_8005_BUFWIN, (EA_BUFFER_SIZE >> 8) - 1);
271 bus_space_write_2(iot, ioh, EA_8005_TX_PTR, 0x0000);
272 bus_space_write_2(iot, ioh, EA_8005_RX_PTR, EA_BUFFER_SIZE - 2);
273
274 #define EA_RAMTEST_LOOP(value) \
275 do { \
276 /* Set the write start address and write a pattern */ \
277 ea_writebuf(sc, NULL, 0x0000, 0); \
278 for (loop = 0; loop < EA_BUFFER_SIZE; loop += 2) \
279 bus_space_write_2(iot, ioh, EA_8005_BUFWIN, (value)); \
280 \
281 /* Set the read start address and verify the pattern */ \
282 ea_readbuf(sc, NULL, 0x0000, 0); \
283 for (loop = 0; loop < EA_BUFFER_SIZE; loop += 2) \
284 if (bus_space_read_2(iot, ioh, EA_8005_BUFWIN) != (value)) \
285 ++sum; \
286 if (sum != 0) \
287 dprintf(("sum=%d\n", sum)); \
288 } while (/*CONSTCOND*/0)
289
290 EA_RAMTEST_LOOP(loop);
291 EA_RAMTEST_LOOP(loop ^ (EA_BUFFER_SIZE - 1));
292 EA_RAMTEST_LOOP(0xaa55);
293 EA_RAMTEST_LOOP(0x55aa);
294
295 /* Report */
296
297 if (sum > 0)
298 printf("%s: buffer RAM failed self test, %d faults\n",
299 sc->sc_dev.dv_xname, sum);
300 }
301
302
303 /*
304 * Stop the tx interface.
305 *
306 * Returns 0 if the tx was already stopped or 1 if it was active
307 */
308
309 static int
310 ea_stoptx(struct seeq8005_softc *sc)
311 {
312 bus_space_tag_t iot = sc->sc_iot;
313 bus_space_handle_t ioh = sc->sc_ioh;
314 int timeout;
315 int status;
316
317 dprintf(("ea_stoptx()\n"));
318
319 status = bus_space_read_2(iot, ioh, EA_8005_STATUS);
320 if (!(status & EA_STATUS_TX_ON))
321 return 0;
322
323 /* Stop any tx and wait for confirmation */
324 bus_space_write_2(iot, ioh, EA_8005_COMMAND,
325 sc->sc_command | EA_CMD_TX_OFF);
326
327 timeout = 20000;
328 do {
329 status = bus_space_read_2(iot, ioh, EA_8005_STATUS);
330 } while ((status & EA_STATUS_TX_ON) && --timeout > 0);
331 if (timeout == 0)
332 dprintf(("ea_stoptx: timeout waiting for tx termination\n"));
333
334 /* Clear any pending tx interrupt */
335 bus_space_write_2(iot, ioh, EA_8005_COMMAND,
336 sc->sc_command | EA_CMD_TX_INTACK);
337 return 1;
338 }
339
340
341 /*
342 * Stop the rx interface.
343 *
344 * Returns 0 if the tx was already stopped or 1 if it was active
345 */
346
347 static int
348 ea_stoprx(struct seeq8005_softc *sc)
349 {
350 bus_space_tag_t iot = sc->sc_iot;
351 bus_space_handle_t ioh = sc->sc_ioh;
352 int timeout;
353 int status;
354
355 dprintf(("ea_stoprx()\n"));
356
357 status = bus_space_read_2(iot, ioh, EA_8005_STATUS);
358 if (!(status & EA_STATUS_RX_ON))
359 return 0;
360
361 /* Stop any rx and wait for confirmation */
362
363 bus_space_write_2(iot, ioh, EA_8005_COMMAND,
364 sc->sc_command | EA_CMD_RX_OFF);
365
366 timeout = 20000;
367 do {
368 status = bus_space_read_2(iot, ioh, EA_8005_STATUS);
369 } while ((status & EA_STATUS_RX_ON) && --timeout > 0);
370 if (timeout == 0)
371 dprintf(("ea_stoprx: timeout waiting for rx termination\n"));
372
373 /* Clear any pending rx interrupt */
374
375 bus_space_write_2(iot, ioh, EA_8005_COMMAND,
376 sc->sc_command | EA_CMD_RX_INTACK);
377 return 1;
378 }
379
380
381 /*
382 * Stop interface.
383 * Stop all IO and shut the interface down
384 */
385
386 static void
387 ea_stop(struct seeq8005_softc *sc)
388 {
389 bus_space_tag_t iot = sc->sc_iot;
390 bus_space_handle_t ioh = sc->sc_ioh;
391
392 dprintf(("ea_stop()\n"));
393
394 /* Stop all IO */
395 ea_stoptx(sc);
396 ea_stoprx(sc);
397
398 /* Disable rx and tx interrupts */
399 sc->sc_command &= (EA_CMD_RX_INTEN | EA_CMD_TX_INTEN);
400
401 /* Clear any pending interrupts */
402 bus_space_write_2(iot, ioh, EA_8005_COMMAND,
403 sc->sc_command | EA_CMD_RX_INTACK |
404 EA_CMD_TX_INTACK | EA_CMD_DMA_INTACK |
405 EA_CMD_BW_INTACK);
406 dprintf(("st=%08x", bus_space_read_2(iot, ioh, EA_8005_STATUS)));
407
408 /* Cancel any watchdog timer */
409 sc->sc_ethercom.ec_if.if_timer = 0;
410 }
411
412
413 /*
414 * Reset the chip
415 * Following this the software registers are reset
416 */
417
418 static void
419 ea_chipreset(struct seeq8005_softc *sc)
420 {
421 bus_space_tag_t iot = sc->sc_iot;
422 bus_space_handle_t ioh = sc->sc_ioh;
423
424 dprintf(("ea_chipreset()\n"));
425
426 /* Reset the controller. Min of 4us delay here */
427
428 bus_space_write_2(iot, ioh, EA_8005_CONFIG2, EA_CFG2_RESET);
429 delay(4);
430
431 sc->sc_command = 0;
432 sc->sc_config1 = 0;
433 sc->sc_config2 = 0;
434 }
435
436
437 /*
438 * If the DMA FIFO's in write mode, wait for it to empty. Needed when
439 * switching the FIFO from write to read. We also use it when changing
440 * the address for writes.
441 */
442 static void
443 ea_await_fifo_empty(struct seeq8005_softc *sc)
444 {
445 bus_space_tag_t iot = sc->sc_iot;
446 bus_space_handle_t ioh = sc->sc_ioh;
447 int timeout;
448
449 timeout = 20000;
450 if ((bus_space_read_2(iot, ioh, EA_8005_STATUS) &
451 EA_STATUS_FIFO_DIR) != 0)
452 return; /* FIFO is reading anyway. */
453 while ((bus_space_read_2(iot, ioh, EA_8005_STATUS) &
454 EA_STATUS_FIFO_EMPTY) == 0 &&
455 --timeout > 0)
456 continue;
457 }
458
459 /*
460 * Wait for the DMA FIFO to fill before reading from it.
461 */
462 static void
463 ea_await_fifo_full(struct seeq8005_softc *sc)
464 {
465 bus_space_tag_t iot = sc->sc_iot;
466 bus_space_handle_t ioh = sc->sc_ioh;
467 int timeout;
468
469 timeout = 20000;
470 while ((bus_space_read_2(iot, ioh, EA_8005_STATUS) &
471 EA_STATUS_FIFO_FULL) == 0 &&
472 --timeout > 0)
473 continue;
474 }
475
476 /*
477 * write to the buffer memory on the interface
478 *
479 * The buffer address is set to ADDR.
480 * If len != 0 then data is copied from the address starting at buf
481 * to the interface buffer.
482 * BUF must be usable as a u_int16_t *.
483 * If LEN is odd, it must be safe to overwrite one extra byte.
484 */
485
486 static void
487 ea_writebuf(struct seeq8005_softc *sc, u_char *buf, u_int addr, size_t len)
488 {
489 bus_space_tag_t iot = sc->sc_iot;
490 bus_space_handle_t ioh = sc->sc_ioh;
491
492 dprintf(("writebuf: st=%04x\n",
493 bus_space_read_2(iot, ioh, EA_8005_STATUS)));
494
495 #ifdef DIAGNOSTIC
496 if (__predict_false(!ALIGNED_POINTER(buf, u_int16_t)))
497 panic("%s: unaligned writebuf", sc->sc_dev.dv_xname);
498 #endif
499 if (__predict_false(addr >= EA_BUFFER_SIZE))
500 panic("%s: writebuf out of range", sc->sc_dev.dv_xname);
501
502 /* Assume that copying too much is safe. */
503 if (len % 2 != 0)
504 len++;
505
506 ea_await_fifo_empty(sc);
507
508 ea_select_buffer(sc, EA_BUFCODE_LOCAL_MEM);
509 bus_space_write_2(iot, ioh, EA_8005_COMMAND,
510 sc->sc_command | EA_CMD_FIFO_WRITE);
511 bus_space_write_2(iot, ioh, EA_8005_DMA_ADDR, addr);
512
513 if (len > 0)
514 bus_space_write_multi_2(iot, ioh, EA_8005_BUFWIN,
515 (u_int16_t *)buf, len / 2);
516 /* Leave FIFO to empty in the background */
517 }
518
519
520 /*
521 * read from the buffer memory on the interface
522 *
523 * The buffer address is set to ADDR.
524 * If len != 0 then data is copied from the interface buffer to the
525 * address starting at buf.
526 * BUF must be usable as a u_int16_t *.
527 * If LEN is odd, it must be safe to overwrite one extra byte.
528 */
529
530 static void
531 ea_readbuf(struct seeq8005_softc *sc, u_char *buf, u_int addr, size_t len)
532 {
533
534 bus_space_tag_t iot = sc->sc_iot;
535 bus_space_handle_t ioh = sc->sc_ioh;
536
537 dprintf(("readbuf: st=%04x addr=%04x len=%d\n",
538 bus_space_read_2(iot, ioh, EA_8005_STATUS), addr, len));
539
540 #ifdef DIAGNOSTIC
541 if (!ALIGNED_POINTER(buf, u_int16_t))
542 panic("%s: unaligned readbuf", sc->sc_dev.dv_xname);
543 #endif
544 if (addr >= EA_BUFFER_SIZE)
545 panic("%s: writebuf out of range", sc->sc_dev.dv_xname);
546
547 /* Assume that copying too much is safe. */
548 if (len % 2 != 0)
549 len++;
550
551 ea_await_fifo_empty(sc);
552
553 ea_select_buffer(sc, EA_BUFCODE_LOCAL_MEM);
554 bus_space_write_2(iot, ioh, EA_8005_DMA_ADDR, addr);
555 bus_space_write_2(iot, ioh, EA_8005_COMMAND,
556 sc->sc_command | EA_CMD_FIFO_READ);
557
558 ea_await_fifo_full(sc);
559
560 if (len > 0)
561 bus_space_read_multi_2(iot, ioh, EA_8005_BUFWIN,
562 (u_int16_t *)buf, len / 2);
563 }
564
565 static void
566 ea_select_buffer(struct seeq8005_softc *sc, int bufcode)
567 {
568
569 bus_space_write_2(sc->sc_iot, sc->sc_ioh, EA_8005_CONFIG1,
570 sc->sc_config1 | bufcode);
571 }
572
573 /*
574 * Initialize interface.
575 *
576 * This should leave the interface in a state for packet reception and
577 * transmission.
578 */
579
580 static int
581 ea_init(struct seeq8005_softc *sc)
582 {
583 struct ifnet *ifp = &sc->sc_ethercom.ec_if;
584 bus_space_tag_t iot = sc->sc_iot;
585 bus_space_handle_t ioh = sc->sc_ioh;
586 int s, loop;
587
588 dprintf(("ea_init()\n"));
589
590 s = splnet();
591
592 /* First, reset the board. */
593
594 ea_chipreset(sc);
595
596 /* Set up defaults for the registers */
597
598 sc->sc_command = 0x00;
599 sc->sc_config1 = 0x00; /* XXX DMA settings? */
600 #if BYTE_ORDER == BIG_ENDIAN
601 sc->sc_config2 = EA_CFG2_BYTESWAP
602 #else
603 sc->sc_config2 = 0;
604 #endif
605
606 bus_space_write_2(iot, ioh, EA_8005_COMMAND, sc->sc_command);
607 bus_space_write_2(iot, ioh, EA_8005_CONFIG1, sc->sc_config1);
608 bus_space_write_2(iot, ioh, EA_8005_CONFIG2, sc->sc_config2);
609
610 /* Split board memory into Rx and Tx. */
611 ea_select_buffer(sc, EA_BUFCODE_TX_EAP);
612 bus_space_write_2(iot, ioh, EA_8005_BUFWIN,
613 (EA_TX_BUFFER_SIZE >> 8) - 1);
614
615 /* Write the station address - the receiver must be off */
616 ea_select_buffer(sc, EA_BUFCODE_STATION_ADDR0);
617 for (loop = 0; loop < ETHER_ADDR_LEN; ++loop)
618 bus_space_write_2(iot, ioh, EA_8005_BUFWIN,
619 LLADDR(ifp->if_sadl)[loop]);
620
621 /* Configure rx. */
622 dprintf(("Configuring rx...\n"));
623 if (ifp->if_flags & IFF_PROMISC)
624 sc->sc_config1 = EA_CFG1_PROMISCUOUS;
625 else
626 sc->sc_config1 = EA_CFG1_BROADCAST;
627 sc->sc_config1 |= EA_CFG1_STATION_ADDR0;
628 bus_space_write_2(iot, ioh, EA_8005_CONFIG1, sc->sc_config1);
629
630 /* Setup the Rx pointers */
631 sc->sc_rx_ptr = EA_TX_BUFFER_SIZE;
632
633 bus_space_write_2(iot, ioh, EA_8005_RX_PTR, sc->sc_rx_ptr);
634 bus_space_write_2(iot, ioh, EA_8005_RX_END, sc->sc_rx_ptr >> 8);
635
636
637 /* Place a NULL header at the beginning of the receive area */
638 ea_writebuf(sc, NULL, sc->sc_rx_ptr, 0);
639
640 bus_space_write_2(iot, ioh, EA_8005_BUFWIN, 0x0000);
641 bus_space_write_2(iot, ioh, EA_8005_BUFWIN, 0x0000);
642
643
644 /* Turn on Rx */
645 sc->sc_command |= EA_CMD_RX_INTEN;
646 bus_space_write_2(iot, ioh, EA_8005_COMMAND,
647 sc->sc_command | EA_CMD_RX_ON);
648
649
650 /* Configure TX. */
651 dprintf(("Configuring tx...\n"));
652
653 bus_space_write_2(iot, ioh, EA_8005_TX_PTR, 0x0000);
654
655 sc->sc_config2 |= EA_CFG2_OUTPUT;
656 bus_space_write_2(iot, ioh, EA_8005_CONFIG2, sc->sc_config2);
657
658
659 /* Place a NULL header at the beginning of the transmit area */
660 ea_writebuf(sc, NULL, 0x0000, 0);
661
662 bus_space_write_2(iot, ioh, EA_8005_BUFWIN, 0x0000);
663 bus_space_write_2(iot, ioh, EA_8005_BUFWIN, 0x0000);
664
665 sc->sc_command |= EA_CMD_TX_INTEN;
666 bus_space_write_2(iot, ioh, EA_8005_COMMAND, sc->sc_command);
667
668 /* TX_ON gets set by ea_txpacket when there's something to transmit. */
669
670
671 /* Set flags appropriately. */
672 ifp->if_flags |= IFF_RUNNING;
673 ifp->if_flags &= ~IFF_OACTIVE;
674
675 dprintf(("init: st=%04x\n",
676 bus_space_read_2(iot, ioh, EA_8005_STATUS)));
677
678
679 /* And start output. */
680 ea_start(ifp);
681
682 splx(s);
683 return 0;
684 }
685
686
687 /*
688 * Start output on interface. Get datagrams from the queue and output them,
689 * giving the receiver a chance between datagrams. Call only from splnet or
690 * interrupt level!
691 */
692
693 static void
694 ea_start(struct ifnet *ifp)
695 {
696 struct seeq8005_softc *sc = ifp->if_softc;
697 int s;
698
699 s = splnet();
700 #ifdef EA_TX_DEBUG
701 dprintf(("ea_start()...\n"));
702 #endif
703
704 /* Don't do anything if output is active. */
705
706 if (ifp->if_flags & IFF_OACTIVE)
707 return;
708
709 /* Mark interface as output active */
710
711 ifp->if_flags |= IFF_OACTIVE;
712
713 /* tx packets */
714
715 eatxpacket(sc);
716 splx(s);
717 }
718
719
720 /*
721 * Transfer a packet to the interface buffer and start transmission
722 *
723 * Called at splnet()
724 */
725
726 void
727 eatxpacket(struct seeq8005_softc *sc)
728 {
729 bus_space_tag_t iot = sc->sc_iot;
730 bus_space_handle_t ioh = sc->sc_ioh;
731 struct mbuf *m, *m0;
732 struct ifnet *ifp;
733 int len, nextpacket;
734 u_int8_t hdr[4];
735
736 ifp = &sc->sc_ethercom.ec_if;
737
738 /* Dequeue the next packet. */
739 IF_DEQUEUE(&ifp->if_snd, m0);
740
741 /* If there's nothing to send, return. */
742 if (!m0) {
743 ifp->if_flags &= ~IFF_OACTIVE;
744 sc->sc_config2 |= EA_CFG2_OUTPUT;
745 bus_space_write_2(iot, ioh, EA_8005_CONFIG2, sc->sc_config2);
746 #ifdef EA_TX_DEBUG
747 dprintf(("tx finished\n"));
748 #endif
749 return;
750 }
751
752 #if NBPFILTER > 0
753 /* Give the packet to the bpf, if any. */
754 if (ifp->if_bpf)
755 bpf_mtap(ifp->if_bpf, m0);
756 #endif
757
758 #ifdef EA_TX_DEBUG
759 dprintf(("Tx new packet\n"));
760 #endif
761
762 sc->sc_config2 &= ~EA_CFG2_OUTPUT;
763 bus_space_write_2(iot, ioh, EA_8005_CONFIG2, sc->sc_config2);
764
765 /*
766 * Copy the frame to the start of the transmit area on the card,
767 * leaving four bytes for the transmit header.
768 */
769 len = 0;
770 for (m = m0; m; m = m->m_next) {
771 if (m->m_len == 0)
772 continue;
773 ea_writebuf(sc, mtod(m, caddr_t), 4 + len, m->m_len);
774 len += m->m_len;
775 }
776 m_freem(m0);
777
778
779 /* If packet size is odd round up to the next 16 bit boundry */
780 if (len % 2)
781 ++len;
782
783 len = max(len, ETHER_MIN_LEN);
784
785 if (len > (ETHER_MAX_LEN - ETHER_CRC_LEN))
786 log(LOG_WARNING, "%s: oversize packet = %d bytes\n",
787 sc->sc_dev.dv_xname, len);
788
789 #if 0 /*def EA_TX_DEBUG*/
790 dprintf(("ea: xfr pkt length=%d...\n", len));
791
792 dprintf(("%s-->", ether_sprintf(sc->sc_pktbuf+6)));
793 dprintf(("%s\n", ether_sprintf(sc->sc_pktbuf)));
794 #endif
795
796 /* dprintf(("st=%04x\n", bus_space_read_2(iot, ioh, EA_8005_STATUS)));*/
797
798 /* Follow it with a NULL packet header */
799 bus_space_write_2(iot, ioh, EA_8005_BUFWIN, 0x0000);
800 bus_space_write_2(iot, ioh, EA_8005_BUFWIN, 0x0000);
801
802
803 /* Write the packet header */
804
805 nextpacket = len + 4;
806 hdr[0] = (nextpacket >> 8) & 0xff;
807 hdr[1] = nextpacket & 0xff;
808 hdr[2] = EA_PKTHDR_TX | EA_PKTHDR_DATA_FOLLOWS |
809 EA_TXHDR_XMIT_SUCCESS_INT | EA_TXHDR_COLLISION_INT;
810 hdr[3] = 0; /* Status byte -- will be update by hardware. */
811 ea_writebuf(sc, hdr, 0x0000, 4);
812
813 bus_space_write_2(iot, ioh, EA_8005_TX_PTR, 0x0000);
814
815 /* dprintf(("st=%04x\n", bus_space_read_2(iot, ioh, EA_8005_STATUS)));*/
816
817 #ifdef EA_PACKET_DEBUG
818 ea_dump_buffer(sc, 0);
819 #endif
820
821
822 /* Now transmit the datagram. */
823 /* dprintf(("st=%04x\n", bus_space_read_2(iot, ioh, EA_8005_STATUS)));*/
824 bus_space_write_2(iot, ioh, EA_8005_COMMAND,
825 sc->sc_command | EA_CMD_TX_ON);
826 #ifdef EA_TX_DEBUG
827 dprintf(("st=%04x\n", bus_space_read_2(iot, ioh, EA_8005_STATUS)));
828 dprintf(("tx: queued\n"));
829 #endif
830 }
831
832
833 /*
834 * Ethernet controller interrupt.
835 */
836
837 int
838 seeq8005intr(void *arg)
839 {
840 struct seeq8005_softc *sc = arg;
841 bus_space_tag_t iot = sc->sc_iot;
842 bus_space_handle_t ioh = sc->sc_ioh;
843 struct ifnet *ifp = &sc->sc_ethercom.ec_if;
844 int status, s, handled;
845 u_int8_t txhdr[4];
846 u_int txstatus;
847
848 handled = 0;
849 dprintf(("eaintr: "));
850
851
852 /* Get the controller status */
853 status = bus_space_read_2(iot, ioh, EA_8005_STATUS);
854 dprintf(("st=%04x ", status));
855
856
857 /* Tx interrupt ? */
858 if (status & EA_STATUS_TX_INT) {
859 dprintf(("txint "));
860 handled = 1;
861
862 /* Acknowledge the interrupt */
863 bus_space_write_2(iot, ioh, EA_8005_COMMAND,
864 sc->sc_command | EA_CMD_TX_INTACK);
865
866 ea_readbuf(sc, txhdr, 0x0000, 4);
867
868 #ifdef EA_TX_DEBUG
869 dprintf(("txstatus=%02x %02x %02x %02x\n",
870 txhdr[0], txhdr[1], txhdr[2], txhdr[3]));
871 #endif
872 txstatus = txhdr[3];
873
874 /*
875 * Did it succeed ? Did we collide ?
876 *
877 * The exact proceedure here is not clear. We should get
878 * an interrupt on a sucessfull tx or on a collision.
879 * The done flag is set after successfull tx or 16 collisions
880 * We should thus get a interrupt for each of collision
881 * and the done bit should not be set. However it does appear
882 * to be set at the same time as the collision bit ...
883 *
884 * So we will count collisions and output errors and will
885 * assume that if the done bit is set the packet was
886 * transmitted. Stats may be wrong if 16 collisions occur on
887 * a packet as the done flag should be set but the packet
888 * may not have been transmitted. so the output count might
889 * not require incrementing if the 16 collisions flags is
890 * set. I don;t know abou this until it happens.
891 */
892
893 if (txstatus & EA_TXHDR_COLLISION)
894 ifp->if_collisions++;
895 else if (txstatus & EA_TXHDR_ERROR_MASK)
896 ifp->if_oerrors++;
897
898 #if 0
899 if (txstatus & EA_TXHDR_ERROR_MASK)
900 log(LOG_WARNING, "tx packet error =%02x\n", txstatus);
901 #endif
902
903 if (txstatus & EA_PKTHDR_DONE) {
904 ifp->if_opackets++;
905
906 /* Tx next packet */
907
908 s = splnet();
909 eatxpacket(sc);
910 splx(s);
911 }
912 }
913
914
915 /* Rx interrupt ? */
916 if (status & EA_STATUS_RX_INT) {
917 dprintf(("rxint "));
918 handled = 1;
919
920 /* Acknowledge the interrupt */
921 bus_space_write_2(iot, ioh, EA_8005_COMMAND,
922 sc->sc_command | EA_CMD_RX_INTACK);
923
924 /* Install a watchdog timer needed atm to fixed rx lockups */
925 ifp->if_timer = EA_TIMEOUT;
926
927 /* Processes the received packets */
928 eagetpackets(sc);
929
930
931 #if 0
932 /* Make sure the receiver is on */
933 if ((status & EA_STATUS_RX_ON) == 0) {
934 bus_space_write_2(iot, ioh, EA_8005_COMMAND,
935 sc->sc_command | EA_CMD_RX_ON);
936 printf("rxintr: rx is off st=%04x\n",status);
937 }
938 #endif
939 }
940
941 #ifdef EA_DEBUG
942 status = bus_space_read_2(iot, ioh, EA_8005_STATUS);
943 dprintf(("st=%04x\n", status));
944 #endif
945
946 return handled;
947 }
948
949
950 void
951 eagetpackets(struct seeq8005_softc *sc)
952 {
953 bus_space_tag_t iot = sc->sc_iot;
954 bus_space_handle_t ioh = sc->sc_ioh;
955 u_int addr;
956 int len;
957 int ctrl;
958 int ptr;
959 int pack;
960 int status;
961 u_int8_t rxhdr[4];
962 struct ifnet *ifp;
963
964 ifp = &sc->sc_ethercom.ec_if;
965
966
967 /* We start from the last rx pointer position */
968 addr = sc->sc_rx_ptr;
969 sc->sc_config2 &= ~EA_CFG2_OUTPUT;
970 bus_space_write_2(iot, ioh, EA_8005_CONFIG2, sc->sc_config2);
971
972 do {
973 /* Read rx header */
974 ea_readbuf(sc, rxhdr, addr, 4);
975
976 /* Split the packet header */
977 ptr = (rxhdr[0] << 8) | rxhdr[1];
978 ctrl = rxhdr[2];
979 status = rxhdr[3];
980
981 #ifdef EA_RX_DEBUG
982 dprintf(("addr=%04x ptr=%04x ctrl=%02x status=%02x\n",
983 addr, ptr, ctrl, status));
984 #endif
985
986
987 /* Zero packet ptr ? then must be null header so exit */
988 if (ptr == 0) break;
989
990
991 /* Get packet length */
992 len = (ptr - addr) - 4;
993
994 if (len < 0)
995 len += EA_RX_BUFFER_SIZE;
996
997 #ifdef EA_RX_DEBUG
998 dprintf(("len=%04x\n", len));
999 #endif
1000
1001
1002 /* Has the packet rx completed ? if not then exit */
1003 if ((status & EA_PKTHDR_DONE) == 0)
1004 break;
1005
1006 /*
1007 * Did we have any errors? then note error and go to
1008 * next packet
1009 */
1010 if (__predict_false(status & 0x0f)) {
1011 ++ifp->if_ierrors;
1012 log(LOG_WARNING,
1013 "%s: rx packet error (%02x) - dropping packet\n",
1014 sc->sc_dev.dv_xname, status & 0x0f);
1015 sc->sc_config2 |= EA_CFG2_OUTPUT;
1016 bus_space_write_2(iot, ioh, EA_8005_CONFIG2,
1017 sc->sc_config2);
1018 ea_init(sc);
1019 return;
1020 }
1021
1022 /*
1023 * Is the packet too big ? - this will probably be trapped
1024 * above as a receive error
1025 */
1026 if (__predict_false(len > (ETHER_MAX_LEN - ETHER_CRC_LEN))) {
1027 ++ifp->if_ierrors;
1028 log(LOG_WARNING, "%s: rx packet size error len=%d\n",
1029 sc->sc_dev.dv_xname, len);
1030 sc->sc_config2 |= EA_CFG2_OUTPUT;
1031 bus_space_write_2(iot, ioh, EA_8005_CONFIG2,
1032 sc->sc_config2);
1033 ea_init(sc);
1034 return;
1035 }
1036
1037 ifp->if_ipackets++;
1038 /* Pass data up to upper levels. */
1039 earead(sc, addr + 4, len);
1040
1041 addr = ptr;
1042 ++pack;
1043 } while (len != 0);
1044
1045 sc->sc_config2 |= EA_CFG2_OUTPUT;
1046 bus_space_write_2(iot, ioh, EA_8005_CONFIG2, sc->sc_config2);
1047
1048 #ifdef EA_RX_DEBUG
1049 dprintf(("new rx ptr=%04x\n", addr));
1050 #endif
1051
1052
1053 /* Store new rx pointer */
1054 sc->sc_rx_ptr = addr;
1055 bus_space_write_2(iot, ioh, EA_8005_RX_END, sc->sc_rx_ptr >> 8);
1056
1057 /* Make sure the receiver is on */
1058 bus_space_write_2(iot, ioh, EA_8005_COMMAND,
1059 sc->sc_command | EA_CMD_RX_ON);
1060
1061 }
1062
1063
1064 /*
1065 * Pass a packet up to the higher levels.
1066 */
1067
1068 static void
1069 earead(struct seeq8005_softc *sc, int addr, int len)
1070 {
1071 struct mbuf *m;
1072 struct ifnet *ifp;
1073
1074 ifp = &sc->sc_ethercom.ec_if;
1075
1076 /* Pull packet off interface. */
1077 m = eaget(sc, addr, len, ifp);
1078 if (m == 0)
1079 return;
1080
1081 #ifdef EA_RX_DEBUG
1082 dprintf(("%s-->", ether_sprintf(eh->ether_shost)));
1083 dprintf(("%s\n", ether_sprintf(eh->ether_dhost)));
1084 #endif
1085
1086 #if NBPFILTER > 0
1087 /*
1088 * Check if there's a BPF listener on this interface.
1089 * If so, hand off the raw packet to bpf.
1090 */
1091 if (ifp->if_bpf)
1092 bpf_mtap(ifp->if_bpf, m);
1093 #endif
1094
1095 (*ifp->if_input)(ifp, m);
1096 }
1097
1098 /*
1099 * Pull read data off a interface. Len is length of data, with local net
1100 * header stripped. We copy the data into mbufs. When full cluster sized
1101 * units are present we copy into clusters.
1102 */
1103
1104 struct mbuf *
1105 eaget(struct seeq8005_softc *sc, int addr, int totlen, struct ifnet *ifp)
1106 {
1107 struct mbuf *top, **mp, *m;
1108 int len;
1109 u_int cp, epkt;
1110
1111 cp = addr;
1112 epkt = cp + totlen;
1113
1114 MGETHDR(m, M_DONTWAIT, MT_DATA);
1115 if (m == 0)
1116 return 0;
1117 m->m_pkthdr.rcvif = ifp;
1118 m->m_pkthdr.len = totlen;
1119 m->m_len = MHLEN;
1120 top = 0;
1121 mp = ⊤
1122
1123 while (totlen > 0) {
1124 if (top) {
1125 MGET(m, M_DONTWAIT, MT_DATA);
1126 if (m == 0) {
1127 m_freem(top);
1128 return 0;
1129 }
1130 m->m_len = MLEN;
1131 }
1132 len = min(totlen, epkt - cp);
1133 if (len >= MINCLSIZE) {
1134 MCLGET(m, M_DONTWAIT);
1135 if (m->m_flags & M_EXT)
1136 m->m_len = len = min(len, MCLBYTES);
1137 else
1138 len = m->m_len;
1139 } else {
1140 /*
1141 * Place initial small packet/header at end of mbuf.
1142 */
1143 if (len < m->m_len) {
1144 if (top == 0 && len + max_linkhdr <= m->m_len)
1145 m->m_data += max_linkhdr;
1146 m->m_len = len;
1147 } else
1148 len = m->m_len;
1149 }
1150 if (top == 0) {
1151 /* Make sure the payload is aligned */
1152 caddr_t newdata = (caddr_t)
1153 ALIGN(m->m_data + sizeof(struct ether_header)) -
1154 sizeof(struct ether_header);
1155 len -= newdata - m->m_data;
1156 m->m_len = len;
1157 m->m_data = newdata;
1158 }
1159 ea_readbuf(sc, mtod(m, u_char *),
1160 cp < EA_BUFFER_SIZE ? cp : cp - EA_RX_BUFFER_SIZE,
1161 len);
1162 cp += len;
1163 *mp = m;
1164 mp = &m->m_next;
1165 totlen -= len;
1166 if (cp == epkt)
1167 cp = addr;
1168 }
1169
1170 return top;
1171 }
1172
1173 /*
1174 * Process an ioctl request. Mostly boilerplate.
1175 */
1176 static int
1177 ea_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
1178 {
1179 struct seeq8005_softc *sc = ifp->if_softc;
1180 struct ifaddr *ifa = (struct ifaddr *)data;
1181 /* struct ifreq *ifr = (struct ifreq *)data;*/
1182 int s, error = 0;
1183
1184 s = splnet();
1185
1186 switch (cmd) {
1187
1188 case SIOCSIFADDR:
1189 ifp->if_flags |= IFF_UP;
1190 dprintf(("if_flags=%08x\n", ifp->if_flags));
1191
1192 switch (ifa->ifa_addr->sa_family) {
1193 #ifdef INET
1194 case AF_INET:
1195 arp_ifinit(ifp, ifa);
1196 dprintf(("Interface ea is coming up (AF_INET)\n"));
1197 ea_init(sc);
1198 break;
1199 #endif
1200 #ifdef NS
1201 /* XXX - This code is probably wrong. */
1202 case AF_NS:
1203 {
1204 register struct ns_addr *ina = &IA_SNS(ifa)->sns_addr;
1205
1206 if (ns_nullhost(*ina))
1207 ina->x_host =
1208 *(union ns_host *)LLADDR(ifp->if_sadl);
1209 else
1210 bcopy(ina->x_host.c_host,
1211 LLADDR(ifp->if_sadl), ETHER_ADDR_LEN);
1212 /* Set new address. */
1213 dprintf(("Interface ea is coming up (AF_NS)\n"));
1214 ea_init(sc);
1215 break;
1216 }
1217 #endif
1218 default:
1219 dprintf(("Interface ea is coming up (default)\n"));
1220 ea_init(sc);
1221 break;
1222 }
1223 break;
1224
1225 case SIOCSIFFLAGS:
1226 dprintf(("if_flags=%08x\n", ifp->if_flags));
1227 if ((ifp->if_flags & IFF_UP) == 0 &&
1228 (ifp->if_flags & IFF_RUNNING) != 0) {
1229 /*
1230 * If interface is marked down and it is running, then
1231 * stop it.
1232 */
1233 dprintf(("Interface ea is stopping\n"));
1234 ea_stop(sc);
1235 ifp->if_flags &= ~IFF_RUNNING;
1236 } else if ((ifp->if_flags & IFF_UP) != 0 &&
1237 (ifp->if_flags & IFF_RUNNING) == 0) {
1238 /*
1239 * If interface is marked up and it is stopped, then
1240 * start it.
1241 */
1242 dprintf(("Interface ea is restarting(1)\n"));
1243 ea_init(sc);
1244 } else {
1245 /*
1246 * Some other important flag might have changed, so
1247 * reset.
1248 */
1249 dprintf(("Interface ea is reinitialising\n"));
1250 ea_init(sc);
1251 }
1252 break;
1253
1254 default:
1255 error = EINVAL;
1256 break;
1257 }
1258
1259 splx(s);
1260 return error;
1261 }
1262
1263 /*
1264 * Device timeout routine.
1265 *
1266 * Ok I am not sure exactly how the device timeout should work....
1267 * Currently what will happens is that that the device timeout is only
1268 * set when a packet it received. This indicates we are on an active
1269 * network and thus we should expect more packets. If non arrive in
1270 * in the timeout period then we reinitialise as we may have jammed.
1271 * We zero the timeout at this point so that we don't end up with
1272 * an endless stream of timeouts if the network goes down.
1273 */
1274
1275 static void
1276 ea_watchdog(struct ifnet *ifp)
1277 {
1278 struct seeq8005_softc *sc = ifp->if_softc;
1279
1280 log(LOG_ERR, "%s: device timeout\n", sc->sc_dev.dv_xname);
1281 ifp->if_oerrors++;
1282 dprintf(("ea_watchdog: "));
1283 dprintf(("st=%04x\n",
1284 bus_space_read_2(sc->sc_iot, sc->sc_ioh, EA_8005_STATUS)));
1285
1286 /* Kick the interface */
1287
1288 ea_init(sc);
1289
1290 /* ifp->if_timer = EA_TIMEOUT;*/
1291 ifp->if_timer = 0;
1292 }
1293
1294 /* End of if_ea.c */
1295