xref: /freebsd/sys/dev/dpaa/if_memac.c (revision 7a40b8a89e7da2a7e8d8e132bc37885b22e9bfb1)
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 #define	DPAA_CSUM_TX_OFFLOAD	(CSUM_IP | CSUM_DELAY_DATA | CSUM_DELAY_DATA_IPV6)
93 
94 
95 /**
96  * @group FMan MAC routines.
97  * @{
98  */
99 #define	MEMAC_MAC_EXCEPTIONS_END	(-1)
100 
101 static void memac_if_init_locked(struct memac_softc *sc);
102 
103 static int
memac_fm_mac_init(struct memac_softc * sc,uint8_t * mac)104 memac_fm_mac_init(struct memac_softc *sc, uint8_t *mac)
105 {
106 	uint32_t reg;
107 
108 	FMAN_GET_REVISION(device_get_parent(sc->sc_base.sc_dev), &sc->sc_base.sc_rev_major,
109 	    &sc->sc_base.sc_rev_minor);
110 
111 	if (FMAN_RESET_MAC(device_get_parent(sc->sc_base.sc_dev), sc->sc_base.sc_eth_id) != 0)
112 		return (ENXIO);
113 
114 	reg = bus_read_4(sc->sc_base.sc_mem, MEMAC_COMMAND_CONFIG);
115 	reg |= COMMAND_CONFIG_SWR;
116 	bus_write_4(sc->sc_base.sc_mem, MEMAC_COMMAND_CONFIG, reg);
117 
118 	while (bus_read_4(sc->sc_base.sc_mem, MEMAC_COMMAND_CONFIG) & COMMAND_CONFIG_SWR)
119 		;
120 
121 	/* TODO: TX_FIFO_SECTIONS */
122 	/* TODO: CL01 pause quantum */
123 	bus_write_4(sc->sc_base.sc_mem, MEMAC_COMMAND_CONFIG,
124 	    COMMAND_CONFIG_NO_LEN_CHK | COMMAND_CONFIG_TXP | COMMAND_CONFIG_CRC);
125 
126 	reg = bus_read_4(sc->sc_base.sc_mem, MEMAC_IF_MODE);
127 	reg &= ~(IF_MODE_IFMODE_M | IF_MODE_RG);
128 	switch (sc->sc_base.sc_mac_enet_mode) {
129 	case MII_CONTYPE_RGMII:
130 		reg |= IF_MODE_RG;
131 		/* FALLTHROUGH */
132 	case MII_CONTYPE_GMII:
133 	case MII_CONTYPE_SGMII:
134 	case MII_CONTYPE_QSGMII:
135 		reg |= IF_MODE_IFMODE_GMII;
136 		break;
137 	case MII_CONTYPE_RMII:
138 		reg |= IF_MODE_RG;
139 		/* FALLTHROUGH */
140 	case MII_CONTYPE_MII:
141 		reg |= IF_MODE_IFMODE_MII;
142 		break;
143 	}
144 
145 	bus_write_4(sc->sc_base.sc_mem, MEMAC_IF_MODE, reg);
146 
147 	return (0);
148 }
149 /** @} */
150 
151 
152 /**
153  * @group IFnet routines.
154  * @{
155  */
156 static int
memac_set_mtu(struct memac_softc * sc,unsigned int mtu)157 memac_set_mtu(struct memac_softc *sc, unsigned int mtu)
158 {
159 
160 	mtu += ETHER_HDR_LEN + ETHER_VLAN_ENCAP_LEN + ETHER_CRC_LEN;
161 
162 	MEMAC_LOCK_ASSERT(sc);
163 
164 	if (mtu >= MEMAC_MIN_FRAME_SIZE && mtu <= MEMAC_MAX_FRAME_SIZE) {
165 		bus_write_4(sc->sc_base.sc_mem, MEMAC_REG_MAXFRM, mtu);
166 		return (mtu);
167 	}
168 
169 	return (0);
170 }
171 
172 static u_int
memac_hash_maddr(void * arg,struct sockaddr_dl * sdl,u_int cnt)173 memac_hash_maddr(void *arg, struct sockaddr_dl *sdl, u_int cnt)
174 {
175 	struct memac_softc *sc = arg;
176 	uint8_t *addr = LLADDR(sdl);
177 	uint32_t hash = 0;
178 	uint8_t a, h;
179 
180 	/* Hash is 6 bits, composed if [XOR{47:40},XOR{39:32},....] */
181 	for (int i = 0; i < 6; i++) {
182 		a = addr[i];
183 		h = 0;
184 		for (int j = 0; j < 8; j++, a >>= 1) {
185 			h ^= (a & 0x1);
186 		}
187 		hash |= (h << i);
188 	}
189 	bus_write_4(sc->sc_base.sc_mem, HASHTABLE_CTRL, hash | CTRL_MCAST);
190 
191 	return (1);
192 }
193 
194 static void
memac_setup_multicast(struct memac_softc * sc)195 memac_setup_multicast(struct memac_softc *sc)
196 {
197 
198 	if (if_getflags(sc->sc_base.sc_ifnet) & IFF_ALLMULTI) {
199 		for (int i = 0; i < HASHTABLE_SIZE; i++)
200 			bus_write_4(sc->sc_base.sc_mem,
201 			    HASHTABLE_CTRL, CTRL_MCAST | i);
202 	} else {
203 		/* Clear the hash table */
204 		for (int i = 0; i < HASHTABLE_SIZE; i++)
205 			bus_write_4(sc->sc_base.sc_mem,
206 			    HASHTABLE_CTRL, i);
207 	}
208 
209 	if_foreach_llmaddr(sc->sc_base.sc_ifnet, memac_hash_maddr, sc);
210 }
211 
212 static void
memac_setup_promisc(struct memac_softc * sc)213 memac_setup_promisc(struct memac_softc *sc)
214 {
215 	uint32_t reg;
216 
217 	reg = bus_read_4(sc->sc_base.sc_mem, MEMAC_COMMAND_CONFIG);
218 	reg &= ~COMMAND_CONFIG_PROMISC;
219 
220 	if ((if_getflags(sc->sc_base.sc_ifnet) & IFF_PROMISC) != 0)
221 		bus_write_4(sc->sc_base.sc_mem, MEMAC_COMMAND_CONFIG,
222 		    reg | COMMAND_CONFIG_PROMISC);
223 }
224 
225 static void
memac_if_graceful_stop(struct memac_softc * sc)226 memac_if_graceful_stop(struct memac_softc *sc)
227 {
228 	struct resource *regs = sc->sc_base.sc_mem;
229 	uint32_t reg;
230 
231 	reg = bus_read_4(regs, MEMAC_COMMAND_CONFIG);
232 	reg |= COMMAND_CONFIG_RXSTP;
233 
234 	bus_write_4(regs, MEMAC_COMMAND_CONFIG, reg);
235 	while ((bus_read_4(regs, MEMAC_IEVENT) & IEVENT_RX_EMPTY) == 0)
236 		;
237 	reg &= COMMAND_CONFIG_RX_EN;
238 	bus_write_4(regs, MEMAC_COMMAND_CONFIG, reg);
239 
240 	while ((bus_read_4(regs, MEMAC_IEVENT) & IEVENT_TX_EMPTY) == 0)
241 		;
242 	bus_write_4(regs, MEMAC_COMMAND_CONFIG, reg & ~COMMAND_CONFIG_TX_EN);
243 }
244 
245 static void
memac_mac_enable(struct memac_softc * sc)246 memac_mac_enable(struct memac_softc *sc)
247 {
248 	uint32_t reg = bus_read_4(sc->sc_base.sc_mem, MEMAC_COMMAND_CONFIG);
249 
250 	reg |= (COMMAND_CONFIG_RX_EN | COMMAND_CONFIG_TX_EN);
251 
252 	bus_write_4(sc->sc_base.sc_mem, MEMAC_COMMAND_CONFIG, reg);
253 }
254 
255 static int
memac_if_enable_locked(struct memac_softc * sc)256 memac_if_enable_locked(struct memac_softc *sc)
257 {
258 	int error;
259 
260 	MEMAC_LOCK_ASSERT(sc);
261 
262 	memac_set_mtu(sc, if_getmtu(sc->sc_base.sc_ifnet));
263 	memac_mac_enable(sc);
264 
265 	error = FMAN_PORT_ENABLE(sc->sc_base.sc_rx_port);
266 	if (error != 0)
267 		return (EIO);
268 
269 	error = FMAN_PORT_ENABLE(sc->sc_base.sc_tx_port);
270 	if (error != 0)
271 		return (EIO);
272 
273 	bus_write_4(sc->sc_base.sc_mem, MEMAC_IEVENT, 0);
274 	memac_setup_multicast(sc);
275 	memac_setup_promisc(sc);
276 
277 	if_setdrvflagbits(sc->sc_base.sc_ifnet, IFF_DRV_RUNNING, 0);
278 
279 	/* Refresh link state */
280 	memac_miibus_statchg(sc->sc_base.sc_dev);
281 
282 	return (0);
283 }
284 
285 static int
memac_if_disable_locked(struct memac_softc * sc)286 memac_if_disable_locked(struct memac_softc *sc)
287 {
288 	int error;
289 
290 	MEMAC_LOCK_ASSERT(sc);
291 
292 	error = FMAN_PORT_DISABLE(sc->sc_base.sc_tx_port);
293 	if (error != 0)
294 		return (EIO);
295 
296 	memac_if_graceful_stop(sc);
297 
298 	error = FMAN_PORT_DISABLE(sc->sc_base.sc_rx_port);
299 	if (error != 0)
300 		return (EIO);
301 
302 	if_setdrvflagbits(sc->sc_base.sc_ifnet, 0, IFF_DRV_RUNNING);
303 
304 	return (0);
305 }
306 
307 static int
memac_if_ioctl(if_t ifp,u_long command,caddr_t data)308 memac_if_ioctl(if_t ifp, u_long command, caddr_t data)
309 {
310 	struct memac_softc *sc;
311 	struct ifreq *ifr;
312 	uint32_t changed;
313 	int error;
314 
315 	sc = if_getsoftc(ifp);
316 	ifr = (struct ifreq *)data;
317 	error = 0;
318 
319 	/* Basic functionality to achieve media status reports */
320 	switch (command) {
321 	case SIOCSIFMTU:
322 		MEMAC_LOCK(sc);
323 		if (memac_set_mtu(sc, ifr->ifr_mtu))
324 			if_setmtu(ifp, ifr->ifr_mtu);
325 		else
326 			error = EINVAL;
327 		MEMAC_UNLOCK(sc);
328 		break;
329 	case SIOCSIFFLAGS:
330 		MEMAC_LOCK(sc);
331 		if (if_getflags(ifp) & IFF_UP) {
332 			if (!(if_getdrvflags(ifp) & IFF_DRV_RUNNING))
333 				memac_if_init_locked(sc);
334 		} else if (if_getdrvflags(ifp) & IFF_DRV_RUNNING)
335 			error = memac_if_disable_locked(sc);
336 
337 		MEMAC_UNLOCK(sc);
338 		break;
339 
340 	case SIOCADDMULTI:
341 	case SIOCDELMULTI:
342 		if (if_getflags(sc->sc_base.sc_ifnet) & IFF_UP) {
343 			MEMAC_LOCK(sc);
344 			memac_setup_multicast(sc);
345 			MEMAC_UNLOCK(sc);
346 		}
347 		break;
348 
349 	case SIOCSIFCAP:
350 		changed = if_getcapenable(ifp) ^ ifr->ifr_reqcap;
351 		if ((changed & (IFCAP_RXCSUM | IFCAP_RXCSUM_IPV6)) != 0)
352 			if_togglecapenable(ifp,
353 			    IFCAP_RXCSUM | IFCAP_RXCSUM_IPV6);
354 		if ((changed & (IFCAP_TXCSUM | IFCAP_TXCSUM_IPV6)) != 0) {
355 			if_togglecapenable(ifp,
356 			    IFCAP_TXCSUM | IFCAP_TXCSUM_IPV6);
357 			if_togglehwassist(ifp, DPAA_CSUM_TX_OFFLOAD);
358 		}
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 RX buffer pool */
572 	error = dpaa_eth_pool_rx_init(&sc->sc_base);
573 	if (error != 0)
574 		return (EIO);
575 
576 	/* Create RX frame queue range */
577 	error = dpaa_eth_fq_rx_init(&sc->sc_base);
578 	if (error != 0)
579 		return (EIO);
580 
581 	/* Create frame info pool */
582 	error = dpaa_eth_fi_pool_init(&sc->sc_base);
583 	if (error != 0)
584 		return (EIO);
585 
586 	/* Create TX frame queue range */
587 	error = dpaa_eth_fq_tx_init(&sc->sc_base);
588 	if (error != 0)
589 		return (EIO);
590 
591 	/* Init FMan MAC module. */
592 	error = memac_fm_mac_init(sc, sc->sc_base.sc_mac_addr);
593 	if (error != 0) {
594 		memac_detach(dev);
595 		return (ENXIO);
596 	}
597 
598 	dpaa_eth_fm_port_rx_init(&sc->sc_base);
599 	dpaa_eth_fm_port_tx_init(&sc->sc_base);
600 
601 	/* Create network interface for upper layers */
602 	ifp = sc->sc_base.sc_ifnet = if_alloc(IFT_ETHER);
603 	if_setsoftc(ifp, sc);
604 
605 	if_setflags(ifp, IFF_SIMPLEX | IFF_BROADCAST | IFF_MULTICAST);
606 	if_setinitfn(ifp, memac_if_init);
607 	if_setstartfn(ifp, memac_if_start);
608 	if_setioctlfn(ifp, memac_if_ioctl);
609 	if_setsendqlen(ifp, IFQ_MAXLEN);
610 	if_setsendqready(ifp);
611 
612 	if (sc->sc_base.sc_phy_addr >= 0)
613 		if_initname(ifp, device_get_name(sc->sc_base.sc_dev),
614 		    device_get_unit(sc->sc_base.sc_dev));
615 	else
616 		if_initname(ifp, "memac_phy",
617 		    device_get_unit(sc->sc_base.sc_dev));
618 
619 
620 	if_setcapabilities(ifp, IFCAP_JUMBO_MTU |
621 	    IFCAP_VLAN_MTU | IFCAP_VLAN_HWCSUM |
622 	    IFCAP_RXCSUM | IFCAP_RXCSUM_IPV6 |
623 	    IFCAP_TXCSUM | IFCAP_TXCSUM_IPV6);
624 	if_setcapenable(ifp, if_getcapabilities(ifp));
625 	if_sethwassist(ifp, DPAA_CSUM_TX_OFFLOAD);
626 
627 	/* Attach PHY(s) */
628 	if (!sc->sc_fixed_link) {
629 		error = mii_attach(sc->sc_base.sc_dev, &sc->sc_base.sc_mii_dev,
630 		    ifp, memac_ifmedia_upd, memac_ifmedia_sts, BMSR_DEFCAPMASK,
631 		    sc->sc_base.sc_phy_addr, MII_OFFSET_ANY, 0);
632 		if (error) {
633 			device_printf(sc->sc_base.sc_dev,
634 			    "attaching PHYs failed: %d\n", error);
635 			memac_detach(sc->sc_base.sc_dev);
636 			return (error);
637 		}
638 		sc->sc_base.sc_mii = device_get_softc(sc->sc_base.sc_mii_dev);
639 	} else {
640 		phandle_t node;
641 		uint32_t type = IFM_ETHER;
642 		uint32_t speed;
643 
644 		node = ofw_bus_find_child(ofw_bus_get_node(dev), "fixed-link");
645 		if (OF_getencprop(node, "speed", &speed, sizeof(speed)) <= 0) {
646 			device_printf(dev,
647 			    "fixed link has no speed property\n");
648 			memac_detach(sc->sc_base.sc_dev);
649 			return (ENXIO);
650 		}
651 		switch (speed) {
652 		case 10:
653 			type |= IFM_10_T;
654 			break;
655 		case 100:
656 			type |= IFM_100_TX;
657 			break;
658 		case 1000:
659 			type |= IFM_1000_T;
660 			break;
661 		case 2500:
662 			type |= IFM_2500_T;
663 			break;
664 		case 5000:
665 			type |= IFM_5000_T;
666 			break;
667 		case 10000:
668 			type |= IFM_10G_T;
669 			break;
670 		}
671 		if (OF_hasprop(node, "full-duplex"))
672 			type |= IFM_FDX;
673 		sc->sc_base.sc_mii = malloc(sizeof(*sc->sc_base.sc_mii),
674 		    M_DEVBUF, M_WAITOK | M_ZERO);
675 		ifmedia_init(&sc->sc_base.sc_mii->mii_media, 0,
676 		    memac_ifmedia_upd, memac_ifmedia_fixed_sts);
677 		ifmedia_add(&sc->sc_base.sc_mii->mii_media, type, 0, NULL);
678 		ifmedia_set(&sc->sc_base.sc_mii->mii_media, type);
679 	}
680 
681 	/* Attach to stack */
682 	ether_ifattach(ifp, sc->sc_base.sc_mac_addr);
683 
684 	return (0);
685 }
686 
687 int
memac_detach(device_t dev)688 memac_detach(device_t dev)
689 {
690 	struct memac_softc *sc;
691 	if_t ifp;
692 
693 	sc = device_get_softc(dev);
694 	ifp = sc->sc_base.sc_ifnet;
695 
696 	if (device_is_attached(dev)) {
697 		ether_ifdetach(ifp);
698 		/* Shutdown interface */
699 		MEMAC_LOCK(sc);
700 		memac_if_deinit_locked(sc);
701 		MEMAC_UNLOCK(sc);
702 	}
703 
704 	if (sc->sc_base.sc_ifnet) {
705 		if_free(sc->sc_base.sc_ifnet);
706 		sc->sc_base.sc_ifnet = NULL;
707 	}
708 
709 	/* Free RX/TX FQRs */
710 	dpaa_eth_fq_rx_free(&sc->sc_base);
711 	dpaa_eth_fq_tx_free(&sc->sc_base);
712 
713 	/* Free frame info pool */
714 	dpaa_eth_fi_pool_free(&sc->sc_base);
715 
716 	/* Free RX buffer pool */
717 	dpaa_eth_pool_rx_free(&sc->sc_base);
718 
719 	/* Destroy lock */
720 	mtx_destroy(&sc->sc_base.sc_lock);
721 
722 	return (0);
723 }
724 
725 int
memac_suspend(device_t dev)726 memac_suspend(device_t dev)
727 {
728 
729 	return (0);
730 }
731 
732 int
memac_resume(device_t dev)733 memac_resume(device_t dev)
734 {
735 
736 	return (0);
737 }
738 
739 int
memac_shutdown(device_t dev)740 memac_shutdown(device_t dev)
741 {
742 
743 	return (0);
744 }
745 /** @} */
746 
747 
748 /**
749  * @group MII bus interface.
750  * @{
751  */
752 int
memac_miibus_readreg(device_t dev,int phy,int reg)753 memac_miibus_readreg(device_t dev, int phy, int reg)
754 {
755 	struct memac_softc *sc;
756 
757 	sc = device_get_softc(dev);
758 
759 	return (MIIBUS_READREG(sc->sc_base.sc_mdio, phy, reg));
760 }
761 
762 int
memac_miibus_writereg(device_t dev,int phy,int reg,int value)763 memac_miibus_writereg(device_t dev, int phy, int reg, int value)
764 {
765 
766 	struct memac_softc *sc;
767 
768 	sc = device_get_softc(dev);
769 
770 	return (MIIBUS_WRITEREG(sc->sc_base.sc_mdio, phy, reg, value));
771 }
772 
773 void
memac_miibus_statchg(device_t dev)774 memac_miibus_statchg(device_t dev)
775 {
776 	struct memac_softc *sc;
777 	uint32_t reg;
778 	bool duplex;
779 	int speed;
780 
781 	sc = device_get_softc(dev);
782 
783 	MEMAC_LOCK_ASSERT(sc);
784 
785 	duplex = ((sc->sc_base.sc_mii->mii_media_active & IFM_GMASK) == IFM_FDX);
786 
787 	switch (IFM_SUBTYPE(sc->sc_base.sc_mii->mii_media_active)) {
788 	case IFM_AUTO:
789 		speed = IF_MODE_ENA;
790 		break;
791 	case IFM_1000_T:
792 	case IFM_1000_SX:
793 		if (!duplex) {
794 			device_printf(sc->sc_base.sc_dev,
795 			    "Only full-duplex supported for 1Gbps speeds");
796 			return;
797 		}
798 		speed = IF_MODE_SSP_1GB;
799 		break;
800 
801 	case IFM_100_TX:
802 		speed = IF_MODE_SSP_100MB;
803 		break;
804 	default:
805 		speed = IF_MODE_SSP_10MB;
806 		break;
807 	}
808 
809 	reg = bus_read_4(sc->sc_base.sc_mem, MEMAC_IF_MODE);
810 	reg &= ~(IF_MODE_ENA | IF_MODE_SSP_M | IF_MODE_SFD);
811 	reg |= 0x2;
812 
813 	if (duplex)
814 		reg |= IF_MODE_SFD;
815 	else
816 		reg |= IF_MODE_HD;
817 	reg |= speed;
818 	bus_write_4(sc->sc_base.sc_mem, MEMAC_IF_MODE, reg);
819 }
820 /** @} */
821