realtek: add support for TP-Link SG2452P v4 aka T1600G-52PS v4
authorAndreas Böhler <dev@aboehler.at>
Fri, 26 Aug 2022 09:21:40 +0000 (11:21 +0200)
committerSander Vanheule <sander@svanheule.net>
Sat, 10 Sep 2022 20:13:52 +0000 (22:13 +0200)
This is an RTL8393-based switch with 802.3af on all 48 ports.

Specifications:
---------------
 * SoC:       Realtek RTL8393M
 * Flash:     32 MiB SPI flash
 * RAM:       256 MiB
 * Ethernet:  48x 10/100/1000 Mbps with PoE+
 * Buttons:   1x "Reset" button, 1x "Speed" button
 * UART:      1x serial header, unpopulated
 * PoE:       12x TI TPS23861 I2C PoE controller, 384W PoE budget
 * SFP:       4 SFP ports

Works:
------
  - (48) RJ-45 ethernet ports
  - Switch functions
  - Buttons
  - All LEDs on front panel except port LEDs
  - Fan monitoring and basic control

Not yet enabled:
----------------
  - PoE - ICs are not in AUTO mode, so the kernel driver is not usable
  - Port LEDs
  - SFP cages

Install via web interface:
-------------------------

Not supported at this time.

Install via serial console/tftp:
--------------------------------

The U-Boot firmware drops to a TP-Link specific "BOOTUTIL" shell at
38400 baud. There is no known way to exit out of this shell, and no
way to do anything useful.

Ideally, one would trick the bootloader into flashing the sysupgrade
image first. However, if the image exceeds 6MiB in size, it will not
work. To install OpenWRT:

Prepare a tftp server with:
 1. server address: 192.168.0.146
 2. the image as: "uImage.img"

Power on device, and stop boot by pressing any key.
Once the shell is active:
 1. Ground out the CLK (pin 16) of the ROM (U6)
 2. Select option "3. Start"
 3. Bootloader notes that "The kernel has been damaged!"
 4. Release CLK as soon as bootloader thinks image is corrupted.
 5. Bootloader enters automatic recovery -- details printed on console
 6. Watch as the bootloader flashes and boots OpenWRT.

Blind install via tftp:
-----------------------

This method works when it's not feasible to install a serial header.

Prepare a tftp server with:
 1. server address: 192.168.0.146
 2. the image as: "uImage.img"
 3. Watch network traffic (tcpdump or wireshark works)
 4. Power on the device.
 5. Wait 1-2 seconds then ground out the CLK (pin 16) of the ROM (U6)
 6. When 192.168.0.30 makes tftp requests, release pin 16
 7. Wait 2-3 minutes for device to auto-flash and boot OpenWRT

Signed-off-by: Andreas Böhler <dev@aboehler.at>
package/boot/uboot-envtools/files/realtek
target/linux/realtek/base-files/etc/board.d/02_network
target/linux/realtek/dts-5.10/rtl8393_tplink_sg2452p-v4.dts [new file with mode: 0644]
target/linux/realtek/dts-5.10/rtl839x.dtsi
target/linux/realtek/image/rtl839x.mk

index e1eb1a6ac66868e3825fe33d359a56f5f6d13998..22568afd125e9ee3a97d7ed7e4540077d93585d2 100644 (file)
@@ -29,7 +29,8 @@ zyxel,gs1900-24hp-v2)
        [ -n "$idx2" ] && \
                ubootenv_add_uci_sys_config "/dev/mtd$idx2" "0x0" "0x1000" "0x10000"
        ;;
-tplink,sg2008p-v1)
+tplink,sg2008p-v1|\
+tplink,sg2452p-v4)
        idx="$(find_mtd_index u-boot-env)"
        [ -n "$idx" ] && \
                ubootenv_add_uci_config "/dev/mtd$idx" "0x0" "0x20000" "0x10000"
index d797960faffd7ccaa63d6d199d5ed58f977a90a2..6e0e0e7e03422be38130149246d485f9fef77180 100644 (file)
@@ -39,7 +39,8 @@ hpe,1920-24g)
        lan_mac_start=$(macaddr_add $lan_mac 2)
        lan_mac_end=$(macaddr_add $lan_mac $((mac_count2-mac_count1)))
        ;;
-tplink,sg2008p-v1)
+tplink,sg2008p-v1|\
+tplink,sg2452p-v4)
        label_mac=$(mtd_get_mac_binary para 0xfdff4)
        lan_mac="$label_mac"
        ;;
diff --git a/target/linux/realtek/dts-5.10/rtl8393_tplink_sg2452p-v4.dts b/target/linux/realtek/dts-5.10/rtl8393_tplink_sg2452p-v4.dts
new file mode 100644 (file)
index 0000000..0649c9f
--- /dev/null
@@ -0,0 +1,411 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "rtl839x.dtsi"
+
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/leds/common.h>
+
+/ {
+       compatible = "tplink,sg2452p-v4", "realtek,rtl8393-soc";
+       model = "TP-Link SG2452P v4";
+
+       memory@0 {
+               device_type = "memory";
+               reg = <0x0 0x10000000>;
+       };
+
+       aliases {
+               led-boot = &led_sys;
+               led-failsafe = &led_sys;
+               led-running = &led_sys;
+               led-upgrade = &led_sys;
+       };
+
+       chosen {
+               bootargs = "console=ttyS0,38400";
+       };
+
+       keys {
+               compatible = "gpio-keys";
+
+               reset {
+                       label = "reset";
+                       gpios = <&gpio0 20 GPIO_ACTIVE_LOW>;
+                       linux,code = <KEY_RESTART>;
+               };
+
+               speed {
+                       label = "speed";
+                       gpios = <&gpio0 19 GPIO_ACTIVE_LOW>;
+                       linux,code = <BTN_0>;
+               };
+       };
+
+       gpio_fan_sys {
+               compatible = "gpio-fan";
+               alarm-gpios = <&gpio0 12 GPIO_ACTIVE_LOW>;
+       };
+
+       gpio_fan_psu_1 {
+               pinctrl-names = "default";
+               pinctrl-0 = <&disable_jtag>;
+               compatible = "gpio-fan";
+
+               alarm-gpios = <&gpio0 7 GPIO_ACTIVE_LOW>;
+               gpios = <&gpio0 4 GPIO_ACTIVE_LOW>;
+               /* the actual speeds (rpm) are unknown, just use dummy values */
+               gpio-fan,speed-map = <1 0>, <2 1>;
+               #cooling-cells = <2>;
+       };
+
+       gpio_fan_psu_2 {
+               /* This fan runs in parallel to PSU1 fan, but has a separate
+                * alarm GPIO. This is not (yet) supported by the gpio-fan driver,
+                * so a separate instance is added
+                */
+               compatible = "gpio-fan";
+               alarm-gpios = <&gpio0 14 GPIO_ACTIVE_LOW>;
+       };
+
+       leds {
+               pinctrl-names = "default";
+               compatible = "gpio-leds";
+
+               led-0 {
+                       label = "green:speed";
+                       gpios = <&gpio0 8 GPIO_ACTIVE_HIGH>;
+                       color = <LED_COLOR_ID_GREEN>;
+                       function = LED_FUNCTION_INDICATOR;
+               };
+
+               led-1 {
+                       label = "green:poe";
+                       gpios = <&gpio0 9 GPIO_ACTIVE_HIGH>;
+                       color = <LED_COLOR_ID_GREEN>;
+                       function = LED_FUNCTION_INDICATOR;
+               };
+
+               led_sys: led-2 {
+                       label = "green:sys";
+                       gpios = <&gpio0 13 GPIO_ACTIVE_HIGH>;
+                       color = <LED_COLOR_ID_GREEN>;
+                       function = LED_FUNCTION_STATUS;
+               };
+
+               led-3 {
+                       label = "green:fan";
+                       gpios = <&gpio0 15 GPIO_ACTIVE_HIGH>;
+                       color = <LED_COLOR_ID_GREEN>;
+                       function = LED_FUNCTION_STATUS;
+               };
+
+               led-4 {
+                       label = "amber:fan";
+                       gpios = <&gpio0 16 GPIO_ACTIVE_HIGH>;
+                       color = <LED_COLOR_ID_AMBER>;
+                       function = "fault-fan";
+               };
+
+               led-5 {
+                       label = "green:poe-max";
+                       gpios = <&gpio0 18 GPIO_ACTIVE_HIGH>;
+                       color = <LED_COLOR_ID_GREEN>;
+                       function = "alarm-poe";
+               };
+       };
+
+       i2c-gpio-0 {
+               compatible = "i2c-gpio";
+               sda-gpios = <&gpio0 2 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+               scl-gpios = <&gpio0 1 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+               i2c-gpio,delay-us = <2>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               /* LAN9 - LAN12 */
+               tps23861@5 {
+                       compatible = "ti,tps23861";
+                       reg = <0x05>;
+               };
+
+               /* LAN17 - LAN20 */
+               tps23861@6 {
+                       compatible = "ti,tps23861";
+                       reg = <0x06>;
+               };
+
+               /* LAN45 - LAN48 */
+               tps23861@9 {
+                       compatible = "ti,tps23861";
+                       reg = <0x09>;
+               };
+
+               /* LAN37 - LAN40 */
+               tps23861@a {
+                       compatible = "ti,tps23861";
+                       reg = <0x0a>;
+               };
+
+               /* LAN1 - LAN4 */
+               tps23861@14 {
+                       compatible = "ti,tps23861";
+                       reg = <0x14>;
+               };
+
+               /* LAN25 - LAN28 */
+               tps23861@24 {
+                       compatible = "ti,tps23861";
+                       reg = <0x24>;
+               };
+
+               /* LAN33 - LAN 36 */
+               tps23861@25 {
+                       compatible = "ti,tps23861";
+                       reg = <0x25>;
+               };
+
+               /* LAN41 - LAN44 */
+               tps23861@26 {
+                       compatible = "ti,tps23861";
+                       reg = <0x26>;
+               };
+
+               /* LAN13 - LAN16 */
+               tps23861@29 {
+                       compatible = "ti,tps23861";
+                       reg = <0x29>;
+               };
+
+               /* LAN29 - LAN32 */
+               tps23861@2c {
+                       compatible = "ti,tps23861";
+                       reg = <0x2c>;
+               };
+
+               /* LAN5 - LAN8 */
+               tps23861@48 {
+                       compatible = "ti,tps23861";
+                       reg = <0x48>;
+               };
+
+               /* LAN21 - LAN24 */
+               tps23861@49 {
+                       compatible = "ti,tps23861";
+                       reg = <0x49>;
+               };
+       };
+
+       gpio-restart {
+               compatible = "gpio-restart";
+               gpios = <&gpio0 17 GPIO_ACTIVE_LOW>;
+       };
+};
+
+&gpio0 {
+       poe-enable {
+               gpio-hog;
+               gpios = <23 GPIO_ACTIVE_HIGH>;
+               output-high;
+               line-name = "poe-enable";
+       };
+};
+
+&spi0 {
+       status = "okay";
+       flash@0 {
+               compatible = "jedec,spi-nor";
+               reg = <0>;
+               spi-max-frequency = <10000000>;
+
+               partitions {
+                       compatible = "fixed-partitions";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+
+                       partition@0 {
+                               label = "u-boot";
+                               reg = <0x0 0xe0000>;
+                               read-only;
+                       };
+                       partition@e0000 {
+                               label = "u-boot-env";
+                               reg = <0xe0000 0x20000>;
+                       };
+
+                       /* We use the "sys", "usrimg1" and "usrimg2" partitions
+                        *  as firmware since the kernel needs to be in "sys", but the
+                        *  partition is too small to hold the "rootfs" as well.
+                        *  The original partition map contains:
+                        *
+                        *   partition@100000 {
+                        *       label = "sys";
+                        *       reg = <0x100000 0x600000>;
+                        *   };
+                        *   partition@700000 {
+                        *       label = "usrimg1";
+                        *       reg = <0x700000 0xa00000>;
+                        *   };
+                        *   partition@1100000 {
+                        *       label = "usrimg2";
+                        *       reg = <0x1100000 0xa00000>;
+                        *   };
+                        */
+
+                       partition@100000 {
+                               label = "firmware";
+                               reg = <0x100000 0x1a00000>;
+                       };
+                       partition@1b00000 {
+                               label = "usrappfs";
+                               reg = <0x1b00000 0x400000>;
+                       };
+                       partition@1f00000 {
+                               label = "para";
+                               reg = <0x1f00000 0x100000>;
+                               read-only;
+                       };
+               };
+       };
+};
+
+&ethernet0 {
+       mdio: mdio-bus {
+               compatible = "realtek,rtl838x-mdio";
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               /* External phy RTL8218B #1 */
+               EXTERNAL_PHY(0)
+               EXTERNAL_PHY(1)
+               EXTERNAL_PHY(2)
+               EXTERNAL_PHY(3)
+               EXTERNAL_PHY(4)
+               EXTERNAL_PHY(5)
+               EXTERNAL_PHY(6)
+               EXTERNAL_PHY(7)
+
+               /* External phy RTL8218B #2 */
+               EXTERNAL_PHY(8)
+               EXTERNAL_PHY(9)
+               EXTERNAL_PHY(10)
+               EXTERNAL_PHY(11)
+               EXTERNAL_PHY(12)
+               EXTERNAL_PHY(13)
+               EXTERNAL_PHY(14)
+               EXTERNAL_PHY(15)
+
+               /* External phy RTL8218B #3 */
+               EXTERNAL_PHY(16)
+               EXTERNAL_PHY(17)
+               EXTERNAL_PHY(18)
+               EXTERNAL_PHY(19)
+               EXTERNAL_PHY(20)
+               EXTERNAL_PHY(21)
+               EXTERNAL_PHY(22)
+               EXTERNAL_PHY(23)
+
+               /* External phy RTL8218B #4 */
+               EXTERNAL_PHY(24)
+               EXTERNAL_PHY(25)
+               EXTERNAL_PHY(26)
+               EXTERNAL_PHY(27)
+               EXTERNAL_PHY(28)
+               EXTERNAL_PHY(29)
+               EXTERNAL_PHY(30)
+               EXTERNAL_PHY(31)
+
+               /* External phy RTL8218B #5 */
+               EXTERNAL_PHY(32)
+               EXTERNAL_PHY(33)
+               EXTERNAL_PHY(34)
+               EXTERNAL_PHY(35)
+               EXTERNAL_PHY(36)
+               EXTERNAL_PHY(37)
+               EXTERNAL_PHY(38)
+               EXTERNAL_PHY(39)
+
+               /* External phy RTL8218B #6 */
+               EXTERNAL_PHY(40)
+               EXTERNAL_PHY(41)
+               EXTERNAL_PHY(42)
+               EXTERNAL_PHY(43)
+               EXTERNAL_PHY(44)
+               EXTERNAL_PHY(45)
+               EXTERNAL_PHY(46)
+               EXTERNAL_PHY(47)
+       };
+};
+
+&switch0 {
+       ports {
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               SWITCH_PORT(0, 01, qsgmii)
+               SWITCH_PORT(1, 02, qsgmii)
+               SWITCH_PORT(2, 03, qsgmii)
+               SWITCH_PORT(3, 04, qsgmii)
+               SWITCH_PORT(4, 05, qsgmii)
+               SWITCH_PORT(5, 06, qsgmii)
+               SWITCH_PORT(6, 07, qsgmii)
+               SWITCH_PORT(7, 08, qsgmii)
+
+               SWITCH_PORT(8, 09, qsgmii)
+               SWITCH_PORT(9, 10, qsgmii)
+               SWITCH_PORT(10, 11, qsgmii)
+               SWITCH_PORT(11, 12, qsgmii)
+               SWITCH_PORT(12, 13, qsgmii)
+               SWITCH_PORT(13, 14, qsgmii)
+               SWITCH_PORT(14, 15, qsgmii)
+               SWITCH_PORT(15, 16, qsgmii)
+
+               SWITCH_PORT(16, 17, qsgmii)
+               SWITCH_PORT(17, 18, qsgmii)
+               SWITCH_PORT(18, 19, qsgmii)
+               SWITCH_PORT(19, 20, qsgmii)
+               SWITCH_PORT(20, 21, qsgmii)
+               SWITCH_PORT(21, 22, qsgmii)
+               SWITCH_PORT(22, 23, qsgmii)
+               SWITCH_PORT(23, 24, qsgmii)
+
+               SWITCH_PORT(24, 25, qsgmii)
+               SWITCH_PORT(25, 26, qsgmii)
+               SWITCH_PORT(26, 27, qsgmii)
+               SWITCH_PORT(27, 28, qsgmii)
+               SWITCH_PORT(28, 29, qsgmii)
+               SWITCH_PORT(29, 30, qsgmii)
+               SWITCH_PORT(30, 31, qsgmii)
+               SWITCH_PORT(31, 32, qsgmii)
+
+               SWITCH_PORT(32, 33, qsgmii)
+               SWITCH_PORT(33, 34, qsgmii)
+               SWITCH_PORT(34, 35, qsgmii)
+               SWITCH_PORT(35, 36, qsgmii)
+               SWITCH_PORT(36, 37, qsgmii)
+               SWITCH_PORT(37, 38, qsgmii)
+               SWITCH_PORT(38, 39, qsgmii)
+               SWITCH_PORT(39, 40, qsgmii)
+
+               SWITCH_PORT(40, 41, qsgmii)
+               SWITCH_PORT(41, 42, qsgmii)
+               SWITCH_PORT(42, 43, qsgmii)
+               SWITCH_PORT(43, 44, qsgmii)
+               SWITCH_PORT(44, 45, qsgmii)
+               SWITCH_PORT(45, 46, qsgmii)
+               SWITCH_PORT(46, 47, qsgmii)
+               SWITCH_PORT(47, 48, qsgmii)
+
+               /* CPU-Port */
+               port@52 {
+                       ethernet = <&ethernet0>;
+                       reg = <52>;
+                       phy-mode = "internal";
+
+                       fixed-link {
+                               speed = <1000>;
+                               full-duplex;
+                       };
+               };
+       };
+};
index b40ca83ac31779bf30b2c82ef4c7e83dc82b243f..2091fe0ba336060c4b6c66a8fe6513651b081f0b 100644 (file)
                enable_uart1: pinmux_enable_uart1 {
                        pinctrl-single,bits = <0x0 0x1 0x3>;
                };
+
+               disable_jtag: pinmux_disable_jtag {
+                       pinctrl-single,bits = <0x0 0x2 0x3>;
+               };
        };
 
        /* LED_GLB_CTRL */
index 8917e8550fae7b2a803c7e9420fa55b906f57a0f..b47c40924497fe5dee364f9d78aa9e5db84e9a1f 100644 (file)
@@ -11,6 +11,17 @@ define Device/panasonic_m48eg-pn28480k
 endef
 TARGET_DEVICES += panasonic_m48eg-pn28480k
 
+define Device/tplink_sg2452p-v4
+  SOC := rtl8393
+  KERNEL_SIZE := 6m
+  IMAGE_SIZE := 26m
+  DEVICE_VENDOR := TP-Link
+  DEVICE_MODEL := SG2452P
+  DEVICE_VARIANT := v4
+  DEVICE_PACKAGES := kmod-hwmon-gpiofan kmod-hwmon-tps23861
+endef
+TARGET_DEVICES += tplink_sg2452p-v4
+
 define Device/zyxel_gs1900-48
   SOC := rtl8393
   IMAGE_SIZE := 13952k