Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/dev/ic Revert the recent support for enhanced descriptor...



details:   https://anonhg.NetBSD.org/src/rev/8c0e97ee2caf
branches:  trunk
changeset: 433699:8c0e97ee2caf
user:      aymeric <aymeric%NetBSD.org@localhost>
date:      Fri Sep 28 21:51:42 2018 +0000

description:
Revert the recent support for enhanced descriptors until a viable solution is
found.

It broke at least Cubietruck, Orange Pi One, and maybe Rock64 ethernets in
different ways. Unfortunately it works on my Olinuxino Micro and Lime 2 so I
can't reproduce the bugs for now.

Should fix PR#53637

diffstat:

 sys/dev/ic/dwc_gmac.c     |  233 ++++++++-------------------------------------
 sys/dev/ic/dwc_gmac_reg.h |   30 +-----
 sys/dev/ic/dwc_gmac_var.h |   19 +---
 3 files changed, 46 insertions(+), 236 deletions(-)

diffs (truncated from 497 to 300 lines):

diff -r af1a25487a0e -r 8c0e97ee2caf sys/dev/ic/dwc_gmac.c
--- a/sys/dev/ic/dwc_gmac.c     Fri Sep 28 17:28:01 2018 +0000
+++ b/sys/dev/ic/dwc_gmac.c     Fri Sep 28 21:51:42 2018 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: dwc_gmac.c,v 1.53 2018/09/17 20:25:49 aymeric Exp $ */
+/* $NetBSD: dwc_gmac.c,v 1.54 2018/09/28 21:51:42 aymeric Exp $ */
 
 /*-
  * Copyright (c) 2013, 2014 The NetBSD Foundation, Inc.
@@ -41,7 +41,7 @@
 
 #include <sys/cdefs.h>
 
-__KERNEL_RCSID(1, "$NetBSD: dwc_gmac.c,v 1.53 2018/09/17 20:25:49 aymeric Exp $");
+__KERNEL_RCSID(1, "$NetBSD: dwc_gmac.c,v 1.54 2018/09/28 21:51:42 aymeric Exp $");
 
 /* #define     DWC_GMAC_DEBUG  1 */
 
@@ -100,53 +100,6 @@
 static void dwc_gmac_setmulti(struct dwc_gmac_softc *sc);
 static int dwc_gmac_ifflags_cb(struct ethercom *);
 static uint32_t        bitrev32(uint32_t x);
-static void dwc_gmac_desc_set_owned_by_dev(struct dwc_gmac_dev_dmadesc *);
-static int  dwc_gmac_desc_is_owned_by_dev(struct dwc_gmac_dev_dmadesc *);
-static void dwc_gmac_desc_std_set_len(struct dwc_gmac_dev_dmadesc *, int);
-static int  dwc_gmac_desc_std_get_len(struct dwc_gmac_dev_dmadesc *);
-static void dwc_gmac_desc_std_tx_init_flags(struct dwc_gmac_dev_dmadesc *);
-static void dwc_gmac_desc_std_tx_set_first_frag(struct dwc_gmac_dev_dmadesc *);
-static void dwc_gmac_desc_std_tx_set_last_frag(struct dwc_gmac_dev_dmadesc *);
-static void dwc_gmac_desc_std_rx_init_flags(struct dwc_gmac_dev_dmadesc *);
-static int  dwc_gmac_desc_std_rx_has_error(struct dwc_gmac_dev_dmadesc *);
-static void dwc_gmac_desc_enh_set_len(struct dwc_gmac_dev_dmadesc *, int);
-static int  dwc_gmac_desc_enh_get_len(struct dwc_gmac_dev_dmadesc *);
-static void dwc_gmac_desc_enh_tx_init_flags(struct dwc_gmac_dev_dmadesc *);
-static void dwc_gmac_desc_enh_tx_set_first_frag(struct dwc_gmac_dev_dmadesc *);
-static void dwc_gmac_desc_enh_tx_set_last_frag(struct dwc_gmac_dev_dmadesc *);
-static void dwc_gmac_desc_enh_rx_init_flags(struct dwc_gmac_dev_dmadesc *);
-static int  dwc_gmac_desc_enh_rx_has_error(struct dwc_gmac_dev_dmadesc *);
-
-static const struct dwc_gmac_desc_methods desc_methods_standard = {
-       .tx_init_flags = dwc_gmac_desc_std_tx_init_flags,
-       .tx_set_owned_by_dev = dwc_gmac_desc_set_owned_by_dev,
-       .tx_is_owned_by_dev = dwc_gmac_desc_is_owned_by_dev,
-       .tx_set_len = dwc_gmac_desc_std_set_len,
-       .tx_set_first_frag = dwc_gmac_desc_std_tx_set_first_frag,
-       .tx_set_last_frag = dwc_gmac_desc_std_tx_set_last_frag,
-       .rx_init_flags = dwc_gmac_desc_std_rx_init_flags,
-       .rx_set_owned_by_dev = dwc_gmac_desc_set_owned_by_dev,
-       .rx_is_owned_by_dev = dwc_gmac_desc_is_owned_by_dev,
-       .rx_set_len = dwc_gmac_desc_std_set_len,
-       .rx_get_len = dwc_gmac_desc_std_get_len,
-       .rx_has_error = dwc_gmac_desc_std_rx_has_error
-};
-
-static const struct dwc_gmac_desc_methods desc_methods_enhanced = {
-       .tx_init_flags = dwc_gmac_desc_enh_tx_init_flags,
-       .tx_set_owned_by_dev = dwc_gmac_desc_set_owned_by_dev,
-       .tx_is_owned_by_dev = dwc_gmac_desc_is_owned_by_dev,
-       .tx_set_len = dwc_gmac_desc_enh_set_len,
-       .tx_set_first_frag = dwc_gmac_desc_enh_tx_set_first_frag,
-       .tx_set_last_frag = dwc_gmac_desc_enh_tx_set_last_frag,
-       .rx_init_flags = dwc_gmac_desc_enh_rx_init_flags,
-       .rx_set_owned_by_dev = dwc_gmac_desc_set_owned_by_dev,
-       .rx_is_owned_by_dev = dwc_gmac_desc_is_owned_by_dev,
-       .rx_set_len = dwc_gmac_desc_enh_set_len,
-       .rx_get_len = dwc_gmac_desc_enh_get_len,
-       .rx_has_error = dwc_gmac_desc_enh_rx_has_error
-};
-
 
 #define        TX_DESC_OFFSET(N)       ((AWGE_RX_RING_COUNT+(N)) \
                                    *sizeof(struct dwc_gmac_dev_dmadesc))
@@ -169,7 +122,7 @@
 
 #define        AWIN_DEF_MAC_INTRMASK   \
        (AWIN_GMAC_MAC_INT_TSI | AWIN_GMAC_MAC_INT_ANEG |       \
-       AWIN_GMAC_MAC_INT_LINKCHG)
+       AWIN_GMAC_MAC_INT_LINKCHG | AWIN_GMAC_MAC_INT_RGSMII)
 
 #ifdef DWC_GMAC_DEBUG
 static void dwc_gmac_dump_dma(struct dwc_gmac_softc *sc);
@@ -241,12 +194,6 @@
        aprint_normal_dev(sc->sc_dev, "Ethernet address %s\n",
            ether_sprintf(enaddr));
 
-       if (bus_space_read_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_DMA_HWFEATURES) &
-           GMAC_DMA_FEAT_ENHANCED_DESC)
-               sc->sc_descm = &desc_methods_enhanced;
-       else
-               sc->sc_descm = &desc_methods_standard;
-
        /*
         * Allocate Tx and Rx rings
         */
@@ -497,9 +444,10 @@
                next = RX_NEXT(i);
                desc->ddesc_next = htole32(ring->r_physaddr
                    + next * sizeof(*desc));
-               sc->sc_descm->rx_init_flags(desc);
-               sc->sc_descm->rx_set_len(desc, AWGE_MAX_PACKET);
-               sc->sc_descm->rx_set_owned_by_dev(desc);
+               desc->ddesc_cntl = htole32(
+                   __SHIFTIN(AWGE_MAX_PACKET,DDESC_CNTL_SIZE1MASK) |
+                   DDESC_CNTL_RXCHAIN);
+               desc->ddesc_status = htole32(DDESC_STATUS_OWNEDBYDEV);
        }
 
        bus_dmamap_sync(sc->sc_dmat, sc->sc_dma_ring_map, 0,
@@ -525,9 +473,10 @@
        mutex_enter(&ring->r_mtx);
        for (i = 0; i < AWGE_RX_RING_COUNT; i++) {
                desc = &sc->sc_rxq.r_desc[i];
-               sc->sc_descm->rx_init_flags(desc);
-               sc->sc_descm->rx_set_len(desc, AWGE_MAX_PACKET);
-               sc->sc_descm->rx_set_owned_by_dev(desc);
+               desc->ddesc_cntl = htole32(
+                   __SHIFTIN(AWGE_MAX_PACKET,DDESC_CNTL_SIZE1MASK) |
+                   DDESC_CNTL_RXCHAIN);
+               desc->ddesc_status = htole32(DDESC_STATUS_OWNEDBYDEV);
        }
 
        bus_dmamap_sync(sc->sc_dmat, sc->sc_dma_ring_map, 0,
@@ -942,11 +891,11 @@
                dwc_gmac_txdesc_sync(sc, start, sc->sc_txq.t_cur,
                    BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
 
+               bus_space_write_4(sc->sc_bst, sc->sc_bsh,
+                   AWIN_GMAC_DMA_TXPOLL, ~0U);
 #ifdef DWC_GMAC_DEBUG
                dwc_dump_status(sc);
 #endif
-               bus_space_write_4(sc->sc_bst, sc->sc_bsh,
-                   AWIN_GMAC_DMA_TXPOLL, ~0U);
        }
 }
 
@@ -993,6 +942,7 @@
        struct dwc_gmac_dev_dmadesc *desc = NULL;
        struct dwc_gmac_tx_data *data = NULL;
        bus_dmamap_t map;
+       uint32_t flags, len, status;
        int error, i, first;
 
 #ifdef DWC_GMAC_DEBUG
@@ -1016,37 +966,38 @@
                return ENOBUFS;
        }
 
+       flags = DDESC_CNTL_TXFIRST|DDESC_CNTL_TXCHAIN;
+       status = 0;
        for (i = 0; i < map->dm_nsegs; i++) {
                data = &sc->sc_txq.t_data[sc->sc_txq.t_cur];
                desc = &sc->sc_txq.t_desc[sc->sc_txq.t_cur];
 
                desc->ddesc_data = htole32(map->dm_segs[i].ds_addr);
+               len = __SHIFTIN(map->dm_segs[i].ds_len, DDESC_CNTL_SIZE1MASK);
 
 #ifdef DWC_GMAC_DEBUG
                aprint_normal_dev(sc->sc_dev, "enqueing desc #%d data %08lx "
-                   "len %lu\n", sc->sc_txq.t_cur,
+                   "len %lu (flags: %08x, len: %08x)\n", sc->sc_txq.t_cur,
                    (unsigned long)map->dm_segs[i].ds_addr,
-                   (unsigned long)map->dm_segs[i].ds_len);
+                   (unsigned long)map->dm_segs[i].ds_len,
+                   flags, len);
 #endif
 
-               sc->sc_descm->tx_init_flags(desc);
-               sc->sc_descm->tx_set_len(desc, map->dm_segs[i].ds_len);
-
-               if (i == 0)
-                       sc->sc_descm->tx_set_first_frag(desc);
+               desc->ddesc_cntl = htole32(len|flags);
+               flags &= ~DDESC_CNTL_TXFIRST;
 
                /*
                 * Defer passing ownership of the first descriptor
                 * until we are done.
                 */
-               if (i != 0)
-                       sc->sc_descm->tx_set_owned_by_dev(desc);
+               desc->ddesc_status = htole32(status);
+               status |= DDESC_STATUS_OWNEDBYDEV;
 
                sc->sc_txq.t_queued++;
                sc->sc_txq.t_cur = TX_NEXT(sc->sc_txq.t_cur);
        }
 
-       sc->sc_descm->tx_set_last_frag(desc);
+       desc->ddesc_cntl |= htole32(DDESC_CNTL_TXLAST|DDESC_CNTL_TXINT);
 
        data->td_m = m0;
        data->td_active = map;
@@ -1055,10 +1006,8 @@
            BUS_DMASYNC_PREWRITE);
 
        /* Pass first to device */
-       sc->sc_descm->tx_set_owned_by_dev(&sc->sc_txq.t_desc[first]);
-
-       bus_dmamap_sync(sc->sc_dmat, map, 0, map->dm_mapsize,
-           BUS_DMASYNC_PREWRITE);
+       sc->sc_txq.t_desc[first].ddesc_status =
+           htole32(DDESC_STATUS_OWNEDBYDEV);
 
        return 0;
 }
@@ -1138,6 +1087,7 @@
        struct ifnet *ifp = &sc->sc_ec.ec_if;
        struct dwc_gmac_tx_data *data;
        struct dwc_gmac_dev_dmadesc *desc;
+       uint32_t status;
        int i, nsegs;
 
        mutex_enter(&sc->sc_txq.t_mtx);
@@ -1158,7 +1108,8 @@
                    BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
 
                desc = &sc->sc_txq.t_desc[i];
-               if (sc->sc_descm->tx_is_owned_by_dev(desc))
+               status = le32toh(desc->ddesc_status);
+               if (status & DDESC_STATUS_OWNEDBYDEV)
                        break;
 
                data = &sc->sc_txq.t_data[i];
@@ -1198,6 +1149,7 @@
        struct dwc_gmac_dev_dmadesc *desc;
        struct dwc_gmac_rx_data *data;
        bus_addr_t physaddr;
+       uint32_t status;
        struct mbuf *m, *mnew;
        int i, len, error;
 
@@ -1209,20 +1161,21 @@
                desc = &sc->sc_rxq.r_desc[i];
                data = &sc->sc_rxq.r_data[i];
 
-               if (sc->sc_descm->rx_is_owned_by_dev(desc))
+               status = le32toh(desc->ddesc_status);
+               if (status & DDESC_STATUS_OWNEDBYDEV)
                        break;
 
-               if (sc->sc_descm->rx_has_error(desc)) {
+               if (status & (DDESC_STATUS_RXERROR|DDESC_STATUS_RXTRUNCATED)) {
 #ifdef DWC_GMAC_DEBUG
                        aprint_normal_dev(sc->sc_dev,
                            "RX error: descriptor status %08x, skipping\n",
-                           le32toh(desc->ddesc_status0));
+                           status);
 #endif
                        ifp->if_ierrors++;
                        goto skip;
                }
 
-               len = sc->sc_descm->rx_get_len(desc);
+               len = __SHIFTOUT(status, DDESC_STATUS_FRMLENMSK);
 
 #ifdef DWC_GMAC_DEBUG
                aprint_normal_dev(sc->sc_dev,
@@ -1288,11 +1241,10 @@
 skip:
                bus_dmamap_sync(sc->sc_dmat, data->rd_map, 0,
                    data->rd_map->dm_mapsize, BUS_DMASYNC_PREREAD);
-
-               sc->sc_descm->rx_init_flags(desc);
-               sc->sc_descm->rx_set_len(desc, AWGE_MAX_PACKET);
-               sc->sc_descm->rx_set_owned_by_dev(desc);
-
+               desc->ddesc_cntl = htole32(
+                   __SHIFTIN(AWGE_MAX_PACKET,DDESC_CNTL_SIZE1MASK) |
+                   DDESC_CNTL_RXCHAIN);
+               desc->ddesc_status = htole32(DDESC_STATUS_OWNEDBYDEV);
                bus_dmamap_sync(sc->sc_dmat, sc->sc_dma_ring_map,
                    RX_DESC_OFFSET(i), sizeof(*desc),
                    BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
@@ -1446,107 +1398,6 @@
        return rv;
 }
 
-static void
-dwc_gmac_desc_set_owned_by_dev(struct dwc_gmac_dev_dmadesc *desc) {
-       desc->ddesc_status0 |= DDESC_STATUS_OWNEDBYDEV;
-}
-
-static int
-dwc_gmac_desc_is_owned_by_dev(struct dwc_gmac_dev_dmadesc *desc) {
-       return !!(desc->ddesc_status0 & DDESC_STATUS_OWNEDBYDEV);
-}
-
-static void
-dwc_gmac_desc_std_set_len(struct dwc_gmac_dev_dmadesc *desc, int len) {
-       uint32_t cntl = le32toh(desc->ddesc_cntl1);
-
-       desc->ddesc_cntl1 = htole32((cntl & ~DDESC_CNTL_SIZE1MASK) |
-               __SHIFTIN(len, DDESC_CNTL_SIZE1MASK));
-}
-
-static int
-dwc_gmac_desc_std_get_len(struct dwc_gmac_dev_dmadesc *desc) {
-       return __SHIFTOUT(le32toh(desc->ddesc_status0), DDESC_STATUS_FRMLENMSK);
-}



Home | Main Index | Thread Index | Old Index