mirror of
https://github.com/logicog/RTLPlayground.git
synced 2026-09-02 15:02:51 +08:00
stp: derive the BPDU flags from the port state
Every RST BPDU we sent carried flags 0x3c - designated, learning, forwarding - whatever the port was actually doing. A blocked port kept announcing itself as forwarding, and the root port would have called itself designated. Nothing on this bench acted on it, but it is a lie in the protocol frame and the kind that surfaces in somebody else's mixed network. Derive the flags instead: the root port reports the root role, every other transmitting port is designated (alternates do not transmit at all), and the learning and forwarding bits mirror the ASIC state, so a listening port now sends 0x0c. TC and TCA stay dynamic as before. Legacy Config BPDUs are unchanged - their flags only ever carried TC and TCA. Costs nothing in internal RAM; the state comes from the register scratch that is already there.
This commit is contained in:
+14
-2
@@ -289,8 +289,20 @@ void stp_cnf_send(uint8_t port) __reentrant
|
|||||||
STP_O->msg_len = HTONS(0x27);
|
STP_O->msg_len = HTONS(0x27);
|
||||||
STP_O->version = 0x02; /* RSTP */
|
STP_O->version = 0x02; /* RSTP */
|
||||||
STP_O->bpdu_type = 0x02; /* Rapid Spanning Tree BPDU */
|
STP_O->bpdu_type = 0x02; /* Rapid Spanning Tree BPDU */
|
||||||
/* flags: role designated (0b11 << 2) + learning + forwarding */
|
/* Flags describe this port, so derive them instead of announcing
|
||||||
STP_O->flags = 0x3c;
|
* designated+learning+forwarding unconditionally: a blocked port
|
||||||
|
* claiming to forward, or the root port claiming designated, is a
|
||||||
|
* lie on the wire even when nothing downstream acts on it (yet).
|
||||||
|
* Role is root on the root port and designated everywhere else -
|
||||||
|
* there is no alternate/backup role computation, so a port blocked
|
||||||
|
* by loop detection still transmits as designated, just with the
|
||||||
|
* learning and forwarding bits clear. Those two mirror the ASIC
|
||||||
|
* state (0b11 = forwarding); a listening or blocked port sends
|
||||||
|
* neither. */
|
||||||
|
reg_read_m(RTL837X_MSTP_STATES);
|
||||||
|
STP_O->flags = (uint8_t)((port == stp_root_port ? 0b10 : 0b11) << 2);
|
||||||
|
if (((sfr_data[3 - (port >> 2)] >> ((port << 1) & 0x7)) & 0b11) == 0b11)
|
||||||
|
STP_O->flags |= 0x30; /* learning + forwarding */
|
||||||
} else {
|
} else {
|
||||||
/* 802.3 length = LLC (3) + Config BPDU body (35) */
|
/* 802.3 length = LLC (3) + Config BPDU body (35) */
|
||||||
STP_O->msg_len = HTONS(0x26);
|
STP_O->msg_len = HTONS(0x26);
|
||||||
|
|||||||
Reference in New Issue
Block a user