httpd: read the table registers straight from the SFRs in l2_delete()

Test the busy flag and compare the entry's MAC against the SFR data
registers directly instead of going through the sfr_data copy, and
rewrite TBL_DATA_0 in place rather than reassembling all four bytes.
Smaller and faster on the deepest httpd path.

Suggested-by: vDorst
This commit is contained in:
bloqaudio committed 2026-09-03 14:33:07 -05:00
1 parent dd7f9f7c7b
commit 1c9bf10b87
1 file changed
+15 -12
+15 -12
View File
@@ -432,29 +432,31 @@ void l2_delete(uint16_t idx)
__xdata uint8_t entries_left = L2_MAX_TRANSFER;
do {
reg_read_m(RTL837X_TBL_CTRL);
} while (sfr_data[3] & TBL_EXECUTE);
reg_read(RTL837X_TBL_CTRL);
} while (SFR_DATA_0 & TBL_EXECUTE);
slen += strtox(outbuf + slen, "{\"result\":");
// First, search for the entry based on the index
reg_read_m(RTL837x_TBL_DATA_0);
REG_WRITE(RTL837x_TBL_DATA_0, sfr_data[0], sfr_data[1] & 0xfc, sfr_data[2] | (TBL_LUTREAD_NEXT_L2UC << 6), sfr_data[3]);
sfr_data[1] &= 0xfc;
sfr_data[2] |= (TBL_LUTREAD_NEXT_L2UC << 6);
reg_write_m(RTL837x_TBL_DATA_0);
REG_WRITE(RTL837X_TBL_CTRL, (idx >> 8) & 0xf, idx, TBL_L2_UNICAST, TBL_EXECUTE);
do {
reg_read_m(RTL837X_TBL_CTRL);
} while (sfr_data[3] & 0x1);
reg_read(RTL837X_TBL_CTRL);
} while (SFR_DATA_0 & 0x1);
reg_read_m(RTL837x_L2_DATA_OUT_B);
if (!(sfr_data[0] & 0x20)) {
if (!(SFR_DATA_24 & 0x20)) {
char_to_html('0');
} else {
__bit own = sfr_data[2] == uip_ethaddr.addr[0] && sfr_data[3] == uip_ethaddr.addr[1];
__bit is_our_mac_addr = uip_ethaddr.addr[0] == SFR_DATA_8 && uip_ethaddr.addr[1] == SFR_DATA_0;
sfr_data[0] &= 0x3f; // Clear SPA
reg_write_m(RTL837x_TBL_DATA_IN_B);
// Second half of MAC is copied
reg_read_m(RTL837x_L2_DATA_OUT_A);
if (own && sfr_data[0] == uip_ethaddr.addr[2] && sfr_data[1] == uip_ethaddr.addr[3]
&& sfr_data[2] == uip_ethaddr.addr[4] && sfr_data[3] == uip_ethaddr.addr[5]) {
if (is_our_mac_addr && uip_ethaddr.addr[2] == SFR_DATA_24 && uip_ethaddr.addr[3] == SFR_DATA_16
&& uip_ethaddr.addr[4] == SFR_DATA_8 && uip_ethaddr.addr[5] == SFR_DATA_0) {
// the switch's own entry keeps management reachable
char_to_html('0');
} else {
@@ -466,12 +468,13 @@ void l2_delete(uint16_t idx)
reg_write_m(RTL837x_TBL_DATA_IN_C);
reg_read_m(RTL837x_TBL_DATA_0);
REG_WRITE(RTL837x_TBL_DATA_0, sfr_data[0], sfr_data[1], TBL_L2_UNICAST, sfr_data[3]);
sfr_data[2] = TBL_L2_UNICAST;
reg_write_m(RTL837x_TBL_DATA_0);
REG_WRITE(RTL837X_TBL_CTRL, idx >> 8, idx, TBL_L2_UNICAST, TBL_WRITE | TBL_EXECUTE);
do {
reg_read_m(RTL837X_TBL_CTRL);
} while (sfr_data[3] & TBL_EXECUTE);
reg_read(RTL837X_TBL_CTRL);
} while (SFR_DATA_0 & TBL_EXECUTE);
char_to_html('1');
}