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