xref: /openbsd/sys/dev/isa/if_ec.c (revision 898184e3)
1 /*	$OpenBSD: if_ec.c,v 1.11 2008/06/26 05:42:16 ray Exp $	*/
2 /*	$NetBSD: if_ec.c,v 1.9 1998/07/05 06:49:12 jonathan Exp $	*/
3 
4 /*-
5  * Copyright (c) 1997, 1998 The NetBSD Foundation, Inc.
6  * All rights reserved.
7  *
8  * This code is derived from software contributed to The NetBSD Foundation
9  * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
10  * NASA Ames Research Center.
11  *
12  * Redistribution and use in source and binary forms, with or without
13  * modification, are permitted provided that the following conditions
14  * are met:
15  * 1. Redistributions of source code must retain the above copyright
16  *    notice, this list of conditions and the following disclaimer.
17  * 2. Redistributions in binary form must reproduce the above copyright
18  *    notice, this list of conditions and the following disclaimer in the
19  *    documentation and/or other materials provided with the distribution.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
22  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
23  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
24  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
25  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31  * POSSIBILITY OF SUCH DAMAGE.
32  */
33 
34 /*
35  * Device driver for National Semiconductor DS8390/WD83C690 based ethernet
36  * adapters.
37  *
38  * Copyright (c) 1994, 1995 Charles M. Hannum.  All rights reserved.
39  *
40  * Copyright (C) 1993, David Greenman.  This software may be used, modified,
41  * copied, distributed, and sold, in both source and binary form provided that
42  * the above copyright and these terms are retained.  Under no circumstances is
43  * the author responsible for the proper functioning of this software, nor does
44  * the author assume any responsibility for damages incurred with its use.
45  */
46 
47 /*
48  * Device driver for the 3Com Etherlink II (3c503).
49  */
50 
51 #include "bpfilter.h"
52 
53 #include <sys/param.h>
54 #include <sys/systm.h>
55 #include <sys/device.h>
56 #include <sys/socket.h>
57 #include <sys/mbuf.h>
58 #include <sys/syslog.h>
59 
60 #include <net/if.h>
61 #include <net/if_dl.h>
62 #include <net/if_types.h>
63 #include <net/if_media.h>
64 
65 #ifdef INET
66 #include <netinet/in.h>
67 #include <netinet/in_systm.h>
68 #include <netinet/in_var.h>
69 #include <netinet/ip.h>
70 #include <netinet/if_ether.h>
71 #endif
72 
73 #if NBPFILTER > 0
74 #include <net/bpf.h>
75 #endif
76 
77 #include <machine/bus.h>
78 #include <machine/intr.h>
79 
80 #include <dev/isa/isareg.h>
81 #include <dev/isa/isavar.h>
82 
83 #include <dev/ic/dp8390reg.h>
84 #include <dev/ic/dp8390var.h>
85 
86 #include <dev/isa/if_ecreg.h>
87 
88 struct ec_softc {
89 	struct dp8390_softc sc_dp8390;
90 
91 	bus_space_tag_t sc_asict;	/* space tag for ASIC */
92 	bus_space_handle_t sc_asich;	/* space handle for ASIC */
93 
94 	int sc_16bitp;			/* are we 16 bit? */
95 
96 	void *sc_ih;			/* interrupt handle */
97 };
98 
99 int	ec_probe(struct device *, void *, void *);
100 void	ec_attach(struct device *, struct device *, void *);
101 
102 struct cfattach ec_ca = {
103 	sizeof(struct ec_softc), ec_probe, ec_attach
104 };
105 
106 int	ec_set_media(struct ec_softc *, int);
107 
108 void	ec_media_init(struct dp8390_softc *);
109 
110 int	ec_mediachange(struct dp8390_softc *);
111 void	ec_mediastatus(struct dp8390_softc *, struct ifmediareq *);
112 
113 void	ec_init_card(struct dp8390_softc *);
114 int	ec_write_mbuf(struct dp8390_softc *, struct mbuf *, int);
115 int	ec_ring_copy(struct dp8390_softc *, int, caddr_t, u_short);
116 void	ec_read_hdr(struct dp8390_softc *, int, struct dp8390_ring *);
117 int	ec_fake_test_mem(struct dp8390_softc *);
118 int	ec_test_mem(struct dp8390_softc *);
119 
120 __inline void ec_readmem(struct ec_softc *, int, u_int8_t *, int);
121 
122 static const int ec_iobase[] = {
123 	0x2e0, 0x2a0, 0x280, 0x250, 0x350, 0x330, 0x310, 0x300,
124 };
125 #define	NEC_IOBASE	(sizeof(ec_iobase) / sizeof(ec_iobase[0]))
126 
127 static const int ec_membase[] = {
128 	MADDRUNK, MADDRUNK, MADDRUNK, MADDRUNK, 0xc8000, 0xcc000,
129 	0xd8000, 0xdc000,
130 };
131 #define	NEC_MEMBASE	(sizeof(ec_membase) / sizeof(ec_membase[0]))
132 
133 struct cfdriver ec_cd = {
134 	NULL, "ec", DV_IFNET
135 };
136 
137 int
138 ec_probe(struct device *parent, void *match, void *aux)
139 {
140 	struct isa_attach_args *ia = aux;
141 	bus_space_tag_t nict, asict, memt;
142 	bus_space_handle_t nich, asich, memh;
143 	bus_size_t memsize;
144 	int nich_valid, asich_valid, memh_valid;
145 	int i, rv = 0;
146 	u_int8_t x;
147 
148 	nict = asict = ia->ia_iot;
149 	memt = ia->ia_memt;
150 
151 	nich_valid = asich_valid = memh_valid = 0;
152 
153 	/*
154 	 * Hmm, a 16-bit card has 16k of memory, but only an 8k window
155 	 * to it.
156 	 */
157 	memsize = 8192;
158 
159 	/* Disallow wildcarded i/o addresses. */
160 	if (ia->ia_iobase == -1 /* ISACF_PORT_DEFAULT */)
161 		return (0);
162 
163 	/* Disallow wildcarded mem address. */
164 	if (ia->ia_maddr == -1 /* ISACF_IOMEM_DEFAULT */)
165 		return (0);
166 
167 	/* Validate the i/o base. */
168 	for (i = 0; i < NEC_IOBASE; i++)
169 		if (ia->ia_iobase == ec_iobase[i])
170 			break;
171 	if (i == NEC_IOBASE)
172 		return (0);
173 
174 	/* Validate the mem base. */
175 	for (i = 0; i < NEC_MEMBASE; i++) {
176 		if (ec_membase[i] == MADDRUNK)
177 			continue;
178 		if (ia->ia_maddr == ec_membase[i])
179 			break;
180 	}
181 	if (i == NEC_MEMBASE)
182 		return (0);
183 
184 	/* Attempt to map the NIC space. */
185 	if (bus_space_map(nict, ia->ia_iobase + ELINK2_NIC_OFFSET,
186 	    ELINK2_NIC_PORTS, 0, &nich))
187 		goto out;
188 	nich_valid = 1;
189 
190 	/* Attempt to map the ASIC space. */
191 	if (bus_space_map(asict, ia->ia_iobase + ELINK2_ASIC_OFFSET,
192 	    ELINK2_ASIC_PORTS, 0, &asich))
193 		goto out;
194 	asich_valid = 1;
195 
196 	/* Attempt to map the memory space. */
197 	if (bus_space_map(memt, ia->ia_maddr, memsize, 0, &memh))
198 		goto out;
199 	memh_valid = 1;
200 
201 	/*
202 	 * Verify that the kernel configured I/O address matches the
203 	 * board configured I/O address.
204 	 *
205 	 * This is really only useful to see if something that looks like
206 	 * the board is there; after all, we're already talking to it at
207 	 * this point.
208 	 */
209 	x = bus_space_read_1(asict, asich, ELINK2_BCFR);
210 	if (x == 0 || (x & (x - 1)) != 0)
211 		goto out;
212 	i = ffs(x) - 1;
213 	if (ia->ia_iobase != ec_iobase[i])
214 		goto out;
215 
216 	/*
217 	 * ...and for the memory address.  Note we do not support
218 	 * cards configured with shared memory disabled.
219 	 */
220 	x = bus_space_read_1(asict, asich, ELINK2_PCFR);
221 	if (x == 0 || (x & (x - 1)) != 0)
222 		goto out;
223 	i = ffs(x) - 1;
224 	if (ia->ia_maddr != ec_membase[i])
225 		goto out;
226 
227 	/* So, we say we've found it! */
228 	ia->ia_iosize = ELINK2_NIC_PORTS;
229 	ia->ia_msize = memsize;
230 	rv = 1;
231 
232  out:
233 	if (nich_valid)
234 		bus_space_unmap(nict, nich, ELINK2_NIC_PORTS);
235 	if (asich_valid)
236 		bus_space_unmap(asict, asich, ELINK2_ASIC_PORTS);
237 	if (memh_valid)
238 		bus_space_unmap(memt, memh, memsize);
239 	return (rv);
240 }
241 
242 void
243 ec_attach(struct device *parent, struct device *self, void *aux)
244 {
245 	struct ec_softc *esc = (struct ec_softc *)self;
246 	struct dp8390_softc *sc = &esc->sc_dp8390;
247 	struct isa_attach_args *ia = aux;
248 	bus_space_tag_t nict, asict, memt;
249 	bus_space_handle_t nich, asich, memh;
250 	bus_size_t memsize;
251 	u_int8_t tmp;
252 	int i;
253 
254 	printf("\n");
255 
256 	nict = asict = ia->ia_iot;
257 	memt = ia->ia_memt;
258 
259 	/*
260 	 * Hmm, a 16-bit card has 16k of memory, but only an 8k window
261 	 * to it.
262 	 */
263 	memsize = 8192;
264 
265 	/* Map the NIC space. */
266 	if (bus_space_map(nict, ia->ia_iobase + ELINK2_NIC_OFFSET,
267 	    ELINK2_NIC_PORTS, 0, &nich)) {
268 		printf("%s: can't map nic i/o space\n",
269 		    sc->sc_dev.dv_xname);
270 		return;
271 	}
272 
273 	/* Map the ASIC space. */
274 	if (bus_space_map(asict, ia->ia_iobase + ELINK2_ASIC_OFFSET,
275 	    ELINK2_ASIC_PORTS, 0, &asich)) {
276 		printf("%s: can't map asic i/o space\n",
277 		    sc->sc_dev.dv_xname);
278 		return;
279 	}
280 
281 	/* Map the memory space. */
282 	if (bus_space_map(memt, ia->ia_maddr, memsize, 0, &memh)) {
283 		printf("%s: can't map shared memory\n",
284 		    sc->sc_dev.dv_xname);
285 		return;
286 	}
287 
288 	esc->sc_asict = asict;
289 	esc->sc_asich = asich;
290 
291 	sc->sc_regt = nict;
292 	sc->sc_regh = nich;
293 
294 	sc->sc_buft = memt;
295 	sc->sc_bufh = memh;
296 
297 	/* Interface is always enabled. */
298 	sc->sc_enabled = 1;
299 
300 	/* Registers are linear. */
301 	for (i = 0; i < 16; i++)
302 		sc->sc_reg_map[i] = i;
303 
304 	/* Now we can use the NIC_{GET,PUT}() macros. */
305 
306 	/*
307 	 * Reset NIC and ASIC.  Enable on-board transeiver throughout
308 	 * reset sequence since it will lock up if the cable isn't
309 	 * connected if we don't.
310 	 */
311 	bus_space_write_1(asict, asich, ELINK2_CR,
312 	    ELINK2_CR_RST | ELINK2_CR_XSEL);
313 
314 	/* Wait for a while, then un-reset it. */
315 	delay(50);
316 
317 	/*
318 	 * The 3Com ASIC defaults to rather strange settings for the CR
319 	 * after a reset.  It's important to set it again after the
320 	 * following write (this is done when we map the PROM below).
321 	 */
322 	bus_space_write_1(asict, asich, ELINK2_CR, ELINK2_CR_XSEL);
323 
324 	/* Wait a bit for the NIC to recover from the reset. */
325 	delay(5000);
326 
327 	/*
328 	 * Get the station address from on-board ROM.
329 	 *
330 	 * First, map Ethernet address PROM over the top of where the NIC
331 	 * registers normally appear.
332 	 */
333 	bus_space_write_1(asict, asich, ELINK2_CR,
334 	    ELINK2_CR_XSEL | ELINK2_CR_EALO);
335 
336 	for (i = 0; i < ETHER_ADDR_LEN; i++)
337 		sc->sc_arpcom.ac_enaddr[i] = NIC_GET(nict, nich, i);
338 
339 	/*
340 	 * Unmap PROM - select NIC registers.  The proper setting of the
341 	 * transciever is set in later in ec_init_card() via dp8390_init().
342 	 */
343 	bus_space_write_1(asict, asich, ELINK2_CR, ELINK2_CR_XSEL);
344 
345 	/* Determine if this is an 8-bit or 16-bit board. */
346 
347 	/* Select page 0 registers. */
348 	NIC_PUT(nict, nich, ED_P0_CR, ED_CR_RD2 | ED_CR_PAGE_0 | ED_CR_STP);
349 
350 	/*
351 	 * Attempt to clear WTS.  If it doesn't clear, then this is a
352 	 * 16-bit board.
353 	 */
354 	NIC_PUT(nict, nich, ED_P0_DCR, 0);
355 
356 	/* Select page 2 registers. */
357 	NIC_PUT(nict, nich, ED_P0_CR, ED_CR_RD2 | ED_CR_PAGE_2 | ED_CR_STP);
358 
359 	/* The 3c503 forces the WTS bit to a one if this is a 16-bit board. */
360 	if (NIC_GET(nict, nich, ED_P2_DCR) & ED_DCR_WTS)
361 		esc->sc_16bitp = 1;
362 	else
363 		esc->sc_16bitp = 0;
364 
365 	printf("%s: 3Com 3c503 Ethernet (%s-bit)",
366 	    sc->sc_dev.dv_xname, esc->sc_16bitp ? "16" : "8");
367 
368 	/* Select page 0 registers. */
369 	NIC_PUT(nict, nich, ED_P2_CR, ED_CR_RD2 | ED_CR_PAGE_0 | ED_CR_STP);
370 
371 	sc->cr_proto = ED_CR_RD2;
372 
373 	/*
374 	 * DCR gets:
375 	 *
376 	 *	FIFO threshold to 8, No auto-init Remote DMA,
377 	 *	byte order=80x86.
378 	 *
379 	 * 16-bit cards also get word-wide DMA transfers.
380 	 */
381 	sc->dcr_reg = ED_DCR_FT1 | ED_DCR_LS |
382 	    (esc->sc_16bitp ? ED_DCR_WTS : 0);
383 
384 	sc->test_mem = ec_fake_test_mem;
385 	sc->ring_copy = ec_ring_copy;
386 	sc->write_mbuf = ec_write_mbuf;
387 	sc->read_hdr = ec_read_hdr;
388 
389 	sc->sc_media_init = ec_media_init;
390 
391 	sc->sc_mediachange = ec_mediachange;
392 	sc->sc_mediastatus = ec_mediastatus;
393 
394 	sc->mem_start = 0;
395 	sc->mem_size = memsize;
396 
397 	/* Do generic parts of attach. */
398 	if (dp8390_config(sc)) {
399 		printf(": configuration failed\n");
400 		return;
401 	}
402 
403 	/*
404 	 * We need to override the way dp8390_config() set up our
405 	 * shared memory.
406 	 *
407 	 * We have an entire 8k window to put the transmit buffers on the
408 	 * 16-bit boards.  But since the 16bit 3c503's shared memory is only
409 	 * fast enough to overlap the loading of one full-size packet, trying
410 	 * to load more than 2 buffers can actually leave the transmitter idle
411 	 * during the load.  So 2 seems the best value.  (Although a mix of
412 	 * variable-sized packets might change this assumption.  Nonetheless,
413 	 * we optimize for linear transfers of same-size packets.)
414 	 */
415 	if (esc->sc_16bitp) {
416 		if (sc->sc_dev.dv_cfdata->cf_flags & DP8390_NO_MULTI_BUFFERING)
417 			sc->txb_cnt = 1;
418 		else
419 			sc->txb_cnt = 2;
420 
421 		sc->tx_page_start = ELINK2_TX_PAGE_OFFSET_16BIT;
422 		sc->rec_page_start = ELINK2_RX_PAGE_OFFSET_16BIT;
423 		sc->rec_page_stop = (memsize >> ED_PAGE_SHIFT) +
424 		    sc->rec_page_start;
425 		sc->mem_ring = sc->mem_start;
426 	} else {
427 		sc->txb_cnt = 1;
428 		sc->tx_page_start = ELINK2_TX_PAGE_OFFSET_8BIT;
429 		sc->rec_page_start = sc->tx_page_start + ED_TXBUF_SIZE;
430 		sc->rec_page_stop = (memsize >> ED_PAGE_SHIFT) +
431 		    sc->tx_page_start;
432 		sc->mem_ring = sc->mem_start +
433 		    (ED_TXBUF_SIZE << ED_PAGE_SHIFT);
434 	}
435 
436 	/*
437 	 * Initialize CA page start/stop registers.  Probably only needed
438 	 * if doing DMA, but what the Hell.
439 	 */
440 	bus_space_write_1(asict, asich, ELINK2_PSTR, sc->rec_page_start);
441 	bus_space_write_1(asict, asich, ELINK2_PSPR, sc->rec_page_stop);
442 
443 	/*
444 	 * Program the IRQ.
445 	 */
446 	switch (ia->ia_irq) {
447 	case 9:	tmp = ELINK2_IDCFR_IRQ2; break;
448 	case 3:	tmp = ELINK2_IDCFR_IRQ3; break;
449 	case 4:	tmp = ELINK2_IDCFR_IRQ4; break;
450 	case 5:	tmp = ELINK2_IDCFR_IRQ5; break;
451 		break;
452 
453 	case IRQUNK:
454 		printf("%s: wildcarded IRQ is not allowed\n",
455 		    sc->sc_dev.dv_xname);
456 		return;
457 
458 	default:
459 		printf("%s: invalid IRQ %d, must be 3, 4, 5, or 9\n",
460 		    sc->sc_dev.dv_xname, ia->ia_irq);
461 		return;
462 	}
463 
464 	bus_space_write_1(asict, asich, ELINK2_IDCFR, tmp);
465 
466 	/*
467 	 * Initialize the GA configuration register.  Set bank and enable
468 	 * shared memory.
469 	 */
470 	bus_space_write_1(asict, asich, ELINK2_GACFR,
471 	    ELINK2_GACFR_RSEL | ELINK2_GACFR_MBS0);
472 
473 	/*
474 	 * Intialize "Vector Pointer" registers.  These gawd-awful things
475 	 * are compared to 20 bits of the address on the ISA, and if they
476 	 * match, the shared memory is disabled.  We se them to 0xffff0...
477 	 * allegedly the reset vector.
478 	 */
479 	bus_space_write_1(asict, asich, ELINK2_VPTR2, 0xff);
480 	bus_space_write_1(asict, asich, ELINK2_VPTR1, 0xff);
481 	bus_space_write_1(asict, asich, ELINK2_VPTR0, 0x00);
482 
483 	/*
484 	 * Now run the real memory test.
485 	 */
486 	if (ec_test_mem(sc)) {
487 		printf("%s: memory test failed\n", sc->sc_dev.dv_xname);
488 		return;
489 	}
490 
491 	/* Establish interrupt handler. */
492 	esc->sc_ih = isa_intr_establish(ia->ia_ic, ia->ia_irq, IST_EDGE,
493 	    IPL_NET, dp8390_intr, sc, sc->sc_dev.dv_xname);
494 	if (esc->sc_ih == NULL)
495 		printf("%s: can't establish interrupt\n", sc->sc_dev.dv_xname);
496 }
497 
498 int
499 ec_fake_test_mem(struct dp8390_softc *sc)
500 {
501 	/*
502 	 * We have to do this after we initialize the GA, but we
503 	 * have to do that after calling dp8390_config(), which
504 	 * wants to test memory.  Put this noop here, and then
505 	 * actually test memory later.
506 	 */
507 	return (0);
508 }
509 
510 int
511 ec_test_mem(struct dp8390_softc *sc)
512 {
513 	struct ec_softc *esc = (struct ec_softc *)sc;
514 	bus_space_tag_t memt = sc->sc_buft;
515 	bus_space_handle_t memh = sc->sc_bufh;
516 	bus_size_t memsize = sc->mem_size;
517 	int i;
518 
519 	if (esc->sc_16bitp)
520 		bus_space_set_region_2(memt, memh, 0, 0, memsize >> 1);
521 	else
522 		bus_space_set_region_1(memt, memh, 0, 0, memsize);
523 
524 	if (esc->sc_16bitp) {
525 		for (i = 0; i < memsize; i += 2) {
526 			if (bus_space_read_2(memt, memh, i) != 0)
527 				goto fail;
528 		}
529 	} else {
530 		for (i = 0; i < memsize; i++) {
531 			if (bus_space_read_1(memt, memh, i) != 0)
532 				goto fail;
533 		}
534 	}
535 
536 	return (0);
537 
538  fail:
539 	printf("%s: failed to clear shared memory at offset 0x%x\n",
540 	    sc->sc_dev.dv_xname, i);
541 	return (1);
542 }
543 
544 /*
545  * Given a NIC memory source address and a host memory destination address,
546  * copy 'len' from NIC to host using shared memory.  The 'len' is rounded
547  * up to a word - ok as long as mbufs are word-sized.
548  */
549 __inline void
550 ec_readmem(struct ec_softc *esc, int from, u_int8_t *to, int len)
551 {
552 	bus_space_tag_t memt = esc->sc_dp8390.sc_buft;
553 	bus_space_handle_t memh = esc->sc_dp8390.sc_bufh;
554 
555 	if (len & 1)
556 		++len;
557 
558 	if (esc->sc_16bitp)
559 		bus_space_read_region_2(memt, memh, from, (u_int16_t *)to,
560 		    len >> 1);
561 	else
562 		bus_space_read_region_1(memt, memh, from, to, len);
563 }
564 
565 int
566 ec_write_mbuf(struct dp8390_softc *sc, struct mbuf *m, int buf)
567 {
568 	struct ec_softc *esc = (struct ec_softc *)sc;
569 	bus_space_tag_t asict = esc->sc_asict;
570 	bus_space_handle_t asich = esc->sc_asich;
571 	bus_space_tag_t memt = esc->sc_dp8390.sc_buft;
572 	bus_space_handle_t memh = esc->sc_dp8390.sc_bufh;
573 	u_int8_t *data, savebyte[2];
574 	int savelen, len, leftover;
575 #ifdef DIAGNOSTIC
576 	u_int8_t *lim;
577 #endif
578 
579 	savelen = m->m_pkthdr.len;
580 
581 	/*
582 	 * 8-bit boards are simple: we're already in the correct
583 	 * page, and no alignment tricks are necessary.
584 	 */
585 	if (esc->sc_16bitp == 0) {
586 		for (; m != NULL; buf += m->m_len, m = m->m_next)
587 			bus_space_write_region_1(memt, memh, buf,
588 			    mtod(m, u_int8_t *), m->m_len);
589 		return (savelen);
590 	}
591 
592 	/*
593 	 * If it's a 16-bit board, we have transmit buffers
594 	 * in a different page; switch to it.
595 	 */
596 	if (esc->sc_16bitp)
597 		bus_space_write_1(asict, asich, ELINK2_GACFR,
598 		    ELINK2_GACFR_RSEL);
599 
600 	/* Start out with no leftover data. */
601 	leftover = 0;
602 	savebyte[0] = savebyte[1] = 0;
603 
604 	for (; m != NULL; m = m->m_next) {
605 		len = m->m_len;
606 		if (len == 0)
607 			continue;
608 		data = mtod(m, u_int8_t *);
609 #ifdef DIAGNOSTIC
610 		lim = data + len;
611 #endif
612 		while (len > 0) {
613 			if (leftover) {
614 				/*
615 				 * Data left over (from mbuf or realignment).
616 				 * Buffer the next byte, and write it and
617 				 * the leftover data out.
618 				 */
619 				savebyte[1] = *data++;
620 				len--;
621 				bus_space_write_2(memt, memh, buf,
622 				    *(u_int16_t *)savebyte);
623 				buf += 2;
624 				leftover = 0;
625 			} else if (ALIGNED_POINTER(data, u_int16_t) == 0) {
626 				/*
627 				 * Unaligned data; buffer the next byte.
628 				 */
629 				savebyte[0] = *data++;
630 				len--;
631 				leftover = 1;
632 			} else {
633 				/*
634 				 * Aligned data; output contiguous words as
635 				 * much as we can, then buffer the remaining
636 				 * byte, if any.
637 				 */
638 				leftover = len & 1;
639 				len &= ~1;
640 				bus_space_write_region_2(memt, memh, buf,
641 				    (u_int16_t *)data, len >> 1);
642 				data += len;
643 				buf += len;
644 				if (leftover)
645 					savebyte[0] = *data++;
646 				len = 0;
647 			}
648 		}
649 		if (len < 0)
650 			panic("ec_write_mbuf: negative len");
651 #ifdef DIAGNOSTIC
652 		if (data != lim)
653 			panic("ec_write_mbuf: data != lim");
654 #endif
655 	}
656 	if (leftover) {
657 		savebyte[1] = 0;
658 		bus_space_write_2(memt, memh, buf, *(u_int16_t *)savebyte);
659 	}
660 
661 	/*
662 	 * Switch back to receive page.
663 	 */
664 	if (esc->sc_16bitp)
665 		bus_space_write_1(asict, asich, ELINK2_GACFR,
666 		    ELINK2_GACFR_RSEL | ELINK2_GACFR_MBS0);
667 
668 	return (savelen);
669 }
670 
671 int
672 ec_ring_copy(struct dp8390_softc *sc, int src, caddr_t dst,
673     u_short amount)
674 {
675 	struct ec_softc *esc = (struct ec_softc *)sc;
676 	u_short tmp_amount;
677 
678 	/* Does copy wrap to lower addr in ring buffer? */
679 	if (src + amount > sc->mem_end) {
680 		tmp_amount = sc->mem_end - src;
681 
682 		/* Copy amount up to end of NIC memory. */
683 		ec_readmem(esc, src, dst, tmp_amount);
684 
685 		amount -= tmp_amount;
686 		src = sc->mem_ring;
687 		dst += tmp_amount;
688 	}
689 
690 	ec_readmem(esc, src, dst, amount);
691 
692 	return (src + amount);
693 }
694 
695 void
696 ec_read_hdr(struct dp8390_softc *sc, int packet_ptr,
697     struct dp8390_ring *packet_hdrp)
698 {
699 	struct ec_softc *esc = (struct ec_softc *)sc;
700 
701 	ec_readmem(esc, packet_ptr, (u_int8_t *)packet_hdrp,
702 	    sizeof(struct dp8390_ring));
703 #if BYTE_ORDER == BIG_ENDIAN
704 	packet_hdrp->count = swap16(packet_hdrp->count);
705 #endif
706 }
707 
708 void
709 ec_media_init(struct dp8390_softc *sc)
710 {
711 	ifmedia_init(&sc->sc_media, 0, dp8390_mediachange, dp8390_mediastatus);
712 	ifmedia_add(&sc->sc_media, IFM_ETHER|IFM_10_2, 0, NULL);
713 	ifmedia_add(&sc->sc_media, IFM_ETHER|IFM_10_5, 0, NULL);
714 	ifmedia_set(&sc->sc_media, IFM_ETHER|IFM_10_2);
715 }
716 
717 int
718 ec_mediachange(struct dp8390_softc *sc)
719 {
720 	struct ec_softc *esc = (struct ec_softc *)sc;
721 	struct ifmedia *ifm = &sc->sc_media;
722 
723 	return (ec_set_media(esc, ifm->ifm_media));
724 }
725 
726 void
727 ec_mediastatus(struct dp8390_softc *sc, struct ifmediareq *ifmr)
728 {
729 	struct ifmedia *ifm = &sc->sc_media;
730 
731 	/*
732 	 * The currently selected media is always the active media.
733 	 */
734 	ifmr->ifm_active = ifm->ifm_cur->ifm_media;
735 }
736 
737 void
738 ec_init_card(struct dp8390_softc *sc)
739 {
740 	struct ec_softc *esc = (struct ec_softc *)sc;
741 	struct ifmedia *ifm = &sc->sc_media;
742 
743 	(void) ec_set_media(esc, ifm->ifm_cur->ifm_media);
744 }
745 
746 int
747 ec_set_media(struct ec_softc *esc, int media)
748 {
749 	u_int8_t new;
750 
751 	if (IFM_TYPE(media) != IFM_ETHER)
752 		return (EINVAL);
753 
754 	switch (IFM_SUBTYPE(media)) {
755 	case IFM_10_2:
756 		new = ELINK2_CR_XSEL;
757 		break;
758 
759 	case IFM_10_5:
760 		new = 0;
761 		break;
762 
763 	default:
764 		return (EINVAL);
765 	}
766 
767 	bus_space_write_1(esc->sc_asict, esc->sc_asich, ELINK2_CR, new);
768 	return (0);
769 }
770