From fb861b682023e9e1af38b4248b28b68f0fa297e6 Mon Sep 17 00:00:00 2001 From: Serge Vasilugin Date: Thu, 15 Aug 2019 15:28:28 +0700 Subject: [PATCH 1/3] rtl8367b: initial support for rtl8367s From driver point of view no differance between rtl8367b and rtl8367s if it connected through EXT2 (rgmii only). So this trivial patch add some identification and initialization only. SGMII/HSGMII mode for EXT1 is not implemented for the sake of patch clairity. Signed-off-by: Serge Vasilugin [Fix code format] Signed-off-by: DENG Qingfang [add flags to separate chip_num/chip_id detection; drop error print in rtl8367b_init_regs, drop unnecessary info prints, code style fixes] Signed-off-by: Chuanhong Guo [rebase; use MII macros] Signed-off-by: Gaspare Bruno --- .../files/drivers/net/phy/rtl8366_smi.h | 2 + .../generic/files/drivers/net/phy/rtl8367b.c | 126 +++++++++++++----- 2 files changed, 98 insertions(+), 30 deletions(-) diff --git a/target/linux/generic/files/drivers/net/phy/rtl8366_smi.h b/target/linux/generic/files/drivers/net/phy/rtl8366_smi.h index d1d988a3727b7..e96d50ce34231 100644 --- a/target/linux/generic/files/drivers/net/phy/rtl8366_smi.h +++ b/target/linux/generic/files/drivers/net/phy/rtl8366_smi.h @@ -64,6 +64,8 @@ struct rtl8366_smi { u8 dbg_vlan_4k_page; #endif struct mii_bus *ext_mbus; + int phy_id; + u32 flags; }; struct rtl8366_vlan_mc { diff --git a/target/linux/generic/files/drivers/net/phy/rtl8367b.c b/target/linux/generic/files/drivers/net/phy/rtl8367b.c index 3599791a517bb..6df6a62d49fe5 100644 --- a/target/linux/generic/files/drivers/net/phy/rtl8367b.c +++ b/target/linux/generic/files/drivers/net/phy/rtl8367b.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include "rtl8366_smi.h" @@ -234,6 +235,7 @@ #define RTL8367B_CPU_PORT_NUM 5 #define RTL8367B_NUM_PORTS 8 +#define RTL8367B_NUM_PHYS 5 #define RTL8367B_NUM_VLANS 32 #define RTL8367B_NUM_VIDS 4096 #define RTL8367B_PRIORITYMAX 7 @@ -258,6 +260,8 @@ RTL8367B_PORT_3 | RTL8367B_PORT_4 | RTL8367B_PORT_E1 | \ RTL8367B_PORT_E2) +#define RTL8367B_FLAG_MATCH_CHIP_NUM BIT(0) + struct rtl8367b_initval { u16 reg; u16 val; @@ -605,6 +609,20 @@ static const struct rtl8367b_initval rtl8367r_vb_initvals_1[] = { {0x133E, 0x000E}, {0x133F, 0x0010}, }; +static const struct rtl8367b_initval rtl8367c_initvals[] = { + {0x13c2, 0x0000}, {0x0018, 0x0f00}, {0x0038, 0x0f00}, {0x0058, 0x0f00}, + {0x0078, 0x0f00}, {0x0098, 0x0f00}, {0x1d15, 0x0a69}, {0x2000, 0x1340}, + {0x2020, 0x1340}, {0x2040, 0x1340}, {0x2060, 0x1340}, {0x2080, 0x1340}, + {0x13eb, 0x15bb}, {0x1303, 0x06d6}, {0x1304, 0x0700}, {0x13E2, 0x003F}, + {0x13F9, 0x0090}, {0x121e, 0x03CA}, {0x1233, 0x0352}, {0x1237, 0x00a0}, + {0x123a, 0x0030}, {0x1239, 0x0084}, {0x0301, 0x1000}, {0x1349, 0x001F}, + {0x18e0, 0x4004}, {0x122b, 0x641c}, {0x1305, 0xc000}, {0x1200, 0x7fcb}, + {0x0884, 0x0003}, {0x06eb, 0x0001}, {0x00cf, 0xffff}, {0x00d0, 0x0007}, + {0x00ce, 0x48b0}, {0x00ce, 0x48b0}, {0x0398, 0xffff}, {0x0399, 0x0007}, + {0x0300, 0x0001}, {0x03fa, 0x0007}, {0x08c8, 0x00c0}, {0x0a30, 0x020e}, + {0x0800, 0x0000}, {0x0802, 0x0000}, {0x09da, 0x0017}, {0x1d32, 0x0002}, +}; + static int rtl8367b_write_initvals(struct rtl8366_smi *smi, const struct rtl8367b_initval *initvals, int count) @@ -716,33 +734,46 @@ static int rtl8367b_write_phy_reg(struct rtl8366_smi *smi, static int rtl8367b_init_regs(struct rtl8366_smi *smi) { const struct rtl8367b_initval *initvals; + u32 chip_num; u32 chip_ver; u32 rlvid; int count; int err; REG_WR(smi, RTL8367B_RTL_MAGIC_ID_REG, RTL8367B_RTL_MAGIC_ID_VAL); + REG_RD(smi, RTL8367B_CHIP_NUMBER_REG, &chip_num); REG_RD(smi, RTL8367B_CHIP_VER_REG, &chip_ver); rlvid = (chip_ver >> RTL8367B_CHIP_VER_RLVID_SHIFT) & RTL8367B_CHIP_VER_RLVID_MASK; - switch (rlvid) { - case 0: - initvals = rtl8367r_vb_initvals_0; - count = ARRAY_SIZE(rtl8367r_vb_initvals_0); - break; + if (smi->flags & RTL8367B_FLAG_MATCH_CHIP_NUM) { + switch (chip_num) { + case 0x0276: + case 0x0597: + case 0x6367: + initvals = rtl8367c_initvals; + count = ARRAY_SIZE(rtl8367c_initvals); + break; + default: + return -ENODEV; + } + } else { + switch (rlvid) { + case 0: + initvals = rtl8367r_vb_initvals_0; + count = ARRAY_SIZE(rtl8367r_vb_initvals_0); + break; - case 1: - initvals = rtl8367r_vb_initvals_1; - count = ARRAY_SIZE(rtl8367r_vb_initvals_1); - break; + case 1: + initvals = rtl8367r_vb_initvals_1; + count = ARRAY_SIZE(rtl8367r_vb_initvals_1); + break; - default: - dev_err(smi->parent, "unknow rlvid %u\n", rlvid); - return -ENODEV; + default: + return -ENODEV; + } } - /* TODO: disable RLTP */ return rtl8367b_write_initvals(smi, initvals, count); @@ -1021,6 +1052,16 @@ static int rtl8367b_setup(struct rtl8366_smi *smi) RTL8367B_PORT_MISC_CFG_EGRESS_MODE_ORIGINAL << RTL8367B_PORT_MISC_CFG_EGRESS_MODE_SHIFT); + for (i = 0; i < RTL8367B_NUM_PHYS; i++) { + int data; + rtl8367b_read_phy_reg(smi, i, MII_BMCR, &data); + /* release phy power down */ + data &= ~BMCR_PDOWN; + /* restart auto negotiation */ + data |= BMCR_ANRESTART; + rtl8367b_write_phy_reg(smi, i, MII_BMCR, data); + } + return 0; } @@ -1509,7 +1550,7 @@ static int rtl8367b_mii_write(struct mii_bus *bus, int addr, int reg, u16 val) static int rtl8367b_detect(struct rtl8366_smi *smi) { - const char *chip_name; + const char *chip_name = NULL; u32 chip_num; u32 chip_ver; u32 chip_mode; @@ -1540,14 +1581,26 @@ static int rtl8367b_detect(struct rtl8366_smi *smi) return ret; } - switch (chip_ver) { - case 0x1000: - chip_name = "8367RB"; - break; - case 0x1010: - chip_name = "8367R-VB"; - break; - default: + if (smi->flags & RTL8367B_FLAG_MATCH_CHIP_NUM) { + switch (chip_num) { + case 0x0276: + case 0x0597: + case 0x6367: + chip_name = "8367C"; + break; + } + } else { + switch (chip_ver) { + case 0x1000: + chip_name = "8367RB"; + break; + case 0x1010: + chip_name = "8367R-VB"; + break; + } + } + + if (!chip_name) { dev_err(smi->parent, "unknown chip num:%04x ver:%04x, mode:%04x\n", chip_num, chip_ver, chip_mode); @@ -1580,8 +1633,23 @@ static struct rtl8366_smi_ops rtl8367b_smi_ops = { .enable_port = rtl8367b_enable_port, }; +#ifdef CONFIG_OF +static const struct of_device_id rtl8367b_match[] = { + { .compatible = "realtek,rtl8367b" }, + { + .compatible = "realtek,rtl8367c", + .data = (void *)RTL8367B_FLAG_MATCH_CHIP_NUM, + }, + {}, +}; +MODULE_DEVICE_TABLE(of, rtl8367b_match); +#endif + static int rtl8367b_probe(struct platform_device *pdev) { +#ifdef CONFIG_OF + const struct of_device_id *match; +#endif struct rtl8366_smi *smi; int err; @@ -1589,6 +1657,12 @@ static int rtl8367b_probe(struct platform_device *pdev) if (IS_ERR(smi)) return PTR_ERR(smi); +#ifdef CONFIG_OF + match = of_match_device(rtl8367b_match, &pdev->dev); + if (match) + smi->flags = (u32)match->data; +#endif + smi->clk_delay = 1500; smi->cmd_read = 0xb9; smi->cmd_write = 0xb8; @@ -1643,14 +1717,6 @@ static void rtl8367b_shutdown(struct platform_device *pdev) rtl8367b_reset_chip(smi); } -#ifdef CONFIG_OF -static const struct of_device_id rtl8367b_match[] = { - { .compatible = "realtek,rtl8367b" }, - {}, -}; -MODULE_DEVICE_TABLE(of, rtl8367b_match); -#endif - static struct platform_driver rtl8367b_driver = { .driver = { .name = RTL8367B_DRIVER_NAME, From fa043601ba1f02cdcc006ef9b0da2fec753d79e1 Mon Sep 17 00:00:00 2001 From: DENG Qingfang Date: Mon, 18 May 2020 16:38:12 +0800 Subject: [PATCH 2/3] ramips: add support for TP-Link Archer C5 v4 TP-Link Archer C5 v4 is a dual band router with 5 GbE ports Advertised as AC1200 for its 867Mbps (2x2) 5GHz band and 300 Mbps (2x2) 2.4GHz band. Specs: - SoC: MediaTek MT7620A - Ethernet: 5x GbE ports (Realtek RTL8367S) - Wireless 2.4GHz: MediaTek MT7620A - Wireless 5GHz: MediaTek MT7612E - RAM: 64MiB - ROM: 8MiB (GD25Q64CSIG) - 1 USB 2.0 port - 2 Buttons (WPS and reset) - 8 LEDs Flash instructions: Currently one has to install OpenWrt only via the serial console 1. Rename the factory.bin to to test.bin 2. start a TFTP server from IP address 192.168.0.225 and serve the image named test.bin 3. connect your device to the LAN port 4. power up the router and press 4 on the console to stop the boot process. 5. enter the following commands on the router console tftp 0x80060000 test.bin erase tplink 0x20000 0x7a0000 cp.b 0x80060000 0x20000 0x7a0000 reset Signed-off-by: DENG Qingfang [Update leds, add fast-read] Signed-off-by: Gaspare Bruno --- .../dts/mt7620a_tplink_archer-c5-v4.dts | 204 ++++++++++++++++++ target/linux/ramips/image/mt7620.mk | 17 ++ .../mt7620/base-files/etc/board.d/01_leds | 4 + .../mt7620/base-files/etc/board.d/02_network | 7 + 4 files changed, 232 insertions(+) create mode 100644 target/linux/ramips/dts/mt7620a_tplink_archer-c5-v4.dts diff --git a/target/linux/ramips/dts/mt7620a_tplink_archer-c5-v4.dts b/target/linux/ramips/dts/mt7620a_tplink_archer-c5-v4.dts new file mode 100644 index 0000000000000..af4a5ef6b20b3 --- /dev/null +++ b/target/linux/ramips/dts/mt7620a_tplink_archer-c5-v4.dts @@ -0,0 +1,204 @@ +// SPDX-License-Identifier: GPL-2.0-or-later OR MIT + +#include "mt7620a.dtsi" + +#include +#include + +/ { + compatible = "tplink,archer-c5-v4", "ralink,mt7620a-soc"; + model = "TP-Link Archer C5 v4"; + + aliases { + led-boot = &led_power; + led-failsafe = &led_power; + led-running = &led_power; + led-upgrade = &led_power; + label-mac-device = ðernet; + }; + + chosen { + bootargs = "console=ttyS0,115200"; + }; + + leds { + compatible = "gpio-leds"; + + led_power: power { + label = "green:power"; + gpios = <&gpio2 2 GPIO_ACTIVE_LOW>; + }; + + wlan2g { + label = "green:wlan2g"; + gpios = <&gpio0 14 GPIO_ACTIVE_LOW>; + linux,default-trigger = "phy1tpt"; + }; + + wlan5g { + label = "green:wlan5g"; + gpios = <&gpio0 12 GPIO_ACTIVE_LOW>; + linux,default-trigger = "phy0tpt"; + }; + + wan { + label = "green:wan"; + gpios = <&gpio0 10 GPIO_ACTIVE_LOW>; + }; + + wan_orange { + label = "orange:wan"; + gpios = <&gpio0 9 GPIO_ACTIVE_LOW>; + }; + + lan { + label = "green:lan"; + gpios = <&gpio0 8 GPIO_ACTIVE_HIGH>; + }; + + usb { + label = "green:usb"; + gpios = <&gpio0 7 GPIO_ACTIVE_LOW>; + trigger-sources = <&ohci_port1>, <&ehci_port1>; + linux,default-trigger = "usbport"; + }; + + wps { + label = "green:wps"; + gpios = <&gpio0 1 GPIO_ACTIVE_LOW>; + }; + }; + + keys { + compatible = "gpio-keys"; + + reset { + label = "reset"; + gpios = <&gpio0 13 GPIO_ACTIVE_LOW>; + linux,code = ; + }; + + rfkill { + label = "rfkill"; + gpios = <&gpio0 2 GPIO_ACTIVE_LOW>; + linux,code = ; + }; + }; + + rtl8367s { + compatible = "realtek,rtl8367c"; + cpu_port = <7>; + realtek,extif2 = <1 0 1 1 1 1 1 1 2>; + mii-bus = <&mdio0>; + phy-id = <29>; + }; +}; + +&gpio2 { + status = "okay"; +}; + +&spi0 { + status = "okay"; + + flash@0 { + compatible = "jedec,spi-nor"; + reg = <0>; + spi-max-frequency = <60000000>; + m25p,fast-read; + + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + partition@0 { + label = "u-boot"; + reg = <0x0 0x20000>; + read-only; + }; + + partition@20000 { + compatible = "tplink,firmware"; + label = "firmware"; + reg = <0x20000 0x7a0000>; + }; + + partition@7c0000 { + label = "config"; + reg = <0x7c0000 0x10000>; + read-only; + }; + + rom: partition@7d0000 { + label = "rom"; + reg = <0x7d0000 0x10000>; + read-only; + }; + + partition@7e0000 { + label = "romfile"; + reg = <0x7e0000 0x10000>; + read-only; + }; + + radio: partition@7f0000 { + label = "radio"; + reg = <0x7f0000 0x10000>; + read-only; + }; + }; + }; +}; + +&state_default { + gpio { + groups = "i2c", "uartf", "ephy", "rgmii2"; + function = "gpio"; + }; +}; + +ðernet { + pinctrl-names = "default"; + mtd-mac-address = <&rom 0xf100>; + pinctrl-0 = <&rgmii1_pins &mdio_pins>; + + port@5 { + status = "okay"; + mediatek,fixed-link = <1000 1 1 1>; + phy-mode = "rgmii"; + }; + + mdio0: mdio-bus { + status = "okay"; + reset-gpios = <&gpio2 20 GPIO_ACTIVE_LOW>; + reset-delay-us = <10000>; + }; +}; + +&ehci { + status = "okay"; +}; + +&ohci { + status = "okay"; +}; + +&wmac { + ralink,mtd-eeprom = <&radio 0x0>; + mtd-mac-address = <&rom 0xf100>; +}; + +&pcie { + status = "okay"; +}; + +&pcie0 { + wifi@0,0 { + reg = <0x0000 0 0 0 0>; + mediatek,mtd-eeprom = <&radio 0x8000>; + ieee80211-freq-limit = <5000000 6000000>; + mtd-mac-address = <&rom 0xf100>; + mtd-mac-address-increment = <2>; + }; +}; diff --git a/target/linux/ramips/image/mt7620.mk b/target/linux/ramips/image/mt7620.mk index 849bd31ef8acd..1db2d53d1622a 100644 --- a/target/linux/ramips/image/mt7620.mk +++ b/target/linux/ramips/image/mt7620.mk @@ -1010,6 +1010,23 @@ define Device/tplink_archer-c2-v1 endef TARGET_DEVICES += tplink_archer-c2-v1 +define Device/tplink_archer-c5-v4 + $(Device/tplink-v2) + SOC := mt7620a + IMAGE_SIZE := 7808k + TPLINK_FLASHLAYOUT := 8Mmtk + TPLINK_HWID := 0x04da857c + TPLINK_HWREV := 0x0c000600 + TPLINK_HWREVADD := 0x04000000 + IMAGES += tftp-recovery.bin + IMAGE/tftp-recovery.bin := pad-extra 128k | $$(IMAGE/factory.bin) + DEVICE_MODEL := Archer C5 + DEVICE_VARIANT := v4 + DEVICE_PACKAGES := kmod-usb2 kmod-usb-ohci kmod-usb-ledtrig-usbport \ + kmod-mt76x2 kmod-switch-rtl8367b +endef +TARGET_DEVICES += tplink_archer-c5-v4 + define Device/tplink_archer-c50-v1 $(Device/tplink-v2) SOC := mt7620a diff --git a/target/linux/ramips/mt7620/base-files/etc/board.d/01_leds b/target/linux/ramips/mt7620/base-files/etc/board.d/01_leds index 53487d752688c..2cffb7603587e 100644 --- a/target/linux/ramips/mt7620/base-files/etc/board.d/01_leds +++ b/target/linux/ramips/mt7620/base-files/etc/board.d/01_leds @@ -183,6 +183,10 @@ tplink,archer-c20i) ucidef_set_led_switch "lan" "lan" "blue:lan" "switch0" "0x1e" ucidef_set_led_switch "wan" "wan" "blue:wan" "switch0" "0x01" ;; +tplink,archer-c5-v4) + ucidef_set_led_switch "lan" "lan" "green:lan" "switch1" "0x0f" + ucidef_set_led_switch "wan" "wan" "green:wan" "switch1" "0x10" + ;; tplink,archer-c50-v1) ucidef_set_led_switch "lan" "lan" "green:lan" "switch0" "0x1e" ucidef_set_led_switch "wan" "wan" "green:wan" "switch0" "0x01" diff --git a/target/linux/ramips/mt7620/base-files/etc/board.d/02_network b/target/linux/ramips/mt7620/base-files/etc/board.d/02_network index eaa8cbf7aa3e3..1ab5ad841af4e 100644 --- a/target/linux/ramips/mt7620/base-files/etc/board.d/02_network +++ b/target/linux/ramips/mt7620/base-files/etc/board.d/02_network @@ -212,6 +212,12 @@ ramips_setup_interfaces() ucidef_add_switch "switch0" \ "1:lan:3" "2:lan:4" "3:lan:1" "4:lan:2" "0:wan" "6@eth0" ;; + tplink,archer-c5-v4) + ucidef_add_switch "switch0" + ucidef_add_switch_attr "switch0" "enable" "0" + ucidef_add_switch "switch1" \ + "0:lan:4" "1:lan:3" "2:lan:2" "3:lan:1" "4:wan" "7@eth0" + ;; tplink,archer-mr200) ucidef_add_switch "switch0" \ "0:lan" "1:lan" "2:lan" "3:lan" "6t@eth0" @@ -363,6 +369,7 @@ ramips_setup_macs() tplink,archer-c2-v1|\ tplink,archer-c20-v1|\ tplink,archer-c20i|\ + tplink,archer-c5-v4|\ tplink,archer-c50-v1|\ tplink,archer-mr200) wan_mac=$(macaddr_add "$(mtd_get_mac_binary rom 0xf100)" 1) From 0730b7f3202672ce09576393224a9ae67054895e Mon Sep 17 00:00:00 2001 From: Serge Vasilugin Date: Thu, 15 Aug 2019 15:27:08 +0700 Subject: [PATCH 3/3] kernel: rtl8366_smi: explicitly set phy addr for switch By default rtl8366_smi use phy addr 0 at mii-bus to access switch registers. This patch allow to set it explicitly in dts-file: rtl8367 { compatible = "realtek,rtl8367b"; phy-id = <29>; /* switch address at mii-bus */ realtek,extif2 = <1 0 1 1 1 1 1 1 2>; mii-bus = <&mdio>; cpu-port = <7>; } Use default 0 address if not set. Backward compatibility tested on tplink archer c2 v1 (rtl8367rb switch) Signed-off-by: Serge Vasilugin [code style fixes, add explicit phy_id assignment in probe_plat, use phy-id instead of phy_id for of property name] Signed-off-by: Chuanhong Guo [rebase] Signed-off-by: Gaspare Bruno --- target/linux/generic/files/drivers/net/phy/rtl8366_smi.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/target/linux/generic/files/drivers/net/phy/rtl8366_smi.c b/target/linux/generic/files/drivers/net/phy/rtl8366_smi.c index e8375e514787e..0cd5c2542fdf7 100644 --- a/target/linux/generic/files/drivers/net/phy/rtl8366_smi.c +++ b/target/linux/generic/files/drivers/net/phy/rtl8366_smi.c @@ -256,7 +256,7 @@ static int __rtl8366_smi_read_reg(struct rtl8366_smi *smi, u32 addr, u32 *data) int __rtl8366_mdio_read_reg(struct rtl8366_smi *smi, u32 addr, u32 *data) { - u32 phy_id = MDC_REALTEK_PHY_ADDR; + u32 phy_id = smi->phy_id; struct mii_bus *mbus = smi->ext_mbus; BUG_ON(in_interrupt()); @@ -293,7 +293,7 @@ int __rtl8366_mdio_read_reg(struct rtl8366_smi *smi, u32 addr, u32 *data) static int __rtl8366_mdio_write_reg(struct rtl8366_smi *smi, u32 addr, u32 data) { - u32 phy_id = MDC_REALTEK_PHY_ADDR; + u32 phy_id = smi->phy_id; struct mii_bus *mbus = smi->ext_mbus; BUG_ON(in_interrupt()); @@ -1550,6 +1550,9 @@ int rtl8366_smi_probe_of(struct platform_device *pdev, struct rtl8366_smi *smi) goto try_gpio; } + if (of_property_read_u32(np, "phy-id", &smi->phy_id)) + smi->phy_id = MDC_REALTEK_PHY_ADDR; + return 0; try_gpio: @@ -1589,6 +1592,7 @@ int rtl8366_smi_probe_plat(struct platform_device *pdev, struct rtl8366_smi *smi smi->gpio_sda = pdata->gpio_sda; smi->gpio_sck = pdata->gpio_sck; smi->hw_reset = pdata->hw_reset; + smi->phy_id = MDC_REALTEK_PHY_ADDR; return 0; }