From: Aleksander Jan Bajkowski Date: Wed, 9 Mar 2022 19:52:50 +0000 (+0100) Subject: kernel: move rtl8152 patches to generic X-Git-Tag: v23.05.0-rc1~3860 X-Git-Url: http://git.lede-project.org./?a=commitdiff_plain;h=210c534ce2be55fc0c59b1700809470e8ba971b8;p=openwrt%2Fopenwrt.git kernel: move rtl8152 patches to generic This commit moves the patches for the r8152.c driver to the generic directory. Previously they were only available on the bcm27xx target. With these patches the Realtek RTL8153C, RTL8153D, RTL8156A and RTL8156B chips are supported on all targets by the kmod-usb-net-rtl8152 module. The RTL8156A and RTL8156B are the 2.5Gb/s Ethernet adapters. The patches have been tested on TP-Link UE300 (RTL8153A) and UNITEK 1313B (RTL8156B). Signed-off-by: Aleksander Jan Bajkowski --- diff --git a/target/linux/bcm27xx/patches-5.10/950-0542-net-usb-r8152-Provide-missing-documentation-for-some.patch b/target/linux/bcm27xx/patches-5.10/950-0542-net-usb-r8152-Provide-missing-documentation-for-some.patch deleted file mode 100644 index bec2867a48..0000000000 --- a/target/linux/bcm27xx/patches-5.10/950-0542-net-usb-r8152-Provide-missing-documentation-for-some.patch +++ /dev/null @@ -1,72 +0,0 @@ -From 586f04ce6a391419ca3cc9cef6b6f38570cede88 Mon Sep 17 00:00:00 2001 -From: Lee Jones -Date: Mon, 2 Nov 2020 11:45:04 +0000 -Subject: [PATCH] net: usb: r8152: Provide missing documentation for - some struct members - -commit 34e653efb602e0651867fb5ab14369b555a61dcd upstream. - -Fixes the following W=1 kernel build warning(s): - - drivers/net/usb/r8152.c:934: warning: Function parameter or member 'blk_hdr' not described in 'fw_mac' - drivers/net/usb/r8152.c:934: warning: Function parameter or member 'reserved' not described in 'fw_mac' - drivers/net/usb/r8152.c:947: warning: Function parameter or member 'blk_hdr' not described in 'fw_phy_patch_key' - drivers/net/usb/r8152.c:947: warning: Function parameter or member 'reserved' not described in 'fw_phy_patch_key' - drivers/net/usb/r8152.c:986: warning: Function parameter or member 'blk_hdr' not described in 'fw_phy_nc' - drivers/net/usb/r8152.c:986: warning: Function parameter or member 'mode_pre' not described in 'fw_phy_nc' - drivers/net/usb/r8152.c:986: warning: Function parameter or member 'mode_post' not described in 'fw_phy_nc' - drivers/net/usb/r8152.c:986: warning: Function parameter or member 'reserved' not described in 'fw_phy_nc' - -Signed-off-by: Lee Jones -Acked-by: Hayes Wang -Link: https://lore.kernel.org/r/20201102114512.1062724-23-lee.jones@linaro.org -Signed-off-by: Jakub Kicinski ---- - drivers/net/usb/r8152.c | 6 ++++++ - 1 file changed, 6 insertions(+) - ---- a/drivers/net/usb/r8152.c -+++ b/drivers/net/usb/r8152.c -@@ -899,6 +899,7 @@ struct fw_header { - * struct fw_mac - a firmware block used by RTL_FW_PLA and RTL_FW_USB. - * The layout of the firmware block is: - * + + . -+ * @blk_hdr: firmware descriptor (type, length) - * @fw_offset: offset of the firmware binary data. The start address of - * the data would be the address of struct fw_mac + @fw_offset. - * @fw_reg: the register to load the firmware. Depends on chip. -@@ -912,6 +913,7 @@ struct fw_header { - * @bp_num: the break point number which needs to be set for this firmware. - * Depends on the firmware. - * @bp: break points. Depends on firmware. -+ * @reserved: reserved space (unused) - * @fw_ver_reg: the register to store the fw version. - * @fw_ver_data: the firmware version of the current type. - * @info: additional information for debugging, and is followed by the -@@ -937,8 +939,10 @@ struct fw_mac { - /** - * struct fw_phy_patch_key - a firmware block used by RTL_FW_PHY_START. - * This is used to set patch key when loading the firmware of PHY. -+ * @blk_hdr: firmware descriptor (type, length) - * @key_reg: the register to write the patch key. - * @key_data: patch key. -+ * @reserved: reserved space (unused) - */ - struct fw_phy_patch_key { - struct fw_block blk_hdr; -@@ -951,6 +955,7 @@ struct fw_phy_patch_key { - * struct fw_phy_nc - a firmware block used by RTL_FW_PHY_NC. - * The layout of the firmware block is: - * + + . -+ * @blk_hdr: firmware descriptor (type, length) - * @fw_offset: offset of the firmware binary data. The start address of - * the data would be the address of struct fw_phy_nc + @fw_offset. - * @fw_reg: the register to load the firmware. Depends on chip. -@@ -961,6 +966,7 @@ struct fw_phy_patch_key { - * @mode_reg: the regitster of switching the mode. - * @mod_pre: the mode needing to be set before loading the firmware. - * @mod_post: the mode to be set when finishing to load the firmware. -+ * @reserved: reserved space (unused) - * @bp_start: the start register of break points. Depends on chip. - * @bp_num: the break point number which needs to be set for this firmware. - * Depends on the firmware. diff --git a/target/linux/bcm27xx/patches-5.10/950-0543-net-usb-r8152-Fix-a-couple-of-spelling-errors-in-fw_.patch b/target/linux/bcm27xx/patches-5.10/950-0543-net-usb-r8152-Fix-a-couple-of-spelling-errors-in-fw_.patch deleted file mode 100644 index aa2763e7de..0000000000 --- a/target/linux/bcm27xx/patches-5.10/950-0543-net-usb-r8152-Fix-a-couple-of-spelling-errors-in-fw_.patch +++ /dev/null @@ -1,34 +0,0 @@ -From 5fcfa846181de6676509696c4cd7b60a22e74077 Mon Sep 17 00:00:00 2001 -From: Lee Jones -Date: Mon, 2 Nov 2020 11:45:09 +0000 -Subject: [PATCH] net: usb: r8152: Fix a couple of spelling errors in - fw_phy_nc's docs - -commit 9f07814d01ad085b2d9f1d55b4ce532fb2c27110 upstream. - -Fixes the following W=1 kernel build warning(s): - - drivers/net/usb/r8152.c:992: warning: Function parameter or member 'mode_pre' not described in 'fw_phy_nc' - drivers/net/usb/r8152.c:992: warning: Function parameter or member 'mode_post' not described in 'fw_phy_nc' - -Signed-off-by: Lee Jones -Acked-by: Hayes Wang -Link: https://lore.kernel.org/r/20201102114512.1062724-28-lee.jones@linaro.org -Signed-off-by: Jakub Kicinski ---- - drivers/net/usb/r8152.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - ---- a/drivers/net/usb/r8152.c -+++ b/drivers/net/usb/r8152.c -@@ -964,8 +964,8 @@ struct fw_phy_patch_key { - * @patch_en_addr: the register of enabling patch mode. Depends on chip. - * @patch_en_value: patch mode enabled mask. Depends on the firmware. - * @mode_reg: the regitster of switching the mode. -- * @mod_pre: the mode needing to be set before loading the firmware. -- * @mod_post: the mode to be set when finishing to load the firmware. -+ * @mode_pre: the mode needing to be set before loading the firmware. -+ * @mode_post: the mode to be set when finishing to load the firmware. - * @reserved: reserved space (unused) - * @bp_start: the start register of break points. Depends on chip. - * @bp_num: the break point number which needs to be set for this firmware. diff --git a/target/linux/bcm27xx/patches-5.10/950-0544-net-usb-r8153_ecm-support-ECM-mode-for-RTL8153.patch b/target/linux/bcm27xx/patches-5.10/950-0544-net-usb-r8153_ecm-support-ECM-mode-for-RTL8153.patch deleted file mode 100644 index 789de8e6fd..0000000000 --- a/target/linux/bcm27xx/patches-5.10/950-0544-net-usb-r8153_ecm-support-ECM-mode-for-RTL8153.patch +++ /dev/null @@ -1,320 +0,0 @@ -From 0ef50460f7f053bd2a911ec53e01bfda646a5574 Mon Sep 17 00:00:00 2001 -From: Hayes Wang -Date: Wed, 4 Nov 2020 10:19:22 +0800 -Subject: [PATCH] net/usb/r8153_ecm: support ECM mode for RTL8153 - -commit c1aedf015ebdd0232757a66e2daccf1246bd609c upstream. - -Support ECM mode based on cdc_ether with relative mii functions, -when CONFIG_USB_RTL8152 is not set, or the device is not supported -by r8152 driver. - -Both r8152 and r8153_ecm would check the return value of -rtl8152_get_version() in porbe(). If rtl8152_get_version() -return none zero value, the r8152 is used for the device -with vendor mode. Otherwise, the r8153_ecm is used for the -device with ECM mode. - -Signed-off-by: Hayes Wang -Link: https://lore.kernel.org/r/1394712342-15778-392-Taiwan-albertk@realtek.com -Signed-off-by: Jakub Kicinski ---- - drivers/net/usb/Makefile | 2 +- - drivers/net/usb/r8152.c | 30 +------ - drivers/net/usb/r8153_ecm.c | 162 ++++++++++++++++++++++++++++++++++++ - include/linux/usb/r8152.h | 37 ++++++++ - 4 files changed, 204 insertions(+), 27 deletions(-) - create mode 100644 drivers/net/usb/r8153_ecm.c - create mode 100644 include/linux/usb/r8152.h - ---- a/drivers/net/usb/Makefile -+++ b/drivers/net/usb/Makefile -@@ -13,7 +13,7 @@ obj-$(CONFIG_USB_LAN78XX) += lan78xx.o - obj-$(CONFIG_USB_NET_AX8817X) += asix.o - asix-y := asix_devices.o asix_common.o ax88172a.o - obj-$(CONFIG_USB_NET_AX88179_178A) += ax88179_178a.o --obj-$(CONFIG_USB_NET_CDCETHER) += cdc_ether.o -+obj-$(CONFIG_USB_NET_CDCETHER) += cdc_ether.o r8153_ecm.o - obj-$(CONFIG_USB_NET_CDC_EEM) += cdc_eem.o - obj-$(CONFIG_USB_NET_DM9601) += dm9601.o - obj-$(CONFIG_USB_NET_SR9700) += sr9700.o ---- a/drivers/net/usb/r8152.c -+++ b/drivers/net/usb/r8152.c -@@ -27,6 +27,7 @@ - #include - #include - #include -+#include - - /* Information for net-next */ - #define NETNEXT_VERSION "11" -@@ -654,18 +655,6 @@ enum rtl_register_content { - - #define INTR_LINK 0x0004 - --#define RTL8152_REQT_READ 0xc0 --#define RTL8152_REQT_WRITE 0x40 --#define RTL8152_REQ_GET_REGS 0x05 --#define RTL8152_REQ_SET_REGS 0x05 -- --#define BYTE_EN_DWORD 0xff --#define BYTE_EN_WORD 0x33 --#define BYTE_EN_BYTE 0x11 --#define BYTE_EN_SIX_BYTES 0x3f --#define BYTE_EN_START_MASK 0x0f --#define BYTE_EN_END_MASK 0xf0 -- - #define RTL8153_MAX_PACKET 9216 /* 9K */ - #define RTL8153_MAX_MTU (RTL8153_MAX_PACKET - VLAN_ETH_HLEN - \ - ETH_FCS_LEN) -@@ -690,21 +679,9 @@ enum rtl8152_flags { - LENOVO_MACPASSTHRU, - }; - --/* Define these values to match your device */ --#define VENDOR_ID_REALTEK 0x0bda --#define VENDOR_ID_MICROSOFT 0x045e --#define VENDOR_ID_SAMSUNG 0x04e8 --#define VENDOR_ID_LENOVO 0x17ef --#define VENDOR_ID_LINKSYS 0x13b1 --#define VENDOR_ID_NVIDIA 0x0955 --#define VENDOR_ID_TPLINK 0x2357 -- - #define DEVICE_ID_THINKPAD_THUNDERBOLT3_DOCK_GEN2 0x3082 - #define DEVICE_ID_THINKPAD_USB_C_DOCK_GEN2 0xa387 - --#define MCU_TYPE_PLA 0x0100 --#define MCU_TYPE_USB 0x0000 -- - struct tally_counter { - __le64 tx_packets; - __le64 rx_packets; -@@ -6625,7 +6602,7 @@ static int rtl_fw_init(struct r8152 *tp) - return 0; - } - --static u8 rtl_get_version(struct usb_interface *intf) -+u8 rtl8152_get_version(struct usb_interface *intf) - { - struct usb_device *udev = interface_to_usbdev(intf); - u32 ocp_data = 0; -@@ -6683,12 +6660,13 @@ static u8 rtl_get_version(struct usb_int - - return version; - } -+EXPORT_SYMBOL_GPL(rtl8152_get_version); - - static int rtl8152_probe(struct usb_interface *intf, - const struct usb_device_id *id) - { - struct usb_device *udev = interface_to_usbdev(intf); -- u8 version = rtl_get_version(intf); -+ u8 version = rtl8152_get_version(intf); - struct r8152 *tp; - struct net_device *netdev; - int ret; ---- /dev/null -+++ b/drivers/net/usb/r8153_ecm.c -@@ -0,0 +1,162 @@ -+// SPDX-License-Identifier: GPL-2.0-or-later -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#define OCP_BASE 0xe86c -+ -+static int pla_read_word(struct usbnet *dev, u16 index) -+{ -+ u16 byen = BYTE_EN_WORD; -+ u8 shift = index & 2; -+ __le32 tmp; -+ int ret; -+ -+ if (shift) -+ byen <<= shift; -+ -+ index &= ~3; -+ -+ ret = usbnet_read_cmd(dev, RTL8152_REQ_GET_REGS, RTL8152_REQT_READ, index, -+ MCU_TYPE_PLA | byen, &tmp, sizeof(tmp)); -+ if (ret < 0) -+ goto out; -+ -+ ret = __le32_to_cpu(tmp); -+ ret >>= (shift * 8); -+ ret &= 0xffff; -+ -+out: -+ return ret; -+} -+ -+static int pla_write_word(struct usbnet *dev, u16 index, u32 data) -+{ -+ u32 mask = 0xffff; -+ u16 byen = BYTE_EN_WORD; -+ u8 shift = index & 2; -+ __le32 tmp; -+ int ret; -+ -+ data &= mask; -+ -+ if (shift) { -+ byen <<= shift; -+ mask <<= (shift * 8); -+ data <<= (shift * 8); -+ } -+ -+ index &= ~3; -+ -+ ret = usbnet_read_cmd(dev, RTL8152_REQ_GET_REGS, RTL8152_REQT_READ, index, -+ MCU_TYPE_PLA | byen, &tmp, sizeof(tmp)); -+ -+ if (ret < 0) -+ goto out; -+ -+ data |= __le32_to_cpu(tmp) & ~mask; -+ tmp = __cpu_to_le32(data); -+ -+ ret = usbnet_write_cmd(dev, RTL8152_REQ_SET_REGS, RTL8152_REQT_WRITE, index, -+ MCU_TYPE_PLA | byen, &tmp, sizeof(tmp)); -+ -+out: -+ return ret; -+} -+ -+static int r8153_ecm_mdio_read(struct net_device *netdev, int phy_id, int reg) -+{ -+ struct usbnet *dev = netdev_priv(netdev); -+ int ret; -+ -+ ret = pla_write_word(dev, OCP_BASE, 0xa000); -+ if (ret < 0) -+ goto out; -+ -+ ret = pla_read_word(dev, 0xb400 + reg * 2); -+ -+out: -+ return ret; -+} -+ -+static void r8153_ecm_mdio_write(struct net_device *netdev, int phy_id, int reg, int val) -+{ -+ struct usbnet *dev = netdev_priv(netdev); -+ int ret; -+ -+ ret = pla_write_word(dev, OCP_BASE, 0xa000); -+ if (ret < 0) -+ return; -+ -+ ret = pla_write_word(dev, 0xb400 + reg * 2, val); -+} -+ -+static int r8153_bind(struct usbnet *dev, struct usb_interface *intf) -+{ -+ int status; -+ -+ status = usbnet_cdc_bind(dev, intf); -+ if (status < 0) -+ return status; -+ -+ dev->mii.dev = dev->net; -+ dev->mii.mdio_read = r8153_ecm_mdio_read; -+ dev->mii.mdio_write = r8153_ecm_mdio_write; -+ dev->mii.reg_num_mask = 0x1f; -+ dev->mii.supports_gmii = 1; -+ -+ return status; -+} -+ -+static const struct driver_info r8153_info = { -+ .description = "RTL8153 ECM Device", -+ .flags = FLAG_ETHER, -+ .bind = r8153_bind, -+ .unbind = usbnet_cdc_unbind, -+ .status = usbnet_cdc_status, -+ .manage_power = usbnet_manage_power, -+}; -+ -+static const struct usb_device_id products[] = { -+{ -+ USB_DEVICE_AND_INTERFACE_INFO(VENDOR_ID_REALTEK, 0x8153, USB_CLASS_COMM, -+ USB_CDC_SUBCLASS_ETHERNET, USB_CDC_PROTO_NONE), -+ .driver_info = (unsigned long)&r8153_info, -+}, -+ -+ { }, /* END */ -+}; -+MODULE_DEVICE_TABLE(usb, products); -+ -+static int rtl8153_ecm_probe(struct usb_interface *intf, -+ const struct usb_device_id *id) -+{ -+#if IS_REACHABLE(CONFIG_USB_RTL8152) -+ if (rtl8152_get_version(intf)) -+ return -ENODEV; -+#endif -+ -+ return usbnet_probe(intf, id); -+} -+ -+static struct usb_driver r8153_ecm_driver = { -+ .name = "r8153_ecm", -+ .id_table = products, -+ .probe = rtl8153_ecm_probe, -+ .disconnect = usbnet_disconnect, -+ .suspend = usbnet_suspend, -+ .resume = usbnet_resume, -+ .reset_resume = usbnet_resume, -+ .supports_autosuspend = 1, -+ .disable_hub_initiated_lpm = 1, -+}; -+ -+module_usb_driver(r8153_ecm_driver); -+ -+MODULE_AUTHOR("Hayes Wang"); -+MODULE_DESCRIPTION("Realtek USB ECM device"); -+MODULE_LICENSE("GPL"); ---- /dev/null -+++ b/include/linux/usb/r8152.h -@@ -0,0 +1,37 @@ -+/* SPDX-License-Identifier: GPL-2.0-only */ -+/* -+ * Copyright (c) 2020 Realtek Semiconductor Corp. All rights reserved. -+ */ -+ -+#ifndef __LINUX_R8152_H -+#define __LINUX_R8152_H -+ -+#define RTL8152_REQT_READ 0xc0 -+#define RTL8152_REQT_WRITE 0x40 -+#define RTL8152_REQ_GET_REGS 0x05 -+#define RTL8152_REQ_SET_REGS 0x05 -+ -+#define BYTE_EN_DWORD 0xff -+#define BYTE_EN_WORD 0x33 -+#define BYTE_EN_BYTE 0x11 -+#define BYTE_EN_SIX_BYTES 0x3f -+#define BYTE_EN_START_MASK 0x0f -+#define BYTE_EN_END_MASK 0xf0 -+ -+#define MCU_TYPE_PLA 0x0100 -+#define MCU_TYPE_USB 0x0000 -+ -+/* Define these values to match your device */ -+#define VENDOR_ID_REALTEK 0x0bda -+#define VENDOR_ID_MICROSOFT 0x045e -+#define VENDOR_ID_SAMSUNG 0x04e8 -+#define VENDOR_ID_LENOVO 0x17ef -+#define VENDOR_ID_LINKSYS 0x13b1 -+#define VENDOR_ID_NVIDIA 0x0955 -+#define VENDOR_ID_TPLINK 0x2357 -+ -+#if IS_REACHABLE(CONFIG_USB_RTL8152) -+extern u8 rtl8152_get_version(struct usb_interface *intf); -+#endif -+ -+#endif /* __LINUX_R8152_H */ diff --git a/target/linux/bcm27xx/patches-5.10/950-0545-net-usb-r8152-use-new-tasklet-API.patch b/target/linux/bcm27xx/patches-5.10/950-0545-net-usb-r8152-use-new-tasklet-API.patch deleted file mode 100644 index b625d5ea99..0000000000 --- a/target/linux/bcm27xx/patches-5.10/950-0545-net-usb-r8152-use-new-tasklet-API.patch +++ /dev/null @@ -1,41 +0,0 @@ -From 90f1afc7f96c8f7cf19c82e5f4b39e61a63b053d Mon Sep 17 00:00:00 2001 -From: Emil Renner Berthing -Date: Sun, 31 Jan 2021 00:47:29 +0100 -Subject: [PATCH] net: usb: r8152: use new tasklet API - -commit f3163f1cb87141c7a41a15a5d4c98b353f807b04 upstream. - -This converts the driver to use the new tasklet API introduced in -commit 12cc923f1ccc ("tasklet: Introduce new initialization API") - -Signed-off-by: Emil Renner Berthing -Signed-off-by: Jakub Kicinski ---- - drivers/net/usb/r8152.c | 8 +++----- - 1 file changed, 3 insertions(+), 5 deletions(-) - ---- a/drivers/net/usb/r8152.c -+++ b/drivers/net/usb/r8152.c -@@ -2394,11 +2394,9 @@ static void tx_bottom(struct r8152 *tp) - } while (res == 0); - } - --static void bottom_half(unsigned long data) -+static void bottom_half(struct tasklet_struct *t) - { -- struct r8152 *tp; -- -- tp = (struct r8152 *)data; -+ struct r8152 *tp = from_tasklet(tp, t, tx_tl); - - if (test_bit(RTL8152_UNPLUG, &tp->flags)) - return; -@@ -6718,7 +6716,7 @@ static int rtl8152_probe(struct usb_inte - mutex_init(&tp->control); - INIT_DELAYED_WORK(&tp->schedule, rtl_work_func_t); - INIT_DELAYED_WORK(&tp->hw_phy_work, rtl_hw_phy_work_func_t); -- tasklet_init(&tp->tx_tl, bottom_half, (unsigned long)tp); -+ tasklet_setup(&tp->tx_tl, bottom_half); - tasklet_disable(&tp->tx_tl); - - netdev->netdev_ops = &rtl8152_netdev_ops; diff --git a/target/linux/bcm27xx/patches-5.10/950-0546-r8152-replace-several-functions-about-phy-patch-requ.patch b/target/linux/bcm27xx/patches-5.10/950-0546-r8152-replace-several-functions-about-phy-patch-requ.patch deleted file mode 100644 index bbb2b5c0c9..0000000000 --- a/target/linux/bcm27xx/patches-5.10/950-0546-r8152-replace-several-functions-about-phy-patch-requ.patch +++ /dev/null @@ -1,198 +0,0 @@ -From 86b98abf4f8c691c260c5113d6a2d32f5377caca Mon Sep 17 00:00:00 2001 -From: Hayes Wang -Date: Wed, 3 Feb 2021 17:14:28 +0800 -Subject: [PATCH] r8152: replace several functions about phy patch - request - -commit a08c0d309d8c078d22717d815cf9853f6f2c07bd upstream. - -Replace r8153_patch_request() with rtl_phy_patch_request(). -Replace r8153_pre_ram_code() with rtl_pre_ram_code(). -Replace r8153_post_ram_code() with rtl_post_ram_code(). -Add rtl_patch_key_set(). - -The new functions have an additional parameter. It is used to wait -the patch request command finished. When the PHY is resumed from -the state of power cut, the PHY is at a safe mode and the -OCP_PHY_PATCH_STAT wouldn't be updated. For this situation, it is -safe to set patch request command without waiting OCP_PHY_PATCH_STAT. - -Signed-off-by: Hayes Wang -Signed-off-by: Jakub Kicinski ---- - drivers/net/usb/r8152.c | 84 ++++++++++++++++++++++++----------------- - 1 file changed, 50 insertions(+), 34 deletions(-) - ---- a/drivers/net/usb/r8152.c -+++ b/drivers/net/usb/r8152.c -@@ -3444,59 +3444,76 @@ static void rtl_clear_bp(struct r8152 *t - ocp_write_word(tp, type, PLA_BP_BA, 0); - } - --static int r8153_patch_request(struct r8152 *tp, bool request) -+static int rtl_phy_patch_request(struct r8152 *tp, bool request, bool wait) - { -- u16 data; -+ u16 data, check; - int i; - - data = ocp_reg_read(tp, OCP_PHY_PATCH_CMD); -- if (request) -+ if (request) { - data |= PATCH_REQUEST; -- else -+ check = 0; -+ } else { - data &= ~PATCH_REQUEST; -+ check = PATCH_READY; -+ } - ocp_reg_write(tp, OCP_PHY_PATCH_CMD, data); - -- for (i = 0; request && i < 5000; i++) { -+ for (i = 0; wait && i < 5000; i++) { -+ u32 ocp_data; -+ - usleep_range(1000, 2000); -- if (ocp_reg_read(tp, OCP_PHY_PATCH_STAT) & PATCH_READY) -+ ocp_data = ocp_reg_read(tp, OCP_PHY_PATCH_STAT); -+ if ((ocp_data & PATCH_READY) ^ check) - break; - } - -- if (request && !(ocp_reg_read(tp, OCP_PHY_PATCH_STAT) & PATCH_READY)) { -- netif_err(tp, drv, tp->netdev, "patch request fail\n"); -- r8153_patch_request(tp, false); -+ if (request && wait && -+ !(ocp_reg_read(tp, OCP_PHY_PATCH_STAT) & PATCH_READY)) { -+ dev_err(&tp->intf->dev, "PHY patch request fail\n"); -+ rtl_phy_patch_request(tp, false, false); - return -ETIME; - } else { - return 0; - } - } - --static int r8153_pre_ram_code(struct r8152 *tp, u16 key_addr, u16 patch_key) -+static void rtl_patch_key_set(struct r8152 *tp, u16 key_addr, u16 patch_key) - { -- if (r8153_patch_request(tp, true)) { -- dev_err(&tp->intf->dev, "patch request fail\n"); -- return -ETIME; -- } -+ if (patch_key && key_addr) { -+ sram_write(tp, key_addr, patch_key); -+ sram_write(tp, SRAM_PHY_LOCK, PHY_PATCH_LOCK); -+ } else if (key_addr) { -+ u16 data; - -- sram_write(tp, key_addr, patch_key); -- sram_write(tp, SRAM_PHY_LOCK, PHY_PATCH_LOCK); -+ sram_write(tp, 0x0000, 0x0000); - -- return 0; -+ data = ocp_reg_read(tp, OCP_PHY_LOCK); -+ data &= ~PATCH_LOCK; -+ ocp_reg_write(tp, OCP_PHY_LOCK, data); -+ -+ sram_write(tp, key_addr, 0x0000); -+ } else { -+ WARN_ON_ONCE(1); -+ } - } - --static int r8153_post_ram_code(struct r8152 *tp, u16 key_addr) -+static int -+rtl_pre_ram_code(struct r8152 *tp, u16 key_addr, u16 patch_key, bool wait) - { -- u16 data; -+ if (rtl_phy_patch_request(tp, true, wait)) -+ return -ETIME; - -- sram_write(tp, 0x0000, 0x0000); -+ rtl_patch_key_set(tp, key_addr, patch_key); - -- data = ocp_reg_read(tp, OCP_PHY_LOCK); -- data &= ~PATCH_LOCK; -- ocp_reg_write(tp, OCP_PHY_LOCK, data); -+ return 0; -+} - -- sram_write(tp, key_addr, 0x0000); -+static int rtl_post_ram_code(struct r8152 *tp, u16 key_addr, bool wait) -+{ -+ rtl_patch_key_set(tp, key_addr, 0); - -- r8153_patch_request(tp, false); -+ rtl_phy_patch_request(tp, false, wait); - - ocp_write_word(tp, MCU_TYPE_PLA, PLA_OCP_GPHY_BASE, tp->ocp_base); - -@@ -3981,7 +3998,7 @@ static void rtl8152_fw_mac_apply(struct - dev_dbg(&tp->intf->dev, "successfully applied %s\n", mac->info); - } - --static void rtl8152_apply_firmware(struct r8152 *tp) -+static void rtl8152_apply_firmware(struct r8152 *tp, bool power_cut) - { - struct rtl_fw *rtl_fw = &tp->rtl_fw; - const struct firmware *fw; -@@ -4012,12 +4029,11 @@ static void rtl8152_apply_firmware(struc - case RTL_FW_PHY_START: - key = (struct fw_phy_patch_key *)block; - key_addr = __le16_to_cpu(key->key_reg); -- r8153_pre_ram_code(tp, key_addr, -- __le16_to_cpu(key->key_data)); -+ rtl_pre_ram_code(tp, key_addr, __le16_to_cpu(key->key_data), !power_cut); - break; - case RTL_FW_PHY_STOP: - WARN_ON(!key_addr); -- r8153_post_ram_code(tp, key_addr); -+ rtl_post_ram_code(tp, key_addr, !power_cut); - break; - case RTL_FW_PHY_NC: - rtl8152_fw_phy_nc_apply(tp, (struct fw_phy_nc *)block); -@@ -4222,7 +4238,7 @@ static void rtl8152_disable(struct r8152 - - static void r8152b_hw_phy_cfg(struct r8152 *tp) - { -- rtl8152_apply_firmware(tp); -+ rtl8152_apply_firmware(tp, false); - rtl_eee_enable(tp, tp->eee_en); - r8152_aldps_en(tp, true); - r8152b_enable_fc(tp); -@@ -4504,7 +4520,7 @@ static void r8153_hw_phy_cfg(struct r815 - /* disable EEE before updating the PHY parameters */ - rtl_eee_enable(tp, false); - -- rtl8152_apply_firmware(tp); -+ rtl8152_apply_firmware(tp, false); - - if (tp->version == RTL_VER_03) { - data = ocp_reg_read(tp, OCP_EEE_CFG); -@@ -4578,7 +4594,7 @@ static void r8153b_hw_phy_cfg(struct r81 - /* disable EEE before updating the PHY parameters */ - rtl_eee_enable(tp, false); - -- rtl8152_apply_firmware(tp); -+ rtl8152_apply_firmware(tp, false); - - r8153b_green_en(tp, test_bit(GREEN_ETHERNET, &tp->flags)); - -@@ -4619,7 +4635,7 @@ static void r8153b_hw_phy_cfg(struct r81 - ocp_write_word(tp, MCU_TYPE_PLA, PLA_PHY_PWR, ocp_data); - - /* Advnace EEE */ -- if (!r8153_patch_request(tp, true)) { -+ if (!rtl_phy_patch_request(tp, true, true)) { - data = ocp_reg_read(tp, OCP_POWER_CFG); - data |= EEE_CLKDIV_EN; - ocp_reg_write(tp, OCP_POWER_CFG, data); -@@ -4636,7 +4652,7 @@ static void r8153b_hw_phy_cfg(struct r81 - ocp_reg_write(tp, OCP_SYSCLK_CFG, clk_div_expo(5)); - tp->ups_info._250m_ckdiv = true; - -- r8153_patch_request(tp, false); -+ rtl_phy_patch_request(tp, false, true); - } - - if (tp->eee_en) diff --git a/target/linux/bcm27xx/patches-5.10/950-0547-r8152-adjust-the-flow-of-power-cut-for-RTL8153B.patch b/target/linux/bcm27xx/patches-5.10/950-0547-r8152-adjust-the-flow-of-power-cut-for-RTL8153B.patch deleted file mode 100644 index b28e89a43f..0000000000 --- a/target/linux/bcm27xx/patches-5.10/950-0547-r8152-adjust-the-flow-of-power-cut-for-RTL8153B.patch +++ /dev/null @@ -1,134 +0,0 @@ -From 29a61d8564ad3439d03c7ec135016a4e70072af1 Mon Sep 17 00:00:00 2001 -From: Hayes Wang -Date: Wed, 3 Feb 2021 17:14:29 +0800 -Subject: [PATCH] r8152: adjust the flow of power cut for RTL8153B - -commit 80fd850b31f09263ad175b2f640d5c5c6f76ed41 upstream. - -For runtime resuming, the RTL8153B may be resumed from the state -of power cut, when enabling the feature of UPS. Then, the PHY -would be reset, so it is necessary to be initailized again. - -Besides, the USB_U1U2_TIMER also has to be set again, so I move -it from r8153b_init() to r8153b_hw_phy_cfg(). - -Signed-off-by: Hayes Wang -Signed-off-by: Jakub Kicinski ---- - drivers/net/usb/r8152.c | 68 ++++++++++++++++++++++++----------------- - 1 file changed, 40 insertions(+), 28 deletions(-) - ---- a/drivers/net/usb/r8152.c -+++ b/drivers/net/usb/r8152.c -@@ -1372,6 +1372,10 @@ void write_mii_word(struct net_device *n - static int - r8152_submit_rx(struct r8152 *tp, struct rx_agg *agg, gfp_t mem_flags); - -+static int -+rtl8152_set_speed(struct r8152 *tp, u8 autoneg, u32 speed, u8 duplex, -+ u32 advertising); -+ - static int rtl8152_set_mac_address(struct net_device *netdev, void *p) - { - struct r8152 *tp = netdev_priv(netdev); -@@ -3183,8 +3187,6 @@ static void r8153b_ups_en(struct r8152 * - ocp_data |= BIT(0); - ocp_write_byte(tp, MCU_TYPE_USB, 0xcfff, ocp_data); - } else { -- u16 data; -- - ocp_data &= ~(UPS_EN | USP_PREWAKE); - ocp_write_byte(tp, MCU_TYPE_USB, USB_POWER_CUT, ocp_data); - -@@ -3192,31 +3194,20 @@ static void r8153b_ups_en(struct r8152 * - ocp_data &= ~BIT(0); - ocp_write_byte(tp, MCU_TYPE_USB, 0xcfff, ocp_data); - -- ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_MISC_0); -- ocp_data &= ~PCUT_STATUS; -- ocp_write_word(tp, MCU_TYPE_USB, USB_MISC_0, ocp_data); -+ if (ocp_read_word(tp, MCU_TYPE_USB, USB_MISC_0) & PCUT_STATUS) { -+ int i; - -- data = r8153_phy_status(tp, 0); -+ for (i = 0; i < 500; i++) { -+ if (ocp_read_word(tp, MCU_TYPE_PLA, PLA_BOOT_CTRL) & -+ AUTOLOAD_DONE) -+ break; -+ msleep(20); -+ } - -- switch (data) { -- case PHY_STAT_PWRDN: -- case PHY_STAT_EXT_INIT: -- r8153b_green_en(tp, -- test_bit(GREEN_ETHERNET, &tp->flags)); -- -- data = r8152_mdio_read(tp, MII_BMCR); -- data &= ~BMCR_PDOWN; -- data |= BMCR_RESET; -- r8152_mdio_write(tp, MII_BMCR, data); -+ tp->rtl_ops.hw_phy_cfg(tp); - -- data = r8153_phy_status(tp, PHY_STAT_LAN_ON); -- fallthrough; -- -- default: -- if (data != PHY_STAT_LAN_ON) -- netif_warn(tp, link, tp->netdev, -- "PHY not ready"); -- break; -+ rtl8152_set_speed(tp, tp->autoneg, tp->speed, -+ tp->duplex, tp->advertising); - } - } - } -@@ -4588,13 +4579,37 @@ static void r8153b_hw_phy_cfg(struct r81 - u32 ocp_data; - u16 data; - -+ ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_MISC_0); -+ if (ocp_data & PCUT_STATUS) { -+ ocp_data &= ~PCUT_STATUS; -+ ocp_write_word(tp, MCU_TYPE_USB, USB_MISC_0, ocp_data); -+ } -+ - /* disable ALDPS before updating the PHY parameters */ - r8153_aldps_en(tp, false); - - /* disable EEE before updating the PHY parameters */ - rtl_eee_enable(tp, false); - -- rtl8152_apply_firmware(tp, false); -+ /* U1/U2/L1 idle timer. 500 us */ -+ ocp_write_word(tp, MCU_TYPE_USB, USB_U1U2_TIMER, 500); -+ -+ data = r8153_phy_status(tp, 0); -+ -+ switch (data) { -+ case PHY_STAT_PWRDN: -+ case PHY_STAT_EXT_INIT: -+ rtl8152_apply_firmware(tp, true); -+ -+ data = r8152_mdio_read(tp, MII_BMCR); -+ data &= ~BMCR_PDOWN; -+ r8152_mdio_write(tp, MII_BMCR, data); -+ break; -+ case PHY_STAT_LAN_ON: -+ default: -+ rtl8152_apply_firmware(tp, false); -+ break; -+ } - - r8153b_green_en(tp, test_bit(GREEN_ETHERNET, &tp->flags)); - -@@ -5543,9 +5558,6 @@ static void r8153b_init(struct r8152 *tp - /* MSC timer = 0xfff * 8ms = 32760 ms */ - ocp_write_word(tp, MCU_TYPE_USB, USB_MSC_TIMER, 0x0fff); - -- /* U1/U2/L1 idle timer. 500 us */ -- ocp_write_word(tp, MCU_TYPE_USB, USB_U1U2_TIMER, 500); -- - r8153b_power_cut_en(tp, false); - r8153b_ups_en(tp, false); - r8153_queue_wake(tp, false); diff --git a/target/linux/bcm27xx/patches-5.10/950-0548-r8152-enable-U1-U2-for-USB_SPEED_SUPER.patch b/target/linux/bcm27xx/patches-5.10/950-0548-r8152-enable-U1-U2-for-USB_SPEED_SUPER.patch deleted file mode 100644 index 8cf91c3893..0000000000 --- a/target/linux/bcm27xx/patches-5.10/950-0548-r8152-enable-U1-U2-for-USB_SPEED_SUPER.patch +++ /dev/null @@ -1,47 +0,0 @@ -From 69b4339c0b9f3edc6a8f681f05efaaf4add1bb0e Mon Sep 17 00:00:00 2001 -From: Hayes Wang -Date: Fri, 19 Feb 2021 17:04:40 +0800 -Subject: [PATCH] r8152: enable U1/U2 for USB_SPEED_SUPER - -commit 7a0ae61acde2cebd69665837170405eced86a6c7 upstream. - -U1/U2 shoued be enabled for USB 3.0 or later. The USB 2.0 doesn't -support it. - -Signed-off-by: Hayes Wang -Signed-off-by: Jakub Kicinski ---- - drivers/net/usb/r8152.c | 7 ++++--- - 1 file changed, 4 insertions(+), 3 deletions(-) - ---- a/drivers/net/usb/r8152.c -+++ b/drivers/net/usb/r8152.c -@@ -3336,7 +3336,7 @@ static void rtl8153b_runtime_enable(stru - r8153b_ups_en(tp, false); - r8153_queue_wake(tp, false); - rtl_runtime_suspend_enable(tp, false); -- if (tp->udev->speed != USB_SPEED_HIGH) -+ if (tp->udev->speed >= USB_SPEED_SUPER) - r8153b_u1u2en(tp, true); - } - } -@@ -5029,7 +5029,7 @@ static void rtl8153b_up(struct r8152 *tp - - r8153_aldps_en(tp, true); - -- if (tp->udev->speed != USB_SPEED_HIGH) -+ if (tp->udev->speed >= USB_SPEED_SUPER) - r8153b_u1u2en(tp, true); - } - -@@ -5571,8 +5571,9 @@ static void r8153b_init(struct r8152 *tp - ocp_data |= POLL_LINK_CHG; - ocp_write_word(tp, MCU_TYPE_PLA, PLA_EXTRA_STATUS, ocp_data); - -- if (tp->udev->speed != USB_SPEED_HIGH) -+ if (tp->udev->speed >= USB_SPEED_SUPER) - r8153b_u1u2en(tp, true); -+ - usb_enable_lpm(tp->udev); - - /* MAC clock speed down */ diff --git a/target/linux/bcm27xx/patches-5.10/950-0549-r8152-check-if-the-pointer-of-the-function-exists.patch b/target/linux/bcm27xx/patches-5.10/950-0549-r8152-check-if-the-pointer-of-the-function-exists.patch deleted file mode 100644 index 5bc4e2b0a1..0000000000 --- a/target/linux/bcm27xx/patches-5.10/950-0549-r8152-check-if-the-pointer-of-the-function-exists.patch +++ /dev/null @@ -1,51 +0,0 @@ -From e78b75f5be204a0a235da995d01c778dc282bb42 Mon Sep 17 00:00:00 2001 -From: Hayes Wang -Date: Fri, 19 Feb 2021 17:04:41 +0800 -Subject: [PATCH] r8152: check if the pointer of the function exists - -commit c79515e47935c747282c6ed2ee5b2ef039756eeb upstream. - -Return error code if autosuspend_en, eee_get, or eee_set don't exist. - -Signed-off-by: Hayes Wang -Signed-off-by: Jakub Kicinski ---- - drivers/net/usb/r8152.c | 13 +++++++++++++ - 1 file changed, 13 insertions(+) - ---- a/drivers/net/usb/r8152.c -+++ b/drivers/net/usb/r8152.c -@@ -5758,6 +5758,9 @@ static int rtl8152_runtime_suspend(struc - struct net_device *netdev = tp->netdev; - int ret = 0; - -+ if (!tp->rtl_ops.autosuspend_en) -+ return -EBUSY; -+ - set_bit(SELECTIVE_SUSPEND, &tp->flags); - smp_mb__after_atomic(); - -@@ -6157,6 +6160,11 @@ rtl_ethtool_get_eee(struct net_device *n - struct r8152 *tp = netdev_priv(net); - int ret; - -+ if (!tp->rtl_ops.eee_get) { -+ ret = -EOPNOTSUPP; -+ goto out; -+ } -+ - ret = usb_autopm_get_interface(tp->intf); - if (ret < 0) - goto out; -@@ -6179,6 +6187,11 @@ rtl_ethtool_set_eee(struct net_device *n - struct r8152 *tp = netdev_priv(net); - int ret; - -+ if (!tp->rtl_ops.eee_set) { -+ ret = -EOPNOTSUPP; -+ goto out; -+ } -+ - ret = usb_autopm_get_interface(tp->intf); - if (ret < 0) - goto out; diff --git a/target/linux/bcm27xx/patches-5.10/950-0550-r8152-replace-netif_err-with-dev_err.patch b/target/linux/bcm27xx/patches-5.10/950-0550-r8152-replace-netif_err-with-dev_err.patch deleted file mode 100644 index 967b4ccc16..0000000000 --- a/target/linux/bcm27xx/patches-5.10/950-0550-r8152-replace-netif_err-with-dev_err.patch +++ /dev/null @@ -1,36 +0,0 @@ -From 38e44c7926512cff0b2809dc329de2a8e769e523 Mon Sep 17 00:00:00 2001 -From: Hayes Wang -Date: Fri, 19 Feb 2021 17:04:42 +0800 -Subject: [PATCH] r8152: replace netif_err with dev_err - -commit 156c3207611262266f0eea589ac3f00c5657320e upstream. - -Some messages are before calling register_netdev(), so replace -netif_err() with dev_err(). - -Signed-off-by: Hayes Wang -Signed-off-by: Jakub Kicinski ---- - drivers/net/usb/r8152.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - ---- a/drivers/net/usb/r8152.c -+++ b/drivers/net/usb/r8152.c -@@ -6594,7 +6594,7 @@ static int rtl_ops_init(struct r8152 *tp - - default: - ret = -ENODEV; -- netif_err(tp, probe, tp->netdev, "Unknown Device\n"); -+ dev_err(&tp->intf->dev, "Unknown Device\n"); - break; - } - -@@ -6851,7 +6851,7 @@ static int rtl8152_probe(struct usb_inte - - ret = register_netdev(netdev); - if (ret != 0) { -- netif_err(tp, probe, netdev, "couldn't register the device\n"); -+ dev_err(&intf->dev, "couldn't register the device\n"); - goto out1; - } - diff --git a/target/linux/bcm27xx/patches-5.10/950-0551-r8152-spilt-rtl_set_eee_plus-and-r8153b_green_en.patch b/target/linux/bcm27xx/patches-5.10/950-0551-r8152-spilt-rtl_set_eee_plus-and-r8153b_green_en.patch deleted file mode 100644 index c49a4ce5b6..0000000000 --- a/target/linux/bcm27xx/patches-5.10/950-0551-r8152-spilt-rtl_set_eee_plus-and-r8153b_green_en.patch +++ /dev/null @@ -1,89 +0,0 @@ -From 260814de2d6cb958767785ffcb2e76915d1be32b Mon Sep 17 00:00:00 2001 -From: Hayes Wang -Date: Fri, 19 Feb 2021 17:04:43 +0800 -Subject: [PATCH] r8152: spilt rtl_set_eee_plus and r8153b_green_en - -commit 40fa7568ac230446d888b7ad402cff9e20fe3ad5 upstream. - -Add rtl_eee_plus_en() and rtl_green_en(). - -Signed-off-by: Hayes Wang -Signed-off-by: Jakub Kicinski ---- - drivers/net/usb/r8152.c | 43 ++++++++++++++++++++++++++--------------- - 1 file changed, 27 insertions(+), 16 deletions(-) - ---- a/drivers/net/usb/r8152.c -+++ b/drivers/net/usb/r8152.c -@@ -2633,21 +2633,24 @@ static inline u8 rtl8152_get_speed(struc - return ocp_read_byte(tp, MCU_TYPE_PLA, PLA_PHYSTATUS); - } - --static void rtl_set_eee_plus(struct r8152 *tp) -+static void rtl_eee_plus_en(struct r8152 *tp, bool enable) - { - u32 ocp_data; -- u8 speed; - -- speed = rtl8152_get_speed(tp); -- if (speed & _10bps) { -- ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_EEEP_CR); -+ ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_EEEP_CR); -+ if (enable) - ocp_data |= EEEP_CR_EEEP_TX; -- ocp_write_word(tp, MCU_TYPE_PLA, PLA_EEEP_CR, ocp_data); -- } else { -- ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_EEEP_CR); -+ else - ocp_data &= ~EEEP_CR_EEEP_TX; -- ocp_write_word(tp, MCU_TYPE_PLA, PLA_EEEP_CR, ocp_data); -- } -+ ocp_write_word(tp, MCU_TYPE_PLA, PLA_EEEP_CR, ocp_data); -+} -+ -+static void rtl_set_eee_plus(struct r8152 *tp) -+{ -+ if (rtl8152_get_speed(tp) & _10bps) -+ rtl_eee_plus_en(tp, true); -+ else -+ rtl_eee_plus_en(tp, false); - } - - static void rxdy_gated_en(struct r8152 *tp, bool enable) -@@ -3128,10 +3131,22 @@ static void r8153b_ups_flags(struct r815 - ocp_write_dword(tp, MCU_TYPE_USB, USB_UPS_FLAGS, ups_flags); - } - --static void r8153b_green_en(struct r8152 *tp, bool enable) -+static void rtl_green_en(struct r8152 *tp, bool enable) - { - u16 data; - -+ data = sram_read(tp, SRAM_GREEN_CFG); -+ if (enable) -+ data |= GREEN_ETH_EN; -+ else -+ data &= ~GREEN_ETH_EN; -+ sram_write(tp, SRAM_GREEN_CFG, data); -+ -+ tp->ups_info.green = enable; -+} -+ -+static void r8153b_green_en(struct r8152 *tp, bool enable) -+{ - if (enable) { - sram_write(tp, 0x8045, 0); /* 10M abiq&ldvbias */ - sram_write(tp, 0x804d, 0x1222); /* 100M short abiq&ldvbias */ -@@ -3142,11 +3157,7 @@ static void r8153b_green_en(struct r8152 - sram_write(tp, 0x805d, 0x2444); /* 1000M short abiq&ldvbias */ - } - -- data = sram_read(tp, SRAM_GREEN_CFG); -- data |= GREEN_ETH_EN; -- sram_write(tp, SRAM_GREEN_CFG, data); -- -- tp->ups_info.green = enable; -+ rtl_green_en(tp, true); - } - - static u16 r8153_phy_status(struct r8152 *tp, u16 desired) diff --git a/target/linux/bcm27xx/patches-5.10/950-0552-r8152-set-inter-fram-gap-time-depending-on-speed.patch b/target/linux/bcm27xx/patches-5.10/950-0552-r8152-set-inter-fram-gap-time-depending-on-speed.patch deleted file mode 100644 index f2593e8f00..0000000000 --- a/target/linux/bcm27xx/patches-5.10/950-0552-r8152-set-inter-fram-gap-time-depending-on-speed.patch +++ /dev/null @@ -1,75 +0,0 @@ -From f1bbbb260a8016373adf239c716d2da90e6ced0b Mon Sep 17 00:00:00 2001 -From: Hayes Wang -Date: Fri, 16 Apr 2021 16:04:32 +0800 -Subject: [PATCH] r8152: set inter fram gap time depending on speed - -commit 5133bcc7481528e36fff0a3b056601efb704fb32 upstream. - -Set the maximum inter frame gap time (144ns) for speed 10M/half and -100M/half. It improves the performance for those speeds. And, there -is no effect for the other speeds. - -For 10M/half and 100M/half, the fast inter frame gap time let the -device couldn't use the feature of the aggregation effectively, -because the transfer would be completed fastly. Therefore, use the -maximum value to improve the effect of the aggregation. However, you -may not feel the improvement for fast CPUs, because they compensate -for the effect of the aggregation. - -Signed-off-by: Hayes Wang -Signed-off-by: David S. Miller ---- - drivers/net/usb/r8152.c | 28 ++++++++++++++++++++++++++++ - 1 file changed, 28 insertions(+) - ---- a/drivers/net/usb/r8152.c -+++ b/drivers/net/usb/r8152.c -@@ -250,6 +250,9 @@ - - /* PLA_TCR1 */ - #define VERSION_MASK 0x7cf0 -+#define IFG_MASK (BIT(3) | BIT(9) | BIT(8)) -+#define IFG_144NS BIT(9) -+#define IFG_96NS (BIT(9) | BIT(8)) - - /* PLA_MTPS */ - #define MTPS_JUMBO (12 * 1024 / 64) -@@ -2748,6 +2751,29 @@ static int rtl_stop_rx(struct r8152 *tp) - return 0; - } - -+static void rtl_set_ifg(struct r8152 *tp, u16 speed) -+{ -+ u32 ocp_data; -+ -+ ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_TCR1); -+ ocp_data &= ~IFG_MASK; -+ if ((speed & (_10bps | _100bps)) && !(speed & FULL_DUP)) { -+ ocp_data |= IFG_144NS; -+ ocp_write_word(tp, MCU_TYPE_PLA, PLA_TCR1, ocp_data); -+ -+ ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL4); -+ ocp_data &= ~TX10MIDLE_EN; -+ ocp_write_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL4, ocp_data); -+ } else { -+ ocp_data |= IFG_96NS; -+ ocp_write_word(tp, MCU_TYPE_PLA, PLA_TCR1, ocp_data); -+ -+ ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL4); -+ ocp_data |= TX10MIDLE_EN; -+ ocp_write_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL4, ocp_data); -+ } -+} -+ - static inline void r8153b_rx_agg_chg_indicate(struct r8152 *tp) - { - ocp_write_byte(tp, MCU_TYPE_USB, USB_UPT_RXDMA_OWN, -@@ -2851,6 +2877,8 @@ static int rtl8153_enable(struct r8152 * - r8153_set_rx_early_timeout(tp); - r8153_set_rx_early_size(tp); - -+ rtl_set_ifg(tp, rtl8152_get_speed(tp)); -+ - if (tp->version == RTL_VER_09) { - u32 ocp_data; - diff --git a/target/linux/bcm27xx/patches-5.10/950-0553-r8152-adjust-rtl8152_check_firmware-function.patch b/target/linux/bcm27xx/patches-5.10/950-0553-r8152-adjust-rtl8152_check_firmware-function.patch deleted file mode 100644 index cddd39ea94..0000000000 --- a/target/linux/bcm27xx/patches-5.10/950-0553-r8152-adjust-rtl8152_check_firmware-function.patch +++ /dev/null @@ -1,152 +0,0 @@ -From f10c9edf47d3fa240d965e151a48c670f5035b73 Mon Sep 17 00:00:00 2001 -From: Hayes Wang -Date: Fri, 16 Apr 2021 16:04:33 +0800 -Subject: [PATCH] r8152: adjust rtl8152_check_firmware function - -commit a8a7be178e81a3d4b6972cbeb0ccd091ca2f9f89 upstream. - -Use bits operations to record and check the firmware. - -Signed-off-by: Hayes Wang -Signed-off-by: David S. Miller ---- - drivers/net/usb/r8152.c | 51 +++++++++++++++++++++++------------------ - 1 file changed, 29 insertions(+), 22 deletions(-) - ---- a/drivers/net/usb/r8152.c -+++ b/drivers/net/usb/r8152.c -@@ -875,6 +875,14 @@ struct fw_header { - struct fw_block blocks[]; - } __packed; - -+enum rtl8152_fw_flags { -+ FW_FLAGS_USB = 0, -+ FW_FLAGS_PLA, -+ FW_FLAGS_START, -+ FW_FLAGS_STOP, -+ FW_FLAGS_NC, -+}; -+ - /** - * struct fw_mac - a firmware block used by RTL_FW_PLA and RTL_FW_USB. - * The layout of the firmware block is: -@@ -3801,10 +3809,7 @@ static long rtl8152_check_firmware(struc - { - const struct firmware *fw = rtl_fw->fw; - struct fw_header *fw_hdr = (struct fw_header *)fw->data; -- struct fw_mac *pla = NULL, *usb = NULL; -- struct fw_phy_patch_key *start = NULL; -- struct fw_phy_nc *phy_nc = NULL; -- struct fw_block *stop = NULL; -+ unsigned long fw_flags = 0; - long ret = -EFAULT; - int i; - -@@ -3833,50 +3838,52 @@ static long rtl8152_check_firmware(struc - goto fail; - goto fw_end; - case RTL_FW_PLA: -- if (pla) { -+ if (test_bit(FW_FLAGS_PLA, &fw_flags)) { - dev_err(&tp->intf->dev, - "multiple PLA firmware encountered"); - goto fail; - } - -- pla = (struct fw_mac *)block; -- if (!rtl8152_is_fw_mac_ok(tp, pla)) { -+ if (!rtl8152_is_fw_mac_ok(tp, (struct fw_mac *)block)) { - dev_err(&tp->intf->dev, - "check PLA firmware failed\n"); - goto fail; - } -+ __set_bit(FW_FLAGS_PLA, &fw_flags); - break; - case RTL_FW_USB: -- if (usb) { -+ if (test_bit(FW_FLAGS_USB, &fw_flags)) { - dev_err(&tp->intf->dev, - "multiple USB firmware encountered"); - goto fail; - } - -- usb = (struct fw_mac *)block; -- if (!rtl8152_is_fw_mac_ok(tp, usb)) { -+ if (!rtl8152_is_fw_mac_ok(tp, (struct fw_mac *)block)) { - dev_err(&tp->intf->dev, - "check USB firmware failed\n"); - goto fail; - } -+ __set_bit(FW_FLAGS_USB, &fw_flags); - break; - case RTL_FW_PHY_START: -- if (start || phy_nc || stop) { -+ if (test_bit(FW_FLAGS_START, &fw_flags) || -+ test_bit(FW_FLAGS_NC, &fw_flags) || -+ test_bit(FW_FLAGS_STOP, &fw_flags)) { - dev_err(&tp->intf->dev, - "check PHY_START fail\n"); - goto fail; - } - -- if (__le32_to_cpu(block->length) != sizeof(*start)) { -+ if (__le32_to_cpu(block->length) != sizeof(struct fw_phy_patch_key)) { - dev_err(&tp->intf->dev, - "Invalid length for PHY_START\n"); - goto fail; - } -- -- start = (struct fw_phy_patch_key *)block; -+ __set_bit(FW_FLAGS_START, &fw_flags); - break; - case RTL_FW_PHY_STOP: -- if (stop || !start) { -+ if (test_bit(FW_FLAGS_STOP, &fw_flags) || -+ !test_bit(FW_FLAGS_START, &fw_flags)) { - dev_err(&tp->intf->dev, - "Check PHY_STOP fail\n"); - goto fail; -@@ -3887,28 +3894,28 @@ static long rtl8152_check_firmware(struc - "Invalid length for PHY_STOP\n"); - goto fail; - } -- -- stop = block; -+ __set_bit(FW_FLAGS_STOP, &fw_flags); - break; - case RTL_FW_PHY_NC: -- if (!start || stop) { -+ if (!test_bit(FW_FLAGS_START, &fw_flags) || -+ test_bit(FW_FLAGS_STOP, &fw_flags)) { - dev_err(&tp->intf->dev, - "check PHY_NC fail\n"); - goto fail; - } - -- if (phy_nc) { -+ if (test_bit(FW_FLAGS_NC, &fw_flags)) { - dev_err(&tp->intf->dev, - "multiple PHY NC encountered\n"); - goto fail; - } - -- phy_nc = (struct fw_phy_nc *)block; -- if (!rtl8152_is_fw_phy_nc_ok(tp, phy_nc)) { -+ if (!rtl8152_is_fw_phy_nc_ok(tp, (struct fw_phy_nc *)block)) { - dev_err(&tp->intf->dev, - "check PHY NC firmware failed\n"); - goto fail; - } -+ __set_bit(FW_FLAGS_NC, &fw_flags); - - break; - default: -@@ -3922,7 +3929,7 @@ static long rtl8152_check_firmware(struc - } - - fw_end: -- if ((phy_nc || start) && !stop) { -+ if (test_bit(FW_FLAGS_START, &fw_flags) && !test_bit(FW_FLAGS_STOP, &fw_flags)) { - dev_err(&tp->intf->dev, "without PHY_STOP\n"); - goto fail; - } diff --git a/target/linux/bcm27xx/patches-5.10/950-0554-r8152-add-help-function-to-change-mtu.patch b/target/linux/bcm27xx/patches-5.10/950-0554-r8152-add-help-function-to-change-mtu.patch deleted file mode 100644 index 3559e3b95a..0000000000 --- a/target/linux/bcm27xx/patches-5.10/950-0554-r8152-add-help-function-to-change-mtu.patch +++ /dev/null @@ -1,157 +0,0 @@ -From f010a7d51cbb42bdb956f0a28b8868b15d7a3816 Mon Sep 17 00:00:00 2001 -From: Hayes Wang -Date: Fri, 16 Apr 2021 16:04:34 +0800 -Subject: [PATCH] r8152: add help function to change mtu - -commit 67ce1a806f164e59a074fea8809725d3411eaa20 upstream. - -The different chips may have different requests when changing mtu. -Therefore, add a new help function of rtl_ops to change mtu. Besides, -reset the tx/rx after changing mtu. - -Additionally, add mtu_to_size() and size_to_mtu() macros to simplify -the code. - -Signed-off-by: Hayes Wang -Signed-off-by: David S. Miller ---- - drivers/net/usb/r8152.c | 53 ++++++++++++++++++++++++----------------- - 1 file changed, 31 insertions(+), 22 deletions(-) - ---- a/drivers/net/usb/r8152.c -+++ b/drivers/net/usb/r8152.c -@@ -658,15 +658,13 @@ enum rtl_register_content { - - #define INTR_LINK 0x0004 - --#define RTL8153_MAX_PACKET 9216 /* 9K */ --#define RTL8153_MAX_MTU (RTL8153_MAX_PACKET - VLAN_ETH_HLEN - \ -- ETH_FCS_LEN) - #define RTL8152_RMS (VLAN_ETH_FRAME_LEN + ETH_FCS_LEN) - #define RTL8153_RMS RTL8153_MAX_PACKET - #define RTL8152_TX_TIMEOUT (5 * HZ) - #define RTL8152_NAPI_WEIGHT 64 --#define rx_reserved_size(x) ((x) + VLAN_ETH_HLEN + ETH_FCS_LEN + \ -- sizeof(struct rx_desc) + RX_ALIGN) -+#define mtu_to_size(m) ((m) + VLAN_ETH_HLEN + ETH_FCS_LEN) -+#define size_to_mtu(s) ((s) - VLAN_ETH_HLEN - ETH_FCS_LEN) -+#define rx_reserved_size(x) (mtu_to_size(x) + sizeof(struct rx_desc) + RX_ALIGN) - - /* rtl8152 flags */ - enum rtl8152_flags { -@@ -796,6 +794,7 @@ struct r8152 { - bool (*in_nway)(struct r8152 *tp); - void (*hw_phy_cfg)(struct r8152 *tp); - void (*autosuspend_en)(struct r8152 *tp, bool enable); -+ void (*change_mtu)(struct r8152 *tp); - } rtl_ops; - - struct ups_info { -@@ -1022,8 +1021,7 @@ enum tx_csum_stat { - static const int multicast_filter_limit = 32; - static unsigned int agg_buf_sz = 16384; - --#define RTL_LIMITED_TSO_SIZE (agg_buf_sz - sizeof(struct tx_desc) - \ -- VLAN_ETH_HLEN - ETH_FCS_LEN) -+#define RTL_LIMITED_TSO_SIZE (size_to_mtu(agg_buf_sz) - sizeof(struct tx_desc)) - - static - int get_registers(struct r8152 *tp, u16 value, u16 index, u16 size, void *data) -@@ -2633,10 +2631,7 @@ static void rtl8152_nic_reset(struct r81 - - static void set_tx_qlen(struct r8152 *tp) - { -- struct net_device *netdev = tp->netdev; -- -- tp->tx_qlen = agg_buf_sz / (netdev->mtu + VLAN_ETH_HLEN + ETH_FCS_LEN + -- sizeof(struct tx_desc)); -+ tp->tx_qlen = agg_buf_sz / (mtu_to_size(tp->netdev->mtu) + sizeof(struct tx_desc)); - } - - static inline u8 rtl8152_get_speed(struct r8152 *tp) -@@ -4725,6 +4720,12 @@ static void r8153b_hw_phy_cfg(struct r81 - set_bit(PHY_RESET, &tp->flags); - } - -+static void rtl8153_change_mtu(struct r8152 *tp) -+{ -+ ocp_write_word(tp, MCU_TYPE_PLA, PLA_RMS, mtu_to_size(tp->netdev->mtu)); -+ ocp_write_byte(tp, MCU_TYPE_PLA, PLA_MTPS, MTPS_JUMBO); -+} -+ - static void r8153_first_init(struct r8152 *tp) - { - u32 ocp_data; -@@ -4757,9 +4758,7 @@ static void r8153_first_init(struct r815 - - rtl_rx_vlan_en(tp, tp->netdev->features & NETIF_F_HW_VLAN_CTAG_RX); - -- ocp_data = tp->netdev->mtu + VLAN_ETH_HLEN + ETH_FCS_LEN; -- ocp_write_word(tp, MCU_TYPE_PLA, PLA_RMS, ocp_data); -- ocp_write_byte(tp, MCU_TYPE_PLA, PLA_MTPS, MTPS_JUMBO); -+ rtl8153_change_mtu(tp); - - ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_TCR0); - ocp_data |= TCR0_AUTO_FIFO; -@@ -4794,8 +4793,7 @@ static void r8153_enter_oob(struct r8152 - - wait_oob_link_list_ready(tp); - -- ocp_data = tp->netdev->mtu + VLAN_ETH_HLEN + ETH_FCS_LEN; -- ocp_write_word(tp, MCU_TYPE_PLA, PLA_RMS, ocp_data); -+ ocp_write_word(tp, MCU_TYPE_PLA, PLA_RMS, mtu_to_size(tp->netdev->mtu)); - - switch (tp->version) { - case RTL_VER_03: -@@ -6518,12 +6516,21 @@ static int rtl8152_change_mtu(struct net - dev->mtu = new_mtu; - - if (netif_running(dev)) { -- u32 rms = new_mtu + VLAN_ETH_HLEN + ETH_FCS_LEN; -- -- ocp_write_word(tp, MCU_TYPE_PLA, PLA_RMS, rms); -+ if (tp->rtl_ops.change_mtu) -+ tp->rtl_ops.change_mtu(tp); - -- if (netif_carrier_ok(dev)) -- r8153_set_rx_early_size(tp); -+ if (netif_carrier_ok(dev)) { -+ netif_stop_queue(dev); -+ napi_disable(&tp->napi); -+ tasklet_disable(&tp->tx_tl); -+ tp->rtl_ops.disable(tp); -+ tp->rtl_ops.enable(tp); -+ rtl_start_rx(tp); -+ tasklet_enable(&tp->tx_tl); -+ napi_enable(&tp->napi); -+ rtl8152_set_rx_mode(dev); -+ netif_wake_queue(dev); -+ } - } - - mutex_unlock(&tp->control); -@@ -6612,6 +6619,7 @@ static int rtl_ops_init(struct r8152 *tp - ops->in_nway = rtl8153_in_nway; - ops->hw_phy_cfg = r8153_hw_phy_cfg; - ops->autosuspend_en = rtl8153_runtime_enable; -+ ops->change_mtu = rtl8153_change_mtu; - if (tp->udev->speed < USB_SPEED_SUPER) - tp->rx_buf_sz = 16 * 1024; - else -@@ -6633,6 +6641,7 @@ static int rtl_ops_init(struct r8152 *tp - ops->in_nway = rtl8153_in_nway; - ops->hw_phy_cfg = r8153b_hw_phy_cfg; - ops->autosuspend_en = rtl8153b_runtime_enable; -+ ops->change_mtu = rtl8153_change_mtu; - tp->rx_buf_sz = 32 * 1024; - tp->eee_en = true; - tp->eee_adv = MDIO_EEE_1000T | MDIO_EEE_100TX; -@@ -6853,7 +6862,7 @@ static int rtl8152_probe(struct usb_inte - netdev->max_mtu = ETH_DATA_LEN; - break; - default: -- netdev->max_mtu = RTL8153_MAX_MTU; -+ netdev->max_mtu = size_to_mtu(9 * 1024); - break; - } - diff --git a/target/linux/bcm27xx/patches-5.10/950-0555-r8152-support-new-chips.patch b/target/linux/bcm27xx/patches-5.10/950-0555-r8152-support-new-chips.patch deleted file mode 100644 index 06a141b451..0000000000 --- a/target/linux/bcm27xx/patches-5.10/950-0555-r8152-support-new-chips.patch +++ /dev/null @@ -1,2886 +0,0 @@ -From e7439e7fd384f55f55837f7e4866e74d8dca3827 Mon Sep 17 00:00:00 2001 -From: Hayes Wang -Date: Fri, 16 Apr 2021 16:04:35 +0800 -Subject: [PATCH] r8152: support new chips - -commit 195aae321c829dd1945900d75561e6aa79cce208 upstream. - -Support RTL8153C, RTL8153D, RTL8156A, and RTL8156B. The RTL8156A -and RTL8156B are the 2.5G ethernet. - -Signed-off-by: Hayes Wang -Signed-off-by: David S. Miller ---- - drivers/net/usb/r8152.c | 2634 +++++++++++++++++++++++++++++++++++---- - 1 file changed, 2359 insertions(+), 275 deletions(-) - ---- a/drivers/net/usb/r8152.c -+++ b/drivers/net/usb/r8152.c -@@ -44,10 +44,14 @@ - - #define PLA_IDR 0xc000 - #define PLA_RCR 0xc010 -+#define PLA_RCR1 0xc012 - #define PLA_RMS 0xc016 - #define PLA_RXFIFO_CTRL0 0xc0a0 -+#define PLA_RXFIFO_FULL 0xc0a2 - #define PLA_RXFIFO_CTRL1 0xc0a4 -+#define PLA_RX_FIFO_FULL 0xc0a6 - #define PLA_RXFIFO_CTRL2 0xc0a8 -+#define PLA_RX_FIFO_EMPTY 0xc0aa - #define PLA_DMY_REG0 0xc0b0 - #define PLA_FMC 0xc0b4 - #define PLA_CFG_WOL 0xc0b6 -@@ -64,6 +68,8 @@ - #define PLA_MACDBG_PRE 0xd38c /* RTL_VER_04 only */ - #define PLA_MACDBG_POST 0xd38e /* RTL_VER_04 only */ - #define PLA_EXTRA_STATUS 0xd398 -+#define PLA_GPHY_CTRL 0xd3ae -+#define PLA_POL_GPIO_CTRL 0xdc6a - #define PLA_EFUSE_DATA 0xdd00 - #define PLA_EFUSE_CMD 0xdd02 - #define PLA_LEDSEL 0xdd90 -@@ -73,6 +79,8 @@ - #define PLA_LWAKE_CTRL_REG 0xe007 - #define PLA_GPHY_INTR_IMR 0xe022 - #define PLA_EEE_CR 0xe040 -+#define PLA_EEE_TXTWSYS 0xe04c -+#define PLA_EEE_TXTWSYS_2P5G 0xe058 - #define PLA_EEEP_CR 0xe080 - #define PLA_MAC_PWR_CTRL 0xe0c0 - #define PLA_MAC_PWR_CTRL2 0xe0ca -@@ -83,6 +91,7 @@ - #define PLA_TCR1 0xe612 - #define PLA_MTPS 0xe615 - #define PLA_TXFIFO_CTRL 0xe618 -+#define PLA_TXFIFO_FULL 0xe61a - #define PLA_RSTTALLY 0xe800 - #define PLA_CR 0xe813 - #define PLA_CRWECR 0xe81c -@@ -99,6 +108,7 @@ - #define PLA_SFF_STS_7 0xe8de - #define PLA_PHYSTATUS 0xe908 - #define PLA_CONFIG6 0xe90a /* CONFIG6 */ -+#define PLA_USB_CFG 0xe952 - #define PLA_BP_BA 0xfc26 - #define PLA_BP_0 0xfc28 - #define PLA_BP_1 0xfc2a -@@ -113,6 +123,7 @@ - #define USB_USB2PHY 0xb41e - #define USB_SSPHYLINK1 0xb426 - #define USB_SSPHYLINK2 0xb428 -+#define USB_L1_CTRL 0xb45e - #define USB_U2P3_CTRL 0xb460 - #define USB_CSR_DUMMY1 0xb464 - #define USB_CSR_DUMMY2 0xb466 -@@ -123,7 +134,12 @@ - #define USB_FW_FIX_EN0 0xcfca - #define USB_FW_FIX_EN1 0xcfcc - #define USB_LPM_CONFIG 0xcfd8 -+#define USB_ECM_OPTION 0xcfee - #define USB_CSTMR 0xcfef /* RTL8153A */ -+#define USB_MISC_2 0xcfff -+#define USB_ECM_OP 0xd26b -+#define USB_GPHY_CTRL 0xd284 -+#define USB_SPEED_OPTION 0xd32a - #define USB_FW_CTRL 0xd334 /* RTL8153B */ - #define USB_FC_TIMER 0xd340 - #define USB_USB_CTRL 0xd406 -@@ -137,16 +153,20 @@ - #define USB_RX_EXTRA_AGGR_TMR 0xd432 /* RTL8153B */ - #define USB_TX_DMA 0xd434 - #define USB_UPT_RXDMA_OWN 0xd437 -+#define USB_UPHY3_MDCMDIO 0xd480 - #define USB_TOLERANCE 0xd490 - #define USB_LPM_CTRL 0xd41a - #define USB_BMU_RESET 0xd4b0 -+#define USB_BMU_CONFIG 0xd4b4 - #define USB_U1U2_TIMER 0xd4da - #define USB_FW_TASK 0xd4e8 /* RTL8153B */ -+#define USB_RX_AGGR_NUM 0xd4ee - #define USB_UPS_CTRL 0xd800 - #define USB_POWER_CUT 0xd80a - #define USB_MISC_0 0xd81a - #define USB_MISC_1 0xd81f - #define USB_AFE_CTRL2 0xd824 -+#define USB_UPHY_XTAL 0xd826 - #define USB_UPS_CFG 0xd842 - #define USB_UPS_FLAGS 0xd848 - #define USB_WDT1_CTRL 0xe404 -@@ -189,6 +209,9 @@ - #define OCP_EEE_ABLE 0xa5c4 - #define OCP_EEE_ADV 0xa5d0 - #define OCP_EEE_LPABLE 0xa5d2 -+#define OCP_10GBT_CTRL 0xa5d4 -+#define OCP_10GBT_STAT 0xa5d6 -+#define OCP_EEE_ADV2 0xa6d4 - #define OCP_PHY_STATE 0xa708 /* nway state for 8153 */ - #define OCP_PHY_PATCH_STAT 0xb800 - #define OCP_PHY_PATCH_CMD 0xb820 -@@ -200,6 +223,7 @@ - /* SRAM Register */ - #define SRAM_GREEN_CFG 0x8011 - #define SRAM_LPF_CFG 0x8012 -+#define SRAM_GPHY_FW_VER 0x801e - #define SRAM_10M_AMP1 0x8080 - #define SRAM_10M_AMP2 0x8082 - #define SRAM_IMPEDANCE 0x8084 -@@ -211,11 +235,19 @@ - #define RCR_AM 0x00000004 - #define RCR_AB 0x00000008 - #define RCR_ACPT_ALL (RCR_AAP | RCR_APM | RCR_AM | RCR_AB) -+#define SLOT_EN BIT(11) -+ -+/* PLA_RCR1 */ -+#define OUTER_VLAN BIT(7) -+#define INNER_VLAN BIT(6) - - /* PLA_RXFIFO_CTRL0 */ - #define RXFIFO_THR1_NORMAL 0x00080002 - #define RXFIFO_THR1_OOB 0x01800003 - -+/* PLA_RXFIFO_FULL */ -+#define RXFIFO_FULL_MASK 0xfff -+ - /* PLA_RXFIFO_CTRL1 */ - #define RXFIFO_THR2_FULL 0x00000060 - #define RXFIFO_THR2_HIGH 0x00000038 -@@ -286,6 +318,7 @@ - #define MCU_BORW_EN 0x4000 - - /* PLA_CPCR */ -+#define FLOW_CTRL_EN BIT(0) - #define CPCR_RX_VLAN 0x0040 - - /* PLA_CFG_WOL */ -@@ -311,6 +344,10 @@ - /* PLA_CONFIG6 */ - #define LANWAKE_CLR_EN BIT(0) - -+/* PLA_USB_CFG */ -+#define EN_XG_LIP BIT(1) -+#define EN_G_LIP BIT(2) -+ - /* PLA_CONFIG5 */ - #define BWF_EN 0x0040 - #define MWF_EN 0x0020 -@@ -334,6 +371,7 @@ - /* PLA_MAC_PWR_CTRL2 */ - #define EEE_SPDWN_RATIO 0x8007 - #define MAC_CLK_SPDWN_EN BIT(15) -+#define EEE_SPDWN_RATIO_MASK 0xff - - /* PLA_MAC_PWR_CTRL3 */ - #define PLA_MCU_SPDWN_EN BIT(14) -@@ -346,6 +384,7 @@ - #define PWRSAVE_SPDWN_EN 0x1000 - #define RXDV_SPDWN_EN 0x0800 - #define TX10MIDLE_EN 0x0100 -+#define IDLE_SPDWN_EN BIT(6) - #define TP100_SPDWN_EN 0x0020 - #define TP500_SPDWN_EN 0x0010 - #define TP1000_SPDWN_EN 0x0008 -@@ -386,6 +425,13 @@ - #define LINK_CHANGE_FLAG BIT(8) - #define POLL_LINK_CHG BIT(0) - -+/* PLA_GPHY_CTRL */ -+#define GPHY_FLASH BIT(1) -+ -+/* PLA_POL_GPIO_CTRL */ -+#define DACK_DET_EN BIT(15) -+#define POL_GPHY_PATCH BIT(4) -+ - /* USB_USB2PHY */ - #define USB2PHY_SUSPEND 0x0001 - #define USB2PHY_L1 0x0002 -@@ -434,6 +480,9 @@ - #define BMU_RESET_EP_IN 0x01 - #define BMU_RESET_EP_OUT 0x02 - -+/* USB_BMU_CONFIG */ -+#define ACT_ODMA BIT(1) -+ - /* USB_UPT_RXDMA_OWN */ - #define OWN_UPDATE BIT(0) - #define OWN_CLEAR BIT(1) -@@ -441,27 +490,52 @@ - /* USB_FW_TASK */ - #define FC_PATCH_TASK BIT(1) - -+/* USB_RX_AGGR_NUM */ -+#define RX_AGGR_NUM_MASK 0x1ff -+ - /* USB_UPS_CTRL */ - #define POWER_CUT 0x0100 - - /* USB_PM_CTRL_STATUS */ - #define RESUME_INDICATE 0x0001 - -+/* USB_ECM_OPTION */ -+#define BYPASS_MAC_RESET BIT(5) -+ - /* USB_CSTMR */ - #define FORCE_SUPER BIT(0) - -+/* USB_MISC_2 */ -+#define UPS_FORCE_PWR_DOWN BIT(0) -+ -+/* USB_ECM_OP */ -+#define EN_ALL_SPEED BIT(0) -+ -+/* USB_GPHY_CTRL */ -+#define GPHY_PATCH_DONE BIT(2) -+#define BYPASS_FLASH BIT(5) -+#define BACKUP_RESTRORE BIT(6) -+ -+/* USB_SPEED_OPTION */ -+#define RG_PWRDN_EN BIT(8) -+#define ALL_SPEED_OFF BIT(9) -+ - /* USB_FW_CTRL */ - #define FLOW_CTRL_PATCH_OPT BIT(1) -+#define AUTO_SPEEDUP BIT(3) -+#define FLOW_CTRL_PATCH_2 BIT(8) - - /* USB_FC_TIMER */ - #define CTRL_TIMER_EN BIT(15) - - /* USB_USB_CTRL */ -+#define CDC_ECM_EN BIT(3) - #define RX_AGG_DISABLE 0x0010 - #define RX_ZERO_EN 0x0080 - - /* USB_U2P3_CTRL */ - #define U2P3_ENABLE 0x0001 -+#define RX_DETECT8 BIT(3) - - /* USB_POWER_CUT */ - #define PWR_EN 0x0001 -@@ -497,8 +571,12 @@ - #define SEN_VAL_NORMAL 0xa000 - #define SEL_RXIDLE 0x0100 - -+/* USB_UPHY_XTAL */ -+#define OOBS_POLLING BIT(8) -+ - /* USB_UPS_CFG */ - #define SAW_CNT_1MS_MASK 0x0fff -+#define MID_REVERSE BIT(5) /* RTL8156A */ - - /* USB_UPS_FLAGS */ - #define UPS_FLAGS_R_TUNE BIT(0) -@@ -506,6 +584,7 @@ - #define UPS_FLAGS_250M_CKDIV BIT(2) - #define UPS_FLAGS_EN_ALDPS BIT(3) - #define UPS_FLAGS_CTAP_SHORT_DIS BIT(4) -+#define UPS_FLAGS_SPEED_MASK (0xf << 16) - #define ups_flags_speed(x) ((x) << 16) - #define UPS_FLAGS_EN_EEE BIT(20) - #define UPS_FLAGS_EN_500M_EEE BIT(21) -@@ -526,6 +605,8 @@ enum spd_duplex { - FORCE_10M_FULL, - FORCE_100M_HALF, - FORCE_100M_FULL, -+ FORCE_1000M_FULL, -+ NWAY_2500M_FULL, - }; - - /* OCP_ALDPS_CONFIG */ -@@ -590,6 +671,9 @@ enum spd_duplex { - #define EN_10M_CLKDIV BIT(11) - #define EN_10M_BGOFF 0x0080 - -+/* OCP_10GBT_CTRL */ -+#define RTL_ADV2_5G_F_R BIT(5) /* Advertise 2.5GBASE-T fast-retrain */ -+ - /* OCP_PHY_STATE */ - #define TXDIS_STATE 0x01 - #define ABD_STATE 0x02 -@@ -609,7 +693,8 @@ enum spd_duplex { - #define EN_EMI_L 0x0040 - - /* OCP_SYSCLK_CFG */ --#define clk_div_expo(x) (min(x, 5) << 8) -+#define sysclk_div_expo(x) (min(x, 5) << 8) -+#define clk_div_expo(x) (min(x, 5) << 4) - - /* SRAM_GREEN_CFG */ - #define GREEN_ETH_EN BIT(15) -@@ -640,6 +725,11 @@ enum spd_duplex { - #define BP4_SUPER_ONLY 0x1578 /* RTL_VER_04 only */ - - enum rtl_register_content { -+ _2500bps = BIT(10), -+ _1250bps = BIT(9), -+ _500bps = BIT(8), -+ _tx_flow = BIT(6), -+ _rx_flow = BIT(5), - _1000bps = 0x10, - _100bps = 0x08, - _10bps = 0x04, -@@ -647,6 +737,9 @@ enum rtl_register_content { - FULL_DUP = 0x01, - }; - -+#define is_speed_2500(_speed) (((_speed) & (_2500bps | LINK_STATUS)) == (_2500bps | LINK_STATUS)) -+#define is_flow_control(_speed) (((_speed) & (_tx_flow | _rx_flow)) == (_tx_flow | _rx_flow)) -+ - #define RTL8152_MAX_TX 4 - #define RTL8152_MAX_RX 10 - #define INTBUFSIZE 2 -@@ -661,7 +754,6 @@ enum rtl_register_content { - #define RTL8152_RMS (VLAN_ETH_FRAME_LEN + ETH_FCS_LEN) - #define RTL8153_RMS RTL8153_MAX_PACKET - #define RTL8152_TX_TIMEOUT (5 * HZ) --#define RTL8152_NAPI_WEIGHT 64 - #define mtu_to_size(m) ((m) + VLAN_ETH_HLEN + ETH_FCS_LEN) - #define size_to_mtu(s) ((s) - VLAN_ETH_HLEN - ETH_FCS_LEN) - #define rx_reserved_size(x) (mtu_to_size(x) + sizeof(struct rx_desc) + RX_ALIGN) -@@ -798,6 +890,7 @@ struct r8152 { - } rtl_ops; - - struct ups_info { -+ u32 r_tune:1; - u32 _10m_ckdiv:1; - u32 _250m_ckdiv:1; - u32 aldps:1; -@@ -839,7 +932,9 @@ struct r8152 { - u32 rx_buf_sz; - u32 rx_copybreak; - u32 rx_pending; -+ u32 fc_pause_on, fc_pause_off; - -+ u32 support_2500full:1; - u16 ocp_base; - u16 speed; - u16 eee_adv; -@@ -999,6 +1094,15 @@ enum rtl_version { - RTL_VER_07, - RTL_VER_08, - RTL_VER_09, -+ -+ RTL_TEST_01, -+ RTL_VER_10, -+ RTL_VER_11, -+ RTL_VER_12, -+ RTL_VER_13, -+ RTL_VER_14, -+ RTL_VER_15, -+ - RTL_VER_MAX - }; - -@@ -1014,6 +1118,7 @@ enum tx_csum_stat { - #define RTL_ADVERTISED_100_FULL BIT(3) - #define RTL_ADVERTISED_1000_HALF BIT(4) - #define RTL_ADVERTISED_1000_FULL BIT(5) -+#define RTL_ADVERTISED_2500_FULL BIT(6) - - /* Maximum number of multicast addresses to filter (vs. Rx-all-multicast). - * The RTL chips use a 64 element hash table based on the Ethernet CRC. -@@ -2607,7 +2712,7 @@ static netdev_tx_t rtl8152_start_xmit(st - - static void r8152b_reset_packet_filter(struct r8152 *tp) - { -- u32 ocp_data; -+ u32 ocp_data; - - ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_FMC); - ocp_data &= ~FMC_FCR_MCU_EN; -@@ -2618,14 +2723,47 @@ static void r8152b_reset_packet_filter(s - - static void rtl8152_nic_reset(struct r8152 *tp) - { -- int i; -+ u32 ocp_data; -+ int i; - -- ocp_write_byte(tp, MCU_TYPE_PLA, PLA_CR, CR_RST); -+ switch (tp->version) { -+ case RTL_TEST_01: -+ case RTL_VER_10: -+ case RTL_VER_11: -+ ocp_data = ocp_read_byte(tp, MCU_TYPE_PLA, PLA_CR); -+ ocp_data &= ~CR_TE; -+ ocp_write_byte(tp, MCU_TYPE_PLA, PLA_CR, ocp_data); -+ -+ ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_BMU_RESET); -+ ocp_data &= ~BMU_RESET_EP_IN; -+ ocp_write_word(tp, MCU_TYPE_USB, USB_BMU_RESET, ocp_data); -+ -+ ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_USB_CTRL); -+ ocp_data |= CDC_ECM_EN; -+ ocp_write_word(tp, MCU_TYPE_USB, USB_USB_CTRL, ocp_data); -+ -+ ocp_data = ocp_read_byte(tp, MCU_TYPE_PLA, PLA_CR); -+ ocp_data &= ~CR_RE; -+ ocp_write_byte(tp, MCU_TYPE_PLA, PLA_CR, ocp_data); -+ -+ ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_BMU_RESET); -+ ocp_data |= BMU_RESET_EP_IN; -+ ocp_write_word(tp, MCU_TYPE_USB, USB_BMU_RESET, ocp_data); -+ -+ ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_USB_CTRL); -+ ocp_data &= ~CDC_ECM_EN; -+ ocp_write_word(tp, MCU_TYPE_USB, USB_USB_CTRL, ocp_data); -+ break; - -- for (i = 0; i < 1000; i++) { -- if (!(ocp_read_byte(tp, MCU_TYPE_PLA, PLA_CR) & CR_RST)) -- break; -- usleep_range(100, 400); -+ default: -+ ocp_write_byte(tp, MCU_TYPE_PLA, PLA_CR, CR_RST); -+ -+ for (i = 0; i < 1000; i++) { -+ if (!(ocp_read_byte(tp, MCU_TYPE_PLA, PLA_CR) & CR_RST)) -+ break; -+ usleep_range(100, 400); -+ } -+ break; - } - } - -@@ -2634,9 +2772,9 @@ static void set_tx_qlen(struct r8152 *tp - tp->tx_qlen = agg_buf_sz / (mtu_to_size(tp->netdev->mtu) + sizeof(struct tx_desc)); - } - --static inline u8 rtl8152_get_speed(struct r8152 *tp) -+static inline u16 rtl8152_get_speed(struct r8152 *tp) - { -- return ocp_read_byte(tp, MCU_TYPE_PLA, PLA_PHYSTATUS); -+ return ocp_read_word(tp, MCU_TYPE_PLA, PLA_PHYSTATUS); - } - - static void rtl_eee_plus_en(struct r8152 *tp, bool enable) -@@ -2796,6 +2934,7 @@ static int rtl_enable(struct r8152 *tp) - switch (tp->version) { - case RTL_VER_08: - case RTL_VER_09: -+ case RTL_VER_14: - r8153b_rx_agg_chg_indicate(tp); - break; - default: -@@ -2833,6 +2972,7 @@ static void r8153_set_rx_early_timeout(s - - case RTL_VER_08: - case RTL_VER_09: -+ case RTL_VER_14: - /* The RTL8153B uses USB_RX_EXTRA_AGGR_TMR for rx timeout - * primarily. For USB_RX_EARLY_TIMEOUT, we fix it to 128ns. - */ -@@ -2842,6 +2982,18 @@ static void r8153_set_rx_early_timeout(s - ocp_data); - break; - -+ case RTL_VER_10: -+ case RTL_VER_11: -+ case RTL_VER_12: -+ case RTL_VER_13: -+ case RTL_VER_15: -+ ocp_write_word(tp, MCU_TYPE_USB, USB_RX_EARLY_TIMEOUT, -+ 640 / 8); -+ ocp_write_word(tp, MCU_TYPE_USB, USB_RX_EXTRA_AGGR_TMR, -+ ocp_data); -+ r8153b_rx_agg_chg_indicate(tp); -+ break; -+ - default: - break; - } -@@ -2861,8 +3013,19 @@ static void r8153_set_rx_early_size(stru - break; - case RTL_VER_08: - case RTL_VER_09: -+ case RTL_VER_14: -+ ocp_write_word(tp, MCU_TYPE_USB, USB_RX_EARLY_SIZE, -+ ocp_data / 8); -+ break; -+ case RTL_TEST_01: -+ case RTL_VER_10: -+ case RTL_VER_11: -+ case RTL_VER_12: -+ case RTL_VER_13: -+ case RTL_VER_15: - ocp_write_word(tp, MCU_TYPE_USB, USB_RX_EARLY_SIZE, - ocp_data / 8); -+ r8153b_rx_agg_chg_indicate(tp); - break; - default: - WARN_ON_ONCE(1); -@@ -2872,6 +3035,8 @@ static void r8153_set_rx_early_size(stru - - static int rtl8153_enable(struct r8152 *tp) - { -+ u32 ocp_data; -+ - if (test_bit(RTL8152_UNPLUG, &tp->flags)) - return -ENODEV; - -@@ -2882,15 +3047,18 @@ static int rtl8153_enable(struct r8152 * - - rtl_set_ifg(tp, rtl8152_get_speed(tp)); - -- if (tp->version == RTL_VER_09) { -- u32 ocp_data; -- -+ switch (tp->version) { -+ case RTL_VER_09: -+ case RTL_VER_14: - ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_FW_TASK); - ocp_data &= ~FC_PATCH_TASK; - ocp_write_word(tp, MCU_TYPE_USB, USB_FW_TASK, ocp_data); - usleep_range(1000, 2000); - ocp_data |= FC_PATCH_TASK; - ocp_write_word(tp, MCU_TYPE_USB, USB_FW_TASK, ocp_data); -+ break; -+ default: -+ break; - } - - return rtl_enable(tp); -@@ -2955,12 +3123,40 @@ static void rtl_rx_vlan_en(struct r8152 - { - u32 ocp_data; - -- ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_CPCR); -- if (enable) -- ocp_data |= CPCR_RX_VLAN; -- else -- ocp_data &= ~CPCR_RX_VLAN; -- ocp_write_word(tp, MCU_TYPE_PLA, PLA_CPCR, ocp_data); -+ switch (tp->version) { -+ case RTL_VER_01: -+ case RTL_VER_02: -+ case RTL_VER_03: -+ case RTL_VER_04: -+ case RTL_VER_05: -+ case RTL_VER_06: -+ case RTL_VER_07: -+ case RTL_VER_08: -+ case RTL_VER_09: -+ case RTL_VER_14: -+ ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_CPCR); -+ if (enable) -+ ocp_data |= CPCR_RX_VLAN; -+ else -+ ocp_data &= ~CPCR_RX_VLAN; -+ ocp_write_word(tp, MCU_TYPE_PLA, PLA_CPCR, ocp_data); -+ break; -+ -+ case RTL_TEST_01: -+ case RTL_VER_10: -+ case RTL_VER_11: -+ case RTL_VER_12: -+ case RTL_VER_13: -+ case RTL_VER_15: -+ default: -+ ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_RCR1); -+ if (enable) -+ ocp_data |= OUTER_VLAN | INNER_VLAN; -+ else -+ ocp_data &= ~(OUTER_VLAN | INNER_VLAN); -+ ocp_write_word(tp, MCU_TYPE_PLA, PLA_RCR1, ocp_data); -+ break; -+ } - } - - static int rtl8152_set_features(struct net_device *dev, -@@ -3053,6 +3249,40 @@ static void __rtl_set_wol(struct r8152 * - device_set_wakeup_enable(&tp->udev->dev, false); - } - -+static void r8153_mac_clk_speed_down(struct r8152 *tp, bool enable) -+{ -+ u32 ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL2); -+ -+ /* MAC clock speed down */ -+ if (enable) -+ ocp_data |= MAC_CLK_SPDWN_EN; -+ else -+ ocp_data &= ~MAC_CLK_SPDWN_EN; -+ -+ ocp_write_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL2, ocp_data); -+} -+ -+static void r8156_mac_clk_spd(struct r8152 *tp, bool enable) -+{ -+ u32 ocp_data; -+ -+ /* MAC clock speed down */ -+ if (enable) { -+ /* aldps_spdwn_ratio, tp10_spdwn_ratio */ -+ ocp_write_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL, -+ 0x0403); -+ -+ ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL2); -+ ocp_data &= ~EEE_SPDWN_RATIO_MASK; -+ ocp_data |= MAC_CLK_SPDWN_EN | 0x03; /* eee_spdwn_ratio */ -+ ocp_write_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL2, ocp_data); -+ } else { -+ ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL2); -+ ocp_data &= ~MAC_CLK_SPDWN_EN; -+ ocp_write_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL2, ocp_data); -+ } -+} -+ - static void r8153_u1u2en(struct r8152 *tp, bool enable) - { - u8 u1u2[8]; -@@ -3112,6 +3342,9 @@ static void r8153b_ups_flags(struct r815 - if (tp->ups_info.eee_cmod_lv) - ups_flags |= UPS_FLAGS_EEE_CMOD_LV_EN; - -+ if (tp->ups_info.r_tune) -+ ups_flags |= UPS_FLAGS_R_TUNE; -+ - if (tp->ups_info._10m_ckdiv) - ups_flags |= UPS_FLAGS_EN_10M_CKDIV; - -@@ -3162,6 +3395,88 @@ static void r8153b_ups_flags(struct r815 - ocp_write_dword(tp, MCU_TYPE_USB, USB_UPS_FLAGS, ups_flags); - } - -+static void r8156_ups_flags(struct r8152 *tp) -+{ -+ u32 ups_flags = 0; -+ -+ if (tp->ups_info.green) -+ ups_flags |= UPS_FLAGS_EN_GREEN; -+ -+ if (tp->ups_info.aldps) -+ ups_flags |= UPS_FLAGS_EN_ALDPS; -+ -+ if (tp->ups_info.eee) -+ ups_flags |= UPS_FLAGS_EN_EEE; -+ -+ if (tp->ups_info.flow_control) -+ ups_flags |= UPS_FLAGS_EN_FLOW_CTR; -+ -+ if (tp->ups_info.eee_ckdiv) -+ ups_flags |= UPS_FLAGS_EN_EEE_CKDIV; -+ -+ if (tp->ups_info._10m_ckdiv) -+ ups_flags |= UPS_FLAGS_EN_10M_CKDIV; -+ -+ if (tp->ups_info.eee_plloff_100) -+ ups_flags |= UPS_FLAGS_EEE_PLLOFF_100; -+ -+ if (tp->ups_info.eee_plloff_giga) -+ ups_flags |= UPS_FLAGS_EEE_PLLOFF_GIGA; -+ -+ if (tp->ups_info._250m_ckdiv) -+ ups_flags |= UPS_FLAGS_250M_CKDIV; -+ -+ switch (tp->ups_info.speed_duplex) { -+ case FORCE_10M_HALF: -+ ups_flags |= ups_flags_speed(0); -+ break; -+ case FORCE_10M_FULL: -+ ups_flags |= ups_flags_speed(1); -+ break; -+ case FORCE_100M_HALF: -+ ups_flags |= ups_flags_speed(2); -+ break; -+ case FORCE_100M_FULL: -+ ups_flags |= ups_flags_speed(3); -+ break; -+ case NWAY_10M_HALF: -+ ups_flags |= ups_flags_speed(4); -+ break; -+ case NWAY_10M_FULL: -+ ups_flags |= ups_flags_speed(5); -+ break; -+ case NWAY_100M_HALF: -+ ups_flags |= ups_flags_speed(6); -+ break; -+ case NWAY_100M_FULL: -+ ups_flags |= ups_flags_speed(7); -+ break; -+ case NWAY_1000M_FULL: -+ ups_flags |= ups_flags_speed(8); -+ break; -+ case NWAY_2500M_FULL: -+ ups_flags |= ups_flags_speed(9); -+ break; -+ default: -+ break; -+ } -+ -+ switch (tp->ups_info.lite_mode) { -+ case 1: -+ ups_flags |= 0 << 5; -+ break; -+ case 2: -+ ups_flags |= 2 << 5; -+ break; -+ case 0: -+ default: -+ ups_flags |= 1 << 5; -+ break; -+ } -+ -+ ocp_write_dword(tp, MCU_TYPE_USB, USB_UPS_FLAGS, ups_flags); -+} -+ - static void rtl_green_en(struct r8152 *tp, bool enable) - { - u16 data; -@@ -3225,16 +3540,16 @@ static void r8153b_ups_en(struct r8152 * - ocp_data |= UPS_EN | USP_PREWAKE | PHASE2_EN; - ocp_write_byte(tp, MCU_TYPE_USB, USB_POWER_CUT, ocp_data); - -- ocp_data = ocp_read_byte(tp, MCU_TYPE_USB, 0xcfff); -- ocp_data |= BIT(0); -- ocp_write_byte(tp, MCU_TYPE_USB, 0xcfff, ocp_data); -+ ocp_data = ocp_read_byte(tp, MCU_TYPE_USB, USB_MISC_2); -+ ocp_data |= UPS_FORCE_PWR_DOWN; -+ ocp_write_byte(tp, MCU_TYPE_USB, USB_MISC_2, ocp_data); - } else { - ocp_data &= ~(UPS_EN | USP_PREWAKE); - ocp_write_byte(tp, MCU_TYPE_USB, USB_POWER_CUT, ocp_data); - -- ocp_data = ocp_read_byte(tp, MCU_TYPE_USB, 0xcfff); -- ocp_data &= ~BIT(0); -- ocp_write_byte(tp, MCU_TYPE_USB, 0xcfff, ocp_data); -+ ocp_data = ocp_read_byte(tp, MCU_TYPE_USB, USB_MISC_2); -+ ocp_data &= ~UPS_FORCE_PWR_DOWN; -+ ocp_write_byte(tp, MCU_TYPE_USB, USB_MISC_2, ocp_data); - - if (ocp_read_word(tp, MCU_TYPE_USB, USB_MISC_0) & PCUT_STATUS) { - int i; -@@ -3254,6 +3569,95 @@ static void r8153b_ups_en(struct r8152 * - } - } - -+static void r8153c_ups_en(struct r8152 *tp, bool enable) -+{ -+ u32 ocp_data = ocp_read_byte(tp, MCU_TYPE_USB, USB_POWER_CUT); -+ -+ if (enable) { -+ r8153b_ups_flags(tp); -+ -+ ocp_data |= UPS_EN | USP_PREWAKE | PHASE2_EN; -+ ocp_write_byte(tp, MCU_TYPE_USB, USB_POWER_CUT, ocp_data); -+ -+ ocp_data = ocp_read_byte(tp, MCU_TYPE_USB, USB_MISC_2); -+ ocp_data |= UPS_FORCE_PWR_DOWN; -+ ocp_data &= ~BIT(7); -+ ocp_write_byte(tp, MCU_TYPE_USB, USB_MISC_2, ocp_data); -+ } else { -+ ocp_data &= ~(UPS_EN | USP_PREWAKE); -+ ocp_write_byte(tp, MCU_TYPE_USB, USB_POWER_CUT, ocp_data); -+ -+ ocp_data = ocp_read_byte(tp, MCU_TYPE_USB, USB_MISC_2); -+ ocp_data &= ~UPS_FORCE_PWR_DOWN; -+ ocp_write_byte(tp, MCU_TYPE_USB, USB_MISC_2, ocp_data); -+ -+ if (ocp_read_word(tp, MCU_TYPE_USB, USB_MISC_0) & PCUT_STATUS) { -+ int i; -+ -+ for (i = 0; i < 500; i++) { -+ if (ocp_read_word(tp, MCU_TYPE_PLA, PLA_BOOT_CTRL) & -+ AUTOLOAD_DONE) -+ break; -+ msleep(20); -+ } -+ -+ tp->rtl_ops.hw_phy_cfg(tp); -+ -+ rtl8152_set_speed(tp, tp->autoneg, tp->speed, -+ tp->duplex, tp->advertising); -+ } -+ -+ ocp_write_byte(tp, MCU_TYPE_PLA, PLA_CRWECR, CRWECR_CONFIG); -+ -+ ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_CONFIG34); -+ ocp_data |= BIT(8); -+ ocp_write_word(tp, MCU_TYPE_PLA, PLA_CONFIG34, ocp_data); -+ -+ ocp_write_byte(tp, MCU_TYPE_PLA, PLA_CRWECR, CRWECR_NORAML); -+ } -+} -+ -+static void r8156_ups_en(struct r8152 *tp, bool enable) -+{ -+ u32 ocp_data = ocp_read_byte(tp, MCU_TYPE_USB, USB_POWER_CUT); -+ -+ if (enable) { -+ r8156_ups_flags(tp); -+ -+ ocp_data |= UPS_EN | USP_PREWAKE | PHASE2_EN; -+ ocp_write_byte(tp, MCU_TYPE_USB, USB_POWER_CUT, ocp_data); -+ -+ ocp_data = ocp_read_byte(tp, MCU_TYPE_USB, USB_MISC_2); -+ ocp_data |= UPS_FORCE_PWR_DOWN; -+ ocp_write_byte(tp, MCU_TYPE_USB, USB_MISC_2, ocp_data); -+ -+ switch (tp->version) { -+ case RTL_VER_13: -+ case RTL_VER_15: -+ ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_UPHY_XTAL); -+ ocp_data &= ~OOBS_POLLING; -+ ocp_write_byte(tp, MCU_TYPE_USB, USB_UPHY_XTAL, ocp_data); -+ break; -+ default: -+ break; -+ } -+ } else { -+ ocp_data &= ~(UPS_EN | USP_PREWAKE); -+ ocp_write_byte(tp, MCU_TYPE_USB, USB_POWER_CUT, ocp_data); -+ -+ ocp_data = ocp_read_byte(tp, MCU_TYPE_USB, USB_MISC_2); -+ ocp_data &= ~UPS_FORCE_PWR_DOWN; -+ ocp_write_byte(tp, MCU_TYPE_USB, USB_MISC_2, ocp_data); -+ -+ if (ocp_read_word(tp, MCU_TYPE_USB, USB_MISC_0) & PCUT_STATUS) { -+ tp->rtl_ops.hw_phy_cfg(tp); -+ -+ rtl8152_set_speed(tp, tp->autoneg, tp->speed, -+ tp->duplex, tp->advertising); -+ } -+ } -+} -+ - static void r8153_power_cut_en(struct r8152 *tp, bool enable) - { - u32 ocp_data; -@@ -3383,6 +3787,38 @@ static void rtl8153b_runtime_enable(stru - } - } - -+static void rtl8153c_runtime_enable(struct r8152 *tp, bool enable) -+{ -+ if (enable) { -+ r8153_queue_wake(tp, true); -+ r8153b_u1u2en(tp, false); -+ r8153_u2p3en(tp, false); -+ rtl_runtime_suspend_enable(tp, true); -+ r8153c_ups_en(tp, true); -+ } else { -+ r8153c_ups_en(tp, false); -+ r8153_queue_wake(tp, false); -+ rtl_runtime_suspend_enable(tp, false); -+ r8153b_u1u2en(tp, true); -+ } -+} -+ -+static void rtl8156_runtime_enable(struct r8152 *tp, bool enable) -+{ -+ if (enable) { -+ r8153_queue_wake(tp, true); -+ r8153b_u1u2en(tp, false); -+ r8153_u2p3en(tp, false); -+ rtl_runtime_suspend_enable(tp, true); -+ } else { -+ r8153_queue_wake(tp, false); -+ rtl_runtime_suspend_enable(tp, false); -+ r8153_u2p3en(tp, true); -+ if (tp->udev->speed >= USB_SPEED_SUPER) -+ r8153b_u1u2en(tp, true); -+ } -+} -+ - static void r8153_teredo_off(struct r8152 *tp) - { - u32 ocp_data; -@@ -3403,14 +3839,19 @@ static void r8153_teredo_off(struct r815 - - case RTL_VER_08: - case RTL_VER_09: -+ case RTL_TEST_01: -+ case RTL_VER_10: -+ case RTL_VER_11: -+ case RTL_VER_12: -+ case RTL_VER_13: -+ case RTL_VER_14: -+ case RTL_VER_15: -+ default: - /* The bit 0 ~ 7 are relative with teredo settings. They are - * W1C (write 1 to clear), so set all 1 to disable it. - */ - ocp_write_byte(tp, MCU_TYPE_PLA, PLA_TEREDO_CFG, 0xff); - break; -- -- default: -- break; - } - - ocp_write_word(tp, MCU_TYPE_PLA, PLA_WDT6_CTRL, WDT6_SET_MODE); -@@ -3445,6 +3886,12 @@ static void rtl_clear_bp(struct r8152 *t - break; - case RTL_VER_08: - case RTL_VER_09: -+ case RTL_VER_10: -+ case RTL_VER_11: -+ case RTL_VER_12: -+ case RTL_VER_13: -+ case RTL_VER_14: -+ case RTL_VER_15: - default: - if (type == MCU_TYPE_USB) { - ocp_write_word(tp, MCU_TYPE_USB, USB_BP2_EN, 0); -@@ -3654,6 +4101,11 @@ static bool rtl8152_is_fw_mac_ok(struct - case RTL_VER_06: - case RTL_VER_08: - case RTL_VER_09: -+ case RTL_VER_11: -+ case RTL_VER_12: -+ case RTL_VER_13: -+ case RTL_VER_14: -+ case RTL_VER_15: - fw_reg = 0xf800; - bp_ba_addr = PLA_BP_BA; - bp_en_addr = PLA_BP_EN; -@@ -3677,6 +4129,11 @@ static bool rtl8152_is_fw_mac_ok(struct - break; - case RTL_VER_08: - case RTL_VER_09: -+ case RTL_VER_11: -+ case RTL_VER_12: -+ case RTL_VER_13: -+ case RTL_VER_14: -+ case RTL_VER_15: - fw_reg = 0xe600; - bp_ba_addr = USB_BP_BA; - bp_en_addr = USB_BP2_EN; -@@ -4216,6 +4673,22 @@ static void r8153_eee_en(struct r8152 *t - tp->ups_info.eee = enable; - } - -+static void r8156_eee_en(struct r8152 *tp, bool enable) -+{ -+ u16 config; -+ -+ r8153_eee_en(tp, enable); -+ -+ config = ocp_reg_read(tp, OCP_EEE_ADV2); -+ -+ if (enable) -+ config |= MDIO_EEE_2_5GT; -+ else -+ config &= ~MDIO_EEE_2_5GT; -+ -+ ocp_reg_write(tp, OCP_EEE_ADV2, config); -+} -+ - static void rtl_eee_enable(struct r8152 *tp, bool enable) - { - switch (tp->version) { -@@ -4237,6 +4710,7 @@ static void rtl_eee_enable(struct r8152 - case RTL_VER_06: - case RTL_VER_08: - case RTL_VER_09: -+ case RTL_VER_14: - if (enable) { - r8153_eee_en(tp, true); - ocp_reg_write(tp, OCP_EEE_ADV, tp->eee_adv); -@@ -4245,6 +4719,19 @@ static void rtl_eee_enable(struct r8152 - ocp_reg_write(tp, OCP_EEE_ADV, 0); - } - break; -+ case RTL_VER_10: -+ case RTL_VER_11: -+ case RTL_VER_12: -+ case RTL_VER_13: -+ case RTL_VER_15: -+ if (enable) { -+ r8156_eee_en(tp, true); -+ ocp_reg_write(tp, OCP_EEE_ADV, tp->eee_adv); -+ } else { -+ r8156_eee_en(tp, false); -+ ocp_reg_write(tp, OCP_EEE_ADV, 0); -+ } -+ break; - default: - break; - } -@@ -4291,6 +4778,20 @@ static void wait_oob_link_list_ready(str - } - } - -+static void r8156b_wait_loading_flash(struct r8152 *tp) -+{ -+ if ((ocp_read_word(tp, MCU_TYPE_PLA, PLA_GPHY_CTRL) & GPHY_FLASH) && -+ !(ocp_read_word(tp, MCU_TYPE_USB, USB_GPHY_CTRL) & BYPASS_FLASH)) { -+ int i; -+ -+ for (i = 0; i < 100; i++) { -+ if (ocp_read_word(tp, MCU_TYPE_USB, USB_GPHY_CTRL) & GPHY_PATCH_DONE) -+ break; -+ usleep_range(1000, 2000); -+ } -+ } -+} -+ - static void r8152b_exit_oob(struct r8152 *tp) - { - u32 ocp_data; -@@ -4341,7 +4842,7 @@ static void r8152b_exit_oob(struct r8152 - } - - /* TX share fifo free credit full threshold */ -- ocp_write_dword(tp, MCU_TYPE_PLA, PLA_TXFIFO_CTRL, TXFIFO_THR_NORMAL); -+ ocp_write_dword(tp, MCU_TYPE_PLA, PLA_TXFIFO_CTRL, TXFIFO_THR_NORMAL2); - - ocp_write_byte(tp, MCU_TYPE_USB, USB_TX_AGG, TX_AGG_MAX_THRESHOLD); - ocp_write_dword(tp, MCU_TYPE_USB, USB_RX_BUF_TH, RX_THR_HIGH); -@@ -4518,6 +5019,21 @@ static int r8153b_post_firmware_1(struct - return 0; - } - -+static int r8153c_post_firmware_1(struct r8152 *tp) -+{ -+ u32 ocp_data; -+ -+ ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_FW_CTRL); -+ ocp_data |= FLOW_CTRL_PATCH_2; -+ ocp_write_word(tp, MCU_TYPE_USB, USB_FW_CTRL, ocp_data); -+ -+ ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_FW_TASK); -+ ocp_data |= FC_PATCH_TASK; -+ ocp_write_word(tp, MCU_TYPE_USB, USB_FW_TASK, ocp_data); -+ -+ return 0; -+} -+ - static void r8153_aldps_en(struct r8152 *tp, bool enable) - { - u16 data; -@@ -4720,6 +5236,13 @@ static void r8153b_hw_phy_cfg(struct r81 - set_bit(PHY_RESET, &tp->flags); - } - -+static void r8153c_hw_phy_cfg(struct r8152 *tp) -+{ -+ r8153b_hw_phy_cfg(tp); -+ -+ tp->ups_info.r_tune = true; -+} -+ - static void rtl8153_change_mtu(struct r8152 *tp) - { - ocp_write_word(tp, MCU_TYPE_PLA, PLA_RMS, mtu_to_size(tp->netdev->mtu)); -@@ -4807,6 +5330,7 @@ static void r8153_enter_oob(struct r8152 - - case RTL_VER_08: - case RTL_VER_09: -+ case RTL_VER_14: - /* Clear teredo wake event. bit[15:8] is the teredo wakeup - * type. Set it to zero. bits[7:0] are the W1C bits about - * the events. Set them to all 1 to clear them. -@@ -4843,6 +5367,96 @@ static void rtl8153_disable(struct r8152 - r8153_aldps_en(tp, true); - } - -+static int rtl8156_enable(struct r8152 *tp) -+{ -+ u32 ocp_data; -+ u16 speed; -+ -+ if (test_bit(RTL8152_UNPLUG, &tp->flags)) -+ return -ENODEV; -+ -+ set_tx_qlen(tp); -+ rtl_set_eee_plus(tp); -+ r8153_set_rx_early_timeout(tp); -+ r8153_set_rx_early_size(tp); -+ -+ speed = rtl8152_get_speed(tp); -+ rtl_set_ifg(tp, speed); -+ -+ ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL4); -+ if (speed & _2500bps) -+ ocp_data &= ~IDLE_SPDWN_EN; -+ else -+ ocp_data |= IDLE_SPDWN_EN; -+ ocp_write_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL4, ocp_data); -+ -+ if (speed & _1000bps) -+ ocp_write_word(tp, MCU_TYPE_PLA, PLA_EEE_TXTWSYS, 0x11); -+ else if (speed & _500bps) -+ ocp_write_word(tp, MCU_TYPE_PLA, PLA_EEE_TXTWSYS, 0x3d); -+ -+ if (tp->udev->speed == USB_SPEED_HIGH) { -+ /* USB 0xb45e[3:0] l1_nyet_hird */ -+ ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_L1_CTRL); -+ ocp_data &= ~0xf; -+ if (is_flow_control(speed)) -+ ocp_data |= 0xf; -+ else -+ ocp_data |= 0x1; -+ ocp_write_word(tp, MCU_TYPE_USB, USB_L1_CTRL, ocp_data); -+ } -+ -+ return rtl_enable(tp); -+} -+ -+static int rtl8156b_enable(struct r8152 *tp) -+{ -+ u32 ocp_data; -+ u16 speed; -+ -+ if (test_bit(RTL8152_UNPLUG, &tp->flags)) -+ return -ENODEV; -+ -+ set_tx_qlen(tp); -+ rtl_set_eee_plus(tp); -+ -+ ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_RX_AGGR_NUM); -+ ocp_data &= ~RX_AGGR_NUM_MASK; -+ ocp_write_word(tp, MCU_TYPE_USB, USB_RX_AGGR_NUM, ocp_data); -+ -+ r8153_set_rx_early_timeout(tp); -+ r8153_set_rx_early_size(tp); -+ -+ speed = rtl8152_get_speed(tp); -+ rtl_set_ifg(tp, speed); -+ -+ ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL4); -+ if (speed & _2500bps) -+ ocp_data &= ~IDLE_SPDWN_EN; -+ else -+ ocp_data |= IDLE_SPDWN_EN; -+ ocp_write_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL4, ocp_data); -+ -+ if (tp->udev->speed == USB_SPEED_HIGH) { -+ ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_L1_CTRL); -+ ocp_data &= ~0xf; -+ if (is_flow_control(speed)) -+ ocp_data |= 0xf; -+ else -+ ocp_data |= 0x1; -+ ocp_write_word(tp, MCU_TYPE_USB, USB_L1_CTRL, ocp_data); -+ } -+ -+ ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_FW_TASK); -+ ocp_data &= ~FC_PATCH_TASK; -+ ocp_write_word(tp, MCU_TYPE_USB, USB_FW_TASK, ocp_data); -+ usleep_range(1000, 2000); -+ ocp_data |= FC_PATCH_TASK; -+ ocp_write_word(tp, MCU_TYPE_USB, USB_FW_TASK, ocp_data); -+ -+ return rtl_enable(tp); -+} -+ - static int rtl8152_set_speed(struct r8152 *tp, u8 autoneg, u32 speed, u8 duplex, - u32 advertising) - { -@@ -4891,58 +5505,73 @@ static int rtl8152_set_speed(struct r815 - - tp->mii.force_media = 1; - } else { -- u16 anar, tmp1; -+ u16 orig, new1; - u32 support; - - support = RTL_ADVERTISED_10_HALF | RTL_ADVERTISED_10_FULL | - RTL_ADVERTISED_100_HALF | RTL_ADVERTISED_100_FULL; - -- if (tp->mii.supports_gmii) -+ if (tp->mii.supports_gmii) { - support |= RTL_ADVERTISED_1000_FULL; - -+ if (tp->support_2500full) -+ support |= RTL_ADVERTISED_2500_FULL; -+ } -+ - if (!(advertising & support)) - return -EINVAL; - -- anar = r8152_mdio_read(tp, MII_ADVERTISE); -- tmp1 = anar & ~(ADVERTISE_10HALF | ADVERTISE_10FULL | -+ orig = r8152_mdio_read(tp, MII_ADVERTISE); -+ new1 = orig & ~(ADVERTISE_10HALF | ADVERTISE_10FULL | - ADVERTISE_100HALF | ADVERTISE_100FULL); - if (advertising & RTL_ADVERTISED_10_HALF) { -- tmp1 |= ADVERTISE_10HALF; -+ new1 |= ADVERTISE_10HALF; - tp->ups_info.speed_duplex = NWAY_10M_HALF; - } - if (advertising & RTL_ADVERTISED_10_FULL) { -- tmp1 |= ADVERTISE_10FULL; -+ new1 |= ADVERTISE_10FULL; - tp->ups_info.speed_duplex = NWAY_10M_FULL; - } - - if (advertising & RTL_ADVERTISED_100_HALF) { -- tmp1 |= ADVERTISE_100HALF; -+ new1 |= ADVERTISE_100HALF; - tp->ups_info.speed_duplex = NWAY_100M_HALF; - } - if (advertising & RTL_ADVERTISED_100_FULL) { -- tmp1 |= ADVERTISE_100FULL; -+ new1 |= ADVERTISE_100FULL; - tp->ups_info.speed_duplex = NWAY_100M_FULL; - } - -- if (anar != tmp1) { -- r8152_mdio_write(tp, MII_ADVERTISE, tmp1); -- tp->mii.advertising = tmp1; -+ if (orig != new1) { -+ r8152_mdio_write(tp, MII_ADVERTISE, new1); -+ tp->mii.advertising = new1; - } - - if (tp->mii.supports_gmii) { -- u16 gbcr; -- -- gbcr = r8152_mdio_read(tp, MII_CTRL1000); -- tmp1 = gbcr & ~(ADVERTISE_1000FULL | -+ orig = r8152_mdio_read(tp, MII_CTRL1000); -+ new1 = orig & ~(ADVERTISE_1000FULL | - ADVERTISE_1000HALF); - - if (advertising & RTL_ADVERTISED_1000_FULL) { -- tmp1 |= ADVERTISE_1000FULL; -+ new1 |= ADVERTISE_1000FULL; - tp->ups_info.speed_duplex = NWAY_1000M_FULL; - } - -- if (gbcr != tmp1) -- r8152_mdio_write(tp, MII_CTRL1000, tmp1); -+ if (orig != new1) -+ r8152_mdio_write(tp, MII_CTRL1000, new1); -+ } -+ -+ if (tp->support_2500full) { -+ orig = ocp_reg_read(tp, OCP_10GBT_CTRL); -+ new1 = orig & ~MDIO_AN_10GBT_CTRL_ADV2_5G; -+ -+ if (advertising & RTL_ADVERTISED_2500_FULL) { -+ new1 |= MDIO_AN_10GBT_CTRL_ADV2_5G; -+ tp->ups_info.speed_duplex = NWAY_2500M_FULL; -+ } -+ -+ if (orig != new1) -+ ocp_reg_write(tp, OCP_10GBT_CTRL, new1); - } - - bmcr = BMCR_ANENABLE | BMCR_ANRESTART; -@@ -5098,6 +5727,253 @@ static void rtl8153b_down(struct r8152 * - r8153_aldps_en(tp, true); - } - -+static void rtl8153c_change_mtu(struct r8152 *tp) -+{ -+ ocp_write_word(tp, MCU_TYPE_PLA, PLA_RMS, mtu_to_size(tp->netdev->mtu)); -+ ocp_write_byte(tp, MCU_TYPE_PLA, PLA_MTPS, 10 * 1024 / 64); -+ -+ ocp_write_word(tp, MCU_TYPE_PLA, PLA_TXFIFO_CTRL, 512 / 64); -+ -+ /* Adjust the tx fifo free credit full threshold, otherwise -+ * the fifo would be too small to send a jumbo frame packet. -+ */ -+ if (tp->netdev->mtu < 8000) -+ ocp_write_word(tp, MCU_TYPE_PLA, PLA_TXFIFO_FULL, 2048 / 8); -+ else -+ ocp_write_word(tp, MCU_TYPE_PLA, PLA_TXFIFO_FULL, 900 / 8); -+} -+ -+static void rtl8153c_up(struct r8152 *tp) -+{ -+ u32 ocp_data; -+ -+ if (test_bit(RTL8152_UNPLUG, &tp->flags)) -+ return; -+ -+ r8153b_u1u2en(tp, false); -+ r8153_u2p3en(tp, false); -+ r8153_aldps_en(tp, false); -+ -+ rxdy_gated_en(tp, true); -+ r8153_teredo_off(tp); -+ -+ ocp_data = ocp_read_dword(tp, MCU_TYPE_PLA, PLA_RCR); -+ ocp_data &= ~RCR_ACPT_ALL; -+ ocp_write_dword(tp, MCU_TYPE_PLA, PLA_RCR, ocp_data); -+ -+ rtl8152_nic_reset(tp); -+ rtl_reset_bmu(tp); -+ -+ ocp_data = ocp_read_byte(tp, MCU_TYPE_PLA, PLA_OOB_CTRL); -+ ocp_data &= ~NOW_IS_OOB; -+ ocp_write_byte(tp, MCU_TYPE_PLA, PLA_OOB_CTRL, ocp_data); -+ -+ ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_SFF_STS_7); -+ ocp_data &= ~MCU_BORW_EN; -+ ocp_write_word(tp, MCU_TYPE_PLA, PLA_SFF_STS_7, ocp_data); -+ -+ wait_oob_link_list_ready(tp); -+ -+ ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_SFF_STS_7); -+ ocp_data |= RE_INIT_LL; -+ ocp_write_word(tp, MCU_TYPE_PLA, PLA_SFF_STS_7, ocp_data); -+ -+ wait_oob_link_list_ready(tp); -+ -+ rtl_rx_vlan_en(tp, tp->netdev->features & NETIF_F_HW_VLAN_CTAG_RX); -+ -+ rtl8153c_change_mtu(tp); -+ -+ rtl8152_nic_reset(tp); -+ -+ /* rx share fifo credit full threshold */ -+ ocp_write_byte(tp, MCU_TYPE_PLA, PLA_RXFIFO_CTRL0, 0x02); -+ ocp_write_byte(tp, MCU_TYPE_PLA, PLA_RXFIFO_FULL, 0x08); -+ ocp_write_word(tp, MCU_TYPE_PLA, PLA_RXFIFO_CTRL1, RXFIFO_THR2_NORMAL); -+ ocp_write_word(tp, MCU_TYPE_PLA, PLA_RXFIFO_CTRL2, RXFIFO_THR3_NORMAL); -+ -+ ocp_write_dword(tp, MCU_TYPE_USB, USB_RX_BUF_TH, RX_THR_B); -+ -+ ocp_write_byte(tp, MCU_TYPE_PLA, PLA_CRWECR, CRWECR_CONFIG); -+ -+ ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_CONFIG34); -+ ocp_data |= BIT(8); -+ ocp_write_word(tp, MCU_TYPE_PLA, PLA_CONFIG34, ocp_data); -+ -+ ocp_write_byte(tp, MCU_TYPE_PLA, PLA_CRWECR, CRWECR_NORAML); -+ -+ ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL3); -+ ocp_data &= ~PLA_MCU_SPDWN_EN; -+ ocp_write_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL3, ocp_data); -+ -+ r8153_aldps_en(tp, true); -+ r8153b_u1u2en(tp, true); -+} -+ -+static inline u32 fc_pause_on_auto(struct r8152 *tp) -+{ -+ return (ALIGN(mtu_to_size(tp->netdev->mtu), 1024) + 6 * 1024); -+} -+ -+static inline u32 fc_pause_off_auto(struct r8152 *tp) -+{ -+ return (ALIGN(mtu_to_size(tp->netdev->mtu), 1024) + 14 * 1024); -+} -+ -+static void r8156_fc_parameter(struct r8152 *tp) -+{ -+ u32 pause_on = tp->fc_pause_on ? tp->fc_pause_on : fc_pause_on_auto(tp); -+ u32 pause_off = tp->fc_pause_off ? tp->fc_pause_off : fc_pause_off_auto(tp); -+ -+ switch (tp->version) { -+ case RTL_VER_10: -+ case RTL_VER_11: -+ ocp_write_word(tp, MCU_TYPE_PLA, PLA_RX_FIFO_FULL, pause_on / 8); -+ ocp_write_word(tp, MCU_TYPE_PLA, PLA_RX_FIFO_EMPTY, pause_off / 8); -+ break; -+ case RTL_VER_12: -+ case RTL_VER_13: -+ case RTL_VER_15: -+ ocp_write_word(tp, MCU_TYPE_PLA, PLA_RX_FIFO_FULL, pause_on / 16); -+ ocp_write_word(tp, MCU_TYPE_PLA, PLA_RX_FIFO_EMPTY, pause_off / 16); -+ break; -+ default: -+ break; -+ } -+} -+ -+static void rtl8156_change_mtu(struct r8152 *tp) -+{ -+ u32 rx_max_size = mtu_to_size(tp->netdev->mtu); -+ -+ ocp_write_word(tp, MCU_TYPE_PLA, PLA_RMS, rx_max_size); -+ ocp_write_byte(tp, MCU_TYPE_PLA, PLA_MTPS, MTPS_JUMBO); -+ r8156_fc_parameter(tp); -+ -+ /* TX share fifo free credit full threshold */ -+ ocp_write_word(tp, MCU_TYPE_PLA, PLA_TXFIFO_CTRL, 512 / 64); -+ ocp_write_word(tp, MCU_TYPE_PLA, PLA_TXFIFO_FULL, -+ ALIGN(rx_max_size + sizeof(struct tx_desc), 1024) / 16); -+} -+ -+static void rtl8156_up(struct r8152 *tp) -+{ -+ u32 ocp_data; -+ -+ if (test_bit(RTL8152_UNPLUG, &tp->flags)) -+ return; -+ -+ r8153b_u1u2en(tp, false); -+ r8153_u2p3en(tp, false); -+ r8153_aldps_en(tp, false); -+ -+ rxdy_gated_en(tp, true); -+ r8153_teredo_off(tp); -+ -+ ocp_data = ocp_read_dword(tp, MCU_TYPE_PLA, PLA_RCR); -+ ocp_data &= ~RCR_ACPT_ALL; -+ ocp_write_dword(tp, MCU_TYPE_PLA, PLA_RCR, ocp_data); -+ -+ rtl8152_nic_reset(tp); -+ rtl_reset_bmu(tp); -+ -+ ocp_data = ocp_read_byte(tp, MCU_TYPE_PLA, PLA_OOB_CTRL); -+ ocp_data &= ~NOW_IS_OOB; -+ ocp_write_byte(tp, MCU_TYPE_PLA, PLA_OOB_CTRL, ocp_data); -+ -+ ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_SFF_STS_7); -+ ocp_data &= ~MCU_BORW_EN; -+ ocp_write_word(tp, MCU_TYPE_PLA, PLA_SFF_STS_7, ocp_data); -+ -+ rtl_rx_vlan_en(tp, tp->netdev->features & NETIF_F_HW_VLAN_CTAG_RX); -+ -+ rtl8156_change_mtu(tp); -+ -+ switch (tp->version) { -+ case RTL_TEST_01: -+ case RTL_VER_10: -+ case RTL_VER_11: -+ ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_BMU_CONFIG); -+ ocp_data |= ACT_ODMA; -+ ocp_write_word(tp, MCU_TYPE_USB, USB_BMU_CONFIG, ocp_data); -+ break; -+ default: -+ break; -+ } -+ -+ /* share FIFO settings */ -+ ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_RXFIFO_FULL); -+ ocp_data &= ~RXFIFO_FULL_MASK; -+ ocp_data |= 0x08; -+ ocp_write_word(tp, MCU_TYPE_PLA, PLA_RXFIFO_FULL, ocp_data); -+ -+ ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL3); -+ ocp_data &= ~PLA_MCU_SPDWN_EN; -+ ocp_write_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL3, ocp_data); -+ -+ ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_SPEED_OPTION); -+ ocp_data &= ~(RG_PWRDN_EN | ALL_SPEED_OFF); -+ ocp_write_word(tp, MCU_TYPE_USB, USB_SPEED_OPTION, ocp_data); -+ -+ ocp_write_dword(tp, MCU_TYPE_USB, USB_RX_BUF_TH, 0x00600400); -+ -+ if (tp->saved_wolopts != __rtl_get_wol(tp)) { -+ netif_warn(tp, ifup, tp->netdev, "wol setting is changed\n"); -+ __rtl_set_wol(tp, tp->saved_wolopts); -+ } -+ -+ r8153_aldps_en(tp, true); -+ r8153_u2p3en(tp, true); -+ -+ if (tp->udev->speed >= USB_SPEED_SUPER) -+ r8153b_u1u2en(tp, true); -+} -+ -+static void rtl8156_down(struct r8152 *tp) -+{ -+ u32 ocp_data; -+ -+ if (test_bit(RTL8152_UNPLUG, &tp->flags)) { -+ rtl_drop_queued_tx(tp); -+ return; -+ } -+ -+ ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL3); -+ ocp_data |= PLA_MCU_SPDWN_EN; -+ ocp_write_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL3, ocp_data); -+ -+ r8153b_u1u2en(tp, false); -+ r8153_u2p3en(tp, false); -+ r8153b_power_cut_en(tp, false); -+ r8153_aldps_en(tp, false); -+ -+ ocp_data = ocp_read_byte(tp, MCU_TYPE_PLA, PLA_OOB_CTRL); -+ ocp_data &= ~NOW_IS_OOB; -+ ocp_write_byte(tp, MCU_TYPE_PLA, PLA_OOB_CTRL, ocp_data); -+ -+ rtl_disable(tp); -+ rtl_reset_bmu(tp); -+ -+ /* Clear teredo wake event. bit[15:8] is the teredo wakeup -+ * type. Set it to zero. bits[7:0] are the W1C bits about -+ * the events. Set them to all 1 to clear them. -+ */ -+ ocp_write_word(tp, MCU_TYPE_PLA, PLA_TEREDO_WAKE_BASE, 0x00ff); -+ -+ ocp_data = ocp_read_byte(tp, MCU_TYPE_PLA, PLA_OOB_CTRL); -+ ocp_data |= NOW_IS_OOB; -+ ocp_write_byte(tp, MCU_TYPE_PLA, PLA_OOB_CTRL, ocp_data); -+ -+ rtl_rx_vlan_en(tp, true); -+ rxdy_gated_en(tp, false); -+ -+ ocp_data = ocp_read_dword(tp, MCU_TYPE_PLA, PLA_RCR); -+ ocp_data |= RCR_APM | RCR_AM | RCR_AB; -+ ocp_write_dword(tp, MCU_TYPE_PLA, PLA_RCR, ocp_data); -+ -+ r8153_aldps_en(tp, true); -+} -+ - static bool rtl8152_in_nway(struct r8152 *tp) - { - u16 nway_state; -@@ -5128,7 +6004,7 @@ static void set_carrier(struct r8152 *tp - { - struct net_device *netdev = tp->netdev; - struct napi_struct *napi = &tp->napi; -- u8 speed; -+ u16 speed; - - speed = rtl8152_get_speed(tp); - -@@ -5141,7 +6017,7 @@ static void set_carrier(struct r8152 *tp - rtl_start_rx(tp); - clear_bit(RTL8152_SET_RX_MODE, &tp->flags); - _rtl8152_set_rx_mode(netdev); -- napi_enable(&tp->napi); -+ napi_enable(napi); - netif_wake_queue(netdev); - netif_info(tp, link, netdev, "carrier on\n"); - } else if (netif_queue_stopped(netdev) && -@@ -5521,14 +6397,9 @@ static void r8153_init(struct r8152 *tp) - - ocp_write_word(tp, MCU_TYPE_USB, USB_CONNECT_TIMER, 0x0001); - -- /* MAC clock speed down */ -- ocp_write_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL, 0); -- ocp_write_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL2, 0); -- ocp_write_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL3, 0); -- ocp_write_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL4, 0); -- - r8153_power_cut_en(tp, false); - rtl_runtime_suspend_enable(tp, false); -+ r8153_mac_clk_speed_down(tp, false); - r8153_u1u2en(tp, true); - usb_enable_lpm(tp->udev); - -@@ -5621,9 +6492,7 @@ static void r8153b_init(struct r8152 *tp - usb_enable_lpm(tp->udev); - - /* MAC clock speed down */ -- ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL2); -- ocp_data |= MAC_CLK_SPDWN_EN; -- ocp_write_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL2, ocp_data); -+ r8153_mac_clk_speed_down(tp, true); - - ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL3); - ocp_data &= ~PLA_MCU_SPDWN_EN; -@@ -5652,6 +6521,1069 @@ static void r8153b_init(struct r8152 *tp - r8152_led_configuration(tp); - } - -+static void r8153c_init(struct r8152 *tp) -+{ -+ u32 ocp_data; -+ u16 data; -+ int i; -+ -+ if (test_bit(RTL8152_UNPLUG, &tp->flags)) -+ return; -+ -+ r8153b_u1u2en(tp, false); -+ -+ /* Disable spi_en */ -+ ocp_write_byte(tp, MCU_TYPE_PLA, PLA_CRWECR, CRWECR_CONFIG); -+ ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_CONFIG5); -+ ocp_data &= ~BIT(3); -+ ocp_write_word(tp, MCU_TYPE_PLA, PLA_CONFIG5, ocp_data); -+ ocp_data = ocp_read_word(tp, MCU_TYPE_USB, 0xcbf0); -+ ocp_data |= BIT(1); -+ ocp_write_word(tp, MCU_TYPE_USB, 0xcbf0, ocp_data); -+ -+ for (i = 0; i < 500; i++) { -+ if (ocp_read_word(tp, MCU_TYPE_PLA, PLA_BOOT_CTRL) & -+ AUTOLOAD_DONE) -+ break; -+ -+ msleep(20); -+ if (test_bit(RTL8152_UNPLUG, &tp->flags)) -+ return; -+ } -+ -+ data = r8153_phy_status(tp, 0); -+ -+ data = r8152_mdio_read(tp, MII_BMCR); -+ if (data & BMCR_PDOWN) { -+ data &= ~BMCR_PDOWN; -+ r8152_mdio_write(tp, MII_BMCR, data); -+ } -+ -+ data = r8153_phy_status(tp, PHY_STAT_LAN_ON); -+ -+ r8153_u2p3en(tp, false); -+ -+ /* MSC timer = 0xfff * 8ms = 32760 ms */ -+ ocp_write_word(tp, MCU_TYPE_USB, USB_MSC_TIMER, 0x0fff); -+ -+ r8153b_power_cut_en(tp, false); -+ r8153c_ups_en(tp, false); -+ r8153_queue_wake(tp, false); -+ rtl_runtime_suspend_enable(tp, false); -+ -+ ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_EXTRA_STATUS); -+ if (rtl8152_get_speed(tp) & LINK_STATUS) -+ ocp_data |= CUR_LINK_OK; -+ else -+ ocp_data &= ~CUR_LINK_OK; -+ -+ ocp_data |= POLL_LINK_CHG; -+ ocp_write_word(tp, MCU_TYPE_PLA, PLA_EXTRA_STATUS, ocp_data); -+ -+ r8153b_u1u2en(tp, true); -+ -+ usb_enable_lpm(tp->udev); -+ -+ /* MAC clock speed down */ -+ r8153_mac_clk_speed_down(tp, true); -+ -+ ocp_data = ocp_read_byte(tp, MCU_TYPE_USB, USB_MISC_2); -+ ocp_data &= ~BIT(7); -+ ocp_write_byte(tp, MCU_TYPE_USB, USB_MISC_2, ocp_data); -+ -+ set_bit(GREEN_ETHERNET, &tp->flags); -+ -+ /* rx aggregation */ -+ ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_USB_CTRL); -+ ocp_data &= ~(RX_AGG_DISABLE | RX_ZERO_EN); -+ ocp_write_word(tp, MCU_TYPE_USB, USB_USB_CTRL, ocp_data); -+ -+ rtl_tally_reset(tp); -+ -+ tp->coalesce = 15000; /* 15 us */ -+} -+ -+static void r8156_hw_phy_cfg(struct r8152 *tp) -+{ -+ u32 ocp_data; -+ u16 data; -+ -+ ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_MISC_0); -+ if (ocp_data & PCUT_STATUS) { -+ ocp_data &= ~PCUT_STATUS; -+ ocp_write_word(tp, MCU_TYPE_USB, USB_MISC_0, ocp_data); -+ } -+ -+ data = r8153_phy_status(tp, 0); -+ switch (data) { -+ case PHY_STAT_EXT_INIT: -+ rtl8152_apply_firmware(tp, true); -+ -+ data = ocp_reg_read(tp, 0xa468); -+ data &= ~(BIT(3) | BIT(1)); -+ ocp_reg_write(tp, 0xa468, data); -+ break; -+ case PHY_STAT_LAN_ON: -+ case PHY_STAT_PWRDN: -+ default: -+ rtl8152_apply_firmware(tp, false); -+ break; -+ } -+ -+ /* disable ALDPS before updating the PHY parameters */ -+ r8153_aldps_en(tp, false); -+ -+ /* disable EEE before updating the PHY parameters */ -+ rtl_eee_enable(tp, false); -+ -+ data = r8153_phy_status(tp, PHY_STAT_LAN_ON); -+ WARN_ON_ONCE(data != PHY_STAT_LAN_ON); -+ -+ ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_PHY_PWR); -+ ocp_data |= PFM_PWM_SWITCH; -+ ocp_write_word(tp, MCU_TYPE_PLA, PLA_PHY_PWR, ocp_data); -+ -+ switch (tp->version) { -+ case RTL_VER_10: -+ data = ocp_reg_read(tp, 0xad40); -+ data &= ~0x3ff; -+ data |= BIT(7) | BIT(2); -+ ocp_reg_write(tp, 0xad40, data); -+ -+ data = ocp_reg_read(tp, 0xad4e); -+ data |= BIT(4); -+ ocp_reg_write(tp, 0xad4e, data); -+ data = ocp_reg_read(tp, 0xad16); -+ data &= ~0x3ff; -+ data |= 0x6; -+ ocp_reg_write(tp, 0xad16, data); -+ data = ocp_reg_read(tp, 0xad32); -+ data &= ~0x3f; -+ data |= 6; -+ ocp_reg_write(tp, 0xad32, data); -+ data = ocp_reg_read(tp, 0xac08); -+ data &= ~(BIT(12) | BIT(8)); -+ ocp_reg_write(tp, 0xac08, data); -+ data = ocp_reg_read(tp, 0xac8a); -+ data |= BIT(12) | BIT(13) | BIT(14); -+ data &= ~BIT(15); -+ ocp_reg_write(tp, 0xac8a, data); -+ data = ocp_reg_read(tp, 0xad18); -+ data |= BIT(10); -+ ocp_reg_write(tp, 0xad18, data); -+ data = ocp_reg_read(tp, 0xad1a); -+ data |= 0x3ff; -+ ocp_reg_write(tp, 0xad1a, data); -+ data = ocp_reg_read(tp, 0xad1c); -+ data |= 0x3ff; -+ ocp_reg_write(tp, 0xad1c, data); -+ -+ data = sram_read(tp, 0x80ea); -+ data &= ~0xff00; -+ data |= 0xc400; -+ sram_write(tp, 0x80ea, data); -+ data = sram_read(tp, 0x80eb); -+ data &= ~0x0700; -+ data |= 0x0300; -+ sram_write(tp, 0x80eb, data); -+ data = sram_read(tp, 0x80f8); -+ data &= ~0xff00; -+ data |= 0x1c00; -+ sram_write(tp, 0x80f8, data); -+ data = sram_read(tp, 0x80f1); -+ data &= ~0xff00; -+ data |= 0x3000; -+ sram_write(tp, 0x80f1, data); -+ -+ data = sram_read(tp, 0x80fe); -+ data &= ~0xff00; -+ data |= 0xa500; -+ sram_write(tp, 0x80fe, data); -+ data = sram_read(tp, 0x8102); -+ data &= ~0xff00; -+ data |= 0x5000; -+ sram_write(tp, 0x8102, data); -+ data = sram_read(tp, 0x8015); -+ data &= ~0xff00; -+ data |= 0x3300; -+ sram_write(tp, 0x8015, data); -+ data = sram_read(tp, 0x8100); -+ data &= ~0xff00; -+ data |= 0x7000; -+ sram_write(tp, 0x8100, data); -+ data = sram_read(tp, 0x8014); -+ data &= ~0xff00; -+ data |= 0xf000; -+ sram_write(tp, 0x8014, data); -+ data = sram_read(tp, 0x8016); -+ data &= ~0xff00; -+ data |= 0x6500; -+ sram_write(tp, 0x8016, data); -+ data = sram_read(tp, 0x80dc); -+ data &= ~0xff00; -+ data |= 0xed00; -+ sram_write(tp, 0x80dc, data); -+ data = sram_read(tp, 0x80df); -+ data |= BIT(8); -+ sram_write(tp, 0x80df, data); -+ data = sram_read(tp, 0x80e1); -+ data &= ~BIT(8); -+ sram_write(tp, 0x80e1, data); -+ -+ data = ocp_reg_read(tp, 0xbf06); -+ data &= ~0x003f; -+ data |= 0x0038; -+ ocp_reg_write(tp, 0xbf06, data); -+ -+ sram_write(tp, 0x819f, 0xddb6); -+ -+ ocp_reg_write(tp, 0xbc34, 0x5555); -+ data = ocp_reg_read(tp, 0xbf0a); -+ data &= ~0x0e00; -+ data |= 0x0a00; -+ ocp_reg_write(tp, 0xbf0a, data); -+ -+ data = ocp_reg_read(tp, 0xbd2c); -+ data &= ~BIT(13); -+ ocp_reg_write(tp, 0xbd2c, data); -+ break; -+ case RTL_VER_11: -+ data = ocp_reg_read(tp, 0xad16); -+ data |= 0x3ff; -+ ocp_reg_write(tp, 0xad16, data); -+ data = ocp_reg_read(tp, 0xad32); -+ data &= ~0x3f; -+ data |= 6; -+ ocp_reg_write(tp, 0xad32, data); -+ data = ocp_reg_read(tp, 0xac08); -+ data &= ~(BIT(12) | BIT(8)); -+ ocp_reg_write(tp, 0xac08, data); -+ data = ocp_reg_read(tp, 0xacc0); -+ data &= ~0x3; -+ data |= BIT(1); -+ ocp_reg_write(tp, 0xacc0, data); -+ data = ocp_reg_read(tp, 0xad40); -+ data &= ~0xe7; -+ data |= BIT(6) | BIT(2); -+ ocp_reg_write(tp, 0xad40, data); -+ data = ocp_reg_read(tp, 0xac14); -+ data &= ~BIT(7); -+ ocp_reg_write(tp, 0xac14, data); -+ data = ocp_reg_read(tp, 0xac80); -+ data &= ~(BIT(8) | BIT(9)); -+ ocp_reg_write(tp, 0xac80, data); -+ data = ocp_reg_read(tp, 0xac5e); -+ data &= ~0x7; -+ data |= BIT(1); -+ ocp_reg_write(tp, 0xac5e, data); -+ ocp_reg_write(tp, 0xad4c, 0x00a8); -+ ocp_reg_write(tp, 0xac5c, 0x01ff); -+ data = ocp_reg_read(tp, 0xac8a); -+ data &= ~0xf0; -+ data |= BIT(4) | BIT(5); -+ ocp_reg_write(tp, 0xac8a, data); -+ ocp_reg_write(tp, 0xb87c, 0x8157); -+ data = ocp_reg_read(tp, 0xb87e); -+ data &= ~0xff00; -+ data |= 0x0500; -+ ocp_reg_write(tp, 0xb87e, data); -+ ocp_reg_write(tp, 0xb87c, 0x8159); -+ data = ocp_reg_read(tp, 0xb87e); -+ data &= ~0xff00; -+ data |= 0x0700; -+ ocp_reg_write(tp, 0xb87e, data); -+ -+ /* AAGC */ -+ ocp_reg_write(tp, 0xb87c, 0x80a2); -+ ocp_reg_write(tp, 0xb87e, 0x0153); -+ ocp_reg_write(tp, 0xb87c, 0x809c); -+ ocp_reg_write(tp, 0xb87e, 0x0153); -+ -+ /* EEE parameter */ -+ ocp_write_word(tp, MCU_TYPE_PLA, PLA_EEE_TXTWSYS_2P5G, 0x0056); -+ -+ ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_USB_CFG); -+ ocp_data |= EN_XG_LIP | EN_G_LIP; -+ ocp_write_word(tp, MCU_TYPE_PLA, PLA_USB_CFG, ocp_data); -+ -+ sram_write(tp, 0x8257, 0x020f); /* XG PLL */ -+ sram_write(tp, 0x80ea, 0x7843); /* GIGA Master */ -+ -+ if (rtl_phy_patch_request(tp, true, true)) -+ return; -+ -+ /* Advance EEE */ -+ ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL4); -+ ocp_data |= EEE_SPDWN_EN; -+ ocp_write_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL4, ocp_data); -+ -+ data = ocp_reg_read(tp, OCP_DOWN_SPEED); -+ data &= ~(EN_EEE_100 | EN_EEE_1000); -+ data |= EN_10M_CLKDIV; -+ ocp_reg_write(tp, OCP_DOWN_SPEED, data); -+ tp->ups_info._10m_ckdiv = true; -+ tp->ups_info.eee_plloff_100 = false; -+ tp->ups_info.eee_plloff_giga = false; -+ -+ data = ocp_reg_read(tp, OCP_POWER_CFG); -+ data &= ~EEE_CLKDIV_EN; -+ ocp_reg_write(tp, OCP_POWER_CFG, data); -+ tp->ups_info.eee_ckdiv = false; -+ -+ ocp_reg_write(tp, OCP_SYSCLK_CFG, 0); -+ ocp_reg_write(tp, OCP_SYSCLK_CFG, sysclk_div_expo(5)); -+ tp->ups_info._250m_ckdiv = false; -+ -+ rtl_phy_patch_request(tp, false, true); -+ -+ /* enable ADC Ibias Cal */ -+ data = ocp_reg_read(tp, 0xd068); -+ data |= BIT(13); -+ ocp_reg_write(tp, 0xd068, data); -+ -+ /* enable Thermal Sensor */ -+ data = sram_read(tp, 0x81a2); -+ data &= ~BIT(8); -+ sram_write(tp, 0x81a2, data); -+ data = ocp_reg_read(tp, 0xb54c); -+ data &= ~0xff00; -+ data |= 0xdb00; -+ ocp_reg_write(tp, 0xb54c, data); -+ -+ /* Nway 2.5G Lite */ -+ data = ocp_reg_read(tp, 0xa454); -+ data &= ~BIT(0); -+ ocp_reg_write(tp, 0xa454, data); -+ -+ /* CS DSP solution */ -+ data = ocp_reg_read(tp, OCP_10GBT_CTRL); -+ data |= RTL_ADV2_5G_F_R; -+ ocp_reg_write(tp, OCP_10GBT_CTRL, data); -+ data = ocp_reg_read(tp, 0xad4e); -+ data &= ~BIT(4); -+ ocp_reg_write(tp, 0xad4e, data); -+ data = ocp_reg_read(tp, 0xa86a); -+ data &= ~BIT(0); -+ ocp_reg_write(tp, 0xa86a, data); -+ -+ /* MDI SWAP */ -+ if ((ocp_read_word(tp, MCU_TYPE_USB, USB_UPS_CFG) & MID_REVERSE) && -+ (ocp_reg_read(tp, 0xd068) & BIT(1))) { -+ u16 swap_a, swap_b; -+ -+ data = ocp_reg_read(tp, 0xd068); -+ data &= ~0x1f; -+ data |= 0x1; /* p0 */ -+ ocp_reg_write(tp, 0xd068, data); -+ swap_a = ocp_reg_read(tp, 0xd06a); -+ data &= ~0x18; -+ data |= 0x18; /* p3 */ -+ ocp_reg_write(tp, 0xd068, data); -+ swap_b = ocp_reg_read(tp, 0xd06a); -+ data &= ~0x18; /* p0 */ -+ ocp_reg_write(tp, 0xd068, data); -+ ocp_reg_write(tp, 0xd06a, -+ (swap_a & ~0x7ff) | (swap_b & 0x7ff)); -+ data |= 0x18; /* p3 */ -+ ocp_reg_write(tp, 0xd068, data); -+ ocp_reg_write(tp, 0xd06a, -+ (swap_b & ~0x7ff) | (swap_a & 0x7ff)); -+ data &= ~0x18; -+ data |= 0x08; /* p1 */ -+ ocp_reg_write(tp, 0xd068, data); -+ swap_a = ocp_reg_read(tp, 0xd06a); -+ data &= ~0x18; -+ data |= 0x10; /* p2 */ -+ ocp_reg_write(tp, 0xd068, data); -+ swap_b = ocp_reg_read(tp, 0xd06a); -+ data &= ~0x18; -+ data |= 0x08; /* p1 */ -+ ocp_reg_write(tp, 0xd068, data); -+ ocp_reg_write(tp, 0xd06a, -+ (swap_a & ~0x7ff) | (swap_b & 0x7ff)); -+ data &= ~0x18; -+ data |= 0x10; /* p2 */ -+ ocp_reg_write(tp, 0xd068, data); -+ ocp_reg_write(tp, 0xd06a, -+ (swap_b & ~0x7ff) | (swap_a & 0x7ff)); -+ swap_a = ocp_reg_read(tp, 0xbd5a); -+ swap_b = ocp_reg_read(tp, 0xbd5c); -+ ocp_reg_write(tp, 0xbd5a, (swap_a & ~0x1f1f) | -+ ((swap_b & 0x1f) << 8) | -+ ((swap_b >> 8) & 0x1f)); -+ ocp_reg_write(tp, 0xbd5c, (swap_b & ~0x1f1f) | -+ ((swap_a & 0x1f) << 8) | -+ ((swap_a >> 8) & 0x1f)); -+ swap_a = ocp_reg_read(tp, 0xbc18); -+ swap_b = ocp_reg_read(tp, 0xbc1a); -+ ocp_reg_write(tp, 0xbc18, (swap_a & ~0x1f1f) | -+ ((swap_b & 0x1f) << 8) | -+ ((swap_b >> 8) & 0x1f)); -+ ocp_reg_write(tp, 0xbc1a, (swap_b & ~0x1f1f) | -+ ((swap_a & 0x1f) << 8) | -+ ((swap_a >> 8) & 0x1f)); -+ } -+ break; -+ default: -+ break; -+ } -+ -+ rtl_green_en(tp, test_bit(GREEN_ETHERNET, &tp->flags)); -+ -+ data = ocp_reg_read(tp, 0xa428); -+ data &= ~BIT(9); -+ ocp_reg_write(tp, 0xa428, data); -+ data = ocp_reg_read(tp, 0xa5ea); -+ data &= ~BIT(0); -+ ocp_reg_write(tp, 0xa5ea, data); -+ tp->ups_info.lite_mode = 0; -+ -+ if (tp->eee_en) -+ rtl_eee_enable(tp, true); -+ -+ r8153_aldps_en(tp, true); -+ r8152b_enable_fc(tp); -+ r8153_u2p3en(tp, true); -+ -+ set_bit(PHY_RESET, &tp->flags); -+} -+ -+static void r8156b_hw_phy_cfg(struct r8152 *tp) -+{ -+ u32 ocp_data; -+ u16 data; -+ -+ switch (tp->version) { -+ case RTL_VER_12: -+ ocp_reg_write(tp, 0xbf86, 0x9000); -+ data = ocp_reg_read(tp, 0xc402); -+ data |= BIT(10); -+ ocp_reg_write(tp, 0xc402, data); -+ data &= ~BIT(10); -+ ocp_reg_write(tp, 0xc402, data); -+ ocp_reg_write(tp, 0xbd86, 0x1010); -+ ocp_reg_write(tp, 0xbd88, 0x1010); -+ data = ocp_reg_read(tp, 0xbd4e); -+ data &= ~(BIT(10) | BIT(11)); -+ data |= BIT(11); -+ ocp_reg_write(tp, 0xbd4e, data); -+ data = ocp_reg_read(tp, 0xbf46); -+ data &= ~0xf00; -+ data |= 0x700; -+ ocp_reg_write(tp, 0xbf46, data); -+ break; -+ case RTL_VER_13: -+ case RTL_VER_15: -+ r8156b_wait_loading_flash(tp); -+ break; -+ default: -+ break; -+ } -+ -+ ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_MISC_0); -+ if (ocp_data & PCUT_STATUS) { -+ ocp_data &= ~PCUT_STATUS; -+ ocp_write_word(tp, MCU_TYPE_USB, USB_MISC_0, ocp_data); -+ } -+ -+ data = r8153_phy_status(tp, 0); -+ switch (data) { -+ case PHY_STAT_EXT_INIT: -+ rtl8152_apply_firmware(tp, true); -+ -+ data = ocp_reg_read(tp, 0xa466); -+ data &= ~BIT(0); -+ ocp_reg_write(tp, 0xa466, data); -+ -+ data = ocp_reg_read(tp, 0xa468); -+ data &= ~(BIT(3) | BIT(1)); -+ ocp_reg_write(tp, 0xa468, data); -+ break; -+ case PHY_STAT_LAN_ON: -+ case PHY_STAT_PWRDN: -+ default: -+ rtl8152_apply_firmware(tp, false); -+ break; -+ } -+ -+ data = r8152_mdio_read(tp, MII_BMCR); -+ if (data & BMCR_PDOWN) { -+ data &= ~BMCR_PDOWN; -+ r8152_mdio_write(tp, MII_BMCR, data); -+ } -+ -+ /* disable ALDPS before updating the PHY parameters */ -+ r8153_aldps_en(tp, false); -+ -+ /* disable EEE before updating the PHY parameters */ -+ rtl_eee_enable(tp, false); -+ -+ data = r8153_phy_status(tp, PHY_STAT_LAN_ON); -+ WARN_ON_ONCE(data != PHY_STAT_LAN_ON); -+ -+ ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_PHY_PWR); -+ ocp_data |= PFM_PWM_SWITCH; -+ ocp_write_word(tp, MCU_TYPE_PLA, PLA_PHY_PWR, ocp_data); -+ -+ switch (tp->version) { -+ case RTL_VER_12: -+ data = ocp_reg_read(tp, 0xbc08); -+ data |= BIT(3) | BIT(2); -+ ocp_reg_write(tp, 0xbc08, data); -+ -+ data = sram_read(tp, 0x8fff); -+ data &= ~0xff00; -+ data |= 0x0400; -+ sram_write(tp, 0x8fff, data); -+ -+ data = ocp_reg_read(tp, 0xacda); -+ data |= 0xff00; -+ ocp_reg_write(tp, 0xacda, data); -+ data = ocp_reg_read(tp, 0xacde); -+ data |= 0xf000; -+ ocp_reg_write(tp, 0xacde, data); -+ ocp_reg_write(tp, 0xac8c, 0x0ffc); -+ ocp_reg_write(tp, 0xac46, 0xb7b4); -+ ocp_reg_write(tp, 0xac50, 0x0fbc); -+ ocp_reg_write(tp, 0xac3c, 0x9240); -+ ocp_reg_write(tp, 0xac4e, 0x0db4); -+ ocp_reg_write(tp, 0xacc6, 0x0707); -+ ocp_reg_write(tp, 0xacc8, 0xa0d3); -+ ocp_reg_write(tp, 0xad08, 0x0007); -+ -+ ocp_reg_write(tp, 0xb87c, 0x8560); -+ ocp_reg_write(tp, 0xb87e, 0x19cc); -+ ocp_reg_write(tp, 0xb87c, 0x8562); -+ ocp_reg_write(tp, 0xb87e, 0x19cc); -+ ocp_reg_write(tp, 0xb87c, 0x8564); -+ ocp_reg_write(tp, 0xb87e, 0x19cc); -+ ocp_reg_write(tp, 0xb87c, 0x8566); -+ ocp_reg_write(tp, 0xb87e, 0x147d); -+ ocp_reg_write(tp, 0xb87c, 0x8568); -+ ocp_reg_write(tp, 0xb87e, 0x147d); -+ ocp_reg_write(tp, 0xb87c, 0x856a); -+ ocp_reg_write(tp, 0xb87e, 0x147d); -+ ocp_reg_write(tp, 0xb87c, 0x8ffe); -+ ocp_reg_write(tp, 0xb87e, 0x0907); -+ ocp_reg_write(tp, 0xb87c, 0x80d6); -+ ocp_reg_write(tp, 0xb87e, 0x2801); -+ ocp_reg_write(tp, 0xb87c, 0x80f2); -+ ocp_reg_write(tp, 0xb87e, 0x2801); -+ ocp_reg_write(tp, 0xb87c, 0x80f4); -+ ocp_reg_write(tp, 0xb87e, 0x6077); -+ ocp_reg_write(tp, 0xb506, 0x01e7); -+ -+ ocp_reg_write(tp, 0xb87c, 0x8013); -+ ocp_reg_write(tp, 0xb87e, 0x0700); -+ ocp_reg_write(tp, 0xb87c, 0x8fb9); -+ ocp_reg_write(tp, 0xb87e, 0x2801); -+ ocp_reg_write(tp, 0xb87c, 0x8fba); -+ ocp_reg_write(tp, 0xb87e, 0x0100); -+ ocp_reg_write(tp, 0xb87c, 0x8fbc); -+ ocp_reg_write(tp, 0xb87e, 0x1900); -+ ocp_reg_write(tp, 0xb87c, 0x8fbe); -+ ocp_reg_write(tp, 0xb87e, 0xe100); -+ ocp_reg_write(tp, 0xb87c, 0x8fc0); -+ ocp_reg_write(tp, 0xb87e, 0x0800); -+ ocp_reg_write(tp, 0xb87c, 0x8fc2); -+ ocp_reg_write(tp, 0xb87e, 0xe500); -+ ocp_reg_write(tp, 0xb87c, 0x8fc4); -+ ocp_reg_write(tp, 0xb87e, 0x0f00); -+ ocp_reg_write(tp, 0xb87c, 0x8fc6); -+ ocp_reg_write(tp, 0xb87e, 0xf100); -+ ocp_reg_write(tp, 0xb87c, 0x8fc8); -+ ocp_reg_write(tp, 0xb87e, 0x0400); -+ ocp_reg_write(tp, 0xb87c, 0x8fca); -+ ocp_reg_write(tp, 0xb87e, 0xf300); -+ ocp_reg_write(tp, 0xb87c, 0x8fcc); -+ ocp_reg_write(tp, 0xb87e, 0xfd00); -+ ocp_reg_write(tp, 0xb87c, 0x8fce); -+ ocp_reg_write(tp, 0xb87e, 0xff00); -+ ocp_reg_write(tp, 0xb87c, 0x8fd0); -+ ocp_reg_write(tp, 0xb87e, 0xfb00); -+ ocp_reg_write(tp, 0xb87c, 0x8fd2); -+ ocp_reg_write(tp, 0xb87e, 0x0100); -+ ocp_reg_write(tp, 0xb87c, 0x8fd4); -+ ocp_reg_write(tp, 0xb87e, 0xf400); -+ ocp_reg_write(tp, 0xb87c, 0x8fd6); -+ ocp_reg_write(tp, 0xb87e, 0xff00); -+ ocp_reg_write(tp, 0xb87c, 0x8fd8); -+ ocp_reg_write(tp, 0xb87e, 0xf600); -+ -+ ocp_data = ocp_read_byte(tp, MCU_TYPE_PLA, PLA_USB_CFG); -+ ocp_data |= EN_XG_LIP | EN_G_LIP; -+ ocp_write_byte(tp, MCU_TYPE_PLA, PLA_USB_CFG, ocp_data); -+ ocp_reg_write(tp, 0xb87c, 0x813d); -+ ocp_reg_write(tp, 0xb87e, 0x390e); -+ ocp_reg_write(tp, 0xb87c, 0x814f); -+ ocp_reg_write(tp, 0xb87e, 0x790e); -+ ocp_reg_write(tp, 0xb87c, 0x80b0); -+ ocp_reg_write(tp, 0xb87e, 0x0f31); -+ data = ocp_reg_read(tp, 0xbf4c); -+ data |= BIT(1); -+ ocp_reg_write(tp, 0xbf4c, data); -+ data = ocp_reg_read(tp, 0xbcca); -+ data |= BIT(9) | BIT(8); -+ ocp_reg_write(tp, 0xbcca, data); -+ ocp_reg_write(tp, 0xb87c, 0x8141); -+ ocp_reg_write(tp, 0xb87e, 0x320e); -+ ocp_reg_write(tp, 0xb87c, 0x8153); -+ ocp_reg_write(tp, 0xb87e, 0x720e); -+ ocp_reg_write(tp, 0xb87c, 0x8529); -+ ocp_reg_write(tp, 0xb87e, 0x050e); -+ data = ocp_reg_read(tp, OCP_EEE_CFG); -+ data &= ~CTAP_SHORT_EN; -+ ocp_reg_write(tp, OCP_EEE_CFG, data); -+ -+ sram_write(tp, 0x816c, 0xc4a0); -+ sram_write(tp, 0x8170, 0xc4a0); -+ sram_write(tp, 0x8174, 0x04a0); -+ sram_write(tp, 0x8178, 0x04a0); -+ sram_write(tp, 0x817c, 0x0719); -+ sram_write(tp, 0x8ff4, 0x0400); -+ sram_write(tp, 0x8ff1, 0x0404); -+ -+ ocp_reg_write(tp, 0xbf4a, 0x001b); -+ ocp_reg_write(tp, 0xb87c, 0x8033); -+ ocp_reg_write(tp, 0xb87e, 0x7c13); -+ ocp_reg_write(tp, 0xb87c, 0x8037); -+ ocp_reg_write(tp, 0xb87e, 0x7c13); -+ ocp_reg_write(tp, 0xb87c, 0x803b); -+ ocp_reg_write(tp, 0xb87e, 0xfc32); -+ ocp_reg_write(tp, 0xb87c, 0x803f); -+ ocp_reg_write(tp, 0xb87e, 0x7c13); -+ ocp_reg_write(tp, 0xb87c, 0x8043); -+ ocp_reg_write(tp, 0xb87e, 0x7c13); -+ ocp_reg_write(tp, 0xb87c, 0x8047); -+ ocp_reg_write(tp, 0xb87e, 0x7c13); -+ -+ ocp_reg_write(tp, 0xb87c, 0x8145); -+ ocp_reg_write(tp, 0xb87e, 0x370e); -+ ocp_reg_write(tp, 0xb87c, 0x8157); -+ ocp_reg_write(tp, 0xb87e, 0x770e); -+ ocp_reg_write(tp, 0xb87c, 0x8169); -+ ocp_reg_write(tp, 0xb87e, 0x0d0a); -+ ocp_reg_write(tp, 0xb87c, 0x817b); -+ ocp_reg_write(tp, 0xb87e, 0x1d0a); -+ -+ data = sram_read(tp, 0x8217); -+ data &= ~0xff00; -+ data |= 0x5000; -+ sram_write(tp, 0x8217, data); -+ data = sram_read(tp, 0x821a); -+ data &= ~0xff00; -+ data |= 0x5000; -+ sram_write(tp, 0x821a, data); -+ sram_write(tp, 0x80da, 0x0403); -+ data = sram_read(tp, 0x80dc); -+ data &= ~0xff00; -+ data |= 0x1000; -+ sram_write(tp, 0x80dc, data); -+ sram_write(tp, 0x80b3, 0x0384); -+ sram_write(tp, 0x80b7, 0x2007); -+ data = sram_read(tp, 0x80ba); -+ data &= ~0xff00; -+ data |= 0x6c00; -+ sram_write(tp, 0x80ba, data); -+ sram_write(tp, 0x80b5, 0xf009); -+ data = sram_read(tp, 0x80bd); -+ data &= ~0xff00; -+ data |= 0x9f00; -+ sram_write(tp, 0x80bd, data); -+ sram_write(tp, 0x80c7, 0xf083); -+ sram_write(tp, 0x80dd, 0x03f0); -+ data = sram_read(tp, 0x80df); -+ data &= ~0xff00; -+ data |= 0x1000; -+ sram_write(tp, 0x80df, data); -+ sram_write(tp, 0x80cb, 0x2007); -+ data = sram_read(tp, 0x80ce); -+ data &= ~0xff00; -+ data |= 0x6c00; -+ sram_write(tp, 0x80ce, data); -+ sram_write(tp, 0x80c9, 0x8009); -+ data = sram_read(tp, 0x80d1); -+ data &= ~0xff00; -+ data |= 0x8000; -+ sram_write(tp, 0x80d1, data); -+ sram_write(tp, 0x80a3, 0x200a); -+ sram_write(tp, 0x80a5, 0xf0ad); -+ sram_write(tp, 0x809f, 0x6073); -+ sram_write(tp, 0x80a1, 0x000b); -+ data = sram_read(tp, 0x80a9); -+ data &= ~0xff00; -+ data |= 0xc000; -+ sram_write(tp, 0x80a9, data); -+ -+ if (rtl_phy_patch_request(tp, true, true)) -+ return; -+ -+ data = ocp_reg_read(tp, 0xb896); -+ data &= ~BIT(0); -+ ocp_reg_write(tp, 0xb896, data); -+ data = ocp_reg_read(tp, 0xb892); -+ data &= ~0xff00; -+ ocp_reg_write(tp, 0xb892, data); -+ ocp_reg_write(tp, 0xb88e, 0xc23e); -+ ocp_reg_write(tp, 0xb890, 0x0000); -+ ocp_reg_write(tp, 0xb88e, 0xc240); -+ ocp_reg_write(tp, 0xb890, 0x0103); -+ ocp_reg_write(tp, 0xb88e, 0xc242); -+ ocp_reg_write(tp, 0xb890, 0x0507); -+ ocp_reg_write(tp, 0xb88e, 0xc244); -+ ocp_reg_write(tp, 0xb890, 0x090b); -+ ocp_reg_write(tp, 0xb88e, 0xc246); -+ ocp_reg_write(tp, 0xb890, 0x0c0e); -+ ocp_reg_write(tp, 0xb88e, 0xc248); -+ ocp_reg_write(tp, 0xb890, 0x1012); -+ ocp_reg_write(tp, 0xb88e, 0xc24a); -+ ocp_reg_write(tp, 0xb890, 0x1416); -+ data = ocp_reg_read(tp, 0xb896); -+ data |= BIT(0); -+ ocp_reg_write(tp, 0xb896, data); -+ -+ rtl_phy_patch_request(tp, false, true); -+ -+ data = ocp_reg_read(tp, 0xa86a); -+ data |= BIT(0); -+ ocp_reg_write(tp, 0xa86a, data); -+ data = ocp_reg_read(tp, 0xa6f0); -+ data |= BIT(0); -+ ocp_reg_write(tp, 0xa6f0, data); -+ -+ ocp_reg_write(tp, 0xbfa0, 0xd70d); -+ ocp_reg_write(tp, 0xbfa2, 0x4100); -+ ocp_reg_write(tp, 0xbfa4, 0xe868); -+ ocp_reg_write(tp, 0xbfa6, 0xdc59); -+ ocp_reg_write(tp, 0xb54c, 0x3c18); -+ data = ocp_reg_read(tp, 0xbfa4); -+ data &= ~BIT(5); -+ ocp_reg_write(tp, 0xbfa4, data); -+ data = sram_read(tp, 0x817d); -+ data |= BIT(12); -+ sram_write(tp, 0x817d, data); -+ break; -+ case RTL_VER_13: -+ /* 2.5G INRX */ -+ data = ocp_reg_read(tp, 0xac46); -+ data &= ~0x00f0; -+ data |= 0x0090; -+ ocp_reg_write(tp, 0xac46, data); -+ data = ocp_reg_read(tp, 0xad30); -+ data &= ~0x0003; -+ data |= 0x0001; -+ ocp_reg_write(tp, 0xad30, data); -+ fallthrough; -+ case RTL_VER_15: -+ /* EEE parameter */ -+ ocp_reg_write(tp, 0xb87c, 0x80f5); -+ ocp_reg_write(tp, 0xb87e, 0x760e); -+ ocp_reg_write(tp, 0xb87c, 0x8107); -+ ocp_reg_write(tp, 0xb87e, 0x360e); -+ ocp_reg_write(tp, 0xb87c, 0x8551); -+ data = ocp_reg_read(tp, 0xb87e); -+ data &= ~0xff00; -+ data |= 0x0800; -+ ocp_reg_write(tp, 0xb87e, data); -+ -+ /* ADC_PGA parameter */ -+ data = ocp_reg_read(tp, 0xbf00); -+ data &= ~0xe000; -+ data |= 0xa000; -+ ocp_reg_write(tp, 0xbf00, data); -+ data = ocp_reg_read(tp, 0xbf46); -+ data &= ~0x0f00; -+ data |= 0x0300; -+ ocp_reg_write(tp, 0xbf46, data); -+ -+ /* Green Table-PGA, 1G full viterbi */ -+ sram_write(tp, 0x8044, 0x2417); -+ sram_write(tp, 0x804a, 0x2417); -+ sram_write(tp, 0x8050, 0x2417); -+ sram_write(tp, 0x8056, 0x2417); -+ sram_write(tp, 0x805c, 0x2417); -+ sram_write(tp, 0x8062, 0x2417); -+ sram_write(tp, 0x8068, 0x2417); -+ sram_write(tp, 0x806e, 0x2417); -+ sram_write(tp, 0x8074, 0x2417); -+ sram_write(tp, 0x807a, 0x2417); -+ -+ /* XG PLL */ -+ data = ocp_reg_read(tp, 0xbf84); -+ data &= ~0xe000; -+ data |= 0xa000; -+ ocp_reg_write(tp, 0xbf84, data); -+ break; -+ default: -+ break; -+ } -+ -+ if (rtl_phy_patch_request(tp, true, true)) -+ return; -+ -+ ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL4); -+ ocp_data |= EEE_SPDWN_EN; -+ ocp_write_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL4, ocp_data); -+ -+ data = ocp_reg_read(tp, OCP_DOWN_SPEED); -+ data &= ~(EN_EEE_100 | EN_EEE_1000); -+ data |= EN_10M_CLKDIV; -+ ocp_reg_write(tp, OCP_DOWN_SPEED, data); -+ tp->ups_info._10m_ckdiv = true; -+ tp->ups_info.eee_plloff_100 = false; -+ tp->ups_info.eee_plloff_giga = false; -+ -+ data = ocp_reg_read(tp, OCP_POWER_CFG); -+ data &= ~EEE_CLKDIV_EN; -+ ocp_reg_write(tp, OCP_POWER_CFG, data); -+ tp->ups_info.eee_ckdiv = false; -+ -+ rtl_phy_patch_request(tp, false, true); -+ -+ rtl_green_en(tp, test_bit(GREEN_ETHERNET, &tp->flags)); -+ -+ data = ocp_reg_read(tp, 0xa428); -+ data &= ~BIT(9); -+ ocp_reg_write(tp, 0xa428, data); -+ data = ocp_reg_read(tp, 0xa5ea); -+ data &= ~BIT(0); -+ ocp_reg_write(tp, 0xa5ea, data); -+ tp->ups_info.lite_mode = 0; -+ -+ if (tp->eee_en) -+ rtl_eee_enable(tp, true); -+ -+ r8153_aldps_en(tp, true); -+ r8152b_enable_fc(tp); -+ r8153_u2p3en(tp, true); -+ -+ set_bit(PHY_RESET, &tp->flags); -+} -+ -+static void r8156_init(struct r8152 *tp) -+{ -+ u32 ocp_data; -+ u16 data; -+ int i; -+ -+ if (test_bit(RTL8152_UNPLUG, &tp->flags)) -+ return; -+ -+ ocp_data = ocp_read_byte(tp, MCU_TYPE_USB, USB_ECM_OP); -+ ocp_data &= ~EN_ALL_SPEED; -+ ocp_write_byte(tp, MCU_TYPE_USB, USB_ECM_OP, ocp_data); -+ -+ ocp_write_word(tp, MCU_TYPE_USB, USB_SPEED_OPTION, 0); -+ -+ ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_ECM_OPTION); -+ ocp_data |= BYPASS_MAC_RESET; -+ ocp_write_word(tp, MCU_TYPE_USB, USB_ECM_OPTION, ocp_data); -+ -+ r8153b_u1u2en(tp, false); -+ -+ for (i = 0; i < 500; i++) { -+ if (ocp_read_word(tp, MCU_TYPE_PLA, PLA_BOOT_CTRL) & -+ AUTOLOAD_DONE) -+ break; -+ -+ msleep(20); -+ if (test_bit(RTL8152_UNPLUG, &tp->flags)) -+ return; -+ } -+ -+ data = r8153_phy_status(tp, 0); -+ if (data == PHY_STAT_EXT_INIT) { -+ data = ocp_reg_read(tp, 0xa468); -+ data &= ~(BIT(3) | BIT(1)); -+ ocp_reg_write(tp, 0xa468, data); -+ } -+ -+ data = r8152_mdio_read(tp, MII_BMCR); -+ if (data & BMCR_PDOWN) { -+ data &= ~BMCR_PDOWN; -+ r8152_mdio_write(tp, MII_BMCR, data); -+ } -+ -+ data = r8153_phy_status(tp, PHY_STAT_LAN_ON); -+ WARN_ON_ONCE(data != PHY_STAT_LAN_ON); -+ -+ r8153_u2p3en(tp, false); -+ -+ /* MSC timer = 0xfff * 8ms = 32760 ms */ -+ ocp_write_word(tp, MCU_TYPE_USB, USB_MSC_TIMER, 0x0fff); -+ -+ /* U1/U2/L1 idle timer. 500 us */ -+ ocp_write_word(tp, MCU_TYPE_USB, USB_U1U2_TIMER, 500); -+ -+ r8153b_power_cut_en(tp, false); -+ r8156_ups_en(tp, false); -+ r8153_queue_wake(tp, false); -+ rtl_runtime_suspend_enable(tp, false); -+ -+ if (tp->udev->speed >= USB_SPEED_SUPER) -+ r8153b_u1u2en(tp, true); -+ -+ usb_enable_lpm(tp->udev); -+ -+ r8156_mac_clk_spd(tp, true); -+ -+ ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL3); -+ ocp_data &= ~PLA_MCU_SPDWN_EN; -+ ocp_write_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL3, ocp_data); -+ -+ ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_EXTRA_STATUS); -+ if (rtl8152_get_speed(tp) & LINK_STATUS) -+ ocp_data |= CUR_LINK_OK; -+ else -+ ocp_data &= ~CUR_LINK_OK; -+ ocp_data |= POLL_LINK_CHG; -+ ocp_write_word(tp, MCU_TYPE_PLA, PLA_EXTRA_STATUS, ocp_data); -+ -+ set_bit(GREEN_ETHERNET, &tp->flags); -+ -+ /* rx aggregation */ -+ ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_USB_CTRL); -+ ocp_data &= ~(RX_AGG_DISABLE | RX_ZERO_EN); -+ ocp_write_word(tp, MCU_TYPE_USB, USB_USB_CTRL, ocp_data); -+ -+ ocp_data = ocp_read_byte(tp, MCU_TYPE_USB, USB_BMU_CONFIG); -+ ocp_data |= ACT_ODMA; -+ ocp_write_byte(tp, MCU_TYPE_USB, USB_BMU_CONFIG, ocp_data); -+ -+ rtl_tally_reset(tp); -+ -+ tp->coalesce = 15000; /* 15 us */ -+} -+ -+static void r8156b_init(struct r8152 *tp) -+{ -+ u32 ocp_data; -+ u16 data; -+ int i; -+ -+ if (test_bit(RTL8152_UNPLUG, &tp->flags)) -+ return; -+ -+ ocp_data = ocp_read_byte(tp, MCU_TYPE_USB, USB_ECM_OP); -+ ocp_data &= ~EN_ALL_SPEED; -+ ocp_write_byte(tp, MCU_TYPE_USB, USB_ECM_OP, ocp_data); -+ -+ ocp_write_word(tp, MCU_TYPE_USB, USB_SPEED_OPTION, 0); -+ -+ ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_ECM_OPTION); -+ ocp_data |= BYPASS_MAC_RESET; -+ ocp_write_word(tp, MCU_TYPE_USB, USB_ECM_OPTION, ocp_data); -+ -+ ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_U2P3_CTRL); -+ ocp_data |= RX_DETECT8; -+ ocp_write_word(tp, MCU_TYPE_USB, USB_U2P3_CTRL, ocp_data); -+ -+ r8153b_u1u2en(tp, false); -+ -+ switch (tp->version) { -+ case RTL_VER_13: -+ case RTL_VER_15: -+ r8156b_wait_loading_flash(tp); -+ break; -+ default: -+ break; -+ } -+ -+ for (i = 0; i < 500; i++) { -+ if (ocp_read_word(tp, MCU_TYPE_PLA, PLA_BOOT_CTRL) & -+ AUTOLOAD_DONE) -+ break; -+ -+ msleep(20); -+ if (test_bit(RTL8152_UNPLUG, &tp->flags)) -+ return; -+ } -+ -+ data = r8153_phy_status(tp, 0); -+ if (data == PHY_STAT_EXT_INIT) { -+ data = ocp_reg_read(tp, 0xa468); -+ data &= ~(BIT(3) | BIT(1)); -+ ocp_reg_write(tp, 0xa468, data); -+ -+ data = ocp_reg_read(tp, 0xa466); -+ data &= ~BIT(0); -+ ocp_reg_write(tp, 0xa466, data); -+ } -+ -+ data = r8152_mdio_read(tp, MII_BMCR); -+ if (data & BMCR_PDOWN) { -+ data &= ~BMCR_PDOWN; -+ r8152_mdio_write(tp, MII_BMCR, data); -+ } -+ -+ data = r8153_phy_status(tp, PHY_STAT_LAN_ON); -+ -+ r8153_u2p3en(tp, false); -+ -+ /* MSC timer = 0xfff * 8ms = 32760 ms */ -+ ocp_write_word(tp, MCU_TYPE_USB, USB_MSC_TIMER, 0x0fff); -+ -+ /* U1/U2/L1 idle timer. 500 us */ -+ ocp_write_word(tp, MCU_TYPE_USB, USB_U1U2_TIMER, 500); -+ -+ r8153b_power_cut_en(tp, false); -+ r8156_ups_en(tp, false); -+ r8153_queue_wake(tp, false); -+ rtl_runtime_suspend_enable(tp, false); -+ -+ if (tp->udev->speed >= USB_SPEED_SUPER) -+ r8153b_u1u2en(tp, true); -+ -+ usb_enable_lpm(tp->udev); -+ -+ ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_RCR); -+ ocp_data &= ~SLOT_EN; -+ ocp_write_word(tp, MCU_TYPE_PLA, PLA_RCR, ocp_data); -+ -+ ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_CPCR); -+ ocp_data |= FLOW_CTRL_EN; -+ ocp_write_word(tp, MCU_TYPE_PLA, PLA_CPCR, ocp_data); -+ -+ /* enable fc timer and set timer to 600 ms. */ -+ ocp_write_word(tp, MCU_TYPE_USB, USB_FC_TIMER, -+ CTRL_TIMER_EN | (600 / 8)); -+ -+ ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_FW_CTRL); -+ if (!(ocp_read_word(tp, MCU_TYPE_PLA, PLA_POL_GPIO_CTRL) & DACK_DET_EN)) -+ ocp_data |= FLOW_CTRL_PATCH_2; -+ ocp_data &= ~AUTO_SPEEDUP; -+ ocp_write_word(tp, MCU_TYPE_USB, USB_FW_CTRL, ocp_data); -+ -+ ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_FW_TASK); -+ ocp_data |= FC_PATCH_TASK; -+ ocp_write_word(tp, MCU_TYPE_USB, USB_FW_TASK, ocp_data); -+ -+ r8156_mac_clk_spd(tp, true); -+ -+ ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL3); -+ ocp_data &= ~PLA_MCU_SPDWN_EN; -+ ocp_write_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL3, ocp_data); -+ -+ ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_EXTRA_STATUS); -+ if (rtl8152_get_speed(tp) & LINK_STATUS) -+ ocp_data |= CUR_LINK_OK; -+ else -+ ocp_data &= ~CUR_LINK_OK; -+ ocp_data |= POLL_LINK_CHG; -+ ocp_write_word(tp, MCU_TYPE_PLA, PLA_EXTRA_STATUS, ocp_data); -+ -+ set_bit(GREEN_ETHERNET, &tp->flags); -+ -+ /* rx aggregation */ -+ ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_USB_CTRL); -+ ocp_data &= ~(RX_AGG_DISABLE | RX_ZERO_EN); -+ ocp_write_word(tp, MCU_TYPE_USB, USB_USB_CTRL, ocp_data); -+ -+ rtl_tally_reset(tp); -+ -+ tp->coalesce = 15000; /* 15 us */ -+} -+ - static int rtl8152_pre_reset(struct usb_interface *intf) - { - struct r8152 *tp = usb_get_intfdata(intf); -@@ -6015,6 +7947,22 @@ int rtl8152_get_link_ksettings(struct ne - - mii_ethtool_get_link_ksettings(&tp->mii, cmd); - -+ linkmode_mod_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT, -+ cmd->link_modes.supported, tp->support_2500full); -+ -+ if (tp->support_2500full) { -+ linkmode_mod_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT, -+ cmd->link_modes.advertising, -+ ocp_reg_read(tp, OCP_10GBT_CTRL) & MDIO_AN_10GBT_CTRL_ADV2_5G); -+ -+ linkmode_mod_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT, -+ cmd->link_modes.lp_advertising, -+ ocp_reg_read(tp, OCP_10GBT_STAT) & MDIO_AN_10GBT_STAT_LP2_5G); -+ -+ if (is_speed_2500(rtl8152_get_speed(tp))) -+ cmd->base.speed = SPEED_2500; -+ } -+ - mutex_unlock(&tp->control); - - usb_autopm_put_interface(tp->intf); -@@ -6058,6 +8006,10 @@ static int rtl8152_set_link_ksettings(st - cmd->link_modes.advertising)) - advertising |= RTL_ADVERTISED_1000_FULL; - -+ if (test_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT, -+ cmd->link_modes.advertising)) -+ advertising |= RTL_ADVERTISED_2500_FULL; -+ - mutex_lock(&tp->control); - - ret = rtl8152_set_speed(tp, cmd->base.autoneg, cmd->base.speed, -@@ -6647,6 +8599,67 @@ static int rtl_ops_init(struct r8152 *tp - tp->eee_adv = MDIO_EEE_1000T | MDIO_EEE_100TX; - break; - -+ case RTL_VER_11: -+ tp->eee_en = true; -+ tp->eee_adv = MDIO_EEE_1000T | MDIO_EEE_100TX; -+ fallthrough; -+ case RTL_VER_10: -+ ops->init = r8156_init; -+ ops->enable = rtl8156_enable; -+ ops->disable = rtl8153_disable; -+ ops->up = rtl8156_up; -+ ops->down = rtl8156_down; -+ ops->unload = rtl8153_unload; -+ ops->eee_get = r8153_get_eee; -+ ops->eee_set = r8152_set_eee; -+ ops->in_nway = rtl8153_in_nway; -+ ops->hw_phy_cfg = r8156_hw_phy_cfg; -+ ops->autosuspend_en = rtl8156_runtime_enable; -+ ops->change_mtu = rtl8156_change_mtu; -+ tp->rx_buf_sz = 48 * 1024; -+ tp->support_2500full = 1; -+ break; -+ -+ case RTL_VER_12: -+ case RTL_VER_13: -+ tp->support_2500full = 1; -+ fallthrough; -+ case RTL_VER_15: -+ tp->eee_en = true; -+ tp->eee_adv = MDIO_EEE_1000T | MDIO_EEE_100TX; -+ ops->init = r8156b_init; -+ ops->enable = rtl8156b_enable; -+ ops->disable = rtl8153_disable; -+ ops->up = rtl8156_up; -+ ops->down = rtl8156_down; -+ ops->unload = rtl8153_unload; -+ ops->eee_get = r8153_get_eee; -+ ops->eee_set = r8152_set_eee; -+ ops->in_nway = rtl8153_in_nway; -+ ops->hw_phy_cfg = r8156b_hw_phy_cfg; -+ ops->autosuspend_en = rtl8156_runtime_enable; -+ ops->change_mtu = rtl8156_change_mtu; -+ tp->rx_buf_sz = 48 * 1024; -+ break; -+ -+ case RTL_VER_14: -+ ops->init = r8153c_init; -+ ops->enable = rtl8153_enable; -+ ops->disable = rtl8153_disable; -+ ops->up = rtl8153c_up; -+ ops->down = rtl8153b_down; -+ ops->unload = rtl8153_unload; -+ ops->eee_get = r8153_get_eee; -+ ops->eee_set = r8152_set_eee; -+ ops->in_nway = rtl8153_in_nway; -+ ops->hw_phy_cfg = r8153c_hw_phy_cfg; -+ ops->autosuspend_en = rtl8153c_runtime_enable; -+ ops->change_mtu = rtl8153c_change_mtu; -+ tp->rx_buf_sz = 32 * 1024; -+ tp->eee_en = true; -+ tp->eee_adv = MDIO_EEE_1000T | MDIO_EEE_100TX; -+ break; -+ - default: - ret = -ENODEV; - dev_err(&tp->intf->dev, "Unknown Device\n"); -@@ -6660,11 +8673,13 @@ static int rtl_ops_init(struct r8152 *tp - #define FIRMWARE_8153A_3 "rtl_nic/rtl8153a-3.fw" - #define FIRMWARE_8153A_4 "rtl_nic/rtl8153a-4.fw" - #define FIRMWARE_8153B_2 "rtl_nic/rtl8153b-2.fw" -+#define FIRMWARE_8153C_1 "rtl_nic/rtl8153c-1.fw" - - MODULE_FIRMWARE(FIRMWARE_8153A_2); - MODULE_FIRMWARE(FIRMWARE_8153A_3); - MODULE_FIRMWARE(FIRMWARE_8153A_4); - MODULE_FIRMWARE(FIRMWARE_8153B_2); -+MODULE_FIRMWARE(FIRMWARE_8153C_1); - - static int rtl_fw_init(struct r8152 *tp) - { -@@ -6690,6 +8705,11 @@ static int rtl_fw_init(struct r8152 *tp) - rtl_fw->pre_fw = r8153b_pre_firmware_1; - rtl_fw->post_fw = r8153b_post_firmware_1; - break; -+ case RTL_VER_14: -+ rtl_fw->fw_name = FIRMWARE_8153C_1; -+ rtl_fw->pre_fw = r8153b_pre_firmware_1; -+ rtl_fw->post_fw = r8153c_post_firmware_1; -+ break; - default: - break; - } -@@ -6745,6 +8765,27 @@ u8 rtl8152_get_version(struct usb_interf - case 0x6010: - version = RTL_VER_09; - break; -+ case 0x7010: -+ version = RTL_TEST_01; -+ break; -+ case 0x7020: -+ version = RTL_VER_10; -+ break; -+ case 0x7030: -+ version = RTL_VER_11; -+ break; -+ case 0x7400: -+ version = RTL_VER_12; -+ break; -+ case 0x7410: -+ version = RTL_VER_13; -+ break; -+ case 0x6400: -+ version = RTL_VER_14; -+ break; -+ case 0x7420: -+ version = RTL_VER_15; -+ break; - default: - version = RTL_VER_UNKNOWN; - dev_info(&intf->dev, "Unknown version 0x%04x\n", ocp_data); -@@ -6857,12 +8898,29 @@ static int rtl8152_probe(struct usb_inte - /* MTU range: 68 - 1500 or 9194 */ - netdev->min_mtu = ETH_MIN_MTU; - switch (tp->version) { -+ case RTL_VER_03: -+ case RTL_VER_04: -+ case RTL_VER_05: -+ case RTL_VER_06: -+ case RTL_VER_08: -+ case RTL_VER_09: -+ case RTL_VER_14: -+ netdev->max_mtu = size_to_mtu(9 * 1024); -+ break; -+ case RTL_VER_10: -+ case RTL_VER_11: -+ netdev->max_mtu = size_to_mtu(15 * 1024); -+ break; -+ case RTL_VER_12: -+ case RTL_VER_13: -+ case RTL_VER_15: -+ netdev->max_mtu = size_to_mtu(16 * 1024); -+ break; - case RTL_VER_01: - case RTL_VER_02: -- netdev->max_mtu = ETH_DATA_LEN; -- break; -+ case RTL_VER_07: - default: -- netdev->max_mtu = size_to_mtu(9 * 1024); -+ netdev->max_mtu = ETH_DATA_LEN; - break; - } - -@@ -6878,7 +8936,13 @@ static int rtl8152_probe(struct usb_inte - tp->advertising = RTL_ADVERTISED_10_HALF | RTL_ADVERTISED_10_FULL | - RTL_ADVERTISED_100_HALF | RTL_ADVERTISED_100_FULL; - if (tp->mii.supports_gmii) { -- tp->speed = SPEED_1000; -+ if (tp->support_2500full && -+ tp->udev->speed >= USB_SPEED_SUPER) { -+ tp->speed = SPEED_2500; -+ tp->advertising |= RTL_ADVERTISED_2500_FULL; -+ } else { -+ tp->speed = SPEED_1000; -+ } - tp->advertising |= RTL_ADVERTISED_1000_FULL; - } - tp->duplex = DUPLEX_FULL; -@@ -6902,7 +8966,11 @@ static int rtl8152_probe(struct usb_inte - set_ethernet_addr(tp); - - usb_set_intfdata(intf, tp); -- netif_napi_add(netdev, &tp->napi, r8152_poll, RTL8152_NAPI_WEIGHT); -+ -+ if (tp->support_2500full) -+ netif_napi_add(netdev, &tp->napi, r8152_poll, 256); -+ else -+ netif_napi_add(netdev, &tp->napi, r8152_poll, 64); - - ret = register_netdev(netdev); - if (ret != 0) { -@@ -6938,7 +9006,8 @@ static void rtl8152_disconnect(struct us - unregister_netdev(tp->netdev); - tasklet_kill(&tp->tx_tl); - cancel_delayed_work_sync(&tp->hw_phy_work); -- tp->rtl_ops.unload(tp); -+ if (tp->rtl_ops.unload) -+ tp->rtl_ops.unload(tp); - rtl8152_release_firmware(tp); - free_netdev(tp->netdev); - } -@@ -6958,13 +9027,28 @@ static void rtl8152_disconnect(struct us - .idProduct = (prod), \ - .bInterfaceClass = USB_CLASS_COMM, \ - .bInterfaceSubClass = USB_CDC_SUBCLASS_ETHERNET, \ -+ .bInterfaceProtocol = USB_CDC_PROTO_NONE \ -+}, \ -+{ \ -+ .match_flags = USB_DEVICE_ID_MATCH_INT_INFO | \ -+ USB_DEVICE_ID_MATCH_DEVICE, \ -+ .idVendor = (vend), \ -+ .idProduct = (prod), \ -+ .bInterfaceClass = USB_CLASS_COMM, \ -+ .bInterfaceSubClass = USB_CDC_SUBCLASS_NCM, \ - .bInterfaceProtocol = USB_CDC_PROTO_NONE - - /* table of devices that work with this driver */ - static const struct usb_device_id rtl8152_table[] = { -+ /* Realtek */ - {REALTEK_USB_DEVICE(VENDOR_ID_REALTEK, 0x8050)}, -+ {REALTEK_USB_DEVICE(VENDOR_ID_REALTEK, 0x8053)}, - {REALTEK_USB_DEVICE(VENDOR_ID_REALTEK, 0x8152)}, - {REALTEK_USB_DEVICE(VENDOR_ID_REALTEK, 0x8153)}, -+ {REALTEK_USB_DEVICE(VENDOR_ID_REALTEK, 0x8155)}, -+ {REALTEK_USB_DEVICE(VENDOR_ID_REALTEK, 0x8156)}, -+ -+ /* Microsoft */ - {REALTEK_USB_DEVICE(VENDOR_ID_MICROSOFT, 0x07ab)}, - {REALTEK_USB_DEVICE(VENDOR_ID_MICROSOFT, 0x07c6)}, - {REALTEK_USB_DEVICE(VENDOR_ID_MICROSOFT, 0x0927)}, diff --git a/target/linux/bcm27xx/patches-5.10/950-0556-r8152-support-PHY-firmware-for-RTL8156-series.patch b/target/linux/bcm27xx/patches-5.10/950-0556-r8152-support-PHY-firmware-for-RTL8156-series.patch deleted file mode 100644 index 943c821b82..0000000000 --- a/target/linux/bcm27xx/patches-5.10/950-0556-r8152-support-PHY-firmware-for-RTL8156-series.patch +++ /dev/null @@ -1,691 +0,0 @@ -From ca09589a72a0aa17389754fb75a5cd1a5d46818f Mon Sep 17 00:00:00 2001 -From: Hayes Wang -Date: Fri, 16 Apr 2021 16:04:36 +0800 -Subject: [PATCH] r8152: support PHY firmware for RTL8156 series - -commit 4a51b0e8a0143b0e83d51d9c58c6416c3818a9f2 upstream. - -Support new firmware type and method for RTL8156 series. - -Signed-off-by: Hayes Wang -Signed-off-by: David S. Miller ---- - drivers/net/usb/r8152.c | 563 +++++++++++++++++++++++++++++++++++++++- - 1 file changed, 561 insertions(+), 2 deletions(-) - ---- a/drivers/net/usb/r8152.c -+++ b/drivers/net/usb/r8152.c -@@ -975,8 +975,60 @@ enum rtl8152_fw_flags { - FW_FLAGS_START, - FW_FLAGS_STOP, - FW_FLAGS_NC, -+ FW_FLAGS_NC1, -+ FW_FLAGS_NC2, -+ FW_FLAGS_UC2, -+ FW_FLAGS_UC, -+ FW_FLAGS_SPEED_UP, -+ FW_FLAGS_VER, - }; - -+enum rtl8152_fw_fixup_cmd { -+ FW_FIXUP_AND = 0, -+ FW_FIXUP_OR, -+ FW_FIXUP_NOT, -+ FW_FIXUP_XOR, -+}; -+ -+struct fw_phy_set { -+ __le16 addr; -+ __le16 data; -+} __packed; -+ -+struct fw_phy_speed_up { -+ struct fw_block blk_hdr; -+ __le16 fw_offset; -+ __le16 version; -+ __le16 fw_reg; -+ __le16 reserved; -+ char info[]; -+} __packed; -+ -+struct fw_phy_ver { -+ struct fw_block blk_hdr; -+ struct fw_phy_set ver; -+ __le32 reserved; -+} __packed; -+ -+struct fw_phy_fixup { -+ struct fw_block blk_hdr; -+ struct fw_phy_set setting; -+ __le16 bit_cmd; -+ __le16 reserved; -+} __packed; -+ -+struct fw_phy_union { -+ struct fw_block blk_hdr; -+ __le16 fw_offset; -+ __le16 fw_reg; -+ struct fw_phy_set pre_set[2]; -+ struct fw_phy_set bp[8]; -+ struct fw_phy_set bp_en; -+ u8 pre_num; -+ u8 bp_num; -+ char info[]; -+} __packed; -+ - /** - * struct fw_mac - a firmware block used by RTL_FW_PLA and RTL_FW_USB. - * The layout of the firmware block is: -@@ -1081,6 +1133,15 @@ enum rtl_fw_type { - RTL_FW_PHY_START, - RTL_FW_PHY_STOP, - RTL_FW_PHY_NC, -+ RTL_FW_PHY_FIXUP, -+ RTL_FW_PHY_UNION_NC, -+ RTL_FW_PHY_UNION_NC1, -+ RTL_FW_PHY_UNION_NC2, -+ RTL_FW_PHY_UNION_UC2, -+ RTL_FW_PHY_UNION_UC, -+ RTL_FW_PHY_UNION_MISC, -+ RTL_FW_PHY_SPEED_UP, -+ RTL_FW_PHY_VER, - }; - - enum rtl_version { -@@ -4000,6 +4061,162 @@ static int rtl_post_ram_code(struct r815 - return 0; - } - -+static bool rtl8152_is_fw_phy_speed_up_ok(struct r8152 *tp, struct fw_phy_speed_up *phy) -+{ -+ u16 fw_offset; -+ u32 length; -+ bool rc = false; -+ -+ switch (tp->version) { -+ case RTL_VER_01: -+ case RTL_VER_02: -+ case RTL_VER_03: -+ case RTL_VER_04: -+ case RTL_VER_05: -+ case RTL_VER_06: -+ case RTL_VER_07: -+ case RTL_VER_08: -+ case RTL_VER_09: -+ case RTL_VER_10: -+ case RTL_VER_11: -+ case RTL_VER_12: -+ case RTL_VER_14: -+ goto out; -+ case RTL_VER_13: -+ case RTL_VER_15: -+ default: -+ break; -+ } -+ -+ fw_offset = __le16_to_cpu(phy->fw_offset); -+ length = __le32_to_cpu(phy->blk_hdr.length); -+ if (fw_offset < sizeof(*phy) || length <= fw_offset) { -+ dev_err(&tp->intf->dev, "invalid fw_offset\n"); -+ goto out; -+ } -+ -+ length -= fw_offset; -+ if (length & 3) { -+ dev_err(&tp->intf->dev, "invalid block length\n"); -+ goto out; -+ } -+ -+ if (__le16_to_cpu(phy->fw_reg) != 0x9A00) { -+ dev_err(&tp->intf->dev, "invalid register to load firmware\n"); -+ goto out; -+ } -+ -+ rc = true; -+out: -+ return rc; -+} -+ -+static bool rtl8152_is_fw_phy_ver_ok(struct r8152 *tp, struct fw_phy_ver *ver) -+{ -+ bool rc = false; -+ -+ switch (tp->version) { -+ case RTL_VER_10: -+ case RTL_VER_11: -+ case RTL_VER_12: -+ case RTL_VER_13: -+ case RTL_VER_15: -+ break; -+ default: -+ goto out; -+ } -+ -+ if (__le32_to_cpu(ver->blk_hdr.length) != sizeof(*ver)) { -+ dev_err(&tp->intf->dev, "invalid block length\n"); -+ goto out; -+ } -+ -+ if (__le16_to_cpu(ver->ver.addr) != SRAM_GPHY_FW_VER) { -+ dev_err(&tp->intf->dev, "invalid phy ver addr\n"); -+ goto out; -+ } -+ -+ rc = true; -+out: -+ return rc; -+} -+ -+static bool rtl8152_is_fw_phy_fixup_ok(struct r8152 *tp, struct fw_phy_fixup *fix) -+{ -+ bool rc = false; -+ -+ switch (tp->version) { -+ case RTL_VER_10: -+ case RTL_VER_11: -+ case RTL_VER_12: -+ case RTL_VER_13: -+ case RTL_VER_15: -+ break; -+ default: -+ goto out; -+ } -+ -+ if (__le32_to_cpu(fix->blk_hdr.length) != sizeof(*fix)) { -+ dev_err(&tp->intf->dev, "invalid block length\n"); -+ goto out; -+ } -+ -+ if (__le16_to_cpu(fix->setting.addr) != OCP_PHY_PATCH_CMD || -+ __le16_to_cpu(fix->setting.data) != BIT(7)) { -+ dev_err(&tp->intf->dev, "invalid phy fixup\n"); -+ goto out; -+ } -+ -+ rc = true; -+out: -+ return rc; -+} -+ -+static bool rtl8152_is_fw_phy_union_ok(struct r8152 *tp, struct fw_phy_union *phy) -+{ -+ u16 fw_offset; -+ u32 length; -+ bool rc = false; -+ -+ switch (tp->version) { -+ case RTL_VER_10: -+ case RTL_VER_11: -+ case RTL_VER_12: -+ case RTL_VER_13: -+ case RTL_VER_15: -+ break; -+ default: -+ goto out; -+ } -+ -+ fw_offset = __le16_to_cpu(phy->fw_offset); -+ length = __le32_to_cpu(phy->blk_hdr.length); -+ if (fw_offset < sizeof(*phy) || length <= fw_offset) { -+ dev_err(&tp->intf->dev, "invalid fw_offset\n"); -+ goto out; -+ } -+ -+ length -= fw_offset; -+ if (length & 1) { -+ dev_err(&tp->intf->dev, "invalid block length\n"); -+ goto out; -+ } -+ -+ if (phy->pre_num > 2) { -+ dev_err(&tp->intf->dev, "invalid pre_num %d\n", phy->pre_num); -+ goto out; -+ } -+ -+ if (phy->bp_num > 8) { -+ dev_err(&tp->intf->dev, "invalid bp_num %d\n", phy->bp_num); -+ goto out; -+ } -+ -+ rc = true; -+out: -+ return rc; -+} -+ - static bool rtl8152_is_fw_phy_nc_ok(struct r8152 *tp, struct fw_phy_nc *phy) - { - u32 length; -@@ -4320,6 +4537,10 @@ static long rtl8152_check_firmware(struc - case RTL_FW_PHY_START: - if (test_bit(FW_FLAGS_START, &fw_flags) || - test_bit(FW_FLAGS_NC, &fw_flags) || -+ test_bit(FW_FLAGS_NC1, &fw_flags) || -+ test_bit(FW_FLAGS_NC2, &fw_flags) || -+ test_bit(FW_FLAGS_UC2, &fw_flags) || -+ test_bit(FW_FLAGS_UC, &fw_flags) || - test_bit(FW_FLAGS_STOP, &fw_flags)) { - dev_err(&tp->intf->dev, - "check PHY_START fail\n"); -@@ -4368,7 +4589,153 @@ static long rtl8152_check_firmware(struc - goto fail; - } - __set_bit(FW_FLAGS_NC, &fw_flags); -+ break; -+ case RTL_FW_PHY_UNION_NC: -+ if (!test_bit(FW_FLAGS_START, &fw_flags) || -+ test_bit(FW_FLAGS_NC1, &fw_flags) || -+ test_bit(FW_FLAGS_NC2, &fw_flags) || -+ test_bit(FW_FLAGS_UC2, &fw_flags) || -+ test_bit(FW_FLAGS_UC, &fw_flags) || -+ test_bit(FW_FLAGS_STOP, &fw_flags)) { -+ dev_err(&tp->intf->dev, "PHY_UNION_NC out of order\n"); -+ goto fail; -+ } -+ -+ if (test_bit(FW_FLAGS_NC, &fw_flags)) { -+ dev_err(&tp->intf->dev, "multiple PHY_UNION_NC encountered\n"); -+ goto fail; -+ } - -+ if (!rtl8152_is_fw_phy_union_ok(tp, (struct fw_phy_union *)block)) { -+ dev_err(&tp->intf->dev, "check PHY_UNION_NC failed\n"); -+ goto fail; -+ } -+ __set_bit(FW_FLAGS_NC, &fw_flags); -+ break; -+ case RTL_FW_PHY_UNION_NC1: -+ if (!test_bit(FW_FLAGS_START, &fw_flags) || -+ test_bit(FW_FLAGS_NC2, &fw_flags) || -+ test_bit(FW_FLAGS_UC2, &fw_flags) || -+ test_bit(FW_FLAGS_UC, &fw_flags) || -+ test_bit(FW_FLAGS_STOP, &fw_flags)) { -+ dev_err(&tp->intf->dev, "PHY_UNION_NC1 out of order\n"); -+ goto fail; -+ } -+ -+ if (test_bit(FW_FLAGS_NC1, &fw_flags)) { -+ dev_err(&tp->intf->dev, "multiple PHY NC1 encountered\n"); -+ goto fail; -+ } -+ -+ if (!rtl8152_is_fw_phy_union_ok(tp, (struct fw_phy_union *)block)) { -+ dev_err(&tp->intf->dev, "check PHY_UNION_NC1 failed\n"); -+ goto fail; -+ } -+ __set_bit(FW_FLAGS_NC1, &fw_flags); -+ break; -+ case RTL_FW_PHY_UNION_NC2: -+ if (!test_bit(FW_FLAGS_START, &fw_flags) || -+ test_bit(FW_FLAGS_UC2, &fw_flags) || -+ test_bit(FW_FLAGS_UC, &fw_flags) || -+ test_bit(FW_FLAGS_STOP, &fw_flags)) { -+ dev_err(&tp->intf->dev, "PHY_UNION_NC2 out of order\n"); -+ goto fail; -+ } -+ -+ if (test_bit(FW_FLAGS_NC2, &fw_flags)) { -+ dev_err(&tp->intf->dev, "multiple PHY NC2 encountered\n"); -+ goto fail; -+ } -+ -+ if (!rtl8152_is_fw_phy_union_ok(tp, (struct fw_phy_union *)block)) { -+ dev_err(&tp->intf->dev, "check PHY_UNION_NC2 failed\n"); -+ goto fail; -+ } -+ __set_bit(FW_FLAGS_NC2, &fw_flags); -+ break; -+ case RTL_FW_PHY_UNION_UC2: -+ if (!test_bit(FW_FLAGS_START, &fw_flags) || -+ test_bit(FW_FLAGS_UC, &fw_flags) || -+ test_bit(FW_FLAGS_STOP, &fw_flags)) { -+ dev_err(&tp->intf->dev, "PHY_UNION_UC2 out of order\n"); -+ goto fail; -+ } -+ -+ if (test_bit(FW_FLAGS_UC2, &fw_flags)) { -+ dev_err(&tp->intf->dev, "multiple PHY UC2 encountered\n"); -+ goto fail; -+ } -+ -+ if (!rtl8152_is_fw_phy_union_ok(tp, (struct fw_phy_union *)block)) { -+ dev_err(&tp->intf->dev, "check PHY_UNION_UC2 failed\n"); -+ goto fail; -+ } -+ __set_bit(FW_FLAGS_UC2, &fw_flags); -+ break; -+ case RTL_FW_PHY_UNION_UC: -+ if (!test_bit(FW_FLAGS_START, &fw_flags) || -+ test_bit(FW_FLAGS_STOP, &fw_flags)) { -+ dev_err(&tp->intf->dev, "PHY_UNION_UC out of order\n"); -+ goto fail; -+ } -+ -+ if (test_bit(FW_FLAGS_UC, &fw_flags)) { -+ dev_err(&tp->intf->dev, "multiple PHY UC encountered\n"); -+ goto fail; -+ } -+ -+ if (!rtl8152_is_fw_phy_union_ok(tp, (struct fw_phy_union *)block)) { -+ dev_err(&tp->intf->dev, "check PHY_UNION_UC failed\n"); -+ goto fail; -+ } -+ __set_bit(FW_FLAGS_UC, &fw_flags); -+ break; -+ case RTL_FW_PHY_UNION_MISC: -+ if (!rtl8152_is_fw_phy_union_ok(tp, (struct fw_phy_union *)block)) { -+ dev_err(&tp->intf->dev, "check RTL_FW_PHY_UNION_MISC failed\n"); -+ goto fail; -+ } -+ break; -+ case RTL_FW_PHY_FIXUP: -+ if (!rtl8152_is_fw_phy_fixup_ok(tp, (struct fw_phy_fixup *)block)) { -+ dev_err(&tp->intf->dev, "check PHY fixup failed\n"); -+ goto fail; -+ } -+ break; -+ case RTL_FW_PHY_SPEED_UP: -+ if (test_bit(FW_FLAGS_SPEED_UP, &fw_flags)) { -+ dev_err(&tp->intf->dev, "multiple PHY firmware encountered"); -+ goto fail; -+ } -+ -+ if (!rtl8152_is_fw_phy_speed_up_ok(tp, (struct fw_phy_speed_up *)block)) { -+ dev_err(&tp->intf->dev, "check PHY speed up failed\n"); -+ goto fail; -+ } -+ __set_bit(FW_FLAGS_SPEED_UP, &fw_flags); -+ break; -+ case RTL_FW_PHY_VER: -+ if (test_bit(FW_FLAGS_START, &fw_flags) || -+ test_bit(FW_FLAGS_NC, &fw_flags) || -+ test_bit(FW_FLAGS_NC1, &fw_flags) || -+ test_bit(FW_FLAGS_NC2, &fw_flags) || -+ test_bit(FW_FLAGS_UC2, &fw_flags) || -+ test_bit(FW_FLAGS_UC, &fw_flags) || -+ test_bit(FW_FLAGS_STOP, &fw_flags)) { -+ dev_err(&tp->intf->dev, "Invalid order to set PHY version\n"); -+ goto fail; -+ } -+ -+ if (test_bit(FW_FLAGS_VER, &fw_flags)) { -+ dev_err(&tp->intf->dev, "multiple PHY version encountered"); -+ goto fail; -+ } -+ -+ if (!rtl8152_is_fw_phy_ver_ok(tp, (struct fw_phy_ver *)block)) { -+ dev_err(&tp->intf->dev, "check PHY version failed\n"); -+ goto fail; -+ } -+ __set_bit(FW_FLAGS_VER, &fw_flags); - break; - default: - dev_warn(&tp->intf->dev, "Unknown type %u is found\n", -@@ -4391,6 +4758,143 @@ fail: - return ret; - } - -+static void rtl_ram_code_speed_up(struct r8152 *tp, struct fw_phy_speed_up *phy, bool wait) -+{ -+ u32 len; -+ u8 *data; -+ -+ if (sram_read(tp, SRAM_GPHY_FW_VER) >= __le16_to_cpu(phy->version)) { -+ dev_dbg(&tp->intf->dev, "PHY firmware has been the newest\n"); -+ return; -+ } -+ -+ len = __le32_to_cpu(phy->blk_hdr.length); -+ len -= __le16_to_cpu(phy->fw_offset); -+ data = (u8 *)phy + __le16_to_cpu(phy->fw_offset); -+ -+ if (rtl_phy_patch_request(tp, true, wait)) -+ return; -+ -+ while (len) { -+ u32 ocp_data, size; -+ int i; -+ -+ if (len < 2048) -+ size = len; -+ else -+ size = 2048; -+ -+ ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_GPHY_CTRL); -+ ocp_data |= GPHY_PATCH_DONE | BACKUP_RESTRORE; -+ ocp_write_word(tp, MCU_TYPE_USB, USB_GPHY_CTRL, ocp_data); -+ -+ generic_ocp_write(tp, __le16_to_cpu(phy->fw_reg), 0xff, size, data, MCU_TYPE_USB); -+ -+ data += size; -+ len -= size; -+ -+ ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_POL_GPIO_CTRL); -+ ocp_data |= POL_GPHY_PATCH; -+ ocp_write_word(tp, MCU_TYPE_PLA, PLA_POL_GPIO_CTRL, ocp_data); -+ -+ for (i = 0; i < 1000; i++) { -+ if (!(ocp_read_word(tp, MCU_TYPE_PLA, PLA_POL_GPIO_CTRL) & POL_GPHY_PATCH)) -+ break; -+ } -+ -+ if (i == 1000) { -+ dev_err(&tp->intf->dev, "ram code speedup mode timeout\n"); -+ return; -+ } -+ } -+ -+ ocp_write_word(tp, MCU_TYPE_PLA, PLA_OCP_GPHY_BASE, tp->ocp_base); -+ rtl_phy_patch_request(tp, false, wait); -+ -+ if (sram_read(tp, SRAM_GPHY_FW_VER) == __le16_to_cpu(phy->version)) -+ dev_dbg(&tp->intf->dev, "successfully applied %s\n", phy->info); -+ else -+ dev_err(&tp->intf->dev, "ram code speedup mode fail\n"); -+} -+ -+static int rtl8152_fw_phy_ver(struct r8152 *tp, struct fw_phy_ver *phy_ver) -+{ -+ u16 ver_addr, ver; -+ -+ ver_addr = __le16_to_cpu(phy_ver->ver.addr); -+ ver = __le16_to_cpu(phy_ver->ver.data); -+ -+ if (sram_read(tp, ver_addr) >= ver) { -+ dev_dbg(&tp->intf->dev, "PHY firmware has been the newest\n"); -+ return 0; -+ } -+ -+ sram_write(tp, ver_addr, ver); -+ -+ dev_dbg(&tp->intf->dev, "PHY firmware version %x\n", ver); -+ -+ return ver; -+} -+ -+static void rtl8152_fw_phy_fixup(struct r8152 *tp, struct fw_phy_fixup *fix) -+{ -+ u16 addr, data; -+ -+ addr = __le16_to_cpu(fix->setting.addr); -+ data = ocp_reg_read(tp, addr); -+ -+ switch (__le16_to_cpu(fix->bit_cmd)) { -+ case FW_FIXUP_AND: -+ data &= __le16_to_cpu(fix->setting.data); -+ break; -+ case FW_FIXUP_OR: -+ data |= __le16_to_cpu(fix->setting.data); -+ break; -+ case FW_FIXUP_NOT: -+ data &= ~__le16_to_cpu(fix->setting.data); -+ break; -+ case FW_FIXUP_XOR: -+ data ^= __le16_to_cpu(fix->setting.data); -+ break; -+ default: -+ return; -+ } -+ -+ ocp_reg_write(tp, addr, data); -+ -+ dev_dbg(&tp->intf->dev, "applied ocp %x %x\n", addr, data); -+} -+ -+static void rtl8152_fw_phy_union_apply(struct r8152 *tp, struct fw_phy_union *phy) -+{ -+ __le16 *data; -+ u32 length; -+ int i, num; -+ -+ num = phy->pre_num; -+ for (i = 0; i < num; i++) -+ sram_write(tp, __le16_to_cpu(phy->pre_set[i].addr), -+ __le16_to_cpu(phy->pre_set[i].data)); -+ -+ length = __le32_to_cpu(phy->blk_hdr.length); -+ length -= __le16_to_cpu(phy->fw_offset); -+ num = length / 2; -+ data = (__le16 *)((u8 *)phy + __le16_to_cpu(phy->fw_offset)); -+ -+ ocp_reg_write(tp, OCP_SRAM_ADDR, __le16_to_cpu(phy->fw_reg)); -+ for (i = 0; i < num; i++) -+ ocp_reg_write(tp, OCP_SRAM_DATA, __le16_to_cpu(data[i])); -+ -+ num = phy->bp_num; -+ for (i = 0; i < num; i++) -+ sram_write(tp, __le16_to_cpu(phy->bp[i].addr), __le16_to_cpu(phy->bp[i].data)); -+ -+ if (phy->bp_num && phy->bp_en.addr) -+ sram_write(tp, __le16_to_cpu(phy->bp_en.addr), __le16_to_cpu(phy->bp_en.data)); -+ -+ dev_dbg(&tp->intf->dev, "successfully applied %s\n", phy->info); -+} -+ - static void rtl8152_fw_phy_nc_apply(struct r8152 *tp, struct fw_phy_nc *phy) - { - u16 mode_reg, bp_index; -@@ -4444,6 +4948,12 @@ static void rtl8152_fw_mac_apply(struct - return; - } - -+ fw_ver_reg = __le16_to_cpu(mac->fw_ver_reg); -+ if (fw_ver_reg && ocp_read_byte(tp, MCU_TYPE_USB, fw_ver_reg) >= mac->fw_ver_data) { -+ dev_dbg(&tp->intf->dev, "%s firmware has been the newest\n", type ? "PLA" : "USB"); -+ return; -+ } -+ - rtl_clear_bp(tp, type); - - /* Enable backup/restore of MACDBG. This is required after clearing PLA -@@ -4479,7 +4989,6 @@ static void rtl8152_fw_mac_apply(struct - ocp_write_word(tp, type, bp_en_addr, - __le16_to_cpu(mac->bp_en_value)); - -- fw_ver_reg = __le16_to_cpu(mac->fw_ver_reg); - if (fw_ver_reg) - ocp_write_byte(tp, MCU_TYPE_USB, fw_ver_reg, - mac->fw_ver_data); -@@ -4494,7 +5003,7 @@ static void rtl8152_apply_firmware(struc - struct fw_header *fw_hdr; - struct fw_phy_patch_key *key; - u16 key_addr = 0; -- int i; -+ int i, patch_phy = 1; - - if (IS_ERR_OR_NULL(rtl_fw->fw)) - return; -@@ -4516,17 +5025,40 @@ static void rtl8152_apply_firmware(struc - rtl8152_fw_mac_apply(tp, (struct fw_mac *)block); - break; - case RTL_FW_PHY_START: -+ if (!patch_phy) -+ break; - key = (struct fw_phy_patch_key *)block; - key_addr = __le16_to_cpu(key->key_reg); - rtl_pre_ram_code(tp, key_addr, __le16_to_cpu(key->key_data), !power_cut); - break; - case RTL_FW_PHY_STOP: -+ if (!patch_phy) -+ break; - WARN_ON(!key_addr); - rtl_post_ram_code(tp, key_addr, !power_cut); - break; - case RTL_FW_PHY_NC: - rtl8152_fw_phy_nc_apply(tp, (struct fw_phy_nc *)block); - break; -+ case RTL_FW_PHY_VER: -+ patch_phy = rtl8152_fw_phy_ver(tp, (struct fw_phy_ver *)block); -+ break; -+ case RTL_FW_PHY_UNION_NC: -+ case RTL_FW_PHY_UNION_NC1: -+ case RTL_FW_PHY_UNION_NC2: -+ case RTL_FW_PHY_UNION_UC2: -+ case RTL_FW_PHY_UNION_UC: -+ case RTL_FW_PHY_UNION_MISC: -+ if (patch_phy) -+ rtl8152_fw_phy_union_apply(tp, (struct fw_phy_union *)block); -+ break; -+ case RTL_FW_PHY_FIXUP: -+ if (patch_phy) -+ rtl8152_fw_phy_fixup(tp, (struct fw_phy_fixup *)block); -+ break; -+ case RTL_FW_PHY_SPEED_UP: -+ rtl_ram_code_speed_up(tp, (struct fw_phy_speed_up *)block, !power_cut); -+ break; - default: - break; - } -@@ -5034,6 +5566,21 @@ static int r8153c_post_firmware_1(struct - return 0; - } - -+static int r8156a_post_firmware_1(struct r8152 *tp) -+{ -+ u32 ocp_data; -+ -+ ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_FW_FIX_EN1); -+ ocp_data |= FW_IP_RESET_EN; -+ ocp_write_word(tp, MCU_TYPE_USB, USB_FW_FIX_EN1, ocp_data); -+ -+ /* Modify U3PHY parameter for compatibility issue */ -+ ocp_write_dword(tp, MCU_TYPE_USB, USB_UPHY3_MDCMDIO, 0x4026840e); -+ ocp_write_dword(tp, MCU_TYPE_USB, USB_UPHY3_MDCMDIO, 0x4001acc9); -+ -+ return 0; -+} -+ - static void r8153_aldps_en(struct r8152 *tp, bool enable) - { - u16 data; -@@ -8674,12 +9221,16 @@ static int rtl_ops_init(struct r8152 *tp - #define FIRMWARE_8153A_4 "rtl_nic/rtl8153a-4.fw" - #define FIRMWARE_8153B_2 "rtl_nic/rtl8153b-2.fw" - #define FIRMWARE_8153C_1 "rtl_nic/rtl8153c-1.fw" -+#define FIRMWARE_8156A_2 "rtl_nic/rtl8156a-2.fw" -+#define FIRMWARE_8156B_2 "rtl_nic/rtl8156b-2.fw" - - MODULE_FIRMWARE(FIRMWARE_8153A_2); - MODULE_FIRMWARE(FIRMWARE_8153A_3); - MODULE_FIRMWARE(FIRMWARE_8153A_4); - MODULE_FIRMWARE(FIRMWARE_8153B_2); - MODULE_FIRMWARE(FIRMWARE_8153C_1); -+MODULE_FIRMWARE(FIRMWARE_8156A_2); -+MODULE_FIRMWARE(FIRMWARE_8156B_2); - - static int rtl_fw_init(struct r8152 *tp) - { -@@ -8705,6 +9256,14 @@ static int rtl_fw_init(struct r8152 *tp) - rtl_fw->pre_fw = r8153b_pre_firmware_1; - rtl_fw->post_fw = r8153b_post_firmware_1; - break; -+ case RTL_VER_11: -+ rtl_fw->fw_name = FIRMWARE_8156A_2; -+ rtl_fw->post_fw = r8156a_post_firmware_1; -+ break; -+ case RTL_VER_13: -+ case RTL_VER_15: -+ rtl_fw->fw_name = FIRMWARE_8156B_2; -+ break; - case RTL_VER_14: - rtl_fw->fw_name = FIRMWARE_8153C_1; - rtl_fw->pre_fw = r8153b_pre_firmware_1; diff --git a/target/linux/bcm27xx/patches-5.10/950-0557-r8152-search-the-configuration-of-vendor-mode.patch b/target/linux/bcm27xx/patches-5.10/950-0557-r8152-search-the-configuration-of-vendor-mode.patch deleted file mode 100644 index 9ce0e778cf..0000000000 --- a/target/linux/bcm27xx/patches-5.10/950-0557-r8152-search-the-configuration-of-vendor-mode.patch +++ /dev/null @@ -1,79 +0,0 @@ -From 579f58dd2819910354753bc5489fc1588fe9cfe2 Mon Sep 17 00:00:00 2001 -From: Hayes Wang -Date: Fri, 16 Apr 2021 16:04:37 +0800 -Subject: [PATCH] r8152: search the configuration of vendor mode - -commit c2198943e33b100ed21dfb636c8fa6baef841e9d upstream. - -The vendor mode is not always at config #1, so it is necessary to -set the correct configuration number. - -Signed-off-by: Hayes Wang -Signed-off-by: David S. Miller ---- - drivers/net/usb/r8152.c | 39 +++++++++++++++++++++++++++++++++++---- - 1 file changed, 35 insertions(+), 4 deletions(-) - ---- a/drivers/net/usb/r8152.c -+++ b/drivers/net/usb/r8152.c -@@ -30,7 +30,7 @@ - #include - - /* Information for net-next */ --#define NETNEXT_VERSION "11" -+#define NETNEXT_VERSION "12" - - /* Information for net */ - #define NET_VERSION "11" -@@ -8131,6 +8131,39 @@ static void r8156b_init(struct r8152 *tp - tp->coalesce = 15000; /* 15 us */ - } - -+static bool rtl_vendor_mode(struct usb_interface *intf) -+{ -+ struct usb_host_interface *alt = intf->cur_altsetting; -+ struct usb_device *udev; -+ struct usb_host_config *c; -+ int i, num_configs; -+ -+ if (alt->desc.bInterfaceClass == USB_CLASS_VENDOR_SPEC) -+ return true; -+ -+ /* The vendor mode is not always config #1, so to find it out. */ -+ udev = interface_to_usbdev(intf); -+ c = udev->config; -+ num_configs = udev->descriptor.bNumConfigurations; -+ for (i = 0; i < num_configs; (i++, c++)) { -+ struct usb_interface_descriptor *desc = NULL; -+ -+ if (c->desc.bNumInterfaces > 0) -+ desc = &c->intf_cache[0]->altsetting->desc; -+ else -+ continue; -+ -+ if (desc->bInterfaceClass == USB_CLASS_VENDOR_SPEC) { -+ usb_driver_set_configuration(udev, c->desc.bConfigurationValue); -+ break; -+ } -+ } -+ -+ WARN_ON_ONCE(i == num_configs); -+ -+ return false; -+} -+ - static int rtl8152_pre_reset(struct usb_interface *intf) - { - struct r8152 *tp = usb_get_intfdata(intf); -@@ -9369,10 +9402,8 @@ static int rtl8152_probe(struct usb_inte - if (version == RTL_VER_UNKNOWN) - return -ENODEV; - -- if (udev->actconfig->desc.bConfigurationValue != 1) { -- usb_driver_set_configuration(udev, 1); -+ if (!rtl_vendor_mode(intf)) - return -ENODEV; -- } - - if (intf->cur_altsetting->desc.bNumEndpoints < 3) - return -ENODEV; diff --git a/target/linux/generic/backport-5.10/780-v5.11-net-usb-r8152-Provide-missing-documentation-for-some.patch b/target/linux/generic/backport-5.10/780-v5.11-net-usb-r8152-Provide-missing-documentation-for-some.patch new file mode 100644 index 0000000000..bec2867a48 --- /dev/null +++ b/target/linux/generic/backport-5.10/780-v5.11-net-usb-r8152-Provide-missing-documentation-for-some.patch @@ -0,0 +1,72 @@ +From 586f04ce6a391419ca3cc9cef6b6f38570cede88 Mon Sep 17 00:00:00 2001 +From: Lee Jones +Date: Mon, 2 Nov 2020 11:45:04 +0000 +Subject: [PATCH] net: usb: r8152: Provide missing documentation for + some struct members + +commit 34e653efb602e0651867fb5ab14369b555a61dcd upstream. + +Fixes the following W=1 kernel build warning(s): + + drivers/net/usb/r8152.c:934: warning: Function parameter or member 'blk_hdr' not described in 'fw_mac' + drivers/net/usb/r8152.c:934: warning: Function parameter or member 'reserved' not described in 'fw_mac' + drivers/net/usb/r8152.c:947: warning: Function parameter or member 'blk_hdr' not described in 'fw_phy_patch_key' + drivers/net/usb/r8152.c:947: warning: Function parameter or member 'reserved' not described in 'fw_phy_patch_key' + drivers/net/usb/r8152.c:986: warning: Function parameter or member 'blk_hdr' not described in 'fw_phy_nc' + drivers/net/usb/r8152.c:986: warning: Function parameter or member 'mode_pre' not described in 'fw_phy_nc' + drivers/net/usb/r8152.c:986: warning: Function parameter or member 'mode_post' not described in 'fw_phy_nc' + drivers/net/usb/r8152.c:986: warning: Function parameter or member 'reserved' not described in 'fw_phy_nc' + +Signed-off-by: Lee Jones +Acked-by: Hayes Wang +Link: https://lore.kernel.org/r/20201102114512.1062724-23-lee.jones@linaro.org +Signed-off-by: Jakub Kicinski +--- + drivers/net/usb/r8152.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +--- a/drivers/net/usb/r8152.c ++++ b/drivers/net/usb/r8152.c +@@ -899,6 +899,7 @@ struct fw_header { + * struct fw_mac - a firmware block used by RTL_FW_PLA and RTL_FW_USB. + * The layout of the firmware block is: + * + + . ++ * @blk_hdr: firmware descriptor (type, length) + * @fw_offset: offset of the firmware binary data. The start address of + * the data would be the address of struct fw_mac + @fw_offset. + * @fw_reg: the register to load the firmware. Depends on chip. +@@ -912,6 +913,7 @@ struct fw_header { + * @bp_num: the break point number which needs to be set for this firmware. + * Depends on the firmware. + * @bp: break points. Depends on firmware. ++ * @reserved: reserved space (unused) + * @fw_ver_reg: the register to store the fw version. + * @fw_ver_data: the firmware version of the current type. + * @info: additional information for debugging, and is followed by the +@@ -937,8 +939,10 @@ struct fw_mac { + /** + * struct fw_phy_patch_key - a firmware block used by RTL_FW_PHY_START. + * This is used to set patch key when loading the firmware of PHY. ++ * @blk_hdr: firmware descriptor (type, length) + * @key_reg: the register to write the patch key. + * @key_data: patch key. ++ * @reserved: reserved space (unused) + */ + struct fw_phy_patch_key { + struct fw_block blk_hdr; +@@ -951,6 +955,7 @@ struct fw_phy_patch_key { + * struct fw_phy_nc - a firmware block used by RTL_FW_PHY_NC. + * The layout of the firmware block is: + * + + . ++ * @blk_hdr: firmware descriptor (type, length) + * @fw_offset: offset of the firmware binary data. The start address of + * the data would be the address of struct fw_phy_nc + @fw_offset. + * @fw_reg: the register to load the firmware. Depends on chip. +@@ -961,6 +966,7 @@ struct fw_phy_patch_key { + * @mode_reg: the regitster of switching the mode. + * @mod_pre: the mode needing to be set before loading the firmware. + * @mod_post: the mode to be set when finishing to load the firmware. ++ * @reserved: reserved space (unused) + * @bp_start: the start register of break points. Depends on chip. + * @bp_num: the break point number which needs to be set for this firmware. + * Depends on the firmware. diff --git a/target/linux/generic/backport-5.10/781-v5.11-net-usb-r8152-Fix-a-couple-of-spelling-errors-in-fw_.patch b/target/linux/generic/backport-5.10/781-v5.11-net-usb-r8152-Fix-a-couple-of-spelling-errors-in-fw_.patch new file mode 100644 index 0000000000..aa2763e7de --- /dev/null +++ b/target/linux/generic/backport-5.10/781-v5.11-net-usb-r8152-Fix-a-couple-of-spelling-errors-in-fw_.patch @@ -0,0 +1,34 @@ +From 5fcfa846181de6676509696c4cd7b60a22e74077 Mon Sep 17 00:00:00 2001 +From: Lee Jones +Date: Mon, 2 Nov 2020 11:45:09 +0000 +Subject: [PATCH] net: usb: r8152: Fix a couple of spelling errors in + fw_phy_nc's docs + +commit 9f07814d01ad085b2d9f1d55b4ce532fb2c27110 upstream. + +Fixes the following W=1 kernel build warning(s): + + drivers/net/usb/r8152.c:992: warning: Function parameter or member 'mode_pre' not described in 'fw_phy_nc' + drivers/net/usb/r8152.c:992: warning: Function parameter or member 'mode_post' not described in 'fw_phy_nc' + +Signed-off-by: Lee Jones +Acked-by: Hayes Wang +Link: https://lore.kernel.org/r/20201102114512.1062724-28-lee.jones@linaro.org +Signed-off-by: Jakub Kicinski +--- + drivers/net/usb/r8152.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/net/usb/r8152.c ++++ b/drivers/net/usb/r8152.c +@@ -964,8 +964,8 @@ struct fw_phy_patch_key { + * @patch_en_addr: the register of enabling patch mode. Depends on chip. + * @patch_en_value: patch mode enabled mask. Depends on the firmware. + * @mode_reg: the regitster of switching the mode. +- * @mod_pre: the mode needing to be set before loading the firmware. +- * @mod_post: the mode to be set when finishing to load the firmware. ++ * @mode_pre: the mode needing to be set before loading the firmware. ++ * @mode_post: the mode to be set when finishing to load the firmware. + * @reserved: reserved space (unused) + * @bp_start: the start register of break points. Depends on chip. + * @bp_num: the break point number which needs to be set for this firmware. diff --git a/target/linux/generic/backport-5.10/782-v5.11-net-usb-r8153_ecm-support-ECM-mode-for-RTL8153.patch b/target/linux/generic/backport-5.10/782-v5.11-net-usb-r8153_ecm-support-ECM-mode-for-RTL8153.patch new file mode 100644 index 0000000000..789de8e6fd --- /dev/null +++ b/target/linux/generic/backport-5.10/782-v5.11-net-usb-r8153_ecm-support-ECM-mode-for-RTL8153.patch @@ -0,0 +1,320 @@ +From 0ef50460f7f053bd2a911ec53e01bfda646a5574 Mon Sep 17 00:00:00 2001 +From: Hayes Wang +Date: Wed, 4 Nov 2020 10:19:22 +0800 +Subject: [PATCH] net/usb/r8153_ecm: support ECM mode for RTL8153 + +commit c1aedf015ebdd0232757a66e2daccf1246bd609c upstream. + +Support ECM mode based on cdc_ether with relative mii functions, +when CONFIG_USB_RTL8152 is not set, or the device is not supported +by r8152 driver. + +Both r8152 and r8153_ecm would check the return value of +rtl8152_get_version() in porbe(). If rtl8152_get_version() +return none zero value, the r8152 is used for the device +with vendor mode. Otherwise, the r8153_ecm is used for the +device with ECM mode. + +Signed-off-by: Hayes Wang +Link: https://lore.kernel.org/r/1394712342-15778-392-Taiwan-albertk@realtek.com +Signed-off-by: Jakub Kicinski +--- + drivers/net/usb/Makefile | 2 +- + drivers/net/usb/r8152.c | 30 +------ + drivers/net/usb/r8153_ecm.c | 162 ++++++++++++++++++++++++++++++++++++ + include/linux/usb/r8152.h | 37 ++++++++ + 4 files changed, 204 insertions(+), 27 deletions(-) + create mode 100644 drivers/net/usb/r8153_ecm.c + create mode 100644 include/linux/usb/r8152.h + +--- a/drivers/net/usb/Makefile ++++ b/drivers/net/usb/Makefile +@@ -13,7 +13,7 @@ obj-$(CONFIG_USB_LAN78XX) += lan78xx.o + obj-$(CONFIG_USB_NET_AX8817X) += asix.o + asix-y := asix_devices.o asix_common.o ax88172a.o + obj-$(CONFIG_USB_NET_AX88179_178A) += ax88179_178a.o +-obj-$(CONFIG_USB_NET_CDCETHER) += cdc_ether.o ++obj-$(CONFIG_USB_NET_CDCETHER) += cdc_ether.o r8153_ecm.o + obj-$(CONFIG_USB_NET_CDC_EEM) += cdc_eem.o + obj-$(CONFIG_USB_NET_DM9601) += dm9601.o + obj-$(CONFIG_USB_NET_SR9700) += sr9700.o +--- a/drivers/net/usb/r8152.c ++++ b/drivers/net/usb/r8152.c +@@ -27,6 +27,7 @@ + #include + #include + #include ++#include + + /* Information for net-next */ + #define NETNEXT_VERSION "11" +@@ -654,18 +655,6 @@ enum rtl_register_content { + + #define INTR_LINK 0x0004 + +-#define RTL8152_REQT_READ 0xc0 +-#define RTL8152_REQT_WRITE 0x40 +-#define RTL8152_REQ_GET_REGS 0x05 +-#define RTL8152_REQ_SET_REGS 0x05 +- +-#define BYTE_EN_DWORD 0xff +-#define BYTE_EN_WORD 0x33 +-#define BYTE_EN_BYTE 0x11 +-#define BYTE_EN_SIX_BYTES 0x3f +-#define BYTE_EN_START_MASK 0x0f +-#define BYTE_EN_END_MASK 0xf0 +- + #define RTL8153_MAX_PACKET 9216 /* 9K */ + #define RTL8153_MAX_MTU (RTL8153_MAX_PACKET - VLAN_ETH_HLEN - \ + ETH_FCS_LEN) +@@ -690,21 +679,9 @@ enum rtl8152_flags { + LENOVO_MACPASSTHRU, + }; + +-/* Define these values to match your device */ +-#define VENDOR_ID_REALTEK 0x0bda +-#define VENDOR_ID_MICROSOFT 0x045e +-#define VENDOR_ID_SAMSUNG 0x04e8 +-#define VENDOR_ID_LENOVO 0x17ef +-#define VENDOR_ID_LINKSYS 0x13b1 +-#define VENDOR_ID_NVIDIA 0x0955 +-#define VENDOR_ID_TPLINK 0x2357 +- + #define DEVICE_ID_THINKPAD_THUNDERBOLT3_DOCK_GEN2 0x3082 + #define DEVICE_ID_THINKPAD_USB_C_DOCK_GEN2 0xa387 + +-#define MCU_TYPE_PLA 0x0100 +-#define MCU_TYPE_USB 0x0000 +- + struct tally_counter { + __le64 tx_packets; + __le64 rx_packets; +@@ -6625,7 +6602,7 @@ static int rtl_fw_init(struct r8152 *tp) + return 0; + } + +-static u8 rtl_get_version(struct usb_interface *intf) ++u8 rtl8152_get_version(struct usb_interface *intf) + { + struct usb_device *udev = interface_to_usbdev(intf); + u32 ocp_data = 0; +@@ -6683,12 +6660,13 @@ static u8 rtl_get_version(struct usb_int + + return version; + } ++EXPORT_SYMBOL_GPL(rtl8152_get_version); + + static int rtl8152_probe(struct usb_interface *intf, + const struct usb_device_id *id) + { + struct usb_device *udev = interface_to_usbdev(intf); +- u8 version = rtl_get_version(intf); ++ u8 version = rtl8152_get_version(intf); + struct r8152 *tp; + struct net_device *netdev; + int ret; +--- /dev/null ++++ b/drivers/net/usb/r8153_ecm.c +@@ -0,0 +1,162 @@ ++// SPDX-License-Identifier: GPL-2.0-or-later ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#define OCP_BASE 0xe86c ++ ++static int pla_read_word(struct usbnet *dev, u16 index) ++{ ++ u16 byen = BYTE_EN_WORD; ++ u8 shift = index & 2; ++ __le32 tmp; ++ int ret; ++ ++ if (shift) ++ byen <<= shift; ++ ++ index &= ~3; ++ ++ ret = usbnet_read_cmd(dev, RTL8152_REQ_GET_REGS, RTL8152_REQT_READ, index, ++ MCU_TYPE_PLA | byen, &tmp, sizeof(tmp)); ++ if (ret < 0) ++ goto out; ++ ++ ret = __le32_to_cpu(tmp); ++ ret >>= (shift * 8); ++ ret &= 0xffff; ++ ++out: ++ return ret; ++} ++ ++static int pla_write_word(struct usbnet *dev, u16 index, u32 data) ++{ ++ u32 mask = 0xffff; ++ u16 byen = BYTE_EN_WORD; ++ u8 shift = index & 2; ++ __le32 tmp; ++ int ret; ++ ++ data &= mask; ++ ++ if (shift) { ++ byen <<= shift; ++ mask <<= (shift * 8); ++ data <<= (shift * 8); ++ } ++ ++ index &= ~3; ++ ++ ret = usbnet_read_cmd(dev, RTL8152_REQ_GET_REGS, RTL8152_REQT_READ, index, ++ MCU_TYPE_PLA | byen, &tmp, sizeof(tmp)); ++ ++ if (ret < 0) ++ goto out; ++ ++ data |= __le32_to_cpu(tmp) & ~mask; ++ tmp = __cpu_to_le32(data); ++ ++ ret = usbnet_write_cmd(dev, RTL8152_REQ_SET_REGS, RTL8152_REQT_WRITE, index, ++ MCU_TYPE_PLA | byen, &tmp, sizeof(tmp)); ++ ++out: ++ return ret; ++} ++ ++static int r8153_ecm_mdio_read(struct net_device *netdev, int phy_id, int reg) ++{ ++ struct usbnet *dev = netdev_priv(netdev); ++ int ret; ++ ++ ret = pla_write_word(dev, OCP_BASE, 0xa000); ++ if (ret < 0) ++ goto out; ++ ++ ret = pla_read_word(dev, 0xb400 + reg * 2); ++ ++out: ++ return ret; ++} ++ ++static void r8153_ecm_mdio_write(struct net_device *netdev, int phy_id, int reg, int val) ++{ ++ struct usbnet *dev = netdev_priv(netdev); ++ int ret; ++ ++ ret = pla_write_word(dev, OCP_BASE, 0xa000); ++ if (ret < 0) ++ return; ++ ++ ret = pla_write_word(dev, 0xb400 + reg * 2, val); ++} ++ ++static int r8153_bind(struct usbnet *dev, struct usb_interface *intf) ++{ ++ int status; ++ ++ status = usbnet_cdc_bind(dev, intf); ++ if (status < 0) ++ return status; ++ ++ dev->mii.dev = dev->net; ++ dev->mii.mdio_read = r8153_ecm_mdio_read; ++ dev->mii.mdio_write = r8153_ecm_mdio_write; ++ dev->mii.reg_num_mask = 0x1f; ++ dev->mii.supports_gmii = 1; ++ ++ return status; ++} ++ ++static const struct driver_info r8153_info = { ++ .description = "RTL8153 ECM Device", ++ .flags = FLAG_ETHER, ++ .bind = r8153_bind, ++ .unbind = usbnet_cdc_unbind, ++ .status = usbnet_cdc_status, ++ .manage_power = usbnet_manage_power, ++}; ++ ++static const struct usb_device_id products[] = { ++{ ++ USB_DEVICE_AND_INTERFACE_INFO(VENDOR_ID_REALTEK, 0x8153, USB_CLASS_COMM, ++ USB_CDC_SUBCLASS_ETHERNET, USB_CDC_PROTO_NONE), ++ .driver_info = (unsigned long)&r8153_info, ++}, ++ ++ { }, /* END */ ++}; ++MODULE_DEVICE_TABLE(usb, products); ++ ++static int rtl8153_ecm_probe(struct usb_interface *intf, ++ const struct usb_device_id *id) ++{ ++#if IS_REACHABLE(CONFIG_USB_RTL8152) ++ if (rtl8152_get_version(intf)) ++ return -ENODEV; ++#endif ++ ++ return usbnet_probe(intf, id); ++} ++ ++static struct usb_driver r8153_ecm_driver = { ++ .name = "r8153_ecm", ++ .id_table = products, ++ .probe = rtl8153_ecm_probe, ++ .disconnect = usbnet_disconnect, ++ .suspend = usbnet_suspend, ++ .resume = usbnet_resume, ++ .reset_resume = usbnet_resume, ++ .supports_autosuspend = 1, ++ .disable_hub_initiated_lpm = 1, ++}; ++ ++module_usb_driver(r8153_ecm_driver); ++ ++MODULE_AUTHOR("Hayes Wang"); ++MODULE_DESCRIPTION("Realtek USB ECM device"); ++MODULE_LICENSE("GPL"); +--- /dev/null ++++ b/include/linux/usb/r8152.h +@@ -0,0 +1,37 @@ ++/* SPDX-License-Identifier: GPL-2.0-only */ ++/* ++ * Copyright (c) 2020 Realtek Semiconductor Corp. All rights reserved. ++ */ ++ ++#ifndef __LINUX_R8152_H ++#define __LINUX_R8152_H ++ ++#define RTL8152_REQT_READ 0xc0 ++#define RTL8152_REQT_WRITE 0x40 ++#define RTL8152_REQ_GET_REGS 0x05 ++#define RTL8152_REQ_SET_REGS 0x05 ++ ++#define BYTE_EN_DWORD 0xff ++#define BYTE_EN_WORD 0x33 ++#define BYTE_EN_BYTE 0x11 ++#define BYTE_EN_SIX_BYTES 0x3f ++#define BYTE_EN_START_MASK 0x0f ++#define BYTE_EN_END_MASK 0xf0 ++ ++#define MCU_TYPE_PLA 0x0100 ++#define MCU_TYPE_USB 0x0000 ++ ++/* Define these values to match your device */ ++#define VENDOR_ID_REALTEK 0x0bda ++#define VENDOR_ID_MICROSOFT 0x045e ++#define VENDOR_ID_SAMSUNG 0x04e8 ++#define VENDOR_ID_LENOVO 0x17ef ++#define VENDOR_ID_LINKSYS 0x13b1 ++#define VENDOR_ID_NVIDIA 0x0955 ++#define VENDOR_ID_TPLINK 0x2357 ++ ++#if IS_REACHABLE(CONFIG_USB_RTL8152) ++extern u8 rtl8152_get_version(struct usb_interface *intf); ++#endif ++ ++#endif /* __LINUX_R8152_H */ diff --git a/target/linux/generic/backport-5.10/783-v5.12-net-usb-r8152-use-new-tasklet-API.patch b/target/linux/generic/backport-5.10/783-v5.12-net-usb-r8152-use-new-tasklet-API.patch new file mode 100644 index 0000000000..b625d5ea99 --- /dev/null +++ b/target/linux/generic/backport-5.10/783-v5.12-net-usb-r8152-use-new-tasklet-API.patch @@ -0,0 +1,41 @@ +From 90f1afc7f96c8f7cf19c82e5f4b39e61a63b053d Mon Sep 17 00:00:00 2001 +From: Emil Renner Berthing +Date: Sun, 31 Jan 2021 00:47:29 +0100 +Subject: [PATCH] net: usb: r8152: use new tasklet API + +commit f3163f1cb87141c7a41a15a5d4c98b353f807b04 upstream. + +This converts the driver to use the new tasklet API introduced in +commit 12cc923f1ccc ("tasklet: Introduce new initialization API") + +Signed-off-by: Emil Renner Berthing +Signed-off-by: Jakub Kicinski +--- + drivers/net/usb/r8152.c | 8 +++----- + 1 file changed, 3 insertions(+), 5 deletions(-) + +--- a/drivers/net/usb/r8152.c ++++ b/drivers/net/usb/r8152.c +@@ -2394,11 +2394,9 @@ static void tx_bottom(struct r8152 *tp) + } while (res == 0); + } + +-static void bottom_half(unsigned long data) ++static void bottom_half(struct tasklet_struct *t) + { +- struct r8152 *tp; +- +- tp = (struct r8152 *)data; ++ struct r8152 *tp = from_tasklet(tp, t, tx_tl); + + if (test_bit(RTL8152_UNPLUG, &tp->flags)) + return; +@@ -6718,7 +6716,7 @@ static int rtl8152_probe(struct usb_inte + mutex_init(&tp->control); + INIT_DELAYED_WORK(&tp->schedule, rtl_work_func_t); + INIT_DELAYED_WORK(&tp->hw_phy_work, rtl_hw_phy_work_func_t); +- tasklet_init(&tp->tx_tl, bottom_half, (unsigned long)tp); ++ tasklet_setup(&tp->tx_tl, bottom_half); + tasklet_disable(&tp->tx_tl); + + netdev->netdev_ops = &rtl8152_netdev_ops; diff --git a/target/linux/generic/backport-5.10/784-v5.12-r8152-replace-several-functions-about-phy-patch-requ.patch b/target/linux/generic/backport-5.10/784-v5.12-r8152-replace-several-functions-about-phy-patch-requ.patch new file mode 100644 index 0000000000..bbb2b5c0c9 --- /dev/null +++ b/target/linux/generic/backport-5.10/784-v5.12-r8152-replace-several-functions-about-phy-patch-requ.patch @@ -0,0 +1,198 @@ +From 86b98abf4f8c691c260c5113d6a2d32f5377caca Mon Sep 17 00:00:00 2001 +From: Hayes Wang +Date: Wed, 3 Feb 2021 17:14:28 +0800 +Subject: [PATCH] r8152: replace several functions about phy patch + request + +commit a08c0d309d8c078d22717d815cf9853f6f2c07bd upstream. + +Replace r8153_patch_request() with rtl_phy_patch_request(). +Replace r8153_pre_ram_code() with rtl_pre_ram_code(). +Replace r8153_post_ram_code() with rtl_post_ram_code(). +Add rtl_patch_key_set(). + +The new functions have an additional parameter. It is used to wait +the patch request command finished. When the PHY is resumed from +the state of power cut, the PHY is at a safe mode and the +OCP_PHY_PATCH_STAT wouldn't be updated. For this situation, it is +safe to set patch request command without waiting OCP_PHY_PATCH_STAT. + +Signed-off-by: Hayes Wang +Signed-off-by: Jakub Kicinski +--- + drivers/net/usb/r8152.c | 84 ++++++++++++++++++++++++----------------- + 1 file changed, 50 insertions(+), 34 deletions(-) + +--- a/drivers/net/usb/r8152.c ++++ b/drivers/net/usb/r8152.c +@@ -3444,59 +3444,76 @@ static void rtl_clear_bp(struct r8152 *t + ocp_write_word(tp, type, PLA_BP_BA, 0); + } + +-static int r8153_patch_request(struct r8152 *tp, bool request) ++static int rtl_phy_patch_request(struct r8152 *tp, bool request, bool wait) + { +- u16 data; ++ u16 data, check; + int i; + + data = ocp_reg_read(tp, OCP_PHY_PATCH_CMD); +- if (request) ++ if (request) { + data |= PATCH_REQUEST; +- else ++ check = 0; ++ } else { + data &= ~PATCH_REQUEST; ++ check = PATCH_READY; ++ } + ocp_reg_write(tp, OCP_PHY_PATCH_CMD, data); + +- for (i = 0; request && i < 5000; i++) { ++ for (i = 0; wait && i < 5000; i++) { ++ u32 ocp_data; ++ + usleep_range(1000, 2000); +- if (ocp_reg_read(tp, OCP_PHY_PATCH_STAT) & PATCH_READY) ++ ocp_data = ocp_reg_read(tp, OCP_PHY_PATCH_STAT); ++ if ((ocp_data & PATCH_READY) ^ check) + break; + } + +- if (request && !(ocp_reg_read(tp, OCP_PHY_PATCH_STAT) & PATCH_READY)) { +- netif_err(tp, drv, tp->netdev, "patch request fail\n"); +- r8153_patch_request(tp, false); ++ if (request && wait && ++ !(ocp_reg_read(tp, OCP_PHY_PATCH_STAT) & PATCH_READY)) { ++ dev_err(&tp->intf->dev, "PHY patch request fail\n"); ++ rtl_phy_patch_request(tp, false, false); + return -ETIME; + } else { + return 0; + } + } + +-static int r8153_pre_ram_code(struct r8152 *tp, u16 key_addr, u16 patch_key) ++static void rtl_patch_key_set(struct r8152 *tp, u16 key_addr, u16 patch_key) + { +- if (r8153_patch_request(tp, true)) { +- dev_err(&tp->intf->dev, "patch request fail\n"); +- return -ETIME; +- } ++ if (patch_key && key_addr) { ++ sram_write(tp, key_addr, patch_key); ++ sram_write(tp, SRAM_PHY_LOCK, PHY_PATCH_LOCK); ++ } else if (key_addr) { ++ u16 data; + +- sram_write(tp, key_addr, patch_key); +- sram_write(tp, SRAM_PHY_LOCK, PHY_PATCH_LOCK); ++ sram_write(tp, 0x0000, 0x0000); + +- return 0; ++ data = ocp_reg_read(tp, OCP_PHY_LOCK); ++ data &= ~PATCH_LOCK; ++ ocp_reg_write(tp, OCP_PHY_LOCK, data); ++ ++ sram_write(tp, key_addr, 0x0000); ++ } else { ++ WARN_ON_ONCE(1); ++ } + } + +-static int r8153_post_ram_code(struct r8152 *tp, u16 key_addr) ++static int ++rtl_pre_ram_code(struct r8152 *tp, u16 key_addr, u16 patch_key, bool wait) + { +- u16 data; ++ if (rtl_phy_patch_request(tp, true, wait)) ++ return -ETIME; + +- sram_write(tp, 0x0000, 0x0000); ++ rtl_patch_key_set(tp, key_addr, patch_key); + +- data = ocp_reg_read(tp, OCP_PHY_LOCK); +- data &= ~PATCH_LOCK; +- ocp_reg_write(tp, OCP_PHY_LOCK, data); ++ return 0; ++} + +- sram_write(tp, key_addr, 0x0000); ++static int rtl_post_ram_code(struct r8152 *tp, u16 key_addr, bool wait) ++{ ++ rtl_patch_key_set(tp, key_addr, 0); + +- r8153_patch_request(tp, false); ++ rtl_phy_patch_request(tp, false, wait); + + ocp_write_word(tp, MCU_TYPE_PLA, PLA_OCP_GPHY_BASE, tp->ocp_base); + +@@ -3981,7 +3998,7 @@ static void rtl8152_fw_mac_apply(struct + dev_dbg(&tp->intf->dev, "successfully applied %s\n", mac->info); + } + +-static void rtl8152_apply_firmware(struct r8152 *tp) ++static void rtl8152_apply_firmware(struct r8152 *tp, bool power_cut) + { + struct rtl_fw *rtl_fw = &tp->rtl_fw; + const struct firmware *fw; +@@ -4012,12 +4029,11 @@ static void rtl8152_apply_firmware(struc + case RTL_FW_PHY_START: + key = (struct fw_phy_patch_key *)block; + key_addr = __le16_to_cpu(key->key_reg); +- r8153_pre_ram_code(tp, key_addr, +- __le16_to_cpu(key->key_data)); ++ rtl_pre_ram_code(tp, key_addr, __le16_to_cpu(key->key_data), !power_cut); + break; + case RTL_FW_PHY_STOP: + WARN_ON(!key_addr); +- r8153_post_ram_code(tp, key_addr); ++ rtl_post_ram_code(tp, key_addr, !power_cut); + break; + case RTL_FW_PHY_NC: + rtl8152_fw_phy_nc_apply(tp, (struct fw_phy_nc *)block); +@@ -4222,7 +4238,7 @@ static void rtl8152_disable(struct r8152 + + static void r8152b_hw_phy_cfg(struct r8152 *tp) + { +- rtl8152_apply_firmware(tp); ++ rtl8152_apply_firmware(tp, false); + rtl_eee_enable(tp, tp->eee_en); + r8152_aldps_en(tp, true); + r8152b_enable_fc(tp); +@@ -4504,7 +4520,7 @@ static void r8153_hw_phy_cfg(struct r815 + /* disable EEE before updating the PHY parameters */ + rtl_eee_enable(tp, false); + +- rtl8152_apply_firmware(tp); ++ rtl8152_apply_firmware(tp, false); + + if (tp->version == RTL_VER_03) { + data = ocp_reg_read(tp, OCP_EEE_CFG); +@@ -4578,7 +4594,7 @@ static void r8153b_hw_phy_cfg(struct r81 + /* disable EEE before updating the PHY parameters */ + rtl_eee_enable(tp, false); + +- rtl8152_apply_firmware(tp); ++ rtl8152_apply_firmware(tp, false); + + r8153b_green_en(tp, test_bit(GREEN_ETHERNET, &tp->flags)); + +@@ -4619,7 +4635,7 @@ static void r8153b_hw_phy_cfg(struct r81 + ocp_write_word(tp, MCU_TYPE_PLA, PLA_PHY_PWR, ocp_data); + + /* Advnace EEE */ +- if (!r8153_patch_request(tp, true)) { ++ if (!rtl_phy_patch_request(tp, true, true)) { + data = ocp_reg_read(tp, OCP_POWER_CFG); + data |= EEE_CLKDIV_EN; + ocp_reg_write(tp, OCP_POWER_CFG, data); +@@ -4636,7 +4652,7 @@ static void r8153b_hw_phy_cfg(struct r81 + ocp_reg_write(tp, OCP_SYSCLK_CFG, clk_div_expo(5)); + tp->ups_info._250m_ckdiv = true; + +- r8153_patch_request(tp, false); ++ rtl_phy_patch_request(tp, false, true); + } + + if (tp->eee_en) diff --git a/target/linux/generic/backport-5.10/785-v5.12-r8152-adjust-the-flow-of-power-cut-for-RTL8153B.patch b/target/linux/generic/backport-5.10/785-v5.12-r8152-adjust-the-flow-of-power-cut-for-RTL8153B.patch new file mode 100644 index 0000000000..b28e89a43f --- /dev/null +++ b/target/linux/generic/backport-5.10/785-v5.12-r8152-adjust-the-flow-of-power-cut-for-RTL8153B.patch @@ -0,0 +1,134 @@ +From 29a61d8564ad3439d03c7ec135016a4e70072af1 Mon Sep 17 00:00:00 2001 +From: Hayes Wang +Date: Wed, 3 Feb 2021 17:14:29 +0800 +Subject: [PATCH] r8152: adjust the flow of power cut for RTL8153B + +commit 80fd850b31f09263ad175b2f640d5c5c6f76ed41 upstream. + +For runtime resuming, the RTL8153B may be resumed from the state +of power cut, when enabling the feature of UPS. Then, the PHY +would be reset, so it is necessary to be initailized again. + +Besides, the USB_U1U2_TIMER also has to be set again, so I move +it from r8153b_init() to r8153b_hw_phy_cfg(). + +Signed-off-by: Hayes Wang +Signed-off-by: Jakub Kicinski +--- + drivers/net/usb/r8152.c | 68 ++++++++++++++++++++++++----------------- + 1 file changed, 40 insertions(+), 28 deletions(-) + +--- a/drivers/net/usb/r8152.c ++++ b/drivers/net/usb/r8152.c +@@ -1372,6 +1372,10 @@ void write_mii_word(struct net_device *n + static int + r8152_submit_rx(struct r8152 *tp, struct rx_agg *agg, gfp_t mem_flags); + ++static int ++rtl8152_set_speed(struct r8152 *tp, u8 autoneg, u32 speed, u8 duplex, ++ u32 advertising); ++ + static int rtl8152_set_mac_address(struct net_device *netdev, void *p) + { + struct r8152 *tp = netdev_priv(netdev); +@@ -3183,8 +3187,6 @@ static void r8153b_ups_en(struct r8152 * + ocp_data |= BIT(0); + ocp_write_byte(tp, MCU_TYPE_USB, 0xcfff, ocp_data); + } else { +- u16 data; +- + ocp_data &= ~(UPS_EN | USP_PREWAKE); + ocp_write_byte(tp, MCU_TYPE_USB, USB_POWER_CUT, ocp_data); + +@@ -3192,31 +3194,20 @@ static void r8153b_ups_en(struct r8152 * + ocp_data &= ~BIT(0); + ocp_write_byte(tp, MCU_TYPE_USB, 0xcfff, ocp_data); + +- ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_MISC_0); +- ocp_data &= ~PCUT_STATUS; +- ocp_write_word(tp, MCU_TYPE_USB, USB_MISC_0, ocp_data); ++ if (ocp_read_word(tp, MCU_TYPE_USB, USB_MISC_0) & PCUT_STATUS) { ++ int i; + +- data = r8153_phy_status(tp, 0); ++ for (i = 0; i < 500; i++) { ++ if (ocp_read_word(tp, MCU_TYPE_PLA, PLA_BOOT_CTRL) & ++ AUTOLOAD_DONE) ++ break; ++ msleep(20); ++ } + +- switch (data) { +- case PHY_STAT_PWRDN: +- case PHY_STAT_EXT_INIT: +- r8153b_green_en(tp, +- test_bit(GREEN_ETHERNET, &tp->flags)); +- +- data = r8152_mdio_read(tp, MII_BMCR); +- data &= ~BMCR_PDOWN; +- data |= BMCR_RESET; +- r8152_mdio_write(tp, MII_BMCR, data); ++ tp->rtl_ops.hw_phy_cfg(tp); + +- data = r8153_phy_status(tp, PHY_STAT_LAN_ON); +- fallthrough; +- +- default: +- if (data != PHY_STAT_LAN_ON) +- netif_warn(tp, link, tp->netdev, +- "PHY not ready"); +- break; ++ rtl8152_set_speed(tp, tp->autoneg, tp->speed, ++ tp->duplex, tp->advertising); + } + } + } +@@ -4588,13 +4579,37 @@ static void r8153b_hw_phy_cfg(struct r81 + u32 ocp_data; + u16 data; + ++ ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_MISC_0); ++ if (ocp_data & PCUT_STATUS) { ++ ocp_data &= ~PCUT_STATUS; ++ ocp_write_word(tp, MCU_TYPE_USB, USB_MISC_0, ocp_data); ++ } ++ + /* disable ALDPS before updating the PHY parameters */ + r8153_aldps_en(tp, false); + + /* disable EEE before updating the PHY parameters */ + rtl_eee_enable(tp, false); + +- rtl8152_apply_firmware(tp, false); ++ /* U1/U2/L1 idle timer. 500 us */ ++ ocp_write_word(tp, MCU_TYPE_USB, USB_U1U2_TIMER, 500); ++ ++ data = r8153_phy_status(tp, 0); ++ ++ switch (data) { ++ case PHY_STAT_PWRDN: ++ case PHY_STAT_EXT_INIT: ++ rtl8152_apply_firmware(tp, true); ++ ++ data = r8152_mdio_read(tp, MII_BMCR); ++ data &= ~BMCR_PDOWN; ++ r8152_mdio_write(tp, MII_BMCR, data); ++ break; ++ case PHY_STAT_LAN_ON: ++ default: ++ rtl8152_apply_firmware(tp, false); ++ break; ++ } + + r8153b_green_en(tp, test_bit(GREEN_ETHERNET, &tp->flags)); + +@@ -5543,9 +5558,6 @@ static void r8153b_init(struct r8152 *tp + /* MSC timer = 0xfff * 8ms = 32760 ms */ + ocp_write_word(tp, MCU_TYPE_USB, USB_MSC_TIMER, 0x0fff); + +- /* U1/U2/L1 idle timer. 500 us */ +- ocp_write_word(tp, MCU_TYPE_USB, USB_U1U2_TIMER, 500); +- + r8153b_power_cut_en(tp, false); + r8153b_ups_en(tp, false); + r8153_queue_wake(tp, false); diff --git a/target/linux/generic/backport-5.10/786-v5.12-r8152-enable-U1-U2-for-USB_SPEED_SUPER.patch b/target/linux/generic/backport-5.10/786-v5.12-r8152-enable-U1-U2-for-USB_SPEED_SUPER.patch new file mode 100644 index 0000000000..8cf91c3893 --- /dev/null +++ b/target/linux/generic/backport-5.10/786-v5.12-r8152-enable-U1-U2-for-USB_SPEED_SUPER.patch @@ -0,0 +1,47 @@ +From 69b4339c0b9f3edc6a8f681f05efaaf4add1bb0e Mon Sep 17 00:00:00 2001 +From: Hayes Wang +Date: Fri, 19 Feb 2021 17:04:40 +0800 +Subject: [PATCH] r8152: enable U1/U2 for USB_SPEED_SUPER + +commit 7a0ae61acde2cebd69665837170405eced86a6c7 upstream. + +U1/U2 shoued be enabled for USB 3.0 or later. The USB 2.0 doesn't +support it. + +Signed-off-by: Hayes Wang +Signed-off-by: Jakub Kicinski +--- + drivers/net/usb/r8152.c | 7 ++++--- + 1 file changed, 4 insertions(+), 3 deletions(-) + +--- a/drivers/net/usb/r8152.c ++++ b/drivers/net/usb/r8152.c +@@ -3336,7 +3336,7 @@ static void rtl8153b_runtime_enable(stru + r8153b_ups_en(tp, false); + r8153_queue_wake(tp, false); + rtl_runtime_suspend_enable(tp, false); +- if (tp->udev->speed != USB_SPEED_HIGH) ++ if (tp->udev->speed >= USB_SPEED_SUPER) + r8153b_u1u2en(tp, true); + } + } +@@ -5029,7 +5029,7 @@ static void rtl8153b_up(struct r8152 *tp + + r8153_aldps_en(tp, true); + +- if (tp->udev->speed != USB_SPEED_HIGH) ++ if (tp->udev->speed >= USB_SPEED_SUPER) + r8153b_u1u2en(tp, true); + } + +@@ -5571,8 +5571,9 @@ static void r8153b_init(struct r8152 *tp + ocp_data |= POLL_LINK_CHG; + ocp_write_word(tp, MCU_TYPE_PLA, PLA_EXTRA_STATUS, ocp_data); + +- if (tp->udev->speed != USB_SPEED_HIGH) ++ if (tp->udev->speed >= USB_SPEED_SUPER) + r8153b_u1u2en(tp, true); ++ + usb_enable_lpm(tp->udev); + + /* MAC clock speed down */ diff --git a/target/linux/generic/backport-5.10/787-v5.12-r8152-check-if-the-pointer-of-the-function-exists.patch b/target/linux/generic/backport-5.10/787-v5.12-r8152-check-if-the-pointer-of-the-function-exists.patch new file mode 100644 index 0000000000..5bc4e2b0a1 --- /dev/null +++ b/target/linux/generic/backport-5.10/787-v5.12-r8152-check-if-the-pointer-of-the-function-exists.patch @@ -0,0 +1,51 @@ +From e78b75f5be204a0a235da995d01c778dc282bb42 Mon Sep 17 00:00:00 2001 +From: Hayes Wang +Date: Fri, 19 Feb 2021 17:04:41 +0800 +Subject: [PATCH] r8152: check if the pointer of the function exists + +commit c79515e47935c747282c6ed2ee5b2ef039756eeb upstream. + +Return error code if autosuspend_en, eee_get, or eee_set don't exist. + +Signed-off-by: Hayes Wang +Signed-off-by: Jakub Kicinski +--- + drivers/net/usb/r8152.c | 13 +++++++++++++ + 1 file changed, 13 insertions(+) + +--- a/drivers/net/usb/r8152.c ++++ b/drivers/net/usb/r8152.c +@@ -5758,6 +5758,9 @@ static int rtl8152_runtime_suspend(struc + struct net_device *netdev = tp->netdev; + int ret = 0; + ++ if (!tp->rtl_ops.autosuspend_en) ++ return -EBUSY; ++ + set_bit(SELECTIVE_SUSPEND, &tp->flags); + smp_mb__after_atomic(); + +@@ -6157,6 +6160,11 @@ rtl_ethtool_get_eee(struct net_device *n + struct r8152 *tp = netdev_priv(net); + int ret; + ++ if (!tp->rtl_ops.eee_get) { ++ ret = -EOPNOTSUPP; ++ goto out; ++ } ++ + ret = usb_autopm_get_interface(tp->intf); + if (ret < 0) + goto out; +@@ -6179,6 +6187,11 @@ rtl_ethtool_set_eee(struct net_device *n + struct r8152 *tp = netdev_priv(net); + int ret; + ++ if (!tp->rtl_ops.eee_set) { ++ ret = -EOPNOTSUPP; ++ goto out; ++ } ++ + ret = usb_autopm_get_interface(tp->intf); + if (ret < 0) + goto out; diff --git a/target/linux/generic/backport-5.10/788-v5.12-r8152-replace-netif_err-with-dev_err.patch b/target/linux/generic/backport-5.10/788-v5.12-r8152-replace-netif_err-with-dev_err.patch new file mode 100644 index 0000000000..967b4ccc16 --- /dev/null +++ b/target/linux/generic/backport-5.10/788-v5.12-r8152-replace-netif_err-with-dev_err.patch @@ -0,0 +1,36 @@ +From 38e44c7926512cff0b2809dc329de2a8e769e523 Mon Sep 17 00:00:00 2001 +From: Hayes Wang +Date: Fri, 19 Feb 2021 17:04:42 +0800 +Subject: [PATCH] r8152: replace netif_err with dev_err + +commit 156c3207611262266f0eea589ac3f00c5657320e upstream. + +Some messages are before calling register_netdev(), so replace +netif_err() with dev_err(). + +Signed-off-by: Hayes Wang +Signed-off-by: Jakub Kicinski +--- + drivers/net/usb/r8152.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/net/usb/r8152.c ++++ b/drivers/net/usb/r8152.c +@@ -6594,7 +6594,7 @@ static int rtl_ops_init(struct r8152 *tp + + default: + ret = -ENODEV; +- netif_err(tp, probe, tp->netdev, "Unknown Device\n"); ++ dev_err(&tp->intf->dev, "Unknown Device\n"); + break; + } + +@@ -6851,7 +6851,7 @@ static int rtl8152_probe(struct usb_inte + + ret = register_netdev(netdev); + if (ret != 0) { +- netif_err(tp, probe, netdev, "couldn't register the device\n"); ++ dev_err(&intf->dev, "couldn't register the device\n"); + goto out1; + } + diff --git a/target/linux/generic/backport-5.10/789-v5.12-r8152-spilt-rtl_set_eee_plus-and-r8153b_green_en.patch b/target/linux/generic/backport-5.10/789-v5.12-r8152-spilt-rtl_set_eee_plus-and-r8153b_green_en.patch new file mode 100644 index 0000000000..c49a4ce5b6 --- /dev/null +++ b/target/linux/generic/backport-5.10/789-v5.12-r8152-spilt-rtl_set_eee_plus-and-r8153b_green_en.patch @@ -0,0 +1,89 @@ +From 260814de2d6cb958767785ffcb2e76915d1be32b Mon Sep 17 00:00:00 2001 +From: Hayes Wang +Date: Fri, 19 Feb 2021 17:04:43 +0800 +Subject: [PATCH] r8152: spilt rtl_set_eee_plus and r8153b_green_en + +commit 40fa7568ac230446d888b7ad402cff9e20fe3ad5 upstream. + +Add rtl_eee_plus_en() and rtl_green_en(). + +Signed-off-by: Hayes Wang +Signed-off-by: Jakub Kicinski +--- + drivers/net/usb/r8152.c | 43 ++++++++++++++++++++++++++--------------- + 1 file changed, 27 insertions(+), 16 deletions(-) + +--- a/drivers/net/usb/r8152.c ++++ b/drivers/net/usb/r8152.c +@@ -2633,21 +2633,24 @@ static inline u8 rtl8152_get_speed(struc + return ocp_read_byte(tp, MCU_TYPE_PLA, PLA_PHYSTATUS); + } + +-static void rtl_set_eee_plus(struct r8152 *tp) ++static void rtl_eee_plus_en(struct r8152 *tp, bool enable) + { + u32 ocp_data; +- u8 speed; + +- speed = rtl8152_get_speed(tp); +- if (speed & _10bps) { +- ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_EEEP_CR); ++ ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_EEEP_CR); ++ if (enable) + ocp_data |= EEEP_CR_EEEP_TX; +- ocp_write_word(tp, MCU_TYPE_PLA, PLA_EEEP_CR, ocp_data); +- } else { +- ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_EEEP_CR); ++ else + ocp_data &= ~EEEP_CR_EEEP_TX; +- ocp_write_word(tp, MCU_TYPE_PLA, PLA_EEEP_CR, ocp_data); +- } ++ ocp_write_word(tp, MCU_TYPE_PLA, PLA_EEEP_CR, ocp_data); ++} ++ ++static void rtl_set_eee_plus(struct r8152 *tp) ++{ ++ if (rtl8152_get_speed(tp) & _10bps) ++ rtl_eee_plus_en(tp, true); ++ else ++ rtl_eee_plus_en(tp, false); + } + + static void rxdy_gated_en(struct r8152 *tp, bool enable) +@@ -3128,10 +3131,22 @@ static void r8153b_ups_flags(struct r815 + ocp_write_dword(tp, MCU_TYPE_USB, USB_UPS_FLAGS, ups_flags); + } + +-static void r8153b_green_en(struct r8152 *tp, bool enable) ++static void rtl_green_en(struct r8152 *tp, bool enable) + { + u16 data; + ++ data = sram_read(tp, SRAM_GREEN_CFG); ++ if (enable) ++ data |= GREEN_ETH_EN; ++ else ++ data &= ~GREEN_ETH_EN; ++ sram_write(tp, SRAM_GREEN_CFG, data); ++ ++ tp->ups_info.green = enable; ++} ++ ++static void r8153b_green_en(struct r8152 *tp, bool enable) ++{ + if (enable) { + sram_write(tp, 0x8045, 0); /* 10M abiq&ldvbias */ + sram_write(tp, 0x804d, 0x1222); /* 100M short abiq&ldvbias */ +@@ -3142,11 +3157,7 @@ static void r8153b_green_en(struct r8152 + sram_write(tp, 0x805d, 0x2444); /* 1000M short abiq&ldvbias */ + } + +- data = sram_read(tp, SRAM_GREEN_CFG); +- data |= GREEN_ETH_EN; +- sram_write(tp, SRAM_GREEN_CFG, data); +- +- tp->ups_info.green = enable; ++ rtl_green_en(tp, true); + } + + static u16 r8153_phy_status(struct r8152 *tp, u16 desired) diff --git a/target/linux/generic/backport-5.10/790-v5.13-r8152-set-inter-fram-gap-time-depending-on-speed.patch b/target/linux/generic/backport-5.10/790-v5.13-r8152-set-inter-fram-gap-time-depending-on-speed.patch new file mode 100644 index 0000000000..f2593e8f00 --- /dev/null +++ b/target/linux/generic/backport-5.10/790-v5.13-r8152-set-inter-fram-gap-time-depending-on-speed.patch @@ -0,0 +1,75 @@ +From f1bbbb260a8016373adf239c716d2da90e6ced0b Mon Sep 17 00:00:00 2001 +From: Hayes Wang +Date: Fri, 16 Apr 2021 16:04:32 +0800 +Subject: [PATCH] r8152: set inter fram gap time depending on speed + +commit 5133bcc7481528e36fff0a3b056601efb704fb32 upstream. + +Set the maximum inter frame gap time (144ns) for speed 10M/half and +100M/half. It improves the performance for those speeds. And, there +is no effect for the other speeds. + +For 10M/half and 100M/half, the fast inter frame gap time let the +device couldn't use the feature of the aggregation effectively, +because the transfer would be completed fastly. Therefore, use the +maximum value to improve the effect of the aggregation. However, you +may not feel the improvement for fast CPUs, because they compensate +for the effect of the aggregation. + +Signed-off-by: Hayes Wang +Signed-off-by: David S. Miller +--- + drivers/net/usb/r8152.c | 28 ++++++++++++++++++++++++++++ + 1 file changed, 28 insertions(+) + +--- a/drivers/net/usb/r8152.c ++++ b/drivers/net/usb/r8152.c +@@ -250,6 +250,9 @@ + + /* PLA_TCR1 */ + #define VERSION_MASK 0x7cf0 ++#define IFG_MASK (BIT(3) | BIT(9) | BIT(8)) ++#define IFG_144NS BIT(9) ++#define IFG_96NS (BIT(9) | BIT(8)) + + /* PLA_MTPS */ + #define MTPS_JUMBO (12 * 1024 / 64) +@@ -2748,6 +2751,29 @@ static int rtl_stop_rx(struct r8152 *tp) + return 0; + } + ++static void rtl_set_ifg(struct r8152 *tp, u16 speed) ++{ ++ u32 ocp_data; ++ ++ ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_TCR1); ++ ocp_data &= ~IFG_MASK; ++ if ((speed & (_10bps | _100bps)) && !(speed & FULL_DUP)) { ++ ocp_data |= IFG_144NS; ++ ocp_write_word(tp, MCU_TYPE_PLA, PLA_TCR1, ocp_data); ++ ++ ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL4); ++ ocp_data &= ~TX10MIDLE_EN; ++ ocp_write_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL4, ocp_data); ++ } else { ++ ocp_data |= IFG_96NS; ++ ocp_write_word(tp, MCU_TYPE_PLA, PLA_TCR1, ocp_data); ++ ++ ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL4); ++ ocp_data |= TX10MIDLE_EN; ++ ocp_write_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL4, ocp_data); ++ } ++} ++ + static inline void r8153b_rx_agg_chg_indicate(struct r8152 *tp) + { + ocp_write_byte(tp, MCU_TYPE_USB, USB_UPT_RXDMA_OWN, +@@ -2851,6 +2877,8 @@ static int rtl8153_enable(struct r8152 * + r8153_set_rx_early_timeout(tp); + r8153_set_rx_early_size(tp); + ++ rtl_set_ifg(tp, rtl8152_get_speed(tp)); ++ + if (tp->version == RTL_VER_09) { + u32 ocp_data; + diff --git a/target/linux/generic/backport-5.10/791-v5.13-r8152-adjust-rtl8152_check_firmware-function.patch b/target/linux/generic/backport-5.10/791-v5.13-r8152-adjust-rtl8152_check_firmware-function.patch new file mode 100644 index 0000000000..cddd39ea94 --- /dev/null +++ b/target/linux/generic/backport-5.10/791-v5.13-r8152-adjust-rtl8152_check_firmware-function.patch @@ -0,0 +1,152 @@ +From f10c9edf47d3fa240d965e151a48c670f5035b73 Mon Sep 17 00:00:00 2001 +From: Hayes Wang +Date: Fri, 16 Apr 2021 16:04:33 +0800 +Subject: [PATCH] r8152: adjust rtl8152_check_firmware function + +commit a8a7be178e81a3d4b6972cbeb0ccd091ca2f9f89 upstream. + +Use bits operations to record and check the firmware. + +Signed-off-by: Hayes Wang +Signed-off-by: David S. Miller +--- + drivers/net/usb/r8152.c | 51 +++++++++++++++++++++++------------------ + 1 file changed, 29 insertions(+), 22 deletions(-) + +--- a/drivers/net/usb/r8152.c ++++ b/drivers/net/usb/r8152.c +@@ -875,6 +875,14 @@ struct fw_header { + struct fw_block blocks[]; + } __packed; + ++enum rtl8152_fw_flags { ++ FW_FLAGS_USB = 0, ++ FW_FLAGS_PLA, ++ FW_FLAGS_START, ++ FW_FLAGS_STOP, ++ FW_FLAGS_NC, ++}; ++ + /** + * struct fw_mac - a firmware block used by RTL_FW_PLA and RTL_FW_USB. + * The layout of the firmware block is: +@@ -3801,10 +3809,7 @@ static long rtl8152_check_firmware(struc + { + const struct firmware *fw = rtl_fw->fw; + struct fw_header *fw_hdr = (struct fw_header *)fw->data; +- struct fw_mac *pla = NULL, *usb = NULL; +- struct fw_phy_patch_key *start = NULL; +- struct fw_phy_nc *phy_nc = NULL; +- struct fw_block *stop = NULL; ++ unsigned long fw_flags = 0; + long ret = -EFAULT; + int i; + +@@ -3833,50 +3838,52 @@ static long rtl8152_check_firmware(struc + goto fail; + goto fw_end; + case RTL_FW_PLA: +- if (pla) { ++ if (test_bit(FW_FLAGS_PLA, &fw_flags)) { + dev_err(&tp->intf->dev, + "multiple PLA firmware encountered"); + goto fail; + } + +- pla = (struct fw_mac *)block; +- if (!rtl8152_is_fw_mac_ok(tp, pla)) { ++ if (!rtl8152_is_fw_mac_ok(tp, (struct fw_mac *)block)) { + dev_err(&tp->intf->dev, + "check PLA firmware failed\n"); + goto fail; + } ++ __set_bit(FW_FLAGS_PLA, &fw_flags); + break; + case RTL_FW_USB: +- if (usb) { ++ if (test_bit(FW_FLAGS_USB, &fw_flags)) { + dev_err(&tp->intf->dev, + "multiple USB firmware encountered"); + goto fail; + } + +- usb = (struct fw_mac *)block; +- if (!rtl8152_is_fw_mac_ok(tp, usb)) { ++ if (!rtl8152_is_fw_mac_ok(tp, (struct fw_mac *)block)) { + dev_err(&tp->intf->dev, + "check USB firmware failed\n"); + goto fail; + } ++ __set_bit(FW_FLAGS_USB, &fw_flags); + break; + case RTL_FW_PHY_START: +- if (start || phy_nc || stop) { ++ if (test_bit(FW_FLAGS_START, &fw_flags) || ++ test_bit(FW_FLAGS_NC, &fw_flags) || ++ test_bit(FW_FLAGS_STOP, &fw_flags)) { + dev_err(&tp->intf->dev, + "check PHY_START fail\n"); + goto fail; + } + +- if (__le32_to_cpu(block->length) != sizeof(*start)) { ++ if (__le32_to_cpu(block->length) != sizeof(struct fw_phy_patch_key)) { + dev_err(&tp->intf->dev, + "Invalid length for PHY_START\n"); + goto fail; + } +- +- start = (struct fw_phy_patch_key *)block; ++ __set_bit(FW_FLAGS_START, &fw_flags); + break; + case RTL_FW_PHY_STOP: +- if (stop || !start) { ++ if (test_bit(FW_FLAGS_STOP, &fw_flags) || ++ !test_bit(FW_FLAGS_START, &fw_flags)) { + dev_err(&tp->intf->dev, + "Check PHY_STOP fail\n"); + goto fail; +@@ -3887,28 +3894,28 @@ static long rtl8152_check_firmware(struc + "Invalid length for PHY_STOP\n"); + goto fail; + } +- +- stop = block; ++ __set_bit(FW_FLAGS_STOP, &fw_flags); + break; + case RTL_FW_PHY_NC: +- if (!start || stop) { ++ if (!test_bit(FW_FLAGS_START, &fw_flags) || ++ test_bit(FW_FLAGS_STOP, &fw_flags)) { + dev_err(&tp->intf->dev, + "check PHY_NC fail\n"); + goto fail; + } + +- if (phy_nc) { ++ if (test_bit(FW_FLAGS_NC, &fw_flags)) { + dev_err(&tp->intf->dev, + "multiple PHY NC encountered\n"); + goto fail; + } + +- phy_nc = (struct fw_phy_nc *)block; +- if (!rtl8152_is_fw_phy_nc_ok(tp, phy_nc)) { ++ if (!rtl8152_is_fw_phy_nc_ok(tp, (struct fw_phy_nc *)block)) { + dev_err(&tp->intf->dev, + "check PHY NC firmware failed\n"); + goto fail; + } ++ __set_bit(FW_FLAGS_NC, &fw_flags); + + break; + default: +@@ -3922,7 +3929,7 @@ static long rtl8152_check_firmware(struc + } + + fw_end: +- if ((phy_nc || start) && !stop) { ++ if (test_bit(FW_FLAGS_START, &fw_flags) && !test_bit(FW_FLAGS_STOP, &fw_flags)) { + dev_err(&tp->intf->dev, "without PHY_STOP\n"); + goto fail; + } diff --git a/target/linux/generic/backport-5.10/792-v5.13-r8152-add-help-function-to-change-mtu.patch b/target/linux/generic/backport-5.10/792-v5.13-r8152-add-help-function-to-change-mtu.patch new file mode 100644 index 0000000000..3559e3b95a --- /dev/null +++ b/target/linux/generic/backport-5.10/792-v5.13-r8152-add-help-function-to-change-mtu.patch @@ -0,0 +1,157 @@ +From f010a7d51cbb42bdb956f0a28b8868b15d7a3816 Mon Sep 17 00:00:00 2001 +From: Hayes Wang +Date: Fri, 16 Apr 2021 16:04:34 +0800 +Subject: [PATCH] r8152: add help function to change mtu + +commit 67ce1a806f164e59a074fea8809725d3411eaa20 upstream. + +The different chips may have different requests when changing mtu. +Therefore, add a new help function of rtl_ops to change mtu. Besides, +reset the tx/rx after changing mtu. + +Additionally, add mtu_to_size() and size_to_mtu() macros to simplify +the code. + +Signed-off-by: Hayes Wang +Signed-off-by: David S. Miller +--- + drivers/net/usb/r8152.c | 53 ++++++++++++++++++++++++----------------- + 1 file changed, 31 insertions(+), 22 deletions(-) + +--- a/drivers/net/usb/r8152.c ++++ b/drivers/net/usb/r8152.c +@@ -658,15 +658,13 @@ enum rtl_register_content { + + #define INTR_LINK 0x0004 + +-#define RTL8153_MAX_PACKET 9216 /* 9K */ +-#define RTL8153_MAX_MTU (RTL8153_MAX_PACKET - VLAN_ETH_HLEN - \ +- ETH_FCS_LEN) + #define RTL8152_RMS (VLAN_ETH_FRAME_LEN + ETH_FCS_LEN) + #define RTL8153_RMS RTL8153_MAX_PACKET + #define RTL8152_TX_TIMEOUT (5 * HZ) + #define RTL8152_NAPI_WEIGHT 64 +-#define rx_reserved_size(x) ((x) + VLAN_ETH_HLEN + ETH_FCS_LEN + \ +- sizeof(struct rx_desc) + RX_ALIGN) ++#define mtu_to_size(m) ((m) + VLAN_ETH_HLEN + ETH_FCS_LEN) ++#define size_to_mtu(s) ((s) - VLAN_ETH_HLEN - ETH_FCS_LEN) ++#define rx_reserved_size(x) (mtu_to_size(x) + sizeof(struct rx_desc) + RX_ALIGN) + + /* rtl8152 flags */ + enum rtl8152_flags { +@@ -796,6 +794,7 @@ struct r8152 { + bool (*in_nway)(struct r8152 *tp); + void (*hw_phy_cfg)(struct r8152 *tp); + void (*autosuspend_en)(struct r8152 *tp, bool enable); ++ void (*change_mtu)(struct r8152 *tp); + } rtl_ops; + + struct ups_info { +@@ -1022,8 +1021,7 @@ enum tx_csum_stat { + static const int multicast_filter_limit = 32; + static unsigned int agg_buf_sz = 16384; + +-#define RTL_LIMITED_TSO_SIZE (agg_buf_sz - sizeof(struct tx_desc) - \ +- VLAN_ETH_HLEN - ETH_FCS_LEN) ++#define RTL_LIMITED_TSO_SIZE (size_to_mtu(agg_buf_sz) - sizeof(struct tx_desc)) + + static + int get_registers(struct r8152 *tp, u16 value, u16 index, u16 size, void *data) +@@ -2633,10 +2631,7 @@ static void rtl8152_nic_reset(struct r81 + + static void set_tx_qlen(struct r8152 *tp) + { +- struct net_device *netdev = tp->netdev; +- +- tp->tx_qlen = agg_buf_sz / (netdev->mtu + VLAN_ETH_HLEN + ETH_FCS_LEN + +- sizeof(struct tx_desc)); ++ tp->tx_qlen = agg_buf_sz / (mtu_to_size(tp->netdev->mtu) + sizeof(struct tx_desc)); + } + + static inline u8 rtl8152_get_speed(struct r8152 *tp) +@@ -4725,6 +4720,12 @@ static void r8153b_hw_phy_cfg(struct r81 + set_bit(PHY_RESET, &tp->flags); + } + ++static void rtl8153_change_mtu(struct r8152 *tp) ++{ ++ ocp_write_word(tp, MCU_TYPE_PLA, PLA_RMS, mtu_to_size(tp->netdev->mtu)); ++ ocp_write_byte(tp, MCU_TYPE_PLA, PLA_MTPS, MTPS_JUMBO); ++} ++ + static void r8153_first_init(struct r8152 *tp) + { + u32 ocp_data; +@@ -4757,9 +4758,7 @@ static void r8153_first_init(struct r815 + + rtl_rx_vlan_en(tp, tp->netdev->features & NETIF_F_HW_VLAN_CTAG_RX); + +- ocp_data = tp->netdev->mtu + VLAN_ETH_HLEN + ETH_FCS_LEN; +- ocp_write_word(tp, MCU_TYPE_PLA, PLA_RMS, ocp_data); +- ocp_write_byte(tp, MCU_TYPE_PLA, PLA_MTPS, MTPS_JUMBO); ++ rtl8153_change_mtu(tp); + + ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_TCR0); + ocp_data |= TCR0_AUTO_FIFO; +@@ -4794,8 +4793,7 @@ static void r8153_enter_oob(struct r8152 + + wait_oob_link_list_ready(tp); + +- ocp_data = tp->netdev->mtu + VLAN_ETH_HLEN + ETH_FCS_LEN; +- ocp_write_word(tp, MCU_TYPE_PLA, PLA_RMS, ocp_data); ++ ocp_write_word(tp, MCU_TYPE_PLA, PLA_RMS, mtu_to_size(tp->netdev->mtu)); + + switch (tp->version) { + case RTL_VER_03: +@@ -6518,12 +6516,21 @@ static int rtl8152_change_mtu(struct net + dev->mtu = new_mtu; + + if (netif_running(dev)) { +- u32 rms = new_mtu + VLAN_ETH_HLEN + ETH_FCS_LEN; +- +- ocp_write_word(tp, MCU_TYPE_PLA, PLA_RMS, rms); ++ if (tp->rtl_ops.change_mtu) ++ tp->rtl_ops.change_mtu(tp); + +- if (netif_carrier_ok(dev)) +- r8153_set_rx_early_size(tp); ++ if (netif_carrier_ok(dev)) { ++ netif_stop_queue(dev); ++ napi_disable(&tp->napi); ++ tasklet_disable(&tp->tx_tl); ++ tp->rtl_ops.disable(tp); ++ tp->rtl_ops.enable(tp); ++ rtl_start_rx(tp); ++ tasklet_enable(&tp->tx_tl); ++ napi_enable(&tp->napi); ++ rtl8152_set_rx_mode(dev); ++ netif_wake_queue(dev); ++ } + } + + mutex_unlock(&tp->control); +@@ -6612,6 +6619,7 @@ static int rtl_ops_init(struct r8152 *tp + ops->in_nway = rtl8153_in_nway; + ops->hw_phy_cfg = r8153_hw_phy_cfg; + ops->autosuspend_en = rtl8153_runtime_enable; ++ ops->change_mtu = rtl8153_change_mtu; + if (tp->udev->speed < USB_SPEED_SUPER) + tp->rx_buf_sz = 16 * 1024; + else +@@ -6633,6 +6641,7 @@ static int rtl_ops_init(struct r8152 *tp + ops->in_nway = rtl8153_in_nway; + ops->hw_phy_cfg = r8153b_hw_phy_cfg; + ops->autosuspend_en = rtl8153b_runtime_enable; ++ ops->change_mtu = rtl8153_change_mtu; + tp->rx_buf_sz = 32 * 1024; + tp->eee_en = true; + tp->eee_adv = MDIO_EEE_1000T | MDIO_EEE_100TX; +@@ -6853,7 +6862,7 @@ static int rtl8152_probe(struct usb_inte + netdev->max_mtu = ETH_DATA_LEN; + break; + default: +- netdev->max_mtu = RTL8153_MAX_MTU; ++ netdev->max_mtu = size_to_mtu(9 * 1024); + break; + } + diff --git a/target/linux/generic/backport-5.10/793-v5.13-r8152-support-new-chips.patch b/target/linux/generic/backport-5.10/793-v5.13-r8152-support-new-chips.patch new file mode 100644 index 0000000000..06a141b451 --- /dev/null +++ b/target/linux/generic/backport-5.10/793-v5.13-r8152-support-new-chips.patch @@ -0,0 +1,2886 @@ +From e7439e7fd384f55f55837f7e4866e74d8dca3827 Mon Sep 17 00:00:00 2001 +From: Hayes Wang +Date: Fri, 16 Apr 2021 16:04:35 +0800 +Subject: [PATCH] r8152: support new chips + +commit 195aae321c829dd1945900d75561e6aa79cce208 upstream. + +Support RTL8153C, RTL8153D, RTL8156A, and RTL8156B. The RTL8156A +and RTL8156B are the 2.5G ethernet. + +Signed-off-by: Hayes Wang +Signed-off-by: David S. Miller +--- + drivers/net/usb/r8152.c | 2634 +++++++++++++++++++++++++++++++++++---- + 1 file changed, 2359 insertions(+), 275 deletions(-) + +--- a/drivers/net/usb/r8152.c ++++ b/drivers/net/usb/r8152.c +@@ -44,10 +44,14 @@ + + #define PLA_IDR 0xc000 + #define PLA_RCR 0xc010 ++#define PLA_RCR1 0xc012 + #define PLA_RMS 0xc016 + #define PLA_RXFIFO_CTRL0 0xc0a0 ++#define PLA_RXFIFO_FULL 0xc0a2 + #define PLA_RXFIFO_CTRL1 0xc0a4 ++#define PLA_RX_FIFO_FULL 0xc0a6 + #define PLA_RXFIFO_CTRL2 0xc0a8 ++#define PLA_RX_FIFO_EMPTY 0xc0aa + #define PLA_DMY_REG0 0xc0b0 + #define PLA_FMC 0xc0b4 + #define PLA_CFG_WOL 0xc0b6 +@@ -64,6 +68,8 @@ + #define PLA_MACDBG_PRE 0xd38c /* RTL_VER_04 only */ + #define PLA_MACDBG_POST 0xd38e /* RTL_VER_04 only */ + #define PLA_EXTRA_STATUS 0xd398 ++#define PLA_GPHY_CTRL 0xd3ae ++#define PLA_POL_GPIO_CTRL 0xdc6a + #define PLA_EFUSE_DATA 0xdd00 + #define PLA_EFUSE_CMD 0xdd02 + #define PLA_LEDSEL 0xdd90 +@@ -73,6 +79,8 @@ + #define PLA_LWAKE_CTRL_REG 0xe007 + #define PLA_GPHY_INTR_IMR 0xe022 + #define PLA_EEE_CR 0xe040 ++#define PLA_EEE_TXTWSYS 0xe04c ++#define PLA_EEE_TXTWSYS_2P5G 0xe058 + #define PLA_EEEP_CR 0xe080 + #define PLA_MAC_PWR_CTRL 0xe0c0 + #define PLA_MAC_PWR_CTRL2 0xe0ca +@@ -83,6 +91,7 @@ + #define PLA_TCR1 0xe612 + #define PLA_MTPS 0xe615 + #define PLA_TXFIFO_CTRL 0xe618 ++#define PLA_TXFIFO_FULL 0xe61a + #define PLA_RSTTALLY 0xe800 + #define PLA_CR 0xe813 + #define PLA_CRWECR 0xe81c +@@ -99,6 +108,7 @@ + #define PLA_SFF_STS_7 0xe8de + #define PLA_PHYSTATUS 0xe908 + #define PLA_CONFIG6 0xe90a /* CONFIG6 */ ++#define PLA_USB_CFG 0xe952 + #define PLA_BP_BA 0xfc26 + #define PLA_BP_0 0xfc28 + #define PLA_BP_1 0xfc2a +@@ -113,6 +123,7 @@ + #define USB_USB2PHY 0xb41e + #define USB_SSPHYLINK1 0xb426 + #define USB_SSPHYLINK2 0xb428 ++#define USB_L1_CTRL 0xb45e + #define USB_U2P3_CTRL 0xb460 + #define USB_CSR_DUMMY1 0xb464 + #define USB_CSR_DUMMY2 0xb466 +@@ -123,7 +134,12 @@ + #define USB_FW_FIX_EN0 0xcfca + #define USB_FW_FIX_EN1 0xcfcc + #define USB_LPM_CONFIG 0xcfd8 ++#define USB_ECM_OPTION 0xcfee + #define USB_CSTMR 0xcfef /* RTL8153A */ ++#define USB_MISC_2 0xcfff ++#define USB_ECM_OP 0xd26b ++#define USB_GPHY_CTRL 0xd284 ++#define USB_SPEED_OPTION 0xd32a + #define USB_FW_CTRL 0xd334 /* RTL8153B */ + #define USB_FC_TIMER 0xd340 + #define USB_USB_CTRL 0xd406 +@@ -137,16 +153,20 @@ + #define USB_RX_EXTRA_AGGR_TMR 0xd432 /* RTL8153B */ + #define USB_TX_DMA 0xd434 + #define USB_UPT_RXDMA_OWN 0xd437 ++#define USB_UPHY3_MDCMDIO 0xd480 + #define USB_TOLERANCE 0xd490 + #define USB_LPM_CTRL 0xd41a + #define USB_BMU_RESET 0xd4b0 ++#define USB_BMU_CONFIG 0xd4b4 + #define USB_U1U2_TIMER 0xd4da + #define USB_FW_TASK 0xd4e8 /* RTL8153B */ ++#define USB_RX_AGGR_NUM 0xd4ee + #define USB_UPS_CTRL 0xd800 + #define USB_POWER_CUT 0xd80a + #define USB_MISC_0 0xd81a + #define USB_MISC_1 0xd81f + #define USB_AFE_CTRL2 0xd824 ++#define USB_UPHY_XTAL 0xd826 + #define USB_UPS_CFG 0xd842 + #define USB_UPS_FLAGS 0xd848 + #define USB_WDT1_CTRL 0xe404 +@@ -189,6 +209,9 @@ + #define OCP_EEE_ABLE 0xa5c4 + #define OCP_EEE_ADV 0xa5d0 + #define OCP_EEE_LPABLE 0xa5d2 ++#define OCP_10GBT_CTRL 0xa5d4 ++#define OCP_10GBT_STAT 0xa5d6 ++#define OCP_EEE_ADV2 0xa6d4 + #define OCP_PHY_STATE 0xa708 /* nway state for 8153 */ + #define OCP_PHY_PATCH_STAT 0xb800 + #define OCP_PHY_PATCH_CMD 0xb820 +@@ -200,6 +223,7 @@ + /* SRAM Register */ + #define SRAM_GREEN_CFG 0x8011 + #define SRAM_LPF_CFG 0x8012 ++#define SRAM_GPHY_FW_VER 0x801e + #define SRAM_10M_AMP1 0x8080 + #define SRAM_10M_AMP2 0x8082 + #define SRAM_IMPEDANCE 0x8084 +@@ -211,11 +235,19 @@ + #define RCR_AM 0x00000004 + #define RCR_AB 0x00000008 + #define RCR_ACPT_ALL (RCR_AAP | RCR_APM | RCR_AM | RCR_AB) ++#define SLOT_EN BIT(11) ++ ++/* PLA_RCR1 */ ++#define OUTER_VLAN BIT(7) ++#define INNER_VLAN BIT(6) + + /* PLA_RXFIFO_CTRL0 */ + #define RXFIFO_THR1_NORMAL 0x00080002 + #define RXFIFO_THR1_OOB 0x01800003 + ++/* PLA_RXFIFO_FULL */ ++#define RXFIFO_FULL_MASK 0xfff ++ + /* PLA_RXFIFO_CTRL1 */ + #define RXFIFO_THR2_FULL 0x00000060 + #define RXFIFO_THR2_HIGH 0x00000038 +@@ -286,6 +318,7 @@ + #define MCU_BORW_EN 0x4000 + + /* PLA_CPCR */ ++#define FLOW_CTRL_EN BIT(0) + #define CPCR_RX_VLAN 0x0040 + + /* PLA_CFG_WOL */ +@@ -311,6 +344,10 @@ + /* PLA_CONFIG6 */ + #define LANWAKE_CLR_EN BIT(0) + ++/* PLA_USB_CFG */ ++#define EN_XG_LIP BIT(1) ++#define EN_G_LIP BIT(2) ++ + /* PLA_CONFIG5 */ + #define BWF_EN 0x0040 + #define MWF_EN 0x0020 +@@ -334,6 +371,7 @@ + /* PLA_MAC_PWR_CTRL2 */ + #define EEE_SPDWN_RATIO 0x8007 + #define MAC_CLK_SPDWN_EN BIT(15) ++#define EEE_SPDWN_RATIO_MASK 0xff + + /* PLA_MAC_PWR_CTRL3 */ + #define PLA_MCU_SPDWN_EN BIT(14) +@@ -346,6 +384,7 @@ + #define PWRSAVE_SPDWN_EN 0x1000 + #define RXDV_SPDWN_EN 0x0800 + #define TX10MIDLE_EN 0x0100 ++#define IDLE_SPDWN_EN BIT(6) + #define TP100_SPDWN_EN 0x0020 + #define TP500_SPDWN_EN 0x0010 + #define TP1000_SPDWN_EN 0x0008 +@@ -386,6 +425,13 @@ + #define LINK_CHANGE_FLAG BIT(8) + #define POLL_LINK_CHG BIT(0) + ++/* PLA_GPHY_CTRL */ ++#define GPHY_FLASH BIT(1) ++ ++/* PLA_POL_GPIO_CTRL */ ++#define DACK_DET_EN BIT(15) ++#define POL_GPHY_PATCH BIT(4) ++ + /* USB_USB2PHY */ + #define USB2PHY_SUSPEND 0x0001 + #define USB2PHY_L1 0x0002 +@@ -434,6 +480,9 @@ + #define BMU_RESET_EP_IN 0x01 + #define BMU_RESET_EP_OUT 0x02 + ++/* USB_BMU_CONFIG */ ++#define ACT_ODMA BIT(1) ++ + /* USB_UPT_RXDMA_OWN */ + #define OWN_UPDATE BIT(0) + #define OWN_CLEAR BIT(1) +@@ -441,27 +490,52 @@ + /* USB_FW_TASK */ + #define FC_PATCH_TASK BIT(1) + ++/* USB_RX_AGGR_NUM */ ++#define RX_AGGR_NUM_MASK 0x1ff ++ + /* USB_UPS_CTRL */ + #define POWER_CUT 0x0100 + + /* USB_PM_CTRL_STATUS */ + #define RESUME_INDICATE 0x0001 + ++/* USB_ECM_OPTION */ ++#define BYPASS_MAC_RESET BIT(5) ++ + /* USB_CSTMR */ + #define FORCE_SUPER BIT(0) + ++/* USB_MISC_2 */ ++#define UPS_FORCE_PWR_DOWN BIT(0) ++ ++/* USB_ECM_OP */ ++#define EN_ALL_SPEED BIT(0) ++ ++/* USB_GPHY_CTRL */ ++#define GPHY_PATCH_DONE BIT(2) ++#define BYPASS_FLASH BIT(5) ++#define BACKUP_RESTRORE BIT(6) ++ ++/* USB_SPEED_OPTION */ ++#define RG_PWRDN_EN BIT(8) ++#define ALL_SPEED_OFF BIT(9) ++ + /* USB_FW_CTRL */ + #define FLOW_CTRL_PATCH_OPT BIT(1) ++#define AUTO_SPEEDUP BIT(3) ++#define FLOW_CTRL_PATCH_2 BIT(8) + + /* USB_FC_TIMER */ + #define CTRL_TIMER_EN BIT(15) + + /* USB_USB_CTRL */ ++#define CDC_ECM_EN BIT(3) + #define RX_AGG_DISABLE 0x0010 + #define RX_ZERO_EN 0x0080 + + /* USB_U2P3_CTRL */ + #define U2P3_ENABLE 0x0001 ++#define RX_DETECT8 BIT(3) + + /* USB_POWER_CUT */ + #define PWR_EN 0x0001 +@@ -497,8 +571,12 @@ + #define SEN_VAL_NORMAL 0xa000 + #define SEL_RXIDLE 0x0100 + ++/* USB_UPHY_XTAL */ ++#define OOBS_POLLING BIT(8) ++ + /* USB_UPS_CFG */ + #define SAW_CNT_1MS_MASK 0x0fff ++#define MID_REVERSE BIT(5) /* RTL8156A */ + + /* USB_UPS_FLAGS */ + #define UPS_FLAGS_R_TUNE BIT(0) +@@ -506,6 +584,7 @@ + #define UPS_FLAGS_250M_CKDIV BIT(2) + #define UPS_FLAGS_EN_ALDPS BIT(3) + #define UPS_FLAGS_CTAP_SHORT_DIS BIT(4) ++#define UPS_FLAGS_SPEED_MASK (0xf << 16) + #define ups_flags_speed(x) ((x) << 16) + #define UPS_FLAGS_EN_EEE BIT(20) + #define UPS_FLAGS_EN_500M_EEE BIT(21) +@@ -526,6 +605,8 @@ enum spd_duplex { + FORCE_10M_FULL, + FORCE_100M_HALF, + FORCE_100M_FULL, ++ FORCE_1000M_FULL, ++ NWAY_2500M_FULL, + }; + + /* OCP_ALDPS_CONFIG */ +@@ -590,6 +671,9 @@ enum spd_duplex { + #define EN_10M_CLKDIV BIT(11) + #define EN_10M_BGOFF 0x0080 + ++/* OCP_10GBT_CTRL */ ++#define RTL_ADV2_5G_F_R BIT(5) /* Advertise 2.5GBASE-T fast-retrain */ ++ + /* OCP_PHY_STATE */ + #define TXDIS_STATE 0x01 + #define ABD_STATE 0x02 +@@ -609,7 +693,8 @@ enum spd_duplex { + #define EN_EMI_L 0x0040 + + /* OCP_SYSCLK_CFG */ +-#define clk_div_expo(x) (min(x, 5) << 8) ++#define sysclk_div_expo(x) (min(x, 5) << 8) ++#define clk_div_expo(x) (min(x, 5) << 4) + + /* SRAM_GREEN_CFG */ + #define GREEN_ETH_EN BIT(15) +@@ -640,6 +725,11 @@ enum spd_duplex { + #define BP4_SUPER_ONLY 0x1578 /* RTL_VER_04 only */ + + enum rtl_register_content { ++ _2500bps = BIT(10), ++ _1250bps = BIT(9), ++ _500bps = BIT(8), ++ _tx_flow = BIT(6), ++ _rx_flow = BIT(5), + _1000bps = 0x10, + _100bps = 0x08, + _10bps = 0x04, +@@ -647,6 +737,9 @@ enum rtl_register_content { + FULL_DUP = 0x01, + }; + ++#define is_speed_2500(_speed) (((_speed) & (_2500bps | LINK_STATUS)) == (_2500bps | LINK_STATUS)) ++#define is_flow_control(_speed) (((_speed) & (_tx_flow | _rx_flow)) == (_tx_flow | _rx_flow)) ++ + #define RTL8152_MAX_TX 4 + #define RTL8152_MAX_RX 10 + #define INTBUFSIZE 2 +@@ -661,7 +754,6 @@ enum rtl_register_content { + #define RTL8152_RMS (VLAN_ETH_FRAME_LEN + ETH_FCS_LEN) + #define RTL8153_RMS RTL8153_MAX_PACKET + #define RTL8152_TX_TIMEOUT (5 * HZ) +-#define RTL8152_NAPI_WEIGHT 64 + #define mtu_to_size(m) ((m) + VLAN_ETH_HLEN + ETH_FCS_LEN) + #define size_to_mtu(s) ((s) - VLAN_ETH_HLEN - ETH_FCS_LEN) + #define rx_reserved_size(x) (mtu_to_size(x) + sizeof(struct rx_desc) + RX_ALIGN) +@@ -798,6 +890,7 @@ struct r8152 { + } rtl_ops; + + struct ups_info { ++ u32 r_tune:1; + u32 _10m_ckdiv:1; + u32 _250m_ckdiv:1; + u32 aldps:1; +@@ -839,7 +932,9 @@ struct r8152 { + u32 rx_buf_sz; + u32 rx_copybreak; + u32 rx_pending; ++ u32 fc_pause_on, fc_pause_off; + ++ u32 support_2500full:1; + u16 ocp_base; + u16 speed; + u16 eee_adv; +@@ -999,6 +1094,15 @@ enum rtl_version { + RTL_VER_07, + RTL_VER_08, + RTL_VER_09, ++ ++ RTL_TEST_01, ++ RTL_VER_10, ++ RTL_VER_11, ++ RTL_VER_12, ++ RTL_VER_13, ++ RTL_VER_14, ++ RTL_VER_15, ++ + RTL_VER_MAX + }; + +@@ -1014,6 +1118,7 @@ enum tx_csum_stat { + #define RTL_ADVERTISED_100_FULL BIT(3) + #define RTL_ADVERTISED_1000_HALF BIT(4) + #define RTL_ADVERTISED_1000_FULL BIT(5) ++#define RTL_ADVERTISED_2500_FULL BIT(6) + + /* Maximum number of multicast addresses to filter (vs. Rx-all-multicast). + * The RTL chips use a 64 element hash table based on the Ethernet CRC. +@@ -2607,7 +2712,7 @@ static netdev_tx_t rtl8152_start_xmit(st + + static void r8152b_reset_packet_filter(struct r8152 *tp) + { +- u32 ocp_data; ++ u32 ocp_data; + + ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_FMC); + ocp_data &= ~FMC_FCR_MCU_EN; +@@ -2618,14 +2723,47 @@ static void r8152b_reset_packet_filter(s + + static void rtl8152_nic_reset(struct r8152 *tp) + { +- int i; ++ u32 ocp_data; ++ int i; + +- ocp_write_byte(tp, MCU_TYPE_PLA, PLA_CR, CR_RST); ++ switch (tp->version) { ++ case RTL_TEST_01: ++ case RTL_VER_10: ++ case RTL_VER_11: ++ ocp_data = ocp_read_byte(tp, MCU_TYPE_PLA, PLA_CR); ++ ocp_data &= ~CR_TE; ++ ocp_write_byte(tp, MCU_TYPE_PLA, PLA_CR, ocp_data); ++ ++ ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_BMU_RESET); ++ ocp_data &= ~BMU_RESET_EP_IN; ++ ocp_write_word(tp, MCU_TYPE_USB, USB_BMU_RESET, ocp_data); ++ ++ ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_USB_CTRL); ++ ocp_data |= CDC_ECM_EN; ++ ocp_write_word(tp, MCU_TYPE_USB, USB_USB_CTRL, ocp_data); ++ ++ ocp_data = ocp_read_byte(tp, MCU_TYPE_PLA, PLA_CR); ++ ocp_data &= ~CR_RE; ++ ocp_write_byte(tp, MCU_TYPE_PLA, PLA_CR, ocp_data); ++ ++ ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_BMU_RESET); ++ ocp_data |= BMU_RESET_EP_IN; ++ ocp_write_word(tp, MCU_TYPE_USB, USB_BMU_RESET, ocp_data); ++ ++ ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_USB_CTRL); ++ ocp_data &= ~CDC_ECM_EN; ++ ocp_write_word(tp, MCU_TYPE_USB, USB_USB_CTRL, ocp_data); ++ break; + +- for (i = 0; i < 1000; i++) { +- if (!(ocp_read_byte(tp, MCU_TYPE_PLA, PLA_CR) & CR_RST)) +- break; +- usleep_range(100, 400); ++ default: ++ ocp_write_byte(tp, MCU_TYPE_PLA, PLA_CR, CR_RST); ++ ++ for (i = 0; i < 1000; i++) { ++ if (!(ocp_read_byte(tp, MCU_TYPE_PLA, PLA_CR) & CR_RST)) ++ break; ++ usleep_range(100, 400); ++ } ++ break; + } + } + +@@ -2634,9 +2772,9 @@ static void set_tx_qlen(struct r8152 *tp + tp->tx_qlen = agg_buf_sz / (mtu_to_size(tp->netdev->mtu) + sizeof(struct tx_desc)); + } + +-static inline u8 rtl8152_get_speed(struct r8152 *tp) ++static inline u16 rtl8152_get_speed(struct r8152 *tp) + { +- return ocp_read_byte(tp, MCU_TYPE_PLA, PLA_PHYSTATUS); ++ return ocp_read_word(tp, MCU_TYPE_PLA, PLA_PHYSTATUS); + } + + static void rtl_eee_plus_en(struct r8152 *tp, bool enable) +@@ -2796,6 +2934,7 @@ static int rtl_enable(struct r8152 *tp) + switch (tp->version) { + case RTL_VER_08: + case RTL_VER_09: ++ case RTL_VER_14: + r8153b_rx_agg_chg_indicate(tp); + break; + default: +@@ -2833,6 +2972,7 @@ static void r8153_set_rx_early_timeout(s + + case RTL_VER_08: + case RTL_VER_09: ++ case RTL_VER_14: + /* The RTL8153B uses USB_RX_EXTRA_AGGR_TMR for rx timeout + * primarily. For USB_RX_EARLY_TIMEOUT, we fix it to 128ns. + */ +@@ -2842,6 +2982,18 @@ static void r8153_set_rx_early_timeout(s + ocp_data); + break; + ++ case RTL_VER_10: ++ case RTL_VER_11: ++ case RTL_VER_12: ++ case RTL_VER_13: ++ case RTL_VER_15: ++ ocp_write_word(tp, MCU_TYPE_USB, USB_RX_EARLY_TIMEOUT, ++ 640 / 8); ++ ocp_write_word(tp, MCU_TYPE_USB, USB_RX_EXTRA_AGGR_TMR, ++ ocp_data); ++ r8153b_rx_agg_chg_indicate(tp); ++ break; ++ + default: + break; + } +@@ -2861,8 +3013,19 @@ static void r8153_set_rx_early_size(stru + break; + case RTL_VER_08: + case RTL_VER_09: ++ case RTL_VER_14: ++ ocp_write_word(tp, MCU_TYPE_USB, USB_RX_EARLY_SIZE, ++ ocp_data / 8); ++ break; ++ case RTL_TEST_01: ++ case RTL_VER_10: ++ case RTL_VER_11: ++ case RTL_VER_12: ++ case RTL_VER_13: ++ case RTL_VER_15: + ocp_write_word(tp, MCU_TYPE_USB, USB_RX_EARLY_SIZE, + ocp_data / 8); ++ r8153b_rx_agg_chg_indicate(tp); + break; + default: + WARN_ON_ONCE(1); +@@ -2872,6 +3035,8 @@ static void r8153_set_rx_early_size(stru + + static int rtl8153_enable(struct r8152 *tp) + { ++ u32 ocp_data; ++ + if (test_bit(RTL8152_UNPLUG, &tp->flags)) + return -ENODEV; + +@@ -2882,15 +3047,18 @@ static int rtl8153_enable(struct r8152 * + + rtl_set_ifg(tp, rtl8152_get_speed(tp)); + +- if (tp->version == RTL_VER_09) { +- u32 ocp_data; +- ++ switch (tp->version) { ++ case RTL_VER_09: ++ case RTL_VER_14: + ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_FW_TASK); + ocp_data &= ~FC_PATCH_TASK; + ocp_write_word(tp, MCU_TYPE_USB, USB_FW_TASK, ocp_data); + usleep_range(1000, 2000); + ocp_data |= FC_PATCH_TASK; + ocp_write_word(tp, MCU_TYPE_USB, USB_FW_TASK, ocp_data); ++ break; ++ default: ++ break; + } + + return rtl_enable(tp); +@@ -2955,12 +3123,40 @@ static void rtl_rx_vlan_en(struct r8152 + { + u32 ocp_data; + +- ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_CPCR); +- if (enable) +- ocp_data |= CPCR_RX_VLAN; +- else +- ocp_data &= ~CPCR_RX_VLAN; +- ocp_write_word(tp, MCU_TYPE_PLA, PLA_CPCR, ocp_data); ++ switch (tp->version) { ++ case RTL_VER_01: ++ case RTL_VER_02: ++ case RTL_VER_03: ++ case RTL_VER_04: ++ case RTL_VER_05: ++ case RTL_VER_06: ++ case RTL_VER_07: ++ case RTL_VER_08: ++ case RTL_VER_09: ++ case RTL_VER_14: ++ ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_CPCR); ++ if (enable) ++ ocp_data |= CPCR_RX_VLAN; ++ else ++ ocp_data &= ~CPCR_RX_VLAN; ++ ocp_write_word(tp, MCU_TYPE_PLA, PLA_CPCR, ocp_data); ++ break; ++ ++ case RTL_TEST_01: ++ case RTL_VER_10: ++ case RTL_VER_11: ++ case RTL_VER_12: ++ case RTL_VER_13: ++ case RTL_VER_15: ++ default: ++ ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_RCR1); ++ if (enable) ++ ocp_data |= OUTER_VLAN | INNER_VLAN; ++ else ++ ocp_data &= ~(OUTER_VLAN | INNER_VLAN); ++ ocp_write_word(tp, MCU_TYPE_PLA, PLA_RCR1, ocp_data); ++ break; ++ } + } + + static int rtl8152_set_features(struct net_device *dev, +@@ -3053,6 +3249,40 @@ static void __rtl_set_wol(struct r8152 * + device_set_wakeup_enable(&tp->udev->dev, false); + } + ++static void r8153_mac_clk_speed_down(struct r8152 *tp, bool enable) ++{ ++ u32 ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL2); ++ ++ /* MAC clock speed down */ ++ if (enable) ++ ocp_data |= MAC_CLK_SPDWN_EN; ++ else ++ ocp_data &= ~MAC_CLK_SPDWN_EN; ++ ++ ocp_write_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL2, ocp_data); ++} ++ ++static void r8156_mac_clk_spd(struct r8152 *tp, bool enable) ++{ ++ u32 ocp_data; ++ ++ /* MAC clock speed down */ ++ if (enable) { ++ /* aldps_spdwn_ratio, tp10_spdwn_ratio */ ++ ocp_write_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL, ++ 0x0403); ++ ++ ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL2); ++ ocp_data &= ~EEE_SPDWN_RATIO_MASK; ++ ocp_data |= MAC_CLK_SPDWN_EN | 0x03; /* eee_spdwn_ratio */ ++ ocp_write_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL2, ocp_data); ++ } else { ++ ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL2); ++ ocp_data &= ~MAC_CLK_SPDWN_EN; ++ ocp_write_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL2, ocp_data); ++ } ++} ++ + static void r8153_u1u2en(struct r8152 *tp, bool enable) + { + u8 u1u2[8]; +@@ -3112,6 +3342,9 @@ static void r8153b_ups_flags(struct r815 + if (tp->ups_info.eee_cmod_lv) + ups_flags |= UPS_FLAGS_EEE_CMOD_LV_EN; + ++ if (tp->ups_info.r_tune) ++ ups_flags |= UPS_FLAGS_R_TUNE; ++ + if (tp->ups_info._10m_ckdiv) + ups_flags |= UPS_FLAGS_EN_10M_CKDIV; + +@@ -3162,6 +3395,88 @@ static void r8153b_ups_flags(struct r815 + ocp_write_dword(tp, MCU_TYPE_USB, USB_UPS_FLAGS, ups_flags); + } + ++static void r8156_ups_flags(struct r8152 *tp) ++{ ++ u32 ups_flags = 0; ++ ++ if (tp->ups_info.green) ++ ups_flags |= UPS_FLAGS_EN_GREEN; ++ ++ if (tp->ups_info.aldps) ++ ups_flags |= UPS_FLAGS_EN_ALDPS; ++ ++ if (tp->ups_info.eee) ++ ups_flags |= UPS_FLAGS_EN_EEE; ++ ++ if (tp->ups_info.flow_control) ++ ups_flags |= UPS_FLAGS_EN_FLOW_CTR; ++ ++ if (tp->ups_info.eee_ckdiv) ++ ups_flags |= UPS_FLAGS_EN_EEE_CKDIV; ++ ++ if (tp->ups_info._10m_ckdiv) ++ ups_flags |= UPS_FLAGS_EN_10M_CKDIV; ++ ++ if (tp->ups_info.eee_plloff_100) ++ ups_flags |= UPS_FLAGS_EEE_PLLOFF_100; ++ ++ if (tp->ups_info.eee_plloff_giga) ++ ups_flags |= UPS_FLAGS_EEE_PLLOFF_GIGA; ++ ++ if (tp->ups_info._250m_ckdiv) ++ ups_flags |= UPS_FLAGS_250M_CKDIV; ++ ++ switch (tp->ups_info.speed_duplex) { ++ case FORCE_10M_HALF: ++ ups_flags |= ups_flags_speed(0); ++ break; ++ case FORCE_10M_FULL: ++ ups_flags |= ups_flags_speed(1); ++ break; ++ case FORCE_100M_HALF: ++ ups_flags |= ups_flags_speed(2); ++ break; ++ case FORCE_100M_FULL: ++ ups_flags |= ups_flags_speed(3); ++ break; ++ case NWAY_10M_HALF: ++ ups_flags |= ups_flags_speed(4); ++ break; ++ case NWAY_10M_FULL: ++ ups_flags |= ups_flags_speed(5); ++ break; ++ case NWAY_100M_HALF: ++ ups_flags |= ups_flags_speed(6); ++ break; ++ case NWAY_100M_FULL: ++ ups_flags |= ups_flags_speed(7); ++ break; ++ case NWAY_1000M_FULL: ++ ups_flags |= ups_flags_speed(8); ++ break; ++ case NWAY_2500M_FULL: ++ ups_flags |= ups_flags_speed(9); ++ break; ++ default: ++ break; ++ } ++ ++ switch (tp->ups_info.lite_mode) { ++ case 1: ++ ups_flags |= 0 << 5; ++ break; ++ case 2: ++ ups_flags |= 2 << 5; ++ break; ++ case 0: ++ default: ++ ups_flags |= 1 << 5; ++ break; ++ } ++ ++ ocp_write_dword(tp, MCU_TYPE_USB, USB_UPS_FLAGS, ups_flags); ++} ++ + static void rtl_green_en(struct r8152 *tp, bool enable) + { + u16 data; +@@ -3225,16 +3540,16 @@ static void r8153b_ups_en(struct r8152 * + ocp_data |= UPS_EN | USP_PREWAKE | PHASE2_EN; + ocp_write_byte(tp, MCU_TYPE_USB, USB_POWER_CUT, ocp_data); + +- ocp_data = ocp_read_byte(tp, MCU_TYPE_USB, 0xcfff); +- ocp_data |= BIT(0); +- ocp_write_byte(tp, MCU_TYPE_USB, 0xcfff, ocp_data); ++ ocp_data = ocp_read_byte(tp, MCU_TYPE_USB, USB_MISC_2); ++ ocp_data |= UPS_FORCE_PWR_DOWN; ++ ocp_write_byte(tp, MCU_TYPE_USB, USB_MISC_2, ocp_data); + } else { + ocp_data &= ~(UPS_EN | USP_PREWAKE); + ocp_write_byte(tp, MCU_TYPE_USB, USB_POWER_CUT, ocp_data); + +- ocp_data = ocp_read_byte(tp, MCU_TYPE_USB, 0xcfff); +- ocp_data &= ~BIT(0); +- ocp_write_byte(tp, MCU_TYPE_USB, 0xcfff, ocp_data); ++ ocp_data = ocp_read_byte(tp, MCU_TYPE_USB, USB_MISC_2); ++ ocp_data &= ~UPS_FORCE_PWR_DOWN; ++ ocp_write_byte(tp, MCU_TYPE_USB, USB_MISC_2, ocp_data); + + if (ocp_read_word(tp, MCU_TYPE_USB, USB_MISC_0) & PCUT_STATUS) { + int i; +@@ -3254,6 +3569,95 @@ static void r8153b_ups_en(struct r8152 * + } + } + ++static void r8153c_ups_en(struct r8152 *tp, bool enable) ++{ ++ u32 ocp_data = ocp_read_byte(tp, MCU_TYPE_USB, USB_POWER_CUT); ++ ++ if (enable) { ++ r8153b_ups_flags(tp); ++ ++ ocp_data |= UPS_EN | USP_PREWAKE | PHASE2_EN; ++ ocp_write_byte(tp, MCU_TYPE_USB, USB_POWER_CUT, ocp_data); ++ ++ ocp_data = ocp_read_byte(tp, MCU_TYPE_USB, USB_MISC_2); ++ ocp_data |= UPS_FORCE_PWR_DOWN; ++ ocp_data &= ~BIT(7); ++ ocp_write_byte(tp, MCU_TYPE_USB, USB_MISC_2, ocp_data); ++ } else { ++ ocp_data &= ~(UPS_EN | USP_PREWAKE); ++ ocp_write_byte(tp, MCU_TYPE_USB, USB_POWER_CUT, ocp_data); ++ ++ ocp_data = ocp_read_byte(tp, MCU_TYPE_USB, USB_MISC_2); ++ ocp_data &= ~UPS_FORCE_PWR_DOWN; ++ ocp_write_byte(tp, MCU_TYPE_USB, USB_MISC_2, ocp_data); ++ ++ if (ocp_read_word(tp, MCU_TYPE_USB, USB_MISC_0) & PCUT_STATUS) { ++ int i; ++ ++ for (i = 0; i < 500; i++) { ++ if (ocp_read_word(tp, MCU_TYPE_PLA, PLA_BOOT_CTRL) & ++ AUTOLOAD_DONE) ++ break; ++ msleep(20); ++ } ++ ++ tp->rtl_ops.hw_phy_cfg(tp); ++ ++ rtl8152_set_speed(tp, tp->autoneg, tp->speed, ++ tp->duplex, tp->advertising); ++ } ++ ++ ocp_write_byte(tp, MCU_TYPE_PLA, PLA_CRWECR, CRWECR_CONFIG); ++ ++ ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_CONFIG34); ++ ocp_data |= BIT(8); ++ ocp_write_word(tp, MCU_TYPE_PLA, PLA_CONFIG34, ocp_data); ++ ++ ocp_write_byte(tp, MCU_TYPE_PLA, PLA_CRWECR, CRWECR_NORAML); ++ } ++} ++ ++static void r8156_ups_en(struct r8152 *tp, bool enable) ++{ ++ u32 ocp_data = ocp_read_byte(tp, MCU_TYPE_USB, USB_POWER_CUT); ++ ++ if (enable) { ++ r8156_ups_flags(tp); ++ ++ ocp_data |= UPS_EN | USP_PREWAKE | PHASE2_EN; ++ ocp_write_byte(tp, MCU_TYPE_USB, USB_POWER_CUT, ocp_data); ++ ++ ocp_data = ocp_read_byte(tp, MCU_TYPE_USB, USB_MISC_2); ++ ocp_data |= UPS_FORCE_PWR_DOWN; ++ ocp_write_byte(tp, MCU_TYPE_USB, USB_MISC_2, ocp_data); ++ ++ switch (tp->version) { ++ case RTL_VER_13: ++ case RTL_VER_15: ++ ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_UPHY_XTAL); ++ ocp_data &= ~OOBS_POLLING; ++ ocp_write_byte(tp, MCU_TYPE_USB, USB_UPHY_XTAL, ocp_data); ++ break; ++ default: ++ break; ++ } ++ } else { ++ ocp_data &= ~(UPS_EN | USP_PREWAKE); ++ ocp_write_byte(tp, MCU_TYPE_USB, USB_POWER_CUT, ocp_data); ++ ++ ocp_data = ocp_read_byte(tp, MCU_TYPE_USB, USB_MISC_2); ++ ocp_data &= ~UPS_FORCE_PWR_DOWN; ++ ocp_write_byte(tp, MCU_TYPE_USB, USB_MISC_2, ocp_data); ++ ++ if (ocp_read_word(tp, MCU_TYPE_USB, USB_MISC_0) & PCUT_STATUS) { ++ tp->rtl_ops.hw_phy_cfg(tp); ++ ++ rtl8152_set_speed(tp, tp->autoneg, tp->speed, ++ tp->duplex, tp->advertising); ++ } ++ } ++} ++ + static void r8153_power_cut_en(struct r8152 *tp, bool enable) + { + u32 ocp_data; +@@ -3383,6 +3787,38 @@ static void rtl8153b_runtime_enable(stru + } + } + ++static void rtl8153c_runtime_enable(struct r8152 *tp, bool enable) ++{ ++ if (enable) { ++ r8153_queue_wake(tp, true); ++ r8153b_u1u2en(tp, false); ++ r8153_u2p3en(tp, false); ++ rtl_runtime_suspend_enable(tp, true); ++ r8153c_ups_en(tp, true); ++ } else { ++ r8153c_ups_en(tp, false); ++ r8153_queue_wake(tp, false); ++ rtl_runtime_suspend_enable(tp, false); ++ r8153b_u1u2en(tp, true); ++ } ++} ++ ++static void rtl8156_runtime_enable(struct r8152 *tp, bool enable) ++{ ++ if (enable) { ++ r8153_queue_wake(tp, true); ++ r8153b_u1u2en(tp, false); ++ r8153_u2p3en(tp, false); ++ rtl_runtime_suspend_enable(tp, true); ++ } else { ++ r8153_queue_wake(tp, false); ++ rtl_runtime_suspend_enable(tp, false); ++ r8153_u2p3en(tp, true); ++ if (tp->udev->speed >= USB_SPEED_SUPER) ++ r8153b_u1u2en(tp, true); ++ } ++} ++ + static void r8153_teredo_off(struct r8152 *tp) + { + u32 ocp_data; +@@ -3403,14 +3839,19 @@ static void r8153_teredo_off(struct r815 + + case RTL_VER_08: + case RTL_VER_09: ++ case RTL_TEST_01: ++ case RTL_VER_10: ++ case RTL_VER_11: ++ case RTL_VER_12: ++ case RTL_VER_13: ++ case RTL_VER_14: ++ case RTL_VER_15: ++ default: + /* The bit 0 ~ 7 are relative with teredo settings. They are + * W1C (write 1 to clear), so set all 1 to disable it. + */ + ocp_write_byte(tp, MCU_TYPE_PLA, PLA_TEREDO_CFG, 0xff); + break; +- +- default: +- break; + } + + ocp_write_word(tp, MCU_TYPE_PLA, PLA_WDT6_CTRL, WDT6_SET_MODE); +@@ -3445,6 +3886,12 @@ static void rtl_clear_bp(struct r8152 *t + break; + case RTL_VER_08: + case RTL_VER_09: ++ case RTL_VER_10: ++ case RTL_VER_11: ++ case RTL_VER_12: ++ case RTL_VER_13: ++ case RTL_VER_14: ++ case RTL_VER_15: + default: + if (type == MCU_TYPE_USB) { + ocp_write_word(tp, MCU_TYPE_USB, USB_BP2_EN, 0); +@@ -3654,6 +4101,11 @@ static bool rtl8152_is_fw_mac_ok(struct + case RTL_VER_06: + case RTL_VER_08: + case RTL_VER_09: ++ case RTL_VER_11: ++ case RTL_VER_12: ++ case RTL_VER_13: ++ case RTL_VER_14: ++ case RTL_VER_15: + fw_reg = 0xf800; + bp_ba_addr = PLA_BP_BA; + bp_en_addr = PLA_BP_EN; +@@ -3677,6 +4129,11 @@ static bool rtl8152_is_fw_mac_ok(struct + break; + case RTL_VER_08: + case RTL_VER_09: ++ case RTL_VER_11: ++ case RTL_VER_12: ++ case RTL_VER_13: ++ case RTL_VER_14: ++ case RTL_VER_15: + fw_reg = 0xe600; + bp_ba_addr = USB_BP_BA; + bp_en_addr = USB_BP2_EN; +@@ -4216,6 +4673,22 @@ static void r8153_eee_en(struct r8152 *t + tp->ups_info.eee = enable; + } + ++static void r8156_eee_en(struct r8152 *tp, bool enable) ++{ ++ u16 config; ++ ++ r8153_eee_en(tp, enable); ++ ++ config = ocp_reg_read(tp, OCP_EEE_ADV2); ++ ++ if (enable) ++ config |= MDIO_EEE_2_5GT; ++ else ++ config &= ~MDIO_EEE_2_5GT; ++ ++ ocp_reg_write(tp, OCP_EEE_ADV2, config); ++} ++ + static void rtl_eee_enable(struct r8152 *tp, bool enable) + { + switch (tp->version) { +@@ -4237,6 +4710,7 @@ static void rtl_eee_enable(struct r8152 + case RTL_VER_06: + case RTL_VER_08: + case RTL_VER_09: ++ case RTL_VER_14: + if (enable) { + r8153_eee_en(tp, true); + ocp_reg_write(tp, OCP_EEE_ADV, tp->eee_adv); +@@ -4245,6 +4719,19 @@ static void rtl_eee_enable(struct r8152 + ocp_reg_write(tp, OCP_EEE_ADV, 0); + } + break; ++ case RTL_VER_10: ++ case RTL_VER_11: ++ case RTL_VER_12: ++ case RTL_VER_13: ++ case RTL_VER_15: ++ if (enable) { ++ r8156_eee_en(tp, true); ++ ocp_reg_write(tp, OCP_EEE_ADV, tp->eee_adv); ++ } else { ++ r8156_eee_en(tp, false); ++ ocp_reg_write(tp, OCP_EEE_ADV, 0); ++ } ++ break; + default: + break; + } +@@ -4291,6 +4778,20 @@ static void wait_oob_link_list_ready(str + } + } + ++static void r8156b_wait_loading_flash(struct r8152 *tp) ++{ ++ if ((ocp_read_word(tp, MCU_TYPE_PLA, PLA_GPHY_CTRL) & GPHY_FLASH) && ++ !(ocp_read_word(tp, MCU_TYPE_USB, USB_GPHY_CTRL) & BYPASS_FLASH)) { ++ int i; ++ ++ for (i = 0; i < 100; i++) { ++ if (ocp_read_word(tp, MCU_TYPE_USB, USB_GPHY_CTRL) & GPHY_PATCH_DONE) ++ break; ++ usleep_range(1000, 2000); ++ } ++ } ++} ++ + static void r8152b_exit_oob(struct r8152 *tp) + { + u32 ocp_data; +@@ -4341,7 +4842,7 @@ static void r8152b_exit_oob(struct r8152 + } + + /* TX share fifo free credit full threshold */ +- ocp_write_dword(tp, MCU_TYPE_PLA, PLA_TXFIFO_CTRL, TXFIFO_THR_NORMAL); ++ ocp_write_dword(tp, MCU_TYPE_PLA, PLA_TXFIFO_CTRL, TXFIFO_THR_NORMAL2); + + ocp_write_byte(tp, MCU_TYPE_USB, USB_TX_AGG, TX_AGG_MAX_THRESHOLD); + ocp_write_dword(tp, MCU_TYPE_USB, USB_RX_BUF_TH, RX_THR_HIGH); +@@ -4518,6 +5019,21 @@ static int r8153b_post_firmware_1(struct + return 0; + } + ++static int r8153c_post_firmware_1(struct r8152 *tp) ++{ ++ u32 ocp_data; ++ ++ ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_FW_CTRL); ++ ocp_data |= FLOW_CTRL_PATCH_2; ++ ocp_write_word(tp, MCU_TYPE_USB, USB_FW_CTRL, ocp_data); ++ ++ ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_FW_TASK); ++ ocp_data |= FC_PATCH_TASK; ++ ocp_write_word(tp, MCU_TYPE_USB, USB_FW_TASK, ocp_data); ++ ++ return 0; ++} ++ + static void r8153_aldps_en(struct r8152 *tp, bool enable) + { + u16 data; +@@ -4720,6 +5236,13 @@ static void r8153b_hw_phy_cfg(struct r81 + set_bit(PHY_RESET, &tp->flags); + } + ++static void r8153c_hw_phy_cfg(struct r8152 *tp) ++{ ++ r8153b_hw_phy_cfg(tp); ++ ++ tp->ups_info.r_tune = true; ++} ++ + static void rtl8153_change_mtu(struct r8152 *tp) + { + ocp_write_word(tp, MCU_TYPE_PLA, PLA_RMS, mtu_to_size(tp->netdev->mtu)); +@@ -4807,6 +5330,7 @@ static void r8153_enter_oob(struct r8152 + + case RTL_VER_08: + case RTL_VER_09: ++ case RTL_VER_14: + /* Clear teredo wake event. bit[15:8] is the teredo wakeup + * type. Set it to zero. bits[7:0] are the W1C bits about + * the events. Set them to all 1 to clear them. +@@ -4843,6 +5367,96 @@ static void rtl8153_disable(struct r8152 + r8153_aldps_en(tp, true); + } + ++static int rtl8156_enable(struct r8152 *tp) ++{ ++ u32 ocp_data; ++ u16 speed; ++ ++ if (test_bit(RTL8152_UNPLUG, &tp->flags)) ++ return -ENODEV; ++ ++ set_tx_qlen(tp); ++ rtl_set_eee_plus(tp); ++ r8153_set_rx_early_timeout(tp); ++ r8153_set_rx_early_size(tp); ++ ++ speed = rtl8152_get_speed(tp); ++ rtl_set_ifg(tp, speed); ++ ++ ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL4); ++ if (speed & _2500bps) ++ ocp_data &= ~IDLE_SPDWN_EN; ++ else ++ ocp_data |= IDLE_SPDWN_EN; ++ ocp_write_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL4, ocp_data); ++ ++ if (speed & _1000bps) ++ ocp_write_word(tp, MCU_TYPE_PLA, PLA_EEE_TXTWSYS, 0x11); ++ else if (speed & _500bps) ++ ocp_write_word(tp, MCU_TYPE_PLA, PLA_EEE_TXTWSYS, 0x3d); ++ ++ if (tp->udev->speed == USB_SPEED_HIGH) { ++ /* USB 0xb45e[3:0] l1_nyet_hird */ ++ ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_L1_CTRL); ++ ocp_data &= ~0xf; ++ if (is_flow_control(speed)) ++ ocp_data |= 0xf; ++ else ++ ocp_data |= 0x1; ++ ocp_write_word(tp, MCU_TYPE_USB, USB_L1_CTRL, ocp_data); ++ } ++ ++ return rtl_enable(tp); ++} ++ ++static int rtl8156b_enable(struct r8152 *tp) ++{ ++ u32 ocp_data; ++ u16 speed; ++ ++ if (test_bit(RTL8152_UNPLUG, &tp->flags)) ++ return -ENODEV; ++ ++ set_tx_qlen(tp); ++ rtl_set_eee_plus(tp); ++ ++ ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_RX_AGGR_NUM); ++ ocp_data &= ~RX_AGGR_NUM_MASK; ++ ocp_write_word(tp, MCU_TYPE_USB, USB_RX_AGGR_NUM, ocp_data); ++ ++ r8153_set_rx_early_timeout(tp); ++ r8153_set_rx_early_size(tp); ++ ++ speed = rtl8152_get_speed(tp); ++ rtl_set_ifg(tp, speed); ++ ++ ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL4); ++ if (speed & _2500bps) ++ ocp_data &= ~IDLE_SPDWN_EN; ++ else ++ ocp_data |= IDLE_SPDWN_EN; ++ ocp_write_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL4, ocp_data); ++ ++ if (tp->udev->speed == USB_SPEED_HIGH) { ++ ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_L1_CTRL); ++ ocp_data &= ~0xf; ++ if (is_flow_control(speed)) ++ ocp_data |= 0xf; ++ else ++ ocp_data |= 0x1; ++ ocp_write_word(tp, MCU_TYPE_USB, USB_L1_CTRL, ocp_data); ++ } ++ ++ ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_FW_TASK); ++ ocp_data &= ~FC_PATCH_TASK; ++ ocp_write_word(tp, MCU_TYPE_USB, USB_FW_TASK, ocp_data); ++ usleep_range(1000, 2000); ++ ocp_data |= FC_PATCH_TASK; ++ ocp_write_word(tp, MCU_TYPE_USB, USB_FW_TASK, ocp_data); ++ ++ return rtl_enable(tp); ++} ++ + static int rtl8152_set_speed(struct r8152 *tp, u8 autoneg, u32 speed, u8 duplex, + u32 advertising) + { +@@ -4891,58 +5505,73 @@ static int rtl8152_set_speed(struct r815 + + tp->mii.force_media = 1; + } else { +- u16 anar, tmp1; ++ u16 orig, new1; + u32 support; + + support = RTL_ADVERTISED_10_HALF | RTL_ADVERTISED_10_FULL | + RTL_ADVERTISED_100_HALF | RTL_ADVERTISED_100_FULL; + +- if (tp->mii.supports_gmii) ++ if (tp->mii.supports_gmii) { + support |= RTL_ADVERTISED_1000_FULL; + ++ if (tp->support_2500full) ++ support |= RTL_ADVERTISED_2500_FULL; ++ } ++ + if (!(advertising & support)) + return -EINVAL; + +- anar = r8152_mdio_read(tp, MII_ADVERTISE); +- tmp1 = anar & ~(ADVERTISE_10HALF | ADVERTISE_10FULL | ++ orig = r8152_mdio_read(tp, MII_ADVERTISE); ++ new1 = orig & ~(ADVERTISE_10HALF | ADVERTISE_10FULL | + ADVERTISE_100HALF | ADVERTISE_100FULL); + if (advertising & RTL_ADVERTISED_10_HALF) { +- tmp1 |= ADVERTISE_10HALF; ++ new1 |= ADVERTISE_10HALF; + tp->ups_info.speed_duplex = NWAY_10M_HALF; + } + if (advertising & RTL_ADVERTISED_10_FULL) { +- tmp1 |= ADVERTISE_10FULL; ++ new1 |= ADVERTISE_10FULL; + tp->ups_info.speed_duplex = NWAY_10M_FULL; + } + + if (advertising & RTL_ADVERTISED_100_HALF) { +- tmp1 |= ADVERTISE_100HALF; ++ new1 |= ADVERTISE_100HALF; + tp->ups_info.speed_duplex = NWAY_100M_HALF; + } + if (advertising & RTL_ADVERTISED_100_FULL) { +- tmp1 |= ADVERTISE_100FULL; ++ new1 |= ADVERTISE_100FULL; + tp->ups_info.speed_duplex = NWAY_100M_FULL; + } + +- if (anar != tmp1) { +- r8152_mdio_write(tp, MII_ADVERTISE, tmp1); +- tp->mii.advertising = tmp1; ++ if (orig != new1) { ++ r8152_mdio_write(tp, MII_ADVERTISE, new1); ++ tp->mii.advertising = new1; + } + + if (tp->mii.supports_gmii) { +- u16 gbcr; +- +- gbcr = r8152_mdio_read(tp, MII_CTRL1000); +- tmp1 = gbcr & ~(ADVERTISE_1000FULL | ++ orig = r8152_mdio_read(tp, MII_CTRL1000); ++ new1 = orig & ~(ADVERTISE_1000FULL | + ADVERTISE_1000HALF); + + if (advertising & RTL_ADVERTISED_1000_FULL) { +- tmp1 |= ADVERTISE_1000FULL; ++ new1 |= ADVERTISE_1000FULL; + tp->ups_info.speed_duplex = NWAY_1000M_FULL; + } + +- if (gbcr != tmp1) +- r8152_mdio_write(tp, MII_CTRL1000, tmp1); ++ if (orig != new1) ++ r8152_mdio_write(tp, MII_CTRL1000, new1); ++ } ++ ++ if (tp->support_2500full) { ++ orig = ocp_reg_read(tp, OCP_10GBT_CTRL); ++ new1 = orig & ~MDIO_AN_10GBT_CTRL_ADV2_5G; ++ ++ if (advertising & RTL_ADVERTISED_2500_FULL) { ++ new1 |= MDIO_AN_10GBT_CTRL_ADV2_5G; ++ tp->ups_info.speed_duplex = NWAY_2500M_FULL; ++ } ++ ++ if (orig != new1) ++ ocp_reg_write(tp, OCP_10GBT_CTRL, new1); + } + + bmcr = BMCR_ANENABLE | BMCR_ANRESTART; +@@ -5098,6 +5727,253 @@ static void rtl8153b_down(struct r8152 * + r8153_aldps_en(tp, true); + } + ++static void rtl8153c_change_mtu(struct r8152 *tp) ++{ ++ ocp_write_word(tp, MCU_TYPE_PLA, PLA_RMS, mtu_to_size(tp->netdev->mtu)); ++ ocp_write_byte(tp, MCU_TYPE_PLA, PLA_MTPS, 10 * 1024 / 64); ++ ++ ocp_write_word(tp, MCU_TYPE_PLA, PLA_TXFIFO_CTRL, 512 / 64); ++ ++ /* Adjust the tx fifo free credit full threshold, otherwise ++ * the fifo would be too small to send a jumbo frame packet. ++ */ ++ if (tp->netdev->mtu < 8000) ++ ocp_write_word(tp, MCU_TYPE_PLA, PLA_TXFIFO_FULL, 2048 / 8); ++ else ++ ocp_write_word(tp, MCU_TYPE_PLA, PLA_TXFIFO_FULL, 900 / 8); ++} ++ ++static void rtl8153c_up(struct r8152 *tp) ++{ ++ u32 ocp_data; ++ ++ if (test_bit(RTL8152_UNPLUG, &tp->flags)) ++ return; ++ ++ r8153b_u1u2en(tp, false); ++ r8153_u2p3en(tp, false); ++ r8153_aldps_en(tp, false); ++ ++ rxdy_gated_en(tp, true); ++ r8153_teredo_off(tp); ++ ++ ocp_data = ocp_read_dword(tp, MCU_TYPE_PLA, PLA_RCR); ++ ocp_data &= ~RCR_ACPT_ALL; ++ ocp_write_dword(tp, MCU_TYPE_PLA, PLA_RCR, ocp_data); ++ ++ rtl8152_nic_reset(tp); ++ rtl_reset_bmu(tp); ++ ++ ocp_data = ocp_read_byte(tp, MCU_TYPE_PLA, PLA_OOB_CTRL); ++ ocp_data &= ~NOW_IS_OOB; ++ ocp_write_byte(tp, MCU_TYPE_PLA, PLA_OOB_CTRL, ocp_data); ++ ++ ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_SFF_STS_7); ++ ocp_data &= ~MCU_BORW_EN; ++ ocp_write_word(tp, MCU_TYPE_PLA, PLA_SFF_STS_7, ocp_data); ++ ++ wait_oob_link_list_ready(tp); ++ ++ ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_SFF_STS_7); ++ ocp_data |= RE_INIT_LL; ++ ocp_write_word(tp, MCU_TYPE_PLA, PLA_SFF_STS_7, ocp_data); ++ ++ wait_oob_link_list_ready(tp); ++ ++ rtl_rx_vlan_en(tp, tp->netdev->features & NETIF_F_HW_VLAN_CTAG_RX); ++ ++ rtl8153c_change_mtu(tp); ++ ++ rtl8152_nic_reset(tp); ++ ++ /* rx share fifo credit full threshold */ ++ ocp_write_byte(tp, MCU_TYPE_PLA, PLA_RXFIFO_CTRL0, 0x02); ++ ocp_write_byte(tp, MCU_TYPE_PLA, PLA_RXFIFO_FULL, 0x08); ++ ocp_write_word(tp, MCU_TYPE_PLA, PLA_RXFIFO_CTRL1, RXFIFO_THR2_NORMAL); ++ ocp_write_word(tp, MCU_TYPE_PLA, PLA_RXFIFO_CTRL2, RXFIFO_THR3_NORMAL); ++ ++ ocp_write_dword(tp, MCU_TYPE_USB, USB_RX_BUF_TH, RX_THR_B); ++ ++ ocp_write_byte(tp, MCU_TYPE_PLA, PLA_CRWECR, CRWECR_CONFIG); ++ ++ ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_CONFIG34); ++ ocp_data |= BIT(8); ++ ocp_write_word(tp, MCU_TYPE_PLA, PLA_CONFIG34, ocp_data); ++ ++ ocp_write_byte(tp, MCU_TYPE_PLA, PLA_CRWECR, CRWECR_NORAML); ++ ++ ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL3); ++ ocp_data &= ~PLA_MCU_SPDWN_EN; ++ ocp_write_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL3, ocp_data); ++ ++ r8153_aldps_en(tp, true); ++ r8153b_u1u2en(tp, true); ++} ++ ++static inline u32 fc_pause_on_auto(struct r8152 *tp) ++{ ++ return (ALIGN(mtu_to_size(tp->netdev->mtu), 1024) + 6 * 1024); ++} ++ ++static inline u32 fc_pause_off_auto(struct r8152 *tp) ++{ ++ return (ALIGN(mtu_to_size(tp->netdev->mtu), 1024) + 14 * 1024); ++} ++ ++static void r8156_fc_parameter(struct r8152 *tp) ++{ ++ u32 pause_on = tp->fc_pause_on ? tp->fc_pause_on : fc_pause_on_auto(tp); ++ u32 pause_off = tp->fc_pause_off ? tp->fc_pause_off : fc_pause_off_auto(tp); ++ ++ switch (tp->version) { ++ case RTL_VER_10: ++ case RTL_VER_11: ++ ocp_write_word(tp, MCU_TYPE_PLA, PLA_RX_FIFO_FULL, pause_on / 8); ++ ocp_write_word(tp, MCU_TYPE_PLA, PLA_RX_FIFO_EMPTY, pause_off / 8); ++ break; ++ case RTL_VER_12: ++ case RTL_VER_13: ++ case RTL_VER_15: ++ ocp_write_word(tp, MCU_TYPE_PLA, PLA_RX_FIFO_FULL, pause_on / 16); ++ ocp_write_word(tp, MCU_TYPE_PLA, PLA_RX_FIFO_EMPTY, pause_off / 16); ++ break; ++ default: ++ break; ++ } ++} ++ ++static void rtl8156_change_mtu(struct r8152 *tp) ++{ ++ u32 rx_max_size = mtu_to_size(tp->netdev->mtu); ++ ++ ocp_write_word(tp, MCU_TYPE_PLA, PLA_RMS, rx_max_size); ++ ocp_write_byte(tp, MCU_TYPE_PLA, PLA_MTPS, MTPS_JUMBO); ++ r8156_fc_parameter(tp); ++ ++ /* TX share fifo free credit full threshold */ ++ ocp_write_word(tp, MCU_TYPE_PLA, PLA_TXFIFO_CTRL, 512 / 64); ++ ocp_write_word(tp, MCU_TYPE_PLA, PLA_TXFIFO_FULL, ++ ALIGN(rx_max_size + sizeof(struct tx_desc), 1024) / 16); ++} ++ ++static void rtl8156_up(struct r8152 *tp) ++{ ++ u32 ocp_data; ++ ++ if (test_bit(RTL8152_UNPLUG, &tp->flags)) ++ return; ++ ++ r8153b_u1u2en(tp, false); ++ r8153_u2p3en(tp, false); ++ r8153_aldps_en(tp, false); ++ ++ rxdy_gated_en(tp, true); ++ r8153_teredo_off(tp); ++ ++ ocp_data = ocp_read_dword(tp, MCU_TYPE_PLA, PLA_RCR); ++ ocp_data &= ~RCR_ACPT_ALL; ++ ocp_write_dword(tp, MCU_TYPE_PLA, PLA_RCR, ocp_data); ++ ++ rtl8152_nic_reset(tp); ++ rtl_reset_bmu(tp); ++ ++ ocp_data = ocp_read_byte(tp, MCU_TYPE_PLA, PLA_OOB_CTRL); ++ ocp_data &= ~NOW_IS_OOB; ++ ocp_write_byte(tp, MCU_TYPE_PLA, PLA_OOB_CTRL, ocp_data); ++ ++ ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_SFF_STS_7); ++ ocp_data &= ~MCU_BORW_EN; ++ ocp_write_word(tp, MCU_TYPE_PLA, PLA_SFF_STS_7, ocp_data); ++ ++ rtl_rx_vlan_en(tp, tp->netdev->features & NETIF_F_HW_VLAN_CTAG_RX); ++ ++ rtl8156_change_mtu(tp); ++ ++ switch (tp->version) { ++ case RTL_TEST_01: ++ case RTL_VER_10: ++ case RTL_VER_11: ++ ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_BMU_CONFIG); ++ ocp_data |= ACT_ODMA; ++ ocp_write_word(tp, MCU_TYPE_USB, USB_BMU_CONFIG, ocp_data); ++ break; ++ default: ++ break; ++ } ++ ++ /* share FIFO settings */ ++ ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_RXFIFO_FULL); ++ ocp_data &= ~RXFIFO_FULL_MASK; ++ ocp_data |= 0x08; ++ ocp_write_word(tp, MCU_TYPE_PLA, PLA_RXFIFO_FULL, ocp_data); ++ ++ ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL3); ++ ocp_data &= ~PLA_MCU_SPDWN_EN; ++ ocp_write_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL3, ocp_data); ++ ++ ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_SPEED_OPTION); ++ ocp_data &= ~(RG_PWRDN_EN | ALL_SPEED_OFF); ++ ocp_write_word(tp, MCU_TYPE_USB, USB_SPEED_OPTION, ocp_data); ++ ++ ocp_write_dword(tp, MCU_TYPE_USB, USB_RX_BUF_TH, 0x00600400); ++ ++ if (tp->saved_wolopts != __rtl_get_wol(tp)) { ++ netif_warn(tp, ifup, tp->netdev, "wol setting is changed\n"); ++ __rtl_set_wol(tp, tp->saved_wolopts); ++ } ++ ++ r8153_aldps_en(tp, true); ++ r8153_u2p3en(tp, true); ++ ++ if (tp->udev->speed >= USB_SPEED_SUPER) ++ r8153b_u1u2en(tp, true); ++} ++ ++static void rtl8156_down(struct r8152 *tp) ++{ ++ u32 ocp_data; ++ ++ if (test_bit(RTL8152_UNPLUG, &tp->flags)) { ++ rtl_drop_queued_tx(tp); ++ return; ++ } ++ ++ ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL3); ++ ocp_data |= PLA_MCU_SPDWN_EN; ++ ocp_write_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL3, ocp_data); ++ ++ r8153b_u1u2en(tp, false); ++ r8153_u2p3en(tp, false); ++ r8153b_power_cut_en(tp, false); ++ r8153_aldps_en(tp, false); ++ ++ ocp_data = ocp_read_byte(tp, MCU_TYPE_PLA, PLA_OOB_CTRL); ++ ocp_data &= ~NOW_IS_OOB; ++ ocp_write_byte(tp, MCU_TYPE_PLA, PLA_OOB_CTRL, ocp_data); ++ ++ rtl_disable(tp); ++ rtl_reset_bmu(tp); ++ ++ /* Clear teredo wake event. bit[15:8] is the teredo wakeup ++ * type. Set it to zero. bits[7:0] are the W1C bits about ++ * the events. Set them to all 1 to clear them. ++ */ ++ ocp_write_word(tp, MCU_TYPE_PLA, PLA_TEREDO_WAKE_BASE, 0x00ff); ++ ++ ocp_data = ocp_read_byte(tp, MCU_TYPE_PLA, PLA_OOB_CTRL); ++ ocp_data |= NOW_IS_OOB; ++ ocp_write_byte(tp, MCU_TYPE_PLA, PLA_OOB_CTRL, ocp_data); ++ ++ rtl_rx_vlan_en(tp, true); ++ rxdy_gated_en(tp, false); ++ ++ ocp_data = ocp_read_dword(tp, MCU_TYPE_PLA, PLA_RCR); ++ ocp_data |= RCR_APM | RCR_AM | RCR_AB; ++ ocp_write_dword(tp, MCU_TYPE_PLA, PLA_RCR, ocp_data); ++ ++ r8153_aldps_en(tp, true); ++} ++ + static bool rtl8152_in_nway(struct r8152 *tp) + { + u16 nway_state; +@@ -5128,7 +6004,7 @@ static void set_carrier(struct r8152 *tp + { + struct net_device *netdev = tp->netdev; + struct napi_struct *napi = &tp->napi; +- u8 speed; ++ u16 speed; + + speed = rtl8152_get_speed(tp); + +@@ -5141,7 +6017,7 @@ static void set_carrier(struct r8152 *tp + rtl_start_rx(tp); + clear_bit(RTL8152_SET_RX_MODE, &tp->flags); + _rtl8152_set_rx_mode(netdev); +- napi_enable(&tp->napi); ++ napi_enable(napi); + netif_wake_queue(netdev); + netif_info(tp, link, netdev, "carrier on\n"); + } else if (netif_queue_stopped(netdev) && +@@ -5521,14 +6397,9 @@ static void r8153_init(struct r8152 *tp) + + ocp_write_word(tp, MCU_TYPE_USB, USB_CONNECT_TIMER, 0x0001); + +- /* MAC clock speed down */ +- ocp_write_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL, 0); +- ocp_write_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL2, 0); +- ocp_write_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL3, 0); +- ocp_write_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL4, 0); +- + r8153_power_cut_en(tp, false); + rtl_runtime_suspend_enable(tp, false); ++ r8153_mac_clk_speed_down(tp, false); + r8153_u1u2en(tp, true); + usb_enable_lpm(tp->udev); + +@@ -5621,9 +6492,7 @@ static void r8153b_init(struct r8152 *tp + usb_enable_lpm(tp->udev); + + /* MAC clock speed down */ +- ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL2); +- ocp_data |= MAC_CLK_SPDWN_EN; +- ocp_write_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL2, ocp_data); ++ r8153_mac_clk_speed_down(tp, true); + + ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL3); + ocp_data &= ~PLA_MCU_SPDWN_EN; +@@ -5652,6 +6521,1069 @@ static void r8153b_init(struct r8152 *tp + r8152_led_configuration(tp); + } + ++static void r8153c_init(struct r8152 *tp) ++{ ++ u32 ocp_data; ++ u16 data; ++ int i; ++ ++ if (test_bit(RTL8152_UNPLUG, &tp->flags)) ++ return; ++ ++ r8153b_u1u2en(tp, false); ++ ++ /* Disable spi_en */ ++ ocp_write_byte(tp, MCU_TYPE_PLA, PLA_CRWECR, CRWECR_CONFIG); ++ ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_CONFIG5); ++ ocp_data &= ~BIT(3); ++ ocp_write_word(tp, MCU_TYPE_PLA, PLA_CONFIG5, ocp_data); ++ ocp_data = ocp_read_word(tp, MCU_TYPE_USB, 0xcbf0); ++ ocp_data |= BIT(1); ++ ocp_write_word(tp, MCU_TYPE_USB, 0xcbf0, ocp_data); ++ ++ for (i = 0; i < 500; i++) { ++ if (ocp_read_word(tp, MCU_TYPE_PLA, PLA_BOOT_CTRL) & ++ AUTOLOAD_DONE) ++ break; ++ ++ msleep(20); ++ if (test_bit(RTL8152_UNPLUG, &tp->flags)) ++ return; ++ } ++ ++ data = r8153_phy_status(tp, 0); ++ ++ data = r8152_mdio_read(tp, MII_BMCR); ++ if (data & BMCR_PDOWN) { ++ data &= ~BMCR_PDOWN; ++ r8152_mdio_write(tp, MII_BMCR, data); ++ } ++ ++ data = r8153_phy_status(tp, PHY_STAT_LAN_ON); ++ ++ r8153_u2p3en(tp, false); ++ ++ /* MSC timer = 0xfff * 8ms = 32760 ms */ ++ ocp_write_word(tp, MCU_TYPE_USB, USB_MSC_TIMER, 0x0fff); ++ ++ r8153b_power_cut_en(tp, false); ++ r8153c_ups_en(tp, false); ++ r8153_queue_wake(tp, false); ++ rtl_runtime_suspend_enable(tp, false); ++ ++ ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_EXTRA_STATUS); ++ if (rtl8152_get_speed(tp) & LINK_STATUS) ++ ocp_data |= CUR_LINK_OK; ++ else ++ ocp_data &= ~CUR_LINK_OK; ++ ++ ocp_data |= POLL_LINK_CHG; ++ ocp_write_word(tp, MCU_TYPE_PLA, PLA_EXTRA_STATUS, ocp_data); ++ ++ r8153b_u1u2en(tp, true); ++ ++ usb_enable_lpm(tp->udev); ++ ++ /* MAC clock speed down */ ++ r8153_mac_clk_speed_down(tp, true); ++ ++ ocp_data = ocp_read_byte(tp, MCU_TYPE_USB, USB_MISC_2); ++ ocp_data &= ~BIT(7); ++ ocp_write_byte(tp, MCU_TYPE_USB, USB_MISC_2, ocp_data); ++ ++ set_bit(GREEN_ETHERNET, &tp->flags); ++ ++ /* rx aggregation */ ++ ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_USB_CTRL); ++ ocp_data &= ~(RX_AGG_DISABLE | RX_ZERO_EN); ++ ocp_write_word(tp, MCU_TYPE_USB, USB_USB_CTRL, ocp_data); ++ ++ rtl_tally_reset(tp); ++ ++ tp->coalesce = 15000; /* 15 us */ ++} ++ ++static void r8156_hw_phy_cfg(struct r8152 *tp) ++{ ++ u32 ocp_data; ++ u16 data; ++ ++ ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_MISC_0); ++ if (ocp_data & PCUT_STATUS) { ++ ocp_data &= ~PCUT_STATUS; ++ ocp_write_word(tp, MCU_TYPE_USB, USB_MISC_0, ocp_data); ++ } ++ ++ data = r8153_phy_status(tp, 0); ++ switch (data) { ++ case PHY_STAT_EXT_INIT: ++ rtl8152_apply_firmware(tp, true); ++ ++ data = ocp_reg_read(tp, 0xa468); ++ data &= ~(BIT(3) | BIT(1)); ++ ocp_reg_write(tp, 0xa468, data); ++ break; ++ case PHY_STAT_LAN_ON: ++ case PHY_STAT_PWRDN: ++ default: ++ rtl8152_apply_firmware(tp, false); ++ break; ++ } ++ ++ /* disable ALDPS before updating the PHY parameters */ ++ r8153_aldps_en(tp, false); ++ ++ /* disable EEE before updating the PHY parameters */ ++ rtl_eee_enable(tp, false); ++ ++ data = r8153_phy_status(tp, PHY_STAT_LAN_ON); ++ WARN_ON_ONCE(data != PHY_STAT_LAN_ON); ++ ++ ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_PHY_PWR); ++ ocp_data |= PFM_PWM_SWITCH; ++ ocp_write_word(tp, MCU_TYPE_PLA, PLA_PHY_PWR, ocp_data); ++ ++ switch (tp->version) { ++ case RTL_VER_10: ++ data = ocp_reg_read(tp, 0xad40); ++ data &= ~0x3ff; ++ data |= BIT(7) | BIT(2); ++ ocp_reg_write(tp, 0xad40, data); ++ ++ data = ocp_reg_read(tp, 0xad4e); ++ data |= BIT(4); ++ ocp_reg_write(tp, 0xad4e, data); ++ data = ocp_reg_read(tp, 0xad16); ++ data &= ~0x3ff; ++ data |= 0x6; ++ ocp_reg_write(tp, 0xad16, data); ++ data = ocp_reg_read(tp, 0xad32); ++ data &= ~0x3f; ++ data |= 6; ++ ocp_reg_write(tp, 0xad32, data); ++ data = ocp_reg_read(tp, 0xac08); ++ data &= ~(BIT(12) | BIT(8)); ++ ocp_reg_write(tp, 0xac08, data); ++ data = ocp_reg_read(tp, 0xac8a); ++ data |= BIT(12) | BIT(13) | BIT(14); ++ data &= ~BIT(15); ++ ocp_reg_write(tp, 0xac8a, data); ++ data = ocp_reg_read(tp, 0xad18); ++ data |= BIT(10); ++ ocp_reg_write(tp, 0xad18, data); ++ data = ocp_reg_read(tp, 0xad1a); ++ data |= 0x3ff; ++ ocp_reg_write(tp, 0xad1a, data); ++ data = ocp_reg_read(tp, 0xad1c); ++ data |= 0x3ff; ++ ocp_reg_write(tp, 0xad1c, data); ++ ++ data = sram_read(tp, 0x80ea); ++ data &= ~0xff00; ++ data |= 0xc400; ++ sram_write(tp, 0x80ea, data); ++ data = sram_read(tp, 0x80eb); ++ data &= ~0x0700; ++ data |= 0x0300; ++ sram_write(tp, 0x80eb, data); ++ data = sram_read(tp, 0x80f8); ++ data &= ~0xff00; ++ data |= 0x1c00; ++ sram_write(tp, 0x80f8, data); ++ data = sram_read(tp, 0x80f1); ++ data &= ~0xff00; ++ data |= 0x3000; ++ sram_write(tp, 0x80f1, data); ++ ++ data = sram_read(tp, 0x80fe); ++ data &= ~0xff00; ++ data |= 0xa500; ++ sram_write(tp, 0x80fe, data); ++ data = sram_read(tp, 0x8102); ++ data &= ~0xff00; ++ data |= 0x5000; ++ sram_write(tp, 0x8102, data); ++ data = sram_read(tp, 0x8015); ++ data &= ~0xff00; ++ data |= 0x3300; ++ sram_write(tp, 0x8015, data); ++ data = sram_read(tp, 0x8100); ++ data &= ~0xff00; ++ data |= 0x7000; ++ sram_write(tp, 0x8100, data); ++ data = sram_read(tp, 0x8014); ++ data &= ~0xff00; ++ data |= 0xf000; ++ sram_write(tp, 0x8014, data); ++ data = sram_read(tp, 0x8016); ++ data &= ~0xff00; ++ data |= 0x6500; ++ sram_write(tp, 0x8016, data); ++ data = sram_read(tp, 0x80dc); ++ data &= ~0xff00; ++ data |= 0xed00; ++ sram_write(tp, 0x80dc, data); ++ data = sram_read(tp, 0x80df); ++ data |= BIT(8); ++ sram_write(tp, 0x80df, data); ++ data = sram_read(tp, 0x80e1); ++ data &= ~BIT(8); ++ sram_write(tp, 0x80e1, data); ++ ++ data = ocp_reg_read(tp, 0xbf06); ++ data &= ~0x003f; ++ data |= 0x0038; ++ ocp_reg_write(tp, 0xbf06, data); ++ ++ sram_write(tp, 0x819f, 0xddb6); ++ ++ ocp_reg_write(tp, 0xbc34, 0x5555); ++ data = ocp_reg_read(tp, 0xbf0a); ++ data &= ~0x0e00; ++ data |= 0x0a00; ++ ocp_reg_write(tp, 0xbf0a, data); ++ ++ data = ocp_reg_read(tp, 0xbd2c); ++ data &= ~BIT(13); ++ ocp_reg_write(tp, 0xbd2c, data); ++ break; ++ case RTL_VER_11: ++ data = ocp_reg_read(tp, 0xad16); ++ data |= 0x3ff; ++ ocp_reg_write(tp, 0xad16, data); ++ data = ocp_reg_read(tp, 0xad32); ++ data &= ~0x3f; ++ data |= 6; ++ ocp_reg_write(tp, 0xad32, data); ++ data = ocp_reg_read(tp, 0xac08); ++ data &= ~(BIT(12) | BIT(8)); ++ ocp_reg_write(tp, 0xac08, data); ++ data = ocp_reg_read(tp, 0xacc0); ++ data &= ~0x3; ++ data |= BIT(1); ++ ocp_reg_write(tp, 0xacc0, data); ++ data = ocp_reg_read(tp, 0xad40); ++ data &= ~0xe7; ++ data |= BIT(6) | BIT(2); ++ ocp_reg_write(tp, 0xad40, data); ++ data = ocp_reg_read(tp, 0xac14); ++ data &= ~BIT(7); ++ ocp_reg_write(tp, 0xac14, data); ++ data = ocp_reg_read(tp, 0xac80); ++ data &= ~(BIT(8) | BIT(9)); ++ ocp_reg_write(tp, 0xac80, data); ++ data = ocp_reg_read(tp, 0xac5e); ++ data &= ~0x7; ++ data |= BIT(1); ++ ocp_reg_write(tp, 0xac5e, data); ++ ocp_reg_write(tp, 0xad4c, 0x00a8); ++ ocp_reg_write(tp, 0xac5c, 0x01ff); ++ data = ocp_reg_read(tp, 0xac8a); ++ data &= ~0xf0; ++ data |= BIT(4) | BIT(5); ++ ocp_reg_write(tp, 0xac8a, data); ++ ocp_reg_write(tp, 0xb87c, 0x8157); ++ data = ocp_reg_read(tp, 0xb87e); ++ data &= ~0xff00; ++ data |= 0x0500; ++ ocp_reg_write(tp, 0xb87e, data); ++ ocp_reg_write(tp, 0xb87c, 0x8159); ++ data = ocp_reg_read(tp, 0xb87e); ++ data &= ~0xff00; ++ data |= 0x0700; ++ ocp_reg_write(tp, 0xb87e, data); ++ ++ /* AAGC */ ++ ocp_reg_write(tp, 0xb87c, 0x80a2); ++ ocp_reg_write(tp, 0xb87e, 0x0153); ++ ocp_reg_write(tp, 0xb87c, 0x809c); ++ ocp_reg_write(tp, 0xb87e, 0x0153); ++ ++ /* EEE parameter */ ++ ocp_write_word(tp, MCU_TYPE_PLA, PLA_EEE_TXTWSYS_2P5G, 0x0056); ++ ++ ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_USB_CFG); ++ ocp_data |= EN_XG_LIP | EN_G_LIP; ++ ocp_write_word(tp, MCU_TYPE_PLA, PLA_USB_CFG, ocp_data); ++ ++ sram_write(tp, 0x8257, 0x020f); /* XG PLL */ ++ sram_write(tp, 0x80ea, 0x7843); /* GIGA Master */ ++ ++ if (rtl_phy_patch_request(tp, true, true)) ++ return; ++ ++ /* Advance EEE */ ++ ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL4); ++ ocp_data |= EEE_SPDWN_EN; ++ ocp_write_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL4, ocp_data); ++ ++ data = ocp_reg_read(tp, OCP_DOWN_SPEED); ++ data &= ~(EN_EEE_100 | EN_EEE_1000); ++ data |= EN_10M_CLKDIV; ++ ocp_reg_write(tp, OCP_DOWN_SPEED, data); ++ tp->ups_info._10m_ckdiv = true; ++ tp->ups_info.eee_plloff_100 = false; ++ tp->ups_info.eee_plloff_giga = false; ++ ++ data = ocp_reg_read(tp, OCP_POWER_CFG); ++ data &= ~EEE_CLKDIV_EN; ++ ocp_reg_write(tp, OCP_POWER_CFG, data); ++ tp->ups_info.eee_ckdiv = false; ++ ++ ocp_reg_write(tp, OCP_SYSCLK_CFG, 0); ++ ocp_reg_write(tp, OCP_SYSCLK_CFG, sysclk_div_expo(5)); ++ tp->ups_info._250m_ckdiv = false; ++ ++ rtl_phy_patch_request(tp, false, true); ++ ++ /* enable ADC Ibias Cal */ ++ data = ocp_reg_read(tp, 0xd068); ++ data |= BIT(13); ++ ocp_reg_write(tp, 0xd068, data); ++ ++ /* enable Thermal Sensor */ ++ data = sram_read(tp, 0x81a2); ++ data &= ~BIT(8); ++ sram_write(tp, 0x81a2, data); ++ data = ocp_reg_read(tp, 0xb54c); ++ data &= ~0xff00; ++ data |= 0xdb00; ++ ocp_reg_write(tp, 0xb54c, data); ++ ++ /* Nway 2.5G Lite */ ++ data = ocp_reg_read(tp, 0xa454); ++ data &= ~BIT(0); ++ ocp_reg_write(tp, 0xa454, data); ++ ++ /* CS DSP solution */ ++ data = ocp_reg_read(tp, OCP_10GBT_CTRL); ++ data |= RTL_ADV2_5G_F_R; ++ ocp_reg_write(tp, OCP_10GBT_CTRL, data); ++ data = ocp_reg_read(tp, 0xad4e); ++ data &= ~BIT(4); ++ ocp_reg_write(tp, 0xad4e, data); ++ data = ocp_reg_read(tp, 0xa86a); ++ data &= ~BIT(0); ++ ocp_reg_write(tp, 0xa86a, data); ++ ++ /* MDI SWAP */ ++ if ((ocp_read_word(tp, MCU_TYPE_USB, USB_UPS_CFG) & MID_REVERSE) && ++ (ocp_reg_read(tp, 0xd068) & BIT(1))) { ++ u16 swap_a, swap_b; ++ ++ data = ocp_reg_read(tp, 0xd068); ++ data &= ~0x1f; ++ data |= 0x1; /* p0 */ ++ ocp_reg_write(tp, 0xd068, data); ++ swap_a = ocp_reg_read(tp, 0xd06a); ++ data &= ~0x18; ++ data |= 0x18; /* p3 */ ++ ocp_reg_write(tp, 0xd068, data); ++ swap_b = ocp_reg_read(tp, 0xd06a); ++ data &= ~0x18; /* p0 */ ++ ocp_reg_write(tp, 0xd068, data); ++ ocp_reg_write(tp, 0xd06a, ++ (swap_a & ~0x7ff) | (swap_b & 0x7ff)); ++ data |= 0x18; /* p3 */ ++ ocp_reg_write(tp, 0xd068, data); ++ ocp_reg_write(tp, 0xd06a, ++ (swap_b & ~0x7ff) | (swap_a & 0x7ff)); ++ data &= ~0x18; ++ data |= 0x08; /* p1 */ ++ ocp_reg_write(tp, 0xd068, data); ++ swap_a = ocp_reg_read(tp, 0xd06a); ++ data &= ~0x18; ++ data |= 0x10; /* p2 */ ++ ocp_reg_write(tp, 0xd068, data); ++ swap_b = ocp_reg_read(tp, 0xd06a); ++ data &= ~0x18; ++ data |= 0x08; /* p1 */ ++ ocp_reg_write(tp, 0xd068, data); ++ ocp_reg_write(tp, 0xd06a, ++ (swap_a & ~0x7ff) | (swap_b & 0x7ff)); ++ data &= ~0x18; ++ data |= 0x10; /* p2 */ ++ ocp_reg_write(tp, 0xd068, data); ++ ocp_reg_write(tp, 0xd06a, ++ (swap_b & ~0x7ff) | (swap_a & 0x7ff)); ++ swap_a = ocp_reg_read(tp, 0xbd5a); ++ swap_b = ocp_reg_read(tp, 0xbd5c); ++ ocp_reg_write(tp, 0xbd5a, (swap_a & ~0x1f1f) | ++ ((swap_b & 0x1f) << 8) | ++ ((swap_b >> 8) & 0x1f)); ++ ocp_reg_write(tp, 0xbd5c, (swap_b & ~0x1f1f) | ++ ((swap_a & 0x1f) << 8) | ++ ((swap_a >> 8) & 0x1f)); ++ swap_a = ocp_reg_read(tp, 0xbc18); ++ swap_b = ocp_reg_read(tp, 0xbc1a); ++ ocp_reg_write(tp, 0xbc18, (swap_a & ~0x1f1f) | ++ ((swap_b & 0x1f) << 8) | ++ ((swap_b >> 8) & 0x1f)); ++ ocp_reg_write(tp, 0xbc1a, (swap_b & ~0x1f1f) | ++ ((swap_a & 0x1f) << 8) | ++ ((swap_a >> 8) & 0x1f)); ++ } ++ break; ++ default: ++ break; ++ } ++ ++ rtl_green_en(tp, test_bit(GREEN_ETHERNET, &tp->flags)); ++ ++ data = ocp_reg_read(tp, 0xa428); ++ data &= ~BIT(9); ++ ocp_reg_write(tp, 0xa428, data); ++ data = ocp_reg_read(tp, 0xa5ea); ++ data &= ~BIT(0); ++ ocp_reg_write(tp, 0xa5ea, data); ++ tp->ups_info.lite_mode = 0; ++ ++ if (tp->eee_en) ++ rtl_eee_enable(tp, true); ++ ++ r8153_aldps_en(tp, true); ++ r8152b_enable_fc(tp); ++ r8153_u2p3en(tp, true); ++ ++ set_bit(PHY_RESET, &tp->flags); ++} ++ ++static void r8156b_hw_phy_cfg(struct r8152 *tp) ++{ ++ u32 ocp_data; ++ u16 data; ++ ++ switch (tp->version) { ++ case RTL_VER_12: ++ ocp_reg_write(tp, 0xbf86, 0x9000); ++ data = ocp_reg_read(tp, 0xc402); ++ data |= BIT(10); ++ ocp_reg_write(tp, 0xc402, data); ++ data &= ~BIT(10); ++ ocp_reg_write(tp, 0xc402, data); ++ ocp_reg_write(tp, 0xbd86, 0x1010); ++ ocp_reg_write(tp, 0xbd88, 0x1010); ++ data = ocp_reg_read(tp, 0xbd4e); ++ data &= ~(BIT(10) | BIT(11)); ++ data |= BIT(11); ++ ocp_reg_write(tp, 0xbd4e, data); ++ data = ocp_reg_read(tp, 0xbf46); ++ data &= ~0xf00; ++ data |= 0x700; ++ ocp_reg_write(tp, 0xbf46, data); ++ break; ++ case RTL_VER_13: ++ case RTL_VER_15: ++ r8156b_wait_loading_flash(tp); ++ break; ++ default: ++ break; ++ } ++ ++ ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_MISC_0); ++ if (ocp_data & PCUT_STATUS) { ++ ocp_data &= ~PCUT_STATUS; ++ ocp_write_word(tp, MCU_TYPE_USB, USB_MISC_0, ocp_data); ++ } ++ ++ data = r8153_phy_status(tp, 0); ++ switch (data) { ++ case PHY_STAT_EXT_INIT: ++ rtl8152_apply_firmware(tp, true); ++ ++ data = ocp_reg_read(tp, 0xa466); ++ data &= ~BIT(0); ++ ocp_reg_write(tp, 0xa466, data); ++ ++ data = ocp_reg_read(tp, 0xa468); ++ data &= ~(BIT(3) | BIT(1)); ++ ocp_reg_write(tp, 0xa468, data); ++ break; ++ case PHY_STAT_LAN_ON: ++ case PHY_STAT_PWRDN: ++ default: ++ rtl8152_apply_firmware(tp, false); ++ break; ++ } ++ ++ data = r8152_mdio_read(tp, MII_BMCR); ++ if (data & BMCR_PDOWN) { ++ data &= ~BMCR_PDOWN; ++ r8152_mdio_write(tp, MII_BMCR, data); ++ } ++ ++ /* disable ALDPS before updating the PHY parameters */ ++ r8153_aldps_en(tp, false); ++ ++ /* disable EEE before updating the PHY parameters */ ++ rtl_eee_enable(tp, false); ++ ++ data = r8153_phy_status(tp, PHY_STAT_LAN_ON); ++ WARN_ON_ONCE(data != PHY_STAT_LAN_ON); ++ ++ ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_PHY_PWR); ++ ocp_data |= PFM_PWM_SWITCH; ++ ocp_write_word(tp, MCU_TYPE_PLA, PLA_PHY_PWR, ocp_data); ++ ++ switch (tp->version) { ++ case RTL_VER_12: ++ data = ocp_reg_read(tp, 0xbc08); ++ data |= BIT(3) | BIT(2); ++ ocp_reg_write(tp, 0xbc08, data); ++ ++ data = sram_read(tp, 0x8fff); ++ data &= ~0xff00; ++ data |= 0x0400; ++ sram_write(tp, 0x8fff, data); ++ ++ data = ocp_reg_read(tp, 0xacda); ++ data |= 0xff00; ++ ocp_reg_write(tp, 0xacda, data); ++ data = ocp_reg_read(tp, 0xacde); ++ data |= 0xf000; ++ ocp_reg_write(tp, 0xacde, data); ++ ocp_reg_write(tp, 0xac8c, 0x0ffc); ++ ocp_reg_write(tp, 0xac46, 0xb7b4); ++ ocp_reg_write(tp, 0xac50, 0x0fbc); ++ ocp_reg_write(tp, 0xac3c, 0x9240); ++ ocp_reg_write(tp, 0xac4e, 0x0db4); ++ ocp_reg_write(tp, 0xacc6, 0x0707); ++ ocp_reg_write(tp, 0xacc8, 0xa0d3); ++ ocp_reg_write(tp, 0xad08, 0x0007); ++ ++ ocp_reg_write(tp, 0xb87c, 0x8560); ++ ocp_reg_write(tp, 0xb87e, 0x19cc); ++ ocp_reg_write(tp, 0xb87c, 0x8562); ++ ocp_reg_write(tp, 0xb87e, 0x19cc); ++ ocp_reg_write(tp, 0xb87c, 0x8564); ++ ocp_reg_write(tp, 0xb87e, 0x19cc); ++ ocp_reg_write(tp, 0xb87c, 0x8566); ++ ocp_reg_write(tp, 0xb87e, 0x147d); ++ ocp_reg_write(tp, 0xb87c, 0x8568); ++ ocp_reg_write(tp, 0xb87e, 0x147d); ++ ocp_reg_write(tp, 0xb87c, 0x856a); ++ ocp_reg_write(tp, 0xb87e, 0x147d); ++ ocp_reg_write(tp, 0xb87c, 0x8ffe); ++ ocp_reg_write(tp, 0xb87e, 0x0907); ++ ocp_reg_write(tp, 0xb87c, 0x80d6); ++ ocp_reg_write(tp, 0xb87e, 0x2801); ++ ocp_reg_write(tp, 0xb87c, 0x80f2); ++ ocp_reg_write(tp, 0xb87e, 0x2801); ++ ocp_reg_write(tp, 0xb87c, 0x80f4); ++ ocp_reg_write(tp, 0xb87e, 0x6077); ++ ocp_reg_write(tp, 0xb506, 0x01e7); ++ ++ ocp_reg_write(tp, 0xb87c, 0x8013); ++ ocp_reg_write(tp, 0xb87e, 0x0700); ++ ocp_reg_write(tp, 0xb87c, 0x8fb9); ++ ocp_reg_write(tp, 0xb87e, 0x2801); ++ ocp_reg_write(tp, 0xb87c, 0x8fba); ++ ocp_reg_write(tp, 0xb87e, 0x0100); ++ ocp_reg_write(tp, 0xb87c, 0x8fbc); ++ ocp_reg_write(tp, 0xb87e, 0x1900); ++ ocp_reg_write(tp, 0xb87c, 0x8fbe); ++ ocp_reg_write(tp, 0xb87e, 0xe100); ++ ocp_reg_write(tp, 0xb87c, 0x8fc0); ++ ocp_reg_write(tp, 0xb87e, 0x0800); ++ ocp_reg_write(tp, 0xb87c, 0x8fc2); ++ ocp_reg_write(tp, 0xb87e, 0xe500); ++ ocp_reg_write(tp, 0xb87c, 0x8fc4); ++ ocp_reg_write(tp, 0xb87e, 0x0f00); ++ ocp_reg_write(tp, 0xb87c, 0x8fc6); ++ ocp_reg_write(tp, 0xb87e, 0xf100); ++ ocp_reg_write(tp, 0xb87c, 0x8fc8); ++ ocp_reg_write(tp, 0xb87e, 0x0400); ++ ocp_reg_write(tp, 0xb87c, 0x8fca); ++ ocp_reg_write(tp, 0xb87e, 0xf300); ++ ocp_reg_write(tp, 0xb87c, 0x8fcc); ++ ocp_reg_write(tp, 0xb87e, 0xfd00); ++ ocp_reg_write(tp, 0xb87c, 0x8fce); ++ ocp_reg_write(tp, 0xb87e, 0xff00); ++ ocp_reg_write(tp, 0xb87c, 0x8fd0); ++ ocp_reg_write(tp, 0xb87e, 0xfb00); ++ ocp_reg_write(tp, 0xb87c, 0x8fd2); ++ ocp_reg_write(tp, 0xb87e, 0x0100); ++ ocp_reg_write(tp, 0xb87c, 0x8fd4); ++ ocp_reg_write(tp, 0xb87e, 0xf400); ++ ocp_reg_write(tp, 0xb87c, 0x8fd6); ++ ocp_reg_write(tp, 0xb87e, 0xff00); ++ ocp_reg_write(tp, 0xb87c, 0x8fd8); ++ ocp_reg_write(tp, 0xb87e, 0xf600); ++ ++ ocp_data = ocp_read_byte(tp, MCU_TYPE_PLA, PLA_USB_CFG); ++ ocp_data |= EN_XG_LIP | EN_G_LIP; ++ ocp_write_byte(tp, MCU_TYPE_PLA, PLA_USB_CFG, ocp_data); ++ ocp_reg_write(tp, 0xb87c, 0x813d); ++ ocp_reg_write(tp, 0xb87e, 0x390e); ++ ocp_reg_write(tp, 0xb87c, 0x814f); ++ ocp_reg_write(tp, 0xb87e, 0x790e); ++ ocp_reg_write(tp, 0xb87c, 0x80b0); ++ ocp_reg_write(tp, 0xb87e, 0x0f31); ++ data = ocp_reg_read(tp, 0xbf4c); ++ data |= BIT(1); ++ ocp_reg_write(tp, 0xbf4c, data); ++ data = ocp_reg_read(tp, 0xbcca); ++ data |= BIT(9) | BIT(8); ++ ocp_reg_write(tp, 0xbcca, data); ++ ocp_reg_write(tp, 0xb87c, 0x8141); ++ ocp_reg_write(tp, 0xb87e, 0x320e); ++ ocp_reg_write(tp, 0xb87c, 0x8153); ++ ocp_reg_write(tp, 0xb87e, 0x720e); ++ ocp_reg_write(tp, 0xb87c, 0x8529); ++ ocp_reg_write(tp, 0xb87e, 0x050e); ++ data = ocp_reg_read(tp, OCP_EEE_CFG); ++ data &= ~CTAP_SHORT_EN; ++ ocp_reg_write(tp, OCP_EEE_CFG, data); ++ ++ sram_write(tp, 0x816c, 0xc4a0); ++ sram_write(tp, 0x8170, 0xc4a0); ++ sram_write(tp, 0x8174, 0x04a0); ++ sram_write(tp, 0x8178, 0x04a0); ++ sram_write(tp, 0x817c, 0x0719); ++ sram_write(tp, 0x8ff4, 0x0400); ++ sram_write(tp, 0x8ff1, 0x0404); ++ ++ ocp_reg_write(tp, 0xbf4a, 0x001b); ++ ocp_reg_write(tp, 0xb87c, 0x8033); ++ ocp_reg_write(tp, 0xb87e, 0x7c13); ++ ocp_reg_write(tp, 0xb87c, 0x8037); ++ ocp_reg_write(tp, 0xb87e, 0x7c13); ++ ocp_reg_write(tp, 0xb87c, 0x803b); ++ ocp_reg_write(tp, 0xb87e, 0xfc32); ++ ocp_reg_write(tp, 0xb87c, 0x803f); ++ ocp_reg_write(tp, 0xb87e, 0x7c13); ++ ocp_reg_write(tp, 0xb87c, 0x8043); ++ ocp_reg_write(tp, 0xb87e, 0x7c13); ++ ocp_reg_write(tp, 0xb87c, 0x8047); ++ ocp_reg_write(tp, 0xb87e, 0x7c13); ++ ++ ocp_reg_write(tp, 0xb87c, 0x8145); ++ ocp_reg_write(tp, 0xb87e, 0x370e); ++ ocp_reg_write(tp, 0xb87c, 0x8157); ++ ocp_reg_write(tp, 0xb87e, 0x770e); ++ ocp_reg_write(tp, 0xb87c, 0x8169); ++ ocp_reg_write(tp, 0xb87e, 0x0d0a); ++ ocp_reg_write(tp, 0xb87c, 0x817b); ++ ocp_reg_write(tp, 0xb87e, 0x1d0a); ++ ++ data = sram_read(tp, 0x8217); ++ data &= ~0xff00; ++ data |= 0x5000; ++ sram_write(tp, 0x8217, data); ++ data = sram_read(tp, 0x821a); ++ data &= ~0xff00; ++ data |= 0x5000; ++ sram_write(tp, 0x821a, data); ++ sram_write(tp, 0x80da, 0x0403); ++ data = sram_read(tp, 0x80dc); ++ data &= ~0xff00; ++ data |= 0x1000; ++ sram_write(tp, 0x80dc, data); ++ sram_write(tp, 0x80b3, 0x0384); ++ sram_write(tp, 0x80b7, 0x2007); ++ data = sram_read(tp, 0x80ba); ++ data &= ~0xff00; ++ data |= 0x6c00; ++ sram_write(tp, 0x80ba, data); ++ sram_write(tp, 0x80b5, 0xf009); ++ data = sram_read(tp, 0x80bd); ++ data &= ~0xff00; ++ data |= 0x9f00; ++ sram_write(tp, 0x80bd, data); ++ sram_write(tp, 0x80c7, 0xf083); ++ sram_write(tp, 0x80dd, 0x03f0); ++ data = sram_read(tp, 0x80df); ++ data &= ~0xff00; ++ data |= 0x1000; ++ sram_write(tp, 0x80df, data); ++ sram_write(tp, 0x80cb, 0x2007); ++ data = sram_read(tp, 0x80ce); ++ data &= ~0xff00; ++ data |= 0x6c00; ++ sram_write(tp, 0x80ce, data); ++ sram_write(tp, 0x80c9, 0x8009); ++ data = sram_read(tp, 0x80d1); ++ data &= ~0xff00; ++ data |= 0x8000; ++ sram_write(tp, 0x80d1, data); ++ sram_write(tp, 0x80a3, 0x200a); ++ sram_write(tp, 0x80a5, 0xf0ad); ++ sram_write(tp, 0x809f, 0x6073); ++ sram_write(tp, 0x80a1, 0x000b); ++ data = sram_read(tp, 0x80a9); ++ data &= ~0xff00; ++ data |= 0xc000; ++ sram_write(tp, 0x80a9, data); ++ ++ if (rtl_phy_patch_request(tp, true, true)) ++ return; ++ ++ data = ocp_reg_read(tp, 0xb896); ++ data &= ~BIT(0); ++ ocp_reg_write(tp, 0xb896, data); ++ data = ocp_reg_read(tp, 0xb892); ++ data &= ~0xff00; ++ ocp_reg_write(tp, 0xb892, data); ++ ocp_reg_write(tp, 0xb88e, 0xc23e); ++ ocp_reg_write(tp, 0xb890, 0x0000); ++ ocp_reg_write(tp, 0xb88e, 0xc240); ++ ocp_reg_write(tp, 0xb890, 0x0103); ++ ocp_reg_write(tp, 0xb88e, 0xc242); ++ ocp_reg_write(tp, 0xb890, 0x0507); ++ ocp_reg_write(tp, 0xb88e, 0xc244); ++ ocp_reg_write(tp, 0xb890, 0x090b); ++ ocp_reg_write(tp, 0xb88e, 0xc246); ++ ocp_reg_write(tp, 0xb890, 0x0c0e); ++ ocp_reg_write(tp, 0xb88e, 0xc248); ++ ocp_reg_write(tp, 0xb890, 0x1012); ++ ocp_reg_write(tp, 0xb88e, 0xc24a); ++ ocp_reg_write(tp, 0xb890, 0x1416); ++ data = ocp_reg_read(tp, 0xb896); ++ data |= BIT(0); ++ ocp_reg_write(tp, 0xb896, data); ++ ++ rtl_phy_patch_request(tp, false, true); ++ ++ data = ocp_reg_read(tp, 0xa86a); ++ data |= BIT(0); ++ ocp_reg_write(tp, 0xa86a, data); ++ data = ocp_reg_read(tp, 0xa6f0); ++ data |= BIT(0); ++ ocp_reg_write(tp, 0xa6f0, data); ++ ++ ocp_reg_write(tp, 0xbfa0, 0xd70d); ++ ocp_reg_write(tp, 0xbfa2, 0x4100); ++ ocp_reg_write(tp, 0xbfa4, 0xe868); ++ ocp_reg_write(tp, 0xbfa6, 0xdc59); ++ ocp_reg_write(tp, 0xb54c, 0x3c18); ++ data = ocp_reg_read(tp, 0xbfa4); ++ data &= ~BIT(5); ++ ocp_reg_write(tp, 0xbfa4, data); ++ data = sram_read(tp, 0x817d); ++ data |= BIT(12); ++ sram_write(tp, 0x817d, data); ++ break; ++ case RTL_VER_13: ++ /* 2.5G INRX */ ++ data = ocp_reg_read(tp, 0xac46); ++ data &= ~0x00f0; ++ data |= 0x0090; ++ ocp_reg_write(tp, 0xac46, data); ++ data = ocp_reg_read(tp, 0xad30); ++ data &= ~0x0003; ++ data |= 0x0001; ++ ocp_reg_write(tp, 0xad30, data); ++ fallthrough; ++ case RTL_VER_15: ++ /* EEE parameter */ ++ ocp_reg_write(tp, 0xb87c, 0x80f5); ++ ocp_reg_write(tp, 0xb87e, 0x760e); ++ ocp_reg_write(tp, 0xb87c, 0x8107); ++ ocp_reg_write(tp, 0xb87e, 0x360e); ++ ocp_reg_write(tp, 0xb87c, 0x8551); ++ data = ocp_reg_read(tp, 0xb87e); ++ data &= ~0xff00; ++ data |= 0x0800; ++ ocp_reg_write(tp, 0xb87e, data); ++ ++ /* ADC_PGA parameter */ ++ data = ocp_reg_read(tp, 0xbf00); ++ data &= ~0xe000; ++ data |= 0xa000; ++ ocp_reg_write(tp, 0xbf00, data); ++ data = ocp_reg_read(tp, 0xbf46); ++ data &= ~0x0f00; ++ data |= 0x0300; ++ ocp_reg_write(tp, 0xbf46, data); ++ ++ /* Green Table-PGA, 1G full viterbi */ ++ sram_write(tp, 0x8044, 0x2417); ++ sram_write(tp, 0x804a, 0x2417); ++ sram_write(tp, 0x8050, 0x2417); ++ sram_write(tp, 0x8056, 0x2417); ++ sram_write(tp, 0x805c, 0x2417); ++ sram_write(tp, 0x8062, 0x2417); ++ sram_write(tp, 0x8068, 0x2417); ++ sram_write(tp, 0x806e, 0x2417); ++ sram_write(tp, 0x8074, 0x2417); ++ sram_write(tp, 0x807a, 0x2417); ++ ++ /* XG PLL */ ++ data = ocp_reg_read(tp, 0xbf84); ++ data &= ~0xe000; ++ data |= 0xa000; ++ ocp_reg_write(tp, 0xbf84, data); ++ break; ++ default: ++ break; ++ } ++ ++ if (rtl_phy_patch_request(tp, true, true)) ++ return; ++ ++ ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL4); ++ ocp_data |= EEE_SPDWN_EN; ++ ocp_write_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL4, ocp_data); ++ ++ data = ocp_reg_read(tp, OCP_DOWN_SPEED); ++ data &= ~(EN_EEE_100 | EN_EEE_1000); ++ data |= EN_10M_CLKDIV; ++ ocp_reg_write(tp, OCP_DOWN_SPEED, data); ++ tp->ups_info._10m_ckdiv = true; ++ tp->ups_info.eee_plloff_100 = false; ++ tp->ups_info.eee_plloff_giga = false; ++ ++ data = ocp_reg_read(tp, OCP_POWER_CFG); ++ data &= ~EEE_CLKDIV_EN; ++ ocp_reg_write(tp, OCP_POWER_CFG, data); ++ tp->ups_info.eee_ckdiv = false; ++ ++ rtl_phy_patch_request(tp, false, true); ++ ++ rtl_green_en(tp, test_bit(GREEN_ETHERNET, &tp->flags)); ++ ++ data = ocp_reg_read(tp, 0xa428); ++ data &= ~BIT(9); ++ ocp_reg_write(tp, 0xa428, data); ++ data = ocp_reg_read(tp, 0xa5ea); ++ data &= ~BIT(0); ++ ocp_reg_write(tp, 0xa5ea, data); ++ tp->ups_info.lite_mode = 0; ++ ++ if (tp->eee_en) ++ rtl_eee_enable(tp, true); ++ ++ r8153_aldps_en(tp, true); ++ r8152b_enable_fc(tp); ++ r8153_u2p3en(tp, true); ++ ++ set_bit(PHY_RESET, &tp->flags); ++} ++ ++static void r8156_init(struct r8152 *tp) ++{ ++ u32 ocp_data; ++ u16 data; ++ int i; ++ ++ if (test_bit(RTL8152_UNPLUG, &tp->flags)) ++ return; ++ ++ ocp_data = ocp_read_byte(tp, MCU_TYPE_USB, USB_ECM_OP); ++ ocp_data &= ~EN_ALL_SPEED; ++ ocp_write_byte(tp, MCU_TYPE_USB, USB_ECM_OP, ocp_data); ++ ++ ocp_write_word(tp, MCU_TYPE_USB, USB_SPEED_OPTION, 0); ++ ++ ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_ECM_OPTION); ++ ocp_data |= BYPASS_MAC_RESET; ++ ocp_write_word(tp, MCU_TYPE_USB, USB_ECM_OPTION, ocp_data); ++ ++ r8153b_u1u2en(tp, false); ++ ++ for (i = 0; i < 500; i++) { ++ if (ocp_read_word(tp, MCU_TYPE_PLA, PLA_BOOT_CTRL) & ++ AUTOLOAD_DONE) ++ break; ++ ++ msleep(20); ++ if (test_bit(RTL8152_UNPLUG, &tp->flags)) ++ return; ++ } ++ ++ data = r8153_phy_status(tp, 0); ++ if (data == PHY_STAT_EXT_INIT) { ++ data = ocp_reg_read(tp, 0xa468); ++ data &= ~(BIT(3) | BIT(1)); ++ ocp_reg_write(tp, 0xa468, data); ++ } ++ ++ data = r8152_mdio_read(tp, MII_BMCR); ++ if (data & BMCR_PDOWN) { ++ data &= ~BMCR_PDOWN; ++ r8152_mdio_write(tp, MII_BMCR, data); ++ } ++ ++ data = r8153_phy_status(tp, PHY_STAT_LAN_ON); ++ WARN_ON_ONCE(data != PHY_STAT_LAN_ON); ++ ++ r8153_u2p3en(tp, false); ++ ++ /* MSC timer = 0xfff * 8ms = 32760 ms */ ++ ocp_write_word(tp, MCU_TYPE_USB, USB_MSC_TIMER, 0x0fff); ++ ++ /* U1/U2/L1 idle timer. 500 us */ ++ ocp_write_word(tp, MCU_TYPE_USB, USB_U1U2_TIMER, 500); ++ ++ r8153b_power_cut_en(tp, false); ++ r8156_ups_en(tp, false); ++ r8153_queue_wake(tp, false); ++ rtl_runtime_suspend_enable(tp, false); ++ ++ if (tp->udev->speed >= USB_SPEED_SUPER) ++ r8153b_u1u2en(tp, true); ++ ++ usb_enable_lpm(tp->udev); ++ ++ r8156_mac_clk_spd(tp, true); ++ ++ ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL3); ++ ocp_data &= ~PLA_MCU_SPDWN_EN; ++ ocp_write_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL3, ocp_data); ++ ++ ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_EXTRA_STATUS); ++ if (rtl8152_get_speed(tp) & LINK_STATUS) ++ ocp_data |= CUR_LINK_OK; ++ else ++ ocp_data &= ~CUR_LINK_OK; ++ ocp_data |= POLL_LINK_CHG; ++ ocp_write_word(tp, MCU_TYPE_PLA, PLA_EXTRA_STATUS, ocp_data); ++ ++ set_bit(GREEN_ETHERNET, &tp->flags); ++ ++ /* rx aggregation */ ++ ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_USB_CTRL); ++ ocp_data &= ~(RX_AGG_DISABLE | RX_ZERO_EN); ++ ocp_write_word(tp, MCU_TYPE_USB, USB_USB_CTRL, ocp_data); ++ ++ ocp_data = ocp_read_byte(tp, MCU_TYPE_USB, USB_BMU_CONFIG); ++ ocp_data |= ACT_ODMA; ++ ocp_write_byte(tp, MCU_TYPE_USB, USB_BMU_CONFIG, ocp_data); ++ ++ rtl_tally_reset(tp); ++ ++ tp->coalesce = 15000; /* 15 us */ ++} ++ ++static void r8156b_init(struct r8152 *tp) ++{ ++ u32 ocp_data; ++ u16 data; ++ int i; ++ ++ if (test_bit(RTL8152_UNPLUG, &tp->flags)) ++ return; ++ ++ ocp_data = ocp_read_byte(tp, MCU_TYPE_USB, USB_ECM_OP); ++ ocp_data &= ~EN_ALL_SPEED; ++ ocp_write_byte(tp, MCU_TYPE_USB, USB_ECM_OP, ocp_data); ++ ++ ocp_write_word(tp, MCU_TYPE_USB, USB_SPEED_OPTION, 0); ++ ++ ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_ECM_OPTION); ++ ocp_data |= BYPASS_MAC_RESET; ++ ocp_write_word(tp, MCU_TYPE_USB, USB_ECM_OPTION, ocp_data); ++ ++ ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_U2P3_CTRL); ++ ocp_data |= RX_DETECT8; ++ ocp_write_word(tp, MCU_TYPE_USB, USB_U2P3_CTRL, ocp_data); ++ ++ r8153b_u1u2en(tp, false); ++ ++ switch (tp->version) { ++ case RTL_VER_13: ++ case RTL_VER_15: ++ r8156b_wait_loading_flash(tp); ++ break; ++ default: ++ break; ++ } ++ ++ for (i = 0; i < 500; i++) { ++ if (ocp_read_word(tp, MCU_TYPE_PLA, PLA_BOOT_CTRL) & ++ AUTOLOAD_DONE) ++ break; ++ ++ msleep(20); ++ if (test_bit(RTL8152_UNPLUG, &tp->flags)) ++ return; ++ } ++ ++ data = r8153_phy_status(tp, 0); ++ if (data == PHY_STAT_EXT_INIT) { ++ data = ocp_reg_read(tp, 0xa468); ++ data &= ~(BIT(3) | BIT(1)); ++ ocp_reg_write(tp, 0xa468, data); ++ ++ data = ocp_reg_read(tp, 0xa466); ++ data &= ~BIT(0); ++ ocp_reg_write(tp, 0xa466, data); ++ } ++ ++ data = r8152_mdio_read(tp, MII_BMCR); ++ if (data & BMCR_PDOWN) { ++ data &= ~BMCR_PDOWN; ++ r8152_mdio_write(tp, MII_BMCR, data); ++ } ++ ++ data = r8153_phy_status(tp, PHY_STAT_LAN_ON); ++ ++ r8153_u2p3en(tp, false); ++ ++ /* MSC timer = 0xfff * 8ms = 32760 ms */ ++ ocp_write_word(tp, MCU_TYPE_USB, USB_MSC_TIMER, 0x0fff); ++ ++ /* U1/U2/L1 idle timer. 500 us */ ++ ocp_write_word(tp, MCU_TYPE_USB, USB_U1U2_TIMER, 500); ++ ++ r8153b_power_cut_en(tp, false); ++ r8156_ups_en(tp, false); ++ r8153_queue_wake(tp, false); ++ rtl_runtime_suspend_enable(tp, false); ++ ++ if (tp->udev->speed >= USB_SPEED_SUPER) ++ r8153b_u1u2en(tp, true); ++ ++ usb_enable_lpm(tp->udev); ++ ++ ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_RCR); ++ ocp_data &= ~SLOT_EN; ++ ocp_write_word(tp, MCU_TYPE_PLA, PLA_RCR, ocp_data); ++ ++ ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_CPCR); ++ ocp_data |= FLOW_CTRL_EN; ++ ocp_write_word(tp, MCU_TYPE_PLA, PLA_CPCR, ocp_data); ++ ++ /* enable fc timer and set timer to 600 ms. */ ++ ocp_write_word(tp, MCU_TYPE_USB, USB_FC_TIMER, ++ CTRL_TIMER_EN | (600 / 8)); ++ ++ ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_FW_CTRL); ++ if (!(ocp_read_word(tp, MCU_TYPE_PLA, PLA_POL_GPIO_CTRL) & DACK_DET_EN)) ++ ocp_data |= FLOW_CTRL_PATCH_2; ++ ocp_data &= ~AUTO_SPEEDUP; ++ ocp_write_word(tp, MCU_TYPE_USB, USB_FW_CTRL, ocp_data); ++ ++ ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_FW_TASK); ++ ocp_data |= FC_PATCH_TASK; ++ ocp_write_word(tp, MCU_TYPE_USB, USB_FW_TASK, ocp_data); ++ ++ r8156_mac_clk_spd(tp, true); ++ ++ ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL3); ++ ocp_data &= ~PLA_MCU_SPDWN_EN; ++ ocp_write_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL3, ocp_data); ++ ++ ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_EXTRA_STATUS); ++ if (rtl8152_get_speed(tp) & LINK_STATUS) ++ ocp_data |= CUR_LINK_OK; ++ else ++ ocp_data &= ~CUR_LINK_OK; ++ ocp_data |= POLL_LINK_CHG; ++ ocp_write_word(tp, MCU_TYPE_PLA, PLA_EXTRA_STATUS, ocp_data); ++ ++ set_bit(GREEN_ETHERNET, &tp->flags); ++ ++ /* rx aggregation */ ++ ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_USB_CTRL); ++ ocp_data &= ~(RX_AGG_DISABLE | RX_ZERO_EN); ++ ocp_write_word(tp, MCU_TYPE_USB, USB_USB_CTRL, ocp_data); ++ ++ rtl_tally_reset(tp); ++ ++ tp->coalesce = 15000; /* 15 us */ ++} ++ + static int rtl8152_pre_reset(struct usb_interface *intf) + { + struct r8152 *tp = usb_get_intfdata(intf); +@@ -6015,6 +7947,22 @@ int rtl8152_get_link_ksettings(struct ne + + mii_ethtool_get_link_ksettings(&tp->mii, cmd); + ++ linkmode_mod_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT, ++ cmd->link_modes.supported, tp->support_2500full); ++ ++ if (tp->support_2500full) { ++ linkmode_mod_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT, ++ cmd->link_modes.advertising, ++ ocp_reg_read(tp, OCP_10GBT_CTRL) & MDIO_AN_10GBT_CTRL_ADV2_5G); ++ ++ linkmode_mod_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT, ++ cmd->link_modes.lp_advertising, ++ ocp_reg_read(tp, OCP_10GBT_STAT) & MDIO_AN_10GBT_STAT_LP2_5G); ++ ++ if (is_speed_2500(rtl8152_get_speed(tp))) ++ cmd->base.speed = SPEED_2500; ++ } ++ + mutex_unlock(&tp->control); + + usb_autopm_put_interface(tp->intf); +@@ -6058,6 +8006,10 @@ static int rtl8152_set_link_ksettings(st + cmd->link_modes.advertising)) + advertising |= RTL_ADVERTISED_1000_FULL; + ++ if (test_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT, ++ cmd->link_modes.advertising)) ++ advertising |= RTL_ADVERTISED_2500_FULL; ++ + mutex_lock(&tp->control); + + ret = rtl8152_set_speed(tp, cmd->base.autoneg, cmd->base.speed, +@@ -6647,6 +8599,67 @@ static int rtl_ops_init(struct r8152 *tp + tp->eee_adv = MDIO_EEE_1000T | MDIO_EEE_100TX; + break; + ++ case RTL_VER_11: ++ tp->eee_en = true; ++ tp->eee_adv = MDIO_EEE_1000T | MDIO_EEE_100TX; ++ fallthrough; ++ case RTL_VER_10: ++ ops->init = r8156_init; ++ ops->enable = rtl8156_enable; ++ ops->disable = rtl8153_disable; ++ ops->up = rtl8156_up; ++ ops->down = rtl8156_down; ++ ops->unload = rtl8153_unload; ++ ops->eee_get = r8153_get_eee; ++ ops->eee_set = r8152_set_eee; ++ ops->in_nway = rtl8153_in_nway; ++ ops->hw_phy_cfg = r8156_hw_phy_cfg; ++ ops->autosuspend_en = rtl8156_runtime_enable; ++ ops->change_mtu = rtl8156_change_mtu; ++ tp->rx_buf_sz = 48 * 1024; ++ tp->support_2500full = 1; ++ break; ++ ++ case RTL_VER_12: ++ case RTL_VER_13: ++ tp->support_2500full = 1; ++ fallthrough; ++ case RTL_VER_15: ++ tp->eee_en = true; ++ tp->eee_adv = MDIO_EEE_1000T | MDIO_EEE_100TX; ++ ops->init = r8156b_init; ++ ops->enable = rtl8156b_enable; ++ ops->disable = rtl8153_disable; ++ ops->up = rtl8156_up; ++ ops->down = rtl8156_down; ++ ops->unload = rtl8153_unload; ++ ops->eee_get = r8153_get_eee; ++ ops->eee_set = r8152_set_eee; ++ ops->in_nway = rtl8153_in_nway; ++ ops->hw_phy_cfg = r8156b_hw_phy_cfg; ++ ops->autosuspend_en = rtl8156_runtime_enable; ++ ops->change_mtu = rtl8156_change_mtu; ++ tp->rx_buf_sz = 48 * 1024; ++ break; ++ ++ case RTL_VER_14: ++ ops->init = r8153c_init; ++ ops->enable = rtl8153_enable; ++ ops->disable = rtl8153_disable; ++ ops->up = rtl8153c_up; ++ ops->down = rtl8153b_down; ++ ops->unload = rtl8153_unload; ++ ops->eee_get = r8153_get_eee; ++ ops->eee_set = r8152_set_eee; ++ ops->in_nway = rtl8153_in_nway; ++ ops->hw_phy_cfg = r8153c_hw_phy_cfg; ++ ops->autosuspend_en = rtl8153c_runtime_enable; ++ ops->change_mtu = rtl8153c_change_mtu; ++ tp->rx_buf_sz = 32 * 1024; ++ tp->eee_en = true; ++ tp->eee_adv = MDIO_EEE_1000T | MDIO_EEE_100TX; ++ break; ++ + default: + ret = -ENODEV; + dev_err(&tp->intf->dev, "Unknown Device\n"); +@@ -6660,11 +8673,13 @@ static int rtl_ops_init(struct r8152 *tp + #define FIRMWARE_8153A_3 "rtl_nic/rtl8153a-3.fw" + #define FIRMWARE_8153A_4 "rtl_nic/rtl8153a-4.fw" + #define FIRMWARE_8153B_2 "rtl_nic/rtl8153b-2.fw" ++#define FIRMWARE_8153C_1 "rtl_nic/rtl8153c-1.fw" + + MODULE_FIRMWARE(FIRMWARE_8153A_2); + MODULE_FIRMWARE(FIRMWARE_8153A_3); + MODULE_FIRMWARE(FIRMWARE_8153A_4); + MODULE_FIRMWARE(FIRMWARE_8153B_2); ++MODULE_FIRMWARE(FIRMWARE_8153C_1); + + static int rtl_fw_init(struct r8152 *tp) + { +@@ -6690,6 +8705,11 @@ static int rtl_fw_init(struct r8152 *tp) + rtl_fw->pre_fw = r8153b_pre_firmware_1; + rtl_fw->post_fw = r8153b_post_firmware_1; + break; ++ case RTL_VER_14: ++ rtl_fw->fw_name = FIRMWARE_8153C_1; ++ rtl_fw->pre_fw = r8153b_pre_firmware_1; ++ rtl_fw->post_fw = r8153c_post_firmware_1; ++ break; + default: + break; + } +@@ -6745,6 +8765,27 @@ u8 rtl8152_get_version(struct usb_interf + case 0x6010: + version = RTL_VER_09; + break; ++ case 0x7010: ++ version = RTL_TEST_01; ++ break; ++ case 0x7020: ++ version = RTL_VER_10; ++ break; ++ case 0x7030: ++ version = RTL_VER_11; ++ break; ++ case 0x7400: ++ version = RTL_VER_12; ++ break; ++ case 0x7410: ++ version = RTL_VER_13; ++ break; ++ case 0x6400: ++ version = RTL_VER_14; ++ break; ++ case 0x7420: ++ version = RTL_VER_15; ++ break; + default: + version = RTL_VER_UNKNOWN; + dev_info(&intf->dev, "Unknown version 0x%04x\n", ocp_data); +@@ -6857,12 +8898,29 @@ static int rtl8152_probe(struct usb_inte + /* MTU range: 68 - 1500 or 9194 */ + netdev->min_mtu = ETH_MIN_MTU; + switch (tp->version) { ++ case RTL_VER_03: ++ case RTL_VER_04: ++ case RTL_VER_05: ++ case RTL_VER_06: ++ case RTL_VER_08: ++ case RTL_VER_09: ++ case RTL_VER_14: ++ netdev->max_mtu = size_to_mtu(9 * 1024); ++ break; ++ case RTL_VER_10: ++ case RTL_VER_11: ++ netdev->max_mtu = size_to_mtu(15 * 1024); ++ break; ++ case RTL_VER_12: ++ case RTL_VER_13: ++ case RTL_VER_15: ++ netdev->max_mtu = size_to_mtu(16 * 1024); ++ break; + case RTL_VER_01: + case RTL_VER_02: +- netdev->max_mtu = ETH_DATA_LEN; +- break; ++ case RTL_VER_07: + default: +- netdev->max_mtu = size_to_mtu(9 * 1024); ++ netdev->max_mtu = ETH_DATA_LEN; + break; + } + +@@ -6878,7 +8936,13 @@ static int rtl8152_probe(struct usb_inte + tp->advertising = RTL_ADVERTISED_10_HALF | RTL_ADVERTISED_10_FULL | + RTL_ADVERTISED_100_HALF | RTL_ADVERTISED_100_FULL; + if (tp->mii.supports_gmii) { +- tp->speed = SPEED_1000; ++ if (tp->support_2500full && ++ tp->udev->speed >= USB_SPEED_SUPER) { ++ tp->speed = SPEED_2500; ++ tp->advertising |= RTL_ADVERTISED_2500_FULL; ++ } else { ++ tp->speed = SPEED_1000; ++ } + tp->advertising |= RTL_ADVERTISED_1000_FULL; + } + tp->duplex = DUPLEX_FULL; +@@ -6902,7 +8966,11 @@ static int rtl8152_probe(struct usb_inte + set_ethernet_addr(tp); + + usb_set_intfdata(intf, tp); +- netif_napi_add(netdev, &tp->napi, r8152_poll, RTL8152_NAPI_WEIGHT); ++ ++ if (tp->support_2500full) ++ netif_napi_add(netdev, &tp->napi, r8152_poll, 256); ++ else ++ netif_napi_add(netdev, &tp->napi, r8152_poll, 64); + + ret = register_netdev(netdev); + if (ret != 0) { +@@ -6938,7 +9006,8 @@ static void rtl8152_disconnect(struct us + unregister_netdev(tp->netdev); + tasklet_kill(&tp->tx_tl); + cancel_delayed_work_sync(&tp->hw_phy_work); +- tp->rtl_ops.unload(tp); ++ if (tp->rtl_ops.unload) ++ tp->rtl_ops.unload(tp); + rtl8152_release_firmware(tp); + free_netdev(tp->netdev); + } +@@ -6958,13 +9027,28 @@ static void rtl8152_disconnect(struct us + .idProduct = (prod), \ + .bInterfaceClass = USB_CLASS_COMM, \ + .bInterfaceSubClass = USB_CDC_SUBCLASS_ETHERNET, \ ++ .bInterfaceProtocol = USB_CDC_PROTO_NONE \ ++}, \ ++{ \ ++ .match_flags = USB_DEVICE_ID_MATCH_INT_INFO | \ ++ USB_DEVICE_ID_MATCH_DEVICE, \ ++ .idVendor = (vend), \ ++ .idProduct = (prod), \ ++ .bInterfaceClass = USB_CLASS_COMM, \ ++ .bInterfaceSubClass = USB_CDC_SUBCLASS_NCM, \ + .bInterfaceProtocol = USB_CDC_PROTO_NONE + + /* table of devices that work with this driver */ + static const struct usb_device_id rtl8152_table[] = { ++ /* Realtek */ + {REALTEK_USB_DEVICE(VENDOR_ID_REALTEK, 0x8050)}, ++ {REALTEK_USB_DEVICE(VENDOR_ID_REALTEK, 0x8053)}, + {REALTEK_USB_DEVICE(VENDOR_ID_REALTEK, 0x8152)}, + {REALTEK_USB_DEVICE(VENDOR_ID_REALTEK, 0x8153)}, ++ {REALTEK_USB_DEVICE(VENDOR_ID_REALTEK, 0x8155)}, ++ {REALTEK_USB_DEVICE(VENDOR_ID_REALTEK, 0x8156)}, ++ ++ /* Microsoft */ + {REALTEK_USB_DEVICE(VENDOR_ID_MICROSOFT, 0x07ab)}, + {REALTEK_USB_DEVICE(VENDOR_ID_MICROSOFT, 0x07c6)}, + {REALTEK_USB_DEVICE(VENDOR_ID_MICROSOFT, 0x0927)}, diff --git a/target/linux/generic/backport-5.10/794-v5.13-r8152-support-PHY-firmware-for-RTL8156-series.patch b/target/linux/generic/backport-5.10/794-v5.13-r8152-support-PHY-firmware-for-RTL8156-series.patch new file mode 100644 index 0000000000..943c821b82 --- /dev/null +++ b/target/linux/generic/backport-5.10/794-v5.13-r8152-support-PHY-firmware-for-RTL8156-series.patch @@ -0,0 +1,691 @@ +From ca09589a72a0aa17389754fb75a5cd1a5d46818f Mon Sep 17 00:00:00 2001 +From: Hayes Wang +Date: Fri, 16 Apr 2021 16:04:36 +0800 +Subject: [PATCH] r8152: support PHY firmware for RTL8156 series + +commit 4a51b0e8a0143b0e83d51d9c58c6416c3818a9f2 upstream. + +Support new firmware type and method for RTL8156 series. + +Signed-off-by: Hayes Wang +Signed-off-by: David S. Miller +--- + drivers/net/usb/r8152.c | 563 +++++++++++++++++++++++++++++++++++++++- + 1 file changed, 561 insertions(+), 2 deletions(-) + +--- a/drivers/net/usb/r8152.c ++++ b/drivers/net/usb/r8152.c +@@ -975,8 +975,60 @@ enum rtl8152_fw_flags { + FW_FLAGS_START, + FW_FLAGS_STOP, + FW_FLAGS_NC, ++ FW_FLAGS_NC1, ++ FW_FLAGS_NC2, ++ FW_FLAGS_UC2, ++ FW_FLAGS_UC, ++ FW_FLAGS_SPEED_UP, ++ FW_FLAGS_VER, + }; + ++enum rtl8152_fw_fixup_cmd { ++ FW_FIXUP_AND = 0, ++ FW_FIXUP_OR, ++ FW_FIXUP_NOT, ++ FW_FIXUP_XOR, ++}; ++ ++struct fw_phy_set { ++ __le16 addr; ++ __le16 data; ++} __packed; ++ ++struct fw_phy_speed_up { ++ struct fw_block blk_hdr; ++ __le16 fw_offset; ++ __le16 version; ++ __le16 fw_reg; ++ __le16 reserved; ++ char info[]; ++} __packed; ++ ++struct fw_phy_ver { ++ struct fw_block blk_hdr; ++ struct fw_phy_set ver; ++ __le32 reserved; ++} __packed; ++ ++struct fw_phy_fixup { ++ struct fw_block blk_hdr; ++ struct fw_phy_set setting; ++ __le16 bit_cmd; ++ __le16 reserved; ++} __packed; ++ ++struct fw_phy_union { ++ struct fw_block blk_hdr; ++ __le16 fw_offset; ++ __le16 fw_reg; ++ struct fw_phy_set pre_set[2]; ++ struct fw_phy_set bp[8]; ++ struct fw_phy_set bp_en; ++ u8 pre_num; ++ u8 bp_num; ++ char info[]; ++} __packed; ++ + /** + * struct fw_mac - a firmware block used by RTL_FW_PLA and RTL_FW_USB. + * The layout of the firmware block is: +@@ -1081,6 +1133,15 @@ enum rtl_fw_type { + RTL_FW_PHY_START, + RTL_FW_PHY_STOP, + RTL_FW_PHY_NC, ++ RTL_FW_PHY_FIXUP, ++ RTL_FW_PHY_UNION_NC, ++ RTL_FW_PHY_UNION_NC1, ++ RTL_FW_PHY_UNION_NC2, ++ RTL_FW_PHY_UNION_UC2, ++ RTL_FW_PHY_UNION_UC, ++ RTL_FW_PHY_UNION_MISC, ++ RTL_FW_PHY_SPEED_UP, ++ RTL_FW_PHY_VER, + }; + + enum rtl_version { +@@ -4000,6 +4061,162 @@ static int rtl_post_ram_code(struct r815 + return 0; + } + ++static bool rtl8152_is_fw_phy_speed_up_ok(struct r8152 *tp, struct fw_phy_speed_up *phy) ++{ ++ u16 fw_offset; ++ u32 length; ++ bool rc = false; ++ ++ switch (tp->version) { ++ case RTL_VER_01: ++ case RTL_VER_02: ++ case RTL_VER_03: ++ case RTL_VER_04: ++ case RTL_VER_05: ++ case RTL_VER_06: ++ case RTL_VER_07: ++ case RTL_VER_08: ++ case RTL_VER_09: ++ case RTL_VER_10: ++ case RTL_VER_11: ++ case RTL_VER_12: ++ case RTL_VER_14: ++ goto out; ++ case RTL_VER_13: ++ case RTL_VER_15: ++ default: ++ break; ++ } ++ ++ fw_offset = __le16_to_cpu(phy->fw_offset); ++ length = __le32_to_cpu(phy->blk_hdr.length); ++ if (fw_offset < sizeof(*phy) || length <= fw_offset) { ++ dev_err(&tp->intf->dev, "invalid fw_offset\n"); ++ goto out; ++ } ++ ++ length -= fw_offset; ++ if (length & 3) { ++ dev_err(&tp->intf->dev, "invalid block length\n"); ++ goto out; ++ } ++ ++ if (__le16_to_cpu(phy->fw_reg) != 0x9A00) { ++ dev_err(&tp->intf->dev, "invalid register to load firmware\n"); ++ goto out; ++ } ++ ++ rc = true; ++out: ++ return rc; ++} ++ ++static bool rtl8152_is_fw_phy_ver_ok(struct r8152 *tp, struct fw_phy_ver *ver) ++{ ++ bool rc = false; ++ ++ switch (tp->version) { ++ case RTL_VER_10: ++ case RTL_VER_11: ++ case RTL_VER_12: ++ case RTL_VER_13: ++ case RTL_VER_15: ++ break; ++ default: ++ goto out; ++ } ++ ++ if (__le32_to_cpu(ver->blk_hdr.length) != sizeof(*ver)) { ++ dev_err(&tp->intf->dev, "invalid block length\n"); ++ goto out; ++ } ++ ++ if (__le16_to_cpu(ver->ver.addr) != SRAM_GPHY_FW_VER) { ++ dev_err(&tp->intf->dev, "invalid phy ver addr\n"); ++ goto out; ++ } ++ ++ rc = true; ++out: ++ return rc; ++} ++ ++static bool rtl8152_is_fw_phy_fixup_ok(struct r8152 *tp, struct fw_phy_fixup *fix) ++{ ++ bool rc = false; ++ ++ switch (tp->version) { ++ case RTL_VER_10: ++ case RTL_VER_11: ++ case RTL_VER_12: ++ case RTL_VER_13: ++ case RTL_VER_15: ++ break; ++ default: ++ goto out; ++ } ++ ++ if (__le32_to_cpu(fix->blk_hdr.length) != sizeof(*fix)) { ++ dev_err(&tp->intf->dev, "invalid block length\n"); ++ goto out; ++ } ++ ++ if (__le16_to_cpu(fix->setting.addr) != OCP_PHY_PATCH_CMD || ++ __le16_to_cpu(fix->setting.data) != BIT(7)) { ++ dev_err(&tp->intf->dev, "invalid phy fixup\n"); ++ goto out; ++ } ++ ++ rc = true; ++out: ++ return rc; ++} ++ ++static bool rtl8152_is_fw_phy_union_ok(struct r8152 *tp, struct fw_phy_union *phy) ++{ ++ u16 fw_offset; ++ u32 length; ++ bool rc = false; ++ ++ switch (tp->version) { ++ case RTL_VER_10: ++ case RTL_VER_11: ++ case RTL_VER_12: ++ case RTL_VER_13: ++ case RTL_VER_15: ++ break; ++ default: ++ goto out; ++ } ++ ++ fw_offset = __le16_to_cpu(phy->fw_offset); ++ length = __le32_to_cpu(phy->blk_hdr.length); ++ if (fw_offset < sizeof(*phy) || length <= fw_offset) { ++ dev_err(&tp->intf->dev, "invalid fw_offset\n"); ++ goto out; ++ } ++ ++ length -= fw_offset; ++ if (length & 1) { ++ dev_err(&tp->intf->dev, "invalid block length\n"); ++ goto out; ++ } ++ ++ if (phy->pre_num > 2) { ++ dev_err(&tp->intf->dev, "invalid pre_num %d\n", phy->pre_num); ++ goto out; ++ } ++ ++ if (phy->bp_num > 8) { ++ dev_err(&tp->intf->dev, "invalid bp_num %d\n", phy->bp_num); ++ goto out; ++ } ++ ++ rc = true; ++out: ++ return rc; ++} ++ + static bool rtl8152_is_fw_phy_nc_ok(struct r8152 *tp, struct fw_phy_nc *phy) + { + u32 length; +@@ -4320,6 +4537,10 @@ static long rtl8152_check_firmware(struc + case RTL_FW_PHY_START: + if (test_bit(FW_FLAGS_START, &fw_flags) || + test_bit(FW_FLAGS_NC, &fw_flags) || ++ test_bit(FW_FLAGS_NC1, &fw_flags) || ++ test_bit(FW_FLAGS_NC2, &fw_flags) || ++ test_bit(FW_FLAGS_UC2, &fw_flags) || ++ test_bit(FW_FLAGS_UC, &fw_flags) || + test_bit(FW_FLAGS_STOP, &fw_flags)) { + dev_err(&tp->intf->dev, + "check PHY_START fail\n"); +@@ -4368,7 +4589,153 @@ static long rtl8152_check_firmware(struc + goto fail; + } + __set_bit(FW_FLAGS_NC, &fw_flags); ++ break; ++ case RTL_FW_PHY_UNION_NC: ++ if (!test_bit(FW_FLAGS_START, &fw_flags) || ++ test_bit(FW_FLAGS_NC1, &fw_flags) || ++ test_bit(FW_FLAGS_NC2, &fw_flags) || ++ test_bit(FW_FLAGS_UC2, &fw_flags) || ++ test_bit(FW_FLAGS_UC, &fw_flags) || ++ test_bit(FW_FLAGS_STOP, &fw_flags)) { ++ dev_err(&tp->intf->dev, "PHY_UNION_NC out of order\n"); ++ goto fail; ++ } ++ ++ if (test_bit(FW_FLAGS_NC, &fw_flags)) { ++ dev_err(&tp->intf->dev, "multiple PHY_UNION_NC encountered\n"); ++ goto fail; ++ } + ++ if (!rtl8152_is_fw_phy_union_ok(tp, (struct fw_phy_union *)block)) { ++ dev_err(&tp->intf->dev, "check PHY_UNION_NC failed\n"); ++ goto fail; ++ } ++ __set_bit(FW_FLAGS_NC, &fw_flags); ++ break; ++ case RTL_FW_PHY_UNION_NC1: ++ if (!test_bit(FW_FLAGS_START, &fw_flags) || ++ test_bit(FW_FLAGS_NC2, &fw_flags) || ++ test_bit(FW_FLAGS_UC2, &fw_flags) || ++ test_bit(FW_FLAGS_UC, &fw_flags) || ++ test_bit(FW_FLAGS_STOP, &fw_flags)) { ++ dev_err(&tp->intf->dev, "PHY_UNION_NC1 out of order\n"); ++ goto fail; ++ } ++ ++ if (test_bit(FW_FLAGS_NC1, &fw_flags)) { ++ dev_err(&tp->intf->dev, "multiple PHY NC1 encountered\n"); ++ goto fail; ++ } ++ ++ if (!rtl8152_is_fw_phy_union_ok(tp, (struct fw_phy_union *)block)) { ++ dev_err(&tp->intf->dev, "check PHY_UNION_NC1 failed\n"); ++ goto fail; ++ } ++ __set_bit(FW_FLAGS_NC1, &fw_flags); ++ break; ++ case RTL_FW_PHY_UNION_NC2: ++ if (!test_bit(FW_FLAGS_START, &fw_flags) || ++ test_bit(FW_FLAGS_UC2, &fw_flags) || ++ test_bit(FW_FLAGS_UC, &fw_flags) || ++ test_bit(FW_FLAGS_STOP, &fw_flags)) { ++ dev_err(&tp->intf->dev, "PHY_UNION_NC2 out of order\n"); ++ goto fail; ++ } ++ ++ if (test_bit(FW_FLAGS_NC2, &fw_flags)) { ++ dev_err(&tp->intf->dev, "multiple PHY NC2 encountered\n"); ++ goto fail; ++ } ++ ++ if (!rtl8152_is_fw_phy_union_ok(tp, (struct fw_phy_union *)block)) { ++ dev_err(&tp->intf->dev, "check PHY_UNION_NC2 failed\n"); ++ goto fail; ++ } ++ __set_bit(FW_FLAGS_NC2, &fw_flags); ++ break; ++ case RTL_FW_PHY_UNION_UC2: ++ if (!test_bit(FW_FLAGS_START, &fw_flags) || ++ test_bit(FW_FLAGS_UC, &fw_flags) || ++ test_bit(FW_FLAGS_STOP, &fw_flags)) { ++ dev_err(&tp->intf->dev, "PHY_UNION_UC2 out of order\n"); ++ goto fail; ++ } ++ ++ if (test_bit(FW_FLAGS_UC2, &fw_flags)) { ++ dev_err(&tp->intf->dev, "multiple PHY UC2 encountered\n"); ++ goto fail; ++ } ++ ++ if (!rtl8152_is_fw_phy_union_ok(tp, (struct fw_phy_union *)block)) { ++ dev_err(&tp->intf->dev, "check PHY_UNION_UC2 failed\n"); ++ goto fail; ++ } ++ __set_bit(FW_FLAGS_UC2, &fw_flags); ++ break; ++ case RTL_FW_PHY_UNION_UC: ++ if (!test_bit(FW_FLAGS_START, &fw_flags) || ++ test_bit(FW_FLAGS_STOP, &fw_flags)) { ++ dev_err(&tp->intf->dev, "PHY_UNION_UC out of order\n"); ++ goto fail; ++ } ++ ++ if (test_bit(FW_FLAGS_UC, &fw_flags)) { ++ dev_err(&tp->intf->dev, "multiple PHY UC encountered\n"); ++ goto fail; ++ } ++ ++ if (!rtl8152_is_fw_phy_union_ok(tp, (struct fw_phy_union *)block)) { ++ dev_err(&tp->intf->dev, "check PHY_UNION_UC failed\n"); ++ goto fail; ++ } ++ __set_bit(FW_FLAGS_UC, &fw_flags); ++ break; ++ case RTL_FW_PHY_UNION_MISC: ++ if (!rtl8152_is_fw_phy_union_ok(tp, (struct fw_phy_union *)block)) { ++ dev_err(&tp->intf->dev, "check RTL_FW_PHY_UNION_MISC failed\n"); ++ goto fail; ++ } ++ break; ++ case RTL_FW_PHY_FIXUP: ++ if (!rtl8152_is_fw_phy_fixup_ok(tp, (struct fw_phy_fixup *)block)) { ++ dev_err(&tp->intf->dev, "check PHY fixup failed\n"); ++ goto fail; ++ } ++ break; ++ case RTL_FW_PHY_SPEED_UP: ++ if (test_bit(FW_FLAGS_SPEED_UP, &fw_flags)) { ++ dev_err(&tp->intf->dev, "multiple PHY firmware encountered"); ++ goto fail; ++ } ++ ++ if (!rtl8152_is_fw_phy_speed_up_ok(tp, (struct fw_phy_speed_up *)block)) { ++ dev_err(&tp->intf->dev, "check PHY speed up failed\n"); ++ goto fail; ++ } ++ __set_bit(FW_FLAGS_SPEED_UP, &fw_flags); ++ break; ++ case RTL_FW_PHY_VER: ++ if (test_bit(FW_FLAGS_START, &fw_flags) || ++ test_bit(FW_FLAGS_NC, &fw_flags) || ++ test_bit(FW_FLAGS_NC1, &fw_flags) || ++ test_bit(FW_FLAGS_NC2, &fw_flags) || ++ test_bit(FW_FLAGS_UC2, &fw_flags) || ++ test_bit(FW_FLAGS_UC, &fw_flags) || ++ test_bit(FW_FLAGS_STOP, &fw_flags)) { ++ dev_err(&tp->intf->dev, "Invalid order to set PHY version\n"); ++ goto fail; ++ } ++ ++ if (test_bit(FW_FLAGS_VER, &fw_flags)) { ++ dev_err(&tp->intf->dev, "multiple PHY version encountered"); ++ goto fail; ++ } ++ ++ if (!rtl8152_is_fw_phy_ver_ok(tp, (struct fw_phy_ver *)block)) { ++ dev_err(&tp->intf->dev, "check PHY version failed\n"); ++ goto fail; ++ } ++ __set_bit(FW_FLAGS_VER, &fw_flags); + break; + default: + dev_warn(&tp->intf->dev, "Unknown type %u is found\n", +@@ -4391,6 +4758,143 @@ fail: + return ret; + } + ++static void rtl_ram_code_speed_up(struct r8152 *tp, struct fw_phy_speed_up *phy, bool wait) ++{ ++ u32 len; ++ u8 *data; ++ ++ if (sram_read(tp, SRAM_GPHY_FW_VER) >= __le16_to_cpu(phy->version)) { ++ dev_dbg(&tp->intf->dev, "PHY firmware has been the newest\n"); ++ return; ++ } ++ ++ len = __le32_to_cpu(phy->blk_hdr.length); ++ len -= __le16_to_cpu(phy->fw_offset); ++ data = (u8 *)phy + __le16_to_cpu(phy->fw_offset); ++ ++ if (rtl_phy_patch_request(tp, true, wait)) ++ return; ++ ++ while (len) { ++ u32 ocp_data, size; ++ int i; ++ ++ if (len < 2048) ++ size = len; ++ else ++ size = 2048; ++ ++ ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_GPHY_CTRL); ++ ocp_data |= GPHY_PATCH_DONE | BACKUP_RESTRORE; ++ ocp_write_word(tp, MCU_TYPE_USB, USB_GPHY_CTRL, ocp_data); ++ ++ generic_ocp_write(tp, __le16_to_cpu(phy->fw_reg), 0xff, size, data, MCU_TYPE_USB); ++ ++ data += size; ++ len -= size; ++ ++ ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_POL_GPIO_CTRL); ++ ocp_data |= POL_GPHY_PATCH; ++ ocp_write_word(tp, MCU_TYPE_PLA, PLA_POL_GPIO_CTRL, ocp_data); ++ ++ for (i = 0; i < 1000; i++) { ++ if (!(ocp_read_word(tp, MCU_TYPE_PLA, PLA_POL_GPIO_CTRL) & POL_GPHY_PATCH)) ++ break; ++ } ++ ++ if (i == 1000) { ++ dev_err(&tp->intf->dev, "ram code speedup mode timeout\n"); ++ return; ++ } ++ } ++ ++ ocp_write_word(tp, MCU_TYPE_PLA, PLA_OCP_GPHY_BASE, tp->ocp_base); ++ rtl_phy_patch_request(tp, false, wait); ++ ++ if (sram_read(tp, SRAM_GPHY_FW_VER) == __le16_to_cpu(phy->version)) ++ dev_dbg(&tp->intf->dev, "successfully applied %s\n", phy->info); ++ else ++ dev_err(&tp->intf->dev, "ram code speedup mode fail\n"); ++} ++ ++static int rtl8152_fw_phy_ver(struct r8152 *tp, struct fw_phy_ver *phy_ver) ++{ ++ u16 ver_addr, ver; ++ ++ ver_addr = __le16_to_cpu(phy_ver->ver.addr); ++ ver = __le16_to_cpu(phy_ver->ver.data); ++ ++ if (sram_read(tp, ver_addr) >= ver) { ++ dev_dbg(&tp->intf->dev, "PHY firmware has been the newest\n"); ++ return 0; ++ } ++ ++ sram_write(tp, ver_addr, ver); ++ ++ dev_dbg(&tp->intf->dev, "PHY firmware version %x\n", ver); ++ ++ return ver; ++} ++ ++static void rtl8152_fw_phy_fixup(struct r8152 *tp, struct fw_phy_fixup *fix) ++{ ++ u16 addr, data; ++ ++ addr = __le16_to_cpu(fix->setting.addr); ++ data = ocp_reg_read(tp, addr); ++ ++ switch (__le16_to_cpu(fix->bit_cmd)) { ++ case FW_FIXUP_AND: ++ data &= __le16_to_cpu(fix->setting.data); ++ break; ++ case FW_FIXUP_OR: ++ data |= __le16_to_cpu(fix->setting.data); ++ break; ++ case FW_FIXUP_NOT: ++ data &= ~__le16_to_cpu(fix->setting.data); ++ break; ++ case FW_FIXUP_XOR: ++ data ^= __le16_to_cpu(fix->setting.data); ++ break; ++ default: ++ return; ++ } ++ ++ ocp_reg_write(tp, addr, data); ++ ++ dev_dbg(&tp->intf->dev, "applied ocp %x %x\n", addr, data); ++} ++ ++static void rtl8152_fw_phy_union_apply(struct r8152 *tp, struct fw_phy_union *phy) ++{ ++ __le16 *data; ++ u32 length; ++ int i, num; ++ ++ num = phy->pre_num; ++ for (i = 0; i < num; i++) ++ sram_write(tp, __le16_to_cpu(phy->pre_set[i].addr), ++ __le16_to_cpu(phy->pre_set[i].data)); ++ ++ length = __le32_to_cpu(phy->blk_hdr.length); ++ length -= __le16_to_cpu(phy->fw_offset); ++ num = length / 2; ++ data = (__le16 *)((u8 *)phy + __le16_to_cpu(phy->fw_offset)); ++ ++ ocp_reg_write(tp, OCP_SRAM_ADDR, __le16_to_cpu(phy->fw_reg)); ++ for (i = 0; i < num; i++) ++ ocp_reg_write(tp, OCP_SRAM_DATA, __le16_to_cpu(data[i])); ++ ++ num = phy->bp_num; ++ for (i = 0; i < num; i++) ++ sram_write(tp, __le16_to_cpu(phy->bp[i].addr), __le16_to_cpu(phy->bp[i].data)); ++ ++ if (phy->bp_num && phy->bp_en.addr) ++ sram_write(tp, __le16_to_cpu(phy->bp_en.addr), __le16_to_cpu(phy->bp_en.data)); ++ ++ dev_dbg(&tp->intf->dev, "successfully applied %s\n", phy->info); ++} ++ + static void rtl8152_fw_phy_nc_apply(struct r8152 *tp, struct fw_phy_nc *phy) + { + u16 mode_reg, bp_index; +@@ -4444,6 +4948,12 @@ static void rtl8152_fw_mac_apply(struct + return; + } + ++ fw_ver_reg = __le16_to_cpu(mac->fw_ver_reg); ++ if (fw_ver_reg && ocp_read_byte(tp, MCU_TYPE_USB, fw_ver_reg) >= mac->fw_ver_data) { ++ dev_dbg(&tp->intf->dev, "%s firmware has been the newest\n", type ? "PLA" : "USB"); ++ return; ++ } ++ + rtl_clear_bp(tp, type); + + /* Enable backup/restore of MACDBG. This is required after clearing PLA +@@ -4479,7 +4989,6 @@ static void rtl8152_fw_mac_apply(struct + ocp_write_word(tp, type, bp_en_addr, + __le16_to_cpu(mac->bp_en_value)); + +- fw_ver_reg = __le16_to_cpu(mac->fw_ver_reg); + if (fw_ver_reg) + ocp_write_byte(tp, MCU_TYPE_USB, fw_ver_reg, + mac->fw_ver_data); +@@ -4494,7 +5003,7 @@ static void rtl8152_apply_firmware(struc + struct fw_header *fw_hdr; + struct fw_phy_patch_key *key; + u16 key_addr = 0; +- int i; ++ int i, patch_phy = 1; + + if (IS_ERR_OR_NULL(rtl_fw->fw)) + return; +@@ -4516,17 +5025,40 @@ static void rtl8152_apply_firmware(struc + rtl8152_fw_mac_apply(tp, (struct fw_mac *)block); + break; + case RTL_FW_PHY_START: ++ if (!patch_phy) ++ break; + key = (struct fw_phy_patch_key *)block; + key_addr = __le16_to_cpu(key->key_reg); + rtl_pre_ram_code(tp, key_addr, __le16_to_cpu(key->key_data), !power_cut); + break; + case RTL_FW_PHY_STOP: ++ if (!patch_phy) ++ break; + WARN_ON(!key_addr); + rtl_post_ram_code(tp, key_addr, !power_cut); + break; + case RTL_FW_PHY_NC: + rtl8152_fw_phy_nc_apply(tp, (struct fw_phy_nc *)block); + break; ++ case RTL_FW_PHY_VER: ++ patch_phy = rtl8152_fw_phy_ver(tp, (struct fw_phy_ver *)block); ++ break; ++ case RTL_FW_PHY_UNION_NC: ++ case RTL_FW_PHY_UNION_NC1: ++ case RTL_FW_PHY_UNION_NC2: ++ case RTL_FW_PHY_UNION_UC2: ++ case RTL_FW_PHY_UNION_UC: ++ case RTL_FW_PHY_UNION_MISC: ++ if (patch_phy) ++ rtl8152_fw_phy_union_apply(tp, (struct fw_phy_union *)block); ++ break; ++ case RTL_FW_PHY_FIXUP: ++ if (patch_phy) ++ rtl8152_fw_phy_fixup(tp, (struct fw_phy_fixup *)block); ++ break; ++ case RTL_FW_PHY_SPEED_UP: ++ rtl_ram_code_speed_up(tp, (struct fw_phy_speed_up *)block, !power_cut); ++ break; + default: + break; + } +@@ -5034,6 +5566,21 @@ static int r8153c_post_firmware_1(struct + return 0; + } + ++static int r8156a_post_firmware_1(struct r8152 *tp) ++{ ++ u32 ocp_data; ++ ++ ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_FW_FIX_EN1); ++ ocp_data |= FW_IP_RESET_EN; ++ ocp_write_word(tp, MCU_TYPE_USB, USB_FW_FIX_EN1, ocp_data); ++ ++ /* Modify U3PHY parameter for compatibility issue */ ++ ocp_write_dword(tp, MCU_TYPE_USB, USB_UPHY3_MDCMDIO, 0x4026840e); ++ ocp_write_dword(tp, MCU_TYPE_USB, USB_UPHY3_MDCMDIO, 0x4001acc9); ++ ++ return 0; ++} ++ + static void r8153_aldps_en(struct r8152 *tp, bool enable) + { + u16 data; +@@ -8674,12 +9221,16 @@ static int rtl_ops_init(struct r8152 *tp + #define FIRMWARE_8153A_4 "rtl_nic/rtl8153a-4.fw" + #define FIRMWARE_8153B_2 "rtl_nic/rtl8153b-2.fw" + #define FIRMWARE_8153C_1 "rtl_nic/rtl8153c-1.fw" ++#define FIRMWARE_8156A_2 "rtl_nic/rtl8156a-2.fw" ++#define FIRMWARE_8156B_2 "rtl_nic/rtl8156b-2.fw" + + MODULE_FIRMWARE(FIRMWARE_8153A_2); + MODULE_FIRMWARE(FIRMWARE_8153A_3); + MODULE_FIRMWARE(FIRMWARE_8153A_4); + MODULE_FIRMWARE(FIRMWARE_8153B_2); + MODULE_FIRMWARE(FIRMWARE_8153C_1); ++MODULE_FIRMWARE(FIRMWARE_8156A_2); ++MODULE_FIRMWARE(FIRMWARE_8156B_2); + + static int rtl_fw_init(struct r8152 *tp) + { +@@ -8705,6 +9256,14 @@ static int rtl_fw_init(struct r8152 *tp) + rtl_fw->pre_fw = r8153b_pre_firmware_1; + rtl_fw->post_fw = r8153b_post_firmware_1; + break; ++ case RTL_VER_11: ++ rtl_fw->fw_name = FIRMWARE_8156A_2; ++ rtl_fw->post_fw = r8156a_post_firmware_1; ++ break; ++ case RTL_VER_13: ++ case RTL_VER_15: ++ rtl_fw->fw_name = FIRMWARE_8156B_2; ++ break; + case RTL_VER_14: + rtl_fw->fw_name = FIRMWARE_8153C_1; + rtl_fw->pre_fw = r8153b_pre_firmware_1; diff --git a/target/linux/generic/backport-5.10/795-v5.13-r8152-search-the-configuration-of-vendor-mode.patch b/target/linux/generic/backport-5.10/795-v5.13-r8152-search-the-configuration-of-vendor-mode.patch new file mode 100644 index 0000000000..9ce0e778cf --- /dev/null +++ b/target/linux/generic/backport-5.10/795-v5.13-r8152-search-the-configuration-of-vendor-mode.patch @@ -0,0 +1,79 @@ +From 579f58dd2819910354753bc5489fc1588fe9cfe2 Mon Sep 17 00:00:00 2001 +From: Hayes Wang +Date: Fri, 16 Apr 2021 16:04:37 +0800 +Subject: [PATCH] r8152: search the configuration of vendor mode + +commit c2198943e33b100ed21dfb636c8fa6baef841e9d upstream. + +The vendor mode is not always at config #1, so it is necessary to +set the correct configuration number. + +Signed-off-by: Hayes Wang +Signed-off-by: David S. Miller +--- + drivers/net/usb/r8152.c | 39 +++++++++++++++++++++++++++++++++++---- + 1 file changed, 35 insertions(+), 4 deletions(-) + +--- a/drivers/net/usb/r8152.c ++++ b/drivers/net/usb/r8152.c +@@ -30,7 +30,7 @@ + #include + + /* Information for net-next */ +-#define NETNEXT_VERSION "11" ++#define NETNEXT_VERSION "12" + + /* Information for net */ + #define NET_VERSION "11" +@@ -8131,6 +8131,39 @@ static void r8156b_init(struct r8152 *tp + tp->coalesce = 15000; /* 15 us */ + } + ++static bool rtl_vendor_mode(struct usb_interface *intf) ++{ ++ struct usb_host_interface *alt = intf->cur_altsetting; ++ struct usb_device *udev; ++ struct usb_host_config *c; ++ int i, num_configs; ++ ++ if (alt->desc.bInterfaceClass == USB_CLASS_VENDOR_SPEC) ++ return true; ++ ++ /* The vendor mode is not always config #1, so to find it out. */ ++ udev = interface_to_usbdev(intf); ++ c = udev->config; ++ num_configs = udev->descriptor.bNumConfigurations; ++ for (i = 0; i < num_configs; (i++, c++)) { ++ struct usb_interface_descriptor *desc = NULL; ++ ++ if (c->desc.bNumInterfaces > 0) ++ desc = &c->intf_cache[0]->altsetting->desc; ++ else ++ continue; ++ ++ if (desc->bInterfaceClass == USB_CLASS_VENDOR_SPEC) { ++ usb_driver_set_configuration(udev, c->desc.bConfigurationValue); ++ break; ++ } ++ } ++ ++ WARN_ON_ONCE(i == num_configs); ++ ++ return false; ++} ++ + static int rtl8152_pre_reset(struct usb_interface *intf) + { + struct r8152 *tp = usb_get_intfdata(intf); +@@ -9369,10 +9402,8 @@ static int rtl8152_probe(struct usb_inte + if (version == RTL_VER_UNKNOWN) + return -ENODEV; + +- if (udev->actconfig->desc.bConfigurationValue != 1) { +- usb_driver_set_configuration(udev, 1); ++ if (!rtl_vendor_mode(intf)) + return -ENODEV; +- } + + if (intf->cur_altsetting->desc.bNumEndpoints < 3) + return -ENODEV;