aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/bcm27xx/patches-5.10/950-0547-r8152-adjust-the-flow-of-power-cut-for-RTL8153B.patch
diff options
context:
space:
mode:
Diffstat (limited to 'target/linux/bcm27xx/patches-5.10/950-0547-r8152-adjust-the-flow-of-power-cut-for-RTL8153B.patch')
-rw-r--r--target/linux/bcm27xx/patches-5.10/950-0547-r8152-adjust-the-flow-of-power-cut-for-RTL8153B.patch134
1 files changed, 134 insertions, 0 deletions
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
new file mode 100644
index 0000000000..9d12cb9761
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.10/950-0547-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 <hayeswang@realtek.com>
+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 <hayeswang@realtek.com>
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ 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
+@@ -1371,6 +1371,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);
+@@ -3182,8 +3186,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);
+
+@@ -3191,31 +3193,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);
+ }
+ }
+ }
+@@ -4587,13 +4578,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));
+
+@@ -5522,9 +5537,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);