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