git: 9b2a503a1179 - main - e6000sw: add support for 88E6190X
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Sun, 27 Apr 2025 18:38:12 UTC
The branch main has been updated by adrian:
URL: https://cgit.FreeBSD.org/src/commit/?id=9b2a503a1179e026a4efc0b2e0a910168bc806ed
commit 9b2a503a1179e026a4efc0b2e0a910168bc806ed
Author: Adrian Chadd <adrian@FreeBSD.org>
AuthorDate: 2025-04-24 17:32:15 +0000
Commit: Adrian Chadd <adrian@FreeBSD.org>
CommitDate: 2025-04-27 18:11:26 +0000
e6000sw: add support for 88E6190X
This adds the minimum support required to probe/attach the 88E6190X.
I've tested this against an AT&T ATT-150 OCP device (Silicom i3000)
with local changes to export MDIO via ixge(4).
Hints are required to probe/attach/configure the switch on amd64,
but with the mentioned diffs, it does work.
Thanks to Stas Alekseev <stas@alekseev.us> for the pull request
and Stas / Jason Hensler <omegadraconis@gmail.com> for chasing
down information about the chipset, linux stuff and AT&T OCP
hardware information.
PR: kern/281211
Pull Request: https://github.com/freebsd/freebsd-src/pull/1408
Differential Revision: https://reviews.freebsd.org/D50044
Reviewed by: imp
---
sys/dev/etherswitch/e6000sw/e6000sw.c | 33 +++++++++++++++++++++++++-------
sys/dev/etherswitch/e6000sw/e6000swreg.h | 9 +++++----
2 files changed, 31 insertions(+), 11 deletions(-)
diff --git a/sys/dev/etherswitch/e6000sw/e6000sw.c b/sys/dev/etherswitch/e6000sw/e6000sw.c
index 19d8e85decf6..0041119ca300 100644
--- a/sys/dev/etherswitch/e6000sw/e6000sw.c
+++ b/sys/dev/etherswitch/e6000sw/e6000sw.c
@@ -217,7 +217,8 @@ e6000sw_probe(device_t dev)
#ifdef FDT
phandle_t switch_node;
#else
- int is_6190;
+ int is_6190 = 0;
+ int is_6190x = 0;
#endif
sc = device_get_softc(dev);
@@ -253,15 +254,25 @@ e6000sw_probe(device_t dev)
device_get_unit(sc->dev), "addr", &sc->sw_addr) != 0)
return (ENXIO);
if (resource_int_value(device_get_name(sc->dev),
- device_get_unit(sc->dev), "is6190", &is_6190) != 0)
+ device_get_unit(sc->dev), "is6190", &is_6190) != 0) {
/*
* Check "is8190" to keep backward compatibility with
* older setups.
*/
resource_int_value(device_get_name(sc->dev),
device_get_unit(sc->dev), "is8190", &is_6190);
+ }
+ resource_int_value(device_get_name(sc->dev),
+ device_get_unit(sc->dev), "is6190x", &is_6190x);
+ if (is_6190 != 0 && is_6190x != 0) {
+ device_printf(dev,
+ "Cannot configure conflicting variants (6190 / 6190x)\n");
+ return (ENXIO);
+ }
if (is_6190 != 0)
sc->swid = MV88E6190;
+ else if (is_6190x != 0)
+ sc->swid = MV88E6190X;
#endif
if (sc->sw_addr < 0 || sc->sw_addr > 32)
return (ENXIO);
@@ -303,6 +314,10 @@ e6000sw_probe(device_t dev)
description = "Marvell 88E6190";
sc->num_ports = 11;
break;
+ case MV88E6190X:
+ description = "Marvell 88E6190X";
+ sc->num_ports = 11;
+ break;
default:
device_printf(dev, "Unrecognized device, id 0x%x.\n", sc->swid);
return (ENXIO);
@@ -333,7 +348,7 @@ e6000sw_parse_fixed_link(e6000sw_softc_t *sc, phandle_t node, uint32_t port)
return (ENXIO);
}
if (speed == 2500 && (MVSWITCH(sc, MV88E6141) ||
- MVSWITCH(sc, MV88E6341) || MVSWITCH(sc, MV88E6190)))
+ MVSWITCH(sc, MV88E6341) || MVSWITCH(sc, MV88E6190) || MVSWITCH(sc, MV88E6190X)))
sc->fixed25_mask |= (1 << port);
}
@@ -597,22 +612,26 @@ e6000sw_attach(device_t dev)
reg |= PSC_CONTROL_SPD2500;
else
reg |= PSC_CONTROL_SPD1000;
- if (MVSWITCH(sc, MV88E6190) &&
+ if ((MVSWITCH(sc, MV88E6190) ||
+ MVSWITCH(sc, MV88E6190X)) &&
e6000sw_is_fixed25port(sc, port))
reg |= PSC_CONTROL_ALT_SPD;
reg |= PSC_CONTROL_FORCED_DPX | PSC_CONTROL_FULLDPX |
PSC_CONTROL_FORCED_LINK | PSC_CONTROL_LINK_UP |
PSC_CONTROL_FORCED_SPD;
- if (!MVSWITCH(sc, MV88E6190))
+ if (!MVSWITCH(sc, MV88E6190) &&
+ !MVSWITCH(sc, MV88E6190X))
reg |= PSC_CONTROL_FORCED_FC | PSC_CONTROL_FC_ON;
if (MVSWITCH(sc, MV88E6141) ||
MVSWITCH(sc, MV88E6341) ||
- MVSWITCH(sc, MV88E6190))
+ MVSWITCH(sc, MV88E6190) ||
+ MVSWITCH(sc, MV88E6190X))
reg |= PSC_CONTROL_FORCED_EEE;
e6000sw_writereg(sc, REG_PORT(sc, port), PSC_CONTROL,
reg);
/* Power on the SERDES interfaces. */
- if (MVSWITCH(sc, MV88E6190) &&
+ if ((MVSWITCH(sc, MV88E6190) ||
+ MVSWITCH(sc, MV88E6190X)) &&
(port == 9 || port == 10)) {
if (e6000sw_is_fixed25port(sc, port))
sgmii = false;
diff --git a/sys/dev/etherswitch/e6000sw/e6000swreg.h b/sys/dev/etherswitch/e6000sw/e6000swreg.h
index 7c952052a401..ec4503faeec5 100644
--- a/sys/dev/etherswitch/e6000sw/e6000swreg.h
+++ b/sys/dev/etherswitch/e6000sw/e6000swreg.h
@@ -47,6 +47,7 @@ struct atu_opt {
#define MV88E6172 0x1720
#define MV88E6176 0x1760
#define MV88E6190 0x1900
+#define MV88E6190X 0x0a00
#define MVSWITCH(_sc, id) ((_sc)->swid == (id))
#define MVSWITCH_MULTICHIP(_sc) ((_sc)->sw_addr != 0)
@@ -56,7 +57,7 @@ struct atu_opt {
*/
#define REG_GLOBAL 0x1b
#define REG_GLOBAL2 0x1c
-#define REG_PORT(_sc, p) ((MVSWITCH((_sc), MV88E6190) ? 0 : 0x10) + (p))
+#define REG_PORT(_sc, p) (((MVSWITCH((_sc), MV88E6190) || MVSWITCH((_sc), MV88E6190X)) ? 0 : 0x10) + (p))
#define REG_NUM_MAX 31
@@ -138,13 +139,13 @@ struct atu_opt {
#define VTU_DATA 7
#define VTU_DATA2 8
-#define VTU_FID_MASK(_sc) (MVSWITCH((_sc), MV88E6190) ? 0xfff : 0xff)
+#define VTU_FID_MASK(_sc) ((MVSWITCH((_sc), MV88E6190) || MVSWITCH((_sc), MV88E6190X)) ? 0xfff : 0xff)
#define VTU_FID_POLICY (1 << 12)
#define VTU_PORT_UNMODIFIED 0
#define VTU_PORT_UNTAGGED 1
#define VTU_PORT_TAGGED 2
#define VTU_PORT_DISCARD 3
-#define VTU_PPREG(_sc) (MVSWITCH((_sc), MV88E6190) ? 8 : 4)
+#define VTU_PPREG(_sc) ((MVSWITCH((_sc), MV88E6190) || MVSWITCH((_sc), MV88E6190X)) ? 8 : 4)
#define VTU_PORT(_sc, p) (((p) % VTU_PPREG(_sc)) * (16 / VTU_PPREG(_sc)))
#define VTU_PORT_MASK 3
#define VTU_BUSY (1 << 15)
@@ -174,7 +175,7 @@ struct atu_opt {
#define ATU_MAC_ADDR45 15
#define ATU_DATA_LAG (1 << 15)
-#define ATU_PORT_MASK(_sc) (MVSWITCH((_sc), MV88E6190) ? 0xfff0 : 0xff0)
+#define ATU_PORT_MASK(_sc) ((MVSWITCH((_sc), MV88E6190) || MVSWITCH((_sc), MV88E6190X)) ? 0xfff0 : 0xff0)
#define ATU_PORT_SHIFT 4
#define ATU_LAG_MASK 0xf0
#define ATU_LAG_SHIFT 4