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