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/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 c5a1e9d..91e675d 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) do { \ diff --git a/rtl837x_port.c b/rtl837x_port.c index 99a89e4..daba16f 100644 --- a/rtl837x_port.c +++ b/rtl837x_port.c @@ -340,7 +340,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 { @@ -425,12 +428,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); @@ -849,19 +854,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 57c2484..4c3d3b7 100644 --- a/rtl837x_port.h +++ b/rtl837x_port.h @@ -74,8 +74,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/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; diff --git a/rtlplayground.c b/rtlplayground.c index cd5e14e..72d1e27 100644 --- a/rtlplayground.c +++ b/rtlplayground.c @@ -1813,18 +1813,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 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