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 714b7a7..754740c 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];
@@ -1683,15 +1684,7 @@ void cmd_parser(void) __banked
print_string("Error: hostname [name] - the name must not contain spaces\n");
}
} else if (cmd_compare(0, "stp")) {
- if (cmd_compare(1, "on")) {
- print_string("STP enabled\n");
- stpEnabled = 1;
- stp_setup();
- } else {
- print_string("STP disabled\n");
- stp_off();
- stpEnabled = 0;
- }
+ stp_parse();
} else if (cmd_compare(0, "pvid")) {
if (cmd_words_len == 3 && cmd_parse_port_separator(cmd_words_b[1]) != 0
&& atoi_short(cmd_words_b[2]) && atoi_results_short && atoi_results_short <= 4094)
diff --git a/doc/CpuPort.md b/doc/CpuPort.md
index 9e0b028..c10d0a1 100644
--- a/doc/CpuPort.md
+++ b/doc/CpuPort.md
@@ -64,3 +64,33 @@ Writing 0x1 to register 0x7850 will transmit the frame. The Ethernet frame
checksum and the TCP checksum are automatically calculated (offloaded) by the
ASIC before transmitting on the wire.
+
+## The RTL tag words
+
+The frame header uses the Realtek Remote Control Protocol (RRCP) format or
+the like.
+
+The `flags` word:
+
+```
+bit15 EFID_EN | 14:12 EFID | 11 PRI_EN | 10:8 PRI |
+bit7 KEEP | 6 VSEL | 5 LEARN_DIS | 4:0 VIDX
+```
+
+All fields are in network byte order.
+
+* `EFID_EN`, `EFID`: look the destination up under this filtering ID
+ instead of the port's own
+* `PRI_EN`, `PRI`: force the given priority on the frame
+* `KEEP`: keep the 802.1Q tagging of the frame exactly as injected,
+ bypassing the egress tagging rules of the port
+* `VSEL`, `VIDX`: classify the frame into the VLAN at this index of the
+ VLAN table
+* `LEARN_DIS`: do not learn the source address from this frame
+
+The `pmask` word: bit 15 is `ALLOW`, bits 14 to 0 are a port mask.
+
+* `ALLOW` clear: the mask is the egress set, the frame goes to exactly
+ the ports given
+* `ALLOW` set: the ASIC looks the destination up as usual and the mask
+ only limits which ports the result may use
diff --git a/doc/l2.md b/doc/l2.md
index c0aaf61..0a785a8 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 | Priority | Version | Hello [s] | Max age [s] | Fwd delay [s] | Tx hold | +
|---|---|---|---|---|---|
| + | + | + | + | + | + |
Changes apply immediately. Edge ports skip the listen period; guard/filter act on received BPDUs.
+| Port | State | Path Cost (0 = Auto) | Priority | Edge Port | BPDU Filter | Guard | Point-to-Point | +
|---|
| Port | Port State | Role | Designated Bridge | Designated Port ID | Designated Cost | Oper. Edge | Oper. P2P | +
|---|