xref: /freebsd/sys/dev/dpaa/if_memac.c (revision aefd61a1de86521abc1551aa98ed94316fc83d86)
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
memac_fm_mac_init(struct memac_softc * sc,uint8_t * mac)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
memac_set_mtu(struct memac_softc * sc,unsigned int mtu)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
memac_hash_maddr(void * arg,struct sockaddr_dl * sdl,u_int cnt)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
memac_setup_multicast(struct memac_softc * sc)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
memac_setup_promisc(struct memac_softc * sc)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
memac_if_graceful_stop(struct memac_softc * sc)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
memac_mac_enable(struct memac_softc * sc)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
memac_if_enable_locked(struct memac_softc * sc)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
memac_if_disable_locked(struct memac_softc * sc)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
memac_if_ioctl(if_t ifp,u_long command,caddr_t data)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 		if ((changed & IFCAP_LRO) != 0)
358 			if_togglecapenable(ifp, IFCAP_LRO);
359 		break;
360 
361 	case SIOCGIFMEDIA:
362 	case SIOCSIFMEDIA:
363 		error = ifmedia_ioctl(ifp, ifr, &sc->sc_base.sc_mii->mii_media,
364 		    command);
365 		break;
366 
367 	default:
368 		error = ether_ioctl(ifp, command, data);
369 	}
370 
371 	return (error);
372 }
373 
374 static void
memac_if_tick(void * arg)375 memac_if_tick(void *arg)
376 {
377 	struct memac_softc *sc;
378 
379 	sc = arg;
380 
381 	/* TODO */
382 	MEMAC_LOCK(sc);
383 
384 	mii_tick(sc->sc_base.sc_mii);
385 	callout_reset(&sc->sc_base.sc_tick_callout, hz, memac_if_tick, sc);
386 
387 	MEMAC_UNLOCK(sc);
388 }
389 
390 static void
memac_if_deinit_locked(struct memac_softc * sc)391 memac_if_deinit_locked(struct memac_softc *sc)
392 {
393 
394 	MEMAC_LOCK_ASSERT(sc);
395 
396 	MEMAC_UNLOCK(sc);
397 	callout_drain(&sc->sc_base.sc_tick_callout);
398 	MEMAC_LOCK(sc);
399 }
400 
401 static void
memac_if_set_macaddr(struct memac_softc * sc,const char * addr)402 memac_if_set_macaddr(struct memac_softc *sc, const char *addr)
403 {
404 	uint32_t reg;
405 
406 	reg = (addr[3] << 24) | (addr[2] << 16) | (addr[1] << 8) | addr[0];
407 	bus_write_4(sc->sc_base.sc_mem, MEMAC_MAC_ADDR_0, reg);
408 	reg = (addr[5] << 8) | (addr[4]);
409 	bus_write_4(sc->sc_base.sc_mem, MEMAC_MAC_ADDR_1, reg);
410 }
411 
412 static void
memac_if_init_locked(struct memac_softc * sc)413 memac_if_init_locked(struct memac_softc *sc)
414 {
415 	int error;
416 	const char *macaddr;
417 
418 	MEMAC_LOCK_ASSERT(sc);
419 
420 	macaddr = if_getlladdr(sc->sc_base.sc_ifnet);
421 	memac_if_set_macaddr(sc, macaddr);
422 
423 	/* Start MII polling */
424 	if (sc->sc_base.sc_mii)
425 		callout_reset(&sc->sc_base.sc_tick_callout, hz,
426 		    memac_if_tick, sc);
427 
428 	if (if_getflags(sc->sc_base.sc_ifnet) & IFF_UP) {
429 		error = memac_if_enable_locked(sc);
430 		if (error != 0)
431 			goto err;
432 	} else {
433 		error = memac_if_disable_locked(sc);
434 		if (error != 0)
435 			goto err;
436 	}
437 
438 	if_link_state_change(sc->sc_base.sc_ifnet, LINK_STATE_UP);
439 
440 	bus_write_4(sc->sc_base.sc_mem, MEMAC_CL01_PAUSE_QUANTA,
441 	    DEFAULT_PAUSE_QUANTA);
442 
443 	return;
444 
445 err:
446 	memac_if_deinit_locked(sc);
447 	device_printf(sc->sc_base.sc_dev, "initialization error.\n");
448 	return;
449 }
450 
451 static void
memac_if_init(void * data)452 memac_if_init(void *data)
453 {
454 	struct memac_softc *sc;
455 
456 	sc = data;
457 
458 	MEMAC_LOCK(sc);
459 	memac_if_init_locked(sc);
460 	MEMAC_UNLOCK(sc);
461 }
462 
463 static void
memac_if_start(if_t ifp)464 memac_if_start(if_t ifp)
465 {
466 	struct memac_softc *sc;
467 
468 	sc = if_getsoftc(ifp);
469 	MEMAC_LOCK(sc);
470 	dpaa_eth_if_start_locked(&sc->sc_base);
471 	MEMAC_UNLOCK(sc);
472 }
473 
474 static void
memac_if_watchdog(if_t ifp)475 memac_if_watchdog(if_t ifp)
476 {
477 	/* TODO */
478 }
479 /** @} */
480 
481 
482 /**
483  * @group IFmedia routines.
484  * @{
485  */
486 static int
memac_ifmedia_upd(if_t ifp)487 memac_ifmedia_upd(if_t ifp)
488 {
489 	struct memac_softc *sc = if_getsoftc(ifp);
490 
491 	return (0);
492 	MEMAC_LOCK(sc);
493 	mii_mediachg(sc->sc_base.sc_mii);
494 	MEMAC_UNLOCK(sc);
495 
496 	return (0);
497 }
498 
499 static void
memac_ifmedia_fixed_sts(if_t ifp,struct ifmediareq * ifmr)500 memac_ifmedia_fixed_sts(if_t ifp, struct ifmediareq *ifmr)
501 {
502 	struct memac_softc *sc = if_getsoftc(ifp);
503 
504 	MEMAC_LOCK(sc);
505 	ifmr->ifm_count = 1;
506 	ifmr->ifm_mask = 0;
507 	ifmr->ifm_status = IFM_AVALID | IFM_ACTIVE;
508 	ifmr->ifm_current = ifmr->ifm_active =
509 	    sc->sc_base.sc_mii->mii_media.ifm_cur->ifm_media;
510 	ifmr->ifm_active = ifmr->ifm_current;
511 
512 	/*
513 	 * In non-PHY usecases, we need to signal link state up, otherwise
514 	 * certain things requiring a link event (e.g async DHCP client) from
515 	 * devd do not happen.
516 	 */
517 	if (if_getlinkstate(ifp) == LINK_STATE_UNKNOWN) {
518 		if_link_state_change(ifp, LINK_STATE_UP);
519 	}
520 
521 	/* We assume the link is static, as in a peer switch. */
522 
523 	MEMAC_UNLOCK(sc);
524 
525 	return;
526 }
527 
528 static void
memac_ifmedia_sts(if_t ifp,struct ifmediareq * ifmr)529 memac_ifmedia_sts(if_t ifp, struct ifmediareq *ifmr)
530 {
531 	struct memac_softc *sc = if_getsoftc(ifp);
532 
533 	MEMAC_LOCK(sc);
534 
535 	mii_pollstat(sc->sc_base.sc_mii);
536 
537 	ifmr->ifm_active = sc->sc_base.sc_mii->mii_media_active;
538 	ifmr->ifm_status = sc->sc_base.sc_mii->mii_media_status;
539 
540 	MEMAC_UNLOCK(sc);
541 }
542 /** @} */
543 
544 
545 /**
546  * @group dTSEC bus interface.
547  * @{
548  */
549 
550 int
memac_attach(device_t dev)551 memac_attach(device_t dev)
552 {
553 	struct memac_softc *sc;
554 	int error;
555 	if_t ifp;
556 
557 	sc = device_get_softc(dev);
558 
559 	sc->sc_base.sc_dev = dev;
560 
561 	/* Init locks */
562 	mtx_init(&sc->sc_base.sc_lock, device_get_nameunit(dev),
563 	    "mEMAC Global Lock", MTX_DEF);
564 
565 	mtx_init(&sc->sc_base.sc_mii_lock, device_get_nameunit(dev),
566 	    "mEMAC MII Lock", MTX_DEF);
567 
568 	/* Init callouts */
569 	callout_init(&sc->sc_base.sc_tick_callout, CALLOUT_MPSAFE);
570 
571 	/* Create network interface for upper layers */
572 	ifp = sc->sc_base.sc_ifnet = if_alloc(IFT_ETHER);
573 
574 	/* Create RX buffer pool */
575 	error = dpaa_eth_pool_rx_init(&sc->sc_base);
576 	if (error != 0)
577 		return (EIO);
578 
579 	/* Create RX frame queue range */
580 	error = dpaa_eth_fq_rx_init(&sc->sc_base);
581 	if (error != 0)
582 		return (EIO);
583 
584 	/* Create frame info pool */
585 	error = dpaa_eth_fi_pool_init(&sc->sc_base);
586 	if (error != 0)
587 		return (EIO);
588 
589 	/* Create TX frame queue range */
590 	error = dpaa_eth_fq_tx_init(&sc->sc_base);
591 	if (error != 0)
592 		return (EIO);
593 
594 	/* Init FMan MAC module. */
595 	error = memac_fm_mac_init(sc, sc->sc_base.sc_mac_addr);
596 	if (error != 0) {
597 		memac_detach(dev);
598 		return (ENXIO);
599 	}
600 
601 	dpaa_eth_fm_port_rx_init(&sc->sc_base);
602 	dpaa_eth_fm_port_tx_init(&sc->sc_base);
603 
604 	if_setsoftc(ifp, sc);
605 
606 	if_setflags(ifp, IFF_SIMPLEX | IFF_BROADCAST | IFF_MULTICAST);
607 	if_setinitfn(ifp, memac_if_init);
608 	if_setstartfn(ifp, memac_if_start);
609 	if_setioctlfn(ifp, memac_if_ioctl);
610 	if_setsendqlen(ifp, IFQ_MAXLEN);
611 	if_setsendqready(ifp);
612 
613 	if (sc->sc_base.sc_phy_addr >= 0)
614 		if_initname(ifp, device_get_name(sc->sc_base.sc_dev),
615 		    device_get_unit(sc->sc_base.sc_dev));
616 	else
617 		if_initname(ifp, "memac_phy",
618 		    device_get_unit(sc->sc_base.sc_dev));
619 
620 
621 	if_setcapabilities(ifp, IFCAP_JUMBO_MTU |
622 	    IFCAP_VLAN_MTU | IFCAP_VLAN_HWCSUM |
623 	    IFCAP_RXCSUM | IFCAP_RXCSUM_IPV6 |
624 	    IFCAP_TXCSUM | IFCAP_TXCSUM_IPV6 |
625 	    IFCAP_LRO);
626 	if_setcapenable(ifp, if_getcapabilities(ifp));
627 	if_sethwassist(ifp, DPAA_CSUM_TX_OFFLOAD);
628 
629 	/* Attach PHY(s) */
630 	if (!sc->sc_fixed_link) {
631 		error = mii_attach(sc->sc_base.sc_dev, &sc->sc_base.sc_mii_dev,
632 		    ifp, memac_ifmedia_upd, memac_ifmedia_sts, BMSR_DEFCAPMASK,
633 		    sc->sc_base.sc_phy_addr, MII_OFFSET_ANY, 0);
634 		if (error) {
635 			device_printf(sc->sc_base.sc_dev,
636 			    "attaching PHYs failed: %d\n", error);
637 			memac_detach(sc->sc_base.sc_dev);
638 			return (error);
639 		}
640 		sc->sc_base.sc_mii = device_get_softc(sc->sc_base.sc_mii_dev);
641 	} else {
642 		phandle_t node;
643 		uint32_t type = IFM_ETHER;
644 		uint32_t speed;
645 
646 		node = ofw_bus_find_child(ofw_bus_get_node(dev), "fixed-link");
647 		if (OF_getencprop(node, "speed", &speed, sizeof(speed)) <= 0) {
648 			device_printf(dev,
649 			    "fixed link has no speed property\n");
650 			memac_detach(sc->sc_base.sc_dev);
651 			return (ENXIO);
652 		}
653 		switch (speed) {
654 		case 10:
655 			type |= IFM_10_T;
656 			break;
657 		case 100:
658 			type |= IFM_100_TX;
659 			break;
660 		case 1000:
661 			type |= IFM_1000_T;
662 			break;
663 		case 2500:
664 			type |= IFM_2500_T;
665 			break;
666 		case 5000:
667 			type |= IFM_5000_T;
668 			break;
669 		case 10000:
670 			type |= IFM_10G_T;
671 			break;
672 		}
673 		if (OF_hasprop(node, "full-duplex"))
674 			type |= IFM_FDX;
675 		sc->sc_base.sc_mii = malloc(sizeof(*sc->sc_base.sc_mii),
676 		    M_DEVBUF, M_WAITOK | M_ZERO);
677 		ifmedia_init(&sc->sc_base.sc_mii->mii_media, 0,
678 		    memac_ifmedia_upd, memac_ifmedia_fixed_sts);
679 		ifmedia_add(&sc->sc_base.sc_mii->mii_media, type, 0, NULL);
680 		ifmedia_set(&sc->sc_base.sc_mii->mii_media, type);
681 	}
682 
683 	/* Attach to stack */
684 	ether_ifattach(ifp, sc->sc_base.sc_mac_addr);
685 
686 	return (0);
687 }
688 
689 int
memac_detach(device_t dev)690 memac_detach(device_t dev)
691 {
692 	struct memac_softc *sc;
693 	if_t ifp;
694 
695 	sc = device_get_softc(dev);
696 	ifp = sc->sc_base.sc_ifnet;
697 
698 	if (device_is_attached(dev)) {
699 		ether_ifdetach(ifp);
700 		/* Shutdown interface */
701 		MEMAC_LOCK(sc);
702 		memac_if_deinit_locked(sc);
703 		MEMAC_UNLOCK(sc);
704 	}
705 
706 	if (sc->sc_base.sc_ifnet) {
707 		if_free(sc->sc_base.sc_ifnet);
708 		sc->sc_base.sc_ifnet = NULL;
709 	}
710 
711 	/* Free RX/TX FQRs */
712 	dpaa_eth_fq_rx_free(&sc->sc_base);
713 	dpaa_eth_fq_tx_free(&sc->sc_base);
714 
715 	/* Free frame info pool */
716 	dpaa_eth_fi_pool_free(&sc->sc_base);
717 
718 	/* Free RX buffer pool */
719 	dpaa_eth_pool_rx_free(&sc->sc_base);
720 
721 	/* Destroy lock */
722 	mtx_destroy(&sc->sc_base.sc_lock);
723 
724 	return (0);
725 }
726 
727 int
memac_suspend(device_t dev)728 memac_suspend(device_t dev)
729 {
730 
731 	return (0);
732 }
733 
734 int
memac_resume(device_t dev)735 memac_resume(device_t dev)
736 {
737 
738 	return (0);
739 }
740 
741 int
memac_shutdown(device_t dev)742 memac_shutdown(device_t dev)
743 {
744 
745 	return (0);
746 }
747 /** @} */
748 
749 
750 /**
751  * @group MII bus interface.
752  * @{
753  */
754 int
memac_miibus_readreg(device_t dev,int phy,int reg)755 memac_miibus_readreg(device_t dev, int phy, int reg)
756 {
757 	struct memac_softc *sc;
758 
759 	sc = device_get_softc(dev);
760 
761 	return (MIIBUS_READREG(sc->sc_base.sc_mdio, phy, reg));
762 }
763 
764 int
memac_miibus_writereg(device_t dev,int phy,int reg,int value)765 memac_miibus_writereg(device_t dev, int phy, int reg, int value)
766 {
767 
768 	struct memac_softc *sc;
769 
770 	sc = device_get_softc(dev);
771 
772 	return (MIIBUS_WRITEREG(sc->sc_base.sc_mdio, phy, reg, value));
773 }
774 
775 void
memac_miibus_statchg(device_t dev)776 memac_miibus_statchg(device_t dev)
777 {
778 	struct memac_softc *sc;
779 	uint32_t reg;
780 	bool duplex;
781 	int speed;
782 
783 	sc = device_get_softc(dev);
784 
785 	MEMAC_LOCK_ASSERT(sc);
786 
787 	duplex = ((sc->sc_base.sc_mii->mii_media_active & IFM_GMASK) == IFM_FDX);
788 
789 	switch (IFM_SUBTYPE(sc->sc_base.sc_mii->mii_media_active)) {
790 	case IFM_AUTO:
791 		speed = IF_MODE_ENA;
792 		break;
793 	case IFM_1000_T:
794 	case IFM_1000_SX:
795 		if (!duplex) {
796 			device_printf(sc->sc_base.sc_dev,
797 			    "Only full-duplex supported for 1Gbps speeds");
798 			return;
799 		}
800 		speed = IF_MODE_SSP_1GB;
801 		break;
802 
803 	case IFM_100_TX:
804 		speed = IF_MODE_SSP_100MB;
805 		break;
806 	default:
807 		speed = IF_MODE_SSP_10MB;
808 		break;
809 	}
810 
811 	reg = bus_read_4(sc->sc_base.sc_mem, MEMAC_IF_MODE);
812 	reg &= ~(IF_MODE_ENA | IF_MODE_SSP_M | IF_MODE_SFD);
813 	reg |= 0x2;
814 
815 	if (duplex)
816 		reg |= IF_MODE_SFD;
817 	else
818 		reg |= IF_MODE_HD;
819 	reg |= speed;
820 	bus_write_4(sc->sc_base.sc_mem, MEMAC_IF_MODE, reg);
821 }
822 /** @} */
823