xref: /freebsd/sys/dev/dpaa/if_memac.c (revision d59c7ea2701fe7b73b32eef49a7c712ef38de5a0)
1 /*
2  * Copyright (c) 2026 Justin Hibbits
3  *
4  * SPDX-License-Identifier: BSD-2-Clause
5  */
6 
7 #include <sys/param.h>
8 #include <sys/systm.h>
9 #include <sys/bus.h>
10 #include <sys/kernel.h>
11 #include <sys/malloc.h>
12 #include <sys/mbuf.h>
13 #include <sys/module.h>
14 #include <sys/rman.h>
15 #include <sys/socket.h>
16 #include <sys/sysctl.h>
17 #include <sys/sockio.h>
18 
19 #include <machine/bus.h>
20 #include <machine/resource.h>
21 
22 #include <net/ethernet.h>
23 #include <net/if.h>
24 #include <net/if_dl.h>
25 #include <net/if_media.h>
26 #include <net/if_types.h>
27 #include <net/if_arp.h>
28 
29 #include <dev/mii/mii.h>
30 #include <dev/mii/miivar.h>
31 #include <dev/ofw/ofw_bus.h>
32 #include <dev/ofw/ofw_bus_subr.h>
33 #include <dev/ofw/openfirm.h>
34 
35 #include "miibus_if.h"
36 
37 #include "dpaa_eth.h"
38 #include "fman.h"
39 #include "fman_port.h"
40 #include "if_memac.h"
41 
42 #include "fman_if.h"
43 #include "fman_port_if.h"
44 
45 #define	MEMAC_MIN_FRAME_SIZE	64
46 #define	MEMAC_MAX_FRAME_SIZE	32736
47 
48 #define	MEMAC_COMMAND_CONFIG		0x008
49 #define	  COMMAND_CONFIG_RXSTP		  0x20000000
50 #define	  COMMAND_CONFIG_NO_LEN_CHK	  0x00020000
51 #define	  COMMAND_CONFIG_SWR		  0x00001000
52 #define	  COMMAND_CONFIG_TXP		  0x00000800
53 #define	  COMMAND_CONFIG_CRC		  0x00000040
54 #define	  COMMAND_CONFIG_PROMISC	  0x00000010
55 #define	  COMMAND_CONFIG_RX_EN		  0x00000002
56 #define	  COMMAND_CONFIG_TX_EN		  0x00000001
57 #define	MEMAC_MAC_ADDR_0		0x00c
58 #define	MEMAC_MAC_ADDR_1		0x010
59 #define	MEMAC_REG_MAXFRM		0x14
60 #define	MEMAC_REG_TX_FIFO_SECTIONS	0x020
61 #define	  TX_FIFO_SECTIONS_TX_EMPTY_M	  0xffff0000
62 #define	  TX_FIFO_SECTIONS_TX_EMPTY_S	  16
63 #define	  TX_FIFO_SECTIONS_TX_AVAIL_M	  0x0000ffff
64 
65 #define	HASHTABLE_CTRL		0x02c
66 #define	  CTRL_MCAST		  0x00000100
67 #define	  CTRL_HASH_ADDR_M	  0x0000003f
68 #define	  HASHTABLE_SIZE	  64
69 #define	MEMAC_IEVENT		0x040
70 #define	  IEVENT_RX_EMPTY	  0x00000040
71 #define	  IEVENT_TX_EMPTY	  0x00000020
72 #define	MEMAC_CL01_PAUSE_QUANTA	0x054
73 #define	MEMAC_IF_MODE		0x300
74 #define	  IF_MODE_ENA		  0x00008000
75 #define	  IF_MODE_SSP_M		  0x00006000
76 #define	  IF_MODE_SSP_100MB	  0x00000000
77 #define	  IF_MODE_SSP_10MB	  0x00002000
78 #define	  IF_MODE_SSP_1GB	  0x00004000
79 #define	  IF_MODE_SFD		  0x00001000
80 #define	  IF_MODE_MSG		  0x00000200
81 #define	  IF_MODE_HG		  0x00000100
82 #define	  IF_MODE_HD		  0x00000040
83 #define	  IF_MODE_RLP		  0x00000020
84 #define	  IF_MODE_RG		  0x00000004
85 #define	  IF_MODE_IFMODE_M	  0x00000003
86 #define	  IF_MODE_IFMODE_XGMII	  0x00000000
87 #define	  IF_MODE_IFMODE_MII	  0x00000001
88 #define	  IF_MODE_IFMODE_GMII	  0x00000002
89 
90 #define	DEFAULT_PAUSE_QUANTA	0xf000
91 
92 
93 /**
94  * @group FMan MAC routines.
95  * @{
96  */
97 #define	MEMAC_MAC_EXCEPTIONS_END	(-1)
98 
99 static void memac_if_init_locked(struct memac_softc *sc);
100 
101 static int
102 memac_fm_mac_init(struct memac_softc *sc, uint8_t *mac)
103 {
104 	uint32_t reg;
105 
106 	FMAN_GET_REVISION(device_get_parent(sc->sc_base.sc_dev), &sc->sc_base.sc_rev_major,
107 	    &sc->sc_base.sc_rev_minor);
108 
109 	if (FMAN_RESET_MAC(device_get_parent(sc->sc_base.sc_dev), sc->sc_base.sc_eth_id) != 0)
110 		return (ENXIO);
111 
112 	reg = bus_read_4(sc->sc_base.sc_mem, MEMAC_COMMAND_CONFIG);
113 	reg |= COMMAND_CONFIG_SWR;
114 	bus_write_4(sc->sc_base.sc_mem, MEMAC_COMMAND_CONFIG, reg);
115 
116 	while (bus_read_4(sc->sc_base.sc_mem, MEMAC_COMMAND_CONFIG) & COMMAND_CONFIG_SWR)
117 		;
118 
119 	/* TODO: TX_FIFO_SECTIONS */
120 	/* TODO: CL01 pause quantum */
121 	bus_write_4(sc->sc_base.sc_mem, MEMAC_COMMAND_CONFIG,
122 	    COMMAND_CONFIG_NO_LEN_CHK | COMMAND_CONFIG_TXP | COMMAND_CONFIG_CRC);
123 
124 	reg = bus_read_4(sc->sc_base.sc_mem, MEMAC_IF_MODE);
125 	reg &= ~(IF_MODE_IFMODE_M | IF_MODE_RG);
126 	switch (sc->sc_base.sc_mac_enet_mode) {
127 	case MII_CONTYPE_RGMII:
128 		reg |= IF_MODE_RG;
129 		/* FALLTHROUGH */
130 	case MII_CONTYPE_GMII:
131 	case MII_CONTYPE_SGMII:
132 	case MII_CONTYPE_QSGMII:
133 		reg |= IF_MODE_IFMODE_GMII;
134 		break;
135 	case MII_CONTYPE_RMII:
136 		reg |= IF_MODE_RG;
137 		/* FALLTHROUGH */
138 	case MII_CONTYPE_MII:
139 		reg |= IF_MODE_IFMODE_MII;
140 		break;
141 	}
142 
143 	bus_write_4(sc->sc_base.sc_mem, MEMAC_IF_MODE, reg);
144 
145 	return (0);
146 }
147 /** @} */
148 
149 
150 /**
151  * @group IFnet routines.
152  * @{
153  */
154 static int
155 memac_set_mtu(struct memac_softc *sc, unsigned int mtu)
156 {
157 
158 	mtu += ETHER_HDR_LEN + ETHER_VLAN_ENCAP_LEN + ETHER_CRC_LEN;
159 
160 	MEMAC_LOCK_ASSERT(sc);
161 
162 	if (mtu >= MEMAC_MIN_FRAME_SIZE && mtu <= MEMAC_MAX_FRAME_SIZE) {
163 		bus_write_4(sc->sc_base.sc_mem, MEMAC_REG_MAXFRM, mtu);
164 		return (mtu);
165 	}
166 
167 	return (0);
168 }
169 
170 static u_int
171 memac_hash_maddr(void *arg, struct sockaddr_dl *sdl, u_int cnt)
172 {
173 	struct memac_softc *sc = arg;
174 	uint8_t *addr = LLADDR(sdl);
175 	uint32_t hash = 0;
176 	uint8_t a, h;
177 
178 	/* Hash is 6 bits, composed if [XOR{47:40},XOR{39:32},....] */
179 	for (int i = 0; i < 6; i++) {
180 		a = addr[i];
181 		h = 0;
182 		for (int j = 0; j < 8; j++, a >>= 1) {
183 			h ^= (a & 0x1);
184 		}
185 		hash |= (h << i);
186 	}
187 	bus_write_4(sc->sc_base.sc_mem, HASHTABLE_CTRL, hash | CTRL_MCAST);
188 
189 	return (1);
190 }
191 
192 static void
193 memac_setup_multicast(struct memac_softc *sc)
194 {
195 
196 	if (if_getflags(sc->sc_base.sc_ifnet) & IFF_ALLMULTI) {
197 		for (int i = 0; i < HASHTABLE_SIZE; i++)
198 			bus_write_4(sc->sc_base.sc_mem,
199 			    HASHTABLE_CTRL, CTRL_MCAST | i);
200 	} else {
201 		/* Clear the hash table */
202 		for (int i = 0; i < HASHTABLE_SIZE; i++)
203 			bus_write_4(sc->sc_base.sc_mem,
204 			    HASHTABLE_CTRL, i);
205 	}
206 
207 	if_foreach_llmaddr(sc->sc_base.sc_ifnet, memac_hash_maddr, sc);
208 }
209 
210 static void
211 memac_setup_promisc(struct memac_softc *sc)
212 {
213 	uint32_t reg;
214 
215 	reg = bus_read_4(sc->sc_base.sc_mem, MEMAC_COMMAND_CONFIG);
216 	reg &= ~COMMAND_CONFIG_PROMISC;
217 
218 	if ((if_getflags(sc->sc_base.sc_ifnet) & IFF_PROMISC) != 0)
219 		bus_write_4(sc->sc_base.sc_mem, MEMAC_COMMAND_CONFIG,
220 		    reg | COMMAND_CONFIG_PROMISC);
221 }
222 
223 static void
224 memac_if_graceful_stop(struct memac_softc *sc)
225 {
226 	struct resource *regs = sc->sc_base.sc_mem;
227 	uint32_t reg;
228 
229 	reg = bus_read_4(regs, MEMAC_COMMAND_CONFIG);
230 	reg |= COMMAND_CONFIG_RXSTP;
231 
232 	bus_write_4(regs, MEMAC_COMMAND_CONFIG, reg);
233 	while ((bus_read_4(regs, MEMAC_IEVENT) & IEVENT_RX_EMPTY) == 0)
234 		;
235 	reg &= COMMAND_CONFIG_RX_EN;
236 	bus_write_4(regs, MEMAC_COMMAND_CONFIG, reg);
237 
238 	while ((bus_read_4(regs, MEMAC_IEVENT) & IEVENT_TX_EMPTY) == 0)
239 		;
240 	bus_write_4(regs, MEMAC_COMMAND_CONFIG, reg & ~COMMAND_CONFIG_TX_EN);
241 }
242 
243 static void
244 memac_mac_enable(struct memac_softc *sc)
245 {
246 	uint32_t reg = bus_read_4(sc->sc_base.sc_mem, MEMAC_COMMAND_CONFIG);
247 
248 	reg |= (COMMAND_CONFIG_RX_EN | COMMAND_CONFIG_TX_EN);
249 
250 	bus_write_4(sc->sc_base.sc_mem, MEMAC_COMMAND_CONFIG, reg);
251 }
252 
253 static int
254 memac_if_enable_locked(struct memac_softc *sc)
255 {
256 	int error;
257 
258 	MEMAC_LOCK_ASSERT(sc);
259 
260 	memac_set_mtu(sc, if_getmtu(sc->sc_base.sc_ifnet));
261 	memac_mac_enable(sc);
262 
263 	error = FMAN_PORT_ENABLE(sc->sc_base.sc_rx_port);
264 	if (error != 0)
265 		return (EIO);
266 
267 	error = FMAN_PORT_ENABLE(sc->sc_base.sc_tx_port);
268 	if (error != 0)
269 		return (EIO);
270 
271 	bus_write_4(sc->sc_base.sc_mem, MEMAC_IEVENT, 0);
272 	memac_setup_multicast(sc);
273 	memac_setup_promisc(sc);
274 
275 	if_setdrvflagbits(sc->sc_base.sc_ifnet, IFF_DRV_RUNNING, 0);
276 
277 	/* Refresh link state */
278 	memac_miibus_statchg(sc->sc_base.sc_dev);
279 
280 	return (0);
281 }
282 
283 static int
284 memac_if_disable_locked(struct memac_softc *sc)
285 {
286 	int error;
287 
288 	MEMAC_LOCK_ASSERT(sc);
289 
290 	error = FMAN_PORT_DISABLE(sc->sc_base.sc_tx_port);
291 	if (error != 0)
292 		return (EIO);
293 
294 	memac_if_graceful_stop(sc);
295 
296 	error = FMAN_PORT_DISABLE(sc->sc_base.sc_rx_port);
297 	if (error != 0)
298 		return (EIO);
299 
300 	if_setdrvflagbits(sc->sc_base.sc_ifnet, 0, IFF_DRV_RUNNING);
301 
302 	return (0);
303 }
304 
305 static int
306 memac_if_ioctl(if_t ifp, u_long command, caddr_t data)
307 {
308 	struct memac_softc *sc;
309 	struct ifreq *ifr;
310 	uint32_t changed;
311 	int error;
312 
313 	sc = if_getsoftc(ifp);
314 	ifr = (struct ifreq *)data;
315 	error = 0;
316 
317 	/* Basic functionality to achieve media status reports */
318 	switch (command) {
319 	case SIOCSIFMTU:
320 		MEMAC_LOCK(sc);
321 		if (memac_set_mtu(sc, ifr->ifr_mtu))
322 			if_setmtu(ifp, ifr->ifr_mtu);
323 		else
324 			error = EINVAL;
325 		MEMAC_UNLOCK(sc);
326 		break;
327 	case SIOCSIFFLAGS:
328 		MEMAC_LOCK(sc);
329 		if (if_getflags(ifp) & IFF_UP) {
330 			if (!(if_getdrvflags(ifp) & IFF_DRV_RUNNING))
331 				memac_if_init_locked(sc);
332 		} else if (if_getdrvflags(ifp) & IFF_DRV_RUNNING)
333 			error = memac_if_disable_locked(sc);
334 
335 		MEMAC_UNLOCK(sc);
336 		break;
337 
338 	case SIOCADDMULTI:
339 	case SIOCDELMULTI:
340 		if (if_getflags(sc->sc_base.sc_ifnet) & IFF_UP) {
341 			MEMAC_LOCK(sc);
342 			memac_setup_multicast(sc);
343 			MEMAC_UNLOCK(sc);
344 		}
345 		break;
346 
347 	case SIOCSIFCAP:
348 		changed = if_getcapenable(ifp) ^ ifr->ifr_reqcap;
349 		if ((changed & (IFCAP_RXCSUM | IFCAP_RXCSUM_IPV6)) != 0)
350 			if_togglecapenable(ifp,
351 			    IFCAP_RXCSUM | IFCAP_RXCSUM_IPV6);
352 		if ((changed & (IFCAP_TXCSUM | IFCAP_TXCSUM_IPV6)) != 0) {
353 			if_togglecapenable(ifp,
354 			    IFCAP_TXCSUM | IFCAP_TXCSUM_IPV6);
355 			if_togglehwassist(ifp, DPAA_CSUM_TX_OFFLOAD);
356 		}
357 		break;
358 
359 	case SIOCGIFMEDIA:
360 	case SIOCSIFMEDIA:
361 		error = ifmedia_ioctl(ifp, ifr, &sc->sc_base.sc_mii->mii_media,
362 		    command);
363 		break;
364 
365 	default:
366 		error = ether_ioctl(ifp, command, data);
367 	}
368 
369 	return (error);
370 }
371 
372 static void
373 memac_if_tick(void *arg)
374 {
375 	struct memac_softc *sc;
376 
377 	sc = arg;
378 
379 	/* TODO */
380 	MEMAC_LOCK(sc);
381 
382 	mii_tick(sc->sc_base.sc_mii);
383 	callout_reset(&sc->sc_base.sc_tick_callout, hz, memac_if_tick, sc);
384 
385 	MEMAC_UNLOCK(sc);
386 }
387 
388 static void
389 memac_if_deinit_locked(struct memac_softc *sc)
390 {
391 
392 	MEMAC_LOCK_ASSERT(sc);
393 
394 	MEMAC_UNLOCK(sc);
395 	callout_drain(&sc->sc_base.sc_tick_callout);
396 	MEMAC_LOCK(sc);
397 }
398 
399 static void
400 memac_if_set_macaddr(struct memac_softc *sc, const char *addr)
401 {
402 	uint32_t reg;
403 
404 	reg = (addr[3] << 24) | (addr[2] << 16) | (addr[1] << 8) | addr[0];
405 	bus_write_4(sc->sc_base.sc_mem, MEMAC_MAC_ADDR_0, reg);
406 	reg = (addr[5] << 8) | (addr[4]);
407 	bus_write_4(sc->sc_base.sc_mem, MEMAC_MAC_ADDR_1, reg);
408 }
409 
410 static void
411 memac_if_init_locked(struct memac_softc *sc)
412 {
413 	int error;
414 	const char *macaddr;
415 
416 	MEMAC_LOCK_ASSERT(sc);
417 
418 	macaddr = if_getlladdr(sc->sc_base.sc_ifnet);
419 	memac_if_set_macaddr(sc, macaddr);
420 
421 	/* Start MII polling */
422 	if (sc->sc_base.sc_mii)
423 		callout_reset(&sc->sc_base.sc_tick_callout, hz,
424 		    memac_if_tick, sc);
425 
426 	if (if_getflags(sc->sc_base.sc_ifnet) & IFF_UP) {
427 		error = memac_if_enable_locked(sc);
428 		if (error != 0)
429 			goto err;
430 	} else {
431 		error = memac_if_disable_locked(sc);
432 		if (error != 0)
433 			goto err;
434 	}
435 
436 	if_link_state_change(sc->sc_base.sc_ifnet, LINK_STATE_UP);
437 
438 	bus_write_4(sc->sc_base.sc_mem, MEMAC_CL01_PAUSE_QUANTA,
439 	    DEFAULT_PAUSE_QUANTA);
440 
441 	return;
442 
443 err:
444 	memac_if_deinit_locked(sc);
445 	device_printf(sc->sc_base.sc_dev, "initialization error.\n");
446 	return;
447 }
448 
449 static void
450 memac_if_init(void *data)
451 {
452 	struct memac_softc *sc;
453 
454 	sc = data;
455 
456 	MEMAC_LOCK(sc);
457 	memac_if_init_locked(sc);
458 	MEMAC_UNLOCK(sc);
459 }
460 
461 static void
462 memac_if_start(if_t ifp)
463 {
464 	struct memac_softc *sc;
465 
466 	sc = if_getsoftc(ifp);
467 	MEMAC_LOCK(sc);
468 	dpaa_eth_if_start_locked(&sc->sc_base);
469 	MEMAC_UNLOCK(sc);
470 }
471 
472 static void
473 memac_if_watchdog(if_t ifp)
474 {
475 	/* TODO */
476 }
477 /** @} */
478 
479 
480 /**
481  * @group IFmedia routines.
482  * @{
483  */
484 static int
485 memac_ifmedia_upd(if_t ifp)
486 {
487 	struct memac_softc *sc = if_getsoftc(ifp);
488 
489 	return (0);
490 	MEMAC_LOCK(sc);
491 	mii_mediachg(sc->sc_base.sc_mii);
492 	MEMAC_UNLOCK(sc);
493 
494 	return (0);
495 }
496 
497 static void
498 memac_ifmedia_fixed_sts(if_t ifp, struct ifmediareq *ifmr)
499 {
500 	struct memac_softc *sc = if_getsoftc(ifp);
501 
502 	MEMAC_LOCK(sc);
503 	ifmr->ifm_count = 1;
504 	ifmr->ifm_mask = 0;
505 	ifmr->ifm_status = IFM_AVALID | IFM_ACTIVE;
506 	ifmr->ifm_current = ifmr->ifm_active =
507 	    sc->sc_base.sc_mii->mii_media.ifm_cur->ifm_media;
508 	ifmr->ifm_active = ifmr->ifm_current;
509 
510 	/*
511 	 * In non-PHY usecases, we need to signal link state up, otherwise
512 	 * certain things requiring a link event (e.g async DHCP client) from
513 	 * devd do not happen.
514 	 */
515 	if (if_getlinkstate(ifp) == LINK_STATE_UNKNOWN) {
516 		if_link_state_change(ifp, LINK_STATE_UP);
517 	}
518 
519 	/* We assume the link is static, as in a peer switch. */
520 
521 	MEMAC_UNLOCK(sc);
522 
523 	return;
524 }
525 
526 static void
527 memac_ifmedia_sts(if_t ifp, struct ifmediareq *ifmr)
528 {
529 	struct memac_softc *sc = if_getsoftc(ifp);
530 
531 	MEMAC_LOCK(sc);
532 
533 	mii_pollstat(sc->sc_base.sc_mii);
534 
535 	ifmr->ifm_active = sc->sc_base.sc_mii->mii_media_active;
536 	ifmr->ifm_status = sc->sc_base.sc_mii->mii_media_status;
537 
538 	MEMAC_UNLOCK(sc);
539 }
540 /** @} */
541 
542 
543 /**
544  * @group dTSEC bus interface.
545  * @{
546  */
547 
548 int
549 memac_attach(device_t dev)
550 {
551 	struct memac_softc *sc;
552 	int error;
553 	if_t ifp;
554 
555 	sc = device_get_softc(dev);
556 
557 	sc->sc_base.sc_dev = dev;
558 
559 	/* Init locks */
560 	mtx_init(&sc->sc_base.sc_lock, device_get_nameunit(dev),
561 	    "mEMAC Global Lock", MTX_DEF);
562 
563 	mtx_init(&sc->sc_base.sc_mii_lock, device_get_nameunit(dev),
564 	    "mEMAC MII Lock", MTX_DEF);
565 
566 	/* Init callouts */
567 	callout_init(&sc->sc_base.sc_tick_callout, CALLOUT_MPSAFE);
568 
569 	/* Create RX buffer pool */
570 	error = dpaa_eth_pool_rx_init(&sc->sc_base);
571 	if (error != 0)
572 		return (EIO);
573 
574 	/* Create RX frame queue range */
575 	error = dpaa_eth_fq_rx_init(&sc->sc_base);
576 	if (error != 0)
577 		return (EIO);
578 
579 	/* Create frame info pool */
580 	error = dpaa_eth_fi_pool_init(&sc->sc_base);
581 	if (error != 0)
582 		return (EIO);
583 
584 	/* Create TX frame queue range */
585 	error = dpaa_eth_fq_tx_init(&sc->sc_base);
586 	if (error != 0)
587 		return (EIO);
588 
589 	/* Init FMan MAC module. */
590 	error = memac_fm_mac_init(sc, sc->sc_base.sc_mac_addr);
591 	if (error != 0) {
592 		memac_detach(dev);
593 		return (ENXIO);
594 	}
595 
596 	dpaa_eth_fm_port_rx_init(&sc->sc_base);
597 	dpaa_eth_fm_port_tx_init(&sc->sc_base);
598 
599 	/* Create network interface for upper layers */
600 	ifp = sc->sc_base.sc_ifnet = if_alloc(IFT_ETHER);
601 	if_setsoftc(ifp, sc);
602 
603 	if_setflags(ifp, IFF_SIMPLEX | IFF_BROADCAST | IFF_MULTICAST);
604 	if_setinitfn(ifp, memac_if_init);
605 	if_setstartfn(ifp, memac_if_start);
606 	if_setioctlfn(ifp, memac_if_ioctl);
607 	if_setsendqlen(ifp, IFQ_MAXLEN);
608 	if_setsendqready(ifp);
609 
610 	if (sc->sc_base.sc_phy_addr >= 0)
611 		if_initname(ifp, device_get_name(sc->sc_base.sc_dev),
612 		    device_get_unit(sc->sc_base.sc_dev));
613 	else
614 		if_initname(ifp, "memac_phy",
615 		    device_get_unit(sc->sc_base.sc_dev));
616 
617 
618 	if_setcapabilities(ifp, IFCAP_JUMBO_MTU |
619 	    IFCAP_VLAN_MTU | IFCAP_VLAN_HWCSUM |
620 	    IFCAP_RXCSUM | IFCAP_RXCSUM_IPV6 |
621 	    IFCAP_TXCSUM | IFCAP_TXCSUM_IPV6);
622 	if_setcapenable(ifp, if_getcapabilities(ifp));
623 	if_sethwassist(ifp, DPAA_CSUM_TX_OFFLOAD);
624 
625 	/* Attach PHY(s) */
626 	if (!sc->sc_fixed_link) {
627 		error = mii_attach(sc->sc_base.sc_dev, &sc->sc_base.sc_mii_dev,
628 		    ifp, memac_ifmedia_upd, memac_ifmedia_sts, BMSR_DEFCAPMASK,
629 		    sc->sc_base.sc_phy_addr, MII_OFFSET_ANY, 0);
630 		if (error) {
631 			device_printf(sc->sc_base.sc_dev,
632 			    "attaching PHYs failed: %d\n", error);
633 			memac_detach(sc->sc_base.sc_dev);
634 			return (error);
635 		}
636 		sc->sc_base.sc_mii = device_get_softc(sc->sc_base.sc_mii_dev);
637 	} else {
638 		phandle_t node;
639 		uint32_t type = IFM_ETHER;
640 		uint32_t speed;
641 
642 		node = ofw_bus_find_child(ofw_bus_get_node(dev), "fixed-link");
643 		if (OF_getencprop(node, "speed", &speed, sizeof(speed)) <= 0) {
644 			device_printf(dev,
645 			    "fixed link has no speed property\n");
646 			memac_detach(sc->sc_base.sc_dev);
647 			return (ENXIO);
648 		}
649 		switch (speed) {
650 		case 10:
651 			type |= IFM_10_T;
652 			break;
653 		case 100:
654 			type |= IFM_100_TX;
655 			break;
656 		case 1000:
657 			type |= IFM_1000_T;
658 			break;
659 		case 2500:
660 			type |= IFM_2500_T;
661 			break;
662 		case 5000:
663 			type |= IFM_5000_T;
664 			break;
665 		case 10000:
666 			type |= IFM_10G_T;
667 			break;
668 		}
669 		if (OF_hasprop(node, "full-duplex"))
670 			type |= IFM_FDX;
671 		sc->sc_base.sc_mii = malloc(sizeof(*sc->sc_base.sc_mii),
672 		    M_DEVBUF, M_WAITOK | M_ZERO);
673 		ifmedia_init(&sc->sc_base.sc_mii->mii_media, 0,
674 		    memac_ifmedia_upd, memac_ifmedia_fixed_sts);
675 		ifmedia_add(&sc->sc_base.sc_mii->mii_media, type, 0, NULL);
676 		ifmedia_set(&sc->sc_base.sc_mii->mii_media, type);
677 	}
678 
679 	/* Attach to stack */
680 	ether_ifattach(ifp, sc->sc_base.sc_mac_addr);
681 
682 	return (0);
683 }
684 
685 int
686 memac_detach(device_t dev)
687 {
688 	struct memac_softc *sc;
689 	if_t ifp;
690 
691 	sc = device_get_softc(dev);
692 	ifp = sc->sc_base.sc_ifnet;
693 
694 	if (device_is_attached(dev)) {
695 		ether_ifdetach(ifp);
696 		/* Shutdown interface */
697 		MEMAC_LOCK(sc);
698 		memac_if_deinit_locked(sc);
699 		MEMAC_UNLOCK(sc);
700 	}
701 
702 	if (sc->sc_base.sc_ifnet) {
703 		if_free(sc->sc_base.sc_ifnet);
704 		sc->sc_base.sc_ifnet = NULL;
705 	}
706 
707 	/* Free RX/TX FQRs */
708 	dpaa_eth_fq_rx_free(&sc->sc_base);
709 	dpaa_eth_fq_tx_free(&sc->sc_base);
710 
711 	/* Free frame info pool */
712 	dpaa_eth_fi_pool_free(&sc->sc_base);
713 
714 	/* Free RX buffer pool */
715 	dpaa_eth_pool_rx_free(&sc->sc_base);
716 
717 	/* Destroy lock */
718 	mtx_destroy(&sc->sc_base.sc_lock);
719 
720 	return (0);
721 }
722 
723 int
724 memac_suspend(device_t dev)
725 {
726 
727 	return (0);
728 }
729 
730 int
731 memac_resume(device_t dev)
732 {
733 
734 	return (0);
735 }
736 
737 int
738 memac_shutdown(device_t dev)
739 {
740 
741 	return (0);
742 }
743 /** @} */
744 
745 
746 /**
747  * @group MII bus interface.
748  * @{
749  */
750 int
751 memac_miibus_readreg(device_t dev, int phy, int reg)
752 {
753 	struct memac_softc *sc;
754 
755 	sc = device_get_softc(dev);
756 
757 	return (MIIBUS_READREG(sc->sc_base.sc_mdio, phy, reg));
758 }
759 
760 int
761 memac_miibus_writereg(device_t dev, int phy, int reg, int value)
762 {
763 
764 	struct memac_softc *sc;
765 
766 	sc = device_get_softc(dev);
767 
768 	return (MIIBUS_WRITEREG(sc->sc_base.sc_mdio, phy, reg, value));
769 }
770 
771 void
772 memac_miibus_statchg(device_t dev)
773 {
774 	struct memac_softc *sc;
775 	uint32_t reg;
776 	bool duplex;
777 	int speed;
778 
779 	sc = device_get_softc(dev);
780 
781 	MEMAC_LOCK_ASSERT(sc);
782 
783 	duplex = ((sc->sc_base.sc_mii->mii_media_active & IFM_GMASK) == IFM_FDX);
784 
785 	switch (IFM_SUBTYPE(sc->sc_base.sc_mii->mii_media_active)) {
786 	case IFM_AUTO:
787 		speed = IF_MODE_ENA;
788 		break;
789 	case IFM_1000_T:
790 	case IFM_1000_SX:
791 		if (!duplex) {
792 			device_printf(sc->sc_base.sc_dev,
793 			    "Only full-duplex supported for 1Gbps speeds");
794 			return;
795 		}
796 		speed = IF_MODE_SSP_1GB;
797 		break;
798 
799 	case IFM_100_TX:
800 		speed = IF_MODE_SSP_100MB;
801 		break;
802 	default:
803 		speed = IF_MODE_SSP_10MB;
804 		break;
805 	}
806 
807 	reg = bus_read_4(sc->sc_base.sc_mem, MEMAC_IF_MODE);
808 	reg &= ~(IF_MODE_ENA | IF_MODE_SSP_M | IF_MODE_SFD);
809 	reg |= 0x2;
810 
811 	if (duplex)
812 		reg |= IF_MODE_SFD;
813 	else
814 		reg |= IF_MODE_HD;
815 	reg |= speed;
816 	bus_write_4(sc->sc_base.sc_mem, MEMAC_IF_MODE, reg);
817 }
818 /** @} */
819