From nobody Fri Sep 25 03:17:45 2026 Received: from rtits2.realtek.com.tw (rtits2.realtek.com [211.75.126.72]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 7DC2B46E011; Thu, 17 Sep 2026 07:07:39 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=211.75.126.72 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789628861; cv=none; b=n/iy8Yw3sC1McvhFHHGz63SvDkbWBVGEjCD19JBu6C4P5Vhjq1AQzBAIgkVOszEXgwg397HEatrCU2/2Yvg2z/xb5YFDR24hMgtmFS7RwdgZ4uMN0YUpASQNooAB/7urx3CiDnGKpBiy4Lu4YRXuiiTcvDkncb6wt0mwPRND9sk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789628861; c=relaxed/simple; bh=7fXnlH6xR/PmRmZBiOc0paMtU6kWmwZ2lBnz2YRzHNk=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=cvYKEznNv2NfD7L9mA3oe1aGrSTgpIsJzsnr/HXtlf2GxFyWIBSNvk4FLS1DC+NRzVQVTtvTF7iSS4fgBq0OGae3K4Emqv7PPc2Fr1uBdPJzjNdx2WbCgHrHg3v0l/Z9L09xYafUwVAO0ofMYN+OqRpsuVnpVVXrCnqqxWOp/Cw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=realtek.com; spf=pass smtp.mailfrom=realtek.com; dkim=pass (2048-bit key) header.d=realtek.com header.i=@realtek.com header.b=f6dByTzr; arc=none smtp.client-ip=211.75.126.72 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=realtek.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=realtek.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=realtek.com header.i=@realtek.com header.b="f6dByTzr" X-SpamFilter-By: ArmorX SpamTrap 5.80 with qID 68H76fc363094124, This message is accepted by code: ctloc85258 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=realtek.com; s=dkim; t=1789628801; bh=ACkFS5sdyNlrqEQEi0sMIksQ3wiqDCYPIgNKf/VMSK8=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Transfer-Encoding:Content-Type; b=f6dByTzru7e/llLypyMvWMNQSFauvi/XPiOFBKgamQ0tJkbX1PXXGTwu0G9i3/zUE En8CcngKHIdscc5+JQIWSebA+wkWmZKsKqgHEVyHiP5DEXqkqZ5qaqy1aC5w+Uh7+D ILn0JaH3BUfXmQehZKag3RT9JSlo8d4llm6EA+B/nIAzRBK9ShkkD/Job7FtQQYxl0 b8qM12IBUfL9aYMU4ZACSE4k/6Uf6xnfA09MfXHDlvx8T2k6PwenWjJA+gNjOraQlr LicXVju/aqxyKiIZfz48YPtyZCVKTeSBZGbykC1fG53xhSuovZhEswHD8JjGioTzqD RYkTmbjo+9yJg== Received: from mail.realtek.com (rtkexhmbs02.realtek.com.tw[172.21.6.41]) by rtits2.realtek.com.tw (8.15.2/3.29/5.94) with ESMTPS id 68H76fc363094124 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL); Thu, 17 Sep 2026 15:06:41 +0800 Received: from RTKEXHMBS04.realtek.com.tw (10.21.1.54) by RTKEXHMBS02.realtek.com.tw (172.21.6.41) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.2562.49; Thu, 17 Sep 2026 15:06:39 +0800 Received: from fc44.realtek.com.tw (172.22.241.7) by RTKEXHMBS04.realtek.com.tw (10.21.1.54) with Microsoft SMTP Server id 15.2.2562.49 via Frontend Transport; Thu, 17 Sep 2026 15:06:39 +0800 From: Chih Kai Hsu To: , CC: , , , , , , , , Subject: [PATCH net-next v4 1/8] r8152: split r8156_init per chip and add missing init writes Date: Thu, 17 Sep 2026 15:06:30 +0800 Message-ID: <20260917070637.62827-2-nic_swsd@realtek.com> X-Mailer: git-send-email 2.54.0 In-Reply-To: <20260917070637.62827-1-nic_swsd@realtek.com> References: <20260917070637.62827-1-nic_swsd@realtek.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" RTL8156, RTL8156B, RTL8157 and RTL8159 shared a single r8156_init(), gated by a dense set of tp->version range checks. That made the init sequence hard to follow, and some checks (e.g. the FC-timer block, which was fenced to "RTL_VER_12 <=3D version <=3D RTL_VER_15") silently skipped RTL8156 (VER_10/11) and RTL8157/RTL8159 (VER_16/17) altogether even though nothing chip-specific justified the gap. Split r8156_init() into one function per chip family: - r8156_init (VER_10/11) - r8156b_init (VER_12/13/15) - r8157_init (VER_16) - r8159_init (VER_17) While splitting: - Factor the repeated "poll PLA_BOOT_CTRL for AUTOLOAD_DONE" loop into wait_autoload_done(), reusing read_poll_timeout() instead of the ad-hoc 500 * msleep(20) busy loops. r8153_init(), r8153b_init(), r8153c_init(), r8153b_ups_en() and r8153c_ups_en() are converted to use it too. wait_autoload_done() only reports failure (nonzero) when RTL8152_INACCESSIBLE is set; a plain AUTOLOAD_DONE timeout is logged but otherwise treated as success, same as every one of the loops it replaces, which only bailed out early on RTL8152_INACCESSIBLE and simply fell through to the rest of the init sequence on their own timeout. This matters because the two failure modes are not equivalent: once RTL8152_INACCESSIBLE is set, generic_ocp_read()/generic_ocp_write() short-circuit to -ENODEV without touching the device, so every OCP access in the remaining init sequence becomes a no-op and returning early costs nothing. A plain timeout, on the other hand, means the device is still reachable, so skipping the rest of a chip bring-up sequence would leave real hardware state half-configured -- keeping going and letting each subsequent access fail or succeed on its own is safer than aborting mid-sequence. - Add PLA_RMT_WAKE (RMT_WAKE_EN) and PLA_INDICATE_FALG's PREBOOT_OPTION bit, and clear both from every split init function. Neither bit was ever touched by the previous shared r8156_init(). - Add r8156b_u2phy_backup(), a new sequence of OCP writes to 0xd3ce/0xd3d0/0xd3d4/0xd3d8/0xd3dc, called only from r8156b_init(). - Explicitly clear AUTO_SPEEDUP as its own write in r8156b_init(), r8157_init() and r8159_init(), instead of folding it into the FLOW_CTRL_PATCH_2 read-modify-write that only ran for VER_12-15. This means RTL8157/RTL8159 (r8157_init/r8159_init) now also clear AUTO_SPEEDUP during init, which the old shared function never did for them. - Add "disable Interrupt Mitigation" (0xcf04, bits 0/1/2/7) to r8157_init() and r8159_init(). This write previously only existed in rtl8153_unload() for VER_16/17; it is now also applied during init. - Add "clear Warm RST / Bus RST event flag" (0xcd06 BIT(11)) to r8157_init() and r8159_init(), and r8159_init()-only "disable FW u1u2 patch option" (0xb9a6 BIT(0)) and "enable u3phy patch backup" (0xb9a2 =3D 0x0448). None of these existed in the previous shared function. Signed-off-by: Chih Kai Hsu --- drivers/net/usb/r8152.c | 489 ++++++++++++++++++++++++++++------------ 1 file changed, 350 insertions(+), 139 deletions(-) diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c index af3d7dcb2f141..00b0fda306c30 100644 --- a/drivers/net/usb/r8152.c +++ b/drivers/net/usb/r8152.c @@ -78,6 +78,7 @@ #define PLA_EEE_TXTWSYS_2P5G 0xe058 #define PLA_EEEP_CR 0xe080 #define PLA_MAC_PWR_CTRL 0xe0c0 +#define PLA_RMT_WAKE 0xe0c8 #define PLA_MAC_PWR_CTRL2 0xe0ca #define PLA_MAC_PWR_CTRL3 0xe0cc #define PLA_MAC_PWR_CTRL4 0xe0ce @@ -371,6 +372,9 @@ #define MCU_CLK_RATIO_MASK 0x0f0f0f0f #define ALDPS_SPDWN_RATIO 0x0f87 =20 +/* PLA_RMT_WAKE */ +#define RMT_WAKE_EN BIT(0) + /* PLA_MAC_PWR_CTRL2 */ #define EEE_SPDWN_RATIO 0x8007 #define MAC_CLK_SPDWN_EN BIT(15) @@ -417,6 +421,7 @@ =20 /* PLA_INDICATE_FALG */ #define UPCOMING_RUNTIME_D3 BIT(0) +#define PREBOOT_OPTION BIT(1) =20 /* PLA_MACDBG_PRE and PLA_MACDBG_POST */ #define DEBUG_OE BIT(0) @@ -542,6 +547,7 @@ #define RX_AGG_DISABLE 0x0010 #define RX_ZERO_EN 0x0080 #define RX_DESC_16B 0x0400 +#define RX_END_TRANSFER_EN BIT(11) =20 /* USB_U2P3_CTRL */ #define U2P3_ENABLE 0x0001 @@ -4172,6 +4178,23 @@ static u16 r8153_phy_status(struct r8152 *tp, u16 de= sired) return data; } =20 +static int wait_autoload_done(struct r8152 *tp) +{ + u16 ocp_data; + int ret; + + ret =3D read_poll_timeout(ocp_read_word, ocp_data, + test_bit(RTL8152_INACCESSIBLE, &tp->flags) || + (ocp_data & AUTOLOAD_DONE), + 20000, 10 * USEC_PER_SEC, false, tp, + MCU_TYPE_PLA, PLA_BOOT_CTRL); + + if (ret) + dev_err(&tp->intf->dev, "autoload done timeout\n"); + + return test_bit(RTL8152_INACCESSIBLE, &tp->flags) ? -ENODEV : 0; +} + static void r8153b_ups_en(struct r8152 *tp, bool enable) { if (enable) { @@ -4190,16 +4213,8 @@ static void r8153b_ups_en(struct r8152 *tp, bool ena= ble) UPS_FORCE_PWR_DOWN); =20 if (ocp_read_word(tp, MCU_TYPE_USB, USB_MISC_0) & PCUT_STATUS) { - int i; - - for (i =3D 0; i < 500; i++) { - if (test_bit(RTL8152_INACCESSIBLE, &tp->flags)) - return; - if (ocp_read_word(tp, MCU_TYPE_PLA, PLA_BOOT_CTRL) & - AUTOLOAD_DONE) - break; - msleep(20); - } + if (wait_autoload_done(tp)) + return; =20 tp->rtl_ops.hw_phy_cfg(tp); =20 @@ -4227,16 +4242,8 @@ static void r8153c_ups_en(struct r8152 *tp, bool ena= ble) UPS_FORCE_PWR_DOWN); =20 if (ocp_read_word(tp, MCU_TYPE_USB, USB_MISC_0) & PCUT_STATUS) { - int i; - - for (i =3D 0; i < 500; i++) { - if (test_bit(RTL8152_INACCESSIBLE, &tp->flags)) - return; - if (ocp_read_word(tp, MCU_TYPE_PLA, PLA_BOOT_CTRL) & - AUTOLOAD_DONE) - break; - msleep(20); - } + if (wait_autoload_done(tp)) + return; =20 tp->rtl_ops.hw_phy_cfg(tp); =20 @@ -7225,22 +7232,14 @@ static void r8152b_init(struct r8152 *tp) static void r8153_init(struct r8152 *tp) { u32 ocp_data; - int i; =20 if (test_bit(RTL8152_INACCESSIBLE, &tp->flags)) return; =20 r8153_u1u2en(tp, false); =20 - for (i =3D 0; i < 500; i++) { - if (ocp_read_word(tp, MCU_TYPE_PLA, PLA_BOOT_CTRL) & - AUTOLOAD_DONE) - break; - - msleep(20); - if (test_bit(RTL8152_INACCESSIBLE, &tp->flags)) - break; - } + if (wait_autoload_done(tp)) + return; =20 r8153_phy_status(tp, 0); =20 @@ -7341,22 +7340,13 @@ static void r8153_init(struct r8152 *tp) =20 static void r8153b_init(struct r8152 *tp) { - int i; - if (test_bit(RTL8152_INACCESSIBLE, &tp->flags)) return; =20 r8153b_u1u2en(tp, false); =20 - for (i =3D 0; i < 500; i++) { - if (ocp_read_word(tp, MCU_TYPE_PLA, PLA_BOOT_CTRL) & - AUTOLOAD_DONE) - break; - - msleep(20); - if (test_bit(RTL8152_INACCESSIBLE, &tp->flags)) - break; - } + if (wait_autoload_done(tp)) + return; =20 r8153_phy_status(tp, 0); =20 @@ -7411,8 +7401,6 @@ static void r8153b_init(struct r8152 *tp) =20 static void r8153c_init(struct r8152 *tp) { - int i; - if (test_bit(RTL8152_INACCESSIBLE, &tp->flags)) return; =20 @@ -7425,15 +7413,8 @@ static void r8153c_init(struct r8152 *tp) =20 ocp_word_set_bits(tp, MCU_TYPE_USB, 0xcbf0, BIT(1)); =20 - for (i =3D 0; i < 500; i++) { - if (ocp_read_word(tp, MCU_TYPE_PLA, PLA_BOOT_CTRL) & - AUTOLOAD_DONE) - break; - - msleep(20); - if (test_bit(RTL8152_INACCESSIBLE, &tp->flags)) - return; - } + if (wait_autoload_done(tp)) + return; =20 r8153_phy_status(tp, 0); =20 @@ -8330,90 +8311,132 @@ static void r8157_hw_phy_cfg(struct r8152 *tp) set_bit(PHY_RESET, &tp->flags); } =20 -static int r8159_wait_backup_restore(struct r8152 *tp) +static void r8156_init(struct r8152 *tp) { - u32 ocp_data; + u16 data; =20 - ocp_data =3D ocp_read_word(tp, MCU_TYPE_USB, USB_MISC_0); - if (!(ocp_data & PCUT_STATUS)) - return 0; + if (test_bit(RTL8152_INACCESSIBLE, &tp->flags)) + return; =20 - return poll_timeout_us(ocp_data =3D ocp_read_word(tp, MCU_TYPE_USB, USB_G= PHY_CTRL), - ocp_data & BACKUP_RESTRORE, 200, 20000, false); + ocp_byte_clr_bits(tp, MCU_TYPE_USB, USB_ECM_OP, EN_ALL_SPEED); + + ocp_write_word(tp, MCU_TYPE_USB, USB_SPEED_OPTION, 0); + + ocp_word_set_bits(tp, MCU_TYPE_USB, USB_ECM_OPTION, BYPASS_MAC_RESET); + + r8153b_u1u2en(tp, false); + + if (wait_autoload_done(tp)) + return; + + data =3D r8153_phy_status(tp, 0); + if (data =3D=3D PHY_STAT_EXT_INIT) + ocp_reg_clr_bits(tp, 0xa468, BIT(3) | BIT(1)); + + r8152_mdio_test_and_clr_bit(tp, MII_BMCR, BMCR_PDOWN); + + data =3D r8153_phy_status(tp, PHY_STAT_LAN_ON); + + r8153_u2p3en(tp, false); + + /* MSC timer =3D 0xfff * 8ms =3D 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); + + ocp_byte_clr_bits(tp, MCU_TYPE_PLA, PLA_INDICATE_FALG, PREBOOT_OPTION); + + ocp_byte_clr_bits(tp, MCU_TYPE_PLA, PLA_RMT_WAKE, RMT_WAKE_EN); + + if (tp->udev->speed >=3D USB_SPEED_SUPER) + r8153b_u1u2en(tp, true); + + usb_enable_lpm(tp->udev); + + r8156_mac_clk_spd(tp, true); + + ocp_word_clr_bits(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL3, + PLA_MCU_SPDWN_EN); + + if (rtl8152_get_speed(tp) & LINK_STATUS) + ocp_word_set_bits(tp, MCU_TYPE_PLA, PLA_EXTRA_STATUS, + CUR_LINK_OK | POLL_LINK_CHG); + else + ocp_word_w0w1(tp, MCU_TYPE_PLA, PLA_EXTRA_STATUS, CUR_LINK_OK, + POLL_LINK_CHG); + + set_bit(GREEN_ETHERNET, &tp->flags); + + ocp_word_clr_bits(tp, MCU_TYPE_USB, USB_USB_CTRL, + RX_AGG_DISABLE | RX_ZERO_EN); + + ocp_byte_set_bits(tp, MCU_TYPE_USB, USB_BMU_CONFIG, ACT_ODMA); + + r8156_mdio_force_mode(tp); + rtl_tally_reset(tp); + + tp->coalesce =3D 15000; /* 15 us */ } =20 -static void r8156_init(struct r8152 *tp) +static void r8156b_u2phy_backup(struct r8152 *tp) +{ + ocp_write_word(tp, MCU_TYPE_USB, 0xd3ce, 0x181b); + ocp_write_dword(tp, MCU_TYPE_USB, 0xd3d0, 0x616ccd99); + ocp_write_dword(tp, MCU_TYPE_USB, 0xd3d4, 0x08fc8101); + ocp_write_dword(tp, MCU_TYPE_USB, 0xd3d8, 0x159b1100); + ocp_write_word(tp, MCU_TYPE_USB, 0xd3dc, 0x0a00); +} + +static void r8156b_init(struct r8152 *tp) { u32 ocp_data; u16 data; - int i; =20 if (test_bit(RTL8152_INACCESSIBLE, &tp->flags)) return; =20 - if (tp->version =3D=3D RTL_VER_16 || tp->version =3D=3D RTL_VER_17) { - ocp_byte_set_bits(tp, MCU_TYPE_USB, 0xcffe, BIT(3)); - ocp_byte_clr_bits(tp, MCU_TYPE_USB, 0xd3ca, BIT(0)); - } - ocp_byte_clr_bits(tp, MCU_TYPE_USB, USB_ECM_OP, EN_ALL_SPEED); =20 - if (tp->version < RTL_VER_16) - ocp_write_word(tp, MCU_TYPE_USB, USB_SPEED_OPTION, 0); + ocp_write_word(tp, MCU_TYPE_USB, USB_SPEED_OPTION, 0); =20 ocp_word_set_bits(tp, MCU_TYPE_USB, USB_ECM_OPTION, BYPASS_MAC_RESET); =20 - if (tp->version >=3D RTL_VER_12 && tp->version <=3D RTL_VER_15) - ocp_word_set_bits(tp, MCU_TYPE_USB, USB_U2P3_CTRL, RX_DETECT8); + ocp_word_set_bits(tp, MCU_TYPE_USB, USB_U2P3_CTRL, RX_DETECT8); =20 r8153b_u1u2en(tp, false); =20 switch (tp->version) { case RTL_VER_13: case RTL_VER_15: - case RTL_VER_16: - case RTL_VER_17: r8156b_wait_loading_flash(tp); break; default: break; } =20 - for (i =3D 0; i < 500; i++) { - if (ocp_read_word(tp, MCU_TYPE_PLA, PLA_BOOT_CTRL) & - AUTOLOAD_DONE) - break; - - msleep(20); - if (test_bit(RTL8152_INACCESSIBLE, &tp->flags)) - return; - } - - if (tp->version =3D=3D RTL_VER_17 && r8159_wait_backup_restore(tp)) { - rtl_set_inaccessible(tp); - dev_err(&tp->intf->dev, "init failed, backup-restore timed out\n"); + if (wait_autoload_done(tp)) return; - } =20 data =3D r8153_phy_status(tp, 0); if (data =3D=3D PHY_STAT_EXT_INIT) { ocp_reg_clr_bits(tp, 0xa468, BIT(3) | BIT(1)); - if (tp->version >=3D RTL_VER_12) - ocp_reg_clr_bits(tp, 0xa466, BIT(0)); + ocp_reg_clr_bits(tp, 0xa466, BIT(0)); } =20 - data =3D r8152_mdio_read(tp, MII_BMCR); - if (data & BMCR_PDOWN) { - data &=3D ~BMCR_PDOWN; - r8152_mdio_write(tp, MII_BMCR, data); - } + r8152_mdio_test_and_clr_bit(tp, MII_BMCR, BMCR_PDOWN); =20 data =3D r8153_phy_status(tp, PHY_STAT_LAN_ON); =20 - if (tp->version >=3D RTL_VER_16) - r8157_u2p3en(tp, false); - else - r8153_u2p3en(tp, false); + r8153_u2p3en(tp, false); + + /* Disable Auto Speed up */ + ocp_word_clr_bits(tp, MCU_TYPE_USB, USB_FW_CTRL, AUTO_SPEEDUP); =20 /* MSC timer =3D 0xfff * 8ms =3D 32760 ms */ ocp_write_word(tp, MCU_TYPE_USB, USB_MSC_TIMER, 0x0fff); @@ -8421,73 +8444,261 @@ static void r8156_init(struct r8152 *tp) /* U1/U2/L1 idle timer. 500 us */ ocp_write_word(tp, MCU_TYPE_USB, USB_U1U2_TIMER, 500); =20 - if (tp->version >=3D RTL_VER_16) - r8157_power_cut_en(tp, false); - else - r8153b_power_cut_en(tp, false); + r8156b_u2phy_backup(tp); =20 + r8153b_power_cut_en(tp, false); r8156_ups_en(tp, false); r8153_queue_wake(tp, false); rtl_runtime_suspend_enable(tp, false); =20 + ocp_byte_clr_bits(tp, MCU_TYPE_PLA, PLA_INDICATE_FALG, PREBOOT_OPTION); + + ocp_byte_clr_bits(tp, MCU_TYPE_PLA, PLA_RMT_WAKE, RMT_WAKE_EN); + if (tp->udev->speed >=3D USB_SPEED_SUPER) r8153b_u1u2en(tp, true); =20 usb_enable_lpm(tp->udev); =20 - if (tp->version >=3D RTL_VER_12 && tp->version <=3D RTL_VER_15) { - ocp_word_clr_bits(tp, MCU_TYPE_PLA, PLA_RCR, SLOT_EN); + ocp_word_clr_bits(tp, MCU_TYPE_PLA, PLA_RCR, SLOT_EN); =20 - ocp_word_set_bits(tp, MCU_TYPE_PLA, PLA_CPCR, FLOW_CTRL_EN); + ocp_word_set_bits(tp, MCU_TYPE_PLA, PLA_CPCR, FLOW_CTRL_EN); =20 - /* enable fc timer and set timer to 600 ms. */ - ocp_write_word(tp, MCU_TYPE_USB, USB_FC_TIMER, CTRL_TIMER_EN | (600 / 8)= ); + /* enable fc timer and set timer to 600 ms. */ + ocp_write_word(tp, MCU_TYPE_USB, USB_FC_TIMER, + CTRL_TIMER_EN | (600 / 8)); =20 - ocp_data =3D 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 |=3D FLOW_CTRL_PATCH_2; - ocp_data &=3D ~AUTO_SPEEDUP; - ocp_write_word(tp, MCU_TYPE_USB, USB_FW_CTRL, ocp_data); + ocp_data =3D ocp_read_word(tp, MCU_TYPE_PLA, PLA_POL_GPIO_CTRL); + if (!(ocp_data & DACK_DET_EN)) + ocp_word_set_bits(tp, MCU_TYPE_USB, USB_FW_CTRL, + FLOW_CTRL_PATCH_2); =20 - ocp_word_set_bits(tp, MCU_TYPE_USB, USB_FW_TASK, FC_PATCH_TASK); - } + ocp_word_set_bits(tp, MCU_TYPE_USB, USB_FW_TASK, FC_PATCH_TASK); =20 r8156_mac_clk_spd(tp, true); =20 - if (tp->version < RTL_VER_16) - ocp_word_clr_bits(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL3, PLA_MCU_SPDWN_EN); + ocp_word_clr_bits(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL3, + PLA_MCU_SPDWN_EN); =20 - ocp_data =3D ocp_read_word(tp, MCU_TYPE_PLA, PLA_EXTRA_STATUS); if (rtl8152_get_speed(tp) & LINK_STATUS) - ocp_data |=3D CUR_LINK_OK; + ocp_word_set_bits(tp, MCU_TYPE_PLA, PLA_EXTRA_STATUS, + CUR_LINK_OK | POLL_LINK_CHG); else - ocp_data &=3D ~CUR_LINK_OK; - ocp_data |=3D POLL_LINK_CHG; - ocp_write_word(tp, MCU_TYPE_PLA, PLA_EXTRA_STATUS, ocp_data); + ocp_word_w0w1(tp, MCU_TYPE_PLA, PLA_EXTRA_STATUS, + CUR_LINK_OK, POLL_LINK_CHG); =20 set_bit(GREEN_ETHERNET, &tp->flags); =20 - /* RX aggregation / 16 bytes RX descriptor - * BIT(11) is specific to RTL8159, with unknown meaning - */ - if (tp->version =3D=3D RTL_VER_17) - ocp_word_clr_bits(tp, MCU_TYPE_USB, USB_USB_CTRL, - RX_AGG_DISABLE | RX_DESC_16B | BIT(11)); - else if (tp->version =3D=3D RTL_VER_16) - ocp_word_clr_bits(tp, MCU_TYPE_USB, USB_USB_CTRL, RX_AGG_DISABLE | RX_DE= SC_16B); + ocp_word_clr_bits(tp, MCU_TYPE_USB, USB_USB_CTRL, + RX_AGG_DISABLE | RX_ZERO_EN); + + r8156_mdio_force_mode(tp); + rtl_tally_reset(tp); + + tp->coalesce =3D 15000; /* 15 us */ +} + +static void r8157_init(struct r8152 *tp) +{ + u16 data; + + if (test_bit(RTL8152_INACCESSIBLE, &tp->flags)) + return; + + /* Enable SW reset */ + ocp_byte_set_bits(tp, MCU_TYPE_USB, 0xcffe, BIT(3)); + ocp_byte_clr_bits(tp, MCU_TYPE_USB, 0xd3ca, BIT(0)); + + ocp_byte_clr_bits(tp, MCU_TYPE_USB, USB_ECM_OP, EN_ALL_SPEED); + + ocp_word_set_bits(tp, MCU_TYPE_USB, USB_ECM_OPTION, BYPASS_MAC_RESET); + + r8153b_u1u2en(tp, false); + + if (wait_autoload_done(tp)) + return; + + r8156b_wait_loading_flash(tp); + + data =3D r8153_phy_status(tp, 0); + if (data =3D=3D PHY_STAT_EXT_INIT) { + ocp_reg_clr_bits(tp, 0xa468, BIT(3) | BIT(1)); + ocp_reg_clr_bits(tp, 0xa466, BIT(0)); + } + + r8152_mdio_test_and_clr_bit(tp, MII_BMCR, BMCR_PDOWN); + + data =3D r8153_phy_status(tp, PHY_STAT_LAN_ON); + + r8157_u2p3en(tp, false); + + /* Disable Interrupt Mitigation */ + ocp_byte_clr_bits(tp, MCU_TYPE_USB, 0xcf04, + BIT(0) | BIT(1) | BIT(2) | BIT(7)); + + /* Disable Auto Speed up */ + ocp_word_clr_bits(tp, MCU_TYPE_USB, USB_FW_CTRL, AUTO_SPEEDUP); + + /* MSC timer =3D 0xfff * 8ms =3D 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); + + r8157_power_cut_en(tp, false); + r8156_ups_en(tp, false); + r8153_queue_wake(tp, false); + rtl_runtime_suspend_enable(tp, false); + + ocp_byte_clr_bits(tp, MCU_TYPE_PLA, PLA_INDICATE_FALG, PREBOOT_OPTION); + + ocp_byte_clr_bits(tp, MCU_TYPE_PLA, PLA_RMT_WAKE, RMT_WAKE_EN); + + /* Clear Warm RST / Bus RST event flag */ + ocp_word_clr_bits(tp, MCU_TYPE_USB, 0xcd06, BIT(11)); + + if (tp->udev->speed >=3D USB_SPEED_SUPER) + r8153b_u1u2en(tp, true); + + usb_enable_lpm(tp->udev); + + r8156_mac_clk_spd(tp, true); + + if (rtl8152_get_speed(tp) & LINK_STATUS) + ocp_word_set_bits(tp, MCU_TYPE_PLA, PLA_EXTRA_STATUS, + CUR_LINK_OK | POLL_LINK_CHG); else - ocp_word_clr_bits(tp, MCU_TYPE_USB, USB_USB_CTRL, RX_AGG_DISABLE | RX_ZE= RO_EN); + ocp_word_w0w1(tp, MCU_TYPE_PLA, PLA_EXTRA_STATUS, + CUR_LINK_OK, POLL_LINK_CHG); =20 - if (tp->version < RTL_VER_12) - ocp_byte_set_bits(tp, MCU_TYPE_USB, USB_BMU_CONFIG, ACT_ODMA); + set_bit(GREEN_ETHERNET, &tp->flags); =20 - if (tp->version >=3D RTL_VER_16) { - /* Disable Rx Zero Len */ - rtl_bmu_clr_bits(tp, 0x2300, BIT(3)); - /* TX descriptor Signature */ - ocp_byte_clr_bits(tp, MCU_TYPE_USB, 0xd4ae, BIT(1)); + /* RX aggregation / 16 bytes RX descriptor / Bulk In End transfer */ + ocp_word_clr_bits(tp, MCU_TYPE_USB, USB_USB_CTRL, + RX_AGG_DISABLE | RX_DESC_16B | RX_END_TRANSFER_EN); + + /* Disable Rx Zero Len */ + rtl_bmu_clr_bits(tp, 0x2300, BIT(3)); + + /* TX descriptor Signature */ + ocp_byte_clr_bits(tp, MCU_TYPE_USB, 0xd4ae, BIT(1)); + + r8156_mdio_force_mode(tp); + rtl_tally_reset(tp); + + tp->coalesce =3D 15000; /* 15 us */ +} + +static int r8159_wait_backup_restore(struct r8152 *tp) +{ + u32 ocp_data; + + ocp_data =3D ocp_read_word(tp, MCU_TYPE_USB, USB_MISC_0); + if (!(ocp_data & PCUT_STATUS)) + return 0; + + return poll_timeout_us(ocp_data =3D ocp_read_word(tp, MCU_TYPE_USB, USB_G= PHY_CTRL), + ocp_data & BACKUP_RESTRORE, 200, 20000, false); +} + +static void r8159_init(struct r8152 *tp) +{ + u16 data; + + if (test_bit(RTL8152_INACCESSIBLE, &tp->flags)) + return; + + /* Enable SW reset */ + ocp_byte_set_bits(tp, MCU_TYPE_USB, 0xcffe, BIT(3)); + ocp_byte_clr_bits(tp, MCU_TYPE_USB, 0xd3ca, BIT(0)); + + ocp_byte_clr_bits(tp, MCU_TYPE_USB, USB_ECM_OP, EN_ALL_SPEED); + + ocp_word_set_bits(tp, MCU_TYPE_USB, USB_ECM_OPTION, BYPASS_MAC_RESET); + + r8153b_u1u2en(tp, false); + + if (wait_autoload_done(tp)) + return; + + if (r8159_wait_backup_restore(tp)) { + rtl_set_inaccessible(tp); + dev_err(&tp->intf->dev, + "init failed, backup-restore timed out\n"); + return; } =20 + r8156b_wait_loading_flash(tp); + + data =3D r8153_phy_status(tp, 0); + if (data =3D=3D PHY_STAT_EXT_INIT) { + ocp_reg_clr_bits(tp, 0xa468, BIT(3) | BIT(1)); + ocp_reg_clr_bits(tp, 0xa466, BIT(0)); + } + + r8152_mdio_test_and_clr_bit(tp, MII_BMCR, BMCR_PDOWN); + + data =3D r8153_phy_status(tp, PHY_STAT_LAN_ON); + + r8157_u2p3en(tp, false); + + /* Disable Interrupt Mitigation */ + ocp_byte_clr_bits(tp, MCU_TYPE_USB, 0xcf04, + BIT(0) | BIT(1) | BIT(2) | BIT(7)); + + /* Disable Auto Speed up */ + ocp_word_clr_bits(tp, MCU_TYPE_USB, USB_FW_CTRL, AUTO_SPEEDUP); + + /* MSC timer =3D 0xfff * 8ms =3D 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); + + r8157_power_cut_en(tp, false); + r8156_ups_en(tp, false); + r8153_queue_wake(tp, false); + rtl_runtime_suspend_enable(tp, false); + + ocp_byte_clr_bits(tp, MCU_TYPE_PLA, PLA_INDICATE_FALG, PREBOOT_OPTION); + + ocp_byte_clr_bits(tp, MCU_TYPE_PLA, PLA_RMT_WAKE, RMT_WAKE_EN); + + /* Clear Warm RST / Bus RST event flag */ + ocp_word_clr_bits(tp, MCU_TYPE_USB, 0xcd06, BIT(11)); + + /* Disable FW u1u2 patch option */ + ocp_byte_clr_bits(tp, MCU_TYPE_USB, 0xb9a6, BIT(0)); + + if (tp->udev->speed >=3D USB_SPEED_SUPER) + r8153b_u1u2en(tp, true); + + usb_enable_lpm(tp->udev); + + r8156_mac_clk_spd(tp, true); + + if (rtl8152_get_speed(tp) & LINK_STATUS) + ocp_word_set_bits(tp, MCU_TYPE_PLA, PLA_EXTRA_STATUS, + CUR_LINK_OK | POLL_LINK_CHG); + else + ocp_word_w0w1(tp, MCU_TYPE_PLA, PLA_EXTRA_STATUS, + CUR_LINK_OK, POLL_LINK_CHG); + + set_bit(GREEN_ETHERNET, &tp->flags); + + /* RX aggregation / 16 bytes RX descriptor / Bulk In End transfer */ + ocp_word_clr_bits(tp, MCU_TYPE_USB, USB_USB_CTRL, + RX_AGG_DISABLE | RX_DESC_16B | RX_END_TRANSFER_EN); + + /* Disable Rx Zero Len */ + rtl_bmu_clr_bits(tp, 0x2300, BIT(3)); + + /* TX descriptor Signature */ + ocp_byte_clr_bits(tp, MCU_TYPE_USB, 0xd4ae, BIT(1)); + + /* Enable u3phy patch backup */ + ocp_write_word(tp, MCU_TYPE_USB, 0xb9a2, 0x0448); + r8156_mdio_force_mode(tp); rtl_tally_reset(tp); =20 @@ -9812,7 +10023,7 @@ static int rtl_ops_init(struct r8152 *tp) tp->eee_en =3D true; tp->eee_adv =3D MDIO_EEE_1000T | MDIO_EEE_100TX; tp->eee_adv2 =3D MDIO_EEE_2_5GT; - ops->init =3D r8156_init; + ops->init =3D r8156b_init; ops->enable =3D rtl8156_enable; ops->disable =3D rtl8153_disable; ops->up =3D rtl8156_up; @@ -9851,7 +10062,7 @@ static int rtl_ops_init(struct r8152 *tp) tp->eee_en =3D true; tp->eee_adv =3D MDIO_EEE_1000T | MDIO_EEE_100TX; tp->eee_adv2 =3D MDIO_EEE_2_5GT | MDIO_EEE_5GT; - ops->init =3D r8156_init; + ops->init =3D r8157_init; ops->enable =3D rtl8156_enable; ops->disable =3D rtl8153_disable; ops->up =3D rtl8156_up; @@ -9873,7 +10084,7 @@ static int rtl_ops_init(struct r8152 *tp) tp->eee_en =3D true; tp->eee_adv =3D MDIO_EEE_100TX | MDIO_EEE_1000T | MDIO_EEE_10GT; tp->eee_adv2 =3D MDIO_EEE_2_5GT | MDIO_EEE_5GT; - ops->init =3D r8156_init; + ops->init =3D r8159_init; ops->enable =3D rtl8156_enable; ops->disable =3D rtl8153_disable; ops->up =3D rtl8156_up; --=20 2.34.1 From nobody Fri Sep 25 03:17:45 2026 Received: from rtits2.realtek.com.tw (rtits2.realtek.com [211.75.126.72]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id B3EB43D0936; Thu, 17 Sep 2026 07:07:21 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=211.75.126.72 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789628843; cv=none; b=EDnBSzMumdMFQt5PHnngsSlM8bH4JYKynoJbGIwOamQHBk4kZhBAWMjkzB51Gf7RdRAZbuJsGz1MiLt0sos0f9waoM5IgyJL5cy6Zjn7PjBoEHiKGH23P7Fy7sBNOzgfOqIlkPmTMLg2lOjKvJkpOfADWSQ9w6/sDBzA7WCYF0o= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789628843; c=relaxed/simple; bh=cp+kqFlCMKvNqatUM4HTuX6XlHJbXyPiTtD9BCc+GDU=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=pc3DkWd8gSu92kzSfkqPqJIjudftrXvvm14JIyqB6fIwkxAm5w6XUjtHvO9NQQ4S8RJN5mtXATy0tIA7qolPPzxCjjoeMahwRIlnM2GMhm3xVcqd8Q8K8kH5B8ONimWMH93mKJeQIl9/EBO5ug2pq2PjRLu+XzjINAcsUPZQ1hA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=realtek.com; spf=pass smtp.mailfrom=realtek.com; dkim=pass (2048-bit key) header.d=realtek.com header.i=@realtek.com header.b=rFfxiD5Z; arc=none smtp.client-ip=211.75.126.72 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=realtek.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=realtek.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=realtek.com header.i=@realtek.com header.b="rFfxiD5Z" X-SpamFilter-By: ArmorX SpamTrap 5.80 with qID 68H76fc463094124, This message is accepted by code: ctloc85258 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=realtek.com; s=dkim; t=1789628801; bh=nXT5GeqaDozveL6JkNVo+uFAjY/lDt+QRSKu7g3cBnw=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Transfer-Encoding:Content-Type; b=rFfxiD5Z1uwT562lSem+zNiNSbJwFdGBhfXPawLhjibdoOY3Je4Vhcd2wKvsAeBxR LF7iPo+QPQgidrPXKzpFk90ghhYICIQt03E+xAmdD46gDPGksKvkb6iqNW7Jm0x+AZ 4zIWOsOa0M0VevHCISjv9vqBMfJ4p+ZqejUAz/9J0AH0BGemsjGZ+mLRVMCgDFqq2c sRWwdBuXFhXAgcluFH7a3np17wbr4VXHLxpcqdbc4m9LnqD4PHc8AjV3f8aCWHy0on p40wrDlobm7Pxj9T3e4e2eNGV6teASkQLfeAPEXirxroL0yqkorfArECkF+xKqcH9C 1XmKDp1dYqKDQ== Received: from mail.realtek.com (rtkexhmbs02.realtek.com.tw[172.21.6.41]) by rtits2.realtek.com.tw (8.15.2/3.29/5.94) with ESMTPS id 68H76fc463094124 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL); Thu, 17 Sep 2026 15:06:41 +0800 Received: from RTKEXHMBS04.realtek.com.tw (10.21.1.54) by RTKEXHMBS02.realtek.com.tw (172.21.6.41) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.2562.49; Thu, 17 Sep 2026 15:06:40 +0800 Received: from fc44.realtek.com.tw (172.22.241.7) by RTKEXHMBS04.realtek.com.tw (10.21.1.54) with Microsoft SMTP Server id 15.2.2562.49 via Frontend Transport; Thu, 17 Sep 2026 15:06:40 +0800 From: Chih Kai Hsu To: , CC: , , , , , , , , Subject: [PATCH net-next v4 2/8] r8152: split RTL_VER_17 into QFN68 and QFN100 package variants Date: Thu, 17 Sep 2026 15:06:31 +0800 Message-ID: <20260917070637.62827-3-nic_swsd@realtek.com> X-Mailer: git-send-email 2.54.0 In-Reply-To: <20260917070637.62827-1-nic_swsd@realtek.com> References: <20260917070637.62827-1-nic_swsd@realtek.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" RTL8159 is sold in two packages, QFN68 and QFN100, which need different PHY tuning (added in a later patch) and a package-specific u2phy backup-restore patch. There was previously no way to tell the two apart at runtime, since both used the same RTL_VER_17. Split RTL_VER_17 into RTL_VER_17_QFN68 and RTL_VER_17_QFN100 and update every switch/case on RTL_VER_17 in the driver to handle both. Detect the package by reading the new PLA_PKG_DET register (0xdc48, masked with PKG_MASK =3D 0x1e) via a new __rtl_get_pkg_det() helper, called from __rtl_get_hw_ver() when the chip ID is 0x2020: pkg_det value 0x1e/0x1c selects QFN68, 0x18/0x1a selects QFN100, and any other value logs "Unknown package" and falls back to RTL_VER_UNKNOWN. r8159_init() gains a QFN68-only write ("Enable u2phy backup restore patch", 0xb99c BIT(0)) that does not apply to QFN100. Signed-off-by: Chih Kai Hsu --- drivers/net/usb/r8152.c | 93 ++++++++++++++++++++++++++++++++++------- 1 file changed, 78 insertions(+), 15 deletions(-) diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c index 00b0fda306c30..9ce072c38b5b5 100644 --- a/drivers/net/usb/r8152.c +++ b/drivers/net/usb/r8152.c @@ -64,6 +64,7 @@ #define PLA_MACDBG_POST 0xd38e /* RTL_VER_04 only */ #define PLA_EXTRA_STATUS 0xd398 #define PLA_GPHY_CTRL 0xd3ae +#define PLA_PKG_DET 0xdc48 #define PLA_POL_GPIO_CTRL 0xdc6a #define PLA_EFUSE_DATA 0xdd00 #define PLA_EFUSE_CMD 0xdd02 @@ -290,6 +291,9 @@ #define IFG_144NS BIT(9) #define IFG_96NS (BIT(9) | BIT(8)) =20 +/* PLA_PKG_DET */ +#define PKG_MASK 0x1e + /* PLA_MTPS */ #define MTPS_JUMBO (12 * 1024 / 64) #define MTPS_DEFAULT (6 * 1024 / 64) @@ -1253,7 +1257,8 @@ enum rtl_version { RTL_VER_14, RTL_VER_15, RTL_VER_16, - RTL_VER_17, + RTL_VER_17_QFN68, + RTL_VER_17_QFN100, =20 RTL_VER_MAX }; @@ -3418,7 +3423,8 @@ static void rtl8152_nic_reset(struct r8152 *tp) break; =20 case RTL_VER_16: - case RTL_VER_17: + case RTL_VER_17_QFN68: + case RTL_VER_17_QFN100: ocp_byte_clr_bits(tp, MCU_TYPE_PLA, PLA_CR, CR_RE | CR_TE); break; =20 @@ -3458,7 +3464,7 @@ static void rtl_eee_plus_en(struct r8152 *tp, bool en= able) =20 static void rtl_set_eee_plus(struct r8152 *tp) { - if (tp->version =3D=3D RTL_VER_17) + if (tp->version =3D=3D RTL_VER_17_QFN68 || tp->version =3D=3D RTL_VER_17_= QFN100) return rtl_eee_plus_en(tp, false); =20 if (rtl8152_get_speed(tp) & _10bps) @@ -3646,7 +3652,8 @@ static void r8153_set_rx_early_timeout(struct r8152 *= tp) case RTL_VER_13: case RTL_VER_15: case RTL_VER_16: - case RTL_VER_17: + case RTL_VER_17_QFN68: + case RTL_VER_17_QFN100: 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, @@ -3691,7 +3698,8 @@ static void r8153_set_rx_early_size(struct r8152 *tp) ocp_data / 8); break; case RTL_VER_16: - case RTL_VER_17: + case RTL_VER_17_QFN68: + case RTL_VER_17_QFN100: ocp_write_word(tp, MCU_TYPE_USB, USB_RX_EARLY_SIZE, ocp_data / 16); break; @@ -3807,6 +3815,8 @@ static void rtl_rx_vlan_en(struct r8152 *tp, bool ena= ble) case RTL_VER_13: case RTL_VER_15: case RTL_VER_16: + case RTL_VER_17_QFN68: + case RTL_VER_17_QFN100: default: if (enable) ocp_word_set_bits(tp, MCU_TYPE_PLA, PLA_RCR1, @@ -4487,6 +4497,8 @@ static void r8153_teredo_off(struct r8152 *tp) case RTL_VER_14: case RTL_VER_15: case RTL_VER_16: + case RTL_VER_17_QFN68: + case RTL_VER_17_QFN100: default: /* The bit 0 ~ 7 are relative with teredo settings. They are * W1C (write 1 to clear), so set all 1 to disable it. @@ -4541,7 +4553,8 @@ static void rtl_clear_bp(struct r8152 *tp, u16 type) break; case RTL_VER_14: case RTL_VER_16: - case RTL_VER_17: + case RTL_VER_17_QFN68: + case RTL_VER_17_QFN100: default: ocp_write_word(tp, type, USB_BP2_EN, 0); bp_num =3D 16; @@ -4653,7 +4666,8 @@ static bool rtl8152_is_fw_phy_speed_up_ok(struct r815= 2 *tp, struct fw_phy_speed_ case RTL_VER_13: case RTL_VER_15: case RTL_VER_16: - case RTL_VER_17: + case RTL_VER_17_QFN68: + case RTL_VER_17_QFN100: default: break; } @@ -5813,7 +5827,8 @@ static void rtl_eee_enable(struct r8152 *tp, bool ena= ble) case RTL_VER_13: case RTL_VER_15: case RTL_VER_16: - case RTL_VER_17: + case RTL_VER_17_QFN68: + case RTL_VER_17_QFN100: if (enable) { r8156_eee_en(tp, true); ocp_reg_write(tp, OCP_EEE_ADV, tp->eee_adv); @@ -6404,8 +6419,15 @@ static int rtl8156_enable(struct r8152 *tp) set_tx_qlen(tp); rtl_set_eee_plus(tp); =20 - if (tp->version >=3D RTL_VER_12 && tp->version <=3D RTL_VER_17) - ocp_word_clr_bits(tp, MCU_TYPE_USB, USB_RX_AGGR_NUM, RX_AGGR_NUM_MASK); + switch (tp->version) { + case RTL_VER_10: + case RTL_VER_11: + break; + default: + ocp_word_clr_bits(tp, MCU_TYPE_USB, USB_RX_AGGR_NUM, + RX_AGGR_NUM_MASK); + break; + } =20 r8153_set_rx_early_timeout(tp); r8153_set_rx_early_size(tp); @@ -8093,7 +8115,8 @@ static void r8157_hw_phy_cfg(struct r8152 *tp) sram2_write_w0w1(tp, 0x809d, 0xff00, 0x5000); break; =20 - case RTL_VER_17: + case RTL_VER_17_QFN68: + case RTL_VER_17_QFN100: /* Disable bypass turn off clk in ALDPS */ ocp_byte_clr_bits(tp, MCU_TYPE_PLA, 0xd3c8, BIT(0)); =20 @@ -8696,6 +8719,10 @@ static void r8159_init(struct r8152 *tp) /* TX descriptor Signature */ ocp_byte_clr_bits(tp, MCU_TYPE_USB, 0xd4ae, BIT(1)); =20 + /* Enable u2phy backup restore patch */ + if (tp->version =3D=3D RTL_VER_17_QFN68) + ocp_byte_set_bits(tp, MCU_TYPE_USB, 0xb99c, BIT(0)); + /* Enable u3phy patch backup */ ocp_write_word(tp, MCU_TYPE_USB, 0xb9a2, 0x0448); =20 @@ -10080,7 +10107,8 @@ static int rtl_ops_init(struct r8152 *tp) r8157_desc_init(tp); break; =20 - case RTL_VER_17: + case RTL_VER_17_QFN68: + case RTL_VER_17_QFN100: tp->eee_en =3D true; tp->eee_adv =3D MDIO_EEE_100TX | MDIO_EEE_1000T | MDIO_EEE_10GT; tp->eee_adv2 =3D MDIO_EEE_2_5GT | MDIO_EEE_5GT; @@ -10172,7 +10200,8 @@ static int rtl_fw_init(struct r8152 *tp) case RTL_VER_16: rtl_fw->fw_name =3D FIRMWARE_8157_1; break; - case RTL_VER_17: + case RTL_VER_17_QFN68: + case RTL_VER_17_QFN100: rtl_fw->fw_name =3D FIRMWARE_8159_1; break; default: @@ -10182,9 +10211,33 @@ static int rtl_fw_init(struct r8152 *tp) return 0; } =20 +static u32 __rtl_get_pkg_det(struct usb_device *udev) +{ + u32 pkg_det =3D 0; + __le32 *tmp; + int ret, i; + + tmp =3D kmalloc_obj(*tmp); + if (!tmp) + return 0; + + for (i =3D 0, ret =3D 0; i < 3 && ret !=3D 4; i++) + ret =3D usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), + RTL8152_REQ_GET_REGS, RTL8152_REQT_READ, + PLA_PKG_DET, MCU_TYPE_PLA, tmp, + sizeof(*tmp), USB_CTRL_GET_TIMEOUT); + + if (ret > 0) + pkg_det =3D __le32_to_cpu(*tmp) & PKG_MASK; + + kfree(tmp); + return pkg_det; +} + static u8 __rtl_get_hw_ver(struct usb_device *udev) { u32 ocp_data =3D 0; + u32 pkg_det =3D 0; __le32 *tmp; u8 version; int ret; @@ -10267,7 +10320,16 @@ static u8 __rtl_get_hw_ver(struct usb_device *udev) version =3D RTL_VER_16; break; case 0x2020: - version =3D RTL_VER_17; + pkg_det =3D __rtl_get_pkg_det(udev); + if (pkg_det =3D=3D 0x1e || pkg_det =3D=3D 0x1c) { + version =3D RTL_VER_17_QFN68; + } else if (pkg_det =3D=3D 0x18 || pkg_det =3D=3D 0x1a) { + version =3D RTL_VER_17_QFN100; + } else { + version =3D RTL_VER_UNKNOWN; + dev_info(&udev->dev, "Unknown package %#02x\n", + pkg_det); + } break; default: version =3D RTL_VER_UNKNOWN; @@ -10426,7 +10488,8 @@ static int rtl8152_probe_once(struct usb_interface = *intf, case RTL_VER_13: case RTL_VER_15: case RTL_VER_16: - case RTL_VER_17: + case RTL_VER_17_QFN68: + case RTL_VER_17_QFN100: netdev->max_mtu =3D size_to_mtu(16 * 1024); break; case RTL_VER_01: --=20 2.34.1 From nobody Fri Sep 25 03:17:45 2026 Received: from rtits2.realtek.com.tw (rtits2.realtek.com [211.75.126.72]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 9D7063B7751; Thu, 17 Sep 2026 07:07:21 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=211.75.126.72 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789628844; cv=none; b=kvjgIKpJUEs0lD3ZSX0TS+vOQog6LgYyDcumXImF9UXsBPlQiq3BX1kGU1JsLLkhjSoIg2csrNmPn/tF6I8qtOCGCPMauPe9wDstwxSiQGD+Vb3eNdbJmOmXhV/keF7RWXqP/HqSjqYb9huJ/4lc7vcTCUjzoC7VZzYEbv2IuqM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789628844; c=relaxed/simple; bh=zJEQ472jwFPpoYNeEp+3okiRaZFlgPvOUmhL53TOsiY=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=omHIWE+I5XqI3O/GQ8+tnSa8gcPLujp/QsPP/yeh8ChTzd3GaUS1eufpm67Qi78HmAm2CYjaJgfIGCIHI1nfSzNNP4FdxuSvck98+PBM8MXSbM/E9jGqyo7pRW3zdrfOZTGYMjS4OJm/ztvWs4hBPJGQLh1Thf8pBfyPGgQYreE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=realtek.com; spf=pass smtp.mailfrom=realtek.com; dkim=pass (2048-bit key) header.d=realtek.com header.i=@realtek.com header.b=Z2DgYBJU; arc=none smtp.client-ip=211.75.126.72 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=realtek.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=realtek.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=realtek.com header.i=@realtek.com header.b="Z2DgYBJU" X-SpamFilter-By: ArmorX SpamTrap 5.80 with qID 68H76fc563094124, This message is accepted by code: ctloc85258 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=realtek.com; s=dkim; t=1789628801; bh=7fBHl/PW6GYkVETW6QnX86SWPNPbhd4jLXupM5uyPsk=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Transfer-Encoding:Content-Type; b=Z2DgYBJUWINZk4ZV0Er3VADVesElwlGOoKSKpKlyB+e8fYYiV1zj/u9nv8NdOwbiv 2U6OwPd6VrQzJ3qBgWx3x6BtKxCsH5EIpzwWZjIZmCIBMRhvDEeYdQ7efdpXbw38/p wLhK3lttsPnWgUPR78l2CWj6fAdk7HvaxIsdG5/wDyS9ed1Rp9i+9GeeqyFpubSc1V +wkxwfb1J13YGNFgZtRjZ1+yr75RKUZpd/+S+fMiZcXBpPRNWdfU7qYdr7Ip3dTdiA l2ljc9Kxi3LAGilx6ZKLyq/66lYz58BR99GK0dyPtR8VieflS50GDQixgees2MkyXX j+srAnUy+Vkuw== Received: from mail.realtek.com (rtkexhmbs02.realtek.com.tw[172.21.6.41]) by rtits2.realtek.com.tw (8.15.2/3.29/5.94) with ESMTPS id 68H76fc563094124 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL); Thu, 17 Sep 2026 15:06:41 +0800 Received: from RTKEXHMBS04.realtek.com.tw (10.21.1.54) by RTKEXHMBS02.realtek.com.tw (172.21.6.41) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.2562.49; Thu, 17 Sep 2026 15:06:40 +0800 Received: from fc44.realtek.com.tw (172.22.241.7) by RTKEXHMBS04.realtek.com.tw (10.21.1.54) with Microsoft SMTP Server id 15.2.2562.49 via Frontend Transport; Thu, 17 Sep 2026 15:06:40 +0800 From: Chih Kai Hsu To: , CC: , , , , , , , , Subject: [PATCH net-next v4 3/8] r8152: split rtl8156_enable/up/down into per-chip-family functions Date: Thu, 17 Sep 2026 15:06:32 +0800 Message-ID: <20260917070637.62827-4-nic_swsd@realtek.com> X-Mailer: git-send-email 2.54.0 In-Reply-To: <20260917070637.62827-1-nic_swsd@realtek.com> References: <20260917070637.62827-1-nic_swsd@realtek.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" rtl8156_enable(), rtl8156_up() and rtl8156_down() had accumulated tp->version range checks to cover RTL8156, RTL8156B, and RTL8157/RTL8159, including an early bail-out in rtl8156_enable() that skipped most of the function body for RTL8157/RTL8159. Add rtl8156b_enable() (VER_12/13/15) and rtl8157_enable()/ rtl8157_up()/rtl8157_down() (VER_16/17) as separate ops callbacks. rtl8156_up()/rtl8156_down() keep serving RTL8156 and RTL8156B (VER_10/11/12/13/15). Per the datasheet, this uncovers real register differences that the old version guards had wrong or missing: - RTL8156/8156B now also clear PLA_RCR1 BIT(3) on up, previously applied only to RTL8157/8159's share of the old function. - RTL8156B (VER_13/15) gains a Clear_SDR enable (USB 0xd3ca BIT(15)) on up. - RTL8157/8159 now also clear USB_SPEED_OPTION's RG_PWRDN_EN/ALL_SPEED_OFF on up, previously excluded for them, and gain their own Clear_SDR enables (USB 0xd378 BIT(7), USB 0xcd06 BIT(15)). - RTL8156/8156B/8157/8159 OOB entry (down) gains PLA_BDC_CR's ALDPS_PROXY_MODE and PLA_OOB_CTRL's DIS_MCU_CLROOB, aligning with r8152b_enter_oob()/r8153_enter_oob(). - RTL8157/8159 OOB entry now uses PLA_RMS=3D1526/PLA_MTPS=3D10K instead of 1522/6K. While extracting rtl8156b_enable(), also drop the "if (tp->version < RTL_VER_12) r8156_fc_parameter(tp)" guard: since this function only runs for VER_12/13/15 chips, the call was always skipped and is removed rather than carried over. Signed-off-by: Chih Kai Hsu --- drivers/net/usb/r8152.c | 235 ++++++++++++++++++++++++++++++++-------- 1 file changed, 189 insertions(+), 46 deletions(-) diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c index 9ce072c38b5b5..c513c286c5499 100644 --- a/drivers/net/usb/r8152.c +++ b/drivers/net/usb/r8152.c @@ -6413,31 +6413,16 @@ static int rtl8156_enable(struct r8152 *tp) if (test_bit(RTL8152_INACCESSIBLE, &tp->flags)) return -ENODEV; =20 - if (tp->version < RTL_VER_12) - r8156_fc_parameter(tp); - + r8156_fc_parameter(tp); set_tx_qlen(tp); rtl_set_eee_plus(tp); =20 - switch (tp->version) { - case RTL_VER_10: - case RTL_VER_11: - break; - default: - ocp_word_clr_bits(tp, MCU_TYPE_USB, USB_RX_AGGR_NUM, - RX_AGGR_NUM_MASK); - break; - } - r8153_set_rx_early_timeout(tp); r8153_set_rx_early_size(tp); =20 speed =3D rtl8152_get_speed(tp); rtl_set_ifg(tp, speed); =20 - if (tp->version >=3D RTL_VER_16) - return rtl_enable(tp); - if (speed & _2500bps) ocp_word_clr_bits(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL4, IDLE_SPDWN_EN); @@ -6445,12 +6430,10 @@ static int rtl8156_enable(struct r8152 *tp) ocp_word_set_bits(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL4, IDLE_SPDWN_EN); =20 - if (tp->version < RTL_VER_12) { - 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 (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); =20 if (tp->udev->speed =3D=3D USB_SPEED_HIGH) { /* USB 0xb45e[3:0] l1_nyet_hird */ @@ -6475,6 +6458,67 @@ static void rtl8156_disable(struct r8152 *tp) rtl8153_disable(tp); } =20 +static int rtl8156b_enable(struct r8152 *tp) +{ + u16 speed; + + if (test_bit(RTL8152_INACCESSIBLE, &tp->flags)) + return -ENODEV; + + set_tx_qlen(tp); + rtl_set_eee_plus(tp); + + ocp_word_clr_bits(tp, MCU_TYPE_USB, USB_RX_AGGR_NUM, RX_AGGR_NUM_MASK); + + r8153_set_rx_early_timeout(tp); + r8153_set_rx_early_size(tp); + + speed =3D rtl8152_get_speed(tp); + rtl_set_ifg(tp, speed); + + if (speed & _2500bps) + ocp_word_clr_bits(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL4, + IDLE_SPDWN_EN); + else + ocp_word_set_bits(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL4, + IDLE_SPDWN_EN); + + if (tp->udev->speed =3D=3D USB_SPEED_HIGH) { + /* USB 0xb45e[3:0] l1_nyet_hird */ + if (is_flow_control(speed)) + ocp_word_w0w1(tp, MCU_TYPE_USB, USB_L1_CTRL, 0xf, 0xf); + else + ocp_word_w0w1(tp, MCU_TYPE_USB, USB_L1_CTRL, 0xf, 0x1); + } + + ocp_word_clr_bits(tp, MCU_TYPE_USB, USB_FW_TASK, FC_PATCH_TASK); + usleep_range(1000, 2000); + ocp_word_set_bits(tp, MCU_TYPE_USB, USB_FW_TASK, FC_PATCH_TASK); + + return rtl_enable(tp); +} + +static int rtl8157_enable(struct r8152 *tp) +{ + u16 speed; + + if (test_bit(RTL8152_INACCESSIBLE, &tp->flags)) + return -ENODEV; + + set_tx_qlen(tp); + rtl_set_eee_plus(tp); + + ocp_word_clr_bits(tp, MCU_TYPE_USB, USB_RX_AGGR_NUM, RX_AGGR_NUM_MASK); + + r8153_set_rx_early_timeout(tp); + r8153_set_rx_early_size(tp); + + speed =3D rtl8152_get_speed(tp); + rtl_set_ifg(tp, speed); + + return rtl_enable(tp); +} + static int rtl8152_set_speed(struct r8152 *tp, u8 autoneg, u32 speed, u8 d= uplex, u32 advertising) { @@ -6835,8 +6879,7 @@ static void rtl8156_up(struct r8152 *tp) return; =20 r8153b_u1u2en(tp, false); - if (tp->version < RTL_VER_16) - r8153_u2p3en(tp, false); + r8153_u2p3en(tp, false); r8153_aldps_en(tp, false); =20 rxdy_gated_en(tp, true); @@ -6849,8 +6892,7 @@ static void rtl8156_up(struct r8152 *tp) =20 ocp_byte_clr_bits(tp, MCU_TYPE_PLA, PLA_OOB_CTRL, NOW_IS_OOB); =20 - if (tp->version >=3D RTL_VER_16) - ocp_word_clr_bits(tp, MCU_TYPE_PLA, PLA_RCR1, BIT(3)); + ocp_word_clr_bits(tp, MCU_TYPE_PLA, PLA_RCR1, BIT(3)); =20 ocp_word_clr_bits(tp, MCU_TYPE_PLA, PLA_SFF_STS_7, MCU_BORW_EN); =20 @@ -6872,11 +6914,11 @@ static void rtl8156_up(struct r8152 *tp) ocp_word_w0w1(tp, MCU_TYPE_PLA, PLA_RXFIFO_FULL, RXFIFO_FULL_MASK, 0x08); =20 - ocp_word_clr_bits(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL3, PLA_MCU_SPDWN_EN); + ocp_word_clr_bits(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL3, + PLA_MCU_SPDWN_EN); =20 - if (tp->version < RTL_VER_16) - ocp_word_clr_bits(tp, MCU_TYPE_USB, USB_SPEED_OPTION, - RG_PWRDN_EN | ALL_SPEED_OFF); + ocp_word_clr_bits(tp, MCU_TYPE_USB, USB_SPEED_OPTION, + RG_PWRDN_EN | ALL_SPEED_OFF); =20 ocp_write_dword(tp, MCU_TYPE_USB, USB_RX_BUF_TH, 0x00600400); =20 @@ -6886,10 +6928,19 @@ static void rtl8156_up(struct r8152 *tp) } =20 r8153_aldps_en(tp, true); - if (tp->version < RTL_VER_16) - r8153_u2p3en(tp, true); + r8153_u2p3en(tp, true); =20 - if (tp->version < RTL_VER_16 && tp->udev->speed >=3D USB_SPEED_SUPER) + switch (tp->version) { + case RTL_VER_13: + case RTL_VER_15: + /* Enable Clear_SDR */ + ocp_word_set_bits(tp, MCU_TYPE_USB, 0xd3ca, BIT(15)); + break; + default: + break; + } + + if (tp->udev->speed >=3D USB_SPEED_SUPER) r8153b_u1u2en(tp, true); } =20 @@ -6902,12 +6953,9 @@ static void rtl8156_down(struct r8152 *tp) =20 ocp_word_set_bits(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL3, PLA_MCU_SPDWN_EN); - r8153b_u1u2en(tp, false); - if (tp->version < RTL_VER_16) { - r8153_u2p3en(tp, false); - r8153b_power_cut_en(tp, false); - } + r8153_u2p3en(tp, false); + r8153b_power_cut_en(tp, false); r8153_aldps_en(tp, false); =20 ocp_byte_clr_bits(tp, MCU_TYPE_PLA, PLA_OOB_CTRL, NOW_IS_OOB); @@ -6929,7 +6977,102 @@ static void rtl8156_down(struct r8152 *tp) */ ocp_write_word(tp, MCU_TYPE_PLA, PLA_TEREDO_WAKE_BASE, 0x00ff); =20 - ocp_byte_set_bits(tp, MCU_TYPE_PLA, PLA_OOB_CTRL, NOW_IS_OOB); + ocp_word_set_bits(tp, MCU_TYPE_PLA, PLA_BDC_CR, ALDPS_PROXY_MODE); + + ocp_byte_set_bits(tp, MCU_TYPE_PLA, PLA_OOB_CTRL, + NOW_IS_OOB | DIS_MCU_CLROOB); + + ocp_word_set_bits(tp, MCU_TYPE_PLA, PLA_SFF_STS_7, MCU_BORW_EN); + + rtl_rx_vlan_en(tp, true); + rxdy_gated_en(tp, false); + + ocp_dword_set_bits(tp, MCU_TYPE_PLA, PLA_RCR, + RCR_APM | RCR_AM | RCR_AB); + + r8153_aldps_en(tp, true); +} + +static void rtl8157_up(struct r8152 *tp) +{ + if (test_bit(RTL8152_INACCESSIBLE, &tp->flags)) + return; + + r8153b_u1u2en(tp, false); + r8153_aldps_en(tp, false); + + rxdy_gated_en(tp, true); + r8153_teredo_off(tp); + + ocp_dword_clr_bits(tp, MCU_TYPE_PLA, PLA_RCR, RCR_ACPT_ALL); + + rtl8152_nic_reset(tp); + rtl_reset_bmu(tp); + + ocp_byte_clr_bits(tp, MCU_TYPE_PLA, PLA_OOB_CTRL, NOW_IS_OOB); + + ocp_word_clr_bits(tp, MCU_TYPE_PLA, PLA_RCR1, BIT(3)); + + ocp_word_clr_bits(tp, MCU_TYPE_PLA, PLA_SFF_STS_7, MCU_BORW_EN); + + rtl_rx_vlan_en(tp, tp->netdev->features & NETIF_F_HW_VLAN_CTAG_RX); + + rtl8156_change_mtu(tp); + + /* share FIFO settings */ + ocp_word_w0w1(tp, MCU_TYPE_PLA, PLA_RXFIFO_FULL, RXFIFO_FULL_MASK, + 0x08); + + ocp_word_clr_bits(tp, MCU_TYPE_USB, USB_SPEED_OPTION, + RG_PWRDN_EN | ALL_SPEED_OFF); + + ocp_write_dword(tp, MCU_TYPE_USB, USB_RX_BUF_TH, 0x00600400); + + if (tp->saved_wolopts !=3D __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); + + /* Clear_SDR */ + ocp_byte_set_bits(tp, MCU_TYPE_USB, 0xd378, BIT(7)); + ocp_word_clr_bits(tp, MCU_TYPE_USB, 0xcd06, BIT(15)); +} + +static void rtl8157_down(struct r8152 *tp) +{ + if (test_bit(RTL8152_INACCESSIBLE, &tp->flags)) { + rtl_drop_queued_tx(tp); + return; + } + + r8153b_u1u2en(tp, false); + r8153_aldps_en(tp, false); + + ocp_byte_clr_bits(tp, MCU_TYPE_PLA, PLA_OOB_CTRL, NOW_IS_OOB); + + /* RX FIFO settings for OOB */ + ocp_write_word(tp, MCU_TYPE_PLA, PLA_RXFIFO_FULL, 64 / 16); + ocp_write_word(tp, MCU_TYPE_PLA, PLA_RX_FIFO_FULL, 1024 / 16); + ocp_write_word(tp, MCU_TYPE_PLA, PLA_RX_FIFO_EMPTY, 4096 / 16); + + rtl_disable(tp); + rtl_reset_bmu(tp); + + ocp_write_word(tp, MCU_TYPE_PLA, PLA_RMS, 1526); + ocp_write_byte(tp, MCU_TYPE_PLA, PLA_MTPS, 10 * 1024 / 64); + + /* 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_word_set_bits(tp, MCU_TYPE_PLA, PLA_BDC_CR, ALDPS_PROXY_MODE); + + ocp_byte_set_bits(tp, MCU_TYPE_PLA, PLA_OOB_CTRL, + NOW_IS_OOB | DIS_MCU_CLROOB); =20 ocp_word_set_bits(tp, MCU_TYPE_PLA, PLA_SFF_STS_7, MCU_BORW_EN); =20 @@ -10051,7 +10194,7 @@ static int rtl_ops_init(struct r8152 *tp) tp->eee_adv =3D MDIO_EEE_1000T | MDIO_EEE_100TX; tp->eee_adv2 =3D MDIO_EEE_2_5GT; ops->init =3D r8156b_init; - ops->enable =3D rtl8156_enable; + ops->enable =3D rtl8156b_enable; ops->disable =3D rtl8153_disable; ops->up =3D rtl8156_up; ops->down =3D rtl8156_down; @@ -10090,10 +10233,10 @@ static int rtl_ops_init(struct r8152 *tp) tp->eee_adv =3D MDIO_EEE_1000T | MDIO_EEE_100TX; tp->eee_adv2 =3D MDIO_EEE_2_5GT | MDIO_EEE_5GT; ops->init =3D r8157_init; - ops->enable =3D rtl8156_enable; + ops->enable =3D rtl8157_enable; ops->disable =3D rtl8153_disable; - ops->up =3D rtl8156_up; - ops->down =3D rtl8156_down; + ops->up =3D rtl8157_up; + ops->down =3D rtl8157_down; ops->unload =3D rtl8153_unload; ops->eee_get =3D r8153_get_eee; ops->eee_set =3D r8152_set_eee; @@ -10113,10 +10256,10 @@ static int rtl_ops_init(struct r8152 *tp) tp->eee_adv =3D MDIO_EEE_100TX | MDIO_EEE_1000T | MDIO_EEE_10GT; tp->eee_adv2 =3D MDIO_EEE_2_5GT | MDIO_EEE_5GT; ops->init =3D r8159_init; - ops->enable =3D rtl8156_enable; + ops->enable =3D rtl8157_enable; ops->disable =3D rtl8153_disable; - ops->up =3D rtl8156_up; - ops->down =3D rtl8156_down; + ops->up =3D rtl8157_up; + ops->down =3D rtl8157_down; ops->unload =3D rtl8153_unload; ops->eee_get =3D r8153_get_eee; ops->eee_set =3D r8152_set_eee; --=20 2.34.1 From nobody Fri Sep 25 03:17:45 2026 Received: from rtits2.realtek.com.tw (rtits2.realtek.com [211.75.126.72]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 8991D3955D0; Thu, 17 Sep 2026 07:07:20 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=211.75.126.72 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789628842; cv=none; b=VSg6tQW9eLegJ7HhDlWW4aqspRbqbAthUM66wVQa6fHduDvJLNQ8lnZtJcTpSPwaxXAfRWPLX2URONo1G/PId8M5R35Sxa53Atvnrjg8rIJKFEDP9Fba7egG/8SWldYtxqk+gDFlzHfDLQbzF5FgVczUg2FfT5MrpYoWl/uNDec= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789628842; c=relaxed/simple; bh=m7gfzTTkeE2MWlErekCqi00eeJBevW9TLSnWArrJvCc=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=dBt6FYeM6726OIbOe0N3fJ76HJnQtFEAIKB297ygQC6v5xRcrc0Z7TXLw1YnstFPmwyobxf1oS4Pxa9G350cy3n/3TawtQnsocaEzuVkQRfRLCBlerjHK58UtVuOaTaTQLrNcN5JdjpggcK3omdNdPkupdw0mgnmMgoPL8fcay4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=realtek.com; spf=pass smtp.mailfrom=realtek.com; dkim=pass (2048-bit key) header.d=realtek.com header.i=@realtek.com header.b=BkIxe2Dw; arc=none smtp.client-ip=211.75.126.72 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=realtek.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=realtek.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=realtek.com header.i=@realtek.com header.b="BkIxe2Dw" X-SpamFilter-By: ArmorX SpamTrap 5.80 with qID 68H76fc663094124, This message is accepted by code: ctloc85258 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=realtek.com; s=dkim; t=1789628802; bh=se5IR1FtNMIjt1ZsTJdBtVSTSZhUqTLFuctzUcnKcsE=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Transfer-Encoding:Content-Type; b=BkIxe2DwAMy25HVHkxiGiH2JENansHenRZUYVZs+Q8u3uKnKRAytL/1KdczWA3BRt DKjKr3H2frUG4na9xwbTG12xhFnFeHfnYSljXJmCdlvHd1gnO2t0AQfBNbXkrtkC59 cPAh9F8O37Cgw0ibjQvm+75u8AQY6fmuSZa2ti8Dy8E58YnxQL9mD1N2FxMbkdMSND 6LzOWcB5JJ7v20bGDkl/wJoFkVQSjsqbVs184weRleWSX8cts826MBw0TmhSnwUAVn tdD7BeLYHNQaJI8eDp9kn+8hM+5sGb+Cc4JQ4U71fOgN0qlZ2BRtzsoxz1GRtSkwa+ AcoFgbidHysTg== Received: from mail.realtek.com (rtkexhmbs02.realtek.com.tw[172.21.6.41]) by rtits2.realtek.com.tw (8.15.2/3.29/5.94) with ESMTPS id 68H76fc663094124 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL); Thu, 17 Sep 2026 15:06:41 +0800 Received: from RTKEXHMBS04.realtek.com.tw (10.21.1.54) by RTKEXHMBS02.realtek.com.tw (172.21.6.41) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.2562.49; Thu, 17 Sep 2026 15:06:40 +0800 Received: from fc44.realtek.com.tw (172.22.241.7) by RTKEXHMBS04.realtek.com.tw (10.21.1.54) with Microsoft SMTP Server id 15.2.2562.49 via Frontend Transport; Thu, 17 Sep 2026 15:06:40 +0800 From: Chih Kai Hsu To: , CC: , , , , , , , , Subject: [PATCH net-next v4 4/8] r8152: split r8157_hw_phy_cfg into RTL8157 and RTL8159 variants Date: Thu, 17 Sep 2026 15:06:33 +0800 Message-ID: <20260917070637.62827-5-nic_swsd@realtek.com> X-Mailer: git-send-email 2.54.0 In-Reply-To: <20260917070637.62827-1-nic_swsd@realtek.com> References: <20260917070637.62827-1-nic_swsd@realtek.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" r8157_hw_phy_cfg() served both RTL8157 (VER_16) and RTL8159 (VER_17_QFN68/QFN100) via a tp->version switch inside a single function, but per the datasheet RTL8159's PHY tuning differs from RTL8157's in more than the per-version blocks already captured. Split it into r8157_hw_phy_cfg() (VER_16 only) and a new r8159_hw_phy_cfg() (VER_17_QFN68/QFN100), each with its own copy of the shared prologue/epilogue instead of switching on version mid-function. Per the datasheet, RTL8159 diverges from RTL8157 in this split in several ways: - RTL8159 doesn't need EEE disabled before reprogramming PHY parameters, so r8159_hw_phy_cfg() drops the rtl_eee_enable(tp, false) call that r8157_hw_phy_cfg() keeps. - RTL8159's EEE clock-divider and 0xa5ea encoding differ from RTL8157's: r8159_hw_phy_cfg() clears EN_10M_CLKDIV (ups_info. _10m_ckdiv =3D false) instead of setting it, and clears an extra bit (BIT(2)) of 0xa5ea. - "Disable bypass_turn_off_clk_in_aldps" (0xd3c8 BIT(0)) is needed by both chips, so it moves from the VER_17-only switch case into the shared prologue and now also runs for RTL8157. Along the way, add sram2_set_bits()/sram2_clr_bits() helpers mirroring the existing sram_set_bits()/sram_clr_bits(), and use the named OCP_POWER_CFG/EN_10M_PLLOFF/EN_ALDPS_PLLOFF macros in place of the raw "ocp_reg_set_bits(tp, 0xa430, BIT(0) | BIT(1))". Signed-off-by: Chih Kai Hsu --- drivers/net/usb/r8152.c | 165 +++++++++++++++++++++++++++++++++------- 1 file changed, 136 insertions(+), 29 deletions(-) diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c index c513c286c5499..d30031dbf2d38 100644 --- a/drivers/net/usb/r8152.c +++ b/drivers/net/usb/r8152.c @@ -655,6 +655,7 @@ enum spd_duplex { /* OCP_POWER_CFG */ #define EEE_CLKDIV_EN 0x8000 #define EN_ALDPS 0x0004 +#define EN_ALDPS_PLLOFF 0x0002 #define EN_10M_PLLOFF 0x0001 =20 /* OCP_EEE_CONFIG1 */ @@ -1964,6 +1965,16 @@ static void sram2_write_w0w1(struct r8152 *tp, u16 a= ddr, u16 clear, u16 set) ocp_reg_write(tp, OCP_SRAM2_DATA, data); } =20 +static void sram2_set_bits(struct r8152 *tp, u16 addr, u16 set) +{ + sram2_write_w0w1(tp, addr, 0, set); +} + +static void sram2_clr_bits(struct r8152 *tp, u16 addr, u16 clear) +{ + sram2_write_w0w1(tp, addr, clear, 0); +} + static void r8152_mdio_clr_bit(struct r8152 *tp, u16 addr, u16 clear) { int data; @@ -8131,11 +8142,14 @@ static void r8157_hw_phy_cfg(struct r8152 *tp) ocp_word_clr_bits(tp, MCU_TYPE_PLA, PLA_PHY_PWR, PFM_PWM_SWITCH); =20 /* Advanced Power Saving parameter */ - ocp_reg_set_bits(tp, 0xa430, BIT(0) | BIT(1)); + ocp_reg_set_bits(tp, OCP_POWER_CFG, EN_10M_PLLOFF | EN_ALDPS_PLLOFF); =20 /* Disable ALDPS force mode */ ocp_reg_clr_bits(tp, 0xa44a, BIT(2)); =20 + /* Disable bypass_turn_off_clk_in_aldps */ + ocp_byte_clr_bits(tp, MCU_TYPE_PLA, 0xd3c8, BIT(0)); + switch (tp->version) { case RTL_VER_16: /* XG_INRX parameter */ @@ -8151,7 +8165,7 @@ static void r8157_hw_phy_cfg(struct r8152 *tp) sram2_write_w0w1(tp, 0x8078, 0xff00, 0x3000); =20 /* green mode */ - sram2_write_w0w1(tp, 0x89e9, 0xff00, 0); + sram2_clr_bits(tp, 0x89e9, 0xff00); sram2_write_w0w1(tp, 0x8ffd, 0xff00, 0x0100); sram2_write_w0w1(tp, 0x8ffe, 0xff00, 0x0200); sram2_write_w0w1(tp, 0x8fff, 0xff00, 0x0400); @@ -8257,12 +8271,85 @@ static void r8157_hw_phy_cfg(struct r8152 *tp) sram2_write_w0w1(tp, 0x807c, 0xff00, 0x5000); sram2_write_w0w1(tp, 0x809d, 0xff00, 0x5000); break; + default: + break; + } =20 + if (rtl_phy_patch_request(tp, true, true)) + return; + + ocp_word_set_bits(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL4, EEE_SPDWN_EN); + + ocp_reg_w0w1(tp, OCP_DOWN_SPEED, EN_EEE_100 | EN_EEE_1000, EN_10M_CLKDIV); + + tp->ups_info._10m_ckdiv =3D true; + tp->ups_info.eee_plloff_100 =3D false; + tp->ups_info.eee_plloff_giga =3D false; + + ocp_reg_set_bits(tp, OCP_POWER_CFG, EEE_CLKDIV_EN); + tp->ups_info.eee_ckdiv =3D true; + + rtl_phy_patch_request(tp, false, true); + + rtl_green_en(tp, test_bit(GREEN_ETHERNET, &tp->flags)); + + ocp_reg_clr_bits(tp, 0xa428, BIT(9)); + ocp_reg_clr_bits(tp, 0xa5ea, BIT(0) | BIT(1)); + tp->ups_info.lite_mode =3D 0; + + if (tp->eee_en) + rtl_eee_enable(tp, true); + + r8153_aldps_en(tp, true); + r8152b_enable_fc(tp); + + set_bit(PHY_RESET, &tp->flags); +} + +static void r8159_hw_phy_cfg(struct r8152 *tp) +{ + u16 data; + + r8156b_wait_loading_flash(tp); + + ocp_word_test_and_clr_bits(tp, MCU_TYPE_USB, USB_MISC_0, PCUT_STATUS); + + data =3D r8153_phy_status(tp, 0); + switch (data) { + case PHY_STAT_EXT_INIT: + rtl8152_apply_firmware(tp, true); + ocp_reg_clr_bits(tp, 0xa466, BIT(0)); + ocp_reg_clr_bits(tp, 0xa468, BIT(3) | BIT(1)); + break; + case PHY_STAT_LAN_ON: + case PHY_STAT_PWRDN: + default: + rtl8152_apply_firmware(tp, false); + break; + } + + r8152_mdio_test_and_clr_bit(tp, MII_BMCR, BMCR_PDOWN); + + r8153_aldps_en(tp, false); + + data =3D r8153_phy_status(tp, PHY_STAT_LAN_ON); + WARN_ON_ONCE(data !=3D PHY_STAT_LAN_ON); + + /* PFM mode */ + ocp_word_clr_bits(tp, MCU_TYPE_PLA, PLA_PHY_PWR, PFM_PWM_SWITCH); + + /* Advanced Power Saving parameter */ + ocp_reg_set_bits(tp, OCP_POWER_CFG, EN_10M_PLLOFF | EN_ALDPS_PLLOFF); + + /* Disable ALDPS force mode */ + ocp_reg_clr_bits(tp, 0xa44a, BIT(2)); + + /* Disable bypass_turn_off_clk_in_aldps */ + ocp_byte_clr_bits(tp, MCU_TYPE_PLA, 0xd3c8, BIT(0)); + + switch (tp->version) { case RTL_VER_17_QFN68: case RTL_VER_17_QFN100: - /* Disable bypass turn off clk in ALDPS */ - ocp_byte_clr_bits(tp, MCU_TYPE_PLA, 0xd3c8, BIT(0)); - /* Power level tuning * test mode power level */ @@ -8272,22 +8359,35 @@ static void r8157_hw_phy_cfg(struct r8152 *tp) sram_write_w0w1(tp, 0x81ae, 0xff00, 0x0f00); sram_write_w0w1(tp, 0x81b9, 0xff00, 0xb900); /* normal link TX filter */ - sram2_write_w0w1(tp, 0x83b0, 0x0e00, 0); - sram2_write_w0w1(tp, 0x83c5, 0x0e00, 0); - sram2_write_w0w1(tp, 0x83da, 0x0e00, 0); - sram2_write_w0w1(tp, 0x83ef, 0x0e00, 0); + sram2_clr_bits(tp, 0x83b0, 0x0e00); + sram2_clr_bits(tp, 0x83c5, 0x0e00); + sram2_clr_bits(tp, 0x83da, 0x0e00); + sram2_clr_bits(tp, 0x83ef, 0x0e00); + + ocp_reg_w0w1(tp, 0xbf38, 0x01f0, 0x0160); + ocp_reg_w0w1(tp, 0xbf3a, 0x001f, 0x0014); + /* shorten CLKS latency */ + ocp_reg_clr_bits(tp, 0xbf28, BIT(14) | BIT(13)); + ocp_reg_clr_bits(tp, 0xbf2c, BIT(15) | BIT(14)); + /* CMP_Timer on MP_Timer=3D333 + * GPHY OCP 0xbf28 bit[0] =3D 0x1 + * GPHY OCP 0xbf28 bit[6:1] =3D 0x3 + * GPHY OCP 0xbf28 bit[12:7] =3D 0x3 + */ + ocp_reg_w0w1(tp, 0xbf28, 0x1fff, 0x0187); + ocp_reg_w0w1(tp, 0xbf2a, 0x3f, 0x03); =20 /* AFE power saving for 2.5G & 5G */ sram_write(tp, 0x8173, 0x8620); sram_write(tp, 0x8175, 0x8671); =20 - sram_write_w0w1(tp, 0x817c, 0, BIT(13)); - sram_write_w0w1(tp, 0x8187, 0, BIT(13)); - sram_write_w0w1(tp, 0x8192, 0, BIT(13)); - sram_write_w0w1(tp, 0x819d, 0, BIT(13)); - sram_write_w0w1(tp, 0x81a8, BIT(13), 0); - sram_write_w0w1(tp, 0x81b3, BIT(13), 0); - sram_write_w0w1(tp, 0x81be, 0, BIT(13)); + sram_set_bits(tp, 0x817c, BIT(13)); + sram_set_bits(tp, 0x8187, BIT(13)); + sram_set_bits(tp, 0x8192, BIT(13)); + sram_set_bits(tp, 0x819d, BIT(13)); + sram_clr_bits(tp, 0x81a8, BIT(13)); + sram_clr_bits(tp, 0x81b3, BIT(13)); + sram_set_bits(tp, 0x81be, BIT(13)); =20 sram_write_w0w1(tp, 0x817d, 0xff00, 0xa600); sram_write_w0w1(tp, 0x8188, 0xff00, 0xa600); @@ -8351,10 +8451,10 @@ static void r8157_hw_phy_cfg(struct r8152 *tp) sram2_write_w0w1(tp, 0x84b2, 0xff00, 0x6000); /* Training AAGC PAR (with uc2 patch) */ sram2_write(tp, 0x8ffc, 0x6008); - sram2_write(tp, 0x8ffe, 0xf450); + sram2_write(tp, 0x8ffe, 0xf4ff); /* DAC BGK */ - sram2_write_w0w1(tp, 0x8015, 0, BIT(9)); - sram2_write_w0w1(tp, 0x8016, 0, BIT(11)); + sram2_set_bits(tp, 0x8015, BIT(9)); + sram2_set_bits(tp, 0x8016, BIT(11)); sram2_write_w0w1(tp, 0x8fe6, 0xff00, 0x0800); sram2_write(tp, 0x8fe4, 0x2114); /* 10G PBO table */ @@ -8363,14 +8463,14 @@ static void r8157_hw_phy_cfg(struct r8152 *tp) sram2_write_w0w1(tp, 0x864b, 0xff00, 0xdc00); /* 2.5G ado power window size */ sram2_write_w0w1(tp, 0x8154, 0xc000, 0x4000); - sram2_write_w0w1(tp, 0x8158, 0xc000, 0); + sram2_clr_bits(tp, 0x8158, 0xc000); /* 10G lock far */ sram2_write(tp, 0x826c, 0xffff); sram2_write(tp, 0x826e, 0xffff); /* XG INRX parameter */ sram2_write_w0w1(tp, 0x8872, 0xff00, 0x0e00); - sram_write_w0w1(tp, 0x8012, 0, BIT(11)); - sram_write_w0w1(tp, 0x8012, 0, BIT(14)); + sram_set_bits(tp, 0x8012, BIT(11)); + sram_set_bits(tp, 0x8012, BIT(14)); ocp_reg_set_bits(tp, 0xb576, BIT(0)); sram_write_w0w1(tp, 0x834a, 0xff00, 0x0700); sram2_write_w0w1(tp, 0x8217, 0x3f00, 0x2a00); @@ -8381,7 +8481,7 @@ static void r8157_hw_phy_cfg(struct r8152 *tp) /* improve UBE */ ocp_reg_set_bits(tp, 0xbf0c, 0x7 << 11); /* close Sparse NEC, improve connect 5EUU cable performance */ - sram2_write_w0w1(tp, 0x88de, 0xff00, 0); + sram2_clr_bits(tp, 0x88de, 0xff00); /* 5G slave compatibility issue */ sram2_write(tp, 0x80b4, 0x5195); =20 @@ -8440,8 +8540,15 @@ static void r8157_hw_phy_cfg(struct r8152 *tp) sram2_write(tp, 0x8ff8, 0xaa5a); =20 sram2_write_w0w1(tp, 0x88d5, 0xff00, 0x0200); - break; =20 + /* spdchg_pga1_lpf_cap */ + sram_write_w0w1(tp, 0x84bb, 0xff00, 0x0a00); + sram_write_w0w1(tp, 0x84c0, 0xff00, 0x1600); + + /* ENET PLL jitter improvement */ + ocp_reg_w0w1(tp, 0xbf8a, 0xfc00, 0x2000); + ocp_reg_set_bits(tp, 0xbf88, BIT(2)); + break; default: break; } @@ -8451,9 +8558,9 @@ static void r8157_hw_phy_cfg(struct r8152 *tp) =20 ocp_word_set_bits(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL4, EEE_SPDWN_EN); =20 - ocp_reg_w0w1(tp, OCP_DOWN_SPEED, EN_EEE_100 | EN_EEE_1000, EN_10M_CLKDIV); - - tp->ups_info._10m_ckdiv =3D true; + ocp_reg_clr_bits(tp, OCP_DOWN_SPEED, + EN_EEE_100 | EN_EEE_1000 | EN_10M_CLKDIV); + tp->ups_info._10m_ckdiv =3D false; tp->ups_info.eee_plloff_100 =3D false; tp->ups_info.eee_plloff_giga =3D false; =20 @@ -8465,7 +8572,7 @@ static void r8157_hw_phy_cfg(struct r8152 *tp) rtl_green_en(tp, test_bit(GREEN_ETHERNET, &tp->flags)); =20 ocp_reg_clr_bits(tp, 0xa428, BIT(9)); - ocp_reg_clr_bits(tp, 0xa5ea, BIT(0) | BIT(1)); + ocp_reg_clr_bits(tp, 0xa5ea, BIT(0) | BIT(1) | BIT(2)); tp->ups_info.lite_mode =3D 0; =20 if (tp->eee_en) @@ -10264,7 +10371,7 @@ static int rtl_ops_init(struct r8152 *tp) ops->eee_get =3D r8153_get_eee; ops->eee_set =3D r8152_set_eee; ops->in_nway =3D rtl8153_in_nway; - ops->hw_phy_cfg =3D r8157_hw_phy_cfg; + ops->hw_phy_cfg =3D r8159_hw_phy_cfg; ops->autosuspend_en =3D rtl8157_runtime_enable; ops->change_mtu =3D rtl8156_change_mtu; tp->rx_buf_sz =3D 48 * 1024; --=20 2.34.1 From nobody Fri Sep 25 03:17:45 2026 Received: from rtits2.realtek.com.tw (rtits2.realtek.com [211.75.126.72]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 8DB733B42E6; Thu, 17 Sep 2026 07:07:21 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=211.75.126.72 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789628843; cv=none; b=MvofpTcyHhHII8CNoE0mS2XEAUdrW/vn9lDSSlZLznvbDjtGP2JzaiJ6aaJzegzigZdEg0MesWeqRoQ9CadpxuULgKI4MLTMR2muUYw7nqytsSbBCk8TiD7kvrc2N5DXvdmXDx+mEHtWA8MtQ+3rOHBN3C2Xq6eSc+HYyfvG7JE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789628843; c=relaxed/simple; bh=1VBGEFMgNfs5Yr4FMLK0dtQpnUgrFbbiyvCshTptYek=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=SBUbc/MzPi0LH87BhQ9X1dkV/TfxJECTTb76cMJ/0twPHhoIfaJGDLaX+sB8KuMcxhdfWSV99cH8C6JKpezYXFLQs5XGoHPu74mSxq27l0aFV3Zzy5Wb+1V4MizUDGWkKJkgPum9jTQ3XkYV2wTZfhm8uxA5IV0Yf5I2Gxtnsf4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=realtek.com; spf=pass smtp.mailfrom=realtek.com; dkim=pass (2048-bit key) header.d=realtek.com header.i=@realtek.com header.b=sMoxL/3C; arc=none smtp.client-ip=211.75.126.72 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=realtek.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=realtek.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=realtek.com header.i=@realtek.com header.b="sMoxL/3C" X-SpamFilter-By: ArmorX SpamTrap 5.80 with qID 68H76gc363094124, This message is accepted by code: ctloc85258 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=realtek.com; s=dkim; t=1789628802; bh=AFesCvUUmcionXxA3qeOOHlRWnM8L4uxGTcaMx4zkf4=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Transfer-Encoding:Content-Type; b=sMoxL/3CD4ZUxhfM40gSbjV+81WJNsbw1BeY8/EV6S2KBFHzTdoedVllpP8jPKfF7 cSYNgVza61Y5hDCuZ2XXHWR+x27cxMJE5ctUfNGwX445ZA+MeAFWlY7Ok5riANW2ui 6g//w7IWMzDPIrzT4hb50yIkw2A0MCVP6+SNEuBnILQul5KFJAVz7YavldMr1OJ30I 9Jr6wVR+o0g7rL8C9WGaFNYL7X7OC3y+GsaMzAnqMqE81RHFcUrdLQGa02WaVm/Q0F NnE0NsNiNC9xuI92GZxsUytuw/W6Z0+raT+tdl8uUqRubufQLfWrKa8Qee7CZPQq33 dCEanDAD4+vqg== Received: from mail.realtek.com (rtkexhmbs02.realtek.com.tw[172.21.6.41]) by rtits2.realtek.com.tw (8.15.2/3.29/5.94) with ESMTPS id 68H76gc363094124 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL); Thu, 17 Sep 2026 15:06:42 +0800 Received: from RTKEXHMBS04.realtek.com.tw (10.21.1.54) by RTKEXHMBS02.realtek.com.tw (172.21.6.41) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.2562.49; Thu, 17 Sep 2026 15:06:40 +0800 Received: from fc44.realtek.com.tw (172.22.241.7) by RTKEXHMBS04.realtek.com.tw (10.21.1.54) with Microsoft SMTP Server id 15.2.2562.49 via Frontend Transport; Thu, 17 Sep 2026 15:06:40 +0800 From: Chih Kai Hsu To: , CC: , , , , , , , , Subject: [PATCH net-next v4 5/8] r8152: add rtl8157_unload and rtl8157_change_mtu Date: Thu, 17 Sep 2026 15:06:34 +0800 Message-ID: <20260917070637.62827-6-nic_swsd@realtek.com> X-Mailer: git-send-email 2.54.0 In-Reply-To: <20260917070637.62827-1-nic_swsd@realtek.com> References: <20260917070637.62827-1-nic_swsd@realtek.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" RTL8157 and RTL8159 used rtl8153_unload() and rtl8156_change_mtu(), which program power-cut and MTPS the way earlier chips require. Per the datasheet, RTL8157/RTL8159 need r8157_power_cut_en() (already used by r8157_init()/r8159_init()) instead of r8153_power_cut_en(), and an MTPS scaled from the configured MTU (10K-16K, max_pkt_size / 64 capped at 0xff) instead of a fixed MTPS_JUMBO/MTPS_DEFAULT. Add rtl8157_unload(), used only by RTL8157/RTL8159: calls r8157_power_cut_en(tp, false), then the Interrupt Mitigation disable that rtl8153_unload() used to gate on "tp->version >=3D RTL_VER_16" unconditionally, since this function now only runs for those versions. Add rtl8157_change_mtu(), also RTL8157/RTL8159-only, and wire it up via ops->change_mtu in place of rtl8156_change_mtu(). Signed-off-by: Chih Kai Hsu --- drivers/net/usb/r8152.c | 47 ++++++++++++++++++++++++++++++++--------- 1 file changed, 37 insertions(+), 10 deletions(-) diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c index d30031dbf2d38..f44dcb88b5c6a 100644 --- a/drivers/net/usb/r8152.c +++ b/drivers/net/usb/r8152.c @@ -7004,6 +7004,28 @@ static void rtl8156_down(struct r8152 *tp) r8153_aldps_en(tp, true); } =20 +static void rtl8157_change_mtu(struct r8152 *tp) +{ + u32 max_pkt_size =3D mtu_to_size(tp->netdev->mtu); + u32 ocp_data; + + ocp_write_word(tp, MCU_TYPE_PLA, PLA_RMS, max_pkt_size); + + /* Use at least 10K for MTPS */ + ocp_data =3D max_t(u32, max_pkt_size, 10 * 1024) / 64; + + /* 16 * 1024 / 64 =3D 0x100, so the max is 0xff for 8 bits data */ + ocp_data =3D min_t(u32, ocp_data, 0xff); + + ocp_write_byte(tp, MCU_TYPE_PLA, PLA_MTPS, ocp_data); + 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(max_pkt_size + tp->tx_desc.size, 1024) / 16); +} + static void rtl8157_up(struct r8152 *tp) { if (test_bit(RTL8152_INACCESSIBLE, &tp->flags)) @@ -7028,7 +7050,7 @@ static void rtl8157_up(struct r8152 *tp) =20 rtl_rx_vlan_en(tp, tp->netdev->features & NETIF_F_HW_VLAN_CTAG_RX); =20 - rtl8156_change_mtu(tp); + rtl8157_change_mtu(tp); =20 /* share FIFO settings */ ocp_word_w0w1(tp, MCU_TYPE_PLA, PLA_RXFIFO_FULL, RXFIFO_FULL_MASK, @@ -10151,11 +10173,6 @@ static void rtl8153_unload(struct r8152 *tp) return; =20 r8153_power_cut_en(tp, false); - - if (tp->version >=3D RTL_VER_16) { - /* Disable Interrupt Mitigation */ - ocp_byte_clr_bits(tp, MCU_TYPE_USB, 0xcf04, BIT(0) | BIT(1) | BIT(2) | B= IT(7)); - } } =20 static void rtl8153b_unload(struct r8152 *tp) @@ -10166,6 +10183,16 @@ static void rtl8153b_unload(struct r8152 *tp) r8153b_power_cut_en(tp, false); } =20 +static void rtl8157_unload(struct r8152 *tp) +{ + if (test_bit(RTL8152_INACCESSIBLE, &tp->flags)) + return; + + r8157_power_cut_en(tp, false); + ocp_byte_clr_bits(tp, MCU_TYPE_USB, 0xcf04, + BIT(0) | BIT(1) | BIT(2) | BIT(7)); +} + static int r8152_desc_init(struct r8152 *tp) { tp->rx_desc.size =3D sizeof(struct rx_desc); @@ -10344,13 +10371,13 @@ static int rtl_ops_init(struct r8152 *tp) ops->disable =3D rtl8153_disable; ops->up =3D rtl8157_up; ops->down =3D rtl8157_down; - ops->unload =3D rtl8153_unload; + ops->unload =3D rtl8157_unload; ops->eee_get =3D r8153_get_eee; ops->eee_set =3D r8152_set_eee; ops->in_nway =3D rtl8153_in_nway; ops->hw_phy_cfg =3D r8157_hw_phy_cfg; ops->autosuspend_en =3D rtl8157_runtime_enable; - ops->change_mtu =3D rtl8156_change_mtu; + ops->change_mtu =3D rtl8157_change_mtu; tp->rx_buf_sz =3D 32 * 1024; tp->support_2500full =3D 1; tp->support_5000full =3D 1; @@ -10367,13 +10394,13 @@ static int rtl_ops_init(struct r8152 *tp) ops->disable =3D rtl8153_disable; ops->up =3D rtl8157_up; ops->down =3D rtl8157_down; - ops->unload =3D rtl8153_unload; + ops->unload =3D rtl8157_unload; ops->eee_get =3D r8153_get_eee; ops->eee_set =3D r8152_set_eee; ops->in_nway =3D rtl8153_in_nway; ops->hw_phy_cfg =3D r8159_hw_phy_cfg; ops->autosuspend_en =3D rtl8157_runtime_enable; - ops->change_mtu =3D rtl8156_change_mtu; + ops->change_mtu =3D rtl8157_change_mtu; tp->rx_buf_sz =3D 48 * 1024; tp->support_2500full =3D 1; tp->support_5000full =3D 1; --=20 2.34.1 From nobody Fri Sep 25 03:17:45 2026 Received: from rtits2.realtek.com.tw (rtits2.realtek.com [211.75.126.72]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 8987F175A7F; Thu, 17 Sep 2026 07:07:20 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=211.75.126.72 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789628843; cv=none; b=vA5BeleGT8wXjCjwyo4pb+//njlQsOh7pvI6LhDwOE+D6afF8lBNJC+A4iTa9VouEkTvzNufKeDYxiVhRnTcbHsNR004bEIYa3Rl+g2s3y5UernVPx7W2kIDHgzha/h5WKbGczuk4yuE3J1JXtbHpogU5/MC1tS2WhkTrWfpJK8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789628843; c=relaxed/simple; bh=YDKLcLsJxOPXX0UrLWM1AACDhQ7V16sjHtyFvCakegQ=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=nt4A05diVX3LfyOnbgqSa6nRaQwHphMbSE0lQoDNIVM3A6b+GfiMkOxMdRyt1d3nNekxumJLdpULr8iwydouSdKB2aLcWLsR80dQh3UjiO6dZnFMva5xPlDX7AaAEXgmec9F7sUYd1261tBirFP0sncsANE+lLh1G1ImY1cmLPU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=realtek.com; spf=pass smtp.mailfrom=realtek.com; dkim=pass (2048-bit key) header.d=realtek.com header.i=@realtek.com header.b=tmUNy5Be; arc=none smtp.client-ip=211.75.126.72 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=realtek.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=realtek.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=realtek.com header.i=@realtek.com header.b="tmUNy5Be" X-SpamFilter-By: ArmorX SpamTrap 5.80 with qID 68H76gc463094124, This message is accepted by code: ctloc85258 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=realtek.com; s=dkim; t=1789628802; bh=IoVqC6iQZzhdoknxHXk3znxwmIN89gvyLiK3db55ojk=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Transfer-Encoding:Content-Type; b=tmUNy5BeE/QrMYx3iMwlts93jJk92b+Q0D4j+HrUs1JF80IuWAJWoE7AelN7JAZJj Q9NkkxBRXYqoBmvxPUdqgmAPvB2qospnzFCBgi3jZajcniM0I8mRallLOcNXtEJFp6 0AYZoJ+gvEVvWrs0D3p0MwDQJ9bknD1n6Q6+ghKVd0lM5QAyDbOUkYT2nyQXVBJe2a 0mQbfGgJ7cFjBI5NLHUnuZqn+8kj8TsuQT7pkA0Vabej3mYp8WwWhUt8CAy3yhPUcc dYU7at9uSJy+yw8o7/wXVbb6eloKXOwTZy2yY3cmQpf1pazgfoAzW8QKFAASnpHdYw t8Sk5aykg8tPQ== Received: from mail.realtek.com (rtkexhmbs02.realtek.com.tw[172.21.6.41]) by rtits2.realtek.com.tw (8.15.2/3.29/5.94) with ESMTPS id 68H76gc463094124 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL); Thu, 17 Sep 2026 15:06:42 +0800 Received: from RTKEXHMBS04.realtek.com.tw (10.21.1.54) by RTKEXHMBS02.realtek.com.tw (172.21.6.41) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.2562.49; Thu, 17 Sep 2026 15:06:40 +0800 Received: from fc44.realtek.com.tw (172.22.241.7) by RTKEXHMBS04.realtek.com.tw (10.21.1.54) with Microsoft SMTP Server id 15.2.2562.49 via Frontend Transport; Thu, 17 Sep 2026 15:06:40 +0800 From: Chih Kai Hsu To: , CC: , , , , , , , , Subject: [PATCH net-next v4 6/8] r8152: add TGPHY register access for RTL8157 and RTL8159 Date: Thu, 17 Sep 2026 15:06:35 +0800 Message-ID: <20260917070637.62827-7-nic_swsd@realtek.com> X-Mailer: git-send-email 2.54.0 In-Reply-To: <20260917070637.62827-1-nic_swsd@realtek.com> References: <20260917070637.62827-1-nic_swsd@realtek.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" RTL8157 and RTL8159 read/write PHY registers through a new TGPHY command interface (USB_TGPHY_ADDR/DATA/CMD) instead of the OCP-base-switching path used by every earlier chip: ocp_reg_read/ write() reprograms PLA_OCP_GPHY_BASE whenever the top nibble of the requested address changes. Support for these chips needs a second PHY access path, so ocp_reg_read()/ocp_reg_write() can no longer hardcode the single implementation shared by all versions. Rename the existing implementations to r8152_phy_read()/ r8152_phy_write(), and turn ocp_reg_read()/ocp_reg_write() into dispatch wrappers over new tp->rtl_ops.phy_read/phy_write function pointers, set per-chip in rtl_ops_init(). Add r8157_phy_read()/ r8157_phy_write(), built on rtl_tgphy_access(), which polls TGPHY_CMD_BUSY the same way wait_autoload_done() polls for autoload completion. Unlike wait_autoload_done() though, rtl_tgphy_access() aborts the remaining steps of the access on a busy-wait failure instead of falling through: USB_TGPHY_ADDR/CMD/DATA form a single hardware transaction gated by TGPHY_CMD_BUSY, not a sequence of independent register writes, so proceeding past an unresolved busy bit would race the in-flight command rather than just leaving an unrelated register unset. Since ocp_reg_read()/ocp_reg_write() can now fail on a TGPHY timeout, every helper built on top of them (sram_read/write, sram2_read/write, the ocp_reg_*_bits and MDIO bit helpers) is converted from void/raw- value returns to int, propagating the failure to callers instead of silently operating on stale data. Signed-off-by: Chih Kai Hsu --- drivers/net/usb/r8152.c | 430 +++++++++++++++++++++++++++++++--------- 1 file changed, 334 insertions(+), 96 deletions(-) diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c index f44dcb88b5c6a..3473061af129a 100644 --- a/drivers/net/usb/r8152.c +++ b/drivers/net/usb/r8152.c @@ -162,6 +162,9 @@ #define USB_ADV_ADDR 0xd5d6 #define USB_ADV_DATA 0xd5d8 #define USB_ADV_CMD 0xd5dc +#define USB_TGPHY_ADDR 0xd630 +#define USB_TGPHY_DATA 0xd632 +#define USB_TGPHY_CMD 0xd634 #define USB_UPS_CTRL 0xd800 #define USB_POWER_CUT 0xd80a #define USB_MISC_0 0xd81a @@ -511,6 +514,10 @@ #define ADV_CMD_WR BIT(1) #define ADV_CMD_IP BIT(2) =20 +/* USB_TGPHY_CMD */ +#define TGPHY_CMD_BUSY BIT(0) +#define TGPHY_CMD_WR BIT(1) + /* USB_UPS_CTRL */ #define POWER_CUT 0x0100 =20 @@ -959,6 +966,8 @@ struct r8152 { void (*hw_phy_cfg)(struct r8152 *tp); void (*autosuspend_en)(struct r8152 *tp, bool enable); void (*change_mtu)(struct r8152 *tp); + int (*phy_read)(struct r8152 *tp, u16 addr, u16 *data); + int (*phy_write)(struct r8152 *tp, u16 addr, u16 data); } rtl_ops; =20 struct ups_info { @@ -1638,7 +1647,7 @@ static void ocp_write_byte(struct r8152 *tp, u16 type= , u16 index, u32 data) generic_ocp_write(tp, index, byen, sizeof(tmp), &tmp, type); } =20 -static u16 ocp_reg_read(struct r8152 *tp, u16 addr) +static int r8152_phy_read(struct r8152 *tp, u16 addr, u16 *data) { u16 ocp_base, ocp_index; =20 @@ -1649,10 +1658,12 @@ static u16 ocp_reg_read(struct r8152 *tp, u16 addr) } =20 ocp_index =3D (addr & 0x0fff) | 0xb000; - return ocp_read_word(tp, MCU_TYPE_PLA, ocp_index); + *data =3D ocp_read_word(tp, MCU_TYPE_PLA, ocp_index); + + return 0; } =20 -static void ocp_reg_write(struct r8152 *tp, u16 addr, u16 data) +static int r8152_phy_write(struct r8152 *tp, u16 addr, u16 data) { u16 ocp_base, ocp_index; =20 @@ -1664,16 +1675,33 @@ static void ocp_reg_write(struct r8152 *tp, u16 add= r, u16 data) =20 ocp_index =3D (addr & 0x0fff) | 0xb000; ocp_write_word(tp, MCU_TYPE_PLA, ocp_index, data); + + return 0; +} + +static int ocp_reg_read(struct r8152 *tp, u16 addr, u16 *data) +{ + return tp->rtl_ops.phy_read(tp, addr, data); +} + +static int ocp_reg_write(struct r8152 *tp, u16 addr, u16 data) +{ + return tp->rtl_ops.phy_write(tp, addr, data); } =20 -static inline void r8152_mdio_write(struct r8152 *tp, u32 reg_addr, u32 va= lue) +static inline int r8152_mdio_write(struct r8152 *tp, u32 reg_addr, u32 val= ue) { - ocp_reg_write(tp, OCP_BASE_MII + reg_addr * 2, value); + return ocp_reg_write(tp, OCP_BASE_MII + reg_addr * 2, value); } =20 static inline int r8152_mdio_read(struct r8152 *tp, u32 reg_addr) { - return ocp_reg_read(tp, OCP_BASE_MII + reg_addr * 2); + u16 data; + int ret; + + ret =3D ocp_reg_read(tp, OCP_BASE_MII + reg_addr * 2, &data); + + return ret < 0 ? ret : data; } =20 static int wait_cmd_ready(struct r8152 *tp, u16 cmd) @@ -1792,16 +1820,32 @@ static int rtl_ip_set_bits(struct r8152 *tp, u16 ad= dr, u32 set) return rtl_ip_w0w1(tp, addr, 0, set); } =20 -static void sram_write(struct r8152 *tp, u16 addr, u16 data) +static int sram_write(struct r8152 *tp, u16 addr, u16 data) { - ocp_reg_write(tp, OCP_SRAM_ADDR, addr); + int ret; + + ret =3D ocp_reg_write(tp, OCP_SRAM_ADDR, addr); + if (ret < 0) + goto out; + ocp_reg_write(tp, OCP_SRAM_DATA, data); + +out: + return ret; } =20 -static u16 sram_read(struct r8152 *tp, u16 addr) +static int sram_read(struct r8152 *tp, u16 addr, u16 *data) { - ocp_reg_write(tp, OCP_SRAM_ADDR, addr); - return ocp_reg_read(tp, OCP_SRAM_DATA); + int ret; + + ret =3D ocp_reg_write(tp, OCP_SRAM_ADDR, addr); + if (ret < 0) + goto out; + + ret =3D ocp_reg_read(tp, OCP_SRAM_DATA, data); + +out: + return ret; } =20 static int read_mii_word(struct net_device *netdev, int phy_id, int reg) @@ -1906,100 +1950,217 @@ static void ocp_byte_set_bits(struct r8152 *tp, u= 16 type, u16 index, u8 set) ocp_byte_w0w1(tp, type, index, 0, set); } =20 -static void ocp_reg_w0w1(struct r8152 *tp, u16 addr, u16 clear, u16 set) +static int ocp_reg_w0w1(struct r8152 *tp, u16 addr, u16 clear, u16 set) { u16 data; + int ret; + + ret =3D ocp_reg_read(tp, addr, &data); + if (ret < 0) + goto out; =20 - data =3D ocp_reg_read(tp, addr); data =3D (data & ~clear) | set; - ocp_reg_write(tp, addr, data); + ret =3D ocp_reg_write(tp, addr, data); + +out: + return ret; } =20 -static void ocp_reg_clr_bits(struct r8152 *tp, u16 addr, u16 clear) +static int ocp_reg_clr_bits(struct r8152 *tp, u16 addr, u16 clear) { - ocp_reg_w0w1(tp, addr, clear, 0); + return ocp_reg_w0w1(tp, addr, clear, 0); } =20 -static void ocp_reg_set_bits(struct r8152 *tp, u16 addr, u16 set) +static int ocp_reg_set_bits(struct r8152 *tp, u16 addr, u16 set) { - ocp_reg_w0w1(tp, addr, 0, set); + return ocp_reg_w0w1(tp, addr, 0, set); } =20 -static void sram_write_w0w1(struct r8152 *tp, u16 addr, u16 clear, u16 set) +static int sram_write_w0w1(struct r8152 *tp, u16 addr, u16 clear, u16 set) { u16 data; + int ret; + + ret =3D sram_read(tp, addr, &data); + if (ret < 0) + goto out; =20 - data =3D sram_read(tp, addr); data =3D (data & ~clear) | set; - ocp_reg_write(tp, OCP_SRAM_DATA, data); + ret =3D ocp_reg_write(tp, OCP_SRAM_DATA, data); + +out: + return ret; } =20 -static void sram_clr_bits(struct r8152 *tp, u16 addr, u16 clear) +static int sram_clr_bits(struct r8152 *tp, u16 addr, u16 clear) { - sram_write_w0w1(tp, addr, clear, 0); + return sram_write_w0w1(tp, addr, clear, 0); } =20 -static void sram_set_bits(struct r8152 *tp, u16 addr, u16 set) +static int sram_set_bits(struct r8152 *tp, u16 addr, u16 set) { - sram_write_w0w1(tp, addr, 0, set); + return sram_write_w0w1(tp, addr, 0, set); } =20 -static void sram2_write(struct r8152 *tp, u16 addr, u16 data) +static int sram2_write(struct r8152 *tp, u16 addr, u16 data) { - ocp_reg_write(tp, OCP_SRAM2_ADDR, addr); - ocp_reg_write(tp, OCP_SRAM2_DATA, data); + int ret; + + ret =3D ocp_reg_write(tp, OCP_SRAM2_ADDR, addr); + if (ret < 0) + goto out; + + ret =3D ocp_reg_write(tp, OCP_SRAM2_DATA, data); + +out: + return ret; } =20 -static u16 sram2_read(struct r8152 *tp, u16 addr) +static int sram2_read(struct r8152 *tp, u16 addr, u16 *data) { - ocp_reg_write(tp, OCP_SRAM2_ADDR, addr); - return ocp_reg_read(tp, OCP_SRAM2_DATA); + int ret; + + ret =3D ocp_reg_write(tp, OCP_SRAM2_ADDR, addr); + if (ret < 0) + goto out; + + ret =3D ocp_reg_read(tp, OCP_SRAM2_DATA, data); + +out: + return ret; } =20 -static void sram2_write_w0w1(struct r8152 *tp, u16 addr, u16 clear, u16 se= t) +static int sram2_write_w0w1(struct r8152 *tp, u16 addr, u16 clear, u16 set) { u16 data; + int ret; + + ret =3D sram2_read(tp, addr, &data); + if (ret < 0) + goto out; =20 - data =3D sram2_read(tp, addr); data =3D (data & ~clear) | set; - ocp_reg_write(tp, OCP_SRAM2_DATA, data); + ret =3D ocp_reg_write(tp, OCP_SRAM2_DATA, data); + +out: + return ret; } =20 -static void sram2_set_bits(struct r8152 *tp, u16 addr, u16 set) +static int sram2_set_bits(struct r8152 *tp, u16 addr, u16 set) { - sram2_write_w0w1(tp, addr, 0, set); + return sram2_write_w0w1(tp, addr, 0, set); } =20 -static void sram2_clr_bits(struct r8152 *tp, u16 addr, u16 clear) +static int sram2_clr_bits(struct r8152 *tp, u16 addr, u16 clear) { - sram2_write_w0w1(tp, addr, clear, 0); + return sram2_write_w0w1(tp, addr, clear, 0); } =20 -static void r8152_mdio_clr_bit(struct r8152 *tp, u16 addr, u16 clear) +static int r8152_mdio_clr_bit(struct r8152 *tp, u16 addr, u16 clear) { int data; =20 data =3D r8152_mdio_read(tp, addr); - r8152_mdio_write(tp, addr, data & ~clear); + if (data < 0) + goto out; + + data =3D r8152_mdio_write(tp, addr, data & ~clear); + +out: + return data; } =20 -static void r8152_mdio_set_bit(struct r8152 *tp, u16 addr, u16 set) +static int r8152_mdio_set_bit(struct r8152 *tp, u16 addr, u16 set) { int data; =20 data =3D r8152_mdio_read(tp, addr); - r8152_mdio_write(tp, addr, data | set); + if (data < 0) + goto out; + + data =3D r8152_mdio_write(tp, addr, data | set); + +out: + return data; } =20 static int r8152_mdio_test_and_clr_bit(struct r8152 *tp, u16 addr, u16 cle= ar) { - int data; + int data, ret; =20 - data =3D r8152_mdio_read(tp, addr); - if (data & clear) - r8152_mdio_write(tp, addr, data & ~clear); + ret =3D r8152_mdio_read(tp, addr); + if (ret < 0) + goto out; =20 - return data & clear; + data =3D ret; + if (data & clear) { + ret =3D r8152_mdio_write(tp, addr, data & ~clear); + if (ret < 0) + goto out; + } + + ret =3D !!(data & clear); + +out: + return ret; +} + +static int wait_tgphy_cmd_ready(struct r8152 *tp) +{ + u16 ocp_data; + int ret; + + ret =3D read_poll_timeout(ocp_read_word, ocp_data, + test_bit(RTL8152_INACCESSIBLE, &tp->flags) || + !(ocp_data & TGPHY_CMD_BUSY), + 2000, 20000, false, tp, + MCU_TYPE_USB, USB_TGPHY_CMD); + + if (ret) + dev_err(&tp->intf->dev, "TGPHY cmd busy timeout\n"); + + return test_bit(RTL8152_INACCESSIBLE, &tp->flags) ? -ENODEV : ret; +} + +static int rtl_tgphy_access(struct r8152 *tp, u16 addr, u16 *data, bool wr= ite) +{ + u16 cmd =3D 0; + int ret; + + ret =3D wait_tgphy_cmd_ready(tp); + if (ret < 0) + goto out; + + if (write) { + cmd |=3D TGPHY_CMD_WR; + ocp_write_word(tp, MCU_TYPE_USB, USB_TGPHY_DATA, *data); + } + + ocp_write_word(tp, MCU_TYPE_USB, USB_TGPHY_ADDR, addr); + + cmd |=3D TGPHY_CMD_BUSY; + ocp_write_word(tp, MCU_TYPE_USB, USB_TGPHY_CMD, cmd); + + if (!write) { + ret =3D wait_tgphy_cmd_ready(tp); + if (ret < 0) + goto out; + + *data =3D ocp_read_word(tp, MCU_TYPE_USB, USB_TGPHY_DATA); + } + +out: + return ret; +} + +static int r8157_phy_read(struct r8152 *tp, u16 addr, u16 *data) +{ + return rtl_tgphy_access(tp, addr, data, false); +} + +static int r8157_phy_write(struct r8152 *tp, u16 addr, u16 data) +{ + return rtl_tgphy_access(tp, addr, &data, true); } =20 static int @@ -4177,11 +4338,13 @@ static void r8153b_green_en(struct r8152 *tp, bool = enable) =20 static u16 r8153_phy_status(struct r8152 *tp, u16 desired) { - u16 data; + u16 data =3D 0; int i; =20 for (i =3D 0; i < 500; i++) { - data =3D ocp_reg_read(tp, OCP_PHY_STATUS); + if (ocp_reg_read(tp, OCP_PHY_STATUS, &data) < 0) + break; + data &=3D PHY_STAT_MASK; if (desired) { if (data =3D=3D desired) @@ -4587,7 +4750,8 @@ static inline void rtl_reset_ocp_base(struct r8152 *t= p) static int rtl_phy_patch_request(struct r8152 *tp, bool request, bool wait) { u16 check; - int i; + u16 ocp_data =3D 0; + int i, ret; =20 if (request) { ocp_reg_set_bits(tp, OCP_PHY_PATCH_CMD, PATCH_REQUEST); @@ -4598,25 +4762,23 @@ static int rtl_phy_patch_request(struct r8152 *tp, = bool request, bool wait) } =20 for (i =3D 0; wait && i < 5000; i++) { - u32 ocp_data; - if (test_bit(RTL8152_INACCESSIBLE, &tp->flags)) return -ENODEV; =20 usleep_range(1000, 2000); - ocp_data =3D ocp_reg_read(tp, OCP_PHY_PATCH_STAT); - if ((ocp_data & PATCH_READY) ^ check) + ret =3D ocp_reg_read(tp, OCP_PHY_PATCH_STAT, &ocp_data); + if (ret < 0 || (ocp_data & PATCH_READY) ^ check) break; } =20 - if (request && wait && - !(ocp_reg_read(tp, OCP_PHY_PATCH_STAT) & PATCH_READY)) { + ret =3D ocp_reg_read(tp, OCP_PHY_PATCH_STAT, &ocp_data); + if (request && wait && (ret < 0 || !(ocp_data & PATCH_READY))) { dev_err(&tp->intf->dev, "PHY patch request fail\n"); rtl_phy_patch_request(tp, false, false); return -ETIME; - } else { - return 0; } + + return 0; } =20 static void rtl_patch_key_set(struct r8152 *tp, u16 key_addr, u16 patch_ke= y) @@ -5331,10 +5493,12 @@ static void rtl_ram_code_speed_up(struct r8152 *tp,= struct fw_phy_speed_up *phy, { u32 len; u8 *data; + u16 ver =3D 0; =20 rtl_reset_ocp_base(tp); =20 - if (sram_read(tp, SRAM_GPHY_FW_VER) >=3D __le16_to_cpu(phy->version)) { + sram_read(tp, SRAM_GPHY_FW_VER, &ver); + if (ver >=3D __le16_to_cpu(phy->version)) { dev_dbg(&tp->intf->dev, "PHY firmware has been the newest\n"); return; } @@ -5381,7 +5545,9 @@ static void rtl_ram_code_speed_up(struct r8152 *tp, s= truct fw_phy_speed_up *phy, =20 rtl_phy_patch_request(tp, false, wait); =20 - if (sram_read(tp, SRAM_GPHY_FW_VER) =3D=3D __le16_to_cpu(phy->version)) + ver =3D 0; + sram_read(tp, SRAM_GPHY_FW_VER, &ver); + if (ver =3D=3D __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"); @@ -5389,14 +5555,15 @@ static void rtl_ram_code_speed_up(struct r8152 *tp,= struct fw_phy_speed_up *phy, =20 static int rtl8152_fw_phy_ver(struct r8152 *tp, struct fw_phy_ver *phy_ver) { - u16 ver_addr, ver; + u16 ver_addr, ver, cur_ver =3D 0; =20 ver_addr =3D __le16_to_cpu(phy_ver->ver.addr); ver =3D __le16_to_cpu(phy_ver->ver.data); =20 rtl_reset_ocp_base(tp); =20 - if (sram_read(tp, ver_addr) >=3D ver) { + sram_read(tp, ver_addr, &cur_ver); + if (cur_ver >=3D ver) { dev_dbg(&tp->intf->dev, "PHY firmware has been the newest\n"); return 0; } @@ -5415,7 +5582,8 @@ static void rtl8152_fw_phy_fixup(struct r8152 *tp, st= ruct fw_phy_fixup *fix) rtl_reset_ocp_base(tp); =20 addr =3D __le16_to_cpu(fix->setting.addr); - data =3D ocp_reg_read(tp, addr); + if (ocp_reg_read(tp, addr, &data) < 0) + return; =20 switch (__le16_to_cpu(fix->bit_cmd)) { case FW_FIXUP_AND: @@ -5719,10 +5887,10 @@ static inline void r8152_mmd_indirect(struct r8152 = *tp, u16 dev, u16 reg) =20 static u16 r8152_mmd_read(struct r8152 *tp, u16 dev, u16 reg) { - u16 data; + u16 data =3D 0; =20 r8152_mmd_indirect(tp, dev, reg); - data =3D ocp_reg_read(tp, OCP_EEE_DATA); + ocp_reg_read(tp, OCP_EEE_DATA, &data); ocp_reg_write(tp, OCP_EEE_AR, 0x0000); =20 return data; @@ -5787,7 +5955,8 @@ static void r8156_eee_en(struct r8152 *tp, bool enabl= e) =20 r8153_eee_en(tp, enable); =20 - config =3D ocp_reg_read(tp, OCP_EEE_ADV2); + if (ocp_reg_read(tp, OCP_EEE_ADV2, &config) < 0) + return; =20 if (enable && (tp->eee_adv2 & MDIO_EEE_2_5GT)) config |=3D MDIO_EEE_2_5GT; @@ -6243,8 +6412,8 @@ static void r8153b_hw_phy_cfg(struct r8152 *tp) * rg_saw_cnt =3D OCP reg 0xC426 Bit[13:0] * swr_cnt_1ms_ini =3D 16000000 / rg_saw_cnt */ - ocp_data =3D ocp_reg_read(tp, 0xc426); - ocp_data &=3D 0x3fff; + ocp_reg_read(tp, 0xc426, &data); + ocp_data =3D data & 0x3fff; if (ocp_data) { u32 swr_cnt_1ms_ini; =20 @@ -6601,7 +6770,11 @@ static int rtl8152_set_speed(struct r8152 *tp, u8 au= toneg, u32 speed, u8 duplex, if (!advertising) return -EINVAL; =20 - orig =3D r8152_mdio_read(tp, MII_ADVERTISE); + ret =3D r8152_mdio_read(tp, MII_ADVERTISE); + if (ret < 0) + goto out; + + orig =3D ret; new1 =3D orig & ~(ADVERTISE_10HALF | ADVERTISE_10FULL | ADVERTISE_100HALF | ADVERTISE_100FULL); if (advertising & RTL_ADVERTISED_10_HALF) { @@ -6628,7 +6801,11 @@ static int rtl8152_set_speed(struct r8152 *tp, u8 au= toneg, u32 speed, u8 duplex, } =20 if (tp->mii.supports_gmii) { - orig =3D r8152_mdio_read(tp, MII_CTRL1000); + ret =3D r8152_mdio_read(tp, MII_CTRL1000); + if (ret < 0) + goto out; + + orig =3D ret; new1 =3D orig & ~(ADVERTISE_1000FULL | ADVERTISE_1000HALF); =20 @@ -6642,7 +6819,10 @@ static int rtl8152_set_speed(struct r8152 *tp, u8 au= toneg, u32 speed, u8 duplex, } =20 if (tp->support_2500full || tp->support_5000full || tp->support_10000ful= l) { - orig =3D ocp_reg_read(tp, OCP_10GBT_CTRL); + ret =3D ocp_reg_read(tp, OCP_10GBT_CTRL, &orig); + if (ret < 0) + goto out; + new1 =3D orig & ~(MDIO_AN_10GBT_CTRL_ADV2_5G | MDIO_AN_10GBT_CTRL_ADV5G | MDIO_AN_10GBT_CTRL_ADV10G); =20 @@ -6686,7 +6866,7 @@ static int rtl8152_set_speed(struct r8152 *tp, u8 aut= oneg, u32 speed, u8 duplex, } =20 out: - return ret; + return ret < 0 ? ret : 0; } =20 static void rtl8152_up(struct r8152 *tp) @@ -7136,7 +7316,12 @@ static bool rtl8152_in_nway(struct r8152 *tp) =20 static bool rtl8153_in_nway(struct r8152 *tp) { - u16 phy_state =3D ocp_reg_read(tp, OCP_PHY_STATE) & 0xff; + u16 phy_state; + + if (ocp_reg_read(tp, OCP_PHY_STATE, &phy_state) < 0) + return false; + + phy_state &=3D 0xff; =20 if (phy_state =3D=3D TXDIS_STATE || phy_state =3D=3D ABD_STATE) return false; @@ -7152,7 +7337,9 @@ static void r8156_mdio_force_mode(struct r8152 *tp) * 0: MDIO force mode * 1: MMD force mode */ - data =3D ocp_reg_read(tp, 0xa5b4); + if (ocp_reg_read(tp, 0xa5b4, &data) < 0) + return; + if (data & BIT(15)) { data &=3D ~BIT(15); ocp_reg_write(tp, 0xa5b4, data); @@ -7791,19 +7978,20 @@ static void r8156_hw_phy_cfg(struct r8152 *tp) ocp_reg_clr_bits(tp, 0xa86a, BIT(0)); =20 /* MDI SWAP */ + ocp_reg_read(tp, 0xd068, &data); if ((ocp_read_word(tp, MCU_TYPE_USB, USB_UPS_CFG) & MID_REVERSE) && - (ocp_reg_read(tp, 0xd068) & BIT(1))) { + (data & BIT(1))) { u16 swap_a, swap_b; =20 - data =3D ocp_reg_read(tp, 0xd068); + ocp_reg_read(tp, 0xd068, &data); data &=3D ~0x1f; data |=3D 0x1; /* p0 */ ocp_reg_write(tp, 0xd068, data); - swap_a =3D ocp_reg_read(tp, 0xd06a); + ocp_reg_read(tp, 0xd06a, &swap_a); data &=3D ~0x18; data |=3D 0x18; /* p3 */ ocp_reg_write(tp, 0xd068, data); - swap_b =3D ocp_reg_read(tp, 0xd06a); + ocp_reg_read(tp, 0xd06a, &swap_b); data &=3D ~0x18; /* p0 */ ocp_reg_write(tp, 0xd068, data); ocp_reg_write(tp, 0xd06a, @@ -7815,11 +8003,11 @@ static void r8156_hw_phy_cfg(struct r8152 *tp) data &=3D ~0x18; data |=3D 0x08; /* p1 */ ocp_reg_write(tp, 0xd068, data); - swap_a =3D ocp_reg_read(tp, 0xd06a); + ocp_reg_read(tp, 0xd06a, &swap_a); data &=3D ~0x18; data |=3D 0x10; /* p2 */ ocp_reg_write(tp, 0xd068, data); - swap_b =3D ocp_reg_read(tp, 0xd06a); + ocp_reg_read(tp, 0xd06a, &swap_b); data &=3D ~0x18; data |=3D 0x08; /* p1 */ ocp_reg_write(tp, 0xd068, data); @@ -7830,16 +8018,16 @@ static void r8156_hw_phy_cfg(struct r8152 *tp) ocp_reg_write(tp, 0xd068, data); ocp_reg_write(tp, 0xd06a, (swap_b & ~0x7ff) | (swap_a & 0x7ff)); - swap_a =3D ocp_reg_read(tp, 0xbd5a); - swap_b =3D ocp_reg_read(tp, 0xbd5c); + ocp_reg_read(tp, 0xbd5a, &swap_a); + ocp_reg_read(tp, 0xbd5c, &swap_b); 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 =3D ocp_reg_read(tp, 0xbc18); - swap_b =3D ocp_reg_read(tp, 0xbc1a); + ocp_reg_read(tp, 0xbc18, &swap_a); + ocp_reg_read(tp, 0xbc1a, &swap_b); ocp_reg_write(tp, 0xbc18, (swap_a & ~0x1f1f) | ((swap_b & 0x1f) << 8) | ((swap_b >> 8) & 0x1f)); @@ -9436,8 +9624,16 @@ int rtl8152_get_link_ksettings(struct net_device *ne= tdev, cmd->link_modes.supported, tp->support_10000full); =20 if (tp->support_2500full || tp->support_5000full || tp->support_10000full= ) { - u16 ocp_10gbt_ctrl =3D ocp_reg_read(tp, OCP_10GBT_CTRL); - u16 ocp_10gbt_stat =3D ocp_reg_read(tp, OCP_10GBT_STAT); + u16 ocp_10gbt_ctrl; + u16 ocp_10gbt_stat; + + ret =3D ocp_reg_read(tp, OCP_10GBT_CTRL, &ocp_10gbt_ctrl); + if (ret < 0) + goto out_unlock; + + ret =3D ocp_reg_read(tp, OCP_10GBT_STAT, &ocp_10gbt_stat); + if (ret < 0) + goto out_unlock; =20 if (tp->support_2500full) { linkmode_mod_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT, @@ -9479,12 +9675,13 @@ int rtl8152_get_link_ksettings(struct net_device *n= etdev, } } =20 +out_unlock: mutex_unlock(&tp->control); =20 usb_autopm_put_interface(tp->intf); =20 out: - return ret; + return ret < 0 ? ret : 0; } =20 static int rtl8152_set_link_ksettings(struct net_device *dev, @@ -9665,21 +9862,37 @@ static int r8153_get_eee(struct r8152 *tp, struct e= thtool_keee *eee) __ETHTOOL_DECLARE_LINK_MODE_MASK(common) =3D {}; u16 speed =3D rtl8152_get_speed(tp); u16 val; + int ret; + + ret =3D ocp_reg_read(tp, OCP_EEE_ABLE, &val); + if (ret < 0) + goto out; =20 - val =3D ocp_reg_read(tp, OCP_EEE_ABLE); mii_eee_cap1_mod_linkmode_t(eee->supported, val); =20 - val =3D ocp_reg_read(tp, OCP_EEE_ADV); + ret =3D ocp_reg_read(tp, OCP_EEE_ADV, &val); + if (ret < 0) + goto out; + mii_eee_cap1_mod_linkmode_t(eee->advertised, val); =20 - val =3D ocp_reg_read(tp, OCP_EEE_LPABLE); + ret =3D ocp_reg_read(tp, OCP_EEE_LPABLE, &val); + if (ret < 0) + goto out; + mii_eee_cap1_mod_linkmode_t(eee->lp_advertised, val); =20 if (tp->support_2500full || tp->support_5000full) { - val =3D ocp_reg_read(tp, OCP_EEE_ADV2); + ret =3D ocp_reg_read(tp, OCP_EEE_ADV2, &val); + if (ret < 0) + goto out; + mii_eee_cap2_mod_linkmode_adv_t(eee->advertised, val); =20 - val =3D ocp_reg_read(tp, OCP_EEE_LPABLE2); + ret =3D ocp_reg_read(tp, OCP_EEE_LPABLE2, &val); + if (ret < 0) + goto out; + mii_eee_cap2_mod_linkmode_adv_t(eee->lp_advertised, val); } =20 @@ -9715,7 +9928,8 @@ static int r8153_get_eee(struct r8152 *tp, struct eth= tool_keee *eee) linkmode_and(common, common, eee->lp_advertised); eee->eee_active =3D !linkmode_empty(common); =20 - return 0; +out: + return ret < 0 ? ret : 0; } =20 static int @@ -10002,7 +10216,11 @@ static int rtl8152_set_pauseparam(struct net_devic= e *netdev, struct ethtool_paus =20 mutex_lock(&tp->control); =20 - if (pause->autoneg && !(r8152_mdio_read(tp, MII_BMCR) & BMCR_ANENABLE)) { + ret =3D r8152_mdio_read(tp, MII_BMCR); + if (ret < 0) + goto out; + + if (pause->autoneg && !(ret & BMCR_ANENABLE)) { ret =3D -EINVAL; goto out; } @@ -10013,7 +10231,11 @@ static int rtl8152_set_pauseparam(struct net_devic= e *netdev, struct ethtool_paus if (pause->tx_pause) cap |=3D FLOW_CTRL_TX; =20 - old =3D r8152_mdio_read(tp, MII_ADVERTISE); + ret =3D r8152_mdio_read(tp, MII_ADVERTISE); + if (ret < 0) + goto out; + + old =3D ret; new1 =3D (old & ~(ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM)) | mii_adve= rtise_flowctrl(cap); if (old !=3D new1) r8152_mdio_write(tp, MII_ADVERTISE, new1); @@ -10022,7 +10244,7 @@ static int rtl8152_set_pauseparam(struct net_device= *netdev, struct ethtool_paus mutex_unlock(&tp->control); usb_autopm_put_interface(tp->intf); =20 - return ret; + return ret < 0 ? ret : 0; } =20 static const struct ethtool_ops ops =3D { @@ -10245,6 +10467,8 @@ static int rtl_ops_init(struct r8152 *tp) ops->in_nway =3D rtl8152_in_nway; ops->hw_phy_cfg =3D r8152b_hw_phy_cfg; ops->autosuspend_en =3D rtl_runtime_suspend_enable; + ops->phy_read =3D r8152_phy_read; + ops->phy_write =3D r8152_phy_write; tp->rx_buf_sz =3D 16 * 1024; tp->eee_en =3D true; tp->eee_adv =3D MDIO_EEE_100TX; @@ -10267,6 +10491,8 @@ static int rtl_ops_init(struct r8152 *tp) ops->hw_phy_cfg =3D r8153_hw_phy_cfg; ops->autosuspend_en =3D rtl8153_runtime_enable; ops->change_mtu =3D rtl8153_change_mtu; + ops->phy_read =3D r8152_phy_read; + ops->phy_write =3D r8152_phy_write; if (tp->udev->speed < USB_SPEED_SUPER) tp->rx_buf_sz =3D 16 * 1024; else @@ -10290,6 +10516,8 @@ static int rtl_ops_init(struct r8152 *tp) ops->hw_phy_cfg =3D r8153b_hw_phy_cfg; ops->autosuspend_en =3D rtl8153b_runtime_enable; ops->change_mtu =3D rtl8153_change_mtu; + ops->phy_read =3D r8152_phy_read; + ops->phy_write =3D r8152_phy_write; tp->rx_buf_sz =3D 32 * 1024; tp->eee_en =3D true; tp->eee_adv =3D MDIO_EEE_1000T | MDIO_EEE_100TX; @@ -10314,6 +10542,8 @@ static int rtl_ops_init(struct r8152 *tp) ops->hw_phy_cfg =3D r8156_hw_phy_cfg; ops->autosuspend_en =3D rtl8156_runtime_enable; ops->change_mtu =3D rtl8156_change_mtu; + ops->phy_read =3D r8152_phy_read; + ops->phy_write =3D r8152_phy_write; tp->rx_buf_sz =3D 48 * 1024; tp->support_2500full =3D 1; r8152_desc_init(tp); @@ -10339,6 +10569,8 @@ static int rtl_ops_init(struct r8152 *tp) ops->hw_phy_cfg =3D r8156b_hw_phy_cfg; ops->autosuspend_en =3D rtl8156_runtime_enable; ops->change_mtu =3D rtl8156_change_mtu; + ops->phy_read =3D r8152_phy_read; + ops->phy_write =3D r8152_phy_write; tp->rx_buf_sz =3D 48 * 1024; r8152_desc_init(tp); break; @@ -10356,6 +10588,8 @@ static int rtl_ops_init(struct r8152 *tp) ops->hw_phy_cfg =3D r8153c_hw_phy_cfg; ops->autosuspend_en =3D rtl8153c_runtime_enable; ops->change_mtu =3D rtl8153c_change_mtu; + ops->phy_read =3D r8152_phy_read; + ops->phy_write =3D r8152_phy_write; tp->rx_buf_sz =3D 32 * 1024; tp->eee_en =3D true; tp->eee_adv =3D MDIO_EEE_1000T | MDIO_EEE_100TX; @@ -10378,6 +10612,8 @@ static int rtl_ops_init(struct r8152 *tp) ops->hw_phy_cfg =3D r8157_hw_phy_cfg; ops->autosuspend_en =3D rtl8157_runtime_enable; ops->change_mtu =3D rtl8157_change_mtu; + ops->phy_read =3D r8157_phy_read; + ops->phy_write =3D r8157_phy_write; tp->rx_buf_sz =3D 32 * 1024; tp->support_2500full =3D 1; tp->support_5000full =3D 1; @@ -10401,6 +10637,8 @@ static int rtl_ops_init(struct r8152 *tp) ops->hw_phy_cfg =3D r8159_hw_phy_cfg; ops->autosuspend_en =3D rtl8157_runtime_enable; ops->change_mtu =3D rtl8157_change_mtu; + ops->phy_read =3D r8157_phy_read; + ops->phy_write =3D r8157_phy_write; tp->rx_buf_sz =3D 48 * 1024; tp->support_2500full =3D 1; tp->support_5000full =3D 1; --=20 2.34.1 From nobody Fri Sep 25 03:17:45 2026 Received: from rtits2.realtek.com.tw (rtits2.realtek.com [211.75.126.72]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 899EA3A83BF; Thu, 17 Sep 2026 07:07:20 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=211.75.126.72 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789628842; cv=none; b=hPHi+IiHlO4LpMNrUEAAFYiqzFIStq4TaRCKx3nAz5Rqna457zIOUXCMMs5VNcIrnqvgnr/7Ofj7ucGDGBiHjUI10S8nUN2t8Jxlsumk43tR03os/W7BZaHpAqJKPUly3quYw0EHE1tvnRfek8wvZkmDdKqGOm7mzdVzt/NCZ2w= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789628842; c=relaxed/simple; bh=ts9GKfwCp6caRLak4YpdW4z899iK8x0TzDZ/3sQ0ttU=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=P9ravQe3kNzUR83gvW5D+zL58a/+bOJfEGWzL9unxlrQvmEaoN6a4oAm0ztIIoeElQOhLobAeVF9A0hjZRU47DOVxKEtVahfeSvYmDGGHvowi1n+9Msb+iev6T8ATbM3tQakUl4VlTcMuaApxtlE0Fp+zMBUwsRlmruF3ZzEiGA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=realtek.com; spf=pass smtp.mailfrom=realtek.com; dkim=pass (2048-bit key) header.d=realtek.com header.i=@realtek.com header.b=JCYu+NjG; arc=none smtp.client-ip=211.75.126.72 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=realtek.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=realtek.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=realtek.com header.i=@realtek.com header.b="JCYu+NjG" X-SpamFilter-By: ArmorX SpamTrap 5.80 with qID 68H76gc663094124, This message is accepted by code: ctloc85258 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=realtek.com; s=dkim; t=1789628803; bh=165Ffk/7PsthNVNc3FRX4MomV14yYGUiU6x3L23pcbE=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Transfer-Encoding:Content-Type; b=JCYu+NjGhbS9sBbLMt9NsuFTGGfhh3C/WbeZmNPGosNlUH+G0RB8mEnZcmXGCRVE8 jiNnZ3pQD/cEIIOBKMuDdHV8+COxsZRIllNVuRYYwUjHHksTJVlcZKdazz7oKg2Io7 JI7NosmW5bzobPxYtqp7aaqmKYprSJKQArkNePOZv1rmQmzQORvZgAV5WgnPi73u6g 1Yp6BKIXht+s9/0Knva/Rz7WKmCoZcN9QJchtERpXEA197NqAURdnxcoGl7zNEl2fV R+cJJATAjYh9pNxZ56SndUTexqUl1oDb6pqcAiv7+RKLfaKB0FRFoUCDwwCkzSujPb V4BBjxzstoz0Q== Received: from mail.realtek.com (rtkexhmbs02.realtek.com.tw[172.21.6.41]) by rtits2.realtek.com.tw (8.15.2/3.29/5.94) with ESMTPS id 68H76gc663094124 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL); Thu, 17 Sep 2026 15:06:43 +0800 Received: from RTKEXHMBS04.realtek.com.tw (10.21.1.54) by RTKEXHMBS02.realtek.com.tw (172.21.6.41) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.2562.49; Thu, 17 Sep 2026 15:06:40 +0800 Received: from fc44.realtek.com.tw (172.22.241.7) by RTKEXHMBS04.realtek.com.tw (10.21.1.54) with Microsoft SMTP Server id 15.2.2562.49 via Frontend Transport; Thu, 17 Sep 2026 15:06:40 +0800 From: Chih Kai Hsu To: , CC: , , , , , , , , Subject: [PATCH net-next v4 7/8] r8152: extract rtl_fc_pause_pkt_en() and apply it to RTL8156/8157/8159 Date: Thu, 17 Sep 2026 15:06:36 +0800 Message-ID: <20260917070637.62827-8-nic_swsd@realtek.com> X-Mailer: git-send-email 2.54.0 In-Reply-To: <20260917070637.62827-1-nic_swsd@realtek.com> References: <20260917070637.62827-1-nic_swsd@realtek.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" The flow-control patch in r8156b_init() only ran for RTL8156B (VER_12/13/15). RTL8156A (VER_10/11) and RTL8157/RTL8159 (VER_16/17) never applied any flow-control patch at all. Extract it into rtl_fc_pause_pkt_en(tp, speed) and add the missing cases: - VER_10/11: same FC timer + FLOW_CTRL_PATCH_OPT sequence RTL8153B (VER_09) already applies via its pre_fw/post_fw hooks, applied directly here instead. - VER_16/17_QFN68/QFN100: RTL8157/RTL8159 use a different mechanism. The datasheet gives a fixed pause-packet count per link speed via the new PLA_PAUSE_LIMIT register; num_pause_pkts is computed with a log2-ratio formula that reproduces that table. Since the count depends on the negotiated speed, call rtl_fc_pause_pkt_en() from rtl8157_enable() instead of from init. Signed-off-by: Chih Kai Hsu --- drivers/net/usb/r8152.c | 112 ++++++++++++++++++++++++++++++++++------ 1 file changed, 97 insertions(+), 15 deletions(-) diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c index 3473061af129a..05b2b79ab3e31 100644 --- a/drivers/net/usb/r8152.c +++ b/drivers/net/usb/r8152.c @@ -89,6 +89,7 @@ #define PLA_MTPS 0xe615 #define PLA_TXFIFO_CTRL 0xe618 #define PLA_TXFIFO_FULL 0xe61a +#define PLA_PAUSE_LIMIT 0xe61e #define PLA_RSTTALLY 0xe800 #define PLA_CR 0xe813 #define PLA_CRWECR 0xe81c @@ -301,6 +302,10 @@ #define MTPS_JUMBO (12 * 1024 / 64) #define MTPS_DEFAULT (6 * 1024 / 64) =20 +/* PLA_PAUSE_LIMIT */ +#define PAUSE_LIMIT_EN BIT(3) +#define PAUSE_LIMIT_MASK 0xf0 + /* PLA_RSTTALLY */ #define TALLY_RESET 0x0001 =20 @@ -6163,6 +6168,93 @@ static void r8152b_enter_oob(struct r8152 *tp) RCR_APM | RCR_AM | RCR_AB); } =20 +static void rtl_fc_pause_pkt_en(struct r8152 *tp, u16 speed) +{ + int log2_ratio, ratio; + u16 num_pause_pkts; + u32 ocp_data; + + switch (tp->version) { + case RTL_VER_10: + case RTL_VER_11: + ocp_write_word(tp, MCU_TYPE_USB, USB_FC_TIMER, + CTRL_TIMER_EN | (1000 / 8)); + + ocp_word_set_bits(tp, MCU_TYPE_USB, USB_FW_CTRL, + FLOW_CTRL_PATCH_OPT); + + ocp_word_set_bits(tp, MCU_TYPE_USB, USB_FW_TASK, FC_PATCH_TASK); + break; + case RTL_VER_12: + case RTL_VER_13: + case RTL_VER_15: + ocp_word_clr_bits(tp, MCU_TYPE_PLA, PLA_RCR, SLOT_EN); + + ocp_word_set_bits(tp, MCU_TYPE_PLA, PLA_CPCR, FLOW_CTRL_EN); + + /* 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 =3D ocp_read_word(tp, MCU_TYPE_PLA, PLA_POL_GPIO_CTRL); + if (!(ocp_data & DACK_DET_EN)) + ocp_word_set_bits(tp, MCU_TYPE_USB, USB_FW_CTRL, + FLOW_CTRL_PATCH_2); + + ocp_word_set_bits(tp, MCU_TYPE_USB, USB_FW_TASK, FC_PATCH_TASK); + break; + case RTL_VER_16: + case RTL_VER_17_QFN68: + case RTL_VER_17_QFN100: + ocp_word_clr_bits(tp, MCU_TYPE_PLA, PLA_RCR, SLOT_EN); + + num_pause_pkts =3D 0xa; + ratio =3D 10000; + + if (!(speed & LINK_STATUS)) { + dev_dbg(&tp->intf->dev, "No link\n"); + goto no_link; + } else if (speed & _10bps) { + ratio /=3D 10; + } else if (speed & _100bps) { + ratio /=3D 100; + } else if (speed & _1000bps) { + ratio /=3D 1000; + } else if (speed & _2500bps) { + ratio /=3D 2500; + } else if (speed & _5000bps) { + ratio /=3D 5000; + } else if (speed & _10000bps) { + ratio /=3D 10000; + } else { + dev_err(&tp->intf->dev, "Unknown link speed\n"); + goto no_link; + } + + log2_ratio =3D ilog2(ratio); + num_pause_pkts -=3D log2_ratio; + + /* Round up if ratio is more than halfway to the next power of 2. + * Floating-point is avoided by rewriting + * ratio > 1.5 * 2^log2_ratio as + * 2 * ratio > 3 * 2^log2_ratio + */ + if (2 * ratio > 3 * (1 << log2_ratio)) + num_pause_pkts--; + +no_link: + ocp_word_w0w1(tp, MCU_TYPE_PLA, PLA_PAUSE_LIMIT, + PAUSE_LIMIT_MASK | PAUSE_LIMIT_EN, + num_pause_pkts << 4); + + ocp_word_set_bits(tp, MCU_TYPE_PLA, PLA_PAUSE_LIMIT, + PAUSE_LIMIT_EN); + break; + default: + break; + } +} + static int r8153_pre_firmware_1(struct r8152 *tp) { int i; @@ -6694,6 +6786,8 @@ static int rtl8157_enable(struct r8152 *tp) r8153_set_rx_early_size(tp); =20 speed =3D rtl8152_get_speed(tp); + rtl_fc_pause_pkt_en(tp, speed); + rtl_set_ifg(tp, speed); =20 return rtl_enable(tp); @@ -8842,6 +8936,8 @@ static void r8156_init(struct r8152 *tp) =20 usb_enable_lpm(tp->udev); =20 + rtl_fc_pause_pkt_en(tp, 0); + r8156_mac_clk_spd(tp, true); =20 ocp_word_clr_bits(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL3, @@ -8878,7 +8974,6 @@ static void r8156b_u2phy_backup(struct r8152 *tp) =20 static void r8156b_init(struct r8152 *tp) { - u32 ocp_data; u16 data; =20 if (test_bit(RTL8152_INACCESSIBLE, &tp->flags)) @@ -8943,20 +9038,7 @@ static void r8156b_init(struct r8152 *tp) =20 usb_enable_lpm(tp->udev); =20 - ocp_word_clr_bits(tp, MCU_TYPE_PLA, PLA_RCR, SLOT_EN); - - ocp_word_set_bits(tp, MCU_TYPE_PLA, PLA_CPCR, FLOW_CTRL_EN); - - /* 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 =3D ocp_read_word(tp, MCU_TYPE_PLA, PLA_POL_GPIO_CTRL); - if (!(ocp_data & DACK_DET_EN)) - ocp_word_set_bits(tp, MCU_TYPE_USB, USB_FW_CTRL, - FLOW_CTRL_PATCH_2); - - ocp_word_set_bits(tp, MCU_TYPE_USB, USB_FW_TASK, FC_PATCH_TASK); + rtl_fc_pause_pkt_en(tp, 0); =20 r8156_mac_clk_spd(tp, true); =20 --=20 2.34.1 From nobody Fri Sep 25 03:17:45 2026 Received: from rtits2.realtek.com.tw (rtits2.realtek.com [211.75.126.72]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 89A803A8FEE; Thu, 17 Sep 2026 07:07:20 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=211.75.126.72 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789628843; cv=none; b=Tu4hy9yzxm3DpGfieuBaT3ap794W0go+/rIXy8D6wGqSZhzeAe0tTBMDmhKogYT4hND9YFLvcl7DE2cjml4XyM/cnY259zbUiwNkGt5iwVrJ71efJmd1F+regkyd+z5EXEwkRPzzkjE+l+qylYbpciVWCYaJ4oKvk+020vtFyTE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789628843; c=relaxed/simple; bh=xpzrVwfK1EYltZWz79nB8WT6KFHKLxZ1EM2u1yjtlq0=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=XO3rMLBZ8BAN6M5so8uHleJpboOKNhi5c/0d44CxaaKlj1XZ//ZBnJHuHADyp+DCulkJxQK0NyVnMUZYkBBrG/zU4aTq9CuixF4qWsq6BrHKSGZeNoBzRpUxa5IykJkeFnkdUvOYpsE1DtfZ5bcguoS1nuluzmBn2pKWROiPKaQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=realtek.com; spf=pass smtp.mailfrom=realtek.com; dkim=pass (2048-bit key) header.d=realtek.com header.i=@realtek.com header.b=bj+fUpfk; arc=none smtp.client-ip=211.75.126.72 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=realtek.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=realtek.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=realtek.com header.i=@realtek.com header.b="bj+fUpfk" X-SpamFilter-By: ArmorX SpamTrap 5.80 with qID 68H76hc363094124, This message is accepted by code: ctloc85258 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=realtek.com; s=dkim; t=1789628803; bh=DZ+2MbGQA9uK6Sfqxt5UEkSrl1Z4DVL4OP6swk2hx+U=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Transfer-Encoding:Content-Type; b=bj+fUpfk6d6ZQczgi+s6J4Qh2mDWjRcmsnMNXH73IHgyur1cjB/tQ72fwZ1cugLP6 rdS2LlNt/x7DOdVlKdWmCmJiD3RmlmsT4fCMaBru6s6w/FQDDobEn/ynFSWz0HbQbM huKE6E2vFsWKEz7ygemLv0MSFZIrzV5mcmUo9iTzGxwWVu6DkHaKcd9qOyARa8Lgts zPzU0fyf9B/1kENpSW3BK9EjrxN5nejzdxGeBeGfPV7Vhz8r5h8Io6AhyeXGh7+4o9 NKVHaPSEDxkvndDxBQbS/8Ijdg0nppUkCYwWsRIVl/v3A4F2QN1eiJBBp/AlYhSx6h LN4iQVWMyxk0g== Received: from mail.realtek.com (rtkexhmbs02.realtek.com.tw[172.21.6.41]) by rtits2.realtek.com.tw (8.15.2/3.29/5.94) with ESMTPS id 68H76hc363094124 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL); Thu, 17 Sep 2026 15:06:43 +0800 Received: from RTKEXHMBS04.realtek.com.tw (10.21.1.54) by RTKEXHMBS02.realtek.com.tw (172.21.6.41) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.2562.49; Thu, 17 Sep 2026 15:06:41 +0800 Received: from fc44.realtek.com.tw (172.22.241.7) by RTKEXHMBS04.realtek.com.tw (10.21.1.54) with Microsoft SMTP Server id 15.2.2562.49 via Frontend Transport; Thu, 17 Sep 2026 15:06:41 +0800 From: Chih Kai Hsu To: , CC: , , , , , , , , Subject: [PATCH net-next v4 8/8] r8152: enable UPS for RTL8157 and RTL8159 QFN68 Date: Thu, 17 Sep 2026 15:06:37 +0800 Message-ID: <20260917070637.62827-9-nic_swsd@realtek.com> X-Mailer: git-send-email 2.54.0 In-Reply-To: <20260917070637.62827-1-nic_swsd@realtek.com> References: <20260917070637.62827-1-nic_swsd@realtek.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" RTL8157 and RTL8159 QFN68 support UPS, but rtl8157_runtime_enable() never toggled it on runtime suspend/resume, and r8156_ups_flags() used the older per-chip EEE/lite_mode encoding instead of the per-speed EEE flags their UPS firmware expects. RTL8159 QFN100 does not support UPS. Add r8157_ups_en(), mirroring r8156_ups_en(), and call it from rtl8157_runtime_enable() for VER_16/QFN68 only; QFN100 keeps its existing no-UPS behaviour there. Use r8157_ups_en(tp, false) in r8157_init()/r8159_init() in place of r8156_ups_en(tp, false). Extend r8156_ups_flags() with per-speed EEE flags (UPS_FLAGS_EN_100M_EEE/1000M_EEE/2500M_EEE/5000M_EEE/10G_EEE) and skip the lite_mode bits[6:5] encoding for VER_16/QFN68. Add ups_flags_speed() entries 10 and 11 for NWAY_5000M_FULL and NWAY_10000M_FULL, previously unmapped. Add the USB_FW_USE_VER register (0xcfd7), used by the new r8157_ups_en() disable path. Signed-off-by: Chih Kai Hsu --- drivers/net/usb/r8152.c | 110 +++++++++++++++++++++++++++++++++++----- 1 file changed, 98 insertions(+), 12 deletions(-) diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c index 05b2b79ab3e31..ebe9cc9322b3c 100644 --- a/drivers/net/usb/r8152.c +++ b/drivers/net/usb/r8152.c @@ -132,6 +132,7 @@ #define USB_BURST_SIZE 0xcfc0 #define USB_FW_FIX_EN0 0xcfca #define USB_FW_FIX_EN1 0xcfcc +#define USB_FW_USE_VER 0xcfd7 #define USB_LPM_CONFIG 0xcfd8 #define USB_ECM_OPTION 0xcfee #define USB_CSTMR 0xcfef /* RTL8153A */ @@ -619,6 +620,11 @@ #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_EN_100M_EEE BIT(9) +#define UPS_FLAGS_EN_1000M_EEE BIT(10) +#define UPS_FLAGS_EN_2500M_EEE BIT(11) +#define UPS_FLAGS_EN_5000M_EEE BIT(12) +#define UPS_FLAGS_EN_10G_EEE BIT(13) #define UPS_FLAGS_SPEED_MASK (0xf << 16) #define ups_flags_speed(x) ((x) << 16) #define UPS_FLAGS_EN_EEE BIT(20) @@ -4244,8 +4250,27 @@ static void r8156_ups_flags(struct r8152 *tp) if (tp->ups_info.aldps) ups_flags |=3D UPS_FLAGS_EN_ALDPS; =20 - if (tp->ups_info.eee) - ups_flags |=3D UPS_FLAGS_EN_EEE; + if (tp->ups_info.eee) { + switch (tp->version) { + case RTL_VER_17_QFN68: + if (tp->eee_adv & MDIO_EEE_10GT) + ups_flags |=3D UPS_FLAGS_EN_10G_EEE; + fallthrough; + case RTL_VER_16: + if (tp->eee_adv & MDIO_EEE_100TX) + ups_flags |=3D UPS_FLAGS_EN_100M_EEE; + if (tp->eee_adv & MDIO_EEE_1000T) + ups_flags |=3D UPS_FLAGS_EN_1000M_EEE; + if (tp->eee_adv2 & MDIO_EEE_2_5GT) + ups_flags |=3D UPS_FLAGS_EN_2500M_EEE; + if (tp->eee_adv2 & MDIO_EEE_5GT) + ups_flags |=3D UPS_FLAGS_EN_5000M_EEE; + break; + default: + ups_flags |=3D UPS_FLAGS_EN_EEE; + break; + } + } =20 if (tp->ups_info.flow_control) ups_flags |=3D UPS_FLAGS_EN_FLOW_CTR; @@ -4296,20 +4321,33 @@ static void r8156_ups_flags(struct r8152 *tp) case NWAY_2500M_FULL: ups_flags |=3D ups_flags_speed(9); break; + case NWAY_5000M_FULL: + ups_flags |=3D ups_flags_speed(10); + break; + case NWAY_10000M_FULL: + ups_flags |=3D ups_flags_speed(11); + break; default: break; } =20 - switch (tp->ups_info.lite_mode) { - case 1: - ups_flags |=3D 0 << 5; - break; - case 2: - ups_flags |=3D 2 << 5; + switch (tp->version) { + case RTL_VER_16: + case RTL_VER_17_QFN68: break; - case 0: default: - ups_flags |=3D 1 << 5; + switch (tp->ups_info.lite_mode) { + case 1: + ups_flags |=3D 0 << 5; + break; + case 2: + ups_flags |=3D 2 << 5; + break; + case 0: + default: + ups_flags |=3D 1 << 5; + break; + } break; } =20 @@ -4484,6 +4522,35 @@ static void r8156_ups_en(struct r8152 *tp, bool enab= le) } } =20 +static void r8157_ups_en(struct r8152 *tp, bool enable) +{ + if (enable) { + r8156_ups_flags(tp); + + ocp_byte_set_bits(tp, MCU_TYPE_USB, USB_POWER_CUT, + UPS_EN | USP_PREWAKE | PHASE2_EN); + + ocp_byte_set_bits(tp, MCU_TYPE_USB, USB_MISC_2, + UPS_FORCE_PWR_DOWN); + } else { + ocp_byte_clr_bits(tp, MCU_TYPE_USB, USB_POWER_CUT, + UPS_EN | USP_PREWAKE); + + ocp_byte_clr_bits(tp, MCU_TYPE_USB, USB_MISC_2, + UPS_FORCE_PWR_DOWN); + + if (ocp_read_word(tp, MCU_TYPE_USB, USB_MISC_0) & PCUT_STATUS) { + /* clear USB fw_ver_reg */ + ocp_write_byte(tp, MCU_TYPE_USB, USB_FW_USE_VER, 0); + + 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) { if (enable) @@ -4642,9 +4709,28 @@ static void rtl8157_runtime_enable(struct r8152 *tp,= bool enable) r8153b_u1u2en(tp, false); r8157_u2p3en(tp, false); rtl_runtime_suspend_enable(tp, true); + + switch (tp->version) { + case RTL_VER_16: + case RTL_VER_17_QFN68: + r8157_ups_en(tp, true); + break; + default: + break; + } } else { r8153_queue_wake(tp, false); rtl_runtime_suspend_enable(tp, false); + + switch (tp->version) { + case RTL_VER_16: + case RTL_VER_17_QFN68: + r8157_ups_en(tp, false); + break; + default: + break; + } + r8157_u2p3en(tp, true); if (tp->udev->speed >=3D USB_SPEED_SUPER) r8153b_u1u2en(tp, true); @@ -9111,7 +9197,7 @@ static void r8157_init(struct r8152 *tp) ocp_write_word(tp, MCU_TYPE_USB, USB_U1U2_TIMER, 500); =20 r8157_power_cut_en(tp, false); - r8156_ups_en(tp, false); + r8157_ups_en(tp, false); r8153_queue_wake(tp, false); rtl_runtime_suspend_enable(tp, false); =20 @@ -9221,7 +9307,7 @@ static void r8159_init(struct r8152 *tp) ocp_write_word(tp, MCU_TYPE_USB, USB_U1U2_TIMER, 500); =20 r8157_power_cut_en(tp, false); - r8156_ups_en(tp, false); + r8157_ups_en(tp, false); r8153_queue_wake(tp, false); rtl_runtime_suspend_enable(tp, false); =20 --=20 2.34.1