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