diff --git a/rtl837x_stp.c b/rtl837x_stp.c index 6ba1847..3266041 100644 --- a/rtl837x_stp.c +++ b/rtl837x_stp.c @@ -34,12 +34,7 @@ extern __xdata struct uip_eth_addr uip_ethaddr; extern __xdata uint8_t uip_buf[UIP_CONF_BUFFER_SIZE + 2]; -struct bridge { - uint8_t prio; - uint8_t ext; - uint8_t mac[6]; -}; - +/* struct bridge now lives in rtl837x_stp.h (shared with the web UI). */ __xdata struct bridge root_bridge; __xdata uint32_t root_bridge_cost; @@ -211,6 +206,22 @@ void stp_timers(void) __banked print_byte(i); write_char('\n'); stp_cnf_send(i); } + /* Promote a port out of the initial blocking state once its listen + * period expires. stp_setup() puts every port into blocking with + * port_timers = 10 s, but nothing ever counted that down - so on a + * network with no other RSTP bridge (nobody sends us BPDUs) every + * port stayed blocking FOREVER and "stp on" killed the whole + * network. If no better root was heard during the listen period we + * are the designated bridge on that port: go to forwarding. */ + if (port_timers[i]) { + if (!--port_timers[i]) { + reg_read_m(RTL837X_MSTP_STATES); + sfr_data[3 - (i >> 2)] |= (uint8_t)(0b11 << ((i << 1) & 0x7)); + reg_write_m(RTL837X_MSTP_STATES); + print_string("STP: port forwarding "); + print_byte(i); write_char('\n'); + } + } } } @@ -258,7 +269,7 @@ void stp_setup(void) __banked uint8_t bit_mask = 0b01 << ( (i << 1) & 0x7); sfr_data[3 - (i >> 2)] |= bit_mask; port_hello[i] = TIME_HELLO; - port_timers[i] = 0xa00; // 10 sec in blocking state + port_timers[i] = 0x280; // 10 s in blocking state (at the ~64 Hz stp_timers rate) } sfr_data[1] |= 0x0f; // Do not block CPU-Port reg_write_m(RTL837X_MSTP_STATES); // R5310-000d555f diff --git a/rtl837x_stp.h b/rtl837x_stp.h index b1c2a71..4aaf959 100644 --- a/rtl837x_stp.h +++ b/rtl837x_stp.h @@ -7,6 +7,20 @@ void stp_setup(void) __banked; void stp_timers(void) __banked; void stp_off(void) __banked; -#define TIME_HELLO 0x200 // 2 sec +#define TIME_HELLO 0x80 // 2 sec (stp_timers runs at ~64 Hz: main loop ~256 Hz / STP_TICK_DIVIDER+1) + +/* Bridge identifier as carried in a BPDU (priority, extension, MAC). */ +struct bridge { + uint8_t prio; + uint8_t ext; + uint8_t mac[6]; +}; + +/* Protocol state, exposed read-only for the web UI (page_impl.c send_stp()) + * - the elected root bridge and our path cost to it. Owned by rtl837x_stp.c; + * stpEnabled is owned by rtlplayground.c. */ +extern __xdata uint8_t stpEnabled; +extern __xdata struct bridge root_bridge; +extern __xdata uint32_t root_bridge_cost; #endif