Merge upstream/main into the Spanning Tree branch

This commit is contained in:
d00f
2026-08-31 22:48:14 +02:00
11 changed files with 127 additions and 51 deletions
+6 -3
View File
@@ -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:
+6 -1
View File
@@ -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");
}
+7 -2
View File
@@ -773,8 +773,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;
+5 -2
View File
@@ -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);
+11 -9
View File
@@ -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 {
+5 -3
View File
@@ -28,14 +28,16 @@ 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); \
#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
+44 -12
View File
@@ -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);
@@ -339,7 +354,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 {
@@ -445,12 +463,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);
@@ -777,6 +797,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
@@ -861,19 +889,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;
}
+7 -4
View File
@@ -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 {
@@ -64,6 +65,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;
@@ -73,8 +76,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;
vlan_ingress_mode_t port_ingress_filter_get(__xdata uint8_t port) __banked;
void port_isolate(uint8_t port, __xdata uint16_t pmask) __banked;
uint16_t port_isolation_get(uint8_t port) __banked;
+7 -2
View File
@@ -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;
+25 -8
View File
@@ -1846,18 +1846,35 @@ 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
*/
// Default: 0x00005555
// Workaround for SDCC BUG 4070: SFR_DATA_U32 = 0x00005555;
SFR_DATA_U16_UPPER = 0x0000;
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
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) {
// 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;
}
}
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
+4 -5
View File
@@ -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