port: show how many MAC addresses each port has learned

The switch keeps a count of the dynamic L2 entries learned on every
port in L2_LRN_PORT_CONSTRT_CNT (0x53ac + 4 * port, 13 bits). `stat`
prints it in a new MACs column and /status.json carries it as "macs".

On a SWTGW218AS the count matched the L2 table port by port, static
entries are not included, and taking a port down drops it to 0.
This commit is contained in:
DrDoof committed 2026-10-10 01:11:11 +02:00
1 parent e67c928eb7
commit 706dea63a2
4 files changed
+27 -1

No files matched your search

+3
View File
@@ -1032,6 +1032,9 @@ void send_status(void)
slen += strtox(outbuf + slen, "\",\"rxB\":\"0x");
STAT_GET(STAT_COUNTER_ERR_PKTS, i);
reg_to_html(RTL837X_STAT_V_HIGH); // 32bit RX packet errors
slen += strtox(outbuf + slen, "\",\"macs\":\"0x");
reg_to_html(RTL837X_L2_LRN_PORT_CONSTRT_CNT + (i << 2));
slen += strtox(outbuf + slen, "\"}");
if (i < machine.max_port)
char_to_html(',');
+4 -1
View File
@@ -510,7 +510,7 @@ void port_media_show(uint8_t port) __banked
void port_stats_print(void) __banked
{
print_string("\nPort\tState\tLink\tTxGood\t\tTxBad\t\tRxGood\t\tRxBad\n");
print_string("\nPort\tState\tLink\tTxGood\t\tTxBad\t\tRxGood\t\tRxBad\t\tMACs\n");
for (uint8_t i = machine.min_port; i <= machine.max_port; i++) {
print_phys_port(i); write_char('\t');
@@ -584,6 +584,9 @@ void port_stats_print(void) __banked
STAT_GET(STAT_COUNTER_ERR_PKTS, i);
print_reg(RTL837X_STAT_V_HIGH); write_char('\t');
reg_read(RTL837X_L2_LRN_PORT_CONSTRT_CNT + (i << 2));
itoa_short(SFR_DATA_U16 & L2_LRN_PORT_CNT_MASK);
print_string("\n");
}
}
+2
View File
@@ -214,6 +214,8 @@
#define RTL837x_L2_TBL_FLUSH_CNF 0x53dc
#define RTL837X_L2_LRN_PORT_CONSTRAINT 0x5384
#define RTL837X_L2_LRN_PORT_CONSTRT_ACT 0x4f80
#define RTL837X_L2_LRN_PORT_CONSTRT_CNT 0x53ac
#define L2_LRN_PORT_CNT_MASK 0x1fff
#define RTL8373_REG_MAC_L2_PORT_MAX_LEN 0x1250
/*
+18
View File
@@ -185,6 +185,23 @@ static void t_l2_page(void)
CHECK(balanced(), "every page is valid JSON");
}
static void t_status_macs(void)
{
const char *p1, *end, *mac;
printf("[test] /status.json reports the MAC addresses learned on each port\n");
hw_reset(); out_reset();
hw_reg_set(RTL837X_L2_LRN_PORT_CONSTRT_CNT + (1 << 2), 0x21);
send_status();
p1 = strstr(body(), "\"logPort\":1,");
end = p1 ? strchr(p1, '}') : NULL;
mac = p1 ? strstr(p1, "\"macs\":\"0x21\"") : NULL;
CHECK(mac && mac < end, "port 1 shows its learned count");
CHECK(has("\"macs\":\"0x0\""), "a port without learned addresses shows 0");
CHECK(slen <= TCP_OUTBUF_SIZE, "fits the buffer");
CHECK(balanced(), "valid JSON");
}
static void t_status_counters(void)
{
printf("[test] /status.json prints 64-bit packet counters in full\n");
@@ -211,6 +228,7 @@ int main(void)
t_l2();
t_l2_page();
t_status_counters();
t_status_macs();
printf("\n%d checks, %d failed\n", tests_run, tests_failed);
return tests_failed ? 1 : 0;
}