From 3c4fb679bda37f6f6557b4b5d2e09810f3332771 Mon Sep 17 00:00:00 2001 From: d00f Date: Tue, 4 Aug 2026 05:32:00 +0200 Subject: [PATCH] stp: correct the timer tick rate (50 Hz, measured) The timers assumed stp_timers() runs at 64 Hz. It does not: the main loop idles on the 200 Hz system tick and calls us every fourth pass, i.e. 50 Hz. Measured on hardware - with hello configured to 2 s the BPDUs left the port 2.560 s apart, exactly the 28 % overshoot the wrong constant implies, and every other timer (forward delay, max age, tx-hold refill) was stretched the same way. Move the constant to the header with the arithmetic spelled out, and use it in the status page too, which had the 64 hardcoded and therefore aged the same counters differently than the engine. --- httpd/page_impl.c | 2 +- rtl837x_stp.c | 2 -- rtl837x_stp.h | 7 +++++++ 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/httpd/page_impl.c b/httpd/page_impl.c index c0d9e0b..42c3503 100644 --- a/httpd/page_impl.c +++ b/httpd/page_impl.c @@ -643,7 +643,7 @@ void send_stp(void) itoa_html(stp_pp2p[pi_i]); /* designated info: a freshly heard BPDU wins, else we are the * segment's designated bridge and report our own values */ - stp_we_root = stp_dbridge[pi_i].mac[5] && stp_bpdu_age[pi_i] < (uint16_t)stp_maxage_s * 64; + stp_we_root = stp_dbridge[pi_i].mac[5] && stp_bpdu_age[pi_i] < (uint16_t)stp_maxage_s * STP_HZ; slen += strtox(outbuf + slen, ",\"db\":\""); if (stp_we_root) { pi_prio = stp_dbridge[pi_i].prio; pi_ext = stp_dbridge[pi_i].ext; diff --git a/rtl837x_stp.c b/rtl837x_stp.c index 610dcc7..be3f79b 100644 --- a/rtl837x_stp.c +++ b/rtl837x_stp.c @@ -101,8 +101,6 @@ __xdata uint16_t stp_tc_while; /* ticks left to set the TC flag in our BPDUs */ __xdata uint8_t stp_i; /* shared loop iterator (DSEG relief) */ __xdata uint32_t stp_cost_scratch; -/* stp_timers() runs at ~64 Hz (main loop ~256 Hz / (STP_TICK_DIVIDER+1)) */ -#define STP_HZ 64 #define STP_EDGE_DELAY (3 * STP_HZ) /* auto-edge: forward after 3 s without BPDU */ #define AUTO_COST 20000UL /* path cost used when stp_pcost == 0 (1G default) */ diff --git a/rtl837x_stp.h b/rtl837x_stp.h index 56aea9d..ce09b69 100644 --- a/rtl837x_stp.h +++ b/rtl837x_stp.h @@ -9,6 +9,13 @@ void stp_off(void) __banked; void stp_parse(void) __banked __reentrant; /* "stp ..." CLI handler (cmd_parser delegates here) */ void stp_defaults(void) __banked; /* boot init: 802.1D/w default configuration */ +/* Tick rate of stp_timers(): the main loop idles on the 200 Hz system tick + * and rtlplayground.c calls us every (STP_TICK_DIVIDER + 1) = 4th pass. + * Measured on hardware: hello 2 s produced BPDUs exactly 2.560 s apart with + * the previous value of 64, i.e. 20 ms per tick - every configured timer ran + * 28 % long. Shared with the web UI, which ages the same counters. */ +#define STP_HZ 50 + /* Bridge identifier as carried in a BPDU (priority, extension, MAC). */ struct bridge { uint8_t prio;