While the firmware provides already considerable improvements over the original managed firmware,
-the firmware still lacks support for STP and the proprietary loop prevention
-protocols as well as DHCP. If you need these features, do not install the playground on your managed
+the firmware still lacks support for the proprietary loop prevention
+protocols as well as DHCP. Spanning Tree is available (see doc/stp.md), but is
+a simplified implementation - read that document before enabling it on a
+switch you administer over the network. If you need these features, do not install the playground on your managed
devices. In any case, installation is strongly discouraged unless you can at least make
a backup of the original flash content via a SOIC clamp such as also used for BIOS
backups and can re-install that firmware in case something is wrong. For this no soldering
diff --git a/cmd_parser.c b/cmd_parser.c
index 66b05bde..bd2fc544 100644
--- a/cmd_parser.c
+++ b/cmd_parser.c
@@ -26,7 +26,8 @@
#pragma constseg BANK2
extern __code struct machine machine;
-extern __xdata uint8_t stpEnabled;
+extern __xdata bool stp_enabled;
+extern __code uint8_t log_to_phys_port[9];
extern volatile __xdata uint32_t ticks;
extern volatile __xdata uint8_t sfr_data[4];
@@ -47,6 +48,7 @@ __xdata uint16_t vlan_ptr;
__xdata char port_names[9][PORT_NAME_SIZE];
extern __xdata uint16_t management_vlan;
+extern __xdata struct uip_eth_addr uip_ethaddr;
extern __xdata uint8_t sfp_speed[2];
extern __xdata uint8_t sfp_pins_last;
extern __xdata uint8_t sfp_options[2];
@@ -65,6 +67,10 @@ __xdata char save_cmd;
__xdata uint8_t ip[4];
+/* Scratch for parse_syslog(), in xdata: a local here would take internal RAM
+ * the linker has none of. */
+__xdata uint8_t syslog_port_was_on;
+
// These variables combined create a Fixed-capacity vector/bounded buffer.
// `N_WORDS`: The total number of command arguments that can be tracked.
// `cmd_words_len` stores the number of arguments found inside `cmd_buffer`
@@ -475,7 +481,9 @@ void parse_vlan(void)
vlan_settings.vlan = atoi_results_short;
if (cmd_compare(2, "mgmt")) {
+ port_l2_static_mgmt(uip_ethaddr.addr, management_vlan, true);
management_vlan = vlan_settings.vlan;
+ port_l2_static_mgmt(uip_ethaddr.addr, management_vlan, false);
if (!vlan_settings.vlan)
print_string("Management VLAN disabled\n");
else
@@ -541,7 +549,7 @@ void parse_vlan(void)
}
return;
err:
- print_string("Error: vlan (
+
+Bottom:
+
+
+
+### Serial console
+
+The PCB has five unpopulated through-holes near the SoC, with a white rectangle surrouding them, labeled as `J18` and a triangle points to the square shaped first pin.
+
+This is where the "expected" UART header should be soldered at, with redundant 3V3 VCC, but also with missing 0Ω resistors between TX/RX and SoC, so simply soldering a header would not work. One need also add the missing resistors or solder the pads together, while making sure not connecting unrelated pads.
+
+Numbered from the triangle, the header pinout is:
+
+| Position | Signal | GPIO | Status |
+|----------|--------|--------|-------------|
+| 1 | GND | GND | Internal |
+| 2 | TX | GPIO31 | Unconnected |
+| 3 | RX | GPIO32 | Unconnected |
+| 4 | 3V3 | - | Internal |
+| 5 | 3V3 | - | Internal |
+
+There're four resistor pads near the header.
+
+| Resistor ID | SoC Side | Header Side |
+|-------------|-------------|-------------|
+| R1240 | TX / GPIO31 | Pin 2 |
+| R1243 | 3V3 | - |
+| R1242 | 3V3 | Pin 3 |
+| R1241 | RX / GPIO32 | - |
+
+To get TX working, solder a 0Ω resistor between the pads for R1240 or solder them together.
+
+For RX However, the designer certainly made a mistake, as the SoC-side lines to the resistor expected for Rx (R1242) and 3V3 (R1241) are swapped. For RX to work, the R1241 SoC side and R1242 header side shall be connected, so either:
+
+- Solder: R1241 SoC side -> R1241 header side -> R1242 header side
+- Jump wire: R1241 SoC side -> R1242 header side
+
+Be sure not to bring R1242 SoC side to the connection as that would wire Rx to 3v3.
+
+A complete working serial header should look like following on this PCB:
+
+
+
+- **Settings**: 115200 baud / 8N1 / 3.3V TTL
+- Connect a USB-TTL adapter: adapter GND → pin 1, RX → pin 2, TX → pin 3
+
+### Power supply
+
+Input power is delivered via barell plug, `12V 1A` adapter was provided.
+
diff --git a/doc/devices/KP-9000-6XH-X2.md b/doc/devices/KP-9000-6XH-X2.md
index 4cc21d71..d0f19b96 100644
--- a/doc/devices/KP-9000-6XH-X2.md
+++ b/doc/devices/KP-9000-6XH-X2.md
@@ -1,17 +1,36 @@
-# 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 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 / 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.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
- All four 2.5GBASE-T RJ45 ports at 10/100/1000/2500 Mbps
@@ -19,7 +38,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 +63,24 @@ Bottom
+### Hardware overview: 2M-PCB43-V1.1 / V1.2
+
+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:
+
+
+
+Top side:
+
+
+
+Bottom:
+
+
+
## Reset Button
There's an unpopulated Reset button on the front left side of the PCB.
@@ -54,4 +91,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/devices/PCB-K0402WS-V2.0.md b/doc/devices/PCB-K0402WS-V2.0.md
new file mode 100644
index 00000000..36dea4d8
--- /dev/null
+++ b/doc/devices/PCB-K0402WS-V2.0.md
@@ -0,0 +1,97 @@
+Hisource Hi-K0402WS V2
+
+RTL8372-based 4×2.5G + 2×SFP+ unmanaged switch.
+
+Using SPI clamp in-board is the only method for initial installation.
+
+### Label specifications
+
+- **Manufacturer**: HISOURCE
+- **Model**: Hi-K0402WS V2
+- **Ports**:
+ - 4 × RJ45: 10/100/1000/2500 Mbps
+ - 2 × SFP+: 1G / 2.5G / 10G
+
+### What works
+
+- All four 2.5GBASE-T RJ45 ports at 10/100/1000/2500 Mbps
+- Both SFP+ ports supporting 1G, 2.5G and 10G modules
+- LEDs: amber (2.5G) and green (1G/100M/10M) per copper port; combined link/act on SFP ports
+
+### PCB overview
+
+**Board markings**
+- PCB-K0402WS-V2.0
+- DIP-K0402WS-V2.0
+
+**Key components**
+- U1: SPI NOR flash, 2 MiB
+- S1: unpopulated slide switch footprint (three through-holes used as serial console)
+
+Front panel
+
+
+
+Bottom label
+
+
+
+Top side (PCB)
+
+
+
+### Port layout
+
+| Front panel position | Logical port | Physical port | Type |
+|----------------------|--------------|---------------|---------|
+| SFP left | 8 | 5 | SFP+ |
+| RJ45 1 | 4 | 1 | Copper |
+| RJ45 2 | 5 | 2 | Copper |
+| RJ45 3 | 6 | 3 | Copper |
+| RJ45 4 | 7 | 4 | Copper |
+| SFP right | 3 | 6 | SFP+ |
+
+### Serial console
+
+The PCB has three unpopulated through-holes intended for a slide switch, directly connected to UART0.
+Numbered from the left (SFP port side), the pinout is:
+
+| Position (left→right) | Signal | GPIO |
+|-----------------------|--------|--------------------------|
+| 1 (leftmost) | RX | GPIO32\_UART0\_RX (32) |
+| 2 (middle) | GND | GND |
+| 3 (rightmost) | TX | GPIO31\_UART0\_TX (31) |
+
+- **Settings**: 115200 baud / 8N1 / 3.3V TTL
+- Connect a USB-TTL adapter: adapter TX → pin 1, GND → pin 2, adapter RX → pin 3
+
+### LED configuration
+
+Copper ports use LED SET0, SFP ports use LED SET1.
+
+| SET | LED0 | LED2 |
+|------|--------------------------------------------------|---------------------------------------------------|
+| SET0 | Amber — lights on 2.5G link | Green — lights on 1G / 100M / 10M link |
+| SET1 | All speeds — lights on any link with activity | — |
+
+LED pad to physical port mapping:
+
+| GPIO pads | Port |
+|-----------|-------------------------|
+| GPIO8–11 | Physical port 5 (left SFP) |
+| GPIO12–14 | Physical port 1 (RJ45 1) |
+| GPIO15–17 | Physical port 2 (RJ45 2) |
+| GPIO18–20 | Physical port 3 (RJ45 3) |
+| GPIO21–23 | Physical port 4 (RJ45 4) |
+| GPIO24–27 | Physical port 6 (right SFP) |
+
+### SFP GPIO assignments
+
+| SFP | pin\_detect (ModAbs) | pin\_los | SerDes | I2C SDA | I2C SCL |
+|------------------|-----------------------------|------------------------|--------|----------------------|--------------------------|
+| Left (logical 8) | GPIO30\_ACL\_BIT3\_EN | GPIO37 | SDS1 | GPIO39\_I2C\_SDA4 | GPIO40\_I2C\_SCL3\_MDC1 |
+| Right (logical 3)| GPIO50\_I2C\_SCL2\_UART1\_TX | GPIO51\_I2C\_SDA2\_UART1\_RX | SDS0 | GPIO41\_I2C\_SDA3\_MDIO1 | GPIO40\_I2C\_SCL3\_MDC1 |
+
+GPIO assignments were verified by observing GPIO state changes during SFP module insertion/removal
+and cross-checked against an original firmware register dump.
+`pin_tx_disable` is GPIO\_NA on both ports (original firmware keeps all GPIOs as inputs).
diff --git a/doc/devices/PCB-K0402WS-V3.0.md b/doc/devices/PCB-K0402WS-V3.0.md
index 759fdd14..0da0f0d5 100644
--- a/doc/devices/PCB-K0402WS-V3.0.md
+++ b/doc/devices/PCB-K0402WS-V3.0.md
@@ -19,6 +19,9 @@ of the device just above the big label, might be covered by a QC sticker.
+* Siscolink SL-G0402F
+
+
### Programming
Using SPI clamp in-board is the only method for initial installation.
diff --git a/doc/devices/photos/FG-8GT-1SX/PCB-bottom.jpg b/doc/devices/photos/FG-8GT-1SX/PCB-bottom.jpg
new file mode 100644
index 00000000..b266d29f
Binary files /dev/null and b/doc/devices/photos/FG-8GT-1SX/PCB-bottom.jpg differ
diff --git a/doc/devices/photos/FG-8GT-1SX/PCB-top.jpg b/doc/devices/photos/FG-8GT-1SX/PCB-top.jpg
new file mode 100644
index 00000000..ca640cd1
Binary files /dev/null and b/doc/devices/photos/FG-8GT-1SX/PCB-top.jpg differ
diff --git a/doc/devices/photos/FG-8GT-1SX/Serial.png b/doc/devices/photos/FG-8GT-1SX/Serial.png
new file mode 100644
index 00000000..7d255a9f
Binary files /dev/null and b/doc/devices/photos/FG-8GT-1SX/Serial.png differ
diff --git a/doc/devices/photos/PCB-K0402WS-V2.0/PCB-top.jpg b/doc/devices/photos/PCB-K0402WS-V2.0/PCB-top.jpg
new file mode 100644
index 00000000..2378dd7a
Binary files /dev/null and b/doc/devices/photos/PCB-K0402WS-V2.0/PCB-top.jpg differ
diff --git a/doc/devices/photos/PCB-K0402WS-V2.0/chassis-bottom.jpg b/doc/devices/photos/PCB-K0402WS-V2.0/chassis-bottom.jpg
new file mode 100644
index 00000000..c30a3b70
Binary files /dev/null and b/doc/devices/photos/PCB-K0402WS-V2.0/chassis-bottom.jpg differ
diff --git a/doc/devices/photos/PCB-K0402WS-V2.0/chassis-front.jpg b/doc/devices/photos/PCB-K0402WS-V2.0/chassis-front.jpg
new file mode 100644
index 00000000..47bf168a
Binary files /dev/null and b/doc/devices/photos/PCB-K0402WS-V2.0/chassis-front.jpg differ
diff --git a/doc/devices/photos/PCB-K0402WS-V3.0/Siscolink SL-G0402F.jpg b/doc/devices/photos/PCB-K0402WS-V3.0/Siscolink SL-G0402F.jpg
new file mode 100644
index 00000000..86f34b7b
Binary files /dev/null and b/doc/devices/photos/PCB-K0402WS-V3.0/Siscolink SL-G0402F.jpg differ
diff --git a/doc/l2.md b/doc/l2.md
index c0aaf610..0a785a8f 100644
--- a/doc/l2.md
+++ b/doc/l2.md
@@ -65,3 +65,36 @@ ASIC and flushing the table in order to quickly forget the learned entries.
3c:18:a0:7e:11:00 0x0001 learned 5
1c:2a:a3:23:00:02 0x0001 learned 7
```
+
+## Static multicast entries
+
+Slow-protocol frames such as LACPDUs and STP BPDUs have to reach the CPU
+without being flooded to the other ports. No bridge relays these frames:
+their addresses are in the set that 802.1D-2004 clause 7.12.6 forbids a
+bridge to forward, and what travels the network is the information, with
+every bridge regenerating BPDUs of its own on its designated ports. The reserved-multicast *trap* action
+cannot do that on this hardware, because its destination is an external CPU
+attached to a physical port, which these boards do not populate. The protocol
+modules therefore leave the reserved-multicast action at *forward* and constrain
+the egress with a static L2 multicast entry instead: the lookup hits the entry's
+own port mask rather than the VLAN flood mask. Verified on a SWTGW218AS both
+ways, with the CPU bit cleared, where delivery stops, and with the CPU bit alone,
+where nothing egresses.
+
+`port_l2mc_set()` writes one such entry. The SMI layout is the L2 multicast
+variant of the table entry:
+
+```
+DATA_IN_A = MAC bytes 5..2 -> c2 00 00