From ecf152990fbed4b05145394a7c9619c7060047ce Mon Sep 17 00:00:00 2001 From: logicog Date: Sat, 31 Jan 2026 13:37:16 +0100 Subject: [PATCH 1/6] Fix MACHINE_KP_9000_6XHML_X2: the SDS ids were swapped --- machine.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/machine.c b/machine.c index 59bf438..60aeac7 100644 --- a/machine.c +++ b/machine.c @@ -14,12 +14,12 @@ __code const struct machine machine = { .sfp_port[0].pin_detect = GPIO50_I2C_SCL2_UART1_TX, .sfp_port[0].pin_los = GPIO10_LED10, .sfp_port[0].pin_tx_disable = GPIO_NA, - .sfp_port[0].sds = 1, + .sfp_port[0].sds = 0, .sfp_port[0].i2c = { .sda = GPIO41_I2C_SDA3_MDIO1, .scl = GPIO40_I2C_SCL3_MDC1 }, .sfp_port[1].pin_detect = GPIO30_ACL_BIT3_EN, .sfp_port[1].pin_los = GPIO37, .sfp_port[1].pin_tx_disable = GPIO_NA, - .sfp_port[1].sds = 0, + .sfp_port[1].sds = 1, .sfp_port[1].i2c = { .sda = GPIO39_I2C_SDA4, .scl = GPIO40_I2C_SCL3_MDC1 }, .reset_pin = GPIO46_I2C_SCL0, }; From 4747eac9bf1b55e96fc579781b5cf04f84488494 Mon Sep 17 00:00:00 2001 From: logicog Date: Sat, 7 Feb 2026 09:43:38 +0100 Subject: [PATCH 2/6] Reduce DSEG usage for parameters used in port/vlan configuration Currently 5 Bytes are used by the port and vlan configuration: -------------------------------------------------------- ; internal ram data ;-------------------------------------------------------- .area DSEG (DATA) _port_ingress_filter_PARM_2: .ds 1 _vlan_create_PARM_2: .ds 2 _vlan_create_PARM_3: .ds 2 They are used for passing parameters. Use __xdata to pass the parameters instead. --- rtl837x_port.c | 28 +++++++++++++++++----------- rtl837x_port.h | 12 ++++++++++-- 2 files changed, 27 insertions(+), 13 deletions(-) diff --git a/rtl837x_port.c b/rtl837x_port.c index 448431f..322e60d 100644 --- a/rtl837x_port.c +++ b/rtl837x_port.c @@ -28,6 +28,8 @@ extern __xdata struct machine_runtime machine_detected; __xdata uint32_t l2_head; +__xdata struct vlan_settings vlan_settings; + void port_mirror_set(register uint8_t port, __xdata uint16_t rx_pmask, __xdata uint16_t tx_pmask) __banked { print_string("\nport_mirror_set called \n"); @@ -46,7 +48,7 @@ void port_mirror_del(void) __banked } -void port_ingress_filter(register uint8_t port, uint8_t type) __banked +void port_ingress_filter(__xdata uint8_t port, __xdata uint8_t type) __banked { if (type & 0x1) reg_bit_set(RTL837x_REG_INGRESS, port << 1); @@ -121,27 +123,31 @@ __xdata uint16_t vlan_name(register uint16_t vlan) __banked /* + * Create a VLAN + * The arguments are passed in global structure vlan_settings * A member that is not tagged, is untagged */ -void vlan_create(register uint16_t vlan, register uint16_t members, register uint16_t tagged) __banked +void vlan_create(void) __banked { // For now, the CPU-port is always a tagged member: - members |= 0x0200; // Set 10th bit - tagged |= 0x0200; - print_string("\nvlan_create called\nvlan: "); print_short(vlan); - print_string(", members: "); print_short(members); - print_string(", tagged: "); print_short(tagged); write_char('\n'); + vlan_settings.members |= 0x0200; // Set 10th bit + vlan_settings.tagged |= 0x0200; + + print_string("\nvlan_create called\nvlan: "); print_short(vlan_settings.vlan); + print_string(", members: "); print_short(vlan_settings.members); + print_string(", tagged: "); print_short(vlan_settings.tagged); write_char('\n'); + + uint16_t a = (~vlan_settings.members) ^ vlan_settings.tagged ^ vlan_settings.members; - uint16_t a = (~members) ^ tagged ^ members; // On RTL8372, port-bits 0-2 must be 0, although they are not members if (!machine_detected.isRTL8373) { a &= 0x1f8; - tagged &= 0x3f8; + vlan_settings.tagged &= 0x3f8; } // Initialize VLAN table with VLAN 1 - REG_WRITE(RTL837x_TBL_DATA_IN_A, 0x02, (a >> 6) & 0x0f, (a << 2) | (members >> 8), members); - REG_WRITE(RTL837X_TBL_CTRL, vlan >> 8, vlan, TBL_VLAN, TBL_WRITE | TBL_EXECUTE); + REG_WRITE(RTL837x_TBL_DATA_IN_A, 0x02, (a >> 6) & 0x0f, (a << 2) | (vlan_settings.members >> 8), vlan_settings.members); + REG_WRITE(RTL837X_TBL_CTRL, vlan_settings.vlan >> 8, vlan_settings.vlan, TBL_VLAN, TBL_WRITE | TBL_EXECUTE); do { reg_read_m(RTL837X_TBL_CTRL); } while (sfr_data[3] & TBL_EXECUTE); diff --git a/rtl837x_port.h b/rtl837x_port.h index 9049082..480f2e8 100644 --- a/rtl837x_port.h +++ b/rtl837x_port.h @@ -13,6 +13,14 @@ reg_read_m(RTL837X_STAT_GET); \ } while (sfr_data[3] & 0x1); +struct vlan_settings { + uint16_t vlan; + uint16_t members; + uint16_t tagged; +}; + +extern __xdata struct vlan_settings vlan_settings; + uint8_t port_l2_forget(void) __banked; void port_l2_learned(void) __banked; void port_stats_print(void) __banked; @@ -20,11 +28,11 @@ int8_t vlan_get(register uint16_t vlan) __banked; __xdata uint16_t vlan_name(register uint16_t vlan) __banked; void vlan_setup(void) __banked; void port_pvid_set(uint8_t port, __xdata uint16_t pvid) __banked; -void vlan_create(register uint16_t vlan, register uint16_t members, register uint16_t tagged) __banked; +void vlan_create(void) __banked; void vlan_delete(uint16_t vlan) __banked; void port_mirror_set(register uint8_t port, __xdata uint16_t rx_pmask, __xdata uint16_t tx_pmask) __banked; void port_mirror_del(void) __banked; -void port_ingress_filter(register uint8_t port, uint8_t type) __banked; +void port_ingress_filter(__xdata uint8_t port, __xdata uint8_t type) __banked; void port_l2_setup(void) __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; From 9d074166414b8197937a5d474268b7b67d4a12bb Mon Sep 17 00:00:00 2001 From: logicog Date: Sat, 7 Feb 2026 16:20:27 +0100 Subject: [PATCH 3/6] Convert phy_set_duplex phy_set_speed to use struct phy_settings --- rtl837x_phy.c | 100 +++++++++++++++++++++++++------------------------- rtl837x_phy.h | 12 +++++- 2 files changed, 61 insertions(+), 51 deletions(-) diff --git a/rtl837x_phy.c b/rtl837x_phy.c index 97a4909..306057d 100644 --- a/rtl837x_phy.c +++ b/rtl837x_phy.c @@ -24,6 +24,8 @@ extern __code uint16_t bit_mask[16]; extern __code const struct machine machine; extern __xdata struct machine_runtime machine_detected; +__xdata struct phy_settings phy_settings; + // SDS-settings for RTL8224 first SerDes which is connected to the RTL837x-SOC. // Array contrains register-value, and SDS-CMD, which already encodes (sds_index, page, reg). // This array is used in phy_config_8224(). @@ -186,106 +188,106 @@ void phy_config_8224(void) __banked * See e.g. RTL8221B datasheet * duplex: 0: half, 1: full, 2: both */ -void phy_set_speed(uint8_t port, uint8_t speed, uint8_t duplex) __banked +void phy_set_speed(void) __banked { uint16_t v; - phy_read(port, PHY_MMD31, 0xa610); + phy_read(phy_settings.port, PHY_MMD31, 0xa610); v = SFR_DATA_U16; - if (speed == PHY_OFF) { - phy_write(port, PHY_MMD31, 0xa610, v | 0x0800); + if (phy_settings.speed == PHY_OFF) { + phy_write(phy_settings.port, PHY_MMD31, 0xa610, v | 0x0800); return; } // Port is on, make sure of it: if (v & 0x0800) - phy_write(port, PHY_MMD31, 0xa610, v & 0xf7ff); + phy_write(phy_settings.port, PHY_MMD31, 0xa610, v & 0xf7ff); - if (speed == PHY_SPEED_AUTO) { + if (phy_settings.speed == PHY_SPEED_AUTO) { // AN Advertisement Register (MMD 7.0x0010) // bits 0-4: 0x1 (802.3 supported), Extended Next Page format used - phy_write(port, PHY_MMD_AN, PHY_ANEG_ADV, 0x15e1); + phy_write(phy_settings.port, PHY_MMD_AN, PHY_ANEG_ADV, 0x15e1); // Multi-GBASE-TBASE-T AN Control 1 Register (MMD 7.0x0020) // bit 14: SLAVE, bit 13: Multi-Port device, bit 8: 2.5GBit available, 1: LD - phy_write(port, PHY_MMD_AN, PHY_ANEG_MGBASE_CTRL, 0x6081); + phy_write(phy_settings.port, PHY_MMD_AN, PHY_ANEG_MGBASE_CTRL, 0x6081); // GBCR (1000Base-T Control Register, MMD 31.0xA412) - phy_modify(port, PHY_MMD31, PHY_MMD31_GBCR, 0x0000, 0x0200); // Loop timing enabled - phy_write(port, PHY_MMD31, PHY_ANEG_CTRL, 0x3200); // Restart AN + phy_modify(phy_settings.port, PHY_MMD31, PHY_MMD31_GBCR, 0x0000, 0x0200); // Loop timing enabled + phy_write(phy_settings.port, PHY_MMD31, PHY_ANEG_CTRL, 0x3200); // Restart AN } else { // AN Control Register (MMD 7.0x0000) - phy_write(port, PHY_MMD31, PHY_ANEG_CTRL, 0x2000); // Clear bit 12: No Autoneg, Set Extended Pages (bit 13) - if (speed == PHY_SPEED_10M) { - phy_write(port, PHY_MMD_AN, PHY_ANEG_MGBASE_CTRL, 0x6001); - if (!duplex) - phy_write(port, PHY_MMD_AN, PHY_ANEG_ADV, 0x1421); - else if (duplex == 1) - phy_write(port, PHY_MMD_AN, PHY_ANEG_ADV, 0x1441); + phy_write(phy_settings.port, PHY_MMD31, PHY_ANEG_CTRL, 0x2000); // Clear bit 12: No Autoneg, Set Extended Pages (bit 13) + if (phy_settings.speed == PHY_SPEED_10M) { + phy_write(phy_settings.port, PHY_MMD_AN, PHY_ANEG_MGBASE_CTRL, 0x6001); + if (!phy_settings.duplex) + phy_write(phy_settings.port, PHY_MMD_AN, PHY_ANEG_ADV, 0x1421); + else if (phy_settings.duplex == 1) + phy_write(phy_settings.port, PHY_MMD_AN, PHY_ANEG_ADV, 0x1441); else - phy_write(port, PHY_MMD_AN, PHY_ANEG_ADV, 0x1461); - phy_modify(port, PHY_MMD31, PHY_MMD31_GBCR, 0x0200, 0x0000); - } else if (speed == PHY_SPEED_100M) { - phy_write(port, PHY_MMD_AN, PHY_ANEG_MGBASE_CTRL, 0x6001); - if (!duplex) - phy_write(port, PHY_MMD_AN, PHY_ANEG_ADV, 0x1481); - if (duplex == 1) - phy_write(port, PHY_MMD_AN, PHY_ANEG_ADV, 0x1501); + phy_write(phy_settings.port, PHY_MMD_AN, PHY_ANEG_ADV, 0x1461); + phy_modify(phy_settings.port, PHY_MMD31, PHY_MMD31_GBCR, 0x0200, 0x0000); + } else if (phy_settings.speed == PHY_SPEED_100M) { + phy_write(phy_settings.port, PHY_MMD_AN, PHY_ANEG_MGBASE_CTRL, 0x6001); + if (!phy_settings.duplex) + phy_write(phy_settings.port, PHY_MMD_AN, PHY_ANEG_ADV, 0x1481); + if (phy_settings.duplex == 1) + phy_write(phy_settings.port, PHY_MMD_AN, PHY_ANEG_ADV, 0x1501); else - phy_write(port, PHY_MMD_AN, PHY_ANEG_ADV, 0x1581); - phy_modify(port, PHY_MMD31, PHY_MMD31_GBCR, 0x0200, 0x0000); + phy_write(phy_settings.port, PHY_MMD_AN, PHY_ANEG_ADV, 0x1581); + phy_modify(phy_settings.port, PHY_MMD31, PHY_MMD31_GBCR, 0x0200, 0x0000); } else { // AN Advertisement Register (MMD 7.0x0010) // bits 0-4: 0x1 (802.3 supported), Extended Next Page format used - phy_write(port, PHY_MMD_AN, PHY_ANEG_ADV, 0x1001); - if (speed == PHY_SPEED_1G) { + phy_write(phy_settings.port, PHY_MMD_AN, PHY_ANEG_ADV, 0x1001); + if (phy_settings.speed == PHY_SPEED_1G) { // Multi-GBASE-TBASE-T AN Control 1 Register (MMD 7.0x0020) // bit 14: SLAVE, bit 13: Multi-Port device, 1: LD Loop timin enableed - phy_write(port, PHY_MMD_AN, PHY_ANEG_MGBASE_CTRL, 0x6001); + phy_write(phy_settings.port, PHY_MMD_AN, PHY_ANEG_MGBASE_CTRL, 0x6001); // GBCR (1000Base-T Control Register, MMD 31.0xA412) - phy_modify(port, PHY_MMD31, PHY_MMD31_GBCR, 0x0000, 0x0200); - } else if (speed == PHY_SPEED_2G5) { + phy_modify(phy_settings.port, PHY_MMD31, PHY_MMD31_GBCR, 0x0000, 0x0200); + } else if (phy_settings.speed == PHY_SPEED_2G5) { // Multi-GBASE-TBASE-T AN Control 1 Register (MMD 7.0x0020) // bit 14: SLAVE, bit 13: Multi-Port device, bit 8: 2.5GBit available, 1: LD Loop timin enableed - phy_write(port, PHY_MMD_AN, PHY_ANEG_MGBASE_CTRL, 0x6081); + phy_write(phy_settings.port, PHY_MMD_AN, PHY_ANEG_MGBASE_CTRL, 0x6081); // GBCR (1000Base-T Control Register, MMD 31.0xA412) - phy_modify(port, PHY_MMD31, PHY_MMD31_GBCR, 0x0200, 0x0000); + phy_modify(phy_settings.port, PHY_MMD31, PHY_MMD31_GBCR, 0x0200, 0x0000); } } - phy_write(port, PHY_MMD31, PHY_ANEG_CTRL, 0x3000); // Enable AN + phy_write(phy_settings.port, PHY_MMD31, PHY_ANEG_CTRL, 0x3000); // Enable AN } } -void phy_set_duplex(uint8_t port, uint8_t fullduplex) __banked +void phy_set_duplex(void) __banked { uint16_t v; - phy_read(port, PHY_MMD31, PHY_ANEG_CTRL); + phy_read(phy_settings.port, PHY_MMD31, PHY_ANEG_CTRL); v = SFR_DATA_U16; if (!(v & 0x1000)) { // AN disabled, we are in forced mode - phy_read(port, PHY_MMD31, PHY_MMD31_FEDCR); + phy_read(phy_settings.port, PHY_MMD31, PHY_MMD31_FEDCR); v = SFR_DATA_U16; - if (fullduplex) + if (phy_settings.duplex) v |= 0x0100; else v &= 0xfeff; - phy_write(port, PHY_MMD31, PHY_MMD31_FEDCR, v); + phy_write(phy_settings.port, PHY_MMD31, PHY_MMD31_FEDCR, v); return; } // Disable AN - phy_write(port, PHY_MMD31, PHY_ANEG_CTRL, 0x2000); - phy_read(port, PHY_MMD_AN, PHY_ANEG_ADV); + phy_write(phy_settings.port, PHY_MMD31, PHY_ANEG_CTRL, 0x2000); + phy_read(phy_settings.port, PHY_MMD_AN, PHY_ANEG_ADV); v = SFR_DATA_U16; if (v & 0x0060) { - if (fullduplex) - phy_modify(port, PHY_MMD_AN, PHY_ANEG_ADV, 0xffbf, 0x0040); + if (phy_settings.duplex) + phy_modify(phy_settings.port, PHY_MMD_AN, PHY_ANEG_ADV, 0xffbf, 0x0040); else - phy_modify(port, PHY_MMD_AN, PHY_ANEG_ADV, 0xffdf, 0x0020); + phy_modify(phy_settings.port, PHY_MMD_AN, PHY_ANEG_ADV, 0xffdf, 0x0020); } if (v & 0x0180) { - if (fullduplex) - phy_modify(port, PHY_MMD_AN, PHY_ANEG_ADV, 0xfeff, 0x0100); + if (phy_settings.duplex) + phy_modify(phy_settings.port, PHY_MMD_AN, PHY_ANEG_ADV, 0xfeff, 0x0100); else - phy_modify(port, PHY_MMD_AN, PHY_ANEG_ADV, 0xff7f, 0x0080); + phy_modify(phy_settings.port, PHY_MMD_AN, PHY_ANEG_ADV, 0xff7f, 0x0080); } // Restart AN - phy_write(port, PHY_MMD31, PHY_ANEG_CTRL, 0x3000); + phy_write(phy_settings.port, PHY_MMD31, PHY_ANEG_CTRL, 0x3000); } diff --git a/rtl837x_phy.h b/rtl837x_phy.h index 0b01e45..84ab214 100644 --- a/rtl837x_phy.h +++ b/rtl837x_phy.h @@ -10,11 +10,19 @@ #define PHY_SPEED_AUTO 0x10 #define PHY_OFF 0xff +struct phy_settings { + uint8_t duplex; + uint8_t port; + uint8_t speed; +}; + +extern __xdata struct phy_settings phy_settings; + void rtl8224_phy_enable(void) __banked; void phy_config(uint8_t phy) __banked; void phy_config_8224(void) __banked; -void phy_set_speed(uint8_t port, uint8_t speed, uint8_t duplex) __banked; -void phy_set_duplex(uint8_t port, uint8_t fullduplex) __banked; +void phy_set_speed(void) __banked; +void phy_set_duplex(void) __banked; void phy_show(uint8_t port) __banked; void phy_reset(uint8_t port) __banked; void rtl8224_read_reg_u16(uint16_t reg) __banked; From 708b6b7f28d6c06030f4f98cf397072091c99f4a Mon Sep 17 00:00:00 2001 From: logicog Date: Sat, 7 Feb 2026 16:21:17 +0100 Subject: [PATCH 4/6] Use new signatures for vlan_create and phy-settings --- cmd_parser.c | 77 ++++++++++++++++++++++++++++------------------------ 1 file changed, 42 insertions(+), 35 deletions(-) diff --git a/cmd_parser.c b/cmd_parser.c index 21e1d1c..33e4101 100644 --- a/cmd_parser.c +++ b/cmd_parser.c @@ -282,17 +282,17 @@ void parse_lag_hash(void) void parse_vlan(void) { - __xdata uint16_t vlan; - __xdata uint16_t members = 0; - __xdata uint16_t tagged = 0; - if (!atoi_short(&vlan, cmd_words_b[1])) { + vlan_settings.vlan = 0; + vlan_settings.members = 0; + vlan_settings.tagged = 0; + if (!atoi_short(&vlan_settings.vlan, cmd_words_b[1])) { if (cmd_words_b[2] > 0 && cmd_buffer[cmd_words_b[2]] == 'd' && cmd_words_b[3] < 0) { - vlan_delete(vlan); + vlan_delete(vlan_settings.vlan); return; } if (cmd_words_b[2] > 0 && cmd_compare(2, "mgmt")) { - management_vlan = vlan; - if (!vlan) + management_vlan = vlan_settings.vlan; + if (!vlan_settings.vlan) print_string("Management VLAN disabled\n"); else print_string("Management VLAN set to "); print_short(management_vlan); write_char('\n'); @@ -301,9 +301,9 @@ void parse_vlan(void) uint8_t w = 2; if (cmd_words_b[w] > 0 && isletter(cmd_buffer[cmd_words_b[w]])) { register uint8_t i = 0; - vlan_names[vlan_ptr++] = hex[(vlan >> 8) & 0xf]; - vlan_names[vlan_ptr++] = hex[(vlan >> 4) & 0xf] ; - vlan_names[vlan_ptr++] = hex[vlan & 0xf]; + vlan_names[vlan_ptr++] = hex[(vlan_settings.vlan >> 8) & 0xf]; + vlan_names[vlan_ptr++] = hex[(vlan_settings.vlan >> 4) & 0xf] ; + vlan_names[vlan_ptr++] = hex[vlan_settings.vlan & 0xf]; while(cmd_buffer[cmd_words_b[w] + i] != ' ') { write_char(cmd_buffer[cmd_words_b[w] + i]); vlan_names[vlan_ptr++] = cmd_buffer[cmd_words_b[w] + i++]; @@ -313,25 +313,25 @@ void parse_vlan(void) print_string("<\n"); } while (cmd_words_b[w] > 0) { - uint8_t port; + __xdata uint8_t port; if (isnumber(cmd_buffer[cmd_words_b[w]])) { port = cmd_buffer[cmd_words_b[w]] - '1'; if (isnumber(cmd_buffer[cmd_words_b[w] + 1])) { port = (port + 1) * 10 + cmd_buffer[cmd_words_b[w] + 1] - '1'; if (cmd_buffer[cmd_words_b[w] + 2] == 't') - tagged |= ((uint16_t)1) << port; + vlan_settings.tagged |= ((uint16_t)1) << port; } else { port = machine.phys_to_log_port[port]; if (cmd_buffer[cmd_words_b[w] + 1] == 't') - tagged |= ((uint16_t)1) << port; + vlan_settings.tagged |= ((uint16_t)1) << port; } if (port > machine.max_port) goto err; - members |= ((uint16_t)1) << port; + vlan_settings.members |= ((uint16_t)1) << port; } w++; } - vlan_create(vlan, members, tagged); + vlan_create(); } if (cmd_words_b[2] > 0 && isletter(cmd_buffer[cmd_words_b[2]])) { print_string("vlan_ptr "); print_short(vlan_ptr); write_char(':'); @@ -422,10 +422,10 @@ void parse_mirror(void) void parse_port(void) { print_string("\nPORT "); - uint8_t p = cmd_buffer[cmd_words_b[1]] - '1'; - p = machine.phys_to_log_port[p]; - print_byte(p); - if (machine.is_sfp[p]) { + phy_settings.port = cmd_buffer[cmd_words_b[1]] - '1'; + phy_settings.port = machine.phys_to_log_port[phy_settings.port]; + print_byte(phy_settings.port); + if (machine.is_sfp[phy_settings.port]) { print_string(" is SFP no PHY information available.\n"); return; } @@ -433,46 +433,53 @@ void parse_port(void) print_string("\nport [show|on|off|10m|100m|1g|2g5] [half|full]"); return; } + phy_settings.duplex = PHY_DUPLEX_BOTH; if (cmd_compare(2, "10m")) { print_string(" 10M\n"); + phy_settings.speed = PHY_SPEED_10M; if (cmd_words_b[3] > 0 && cmd_compare(3, "half")) - phy_set_speed(p, PHY_SPEED_10M, PHY_DUPLEX_HALF); + phy_settings.duplex = PHY_DUPLEX_HALF; else if (cmd_words_b[3] > 0 && cmd_compare(3, "full")) - phy_set_speed(p, PHY_SPEED_10M, PHY_DUPLEX_FULL); - else - phy_set_speed(p, PHY_SPEED_10M, PHY_DUPLEX_BOTH); + phy_settings.duplex = PHY_DUPLEX_FULL; + phy_set_speed(); } else if (cmd_compare(2, "100m")) { print_string(" 100M\n"); + phy_settings.speed = PHY_SPEED_100M; if (cmd_words_b[3] > 0 && cmd_compare(3, "half")) - phy_set_speed(p, PHY_SPEED_100M, PHY_DUPLEX_HALF); + phy_settings.duplex = PHY_DUPLEX_HALF; else if (cmd_words_b[3] > 0 && cmd_compare(3, "full")) - phy_set_speed(p, PHY_SPEED_100M, PHY_DUPLEX_FULL); - else - phy_set_speed(p, PHY_SPEED_100M, PHY_DUPLEX_BOTH); + phy_settings.duplex = PHY_DUPLEX_FULL; + phy_set_speed(); } else if (cmd_compare(2, "2g5")) { print_string(" 2.5G\n"); - phy_set_speed(p, PHY_SPEED_2G5, PHY_DUPLEX_BOTH); + phy_settings.speed = PHY_SPEED_2G5; + phy_set_speed(); } else if (cmd_compare(2, "1g")) { print_string(" 1G\n"); - phy_set_speed(p, PHY_SPEED_1G, PHY_DUPLEX_BOTH); + phy_settings.speed = PHY_SPEED_1G; + phy_set_speed(); } else if (cmd_compare(2, "auto")) { print_string(" AUTO\n"); - phy_set_speed(p, PHY_SPEED_AUTO, PHY_DUPLEX_BOTH); + phy_settings.speed = PHY_SPEED_AUTO; + phy_set_speed(); } else if (cmd_compare(2, "off")) { print_string(" OFF\n"); - phy_set_speed(p, PHY_OFF, PHY_DUPLEX_BOTH); + phy_settings.speed = PHY_OFF; + phy_set_speed(); } else if (cmd_compare(2, "on")) { print_string(" ON\n"); - phy_set_speed(p, PHY_SPEED_AUTO, PHY_DUPLEX_BOTH); + phy_settings.speed = PHY_SPEED_AUTO; + phy_set_speed(); } else if (cmd_compare(2, "duplex")) { print_string(" DUPLEX\n"); if (cmd_words_b[3] > 0 && cmd_compare(3, "full")) - phy_set_duplex(p, PHY_DUPLEX_FULL); + phy_settings.speed = PHY_DUPLEX_FULL; else - phy_set_duplex(p, PHY_DUPLEX_HALF); + phy_settings.speed = PHY_DUPLEX_HALF; + phy_set_duplex(); } if (cmd_words_b[2] > 0 && cmd_compare(2, "show")) { - phy_show(p); + phy_show(phy_settings.port); } } From d83f91f9e8a992d081c936f65ad95c822ed46a1b Mon Sep 17 00:00:00 2001 From: logicog Date: Sat, 7 Feb 2026 16:24:58 +0100 Subject: [PATCH 5/6] Fix Auto-negotiation Commit 7f4c276 used the wrong MMD device for use with the auto-negotiation page: - phy_write(port, PHY_MMD_AN, 0x00, 0x3200); // Restart AN + phy_write(port, PHY_MMD31, PHY_ANEG_CTRL, 0x3200); // Restart AN Fix this. --- rtl837x_phy.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/rtl837x_phy.c b/rtl837x_phy.c index 306057d..b4e944a 100644 --- a/rtl837x_phy.c +++ b/rtl837x_phy.c @@ -210,10 +210,10 @@ void phy_set_speed(void) __banked phy_write(phy_settings.port, PHY_MMD_AN, PHY_ANEG_MGBASE_CTRL, 0x6081); // GBCR (1000Base-T Control Register, MMD 31.0xA412) phy_modify(phy_settings.port, PHY_MMD31, PHY_MMD31_GBCR, 0x0000, 0x0200); // Loop timing enabled - phy_write(phy_settings.port, PHY_MMD31, PHY_ANEG_CTRL, 0x3200); // Restart AN + phy_write(phy_settings.port, PHY_MMD_AN, PHY_ANEG_CTRL, 0x3200); // Restart AN } else { // AN Control Register (MMD 7.0x0000) - phy_write(phy_settings.port, PHY_MMD31, PHY_ANEG_CTRL, 0x2000); // Clear bit 12: No Autoneg, Set Extended Pages (bit 13) + phy_write(phy_settings.port, PHY_MMD_AN, PHY_ANEG_CTRL, 0x2000); // Clear bit 12: No Autoneg, Set Extended Pages (bit 13) if (phy_settings.speed == PHY_SPEED_10M) { phy_write(phy_settings.port, PHY_MMD_AN, PHY_ANEG_MGBASE_CTRL, 0x6001); if (!phy_settings.duplex) @@ -250,7 +250,7 @@ void phy_set_speed(void) __banked phy_modify(phy_settings.port, PHY_MMD31, PHY_MMD31_GBCR, 0x0200, 0x0000); } } - phy_write(phy_settings.port, PHY_MMD31, PHY_ANEG_CTRL, 0x3000); // Enable AN + phy_write(phy_settings.port, PHY_MMD_AN, PHY_ANEG_CTRL, 0x3000); // Enable AN } } @@ -258,7 +258,7 @@ void phy_set_speed(void) __banked void phy_set_duplex(void) __banked { uint16_t v; - phy_read(phy_settings.port, PHY_MMD31, PHY_ANEG_CTRL); + phy_read(phy_settings.port, PHY_MMD_AN, PHY_ANEG_CTRL); v = SFR_DATA_U16; if (!(v & 0x1000)) { // AN disabled, we are in forced mode phy_read(phy_settings.port, PHY_MMD31, PHY_MMD31_FEDCR); @@ -271,7 +271,7 @@ void phy_set_duplex(void) __banked return; } // Disable AN - phy_write(phy_settings.port, PHY_MMD31, PHY_ANEG_CTRL, 0x2000); + phy_write(phy_settings.port, PHY_MMD_AN, PHY_ANEG_CTRL, 0x2000); phy_read(phy_settings.port, PHY_MMD_AN, PHY_ANEG_ADV); v = SFR_DATA_U16; if (v & 0x0060) { @@ -287,7 +287,7 @@ void phy_set_duplex(void) __banked phy_modify(phy_settings.port, PHY_MMD_AN, PHY_ANEG_ADV, 0xff7f, 0x0080); } // Restart AN - phy_write(phy_settings.port, PHY_MMD31, PHY_ANEG_CTRL, 0x3000); + phy_write(phy_settings.port, PHY_MMD_AN, PHY_ANEG_CTRL, 0x3000); } @@ -329,7 +329,7 @@ void phy_show(uint8_t port) __banked else print_string(" half duplex"); - phy_read(port, PHY_MMD31, PHY_ANEG_CTRL); + phy_read(port, PHY_MMD_AN, PHY_ANEG_CTRL); v = SFR_DATA_U16; if (!(v & 0x1000)) { // AN disabled, we are in forced mode phy_read(port, PHY_MMD_PMAPMD, 0); From 47878ac580262b9bf8e20338ef9d02fc7caf8e1f Mon Sep 17 00:00:00 2001 From: logicog Date: Sat, 7 Feb 2026 16:30:21 +0100 Subject: [PATCH 6/6] Add more printout --- rtl837x_phy.c | 45 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/rtl837x_phy.c b/rtl837x_phy.c index b4e944a..0846e9c 100644 --- a/rtl837x_phy.c +++ b/rtl837x_phy.c @@ -191,6 +191,43 @@ void phy_config_8224(void) __banked void phy_set_speed(void) __banked { uint16_t v; + + print_string("Setting port "); write_char(machine.log_to_phys_port[phy_settings.port] + '0'); + if (phy_settings.speed == PHY_OFF) { + print_string(" to disabled"); + } else { + print_string(" to speed "); + switch(phy_settings.speed) { + case PHY_SPEED_AUTO: + print_string("auto"); + break; + case PHY_SPEED_10M: + print_string("10M"); + if (phy_settings.duplex) + print_string(" full duplex"); + else + print_string(" half duplex"); + break; + case PHY_SPEED_100M: + print_string("100M"); + if (phy_settings.duplex) + print_string(" full duplex"); + else + print_string(" half duplex"); + break; + case PHY_SPEED_1G: + print_string("1G"); + break; + case PHY_SPEED_2G5: + print_string("2G5"); + break; + default: + print_string("UNKNOWN"); + break; + } + } + write_char('\n'); + phy_read(phy_settings.port, PHY_MMD31, 0xa610); v = SFR_DATA_U16; if (phy_settings.speed == PHY_OFF) { @@ -258,6 +295,14 @@ void phy_set_speed(void) __banked void phy_set_duplex(void) __banked { uint16_t v; + + print_string("Setting port "); write_char(machine.log_to_phys_port[phy_settings.port] + '0'); + if (phy_settings.duplex) + print_string(" to full duplex"); + else + print_string(" to half duplex"); + write_char('\n'); + phy_read(phy_settings.port, PHY_MMD_AN, PHY_ANEG_CTRL); v = SFR_DATA_U16; if (!(v & 0x1000)) { // AN disabled, we are in forced mode