From d3e8698e407f8cf3582d1f2c44f0dbb050a4a88f Mon Sep 17 00:00:00 2001
From: donbernhardo <87759236+donbernhardo@users.noreply.github.com>
Date: Wed, 17 Jun 2026 21:16:21 +0200
Subject: [PATCH 1/4] Fix KP-9000-6XHML-X2 LED mux mapping
---
machine.c | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/machine.c b/machine.c
index 04db39a..b735167 100644
--- a/machine.c
+++ b/machine.c
@@ -40,6 +40,17 @@ __code const struct machine machine = {
LEDS_1G | LEDS_LINK,
0 },
},
+ .led_mux_custom = 1,
+ /* Measured front-panel LED pads:
+ * P1 amber/green: 9/10, P2: 12/15, P3: 18/21, P4: 24/25, left SFP: 26.
+ */
+ .led_mux = {
+ 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f,
+ 0x3f, 0x10, 0x12, 0x3f,
+ 0x14, 0x3f, 0x3f, 0x16, 0x3f, 0x3f,
+ 0x18, 0x3f, 0x3f, 0x1a, 0x3f, 0x3f,
+ 0x1c, 0x1e, 0x0c, 0x20
+ },
};
void machine_custom_init(void) { }
From 64a1d252cd4cb199b2f7b1227fcddadb0c60bdc4 Mon Sep 17 00:00:00 2001
From: donbernhardo <87759236+donbernhardo@users.noreply.github.com>
Date: Mon, 29 Jun 2026 13:54:47 +0200
Subject: [PATCH 2/4] Split KP-9000 6XH targets by PCB revision
---
Makefile | 2 +-
doc/devices/KP-9000-6XH-X2.md | 40 ++++++++++++++++++++++++++++++-----
doc/supported_devices.md | 4 ++--
machine.c | 14 ++++++++++--
machine.h | 3 +++
5 files changed, 53 insertions(+), 10 deletions(-)
diff --git a/Makefile b/Makefile
index 3b8027b..ada70cf 100644
--- a/Makefile
+++ b/Makefile
@@ -96,7 +96,7 @@ $(BUILDDIR)/rtlplayground-$(FILENAME_EXTENSION).bin: $(BUILDDIR)/rtlplayground.i
machine_check:
@mkdir -p $(BUILDDIR)/tmp
@set -eo pipefail; \
- for MACHINE in `grep -e ' MACHINE_' machine.c | sed -e 's%^.* MACHINE_%%' -e 's%[ ]*//.*$$%%' | sort -u`; \
+ for MACHINE in `grep -E '^[[:space:]]*(//[[:space:]]*)?#define MACHINE_' machine.h | sed -E 's%^[[:space:]]*(//[[:space:]]*)?#define MACHINE_%%' | awk '{print $$1}' | sort -u`; \
do \
echo "Checking $${MACHINE}"; \
$(CC) $(CC_FLAGS) -DMACHINE_$${MACHINE} -MMD -o $(BUILDDIR)/tmp/machine_check -c machine.c; \
diff --git a/doc/devices/KP-9000-6XH-X2.md b/doc/devices/KP-9000-6XH-X2.md
index 4cc21d7..b1c8fdc 100644
--- a/doc/devices/KP-9000-6XH-X2.md
+++ b/doc/devices/KP-9000-6XH-X2.md
@@ -1,17 +1,32 @@
-# Keeplink KP-9000-6XH-X2
+# Keeplink KP-9000-6XH-X2 / KP-9000-6XHML-X2
-Following is documentation for unmanaged switch marked as `KP-9000-6XH-X2`.
+Following is documentation for switches marked as `KP-9000-6XH-X2` or
+`KP-9000-6XHML-X2`.
Using SPI clamp in-board is the only method for initial installation.
### Label specifications
- **Name**: 4X 2.5G RJ45 Port + 2 X 10G SFP+ Port
-- **Model**: KP-9000-6XH-X2
+- **Model**: KP-9000-6XH-X2 / KP-9000-6XHML-X2
- **Ports**:
- 4 × RJ45: 10/100/1000/2500 Mbps
- 2 × SFP+: 1000 / 2500 / 10000 Mbps
+### Machine target
+
+These devices exist with different PCB revisions. Select the machine target by
+the PCB silkscreen, not only by the label on the case.
+
+| PCB silkscreen | Known labels | Recommended machine target | Legacy target |
+| --- | --- | --- | --- |
+| `2M-PCB43-V1.2` | `KP-9000-6XHML-X2` | `MACHINE_KP_9000_6XHML_X2_V1_2` | `MACHINE_KP_9000_6XHML_X2` |
+| `2M-PCB43-V2.1` | `KP-9000-6XH-X2`, `KP-9000-6XHML-X2` | `MACHINE_KP_9000_6XH_X2_V2_1` or `MACHINE_KP_9000_6XHML_X2_V2_1` | `MACHINE_KP_9000_6XH_X2` |
+
+The V1.2 and V2.1 boards use different GPIO, SFP, port and LED mappings.
+The unmanaged and managed labels are firmware/SKU differences and do not by
+themselves identify the PCB wiring.
+
### What works
- All four 2.5GBASE-T RJ45 ports at 10/100/1000/2500 Mbps
@@ -19,7 +34,7 @@ Using SPI clamp in-board is the only method for initial installation.
- LEDs
- untested due to missing Hardware: SFP+ ports equipped with 1G or 2.5G SFPs.
-### Hardware overview
+### Hardware overview: 2M-PCB43-V2.1
Front side:
@@ -44,6 +59,22 @@ Bottom
+### Hardware overview: 2M-PCB43-V1.2
+
+The V1.2 board has been seen in managed `KP-9000-6XHML-X2` devices.
+
+Label:
+
+
+
+Top side:
+
+
+
+Bottom:
+
+
+
## Reset Button
There's an unpopulated Reset button on the front left side of the PCB.
@@ -54,4 +85,3 @@ The front case has already the hole in the metal case, you just have to punch a
## Power supply
Input power is delivered via barell plug, `12V 1A` adapter was provided.
-
diff --git a/doc/supported_devices.md b/doc/supported_devices.md
index 59e54d8..c1b3f9a 100644
--- a/doc/supported_devices.md
+++ b/doc/supported_devices.md
@@ -1,8 +1,8 @@
# Supported Hardware
The following devices have been tested and are fully working:
- Horaco ZX_SG4T2
-- keepLINK kp-9000-6hx-x2 (RTL8372: 4x 2.5GBit + 2x 10GBit SFP+)
-- keepLINK KP-9000-6XHML-X2, same as above, but Managed
+- keepLINK KP-9000-6XH-X2 / KP-9000-6XHML-X2 (RTL8372: 4x 2.5GBit + 2x 10GBit SFP+);
+ select the machine target by PCB revision, see [KP-9000-6XH-X2](devices/KP-9000-6XH-X2.md)
- keepLINK kp-9000-6hx-x (RTL8372 + RTL8221B 2.5GBit PHY: 5 x 2.5GBit + 1x 10GBit SFP+)
- keepLINK kp-9000-9xh-x-eu (1 x RTL8373 + RTL8224: 8x 2.5GBit + 1x 10GBit SFP+)
- Lianguo LG-SWTGW218AS (RTL8373 + RTL8224 PHY: 8x 2.5GBit + 1x 10GBit SFP+)
diff --git a/machine.c b/machine.c
index b735167..96c6f0b 100644
--- a/machine.c
+++ b/machine.c
@@ -5,9 +5,13 @@
#include "rtl837x_regs.h"
#include "rtl837x_common.h"
-#ifdef MACHINE_KP_9000_6XHML_X2
+#if defined(MACHINE_KP_9000_6XHML_X2) || defined(MACHINE_KP_9000_6XHML_X2_V1_2)
__code const struct machine machine = {
+#if defined(MACHINE_KP_9000_6XHML_X2_V1_2)
+ .machine_name = "keepLink KP-9000-6XHML V1.2",
+#else
.machine_name = "keepLink KP-9000-6XHML-X2",
+#endif
.isRTL8373 = 0,
.min_port = 3,
.max_port = 8,
@@ -85,9 +89,15 @@ __code const struct machine machine = {
void machine_custom_init(void) { }
-#elif defined MACHINE_KP_9000_6XH_X2
+#elif defined(MACHINE_KP_9000_6XH_X2) || defined(MACHINE_KP_9000_6XH_X2_V2_1) || defined(MACHINE_KP_9000_6XHML_X2_V2_1)
__code const struct machine machine = {
+#if defined(MACHINE_KP_9000_6XHML_X2_V2_1)
+ .machine_name = "keepLink KP-9000-6XHML V2.1",
+#elif defined(MACHINE_KP_9000_6XH_X2_V2_1)
+ .machine_name = "keepLink KP-9000-6XH-X2 V2.1",
+#else
.machine_name = "keepLink KP-9000-6XH-X2",
+#endif
.isRTL8373 = 0,
.min_port = 3,
.max_port = 8,
diff --git a/machine.h b/machine.h
index 931a17e..3483f2e 100644
--- a/machine.h
+++ b/machine.h
@@ -7,8 +7,11 @@
* Select your machine type below
*/
// #define MACHINE_KP_9000_6XHML_X2
+// #define MACHINE_KP_9000_6XHML_X2_V1_2
+// #define MACHINE_KP_9000_6XHML_X2_V2_1
// #define MACHINE_KP_9000_6XH_X
// #define MACHINE_KP_9000_6XH_X2
+// #define MACHINE_KP_9000_6XH_X2_V2_1
// #define MACHINE_KP_9000_9XH_X_EU
// #define MACHINE_KP_9000_9XHML_X_V2_2
// #define MACHINE_KP_9000_9XHML_X_V3_1
From dd52e8e85e077870a0e675f6894eb3b675934b43 Mon Sep 17 00:00:00 2001
From: donbernhardo <87759236+donbernhardo@users.noreply.github.com>
Date: Mon, 29 Jun 2026 14:12:31 +0200
Subject: [PATCH 3/4] Discard incorrect KP-9000 V1.2 LED mux override
---
machine.c | 11 -----------
1 file changed, 11 deletions(-)
diff --git a/machine.c b/machine.c
index a25fe98..d54998b 100644
--- a/machine.c
+++ b/machine.c
@@ -44,17 +44,6 @@ __code const struct machine machine = {
LEDS_1G | LEDS_LINK,
0 },
},
- .led_mux_custom = 1,
- /* Measured front-panel LED pads:
- * P1 amber/green: 9/10, P2: 12/15, P3: 18/21, P4: 24/25, left SFP: 26.
- */
- .led_mux = {
- 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f,
- 0x3f, 0x10, 0x12, 0x3f,
- 0x14, 0x3f, 0x3f, 0x16, 0x3f, 0x3f,
- 0x18, 0x3f, 0x3f, 0x1a, 0x3f, 0x3f,
- 0x1c, 0x1e, 0x0c, 0x20
- },
};
void machine_custom_init(void) { }
From 457f117216818b588ab01d397222b4e835135ab9 Mon Sep 17 00:00:00 2001
From: donbernhardo <87759236+donbernhardo@users.noreply.github.com>
Date: Mon, 29 Jun 2026 20:59:28 +0200
Subject: [PATCH 4/4] Add PCB43 V1.1 and symmetric KP-9000 6XH targets
---
doc/devices/KP-9000-6XH-X2.md | 26 ++++++++++++++++----------
doc/supported_devices.md | 8 +++++---
machine.c | 14 ++++++++++++--
machine.h | 13 ++++++++++---
4 files changed, 43 insertions(+), 18 deletions(-)
diff --git a/doc/devices/KP-9000-6XH-X2.md b/doc/devices/KP-9000-6XH-X2.md
index b1c8fdc..d0f19b9 100644
--- a/doc/devices/KP-9000-6XH-X2.md
+++ b/doc/devices/KP-9000-6XH-X2.md
@@ -16,16 +16,20 @@ Using SPI clamp in-board is the only method for initial installation.
### Machine target
These devices exist with different PCB revisions. Select the machine target by
-the PCB silkscreen, not only by the label on the case.
+the PCB silkscreen, not by the label on the case. The `6XH` / `6XHML`
+distinction appears to be a stock firmware, SKU or label difference, not a
+reliable indicator of PCB wiring. The PCB revision defines the hardware layout.
-| PCB silkscreen | Known labels | Recommended machine target | Legacy target |
-| --- | --- | --- | --- |
-| `2M-PCB43-V1.2` | `KP-9000-6XHML-X2` | `MACHINE_KP_9000_6XHML_X2_V1_2` | `MACHINE_KP_9000_6XHML_X2` |
-| `2M-PCB43-V2.1` | `KP-9000-6XH-X2`, `KP-9000-6XHML-X2` | `MACHINE_KP_9000_6XH_X2_V2_1` or `MACHINE_KP_9000_6XHML_X2_V2_1` | `MACHINE_KP_9000_6XH_X2` |
+| PCB silkscreen | Known labels / devices | Recommended machine target | Equivalent target | Legacy target |
+| --- | --- | --- | --- | --- |
+| `2M-PCB43-V1.1` | Mokerlink 2G040210GSM web-managed 4+2 switch | `MACHINE_KP_9000_6XHML_X2_V1_1` | `MACHINE_KP_9000_6XH_X2_V1_1` | `MACHINE_KP_9000_6XHML_X2` |
+| `2M-PCB43-V1.2` | `KP-9000-6XHML-X2` | `MACHINE_KP_9000_6XHML_X2_V1_2` | `MACHINE_KP_9000_6XH_X2_V1_2` | `MACHINE_KP_9000_6XHML_X2` |
+| `2M-PCB43-V2.1` | `KP-9000-6XH-X2`, `KP-9000-6XHML-X2` | `MACHINE_KP_9000_6XH_X2_V2_1` or `MACHINE_KP_9000_6XHML_X2_V2_1` | same V2.1 layout | `MACHINE_KP_9000_6XH_X2` |
-The V1.2 and V2.1 boards use different GPIO, SFP, port and LED mappings.
-The unmanaged and managed labels are firmware/SKU differences and do not by
-themselves identify the PCB wiring.
+The V1.1 and V1.2 boards currently use the same V1.x GPIO, SFP, port and LED
+layout. The V2.1 board uses a different V2.1 layout with custom LED muxing.
+Legacy targets are preserved for compatibility with already-tested devices, but
+new builds should prefer the explicit PCB-revision targets.
### What works
@@ -59,9 +63,11 @@ Bottom
-### Hardware overview: 2M-PCB43-V1.2
+### Hardware overview: 2M-PCB43-V1.1 / V1.2
-The V1.2 board has been seen in managed `KP-9000-6XHML-X2` devices.
+The V1.1 board has been reported in the Mokerlink 2G040210GSM web-managed 4+2
+switch. The V1.2 board has been seen in managed `KP-9000-6XHML-X2` devices.
+Both use the same V1.x layout.
Label:
diff --git a/doc/supported_devices.md b/doc/supported_devices.md
index b367c1e..bdb21c2 100644
--- a/doc/supported_devices.md
+++ b/doc/supported_devices.md
@@ -13,7 +13,8 @@ The following devices have been tested and are fully working:
| Horaco | ZX310S-4T2XH | Yes | [PCB-SL310S-4T1T1X-V1.0.1-24107](https://github.com/logicog/RTLPlayground/blob/main/doc/devices/ZX310S-4T2XH.md) | 2M | 5 + 1 |
| Horaco | ZX310S-4T2XT | Yes | [PCB-SL310S-4T2XT-V1.0.0-22273](https://github.com/logicog/RTLPlayground/blob/main/doc/devices/ZX310S-4T2XT.md) | 2M | 6 |
| Horaco | ZX-SWTG124AS | Yes | [SWTG024AS-v2.0](https://github.com/logicog/RTLPlayground/blob/main/doc/devices/SWTG024AS.md) | | 4 + 2 |
-| Keeplink | KP-9000-6XH-X2 / KP-9000-6XHML-X2 | No/Yes | [2M-PCB43-V1.2 / V2.1](https://github.com/logicog/RTLPlayground/blob/main/doc/devices/KP-9000-6XH-X2.md) | | 4 + 2 |
+| Keeplink | KP-9000-6XH-X2 / KP-9000-6XHML-X2 | No/Yes | [2M-PCB43-V1.2 / V2.1](https://github.com/logicog/RTLPlayground/blob/main/doc/devices/KP-9000-6XH-X2.md) | | 4 + 2 |
+| Mokerlink | 2G040210GSM | Yes | [2M-PCB43-V1.1](https://github.com/logicog/RTLPlayground/blob/main/doc/devices/KP-9000-6XH-X2.md) | | 4 + 2 |
| keepLINK | KP-9000-9XHML-X | Yes | [2M-PCB23-V2.2](https://github.com/logicog/RTLPlayground/blob/main/doc/devices/2M-PCB23-V2_2.md) | 2M | 8 + 1 |
| keepLINK | KP-9000-9XHML-X | Yes | [2M-PCB23-V3.1](https://github.com/logicog/RTLPlayground/blob/main/doc/devices/2M-PCB23-V3_1.md) | 2M | 8 + 1 |
| LIANGUO | SWTG024AS | No | [SWTG024AS-v2.0-17452](https://github.com/logicog/RTLPlayground/blob/main/doc/devices/SWTG024AS.md) | 0.5M | 4 + 2 |
@@ -26,8 +27,9 @@ The following devices have been tested and are fully working:
| XikeStor | SKS3200-8E1X | Yes | [SWTG118AS-V2.1-17462](https://github.com/logicog/RTLPlayground/blob/main/doc/devices/SWTGW218AS.md) | 2M | 8 + 1 |
| Ztyuav | Z-QWYT0402 | No | [PCB-K0402WS-V3.0](https://github.com/logicog/RTLPlayground/blob/main/doc/devices/PCB-K0402WS-V3.0.md) | | 4 + 2 |
-For KP-9000-6XH-X2 / KP-9000-6XHML-X2 devices, select the machine target by PCB
-revision. The managed/unmanaged label alone does not identify the wiring.
+For KP-9000-6XH-X2 / KP-9000-6XHML-X2 / Mokerlink 2G040210GSM devices, select
+the machine target by PCB revision. The ML/non-ML or managed/unmanaged label
+alone does not identify the wiring.
Other device based on RTL8272/3 that may work are described here: [Up-N-Atoms 2.5 GBit RTL Switch hacking guide](https://github.com/up-n-atom/SWTG118AS)
diff --git a/machine.c b/machine.c
index d54998b..35b545d 100644
--- a/machine.c
+++ b/machine.c
@@ -5,9 +5,19 @@
#include "rtl837x_regs.h"
#include "rtl837x_common.h"
-#if defined(MACHINE_KP_9000_6XHML_X2) || defined(MACHINE_KP_9000_6XHML_X2_V1_2)
+#if defined(MACHINE_KP_9000_6XHML_X2) || \
+ defined(MACHINE_KP_9000_6XH_X2_V1_1) || \
+ defined(MACHINE_KP_9000_6XHML_X2_V1_1) || \
+ defined(MACHINE_KP_9000_6XH_X2_V1_2) || \
+ defined(MACHINE_KP_9000_6XHML_X2_V1_2)
__code const struct machine machine = {
-#if defined(MACHINE_KP_9000_6XHML_X2_V1_2)
+#if defined(MACHINE_KP_9000_6XH_X2_V1_1)
+ .machine_name = "keepLink KP-9000-6XH V1.1",
+#elif defined(MACHINE_KP_9000_6XHML_X2_V1_1)
+ .machine_name = "keepLink KP-9000-6XHML V1.1",
+#elif defined(MACHINE_KP_9000_6XH_X2_V1_2)
+ .machine_name = "keepLink KP-9000-6XH V1.2",
+#elif defined(MACHINE_KP_9000_6XHML_X2_V1_2)
.machine_name = "keepLink KP-9000-6XHML V1.2",
#else
.machine_name = "keepLink KP-9000-6XHML-X2",
diff --git a/machine.h b/machine.h
index 5ae75c9..1da0458 100644
--- a/machine.h
+++ b/machine.h
@@ -6,12 +6,19 @@
/*
* Select your machine type below
*/
+// Legacy KP-9000 4+2 targets. Prefer the PCB-revision-specific targets below.
// #define MACHINE_KP_9000_6XHML_X2
-// #define MACHINE_KP_9000_6XHML_X2_V1_2
-// #define MACHINE_KP_9000_6XHML_X2_V2_1
-// #define MACHINE_KP_9000_6XH_X
// #define MACHINE_KP_9000_6XH_X2
+
+// KP-9000 4+2 targets by PCB silkscreen revision.
+// #define MACHINE_KP_9000_6XH_X2_V1_1
+// #define MACHINE_KP_9000_6XHML_X2_V1_1
+// #define MACHINE_KP_9000_6XH_X2_V1_2
+// #define MACHINE_KP_9000_6XHML_X2_V1_2
// #define MACHINE_KP_9000_6XH_X2_V2_1
+// #define MACHINE_KP_9000_6XHML_X2_V2_1
+
+// #define MACHINE_KP_9000_6XH_X
// #define MACHINE_KP_9000_9XH_X_EU
// #define MACHINE_KP_9000_9XHML_X_V2_2
// #define MACHINE_KP_9000_9XHML_X_V3_1