xref: /openbsd/sys/dev/isa/if_ef_isapnp.c (revision 3d8817e4)
1 /*	$OpenBSD: if_ef_isapnp.c,v 1.24 2008/11/28 02:44:17 brad Exp $	*/
2 
3 /*
4  * Copyright (c) 1999 Jason L. Wright (jason@thought.net)
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19  * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
20  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
22  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
24  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
25  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26  * POSSIBILITY OF SUCH DAMAGE.
27  */
28 
29 #include "bpfilter.h"
30 
31 #include <sys/param.h>
32 #include <sys/systm.h>
33 #include <sys/mbuf.h>
34 #include <sys/socket.h>
35 #include <sys/ioctl.h>
36 #include <sys/errno.h>
37 #include <sys/syslog.h>
38 #include <sys/selinfo.h>
39 #include <sys/device.h>
40 #include <sys/queue.h>
41 #include <sys/kernel.h>
42 #include <sys/timeout.h>
43 
44 #include <net/if.h>
45 #include <net/if_dl.h>
46 #include <net/if_types.h>
47 #include <net/netisr.h>
48 #include <net/if_media.h>
49 
50 #ifdef INET
51 #include <netinet/in.h>
52 #include <netinet/in_systm.h>
53 #include <netinet/in_var.h>
54 #include <netinet/ip.h>
55 #include <netinet/if_ether.h>
56 #endif
57 
58 #if NBPFILTER > 0
59 #include <net/bpf.h>
60 #endif
61 
62 #include <machine/cpu.h>
63 #include <machine/bus.h>
64 #include <machine/intr.h>
65 
66 #include <dev/mii/mii.h>
67 #include <dev/mii/miivar.h>
68 #include <dev/isa/isavar.h>
69 #include <dev/isa/isadmavar.h>
70 #include <dev/ic/elink3reg.h>
71 
72 #undef EF_DEBUG
73 
74 struct ef_softc {
75 	struct device		sc_dv;
76 	bus_space_tag_t		sc_iot;
77 	bus_space_handle_t	sc_ioh;
78 	struct arpcom		sc_arpcom;
79 	struct mii_data		sc_mii;
80 	struct timeout		sc_tick_tmo;
81 	void *			sc_ih;
82 	int			sc_tx_start_thresh;
83 	int			sc_tx_succ_ok;
84 	int			sc_busmaster;
85 };
86 
87 #define	EF_W0_EEPROM_COMMAND	0x200a
88 #define    EF_EEPROM_BUSY	(1 << 9)
89 #define    EF_EEPROM_READ	(1 << 7)
90 #define	EF_W0_EEPROM_DATA	0x200c
91 
92 #define	EF_W1_TX_PIO_WR_1	0x10
93 #define	EF_W1_RX_PIO_RR_1	0x10
94 #define	EF_W1_RX_ERRORS		0x14
95 #define	EF_W1_RX_STATUS		0x18
96 #define	EF_W1_TX_STATUS		0x1b
97 #define	EF_W1_FREE_TX		0x1c
98 
99 #define	EF_W4_MEDIA		0x0a
100 #define    EF_MEDIA_SQE		0x0008		/* sqe error for aui */
101 #define	   EF_MEDIA_TP		0x00c0		/* link/jabber, 10baseT */
102 #define	   EF_MEDIA_LNK		0x0080		/* linkbeat, 100baseTX/FX */
103 #define	   EF_MEDIA_LNKBEAT	0x0800
104 
105 /* Window 4: EP_W4_CTRLR_STATUS: mii manipulation */
106 #define	EF_MII_CLK		0x01		/* clock bit */
107 #define	EF_MII_DATA		0x02		/* data bit */
108 #define	EF_MII_DIR		0x04		/* direction */
109 
110 int ef_isapnp_match(struct device *, void *, void *);
111 void ef_isapnp_attach(struct device *, struct device *, void *);
112 
113 void efstart(struct ifnet *);
114 int efioctl(struct ifnet *, u_long, caddr_t);
115 void efwatchdog(struct ifnet *);
116 void efreset(struct ef_softc *);
117 void efstop(struct ef_softc *);
118 void efsetmulti(struct ef_softc *);
119 int efbusyeeprom(struct ef_softc *);
120 int efintr(void *);
121 void efinit(struct ef_softc *);
122 void efcompletecmd(struct ef_softc *, u_int, u_int);
123 void eftxstat(struct ef_softc *);
124 void efread(struct ef_softc *);
125 struct mbuf *efget(struct ef_softc *, int totlen);
126 
127 void ef_miibus_writereg(struct device *, int, int, int);
128 void ef_miibus_statchg(struct device *);
129 int ef_miibus_readreg(struct device *, int, int);
130 void ef_mii_writeb(struct ef_softc *, int);
131 void ef_mii_sync(struct ef_softc *);
132 int ef_ifmedia_upd(struct ifnet *);
133 void ef_ifmedia_sts(struct ifnet *, struct ifmediareq *);
134 void ef_tick(void *);
135 
136 struct cfdriver ef_cd = {
137 	NULL, "ef", DV_IFNET
138 };
139 
140 struct cfattach ef_isapnp_ca = {
141 	sizeof(struct ef_softc), ef_isapnp_match, ef_isapnp_attach
142 };
143 
144 int
145 ef_isapnp_match(parent, match, aux)
146 	struct device *parent;
147 	void *match, *aux;
148 {
149 	return (1);
150 }
151 
152 void
153 ef_isapnp_attach(parent, self, aux)
154 	struct device *parent, *self;
155 	void *aux;
156 {
157 	struct ef_softc *sc = (void *)self;
158 	struct isa_attach_args *ia = aux;
159 	struct ifnet *ifp = &sc->sc_arpcom.ac_if;
160 	bus_space_tag_t iot;
161 	bus_space_handle_t ioh;
162 	int i;
163 	u_int16_t x;
164 	u_int32_t cfg;
165 
166 	sc->sc_iot = iot = ia->ia_iot;
167 	sc->sc_ioh = ioh = ia->ipa_io[0].h;
168 
169 	efcompletecmd(sc, EP_COMMAND, GLOBAL_RESET);
170 	DELAY(1500);
171 
172 	for (i = 0; i < 3; i++) {
173 		if (efbusyeeprom(sc))
174 			return;
175 
176 		bus_space_write_2(iot, ioh, EF_W0_EEPROM_COMMAND,
177 		    EF_EEPROM_READ | i);
178 
179 		if (efbusyeeprom(sc))
180 			return;
181 
182 		x = bus_space_read_2(iot, ioh, EF_W0_EEPROM_DATA);
183 
184 		sc->sc_arpcom.ac_enaddr[(i << 1)] = x >> 8;
185 		sc->sc_arpcom.ac_enaddr[(i << 1) + 1] = x;
186 	}
187 
188 	printf(": address %s\n", ether_sprintf(sc->sc_arpcom.ac_enaddr));
189 
190 	GO_WINDOW(3);
191 	cfg = bus_space_read_4(iot, ioh, EP_W3_INTERNAL_CONFIG);
192 	cfg &= ~(0x00f00000);
193 	cfg |= (0x06 << 20);
194 	bus_space_write_4(iot, ioh, EP_W3_INTERNAL_CONFIG, cfg);
195 
196 	sc->sc_ih = isa_intr_establish(ia->ia_ic, ia->ia_irq, IST_EDGE,
197 	    IPL_NET, efintr, sc, sc->sc_dv.dv_xname);
198 
199 	if (ia->ia_drq != DRQUNK)
200 		isadma_cascade(ia->ia_drq);
201 
202 	timeout_set(&sc->sc_tick_tmo, ef_tick, sc);
203 
204 	bcopy(sc->sc_dv.dv_xname, ifp->if_xname, IFNAMSIZ);
205 	ifp->if_softc = sc;
206 	ifp->if_start = efstart;
207 	ifp->if_ioctl = efioctl;
208 	ifp->if_watchdog = efwatchdog;
209 	ifp->if_flags =
210 	    IFF_BROADCAST | IFF_SIMPLEX | IFF_NOTRAILERS | IFF_MULTICAST;
211 	IFQ_SET_READY(&ifp->if_snd);
212 
213 	sc->sc_mii.mii_ifp = ifp;
214 	sc->sc_mii.mii_readreg = ef_miibus_readreg;
215 	sc->sc_mii.mii_writereg = ef_miibus_writereg;
216 	sc->sc_mii.mii_statchg = ef_miibus_statchg;
217 	ifmedia_init(&sc->sc_mii.mii_media, 0, ef_ifmedia_upd, ef_ifmedia_sts);
218 	mii_attach(self, &sc->sc_mii, 0xffffffff, MII_PHY_ANY, MII_OFFSET_ANY,
219 	    0);
220 	if (LIST_FIRST(&sc->sc_mii.mii_phys) == NULL) {
221 		ifmedia_add(&sc->sc_mii.mii_media, IFM_ETHER|IFM_NONE, 0, NULL);
222 		ifmedia_set(&sc->sc_mii.mii_media, IFM_ETHER|IFM_NONE);
223 	} else
224 		ifmedia_set(&sc->sc_mii.mii_media, IFM_ETHER|IFM_AUTO);
225 
226 	if_attach(ifp);
227 	ether_ifattach(ifp);
228 
229 	sc->sc_tx_start_thresh = 20;
230 
231 	efcompletecmd(sc, EP_COMMAND, RX_RESET);
232 	efcompletecmd(sc, EP_COMMAND, TX_RESET);
233 }
234 
235 void
236 efstart(ifp)
237 	struct ifnet *ifp;
238 {
239 	struct ef_softc *sc = ifp->if_softc;
240 	bus_space_tag_t iot = sc->sc_iot;
241 	bus_space_handle_t ioh = sc->sc_ioh;
242 	struct mbuf *m, *m0;
243 	int s, len, pad, i;
244 	int fillcnt = 0;
245 	u_int32_t filler = 0;
246 
247 	if ((ifp->if_flags & (IFF_RUNNING | IFF_OACTIVE)) != IFF_RUNNING)
248 		return;
249 
250 startagain:
251 	IFQ_POLL(&ifp->if_snd, m0);
252 	if (m0 == NULL)
253 		return;
254 
255 	if ((m0->m_flags & M_PKTHDR) == 0)
256 		panic("efstart: no header mbuf");
257 	len = m0->m_pkthdr.len;
258 	pad = (4 - len) & 3;
259 
260 	if (len + pad > ETHER_MAX_LEN) {
261 		ifp->if_oerrors++;
262 		IFQ_DEQUEUE(&ifp->if_snd, m0);
263 		m_freem(m0);
264 		goto startagain;
265 	}
266 
267 	if (bus_space_read_2(iot, ioh, EF_W1_FREE_TX) < len + pad + 4) {
268 		bus_space_write_2(iot, ioh, EP_COMMAND,
269 		    SET_TX_AVAIL_THRESH | ((len + pad) >> 2));
270 		ifp->if_flags |= IFF_OACTIVE;
271 		return;
272 	} else {
273 		bus_space_write_2(iot, ioh, EP_COMMAND,
274 		    SET_TX_AVAIL_THRESH | EP_THRESH_DISABLE);
275 	}
276 
277 	bus_space_write_2(iot, ioh, EP_COMMAND, SET_TX_START_THRESH |
278 	    ((len / 4 + sc->sc_tx_start_thresh)));
279 
280 #if NBPFILTER
281 	if (ifp->if_bpf)
282 		bpf_mtap(ifp->if_bpf, m0, BPF_DIRECTION_OUT);
283 #endif
284 
285 	IFQ_DEQUEUE(&ifp->if_snd, m0);
286 	if (m0 == NULL) /* XXX not needed */
287 		return;
288 
289 	s = splhigh();
290 
291 	bus_space_write_4(iot, ioh, EF_W1_TX_PIO_WR_1, len);
292 	for (m = m0; m; ) {
293 		if (fillcnt) {
294 			while (m->m_len && fillcnt < 4) {
295 				fillcnt++;
296 				filler >>= 8;
297 				filler |= m->m_data[0] << 24;
298 				m->m_data++;
299 				m->m_len--;
300 			}
301 			if (fillcnt == 4) {
302 				bus_space_write_4(iot, ioh,
303 				    EF_W1_TX_PIO_WR_1, filler);
304 				filler = 0;
305 				fillcnt = 0;
306 			}
307 		}
308 
309 		if (m->m_len & ~3)
310 			bus_space_write_multi_4(iot, ioh,
311 			    EF_W1_TX_PIO_WR_1, (u_int32_t *)m->m_data,
312 			    m->m_len >> 2);
313 		for (i = 0; i < (m->m_len & 3); i++) {
314 			fillcnt++;
315 			filler >>= 8;
316 			filler |= m->m_data[(m->m_len & ~3) + i] << 24;
317 		}
318 		MFREE(m, m0);
319 		m = m0;
320 	}
321 
322 	if (fillcnt) {
323 		bus_space_write_4(iot, ioh, EF_W1_TX_PIO_WR_1,
324 		    filler >> (32 - (8 * fillcnt)));
325 		fillcnt = 0;
326 		filler = 0;
327 	}
328 
329 	splx(s);
330 
331 	ifp->if_opackets++;
332 
333 	goto startagain;
334 }
335 
336 int
337 efioctl(ifp, cmd, data)
338 	struct ifnet *ifp;
339 	u_long cmd;
340 	caddr_t data;
341 {
342 	struct ef_softc *sc = ifp->if_softc;
343 	struct ifaddr *ifa = (struct ifaddr *)data;
344 	struct ifreq *ifr = (struct ifreq *)data;
345 	int s, error = 0;
346 
347 	s = splnet();
348 
349 	switch (cmd) {
350 	case SIOCSIFADDR:
351 		ifp->if_flags |= IFF_UP;
352 		switch (ifa->ifa_addr->sa_family) {
353 #ifdef INET
354 		case AF_INET:
355 			efinit(sc);
356 			arp_ifinit(&sc->sc_arpcom, ifa);
357 			break;
358 #endif
359 		default:
360 			efinit(sc);
361 			break;
362 		}
363 		break;
364 	case SIOCSIFMEDIA:
365 	case SIOCGIFMEDIA:
366 		error = ifmedia_ioctl(ifp, ifr, &sc->sc_mii.mii_media, cmd);
367 		break;
368 	case SIOCSIFFLAGS:
369 		if ((ifp->if_flags & IFF_UP) == 0 &&
370 		    (ifp->if_flags & IFF_RUNNING) != 0) {
371 			efstop(sc);
372 			ifp->if_flags &= ~IFF_RUNNING;
373 		} else if ((ifp->if_flags & IFF_UP) != 0 &&
374 			   (ifp->if_flags & IFF_RUNNING) == 0) {
375 			efinit(sc);
376 		}
377 		efsetmulti(sc);
378 		break;
379 
380 	default:
381 		error = ether_ioctl(ifp, &sc->sc_arpcom, cmd, data);
382 	}
383 
384 	if (error == ENETRESET) {
385 		if (ifp->if_flags & IFF_RUNNING) {
386 			efreset(sc);
387 			efsetmulti(sc);
388 		}
389 		error = 0;
390 	}
391 
392 	splx(s);
393 	return (error);
394 }
395 
396 void
397 efinit(sc)
398 	struct ef_softc *sc;
399 {
400 	struct ifnet *ifp = &sc->sc_arpcom.ac_if;
401 	bus_space_tag_t iot = sc->sc_iot;
402 	bus_space_handle_t ioh = sc->sc_ioh;
403 	int i, s;
404 
405 	s = splnet();
406 
407 	efstop(sc);
408 
409 	while (bus_space_read_2(iot, ioh, EP_STATUS) & S_COMMAND_IN_PROGRESS)
410 		;
411 
412 	GO_WINDOW(2);
413 	for (i = 0; i < 6; i++)
414 		bus_space_write_1(iot, ioh, EP_W2_ADDR_0 + i,
415 		    sc->sc_arpcom.ac_enaddr[i]);
416 	for (i = 0; i < 3; i += 2)
417 		bus_space_write_2(iot, ioh, EP_W2_RECVMASK_0 + (i * 2), 0);
418 
419 	efcompletecmd(sc, EP_COMMAND, RX_RESET);
420 	efcompletecmd(sc, EP_COMMAND, TX_RESET);
421 
422 	bus_space_write_2(iot, ioh, EP_COMMAND,
423 	    SET_TX_AVAIL_THRESH | (ETHER_MAX_DIX_LEN >> 2));
424 
425 	efsetmulti(sc);
426 
427 	bus_space_write_2(iot, ioh, EP_COMMAND, STATUS_ENABLE | 0);
428 
429 	GO_WINDOW(6);
430 	for (i = 0; i < 10; i++)
431 		(void)bus_space_read_1(iot, ioh, i);
432 	(void)bus_space_read_2(iot, ioh, 10);
433 	(void)bus_space_read_2(iot, ioh, 12);
434 	GO_WINDOW(4);
435 	(void)bus_space_read_1(iot, ioh, 12);
436 	bus_space_write_2(iot, ioh, EP_W4_NET_DIAG, 0x0040);
437 
438 	GO_WINDOW(7);
439 
440 	efsetmulti(sc);
441 
442 	bus_space_write_2(iot, ioh, EP_COMMAND, RX_ENABLE);
443 	bus_space_write_2(iot, ioh, EP_COMMAND, TX_ENABLE);
444 
445 	bus_space_write_2(iot, ioh, EP_COMMAND, STATUS_ENABLE |
446 	    S_CARD_FAILURE | S_INT_RQD | S_UPD_STATS | S_TX_COMPLETE |
447 	    S_TX_AVAIL | S_RX_COMPLETE |
448 	    (sc->sc_busmaster ? S_DMA_DONE : 0));
449 	bus_space_write_2(iot, ioh, EP_COMMAND, ACK_INTR |
450 	    S_INTR_LATCH | S_TX_AVAIL | S_RX_EARLY | S_INT_RQD);
451 	bus_space_write_2(iot, ioh, EP_COMMAND, SET_INTR_MASK |
452 	    S_INTR_LATCH | S_TX_AVAIL | S_RX_COMPLETE | S_UPD_STATS |
453 	    (sc->sc_busmaster ? S_DMA_DONE : 0) | S_UP_COMPLETE |
454 	    S_DOWN_COMPLETE | S_CARD_FAILURE | S_TX_COMPLETE);
455 
456 	mii_mediachg(&sc->sc_mii);
457 
458 	ifp->if_flags |= IFF_RUNNING;
459 	ifp->if_flags &= ~IFF_OACTIVE;
460 
461 	splx(s);
462 
463 	timeout_add_sec(&sc->sc_tick_tmo, 1);
464 
465 	efstart(ifp);
466 }
467 
468 void
469 efreset(sc)
470 	struct ef_softc *sc;
471 {
472 	int s;
473 
474 	s = splnet();
475 	efstop(sc);
476 	efinit(sc);
477 	splx(s);
478 }
479 
480 void
481 efstop(sc)
482 	struct ef_softc *sc;
483 {
484 	struct ifnet *ifp = &sc->sc_arpcom.ac_if;
485 	bus_space_tag_t iot = sc->sc_iot;
486 	bus_space_handle_t ioh = sc->sc_ioh;
487 
488 	ifp->if_timer = 0;
489 	ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
490 
491 	timeout_del(&sc->sc_tick_tmo);
492 
493 	bus_space_write_2(iot, ioh, EP_COMMAND, RX_DISABLE);
494 	efcompletecmd(sc, EP_COMMAND, RX_DISCARD_TOP_PACK);
495 
496 	bus_space_write_2(iot, ioh, EP_COMMAND, TX_DISABLE);
497 	bus_space_write_2(iot, ioh, EP_COMMAND, STOP_TRANSCEIVER);
498 
499 	efcompletecmd(sc, EP_COMMAND, RX_RESET);
500 	efcompletecmd(sc, EP_COMMAND, TX_RESET);
501 
502 	bus_space_write_2(iot, ioh, EP_COMMAND, C_INTR_LATCH);
503 	bus_space_write_2(iot, ioh, EP_COMMAND, SET_RD_0_MASK);
504 	bus_space_write_2(iot, ioh, EP_COMMAND, SET_INTR_MASK);
505 	bus_space_write_2(iot, ioh, EP_COMMAND, SET_RX_FILTER);
506 }
507 
508 void
509 efcompletecmd(sc, cmd, arg)
510 	struct ef_softc *sc;
511 	u_int cmd, arg;
512 {
513 	bus_space_tag_t iot = sc->sc_iot;
514 	bus_space_handle_t ioh = sc->sc_ioh;
515 
516 	bus_space_write_2(iot, ioh, cmd, arg);
517 	while (bus_space_read_2(iot, ioh, EP_STATUS) & S_COMMAND_IN_PROGRESS)
518 		;
519 }
520 
521 int
522 efintr(vsc)
523 	void *vsc;
524 {
525 	struct ef_softc *sc = vsc;
526 	bus_space_tag_t iot = sc->sc_iot;
527 	bus_space_handle_t ioh = sc->sc_ioh;
528 	struct ifnet *ifp = &sc->sc_arpcom.ac_if;
529 	u_int16_t status;
530 	int r = 0;
531 
532 	status = bus_space_read_2(iot, ioh, EP_STATUS);
533 
534 	do {
535 		if (status & S_RX_COMPLETE) {
536 			r = 1;
537 			bus_space_write_2(iot, ioh, EP_STATUS, C_RX_COMPLETE);
538 			efread(sc);
539 		}
540 		if (status & S_TX_AVAIL) {
541 			bus_space_write_2(iot, ioh, EP_STATUS, C_TX_AVAIL);
542 			r = 1;
543 			sc->sc_arpcom.ac_if.if_flags &= ~IFF_OACTIVE;
544 			efstart(&sc->sc_arpcom.ac_if);
545 		}
546 		if (status & S_CARD_FAILURE) {
547 			r = 1;
548 			efreset(sc);
549 			printf("%s: adapter failure (%x)\n",
550 			   sc->sc_dv.dv_xname, status);
551 			bus_space_write_2(iot, ioh, EP_COMMAND,
552 					  C_CARD_FAILURE);
553 			return (1);
554 		}
555 		if (status & S_TX_COMPLETE) {
556 			r = 1;
557 			eftxstat(sc);
558 			efstart(ifp);
559 		}
560 		bus_space_write_2(iot, ioh, EP_COMMAND,
561 		    C_INTR_LATCH | C_INT_RQD);
562 	} while ((status = bus_space_read_2(iot, ioh, EP_STATUS)) &
563 	    (S_INT_RQD | S_RX_COMPLETE));
564 
565 	return (r);
566 }
567 
568 void
569 eftxstat(sc)
570 	struct ef_softc *sc;
571 {
572 	bus_space_tag_t iot = sc->sc_iot;
573 	bus_space_handle_t ioh = sc->sc_ioh;
574 	int i;
575 
576 	while ((i = bus_space_read_1(iot, ioh, EF_W1_TX_STATUS)) &
577 	   TXS_COMPLETE) {
578 		bus_space_write_1(iot, ioh, EF_W1_TX_STATUS, 0);
579 
580 		if (i & TXS_JABBER) {
581 			sc->sc_arpcom.ac_if.if_oerrors++;
582 #ifdef EF_DEBUG
583 			if (sc->sc_arpcom.ac_if.if_flags & IFF_DEBUG)
584 				printf("%s: jabber (%x)\n",
585 				    sc->sc_dv.dv_xname, i);
586 #endif
587 			efreset(sc);
588 		}
589 		else if (i & TXS_UNDERRUN) {
590 			sc->sc_arpcom.ac_if.if_oerrors++;
591 #ifdef EF_DEBUG
592 			if (sc->sc_arpcom.ac_if.if_flags & IFF_DEBUG)
593 				printf("%s: fifo underrun (%x) @%d\n",
594 				    sc->sc_dv.dv_xname, i,
595 				    sc->sc_tx_start_thresh);
596 #endif
597 			if (sc->sc_tx_succ_ok < 100)
598 				sc->sc_tx_start_thresh = min(ETHER_MAX_LEN,
599 				    sc->sc_tx_start_thresh + 20);
600 			sc->sc_tx_succ_ok = 0;
601 			efreset(sc);
602 		}
603 		else if (i & TXS_MAX_COLLISION) {
604 			sc->sc_arpcom.ac_if.if_collisions++;
605 			bus_space_write_2(iot, ioh, EP_COMMAND, TX_ENABLE);
606 			sc->sc_arpcom.ac_if.if_flags &= ~IFF_OACTIVE;
607 		}
608 		else
609 			sc->sc_tx_succ_ok = (sc->sc_tx_succ_ok + 1) & 127;
610 	}
611 }
612 
613 int
614 efbusyeeprom(sc)
615 	struct ef_softc *sc;
616 {
617 	int i = 100, j;
618 
619 	while (i--) {
620 		j = bus_space_read_2(sc->sc_iot, sc->sc_ioh,
621 				     EF_W0_EEPROM_COMMAND);
622 		if (j & EF_EEPROM_BUSY)
623 			delay(100);
624 		else
625 			break;
626 	}
627 	if (i == 0) {
628 		printf("%s: eeprom failed to come ready\n",
629 		   sc->sc_dv.dv_xname);
630 		return (1);
631 	}
632 
633 	return (0);
634 }
635 
636 void
637 efwatchdog(ifp)
638 	struct ifnet *ifp;
639 {
640 	struct ef_softc *sc = ifp->if_softc;
641 
642 	printf("%s: device timeout\n", sc->sc_dv.dv_xname);
643 	sc->sc_arpcom.ac_if.if_oerrors++;
644 	efreset(sc);
645 }
646 
647 void
648 efsetmulti(sc)
649 	struct ef_softc *sc;
650 {
651 	struct ifnet *ifp = &sc->sc_arpcom.ac_if;
652 	struct arpcom *ac = &sc->sc_arpcom;
653 	bus_space_tag_t iot = sc->sc_iot;
654 	bus_space_handle_t ioh = sc->sc_ioh;
655 	struct ether_multi *enm;
656 	struct ether_multistep step;
657 	u_int16_t cmd = SET_RX_FILTER | FIL_INDIVIDUAL | FIL_BRDCST;
658 	int mcnt = 0;
659 
660 	ETHER_FIRST_MULTI(step, ac, enm);
661 	while (enm != NULL) {
662 		mcnt++;
663 		ETHER_NEXT_MULTI(step, enm);
664 	}
665 	if (mcnt || ifp->if_flags & IFF_ALLMULTI)
666 		cmd |= FIL_MULTICAST;
667 
668 	if (ifp->if_flags & IFF_PROMISC)
669 		cmd |= FIL_PROMISC;
670 
671 	bus_space_write_2(iot, ioh, EP_COMMAND, cmd);
672 }
673 
674 void
675 efread(sc)
676 	struct ef_softc *sc;
677 {
678 	bus_space_tag_t iot = sc->sc_iot;
679 	bus_space_handle_t ioh = sc->sc_ioh;
680 	struct ifnet *ifp = &sc->sc_arpcom.ac_if;
681 	struct mbuf *m;
682 	int len;
683 
684 	len = bus_space_read_2(iot, ioh, EF_W1_RX_STATUS);
685 
686 #ifdef EF_DEBUG
687 	if (ifp->if_flags & IFF_DEBUG) {
688 		int err = len & ERR_MASK;
689 		char *s = NULL;
690 
691 		if (len & ERR_INCOMPLETE)
692 			s = "incomplete packet";
693 		else if (err == ERR_OVERRUN)
694 			s = "packet overrun";
695 		else if (err == ERR_RUNT)
696 			s = "runt packet";
697 		else if (err == ERR_ALIGNMENT)
698 			s = "bad alignment";
699 		else if (err == ERR_CRC)
700 			s = "bad crc";
701 		else if (err == ERR_OVERSIZE)
702 			s = "oversized packet";
703 		else if (err == ERR_DRIBBLE)
704 			s = "dribble bits";
705 
706 		if (s)
707 			printf("%s: %s\n", sc->sc_dv.dv_xname, s);
708 	}
709 #endif
710 
711 	if (len & ERR_INCOMPLETE)
712 		return;
713 
714 	if (len & ERR_RX) {
715 		ifp->if_ierrors++;
716 		efcompletecmd(sc, EP_COMMAND, RX_DISCARD_TOP_PACK);
717 		return;
718 	}
719 
720 	len &= RX_BYTES_MASK;
721 	m = efget(sc, len);
722 	if (m == NULL) {
723 		ifp->if_ierrors++;
724 		efcompletecmd(sc, EP_COMMAND, RX_DISCARD_TOP_PACK);
725 		return;
726 	}
727 
728 	ifp->if_ipackets++;
729 
730 #if NBPFILTER > 0
731 	if (ifp->if_bpf)
732 		bpf_mtap(ifp->if_bpf, m, BPF_DIRECTION_IN);
733 #endif
734 
735 	ether_input_mbuf(ifp, m);
736 }
737 
738 struct mbuf *
739 efget(sc, totlen)
740 	struct ef_softc *sc;
741 	int totlen;
742 {
743 	bus_space_tag_t iot = sc->sc_iot;
744 	bus_space_handle_t ioh = sc->sc_ioh;
745 	struct ifnet *ifp = &sc->sc_arpcom.ac_if;
746 	struct mbuf *top, **mp, *m;
747 	int len, pad, s;
748 
749 	MGETHDR(m, M_DONTWAIT, MT_DATA);
750 	if (m == NULL)
751 		return (NULL);
752 	m->m_pkthdr.rcvif = ifp;
753 	m->m_pkthdr.len = totlen;
754 	pad = ALIGN(sizeof(struct ether_header)) - sizeof(struct ether_header);
755 	m->m_data += pad;
756 	len = MHLEN -pad;
757 	top = 0;
758 	mp = &top;
759 
760 	s = splhigh();
761 
762 	while (totlen > 0) {
763 		if (top) {
764 			MGET(m, M_DONTWAIT, MT_DATA);
765 			if (m == NULL) {
766 				m_freem(top);
767 				splx(s);
768 				return (NULL);
769 			}
770 			len = MLEN;
771 		}
772 		if (top && totlen >= MINCLSIZE) {
773 			MCLGET(m, M_DONTWAIT);
774 			if (m->m_flags & M_EXT)
775 				len = MCLBYTES;
776 		}
777 		len = min(totlen, len);
778 		if (len > 1) {
779 			len &= ~1;
780 			bus_space_read_raw_multi_2(iot, ioh,
781 			    EF_W1_RX_PIO_RR_1, mtod(m, u_int8_t *),
782 			    len);
783 		} else
784 			*(mtod(m, u_int8_t *)) =
785 			    bus_space_read_1(iot, ioh, EF_W1_RX_PIO_RR_1);
786 
787 		m->m_len = len;
788 		totlen -= len;
789 		*mp = m;
790 		mp = &m->m_next;
791 	}
792 
793 	efcompletecmd(sc, EP_COMMAND, RX_DISCARD_TOP_PACK);
794 
795 	splx(s);
796 
797 	return (top);
798 }
799 
800 #define MII_SET(sc, x) \
801 	bus_space_write_2((sc)->sc_iot, (sc)->sc_ioh, EP_W4_CTRLR_STATUS, \
802 	    bus_space_read_2((sc)->sc_iot, (sc)->sc_ioh, EP_W4_CTRLR_STATUS) \
803 	    | (x))
804 
805 #define MII_CLR(sc, x) \
806 	bus_space_write_2((sc)->sc_iot, (sc)->sc_ioh, EP_W4_CTRLR_STATUS, \
807 	    bus_space_read_2((sc)->sc_iot, (sc)->sc_ioh, EP_W4_CTRLR_STATUS) \
808 	    & (~(x)))
809 
810 void
811 ef_mii_writeb(sc, b)
812 	struct ef_softc *sc;
813 	int b;
814 {
815 	MII_CLR(sc, EF_MII_CLK);
816 
817 	if (b)
818 		MII_SET(sc, EF_MII_DATA);
819 	else
820 		MII_CLR(sc, EF_MII_DATA);
821 
822 	MII_CLR(sc, EF_MII_CLK);
823 	DELAY(1);
824 	MII_SET(sc, EF_MII_CLK);
825 	DELAY(1);
826 }
827 
828 void
829 ef_mii_sync(sc)
830 	struct ef_softc *sc;
831 {
832 	int i;
833 
834 	for (i = 0; i < 32; i++)
835 		ef_mii_writeb(sc, 1);
836 }
837 
838 int
839 ef_miibus_readreg(dev, phy, reg)
840 	struct device *dev;
841 	int phy, reg;
842 {
843 	struct ef_softc *sc = (struct ef_softc *)dev;
844 	int i, ack, s, val = 0;
845 
846 	s = splnet();
847 
848 	GO_WINDOW(4);
849 	bus_space_write_2(sc->sc_iot, sc->sc_ioh, EP_W4_CTRLR_STATUS, 0);
850 
851 	/* Turn on xmit */
852 	MII_SET(sc, EF_MII_DIR);
853 	MII_CLR(sc, EF_MII_CLK);
854 
855 	ef_mii_sync(sc);
856 
857 	/* Transmit start sequence */
858 	ef_mii_writeb(sc, 0);
859 	ef_mii_writeb(sc, 1);
860 
861 	/* Transmit read sequence */
862 	ef_mii_writeb(sc, 1);
863 	ef_mii_writeb(sc, 0);
864 
865 	/* Transmit phy addr */
866 	for (i = 0x10; i; i >>= 1)
867 		ef_mii_writeb(sc, (phy & i) ? 1 : 0);
868 
869 	/* Transmit reg addr */
870 	for (i = 0x10; i; i >>= 1)
871 		ef_mii_writeb(sc, (reg & i) ? 1 : 0);
872 
873 	/* First cycle of turnaround */
874 	MII_CLR(sc, EF_MII_CLK | EF_MII_DATA);
875 	DELAY(1);
876 	MII_SET(sc, EF_MII_CLK);
877 	DELAY(1);
878 
879 	/* Turn off xmit */
880 	MII_CLR(sc, EF_MII_DIR);
881 
882 	/* Second cycle of turnaround */
883 	MII_CLR(sc, EF_MII_CLK);
884 	DELAY(1);
885 	MII_SET(sc, EF_MII_CLK);
886 	DELAY(1);
887 	ack = bus_space_read_2(sc->sc_iot, sc->sc_ioh, EP_W4_CTRLR_STATUS) &
888 	    EF_MII_DATA;
889 
890 	/* Read 16bit data */
891 	for (i = 0x8000; i; i >>= 1) {
892 		MII_CLR(sc, EF_MII_CLK);
893 		DELAY(1);
894 		if (bus_space_read_2(sc->sc_iot, sc->sc_ioh,
895 				     EP_W4_CTRLR_STATUS) & EF_MII_DATA)
896 			val |= i;
897 		MII_SET(sc, EF_MII_CLK);
898 		DELAY(1);
899 	}
900 
901 	MII_CLR(sc, EF_MII_CLK);
902 	DELAY(1);
903 	MII_SET(sc, EF_MII_CLK);
904 	DELAY(1);
905 
906 	splx(s);
907 
908 	return (val);
909 }
910 
911 void
912 ef_miibus_writereg(dev, phy, reg, val)
913 	struct device *dev;
914 	int phy, reg, val;
915 {
916 	struct ef_softc *sc = (struct ef_softc *)dev;
917 	int s, i;
918 
919 	s = splnet();
920 
921 	GO_WINDOW(4);
922 	bus_space_write_2(sc->sc_iot, sc->sc_ioh, EP_W4_CTRLR_STATUS, 0);
923 
924 	/* Turn on xmit */
925 	MII_SET(sc, EF_MII_DIR);
926 
927 	ef_mii_sync(sc);
928 
929 	ef_mii_writeb(sc, 0);
930 	ef_mii_writeb(sc, 1);
931 	ef_mii_writeb(sc, 0);
932 	ef_mii_writeb(sc, 1);
933 
934 	for (i = 0x10; i; i >>= 1)
935 		ef_mii_writeb(sc, (phy & i) ? 1 : 0);
936 
937 	for (i = 0x10; i; i >>= 1)
938 		ef_mii_writeb(sc, (reg & i) ? 1 : 0);
939 
940 	ef_mii_writeb(sc, 1);
941 	ef_mii_writeb(sc, 0);
942 
943 	for (i = 0x8000; i; i >>= 1)
944 		ef_mii_writeb(sc, (val & i) ? 1 : 0);
945 
946 	splx(s);
947 }
948 
949 int
950 ef_ifmedia_upd(ifp)
951 	struct ifnet *ifp;
952 {
953 	struct ef_softc *sc = ifp->if_softc;
954 
955 	mii_mediachg(&sc->sc_mii);
956 	return (0);
957 }
958 
959 void
960 ef_ifmedia_sts(ifp, ifmr)
961 	struct ifnet *ifp;
962 	struct ifmediareq *ifmr;
963 {
964 	struct ef_softc *sc = ifp->if_softc;
965 
966 	mii_pollstat(&sc->sc_mii);
967 	ifmr->ifm_status = sc->sc_mii.mii_media_status;
968 	ifmr->ifm_active = sc->sc_mii.mii_media_active;
969 }
970 
971 void
972 ef_miibus_statchg(self)
973 	struct device *self;
974 {
975 	struct ef_softc *sc = (struct ef_softc *)self;
976 	int s;
977 
978 	s = splnet();
979 	GO_WINDOW(3);
980 	/* Set duplex bit appropriately */
981 	if ((sc->sc_mii.mii_media_active & IFM_GMASK) == IFM_FDX)
982 		bus_space_write_1(sc->sc_iot, sc->sc_ioh,
983 		    EP_W3_MAC_CONTROL, 0x20);
984 	else
985 		bus_space_write_1(sc->sc_iot, sc->sc_ioh,
986 		    EP_W3_MAC_CONTROL, 0x00);
987 	GO_WINDOW(7);
988 	splx(s);
989 }
990 
991 void
992 ef_tick(v)
993 	void *v;
994 {
995 	struct ef_softc *sc = v;
996 	int s;
997 
998 	s = splnet();
999 	mii_tick(&sc->sc_mii);
1000 	splx(s);
1001 	timeout_add_sec(&sc->sc_tick_tmo, 1);
1002 }
1003