seeq8005.c revision 1.5 1 /* $NetBSD: seeq8005.c,v 1.5 2000/11/03 00:25:36 bjh21 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.5 2000/11/03 00:25:36 bjh21 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 ifnet *);
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 ifnet *, int);
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 ea_set_address(struct seeq8005_softc *, int, const u_int8_t *);
140 static void earead(struct seeq8005_softc *, int, int);
141 static struct mbuf *eaget(struct seeq8005_softc *, int, int, struct ifnet *);
142 static void eagetpackets(struct seeq8005_softc *);
143 static void eatxpacket(struct seeq8005_softc *);
144 static void ea_mc_reset(struct seeq8005_softc *);
145
146
147 #ifdef EA_PACKET_DEBUG
148 void ea_dump_buffer(struct seeq8005_softc *, int);
149 #endif
150
151
152 #ifdef EA_PACKET_DEBUG
153 /*
154 * Dump the interface buffer
155 */
156
157 void
158 ea_dump_buffer(struct seeq8005_softc *sc, u_int offset)
159 {
160 bus_space_tag_t iot = sc->sc_iot;
161 bus_space_handle_t ioh = sc->sc_ioh;
162 u_int addr;
163 int loop, ctrl, ptr;
164 size_t size;
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_init = ea_init;
228 ifp->if_stop = ea_stop;
229 ifp->if_watchdog = ea_watchdog;
230 ifp->if_flags = IFF_BROADCAST | IFF_MULTICAST | IFF_NOTRAILERS;
231
232 /* Now we can attach the interface. */
233
234 if_attach(ifp);
235 ether_ifattach(ifp, myaddr);
236
237 /* Finally, attach to bpf filter if it is present. */
238
239 #if NBPFILTER > 0
240 bpfattach(&ifp->if_bpf, ifp, DLT_EN10MB, sizeof(struct ether_header));
241 #endif
242
243 printf("\n");
244
245 /* Test the RAM */
246 ea_ramtest(sc);
247 }
248
249
250 /*
251 * Test the RAM on the ethernet card.
252 */
253
254 void
255 ea_ramtest(struct seeq8005_softc *sc)
256 {
257 bus_space_tag_t iot = sc->sc_iot;
258 bus_space_handle_t ioh = sc->sc_ioh;
259 int loop;
260 u_int sum = 0;
261
262 /* dprintf(("ea_ramtest()\n"));*/
263
264 /*
265 * Test the buffer memory on the board.
266 * Write simple pattens to it and read them back.
267 */
268
269 /* Set up the whole buffer RAM for writing */
270
271 ea_select_buffer(sc, EA_BUFCODE_TX_EAP);
272 bus_space_write_2(iot, ioh, EA_8005_BUFWIN, (EA_BUFFER_SIZE >> 8) - 1);
273 bus_space_write_2(iot, ioh, EA_8005_TX_PTR, 0x0000);
274 bus_space_write_2(iot, ioh, EA_8005_RX_PTR, EA_BUFFER_SIZE - 2);
275
276 #define EA_RAMTEST_LOOP(value) \
277 do { \
278 /* Set the write start address and write a pattern */ \
279 ea_writebuf(sc, NULL, 0x0000, 0); \
280 for (loop = 0; loop < EA_BUFFER_SIZE; loop += 2) \
281 bus_space_write_2(iot, ioh, EA_8005_BUFWIN, (value)); \
282 \
283 /* Set the read start address and verify the pattern */ \
284 ea_readbuf(sc, NULL, 0x0000, 0); \
285 for (loop = 0; loop < EA_BUFFER_SIZE; loop += 2) \
286 if (bus_space_read_2(iot, ioh, EA_8005_BUFWIN) != (value)) \
287 ++sum; \
288 if (sum != 0) \
289 dprintf(("sum=%d\n", sum)); \
290 } while (/*CONSTCOND*/0)
291
292 EA_RAMTEST_LOOP(loop);
293 EA_RAMTEST_LOOP(loop ^ (EA_BUFFER_SIZE - 1));
294 EA_RAMTEST_LOOP(0xaa55);
295 EA_RAMTEST_LOOP(0x55aa);
296
297 /* Report */
298
299 if (sum > 0)
300 printf("%s: buffer RAM failed self test, %d faults\n",
301 sc->sc_dev.dv_xname, sum);
302 }
303
304
305 /*
306 * Stop the tx interface.
307 *
308 * Returns 0 if the tx was already stopped or 1 if it was active
309 */
310
311 static int
312 ea_stoptx(struct seeq8005_softc *sc)
313 {
314 bus_space_tag_t iot = sc->sc_iot;
315 bus_space_handle_t ioh = sc->sc_ioh;
316 int timeout;
317 int status;
318
319 dprintf(("ea_stoptx()\n"));
320
321 status = bus_space_read_2(iot, ioh, EA_8005_STATUS);
322 if (!(status & EA_STATUS_TX_ON))
323 return 0;
324
325 /* Stop any tx and wait for confirmation */
326 bus_space_write_2(iot, ioh, EA_8005_COMMAND,
327 sc->sc_command | EA_CMD_TX_OFF);
328
329 timeout = 20000;
330 do {
331 status = bus_space_read_2(iot, ioh, EA_8005_STATUS);
332 } while ((status & EA_STATUS_TX_ON) && --timeout > 0);
333 if (timeout == 0)
334 dprintf(("ea_stoptx: timeout waiting for tx termination\n"));
335
336 /* Clear any pending tx interrupt */
337 bus_space_write_2(iot, ioh, EA_8005_COMMAND,
338 sc->sc_command | EA_CMD_TX_INTACK);
339 return 1;
340 }
341
342
343 /*
344 * Stop the rx interface.
345 *
346 * Returns 0 if the tx was already stopped or 1 if it was active
347 */
348
349 static int
350 ea_stoprx(struct seeq8005_softc *sc)
351 {
352 bus_space_tag_t iot = sc->sc_iot;
353 bus_space_handle_t ioh = sc->sc_ioh;
354 int timeout;
355 int status;
356
357 dprintf(("ea_stoprx()\n"));
358
359 status = bus_space_read_2(iot, ioh, EA_8005_STATUS);
360 if (!(status & EA_STATUS_RX_ON))
361 return 0;
362
363 /* Stop any rx and wait for confirmation */
364
365 bus_space_write_2(iot, ioh, EA_8005_COMMAND,
366 sc->sc_command | EA_CMD_RX_OFF);
367
368 timeout = 20000;
369 do {
370 status = bus_space_read_2(iot, ioh, EA_8005_STATUS);
371 } while ((status & EA_STATUS_RX_ON) && --timeout > 0);
372 if (timeout == 0)
373 dprintf(("ea_stoprx: timeout waiting for rx termination\n"));
374
375 /* Clear any pending rx interrupt */
376
377 bus_space_write_2(iot, ioh, EA_8005_COMMAND,
378 sc->sc_command | EA_CMD_RX_INTACK);
379 return 1;
380 }
381
382
383 /*
384 * Stop interface.
385 * Stop all IO and shut the interface down
386 */
387
388 static void
389 ea_stop(struct ifnet *ifp, int disable)
390 {
391 struct seeq8005_softc *sc = ifp->if_softc;
392 bus_space_tag_t iot = sc->sc_iot;
393 bus_space_handle_t ioh = sc->sc_ioh;
394
395 dprintf(("ea_stop()\n"));
396
397 /* Stop all IO */
398 ea_stoptx(sc);
399 ea_stoprx(sc);
400
401 /* Disable rx and tx interrupts */
402 sc->sc_command &= (EA_CMD_RX_INTEN | EA_CMD_TX_INTEN);
403
404 /* Clear any pending interrupts */
405 bus_space_write_2(iot, ioh, EA_8005_COMMAND,
406 sc->sc_command | EA_CMD_RX_INTACK |
407 EA_CMD_TX_INTACK | EA_CMD_DMA_INTACK |
408 EA_CMD_BW_INTACK);
409 dprintf(("st=%08x", bus_space_read_2(iot, ioh, EA_8005_STATUS)));
410
411 /* Cancel any watchdog timer */
412 sc->sc_ethercom.ec_if.if_timer = 0;
413 }
414
415
416 /*
417 * Reset the chip
418 * Following this the software registers are reset
419 */
420
421 static void
422 ea_chipreset(struct seeq8005_softc *sc)
423 {
424 bus_space_tag_t iot = sc->sc_iot;
425 bus_space_handle_t ioh = sc->sc_ioh;
426
427 dprintf(("ea_chipreset()\n"));
428
429 /* Reset the controller. Min of 4us delay here */
430
431 bus_space_write_2(iot, ioh, EA_8005_CONFIG2, EA_CFG2_RESET);
432 delay(4);
433
434 sc->sc_command = 0;
435 sc->sc_config1 = 0;
436 sc->sc_config2 = 0;
437 }
438
439
440 /*
441 * If the DMA FIFO's in write mode, wait for it to empty. Needed when
442 * switching the FIFO from write to read. We also use it when changing
443 * the address for writes.
444 */
445 static void
446 ea_await_fifo_empty(struct seeq8005_softc *sc)
447 {
448 bus_space_tag_t iot = sc->sc_iot;
449 bus_space_handle_t ioh = sc->sc_ioh;
450 int timeout;
451
452 timeout = 20000;
453 if ((bus_space_read_2(iot, ioh, EA_8005_STATUS) &
454 EA_STATUS_FIFO_DIR) != 0)
455 return; /* FIFO is reading anyway. */
456 while ((bus_space_read_2(iot, ioh, EA_8005_STATUS) &
457 EA_STATUS_FIFO_EMPTY) == 0 &&
458 --timeout > 0)
459 continue;
460 }
461
462 /*
463 * Wait for the DMA FIFO to fill before reading from it.
464 */
465 static void
466 ea_await_fifo_full(struct seeq8005_softc *sc)
467 {
468 bus_space_tag_t iot = sc->sc_iot;
469 bus_space_handle_t ioh = sc->sc_ioh;
470 int timeout;
471
472 timeout = 20000;
473 while ((bus_space_read_2(iot, ioh, EA_8005_STATUS) &
474 EA_STATUS_FIFO_FULL) == 0 &&
475 --timeout > 0)
476 continue;
477 }
478
479 /*
480 * write to the buffer memory on the interface
481 *
482 * The buffer address is set to ADDR.
483 * If len != 0 then data is copied from the address starting at buf
484 * to the interface buffer.
485 * BUF must be usable as a u_int16_t *.
486 * If LEN is odd, it must be safe to overwrite one extra byte.
487 */
488
489 static void
490 ea_writebuf(struct seeq8005_softc *sc, u_char *buf, u_int addr, size_t len)
491 {
492 bus_space_tag_t iot = sc->sc_iot;
493 bus_space_handle_t ioh = sc->sc_ioh;
494
495 dprintf(("writebuf: st=%04x\n",
496 bus_space_read_2(iot, ioh, EA_8005_STATUS)));
497
498 #ifdef DIAGNOSTIC
499 if (__predict_false(!ALIGNED_POINTER(buf, u_int16_t)))
500 panic("%s: unaligned writebuf", sc->sc_dev.dv_xname);
501 #endif
502 if (__predict_false(addr >= EA_BUFFER_SIZE))
503 panic("%s: writebuf out of range", sc->sc_dev.dv_xname);
504
505 /* Assume that copying too much is safe. */
506 if (len % 2 != 0)
507 len++;
508
509 ea_await_fifo_empty(sc);
510
511 ea_select_buffer(sc, EA_BUFCODE_LOCAL_MEM);
512 bus_space_write_2(iot, ioh, EA_8005_COMMAND,
513 sc->sc_command | EA_CMD_FIFO_WRITE);
514 bus_space_write_2(iot, ioh, EA_8005_DMA_ADDR, addr);
515
516 if (len > 0)
517 bus_space_write_multi_2(iot, ioh, EA_8005_BUFWIN,
518 (u_int16_t *)buf, len / 2);
519 /* Leave FIFO to empty in the background */
520 }
521
522
523 /*
524 * read from the buffer memory on the interface
525 *
526 * The buffer address is set to ADDR.
527 * If len != 0 then data is copied from the interface buffer to the
528 * address starting at buf.
529 * BUF must be usable as a u_int16_t *.
530 * If LEN is odd, it must be safe to overwrite one extra byte.
531 */
532
533 static void
534 ea_readbuf(struct seeq8005_softc *sc, u_char *buf, u_int addr, size_t len)
535 {
536
537 bus_space_tag_t iot = sc->sc_iot;
538 bus_space_handle_t ioh = sc->sc_ioh;
539
540 dprintf(("readbuf: st=%04x addr=%04x len=%d\n",
541 bus_space_read_2(iot, ioh, EA_8005_STATUS), addr, len));
542
543 #ifdef DIAGNOSTIC
544 if (!ALIGNED_POINTER(buf, u_int16_t))
545 panic("%s: unaligned readbuf", sc->sc_dev.dv_xname);
546 #endif
547 if (addr >= EA_BUFFER_SIZE)
548 panic("%s: writebuf out of range", sc->sc_dev.dv_xname);
549
550 /* Assume that copying too much is safe. */
551 if (len % 2 != 0)
552 len++;
553
554 ea_await_fifo_empty(sc);
555
556 ea_select_buffer(sc, EA_BUFCODE_LOCAL_MEM);
557 bus_space_write_2(iot, ioh, EA_8005_DMA_ADDR, addr);
558 bus_space_write_2(iot, ioh, EA_8005_COMMAND,
559 sc->sc_command | EA_CMD_FIFO_READ);
560
561 ea_await_fifo_full(sc);
562
563 if (len > 0)
564 bus_space_read_multi_2(iot, ioh, EA_8005_BUFWIN,
565 (u_int16_t *)buf, len / 2);
566 }
567
568 static void
569 ea_select_buffer(struct seeq8005_softc *sc, int bufcode)
570 {
571
572 bus_space_write_2(sc->sc_iot, sc->sc_ioh, EA_8005_CONFIG1,
573 sc->sc_config1 | bufcode);
574 }
575
576 /* Must be called at splnet */
577 static void
578 ea_set_address(struct seeq8005_softc *sc, int which, u_int8_t const *ea)
579 {
580 int i;
581
582 ea_select_buffer(sc, EA_BUFCODE_STATION_ADDR0 + which);
583 for (i = 0; i < ETHER_ADDR_LEN; ++i)
584 bus_space_write_2(sc->sc_iot, sc->sc_ioh, EA_8005_BUFWIN,
585 ea[i]);
586 }
587
588 /*
589 * Initialize interface.
590 *
591 * This should leave the interface in a state for packet reception and
592 * transmission.
593 */
594
595 static int
596 ea_init(struct ifnet *ifp)
597 {
598 struct seeq8005_softc *sc = ifp->if_softc;
599 bus_space_tag_t iot = sc->sc_iot;
600 bus_space_handle_t ioh = sc->sc_ioh;
601 int s;
602
603 dprintf(("ea_init()\n"));
604
605 s = splnet();
606
607 /* First, reset the board. */
608
609 ea_chipreset(sc);
610
611 /* Set up defaults for the registers */
612
613 sc->sc_command = 0x00;
614 sc->sc_config1 = 0x00; /* XXX DMA settings? */
615 #if BYTE_ORDER == BIG_ENDIAN
616 sc->sc_config2 = EA_CFG2_BYTESWAP
617 #else
618 sc->sc_config2 = 0;
619 #endif
620
621 bus_space_write_2(iot, ioh, EA_8005_COMMAND, sc->sc_command);
622 bus_space_write_2(iot, ioh, EA_8005_CONFIG1, sc->sc_config1);
623 bus_space_write_2(iot, ioh, EA_8005_CONFIG2, sc->sc_config2);
624
625 /* Split board memory into Rx and Tx. */
626 ea_select_buffer(sc, EA_BUFCODE_TX_EAP);
627 bus_space_write_2(iot, ioh, EA_8005_BUFWIN,
628 (EA_TX_BUFFER_SIZE >> 8) - 1);
629
630 /* Write the station address - the receiver must be off */
631 ea_set_address(sc, 0, LLADDR(ifp->if_sadl));
632
633 /* Configure rx. */
634 dprintf(("Configuring rx...\n"));
635 if (ifp->if_flags & IFF_PROMISC)
636 sc->sc_config1 = EA_CFG1_PROMISCUOUS;
637 else
638 sc->sc_config1 = EA_CFG1_BROADCAST;
639 sc->sc_config1 |= EA_CFG1_STATION_ADDR0;
640 bus_space_write_2(iot, ioh, EA_8005_CONFIG1, sc->sc_config1);
641
642 /* Setup the Rx pointers */
643 sc->sc_rx_ptr = EA_TX_BUFFER_SIZE;
644
645 bus_space_write_2(iot, ioh, EA_8005_RX_PTR, sc->sc_rx_ptr);
646 bus_space_write_2(iot, ioh, EA_8005_RX_END, sc->sc_rx_ptr >> 8);
647
648
649 /* Place a NULL header at the beginning of the receive area */
650 ea_writebuf(sc, NULL, sc->sc_rx_ptr, 0);
651
652 bus_space_write_2(iot, ioh, EA_8005_BUFWIN, 0x0000);
653 bus_space_write_2(iot, ioh, EA_8005_BUFWIN, 0x0000);
654
655
656 /* Turn on Rx */
657 sc->sc_command |= EA_CMD_RX_INTEN;
658 bus_space_write_2(iot, ioh, EA_8005_COMMAND,
659 sc->sc_command | EA_CMD_RX_ON);
660
661
662 /* Configure TX. */
663 dprintf(("Configuring tx...\n"));
664
665 bus_space_write_2(iot, ioh, EA_8005_TX_PTR, 0x0000);
666
667 sc->sc_config2 |= EA_CFG2_OUTPUT;
668 bus_space_write_2(iot, ioh, EA_8005_CONFIG2, sc->sc_config2);
669
670
671 /* Place a NULL header at the beginning of the transmit area */
672 ea_writebuf(sc, NULL, 0x0000, 0);
673
674 bus_space_write_2(iot, ioh, EA_8005_BUFWIN, 0x0000);
675 bus_space_write_2(iot, ioh, EA_8005_BUFWIN, 0x0000);
676
677 sc->sc_command |= EA_CMD_TX_INTEN;
678 bus_space_write_2(iot, ioh, EA_8005_COMMAND, sc->sc_command);
679
680 /* TX_ON gets set by ea_txpacket when there's something to transmit. */
681
682
683 /* Set flags appropriately. */
684 ifp->if_flags |= IFF_RUNNING;
685 ifp->if_flags &= ~IFF_OACTIVE;
686
687 dprintf(("init: st=%04x\n",
688 bus_space_read_2(iot, ioh, EA_8005_STATUS)));
689
690
691 /* And start output. */
692 ea_start(ifp);
693
694 splx(s);
695 return 0;
696 }
697
698
699 /*
700 * Start output on interface. Get datagrams from the queue and output them,
701 * giving the receiver a chance between datagrams. Call only from splnet or
702 * interrupt level!
703 */
704
705 static void
706 ea_start(struct ifnet *ifp)
707 {
708 struct seeq8005_softc *sc = ifp->if_softc;
709 int s;
710
711 s = splnet();
712 #ifdef EA_TX_DEBUG
713 dprintf(("ea_start()...\n"));
714 #endif
715
716 /* Don't do anything if output is active. */
717
718 if (ifp->if_flags & IFF_OACTIVE)
719 return;
720
721 /* Mark interface as output active */
722
723 ifp->if_flags |= IFF_OACTIVE;
724
725 /* tx packets */
726
727 eatxpacket(sc);
728 splx(s);
729 }
730
731
732 /*
733 * Transfer a packet to the interface buffer and start transmission
734 *
735 * Called at splnet()
736 */
737
738 void
739 eatxpacket(struct seeq8005_softc *sc)
740 {
741 bus_space_tag_t iot = sc->sc_iot;
742 bus_space_handle_t ioh = sc->sc_ioh;
743 struct mbuf *m, *m0;
744 struct ifnet *ifp;
745 int len, nextpacket;
746 u_int8_t hdr[4];
747
748 ifp = &sc->sc_ethercom.ec_if;
749
750 /* Dequeue the next packet. */
751 IF_DEQUEUE(&ifp->if_snd, m0);
752
753 /* If there's nothing to send, return. */
754 if (!m0) {
755 ifp->if_flags &= ~IFF_OACTIVE;
756 sc->sc_config2 |= EA_CFG2_OUTPUT;
757 bus_space_write_2(iot, ioh, EA_8005_CONFIG2, sc->sc_config2);
758 #ifdef EA_TX_DEBUG
759 dprintf(("tx finished\n"));
760 #endif
761 return;
762 }
763
764 #if NBPFILTER > 0
765 /* Give the packet to the bpf, if any. */
766 if (ifp->if_bpf)
767 bpf_mtap(ifp->if_bpf, m0);
768 #endif
769
770 #ifdef EA_TX_DEBUG
771 dprintf(("Tx new packet\n"));
772 #endif
773
774 sc->sc_config2 &= ~EA_CFG2_OUTPUT;
775 bus_space_write_2(iot, ioh, EA_8005_CONFIG2, sc->sc_config2);
776
777 /*
778 * Copy the frame to the start of the transmit area on the card,
779 * leaving four bytes for the transmit header.
780 */
781 len = 0;
782 for (m = m0; m; m = m->m_next) {
783 if (m->m_len == 0)
784 continue;
785 ea_writebuf(sc, mtod(m, caddr_t), 4 + len, m->m_len);
786 len += m->m_len;
787 }
788 m_freem(m0);
789
790
791 /* If packet size is odd round up to the next 16 bit boundry */
792 if (len % 2)
793 ++len;
794
795 len = max(len, ETHER_MIN_LEN);
796
797 if (len > (ETHER_MAX_LEN - ETHER_CRC_LEN))
798 log(LOG_WARNING, "%s: oversize packet = %d bytes\n",
799 sc->sc_dev.dv_xname, len);
800
801 #if 0 /*def EA_TX_DEBUG*/
802 dprintf(("ea: xfr pkt length=%d...\n", len));
803
804 dprintf(("%s-->", ether_sprintf(sc->sc_pktbuf+6)));
805 dprintf(("%s\n", ether_sprintf(sc->sc_pktbuf)));
806 #endif
807
808 /* dprintf(("st=%04x\n", bus_space_read_2(iot, ioh, EA_8005_STATUS)));*/
809
810 /* Follow it with a NULL packet header */
811 bus_space_write_2(iot, ioh, EA_8005_BUFWIN, 0x0000);
812 bus_space_write_2(iot, ioh, EA_8005_BUFWIN, 0x0000);
813
814
815 /* Write the packet header */
816
817 nextpacket = len + 4;
818 hdr[0] = (nextpacket >> 8) & 0xff;
819 hdr[1] = nextpacket & 0xff;
820 hdr[2] = EA_PKTHDR_TX | EA_PKTHDR_DATA_FOLLOWS |
821 EA_TXHDR_XMIT_SUCCESS_INT | EA_TXHDR_COLLISION_INT;
822 hdr[3] = 0; /* Status byte -- will be update by hardware. */
823 ea_writebuf(sc, hdr, 0x0000, 4);
824
825 bus_space_write_2(iot, ioh, EA_8005_TX_PTR, 0x0000);
826
827 /* dprintf(("st=%04x\n", bus_space_read_2(iot, ioh, EA_8005_STATUS)));*/
828
829 #ifdef EA_PACKET_DEBUG
830 ea_dump_buffer(sc, 0);
831 #endif
832
833
834 /* Now transmit the datagram. */
835 /* dprintf(("st=%04x\n", bus_space_read_2(iot, ioh, EA_8005_STATUS)));*/
836 bus_space_write_2(iot, ioh, EA_8005_COMMAND,
837 sc->sc_command | EA_CMD_TX_ON);
838 #ifdef EA_TX_DEBUG
839 dprintf(("st=%04x\n", bus_space_read_2(iot, ioh, EA_8005_STATUS)));
840 dprintf(("tx: queued\n"));
841 #endif
842 }
843
844
845 /*
846 * Ethernet controller interrupt.
847 */
848
849 int
850 seeq8005intr(void *arg)
851 {
852 struct seeq8005_softc *sc = arg;
853 bus_space_tag_t iot = sc->sc_iot;
854 bus_space_handle_t ioh = sc->sc_ioh;
855 struct ifnet *ifp = &sc->sc_ethercom.ec_if;
856 int status, s, handled;
857 u_int8_t txhdr[4];
858 u_int txstatus;
859
860 handled = 0;
861 dprintf(("eaintr: "));
862
863
864 /* Get the controller status */
865 status = bus_space_read_2(iot, ioh, EA_8005_STATUS);
866 dprintf(("st=%04x ", status));
867
868
869 /* Tx interrupt ? */
870 if (status & EA_STATUS_TX_INT) {
871 dprintf(("txint "));
872 handled = 1;
873
874 /* Acknowledge the interrupt */
875 bus_space_write_2(iot, ioh, EA_8005_COMMAND,
876 sc->sc_command | EA_CMD_TX_INTACK);
877
878 ea_readbuf(sc, txhdr, 0x0000, 4);
879
880 #ifdef EA_TX_DEBUG
881 dprintf(("txstatus=%02x %02x %02x %02x\n",
882 txhdr[0], txhdr[1], txhdr[2], txhdr[3]));
883 #endif
884 txstatus = txhdr[3];
885
886 /*
887 * Did it succeed ? Did we collide ?
888 *
889 * The exact proceedure here is not clear. We should get
890 * an interrupt on a sucessfull tx or on a collision.
891 * The done flag is set after successfull tx or 16 collisions
892 * We should thus get a interrupt for each of collision
893 * and the done bit should not be set. However it does appear
894 * to be set at the same time as the collision bit ...
895 *
896 * So we will count collisions and output errors and will
897 * assume that if the done bit is set the packet was
898 * transmitted. Stats may be wrong if 16 collisions occur on
899 * a packet as the done flag should be set but the packet
900 * may not have been transmitted. so the output count might
901 * not require incrementing if the 16 collisions flags is
902 * set. I don;t know abou this until it happens.
903 */
904
905 if (txstatus & EA_TXHDR_COLLISION)
906 ifp->if_collisions++;
907 else if (txstatus & EA_TXHDR_ERROR_MASK)
908 ifp->if_oerrors++;
909
910 #if 0
911 if (txstatus & EA_TXHDR_ERROR_MASK)
912 log(LOG_WARNING, "tx packet error =%02x\n", txstatus);
913 #endif
914
915 if (txstatus & EA_PKTHDR_DONE) {
916 ifp->if_opackets++;
917
918 /* Tx next packet */
919
920 s = splnet();
921 eatxpacket(sc);
922 splx(s);
923 }
924 }
925
926
927 /* Rx interrupt ? */
928 if (status & EA_STATUS_RX_INT) {
929 dprintf(("rxint "));
930 handled = 1;
931
932 /* Acknowledge the interrupt */
933 bus_space_write_2(iot, ioh, EA_8005_COMMAND,
934 sc->sc_command | EA_CMD_RX_INTACK);
935
936 /* Install a watchdog timer needed atm to fixed rx lockups */
937 ifp->if_timer = EA_TIMEOUT;
938
939 /* Processes the received packets */
940 eagetpackets(sc);
941
942
943 #if 0
944 /* Make sure the receiver is on */
945 if ((status & EA_STATUS_RX_ON) == 0) {
946 bus_space_write_2(iot, ioh, EA_8005_COMMAND,
947 sc->sc_command | EA_CMD_RX_ON);
948 printf("rxintr: rx is off st=%04x\n",status);
949 }
950 #endif
951 }
952
953 #ifdef EA_DEBUG
954 status = bus_space_read_2(iot, ioh, EA_8005_STATUS);
955 dprintf(("st=%04x\n", status));
956 #endif
957
958 return handled;
959 }
960
961
962 void
963 eagetpackets(struct seeq8005_softc *sc)
964 {
965 bus_space_tag_t iot = sc->sc_iot;
966 bus_space_handle_t ioh = sc->sc_ioh;
967 u_int addr;
968 int len;
969 int ctrl;
970 int ptr;
971 int pack;
972 int status;
973 u_int8_t rxhdr[4];
974 struct ifnet *ifp;
975
976 ifp = &sc->sc_ethercom.ec_if;
977
978
979 /* We start from the last rx pointer position */
980 addr = sc->sc_rx_ptr;
981 sc->sc_config2 &= ~EA_CFG2_OUTPUT;
982 bus_space_write_2(iot, ioh, EA_8005_CONFIG2, sc->sc_config2);
983
984 do {
985 /* Read rx header */
986 ea_readbuf(sc, rxhdr, addr, 4);
987
988 /* Split the packet header */
989 ptr = (rxhdr[0] << 8) | rxhdr[1];
990 ctrl = rxhdr[2];
991 status = rxhdr[3];
992
993 #ifdef EA_RX_DEBUG
994 dprintf(("addr=%04x ptr=%04x ctrl=%02x status=%02x\n",
995 addr, ptr, ctrl, status));
996 #endif
997
998
999 /* Zero packet ptr ? then must be null header so exit */
1000 if (ptr == 0) break;
1001
1002
1003 /* Get packet length */
1004 len = (ptr - addr) - 4;
1005
1006 if (len < 0)
1007 len += EA_RX_BUFFER_SIZE;
1008
1009 #ifdef EA_RX_DEBUG
1010 dprintf(("len=%04x\n", len));
1011 #endif
1012
1013
1014 /* Has the packet rx completed ? if not then exit */
1015 if ((status & EA_PKTHDR_DONE) == 0)
1016 break;
1017
1018 /*
1019 * Did we have any errors? then note error and go to
1020 * next packet
1021 */
1022 if (__predict_false(status & 0x0f)) {
1023 ++ifp->if_ierrors;
1024 log(LOG_WARNING,
1025 "%s: rx packet error (%02x) - dropping packet\n",
1026 sc->sc_dev.dv_xname, status & 0x0f);
1027 sc->sc_config2 |= EA_CFG2_OUTPUT;
1028 bus_space_write_2(iot, ioh, EA_8005_CONFIG2,
1029 sc->sc_config2);
1030 ea_init(ifp);
1031 return;
1032 }
1033
1034 /*
1035 * Is the packet too big ? - this will probably be trapped
1036 * above as a receive error
1037 */
1038 if (__predict_false(len > (ETHER_MAX_LEN - ETHER_CRC_LEN))) {
1039 ++ifp->if_ierrors;
1040 log(LOG_WARNING, "%s: rx packet size error len=%d\n",
1041 sc->sc_dev.dv_xname, len);
1042 sc->sc_config2 |= EA_CFG2_OUTPUT;
1043 bus_space_write_2(iot, ioh, EA_8005_CONFIG2,
1044 sc->sc_config2);
1045 ea_init(ifp);
1046 return;
1047 }
1048
1049 ifp->if_ipackets++;
1050 /* Pass data up to upper levels. */
1051 earead(sc, addr + 4, len);
1052
1053 addr = ptr;
1054 ++pack;
1055 } while (len != 0);
1056
1057 sc->sc_config2 |= EA_CFG2_OUTPUT;
1058 bus_space_write_2(iot, ioh, EA_8005_CONFIG2, sc->sc_config2);
1059
1060 #ifdef EA_RX_DEBUG
1061 dprintf(("new rx ptr=%04x\n", addr));
1062 #endif
1063
1064
1065 /* Store new rx pointer */
1066 sc->sc_rx_ptr = addr;
1067 bus_space_write_2(iot, ioh, EA_8005_RX_END, sc->sc_rx_ptr >> 8);
1068
1069 /* Make sure the receiver is on */
1070 bus_space_write_2(iot, ioh, EA_8005_COMMAND,
1071 sc->sc_command | EA_CMD_RX_ON);
1072
1073 }
1074
1075
1076 /*
1077 * Pass a packet up to the higher levels.
1078 */
1079
1080 static void
1081 earead(struct seeq8005_softc *sc, int addr, int len)
1082 {
1083 struct mbuf *m;
1084 struct ifnet *ifp;
1085
1086 ifp = &sc->sc_ethercom.ec_if;
1087
1088 /* Pull packet off interface. */
1089 m = eaget(sc, addr, len, ifp);
1090 if (m == 0)
1091 return;
1092
1093 #ifdef EA_RX_DEBUG
1094 dprintf(("%s-->", ether_sprintf(eh->ether_shost)));
1095 dprintf(("%s\n", ether_sprintf(eh->ether_dhost)));
1096 #endif
1097
1098 #if NBPFILTER > 0
1099 /*
1100 * Check if there's a BPF listener on this interface.
1101 * If so, hand off the raw packet to bpf.
1102 */
1103 if (ifp->if_bpf)
1104 bpf_mtap(ifp->if_bpf, m);
1105 #endif
1106
1107 (*ifp->if_input)(ifp, m);
1108 }
1109
1110 /*
1111 * Pull read data off a interface. Len is length of data, with local net
1112 * header stripped. We copy the data into mbufs. When full cluster sized
1113 * units are present we copy into clusters.
1114 */
1115
1116 struct mbuf *
1117 eaget(struct seeq8005_softc *sc, int addr, int totlen, struct ifnet *ifp)
1118 {
1119 struct mbuf *top, **mp, *m;
1120 int len;
1121 u_int cp, epkt;
1122
1123 cp = addr;
1124 epkt = cp + totlen;
1125
1126 MGETHDR(m, M_DONTWAIT, MT_DATA);
1127 if (m == 0)
1128 return 0;
1129 m->m_pkthdr.rcvif = ifp;
1130 m->m_pkthdr.len = totlen;
1131 m->m_len = MHLEN;
1132 top = 0;
1133 mp = ⊤
1134
1135 while (totlen > 0) {
1136 if (top) {
1137 MGET(m, M_DONTWAIT, MT_DATA);
1138 if (m == 0) {
1139 m_freem(top);
1140 return 0;
1141 }
1142 m->m_len = MLEN;
1143 }
1144 len = min(totlen, epkt - cp);
1145 if (len >= MINCLSIZE) {
1146 MCLGET(m, M_DONTWAIT);
1147 if (m->m_flags & M_EXT)
1148 m->m_len = len = min(len, MCLBYTES);
1149 else
1150 len = m->m_len;
1151 } else {
1152 /*
1153 * Place initial small packet/header at end of mbuf.
1154 */
1155 if (len < m->m_len) {
1156 if (top == 0 && len + max_linkhdr <= m->m_len)
1157 m->m_data += max_linkhdr;
1158 m->m_len = len;
1159 } else
1160 len = m->m_len;
1161 }
1162 if (top == 0) {
1163 /* Make sure the payload is aligned */
1164 caddr_t newdata = (caddr_t)
1165 ALIGN(m->m_data + sizeof(struct ether_header)) -
1166 sizeof(struct ether_header);
1167 len -= newdata - m->m_data;
1168 m->m_len = len;
1169 m->m_data = newdata;
1170 }
1171 ea_readbuf(sc, mtod(m, u_char *),
1172 cp < EA_BUFFER_SIZE ? cp : cp - EA_RX_BUFFER_SIZE,
1173 len);
1174 cp += len;
1175 *mp = m;
1176 mp = &m->m_next;
1177 totlen -= len;
1178 if (cp == epkt)
1179 cp = addr;
1180 }
1181
1182 return top;
1183 }
1184
1185 /*
1186 * Process an ioctl request. Mostly boilerplate.
1187 */
1188 static int
1189 ea_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
1190 {
1191 struct seeq8005_softc *sc = ifp->if_softc;
1192 int s, error = 0;
1193
1194 s = splnet();
1195 switch (cmd) {
1196
1197 default:
1198 error = ether_ioctl(ifp, cmd, data);
1199 if (error == ENETRESET) {
1200 /*
1201 * Multicast list has changed; set the hardware filter
1202 * accordingly.
1203 */
1204 ea_mc_reset(sc);
1205 error = 0;
1206 }
1207 break;
1208 }
1209
1210 splx(s);
1211 return error;
1212 }
1213
1214 /* Must be called at splnet() */
1215 static void
1216 ea_mc_reset(struct seeq8005_softc *sc)
1217 {
1218 struct ether_multi *enm;
1219 struct ether_multistep step;
1220 int naddr, maxaddrs;
1221
1222 naddr = 0;
1223 maxaddrs = (sc->sc_flags & SEEQ8005_80C04) ? 5 : 0;
1224 ETHER_FIRST_MULTI(step, &sc->sc_ethercom, enm);
1225 while (enm != NULL) {
1226 /* Have we got space? */
1227 if (naddr >= maxaddrs ||
1228 bcmp(enm->enm_addrlo, enm->enm_addrhi, 6) != 0) {
1229 sc->sc_ethercom.ec_if.if_flags |= IFF_ALLMULTI;
1230 ea_ioctl(&sc->sc_ethercom.ec_if, SIOCSIFFLAGS, NULL);
1231 return;
1232 }
1233 ea_set_address(sc, naddr, enm->enm_addrlo);
1234 sc->sc_config1 |= EA_CFG1_STATION_ADDR0 << naddr;
1235 naddr++;
1236 ETHER_NEXT_MULTI(step, enm);
1237 }
1238 for (; naddr < maxaddrs; naddr++)
1239 sc->sc_config1 &= ~(EA_CFG1_STATION_ADDR0 << naddr);
1240 bus_space_write_2(sc->sc_iot, sc->sc_ioh, EA_8005_CONFIG1,
1241 sc->sc_config1);
1242 }
1243
1244 /*
1245 * Device timeout routine.
1246 *
1247 * Ok I am not sure exactly how the device timeout should work....
1248 * Currently what will happens is that that the device timeout is only
1249 * set when a packet it received. This indicates we are on an active
1250 * network and thus we should expect more packets. If non arrive in
1251 * in the timeout period then we reinitialise as we may have jammed.
1252 * We zero the timeout at this point so that we don't end up with
1253 * an endless stream of timeouts if the network goes down.
1254 */
1255
1256 static void
1257 ea_watchdog(struct ifnet *ifp)
1258 {
1259 struct seeq8005_softc *sc = ifp->if_softc;
1260
1261 log(LOG_ERR, "%s: device timeout\n", sc->sc_dev.dv_xname);
1262 ifp->if_oerrors++;
1263 dprintf(("ea_watchdog: "));
1264 dprintf(("st=%04x\n",
1265 bus_space_read_2(sc->sc_iot, sc->sc_ioh, EA_8005_STATUS)));
1266
1267 /* Kick the interface */
1268
1269 ea_init(ifp);
1270
1271 /* ifp->if_timer = EA_TIMEOUT;*/
1272 ifp->if_timer = 0;
1273 }
1274
1275 /* End of if_ea.c */
1276