source: rtems-libbsd/freebsd/sys/dev/dwc/if_dwc.c @ c40e45b

5-freebsd-12
Last change on this file since c40e45b was c40e45b, checked in by Sebastian Huber <sebastian.huber@…>, on Oct 7, 2016 at 1:10:20 PM

Update to FreeBSD head 2016-08-23

Git mirror commit 9fe7c416e6abb28b1398fd3e5687099846800cfd.

  • Property mode set to 100644
File size: 32.7 KB
Line 
1#include <machine/rtems-bsd-kernel-space.h>
2
3/*-
4 * Copyright (c) 2014 Ruslan Bukin <br@bsdpad.com>
5 * All rights reserved.
6 *
7 * This software was developed by SRI International and the University of
8 * Cambridge Computer Laboratory under DARPA/AFRL contract (FA8750-10-C-0237)
9 * ("CTSRD"), as part of the DARPA CRASH 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/*
34 * Ethernet media access controller (EMAC)
35 * Chapter 17, Altera Cyclone V Device Handbook (CV-5V2 2014.07.22)
36 *
37 * EMAC is an instance of the Synopsys DesignWare 3504-0
38 * Universal 10/100/1000 Ethernet MAC (DWC_gmac).
39 */
40
41#include <sys/cdefs.h>
42__FBSDID("$FreeBSD$");
43
44#include <rtems/bsd/sys/param.h>
45#include <sys/systm.h>
46#include <sys/bus.h>
47#include <sys/gpio.h>
48#include <sys/kernel.h>
49#include <rtems/bsd/sys/lock.h>
50#include <sys/malloc.h>
51#include <sys/mbuf.h>
52#include <sys/module.h>
53#include <sys/mutex.h>
54#include <sys/rman.h>
55#include <sys/socket.h>
56#include <sys/sockio.h>
57
58#include <net/bpf.h>
59#include <net/if.h>
60#include <net/ethernet.h>
61#include <net/if_dl.h>
62#include <net/if_media.h>
63#include <net/if_types.h>
64#include <net/if_var.h>
65
66#include <machine/bus.h>
67
68#include <dev/dwc/if_dwc.h>
69#include <dev/dwc/if_dwcvar.h>
70#include <dev/mii/mii.h>
71#include <dev/mii/miivar.h>
72#ifndef __rtems__
73#include <dev/ofw/ofw_bus.h>
74#include <dev/ofw/ofw_bus_subr.h>
75#endif /* __rtems__ */
76
77#ifdef EXT_RESOURCES
78#include <dev/extres/clk/clk.h>
79#include <dev/extres/hwreset/hwreset.h>
80#endif
81
82#include <rtems/bsd/local/if_dwc_if.h>
83#include <rtems/bsd/local/gpio_if.h>
84#include <rtems/bsd/local/miibus_if.h>
85
86#define READ4(_sc, _reg) \
87        bus_read_4((_sc)->res[0], _reg)
88#define WRITE4(_sc, _reg, _val) \
89        bus_write_4((_sc)->res[0], _reg, _val)
90
91#define MAC_RESET_TIMEOUT       100
92#define WATCHDOG_TIMEOUT_SECS   5
93#define STATS_HARVEST_INTERVAL  2
94
95#define DWC_LOCK(sc)                    mtx_lock(&(sc)->mtx)
96#define DWC_UNLOCK(sc)                  mtx_unlock(&(sc)->mtx)
97#define DWC_ASSERT_LOCKED(sc)           mtx_assert(&(sc)->mtx, MA_OWNED)
98#define DWC_ASSERT_UNLOCKED(sc)         mtx_assert(&(sc)->mtx, MA_NOTOWNED)
99
100#define DDESC_TDES0_OWN                 (1U << 31)
101#define DDESC_TDES0_TXINT               (1U << 30)
102#define DDESC_TDES0_TXLAST              (1U << 29)
103#define DDESC_TDES0_TXFIRST             (1U << 28)
104#define DDESC_TDES0_TXCRCDIS            (1U << 27)
105#define DDESC_TDES0_TXRINGEND           (1U << 21)
106#define DDESC_TDES0_TXCHAIN             (1U << 20)
107
108#define DDESC_RDES0_OWN                 (1U << 31)
109#define DDESC_RDES0_FL_MASK             0x3fff
110#define DDESC_RDES0_FL_SHIFT            16      /* Frame Length */
111#define DDESC_RDES1_CHAINED             (1U << 14)
112
113/* Alt descriptor bits. */
114#define DDESC_CNTL_TXINT                (1U << 31)
115#define DDESC_CNTL_TXLAST               (1U << 30)
116#define DDESC_CNTL_TXFIRST              (1U << 29)
117#define DDESC_CNTL_TXCRCDIS             (1U << 26)
118#define DDESC_CNTL_TXRINGEND            (1U << 25)
119#define DDESC_CNTL_TXCHAIN              (1U << 24)
120
121#define DDESC_CNTL_CHAINED              (1U << 24)
122
123/*
124 * A hardware buffer descriptor.  Rx and Tx buffers have the same descriptor
125 * layout, but the bits in the fields have different meanings.
126 */
127struct dwc_hwdesc
128{
129        uint32_t tdes0;         /* status for alt layout */
130        uint32_t tdes1;         /* cntl for alt layout */
131        uint32_t addr;          /* pointer to buffer data */
132        uint32_t addr_next;     /* link to next descriptor */
133};
134
135/*
136 * The hardware imposes alignment restrictions on various objects involved in
137 * DMA transfers.  These values are expressed in bytes (not bits).
138 */
139#define DWC_DESC_RING_ALIGN             2048
140
141static struct resource_spec dwc_spec[] = {
142        { SYS_RES_MEMORY,       0,      RF_ACTIVE },
143        { SYS_RES_IRQ,          0,      RF_ACTIVE },
144        { -1, 0 }
145};
146
147static void dwc_txfinish_locked(struct dwc_softc *sc);
148static void dwc_rxfinish_locked(struct dwc_softc *sc);
149static void dwc_stop_locked(struct dwc_softc *sc);
150static void dwc_setup_rxfilter(struct dwc_softc *sc);
151
152static inline uint32_t
153next_rxidx(struct dwc_softc *sc, uint32_t curidx)
154{
155
156        return ((curidx + 1) % RX_DESC_COUNT);
157}
158
159static inline uint32_t
160next_txidx(struct dwc_softc *sc, uint32_t curidx)
161{
162
163        return ((curidx + 1) % TX_DESC_COUNT);
164}
165
166static void
167dwc_get1paddr(void *arg, bus_dma_segment_t *segs, int nsegs, int error)
168{
169
170        if (error != 0)
171                return;
172        *(bus_addr_t *)arg = segs[0].ds_addr;
173}
174
175inline static uint32_t
176dwc_setup_txdesc(struct dwc_softc *sc, int idx, bus_addr_t paddr,
177    uint32_t len)
178{
179        uint32_t flags;
180        uint32_t nidx;
181
182        nidx = next_txidx(sc, idx);
183
184        /* Addr/len 0 means we're clearing the descriptor after xmit done. */
185        if (paddr == 0 || len == 0) {
186                flags = 0;
187                --sc->txcount;
188        } else {
189                if (sc->mactype == DWC_GMAC_ALT_DESC)
190                        flags = DDESC_CNTL_TXCHAIN | DDESC_CNTL_TXFIRST
191                            | DDESC_CNTL_TXLAST | DDESC_CNTL_TXINT;
192                else
193                        flags = DDESC_TDES0_TXCHAIN | DDESC_TDES0_TXFIRST
194                            | DDESC_TDES0_TXLAST | DDESC_TDES0_TXINT;
195                ++sc->txcount;
196        }
197
198        sc->txdesc_ring[idx].addr = (uint32_t)(paddr);
199        if (sc->mactype == DWC_GMAC_ALT_DESC) {
200                sc->txdesc_ring[idx].tdes0 = 0;
201                sc->txdesc_ring[idx].tdes1 = flags | len;
202        } else {
203                sc->txdesc_ring[idx].tdes0 = flags;
204                sc->txdesc_ring[idx].tdes1 = len;
205        }
206
207        if (paddr && len) {
208                wmb();
209                sc->txdesc_ring[idx].tdes0 |= DDESC_TDES0_OWN;
210                wmb();
211        }
212
213        return (nidx);
214}
215
216static int
217dwc_setup_txbuf(struct dwc_softc *sc, int idx, struct mbuf **mp)
218{
219        struct bus_dma_segment seg;
220        int error, nsegs;
221        struct mbuf * m;
222
223        if ((m = m_defrag(*mp, M_NOWAIT)) == NULL)
224                return (ENOMEM);
225        *mp = m;
226
227        error = bus_dmamap_load_mbuf_sg(sc->txbuf_tag, sc->txbuf_map[idx].map,
228            m, &seg, &nsegs, 0);
229        if (error != 0) {
230                return (ENOMEM);
231        }
232
233        KASSERT(nsegs == 1, ("%s: %d segments returned!", __func__, nsegs));
234
235        bus_dmamap_sync(sc->txbuf_tag, sc->txbuf_map[idx].map,
236            BUS_DMASYNC_PREWRITE);
237
238        sc->txbuf_map[idx].mbuf = m;
239
240        dwc_setup_txdesc(sc, idx, seg.ds_addr, seg.ds_len);
241
242        return (0);
243}
244
245static void
246dwc_txstart_locked(struct dwc_softc *sc)
247{
248        struct ifnet *ifp;
249        struct mbuf *m;
250        int enqueued;
251
252        DWC_ASSERT_LOCKED(sc);
253
254        if (!sc->link_is_up)
255                return;
256
257        ifp = sc->ifp;
258
259        if (ifp->if_drv_flags & IFF_DRV_OACTIVE) {
260                return;
261        }
262
263        enqueued = 0;
264
265        for (;;) {
266                if (sc->txcount == (TX_DESC_COUNT-1)) {
267                        ifp->if_drv_flags |= IFF_DRV_OACTIVE;
268                        break;
269                }
270
271                IFQ_DRV_DEQUEUE(&ifp->if_snd, m);
272                if (m == NULL)
273                        break;
274                if (dwc_setup_txbuf(sc, sc->tx_idx_head, &m) != 0) {
275                        IFQ_DRV_PREPEND(&ifp->if_snd, m);
276                        break;
277                }
278                BPF_MTAP(ifp, m);
279                sc->tx_idx_head = next_txidx(sc, sc->tx_idx_head);
280                ++enqueued;
281        }
282
283        if (enqueued != 0) {
284                WRITE4(sc, TRANSMIT_POLL_DEMAND, 0x1);
285                sc->tx_watchdog_count = WATCHDOG_TIMEOUT_SECS;
286        }
287}
288
289static void
290dwc_txstart(struct ifnet *ifp)
291{
292        struct dwc_softc *sc = ifp->if_softc;
293
294        DWC_LOCK(sc);
295        dwc_txstart_locked(sc);
296        DWC_UNLOCK(sc);
297}
298
299static void
300dwc_stop_locked(struct dwc_softc *sc)
301{
302        struct ifnet *ifp;
303        uint32_t reg;
304
305        DWC_ASSERT_LOCKED(sc);
306
307        ifp = sc->ifp;
308        ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
309        sc->tx_watchdog_count = 0;
310        sc->stats_harvest_count = 0;
311
312        callout_stop(&sc->dwc_callout);
313
314        /* Stop DMA TX */
315        reg = READ4(sc, OPERATION_MODE);
316        reg &= ~(MODE_ST);
317        WRITE4(sc, OPERATION_MODE, reg);
318
319        /* Flush TX */
320        reg = READ4(sc, OPERATION_MODE);
321        reg |= (MODE_FTF);
322        WRITE4(sc, OPERATION_MODE, reg);
323
324        /* Stop transmitters */
325        reg = READ4(sc, MAC_CONFIGURATION);
326        reg &= ~(CONF_TE | CONF_RE);
327        WRITE4(sc, MAC_CONFIGURATION, reg);
328
329        /* Stop DMA RX */
330        reg = READ4(sc, OPERATION_MODE);
331        reg &= ~(MODE_SR);
332        WRITE4(sc, OPERATION_MODE, reg);
333}
334
335static void dwc_clear_stats(struct dwc_softc *sc)
336{
337        uint32_t reg;
338
339        reg = READ4(sc, MMC_CONTROL);
340        reg |= (MMC_CONTROL_CNTRST);
341        WRITE4(sc, MMC_CONTROL, reg);
342}
343
344static void
345dwc_harvest_stats(struct dwc_softc *sc)
346{
347        struct ifnet *ifp;
348
349        /* We don't need to harvest too often. */
350        if (++sc->stats_harvest_count < STATS_HARVEST_INTERVAL)
351                return;
352
353        sc->stats_harvest_count = 0;
354        ifp = sc->ifp;
355
356        if_inc_counter(ifp, IFCOUNTER_IPACKETS, READ4(sc, RXFRAMECOUNT_GB));
357        if_inc_counter(ifp, IFCOUNTER_IMCASTS, READ4(sc, RXMULTICASTFRAMES_G));
358        if_inc_counter(ifp, IFCOUNTER_IERRORS,
359            READ4(sc, RXOVERSIZE_G) + READ4(sc, RXUNDERSIZE_G) +
360            READ4(sc, RXCRCERROR) + READ4(sc, RXALIGNMENTERROR) +
361            READ4(sc, RXRUNTERROR) + READ4(sc, RXJABBERERROR) +
362            READ4(sc, RXLENGTHERROR));
363
364        if_inc_counter(ifp, IFCOUNTER_OPACKETS, READ4(sc, TXFRAMECOUNT_G));
365        if_inc_counter(ifp, IFCOUNTER_OMCASTS, READ4(sc, TXMULTICASTFRAMES_G));
366        if_inc_counter(ifp, IFCOUNTER_OERRORS,
367            READ4(sc, TXOVERSIZE_G) + READ4(sc, TXEXCESSDEF) +
368            READ4(sc, TXCARRIERERR) + READ4(sc, TXUNDERFLOWERROR));
369
370        if_inc_counter(ifp, IFCOUNTER_COLLISIONS,
371            READ4(sc, TXEXESSCOL) + READ4(sc, TXLATECOL));
372
373        dwc_clear_stats(sc);
374}
375
376static void
377dwc_tick(void *arg)
378{
379        struct dwc_softc *sc;
380        struct ifnet *ifp;
381        int link_was_up;
382
383        sc = arg;
384
385        DWC_ASSERT_LOCKED(sc);
386
387        ifp = sc->ifp;
388
389        if (!(ifp->if_drv_flags & IFF_DRV_RUNNING))
390            return;
391
392        /*
393         * Typical tx watchdog.  If this fires it indicates that we enqueued
394         * packets for output and never got a txdone interrupt for them.  Maybe
395         * it's a missed interrupt somehow, just pretend we got one.
396         */
397        if (sc->tx_watchdog_count > 0) {
398                if (--sc->tx_watchdog_count == 0) {
399                        dwc_txfinish_locked(sc);
400                }
401        }
402
403        /* Gather stats from hardware counters. */
404        dwc_harvest_stats(sc);
405
406        /* Check the media status. */
407        link_was_up = sc->link_is_up;
408        mii_tick(sc->mii_softc);
409        if (sc->link_is_up && !link_was_up)
410                dwc_txstart_locked(sc);
411
412        /* Schedule another check one second from now. */
413        callout_reset(&sc->dwc_callout, hz, dwc_tick, sc);
414}
415
416static void
417dwc_init_locked(struct dwc_softc *sc)
418{
419        struct ifnet *ifp = sc->ifp;
420        uint32_t reg;
421
422        DWC_ASSERT_LOCKED(sc);
423
424        if (ifp->if_drv_flags & IFF_DRV_RUNNING)
425                return;
426
427        ifp->if_drv_flags |= IFF_DRV_RUNNING;
428
429        dwc_setup_rxfilter(sc);
430
431        /* Initializa DMA and enable transmitters */
432        reg = READ4(sc, OPERATION_MODE);
433        reg |= (MODE_TSF | MODE_OSF | MODE_FUF);
434        reg &= ~(MODE_RSF);
435        reg |= (MODE_RTC_LEV32 << MODE_RTC_SHIFT);
436        WRITE4(sc, OPERATION_MODE, reg);
437
438        WRITE4(sc, INTERRUPT_ENABLE, INT_EN_DEFAULT);
439
440        /* Start DMA */
441        reg = READ4(sc, OPERATION_MODE);
442        reg |= (MODE_ST | MODE_SR);
443        WRITE4(sc, OPERATION_MODE, reg);
444
445        /* Enable transmitters */
446        reg = READ4(sc, MAC_CONFIGURATION);
447        reg |= (CONF_JD | CONF_ACS | CONF_BE);
448        reg |= (CONF_TE | CONF_RE);
449        WRITE4(sc, MAC_CONFIGURATION, reg);
450
451        /*
452         * Call mii_mediachg() which will call back into dwc_miibus_statchg()
453         * to set up the remaining config registers based on current media.
454         */
455        mii_mediachg(sc->mii_softc);
456        callout_reset(&sc->dwc_callout, hz, dwc_tick, sc);
457}
458
459static void
460dwc_init(void *if_softc)
461{
462        struct dwc_softc *sc = if_softc;
463
464        DWC_LOCK(sc);
465        dwc_init_locked(sc);
466        DWC_UNLOCK(sc);
467}
468
469inline static uint32_t
470dwc_setup_rxdesc(struct dwc_softc *sc, int idx, bus_addr_t paddr)
471{
472        uint32_t nidx;
473
474        sc->rxdesc_ring[idx].addr = (uint32_t)paddr;
475        nidx = next_rxidx(sc, idx);
476        sc->rxdesc_ring[idx].addr_next = sc->rxdesc_ring_paddr +        \
477            (nidx * sizeof(struct dwc_hwdesc));
478        if (sc->mactype == DWC_GMAC_ALT_DESC)
479                sc->rxdesc_ring[idx].tdes1 = DDESC_CNTL_CHAINED | RX_MAX_PACKET;
480        else
481                sc->rxdesc_ring[idx].tdes1 = DDESC_RDES1_CHAINED | MCLBYTES;
482
483        wmb();
484        sc->rxdesc_ring[idx].tdes0 = DDESC_RDES0_OWN;
485        wmb();
486
487        return (nidx);
488}
489
490static int
491dwc_setup_rxbuf(struct dwc_softc *sc, int idx, struct mbuf *m)
492{
493        struct bus_dma_segment seg;
494        int error, nsegs;
495
496        m_adj(m, ETHER_ALIGN);
497
498        error = bus_dmamap_load_mbuf_sg(sc->rxbuf_tag, sc->rxbuf_map[idx].map,
499            m, &seg, &nsegs, 0);
500        if (error != 0) {
501                return (error);
502        }
503
504        KASSERT(nsegs == 1, ("%s: %d segments returned!", __func__, nsegs));
505
506        bus_dmamap_sync(sc->rxbuf_tag, sc->rxbuf_map[idx].map,
507            BUS_DMASYNC_PREREAD);
508
509        sc->rxbuf_map[idx].mbuf = m;
510        dwc_setup_rxdesc(sc, idx, seg.ds_addr);
511
512        return (0);
513}
514
515static struct mbuf *
516dwc_alloc_mbufcl(struct dwc_softc *sc)
517{
518        struct mbuf *m;
519
520        m = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR);
521        if (m != NULL)
522                m->m_pkthdr.len = m->m_len = m->m_ext.ext_size;
523
524        return (m);
525}
526
527static void
528dwc_media_status(struct ifnet * ifp, struct ifmediareq *ifmr)
529{
530        struct dwc_softc *sc;
531        struct mii_data *mii;
532
533        sc = ifp->if_softc;
534        mii = sc->mii_softc;
535        DWC_LOCK(sc);
536        mii_pollstat(mii);
537        ifmr->ifm_active = mii->mii_media_active;
538        ifmr->ifm_status = mii->mii_media_status;
539        DWC_UNLOCK(sc);
540}
541
542static int
543dwc_media_change_locked(struct dwc_softc *sc)
544{
545
546        return (mii_mediachg(sc->mii_softc));
547}
548
549static int
550dwc_media_change(struct ifnet * ifp)
551{
552        struct dwc_softc *sc;
553        int error;
554
555        sc = ifp->if_softc;
556
557        DWC_LOCK(sc);
558        error = dwc_media_change_locked(sc);
559        DWC_UNLOCK(sc);
560        return (error);
561}
562
563static const uint8_t nibbletab[] = {
564        /* 0x0 0000 -> 0000 */  0x0,
565        /* 0x1 0001 -> 1000 */  0x8,
566        /* 0x2 0010 -> 0100 */  0x4,
567        /* 0x3 0011 -> 1100 */  0xc,
568        /* 0x4 0100 -> 0010 */  0x2,
569        /* 0x5 0101 -> 1010 */  0xa,
570        /* 0x6 0110 -> 0110 */  0x6,
571        /* 0x7 0111 -> 1110 */  0xe,
572        /* 0x8 1000 -> 0001 */  0x1,
573        /* 0x9 1001 -> 1001 */  0x9,
574        /* 0xa 1010 -> 0101 */  0x5,
575        /* 0xb 1011 -> 1101 */  0xd,
576        /* 0xc 1100 -> 0011 */  0x3,
577        /* 0xd 1101 -> 1011 */  0xb,
578        /* 0xe 1110 -> 0111 */  0x7,
579        /* 0xf 1111 -> 1111 */  0xf, };
580
581static uint8_t
582bitreverse(uint8_t x)
583{
584
585        return (nibbletab[x & 0xf] << 4) | nibbletab[x >> 4];
586}
587
588static void
589dwc_setup_rxfilter(struct dwc_softc *sc)
590{
591        struct ifmultiaddr *ifma;
592        struct ifnet *ifp;
593        uint8_t *eaddr, val;
594        uint32_t crc, ffval, hashbit, hashreg, hi, lo, hash[8];
595        int nhash, i;
596
597        DWC_ASSERT_LOCKED(sc);
598
599        ifp = sc->ifp;
600        nhash = sc->mactype == DWC_GMAC_ALT_DESC ? 2 : 8;
601
602        /*
603         * Set the multicast (group) filter hash.
604         */
605        if ((ifp->if_flags & IFF_ALLMULTI) != 0) {
606                ffval = (FRAME_FILTER_PM);
607                for (i = 0; i < nhash; i++)
608                        hash[i] = ~0;
609        } else {
610                ffval = (FRAME_FILTER_HMC);
611                for (i = 0; i < nhash; i++)
612                        hash[i] = 0;
613                if_maddr_rlock(ifp);
614                TAILQ_FOREACH(ifma, &sc->ifp->if_multiaddrs, ifma_link) {
615                        if (ifma->ifma_addr->sa_family != AF_LINK)
616                                continue;
617                        crc = ether_crc32_le(LLADDR((struct sockaddr_dl *)
618                                ifma->ifma_addr), ETHER_ADDR_LEN);
619
620                        /* Take lower 8 bits and reverse it */
621                        val = bitreverse(~crc & 0xff);
622                        if (sc->mactype == DWC_GMAC_ALT_DESC)
623                                val >>= nhash; /* Only need lower 6 bits */
624                        hashreg = (val >> 5);
625                        hashbit = (val & 31);
626                        hash[hashreg] |= (1 << hashbit);
627                }
628                if_maddr_runlock(ifp);
629        }
630
631        /*
632         * Set the individual address filter hash.
633         */
634        if (ifp->if_flags & IFF_PROMISC)
635                ffval |= (FRAME_FILTER_PR);
636
637        /*
638         * Set the primary address.
639         */
640        eaddr = IF_LLADDR(ifp);
641        lo = eaddr[0] | (eaddr[1] << 8) | (eaddr[2] << 16) |
642            (eaddr[3] << 24);
643        hi = eaddr[4] | (eaddr[5] << 8);
644        WRITE4(sc, MAC_ADDRESS_LOW(0), lo);
645        WRITE4(sc, MAC_ADDRESS_HIGH(0), hi);
646        WRITE4(sc, MAC_FRAME_FILTER, ffval);
647        if (sc->mactype == DWC_GMAC_ALT_DESC) {
648                WRITE4(sc, GMAC_MAC_HTLOW, hash[0]);
649                WRITE4(sc, GMAC_MAC_HTHIGH, hash[1]);
650        } else {
651                for (i = 0; i < nhash; i++)
652                        WRITE4(sc, HASH_TABLE_REG(i), hash[i]);
653        }
654}
655
656static int
657dwc_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
658{
659        struct dwc_softc *sc;
660        struct mii_data *mii;
661        struct ifreq *ifr;
662        int mask, error;
663
664        sc = ifp->if_softc;
665        ifr = (struct ifreq *)data;
666
667        error = 0;
668        switch (cmd) {
669        case SIOCSIFFLAGS:
670                DWC_LOCK(sc);
671                if (ifp->if_flags & IFF_UP) {
672                        if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
673                                if ((ifp->if_flags ^ sc->if_flags) &
674                                    (IFF_PROMISC | IFF_ALLMULTI))
675                                        dwc_setup_rxfilter(sc);
676                        } else {
677                                if (!sc->is_detaching)
678                                        dwc_init_locked(sc);
679                        }
680                } else {
681                        if (ifp->if_drv_flags & IFF_DRV_RUNNING)
682                                dwc_stop_locked(sc);
683                }
684                sc->if_flags = ifp->if_flags;
685                DWC_UNLOCK(sc);
686                break;
687        case SIOCADDMULTI:
688        case SIOCDELMULTI:
689                if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
690                        DWC_LOCK(sc);
691                        dwc_setup_rxfilter(sc);
692                        DWC_UNLOCK(sc);
693                }
694                break;
695        case SIOCSIFMEDIA:
696        case SIOCGIFMEDIA:
697                mii = sc->mii_softc;
698                error = ifmedia_ioctl(ifp, ifr, &mii->mii_media, cmd);
699                break;
700        case SIOCSIFCAP:
701                mask = ifp->if_capenable ^ ifr->ifr_reqcap;
702                if (mask & IFCAP_VLAN_MTU) {
703                        /* No work to do except acknowledge the change took */
704                        ifp->if_capenable ^= IFCAP_VLAN_MTU;
705                }
706                break;
707
708        default:
709                error = ether_ioctl(ifp, cmd, data);
710                break;
711        }
712
713        return (error);
714}
715
716static void
717dwc_txfinish_locked(struct dwc_softc *sc)
718{
719        struct dwc_bufmap *bmap;
720        struct dwc_hwdesc *desc;
721        struct ifnet *ifp;
722
723        DWC_ASSERT_LOCKED(sc);
724
725        ifp = sc->ifp;
726        while (sc->tx_idx_tail != sc->tx_idx_head) {
727                desc = &sc->txdesc_ring[sc->tx_idx_tail];
728                if ((desc->tdes0 & DDESC_TDES0_OWN) != 0)
729                        break;
730                bmap = &sc->txbuf_map[sc->tx_idx_tail];
731                bus_dmamap_sync(sc->txbuf_tag, bmap->map,
732                    BUS_DMASYNC_POSTWRITE);
733                bus_dmamap_unload(sc->txbuf_tag, bmap->map);
734                m_freem(bmap->mbuf);
735                bmap->mbuf = NULL;
736                dwc_setup_txdesc(sc, sc->tx_idx_tail, 0, 0);
737                sc->tx_idx_tail = next_txidx(sc, sc->tx_idx_tail);
738                ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
739                if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1);
740        }
741
742        /* If there are no buffers outstanding, muzzle the watchdog. */
743        if (sc->tx_idx_tail == sc->tx_idx_head) {
744                sc->tx_watchdog_count = 0;
745        }
746}
747
748static void
749dwc_rxfinish_locked(struct dwc_softc *sc)
750{
751        struct ifnet *ifp;
752        struct mbuf *m0;
753        struct mbuf *m;
754        int error, idx, len;
755        uint32_t rdes0;
756
757        ifp = sc->ifp;
758
759        for (;;) {
760                idx = sc->rx_idx;
761
762                rdes0 = sc->rxdesc_ring[idx].tdes0;
763                if ((rdes0 & DDESC_RDES0_OWN) != 0)
764                        break;
765
766                bus_dmamap_sync(sc->rxbuf_tag, sc->rxbuf_map[idx].map,
767                    BUS_DMASYNC_POSTREAD);
768                bus_dmamap_unload(sc->rxbuf_tag, sc->rxbuf_map[idx].map);
769
770                len = (rdes0 >> DDESC_RDES0_FL_SHIFT) & DDESC_RDES0_FL_MASK;
771                if (len != 0) {
772                        m = sc->rxbuf_map[idx].mbuf;
773                        m->m_pkthdr.rcvif = ifp;
774                        m->m_pkthdr.len = len;
775                        m->m_len = len;
776                        if_inc_counter(ifp, IFCOUNTER_IPACKETS, 1);
777
778                        /* Remove trailing FCS */
779                        m_adj(m, -ETHER_CRC_LEN);
780
781                        DWC_UNLOCK(sc);
782                        (*ifp->if_input)(ifp, m);
783                        DWC_LOCK(sc);
784                } else {
785                        /* XXX Zero-length packet ? */
786                }
787
788                if ((m0 = dwc_alloc_mbufcl(sc)) != NULL) {
789                        if ((error = dwc_setup_rxbuf(sc, idx, m0)) != 0) {
790                                /*
791                                 * XXX Now what?
792                                 * We've got a hole in the rx ring.
793                                 */
794                        }
795                } else
796                        if_inc_counter(sc->ifp, IFCOUNTER_IQDROPS, 1);
797
798                sc->rx_idx = next_rxidx(sc, sc->rx_idx);
799        }
800}
801
802static void
803dwc_intr(void *arg)
804{
805        struct dwc_softc *sc;
806        uint32_t reg;
807
808        sc = arg;
809
810        DWC_LOCK(sc);
811
812        reg = READ4(sc, INTERRUPT_STATUS);
813        if (reg)
814                READ4(sc, SGMII_RGMII_SMII_CTRL_STATUS);
815
816        reg = READ4(sc, DMA_STATUS);
817        if (reg & DMA_STATUS_NIS) {
818                if (reg & DMA_STATUS_RI)
819                        dwc_rxfinish_locked(sc);
820
821                if (reg & DMA_STATUS_TI) {
822                        dwc_txfinish_locked(sc);
823                        dwc_txstart_locked(sc);
824                }
825        }
826
827        if (reg & DMA_STATUS_AIS) {
828                if (reg & DMA_STATUS_FBI) {
829                        /* Fatal bus error */
830                        device_printf(sc->dev,
831                            "Ethernet DMA error, restarting controller.\n");
832                        dwc_stop_locked(sc);
833                        dwc_init_locked(sc);
834                }
835        }
836
837        WRITE4(sc, DMA_STATUS, reg & DMA_STATUS_INTR_MASK);
838        DWC_UNLOCK(sc);
839}
840
841static int
842setup_dma(struct dwc_softc *sc)
843{
844        struct mbuf *m;
845        int error;
846        int nidx;
847        int idx;
848
849        /*
850         * Set up TX descriptor ring, descriptors, and dma maps.
851         */
852        error = bus_dma_tag_create(
853            bus_get_dma_tag(sc->dev),   /* Parent tag. */
854            DWC_DESC_RING_ALIGN, 0,     /* alignment, boundary */
855            BUS_SPACE_MAXADDR_32BIT,    /* lowaddr */
856            BUS_SPACE_MAXADDR,          /* highaddr */
857            NULL, NULL,                 /* filter, filterarg */
858            TX_DESC_SIZE, 1,            /* maxsize, nsegments */
859            TX_DESC_SIZE,               /* maxsegsize */
860            0,                          /* flags */
861            NULL, NULL,                 /* lockfunc, lockarg */
862            &sc->txdesc_tag);
863        if (error != 0) {
864                device_printf(sc->dev,
865                    "could not create TX ring DMA tag.\n");
866                goto out;
867        }
868
869        error = bus_dmamem_alloc(sc->txdesc_tag, (void**)&sc->txdesc_ring,
870            BUS_DMA_COHERENT | BUS_DMA_WAITOK | BUS_DMA_ZERO,
871            &sc->txdesc_map);
872        if (error != 0) {
873                device_printf(sc->dev,
874                    "could not allocate TX descriptor ring.\n");
875                goto out;
876        }
877
878        error = bus_dmamap_load(sc->txdesc_tag, sc->txdesc_map,
879            sc->txdesc_ring, TX_DESC_SIZE, dwc_get1paddr,
880            &sc->txdesc_ring_paddr, 0);
881        if (error != 0) {
882                device_printf(sc->dev,
883                    "could not load TX descriptor ring map.\n");
884                goto out;
885        }
886
887        for (idx = 0; idx < TX_DESC_COUNT; idx++) {
888                nidx = next_txidx(sc, idx);
889                sc->txdesc_ring[idx].addr_next = sc->txdesc_ring_paddr +
890                    (nidx * sizeof(struct dwc_hwdesc));
891        }
892
893        error = bus_dma_tag_create(
894            bus_get_dma_tag(sc->dev),   /* Parent tag. */
895            1, 0,                       /* alignment, boundary */
896            BUS_SPACE_MAXADDR_32BIT,    /* lowaddr */
897            BUS_SPACE_MAXADDR,          /* highaddr */
898            NULL, NULL,                 /* filter, filterarg */
899            MCLBYTES, 1,                /* maxsize, nsegments */
900            MCLBYTES,                   /* maxsegsize */
901            0,                          /* flags */
902            NULL, NULL,                 /* lockfunc, lockarg */
903            &sc->txbuf_tag);
904        if (error != 0) {
905                device_printf(sc->dev,
906                    "could not create TX ring DMA tag.\n");
907                goto out;
908        }
909
910        for (idx = 0; idx < TX_DESC_COUNT; idx++) {
911                error = bus_dmamap_create(sc->txbuf_tag, BUS_DMA_COHERENT,
912                    &sc->txbuf_map[idx].map);
913                if (error != 0) {
914                        device_printf(sc->dev,
915                            "could not create TX buffer DMA map.\n");
916                        goto out;
917                }
918                dwc_setup_txdesc(sc, idx, 0, 0);
919        }
920
921        /*
922         * Set up RX descriptor ring, descriptors, dma maps, and mbufs.
923         */
924        error = bus_dma_tag_create(
925            bus_get_dma_tag(sc->dev),   /* Parent tag. */
926            DWC_DESC_RING_ALIGN, 0,     /* alignment, boundary */
927            BUS_SPACE_MAXADDR_32BIT,    /* lowaddr */
928            BUS_SPACE_MAXADDR,          /* highaddr */
929            NULL, NULL,                 /* filter, filterarg */
930            RX_DESC_SIZE, 1,            /* maxsize, nsegments */
931            RX_DESC_SIZE,               /* maxsegsize */
932            0,                          /* flags */
933            NULL, NULL,                 /* lockfunc, lockarg */
934            &sc->rxdesc_tag);
935        if (error != 0) {
936                device_printf(sc->dev,
937                    "could not create RX ring DMA tag.\n");
938                goto out;
939        }
940
941        error = bus_dmamem_alloc(sc->rxdesc_tag, (void **)&sc->rxdesc_ring,
942            BUS_DMA_COHERENT | BUS_DMA_WAITOK | BUS_DMA_ZERO,
943            &sc->rxdesc_map);
944        if (error != 0) {
945                device_printf(sc->dev,
946                    "could not allocate RX descriptor ring.\n");
947                goto out;
948        }
949
950        error = bus_dmamap_load(sc->rxdesc_tag, sc->rxdesc_map,
951            sc->rxdesc_ring, RX_DESC_SIZE, dwc_get1paddr,
952            &sc->rxdesc_ring_paddr, 0);
953        if (error != 0) {
954                device_printf(sc->dev,
955                    "could not load RX descriptor ring map.\n");
956                goto out;
957        }
958
959        error = bus_dma_tag_create(
960            bus_get_dma_tag(sc->dev),   /* Parent tag. */
961            1, 0,                       /* alignment, boundary */
962            BUS_SPACE_MAXADDR_32BIT,    /* lowaddr */
963            BUS_SPACE_MAXADDR,          /* highaddr */
964            NULL, NULL,                 /* filter, filterarg */
965            MCLBYTES, 1,                /* maxsize, nsegments */
966            MCLBYTES,                   /* maxsegsize */
967            0,                          /* flags */
968            NULL, NULL,                 /* lockfunc, lockarg */
969            &sc->rxbuf_tag);
970        if (error != 0) {
971                device_printf(sc->dev,
972                    "could not create RX buf DMA tag.\n");
973                goto out;
974        }
975
976        for (idx = 0; idx < RX_DESC_COUNT; idx++) {
977                error = bus_dmamap_create(sc->rxbuf_tag, BUS_DMA_COHERENT,
978                    &sc->rxbuf_map[idx].map);
979                if (error != 0) {
980                        device_printf(sc->dev,
981                            "could not create RX buffer DMA map.\n");
982                        goto out;
983                }
984                if ((m = dwc_alloc_mbufcl(sc)) == NULL) {
985                        device_printf(sc->dev, "Could not alloc mbuf\n");
986                        error = ENOMEM;
987                        goto out;
988                }
989                if ((error = dwc_setup_rxbuf(sc, idx, m)) != 0) {
990                        device_printf(sc->dev,
991                            "could not create new RX buffer.\n");
992                        goto out;
993                }
994        }
995
996out:
997        if (error != 0)
998                return (ENXIO);
999
1000        return (0);
1001}
1002
1003static int
1004dwc_get_hwaddr(struct dwc_softc *sc, uint8_t *hwaddr)
1005{
1006        uint32_t hi, lo, rnd;
1007
1008        /*
1009         * Try to recover a MAC address from the running hardware. If there's
1010         * something non-zero there, assume the bootloader did the right thing
1011         * and just use it.
1012         *
1013         * Otherwise, set the address to a convenient locally assigned address,
1014         * 'bsd' + random 24 low-order bits.  'b' is 0x62, which has the locally
1015         * assigned bit set, and the broadcast/multicast bit clear.
1016         */
1017        lo = READ4(sc, MAC_ADDRESS_LOW(0));
1018        hi = READ4(sc, MAC_ADDRESS_HIGH(0)) & 0xffff;
1019        if ((lo != 0xffffffff) || (hi != 0xffff)) {
1020                hwaddr[0] = (lo >>  0) & 0xff;
1021                hwaddr[1] = (lo >>  8) & 0xff;
1022                hwaddr[2] = (lo >> 16) & 0xff;
1023                hwaddr[3] = (lo >> 24) & 0xff;
1024                hwaddr[4] = (hi >>  0) & 0xff;
1025                hwaddr[5] = (hi >>  8) & 0xff;
1026        } else {
1027                rnd = arc4random() & 0x00ffffff;
1028                hwaddr[0] = 'b';
1029                hwaddr[1] = 's';
1030                hwaddr[2] = 'd';
1031                hwaddr[3] = rnd >> 16;
1032                hwaddr[4] = rnd >>  8;
1033                hwaddr[5] = rnd >>  0;
1034        }
1035
1036        return (0);
1037}
1038
1039#define GPIO_ACTIVE_LOW 1
1040
1041static int
1042dwc_reset(device_t dev)
1043{
1044#ifndef __rtems__
1045        pcell_t gpio_prop[4];
1046        pcell_t delay_prop[3];
1047        phandle_t node, gpio_node;
1048        device_t gpio;
1049        uint32_t pin, flags;
1050        uint32_t pin_value;
1051
1052        node = ofw_bus_get_node(dev);
1053        if (OF_getencprop(node, "snps,reset-gpio",
1054            gpio_prop, sizeof(gpio_prop)) <= 0)
1055                return (0);
1056
1057        if (OF_getencprop(node, "snps,reset-delays-us",
1058            delay_prop, sizeof(delay_prop)) <= 0) {
1059                device_printf(dev,
1060                    "Wrong property for snps,reset-delays-us");
1061                return (ENXIO);
1062        }
1063
1064        gpio_node = OF_node_from_xref(gpio_prop[0]);
1065        if ((gpio = OF_device_from_xref(gpio_prop[0])) == NULL) {
1066                device_printf(dev,
1067                    "Can't find gpio controller for phy reset\n");
1068                return (ENXIO);
1069        }
1070
1071        if (GPIO_MAP_GPIOS(gpio, node, gpio_node,
1072            nitems(gpio_prop) - 1,
1073            gpio_prop + 1, &pin, &flags) != 0) {
1074                device_printf(dev, "Can't map gpio for phy reset\n");
1075                return (ENXIO);
1076        }
1077
1078        pin_value = GPIO_PIN_LOW;
1079        if (OF_hasprop(node, "snps,reset-active-low"))
1080                pin_value = GPIO_PIN_HIGH;
1081
1082        if (flags & GPIO_ACTIVE_LOW)
1083                pin_value = !pin_value;
1084
1085        GPIO_PIN_SETFLAGS(gpio, pin, GPIO_PIN_OUTPUT);
1086        GPIO_PIN_SET(gpio, pin, pin_value);
1087        DELAY(delay_prop[0]);
1088        GPIO_PIN_SET(gpio, pin, !pin_value);
1089        DELAY(delay_prop[1]);
1090        GPIO_PIN_SET(gpio, pin, pin_value);
1091        DELAY(delay_prop[2]);
1092#endif /* __rtems__ */
1093
1094        return (0);
1095}
1096
1097#ifdef EXT_RESOURCES
1098static int
1099dwc_clock_init(device_t dev)
1100{
1101        hwreset_t rst;
1102        clk_t clk;
1103        int error;
1104
1105        /* Enable clock */
1106        if (clk_get_by_ofw_name(dev, 0, "stmmaceth", &clk) == 0) {
1107                error = clk_enable(clk);
1108                if (error != 0) {
1109                        device_printf(dev, "could not enable main clock\n");
1110                        return (error);
1111                }
1112        }
1113
1114        /* De-assert reset */
1115        if (hwreset_get_by_ofw_name(dev, 0, "stmmaceth", &rst) == 0) {
1116                error = hwreset_deassert(rst);
1117                if (error != 0) {
1118                        device_printf(dev, "could not de-assert reset\n");
1119                        return (error);
1120                }
1121        }
1122
1123        return (0);
1124}
1125#endif
1126
1127static int
1128dwc_probe(device_t dev)
1129{
1130
1131#ifndef __rtems__
1132        if (!ofw_bus_status_okay(dev))
1133                return (ENXIO);
1134
1135        if (!ofw_bus_is_compatible(dev, "snps,dwmac"))
1136                return (ENXIO);
1137#endif /* __rtems__ */
1138
1139        device_set_desc(dev, "Gigabit Ethernet Controller");
1140        return (BUS_PROBE_DEFAULT);
1141}
1142
1143static int
1144dwc_attach(device_t dev)
1145{
1146        uint8_t macaddr[ETHER_ADDR_LEN];
1147        struct dwc_softc *sc;
1148        struct ifnet *ifp;
1149        int error, i;
1150        uint32_t reg;
1151
1152        sc = device_get_softc(dev);
1153        sc->dev = dev;
1154        sc->rx_idx = 0;
1155        sc->txcount = TX_DESC_COUNT;
1156        sc->mii_clk = IF_DWC_MII_CLK(dev);
1157        sc->mactype = IF_DWC_MAC_TYPE(dev);
1158
1159        if (IF_DWC_INIT(dev) != 0)
1160                return (ENXIO);
1161
1162#ifdef EXT_RESOURCES
1163        if (dwc_clock_init(dev) != 0)
1164                return (ENXIO);
1165#endif
1166
1167        if (bus_alloc_resources(dev, dwc_spec, sc->res)) {
1168                device_printf(dev, "could not allocate resources\n");
1169                return (ENXIO);
1170        }
1171
1172        /* Memory interface */
1173        sc->bst = rman_get_bustag(sc->res[0]);
1174        sc->bsh = rman_get_bushandle(sc->res[0]);
1175
1176        /* Read MAC before reset */
1177        if (dwc_get_hwaddr(sc, macaddr)) {
1178                device_printf(sc->dev, "can't get mac\n");
1179                return (ENXIO);
1180        }
1181
1182        /* Reset the PHY if needed */
1183        if (dwc_reset(dev) != 0) {
1184                device_printf(dev, "Can't reset the PHY\n");
1185                return (ENXIO);
1186        }
1187
1188        /* Reset */
1189        reg = READ4(sc, BUS_MODE);
1190        reg |= (BUS_MODE_SWR);
1191        WRITE4(sc, BUS_MODE, reg);
1192
1193        for (i = 0; i < MAC_RESET_TIMEOUT; i++) {
1194                if ((READ4(sc, BUS_MODE) & BUS_MODE_SWR) == 0)
1195                        break;
1196                DELAY(10);
1197        }
1198        if (i >= MAC_RESET_TIMEOUT) {
1199                device_printf(sc->dev, "Can't reset DWC.\n");
1200                return (ENXIO);
1201        }
1202
1203        if (sc->mactype == DWC_GMAC_ALT_DESC) {
1204                reg = BUS_MODE_FIXEDBURST;
1205                reg |= (BUS_MODE_PRIORXTX_41 << BUS_MODE_PRIORXTX_SHIFT);
1206        } else
1207                reg = (BUS_MODE_EIGHTXPBL);
1208        reg |= (BUS_MODE_PBL_BEATS_8 << BUS_MODE_PBL_SHIFT);
1209        WRITE4(sc, BUS_MODE, reg);
1210
1211        /*
1212         * DMA must be stop while changing descriptor list addresses.
1213         */
1214        reg = READ4(sc, OPERATION_MODE);
1215        reg &= ~(MODE_ST | MODE_SR);
1216        WRITE4(sc, OPERATION_MODE, reg);
1217
1218        if (setup_dma(sc))
1219                return (ENXIO);
1220
1221        /* Setup addresses */
1222        WRITE4(sc, RX_DESCR_LIST_ADDR, sc->rxdesc_ring_paddr);
1223        WRITE4(sc, TX_DESCR_LIST_ADDR, sc->txdesc_ring_paddr);
1224
1225        mtx_init(&sc->mtx, device_get_nameunit(sc->dev),
1226            MTX_NETWORK_LOCK, MTX_DEF);
1227
1228        callout_init_mtx(&sc->dwc_callout, &sc->mtx, 0);
1229
1230        /* Setup interrupt handler. */
1231        error = bus_setup_intr(dev, sc->res[1], INTR_TYPE_NET | INTR_MPSAFE,
1232            NULL, dwc_intr, sc, &sc->intr_cookie);
1233        if (error != 0) {
1234                device_printf(dev, "could not setup interrupt handler.\n");
1235                return (ENXIO);
1236        }
1237
1238        /* Set up the ethernet interface. */
1239        sc->ifp = ifp = if_alloc(IFT_ETHER);
1240
1241        ifp->if_softc = sc;
1242        if_initname(ifp, device_get_name(dev), device_get_unit(dev));
1243        ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
1244        ifp->if_capabilities = IFCAP_VLAN_MTU;
1245        ifp->if_capenable = ifp->if_capabilities;
1246        ifp->if_start = dwc_txstart;
1247        ifp->if_ioctl = dwc_ioctl;
1248        ifp->if_init = dwc_init;
1249        IFQ_SET_MAXLEN(&ifp->if_snd, TX_DESC_COUNT - 1);
1250        ifp->if_snd.ifq_drv_maxlen = TX_DESC_COUNT - 1;
1251        IFQ_SET_READY(&ifp->if_snd);
1252
1253        /* Attach the mii driver. */
1254        error = mii_attach(dev, &sc->miibus, ifp, dwc_media_change,
1255            dwc_media_status, BMSR_DEFCAPMASK, MII_PHY_ANY,
1256            MII_OFFSET_ANY, 0);
1257
1258        if (error != 0) {
1259                device_printf(dev, "PHY attach failed\n");
1260                return (ENXIO);
1261        }
1262        sc->mii_softc = device_get_softc(sc->miibus);
1263
1264        /* All ready to run, attach the ethernet interface. */
1265        ether_ifattach(ifp, macaddr);
1266        sc->is_attached = true;
1267
1268        return (0);
1269}
1270
1271static int
1272dwc_miibus_read_reg(device_t dev, int phy, int reg)
1273{
1274        struct dwc_softc *sc;
1275        uint16_t mii;
1276        size_t cnt;
1277        int rv = 0;
1278
1279        sc = device_get_softc(dev);
1280
1281        mii = ((phy & GMII_ADDRESS_PA_MASK) << GMII_ADDRESS_PA_SHIFT)
1282            | ((reg & GMII_ADDRESS_GR_MASK) << GMII_ADDRESS_GR_SHIFT)
1283            | (sc->mii_clk << GMII_ADDRESS_CR_SHIFT)
1284            | GMII_ADDRESS_GB; /* Busy flag */
1285
1286        WRITE4(sc, GMII_ADDRESS, mii);
1287
1288        for (cnt = 0; cnt < 1000; cnt++) {
1289                if (!(READ4(sc, GMII_ADDRESS) & GMII_ADDRESS_GB)) {
1290                        rv = READ4(sc, GMII_DATA);
1291                        break;
1292                }
1293                DELAY(10);
1294        }
1295
1296        return rv;
1297}
1298
1299static int
1300dwc_miibus_write_reg(device_t dev, int phy, int reg, int val)
1301{
1302        struct dwc_softc *sc;
1303        uint16_t mii;
1304        size_t cnt;
1305
1306        sc = device_get_softc(dev);
1307
1308        mii = ((phy & GMII_ADDRESS_PA_MASK) << GMII_ADDRESS_PA_SHIFT)
1309            | ((reg & GMII_ADDRESS_GR_MASK) << GMII_ADDRESS_GR_SHIFT)
1310            | (sc->mii_clk << GMII_ADDRESS_CR_SHIFT)
1311            | GMII_ADDRESS_GB | GMII_ADDRESS_GW;
1312
1313        WRITE4(sc, GMII_DATA, val);
1314        WRITE4(sc, GMII_ADDRESS, mii);
1315
1316        for (cnt = 0; cnt < 1000; cnt++) {
1317                if (!(READ4(sc, GMII_ADDRESS) & GMII_ADDRESS_GB)) {
1318                        break;
1319                }
1320                DELAY(10);
1321        }
1322
1323        return (0);
1324}
1325
1326static void
1327dwc_miibus_statchg(device_t dev)
1328{
1329        struct dwc_softc *sc;
1330        struct mii_data *mii;
1331        uint32_t reg;
1332
1333        /*
1334         * Called by the MII bus driver when the PHY establishes
1335         * link to set the MAC interface registers.
1336         */
1337
1338        sc = device_get_softc(dev);
1339
1340        DWC_ASSERT_LOCKED(sc);
1341
1342        mii = sc->mii_softc;
1343
1344        if (mii->mii_media_status & IFM_ACTIVE)
1345                sc->link_is_up = true;
1346        else
1347                sc->link_is_up = false;
1348
1349        reg = READ4(sc, MAC_CONFIGURATION);
1350        switch (IFM_SUBTYPE(mii->mii_media_active)) {
1351        case IFM_1000_T:
1352        case IFM_1000_SX:
1353                reg &= ~(CONF_FES | CONF_PS);
1354                break;
1355        case IFM_100_TX:
1356                reg |= (CONF_FES | CONF_PS);
1357                break;
1358        case IFM_10_T:
1359                reg &= ~(CONF_FES);
1360                reg |= (CONF_PS);
1361                break;
1362        case IFM_NONE:
1363                sc->link_is_up = false;
1364                return;
1365        default:
1366                sc->link_is_up = false;
1367                device_printf(dev, "Unsupported media %u\n",
1368                    IFM_SUBTYPE(mii->mii_media_active));
1369                return;
1370        }
1371        if ((IFM_OPTIONS(mii->mii_media_active) & IFM_FDX) != 0)
1372                reg |= (CONF_DM);
1373        else
1374                reg &= ~(CONF_DM);
1375        WRITE4(sc, MAC_CONFIGURATION, reg);
1376}
1377
1378static device_method_t dwc_methods[] = {
1379        DEVMETHOD(device_probe,         dwc_probe),
1380        DEVMETHOD(device_attach,        dwc_attach),
1381
1382        /* MII Interface */
1383        DEVMETHOD(miibus_readreg,       dwc_miibus_read_reg),
1384        DEVMETHOD(miibus_writereg,      dwc_miibus_write_reg),
1385        DEVMETHOD(miibus_statchg,       dwc_miibus_statchg),
1386
1387        { 0, 0 }
1388};
1389
1390driver_t dwc_driver = {
1391        "dwc",
1392        dwc_methods,
1393        sizeof(struct dwc_softc),
1394};
1395
1396static devclass_t dwc_devclass;
1397
1398DRIVER_MODULE(dwc, simplebus, dwc_driver, dwc_devclass, 0, 0);
1399DRIVER_MODULE(miibus, dwc, miibus_driver, miibus_devclass, 0, 0);
1400
1401MODULE_DEPEND(dwc, ether, 1, 1, 1);
1402MODULE_DEPEND(dwc, miibus, 1, 1, 1);
Note: See TracBrowser for help on using the repository browser.