xref: /freebsd/sys/dev/dpaa/if_dtsec.c (revision 667dd9eafa4d5352efdfcdc1a9e228c23fbc60f5)
1 /*-
2  * Copyright (c) 2011-2012 Semihalf.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24  * SUCH DAMAGE.
25  */
26 
27 #include <sys/param.h>
28 #include <sys/systm.h>
29 #include <sys/kernel.h>
30 #include <sys/module.h>
31 #include <sys/bus.h>
32 #include <sys/rman.h>
33 #include <sys/malloc.h>
34 #include <sys/mbuf.h>
35 #include <sys/socket.h>
36 #include <sys/sysctl.h>
37 #include <sys/sockio.h>
38 
39 #include <machine/bus.h>
40 #include <machine/resource.h>
41 
42 #include <net/ethernet.h>
43 #include <net/if.h>
44 #include <net/if_dl.h>
45 #include <net/if_media.h>
46 #include <net/if_types.h>
47 #include <net/if_arp.h>
48 
49 #include <dev/mii/mii.h>
50 #include <dev/mii/miivar.h>
51 #include <dev/ofw/ofw_bus.h>
52 #include <dev/ofw/ofw_bus_subr.h>
53 #include <dev/ofw/openfirm.h>
54 
55 #include "miibus_if.h"
56 
57 #include "dpaa_eth.h"
58 #include "fman.h"
59 #include "fman_port.h"
60 #include "if_dtsec.h"
61 
62 #include "fman_if.h"
63 #include "fman_port_if.h"
64 
65 #define	DTSEC_MIN_FRAME_SIZE	64
66 #define	DTSEC_MAX_FRAME_SIZE	9600
67 
68 #define	DTSEC_REG_MAXFRM	0x110
69 #define	DTSEC_REG_IGADDR(i)	(0x080 + 4 * (i))
70 #define	DTSEC_REG_GADDR(i)	(0x0a0 + 4 * (i))
71 
72 #define	DTSEC_ECNTRL		0x014
73 #define	  ECNTRL_R100M		  0x00000008
74 #define	DTSEC_TCTRL		0x040
75 #define	  TCTRL_GTS		  0x00000020
76 #define	DTSEC_RCTRL		0x050
77 #define	  RCTRL_CFA		  0x00008000
78 #define	  RCTRL_GHTX		  0x00000400
79 #define	  RCTRL_GRS		  0x00000020
80 #define	  RCTRL_MPROM		  0x00000008
81 #define	DTSEC_MACCFG1		0x100
82 #define	DTSEC_MACCFG2		0x104
83 #define	  MACCFG_IF_M		  0x00000300
84 #define	  MACCFG_IF_10_100	  0x00000100
85 #define	  MACCFG_IF_1G		  0x00000200
86 #define	  MACCFG_FULLDUPLEX	  0x00000001
87 #define	DTSEC_MACSTNADDR1	0x140
88 #define	DTSEC_MACSTNADDR2	0x144
89 
90 static void dtsec_if_init_locked(struct dtsec_softc *sc);
91 
92 /**
93  * @group FMan MAC routines.
94  * @{
95  */
96 
97 static int
98 dtsec_fm_mac_init(struct dtsec_softc *sc, uint8_t *mac)
99 {
100 	FMAN_GET_REVISION(device_get_parent(sc->sc_base.sc_dev), &sc->sc_base.sc_rev_major,
101 	    &sc->sc_base.sc_rev_minor);
102 
103 	if (FMAN_RESET_MAC(device_get_parent(sc->sc_base.sc_dev), sc->sc_base.sc_eth_id) != 0)
104 		return (ENXIO);
105 
106 	return (0);
107 }
108 /** @} */
109 
110 
111 /**
112  * @group IFnet routines.
113  * @{
114  */
115 static int
116 dtsec_set_mtu(struct dtsec_softc *sc, unsigned int mtu)
117 {
118 
119 	mtu += ETHER_HDR_LEN + ETHER_VLAN_ENCAP_LEN + ETHER_CRC_LEN;
120 
121 	DTSEC_LOCK_ASSERT(sc);
122 
123 	if (mtu >= DTSEC_MIN_FRAME_SIZE && mtu <= DTSEC_MAX_FRAME_SIZE) {
124 		bus_write_4(sc->sc_base.sc_mem, DTSEC_REG_MAXFRM, mtu);
125 		return (mtu);
126 	}
127 
128 	return (0);
129 }
130 
131 static u_int
132 dtsec_hash_maddr(void *arg, struct sockaddr_dl *sdl, u_int cnt)
133 {
134 	uint32_t h, *hashtable = arg;
135 
136 	h = (ether_crc32_be(LLADDR(sdl), ETHER_ADDR_LEN) >> 24) & 0xFF;
137 	hashtable[(h >> 5)] |= 1 << (0x1F - (h & 0x1F));
138 
139 	return (1);
140 }
141 
142 static void
143 dtsec_setup_multicast(struct dtsec_softc *sc)
144 {
145 	uint32_t hashtable[8] = {};
146 	int i;
147 
148 	if (if_getflags(sc->sc_base.sc_ifnet) & IFF_ALLMULTI) {
149 		for (i = 0; i < 8; i++)
150 			bus_write_4(sc->sc_base.sc_mem, DTSEC_REG_GADDR(i), 0xFFFFFFFF);
151 		bus_write_4(sc->sc_base.sc_mem, DTSEC_RCTRL,
152 		    bus_read_4(sc->sc_base.sc_mem, DTSEC_RCTRL) | RCTRL_MPROM);
153 
154 		return;
155 	}
156 	bus_write_4(sc->sc_base.sc_mem, DTSEC_RCTRL,
157 	    bus_read_4(sc->sc_base.sc_mem, DTSEC_RCTRL) & ~RCTRL_MPROM);
158 
159 	if_foreach_llmaddr(sc->sc_base.sc_ifnet, dtsec_hash_maddr, hashtable);
160 	for (i = 0; i < 8; i++)
161 		bus_write_4(sc->sc_base.sc_mem, DTSEC_REG_GADDR(i),
162 		    hashtable[i]);
163 }
164 
165 static void
166 dtsec_if_graceful_stop(struct dtsec_softc *sc)
167 {
168 	bus_write_4(sc->sc_base.sc_mem, DTSEC_RCTRL,
169 	    bus_read_4(sc->sc_base.sc_mem, DTSEC_RCTRL) | RCTRL_GRS);
170 	if (sc->sc_base.sc_rev_major == 2)
171 		DELAY(100);
172 	else
173 		DELAY(10);
174 
175 	bus_write_4(sc->sc_base.sc_mem, DTSEC_TCTRL,
176 	    bus_read_4(sc->sc_base.sc_mem, DTSEC_TCTRL) | TCTRL_GTS);
177 }
178 
179 static void
180 dtsec_if_graceful_start(struct dtsec_softc *sc)
181 {
182 	bus_write_4(sc->sc_base.sc_mem, DTSEC_RCTRL,
183 	    bus_read_4(sc->sc_base.sc_mem, DTSEC_RCTRL) & ~RCTRL_GRS);
184 	if (sc->sc_base.sc_rev_major == 2)
185 		DELAY(100);
186 	else
187 		DELAY(10);
188 
189 	bus_write_4(sc->sc_base.sc_mem, DTSEC_TCTRL,
190 	    bus_read_4(sc->sc_base.sc_mem, DTSEC_TCTRL) & ~TCTRL_GTS);
191 }
192 
193 static int
194 dtsec_if_enable_locked(struct dtsec_softc *sc)
195 {
196 	int error;
197 
198 	DTSEC_LOCK_ASSERT(sc);
199 
200 	dtsec_if_graceful_start(sc);
201 
202 	error = FMAN_PORT_ENABLE(sc->sc_base.sc_rx_port);
203 	if (error != 0)
204 		return (EIO);
205 
206 	error = FMAN_PORT_ENABLE(sc->sc_base.sc_tx_port);
207 	if (error != 0)
208 		return (EIO);
209 
210 	dtsec_setup_multicast(sc);
211 
212 	if_setdrvflagbits(sc->sc_base.sc_ifnet, IFF_DRV_RUNNING, 0);
213 
214 	/* Refresh link state */
215 	dtsec_miibus_statchg(sc->sc_base.sc_dev);
216 
217 	return (0);
218 }
219 
220 static int
221 dtsec_if_disable_locked(struct dtsec_softc *sc)
222 {
223 	int error;
224 
225 	DTSEC_LOCK_ASSERT(sc);
226 
227 	dtsec_if_graceful_stop(sc);
228 
229 	error = FMAN_PORT_DISABLE(sc->sc_base.sc_rx_port);
230 	if (error != 0)
231 		return (EIO);
232 
233 	error = FMAN_PORT_DISABLE(sc->sc_base.sc_tx_port);
234 	if (error != 0)
235 		return (EIO);
236 
237 	if_setdrvflagbits(sc->sc_base.sc_ifnet, 0, IFF_DRV_RUNNING);
238 
239 	return (0);
240 }
241 
242 static int
243 dtsec_if_ioctl(if_t ifp, u_long command, caddr_t data)
244 {
245 	struct dtsec_softc *sc;
246 	struct ifreq *ifr;
247 	int error;
248 
249 	sc = if_getsoftc(ifp);
250 	ifr = (struct ifreq *)data;
251 	error = 0;
252 
253 	/* Basic functionality to achieve media status reports */
254 	switch (command) {
255 	case SIOCSIFMTU:
256 		DTSEC_LOCK(sc);
257 		if (dtsec_set_mtu(sc, ifr->ifr_mtu))
258 			if_setmtu(ifp, ifr->ifr_mtu);
259 		else
260 			error = EINVAL;
261 		DTSEC_UNLOCK(sc);
262 		break;
263 	case SIOCSIFFLAGS:
264 		DTSEC_LOCK(sc);
265 
266 		if (if_getflags(ifp) & IFF_UP) {
267 			if (!(if_getdrvflags(ifp) & IFF_DRV_RUNNING))
268 				dtsec_if_init_locked(sc);
269 		} else
270 			error = dtsec_if_disable_locked(sc);
271 
272 		DTSEC_UNLOCK(sc);
273 		break;
274 
275 	case SIOCGIFMEDIA:
276 	case SIOCSIFMEDIA:
277 		error = ifmedia_ioctl(ifp, ifr, &sc->sc_base.sc_mii->mii_media,
278 		    command);
279 		break;
280 
281 	default:
282 		error = ether_ioctl(ifp, command, data);
283 	}
284 
285 	return (error);
286 }
287 
288 static void
289 dtsec_if_tick(void *arg)
290 {
291 	struct dtsec_softc *sc;
292 
293 	sc = arg;
294 
295 	/* TODO */
296 	DTSEC_LOCK(sc);
297 
298 	mii_tick(sc->sc_base.sc_mii);
299 	callout_reset(&sc->sc_base.sc_tick_callout, hz, dtsec_if_tick, sc);
300 
301 	DTSEC_UNLOCK(sc);
302 }
303 
304 static void
305 dtsec_if_deinit_locked(struct dtsec_softc *sc)
306 {
307 
308 	DTSEC_LOCK_ASSERT(sc);
309 
310 	DTSEC_UNLOCK(sc);
311 	callout_drain(&sc->sc_base.sc_tick_callout);
312 	DTSEC_LOCK(sc);
313 }
314 
315 static void
316 dtsec_if_set_macaddr(struct dtsec_softc *sc, const char *addr)
317 {
318 	uint32_t reg;
319 
320 	reg = (addr[5] << 24) | (addr[4] << 16) | (addr[3] << 8) | addr[2];
321 	bus_write_4(sc->sc_base.sc_mem, DTSEC_MACSTNADDR1, reg);
322 	reg = (addr[1] << 24) | (addr[0] << 16);
323 	bus_write_4(sc->sc_base.sc_mem, DTSEC_MACSTNADDR2, reg);
324 }
325 
326 static void
327 dtsec_if_init_locked(struct dtsec_softc *sc)
328 {
329 	int error;
330 	const char *macaddr;
331 
332 	DTSEC_LOCK_ASSERT(sc);
333 
334 	macaddr = if_getlladdr(sc->sc_base.sc_ifnet);
335 	dtsec_if_set_macaddr(sc, macaddr);
336 
337 	/* Start MII polling */
338 	if (sc->sc_base.sc_mii)
339 		callout_reset(&sc->sc_base.sc_tick_callout, hz,
340 		    dtsec_if_tick, sc);
341 
342 	if (if_getflags(sc->sc_base.sc_ifnet) & IFF_UP) {
343 		error = dtsec_if_enable_locked(sc);
344 		if (error != 0)
345 			goto err;
346 	} else {
347 		error = dtsec_if_disable_locked(sc);
348 		if (error != 0)
349 			goto err;
350 	}
351 
352 	return;
353 
354 err:
355 	dtsec_if_deinit_locked(sc);
356 	device_printf(sc->sc_base.sc_dev, "initialization error.\n");
357 	return;
358 }
359 
360 static void
361 dtsec_if_init(void *data)
362 {
363 	struct dtsec_softc *sc;
364 
365 	sc = data;
366 
367 	DTSEC_LOCK(sc);
368 	dtsec_if_init_locked(sc);
369 	DTSEC_UNLOCK(sc);
370 }
371 
372 static void
373 dtsec_if_start(if_t ifp)
374 {
375 	struct dtsec_softc *sc;
376 
377 	sc = if_getsoftc(ifp);
378 	DTSEC_LOCK(sc);
379 	dpaa_eth_if_start_locked(&sc->sc_base);
380 	DTSEC_UNLOCK(sc);
381 }
382 
383 static void
384 dtsec_if_watchdog(if_t ifp)
385 {
386 	/* TODO */
387 }
388 /** @} */
389 
390 
391 /**
392  * @group IFmedia routines.
393  * @{
394  */
395 static int
396 dtsec_ifmedia_upd(if_t ifp)
397 {
398 	struct dtsec_softc *sc = if_getsoftc(ifp);
399 
400 	DTSEC_LOCK(sc);
401 	mii_mediachg(sc->sc_base.sc_mii);
402 	DTSEC_UNLOCK(sc);
403 
404 	return (0);
405 }
406 
407 static void
408 dtsec_ifmedia_sts(if_t ifp, struct ifmediareq *ifmr)
409 {
410 	struct dtsec_softc *sc = if_getsoftc(ifp);
411 
412 	DTSEC_LOCK(sc);
413 
414 	mii_pollstat(sc->sc_base.sc_mii);
415 
416 	ifmr->ifm_active = sc->sc_base.sc_mii->mii_media_active;
417 	ifmr->ifm_status = sc->sc_base.sc_mii->mii_media_status;
418 
419 	DTSEC_UNLOCK(sc);
420 }
421 /** @} */
422 
423 
424 /**
425  * @group dTSEC bus interface.
426  * @{
427  */
428 
429 int
430 dtsec_attach(device_t dev)
431 {
432 	struct dtsec_softc *sc;
433 	cell_t ports[2];
434 	phandle_t node;
435 	int error;
436 	if_t ifp;
437 
438 	sc = device_get_softc(dev);
439 
440 	sc->sc_base.sc_dev = dev;
441 	node = ofw_bus_get_node(dev);
442 
443 	/* Init locks */
444 	mtx_init(&sc->sc_base.sc_lock, device_get_nameunit(dev),
445 	    "DTSEC Global Lock", MTX_DEF);
446 
447 	mtx_init(&sc->sc_base.sc_mii_lock, device_get_nameunit(dev),
448 	    "DTSEC MII Lock", MTX_DEF);
449 
450 	/* Init callouts */
451 	callout_init(&sc->sc_base.sc_tick_callout, CALLOUT_MPSAFE);
452 
453 	/* Create RX buffer pool */
454 	error = dpaa_eth_pool_rx_init(&sc->sc_base);
455 	if (error != 0)
456 		return (EIO);
457 
458 	/* Create RX frame queue range */
459 	error = dpaa_eth_fq_rx_init(&sc->sc_base);
460 	if (error != 0)
461 		return (EIO);
462 
463 	/* Create frame info pool */
464 	error = dpaa_eth_fi_pool_init(&sc->sc_base);
465 	if (error != 0)
466 		return (EIO);
467 
468 	/* Create TX frame queue range */
469 	error = dpaa_eth_fq_tx_init(&sc->sc_base);
470 	if (error != 0)
471 		return (EIO);
472 
473 	if (OF_getencprop(node, "fsl,fman-ports", ports, sizeof(ports)) < 0) {
474 		device_printf(dev, "missing ports in device tree\n");
475 		return (ENXIO);
476 	}
477 	/* Init FMan MAC module. */
478 	error = dtsec_fm_mac_init(sc, sc->sc_base.sc_mac_addr);
479 	if (error != 0) {
480 		dtsec_detach(dev);
481 		return (ENXIO);
482 	}
483 
484 	sc->sc_base.sc_rx_port = OF_device_from_xref(ports[0]);
485 	sc->sc_base.sc_tx_port = OF_device_from_xref(ports[1]);
486 	dpaa_eth_fm_port_rx_init(&sc->sc_base);
487 	dpaa_eth_fm_port_tx_init(&sc->sc_base);
488 
489 	if (sc->sc_base.sc_rx_port == NULL || sc->sc_base.sc_tx_port == NULL) {
490 		device_printf(dev, "invalid ports");
491 		dtsec_detach(dev);
492 		return (ENXIO);
493 	}
494 
495 	/* Create network interface for upper layers */
496 	ifp = sc->sc_base.sc_ifnet = if_alloc(IFT_ETHER);
497 	if_setsoftc(ifp, sc);
498 
499 	if_setflags(ifp, IFF_SIMPLEX | IFF_BROADCAST | IFF_MULTICAST);
500 	if_setinitfn(ifp, dtsec_if_init);
501 	if_setstartfn(ifp, dtsec_if_start);
502 	if_setioctlfn(ifp, dtsec_if_ioctl);
503 	if_setsendqlen(ifp, IFQ_MAXLEN);
504 
505 	if (sc->sc_base.sc_phy_addr >= 0)
506 		if_initname(ifp, device_get_name(sc->sc_base.sc_dev),
507 		    device_get_unit(sc->sc_base.sc_dev));
508 	else
509 		if_initname(ifp, "dtsec_phy",
510 		    device_get_unit(sc->sc_base.sc_dev));
511 
512 	/* TODO */
513 #if 0
514 	if_setsendqlen(ifp, TSEC_TX_NUM_DESC - 1);
515 	if_setsendqready(ifp);
516 #endif
517 
518 	if_setcapabilities(ifp, IFCAP_JUMBO_MTU | IFCAP_VLAN_MTU);
519 	if_setcapenable(ifp, if_getcapabilities(ifp));
520 
521 	/* Attach PHY(s) */
522 	error = mii_attach(sc->sc_base.sc_dev, &sc->sc_base.sc_mii_dev,
523 	    ifp, dtsec_ifmedia_upd, dtsec_ifmedia_sts, BMSR_DEFCAPMASK,
524 	    sc->sc_base.sc_phy_addr, MII_OFFSET_ANY, 0);
525 	if (error) {
526 		device_printf(sc->sc_base.sc_dev,
527 		    "attaching PHYs failed: %d\n", error);
528 		dtsec_detach(sc->sc_base.sc_dev);
529 		return (error);
530 	}
531 
532 	/* Attach to stack */
533 	ether_ifattach(ifp, sc->sc_base.sc_mac_addr);
534 
535 	return (0);
536 }
537 
538 int
539 dtsec_detach(device_t dev)
540 {
541 	struct dtsec_softc *sc;
542 	if_t ifp;
543 
544 	sc = device_get_softc(dev);
545 	ifp = sc->sc_base.sc_ifnet;
546 
547 	if (device_is_attached(dev)) {
548 		ether_ifdetach(ifp);
549 		/* Shutdown interface */
550 		DTSEC_LOCK(sc);
551 		dtsec_if_deinit_locked(sc);
552 		DTSEC_UNLOCK(sc);
553 	}
554 
555 	if (sc->sc_base.sc_ifnet) {
556 		if_free(sc->sc_base.sc_ifnet);
557 		sc->sc_base.sc_ifnet = NULL;
558 	}
559 
560 	/* Free RX/TX FQRs */
561 	dpaa_eth_fq_rx_free(&sc->sc_base);
562 	dpaa_eth_fq_tx_free(&sc->sc_base);
563 
564 	/* Free frame info pool */
565 	dpaa_eth_fi_pool_free(&sc->sc_base);
566 
567 	/* Free RX buffer pool */
568 	dpaa_eth_pool_rx_free(&sc->sc_base);
569 
570 	/* Destroy lock */
571 	mtx_destroy(&sc->sc_base.sc_lock);
572 
573 	return (0);
574 }
575 
576 int
577 dtsec_suspend(device_t dev)
578 {
579 
580 	return (0);
581 }
582 
583 int
584 dtsec_resume(device_t dev)
585 {
586 
587 	return (0);
588 }
589 
590 int
591 dtsec_shutdown(device_t dev)
592 {
593 
594 	return (0);
595 }
596 /** @} */
597 
598 
599 /**
600  * @group MII bus interface.
601  * @{
602  */
603 int
604 dtsec_miibus_readreg(device_t dev, int phy, int reg)
605 {
606 	struct dtsec_softc *sc;
607 
608 	sc = device_get_softc(dev);
609 
610 	return (MIIBUS_READREG(sc->sc_base.sc_mdio, phy, reg));
611 }
612 
613 int
614 dtsec_miibus_writereg(device_t dev, int phy, int reg, int value)
615 {
616 
617 	struct dtsec_softc *sc;
618 
619 	sc = device_get_softc(dev);
620 
621 	return (MIIBUS_WRITEREG(sc->sc_base.sc_mdio, phy, reg, value));
622 }
623 
624 void
625 dtsec_miibus_statchg(device_t dev)
626 {
627 	struct dtsec_softc *sc;
628 	uint32_t reg;
629 	bool duplex;
630 	int speed;
631 
632 	sc = device_get_softc(dev);
633 
634 	DTSEC_LOCK_ASSERT(sc);
635 
636 	duplex = ((sc->sc_base.sc_mii->mii_media_active & IFM_GMASK) == IFM_FDX);
637 
638 	switch (IFM_SUBTYPE(sc->sc_base.sc_mii->mii_media_active)) {
639 	case IFM_1000_T:
640 	case IFM_1000_SX:
641 		if (!duplex) {
642 			device_printf(sc->sc_base.sc_dev,
643 			    "Only full-duplex supported for 1Gbps speeds");
644 			return;
645 		}
646 		speed = MACCFG_IF_1G;
647 		break;
648 
649 	default:
650 		speed = MACCFG_IF_10_100;
651 	}
652 
653 	reg = bus_read_4(sc->sc_base.sc_mem, DTSEC_MACCFG2);
654 	reg &= ~(MACCFG_IF_M | MACCFG_FULLDUPLEX);
655 
656 	if (duplex)
657 		reg |= MACCFG_FULLDUPLEX;
658 	reg |= speed;
659 	bus_write_4(sc->sc_base.sc_mem, DTSEC_MACCFG2, reg);
660 
661 	reg = bus_read_4(sc->sc_base.sc_mem, DTSEC_ECNTRL) & ~ECNTRL_R100M;
662 	if (IFM_SUBTYPE(sc->sc_base.sc_mii->mii_media_active) == IFM_100_TX)
663 		reg |= ECNTRL_R100M;
664 	bus_write_4(sc->sc_base.sc_mem, DTSEC_ECNTRL, reg);
665 }
666 /** @} */
667