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