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