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