seeq8005.c revision 1.8.2.2 1 /* $NetBSD: seeq8005.c,v 1.8.2.2 2001/06/21 20:03:14 nathanw Exp $ */
2
3 /*
4 * Copyright (c) 2000 Ben Harris
5 * Copyright (c) 1995-1998 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 * for the NetBSD Project.
20 * 4. The name of the company nor the name of the author may be used to
21 * endorse or promote products derived from this software without specific
22 * prior written permission.
23 *
24 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
25 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
26 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
27 * IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
28 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
29 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
30 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 * SUCH DAMAGE.
35 */
36 /*
37 * seeq8005.c - SEEQ 8005 device driver
38 */
39 /*
40 * This driver currently supports the following chip:
41 * SEEQ 8005 Advanced Ethernet Data Link Controller
42 * SEEQ 80C04 Ethernet Data Link Controller
43 * SEEQ 80C04A AutoDUPLEX CMOS Ethernet Data Link Controller
44 */
45 /*
46 * More information on the 8004 and 8005 AEDLC controllers can be found in
47 * the SEEQ Technology Inc 1992 Data Comm Devices data book.
48 *
49 * This data book may no longer be available as these are rather old chips
50 * (1991 - 1993)
51 */
52 /*
53 * This driver is based on the arm32 ea(4) driver, hence the names of many
54 * of the functions.
55 */
56 /*
57 * Bugs/possible improvements:
58 * - Does not currently support DMA
59 * - Does not transmit multiple packets in one go
60 * - Does not support 8-bit busses
61 */
62
63 #include <sys/types.h>
64 #include <sys/param.h>
65
66 __RCSID("$NetBSD: seeq8005.c,v 1.8.2.2 2001/06/21 20:03:14 nathanw Exp $");
67
68 #include <sys/systm.h>
69 #include <sys/endian.h>
70 #include <sys/errno.h>
71 #include <sys/ioctl.h>
72 #include <sys/mbuf.h>
73 #include <sys/socket.h>
74 #include <sys/syslog.h>
75 #include <sys/device.h>
76
77 #include <net/if.h>
78 #include <net/if_dl.h>
79 #include <net/if_types.h>
80 #include <net/if_ether.h>
81 #include <net/if_media.h>
82
83 #include "bpfilter.h"
84 #if NBPFILTER > 0
85 #include <net/bpf.h>
86 #include <net/bpfdesc.h>
87 #endif
88
89 #include <machine/bus.h>
90 #include <machine/intr.h>
91
92 #include <dev/ic/seeq8005reg.h>
93 #include <dev/ic/seeq8005var.h>
94
95 /*#define SEEQ_DEBUG*/
96
97 /* for debugging convenience */
98 #ifdef SEEQ8005_DEBUG
99 #define SEEQ_DEBUG_MISC 1
100 #define SEEQ_DEBUG_TX 2
101 #define SEEQ_DEBUG_RX 4
102 #define SEEQ_DEBUG_PKT 8
103 #define SEEQ_DEBUG_TXINT 16
104 #define SEEQ_DEBUG_RXINT 32
105 int seeq8005_debug = 0;
106 #define DPRINTF(f, x) { if (seeq8005_debug & (f)) printf x; }
107 #else
108 #define DPRINTF(f, x)
109 #endif
110
111 #define SEEQ_TX_BUFFER_SIZE 0x800 /* (> MAX_ETHER_LEN) */
112
113 /*
114 * prototypes
115 */
116
117 static int ea_init(struct ifnet *);
118 static int ea_ioctl(struct ifnet *, u_long, caddr_t);
119 static void ea_start(struct ifnet *);
120 static void ea_watchdog(struct ifnet *);
121 static void ea_chipreset(struct seeq8005_softc *);
122 static void ea_ramtest(struct seeq8005_softc *);
123 static int ea_stoptx(struct seeq8005_softc *);
124 static int ea_stoprx(struct seeq8005_softc *);
125 static void ea_stop(struct ifnet *, int);
126 static void ea_await_fifo_empty(struct seeq8005_softc *);
127 static void ea_await_fifo_full(struct seeq8005_softc *);
128 static void ea_writebuf(struct seeq8005_softc *, u_char *, int, size_t);
129 static void ea_readbuf(struct seeq8005_softc *, u_char *, int, size_t);
130 static void ea_select_buffer(struct seeq8005_softc *, int);
131 static void ea_set_address(struct seeq8005_softc *, int, const u_int8_t *);
132 static void ea_read(struct seeq8005_softc *, int, int);
133 static struct mbuf *ea_get(struct seeq8005_softc *, int, int, struct ifnet *);
134 static void ea_txint(struct seeq8005_softc *);
135 static void ea_rxint(struct seeq8005_softc *);
136 static void eatxpacket(struct seeq8005_softc *);
137 static int ea_writembuf(struct seeq8005_softc *, struct mbuf *, int);
138 static void ea_mc_reset(struct seeq8005_softc *);
139 static void ea_mc_reset_8004(struct seeq8005_softc *);
140 static void ea_mc_reset_8005(struct seeq8005_softc *);
141 static int ea_mediachange(struct ifnet *);
142 static void ea_mediastatus(struct ifnet *, struct ifmediareq *);
143
144
145 /*
146 * Attach chip.
147 */
148
149 void
150 seeq8005_attach(struct seeq8005_softc *sc, const u_int8_t *myaddr, int *media,
151 int nmedia, int defmedia)
152 {
153 struct ifnet *ifp = &sc->sc_ethercom.ec_if;
154 u_int id;
155
156 KASSERT(myaddr != NULL);
157 printf(" address %s", ether_sprintf(myaddr));
158
159 /* Stop the board. */
160
161 ea_chipreset(sc);
162
163 /* Get the product ID */
164
165 ea_select_buffer(sc, SEEQ_BUFCODE_PRODUCTID);
166 id = bus_space_read_2(sc->sc_iot, sc->sc_ioh, SEEQ_BUFWIN);
167
168 switch (id & SEEQ_PRODUCTID_MASK) {
169 case SEEQ_PRODUCTID_8004:
170 sc->sc_variant = SEEQ_8004;
171 switch (id & SEEQ_PRODUCTID_REV_MASK) {
172 case SEEQ_PRODUCTID_REV_80C04:
173 printf(", SEEQ 80C04\n");
174 break;
175 case SEEQ_PRODUCTID_REV_80C04A:
176 printf(", SEEQ 80C04A\n");
177 break;
178 default:
179 /* Unknown SEEQ 8004 variants */
180 printf(", SEEQ 8004 rev %x\n",
181 id & SEEQ_PRODUCTID_REV_MASK);
182 break;
183 }
184 break;
185 default: /* XXX */
186 sc->sc_variant = SEEQ_8005;
187 printf(", SEEQ 8005\n");
188 break;
189 }
190
191 /* Both the 8004 and 8005 are designed for 64K Buffer memory */
192 sc->sc_buffersize = SEEQ_MAX_BUFFER_SIZE;
193
194 /*
195 * Set up tx and rx buffers.
196 *
197 * We use approximately a quarter of the packet memory for TX
198 * buffers and the rest for RX buffers
199 */
200 /* sc->sc_tx_bufs = sc->sc_buffersize / SEEQ_TX_BUFFER_SIZE / 4; */
201 sc->sc_tx_bufs = 1;
202 sc->sc_tx_bufsize = sc->sc_tx_bufs * SEEQ_TX_BUFFER_SIZE;
203 sc->sc_rx_bufsize = sc->sc_buffersize - sc->sc_tx_bufsize;
204 sc->sc_enabled = 0;
205
206 /* Test the RAM */
207 ea_ramtest(sc);
208
209 printf("%s: %dKB packet memory, txbuf=%dKB (%d buffers), rxbuf=%dKB",
210 sc->sc_dev.dv_xname, sc->sc_buffersize >> 10,
211 sc->sc_tx_bufsize >> 10, sc->sc_tx_bufs, sc->sc_rx_bufsize >> 10);
212
213 /* Initialise ifnet structure. */
214
215 bcopy(sc->sc_dev.dv_xname, ifp->if_xname, IFNAMSIZ);
216 ifp->if_softc = sc;
217 ifp->if_start = ea_start;
218 ifp->if_ioctl = ea_ioctl;
219 ifp->if_init = ea_init;
220 ifp->if_stop = ea_stop;
221 ifp->if_watchdog = ea_watchdog;
222 ifp->if_flags = IFF_BROADCAST | IFF_MULTICAST | IFF_NOTRAILERS;
223 if (sc->sc_variant == SEEQ_8004)
224 ifp->if_flags |= IFF_SIMPLEX;
225 IFQ_SET_READY(&ifp->if_snd);
226
227 /* Initialize media goo. */
228 ifmedia_init(&sc->sc_media, 0, ea_mediachange, ea_mediastatus);
229 if (media != NULL) {
230 int i;
231
232 for (i = 0; i < nmedia; i++)
233 ifmedia_add(&sc->sc_media, media[i], 0, NULL);
234 ifmedia_set(&sc->sc_media, defmedia);
235 } else {
236 ifmedia_add(&sc->sc_media, IFM_ETHER|IFM_MANUAL, 0, NULL);
237 ifmedia_set(&sc->sc_media, IFM_ETHER|IFM_MANUAL);
238 }
239
240 /* Now we can attach the interface. */
241
242 if_attach(ifp);
243 ether_ifattach(ifp, myaddr);
244
245 printf("\n");
246 }
247
248 /*
249 * Media change callback.
250 */
251 static int
252 ea_mediachange(struct ifnet *ifp)
253 {
254 struct seeq8005_softc *sc = ifp->if_softc;
255
256 if (sc->sc_mediachange)
257 return ((*sc->sc_mediachange)(sc));
258 return (EINVAL);
259 }
260
261 /*
262 * Media status callback.
263 */
264 static void
265 ea_mediastatus(struct ifnet *ifp, struct ifmediareq *ifmr)
266 {
267 struct seeq8005_softc *sc = ifp->if_softc;
268
269 if (sc->sc_enabled == 0) {
270 ifmr->ifm_active = IFM_ETHER | IFM_NONE;
271 ifmr->ifm_status = 0;
272 return;
273 }
274
275 if (sc->sc_mediastatus)
276 (*sc->sc_mediastatus)(sc, ifmr);
277 }
278
279 /*
280 * Test the RAM on the ethernet card.
281 */
282
283 void
284 ea_ramtest(struct seeq8005_softc *sc)
285 {
286 bus_space_tag_t iot = sc->sc_iot;
287 bus_space_handle_t ioh = sc->sc_ioh;
288 int loop;
289 u_int sum = 0;
290
291 /*
292 * Test the buffer memory on the board.
293 * Write simple pattens to it and read them back.
294 */
295
296 /* Set up the whole buffer RAM for writing */
297
298 ea_select_buffer(sc, SEEQ_BUFCODE_TX_EAP);
299 bus_space_write_2(iot, ioh, SEEQ_BUFWIN, (SEEQ_MAX_BUFFER_SIZE >> 8) - 1);
300 bus_space_write_2(iot, ioh, SEEQ_TX_PTR, 0x0000);
301 bus_space_write_2(iot, ioh, SEEQ_RX_PTR, SEEQ_MAX_BUFFER_SIZE - 2);
302
303 #define SEEQ_RAMTEST_LOOP(value) \
304 do { \
305 /* Set the write start address and write a pattern */ \
306 ea_writebuf(sc, NULL, 0x0000, 0); \
307 for (loop = 0; loop < SEEQ_MAX_BUFFER_SIZE; loop += 2) \
308 bus_space_write_2(iot, ioh, SEEQ_BUFWIN, (value)); \
309 \
310 /* Set the read start address and verify the pattern */ \
311 ea_readbuf(sc, NULL, 0x0000, 0); \
312 for (loop = 0; loop < SEEQ_MAX_BUFFER_SIZE; loop += 2) \
313 if (bus_space_read_2(iot, ioh, SEEQ_BUFWIN) != (value)) \
314 ++sum; \
315 } while (/*CONSTCOND*/0)
316
317 SEEQ_RAMTEST_LOOP(loop);
318 SEEQ_RAMTEST_LOOP(loop ^ (SEEQ_MAX_BUFFER_SIZE - 1));
319 SEEQ_RAMTEST_LOOP(0xaa55);
320 SEEQ_RAMTEST_LOOP(0x55aa);
321
322 /* Report */
323
324 if (sum > 0)
325 printf("%s: buffer RAM failed self test, %d faults\n",
326 sc->sc_dev.dv_xname, sum);
327 }
328
329
330 /*
331 * Stop the tx interface.
332 *
333 * Returns 0 if the tx was already stopped or 1 if it was active
334 */
335
336 static int
337 ea_stoptx(struct seeq8005_softc *sc)
338 {
339 bus_space_tag_t iot = sc->sc_iot;
340 bus_space_handle_t ioh = sc->sc_ioh;
341 int timeout;
342 int status;
343
344 DPRINTF(SEEQ_DEBUG_TX, ("ea_stoptx()\n"));
345
346 sc->sc_enabled = 0;
347
348 status = bus_space_read_2(iot, ioh, SEEQ_STATUS);
349 if (!(status & SEEQ_STATUS_TX_ON))
350 return 0;
351
352 /* Stop any tx and wait for confirmation */
353 bus_space_write_2(iot, ioh, SEEQ_COMMAND,
354 sc->sc_command | SEEQ_CMD_TX_OFF);
355
356 timeout = 20000;
357 do {
358 status = bus_space_read_2(iot, ioh, SEEQ_STATUS);
359 delay(1);
360 } while ((status & SEEQ_STATUS_TX_ON) && --timeout > 0);
361 if (timeout == 0)
362 log(LOG_ERR, "%s: timeout waiting for tx termination\n",
363 sc->sc_dev.dv_xname);
364
365 /* Clear any pending tx interrupt */
366 bus_space_write_2(iot, ioh, SEEQ_COMMAND,
367 sc->sc_command | SEEQ_CMD_TX_INTACK);
368 return 1;
369 }
370
371
372 /*
373 * Stop the rx interface.
374 *
375 * Returns 0 if the tx was already stopped or 1 if it was active
376 */
377
378 static int
379 ea_stoprx(struct seeq8005_softc *sc)
380 {
381 bus_space_tag_t iot = sc->sc_iot;
382 bus_space_handle_t ioh = sc->sc_ioh;
383 int timeout;
384 int status;
385
386 DPRINTF(SEEQ_DEBUG_RX, ("ea_stoprx()\n"));
387
388 status = bus_space_read_2(iot, ioh, SEEQ_STATUS);
389 if (!(status & SEEQ_STATUS_RX_ON))
390 return 0;
391
392 /* Stop any rx and wait for confirmation */
393
394 bus_space_write_2(iot, ioh, SEEQ_COMMAND,
395 sc->sc_command | SEEQ_CMD_RX_OFF);
396
397 timeout = 20000;
398 do {
399 status = bus_space_read_2(iot, ioh, SEEQ_STATUS);
400 } while ((status & SEEQ_STATUS_RX_ON) && --timeout > 0);
401 if (timeout == 0)
402 log(LOG_ERR, "%s: timeout waiting for rx termination\n",
403 sc->sc_dev.dv_xname);
404
405 /* Clear any pending rx interrupt */
406
407 bus_space_write_2(iot, ioh, SEEQ_COMMAND,
408 sc->sc_command | SEEQ_CMD_RX_INTACK);
409 return 1;
410 }
411
412
413 /*
414 * Stop interface.
415 * Stop all IO and shut the interface down
416 */
417
418 static void
419 ea_stop(struct ifnet *ifp, int disable)
420 {
421 struct seeq8005_softc *sc = ifp->if_softc;
422 bus_space_tag_t iot = sc->sc_iot;
423 bus_space_handle_t ioh = sc->sc_ioh;
424
425 DPRINTF(SEEQ_DEBUG_MISC, ("ea_stop()\n"));
426
427 /* Stop all IO */
428 ea_stoptx(sc);
429 ea_stoprx(sc);
430
431 /* Disable rx and tx interrupts */
432 sc->sc_command &= (SEEQ_CMD_RX_INTEN | SEEQ_CMD_TX_INTEN);
433
434 /* Clear any pending interrupts */
435 bus_space_write_2(iot, ioh, SEEQ_COMMAND,
436 sc->sc_command | SEEQ_CMD_RX_INTACK |
437 SEEQ_CMD_TX_INTACK | SEEQ_CMD_DMA_INTACK |
438 SEEQ_CMD_BW_INTACK);
439
440 if (sc->sc_variant == SEEQ_8004) {
441 /* Put the chip to sleep */
442 ea_select_buffer(sc, SEEQ_BUFCODE_CONFIG3);
443 bus_space_write_2(iot, ioh, SEEQ_BUFWIN,
444 sc->sc_config3 | SEEQ_CFG3_SLEEP);
445 }
446
447 /* Cancel any watchdog timer */
448 sc->sc_ethercom.ec_if.if_timer = 0;
449 }
450
451
452 /*
453 * Reset the chip
454 * Following this the software registers are reset
455 */
456
457 static void
458 ea_chipreset(struct seeq8005_softc *sc)
459 {
460 bus_space_tag_t iot = sc->sc_iot;
461 bus_space_handle_t ioh = sc->sc_ioh;
462
463 DPRINTF(SEEQ_DEBUG_MISC, ("ea_chipreset()\n"));
464
465 /* Reset the controller. Min of 4us delay here */
466
467 bus_space_write_2(iot, ioh, SEEQ_CONFIG2, SEEQ_CFG2_RESET);
468 delay(4);
469
470 sc->sc_command = 0;
471 sc->sc_config1 = 0;
472 sc->sc_config2 = 0;
473 sc->sc_config3 = 0;
474 }
475
476
477 /*
478 * If the DMA FIFO's in write mode, wait for it to empty. Needed when
479 * switching the FIFO from write to read. We also use it when changing
480 * the address for writes.
481 */
482 static void
483 ea_await_fifo_empty(struct seeq8005_softc *sc)
484 {
485 bus_space_tag_t iot = sc->sc_iot;
486 bus_space_handle_t ioh = sc->sc_ioh;
487 int timeout;
488
489 timeout = 20000;
490 if ((bus_space_read_2(iot, ioh, SEEQ_STATUS) &
491 SEEQ_STATUS_FIFO_DIR) != 0)
492 return; /* FIFO is reading anyway. */
493 while (--timeout > 0)
494 if (bus_space_read_2(iot, ioh, SEEQ_STATUS) &
495 SEEQ_STATUS_FIFO_EMPTY)
496 return;
497 log(LOG_ERR, "%s: DMA FIFO failed to empty\n", sc->sc_dev.dv_xname);
498 }
499
500 /*
501 * Wait for the DMA FIFO to fill before reading from it.
502 */
503 static void
504 ea_await_fifo_full(struct seeq8005_softc *sc)
505 {
506 bus_space_tag_t iot = sc->sc_iot;
507 bus_space_handle_t ioh = sc->sc_ioh;
508 int timeout;
509
510 timeout = 20000;
511 while (--timeout > 0)
512 if (bus_space_read_2(iot, ioh, SEEQ_STATUS) &
513 SEEQ_STATUS_FIFO_FULL)
514 return;
515 log(LOG_ERR, "%s: DMA FIFO failed to fill\n", sc->sc_dev.dv_xname);
516 }
517
518 /*
519 * write to the buffer memory on the interface
520 *
521 * The buffer address is set to ADDR.
522 * If len != 0 then data is copied from the address starting at buf
523 * to the interface buffer.
524 * BUF must be usable as a u_int16_t *.
525 * If LEN is odd, it must be safe to overwrite one extra byte.
526 */
527
528 static void
529 ea_writebuf(struct seeq8005_softc *sc, u_char *buf, int addr, size_t len)
530 {
531 bus_space_tag_t iot = sc->sc_iot;
532 bus_space_handle_t ioh = sc->sc_ioh;
533
534 DPRINTF(SEEQ_DEBUG_MISC, ("writebuf: st=%04x\n",
535 bus_space_read_2(iot, ioh, SEEQ_STATUS)));
536
537 #ifdef DIAGNOSTIC
538 if (__predict_false(!ALIGNED_POINTER(buf, u_int16_t)))
539 panic("%s: unaligned writebuf", sc->sc_dev.dv_xname);
540 if (__predict_false(addr >= SEEQ_MAX_BUFFER_SIZE))
541 panic("%s: writebuf out of range", sc->sc_dev.dv_xname);
542 #endif
543
544 /* Assume that copying too much is safe. */
545 if (len % 2 != 0)
546 len++;
547
548 if (addr != -1) {
549 ea_await_fifo_empty(sc);
550
551 ea_select_buffer(sc, SEEQ_BUFCODE_LOCAL_MEM);
552 bus_space_write_2(iot, ioh, SEEQ_COMMAND,
553 sc->sc_command | SEEQ_CMD_FIFO_WRITE);
554 bus_space_write_2(iot, ioh, SEEQ_DMA_ADDR, addr);
555 }
556
557 if (len > 0)
558 bus_space_write_multi_2(iot, ioh, SEEQ_BUFWIN,
559 (u_int16_t *)buf, len / 2);
560 /* Leave FIFO to empty in the background */
561 }
562
563
564 /*
565 * read from the buffer memory on the interface
566 *
567 * The buffer address is set to ADDR.
568 * If len != 0 then data is copied from the interface buffer to the
569 * address starting at buf.
570 * BUF must be usable as a u_int16_t *.
571 * If LEN is odd, it must be safe to overwrite one extra byte.
572 */
573
574 static void
575 ea_readbuf(struct seeq8005_softc *sc, u_char *buf, int addr, size_t len)
576 {
577 bus_space_tag_t iot = sc->sc_iot;
578 bus_space_handle_t ioh = sc->sc_ioh;
579 int runup;
580
581 DPRINTF(SEEQ_DEBUG_MISC, ("readbuf: st=%04x addr=%04x len=%d\n",
582 bus_space_read_2(iot, ioh, SEEQ_STATUS), addr, len));
583
584 #ifdef DIAGNOSTIC
585 if (__predict_false(!ALIGNED_POINTER(buf, u_int16_t)))
586 panic("%s: unaligned readbuf", sc->sc_dev.dv_xname);
587 if (__predict_false(addr >= SEEQ_MAX_BUFFER_SIZE))
588 panic("%s: readbuf out of range", sc->sc_dev.dv_xname);
589 #endif
590
591 /* Assume that copying too much is safe. */
592 if (len % 2 != 0)
593 len++;
594
595 if (addr != -1) {
596 /*
597 * SEEQ 80C04 bug:
598 * Starting reading from certain addresses seems to cause
599 * us to get bogus results, so we avoid them.
600 */
601 runup = 0;
602 if (sc->sc_variant == SEEQ_8004 &&
603 ((addr & 0x00ff) == 0x00ea ||
604 (addr & 0x00ff) == 0x00ee ||
605 (addr & 0x00ff) == 0x00f0))
606 runup = (addr & 0x00ff) - 0x00e8;
607
608 ea_await_fifo_empty(sc);
609
610 ea_select_buffer(sc, SEEQ_BUFCODE_LOCAL_MEM);
611
612 /*
613 * 80C04 bug workaround. I found this in the old arm32 "eb"
614 * driver. I've no idea what it does, but it seems to stop
615 * the chip mangling data so often.
616 */
617 bus_space_write_2(iot, ioh, SEEQ_COMMAND,
618 sc->sc_command | SEEQ_CMD_FIFO_WRITE);
619 ea_await_fifo_empty(sc);
620
621 bus_space_write_2(iot, ioh, SEEQ_DMA_ADDR, addr - runup);
622 bus_space_write_2(iot, ioh, SEEQ_COMMAND,
623 sc->sc_command | SEEQ_CMD_FIFO_READ);
624
625 ea_await_fifo_full(sc);
626 while (runup > 0) {
627 (void)bus_space_read_2(iot, ioh, SEEQ_BUFWIN);
628 runup -= 2;
629 }
630 }
631
632 if (len > 0)
633 bus_space_read_multi_2(iot, ioh, SEEQ_BUFWIN,
634 (u_int16_t *)buf, len / 2);
635 }
636
637 static void
638 ea_select_buffer(struct seeq8005_softc *sc, int bufcode)
639 {
640
641 bus_space_write_2(sc->sc_iot, sc->sc_ioh, SEEQ_CONFIG1,
642 sc->sc_config1 | bufcode);
643 }
644
645 /* Must be called at splnet */
646 static void
647 ea_set_address(struct seeq8005_softc *sc, int which, u_int8_t const *ea)
648 {
649 int i;
650
651 ea_select_buffer(sc, SEEQ_BUFCODE_STATION_ADDR0 + which);
652 for (i = 0; i < ETHER_ADDR_LEN; ++i)
653 bus_space_write_2(sc->sc_iot, sc->sc_ioh, SEEQ_BUFWIN,
654 ea[i]);
655 }
656
657 /*
658 * Initialize interface.
659 *
660 * This should leave the interface in a state for packet reception and
661 * transmission.
662 */
663
664 static int
665 ea_init(struct ifnet *ifp)
666 {
667 struct seeq8005_softc *sc = ifp->if_softc;
668 bus_space_tag_t iot = sc->sc_iot;
669 bus_space_handle_t ioh = sc->sc_ioh;
670 int s;
671
672 DPRINTF(SEEQ_DEBUG_MISC, ("ea_init()\n"));
673
674 s = splnet();
675
676 /* First, reset the board. */
677
678 ea_chipreset(sc);
679
680 /* Set up defaults for the registers */
681
682 sc->sc_command = 0;
683 sc->sc_config1 = 0;
684 #if BYTE_ORDER == BIG_ENDIAN
685 sc->sc_config2 = SEEQ_CFG2_BYTESWAP;
686 #else
687 sc->sc_config2 = 0;
688 #endif
689 sc->sc_config3 = 0;
690
691 bus_space_write_2(iot, ioh, SEEQ_COMMAND, sc->sc_command);
692 bus_space_write_2(iot, ioh, SEEQ_CONFIG1, sc->sc_config1);
693 bus_space_write_2(iot, ioh, SEEQ_CONFIG2, sc->sc_config2);
694 if (sc->sc_variant == SEEQ_8004) {
695 ea_select_buffer(sc, SEEQ_BUFCODE_CONFIG3);
696 bus_space_write_2(iot, ioh, SEEQ_BUFWIN, sc->sc_config3);
697 }
698
699 /* Write the station address - the receiver must be off */
700 ea_set_address(sc, 0, LLADDR(ifp->if_sadl));
701
702 /* Split board memory into Rx and Tx. */
703 ea_select_buffer(sc, SEEQ_BUFCODE_TX_EAP);
704 bus_space_write_2(iot, ioh, SEEQ_BUFWIN, (sc->sc_tx_bufsize>> 8) - 1);
705
706 if (sc->sc_variant == SEEQ_8004)
707 sc->sc_config2 |= SEEQ_CFG2_RX_TX_DISABLE;
708
709 /* Configure rx. */
710 ea_mc_reset(sc);
711 if (ifp->if_flags & IFF_PROMISC)
712 sc->sc_config1 = SEEQ_CFG1_PROMISCUOUS;
713 else if ((ifp->if_flags & IFF_ALLMULTI) || sc->sc_variant == SEEQ_8004)
714 sc->sc_config1 = SEEQ_CFG1_MULTICAST;
715 else
716 sc->sc_config1 = SEEQ_CFG1_BROADCAST;
717 sc->sc_config1 |= SEEQ_CFG1_STATION_ADDR0;
718 bus_space_write_2(iot, ioh, SEEQ_CONFIG1, sc->sc_config1);
719
720 /* Setup the Rx pointers */
721 sc->sc_rx_ptr = sc->sc_tx_bufsize;
722
723 bus_space_write_2(iot, ioh, SEEQ_RX_PTR, sc->sc_rx_ptr);
724 bus_space_write_2(iot, ioh, SEEQ_RX_END, sc->sc_rx_ptr >> 8);
725
726
727 /* Place a NULL header at the beginning of the receive area */
728 ea_writebuf(sc, NULL, sc->sc_rx_ptr, 0);
729
730 bus_space_write_2(iot, ioh, SEEQ_BUFWIN, 0x0000);
731 bus_space_write_2(iot, ioh, SEEQ_BUFWIN, 0x0000);
732
733
734 /* Configure TX. */
735 DPRINTF(SEEQ_DEBUG_MISC, ("Configuring tx...\n"));
736
737 bus_space_write_2(iot, ioh, SEEQ_TX_PTR, 0x0000);
738
739 sc->sc_config2 |= SEEQ_CFG2_OUTPUT;
740 bus_space_write_2(iot, ioh, SEEQ_CONFIG2, sc->sc_config2);
741
742 /* Reset tx buffer pointers */
743 sc->sc_tx_cur = 0;
744 sc->sc_tx_used = 0;
745 sc->sc_tx_next = 0;
746
747 /* Place a NULL header at the beginning of the transmit area */
748 ea_writebuf(sc, NULL, 0x0000, 0);
749
750 bus_space_write_2(iot, ioh, SEEQ_BUFWIN, 0x0000);
751 bus_space_write_2(iot, ioh, SEEQ_BUFWIN, 0x0000);
752
753 sc->sc_command |= SEEQ_CMD_TX_INTEN;
754 bus_space_write_2(iot, ioh, SEEQ_COMMAND, sc->sc_command);
755
756 /* Turn on Rx */
757 sc->sc_command |= SEEQ_CMD_RX_INTEN;
758 bus_space_write_2(iot, ioh, SEEQ_COMMAND,
759 sc->sc_command | SEEQ_CMD_RX_ON);
760
761 /* TX_ON gets set by ea_txpacket when there's something to transmit. */
762
763
764 /* Set flags appropriately. */
765 ifp->if_flags |= IFF_RUNNING;
766 ifp->if_flags &= ~IFF_OACTIVE;
767 sc->sc_enabled = 1;
768
769 /* And start output. */
770 ea_start(ifp);
771
772 splx(s);
773 return 0;
774 }
775
776 /*
777 * Start output on interface. Get datagrams from the queue and output them,
778 * giving the receiver a chance between datagrams. Call only from splnet or
779 * interrupt level!
780 */
781
782 static void
783 ea_start(struct ifnet *ifp)
784 {
785 struct seeq8005_softc *sc = ifp->if_softc;
786 int s;
787
788 s = splnet();
789 DPRINTF(SEEQ_DEBUG_TX, ("ea_start()...\n"));
790
791 /*
792 * Don't do anything if output is active. seeq8005intr() will call
793 * us (actually eatxpacket()) back when the card's ready for more
794 * frames.
795 */
796 if (ifp->if_flags & IFF_OACTIVE)
797 return;
798
799 /* Mark interface as output active */
800
801 ifp->if_flags |= IFF_OACTIVE;
802
803 /* tx packets */
804
805 eatxpacket(sc);
806 splx(s);
807 }
808
809
810 /*
811 * Transfer a packet to the interface buffer and start transmission
812 *
813 * Called at splnet()
814 */
815
816 void
817 eatxpacket(struct seeq8005_softc *sc)
818 {
819 bus_space_tag_t iot = sc->sc_iot;
820 bus_space_handle_t ioh = sc->sc_ioh;
821 struct mbuf *m0;
822 struct ifnet *ifp;
823
824 ifp = &sc->sc_ethercom.ec_if;
825
826 /* Dequeue the next packet. */
827 IFQ_DEQUEUE(&ifp->if_snd, m0);
828
829 /* If there's nothing to send, return. */
830 if (!m0) {
831 ifp->if_flags &= ~IFF_OACTIVE;
832 sc->sc_config2 |= SEEQ_CFG2_OUTPUT;
833 bus_space_write_2(iot, ioh, SEEQ_CONFIG2, sc->sc_config2);
834 DPRINTF(SEEQ_DEBUG_TX, ("tx finished\n"));
835 return;
836 }
837
838 #if NBPFILTER > 0
839 /* Give the packet to the bpf, if any. */
840 if (ifp->if_bpf)
841 bpf_mtap(ifp->if_bpf, m0);
842 #endif
843
844 DPRINTF(SEEQ_DEBUG_TX, ("Tx new packet\n"));
845
846 sc->sc_config2 &= ~SEEQ_CFG2_OUTPUT;
847 bus_space_write_2(iot, ioh, SEEQ_CONFIG2, sc->sc_config2);
848
849 ea_writembuf(sc, m0, 0x0000);
850 m_freem(m0);
851
852 bus_space_write_2(iot, ioh, SEEQ_TX_PTR, 0x0000);
853
854 /* Now transmit the datagram. */
855 bus_space_write_2(iot, ioh, SEEQ_COMMAND,
856 sc->sc_command | SEEQ_CMD_TX_ON);
857
858 /* Make sure we notice if the chip goes silent on us. */
859 ifp->if_timer = 5;
860
861 DPRINTF(SEEQ_DEBUG_TX,
862 ("st=%04x\n", bus_space_read_2(iot, ioh, SEEQ_STATUS)));
863 DPRINTF(SEEQ_DEBUG_TX, ("tx: queued\n"));
864 }
865
866 /*
867 * Copy a packet from an mbuf to the transmit buffer on the card.
868 *
869 * Puts a valid Tx header at the start of the packet, and a null header at
870 * the end.
871 */
872 static int
873 ea_writembuf(struct seeq8005_softc *sc, struct mbuf *m0, int bufstart)
874 {
875 struct mbuf *m;
876 int len, nextpacket;
877 u_int8_t hdr[4];
878
879 /*
880 * Copy the datagram to the packet buffer.
881 */
882 len = 0;
883 for (m = m0; m; m = m->m_next) {
884 if (m->m_len == 0)
885 continue;
886 ea_writebuf(sc, mtod(m, caddr_t), bufstart + 4 + len,
887 m->m_len);
888 len += m->m_len;
889 }
890
891 len = max(len, ETHER_MIN_LEN);
892
893 /* Follow it with a NULL packet header */
894 memset(hdr, 0, 4);
895 ea_writebuf(sc, hdr, bufstart + 4 + len, 4);
896 bus_space_write_2(sc->sc_iot, sc->sc_ioh, SEEQ_BUFWIN, 0x0000);
897 bus_space_write_2(sc->sc_iot, sc->sc_ioh, SEEQ_BUFWIN, 0x0000);
898
899 /* Ok we now have a packet len bytes long in our packet buffer */
900 DPRINTF(SEEQ_DEBUG_TX, ("ea_writembuf: length=%d\n", len));
901
902 /* Write the packet header */
903 nextpacket = len + 4;
904 hdr[0] = (nextpacket >> 8) & 0xff;
905 hdr[1] = nextpacket & 0xff;
906 hdr[2] = SEEQ_PKTCMD_TX | SEEQ_PKTCMD_DATA_FOLLOWS |
907 SEEQ_TXCMD_XMIT_SUCCESS_INT | SEEQ_TXCMD_COLLISION_INT;
908 hdr[3] = 0; /* Status byte -- will be update by hardware. */
909 ea_writebuf(sc, hdr, 0x0000, 4);
910
911 return len;
912 }
913
914 /*
915 * Ethernet controller interrupt.
916 */
917
918 int
919 seeq8005intr(void *arg)
920 {
921 struct seeq8005_softc *sc = arg;
922 bus_space_tag_t iot = sc->sc_iot;
923 bus_space_handle_t ioh = sc->sc_ioh;
924 int status, handled;
925
926 handled = 0;
927
928 /* Get the controller status */
929 status = bus_space_read_2(iot, ioh, SEEQ_STATUS);
930
931 /* Tx interrupt ? */
932 if (status & SEEQ_STATUS_TX_INT) {
933 handled = 1;
934
935 /* Acknowledge the interrupt */
936 bus_space_write_2(iot, ioh, SEEQ_COMMAND,
937 sc->sc_command | SEEQ_CMD_TX_INTACK);
938
939 ea_txint(sc);
940 }
941
942
943 /* Rx interrupt ? */
944 if (status & SEEQ_STATUS_RX_INT) {
945 handled = 1;
946
947 /* Acknowledge the interrupt */
948 bus_space_write_2(iot, ioh, SEEQ_COMMAND,
949 sc->sc_command | SEEQ_CMD_RX_INTACK);
950
951 /* Processes the received packets */
952 ea_rxint(sc);
953 }
954
955 return handled;
956 }
957
958 static void
959 ea_txint(struct seeq8005_softc *sc)
960 {
961 struct ifnet *ifp = &sc->sc_ethercom.ec_if;
962 bus_space_tag_t iot = sc->sc_iot;
963 bus_space_handle_t ioh = sc->sc_ioh;
964 u_int8_t txhdr[4];
965 u_int txstatus;
966
967 ea_readbuf(sc, txhdr, 0x0000, 4);
968
969 DPRINTF(SEEQ_DEBUG_TX, ("txstatus=%02x %02x %02x %02x\n",
970 txhdr[0], txhdr[1], txhdr[2], txhdr[3]));
971 txstatus = txhdr[3];
972
973 /*
974 * If SEEQ_TXSTAT_COLLISION is set then we received at least
975 * one collision. On the 8004 we can find out exactly how many
976 * collisions occurred.
977 *
978 * The SEEQ_PKTSTAT_DONE will be set if the transmission has
979 * completed.
980 *
981 * If SEEQ_TXSTAT_COLLISION16 is set then 16 collisions
982 * occurred and the packet transmission was aborted.
983 * This situation is untested as present.
984 *
985 * The SEEQ_TXSTAT_BABBLE should never be set and is untested
986 * as we should never xmit oversized packets.
987 */
988 if (txstatus & SEEQ_TXSTAT_COLLISION) {
989 switch (sc->sc_variant) {
990 case SEEQ_8004: {
991 int colls;
992
993 /*
994 * The 8004 contains a 4 bit collision count
995 * in the status register.
996 */
997
998 /* This appears to be broken on 80C04.AE */
999 /* ifp->if_collisions +=
1000 (txstatus >> SEEQ_TXSTAT_COLLISIONS_SHIFT)
1001 & SEEQ_TXSTAT_COLLISION_MASK;*/
1002
1003 /* Use the TX Collision register */
1004 ea_select_buffer(sc, SEEQ_BUFCODE_TX_COLLS);
1005 colls = bus_space_read_1(iot, ioh, SEEQ_BUFWIN);
1006 ifp->if_collisions += colls;
1007 break;
1008 }
1009 case SEEQ_8005:
1010 /* We known there was at least 1 collision */
1011 ifp->if_collisions++;
1012 break;
1013 }
1014 } else if (txstatus & SEEQ_TXSTAT_COLLISION16) {
1015 printf("seeq_intr: col16 %x\n", txstatus);
1016 ifp->if_collisions += 16;
1017 ifp->if_oerrors++;
1018 } else if (txstatus & SEEQ_TXSTAT_BABBLE) {
1019 ifp->if_oerrors++;
1020 }
1021
1022 /* Have we completed transmission on the packet ? */
1023 if (txstatus & SEEQ_PKTSTAT_DONE) {
1024 /* Clear watchdog timer. */
1025 ifp->if_timer = 0;
1026 ifp->if_flags &= ~IFF_OACTIVE;
1027
1028 /* Update stats */
1029 ifp->if_opackets++;
1030
1031 /* Tx next packet */
1032
1033 eatxpacket(sc);
1034 }
1035 }
1036
1037 void
1038 ea_rxint(struct seeq8005_softc *sc)
1039 {
1040 bus_space_tag_t iot = sc->sc_iot;
1041 bus_space_handle_t ioh = sc->sc_ioh;
1042 u_int addr;
1043 int len;
1044 int ctrl;
1045 int ptr;
1046 int pack;
1047 int status;
1048 u_int8_t rxhdr[4];
1049 struct ifnet *ifp;
1050
1051 ifp = &sc->sc_ethercom.ec_if;
1052
1053
1054 /* We start from the last rx pointer position */
1055 addr = sc->sc_rx_ptr;
1056 sc->sc_config2 &= ~SEEQ_CFG2_OUTPUT;
1057 bus_space_write_2(iot, ioh, SEEQ_CONFIG2, sc->sc_config2);
1058
1059 do {
1060 /* Read rx header */
1061 ea_readbuf(sc, rxhdr, addr, 4);
1062
1063 /* Split the packet header */
1064 ptr = (rxhdr[0] << 8) | rxhdr[1];
1065 ctrl = rxhdr[2];
1066 status = rxhdr[3];
1067
1068 DPRINTF(SEEQ_DEBUG_RX,
1069 ("addr=%04x ptr=%04x ctrl=%02x status=%02x\n",
1070 addr, ptr, ctrl, status));
1071
1072 /* Zero packet ptr ? then must be null header so exit */
1073 if (ptr == 0) break;
1074
1075 /* Sanity-check the next-packet pointer and flags. */
1076 if (__predict_false(ptr < sc->sc_tx_bufsize ||
1077 (ctrl & SEEQ_PKTCMD_TX))) {
1078 ++ifp->if_ierrors;
1079 log(LOG_ERR,
1080 "%s: Rx chain corrupt at %04x (ptr = %04x)\n",
1081 sc->sc_dev.dv_xname, addr, ptr);
1082 ea_init(ifp);
1083 return;
1084 }
1085
1086 /* Get packet length */
1087 len = (ptr - addr) - 4;
1088
1089 if (len < 0)
1090 len += sc->sc_rx_bufsize;
1091 DPRINTF(SEEQ_DEBUG_RX, ("len=%04x\n", len));
1092
1093 /* Has the packet rx completed ? if not then exit */
1094 if ((status & SEEQ_PKTSTAT_DONE) == 0)
1095 break;
1096
1097 /*
1098 * Did we have any errors? then note error and go to
1099 * next packet
1100 */
1101 if (__predict_false(status & SEEQ_RXSTAT_ERROR_MASK)) {
1102 ++ifp->if_ierrors;
1103 /* XXX oversize packets may be OK */
1104 log(LOG_WARNING,
1105 "%s: rx packet error at %04x (err=%02x)\n",
1106 sc->sc_dev.dv_xname, addr, status & 0x0f);
1107 /* XXX shouldn't need to reset if it's genuine. */
1108 ea_init(ifp);
1109 return;
1110 }
1111 /*
1112 * Is the packet too big ? - this will probably be trapped
1113 * above as a receive error. If it's not, this is indicative
1114 * of buffer corruption.
1115 */
1116 if (__predict_false(len > (ETHER_MAX_LEN - ETHER_CRC_LEN))) {
1117 ++ifp->if_ierrors;
1118 log(LOG_ERR,
1119 "%s: rx packet size error at %04x (len=%d)\n",
1120 sc->sc_dev.dv_xname, addr, len);
1121 sc->sc_config2 |= SEEQ_CFG2_OUTPUT;
1122 bus_space_write_2(iot, ioh, SEEQ_CONFIG2,
1123 sc->sc_config2);
1124 ea_init(ifp);
1125 return;
1126 }
1127
1128 ifp->if_ipackets++;
1129 /* Pass data up to upper levels. */
1130 ea_read(sc, addr + 4, len);
1131
1132 addr = ptr;
1133 ++pack;
1134 } while (len != 0);
1135
1136 sc->sc_config2 |= SEEQ_CFG2_OUTPUT;
1137 bus_space_write_2(iot, ioh, SEEQ_CONFIG2, sc->sc_config2);
1138
1139 DPRINTF(SEEQ_DEBUG_RX, ("new rx ptr=%04x\n", addr));
1140
1141 /* Store new rx pointer */
1142 sc->sc_rx_ptr = addr;
1143 bus_space_write_2(iot, ioh, SEEQ_RX_END, sc->sc_rx_ptr >> 8);
1144
1145 /* Make sure the receiver is on */
1146 bus_space_write_2(iot, ioh, SEEQ_COMMAND,
1147 sc->sc_command | SEEQ_CMD_RX_ON);
1148 }
1149
1150
1151 /*
1152 * Pass a packet up to the higher levels.
1153 */
1154
1155 static void
1156 ea_read(struct seeq8005_softc *sc, int addr, int len)
1157 {
1158 struct mbuf *m;
1159 struct ifnet *ifp;
1160
1161 ifp = &sc->sc_ethercom.ec_if;
1162
1163 /* Pull packet off interface. */
1164 m = ea_get(sc, addr, len, ifp);
1165 if (m == 0)
1166 return;
1167
1168 #if NBPFILTER > 0
1169 /*
1170 * Check if there's a BPF listener on this interface.
1171 * If so, hand off the raw packet to bpf.
1172 */
1173 if (ifp->if_bpf)
1174 bpf_mtap(ifp->if_bpf, m);
1175 #endif
1176
1177 (*ifp->if_input)(ifp, m);
1178 }
1179
1180 /*
1181 * Pull read data off a interface. Len is length of data, with local net
1182 * header stripped. We copy the data into mbufs. When full cluster sized
1183 * units are present we copy into clusters.
1184 */
1185
1186 struct mbuf *
1187 ea_get(struct seeq8005_softc *sc, int addr, int totlen, struct ifnet *ifp)
1188 {
1189 struct mbuf *top, **mp, *m;
1190 int len;
1191 u_int cp, epkt;
1192
1193 cp = addr;
1194 epkt = cp + totlen;
1195
1196 MGETHDR(m, M_DONTWAIT, MT_DATA);
1197 if (m == 0)
1198 return 0;
1199 m->m_pkthdr.rcvif = ifp;
1200 m->m_pkthdr.len = totlen;
1201 m->m_len = MHLEN;
1202 top = 0;
1203 mp = ⊤
1204
1205 while (totlen > 0) {
1206 if (top) {
1207 MGET(m, M_DONTWAIT, MT_DATA);
1208 if (m == 0) {
1209 m_freem(top);
1210 return 0;
1211 }
1212 m->m_len = MLEN;
1213 }
1214 len = min(totlen, epkt - cp);
1215 if (len >= MINCLSIZE) {
1216 MCLGET(m, M_DONTWAIT);
1217 if (m->m_flags & M_EXT)
1218 m->m_len = len = min(len, MCLBYTES);
1219 else
1220 len = m->m_len;
1221 } else {
1222 /*
1223 * Place initial small packet/header at end of mbuf.
1224 */
1225 if (len < m->m_len) {
1226 if (top == 0 && len + max_linkhdr <= m->m_len)
1227 m->m_data += max_linkhdr;
1228 m->m_len = len;
1229 } else
1230 len = m->m_len;
1231 }
1232 if (top == 0) {
1233 /* Make sure the payload is aligned */
1234 caddr_t newdata = (caddr_t)
1235 ALIGN(m->m_data + sizeof(struct ether_header)) -
1236 sizeof(struct ether_header);
1237 len -= newdata - m->m_data;
1238 m->m_len = len;
1239 m->m_data = newdata;
1240 }
1241 ea_readbuf(sc, mtod(m, u_char *),
1242 cp < SEEQ_MAX_BUFFER_SIZE ? cp : cp - sc->sc_rx_bufsize,
1243 len);
1244 cp += len;
1245 *mp = m;
1246 mp = &m->m_next;
1247 totlen -= len;
1248 if (cp == epkt)
1249 cp = addr;
1250 }
1251
1252 return top;
1253 }
1254
1255 /*
1256 * Process an ioctl request. Mostly boilerplate.
1257 */
1258 static int
1259 ea_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
1260 {
1261 struct seeq8005_softc *sc = ifp->if_softc;
1262 int s, error = 0;
1263
1264 s = splnet();
1265 switch (cmd) {
1266
1267 default:
1268 error = ether_ioctl(ifp, cmd, data);
1269 if (error == ENETRESET) {
1270 /*
1271 * Multicast list has changed; set the hardware filter
1272 * accordingly.
1273 */
1274 ea_mc_reset(sc);
1275 error = 0;
1276 }
1277 break;
1278 }
1279
1280 splx(s);
1281 return error;
1282 }
1283
1284 /* Must be called at splnet() */
1285
1286 static void
1287 ea_mc_reset(struct seeq8005_softc *sc)
1288 {
1289
1290 switch (sc->sc_variant) {
1291 case SEEQ_8004:
1292 ea_mc_reset_8004(sc);
1293 return;
1294 case SEEQ_8005:
1295 ea_mc_reset_8005(sc);
1296 return;
1297 }
1298 }
1299
1300 static void
1301 ea_mc_reset_8004(struct seeq8005_softc *sc)
1302 {
1303 struct ethercom *ec = &sc->sc_ethercom;
1304 struct ifnet *ifp = &ec->ec_if;
1305 struct ether_multi *enm;
1306 u_int8_t *cp, c;
1307 u_int32_t crc;
1308 int i, len;
1309 struct ether_multistep step;
1310 u_int8_t af[8];
1311
1312 /*
1313 * Set up multicast address filter by passing all multicast addresses
1314 * through a crc generator, and then using bits 2 - 7 as an index
1315 * into the 64 bit logical address filter. The high order bits
1316 * selects the word, while the rest of the bits select the bit within
1317 * the word.
1318 */
1319
1320 if (ifp->if_flags & IFF_PROMISC) {
1321 ifp->if_flags |= IFF_ALLMULTI;
1322 for (i = 0; i < 8; i++)
1323 af[i] = 0xff;
1324 return;
1325 }
1326 for (i = 0; i < 8; i++)
1327 af[i] = 0;
1328 ETHER_FIRST_MULTI(step, ec, enm);
1329 while (enm != NULL) {
1330 if (bcmp(enm->enm_addrlo, enm->enm_addrhi,
1331 sizeof(enm->enm_addrlo)) != 0) {
1332 /*
1333 * We must listen to a range of multicast addresses.
1334 * For now, just accept all multicasts, rather than
1335 * trying to set only those filter bits needed to match
1336 * the range. (At this time, the only use of address
1337 * ranges is for IP multicast routing, for which the
1338 * range is big enough to require all bits set.)
1339 */
1340 ifp->if_flags |= IFF_ALLMULTI;
1341 for (i = 0; i < 8; i++)
1342 af[i] = 0xff;
1343 break;
1344 }
1345 cp = enm->enm_addrlo;
1346 crc = 0xffffffff;
1347 for (len = sizeof(enm->enm_addrlo); --len >= 0;) {
1348 c = *cp++;
1349 for (i = 8; --i >= 0;) {
1350 if (((crc & 0x80000000) ? 1 : 0) ^ (c & 0x01)) {
1351 crc <<= 1;
1352 crc ^= 0x04c11db6 | 1;
1353 } else
1354 crc <<= 1;
1355 c >>= 1;
1356 }
1357 }
1358 /* Just want the 6 most significant bits. */
1359 crc = (crc >> 2) & 0x3f;
1360
1361 /* Turn on the corresponding bit in the filter. */
1362 af[crc >> 3] |= 1 << (crc & 0x7);
1363
1364 ETHER_NEXT_MULTI(step, enm);
1365 }
1366 ifp->if_flags &= ~IFF_ALLMULTI;
1367
1368 ea_select_buffer(sc, SEEQ_BUFCODE_MULTICAST);
1369 for (i = 0; i < 8; ++i)
1370 bus_space_write_1(sc->sc_iot, sc->sc_ioh,
1371 SEEQ_BUFWIN, af[i]);
1372 }
1373
1374 static void
1375 ea_mc_reset_8005(struct seeq8005_softc *sc)
1376 {
1377 struct ether_multi *enm;
1378 struct ether_multistep step;
1379 int naddr, maxaddrs;
1380
1381 naddr = 0;
1382 maxaddrs = 5;
1383 ETHER_FIRST_MULTI(step, &sc->sc_ethercom, enm);
1384 while (enm != NULL) {
1385 /* Have we got space? */
1386 if (naddr >= maxaddrs ||
1387 bcmp(enm->enm_addrlo, enm->enm_addrhi, 6) != 0) {
1388 sc->sc_ethercom.ec_if.if_flags |= IFF_ALLMULTI;
1389 ea_ioctl(&sc->sc_ethercom.ec_if, SIOCSIFFLAGS, NULL);
1390 return;
1391 }
1392 ea_set_address(sc, 1 + naddr, enm->enm_addrlo);
1393 sc->sc_config1 |= SEEQ_CFG1_STATION_ADDR1 << naddr;
1394 naddr++;
1395 ETHER_NEXT_MULTI(step, enm);
1396 }
1397 for (; naddr < maxaddrs; naddr++)
1398 sc->sc_config1 &= ~(SEEQ_CFG1_STATION_ADDR1 << naddr);
1399 bus_space_write_2(sc->sc_iot, sc->sc_ioh, SEEQ_CONFIG1,
1400 sc->sc_config1);
1401 }
1402
1403 /*
1404 * Device timeout routine.
1405 */
1406
1407 static void
1408 ea_watchdog(struct ifnet *ifp)
1409 {
1410 struct seeq8005_softc *sc = ifp->if_softc;
1411
1412 log(LOG_ERR, "%s: lost Tx interrupt (status = 0x%04x)\n",
1413 sc->sc_dev.dv_xname,
1414 bus_space_read_2(sc->sc_iot, sc->sc_ioh, SEEQ_STATUS));
1415 ifp->if_oerrors++;
1416
1417 /* Kick the interface */
1418
1419 ea_init(ifp);
1420
1421 ifp->if_timer = 0;
1422 }
1423
1424 /* End of if_ea.c */
1425