From d405dd77765b3573ba2aea3d59e688d2fc0be3ee Mon Sep 17 00:00:00 2001 From: d00f <8052722+DrDoof@users.noreply.github.com> Date: Sun, 16 Aug 2026 01:52:03 +0200 Subject: [PATCH 1/7] port: let a pvid name an aggregation group VLAN membership, PVID, egress tagging, isolation and MTU are all per physical port in this ASIC, so nothing stopped a member of a working aggregation group being given a different PVID from its peers. The group then forwards asymmetrically depending on which member the hash picks, and no part of the firmware says a word about it. port_lag_of() answers which group a port belongs to, reading the membership through the shared reader rather than a fourth private copy. port_pvid_set() expands to the whole group when the port it is given is a member, and ports outside a group keep the path they had. This is the second and third of the three steps set out in #347. I said there that the lookup would come when something needed it, which had it the wrong way round: nothing in the tree asks which group a port is in, so the lookup only earns its place alongside a caller. PVID is the smallest such caller, and the rest of the per port settings can follow the same shape once this one is agreed. Built for SWTGW218AS and KP_9000_6XHML_X2 on sdcc 4.5.0. --- rtl837x_port.c | 27 +++++++++++++++++++++++++-- rtl837x_port.h | 2 ++ 2 files changed, 27 insertions(+), 2 deletions(-) diff --git a/rtl837x_port.c b/rtl837x_port.c index 9388cc6..0a7cabf 100644 --- a/rtl837x_port.c +++ b/rtl837x_port.c @@ -87,10 +87,9 @@ vlan_ingress_mode_t port_ingress_filter_get(__xdata uint8_t port) __banked /* * Define a Primary VLAN ID for a port */ -void port_pvid_set(uint8_t port, __xdata uint16_t pvid) __banked +static void port_pvid_write(uint8_t port, __xdata uint16_t pvid) { // r4e1c:00001001 R4e1c-000017d0 r6738:00000000 R6738-00000000 (no filtering) - print_string("\nport_pvid_set called \n"); uint16_t reg = RTL837x_PVID_BASE_REG + ((port >> 1) << 2); reg_read_m(reg); @@ -101,6 +100,22 @@ void port_pvid_set(uint8_t port, __xdata uint16_t pvid) __banked } } +void port_pvid_set(uint8_t port, __xdata uint16_t pvid) __banked +{ + uint8_t lag = port_lag_of(port); + + print_string("\nport_pvid_set called \n"); + if (lag == PORT_LAG_NONE) { + port_pvid_write(port, pvid); + return; + } + + uint16_t members = port_lag_members_get(lag); + for (uint8_t i = 0; i < 10; i++) + if ((members >> i) & 1) + port_pvid_write(i, pvid); +} + uint16_t port_pvid_get(uint8_t port) __banked { uint16_t reg = RTL837x_PVID_BASE_REG + ((port >> 1) << 2); @@ -745,6 +760,14 @@ uint16_t port_lag_members_get(uint8_t lag) __banked return ((uint16_t)SFR_DATA_8 << 8) | SFR_DATA_0; } +uint8_t port_lag_of(uint8_t port) __banked +{ + for (uint8_t lag = 0; lag < 4; lag++) + if ((port_lag_members_get(lag) >> port) & 1) + return lag; + return PORT_LAG_NONE; +} + /* * Configure LAGs diff --git a/rtl837x_port.h b/rtl837x_port.h index b459832..c0185a1 100644 --- a/rtl837x_port.h +++ b/rtl837x_port.h @@ -62,6 +62,8 @@ void port_mirror_del(void) __banked; bool port_ingress_filter(__xdata uint8_t port, __xdata vlan_ingress_mode_t type) __banked; void port_l2_setup(void) __banked; uint16_t port_lag_members_get(uint8_t lag) __banked; +#define PORT_LAG_NONE 0xff +uint8_t port_lag_of(uint8_t port) __banked; void port_lag_members_set(__xdata uint8_t lag, __xdata uint16_t members) __banked; void port_lag_hash_set(__xdata uint8_t lag, __xdata uint8_t hash) __banked; void port_eee_enable_all(__xdata uint8_t speed) __banked; From 4e04735a5f47736c052e2934d898f5c69087842f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20van=20Dorst?= Date: Sun, 30 Aug 2026 19:09:36 +0200 Subject: [PATCH 2/7] Fix define macros, was missing the do {} while (0) wrapping --- rtl837x_phy.h | 6 ++++-- rtl837x_port.h | 5 +++-- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/rtl837x_phy.h b/rtl837x_phy.h index 932516a..c5a1e9d 100644 --- a/rtl837x_phy.h +++ b/rtl837x_phy.h @@ -31,11 +31,13 @@ void rtl8224_write_reg_u16(uint16_t reg, uint16_t val) __banked; void rtl8224_sds_write(uint16_t sds_cmd, uint16_t val) __banked; void phy_config_8261(uint8_t phy, uint8_t sds) __banked; -#define RTL8224_SDS_WRITE(sds_id, page, reg, v) uint16_t _sdscmd = (uint16_t)(sds_id & 0x01) | (1 << 14) | (1 << 15); \ +#define RTL8224_SDS_WRITE(sds_id, page, reg, v) do { \ + uint16_t _sdscmd = (uint16_t)(sds_id & 0x01) | (1 << 14) | (1 << 15); \ _sdscmd |= (page & 0x3F) << 1; \ _sdscmd |= ((uint16_t)(reg & 0x1f)) << 7; \ print_string("CMD: "); print_short(_sdscmd); \ write_char('-'); print_short(v); \ - rtl8224_sds_write(_sdscmd, v); + rtl8224_sds_write(_sdscmd, v); \ + } while (0) #endif diff --git a/rtl837x_port.h b/rtl837x_port.h index b9bc84a..f8d5335 100644 --- a/rtl837x_port.h +++ b/rtl837x_port.h @@ -8,11 +8,12 @@ #define STAT_COUNTER_RX_PKTS 47 #define STAT_COUNTER_ERR_PKTS 48 -#define STAT_GET(cnt, port) \ +#define STAT_GET(cnt, port) do { \ REG_WRITE(RTL837X_STAT_GET, 0x00, 0x00, cnt >> 3, (cnt << 5) | (port << 1) | 1); \ do { \ reg_read_m(RTL837X_STAT_GET); \ - } while (sfr_data[3] & 0x1); + } while (sfr_data[3] & 0x1); \ + } while (0) // Possible values for ingress filter type typedef enum { From b6dcb75130a2aa828a4786f716c3b21c825215b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20van=20Dorst?= Date: Sun, 30 Aug 2026 20:15:34 +0200 Subject: [PATCH 3/7] Disable all __sfr32 due to bug SDCC 4070 and add workarounds. Generate wrong address for `a4` location. Both on read from and write to a __sfr32 variable. Workaround: Use two __sfr16 instead of one __sfr32. We still get some optimalizations / better code gen. --- rtl837x_sfr.h | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/rtl837x_sfr.h b/rtl837x_sfr.h index f3e4a72..45c117a 100644 --- a/rtl837x_sfr.h +++ b/rtl837x_sfr.h @@ -5,8 +5,13 @@ __sfr16 __at(0xa2a3) SFR_REG_ADDR_U16; __sfr __at(0xa2) SFR_REG_ADDRH; __sfr __at(0xa3) SFR_REG_ADDRL; __sfr16 __at(0xa6a7) SFR_DATA_U16; -__sfr32 __at(0xa4a5a6a7) SFR_DATA_U32; -__sfr32 __at(0xa7a6a5a4) SFR_DATA_U32LE; +// Disabling until the SDCC bug #4070 is fixed. +// Generate wrong address for `a4` location. +// Both read from and write to `SFR_DATA_U32`. +// __sfr32 __at(0xa4a5a6a7) SFR_DATA_U32; +// __sfr32 __at(0xa7a6a5a4) SFR_DATA_U32LE; +// This is the upper part of the U32 as a workaround for SDCC bug #4070. +__sfr16 __at(0xa4a5) SFR_DATA_U16_UPPER; __sfr __at(0xa4) SFR_DATA_24; __sfr __at(0xa5) SFR_DATA_16; __sfr __at(0xa6) SFR_DATA_8; From aba69cd6405e8e8248db03c059c5c42f71097365 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20van=20Dorst?= Date: Sun, 30 Aug 2026 20:40:21 +0200 Subject: [PATCH 4/7] DHCP: Added workarounds for SDCC bug 4070 --- dhcp.c | 7 ++++++- rtlplayground.c | 23 +++++++++++++++++++---- 2 files changed, 25 insertions(+), 5 deletions(-) diff --git a/dhcp.c b/dhcp.c index ad5c536..d821f80 100644 --- a/dhcp.c +++ b/dhcp.c @@ -351,7 +351,12 @@ void dhcp_start(void) __banked return; } get_random_32(); - dhcp_state.transaction_id = SFR_DATA_U32; + // Workaround SDCC bug 4070: dhcp_state.transaction_id = SFR_DATA_U32; + __xdata uint8_t * tid = &dhcp_state.transaction_id; + *tid++ = SFR_DATA_24; + *tid++ = SFR_DATA_16; + *tid++ = SFR_DATA_8; + *tid = SFR_DATA_0; dhcp_state.state = DHCP_START; print_string("dhcp_start done\n"); } diff --git a/rtlplayground.c b/rtlplayground.c index cd5e14e..a4c133d 100644 --- a/rtlplayground.c +++ b/rtlplayground.c @@ -1813,6 +1813,12 @@ void init_smi(void) /* Set the SMI(i.e.I2C) type for PHY polling, 0b01 is 2.5/10G PHY. Disable (0b00) for the SFP-ports * which are at port 8 and additionally at port 3 for a dual SFP device */ + + // using 16bit value, because it can load cheap. + // Default: 0x00005555 + // Workaround for SDCC BUG 4070: SFR_DATA_U32 = 0x00005555; + SFR_DATA_U16_UPPER = 0x0000; + SFR_DATA_U16= 05555; if (machine.n_10g == 2) { REG_SET(RTL837X_REG_SMI_MAC_TYPE, 0x00015555); } else { @@ -1820,11 +1826,20 @@ void init_smi(void) } // Configure polling of all PHYs by the MAC to detect link-state changes - if (machine_detected.isRTL8373) { - REG_SET(RTL837X_REG_SMI_PORT_POLLING, 0xff); - } else { - REG_SET(RTL837X_REG_SMI_PORT_POLLING, machine.n_sfp == 2 ? 0xf0 : 0x1f8); + // Default: 0x000000ff + // Workaround for SDCC BUG 4070: SFR_DATA_U32 = 0x000000ff; + SFR_DATA_U16_UPPER = 0x0000; + SFR_DATA_U16= 0x00ff; + if (!machine_detected.isRTL8373) { + if (machine.n_sfp == 2) { + SFR_DATA_0 = 0xf0; + } else { + SFR_DATA_0 = 0xf8; + SFR_DATA_16 = 0x1f; + } } + reg_write(RTL837X_REG_SMI_PORT_POLLING); + // Enable MDC reg_read_m(RTL837X_REG_SMI_CTRL); sfr_mask_data(1, 0, 0x70); // Set bits 12-14 to enable MDC for SMI0-SMI2 From f187261085ac2d237c735deb9cb0dc73caa8ae0c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20van=20Dorst?= Date: Fri, 28 Aug 2026 20:37:07 +0200 Subject: [PATCH 5/7] Fix all compiler warnings. - Many times we need help the compiler to reason about variable type or define. --- httpd/httpd.c | 9 +++++++-- rtl837x_igmp.c | 7 +++++-- rtl837x_phy.c | 20 +++++++++++--------- rtl837x_phy.h | 2 +- rtl837x_port.c | 29 +++++++++++++++++++---------- rtl837x_port.h | 4 ++-- rtlplayground.c | 14 +++++++------- uip/uip.c | 9 ++++----- 8 files changed, 56 insertions(+), 38 deletions(-) diff --git a/httpd/httpd.c b/httpd/httpd.c index 23fef5d..6191aff 100644 --- a/httpd/httpd.c +++ b/httpd/httpd.c @@ -772,8 +772,13 @@ void httpd_appcall(void) goto do_send; } - if (is_word(p, "GET")) - dbg_string("GET request "); + // We only expect a GET request here. + if (!is_word(p, "GET")) { + send_bad_request(); + goto do_send; + } + + dbg_string("GET request "); p += 4; scan_header(p); __xdata uint8_t *q = p; diff --git a/rtl837x_igmp.c b/rtl837x_igmp.c index feddf9a..da02903 100644 --- a/rtl837x_igmp.c +++ b/rtl837x_igmp.c @@ -92,8 +92,11 @@ void igmp_setup(void) __banked REG_SET(RTL837X_IPV6_PORT_MC_LM_ACT, LOOKUP_MISS_FLOOD); // Define ports where unknown MC addresses are flooded to: - REG_SET(RTL837X_IPV4_UNKN_MC_FLD_PMSK, machine_detected.isRTL8373? PMASK_9: PMASK_6); - REG_SET(RTL837X_IPV6_UNKN_MC_FLD_PMSK, machine_detected.isRTL8373? PMASK_9: PMASK_6); + uint16_t mask = PMASK_6; + if (machine_detected.isRTL8373) + mask = PMASK_9; + REG_SET(RTL837X_IPV4_UNKN_MC_FLD_PMSK, mask); + REG_SET(RTL837X_IPV6_UNKN_MC_FLD_PMSK, mask); // Enable lookup of IPv4 MC addresses in table reg_bit_set(RTL837X_L2_CTRL, L2_CTRL_LUT_IPMC_HASH); diff --git a/rtl837x_phy.c b/rtl837x_phy.c index 240d1d0..a338354 100644 --- a/rtl837x_phy.c +++ b/rtl837x_phy.c @@ -468,9 +468,13 @@ void phy_show(uint8_t port) __banked phy_read(port, PHY_MMD_PMAPMD, 0); v = SFR_DATA_U16; print_string("\nForced speed: "); print_short(v); write_char('\n'); - uint8_t s1 = ((v & 0x40) ? 0x2 : 0x0) | ((v & 0x2000) ? 0x1 : 0x0); - uint8_t s2 = (v >> 2) & 0xf; - switch(s1) { + uint8_t s1 = 0x00; + if ((uint8_t)v & 0x40) + s1 = 0x2; + if (v & 0x2000) + s1 |= 0x1; + uint8_t s2 = ((uint8_t)v >> 2) & 0xf; + switch(s1 & 0x3) { case 0: print_string("10M\n"); break; @@ -495,8 +499,6 @@ void phy_show(uint8_t port) __banked print_string("Unknown\n"); } break; - default: - print_string("Unknown\n"); } phy_read(port, PHY_MMD31, PHY_MMD31_FEDCR); v = SFR_DATA_U16; @@ -582,7 +584,7 @@ void phy_reset(uint8_t port) __banked // Reading only reads the lower 16-bit part of the 32-bit register. // When also needing read the upper 16-bits, use register address + 1. // Readed values it return via sfr-data. -void inline rtl8224_read_reg_u16(uint16_t reg) __banked +void rtl8224_read_reg_u16(uint16_t reg) __banked { // void phy_read(uint8_t phy_id, uint8_t dev_id, uint16_t reg) // phy_read(RTL8224_PHY_ID, PHY_MMD30, reg); @@ -590,7 +592,7 @@ void inline rtl8224_read_reg_u16(uint16_t reg) __banked SFR_SMI_REG_U16 = reg; // c2, c2 SFR_SMI_PHY = RTL8224_PHY_ID; // a5 - SFR_SMI_DEV = PHY_MMD30 << 3 | 2; // c4 + SFR_SMI_DEV = (uint8_t)PHY_MMD30 << 3 | 2; // c4 SFR_EXEC_GO = SFR_EXEC_READ_SMI; do { @@ -601,7 +603,7 @@ void inline rtl8224_read_reg_u16(uint16_t reg) __banked // Registers names are the same as on the RTL837x. // Writing only the lower 16-bit part of the 32-bit register. // When also needing to write the upper 16-bits, use register address + 1. -void inline rtl8224_write_reg_u16(uint16_t reg, uint16_t val) __banked +void rtl8224_write_reg_u16(uint16_t reg, uint16_t val) __banked { SFR_DATA_U16 = val; // SFR_A6, SFR_A7 SFR_SMI_REG_U16 = reg; // SFR_C2, SFR_C3 @@ -633,7 +635,7 @@ void inline rtl8224_write_reg_u16(uint16_t reg, uint16_t val) __banked // Write to the RTL8224 SDS registers. -void rtl8224_sds_write(uint16_t sds_cmd, uint16_t value) __banked +void rtl8224_sds_write(uint16_t sds_cmd, __xdata uint16_t value) __banked { // Wait for command bit is cleared do { diff --git a/rtl837x_phy.h b/rtl837x_phy.h index 932516a..9ec3ebd 100644 --- a/rtl837x_phy.h +++ b/rtl837x_phy.h @@ -28,7 +28,7 @@ void phy_show(uint8_t port) __banked; void phy_reset(uint8_t port) __banked; void rtl8224_read_reg_u16(uint16_t reg) __banked; void rtl8224_write_reg_u16(uint16_t reg, uint16_t val) __banked; -void rtl8224_sds_write(uint16_t sds_cmd, uint16_t val) __banked; +void rtl8224_sds_write(uint16_t sds_cmd, __xdata uint16_t val) __banked; void phy_config_8261(uint8_t phy, uint8_t sds) __banked; #define RTL8224_SDS_WRITE(sds_id, page, reg, v) uint16_t _sdscmd = (uint16_t)(sds_id & 0x01) | (1 << 14) | (1 << 15); \ diff --git a/rtl837x_port.c b/rtl837x_port.c index 808521f..05693f50 100644 --- a/rtl837x_port.c +++ b/rtl837x_port.c @@ -325,7 +325,10 @@ uint8_t port_l2_forget(void) __banked REG_SET(RTL837x_L2_TBL_FLUSH_CNF, 0x0); // Flush L2 table for all ports by setting the ports and the flush-exec bit (bit 16) - REG_SET(RTL837x_L2_TBL_FLUSH_CTRL, L2_TBL_FLUSH_EXEC | (machine_detected.isRTL8373 ? PMASK_9 : PMASK_6)); + uint16_t mask = PMASK_6; + if (machine_detected.isRTL8373) + mask = PMASK_9; + REG_SET(RTL837x_L2_TBL_FLUSH_CTRL, L2_TBL_FLUSH_EXEC | mask); // Wait for flush completed do { @@ -410,12 +413,14 @@ void port_l2_setup(void) __banked for (uint8_t i = machine.min_port; i <= machine.max_port; i++) { // Limit the number of automatically learned MAC-Entries per port to 0x1040 - uint16_t reg = RTL837X_L2_LRN_PORT_CONSTRAINT + (i << 2); - REG_SET(reg, 0x00001040); + uint8_t idx = (i << 2); + REG_SET(RTL837X_L2_LRN_PORT_CONSTRAINT + idx, 0x00001040); // All ports may communicate with each other and CPU-Port - reg = RTL837X_PORT_ISOLATION_BASE + (i << 2); - REG_SET(reg, PMASK_CPU | (machine_detected.isRTL8373? PMASK_9 : PMASK_6)); + uint16_t mask = PMASK_CPU | PMASK_6; + if (machine_detected.isRTL8373) + mask = PMASK_CPU | PMASK_9; + REG_SET(RTL837X_PORT_ISOLATION_BASE + idx, mask); } // When maximim entries learned, then simply flood the packet reg_bit_set(RTL837X_L2_LRN_PORT_CONSTRT_ACT, 0); @@ -826,19 +831,23 @@ void vlan_dump(void) __banked /** Set the ingress VLAN filtering */ -bool port_ingress_vlan_filter_set(__xdata uint8_t port, __xdata bool enabled) __banked +bool port_ingress_vlan_filter_set(uint8_t port, __xdata bool enabled) __banked { - if (port < machine.min_port || port > machine.max_port && port != 9) { + if (port < machine.min_port || port > machine.max_port && port != CPU_PORT) { return false; } - reg_bit_set(RTL837X_VLAN_PORT_IGR_FLTR, port); + if (enabled) + reg_bit_set(RTL837X_VLAN_PORT_IGR_FLTR, port); + else + reg_bit_clear(RTL837X_VLAN_PORT_IGR_FLTR, port); + return true; } /** Get the ingress VLAN filtering status */ -bool port_ingress_vlan_filter_get(__xdata uint8_t port) __banked +bool port_ingress_vlan_filter_get(uint8_t port) __banked { - if (port < machine.min_port || port > machine.max_port && port != 9) { + if (port < machine.min_port || port > machine.max_port && port != CPU_PORT) { return false; } diff --git a/rtl837x_port.h b/rtl837x_port.h index b9bc84a..1ef8ad2 100644 --- a/rtl837x_port.h +++ b/rtl837x_port.h @@ -71,8 +71,8 @@ void port_eee_enable(__xdata uint8_t port, __xdata uint8_t speed) __banked; void port_eee_disable(uint8_t port) __banked; void port_eee_status(uint8_t port) __banked; void print_port_ingress_filter_mode(vlan_ingress_mode_t mode) __banked; -bool port_ingress_vlan_filter_set(__xdata uint8_t port, __xdata bool enabled) __banked; -bool port_ingress_vlan_filter_get(__xdata uint8_t port) __banked; +bool port_ingress_vlan_filter_set(uint8_t port, __xdata bool enabled) __banked; +bool port_ingress_vlan_filter_get(uint8_t port) __banked; void port_isolate(uint8_t port, __xdata uint16_t pmask) __banked; uint16_t port_isolation_get(uint8_t port) __banked; diff --git a/rtlplayground.c b/rtlplayground.c index a4c133d..dca7cfa 100644 --- a/rtlplayground.c +++ b/rtlplayground.c @@ -1814,16 +1814,17 @@ void init_smi(void) * which are at port 8 and additionally at port 3 for a dual SFP device */ - // using 16bit value, because it can load cheap. // Default: 0x00005555 // Workaround for SDCC BUG 4070: SFR_DATA_U32 = 0x00005555; SFR_DATA_U16_UPPER = 0x0000; - SFR_DATA_U16= 05555; + SFR_DATA_U16 = 0x5555; if (machine.n_10g == 2) { - REG_SET(RTL837X_REG_SMI_MAC_TYPE, 0x00015555); - } else { - REG_SET(RTL837X_REG_SMI_MAC_TYPE, machine.n_sfp == 2 ? 0x00005515 : 0x00005555); - } + // 0x00015555, only change the bytes that differs from the default. + SFR_DATA_16 = 0x01; + } else if (machine.n_sfp == 2) + // 0x00005515 + SFR_DATA_0 = 0x15; + reg_write(RTL837X_REG_SMI_MAC_TYPE); // Configure polling of all PHYs by the MAC to detect link-state changes // Default: 0x000000ff @@ -1839,7 +1840,6 @@ void init_smi(void) } } reg_write(RTL837X_REG_SMI_PORT_POLLING); - // Enable MDC reg_read_m(RTL837X_REG_SMI_CTRL); sfr_mask_data(1, 0, 0x70); // Set bits 12-14 to enable MDC for SMI0-SMI2 diff --git a/uip/uip.c b/uip/uip.c index 1d015fc..47ba3af 100644 --- a/uip/uip.c +++ b/uip/uip.c @@ -373,11 +373,10 @@ uip_udpchksum(void) void uip_init(void) __banked { - uint8_t c; - for(c = 0; c < UIP_LISTENPORTS; ++c) { + for(uint8_t c = 0; c < UIP_LISTENPORTS; c++) { uip_listenports[c] = 0; } - for(c = 0; c < UIP_CONNS; ++c) { + for(uint8_t c = 0; c < UIP_CONNS; c++) { uip_conns[c].tcpstateflags = UIP_CLOSED; } #if UIP_ACTIVE_OPEN @@ -385,7 +384,7 @@ uip_init(void) __banked #endif /* UIP_ACTIVE_OPEN */ #if UIP_UDP - for(c = 0; c < UIP_UDP_CONNS; ++c) { + for(uint8_t c = 0; c < UIP_UDP_CONNS; c++) { uip_udp_conns[c].lport = 0; } #endif /* UIP_UDP */ @@ -1461,7 +1460,7 @@ uip_process(u8_t flag) __banked } /* Do different things depending on in what state the connection is. */ - switch(uip_connr->tcpstateflags & UIP_TS_MASK) { + switch(uip_connr->tcpstateflags & (uint8_t)UIP_TS_MASK) { /* CLOSED and LISTEN are not handled here. CLOSE_WAIT is not implemented, since we force the application to close when the peer sends a FIN (hence the application goes directly from From 6be5693385af7ad05f6e579b81fd8805403f3fb6 Mon Sep 17 00:00:00 2001 From: bloqaudio Date: Sun, 30 Aug 2026 21:49:56 -0500 Subject: [PATCH 6/7] Makefile: have clean and distclean recurse into the tool directory make clean left tools/output in place, so the host tools were never rebuilt after a clean. SUBDIRSCLEAN, which builds the per-directory clean target names for exactly that purpose, was defined but nothing consumed it. Give clean and distclean those targets as prerequisites and add the rule that runs the subdirectory's own clean, which tools/Makefile already provides. --- Makefile | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/Makefile b/Makefile index 2a3f01f..5e1d1df 100644 --- a/Makefile +++ b/Makefile @@ -103,14 +103,17 @@ httpd: html_data.h $(SUBDIRS): $(MAKE) -C $@ -clean: +clean: $(SUBDIRSCLEAN) -rm -f html_data.c html_data.h $(VERSION_HEADER) -if [ -d $(BUILDDIR) ]; then find $(BUILDDIR) -type f ! -name "*.bin" -delete; fi -distclean: +distclean: $(SUBDIRSCLEAN) -rm -f html_data.c html_data.h $(VERSION_HEADER) -rm -rf $(BUILDDIR) +$(SUBDIRSCLEAN): + $(MAKE) -C $(@:clean=) clean + $(BUILDDIR)/%.rel: %.c | create_build_dir html_data.h $(CC) -MMD $(CC_FLAGS) -o $@ -c $< @@ -133,7 +136,7 @@ $(BUILDDIR)/rtlplayground-$(FILENAME_EXTENSION).bin: $(BUILDDIR)/rtlplayground.i tools/output/crc_calculator -u $@ ln -sf $(MACHINE)/rtlplayground-$(FILENAME_EXTENSION).bin output/rtlplayground.bin -.PHONY: clean all $(SUBDIRS) $(VERSION_HEADER) create_build_dir +.PHONY: clean distclean all $(SUBDIRS) $(SUBDIRSCLEAN) $(VERSION_HEADER) create_build_dir .PHONY: machine_check: From 2fa4686b334f1d28bfa0f047296d2dfcac62865f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20van=20Dorst?= Date: Mon, 31 Aug 2026 21:00:37 +0200 Subject: [PATCH 7/7] fix review points. --- rtlplayground.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/rtlplayground.c b/rtlplayground.c index dca7cfa..72d1e27 100644 --- a/rtlplayground.c +++ b/rtlplayground.c @@ -1830,13 +1830,15 @@ void init_smi(void) // Default: 0x000000ff // Workaround for SDCC BUG 4070: SFR_DATA_U32 = 0x000000ff; SFR_DATA_U16_UPPER = 0x0000; - SFR_DATA_U16= 0x00ff; + SFR_DATA_U16 = 0x00ff; if (!machine_detected.isRTL8373) { if (machine.n_sfp == 2) { + // 0x000000f0, only change the bytes that differs from the default. SFR_DATA_0 = 0xf0; } else { + // 0x000001f8, only change the bytes that differs from the default. + SFR_DATA_8 = 0x01; SFR_DATA_0 = 0xf8; - SFR_DATA_16 = 0x1f; } } reg_write(RTL837X_REG_SMI_PORT_POLLING);