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