Source-Changes-HG archive

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

[src/trunk]: src/sys/dev/marvell Add ARMEB support to mvgbe(4).



details:   https://anonhg.NetBSD.org/src/rev/a70cb3cfa5e5
branches:  trunk
changeset: 1023216:a70cb3cfa5e5
user:      rin <rin%NetBSD.org@localhost>
date:      Mon Aug 30 00:08:28 2021 +0000

description:
Add ARMEB support to mvgbe(4).

For ARMEB, peripheral is configured to little-endian mode, even if
CPU itself is in big-endian mode. Therefore, we need to configure
the device to little-endian mode, and byte-swap descriptor fields
(unlike the case of powerpc).

diffstat:

 sys/dev/marvell/if_mvgbe.c |  72 ++++++++++++++++++++++++---------------------
 sys/dev/marvell/mvgbereg.h |  35 +++++++++++++++++++---
 2 files changed, 68 insertions(+), 39 deletions(-)

diffs (281 lines):

diff -r 239ea346ef32 -r a70cb3cfa5e5 sys/dev/marvell/if_mvgbe.c
--- a/sys/dev/marvell/if_mvgbe.c        Mon Aug 30 00:06:26 2021 +0000
+++ b/sys/dev/marvell/if_mvgbe.c        Mon Aug 30 00:08:28 2021 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: if_mvgbe.c,v 1.61 2021/08/07 16:19:13 thorpej Exp $    */
+/*     $NetBSD: if_mvgbe.c,v 1.62 2021/08/30 00:08:28 rin Exp $        */
 /*
  * Copyright (c) 2007, 2008, 2013 KIYOHARA Takashi
  * All rights reserved.
@@ -25,7 +25,7 @@
  * POSSIBILITY OF SUCH DAMAGE.
  */
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_mvgbe.c,v 1.61 2021/08/07 16:19:13 thorpej Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_mvgbe.c,v 1.62 2021/08/30 00:08:28 rin Exp $");
 
 #include "opt_multiprocessor.h"
 
@@ -1254,7 +1254,7 @@
        /* Set SDC register except IPGINT bits */
        MVGBE_WRITE(sc, MVGBE_SDC,
            MVGBE_SDC_RXBSZ_16_64BITWORDS |
-#if BYTE_ORDER == LITTLE_ENDIAN
+#ifndef MVGBE_BIG_ENDIAN
            MVGBE_SDC_BLMR |    /* Big/Little Endian Receive Mode: No swap */
            MVGBE_SDC_BLMT |    /* Big/Little Endian Transmit Mode: No swap */
 #endif
@@ -1517,12 +1517,12 @@
                        cd->mvgbe_rx_chain[i].mvgbe_next =
                            &cd->mvgbe_rx_chain[0];
                        rd->mvgbe_rx_ring[i].nextdescptr =
-                           MVGBE_RX_RING_ADDR(sc, 0);
+                           H2MVGBE32(MVGBE_RX_RING_ADDR(sc, 0));
                } else {
                        cd->mvgbe_rx_chain[i].mvgbe_next =
                            &cd->mvgbe_rx_chain[i + 1];
                        rd->mvgbe_rx_ring[i].nextdescptr =
-                           MVGBE_RX_RING_ADDR(sc, i + 1);
+                           H2MVGBE32(MVGBE_RX_RING_ADDR(sc, i + 1));
                }
        }
 
@@ -1557,14 +1557,15 @@
                        cd->mvgbe_tx_chain[i].mvgbe_next =
                            &cd->mvgbe_tx_chain[0];
                        rd->mvgbe_tx_ring[i].nextdescptr =
-                           MVGBE_TX_RING_ADDR(sc, 0);
+                           H2MVGBE32(MVGBE_TX_RING_ADDR(sc, 0));
                } else {
                        cd->mvgbe_tx_chain[i].mvgbe_next =
                            &cd->mvgbe_tx_chain[i + 1];
                        rd->mvgbe_tx_ring[i].nextdescptr =
-                           MVGBE_TX_RING_ADDR(sc, i + 1);
+                           H2MVGBE32(MVGBE_TX_RING_ADDR(sc, i + 1));
                }
-               rd->mvgbe_tx_ring[i].cmdsts = MVGBE_BUFFER_OWNED_BY_HOST;
+               rd->mvgbe_tx_ring[i].cmdsts =
+                   H2MVGBE32(MVGBE_BUFFER_OWNED_BY_HOST);
        }
 
        sc->sc_cdata.mvgbe_tx_prod = 0;
@@ -1629,9 +1630,10 @@
        r = c->mvgbe_desc;
        c->mvgbe_mbuf = m_new;
        offset = (vaddr_t)m_new->m_data - (vaddr_t)sc->sc_cdata.mvgbe_jumbo_buf;
-       r->bufptr = dmamap->dm_segs[0].ds_addr + offset;
+       r->bufptr = H2MVGBE32(dmamap->dm_segs[0].ds_addr + offset);
        r->bufsize = MVGBE_JLEN & ~MVGBE_RXBUF_MASK;
-       r->cmdsts = MVGBE_BUFFER_OWNED_BY_DMA | MVGBE_RX_ENABLE_INTERRUPT;
+       r->cmdsts =
+           H2MVGBE32(MVGBE_BUFFER_OWNED_BY_DMA | MVGBE_RX_ENABLE_INTERRUPT);
 
        /* Invalidate RX buffer */
        bus_dmamap_sync(sc->sc_dmat, dmamap, offset, r->bufsize,
@@ -1873,10 +1875,10 @@
 
        for (i = 0; i < txmap->dm_nsegs; i++) {
                f = &sc->sc_rdata->mvgbe_tx_ring[current];
-               f->bufptr = txseg[i].ds_addr;
-               f->bytecnt = txseg[i].ds_len;
+               f->bufptr = H2MVGBE32(txseg[i].ds_addr);
+               f->bytecnt = H2MVGBE16(txseg[i].ds_len);
                if (i != 0)
-                       f->cmdsts = MVGBE_BUFFER_OWNED_BY_DMA;
+                       f->cmdsts = H2MVGBE32(MVGBE_BUFFER_OWNED_BY_DMA);
                last = current;
                current = MVGBE_TX_RING_NEXT(current);
        }
@@ -1897,21 +1899,21 @@
                    MVGBE_TX_IP_HEADER_LEN(iphdr_unitlen);      /* unit is 4B */
        }
        if (txmap->dm_nsegs == 1)
-               f->cmdsts = cmdsts              |
+               f->cmdsts = H2MVGBE32(cmdsts    |
                    MVGBE_TX_ENABLE_INTERRUPT   |
                    MVGBE_TX_ZERO_PADDING       |
                    MVGBE_TX_FIRST_DESC         |
-                   MVGBE_TX_LAST_DESC;
+                   MVGBE_TX_LAST_DESC);
        else {
                f = &sc->sc_rdata->mvgbe_tx_ring[first];
-               f->cmdsts = cmdsts | MVGBE_TX_FIRST_DESC;
+               f->cmdsts = H2MVGBE32(cmdsts | MVGBE_TX_FIRST_DESC);
 
                f = &sc->sc_rdata->mvgbe_tx_ring[last];
-               f->cmdsts =
+               f->cmdsts = H2MVGBE32(
                    MVGBE_BUFFER_OWNED_BY_DMA   |
                    MVGBE_TX_ENABLE_INTERRUPT   |
                    MVGBE_TX_ZERO_PADDING       |
-                   MVGBE_TX_LAST_DESC;
+                   MVGBE_TX_LAST_DESC);
 
                /* Sync descriptors except first */
                MVGBE_CDTXSYNC(sc,
@@ -1926,7 +1928,7 @@
 
        /* Finally, sync first descriptor */
        sc->sc_rdata->mvgbe_tx_ring[first].cmdsts |=
-           MVGBE_BUFFER_OWNED_BY_DMA;
+           H2MVGBE32(MVGBE_BUFFER_OWNED_BY_DMA);
        MVGBE_CDTXSYNC(sc, *txidx, 1,
            BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
 
@@ -1963,7 +1965,8 @@
 
                cur_rx = &sc->sc_rdata->mvgbe_rx_ring[idx];
 
-               if ((cur_rx->cmdsts & MVGBE_BUFFER_OWNED_MASK) ==
+               rxstat = MVGBE2H32(cur_rx->cmdsts);
+               if ((rxstat & MVGBE_BUFFER_OWNED_MASK) ==
                    MVGBE_BUFFER_OWNED_BY_DMA) {
                        /* Invalidate the descriptor -- it's not ready yet */
                        MVGBE_CDRXSYNC(sc, idx, BUS_DMASYNC_PREREAD);
@@ -1971,7 +1974,7 @@
                        break;
                }
 #ifdef DIAGNOSTIC
-               if ((cur_rx->cmdsts &
+               if ((rxstat &
                    (MVGBE_RX_LAST_DESC | MVGBE_RX_FIRST_DESC)) !=
                    (MVGBE_RX_LAST_DESC | MVGBE_RX_FIRST_DESC))
                        panic(
@@ -1985,8 +1988,7 @@
 
                m = cdata->mvgbe_rx_chain[idx].mvgbe_mbuf;
                cdata->mvgbe_rx_chain[idx].mvgbe_mbuf = NULL;
-               total_len = cur_rx->bytecnt - ETHER_CRC_LEN;
-               rxstat = cur_rx->cmdsts;
+               total_len = MVGBE2H16(cur_rx->bytecnt) - ETHER_CRC_LEN;
                bufsize = cur_rx->bufsize;
 
                cdata->mvgbe_rx_map[idx] = NULL;
@@ -2083,6 +2085,7 @@
        struct mvgbe_tx_desc *cur_tx;
        struct ifnet *ifp = &sc->sc_ethercom.ec_if;
        struct mvgbe_txmap_entry *entry;
+       uint32_t txstat;
        int idx;
 
        DPRINTFN(3, ("mvgbe_txeof\n"));
@@ -2101,15 +2104,16 @@
                if (mvgbe_debug >= 3)
                        mvgbe_dump_txdesc(cur_tx, idx);
 #endif
-               if ((cur_tx->cmdsts & MVGBE_BUFFER_OWNED_MASK) ==
+               txstat = MVGBE2H32(cur_tx->cmdsts);
+               if ((txstat & MVGBE_BUFFER_OWNED_MASK) ==
                    MVGBE_BUFFER_OWNED_BY_DMA) {
                        MVGBE_CDTXSYNC(sc, idx, 1, BUS_DMASYNC_PREREAD);
                        break;
                }
-               if (cur_tx->cmdsts & MVGBE_TX_LAST_DESC)
+               if (txstat & MVGBE_TX_LAST_DESC)
                        if_statinc(ifp, if_opackets);
-               if (cur_tx->cmdsts & MVGBE_ERROR_SUMMARY) {
-                       int err = cur_tx->cmdsts & MVGBE_TX_ERROR_CODE_MASK;
+               if (txstat & MVGBE_ERROR_SUMMARY) {
+                       int err = txstat & MVGBE_TX_ERROR_CODE_MASK;
 
                        if (err == MVGBE_TX_LATE_COLLISION_ERROR)
                                if_statinc(ifp, if_collisions);
@@ -2256,18 +2260,18 @@
        if (X)                                          \
                printf("txdesc[%d]." #X "=%#x\n", idx, X);
 
-#if BYTE_ORDER == BIG_ENDIAN
+#ifdef MVGBE_BIG_ENDIAN
        DESC_PRINT(desc->bytecnt);
        DESC_PRINT(desc->l4ichk);
        DESC_PRINT(desc->cmdsts);
        DESC_PRINT(desc->nextdescptr);
        DESC_PRINT(desc->bufptr);
-#else  /* LITTLE_ENDIAN */
-       DESC_PRINT(desc->cmdsts);
-       DESC_PRINT(desc->l4ichk);
-       DESC_PRINT(desc->bytecnt);
-       DESC_PRINT(desc->bufptr);
-       DESC_PRINT(desc->nextdescptr);
+#else
+       DESC_PRINT(MVGBE2H32(desc->cmdsts));
+       DESC_PRINT(MVGBE2H16(desc->l4ichk));
+       DESC_PRINT(MVGBE2H16(desc->bytecnt));
+       DESC_PRINT(MVGBE2H32(desc->bufptr));
+       DESC_PRINT(MVGBE2H32(desc->nextdescptr));
 #endif
 #undef DESC_PRINT
 }
diff -r 239ea346ef32 -r a70cb3cfa5e5 sys/dev/marvell/mvgbereg.h
--- a/sys/dev/marvell/mvgbereg.h        Mon Aug 30 00:06:26 2021 +0000
+++ b/sys/dev/marvell/mvgbereg.h        Mon Aug 30 00:08:28 2021 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: mvgbereg.h,v 1.8 2013/12/23 02:23:25 kiyohara Exp $    */
+/*     $NetBSD: mvgbereg.h,v 1.9 2021/08/30 00:08:28 rin Exp $ */
 /*
  * Copyright (c) 2007, 2013 KIYOHARA Takashi
  * All rights reserved.
@@ -27,6 +27,31 @@
 #ifndef _MVGBEREG_H_
 #define _MVGBEREG_H_
 
+/*
+ * For ARMEB, peripheral is configured to little-endian mode, even if
+ * CPU itself is in big-endian mode...
+ */
+
+#if BYTE_ORDER == BIG_ENDIAN && !defined(__arm__)
+#define        MVGBE_BIG_ENDIAN
+#endif
+
+/*
+ * ... therefore, we need byte-swapping descriptor fields.
+ */
+
+#if BYTE_ORDER == BIG_ENDIAN && defined(__arm__)
+#define        H2MVGBE16(x)    htole16(x)
+#define        H2MVGBE32(x)    htole32(x)
+#define        MVGBE2H16(x)    le16toh(x)
+#define        MVGBE2H32(x)    le32toh(x)
+#else
+#define        H2MVGBE16(x)    (x)
+#define        H2MVGBE32(x)    (x)
+#define        MVGBE2H16(x)    (x)
+#define        MVGBE2H32(x)    (x)
+#endif
+
 #define MVGBE_SIZE             0x4000
 
 #define MVGBE_NWINDOW          6
@@ -758,13 +783,13 @@
  *    by the hardware.  We'll just pad them out to that to make it easier.
  */
 struct mvgbe_tx_desc {
-#if BYTE_ORDER == BIG_ENDIAN
+#ifdef MVGBE_BIG_ENDIAN
        uint16_t bytecnt;               /* Descriptor buffer byte count */
        uint16_t l4ichk;                /* CPU provided TCP Checksum */
        uint32_t cmdsts;                /* Descriptor command status */
        uint32_t nextdescptr;           /* Next descriptor pointer */
        uint32_t bufptr;                /* Descriptor buffer pointer */
-#else  /* LITTLE_ENDIAN */
+#else
        uint32_t cmdsts;                /* Descriptor command status */
        uint16_t l4ichk;                /* CPU provided TCP Checksum */
        uint16_t bytecnt;               /* Descriptor buffer byte count */
@@ -775,13 +800,13 @@
 } __packed;
 
 struct mvgbe_rx_desc {
-#if BYTE_ORDER == BIG_ENDIAN
+#ifdef MVGBE_BIG_ENDIAN
        uint16_t bytecnt;               /* Descriptor buffer byte count */
        uint16_t bufsize;               /* Buffer size */
        uint32_t cmdsts;                /* Descriptor command status */
        uint32_t nextdescptr;           /* Next descriptor pointer */
        uint32_t bufptr;                /* Descriptor buffer pointer */
-#else  /* LITTLE_ENDIAN */
+#else
        uint32_t cmdsts;                /* Descriptor command status */
        uint16_t bufsize;               /* Buffer size */
        uint16_t bytecnt;               /* Descriptor buffer byte count */



Home | Main Index | Thread Index | Old Index