diff --git a/doc/devices/PCB-AFGW_SWTG218ANS_V2.0.2.md b/doc/devices/PCB-AFGW_SWTG218ANS_V2.0.2.md
new file mode 100644
index 00000000..59b18701
--- /dev/null
+++ b/doc/devices/PCB-AFGW_SWTG218ANS_V2.0.2.md
@@ -0,0 +1,93 @@
+# PCB-AFGW SWTG218ANS V2.0.2
+
+RTL8373-based 8×2.5G PoE + 1×10G SFP+ web-managed switch, sold as the
+**RealHD PSW8-25MG**.
+
+### Label specifications
+
+- **Manufacturer**: RealHD
+- **Model**: PSW8-25MG
+- **PCB marking**: `PCB-AFGW SWTG218ANS_V2.0.2` (silkscreened as `PCB-AFGW SWTG218ANS_V2.0.2_23308`)
+- **Ports**:
+ - 8 × RJ45: 10/100/1000/2500 Mbps with PoE
+ - 1 × SFP+: 1G / 2.5G / 10G (front panel marking `9(10G)`)
+- **Power input**: internal AC PSU, `100-240V~ 50/60Hz 2A MAX`, DC output `53.5V 2.8A 150W`
+- **Front panel LEDs**: `PWR`, `SYS`, per RJ45 port `Link/Act` and `PoE`, per SFP port 2.5G (green) and 10G (blue)
+- **Stock firmware defaults**: web-managed PoE switch
+
+### What works
+
+- All eight 2.5GBASE-T RJ45 ports at 10/100/1000/2500 Mbps (PoE is not configurable via RTLPlayground)
+- SFP+ port supporting 1G, 2.5G and 10G modules
+- LEDs: green (2.5G) and amber (1G/100M/10M) per RJ45 port with activity, green (1G/2.5G) and blue (10G) on the SFP port, plus the `SYS` LED
+
+### Photos
+
+Front panel:
+
+
+
+Board mounted in the case, with the internal PSU above it:
+
+
+
+### PCB overview
+
+Top side:
+
+
+
+Bottom side:
+
+
+
+A 4-pad UART header with `RXD` / `TXD` silkscreened sits next to the right heatsink.
+
+### Port layout
+
+| Logical port | Physical port | Type |
+|--------------|---------------|--------|
+| 1-8 | 1-8 | RJ45 |
+| 9 | 9 | SFP+ |
+
+### LED configuration
+
+RJ45 ports use LED SET0, the SFP+ port uses LED SET1. The board needs the custom
+LED mux (`led_mux_custom = 1`), and `RTL837X_REG_LED_GLB_IO_EN` is written to
+`0x7f24977f` in `machine_custom_init()` so the LED pins are enabled as wired here.
+
+| SET | LED pin 0 | LED pin 1 |
+|------|-----------------------------------------------|-------------------------------------------------------|
+| SET0 | Green — lights on 2.5G link with activity | Amber — lights on 1G / 100M / 10M link with activity |
+| SET1 | All speeds — lights on any link with activity | 10G — lights on 10G link with activity |
+
+On the front panel this gives one bi-color `Link/Act` LED per RJ45 port (green at
+2.5G, amber at 10/100/1000M, blinking with activity) and one `PoE` LED per RJ45
+port, which is driven by the PoE hardware and not by the switch. The SFP+ port has
+a green 2.5G LED and a blue 10G LED.
+
+### SFP GPIO assignments
+
+| SFP (logical 9) | pin_detect (ModAbs) | pin_los | pin_tx_disable | SerDes | I2C SDA | I2C SCL |
+|-----------------|---------------------|---------|----------------|--------|------------------|----------------------|
+| SFP | GPIO38 | GPIO_NA | GPIO_NA | SDS1 | GPIO39_I2C_SDA4 | GPIO40_I2C_SCL3_MDC1 |
+
+### Machine configuration
+
+```
+make MACHINE=REALHD_PSW8_25MG
+```
+
+### Programming
+
+The serial console runs at 8N1 on 115200 baud with the RTLPlayground firmware
+(see the UART header note under *PCB overview*). The stock firmware baud rate 57600. The flash chip was 2MB.
+
+### PoE
+
+The 8 RJ45 ports support PoE, powered by the internal 150W AC PSU (DC output
+53.5V 2.8A) mounted above the main board.
+
+Note: RTLPlayground does not provide PoE management for this board. The PoE
+hardware runs with its own configuration, the same as on the other PoE boards in
+this project.
diff --git a/doc/devices/photos/PCB-AFGW_SWTG218ANS_V2.0.2/dev_top_w_pcb.jpg b/doc/devices/photos/PCB-AFGW_SWTG218ANS_V2.0.2/dev_top_w_pcb.jpg
new file mode 100644
index 00000000..04e604f7
Binary files /dev/null and b/doc/devices/photos/PCB-AFGW_SWTG218ANS_V2.0.2/dev_top_w_pcb.jpg differ
diff --git a/doc/devices/photos/PCB-AFGW_SWTG218ANS_V2.0.2/device_front.jpg b/doc/devices/photos/PCB-AFGW_SWTG218ANS_V2.0.2/device_front.jpg
new file mode 100644
index 00000000..71bdd845
Binary files /dev/null and b/doc/devices/photos/PCB-AFGW_SWTG218ANS_V2.0.2/device_front.jpg differ
diff --git a/doc/devices/photos/PCB-AFGW_SWTG218ANS_V2.0.2/pcb_back.jpg b/doc/devices/photos/PCB-AFGW_SWTG218ANS_V2.0.2/pcb_back.jpg
new file mode 100644
index 00000000..6a498b96
Binary files /dev/null and b/doc/devices/photos/PCB-AFGW_SWTG218ANS_V2.0.2/pcb_back.jpg differ
diff --git a/doc/devices/photos/PCB-AFGW_SWTG218ANS_V2.0.2/pcb_front.jpg b/doc/devices/photos/PCB-AFGW_SWTG218ANS_V2.0.2/pcb_front.jpg
new file mode 100644
index 00000000..f6e39ffe
Binary files /dev/null and b/doc/devices/photos/PCB-AFGW_SWTG218ANS_V2.0.2/pcb_front.jpg differ
diff --git a/doc/supported_devices.md b/doc/supported_devices.md
index 5e918c1d..08245ea5 100644
--- a/doc/supported_devices.md
+++ b/doc/supported_devices.md
@@ -39,6 +39,7 @@ The following devices have been tested and are fully working:
| MokerLink| 2G08110GSN | No | [SWTG018AS-A V2.0](devices/SWTG018AS_A_V2_0.md) | 0.5M | 8 + 1 |
| Netcore | GS9 | No | [PB-2132](devices/PB-2132.md) | 4M | 8 + 1 |
| ONT | ONT-S207CW-62TS-SE | No | [PCB-SWTG024AS-A-2.0.1](devices/ONT-S207CW-62TS-SE.md) | 0.5M | 4 + 2 |
+| RealHD | PSW8-25MG | Yes | [PCB-AFGW SWTG218ANS V2.0.2](devices/PCB-AFGW_SWTG218ANS_V2.0.2.md) | 2M | 8 + 1 |
| Ruiying | RY-4GT-2SX | No | [FG-4GT-2SX_V2.0](devices/FG-4GT-2SX_V2.0.md) | 4M | 4 + 2 |
| Ruiying | RY-8GT-1SX | No | [FG-8GT-1SX](devices/FG-8GT-1SX.md) | 1M | 8 + 1 |
| SICSOLINK| SL-G0402F | No | [PCB-K0402WS-V3.0](devices/PCB-K0402WS-V3.0.md) | | 4 + 2 |
diff --git a/machine/PCB_AFGW_SWTG218ANS_V_2_0_2.c b/machine/PCB_AFGW_SWTG218ANS_V_2_0_2.c
new file mode 100644
index 00000000..20bcdad9
--- /dev/null
+++ b/machine/PCB_AFGW_SWTG218ANS_V_2_0_2.c
@@ -0,0 +1,31 @@
+#include "machine_defs.h"
+
+__code const struct machine machine = {
+ MACHINE_COMMON_SETTING,
+ .mac_flash_offset = 0x1FC000,
+ .n_sfp = 1,
+ .log_to_phys_port = {1, 2, 3, 4, 5, 6, 7, 8, 9},
+ .phys_to_log_port = {0, 1, 2, 3, 4, 5, 6, 7, 8},
+ .is_sfp = {0, 0, 0, 0, 0, 0, 0, 0, 1},
+ .sfp_port[0].pin_detect = GPIO38,
+ .sfp_port[0].pin_los = GPIO_NA,
+ .sfp_port[0].pin_tx_disable = GPIO_NA,
+ .sfp_port[0].sds = 1,
+ .sfp_port[0].i2c = I2CBUS( GPIO39_I2C_SDA4, GPIO40_I2C_SCL3_MDC1 ),
+ .reset_pin = GPIO48_I2C_SCL1,
+ .high_leds = { .mux = LED_28_SYS | LED_29, .enable = LED_28_SYS | LED_29 },
+ .port_led_set = { 0, 0, 0, 0, 0, 0, 0, 0, 1},
+ .led_mux = { 0x00, 0x01, 0x04, 0x05, 0x08, 0x09, 0x0c, 0x09, 0x0d, 0x10, 0x11, 0x0e, 0x14, 0x11, 0x12, 0x15, 0x15, 0x16, 0x18, 0x19, 0x1a, 0x19, 0x1d, 0x1e, 0x1c, 0x1d, 0x20, 0x21 },
+ .led_mux_custom = 1,
+ .led_sets = { { LEDS_2G5 | LEDS_LINK | LEDS_ACT,
+ LEDS_1G | LEDS_100M | LEDS_10M | LEDS_LINK | LEDS_ACT,
+ LEDS_DUPLEX,
+ LEDS_2G5 | LEDS_LINK | LEDS_ACT
+ },
+ { LEDS_2G5 | LEDS_1G | LEDS_100M | LEDS_LINK | LEDS_ACT,
+ LEDS_10G | LEDS_LINK | LEDS_ACT,
+ LEDS_2G5 | LEDS_LINK,
+ LEDS_COL | LEDS_DUPLEX
+ },
+ },
+};
diff --git a/machine/PCB_AFGW_SWTG218ANS_V_2_0_2_init.c b/machine/PCB_AFGW_SWTG218ANS_V_2_0_2_init.c
new file mode 100644
index 00000000..d1b139dc
--- /dev/null
+++ b/machine/PCB_AFGW_SWTG218ANS_V_2_0_2_init.c
@@ -0,0 +1,6 @@
+#include "machine_init_defs.h"
+
+void machine_custom_init(void) __banked
+{
+ REG_SET(RTL837X_REG_LED_GLB_IO_EN, 0x7f24977f);
+}
diff --git a/machine/REALHD_PSW8_25MG.c b/machine/REALHD_PSW8_25MG.c
new file mode 120000
index 00000000..12d765dd
--- /dev/null
+++ b/machine/REALHD_PSW8_25MG.c
@@ -0,0 +1 @@
+PCB_AFGW_SWTG218ANS_V_2_0_2.c
\ No newline at end of file
diff --git a/machine/REALHD_PSW8_25MG.h b/machine/REALHD_PSW8_25MG.h
new file mode 100644
index 00000000..0e699d95
--- /dev/null
+++ b/machine/REALHD_PSW8_25MG.h
@@ -0,0 +1,7 @@
+#ifndef _MACHINE_SWTG218ANS_V_2_0_2_H_
+#define _MACHINE_SWTG218ANS_V_2_0_2_H_
+
+#define MACHINE_MODEL "RealHD PSW8-25MG"
+#define MACHINE_CHIPSET RTL8373
+
+#endif
diff --git a/machine/REALHD_PSW8_25MG_init.c b/machine/REALHD_PSW8_25MG_init.c
new file mode 120000
index 00000000..dfe02f48
--- /dev/null
+++ b/machine/REALHD_PSW8_25MG_init.c
@@ -0,0 +1 @@
+PCB_AFGW_SWTG218ANS_V_2_0_2_init.c
\ No newline at end of file