Source-Changes-HG archive

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

[src/trunk]: src/sys/dev/marvell Support Basic Mode for Armada XP.



details:   https://anonhg.NetBSD.org/src/rev/9f0f23a51712
branches:  trunk
changeset: 325400:9f0f23a51712
user:      kiyohara <kiyohara%NetBSD.org@localhost>
date:      Mon Dec 23 02:23:25 2013 +0000

description:
Support Basic Mode for Armada XP.

diffstat:

 sys/dev/marvell/if_mvgbe.c |  203 +++++++++++++++++----
 sys/dev/marvell/mvgbereg.h |  414 ++++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 565 insertions(+), 52 deletions(-)

diffs (truncated from 919 to 300 lines):

diff -r 7d24bdc3ab76 -r 9f0f23a51712 sys/dev/marvell/if_mvgbe.c
--- a/sys/dev/marvell/if_mvgbe.c        Sun Dec 22 23:02:38 2013 +0000
+++ b/sys/dev/marvell/if_mvgbe.c        Mon Dec 23 02:23:25 2013 +0000
@@ -1,6 +1,6 @@
-/*     $NetBSD: if_mvgbe.c,v 1.34 2012/12/28 08:16:53 msaitoh Exp $    */
+/*     $NetBSD: if_mvgbe.c,v 1.35 2013/12/23 02:23:25 kiyohara Exp $   */
 /*
- * Copyright (c) 2007, 2008 KIYOHARA Takashi
+ * Copyright (c) 2007, 2008, 2013 KIYOHARA Takashi
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -25,7 +25,13 @@
  * POSSIBILITY OF SUCH DAMAGE.
  */
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_mvgbe.c,v 1.34 2012/12/28 08:16:53 msaitoh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_mvgbe.c,v 1.35 2013/12/23 02:23:25 kiyohara Exp $");
+
+#include "opt_multiprocessor.h"
+
+#if defined MULTIPROCESSOR
+#warning Queue Management Method 'Counters' not support yet 
+#endif
 
 #include <sys/param.h>
 #include <sys/bus.h>
@@ -80,6 +86,10 @@
 #define MVGBE_WRITE_FILTER(sc, reg, val, c) \
        bus_space_write_region_4((sc)->sc_iot, (sc)->sc_dafh, (reg), (val), (c))
 
+#define MVGBE_LINKUP_READ(sc) \
+    bus_space_read_4((sc)->sc_iot, (sc)->sc_linkup.ioh, 0)
+#define MVGBE_IS_LINKUP(sc)    (MVGBE_LINKUP_READ(sc) & (sc)->sc_linkup.bit)
+
 #define MVGBE_TX_RING_CNT      256
 #define MVGBE_TX_RING_MSK      (MVGBE_TX_RING_CNT - 1)
 #define MVGBE_TX_RING_NEXT(x)  (((x) + 1) & MVGBE_TX_RING_MSK)
@@ -208,6 +218,7 @@
 struct mvgbe_softc {
        device_t sc_dev;
        int sc_port;
+       uint32_t sc_version;
 
        bus_space_tag_t sc_iot;
        bus_space_handle_t sc_ioh;
@@ -232,6 +243,12 @@
        LIST_HEAD(__mvgbe_jinusehead, mvgbe_jpool_entry) sc_jinuse_listhead;
        SIMPLEQ_HEAD(__mvgbe_txmaphead, mvgbe_txmap_entry) sc_txmap_head;
 
+       struct {
+               bus_space_handle_t ioh;
+               uint32_t bit;
+       } sc_linkup;
+       uint32_t sc_cmdsts_opts;
+
        krndsource_t sc_rnd_source;
        struct sysctllog *mvgbe_clog;
 #ifdef MVGBE_EVENT_COUNTERS
@@ -318,6 +335,7 @@
 #define FLAGS_FIX_MTU  (1 << 1)
 #define        FLAGS_IPG1      (1 << 2)
 #define        FLAGS_IPG2      (1 << 3)
+#define        FLAGS_HAS_PV    (1 << 4)        /* Has Port Version Register */
 } mvgbe_ports[] = {
        { MARVELL_DISCOVERY_II,         0, 3, { 32, 33, 34 }, 0 },
        { MARVELL_DISCOVERY_III,        0, 3, { 32, 33, 34 }, 0 },
@@ -348,6 +366,25 @@
        { MARVELL_MV78XX0_MV78200,      1, 1, { 44 }, FLAGS_FIX_TQTB | FLAGS_IPG2 },
        { MARVELL_MV78XX0_MV78200,      2, 1, { 48 }, FLAGS_FIX_TQTB | FLAGS_IPG2 },
        { MARVELL_MV78XX0_MV78200,      3, 1, { 52 }, FLAGS_FIX_TQTB | FLAGS_IPG2 },
+
+       { MARVELL_ARMADAXP_MV78130,     0, 1, { 66 }, FLAGS_HAS_PV },
+       { MARVELL_ARMADAXP_MV78130,     1, 1, { 70 }, FLAGS_HAS_PV },
+       { MARVELL_ARMADAXP_MV78130,     2, 1, { 74 }, FLAGS_HAS_PV },
+       { MARVELL_ARMADAXP_MV78160,     0, 1, { 66 }, FLAGS_HAS_PV },
+       { MARVELL_ARMADAXP_MV78160,     1, 1, { 70 }, FLAGS_HAS_PV },
+       { MARVELL_ARMADAXP_MV78160,     2, 1, { 74 }, FLAGS_HAS_PV },
+       { MARVELL_ARMADAXP_MV78160,     3, 1, { 78 }, FLAGS_HAS_PV },
+       { MARVELL_ARMADAXP_MV78230,     0, 1, { 66 }, FLAGS_HAS_PV },
+       { MARVELL_ARMADAXP_MV78230,     1, 1, { 70 }, FLAGS_HAS_PV },
+       { MARVELL_ARMADAXP_MV78230,     2, 1, { 74 }, FLAGS_HAS_PV },
+       { MARVELL_ARMADAXP_MV78260,     0, 1, { 66 }, FLAGS_HAS_PV },
+       { MARVELL_ARMADAXP_MV78260,     1, 1, { 70 }, FLAGS_HAS_PV },
+       { MARVELL_ARMADAXP_MV78260,     2, 1, { 74 }, FLAGS_HAS_PV },
+       { MARVELL_ARMADAXP_MV78260,     3, 1, { 78 }, FLAGS_HAS_PV },
+       { MARVELL_ARMADAXP_MV78460,     0, 1, { 66 }, FLAGS_HAS_PV },
+       { MARVELL_ARMADAXP_MV78460,     1, 1, { 70 }, FLAGS_HAS_PV },
+       { MARVELL_ARMADAXP_MV78460,     2, 1, { 74 }, FLAGS_HAS_PV },
+       { MARVELL_ARMADAXP_MV78460,     3, 1, { 78 }, FLAGS_HAS_PV },
 };
 
 
@@ -654,6 +691,7 @@
 static void
 mvgbe_attach(device_t parent, device_t self, void *aux)
 {
+       struct mvgbec_softc *csc = device_private(parent);
        struct mvgbe_softc *sc = device_private(self);
        struct marvell_attach_args *mva = aux;
        struct mvgbe_txmap_entry *entry;
@@ -687,6 +725,33 @@
        }
        sc->sc_dmat = mva->mva_dmat;
 
+       if (csc->sc_flags & FLAGS_HAS_PV) {
+               /* GbE port has Port Version register. */
+               sc->sc_version = MVGBE_READ(sc, MVGBE_PV);
+               aprint_normal_dev(self, "Port Version 0x%x\n", sc->sc_version);
+       }
+
+       if (sc->sc_version >= 0x10) {
+               /*
+                * Armada XP
+                */
+
+               if (bus_space_subregion(mva->mva_iot, mva->mva_ioh,
+                   MVGBE_PS0, sizeof(uint32_t), &sc->sc_linkup.ioh)) {
+                       aprint_error_dev(self, "Cannot map linkup register\n");
+                       return;
+               }
+               sc->sc_linkup.bit = MVGBE_PS0_LINKUP;
+               csc->sc_flags |= FLAGS_IPG2;
+       } else {
+               if (bus_space_subregion(mva->mva_iot, sc->sc_ioh,
+                   MVGBE_PS, sizeof(uint32_t), &sc->sc_linkup.ioh)) {
+                       aprint_error_dev(self, "Cannot map linkup register\n");
+                       return;
+               }
+               sc->sc_linkup.bit = MVGBE_PS_LINKUP;
+       }
+
        maddrh = MVGBE_READ(sc, MVGBE_MACAH);
        maddrl = MVGBE_READ(sc, MVGBE_MACAL);
        sc->sc_enaddr[0] = maddrh >> 24;
@@ -938,13 +1003,13 @@
                        break;
 
                if (ice & MVGBE_ICE_LINKCHG) {
-                       if (MVGBE_READ(sc, MVGBE_PS) & MVGBE_PS_LINKUP) {
+                       if (MVGBE_IS_LINKUP(sc)) {
                                /* Enable port RX and TX. */
                                MVGBE_WRITE(sc, MVGBE_RQC, MVGBE_RQC_ENQ(0));
-                               MVGBE_WRITE(sc, MVGBE_TQC, MVGBE_TQC_ENQ);
+                               MVGBE_WRITE(sc, MVGBE_TQC, MVGBE_TQC_ENQ(0));
                        } else {
                                MVGBE_WRITE(sc, MVGBE_RQC, MVGBE_RQC_DISQ(0));
-                               MVGBE_WRITE(sc, MVGBE_TQC, MVGBE_TQC_DISQ);
+                               MVGBE_WRITE(sc, MVGBE_TQC, MVGBE_TQC_DISQ(0));
                        }
 
                        /* Notify link change event to mii layer */
@@ -954,7 +1019,7 @@
                if (ic & (MVGBE_IC_RXBUF | MVGBE_IC_RXERROR))
                        mvgbe_rxeof(sc);
 
-               if (ice & (MVGBE_ICE_TXBUF | MVGBE_ICE_TXERR))
+               if (ice & (MVGBE_ICE_TXBUF_MASK | MVGBE_ICE_TXERR_MASK))
                        mvgbe_txeof(sc);
        }
 
@@ -980,7 +1045,7 @@
        if ((ifp->if_flags & (IFF_RUNNING|IFF_OACTIVE)) != IFF_RUNNING)
                return;
        /* If Link is DOWN, can't start TX */
-       if (!(MVGBE_READ(sc, MVGBE_PS) & MVGBE_PS_LINKUP))
+       if (!MVGBE_IS_LINKUP(sc))
                return;
 
        while (sc->sc_cdata.mvgbe_tx_chain[idx].mvgbe_mbuf == NULL) {
@@ -1014,7 +1079,7 @@
        /* Transmit at Queue 0 */
        if (idx != sc->sc_cdata.mvgbe_tx_prod) {
                sc->sc_cdata.mvgbe_tx_prod = idx;
-               MVGBE_WRITE(sc, MVGBE_TQC, MVGBE_TQC_ENQ);
+               MVGBE_WRITE(sc, MVGBE_TQC, MVGBE_TQC_ENQ(0));
 
                /*
                 * Set a timeout in case the chip goes out to lunch.
@@ -1092,17 +1157,49 @@
        }
        if (csc->sc_flags & FLAGS_FIX_MTU)
                MVGBE_WRITE(sc, MVGBE_MTU, 0);  /* hw reset value is wrong */
-       MVGBE_WRITE(sc, MVGBE_PSC,
-           MVGBE_PSC_ANFC |                    /* Enable Auto-Neg Flow Ctrl */
-           MVGBE_PSC_RESERVED |                /* Must be set to 1 */
-           MVGBE_PSC_FLFAIL |                  /* Do NOT Force Link Fail */
-           MVGBE_PSC_MRU(MVGBE_PSC_MRU_9022) | /* we want 9k */
-           MVGBE_PSC_SETFULLDX);               /* Set_FullDx */
-       /* XXXX: mvgbe(4) always use RGMII. */
-       MVGBE_WRITE(sc, MVGBE_PSC1,
-           MVGBE_READ(sc, MVGBE_PSC1) | MVGBE_PSC1_RGMIIEN);
-       /* XXXX: Also always Weighted Round-Robin Priority Mode */
-       MVGBE_WRITE(sc, MVGBE_TQFPC, MVGBE_TQFPC_EN(0));
+       if (sc->sc_version >= 0x10) {
+               MVGBE_WRITE(csc, MVGBE_PANC,
+                   MVGBE_PANC_FORCELINKPASS    |
+                   MVGBE_PANC_INBANDANBYPASSEN |
+                   MVGBE_PANC_SETMIISPEED      |
+                   MVGBE_PANC_SETGMIISPEED     |
+                   MVGBE_PANC_ANSPEEDEN        |
+                   MVGBE_PANC_SETFCEN          |
+                   MVGBE_PANC_PAUSEADV         |
+                   MVGBE_PANC_SETFULLDX        |
+                   MVGBE_PANC_ANDUPLEXEN       |
+                   MVGBE_PANC_RESERVED);
+               MVGBE_WRITE(csc, MVGBE_PMACC0,
+                   MVGBE_PMACC0_RESERVED |
+                   MVGBE_PMACC0_FRAMESIZELIMIT(1600));
+               MVGBE_WRITE(csc, MVGBE_PMACC2,
+                   MVGBE_PMACC2_PCSEN          |
+                   MVGBE_PMACC2_RESERVED       |
+                   MVGBE_PMACC2_RGMIIEN);
+
+               MVGBE_WRITE(sc, MVGBE_PXCX,
+                   MVGBE_READ(sc, MVGBE_PXCX) & ~MVGBE_PXCX_TXCRCDIS);
+
+#ifndef MULTIPROCESSOR
+               MVGBE_WRITE(sc, MVGBE_PACC, MVGVE_PACC_ACCELERATIONMODE_BM);
+#else
+               MVGBE_WRITE(sc, MVGBE_PACC, MVGVE_PACC_ACCELERATIONMODE_EDM);
+#endif
+       } else {
+               MVGBE_WRITE(sc, MVGBE_PSC,
+                   MVGBE_PSC_ANFC |            /* Enable Auto-Neg Flow Ctrl */
+                   MVGBE_PSC_RESERVED |        /* Must be set to 1 */
+                   MVGBE_PSC_FLFAIL |          /* Do NOT Force Link Fail */
+                   MVGBE_PSC_MRU(MVGBE_PSC_MRU_9022) | /* we want 9k */
+                   MVGBE_PSC_SETFULLDX);       /* Set_FullDx */
+               /* XXXX: mvgbe(4) always use RGMII. */
+               MVGBE_WRITE(sc, MVGBE_PSC1,
+                   MVGBE_READ(sc, MVGBE_PSC1) | MVGBE_PSC1_RGMIIEN);
+               /* XXXX: Also always Weighted Round-Robin Priority Mode */
+               MVGBE_WRITE(sc, MVGBE_TQFPC, MVGBE_TQFPC_EN(0));
+
+               sc->sc_cmdsts_opts = MVGBE_TX_GENERATE_CRC;
+       }
 
        MVGBE_WRITE(sc, MVGBE_CRDP(0), MVGBE_RX_RING_ADDR(sc, 0));
        MVGBE_WRITE(sc, MVGBE_TCQDP, MVGBE_TX_RING_ADDR(sc, 0));
@@ -1119,7 +1216,7 @@
                        MVGBE_WRITE(sc, MVGBE_TQTBCOUNT(i), 0x0);
                        MVGBE_WRITE(sc, MVGBE_TQTBCONFIG(i), 0x0);
                }
-       } else
+       } else if (sc->sc_version < 0x10)
                for (i = 1; i < 8; i++) {
                        MVGBE_WRITE(sc, MVGBE_TQTBCOUNT(i), 0x3fffffff);
                        MVGBE_WRITE(sc, MVGBE_TQTBCONFIG(i), 0xffff7fff);
@@ -1149,14 +1246,19 @@
        mii_mediachg(mii);
 
        /* Enable port */
-       reg = MVGBE_READ(sc, MVGBE_PSC);
-       MVGBE_WRITE(sc, MVGBE_PSC, reg | MVGBE_PSC_PORTEN);
+       if (sc->sc_version >= 0x10) {
+               reg = MVGBE_READ(csc, MVGBE_PMACC0);
+               MVGBE_WRITE(csc, MVGBE_PMACC0, reg | MVGBE_PMACC0_PORTEN);
+       } else {
+               reg = MVGBE_READ(sc, MVGBE_PSC);
+               MVGBE_WRITE(sc, MVGBE_PSC, reg | MVGBE_PSC_PORTEN);
+       }
 
        /* If Link is UP, Start RX and TX traffic */
-       if (MVGBE_READ(sc, MVGBE_PS) & MVGBE_PS_LINKUP) {
+       if (MVGBE_IS_LINKUP(sc)) {
                /* Enable port RX/TX. */
                MVGBE_WRITE(sc, MVGBE_RQC, MVGBE_RQC_ENQ(0));
-               MVGBE_WRITE(sc, MVGBE_TQC, MVGBE_TQC_ENQ);
+               MVGBE_WRITE(sc, MVGBE_TQC, MVGBE_TQC_ENQ(0));
        }
 
        /* Enable interrupt masks */
@@ -1167,8 +1269,8 @@
            MVGBE_IC_RXERROR |
            MVGBE_IC_RXERRQ_MASK);
        MVGBE_WRITE(sc, MVGBE_PEIM,
-           MVGBE_ICE_TXBUF |
-           MVGBE_ICE_TXERR |
+           MVGBE_ICE_TXBUF_MASK |
+           MVGBE_ICE_TXERR_MASK |
            MVGBE_ICE_LINKCHG);
 
        callout_schedule(&sc->sc_tick_ch, hz);
@@ -1186,7 +1288,7 @@
        struct mvgbe_softc *sc = ifp->if_softc;
        struct mvgbec_softc *csc = device_private(device_parent(sc->sc_dev));
        struct mvgbe_chain_data *cdata = &sc->sc_cdata;
-       uint32_t reg;
+       uint32_t reg, txinprog, txfifoemp;
        int i, cnt;
 
        DPRINTFN(2, ("mvgbe_stop\n"));
@@ -1200,12 +1302,23 @@
                MVGBE_WRITE(sc, MVGBE_RQC, MVGBE_RQC_DISQ_DISABLE(reg));
 
        /* Stop Tx port activity. Check port Tx activity. */
-       if (MVGBE_READ(sc, MVGBE_TQC) & MVGBE_TQC_ENQ)
-               MVGBE_WRITE(sc, MVGBE_TQC, MVGBE_TQC_DISQ);
+       if (MVGBE_READ(sc, MVGBE_TQC) & MVGBE_TQC_ENQ(0))



Home | Main Index | Thread Index | Old Index