stp: name the port state, role and edge in stp status

The table printed the ASIC's raw two bit state, a 1 or a 2 for the role and
a 1 or a 0 for the edge flag, so reading it meant having the source open
next to the console. The columns carry the words now:

    port state role edge bpdu
     05  fwd   desg yes  255
     01  block desg no   21
     02  learn desg no   5
     03  fwd   root no   0

They come from fixed width tables indexed by the same values as before, so
nothing about how any of the three is derived changes, and the columns line
up under the header without a formatter.

The role column still only tells the root port from everything else,
because that is all the state machine tracks. A port sitting in blocking
because a better BPDU arrived on it reads as designated here. Naming the
column makes that visible rather than introducing it.

154 bytes of BANK2, nothing in BANK1, xdata or internal RAM. Built for
SWTGW218AS and KP_9000_6XHML_X2 on sdcc 4.5.0.
This commit is contained in:
d00f
2026-08-18 23:30:37 +02:00
parent 38b19820e4
commit 266c95e4d7
+24 -6
View File
@@ -153,6 +153,21 @@ static void print_bridge_id(uint8_t prio, uint8_t ext, __xdata uint8_t *mac) __r
} }
/* Fixed width columns so the rows line up under the header without a
* formatter. The state indices are the ASIC's own two bits, in the order
* stp_state_set() writes them. */
static __code const char stp_state_txt[] = "off blocklearnfwd ";
static __code const char stp_role_txt[] = "desgroot";
static __code const char stp_edge_txt[] = "no yes ";
static void print_field(__code const char *txt, uint8_t idx, uint8_t width) __reentrant
{
txt += idx * width;
while (width--)
write_char(*txt++);
}
/* Where you look when the tree is not what you expected. */ /* Where you look when the tree is not what you expected. */
static void stp_status(void) static void stp_status(void)
{ {
@@ -182,12 +197,15 @@ static void stp_status(void)
for (stp_i = machine.min_port; stp_i <= machine.max_port; stp_i++) { for (stp_i = machine.min_port; stp_i <= machine.max_port; stp_i++) {
write_char(' '); write_char(' ');
print_byte(machine.log_to_phys_port[stp_i]); print_byte(machine.log_to_phys_port[stp_i]);
print_string(" "); print_string(" ");
print_byte((sfr_data[3 - (stp_i >> 2)] >> ((stp_i << 1) & 0x7)) & 0x3); print_field(stp_state_txt, (sfr_data[3 - (stp_i >> 2)] >> ((stp_i << 1) & 0x7)) & 0x3, 5);
print_string(" "); write_char(' ');
print_byte(stp_i == stp_root_port ? 1 : 2); /* Only the root port is named. Everything else reads as designated
print_string(" "); * because that is all the state machine tracks today; an alternate
print_byte(stp_pflags[stp_i] & STP_PF_OPEREDGE ? 1 : 0); * port is a designated one that happens to sit in blocking. */
print_field(stp_role_txt, stp_i == stp_root_port ? 1 : 0, 4);
write_char(' ');
print_field(stp_edge_txt, stp_pflags[stp_i] & STP_PF_OPEREDGE ? 1 : 0, 4);
/* Seconds since the last BPDU on this port, capped at 255. Without /* Seconds since the last BPDU on this port, capped at 255. Without
* it nothing in the output separates "nobody is speaking (R)STP * it nothing in the output separates "nobody is speaking (R)STP
* out there" from "we are dropping what arrives", and stp_in() * out there" from "we are dropping what arrives", and stp_in()