xref: /freebsd/sys/dev/xilinx/if_xae.c (revision d9a42747950146bf03cda7f6e25d219253f8a57a)
1 /*-
2  * SPDX-License-Identifier: BSD-2-Clause
3  *
4  * Copyright (c) 2019 Ruslan Bukin <br@bsdpad.com>
5  *
6  * This software was developed by SRI International and the University of
7  * Cambridge Computer Laboratory (Department of Computer Science and
8  * Technology) under DARPA contract HR0011-18-C-0016 ("ECATS"), as part of the
9  * DARPA SSITH research programme.
10  *
11  * Redistribution and use in source and binary forms, with or without
12  * modification, are permitted provided that the following conditions
13  * are met:
14  * 1. Redistributions of source code must retain the above copyright
15  *    notice, this list of conditions and the following disclaimer.
16  * 2. Redistributions in binary form must reproduce the above copyright
17  *    notice, this list of conditions and the following disclaimer in the
18  *    documentation and/or other materials provided with the distribution.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
21  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
24  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30  * SUCH DAMAGE.
31  */
32 
33 #include <sys/cdefs.h>
34 __FBSDID("$FreeBSD$");
35 
36 #include <sys/param.h>
37 #include <sys/systm.h>
38 #include <sys/bus.h>
39 #include <sys/kernel.h>
40 #include <sys/lock.h>
41 #include <sys/malloc.h>
42 #include <sys/mbuf.h>
43 #include <sys/module.h>
44 #include <sys/mutex.h>
45 #include <sys/rman.h>
46 #include <sys/socket.h>
47 #include <sys/sockio.h>
48 
49 #include <net/bpf.h>
50 #include <net/if.h>
51 #include <net/ethernet.h>
52 #include <net/if_dl.h>
53 #include <net/if_media.h>
54 #include <net/if_types.h>
55 #include <net/if_var.h>
56 
57 #include <machine/bus.h>
58 
59 #include <dev/mii/mii.h>
60 #include <dev/mii/miivar.h>
61 #include <dev/mii/tiphy.h>
62 #include <dev/ofw/ofw_bus.h>
63 #include <dev/ofw/ofw_bus_subr.h>
64 #include <dev/xilinx/if_xaereg.h>
65 #include <dev/xilinx/if_xaevar.h>
66 
67 #include <dev/xilinx/axidma.h>
68 
69 #include "miibus_if.h"
70 
71 #define	READ4(_sc, _reg) \
72 	bus_read_4((_sc)->res[0], _reg)
73 #define	WRITE4(_sc, _reg, _val) \
74 	bus_write_4((_sc)->res[0], _reg, _val)
75 
76 #define	READ8(_sc, _reg) \
77 	bus_read_8((_sc)->res[0], _reg)
78 #define	WRITE8(_sc, _reg, _val) \
79 	bus_write_8((_sc)->res[0], _reg, _val)
80 
81 #define	XAE_LOCK(sc)			mtx_lock(&(sc)->mtx)
82 #define	XAE_UNLOCK(sc)			mtx_unlock(&(sc)->mtx)
83 #define	XAE_ASSERT_LOCKED(sc)		mtx_assert(&(sc)->mtx, MA_OWNED)
84 #define	XAE_ASSERT_UNLOCKED(sc)		mtx_assert(&(sc)->mtx, MA_NOTOWNED)
85 
86 #define XAE_DEBUG
87 #undef XAE_DEBUG
88 
89 #ifdef XAE_DEBUG
90 #define dprintf(fmt, ...)  printf(fmt, ##__VA_ARGS__)
91 #else
92 #define dprintf(fmt, ...)
93 #endif
94 
95 #define	RX_QUEUE_SIZE		64
96 #define	TX_QUEUE_SIZE		64
97 #define	NUM_RX_MBUF		16
98 #define	BUFRING_SIZE		8192
99 #define	MDIO_CLK_DIV_DEFAULT	29
100 
101 #define	PHY1_RD(sc, _r)		\
102 	xae_miibus_read_reg(sc->dev, 1, _r)
103 #define	PHY1_WR(sc, _r, _v)	\
104 	xae_miibus_write_reg(sc->dev, 1, _r, _v)
105 
106 #define	PHY_RD(sc, _r)		\
107 	xae_miibus_read_reg(sc->dev, sc->phy_addr, _r)
108 #define	PHY_WR(sc, _r, _v)	\
109 	xae_miibus_write_reg(sc->dev, sc->phy_addr, _r, _v)
110 
111 /* Use this macro to access regs > 0x1f */
112 #define WRITE_TI_EREG(sc, reg, data) {					\
113 	PHY_WR(sc, MII_MMDACR, MMDACR_DADDRMASK);			\
114 	PHY_WR(sc, MII_MMDAADR, reg);					\
115 	PHY_WR(sc, MII_MMDACR, MMDACR_DADDRMASK | MMDACR_FN_DATANPI);	\
116 	PHY_WR(sc, MII_MMDAADR, data);					\
117 }
118 
119 /* Not documented, Xilinx VCU118 workaround */
120 #define	 CFG4_SGMII_TMR			0x160 /* bits 8:7 MUST be '10' */
121 #define	DP83867_SGMIICTL1		0xD3 /* not documented register */
122 #define	 SGMIICTL1_SGMII_6W		(1 << 14) /* no idea what it is */
123 
124 static struct resource_spec xae_spec[] = {
125 	{ SYS_RES_MEMORY,	0,	RF_ACTIVE },
126 	{ SYS_RES_IRQ,		0,	RF_ACTIVE },
127 	{ -1, 0 }
128 };
129 
130 static void xae_stop_locked(struct xae_softc *sc);
131 static void xae_setup_rxfilter(struct xae_softc *sc);
132 
133 static int
134 xae_rx_enqueue(struct xae_softc *sc, uint32_t n)
135 {
136 	struct mbuf *m;
137 	int i;
138 
139 	for (i = 0; i < n; i++) {
140 		m = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR);
141 		if (m == NULL) {
142 			device_printf(sc->dev,
143 			    "%s: Can't alloc rx mbuf\n", __func__);
144 			return (-1);
145 		}
146 
147 		m->m_pkthdr.len = m->m_len = m->m_ext.ext_size;
148 		xdma_enqueue_mbuf(sc->xchan_rx, &m, 0, 4, 4, XDMA_DEV_TO_MEM);
149 	}
150 
151 	return (0);
152 }
153 
154 static int
155 xae_get_phyaddr(phandle_t node, int *phy_addr)
156 {
157 	phandle_t phy_node;
158 	pcell_t phy_handle, phy_reg;
159 
160 	if (OF_getencprop(node, "phy-handle", (void *)&phy_handle,
161 	    sizeof(phy_handle)) <= 0)
162 		return (ENXIO);
163 
164 	phy_node = OF_node_from_xref(phy_handle);
165 
166 	if (OF_getencprop(phy_node, "reg", (void *)&phy_reg,
167 	    sizeof(phy_reg)) <= 0)
168 		return (ENXIO);
169 
170 	*phy_addr = phy_reg;
171 
172 	return (0);
173 }
174 
175 static int
176 xae_xdma_tx_intr(void *arg, xdma_transfer_status_t *status)
177 {
178 	xdma_transfer_status_t st;
179 	struct xae_softc *sc;
180 	if_t ifp;
181 	struct mbuf *m;
182 	int err;
183 
184 	sc = arg;
185 
186 	XAE_LOCK(sc);
187 
188 	ifp = sc->ifp;
189 
190 	for (;;) {
191 		err = xdma_dequeue_mbuf(sc->xchan_tx, &m, &st);
192 		if (err != 0) {
193 			break;
194 		}
195 
196 		if (st.error != 0) {
197 			if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
198 		}
199 
200 		m_freem(m);
201 	}
202 
203 	if_setdrvflagbits(ifp, 0, IFF_DRV_OACTIVE);
204 
205 	XAE_UNLOCK(sc);
206 
207 	return (0);
208 }
209 
210 static int
211 xae_xdma_rx_intr(void *arg, xdma_transfer_status_t *status)
212 {
213 	xdma_transfer_status_t st;
214 	struct xae_softc *sc;
215 	if_t ifp;
216 	struct mbuf *m;
217 	int err;
218 	uint32_t cnt_processed;
219 
220 	sc = arg;
221 
222 	dprintf("%s\n", __func__);
223 
224 	XAE_LOCK(sc);
225 
226 	ifp = sc->ifp;
227 
228 	cnt_processed = 0;
229 	for (;;) {
230 		err = xdma_dequeue_mbuf(sc->xchan_rx, &m, &st);
231 		if (err != 0) {
232 			break;
233 		}
234 		cnt_processed++;
235 
236 		if (st.error != 0) {
237 			if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
238 			m_freem(m);
239 			continue;
240 		}
241 
242 		m->m_pkthdr.len = m->m_len = st.transferred;
243 		m->m_pkthdr.rcvif = ifp;
244 		XAE_UNLOCK(sc);
245 		if_input(ifp, m);
246 		XAE_LOCK(sc);
247 	}
248 
249 	xae_rx_enqueue(sc, cnt_processed);
250 
251 	XAE_UNLOCK(sc);
252 
253 	return (0);
254 }
255 
256 static void
257 xae_qflush(if_t ifp)
258 {
259 }
260 
261 static int
262 xae_transmit_locked(if_t ifp)
263 {
264 	struct xae_softc *sc;
265 	struct mbuf *m;
266 	struct buf_ring *br;
267 	int error;
268 	int enq;
269 
270 	dprintf("%s\n", __func__);
271 
272 	sc = if_getsoftc(ifp);
273 	br = sc->br;
274 
275 	enq = 0;
276 
277 	while ((m = drbr_peek(ifp, br)) != NULL) {
278 		error = xdma_enqueue_mbuf(sc->xchan_tx,
279 		    &m, 0, 4, 4, XDMA_MEM_TO_DEV);
280 		if (error != 0) {
281 			/* No space in request queue available yet. */
282 			drbr_putback(ifp, br, m);
283 			break;
284 		}
285 
286 		drbr_advance(ifp, br);
287 
288 		enq++;
289 
290 		/* If anyone is interested give them a copy. */
291 		ETHER_BPF_MTAP(ifp, m);
292         }
293 
294 	if (enq > 0)
295 		xdma_queue_submit(sc->xchan_tx);
296 
297 	return (0);
298 }
299 
300 static int
301 xae_transmit(if_t ifp, struct mbuf *m)
302 {
303 	struct xae_softc *sc;
304 	int error;
305 
306 	dprintf("%s\n", __func__);
307 
308 	sc = if_getsoftc(ifp);
309 
310 	XAE_LOCK(sc);
311 
312 	error = drbr_enqueue(ifp, sc->br, m);
313 	if (error) {
314 		XAE_UNLOCK(sc);
315 		return (error);
316 	}
317 
318 	if ((if_getdrvflags(ifp) & (IFF_DRV_RUNNING | IFF_DRV_OACTIVE)) !=
319 	    IFF_DRV_RUNNING) {
320 		XAE_UNLOCK(sc);
321 		return (0);
322 	}
323 
324 	if (!sc->link_is_up) {
325 		XAE_UNLOCK(sc);
326 		return (0);
327 	}
328 
329 	error = xae_transmit_locked(ifp);
330 
331 	XAE_UNLOCK(sc);
332 
333 	return (error);
334 }
335 
336 static void
337 xae_stop_locked(struct xae_softc *sc)
338 {
339 	if_t ifp;
340 	uint32_t reg;
341 
342 	XAE_ASSERT_LOCKED(sc);
343 
344 	ifp = sc->ifp;
345 	if_setdrvflagbits(ifp, 0, (IFF_DRV_RUNNING | IFF_DRV_OACTIVE));
346 
347 	callout_stop(&sc->xae_callout);
348 
349 	/* Stop the transmitter */
350 	reg = READ4(sc, XAE_TC);
351 	reg &= ~TC_TX;
352 	WRITE4(sc, XAE_TC, reg);
353 
354 	/* Stop the receiver. */
355 	reg = READ4(sc, XAE_RCW1);
356 	reg &= ~RCW1_RX;
357 	WRITE4(sc, XAE_RCW1, reg);
358 }
359 
360 static uint64_t
361 xae_stat(struct xae_softc *sc, int counter_id)
362 {
363 	uint64_t new, old;
364 	uint64_t delta;
365 
366 	KASSERT(counter_id < XAE_MAX_COUNTERS,
367 		("counter %d is out of range", counter_id));
368 
369 	new = READ8(sc, XAE_STATCNT(counter_id));
370 	old = sc->counters[counter_id];
371 
372 	if (new >= old)
373 		delta = new - old;
374 	else
375 		delta = UINT64_MAX - old + new;
376 	sc->counters[counter_id] = new;
377 
378 	return (delta);
379 }
380 
381 static void
382 xae_harvest_stats(struct xae_softc *sc)
383 {
384 	if_t ifp;
385 
386 	ifp = sc->ifp;
387 
388 	if_inc_counter(ifp, IFCOUNTER_IPACKETS, xae_stat(sc, RX_GOOD_FRAMES));
389 	if_inc_counter(ifp, IFCOUNTER_IMCASTS, xae_stat(sc, RX_GOOD_MCASTS));
390 	if_inc_counter(ifp, IFCOUNTER_IERRORS,
391 	    xae_stat(sc, RX_FRAME_CHECK_SEQ_ERROR) +
392 	    xae_stat(sc, RX_LEN_OUT_OF_RANGE) +
393 	    xae_stat(sc, RX_ALIGNMENT_ERRORS));
394 
395 	if_inc_counter(ifp, IFCOUNTER_OBYTES, xae_stat(sc, TX_BYTES));
396 	if_inc_counter(ifp, IFCOUNTER_OPACKETS, xae_stat(sc, TX_GOOD_FRAMES));
397 	if_inc_counter(ifp, IFCOUNTER_OMCASTS, xae_stat(sc, TX_GOOD_MCASTS));
398 	if_inc_counter(ifp, IFCOUNTER_OERRORS,
399 	    xae_stat(sc, TX_GOOD_UNDERRUN_ERRORS));
400 
401 	if_inc_counter(ifp, IFCOUNTER_COLLISIONS,
402 	    xae_stat(sc, TX_SINGLE_COLLISION_FRAMES) +
403 	    xae_stat(sc, TX_MULTI_COLLISION_FRAMES) +
404 	    xae_stat(sc, TX_LATE_COLLISIONS) +
405 	    xae_stat(sc, TX_EXCESS_COLLISIONS));
406 }
407 
408 static void
409 xae_tick(void *arg)
410 {
411 	struct xae_softc *sc;
412 	if_t ifp;
413 	int link_was_up;
414 
415 	sc = arg;
416 
417 	XAE_ASSERT_LOCKED(sc);
418 
419 	ifp = sc->ifp;
420 
421 	if (!(if_getdrvflags(ifp) & IFF_DRV_RUNNING))
422 		return;
423 
424 	/* Gather stats from hardware counters. */
425 	xae_harvest_stats(sc);
426 
427 	/* Check the media status. */
428 	link_was_up = sc->link_is_up;
429 	mii_tick(sc->mii_softc);
430 	if (sc->link_is_up && !link_was_up)
431 		xae_transmit_locked(sc->ifp);
432 
433 	/* Schedule another check one second from now. */
434 	callout_reset(&sc->xae_callout, hz, xae_tick, sc);
435 }
436 
437 static void
438 xae_init_locked(struct xae_softc *sc)
439 {
440 	if_t ifp;
441 
442 	XAE_ASSERT_LOCKED(sc);
443 
444 	ifp = sc->ifp;
445 	if (if_getdrvflags(ifp) & IFF_DRV_RUNNING)
446 		return;
447 
448 	if_setdrvflagbits(ifp, IFF_DRV_RUNNING, 0);
449 
450 	xae_setup_rxfilter(sc);
451 
452 	/* Enable the transmitter */
453 	WRITE4(sc, XAE_TC, TC_TX);
454 
455 	/* Enable the receiver. */
456 	WRITE4(sc, XAE_RCW1, RCW1_RX);
457 
458 	/*
459 	 * Call mii_mediachg() which will call back into xae_miibus_statchg()
460 	 * to set up the remaining config registers based on current media.
461 	 */
462 	mii_mediachg(sc->mii_softc);
463 	callout_reset(&sc->xae_callout, hz, xae_tick, sc);
464 }
465 
466 static void
467 xae_init(void *arg)
468 {
469 	struct xae_softc *sc;
470 
471 	sc = arg;
472 
473 	XAE_LOCK(sc);
474 	xae_init_locked(sc);
475 	XAE_UNLOCK(sc);
476 }
477 
478 static void
479 xae_media_status(if_t  ifp, struct ifmediareq *ifmr)
480 {
481 	struct xae_softc *sc;
482 	struct mii_data *mii;
483 
484 	sc = if_getsoftc(ifp);
485 	mii = sc->mii_softc;
486 
487 	XAE_LOCK(sc);
488 	mii_pollstat(mii);
489 	ifmr->ifm_active = mii->mii_media_active;
490 	ifmr->ifm_status = mii->mii_media_status;
491 	XAE_UNLOCK(sc);
492 }
493 
494 static int
495 xae_media_change_locked(struct xae_softc *sc)
496 {
497 
498 	return (mii_mediachg(sc->mii_softc));
499 }
500 
501 static int
502 xae_media_change(if_t  ifp)
503 {
504 	struct xae_softc *sc;
505 	int error;
506 
507 	sc = if_getsoftc(ifp);
508 
509 	XAE_LOCK(sc);
510 	error = xae_media_change_locked(sc);
511 	XAE_UNLOCK(sc);
512 
513 	return (error);
514 }
515 
516 static u_int
517 xae_write_maddr(void *arg, struct sockaddr_dl *sdl, u_int cnt)
518 {
519 	struct xae_softc *sc = arg;
520 	uint32_t reg;
521 	uint8_t *ma;
522 
523 	if (cnt >= XAE_MULTICAST_TABLE_SIZE)
524 		return (1);
525 
526 	ma = LLADDR(sdl);
527 
528 	reg = READ4(sc, XAE_FFC) & 0xffffff00;
529 	reg |= cnt;
530 	WRITE4(sc, XAE_FFC, reg);
531 
532 	reg = (ma[0]);
533 	reg |= (ma[1] << 8);
534 	reg |= (ma[2] << 16);
535 	reg |= (ma[3] << 24);
536 	WRITE4(sc, XAE_FFV(0), reg);
537 
538 	reg = ma[4];
539 	reg |= ma[5] << 8;
540 	WRITE4(sc, XAE_FFV(1), reg);
541 
542 	return (1);
543 }
544 
545 static void
546 xae_setup_rxfilter(struct xae_softc *sc)
547 {
548 	if_t ifp;
549 	uint32_t reg;
550 
551 	XAE_ASSERT_LOCKED(sc);
552 
553 	ifp = sc->ifp;
554 
555 	/*
556 	 * Set the multicast (group) filter hash.
557 	 */
558 	if ((if_getflags(ifp) & (IFF_ALLMULTI | IFF_PROMISC)) != 0) {
559 		reg = READ4(sc, XAE_FFC);
560 		reg |= FFC_PM;
561 		WRITE4(sc, XAE_FFC, reg);
562 	} else {
563 		reg = READ4(sc, XAE_FFC);
564 		reg &= ~FFC_PM;
565 		WRITE4(sc, XAE_FFC, reg);
566 
567 		if_foreach_llmaddr(ifp, xae_write_maddr, sc);
568 	}
569 
570 	/*
571 	 * Set the primary address.
572 	 */
573 	reg = sc->macaddr[0];
574 	reg |= (sc->macaddr[1] << 8);
575 	reg |= (sc->macaddr[2] << 16);
576 	reg |= (sc->macaddr[3] << 24);
577 	WRITE4(sc, XAE_UAW0, reg);
578 
579 	reg = sc->macaddr[4];
580 	reg |= (sc->macaddr[5] << 8);
581 	WRITE4(sc, XAE_UAW1, reg);
582 }
583 
584 static int
585 xae_ioctl(if_t ifp, u_long cmd, caddr_t data)
586 {
587 	struct xae_softc *sc;
588 	struct mii_data *mii;
589 	struct ifreq *ifr;
590 	int mask, error;
591 
592 	sc = if_getsoftc(ifp);
593 	ifr = (struct ifreq *)data;
594 
595 	error = 0;
596 	switch (cmd) {
597 	case SIOCSIFFLAGS:
598 		XAE_LOCK(sc);
599 		if (if_getflags(ifp) & IFF_UP) {
600 			if (if_getdrvflags(ifp) & IFF_DRV_RUNNING) {
601 				if ((if_getflags(ifp) ^ sc->if_flags) &
602 				    (IFF_PROMISC | IFF_ALLMULTI))
603 					xae_setup_rxfilter(sc);
604 			} else {
605 				if (!sc->is_detaching)
606 					xae_init_locked(sc);
607 			}
608 		} else {
609 			if (if_getdrvflags(ifp) & IFF_DRV_RUNNING)
610 				xae_stop_locked(sc);
611 		}
612 		sc->if_flags = if_getflags(ifp);
613 		XAE_UNLOCK(sc);
614 		break;
615 	case SIOCADDMULTI:
616 	case SIOCDELMULTI:
617 		if (if_getdrvflags(ifp) & IFF_DRV_RUNNING) {
618 			XAE_LOCK(sc);
619 			xae_setup_rxfilter(sc);
620 			XAE_UNLOCK(sc);
621 		}
622 		break;
623 	case SIOCSIFMEDIA:
624 	case SIOCGIFMEDIA:
625 		mii = sc->mii_softc;
626 		error = ifmedia_ioctl(ifp, ifr, &mii->mii_media, cmd);
627 		break;
628 	case SIOCSIFCAP:
629 		mask = if_getcapenable(ifp) ^ ifr->ifr_reqcap;
630 		if (mask & IFCAP_VLAN_MTU) {
631 			/* No work to do except acknowledge the change took */
632 			if_togglecapenable(ifp, IFCAP_VLAN_MTU);
633 		}
634 		break;
635 
636 	default:
637 		error = ether_ioctl(ifp, cmd, data);
638 		break;
639 	}
640 
641 	return (error);
642 }
643 
644 static void
645 xae_intr(void *arg)
646 {
647 
648 }
649 
650 static int
651 xae_get_hwaddr(struct xae_softc *sc, uint8_t *hwaddr)
652 {
653 	phandle_t node;
654 	int len;
655 
656 	node = ofw_bus_get_node(sc->dev);
657 
658 	/* Check if there is property */
659 	if ((len = OF_getproplen(node, "local-mac-address")) <= 0)
660 		return (EINVAL);
661 
662 	if (len != ETHER_ADDR_LEN)
663 		return (EINVAL);
664 
665 	OF_getprop(node, "local-mac-address", hwaddr,
666 	    ETHER_ADDR_LEN);
667 
668 	return (0);
669 }
670 
671 static int
672 mdio_wait(struct xae_softc *sc)
673 {
674 	uint32_t reg;
675 	int timeout;
676 
677 	timeout = 200;
678 
679 	do {
680 		reg = READ4(sc, XAE_MDIO_CTRL);
681 		if (reg & MDIO_CTRL_READY)
682 			break;
683 		DELAY(1);
684 	} while (timeout--);
685 
686 	if (timeout <= 0) {
687 		printf("Failed to get MDIO ready\n");
688 		return (1);
689 	}
690 
691 	return (0);
692 }
693 
694 static int
695 xae_miibus_read_reg(device_t dev, int phy, int reg)
696 {
697 	struct xae_softc *sc;
698 	uint32_t mii;
699 	int rv;
700 
701 	sc = device_get_softc(dev);
702 
703 	if (mdio_wait(sc))
704 		return (0);
705 
706 	mii = MDIO_CTRL_TX_OP_READ | MDIO_CTRL_INITIATE;
707 	mii |= (reg << MDIO_TX_REGAD_S);
708 	mii |= (phy << MDIO_TX_PHYAD_S);
709 
710 	WRITE4(sc, XAE_MDIO_CTRL, mii);
711 
712 	if (mdio_wait(sc))
713 		return (0);
714 
715 	rv = READ4(sc, XAE_MDIO_READ);
716 
717 	return (rv);
718 }
719 
720 static int
721 xae_miibus_write_reg(device_t dev, int phy, int reg, int val)
722 {
723 	struct xae_softc *sc;
724 	uint32_t mii;
725 
726 	sc = device_get_softc(dev);
727 
728 	if (mdio_wait(sc))
729 		return (1);
730 
731 	mii = MDIO_CTRL_TX_OP_WRITE | MDIO_CTRL_INITIATE;
732 	mii |= (reg << MDIO_TX_REGAD_S);
733 	mii |= (phy << MDIO_TX_PHYAD_S);
734 
735 	WRITE4(sc, XAE_MDIO_WRITE, val);
736 	WRITE4(sc, XAE_MDIO_CTRL, mii);
737 
738 	if (mdio_wait(sc))
739 		return (1);
740 
741 	return (0);
742 }
743 
744 static void
745 xae_phy_fixup(struct xae_softc *sc)
746 {
747 	uint32_t reg;
748 
749 	do {
750 		WRITE_TI_EREG(sc, DP83867_SGMIICTL1, SGMIICTL1_SGMII_6W);
751 		PHY_WR(sc, DP83867_PHYCR, PHYCR_SGMII_EN);
752 
753 		reg = PHY_RD(sc, DP83867_CFG2);
754 		reg &= ~CFG2_SPEED_OPT_ATTEMPT_CNT_M;
755 		reg |= (CFG2_SPEED_OPT_ATTEMPT_CNT_4);
756 		reg |= CFG2_INTERRUPT_POLARITY;
757 		reg |= CFG2_SPEED_OPT_ENHANCED_EN;
758 		reg |= CFG2_SPEED_OPT_10M_EN;
759 		PHY_WR(sc, DP83867_CFG2, reg);
760 
761 		WRITE_TI_EREG(sc, DP83867_CFG4, CFG4_SGMII_TMR);
762 		PHY_WR(sc, MII_BMCR,
763 		    BMCR_AUTOEN | BMCR_FDX | BMCR_SPEED1 | BMCR_RESET);
764 	} while (PHY1_RD(sc, MII_BMCR) == 0x0ffff);
765 
766 	do {
767 		PHY1_WR(sc, MII_BMCR,
768 		    BMCR_AUTOEN | BMCR_FDX | BMCR_SPEED1 | BMCR_STARTNEG);
769 		DELAY(40000);
770 	} while ((PHY1_RD(sc, MII_BMSR) & BMSR_ACOMP) == 0);
771 }
772 
773 static int
774 get_xdma_std(struct xae_softc *sc)
775 {
776 
777 	sc->xdma_tx = xdma_ofw_get(sc->dev, "tx");
778 	if (sc->xdma_tx == NULL)
779 		return (ENXIO);
780 
781 	sc->xdma_rx = xdma_ofw_get(sc->dev, "rx");
782 	if (sc->xdma_rx == NULL) {
783 		xdma_put(sc->xdma_tx);
784 		return (ENXIO);
785 	}
786 
787 	return (0);
788 }
789 
790 static int
791 get_xdma_axistream(struct xae_softc *sc)
792 {
793 	struct axidma_fdt_data *data;
794 	device_t dma_dev;
795 	phandle_t node;
796 	pcell_t prop;
797 	size_t len;
798 
799 	node = ofw_bus_get_node(sc->dev);
800 	len = OF_getencprop(node, "axistream-connected", &prop, sizeof(prop));
801 	if (len != sizeof(prop)) {
802 		device_printf(sc->dev,
803 		    "%s: Couldn't get axistream-connected prop.\n", __func__);
804 		return (ENXIO);
805 	}
806 	dma_dev = OF_device_from_xref(prop);
807 	if (dma_dev == NULL) {
808 		device_printf(sc->dev, "Could not get DMA device by xref.\n");
809 		return (ENXIO);
810 	}
811 
812 	sc->xdma_tx = xdma_get(sc->dev, dma_dev);
813 	if (sc->xdma_tx == NULL) {
814 		device_printf(sc->dev, "Could not find DMA controller.\n");
815 		return (ENXIO);
816 	}
817 	data = malloc(sizeof(struct axidma_fdt_data),
818 	    M_DEVBUF, (M_WAITOK | M_ZERO));
819 	data->id = AXIDMA_TX_CHAN;
820 	sc->xdma_tx->data = data;
821 
822 	sc->xdma_rx = xdma_get(sc->dev, dma_dev);
823 	if (sc->xdma_rx == NULL) {
824 		device_printf(sc->dev, "Could not find DMA controller.\n");
825 		return (ENXIO);
826 	}
827 	data = malloc(sizeof(struct axidma_fdt_data),
828 	    M_DEVBUF, (M_WAITOK | M_ZERO));
829 	data->id = AXIDMA_RX_CHAN;
830 	sc->xdma_rx->data = data;
831 
832 	return (0);
833 }
834 
835 static int
836 setup_xdma(struct xae_softc *sc)
837 {
838 	device_t dev;
839 	vmem_t *vmem;
840 	int error;
841 
842 	dev = sc->dev;
843 
844 	/* Get xDMA controller */
845 	error = get_xdma_std(sc);
846 
847 	if (error) {
848 		device_printf(sc->dev,
849 		    "Fallback to axistream-connected property\n");
850 		error = get_xdma_axistream(sc);
851 	}
852 
853 	if (error) {
854 		device_printf(dev, "Could not find xDMA controllers.\n");
855 		return (ENXIO);
856 	}
857 
858 	/* Alloc xDMA TX virtual channel. */
859 	sc->xchan_tx = xdma_channel_alloc(sc->xdma_tx, 0);
860 	if (sc->xchan_tx == NULL) {
861 		device_printf(dev, "Can't alloc virtual DMA TX channel.\n");
862 		return (ENXIO);
863 	}
864 
865 	/* Setup interrupt handler. */
866 	error = xdma_setup_intr(sc->xchan_tx, 0,
867 	    xae_xdma_tx_intr, sc, &sc->ih_tx);
868 	if (error) {
869 		device_printf(sc->dev,
870 		    "Can't setup xDMA TX interrupt handler.\n");
871 		return (ENXIO);
872 	}
873 
874 	/* Alloc xDMA RX virtual channel. */
875 	sc->xchan_rx = xdma_channel_alloc(sc->xdma_rx, 0);
876 	if (sc->xchan_rx == NULL) {
877 		device_printf(dev, "Can't alloc virtual DMA RX channel.\n");
878 		return (ENXIO);
879 	}
880 
881 	/* Setup interrupt handler. */
882 	error = xdma_setup_intr(sc->xchan_rx, XDMA_INTR_NET,
883 	    xae_xdma_rx_intr, sc, &sc->ih_rx);
884 	if (error) {
885 		device_printf(sc->dev,
886 		    "Can't setup xDMA RX interrupt handler.\n");
887 		return (ENXIO);
888 	}
889 
890 	/* Setup bounce buffer */
891 	vmem = xdma_get_memory(dev);
892 	if (vmem) {
893 		xchan_set_memory(sc->xchan_tx, vmem);
894 		xchan_set_memory(sc->xchan_rx, vmem);
895 	}
896 
897 	xdma_prep_sg(sc->xchan_tx,
898 	    TX_QUEUE_SIZE,	/* xchan requests queue size */
899 	    MCLBYTES,	/* maxsegsize */
900 	    8,		/* maxnsegs */
901 	    16,		/* alignment */
902 	    0,		/* boundary */
903 	    BUS_SPACE_MAXADDR_32BIT,
904 	    BUS_SPACE_MAXADDR);
905 
906 	xdma_prep_sg(sc->xchan_rx,
907 	    RX_QUEUE_SIZE,	/* xchan requests queue size */
908 	    MCLBYTES,	/* maxsegsize */
909 	    1,		/* maxnsegs */
910 	    16,		/* alignment */
911 	    0,		/* boundary */
912 	    BUS_SPACE_MAXADDR_32BIT,
913 	    BUS_SPACE_MAXADDR);
914 
915 	return (0);
916 }
917 
918 static int
919 xae_probe(device_t dev)
920 {
921 
922 	if (!ofw_bus_status_okay(dev))
923 		return (ENXIO);
924 
925 	if (!ofw_bus_is_compatible(dev, "xlnx,axi-ethernet-1.00.a"))
926 		return (ENXIO);
927 
928 	device_set_desc(dev, "Xilinx AXI Ethernet");
929 
930 	return (BUS_PROBE_DEFAULT);
931 }
932 
933 static int
934 xae_attach(device_t dev)
935 {
936 	struct xae_softc *sc;
937 	if_t ifp;
938 	phandle_t node;
939 	uint32_t reg;
940 	int error;
941 
942 	sc = device_get_softc(dev);
943 	sc->dev = dev;
944 	node = ofw_bus_get_node(dev);
945 
946 	if (setup_xdma(sc) != 0) {
947 		device_printf(dev, "Could not setup xDMA.\n");
948 		return (ENXIO);
949 	}
950 
951 	mtx_init(&sc->mtx, device_get_nameunit(sc->dev),
952 	    MTX_NETWORK_LOCK, MTX_DEF);
953 
954 	sc->br = buf_ring_alloc(BUFRING_SIZE, M_DEVBUF,
955 	    M_NOWAIT, &sc->mtx);
956 	if (sc->br == NULL)
957 		return (ENOMEM);
958 
959 	if (bus_alloc_resources(dev, xae_spec, sc->res)) {
960 		device_printf(dev, "could not allocate resources\n");
961 		return (ENXIO);
962 	}
963 
964 	/* Memory interface */
965 	sc->bst = rman_get_bustag(sc->res[0]);
966 	sc->bsh = rman_get_bushandle(sc->res[0]);
967 
968 	device_printf(sc->dev, "Identification: %x\n",
969 	    READ4(sc, XAE_IDENT));
970 
971 	/* Get MAC addr */
972 	if (xae_get_hwaddr(sc, sc->macaddr)) {
973 		device_printf(sc->dev, "can't get mac\n");
974 		return (ENXIO);
975 	}
976 
977 	/* Enable MII clock */
978 	reg = (MDIO_CLK_DIV_DEFAULT << MDIO_SETUP_CLK_DIV_S);
979 	reg |= MDIO_SETUP_ENABLE;
980 	WRITE4(sc, XAE_MDIO_SETUP, reg);
981 	if (mdio_wait(sc))
982 		return (ENXIO);
983 
984 	callout_init_mtx(&sc->xae_callout, &sc->mtx, 0);
985 
986 	/* Setup interrupt handler. */
987 	error = bus_setup_intr(dev, sc->res[1], INTR_TYPE_NET | INTR_MPSAFE,
988 	    NULL, xae_intr, sc, &sc->intr_cookie);
989 	if (error != 0) {
990 		device_printf(dev, "could not setup interrupt handler.\n");
991 		return (ENXIO);
992 	}
993 
994 	/* Set up the ethernet interface. */
995 	sc->ifp = ifp = if_alloc(IFT_ETHER);
996 	if (ifp == NULL) {
997 		device_printf(dev, "could not allocate ifp.\n");
998 		return (ENXIO);
999 	}
1000 
1001 	if_setsoftc(ifp, sc);
1002 	if_initname(ifp, device_get_name(dev), device_get_unit(dev));
1003 	if_setflags(ifp, IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST);
1004 	if_setcapabilities(ifp, IFCAP_VLAN_MTU);
1005 	if_setcapenable(ifp, if_getcapabilities(ifp));
1006 	if_settransmitfn(ifp, xae_transmit);
1007 	if_setqflushfn(ifp, xae_qflush);
1008 	if_setioctlfn(ifp, xae_ioctl);
1009 	if_setinitfn(ifp, xae_init);
1010 	if_setsendqlen(ifp, TX_DESC_COUNT - 1);
1011 	if_setsendqready(ifp);
1012 
1013 	if (xae_get_phyaddr(node, &sc->phy_addr) != 0)
1014 		return (ENXIO);
1015 
1016 	/* Attach the mii driver. */
1017 	error = mii_attach(dev, &sc->miibus, ifp, xae_media_change,
1018 	    xae_media_status, BMSR_DEFCAPMASK, sc->phy_addr,
1019 	    MII_OFFSET_ANY, 0);
1020 
1021 	if (error != 0) {
1022 		device_printf(dev, "PHY attach failed\n");
1023 		return (ENXIO);
1024 	}
1025 	sc->mii_softc = device_get_softc(sc->miibus);
1026 
1027 	/* Apply vcu118 workaround. */
1028 	if (OF_getproplen(node, "xlnx,vcu118") >= 0)
1029 		xae_phy_fixup(sc);
1030 
1031 	/* All ready to run, attach the ethernet interface. */
1032 	ether_ifattach(ifp, sc->macaddr);
1033 	sc->is_attached = true;
1034 
1035 	xae_rx_enqueue(sc, NUM_RX_MBUF);
1036 	xdma_queue_submit(sc->xchan_rx);
1037 
1038 	return (0);
1039 }
1040 
1041 static int
1042 xae_detach(device_t dev)
1043 {
1044 	struct xae_softc *sc;
1045 	if_t ifp;
1046 
1047 	sc = device_get_softc(dev);
1048 
1049 	KASSERT(mtx_initialized(&sc->mtx), ("%s: mutex not initialized",
1050 	    device_get_nameunit(dev)));
1051 
1052 	ifp = sc->ifp;
1053 
1054 	/* Only cleanup if attach succeeded. */
1055 	if (device_is_attached(dev)) {
1056 		XAE_LOCK(sc);
1057 		xae_stop_locked(sc);
1058 		XAE_UNLOCK(sc);
1059 		callout_drain(&sc->xae_callout);
1060 		ether_ifdetach(ifp);
1061 	}
1062 
1063 	if (sc->miibus != NULL)
1064 		device_delete_child(dev, sc->miibus);
1065 
1066 	if (ifp != NULL)
1067 		if_free(ifp);
1068 
1069 	mtx_destroy(&sc->mtx);
1070 
1071 	bus_teardown_intr(dev, sc->res[1], sc->intr_cookie);
1072 
1073 	bus_release_resources(dev, xae_spec, sc->res);
1074 
1075 	xdma_channel_free(sc->xchan_tx);
1076 	xdma_channel_free(sc->xchan_rx);
1077 	xdma_put(sc->xdma_tx);
1078 	xdma_put(sc->xdma_rx);
1079 
1080 	return (0);
1081 }
1082 
1083 static void
1084 xae_miibus_statchg(device_t dev)
1085 {
1086 	struct xae_softc *sc;
1087 	struct mii_data *mii;
1088 	uint32_t reg;
1089 
1090 	/*
1091 	 * Called by the MII bus driver when the PHY establishes
1092 	 * link to set the MAC interface registers.
1093 	 */
1094 
1095 	sc = device_get_softc(dev);
1096 
1097 	XAE_ASSERT_LOCKED(sc);
1098 
1099 	mii = sc->mii_softc;
1100 
1101 	if (mii->mii_media_status & IFM_ACTIVE)
1102 		sc->link_is_up = true;
1103 	else
1104 		sc->link_is_up = false;
1105 
1106 	switch (IFM_SUBTYPE(mii->mii_media_active)) {
1107 	case IFM_1000_T:
1108 	case IFM_1000_SX:
1109 		reg = SPEED_1000;
1110 		break;
1111 	case IFM_100_TX:
1112 		reg = SPEED_100;
1113 		break;
1114 	case IFM_10_T:
1115 		reg = SPEED_10;
1116 		break;
1117 	case IFM_NONE:
1118 		sc->link_is_up = false;
1119 		return;
1120 	default:
1121 		sc->link_is_up = false;
1122 		device_printf(dev, "Unsupported media %u\n",
1123 		    IFM_SUBTYPE(mii->mii_media_active));
1124 		return;
1125 	}
1126 
1127 	WRITE4(sc, XAE_SPEED, reg);
1128 }
1129 
1130 static device_method_t xae_methods[] = {
1131 	DEVMETHOD(device_probe,		xae_probe),
1132 	DEVMETHOD(device_attach,	xae_attach),
1133 	DEVMETHOD(device_detach,	xae_detach),
1134 
1135 	/* MII Interface */
1136 	DEVMETHOD(miibus_readreg,	xae_miibus_read_reg),
1137 	DEVMETHOD(miibus_writereg,	xae_miibus_write_reg),
1138 	DEVMETHOD(miibus_statchg,	xae_miibus_statchg),
1139 	{ 0, 0 }
1140 };
1141 
1142 driver_t xae_driver = {
1143 	"xae",
1144 	xae_methods,
1145 	sizeof(struct xae_softc),
1146 };
1147 
1148 DRIVER_MODULE(xae, simplebus, xae_driver, 0, 0);
1149 DRIVER_MODULE(miibus, xae, miibus_driver, 0, 0);
1150 
1151 MODULE_DEPEND(xae, ether, 1, 1, 1);
1152 MODULE_DEPEND(xae, miibus, 1, 1, 1);
1153