mirror of
https://github.com/openwrt/openwrt.git
synced 2024-12-22 15:02:32 +00:00
135 lines
3.9 KiB
Diff
135 lines
3.9 KiB
Diff
|
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);
|