diff --git a/cmd_parser.c b/cmd_parser.c index 8097c2a..2dcdb87 100644 --- a/cmd_parser.c +++ b/cmd_parser.c @@ -633,6 +633,64 @@ void parse_passwd(void) } +void parse_eee(void) +{ + __xdata int8_t port = -1; + __xdata uint8_t speed = EEE_2G5; + __xdata uint8_t speed_word = 0; + // Check if word 2 is a speed (contains 'g' or 'm') or a port number + if (cmd_words_b[3] > 0) { + uint8_t idx = cmd_words_b[2]; + // Skip digits to check if there's a letter after + while (isnumber(cmd_buffer[idx])) + idx++; + if (cmd_buffer[idx] == 'g' || cmd_buffer[idx] == 'm') { + // Word 2 is a speed (e.g., "2g5", "100m", "1g") + speed_word = 2; + } else if (cmd_buffer[idx] == ' ' || cmd_buffer[idx] == '\0') { + // Word 2 is a port number + port = cmd_buffer[cmd_words_b[2]] - '1'; + port = machine.phys_to_log_port[port]; + // Check if word 3 is a speed + if (cmd_words_b[4] > 0) + speed_word = 3; + } + } + // Parse speed if found + if (speed_word > 0) { + if (cmd_compare(speed_word, "100m")) + speed = EEE_100; + else if (cmd_compare(speed_word, "1g")) + speed = EEE_1000; + else if (cmd_compare(speed_word, "2g5")) + speed = EEE_2G5; + else + { + print_string("Speed word invalid, use: [100m|1g|2g5]\n"); + return; + } + } + if (cmd_words_b[1] > 0 && cmd_compare(1, "on")) { + if (port >= 0) + port_eee_enable(port, speed); + else + port_eee_enable_all(speed); + } else if (cmd_words_b[1] > 0 && cmd_compare(1, "off")) { + if (port >= 0) + port_eee_disable(port); + else + port_eee_disable_all(); + } else if (cmd_words_b[1] > 0 && cmd_compare(1, "status")) { + if (port >= 0) + port_eee_status(port); + else + port_eee_status_all(); + } else { + print_string("eee [on|off|status] [port] [100m|1g|2g5]\n"); + } +} + + // Parse command into words uint8_t cmd_tokenize(void) __banked { @@ -895,27 +953,7 @@ void cmd_parser(void) __banked } else if (cmd_compare(0, "passwd")) { parse_passwd(); } else if (cmd_compare(0, "eee")) { - int8_t port = -1; - if (cmd_words_b[3] > 0) { - port = cmd_buffer[cmd_words_b[2]] - '1'; - port = machine.phys_to_log_port[port]; - } - if (cmd_words_b[1] > 0 && cmd_compare(1, "on")) { - if (port >= 0) - port_eee_enable(port); - else - port_eee_enable_all(); - } else if (cmd_words_b[1] > 0 && cmd_compare(1, "off")) { - if (port >= 0) - port_eee_disable(port); - else - port_eee_disable_all(); - } else if (cmd_words_b[1] > 0 && cmd_compare(1, "status")) { - if (port >= 0) - port_eee_status(port); - else - port_eee_status_all(); - } + parse_eee(); } else if (cmd_compare(0, "version")) { print_sw_version(); } else if (cmd_compare(0, "time")) { diff --git a/doc/devices/TEG-S562.md b/doc/devices/TEG-S562.md new file mode 100644 index 0000000..5122f4e --- /dev/null +++ b/doc/devices/TEG-S562.md @@ -0,0 +1,175 @@ +# TrendNet TEG-S562 + +Following is documentation for unmanaged switch marked as `TEG-S563/EU H/W: V1.0R`. + +Original software is running UART on 57600 baud rate. The software does not allow to +do anything fancy via serial. There is `IP` configuration which can be printed as well. +There might be also some flash upload procedure, but using SPI clamp in-board seems to +be easier method. + +The memory chip is `Winbond W25Q16JV` with 16M-bit size. + +## What does work + +1. 2.5G ports on all advertised speeds. +2. SFP+ communication. +3. Serial, Web UI. + +## Known issues + +1. LEDs are not initialized properly. + +## PCB + +Manufacturer information be found [on the product page](https://www.trendnet.com/support/support-detail.asp?prod=105_TEG-S562). + +Top side + + + +Bottom + + + +## Connectors + +### Port overview + +``` +┌─────────────────────────────────────────────────────────────────────────────┐ +│ ┌──────────┐ ┌──────────┐ │ +│ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ │ SFP │ │ SFP │ │ +│ │ RJ45 │ │ RJ45 │ │ RJ45 │ │ RJ45 │ │ PORT 5 │ │ PORT 6 │ │ +│ │ PORT 1 │ │ PORT 2 │ │ PORT 3 │ │ PORT 4 │ │ MAC ? │ │ MAC ? │ │ +│ │ MAC 4 │ │ MAC 5 │ │ MAC 6 │ │ MAC 7 │ │ SerDes ? │ │ SerDes ? │ │ +│ └─────────┘ └─────────┘ └─────────┘ └─────────┘ └──────────┘ └──────────┘ │ +└─────────────────────────────────────────────────────────────────────────────┘ +``` + +### J2, serial console + +| `J2` pin | Signal | +| -------- | ----------- | +| 1 | 3V3 | +| 2 | TX (Output) | +| 3 | RX (Input) | +| 4 | GND | + +Note: 1 pin is square shaped, towards the power input. + +### J5, power pass-thru + +| `J5` pin | Signal | +| -------- | ------ | +| 1 | 12V | +| 2 | 12V | +| 3 | GND | +| 4 | GND | + +Note: 1 pin is square shaped. + +### U5, I2C eeprom placeholder + +| `J5` pin | Signal | +| -------- | ------------- | +| 1 | GND | +| 2 | GND | +| 3 | GND | +| 4 | GND | +| 5 | 3V3 | +| 6 | ??? Logic Low | +| 7 | SCL | +| 8 | SDA | + +SOC I2C address is 0x5c. + +### SW1 GPIO switch? + +Not populated but looks like a switch for selecting +GPIO level. Missing resistors in place. + +GPIO mapping unknown. + +### S2 Reset ciruit + +Not populated but looks like a button can be added on `S2` connector, +requires additional `R571` resistor which will pull signal to ground. + +GPIO mapping unknown. + +### GPIO + +| HEX VAL. | GPIO | When | GPIO | When | +| -------- | ------ | ----------------| ------ | -----------------------| +| 00000001 | GPIO00 | | GPIO32 | | +| 00000002 | GPIO01 | | GPIO33 | | +| 00000004 | GPIO02 | | GPIO34 | Random changes | +| 00000008 | GPIO03 | | GPIO35 | | +| 00000010 | GPIO04 | | GPIO36 | SFP1 Present | +| 00000020 | GPIO05 | | GPIO37 | SFP1 RX Los | +| 00000040 | GPIO06 | | GPIO38 | SFP2 Present | +| 00000080 | GPIO07 | | GPIO39 | | +| 00000100 | GPIO08 | | GPIO40 | | +| 00000200 | GPIO09 | | GPIO41 | | +| 00000400 | GPIO10 | | GPIO42 | Random changes | +| 00000800 | GPIO11 | | GPIO43 | | +| 00001000 | GPIO12 | PORT1 Link | GPIO44 | | +| 00002000 | GPIO13 | PORT1-LED-GREEN | GPIO45 | | +| 00004000 | GPIO14 | PORT1-LED-AMBER | GPIO46 | SFP1 I2C CLK | +| 00008000 | GPIO15 | PORT2 Link | GPIO47 | SFP1 I2C SDA | +| 00010000 | GPIO16 | PORT2-LED-GREEN | GPIO48 | SFP2 I2C CLK | +| 00020000 | GPIO17 | PORT2-LED-AMBER | GPIO49 | SFP2 I2C SDA | +| 00040000 | GPIO18 | PORT3 Link | GPIO50 | SFP2 Rx LOS | +| 00080000 | GPIO19 | PORT3-LED-GREEN | GPIO51 | SFP1 TX Disable | +| 00100000 | GPIO20 | PORT4-LED-AMBER | GPIO52 | | +| 00200000 | GPIO21 | PORT4 Link | GPIO53 | | +| 00400000 | GPIO22 | PORT4-LED-GREEN | GPIO54 | SFP2 TX Disable | +| 00800000 | GPIO23 | PORT4-LED-AMBER | GPIO55 | | +| 01000000 | GPIO24 | | GPIO56 | | +| 02000000 | GPIO25 | | GPIO57 | | +| 04000000 | GPIO26 | | GPIO58 | | +| 08000000 | GPIO27 | | GPIO59 | | +| 10000000 | GPIO28 | | GPIO60 | | +| 20000000 | GPIO29 | | GPIO61 | | +| 40000000 | GPIO30 | | GPIO62 | | +| 80000000 | GPIO31 | | GPIO63 | | + +## LEDs + +Leds are not yet working as in stock firmware. This will be handled later. + +Ports 1-4 are amber for 100M/1G links, Green for 2.5G. +Port 5-6 are green for 10G/1G link. Both should flash on activity. + +| NAME | When active | +| ---------------- | ---------------| +| PWR | 3V3 | +| SFP1 | | +| SFP2 | | +| PORT1-LED-GREEN | - | +| PORT2-LED-GREEN | PORT2 2.5G | +| PORT3-LED-GREEN | PORT3 2.5G | +| PORT4-LED-GREEN | PORT4 2.5G | +| PORT1-LED-AMBER | PORT1 1GB/100M | +| PORT2-LED-AMBER | PORT2 1GB/100M | +| PORT3-LED-AMBER | PORT3 1GB/100M | +| PORT4-LED-AMBER | PORT4 1GB/100M | + +## Power supply + +Input power is delivered via barell plug, `12V 1A` adapter was provided. +Board has two supply rails. `0.95` and `3.3` volt. + +### `0.95` Core Voltage + +Voltage is made by a `APW8713` (U3). + +### `3.3` Voltage + +Voltage is crated regulated by chip marke as `GoIAT` (U2). + +## SFP SPI + +There is separate clock and data lines for both SFP modules. MSDA/MSCK 0 and 1 need to be enabled. + +SFP1 slot is connected to SPI0. SFP2 slot is connected to SPI1. diff --git a/doc/devices/photos/TEG-S562/TEG-S562-v1.0R-bottom.jpg b/doc/devices/photos/TEG-S562/TEG-S562-v1.0R-bottom.jpg new file mode 100644 index 0000000..e38d515 Binary files /dev/null and b/doc/devices/photos/TEG-S562/TEG-S562-v1.0R-bottom.jpg differ diff --git a/doc/devices/photos/TEG-S562/TEG-S562-v1.0R-top.jpg b/doc/devices/photos/TEG-S562/TEG-S562-v1.0R-top.jpg new file mode 100644 index 0000000..e630fcb Binary files /dev/null and b/doc/devices/photos/TEG-S562/TEG-S562-v1.0R-top.jpg differ diff --git a/doc/supported_devices.md b/doc/supported_devices.md index d1e66ed..3170160 100644 --- a/doc/supported_devices.md +++ b/doc/supported_devices.md @@ -8,6 +8,7 @@ The following devices have been tested and are fully working: - Lianguo LG-SWTGW218AS (RTL8373 + RTL8224 PHY: 8x 2.5GBit + 1x 10GBit SFP+) - No-Name ZX-SWTGW215AS, managed version of kp-9000-6hx-x, ordered on AliExpress as keepLINK 5+1 port managed +- TrendNet TEG-S562 (RTL8372: 4x 2.5GBit + 2x 10GBit SFP+) Other device based on RTL8272/3 that may work are described here: [Up-N-Atoms 2.5 GBit RTL Switch hacking guide] (https://github.com/up-n-atom/SWTG118AS) diff --git a/machine.c b/machine.c index 84f1d2c..59bf438 100644 --- a/machine.c +++ b/machine.c @@ -100,4 +100,26 @@ __code const struct machine machine = { .sfp_port[0].i2c = { .sda = GPIO39_I2C_SDA4, .scl = GPIO40_I2C_SCL3_MDC1 }, .reset_pin = GPIO_NA, }; +#elif defined MACHINE_TRENDNET_TEG_S562 +__code const struct machine machine = { + .machine_name = "Trendnet TEG-S562", + .isRTL8373 = 0, + .min_port = 3, + .max_port = 8, + .n_sfp = 2, + .log_to_phys_port = {0, 0, 0, 6, 1, 2, 3, 4, 5}, + .phys_to_log_port = {4, 5, 6, 7, 3, 8, 0, 0, 0}, + .is_sfp = {0, 0, 0, 2, 0, 0, 0, 0, 1}, + .sfp_port[0].pin_detect = GPIO36_PWM_OUT, + .sfp_port[0].pin_los = GPIO37, + .sfp_port[0].pin_tx_disable = GPIO51_I2C_SDA2_UART1_RX, + .sfp_port[0].sds = 0, + .sfp_port[0].i2c = { .sda = GPIO47_I2C_SDA0, .scl = GPIO46_I2C_SCL0 }, + .sfp_port[1].pin_detect = GPIO38, + .sfp_port[1].pin_los = GPIO50_I2C_SCL2_UART1_TX, + .sfp_port[1].pin_tx_disable = GPIO54_ACL_BIT2_EN, + .sfp_port[1].sds = 1, + .sfp_port[1].i2c = { .sda = GPIO49_I2C_SDA1, .scl = GPIO48_I2C_SCL1 }, + .reset_pin = GPIO_NA, +}; #endif diff --git a/machine.h b/machine.h index b1051b3..24de207 100644 --- a/machine.h +++ b/machine.h @@ -11,6 +11,7 @@ // #define MACHINE_KP_9000_9XH_X_EU // #define MACHINE_SWGT024_V2_0 // #define MACHINE_HORACO_ZX_SG4T2 +// #define MACHINE_TRENDNET_TEG_S562 // #define DEFAULT_8C_1SFP diff --git a/rtl837x_port.c b/rtl837x_port.c index dbd1715..448431f 100644 --- a/rtl837x_port.c +++ b/rtl837x_port.c @@ -422,17 +422,49 @@ uint16_t port_isolation_get(register uint8_t port) } -void port_eee_enable(uint8_t port) __banked +void port_eee_enable(__xdata uint8_t port,__xdata uint8_t speed) __banked { - if (machine.is_sfp[port]) - return; - REG_SET(RTL8373_EEE_CTRL_BASE + (port << 2), EEE_100 | EEE_1000 | EEE_2G5); - // Enable EEE advertisement for 100/1000BASE-T via EEE Advertisement Reg - phy_write(port, PHY_MMD_AN, PHY_EEE_ADV, PHY_EEE_BIT_1G | PHY_EEE_BIT_100M); - // Enable EEE advertisement for 2.5GBASE-T via EEE Advertisement Reg 2 - phy_write(port, PHY_MMD_AN, PHY_EEE_ADV2, PHY_EEE_BIT_2G5); - phy_reset(port); + if (machine.is_sfp[port]) + { + print_string("EEE can't be enabled for SFP port "); print_byte(port); print_string("\n"); + return; + } + + print_string("EEE on for "); print_byte(port); print_string(" speed "); + // Enable all speeds up to the specified speed + if ((speed & (EEE_100 | EEE_1000 | EEE_2G5)) == EEE_100) { + print_string("100m\n"); + REG_SET(RTL8373_EEE_CTRL_BASE + (port << 2), EEE_100); + // Enable EEE advertisement for 100BASE-T via EEE Advertisement Reg + phy_write(port, PHY_MMD_AN, PHY_EEE_ADV, PHY_EEE_BIT_100M); + if (!(speed & EEE_NORESET)) + phy_reset(port); + return; + } + if ((speed & (EEE_100 | EEE_1000 | EEE_2G5)) == EEE_1000) { + print_string("1g\n"); + REG_SET(RTL8373_EEE_CTRL_BASE + (port << 2), EEE_100 | EEE_1000); + // Disable EEE advertisement for 2.5GBASE-T via EEE Advertisement Reg 2 + phy_write(port, PHY_MMD_AN, PHY_EEE_ADV2, 0); + // Enable EEE advertisement for 100/1000BASE-T via EEE Advertisement Reg + phy_write(port, PHY_MMD_AN, PHY_EEE_ADV, PHY_EEE_BIT_1G | PHY_EEE_BIT_100M); + if (!(speed & EEE_NORESET)) + phy_reset(port); + return; + } + if ((speed & (EEE_100 | EEE_1000 | EEE_2G5)) == EEE_2G5) { + print_string("2g5\n"); + REG_SET(RTL8373_EEE_CTRL_BASE + (port << 2), EEE_100 | EEE_1000 | EEE_2G5); + // Enable EEE advertisement for 100/1000BASE-T via EEE Advertisement Reg + phy_write(port, PHY_MMD_AN, PHY_EEE_ADV, PHY_EEE_BIT_1G | PHY_EEE_BIT_100M); + // Enable EEE advertisement for 2.5GBASE-T via EEE Advertisement Reg 2 + phy_write(port, PHY_MMD_AN, PHY_EEE_ADV2, PHY_EEE_BIT_2G5); + if (!(speed & EEE_NORESET)) + phy_reset(port); + return; + } + } @@ -506,10 +538,10 @@ void port_eee_status(uint8_t port) __banked } -void port_eee_enable_all(void) __banked +void port_eee_enable_all(__xdata uint8_t speed) __banked { for (uint8_t i = machine.min_port; i <= machine.max_port; i++) { - port_eee_enable(i); + port_eee_enable(i, speed); } } diff --git a/rtl837x_port.h b/rtl837x_port.h index 22ea1dd..9049082 100644 --- a/rtl837x_port.h +++ b/rtl837x_port.h @@ -28,10 +28,10 @@ void port_ingress_filter(register uint8_t port, 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; -void port_eee_enable_all(void) __banked; +void port_eee_enable_all(__xdata uint8_t speed) __banked; void port_eee_disable_all(void) __banked; void port_eee_status_all(void) __banked; -void port_eee_enable(uint8_t port) __banked; +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; #endif diff --git a/rtl837x_regs.h b/rtl837x_regs.h index cd7a2eb..fcb2928 100644 --- a/rtl837x_regs.h +++ b/rtl837x_regs.h @@ -257,6 +257,7 @@ #define EEE_100 0x01 #define EEE_1000 0x04 #define EEE_2G5 0x10 +#define EEE_NORESET 0x80 /* * RANDOM diff --git a/rtlplayground.c b/rtlplayground.c index ad0aa8c..cd468dc 100644 --- a/rtlplayground.c +++ b/rtlplayground.c @@ -1637,6 +1637,9 @@ void rtl8373_init(void) reg_bit_set(RTL837X_REG_HW_CONF, 0); + // enable EEE for all ports at 2.5G and 10G, but don't reset the PHYs + port_eee_enable_all(EEE_2G5 | EEE_NORESET); + // TODO: patch the PHYs // Re-enable PHY after configuration @@ -1700,6 +1703,10 @@ void rtl8372_init(void) reg_bit_set(RTL837X_REG_HW_CONF, 0); + + // enable EEE for all ports at 2.5G and 10G, but don't reset the PHYs + port_eee_enable_all(EEE_2G5 | EEE_NORESET); + // TODO: patch the PHYs // Re-enable PHY after configuration @@ -1954,6 +1961,8 @@ void bootloader(void) REG_SET(RTL837X_PIN_MUX_2, 0x0); // Disable pins for ACL init_smi(); + + rtl8373_revision(); if (machine_detected.isRTL8373) rtl8373_init();