xref: /netbsd-src/sys/dev/ic/lemac.c (revision 181254a7b1bdde6873432bffef2d2decc4b5c22f)
1 /* $NetBSD: lemac.c,v 1.55 2020/01/29 14:53:40 thorpej Exp $ */
2 
3 /*-
4  * Copyright (c) 1994, 1995, 1997 Matt Thomas <matt@3am-software.com>
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. The name of the author may not be used to endorse or promote products
13  *    derived from this software without specific prior written permission
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25  */
26 
27 /*
28  * DEC EtherWORKS 3 Ethernet Controllers
29  *
30  * Written by Matt Thomas
31  * BPF support code stolen directly from if_ec.c
32  *
33  *   This driver supports the LEMAC DE203/204/205 cards.
34  */
35 
36 #include <sys/cdefs.h>
37 __KERNEL_RCSID(0, "$NetBSD: lemac.c,v 1.55 2020/01/29 14:53:40 thorpej Exp $");
38 
39 #include "opt_inet.h"
40 
41 #include <sys/param.h>
42 #include <sys/systm.h>
43 #include <sys/mbuf.h>
44 #include <sys/protosw.h>
45 #include <sys/socket.h>
46 #include <sys/sockio.h>
47 #include <sys/errno.h>
48 #include <sys/malloc.h>
49 #include <sys/device.h>
50 #include <sys/rndsource.h>
51 
52 #include <net/if.h>
53 #include <net/if_types.h>
54 #include <net/if_dl.h>
55 #include <net/route.h>
56 #include <net/if_ether.h>
57 #include <net/if_media.h>
58 #include <net/bpf.h>
59 
60 #ifdef INET
61 #include <netinet/in.h>
62 #include <netinet/in_systm.h>
63 #include <netinet/in_var.h>
64 #include <netinet/ip.h>
65 #include <netinet/if_inarp.h>
66 #endif
67 
68 
69 #include <sys/bus.h>
70 
71 #include <dev/ic/lemacreg.h>
72 #include <dev/ic/lemacvar.h>
73 #if 0
74 #include <i386/isa/decether.h>
75 #endif
76 
77 static void lemac_init(lemac_softc_t *sc);
78 static void lemac_ifstart(struct ifnet *ifp);
79 static void lemac_reset(lemac_softc_t *sc);
80 static void lemac_rne_intr(lemac_softc_t *sc);
81 static void lemac_tne_intr(lemac_softc_t *sc);
82 static void lemac_txd_intr(lemac_softc_t *sc, unsigned cs_value);
83 static void lemac_rxd_intr(lemac_softc_t *sc, unsigned cs_value);
84 static int  lemac_read_eeprom(lemac_softc_t *sc);
85 static void lemac_init_adapmem(lemac_softc_t *sc);
86 
87 static const uint16_t lemac_allmulti_mctbl[LEMAC_MCTBL_SIZE/sizeof(uint16_t)] =  {
88 	0xFFFFU, 0xFFFFU, 0xFFFFU, 0xFFFFU,
89 	0xFFFFU, 0xFFFFU, 0xFFFFU, 0xFFFFU,
90 	0xFFFFU, 0xFFFFU, 0xFFFFU, 0xFFFFU,
91 	0xFFFFU, 0xFFFFU, 0xFFFFU, 0xFFFFU,
92 	0xFFFFU, 0xFFFFU, 0xFFFFU, 0xFFFFU,
93 	0xFFFFU, 0xFFFFU, 0xFFFFU, 0xFFFFU,
94 	0xFFFFU, 0xFFFFU, 0xFFFFU, 0xFFFFU,
95 	0xFFFFU, 0xFFFFU, 0xFFFFU, 0xFFFFU,
96 };
97 
98 /*
99  * Some tuning/monitoring variables.
100  */
101 unsigned lemac_txmax = 16;
102 
103 static void
104 lemac_rxd_intr(lemac_softc_t *sc, unsigned cs_value)
105 {
106 	/*
107 	 * Handle CS_RXD (Receiver disabled) here.
108 	 *
109 	 * Check Free Memory Queue Count. If not equal to zero
110 	 * then just turn Receiver back on. If it is equal to
111 	 * zero then check to see if transmitter is disabled.
112 	 * Process transmit TXD loop once more.  If all else
113 	 * fails then do software init (0xC0 to EEPROM Init)
114 	 * and rebuild Free Memory Queue.
115 	 */
116 
117 	sc->sc_cntrs.cntr_rxd_intrs++;
118 
119 	/* Re-enable Receiver. */
120 
121 	cs_value &= ~LEMAC_CS_RXD;
122 	LEMAC_OUTB(sc, LEMAC_REG_CS, cs_value);
123 
124 	if (LEMAC_INB(sc, LEMAC_REG_FMC) > 0)
125 		return;
126 
127 	if (cs_value & LEMAC_CS_TXD)
128 		lemac_txd_intr(sc, cs_value);
129 
130 	if ((LEMAC_INB(sc, LEMAC_REG_CS) & LEMAC_CS_RXD) == 0)
131 		return;
132 
133 	printf("%s: fatal RXD error, attempting recovery\n",
134 	    sc->sc_if.if_xname);
135 
136 	lemac_reset(sc);
137 	if (sc->sc_if.if_flags & IFF_UP) {
138 		lemac_init(sc);
139 		return;
140 	}
141 
142 	/* Error during initialization.  Mark card as disabled. */
143 	printf("%s: recovery failed -- board disabled\n", sc->sc_if.if_xname);
144 }
145 
146 static void
147 lemac_tne_intr(lemac_softc_t *sc)
148 {
149 	unsigned txcount = LEMAC_INB(sc, LEMAC_REG_TDC);
150 
151 	sc->sc_cntrs.cntr_tne_intrs++;
152 	while (txcount-- > 0) {
153 		unsigned txsts = LEMAC_INB(sc, LEMAC_REG_TDQ);
154 		if_statinc(&sc->sc_if, if_opackets);	/* another one done */
155 		if ((txsts & (LEMAC_TDQ_LCL | LEMAC_TDQ_NCL))
156 		    || (txsts & LEMAC_TDQ_COL) == LEMAC_TDQ_EXCCOL) {
157 			if (txsts & LEMAC_TDQ_NCL)
158 				sc->sc_flags &= ~LEMAC_LINKUP;
159 			if_statinc(&sc->sc_if, if_oerrors);
160 		} else {
161 			sc->sc_flags |= LEMAC_LINKUP;
162 			if ((txsts & LEMAC_TDQ_COL) != LEMAC_TDQ_NOCOL)
163 				if_statinc(&sc->sc_if, if_collisions);
164 		}
165 	}
166 	sc->sc_if.if_flags &= ~IFF_OACTIVE;
167 	if_schedule_deferred_start(&sc->sc_if);
168 }
169 
170 static void
171 lemac_txd_intr(lemac_softc_t *sc, unsigned cs_value)
172 {
173 	/*
174 	 * Read transmit status, remove transmit buffer from
175 	 * transmit queue and place on free memory queue,
176 	 * then reset transmitter.
177 	 * Increment appropriate counters.
178 	 */
179 
180 	sc->sc_cntrs.cntr_txd_intrs++;
181 	if (sc->sc_txctl & LEMAC_TX_STP) {
182 		if_statinc(&sc->sc_if, if_oerrors);
183 		/* return page to free queue */
184 		LEMAC_OUTB(sc, LEMAC_REG_FMQ, LEMAC_INB(sc, LEMAC_REG_TDQ));
185 	}
186 
187 	/* Turn back on transmitter if disabled */
188 	LEMAC_OUTB(sc, LEMAC_REG_CS, cs_value & ~LEMAC_CS_TXD);
189 	sc->sc_if.if_flags &= ~IFF_OACTIVE;
190 }
191 
192 static int
193 lemac_read_eeprom(lemac_softc_t *sc)
194 {
195 	int	word_off, cksum;
196 	u_char *ep;
197 
198 	cksum = 0;
199 	ep = sc->sc_eeprom;
200 	for (word_off = 0; word_off < LEMAC_EEP_SIZE / 2; word_off++) {
201 		LEMAC_OUTB(sc, LEMAC_REG_PI1, word_off);
202 		LEMAC_OUTB(sc, LEMAC_REG_IOP, LEMAC_IOP_EEREAD);
203 
204 		DELAY(LEMAC_EEP_DELAY);
205 
206 		*ep = LEMAC_INB(sc, LEMAC_REG_EE1);	cksum += *ep++;
207 		*ep = LEMAC_INB(sc, LEMAC_REG_EE2);	cksum += *ep++;
208 	}
209 
210 	/* Set up Transmit Control Byte for use later during transmit. */
211 
212 	sc->sc_txctl |= LEMAC_TX_FLAGS;
213 
214 	if ((sc->sc_eeprom[LEMAC_EEP_SWFLAGS] & LEMAC_EEP_SW_SQE) == 0)
215 		sc->sc_txctl &= ~LEMAC_TX_SQE;
216 
217 	if (sc->sc_eeprom[LEMAC_EEP_SWFLAGS] & LEMAC_EEP_SW_LAB)
218 		sc->sc_txctl |= LEMAC_TX_LAB;
219 
220 	memcpy(sc->sc_prodname, &sc->sc_eeprom[LEMAC_EEP_PRDNM],
221 	    LEMAC_EEP_PRDNMSZ);
222 	sc->sc_prodname[LEMAC_EEP_PRDNMSZ] = '\0';
223 
224 	return cksum % 256;
225 }
226 
227 static void
228 lemac_init_adapmem(lemac_softc_t *sc)
229 {
230 	int pg, conf;
231 
232 	conf = LEMAC_INB(sc, LEMAC_REG_CNF);
233 
234 	if ((sc->sc_eeprom[LEMAC_EEP_SETUP] & LEMAC_EEP_ST_DRAM) == 0) {
235 		sc->sc_lastpage = 63;
236 		conf &= ~LEMAC_CNF_DRAM;
237 	} else {
238 		sc->sc_lastpage = 127;
239 		conf |= LEMAC_CNF_DRAM;
240 	}
241 
242 	LEMAC_OUTB(sc, LEMAC_REG_CNF, conf);
243 
244 	for (pg = 1; pg <= sc->sc_lastpage; pg++)
245 		LEMAC_OUTB(sc, LEMAC_REG_FMQ, pg);
246 }
247 
248 static void
249 lemac_input(lemac_softc_t *sc, bus_addr_t offset, size_t length)
250 {
251 	struct ether_header eh;
252 	struct mbuf *m;
253 
254 	if (length - sizeof(eh) > ETHERMTU || length - sizeof(eh) < ETHERMIN) {
255 		if_statinc(&sc->sc_if, if_ierrors);
256 		return;
257 	}
258 	if (LEMAC_USE_PIO_MODE(sc))
259 		LEMAC_INSB(sc, LEMAC_REG_DAT, sizeof(eh), (void *)&eh);
260 	else
261 		LEMAC_GETBUF16(sc, offset, sizeof(eh) / 2, (void *)&eh);
262 
263 	MGETHDR(m, M_DONTWAIT, MT_DATA);
264 	if (m == NULL) {
265 		if_statinc(&sc->sc_if, if_ierrors);
266 		return;
267 	}
268 	if (length + 2 > MHLEN) {
269 		MCLGET(m, M_DONTWAIT);
270 		if ((m->m_flags & M_EXT) == 0) {
271 			m_free(m);
272 			if_statinc(&sc->sc_if, if_ierrors);
273 			return;
274 		}
275 	}
276 	m->m_data += 2;
277 	memcpy(m->m_data, (void *)&eh, sizeof(eh));
278 	if (LEMAC_USE_PIO_MODE(sc)) {
279 		LEMAC_INSB(sc, LEMAC_REG_DAT, length - sizeof(eh),
280 		    mtod(m, char *) + sizeof(eh));
281 	} else {
282 		LEMAC_GETBUF16(sc, offset + sizeof(eh),
283 		    (length - sizeof(eh)) / 2,
284 		    (void *)(mtod(m, char *) + sizeof(eh)));
285 		if (length & 1)
286 			m->m_data[length - 1]
287 			    = LEMAC_GET8(sc, offset + length - 1);
288 	}
289 
290 	m->m_pkthdr.len = m->m_len = length;
291 	m_set_rcvif(m, &sc->sc_if);
292 
293 	if_percpuq_enqueue((&sc->sc_if)->if_percpuq, m);
294 }
295 
296 static void
297 lemac_rne_intr(lemac_softc_t *sc)
298 {
299 	int rxcount;
300 
301 	sc->sc_cntrs.cntr_rne_intrs++;
302 	rxcount = LEMAC_INB(sc, LEMAC_REG_RQC);
303 	while (rxcount--) {
304 		unsigned rxpg = LEMAC_INB(sc, LEMAC_REG_RQ);
305 		uint32_t rxlen;
306 
307 		if (LEMAC_USE_PIO_MODE(sc)) {
308 			LEMAC_OUTB(sc, LEMAC_REG_IOP, rxpg);
309 			LEMAC_OUTB(sc, LEMAC_REG_PI1, 0);
310 			LEMAC_OUTB(sc, LEMAC_REG_PI2, 0);
311 			LEMAC_INSB(sc, LEMAC_REG_DAT, sizeof(rxlen),
312 			    (void *)&rxlen);
313 		} else {
314 			LEMAC_OUTB(sc, LEMAC_REG_MPN, rxpg);
315 			rxlen = LEMAC_GET32(sc, 0);
316 		}
317 		if (rxlen & LEMAC_RX_OK) {
318 			sc->sc_flags |= LEMAC_LINKUP;
319 			/* Get receive length - subtract out checksum. */
320 			rxlen = ((rxlen >> 8) & 0x7FF) - 4;
321 			lemac_input(sc, sizeof(rxlen), rxlen);
322 		} else {
323 			if_statinc(&sc->sc_if, if_ierrors);
324 		}
325 		/* Return this page to Free Memory Queue */
326 		LEMAC_OUTB(sc, LEMAC_REG_FMQ, rxpg);
327 	}  /* end while (recv_count--) */
328 
329 	return;
330 }
331 
332 /*
333  *  This is the standard method of reading the DEC Address ROMS.
334  *  I don't understand it but it does work.
335  */
336 static int
337 lemac_read_macaddr(unsigned char *hwaddr, const bus_space_tag_t iot,
338 	const bus_space_handle_t ioh, const bus_addr_t ioreg, int skippat)
339 {
340 	int cksum, rom_cksum;
341 	unsigned char addrbuf[6];
342 
343 	if (!skippat) {
344 		int idx, idx2, found, octet;
345 		static u_char testpat[]
346 		    = { 0xFF, 0, 0x55, 0xAA, 0xFF, 0, 0x55, 0xAA };
347 
348 		idx2 = found = 0;
349 
350 		for (idx = 0; idx < 32; idx++) {
351 			octet = bus_space_read_1(iot, ioh, ioreg);
352 
353 			if (octet == testpat[idx2]) {
354 				if (++idx2 == sizeof(testpat)) {
355 					++found;
356 					break;
357 				}
358 			} else
359 				idx2 = 0;
360 		}
361 
362 		if (!found)
363 			return -1;
364 	}
365 
366 	if (hwaddr == NULL)
367 		hwaddr = addrbuf;
368 
369 	cksum = 0;
370 	hwaddr[0] = bus_space_read_1(iot, ioh, ioreg);
371 	hwaddr[1] = bus_space_read_1(iot, ioh, ioreg);
372 
373 	/* hardware address can't be multicast */
374 	if (hwaddr[0] & 1)
375 		return -1;
376 
377 	cksum = *(u_short *)&hwaddr[0];
378 
379 	hwaddr[2] = bus_space_read_1(iot, ioh, ioreg);
380 	hwaddr[3] = bus_space_read_1(iot, ioh, ioreg);
381 	cksum *= 2;
382 	if (cksum > 65535) cksum -= 65535;
383 	cksum += *(u_short *) &hwaddr[2];
384 	if (cksum > 65535) cksum -= 65535;
385 
386 	hwaddr[4] = bus_space_read_1(iot, ioh, ioreg);
387 	hwaddr[5] = bus_space_read_1(iot, ioh, ioreg);
388 	cksum *= 2;
389 	if (cksum > 65535) cksum -= 65535;
390 	cksum += *(u_short *)&hwaddr[4];
391 	if (cksum >= 65535) cksum -= 65535;
392 
393 	/* 00-00-00 is an illegal OUI */
394 	if (hwaddr[0] == 0 && hwaddr[1] == 0 && hwaddr[2] == 0)
395 		return -1;
396 
397 	rom_cksum = bus_space_read_1(iot, ioh, ioreg);
398 	rom_cksum |= bus_space_read_1(iot, ioh, ioreg) << 8;
399 
400 	if (cksum != rom_cksum)
401 		return -1;
402 	return 0;
403 }
404 
405 static void
406 lemac_multicast_op(
407 	uint16_t *mctbl,
408 	const u_char *mca,
409 	int enable)
410 {
411 	u_int idx, bit, crc;
412 
413 	crc = ether_crc32_le(mca, ETHER_ADDR_LEN);
414 
415 	/*
416 	 * The following two lines convert the N bit index into a longword
417 	 * index and a longword mask.
418 	 */
419 #if LEMAC_MCTBL_BITS < 0
420 	crc >>= (32 + LEMAC_MCTBL_BITS);
421 	crc &= (1 << -LEMAC_MCTBL_BITS) - 1;
422 #else
423 	crc &= (1 << LEMAC_MCTBL_BITS) - 1;
424 #endif
425 	bit = 1 << (crc & 0x0F);
426 	idx = crc >> 4;
427 
428 	/* Set or clear hash filter bit in our table. */
429 	if (enable)
430 		mctbl[idx] |= bit;		/* Set Bit */
431 	else
432 		mctbl[idx] &= ~bit;		/* Clear Bit */
433 }
434 
435 static void
436 lemac_multicast_filter(lemac_softc_t *sc)
437 {
438 	struct ethercom *ec = &sc->sc_ec;
439 	struct ether_multistep step;
440 	struct ether_multi *enm;
441 
442 	memset(sc->sc_mctbl, 0, LEMAC_MCTBL_BITS / 8);
443 
444 	lemac_multicast_op(sc->sc_mctbl, etherbroadcastaddr, TRUE);
445 
446 	ETHER_LOCK(ec);
447 	ETHER_FIRST_MULTI(step, ec, enm);
448 	while (enm != NULL) {
449 		if (!LEMAC_ADDREQUAL(enm->enm_addrlo, enm->enm_addrhi)) {
450 			sc->sc_flags |= LEMAC_ALLMULTI;
451 			sc->sc_if.if_flags |= IFF_ALLMULTI;
452 			ETHER_UNLOCK(ec);
453 			return;
454 		}
455 		lemac_multicast_op(sc->sc_mctbl, enm->enm_addrlo, TRUE);
456 		ETHER_NEXT_MULTI(step, enm);
457 	}
458 	ETHER_UNLOCK(ec);
459 	sc->sc_flags &= ~LEMAC_ALLMULTI;
460 	sc->sc_if.if_flags &= ~IFF_ALLMULTI;
461 }
462 
463 /*
464  * Do a hard reset of the board;
465  */
466 static void
467 lemac_reset(lemac_softc_t * const sc)
468 {
469 	unsigned data;
470 
471 	/*
472 	 * Initialize board..
473 	 */
474 	sc->sc_flags &= ~LEMAC_LINKUP;
475 	sc->sc_if.if_flags &= ~IFF_OACTIVE;
476 	LEMAC_INTR_DISABLE(sc);
477 
478 	LEMAC_OUTB(sc, LEMAC_REG_IOP, LEMAC_IOP_EEINIT);
479 	DELAY(LEMAC_EEP_DELAY);
480 
481 	/*
482 	 * Read EEPROM information.  NOTE - the placement of this function
483 	 * is important because functions hereafter may rely on information
484 	 * read from the EEPROM.
485 	 */
486 	if ((data = lemac_read_eeprom(sc)) != LEMAC_EEP_CKSUM) {
487 		printf("%s: reset: EEPROM checksum failed (0x%x)\n",
488 		    sc->sc_if.if_xname, data);
489 		return;
490 	}
491 
492 	/* Update the control register to reflect the media choice */
493 	data = LEMAC_INB(sc, LEMAC_REG_CTL);
494 	if ((data & (LEMAC_CTL_APD | LEMAC_CTL_PSL)) != sc->sc_ctlmode) {
495 		data &= ~(LEMAC_CTL_APD | LEMAC_CTL_PSL);
496 		data |= sc->sc_ctlmode;
497 		LEMAC_OUTB(sc, LEMAC_REG_CTL, data);
498 	}
499 
500 	/* Force to 2K mode if not already configured. */
501 
502 	data = LEMAC_INB(sc, LEMAC_REG_MBR);
503 	if (LEMAC_IS_2K_MODE(data)) {
504 		sc->sc_flags |= LEMAC_2K_MODE;
505 	} else if (LEMAC_IS_64K_MODE(data)) {
506 		data = (((data * 2) & 0xF) << 4);
507 		sc->sc_flags |= LEMAC_WAS_64K_MODE;
508 		LEMAC_OUTB(sc, LEMAC_REG_MBR, data);
509 	} else if (LEMAC_IS_32K_MODE(data)) {
510 		data = ((data & 0xF) << 4);
511 		sc->sc_flags |= LEMAC_WAS_32K_MODE;
512 		LEMAC_OUTB(sc, LEMAC_REG_MBR, data);
513 	} else {
514 		sc->sc_flags |= LEMAC_PIO_MODE;
515 		/* PIO mode */
516 	}
517 
518 	/* Initialize Free Memory Queue, Init mcast table with broadcast. */
519 
520 	lemac_init_adapmem(sc);
521 	sc->sc_flags |= LEMAC_ALIVE;
522 }
523 
524 static void
525 lemac_init(lemac_softc_t * const sc)
526 {
527 	if ((sc->sc_flags & LEMAC_ALIVE) == 0)
528 		return;
529 
530 	/*
531 	 * If the interface has the up flag
532 	 */
533 	if (sc->sc_if.if_flags & IFF_UP) {
534 		int saved_cs = LEMAC_INB(sc, LEMAC_REG_CS);
535 		LEMAC_OUTB(sc, LEMAC_REG_CS,
536 		    saved_cs | (LEMAC_CS_TXD | LEMAC_CS_RXD));
537 		LEMAC_OUTB(sc, LEMAC_REG_PA0, sc->sc_enaddr[0]);
538 		LEMAC_OUTB(sc, LEMAC_REG_PA1, sc->sc_enaddr[1]);
539 		LEMAC_OUTB(sc, LEMAC_REG_PA2, sc->sc_enaddr[2]);
540 		LEMAC_OUTB(sc, LEMAC_REG_PA3, sc->sc_enaddr[3]);
541 		LEMAC_OUTB(sc, LEMAC_REG_PA4, sc->sc_enaddr[4]);
542 		LEMAC_OUTB(sc, LEMAC_REG_PA5, sc->sc_enaddr[5]);
543 
544 		LEMAC_OUTB(sc, LEMAC_REG_IC,
545 		    LEMAC_INB(sc, LEMAC_REG_IC) | LEMAC_IC_IE);
546 
547 		if (sc->sc_if.if_flags & IFF_PROMISC) {
548 			LEMAC_OUTB(sc, LEMAC_REG_CS,
549 			    LEMAC_CS_MCE | LEMAC_CS_PME);
550 		} else {
551 			LEMAC_INTR_DISABLE(sc);
552 			lemac_multicast_filter(sc);
553 			if (sc->sc_flags & LEMAC_ALLMULTI)
554 				memcpy(sc->sc_mctbl, lemac_allmulti_mctbl,
555 				    sizeof(sc->sc_mctbl));
556 			if (LEMAC_USE_PIO_MODE(sc)) {
557 				LEMAC_OUTB(sc, LEMAC_REG_IOP, 0);
558 				LEMAC_OUTB(sc, LEMAC_REG_PI1,
559 				    LEMAC_MCTBL_OFF & 0xFF);
560 				LEMAC_OUTB(sc, LEMAC_REG_PI2,
561 				    LEMAC_MCTBL_OFF >> 8);
562 				LEMAC_OUTSB(sc, LEMAC_REG_DAT,
563 				    sizeof(sc->sc_mctbl),
564 				    (void *)sc->sc_mctbl);
565 			} else {
566 				LEMAC_OUTB(sc, LEMAC_REG_MPN, 0);
567 				LEMAC_PUTBUF8(sc, LEMAC_MCTBL_OFF,
568 				    sizeof(sc->sc_mctbl),
569 				    (void *)sc->sc_mctbl);
570 			}
571 
572 			LEMAC_OUTB(sc, LEMAC_REG_CS, LEMAC_CS_MCE);
573 		}
574 
575 		LEMAC_OUTB(sc, LEMAC_REG_CTL,
576 		    LEMAC_INB(sc, LEMAC_REG_CTL) ^ LEMAC_CTL_LED);
577 
578 		LEMAC_INTR_ENABLE(sc);
579 		sc->sc_if.if_flags |= IFF_RUNNING;
580 		lemac_ifstart(&sc->sc_if);
581 	} else {
582 		LEMAC_OUTB(sc, LEMAC_REG_CS, LEMAC_CS_RXD | LEMAC_CS_TXD);
583 
584 		LEMAC_INTR_DISABLE(sc);
585 		sc->sc_if.if_flags &= ~IFF_RUNNING;
586 	}
587 }
588 
589 static void
590 lemac_ifstart(
591 	struct ifnet *ifp)
592 {
593 	lemac_softc_t * const sc = LEMAC_IFP_TO_SOFTC(ifp);
594 
595 	if ((ifp->if_flags & IFF_RUNNING) == 0)
596 		return;
597 
598 	LEMAC_INTR_DISABLE(sc);
599 
600 	for (;;) {
601 		struct mbuf *m;
602 		struct mbuf *m0;
603 		int tx_pg;
604 
605 		IFQ_POLL(&ifp->if_snd, m);
606 		if (m == NULL)
607 			break;
608 
609 		if ((sc->sc_csr.csr_tqc = LEMAC_INB(sc, LEMAC_REG_TQC))
610 		    >= lemac_txmax) {
611 			sc->sc_cntrs.cntr_txfull++;
612 			ifp->if_flags |= IFF_OACTIVE;
613 			break;
614 		}
615 
616 		/* Get free memory page */
617 		tx_pg = sc->sc_csr.csr_fmq = LEMAC_INB(sc, LEMAC_REG_FMQ);
618 
619 		/* Check for good transmit page. */
620 		if (tx_pg == 0 || tx_pg > sc->sc_lastpage) {
621 			sc->sc_cntrs.cntr_txnospc++;
622 			ifp->if_flags |= IFF_OACTIVE;
623 			break;
624 		}
625 
626 		IFQ_DEQUEUE(&ifp->if_snd, m);
627 
628 		/*
629 		 * The first four bytes of each transmit buffer are for
630 		 * control information.  The first byte is the control
631 		 * byte, then the length (why not word aligned?), then
632 		 * the offset to the buffer.
633 		 */
634 
635 		if (LEMAC_USE_PIO_MODE(sc)) {
636 			/* Shift 2K window. */
637 			LEMAC_OUTB(sc, LEMAC_REG_IOP, tx_pg);
638 
639 			LEMAC_OUTB(sc, LEMAC_REG_PI1, 0);
640 			LEMAC_OUTB(sc, LEMAC_REG_PI2, 0);
641 			LEMAC_OUTB(sc, LEMAC_REG_DAT, sc->sc_txctl);
642 			LEMAC_OUTB(sc, LEMAC_REG_DAT,
643 			    (m->m_pkthdr.len >> 0) & 0xFF);
644 			LEMAC_OUTB(sc, LEMAC_REG_DAT,
645 			    (m->m_pkthdr.len >> 8) & 0xFF);
646 			LEMAC_OUTB(sc, LEMAC_REG_DAT, LEMAC_TX_HDRSZ);
647 			for (m0 = m; m0 != NULL; m0 = m0->m_next)
648 				LEMAC_OUTSB(sc, LEMAC_REG_DAT,
649 				    m0->m_len, m0->m_data);
650 		} else {
651 			bus_size_t txoff = /* (mtod(m, uint32_t) & (sizeof(uint32_t) - 1)) + */ LEMAC_TX_HDRSZ;
652 
653 			/* Shift 2K window. */
654 			LEMAC_OUTB(sc, LEMAC_REG_MPN, tx_pg);
655 
656 			LEMAC_PUT8(sc, 0, sc->sc_txctl);
657 			LEMAC_PUT8(sc, 1, (m->m_pkthdr.len >> 0) & 0xFF);
658 			LEMAC_PUT8(sc, 2, (m->m_pkthdr.len >> 8) & 0xFF);
659 			LEMAC_PUT8(sc, 3, txoff);
660 
661 			/* Copy the packet to the board */
662 			for (m0 = m; m0 != NULL; m0 = m0->m_next) {
663 #if 0
664 				LEMAC_PUTBUF8(sc, txoff, m0->m_len, m0->m_data);
665 				txoff += m0->m_len;
666 #else
667 				const uint8_t *cp = m0->m_data;
668 				int len = m0->m_len;
669 #if 0
670 				if ((txoff & 3) == (((long)cp) & 3)
671 				    && len >= 4) {
672 					if (txoff & 3) {
673 						int alen = (~txoff & 3);
674 						LEMAC_PUTBUF8(sc, txoff, alen,
675 						    cp);
676 						cp += alen;
677 						txoff += alen;
678 						len -= alen;
679 					}
680 					if (len >= 4) {
681 						LEMAC_PUTBUF32(sc, txoff,
682 						    len / 4, cp);
683 						cp += len & ~3;
684 						txoff += len & ~3;
685 						len &= 3;
686 					}
687 				}
688 #endif
689 				if ((txoff & 1) == (((long)cp) & 1)
690 				    && len >= 2) {
691 					if (txoff & 1) {
692 						int alen = (~txoff & 1);
693 						LEMAC_PUTBUF8(sc, txoff, alen,
694 						    cp);
695 						cp += alen;
696 						txoff += alen;
697 						len -= alen;
698 					}
699 					if (len >= 2) {
700 						LEMAC_PUTBUF16(sc, txoff,
701 						    len / 2, (const void *)cp);
702 						cp += len & ~1;
703 						txoff += len & ~1;
704 						len &= 1;
705 					}
706 				}
707 				if (len > 0) {
708 					LEMAC_PUTBUF8(sc, txoff, len, cp);
709 					txoff += len;
710 				}
711 #endif
712 			}
713 		}
714 
715 		/* Tell chip to transmit this packet */
716 		LEMAC_OUTB(sc, LEMAC_REG_TQ, tx_pg);
717 		bpf_mtap(&sc->sc_if, m, BPF_D_OUT);
718 		m_freem(m);			/* Free the mbuf */
719 	}
720 	LEMAC_INTR_ENABLE(sc);
721 }
722 
723 static int
724 lemac_ifioctl(
725 	struct ifnet *ifp,
726 	u_long cmd,
727 	void *data)
728 {
729 	lemac_softc_t * const sc = LEMAC_IFP_TO_SOFTC(ifp);
730 	int s;
731 	int error = 0;
732 
733 	s = splnet();
734 
735 	switch (cmd) {
736 	case SIOCINITIFADDR: {
737 		struct ifaddr *ifa = (struct ifaddr *)data;
738 
739 		ifp->if_flags |= IFF_UP;
740 		lemac_init(sc);
741 		switch (ifa->ifa_addr->sa_family) {
742 #ifdef INET
743 		case AF_INET:
744 			arp_ifinit(&sc->sc_if, ifa);
745 			break;
746 #endif /* INET */
747 
748 
749 		default:
750 			break;
751 		}
752 		break;
753 	}
754 
755 	case SIOCSIFFLAGS:
756 		if ((error = ifioctl_common(ifp, cmd, data)) != 0)
757 			break;
758 		lemac_init(sc);
759 		break;
760 
761 	case SIOCADDMULTI:
762 	case SIOCDELMULTI:
763 		/*
764 		 * Update multicast listeners
765 		 */
766 		if ((error = ether_ioctl(ifp, cmd, data)) == ENETRESET) {
767 			/* reset multicast filtering */
768 			if (ifp->if_flags & IFF_RUNNING)
769 				lemac_init(sc);
770 			error = 0;
771 		}
772 		break;
773 
774 	default:
775 		error = ether_ioctl(ifp, cmd, data);
776 		break;
777 	}
778 
779 	splx(s);
780 	return error;
781 }
782 
783 static int
784 lemac_ifmedia_change(struct ifnet * const ifp)
785 {
786 	lemac_softc_t * const sc = LEMAC_IFP_TO_SOFTC(ifp);
787 	unsigned new_ctl;
788 
789 	switch (IFM_SUBTYPE(sc->sc_ifmedia.ifm_media)) {
790 	case IFM_10_T: new_ctl = LEMAC_CTL_APD; break;
791 	case IFM_10_2:
792 	case IFM_10_5: new_ctl = LEMAC_CTL_APD | LEMAC_CTL_PSL; break;
793 	case IFM_AUTO: new_ctl = 0; break;
794 	default:       return EINVAL;
795 	}
796 	if (sc->sc_ctlmode != new_ctl) {
797 		sc->sc_ctlmode = new_ctl;
798 		lemac_reset(sc);
799 		if (sc->sc_if.if_flags & IFF_UP)
800 			lemac_init(sc);
801 	}
802 	return 0;
803 }
804 
805 /*
806  * Media status callback
807  */
808 static void
809 lemac_ifmedia_status(struct ifnet * const ifp, struct ifmediareq *req)
810 {
811 	lemac_softc_t *sc = LEMAC_IFP_TO_SOFTC(ifp);
812 	unsigned data = LEMAC_INB(sc, LEMAC_REG_CNF);
813 
814 	req->ifm_status = IFM_AVALID;
815 	if (sc->sc_flags & LEMAC_LINKUP)
816 		req->ifm_status |= IFM_ACTIVE;
817 
818 	if (sc->sc_ctlmode & LEMAC_CTL_APD) {
819 		if (sc->sc_ctlmode & LEMAC_CTL_PSL)
820 			req->ifm_active = IFM_10_5;
821 		else
822 			req->ifm_active = IFM_10_T;
823 	} else {
824 		/*
825 		 * The link bit of the configuration register reflects the
826 		 * current media choice when auto-port is enabled.
827 		 */
828 		if (data & LEMAC_CNF_NOLINK)
829 			req->ifm_active = IFM_10_5;
830 		else
831 			req->ifm_active = IFM_10_T;
832 	}
833 
834 	req->ifm_active |= IFM_ETHER;
835 }
836 
837 int
838 lemac_port_check(const bus_space_tag_t iot, const bus_space_handle_t ioh)
839 {
840 	unsigned char hwaddr[6];
841 
842 	if (lemac_read_macaddr(hwaddr, iot, ioh, LEMAC_REG_APD, 0) == 0)
843 		return 1;
844 	if (lemac_read_macaddr(hwaddr, iot, ioh, LEMAC_REG_APD, 1) == 0)
845 		return 1;
846 	return 0;
847 }
848 
849 void
850 lemac_info_get(const bus_space_tag_t iot, const bus_space_handle_t ioh,
851 	bus_addr_t *maddr_p, bus_size_t *msize_p, int *irq_p)
852 {
853 	unsigned data;
854 
855 	*irq_p = LEMAC_DECODEIRQ(bus_space_read_1(iot, ioh, LEMAC_REG_IC)
856 	    & LEMAC_IC_IRQMSK);
857 
858 	data = bus_space_read_1(iot, ioh, LEMAC_REG_MBR);
859 	if (LEMAC_IS_2K_MODE(data)) {
860 		*maddr_p = data * (2 * 1024) + (512 * 1024);
861 		*msize_p =  2 * 1024;
862 	} else if (LEMAC_IS_64K_MODE(data)) {
863 		*maddr_p = data * 64 * 1024;
864 		*msize_p = 64 * 1024;
865 	} else if (LEMAC_IS_32K_MODE(data)) {
866 		*maddr_p = data * 32 * 1024;
867 		*msize_p = 32* 1024;
868 	} else {
869 		*maddr_p = 0;
870 		*msize_p = 0;
871 	}
872 }
873 
874 /*
875  * What to do upon receipt of an interrupt.
876  */
877 int
878 lemac_intr(void *arg)
879 {
880 	lemac_softc_t * const sc = arg;
881 	int cs_value;
882 
883 	LEMAC_INTR_DISABLE(sc);	/* Mask interrupts */
884 
885 	/*
886 	 * Determine cause of interrupt.  Receive events take
887 	 * priority over Transmit.
888 	 */
889 
890 	cs_value = LEMAC_INB(sc, LEMAC_REG_CS);
891 
892 	/*
893 	 * Check for Receive Queue not being empty.
894 	 * Check for Transmit Done Queue not being empty.
895 	 */
896 
897 	if (cs_value & LEMAC_CS_RNE)
898 		lemac_rne_intr(sc);
899 	if (cs_value & LEMAC_CS_TNE)
900 		lemac_tne_intr(sc);
901 
902 	/*
903 	 * Check for Transmitter Disabled.
904 	 * Check for Receiver Disabled.
905 	 */
906 
907 	if (cs_value & LEMAC_CS_TXD)
908 		lemac_txd_intr(sc, cs_value);
909 	if (cs_value & LEMAC_CS_RXD)
910 		lemac_rxd_intr(sc, cs_value);
911 
912 	/* Toggle LED and unmask interrupts. */
913 
914 	sc->sc_csr.csr_cs = LEMAC_INB(sc, LEMAC_REG_CS);
915 
916 	LEMAC_OUTB(sc, LEMAC_REG_CTL,
917 	    LEMAC_INB(sc, LEMAC_REG_CTL) ^ LEMAC_CTL_LED);
918 	LEMAC_INTR_ENABLE(sc);		/* Unmask interrupts */
919 
920 	if (cs_value)
921 		rnd_add_uint32(&sc->rnd_source, cs_value);
922 
923 	return 1;
924 }
925 
926 void
927 lemac_shutdown(void *arg)
928 {
929 
930 	lemac_reset((lemac_softc_t *) arg);
931 }
932 
933 static const char * const lemac_modes[4] = {
934 	"PIO mode (internal 2KB window)",
935 	"2KB window",
936 	"changed 32KB window to 2KB",
937 	"changed 64KB window to 2KB",
938 };
939 
940 void
941 lemac_ifattach(lemac_softc_t *sc)
942 {
943 	struct ifnet * const ifp = &sc->sc_if;
944 
945 	strlcpy(ifp->if_xname, device_xname(sc->sc_dev), IFNAMSIZ);
946 
947 	lemac_reset(sc);
948 
949 	(void)lemac_read_macaddr(sc->sc_enaddr, sc->sc_iot, sc->sc_ioh,
950 	    LEMAC_REG_APD, 0);
951 
952 	printf(": %s\n", sc->sc_prodname);
953 
954 	printf("%s: address %s, %dKB RAM, %s\n",
955 	    ifp->if_xname,
956 	    ether_sprintf(sc->sc_enaddr),
957 	    sc->sc_lastpage * 2 + 2,
958 	    lemac_modes[sc->sc_flags & LEMAC_MODE_MASK]);
959 
960 	ifp->if_softc = (void *)sc;
961 	ifp->if_start = lemac_ifstart;
962 	ifp->if_ioctl = lemac_ifioctl;
963 
964 	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
965 
966 	if (sc->sc_flags & LEMAC_ALIVE) {
967 		int media;
968 
969 		IFQ_SET_READY(&ifp->if_snd);
970 
971 		if_attach(ifp);
972 		if_deferred_start_init(ifp, NULL);
973 		ether_ifattach(ifp, sc->sc_enaddr);
974 
975 		rnd_attach_source(&sc->rnd_source, device_xname(sc->sc_dev),
976 		    RND_TYPE_NET, RND_FLAG_DEFAULT);
977 
978 		/* Initialize ifmedia structures. */
979 		sc->sc_ec.ec_ifmedia = &sc->sc_ifmedia;
980 		ifmedia_init(&sc->sc_ifmedia, 0,
981 		    lemac_ifmedia_change, lemac_ifmedia_status);
982 		if (sc->sc_prodname[4] == '5')	/* DE205 is UTP/AUI */
983 			ifmedia_add(&sc->sc_ifmedia, IFM_ETHER | IFM_AUTO,
984 			    0, 0);
985 		if (sc->sc_prodname[4] != '3')	/* DE204 & 205 have UTP */
986 			ifmedia_add(&sc->sc_ifmedia, IFM_ETHER | IFM_10_T,
987 			    0, 0);
988 		if (sc->sc_prodname[4] != '4')	/* DE203 & 205 have BNC */
989 			ifmedia_add(&sc->sc_ifmedia, IFM_ETHER | IFM_10_5,
990 			    0, 0);
991 		switch (sc->sc_prodname[4]) {
992 		case '3': media = IFM_10_5; break;
993 		case '4': media = IFM_10_T; break;
994 		default:  media = IFM_AUTO; break;
995 		}
996 		ifmedia_set(&sc->sc_ifmedia, IFM_ETHER | media);
997 	} else
998 		printf("%s: disabled due to error\n", ifp->if_xname);
999 }
1000