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