]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/dev/xilinx/if_xae.c
MFV r353141 (by phillip):
[FreeBSD/FreeBSD.git] / sys / dev / xilinx / if_xae.c
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 "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
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
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
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         struct ifnet *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         ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
202
203         XAE_UNLOCK(sc);
204
205         return (0);
206 }
207
208 static int
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         struct ifnet *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                 (*ifp->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
255 xae_qflush(struct ifnet *ifp)
256 {
257         struct xae_softc *sc;
258
259         sc = ifp->if_softc;
260 }
261
262 static int
263 xae_transmit_locked(struct ifnet *ifp)
264 {
265         struct xae_softc *sc;
266         struct mbuf *m;
267         struct buf_ring *br;
268         int error;
269         int enq;
270
271         dprintf("%s\n", __func__);
272
273         sc = ifp->if_softc;
274         br = sc->br;
275
276         enq = 0;
277
278         while ((m = drbr_peek(ifp, br)) != NULL) {
279                 error = xdma_enqueue_mbuf(sc->xchan_tx,
280                     &m, 0, 4, 4, XDMA_MEM_TO_DEV);
281                 if (error != 0) {
282                         /* No space in request queue available yet. */
283                         drbr_putback(ifp, br, m);
284                         break;
285                 }
286
287                 drbr_advance(ifp, br);
288
289                 enq++;
290
291                 /* If anyone is interested give them a copy. */
292                 ETHER_BPF_MTAP(ifp, m);
293         }
294
295         if (enq > 0)
296                 xdma_queue_submit(sc->xchan_tx);
297
298         return (0);
299 }
300
301 static int
302 xae_transmit(struct ifnet *ifp, struct mbuf *m)
303 {
304         struct xae_softc *sc;
305         int error;
306
307         dprintf("%s\n", __func__);
308
309         sc = ifp->if_softc;
310
311         XAE_LOCK(sc);
312
313         error = drbr_enqueue(ifp, sc->br, m);
314         if (error) {
315                 XAE_UNLOCK(sc);
316                 return (error);
317         }
318
319         if ((ifp->if_drv_flags & (IFF_DRV_RUNNING | IFF_DRV_OACTIVE)) !=
320             IFF_DRV_RUNNING) {
321                 XAE_UNLOCK(sc);
322                 return (0);
323         }
324
325         if (!sc->link_is_up) {
326                 XAE_UNLOCK(sc);
327                 return (0);
328         }
329
330         error = xae_transmit_locked(ifp);
331
332         XAE_UNLOCK(sc);
333
334         return (error);
335 }
336
337 static void
338 xae_stop_locked(struct xae_softc *sc)
339 {
340         struct ifnet *ifp;
341         uint32_t reg;
342
343         XAE_ASSERT_LOCKED(sc);
344
345         ifp = sc->ifp;
346         ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
347
348         callout_stop(&sc->xae_callout);
349
350         /* Stop the transmitter */
351         reg = READ4(sc, XAE_TC);
352         reg &= ~TC_TX;
353         WRITE4(sc, XAE_TC, reg);
354
355         /* Stop the receiver. */
356         reg = READ4(sc, XAE_RCW1);
357         reg &= ~RCW1_RX;
358         WRITE4(sc, XAE_RCW1, reg);
359 }
360
361 static uint64_t
362 xae_stat(struct xae_softc *sc, int counter_id)
363 {
364         uint64_t new, old;
365         uint64_t delta;
366
367         KASSERT(counter_id < XAE_MAX_COUNTERS,
368                 ("counter %d is out of range", counter_id));
369
370         new = READ8(sc, XAE_STATCNT(counter_id));
371         old = sc->counters[counter_id];
372
373         if (new >= old)
374                 delta = new - old;
375         else
376                 delta = UINT64_MAX - old + new;
377         sc->counters[counter_id] = new;
378
379         return (delta);
380 }
381
382 static void
383 xae_harvest_stats(struct xae_softc *sc)
384 {
385         struct ifnet *ifp;
386
387         ifp = sc->ifp;
388
389         if_inc_counter(ifp, IFCOUNTER_IPACKETS, xae_stat(sc, RX_GOOD_FRAMES));
390         if_inc_counter(ifp, IFCOUNTER_IMCASTS, xae_stat(sc, RX_GOOD_MCASTS));
391         if_inc_counter(ifp, IFCOUNTER_IERRORS,
392             xae_stat(sc, RX_FRAME_CHECK_SEQ_ERROR) +
393             xae_stat(sc, RX_LEN_OUT_OF_RANGE) +
394             xae_stat(sc, RX_ALIGNMENT_ERRORS));
395
396         if_inc_counter(ifp, IFCOUNTER_OBYTES, xae_stat(sc, TX_BYTES));
397         if_inc_counter(ifp, IFCOUNTER_OPACKETS, xae_stat(sc, TX_GOOD_FRAMES));
398         if_inc_counter(ifp, IFCOUNTER_OMCASTS, xae_stat(sc, TX_GOOD_MCASTS));
399         if_inc_counter(ifp, IFCOUNTER_OERRORS,
400             xae_stat(sc, TX_GOOD_UNDERRUN_ERRORS));
401
402         if_inc_counter(ifp, IFCOUNTER_COLLISIONS,
403             xae_stat(sc, TX_SINGLE_COLLISION_FRAMES) +
404             xae_stat(sc, TX_MULTI_COLLISION_FRAMES) +
405             xae_stat(sc, TX_LATE_COLLISIONS) +
406             xae_stat(sc, TX_EXCESS_COLLISIONS));
407 }
408
409 static void
410 xae_tick(void *arg)
411 {
412         struct xae_softc *sc;
413         struct ifnet *ifp;
414         int link_was_up;
415
416         sc = arg;
417
418         XAE_ASSERT_LOCKED(sc);
419
420         ifp = sc->ifp;
421
422         if (!(ifp->if_drv_flags & IFF_DRV_RUNNING))
423                 return;
424
425         /* Gather stats from hardware counters. */
426         xae_harvest_stats(sc);
427
428         /* Check the media status. */
429         link_was_up = sc->link_is_up;
430         mii_tick(sc->mii_softc);
431         if (sc->link_is_up && !link_was_up)
432                 xae_transmit_locked(sc->ifp);
433
434         /* Schedule another check one second from now. */
435         callout_reset(&sc->xae_callout, hz, xae_tick, sc);
436 }
437
438 static void
439 xae_init_locked(struct xae_softc *sc)
440 {
441         struct ifnet *ifp;
442
443         XAE_ASSERT_LOCKED(sc);
444
445         ifp = sc->ifp;
446         if (ifp->if_drv_flags & IFF_DRV_RUNNING)
447                 return;
448
449         ifp->if_drv_flags |= IFF_DRV_RUNNING;
450
451         xae_setup_rxfilter(sc);
452
453         /* Enable the transmitter */
454         WRITE4(sc, XAE_TC, TC_TX);
455
456         /* Enable the receiver. */
457         WRITE4(sc, XAE_RCW1, RCW1_RX);
458
459         /*
460          * Call mii_mediachg() which will call back into xae_miibus_statchg()
461          * to set up the remaining config registers based on current media.
462          */
463         mii_mediachg(sc->mii_softc);
464         callout_reset(&sc->xae_callout, hz, xae_tick, sc);
465 }
466
467 static void
468 xae_init(void *arg)
469 {
470         struct xae_softc *sc;
471
472         sc = arg;
473
474         XAE_LOCK(sc);
475         xae_init_locked(sc);
476         XAE_UNLOCK(sc);
477 }
478
479 static void
480 xae_media_status(struct ifnet * ifp, struct ifmediareq *ifmr)
481 {
482         struct xae_softc *sc;
483         struct mii_data *mii;
484
485         sc = ifp->if_softc;
486         mii = sc->mii_softc;
487
488         XAE_LOCK(sc);
489         mii_pollstat(mii);
490         ifmr->ifm_active = mii->mii_media_active;
491         ifmr->ifm_status = mii->mii_media_status;
492         XAE_UNLOCK(sc);
493 }
494
495 static int
496 xae_media_change_locked(struct xae_softc *sc)
497 {
498
499         return (mii_mediachg(sc->mii_softc));
500 }
501
502 static int
503 xae_media_change(struct ifnet * ifp)
504 {
505         struct xae_softc *sc;
506         int error;
507
508         sc = ifp->if_softc;
509
510         XAE_LOCK(sc);
511         error = xae_media_change_locked(sc);
512         XAE_UNLOCK(sc);
513
514         return (error);
515 }
516
517 static u_int
518 xae_write_maddr(void *arg, struct sockaddr_dl *sdl, u_int cnt)
519 {
520         struct xae_softc *sc = arg;
521         uint32_t reg;
522         uint8_t *ma;
523
524         if (cnt >= XAE_MULTICAST_TABLE_SIZE)
525                 return (1);
526
527         ma = LLADDR(sdl);
528
529         reg = READ4(sc, XAE_FFC) & 0xffffff00;
530         reg |= cnt;
531         WRITE4(sc, XAE_FFC, reg);
532
533         reg = (ma[0]);
534         reg |= (ma[1] << 8);
535         reg |= (ma[2] << 16);
536         reg |= (ma[3] << 24);
537         WRITE4(sc, XAE_FFV(0), reg);
538
539         reg = ma[4];
540         reg |= ma[5] << 8;
541         WRITE4(sc, XAE_FFV(1), reg);
542
543         return (1);
544 }
545
546 static void
547 xae_setup_rxfilter(struct xae_softc *sc)
548 {
549         struct ifnet *ifp;
550         uint32_t reg;
551
552         XAE_ASSERT_LOCKED(sc);
553
554         ifp = sc->ifp;
555
556         /*
557          * Set the multicast (group) filter hash.
558          */
559         if ((ifp->if_flags & (IFF_ALLMULTI | IFF_PROMISC)) != 0) {
560                 reg = READ4(sc, XAE_FFC);
561                 reg |= FFC_PM;
562                 WRITE4(sc, XAE_FFC, reg);
563         } else {
564                 reg = READ4(sc, XAE_FFC);
565                 reg &= ~FFC_PM;
566                 WRITE4(sc, XAE_FFC, reg);
567
568                 if_foreach_llmaddr(ifp, xae_write_maddr, sc);
569         }
570
571         /*
572          * Set the primary address.
573          */
574         reg = sc->macaddr[0];
575         reg |= (sc->macaddr[1] << 8);
576         reg |= (sc->macaddr[2] << 16);
577         reg |= (sc->macaddr[3] << 24);
578         WRITE4(sc, XAE_UAW0, reg);
579
580         reg = sc->macaddr[4];
581         reg |= (sc->macaddr[5] << 8);
582         WRITE4(sc, XAE_UAW1, reg);
583 }
584
585 static int
586 xae_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
587 {
588         struct xae_softc *sc;
589         struct mii_data *mii;
590         struct ifreq *ifr;
591         int mask, error;
592
593         sc = ifp->if_softc;
594         ifr = (struct ifreq *)data;
595
596         error = 0;
597         switch (cmd) {
598         case SIOCSIFFLAGS:
599                 XAE_LOCK(sc);
600                 if (ifp->if_flags & IFF_UP) {
601                         if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
602                                 if ((ifp->if_flags ^ sc->if_flags) &
603                                     (IFF_PROMISC | IFF_ALLMULTI))
604                                         xae_setup_rxfilter(sc);
605                         } else {
606                                 if (!sc->is_detaching)
607                                         xae_init_locked(sc);
608                         }
609                 } else {
610                         if (ifp->if_drv_flags & IFF_DRV_RUNNING)
611                                 xae_stop_locked(sc);
612                 }
613                 sc->if_flags = ifp->if_flags;
614                 XAE_UNLOCK(sc);
615                 break;
616         case SIOCADDMULTI:
617         case SIOCDELMULTI:
618                 if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
619                         XAE_LOCK(sc);
620                         xae_setup_rxfilter(sc);
621                         XAE_UNLOCK(sc);
622                 }
623                 break;
624         case SIOCSIFMEDIA:
625         case SIOCGIFMEDIA:
626                 mii = sc->mii_softc;
627                 error = ifmedia_ioctl(ifp, ifr, &mii->mii_media, cmd);
628                 break;
629         case SIOCSIFCAP:
630                 mask = ifp->if_capenable ^ ifr->ifr_reqcap;
631                 if (mask & IFCAP_VLAN_MTU) {
632                         /* No work to do except acknowledge the change took */
633                         ifp->if_capenable ^= IFCAP_VLAN_MTU;
634                 }
635                 break;
636
637         default:
638                 error = ether_ioctl(ifp, cmd, data);
639                 break;
640         }
641
642         return (error);
643 }
644
645 static void
646 xae_intr(void *arg)
647 {
648
649 }
650
651 static int
652 xae_get_hwaddr(struct xae_softc *sc, uint8_t *hwaddr)
653 {
654         phandle_t node;
655         int len;
656
657         node = ofw_bus_get_node(sc->dev);
658
659         /* Check if there is property */
660         if ((len = OF_getproplen(node, "local-mac-address")) <= 0)
661                 return (EINVAL);
662
663         if (len != ETHER_ADDR_LEN)
664                 return (EINVAL);
665
666         OF_getprop(node, "local-mac-address", hwaddr,
667             ETHER_ADDR_LEN);
668
669         return (0);
670 }
671
672 static int
673 mdio_wait(struct xae_softc *sc)
674 {
675         uint32_t reg;
676         int timeout;
677
678         timeout = 200;
679
680         do {
681                 reg = READ4(sc, XAE_MDIO_CTRL);
682                 if (reg & MDIO_CTRL_READY)
683                         break;
684                 DELAY(1);
685         } while (timeout--);
686
687         if (timeout <= 0) {
688                 printf("Failed to get MDIO ready\n");
689                 return (1);
690         }
691
692         return (0);
693 }
694
695 static int
696 xae_miibus_read_reg(device_t dev, int phy, int reg)
697 {
698         struct xae_softc *sc;
699         uint32_t mii;
700         int rv;
701
702         sc = device_get_softc(dev);
703
704         if (mdio_wait(sc))
705                 return (0);
706
707         mii = MDIO_CTRL_TX_OP_READ | MDIO_CTRL_INITIATE;
708         mii |= (reg << MDIO_TX_REGAD_S);
709         mii |= (phy << MDIO_TX_PHYAD_S);
710
711         WRITE4(sc, XAE_MDIO_CTRL, mii);
712
713         if (mdio_wait(sc))
714                 return (0);
715
716         rv = READ4(sc, XAE_MDIO_READ);
717
718         return (rv);
719 }
720
721 static int
722 xae_miibus_write_reg(device_t dev, int phy, int reg, int val)
723 {
724         struct xae_softc *sc;
725         uint32_t mii;
726
727         sc = device_get_softc(dev);
728
729         if (mdio_wait(sc))
730                 return (1);
731
732         mii = MDIO_CTRL_TX_OP_WRITE | MDIO_CTRL_INITIATE;
733         mii |= (reg << MDIO_TX_REGAD_S);
734         mii |= (phy << MDIO_TX_PHYAD_S);
735
736         WRITE4(sc, XAE_MDIO_WRITE, val);
737         WRITE4(sc, XAE_MDIO_CTRL, mii);
738
739         if (mdio_wait(sc))
740                 return (1);
741
742         return (0);
743 }
744
745 static void
746 xae_phy_fixup(struct xae_softc *sc)
747 {
748         uint32_t reg;
749         device_t dev;
750
751         dev = sc->dev;
752
753         do {
754                 WRITE_TI_EREG(sc, DP83867_SGMIICTL1, SGMIICTL1_SGMII_6W);
755                 PHY_WR(sc, DP83867_PHYCR, PHYCR_SGMII_EN);
756
757                 reg = PHY_RD(sc, DP83867_CFG2);
758                 reg &= ~CFG2_SPEED_OPT_ATTEMPT_CNT_M;
759                 reg |= (CFG2_SPEED_OPT_ATTEMPT_CNT_4);
760                 reg |= CFG2_INTERRUPT_POLARITY;
761                 reg |= CFG2_SPEED_OPT_ENHANCED_EN;
762                 reg |= CFG2_SPEED_OPT_10M_EN;
763                 PHY_WR(sc, DP83867_CFG2, reg);
764
765                 WRITE_TI_EREG(sc, DP83867_CFG4, CFG4_SGMII_TMR);
766                 PHY_WR(sc, MII_BMCR,
767                     BMCR_AUTOEN | BMCR_FDX | BMCR_SPEED1 | BMCR_RESET);
768         } while (PHY1_RD(sc, MII_BMCR) == 0x0ffff);
769
770         do {
771                 PHY1_WR(sc, MII_BMCR,
772                     BMCR_AUTOEN | BMCR_FDX | BMCR_SPEED1 | BMCR_STARTNEG);
773                 DELAY(40000);
774         } while ((PHY1_RD(sc, MII_BMSR) & BMSR_ACOMP) == 0);
775 }
776
777 static int
778 setup_xdma(struct xae_softc *sc)
779 {
780         device_t dev;
781         vmem_t *vmem;
782         int error;
783
784         dev = sc->dev;
785
786         /* Get xDMA controller */   
787         sc->xdma_tx = xdma_ofw_get(sc->dev, "tx");
788         if (sc->xdma_tx == NULL) {
789                 device_printf(dev, "Could not find DMA controller.\n");
790                 return (ENXIO);
791         }
792
793         sc->xdma_rx = xdma_ofw_get(sc->dev, "rx");
794         if (sc->xdma_rx == NULL) {
795                 device_printf(dev, "Could not find DMA controller.\n");
796                 return (ENXIO);
797         }
798
799         /* Alloc xDMA TX virtual channel. */
800         sc->xchan_tx = xdma_channel_alloc(sc->xdma_tx, 0);
801         if (sc->xchan_tx == NULL) {
802                 device_printf(dev, "Can't alloc virtual DMA TX channel.\n");
803                 return (ENXIO);
804         }
805
806         /* Setup interrupt handler. */
807         error = xdma_setup_intr(sc->xchan_tx,
808             xae_xdma_tx_intr, sc, &sc->ih_tx);
809         if (error) {
810                 device_printf(sc->dev,
811                     "Can't setup xDMA TX interrupt handler.\n");
812                 return (ENXIO);
813         }
814
815         /* Alloc xDMA RX virtual channel. */
816         sc->xchan_rx = xdma_channel_alloc(sc->xdma_rx, 0);
817         if (sc->xchan_rx == NULL) {
818                 device_printf(dev, "Can't alloc virtual DMA RX channel.\n");
819                 return (ENXIO);
820         }
821
822         /* Setup interrupt handler. */
823         error = xdma_setup_intr(sc->xchan_rx,
824             xae_xdma_rx_intr, sc, &sc->ih_rx);
825         if (error) {
826                 device_printf(sc->dev,
827                     "Can't setup xDMA RX interrupt handler.\n");
828                 return (ENXIO);
829         }
830
831         /* Setup bounce buffer */
832         vmem = xdma_get_memory(dev);
833         if (vmem) {
834                 xchan_set_memory(sc->xchan_tx, vmem);
835                 xchan_set_memory(sc->xchan_rx, vmem);
836         }
837
838         xdma_prep_sg(sc->xchan_tx,
839             TX_QUEUE_SIZE,      /* xchan requests queue size */
840             MCLBYTES,   /* maxsegsize */
841             8,          /* maxnsegs */
842             16,         /* alignment */
843             0,          /* boundary */
844             BUS_SPACE_MAXADDR_32BIT,
845             BUS_SPACE_MAXADDR);
846
847         xdma_prep_sg(sc->xchan_rx,
848             RX_QUEUE_SIZE,      /* xchan requests queue size */
849             MCLBYTES,   /* maxsegsize */
850             1,          /* maxnsegs */
851             16,         /* alignment */
852             0,          /* boundary */
853             BUS_SPACE_MAXADDR_32BIT,
854             BUS_SPACE_MAXADDR);
855
856         return (0);
857 }
858
859 static int
860 xae_probe(device_t dev)
861 {
862
863         if (!ofw_bus_status_okay(dev))
864                 return (ENXIO);
865
866         if (!ofw_bus_is_compatible(dev, "xlnx,axi-ethernet-1.00.a"))
867                 return (ENXIO);
868
869         device_set_desc(dev, "Xilinx AXI Ethernet");
870
871         return (BUS_PROBE_DEFAULT);
872 }
873
874 static int
875 xae_attach(device_t dev)
876 {
877         struct xae_softc *sc;
878         struct ifnet *ifp;
879         phandle_t node;
880         uint32_t reg;
881         int error;
882
883         sc = device_get_softc(dev);
884         sc->dev = dev;
885         node = ofw_bus_get_node(dev);
886
887         if (setup_xdma(sc) != 0) {
888                 device_printf(dev, "Could not setup xDMA.\n");
889                 return (ENXIO);
890         }
891
892         mtx_init(&sc->mtx, device_get_nameunit(sc->dev),
893             MTX_NETWORK_LOCK, MTX_DEF);
894
895         sc->br = buf_ring_alloc(BUFRING_SIZE, M_DEVBUF,
896             M_NOWAIT, &sc->mtx);
897         if (sc->br == NULL)
898                 return (ENOMEM);
899
900         if (bus_alloc_resources(dev, xae_spec, sc->res)) {
901                 device_printf(dev, "could not allocate resources\n");
902                 return (ENXIO);
903         }
904
905         /* Memory interface */
906         sc->bst = rman_get_bustag(sc->res[0]);
907         sc->bsh = rman_get_bushandle(sc->res[0]);
908
909         device_printf(sc->dev, "Identification: %x\n",
910             READ4(sc, XAE_IDENT));
911
912         /* Get MAC addr */
913         if (xae_get_hwaddr(sc, sc->macaddr)) {
914                 device_printf(sc->dev, "can't get mac\n");
915                 return (ENXIO);
916         }
917
918         /* Enable MII clock */
919         reg = (MDIO_CLK_DIV_DEFAULT << MDIO_SETUP_CLK_DIV_S);
920         reg |= MDIO_SETUP_ENABLE;
921         WRITE4(sc, XAE_MDIO_SETUP, reg);
922         if (mdio_wait(sc))
923                 return (ENXIO);
924
925         callout_init_mtx(&sc->xae_callout, &sc->mtx, 0);
926
927         /* Setup interrupt handler. */
928         error = bus_setup_intr(dev, sc->res[1], INTR_TYPE_NET | INTR_MPSAFE,
929             NULL, xae_intr, sc, &sc->intr_cookie);
930         if (error != 0) {
931                 device_printf(dev, "could not setup interrupt handler.\n");
932                 return (ENXIO);
933         }
934
935         /* Set up the ethernet interface. */
936         sc->ifp = ifp = if_alloc(IFT_ETHER);
937         if (ifp == NULL) {
938                 device_printf(dev, "could not allocate ifp.\n");
939                 return (ENXIO);
940         }
941
942         ifp->if_softc = sc;
943         if_initname(ifp, device_get_name(dev), device_get_unit(dev));
944         ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
945         ifp->if_capabilities = IFCAP_VLAN_MTU;
946         ifp->if_capenable = ifp->if_capabilities;
947         ifp->if_transmit = xae_transmit;
948         ifp->if_qflush = xae_qflush;
949         ifp->if_ioctl = xae_ioctl;
950         ifp->if_init = xae_init;
951         IFQ_SET_MAXLEN(&ifp->if_snd, TX_DESC_COUNT - 1);
952         ifp->if_snd.ifq_drv_maxlen = TX_DESC_COUNT - 1;
953         IFQ_SET_READY(&ifp->if_snd);
954
955         if (xae_get_phyaddr(node, &sc->phy_addr) != 0)
956                 return (ENXIO);
957
958         /* Attach the mii driver. */
959         error = mii_attach(dev, &sc->miibus, ifp, xae_media_change,
960             xae_media_status, BMSR_DEFCAPMASK, sc->phy_addr,
961             MII_OFFSET_ANY, 0);
962
963         if (error != 0) {
964                 device_printf(dev, "PHY attach failed\n");
965                 return (ENXIO);
966         }
967         sc->mii_softc = device_get_softc(sc->miibus);
968
969         /* Apply vcu118 workaround. */
970         if (OF_getproplen(node, "xlnx,vcu118") >= 0)
971                 xae_phy_fixup(sc);
972
973         /* All ready to run, attach the ethernet interface. */
974         ether_ifattach(ifp, sc->macaddr);
975         sc->is_attached = true;
976
977         xae_rx_enqueue(sc, NUM_RX_MBUF);
978         xdma_queue_submit(sc->xchan_rx);
979
980         return (0);
981 }
982
983 static int
984 xae_detach(device_t dev)
985 {
986         struct xae_softc *sc;
987         struct ifnet *ifp;
988
989         sc = device_get_softc(dev);
990
991         KASSERT(mtx_initialized(&sc->mtx), ("%s: mutex not initialized",
992             device_get_nameunit(dev)));
993
994         ifp = sc->ifp;
995
996         /* Only cleanup if attach succeeded. */
997         if (device_is_attached(dev)) {
998                 XAE_LOCK(sc);
999                 xae_stop_locked(sc);
1000                 XAE_UNLOCK(sc);
1001                 callout_drain(&sc->xae_callout);
1002                 ether_ifdetach(ifp);
1003         }
1004
1005         if (sc->miibus != NULL)
1006                 device_delete_child(dev, sc->miibus);
1007
1008         if (ifp != NULL)
1009                 if_free(ifp);
1010
1011         mtx_destroy(&sc->mtx);
1012
1013         bus_teardown_intr(dev, sc->res[1], sc->intr_cookie);
1014
1015         bus_release_resources(dev, xae_spec, sc->res);
1016
1017         xdma_channel_free(sc->xchan_tx);
1018         xdma_channel_free(sc->xchan_rx);
1019         xdma_put(sc->xdma_tx);
1020         xdma_put(sc->xdma_rx);
1021
1022         return (0);
1023 }
1024
1025 static void
1026 xae_miibus_statchg(device_t dev)
1027 {
1028         struct xae_softc *sc;
1029         struct mii_data *mii;
1030         uint32_t reg;
1031
1032         /*
1033          * Called by the MII bus driver when the PHY establishes
1034          * link to set the MAC interface registers.
1035          */
1036
1037         sc = device_get_softc(dev);
1038
1039         XAE_ASSERT_LOCKED(sc);
1040
1041         mii = sc->mii_softc;
1042
1043         if (mii->mii_media_status & IFM_ACTIVE)
1044                 sc->link_is_up = true;
1045         else
1046                 sc->link_is_up = false;
1047
1048         switch (IFM_SUBTYPE(mii->mii_media_active)) {
1049         case IFM_1000_T:
1050         case IFM_1000_SX:
1051                 reg = SPEED_1000;
1052                 break;
1053         case IFM_100_TX:
1054                 reg = SPEED_100;
1055                 break;
1056         case IFM_10_T:
1057                 reg = SPEED_10;
1058                 break;
1059         case IFM_NONE:
1060                 sc->link_is_up = false;
1061                 return;
1062         default:
1063                 sc->link_is_up = false;
1064                 device_printf(dev, "Unsupported media %u\n",
1065                     IFM_SUBTYPE(mii->mii_media_active));
1066                 return;
1067         }
1068
1069         WRITE4(sc, XAE_SPEED, reg);
1070 }
1071
1072 static device_method_t xae_methods[] = {
1073         DEVMETHOD(device_probe,         xae_probe),
1074         DEVMETHOD(device_attach,        xae_attach),
1075         DEVMETHOD(device_detach,        xae_detach),
1076
1077         /* MII Interface */
1078         DEVMETHOD(miibus_readreg,       xae_miibus_read_reg),
1079         DEVMETHOD(miibus_writereg,      xae_miibus_write_reg),
1080         DEVMETHOD(miibus_statchg,       xae_miibus_statchg),
1081
1082         { 0, 0 }
1083 };
1084
1085 driver_t xae_driver = {
1086         "xae",
1087         xae_methods,
1088         sizeof(struct xae_softc),
1089 };
1090
1091 static devclass_t xae_devclass;
1092
1093 DRIVER_MODULE(xae, simplebus, xae_driver, xae_devclass, 0, 0);
1094 DRIVER_MODULE(miibus, xae, miibus_driver, miibus_devclass, 0, 0);
1095
1096 MODULE_DEPEND(xae, ether, 1, 1, 1);
1097 MODULE_DEPEND(xae, miibus, 1, 1, 1);