From a7fd866a2caf4b5549d099e1f42a3da35c51772f Mon Sep 17 00:00:00 2001 From: Aleksander Jan Bajkowski Date: Fri, 24 Apr 2026 22:35:44 +0200 Subject: [PATCH] kernel: backport RTL8157 support to 6.18 Backport support for the RTL8157. The RTL8157 is a low-cost chipset designed for USB to 5Gb Ethernet adapters. Tested on Sabrent NT-C5GA (RTL8157), Wavlink WL-NWU340G (RTL8157) and UGREEN CM648 (RTL8156BG) adapters. Signed-off-by: Aleksander Jan Bajkowski Link: https://github.com/openwrt/openwrt/pull/23088 Signed-off-by: Hauke Mehrtens --- ...rtise-software-timestamp-information.patch | 27 + ...seT-EEE-status-configuration-support.patch | 148 ++ ...rect-register-write-to-USB_UPHY_XTAL.patch | 31 + ...-functions-for-PLA-USB-OCP-registers.patch | 2182 +++++++++++++++++ ...lper-functions-for-PHY-OCP-registers.patch | 1127 +++++++++ ...r8152-Add-helper-functions-for-SRAM2.patch | 252 ++ ...upport-for-5Gbit-Link-Speeds-and-EEE.patch | 235 ++ ...Add-support-for-the-RTL8157-hardware.patch | 1553 ++++++++++++ ...-r8152-add-LED-configuration-from-OF.patch | 16 +- 9 files changed, 5563 insertions(+), 8 deletions(-) create mode 100644 target/linux/generic/backport-6.18/740-v6.19-r8152-Advertise-software-timestamp-information.patch create mode 100644 target/linux/generic/backport-6.18/741-v7.1-r8152-Add-2500baseT-EEE-status-configuration-support.patch create mode 100644 target/linux/generic/backport-6.18/742-v7.1-r8152-fix-incorrect-register-write-to-USB_UPHY_XTAL.patch create mode 100644 target/linux/generic/backport-6.18/743-v7.1-r8152-add-helper-functions-for-PLA-USB-OCP-registers.patch create mode 100644 target/linux/generic/backport-6.18/744-v7.1-r8152-add-helper-functions-for-PHY-OCP-registers.patch create mode 100644 target/linux/generic/backport-6.18/745-v7.1-r8152-Add-helper-functions-for-SRAM2.patch create mode 100644 target/linux/generic/backport-6.18/746-v7.1-r8152-Add-support-for-5Gbit-Link-Speeds-and-EEE.patch create mode 100644 target/linux/generic/backport-6.18/747-v7.1-r8152-Add-support-for-the-RTL8157-hardware.patch diff --git a/target/linux/generic/backport-6.18/740-v6.19-r8152-Advertise-software-timestamp-information.patch b/target/linux/generic/backport-6.18/740-v6.19-r8152-Advertise-software-timestamp-information.patch new file mode 100644 index 00000000000..5fe99fe7697 --- /dev/null +++ b/target/linux/generic/backport-6.18/740-v6.19-r8152-Advertise-software-timestamp-information.patch @@ -0,0 +1,27 @@ +From a8e846b8d93de748485653dd8a6a8efd8f5d7613 Mon Sep 17 00:00:00 2001 +From: Abhishek Rawal +Date: Tue, 14 Oct 2025 11:22:33 +0530 +Subject: [PATCH] r8152: Advertise software timestamp information. + +Driver calls skb_tx_timestamp(skb) in rtl8152_start_xmit(), but does not advertise the capability in ethtool. +Advertise software timestamp capabilities on struct ethtool_ops. + +Signed-off-by: Abhishek Rawal +Reviewed-by: Jamie Bainbridge +Reviewed-by: Vadim Fedorenko +Link: https://patch.msgid.link/20251014055234.46527-1-rawal.abhishek92@gmail.com +Signed-off-by: Jakub Kicinski +--- + drivers/net/usb/r8152.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/net/usb/r8152.c ++++ b/drivers/net/usb/r8152.c +@@ -9314,6 +9314,7 @@ static const struct ethtool_ops ops = { + .set_ringparam = rtl8152_set_ringparam, + .get_pauseparam = rtl8152_get_pauseparam, + .set_pauseparam = rtl8152_set_pauseparam, ++ .get_ts_info = ethtool_op_get_ts_info, + }; + + static int rtl8152_ioctl(struct net_device *netdev, struct ifreq *rq, int cmd) diff --git a/target/linux/generic/backport-6.18/741-v7.1-r8152-Add-2500baseT-EEE-status-configuration-support.patch b/target/linux/generic/backport-6.18/741-v7.1-r8152-Add-2500baseT-EEE-status-configuration-support.patch new file mode 100644 index 00000000000..39c573a8737 --- /dev/null +++ b/target/linux/generic/backport-6.18/741-v7.1-r8152-Add-2500baseT-EEE-status-configuration-support.patch @@ -0,0 +1,148 @@ +From e8e83b67960c20a9e60d4181631509d59f03488b Mon Sep 17 00:00:00 2001 +From: Birger Koblitz +Date: Tue, 24 Feb 2026 18:40:14 +0100 +Subject: [PATCH] r8152: Add 2500baseT EEE status/configuration support + +The r8152 driver supports the RTL8156, which is a 2.5Gbit Ethernet controller for +USB 3.0, for which support is added for configuring and displaying the EEE +advertisement status for 2.5GBit connections. + +The patch also corrects the determination of whether EEE is active to include +the 2.5GBit connection status and make the determination dependent not on the +desired speed configuration (tp->speed), but on the actual speed used by +the controller. For consistency, this is corrected also for the RTL8152/3. + +This was tested on an Edimax EU-4307 V1.0 USB-Ethernet adapter with RTL8156, +and a SECOMP Value 12.99.1115 USB-C 3.1 Ethernet converter with RTL8153. + +Signed-off-by: Birger Koblitz +Link: https://patch.msgid.link/20260224-b4-eee2g5-v2-1-cf5c83df036e@birger-koblitz.de +Signed-off-by: Jakub Kicinski +--- + drivers/net/usb/r8152.c | 50 ++++++++++++++++++++++++++++++++++------- + 1 file changed, 42 insertions(+), 8 deletions(-) + +--- a/drivers/net/usb/r8152.c ++++ b/drivers/net/usb/r8152.c +@@ -213,6 +213,7 @@ + #define OCP_EEE_LPABLE 0xa5d2 + #define OCP_10GBT_CTRL 0xa5d4 + #define OCP_10GBT_STAT 0xa5d6 ++#define OCP_EEE_LPABLE2 0xa6d0 + #define OCP_EEE_ADV2 0xa6d4 + #define OCP_PHY_STATE 0xa708 /* nway state for 8153 */ + #define OCP_PHY_PATCH_STAT 0xb800 +@@ -954,6 +955,7 @@ struct r8152 { + u16 ocp_base; + u16 speed; + u16 eee_adv; ++ u16 eee_adv2; + u8 *intr_buff; + u8 version; + u8 duplex; +@@ -5399,7 +5401,7 @@ static void r8156_eee_en(struct r8152 *t + + config = ocp_reg_read(tp, OCP_EEE_ADV2); + +- if (enable) ++ if (enable && (tp->eee_adv2 & MDIO_EEE_2_5GT)) + config |= MDIO_EEE_2_5GT; + else + config &= ~MDIO_EEE_2_5GT; +@@ -8929,7 +8931,8 @@ static void rtl8152_get_strings(struct n + + static int r8152_get_eee(struct r8152 *tp, struct ethtool_keee *eee) + { +- __ETHTOOL_DECLARE_LINK_MODE_MASK(common); ++ __ETHTOOL_DECLARE_LINK_MODE_MASK(common) = {}; ++ u16 speed = rtl8152_get_speed(tp); + u16 val; + + val = r8152_mmd_read(tp, MDIO_MMD_PCS, MDIO_PCS_EEE_ABLE); +@@ -8943,8 +8946,14 @@ static int r8152_get_eee(struct r8152 *t + + eee->eee_enabled = tp->eee_en; + +- linkmode_and(common, eee->advertised, eee->lp_advertised); +- eee->eee_active = phy_check_valid(tp->speed, tp->duplex, common); ++ if (speed & _1000bps) ++ linkmode_set_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT, common); ++ if (speed & _100bps) ++ linkmode_set_bit(ETHTOOL_LINK_MODE_100baseT_Full_BIT, common); ++ ++ linkmode_and(common, common, eee->advertised); ++ linkmode_and(common, common, eee->lp_advertised); ++ eee->eee_active = !linkmode_empty(common); + + return 0; + } +@@ -8955,7 +8964,10 @@ static int r8152_set_eee(struct r8152 *t + + tp->eee_en = eee->eee_enabled; + tp->eee_adv = val; +- ++ if (tp->support_2500full) { ++ val = linkmode_to_mii_eee_cap2_t(eee->advertised); ++ tp->eee_adv2 = val; ++ } + rtl_eee_enable(tp, tp->eee_en); + + return 0; +@@ -8963,7 +8975,8 @@ static int r8152_set_eee(struct r8152 *t + + static int r8153_get_eee(struct r8152 *tp, struct ethtool_keee *eee) + { +- __ETHTOOL_DECLARE_LINK_MODE_MASK(common); ++ __ETHTOOL_DECLARE_LINK_MODE_MASK(common) = {}; ++ u16 speed = rtl8152_get_speed(tp); + u16 val; + + val = ocp_reg_read(tp, OCP_EEE_ABLE); +@@ -8975,10 +8988,29 @@ static int r8153_get_eee(struct r8152 *t + val = ocp_reg_read(tp, OCP_EEE_LPABLE); + mii_eee_cap1_mod_linkmode_t(eee->lp_advertised, val); + ++ if (tp->support_2500full) { ++ linkmode_set_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT, eee->supported); ++ ++ val = ocp_reg_read(tp, OCP_EEE_ADV2); ++ mii_eee_cap2_mod_linkmode_adv_t(eee->advertised, val); ++ ++ val = ocp_reg_read(tp, OCP_EEE_LPABLE2); ++ mii_eee_cap2_mod_linkmode_adv_t(eee->lp_advertised, val); ++ ++ if (speed & _2500bps) ++ linkmode_set_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT, common); ++ } ++ + eee->eee_enabled = tp->eee_en; + +- linkmode_and(common, eee->advertised, eee->lp_advertised); +- eee->eee_active = phy_check_valid(tp->speed, tp->duplex, common); ++ if (speed & _1000bps) ++ linkmode_set_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT, common); ++ if (speed & _100bps) ++ linkmode_set_bit(ETHTOOL_LINK_MODE_100baseT_Full_BIT, common); ++ ++ linkmode_and(common, common, eee->advertised); ++ linkmode_and(common, common, eee->lp_advertised); ++ eee->eee_active = !linkmode_empty(common); + + return 0; + } +@@ -9519,6 +9551,7 @@ static int rtl_ops_init(struct r8152 *tp + case RTL_VER_11: + tp->eee_en = true; + tp->eee_adv = MDIO_EEE_1000T | MDIO_EEE_100TX; ++ tp->eee_adv2 = MDIO_EEE_2_5GT; + fallthrough; + case RTL_VER_10: + ops->init = r8156_init; +@@ -9544,6 +9577,7 @@ static int rtl_ops_init(struct r8152 *tp + case RTL_VER_15: + tp->eee_en = true; + tp->eee_adv = MDIO_EEE_1000T | MDIO_EEE_100TX; ++ tp->eee_adv2 = MDIO_EEE_2_5GT; + ops->init = r8156b_init; + ops->enable = rtl8156b_enable; + ops->disable = rtl8153_disable; diff --git a/target/linux/generic/backport-6.18/742-v7.1-r8152-fix-incorrect-register-write-to-USB_UPHY_XTAL.patch b/target/linux/generic/backport-6.18/742-v7.1-r8152-fix-incorrect-register-write-to-USB_UPHY_XTAL.patch new file mode 100644 index 00000000000..1dee906123b --- /dev/null +++ b/target/linux/generic/backport-6.18/742-v7.1-r8152-fix-incorrect-register-write-to-USB_UPHY_XTAL.patch @@ -0,0 +1,31 @@ +From 48afd5124fd6129c46fd12cb06155384b1c4a0c4 Mon Sep 17 00:00:00 2001 +From: Chih Kai Hsu +Date: Thu, 26 Mar 2026 15:39:23 +0800 +Subject: [PATCH] r8152: fix incorrect register write to USB_UPHY_XTAL + +The old code used ocp_write_byte() to clear the OOBS_POLLING bit +(BIT(8)) in the USB_UPHY_XTAL register, but this doesn't correctly +clear a bit in the upper byte of the 16-bit register. + +Fix this by using ocp_write_word() instead. + +Fixes: 195aae321c82 ("r8152: support new chips") +Signed-off-by: Chih Kai Hsu +Reviewed-by: Hayes Wang +Link: https://patch.msgid.link/20260326073925.32976-454-nic_swsd@realtek.com +Signed-off-by: Paolo Abeni +--- + drivers/net/usb/r8152.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/net/usb/r8152.c ++++ b/drivers/net/usb/r8152.c +@@ -3898,7 +3898,7 @@ static void r8156_ups_en(struct r8152 *t + case RTL_VER_15: + ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_UPHY_XTAL); + ocp_data &= ~OOBS_POLLING; +- ocp_write_byte(tp, MCU_TYPE_USB, USB_UPHY_XTAL, ocp_data); ++ ocp_write_word(tp, MCU_TYPE_USB, USB_UPHY_XTAL, ocp_data); + break; + default: + break; diff --git a/target/linux/generic/backport-6.18/743-v7.1-r8152-add-helper-functions-for-PLA-USB-OCP-registers.patch b/target/linux/generic/backport-6.18/743-v7.1-r8152-add-helper-functions-for-PLA-USB-OCP-registers.patch new file mode 100644 index 00000000000..1d6d9f6bc91 --- /dev/null +++ b/target/linux/generic/backport-6.18/743-v7.1-r8152-add-helper-functions-for-PLA-USB-OCP-registers.patch @@ -0,0 +1,2182 @@ +From d16133f177fea620d6b413990683b6a8b2641be5 Mon Sep 17 00:00:00 2001 +From: Chih Kai Hsu +Date: Thu, 26 Mar 2026 15:39:24 +0800 +Subject: [PATCH] r8152: add helper functions for PLA/USB OCP registers + +Add the following bitwise operation functions for PLA/USB OCP registers +to simplify the code. + +- ocp_dword_w0w1() +- ocp_word_w0w1() +- ocp_byte_w0w1() +- ocp_dword_clr_bits() +- ocp_dword_set_bits() +- ocp_word_clr_bits() +- ocp_word_set_bits() +- ocp_word_test_and_clr_bits() +- ocp_byte_clr_bits() +- ocp_byte_set_bits() + +Signed-off-by: Chih Kai Hsu +Reviewed-by: Hayes Wang +Link: https://patch.msgid.link/20260326073925.32976-455-nic_swsd@realtek.com +Signed-off-by: Paolo Abeni +--- + drivers/net/usb/r8152.c | 1103 +++++++++++++++------------------------ + 1 file changed, 408 insertions(+), 695 deletions(-) + +--- a/drivers/net/usb/r8152.c ++++ b/drivers/net/usb/r8152.c +@@ -1660,6 +1660,78 @@ void write_mii_word(struct net_device *n + r8152_mdio_write(tp, reg, val); + } + ++static void ++ocp_dword_w0w1(struct r8152 *tp, u16 type, u16 index, u32 clear, u32 set) ++{ ++ u32 ocp_data; ++ ++ ocp_data = ocp_read_dword(tp, type, index); ++ ocp_data = (ocp_data & ~clear) | set; ++ ocp_write_dword(tp, type, index, ocp_data); ++} ++ ++static void ++ocp_word_w0w1(struct r8152 *tp, u16 type, u16 index, u16 clear, u16 set) ++{ ++ u16 ocp_data; ++ ++ ocp_data = ocp_read_word(tp, type, index); ++ ocp_data = (ocp_data & ~clear) | set; ++ ocp_write_word(tp, type, index, ocp_data); ++} ++ ++static void ++ocp_byte_w0w1(struct r8152 *tp, u16 type, u16 index, u8 clear, u8 set) ++{ ++ u8 ocp_data; ++ ++ ocp_data = ocp_read_byte(tp, type, index); ++ ocp_data = (ocp_data & ~clear) | set; ++ ocp_write_byte(tp, type, index, ocp_data); ++} ++ ++static void ocp_dword_clr_bits(struct r8152 *tp, u16 type, u16 index, u32 clear) ++{ ++ ocp_dword_w0w1(tp, type, index, clear, 0); ++} ++ ++static void ocp_dword_set_bits(struct r8152 *tp, u16 type, u16 index, u32 set) ++{ ++ ocp_dword_w0w1(tp, type, index, 0, set); ++} ++ ++static void ocp_word_clr_bits(struct r8152 *tp, u16 type, u16 index, u16 clear) ++{ ++ ocp_word_w0w1(tp, type, index, clear, 0); ++} ++ ++static void ocp_word_set_bits(struct r8152 *tp, u16 type, u16 index, u16 set) ++{ ++ ocp_word_w0w1(tp, type, index, 0, set); ++} ++ ++static int ++ocp_word_test_and_clr_bits(struct r8152 *tp, u16 type, u16 index, u16 clear) ++{ ++ u16 ocp_data; ++ ++ ocp_data = ocp_read_word(tp, type, index); ++ if (ocp_data & clear) ++ ocp_write_word(tp, type, index, ocp_data & ~clear); ++ ++ return ocp_data & clear; ++} ++ ++static void ocp_byte_clr_bits(struct r8152 *tp, u16 type, u16 index, u8 clear) ++{ ++ ocp_byte_w0w1(tp, type, index, clear, 0); ++} ++ ++static void ocp_byte_set_bits(struct r8152 *tp, u16 type, u16 index, u8 set) ++{ ++ ocp_byte_w0w1(tp, type, index, 0, set); ++} ++ + static int + r8152_submit_rx(struct r8152 *tp, struct rx_agg *agg, gfp_t mem_flags); + +@@ -2962,47 +3034,31 @@ static netdev_tx_t rtl8152_start_xmit(st + + static void r8152b_reset_packet_filter(struct r8152 *tp) + { +- u32 ocp_data; +- +- ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_FMC); +- ocp_data &= ~FMC_FCR_MCU_EN; +- ocp_write_word(tp, MCU_TYPE_PLA, PLA_FMC, ocp_data); +- ocp_data |= FMC_FCR_MCU_EN; +- ocp_write_word(tp, MCU_TYPE_PLA, PLA_FMC, ocp_data); ++ ocp_word_clr_bits(tp, MCU_TYPE_PLA, PLA_FMC, FMC_FCR_MCU_EN); ++ ocp_word_set_bits(tp, MCU_TYPE_PLA, PLA_FMC, FMC_FCR_MCU_EN); + } + + static void rtl8152_nic_reset(struct r8152 *tp) + { +- u32 ocp_data; + int i; + + switch (tp->version) { + case RTL_TEST_01: + case RTL_VER_10: + case RTL_VER_11: +- ocp_data = ocp_read_byte(tp, MCU_TYPE_PLA, PLA_CR); +- ocp_data &= ~CR_TE; +- ocp_write_byte(tp, MCU_TYPE_PLA, PLA_CR, ocp_data); +- +- ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_BMU_RESET); +- ocp_data &= ~BMU_RESET_EP_IN; +- ocp_write_word(tp, MCU_TYPE_USB, USB_BMU_RESET, ocp_data); +- +- ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_USB_CTRL); +- ocp_data |= CDC_ECM_EN; +- ocp_write_word(tp, MCU_TYPE_USB, USB_USB_CTRL, ocp_data); +- +- ocp_data = ocp_read_byte(tp, MCU_TYPE_PLA, PLA_CR); +- ocp_data &= ~CR_RE; +- ocp_write_byte(tp, MCU_TYPE_PLA, PLA_CR, ocp_data); +- +- ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_BMU_RESET); +- ocp_data |= BMU_RESET_EP_IN; +- ocp_write_word(tp, MCU_TYPE_USB, USB_BMU_RESET, ocp_data); +- +- ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_USB_CTRL); +- ocp_data &= ~CDC_ECM_EN; +- ocp_write_word(tp, MCU_TYPE_USB, USB_USB_CTRL, ocp_data); ++ ocp_byte_clr_bits(tp, MCU_TYPE_PLA, PLA_CR, CR_TE); ++ ++ ocp_word_clr_bits(tp, MCU_TYPE_USB, USB_BMU_RESET, ++ BMU_RESET_EP_IN); ++ ++ ocp_word_set_bits(tp, MCU_TYPE_USB, USB_USB_CTRL, CDC_ECM_EN); ++ ++ ocp_byte_clr_bits(tp, MCU_TYPE_PLA, PLA_CR, CR_RE); ++ ++ ocp_word_set_bits(tp, MCU_TYPE_USB, USB_BMU_RESET, ++ BMU_RESET_EP_IN); ++ ++ ocp_word_clr_bits(tp, MCU_TYPE_USB, USB_USB_CTRL, CDC_ECM_EN); + break; + + default: +@@ -3031,14 +3087,12 @@ static inline u16 rtl8152_get_speed(stru + + static void rtl_eee_plus_en(struct r8152 *tp, bool enable) + { +- u32 ocp_data; +- +- ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_EEEP_CR); + if (enable) +- ocp_data |= EEEP_CR_EEEP_TX; ++ ocp_word_set_bits(tp, MCU_TYPE_PLA, PLA_EEEP_CR, ++ EEEP_CR_EEEP_TX); + else +- ocp_data &= ~EEEP_CR_EEEP_TX; +- ocp_write_word(tp, MCU_TYPE_PLA, PLA_EEEP_CR, ocp_data); ++ ocp_word_clr_bits(tp, MCU_TYPE_PLA, PLA_EEEP_CR, ++ EEEP_CR_EEEP_TX); + } + + static void rtl_set_eee_plus(struct r8152 *tp) +@@ -3051,14 +3105,10 @@ static void rtl_set_eee_plus(struct r815 + + static void rxdy_gated_en(struct r8152 *tp, bool enable) + { +- u32 ocp_data; +- +- ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_MISC_1); + if (enable) +- ocp_data |= RXDY_GATED_EN; ++ ocp_word_set_bits(tp, MCU_TYPE_PLA, PLA_MISC_1, RXDY_GATED_EN); + else +- ocp_data &= ~RXDY_GATED_EN; +- ocp_write_word(tp, MCU_TYPE_PLA, PLA_MISC_1, ocp_data); ++ ocp_word_clr_bits(tp, MCU_TYPE_PLA, PLA_MISC_1, RXDY_GATED_EN); + } + + static int rtl_start_rx(struct r8152 *tp) +@@ -3146,24 +3196,16 @@ static int rtl_stop_rx(struct r8152 *tp) + + static void rtl_set_ifg(struct r8152 *tp, u16 speed) + { +- u32 ocp_data; +- +- ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_TCR1); +- ocp_data &= ~IFG_MASK; + if ((speed & (_10bps | _100bps)) && !(speed & FULL_DUP)) { +- ocp_data |= IFG_144NS; +- ocp_write_word(tp, MCU_TYPE_PLA, PLA_TCR1, ocp_data); ++ ocp_word_w0w1(tp, MCU_TYPE_PLA, PLA_TCR1, IFG_MASK, IFG_144NS); + +- ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL4); +- ocp_data &= ~TX10MIDLE_EN; +- ocp_write_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL4, ocp_data); ++ ocp_word_clr_bits(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL4, ++ TX10MIDLE_EN); + } else { +- ocp_data |= IFG_96NS; +- ocp_write_word(tp, MCU_TYPE_PLA, PLA_TCR1, ocp_data); ++ ocp_word_w0w1(tp, MCU_TYPE_PLA, PLA_TCR1, IFG_MASK, IFG_96NS); + +- ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL4); +- ocp_data |= TX10MIDLE_EN; +- ocp_write_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL4, ocp_data); ++ ocp_word_set_bits(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL4, ++ TX10MIDLE_EN); + } + } + +@@ -3175,13 +3217,9 @@ static inline void r8153b_rx_agg_chg_ind + + static int rtl_enable(struct r8152 *tp) + { +- u32 ocp_data; +- + r8152b_reset_packet_filter(tp); + +- ocp_data = ocp_read_byte(tp, MCU_TYPE_PLA, PLA_CR); +- ocp_data |= CR_RE | CR_TE; +- ocp_write_byte(tp, MCU_TYPE_PLA, PLA_CR, ocp_data); ++ ocp_byte_set_bits(tp, MCU_TYPE_PLA, PLA_CR, CR_RE | CR_TE); + + switch (tp->version) { + case RTL_VER_01: +@@ -3289,8 +3327,6 @@ static void r8153_set_rx_early_size(stru + + static int rtl8153_enable(struct r8152 *tp) + { +- u32 ocp_data; +- + if (test_bit(RTL8152_INACCESSIBLE, &tp->flags)) + return -ENODEV; + +@@ -3304,12 +3340,9 @@ static int rtl8153_enable(struct r8152 * + switch (tp->version) { + case RTL_VER_09: + case RTL_VER_14: +- ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_FW_TASK); +- ocp_data &= ~FC_PATCH_TASK; +- ocp_write_word(tp, MCU_TYPE_USB, USB_FW_TASK, ocp_data); ++ ocp_word_clr_bits(tp, MCU_TYPE_USB, USB_FW_TASK, FC_PATCH_TASK); + usleep_range(1000, 2000); +- ocp_data |= FC_PATCH_TASK; +- ocp_write_word(tp, MCU_TYPE_USB, USB_FW_TASK, ocp_data); ++ ocp_word_set_bits(tp, MCU_TYPE_USB, USB_FW_TASK, FC_PATCH_TASK); + break; + default: + break; +@@ -3328,9 +3361,7 @@ static void rtl_disable(struct r8152 *tp + return; + } + +- ocp_data = ocp_read_dword(tp, MCU_TYPE_PLA, PLA_RCR); +- ocp_data &= ~RCR_ACPT_ALL; +- ocp_write_dword(tp, MCU_TYPE_PLA, PLA_RCR, ocp_data); ++ ocp_dword_clr_bits(tp, MCU_TYPE_PLA, PLA_RCR, RCR_ACPT_ALL); + + rtl_drop_queued_tx(tp); + +@@ -3363,24 +3394,17 @@ static void rtl_disable(struct r8152 *tp + + static void r8152_power_cut_en(struct r8152 *tp, bool enable) + { +- u32 ocp_data; +- +- ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_UPS_CTRL); + if (enable) +- ocp_data |= POWER_CUT; ++ ocp_word_set_bits(tp, MCU_TYPE_USB, USB_UPS_CTRL, POWER_CUT); + else +- ocp_data &= ~POWER_CUT; +- ocp_write_word(tp, MCU_TYPE_USB, USB_UPS_CTRL, ocp_data); ++ ocp_word_clr_bits(tp, MCU_TYPE_USB, USB_UPS_CTRL, POWER_CUT); + +- ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_PM_CTRL_STATUS); +- ocp_data &= ~RESUME_INDICATE; +- ocp_write_word(tp, MCU_TYPE_USB, USB_PM_CTRL_STATUS, ocp_data); ++ ocp_word_clr_bits(tp, MCU_TYPE_USB, USB_PM_CTRL_STATUS, ++ RESUME_INDICATE); + } + + static void rtl_rx_vlan_en(struct r8152 *tp, bool enable) + { +- u32 ocp_data; +- + switch (tp->version) { + case RTL_VER_01: + case RTL_VER_02: +@@ -3392,12 +3416,12 @@ static void rtl_rx_vlan_en(struct r8152 + case RTL_VER_08: + case RTL_VER_09: + case RTL_VER_14: +- ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_CPCR); + if (enable) +- ocp_data |= CPCR_RX_VLAN; ++ ocp_word_set_bits(tp, MCU_TYPE_PLA, PLA_CPCR, ++ CPCR_RX_VLAN); + else +- ocp_data &= ~CPCR_RX_VLAN; +- ocp_write_word(tp, MCU_TYPE_PLA, PLA_CPCR, ocp_data); ++ ocp_word_clr_bits(tp, MCU_TYPE_PLA, PLA_CPCR, ++ CPCR_RX_VLAN); + break; + + case RTL_TEST_01: +@@ -3407,12 +3431,12 @@ static void rtl_rx_vlan_en(struct r8152 + case RTL_VER_13: + case RTL_VER_15: + default: +- ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_RCR1); + if (enable) +- ocp_data |= OUTER_VLAN | INNER_VLAN; ++ ocp_word_set_bits(tp, MCU_TYPE_PLA, PLA_RCR1, ++ OUTER_VLAN | INNER_VLAN); + else +- ocp_data &= ~(OUTER_VLAN | INNER_VLAN); +- ocp_write_word(tp, MCU_TYPE_PLA, PLA_RCR1, ocp_data); ++ ocp_word_clr_bits(tp, MCU_TYPE_PLA, PLA_RCR1, ++ OUTER_VLAN | INNER_VLAN); + break; + } + } +@@ -3473,33 +3497,33 @@ static u32 __rtl_get_wol(struct r8152 *t + + static void __rtl_set_wol(struct r8152 *tp, u32 wolopts) + { +- u32 ocp_data; ++ u16 ocp_data; + + ocp_write_byte(tp, MCU_TYPE_PLA, PLA_CRWECR, CRWECR_CONFIG); + +- ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_CONFIG34); +- ocp_data &= ~LINK_ON_WAKE_EN; + if (wolopts & WAKE_PHY) +- ocp_data |= LINK_ON_WAKE_EN; +- ocp_write_word(tp, MCU_TYPE_PLA, PLA_CONFIG34, ocp_data); ++ ocp_word_set_bits(tp, MCU_TYPE_PLA, PLA_CONFIG34, ++ LINK_ON_WAKE_EN); ++ else ++ ocp_word_clr_bits(tp, MCU_TYPE_PLA, PLA_CONFIG34, ++ LINK_ON_WAKE_EN); + +- ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_CONFIG5); +- ocp_data &= ~(UWF_EN | BWF_EN | MWF_EN); ++ ocp_data = 0; + if (wolopts & WAKE_UCAST) + ocp_data |= UWF_EN; + if (wolopts & WAKE_BCAST) + ocp_data |= BWF_EN; + if (wolopts & WAKE_MCAST) + ocp_data |= MWF_EN; +- ocp_write_word(tp, MCU_TYPE_PLA, PLA_CONFIG5, ocp_data); ++ ocp_word_w0w1(tp, MCU_TYPE_PLA, PLA_CONFIG5, UWF_EN | BWF_EN | MWF_EN, ++ ocp_data); + + ocp_write_byte(tp, MCU_TYPE_PLA, PLA_CRWECR, CRWECR_NORAML); + +- ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_CFG_WOL); +- ocp_data &= ~MAGIC_EN; + if (wolopts & WAKE_MAGIC) +- ocp_data |= MAGIC_EN; +- ocp_write_word(tp, MCU_TYPE_PLA, PLA_CFG_WOL, ocp_data); ++ ocp_word_set_bits(tp, MCU_TYPE_PLA, PLA_CFG_WOL, MAGIC_EN); ++ else ++ ocp_word_clr_bits(tp, MCU_TYPE_PLA, PLA_CFG_WOL, MAGIC_EN); + + if (wolopts & WAKE_ANY) + device_set_wakeup_enable(&tp->udev->dev, true); +@@ -3509,35 +3533,27 @@ static void __rtl_set_wol(struct r8152 * + + static void r8153_mac_clk_speed_down(struct r8152 *tp, bool enable) + { +- u32 ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL2); +- + /* MAC clock speed down */ + if (enable) +- ocp_data |= MAC_CLK_SPDWN_EN; ++ ocp_word_set_bits(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL2, ++ MAC_CLK_SPDWN_EN); + else +- ocp_data &= ~MAC_CLK_SPDWN_EN; +- +- ocp_write_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL2, ocp_data); ++ ocp_word_clr_bits(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL2, ++ MAC_CLK_SPDWN_EN); + } + + static void r8156_mac_clk_spd(struct r8152 *tp, bool enable) + { +- u32 ocp_data; +- + /* MAC clock speed down */ + if (enable) { + /* aldps_spdwn_ratio, tp10_spdwn_ratio */ +- ocp_write_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL, +- 0x0403); ++ ocp_write_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL, 0x0403); + +- ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL2); +- ocp_data &= ~EEE_SPDWN_RATIO_MASK; +- ocp_data |= MAC_CLK_SPDWN_EN | 0x03; /* eee_spdwn_ratio */ +- ocp_write_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL2, ocp_data); ++ ocp_word_w0w1(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL2, ++ EEE_SPDWN_RATIO_MASK, MAC_CLK_SPDWN_EN | 0x03); + } else { +- ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL2); +- ocp_data &= ~MAC_CLK_SPDWN_EN; +- ocp_write_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL2, ocp_data); ++ ocp_word_clr_bits(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL2, ++ MAC_CLK_SPDWN_EN); + } + } + +@@ -3555,27 +3571,20 @@ static void r8153_u1u2en(struct r8152 *t + + static void r8153b_u1u2en(struct r8152 *tp, bool enable) + { +- u32 ocp_data; +- +- ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_LPM_CONFIG); + if (enable) +- ocp_data |= LPM_U1U2_EN; ++ ocp_word_set_bits(tp, MCU_TYPE_USB, USB_LPM_CONFIG, ++ LPM_U1U2_EN); + else +- ocp_data &= ~LPM_U1U2_EN; +- +- ocp_write_word(tp, MCU_TYPE_USB, USB_LPM_CONFIG, ocp_data); ++ ocp_word_clr_bits(tp, MCU_TYPE_USB, USB_LPM_CONFIG, ++ LPM_U1U2_EN); + } + + static void r8153_u2p3en(struct r8152 *tp, bool enable) + { +- u32 ocp_data; +- +- ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_U2P3_CTRL); + if (enable) +- ocp_data |= U2P3_ENABLE; ++ ocp_word_set_bits(tp, MCU_TYPE_USB, USB_U2P3_CTRL, U2P3_ENABLE); + else +- ocp_data &= ~U2P3_ENABLE; +- ocp_write_word(tp, MCU_TYPE_USB, USB_U2P3_CTRL, ocp_data); ++ ocp_word_clr_bits(tp, MCU_TYPE_USB, USB_U2P3_CTRL, U2P3_ENABLE); + } + + static void r8153b_ups_flags(struct r8152 *tp) +@@ -3790,24 +3799,20 @@ static u16 r8153_phy_status(struct r8152 + + static void r8153b_ups_en(struct r8152 *tp, bool enable) + { +- u32 ocp_data = ocp_read_byte(tp, MCU_TYPE_USB, USB_POWER_CUT); +- + if (enable) { + r8153b_ups_flags(tp); + +- ocp_data |= UPS_EN | USP_PREWAKE | PHASE2_EN; +- ocp_write_byte(tp, MCU_TYPE_USB, USB_POWER_CUT, ocp_data); ++ ocp_byte_set_bits(tp, MCU_TYPE_USB, USB_POWER_CUT, ++ UPS_EN | USP_PREWAKE | PHASE2_EN); + +- ocp_data = ocp_read_byte(tp, MCU_TYPE_USB, USB_MISC_2); +- ocp_data |= UPS_FORCE_PWR_DOWN; +- ocp_write_byte(tp, MCU_TYPE_USB, USB_MISC_2, ocp_data); ++ ocp_byte_set_bits(tp, MCU_TYPE_USB, USB_MISC_2, ++ UPS_FORCE_PWR_DOWN); + } else { +- ocp_data &= ~(UPS_EN | USP_PREWAKE); +- ocp_write_byte(tp, MCU_TYPE_USB, USB_POWER_CUT, ocp_data); ++ ocp_byte_clr_bits(tp, MCU_TYPE_USB, USB_POWER_CUT, ++ UPS_EN | USP_PREWAKE); + +- ocp_data = ocp_read_byte(tp, MCU_TYPE_USB, USB_MISC_2); +- ocp_data &= ~UPS_FORCE_PWR_DOWN; +- ocp_write_byte(tp, MCU_TYPE_USB, USB_MISC_2, ocp_data); ++ 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) { + int i; +@@ -3831,25 +3836,20 @@ static void r8153b_ups_en(struct r8152 * + + static void r8153c_ups_en(struct r8152 *tp, bool enable) + { +- u32 ocp_data = ocp_read_byte(tp, MCU_TYPE_USB, USB_POWER_CUT); +- + if (enable) { + r8153b_ups_flags(tp); + +- ocp_data |= UPS_EN | USP_PREWAKE | PHASE2_EN; +- ocp_write_byte(tp, MCU_TYPE_USB, USB_POWER_CUT, ocp_data); ++ ocp_byte_set_bits(tp, MCU_TYPE_USB, USB_POWER_CUT, ++ UPS_EN | USP_PREWAKE | PHASE2_EN); + +- ocp_data = ocp_read_byte(tp, MCU_TYPE_USB, USB_MISC_2); +- ocp_data |= UPS_FORCE_PWR_DOWN; +- ocp_data &= ~BIT(7); +- ocp_write_byte(tp, MCU_TYPE_USB, USB_MISC_2, ocp_data); ++ ocp_byte_w0w1(tp, MCU_TYPE_USB, USB_MISC_2, BIT(7), ++ UPS_FORCE_PWR_DOWN); + } else { +- ocp_data &= ~(UPS_EN | USP_PREWAKE); +- ocp_write_byte(tp, MCU_TYPE_USB, USB_POWER_CUT, ocp_data); ++ ocp_byte_clr_bits(tp, MCU_TYPE_USB, USB_POWER_CUT, ++ UPS_EN | USP_PREWAKE); + +- ocp_data = ocp_read_byte(tp, MCU_TYPE_USB, USB_MISC_2); +- ocp_data &= ~UPS_FORCE_PWR_DOWN; +- ocp_write_byte(tp, MCU_TYPE_USB, USB_MISC_2, ocp_data); ++ 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) { + int i; +@@ -3871,9 +3871,7 @@ static void r8153c_ups_en(struct r8152 * + + ocp_write_byte(tp, MCU_TYPE_PLA, PLA_CRWECR, CRWECR_CONFIG); + +- ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_CONFIG34); +- ocp_data |= BIT(8); +- ocp_write_word(tp, MCU_TYPE_PLA, PLA_CONFIG34, ocp_data); ++ ocp_word_set_bits(tp, MCU_TYPE_PLA, PLA_CONFIG34, BIT(8)); + + ocp_write_byte(tp, MCU_TYPE_PLA, PLA_CRWECR, CRWECR_NORAML); + } +@@ -3881,35 +3879,30 @@ static void r8153c_ups_en(struct r8152 * + + static void r8156_ups_en(struct r8152 *tp, bool enable) + { +- u32 ocp_data = ocp_read_byte(tp, MCU_TYPE_USB, USB_POWER_CUT); +- + if (enable) { + r8156_ups_flags(tp); + +- ocp_data |= UPS_EN | USP_PREWAKE | PHASE2_EN; +- ocp_write_byte(tp, MCU_TYPE_USB, USB_POWER_CUT, ocp_data); ++ ocp_byte_set_bits(tp, MCU_TYPE_USB, USB_POWER_CUT, ++ UPS_EN | USP_PREWAKE | PHASE2_EN); + +- ocp_data = ocp_read_byte(tp, MCU_TYPE_USB, USB_MISC_2); +- ocp_data |= UPS_FORCE_PWR_DOWN; +- ocp_write_byte(tp, MCU_TYPE_USB, USB_MISC_2, ocp_data); ++ ocp_byte_set_bits(tp, MCU_TYPE_USB, USB_MISC_2, ++ UPS_FORCE_PWR_DOWN); + + switch (tp->version) { + case RTL_VER_13: + case RTL_VER_15: +- ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_UPHY_XTAL); +- ocp_data &= ~OOBS_POLLING; +- ocp_write_word(tp, MCU_TYPE_USB, USB_UPHY_XTAL, ocp_data); ++ ocp_word_clr_bits(tp, MCU_TYPE_USB, USB_UPHY_XTAL, ++ OOBS_POLLING); + break; + default: + break; + } + } else { +- ocp_data &= ~(UPS_EN | USP_PREWAKE); +- ocp_write_byte(tp, MCU_TYPE_USB, USB_POWER_CUT, ocp_data); ++ ocp_byte_clr_bits(tp, MCU_TYPE_USB, USB_POWER_CUT, ++ UPS_EN | USP_PREWAKE); + +- ocp_data = ocp_read_byte(tp, MCU_TYPE_USB, USB_MISC_2); +- ocp_data &= ~UPS_FORCE_PWR_DOWN; +- ocp_write_byte(tp, MCU_TYPE_USB, USB_MISC_2, ocp_data); ++ 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) { + tp->rtl_ops.hw_phy_cfg(tp); +@@ -3922,54 +3915,38 @@ static void r8156_ups_en(struct r8152 *t + + static void r8153_power_cut_en(struct r8152 *tp, bool enable) + { +- u32 ocp_data; +- +- ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_POWER_CUT); + if (enable) +- ocp_data |= PWR_EN | PHASE2_EN; ++ ocp_word_set_bits(tp, MCU_TYPE_USB, USB_POWER_CUT, ++ PWR_EN | PHASE2_EN); + else +- ocp_data &= ~(PWR_EN | PHASE2_EN); +- ocp_write_word(tp, MCU_TYPE_USB, USB_POWER_CUT, ocp_data); ++ ocp_word_clr_bits(tp, MCU_TYPE_USB, USB_POWER_CUT, ++ PWR_EN | PHASE2_EN); + +- ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_MISC_0); +- ocp_data &= ~PCUT_STATUS; +- ocp_write_word(tp, MCU_TYPE_USB, USB_MISC_0, ocp_data); ++ ocp_word_clr_bits(tp, MCU_TYPE_USB, USB_MISC_0, PCUT_STATUS); + } + + static void r8153b_power_cut_en(struct r8152 *tp, bool enable) + { +- u32 ocp_data; +- +- ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_POWER_CUT); + if (enable) +- ocp_data |= PWR_EN | PHASE2_EN; ++ ocp_word_set_bits(tp, MCU_TYPE_USB, USB_POWER_CUT, ++ PWR_EN | PHASE2_EN); + else +- ocp_data &= ~PWR_EN; +- ocp_write_word(tp, MCU_TYPE_USB, USB_POWER_CUT, ocp_data); ++ ocp_word_clr_bits(tp, MCU_TYPE_USB, USB_POWER_CUT, PWR_EN); + +- ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_MISC_0); +- ocp_data &= ~PCUT_STATUS; +- ocp_write_word(tp, MCU_TYPE_USB, USB_MISC_0, ocp_data); ++ ocp_word_clr_bits(tp, MCU_TYPE_USB, USB_MISC_0, PCUT_STATUS); + } + + static void r8153_queue_wake(struct r8152 *tp, bool enable) + { +- u32 ocp_data; +- +- ocp_data = ocp_read_byte(tp, MCU_TYPE_PLA, PLA_INDICATE_FALG); + if (enable) +- ocp_data |= UPCOMING_RUNTIME_D3; ++ ocp_byte_set_bits(tp, MCU_TYPE_PLA, PLA_INDICATE_FALG, ++ UPCOMING_RUNTIME_D3); + else +- ocp_data &= ~UPCOMING_RUNTIME_D3; +- ocp_write_byte(tp, MCU_TYPE_PLA, PLA_INDICATE_FALG, ocp_data); ++ ocp_byte_clr_bits(tp, MCU_TYPE_PLA, PLA_INDICATE_FALG, ++ UPCOMING_RUNTIME_D3); + +- ocp_data = ocp_read_byte(tp, MCU_TYPE_PLA, PLA_SUSPEND_FLAG); +- ocp_data &= ~LINK_CHG_EVENT; +- ocp_write_byte(tp, MCU_TYPE_PLA, PLA_SUSPEND_FLAG, ocp_data); +- +- ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_EXTRA_STATUS); +- ocp_data &= ~LINK_CHANGE_FLAG; +- ocp_write_word(tp, MCU_TYPE_PLA, PLA_EXTRA_STATUS, ocp_data); ++ ocp_byte_clr_bits(tp, MCU_TYPE_PLA, PLA_SUSPEND_FLAG, LINK_CHG_EVENT); ++ ocp_word_clr_bits(tp, MCU_TYPE_PLA, PLA_EXTRA_STATUS, LINK_CHANGE_FLAG); + } + + static bool rtl_can_wakeup(struct r8152 *tp) +@@ -3982,27 +3959,21 @@ static bool rtl_can_wakeup(struct r8152 + static void rtl_runtime_suspend_enable(struct r8152 *tp, bool enable) + { + if (enable) { +- u32 ocp_data; +- + __rtl_set_wol(tp, WAKE_ANY); + + ocp_write_byte(tp, MCU_TYPE_PLA, PLA_CRWECR, CRWECR_CONFIG); + +- ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_CONFIG34); +- ocp_data |= LINK_OFF_WAKE_EN; +- ocp_write_word(tp, MCU_TYPE_PLA, PLA_CONFIG34, ocp_data); ++ ocp_word_set_bits(tp, MCU_TYPE_PLA, PLA_CONFIG34, ++ LINK_OFF_WAKE_EN); + + ocp_write_byte(tp, MCU_TYPE_PLA, PLA_CRWECR, CRWECR_NORAML); + } else { +- u32 ocp_data; +- + __rtl_set_wol(tp, tp->saved_wolopts); + + ocp_write_byte(tp, MCU_TYPE_PLA, PLA_CRWECR, CRWECR_CONFIG); + +- ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_CONFIG34); +- ocp_data &= ~LINK_OFF_WAKE_EN; +- ocp_write_word(tp, MCU_TYPE_PLA, PLA_CONFIG34, ocp_data); ++ ocp_word_clr_bits(tp, MCU_TYPE_PLA, PLA_CONFIG34, ++ LINK_OFF_WAKE_EN); + + ocp_write_byte(tp, MCU_TYPE_PLA, PLA_CRWECR, CRWECR_NORAML); + } +@@ -4083,8 +4054,6 @@ static void rtl8156_runtime_enable(struc + + static void r8153_teredo_off(struct r8152 *tp) + { +- u32 ocp_data; +- + switch (tp->version) { + case RTL_VER_01: + case RTL_VER_02: +@@ -4093,10 +4062,9 @@ static void r8153_teredo_off(struct r815 + case RTL_VER_05: + case RTL_VER_06: + case RTL_VER_07: +- ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_TEREDO_CFG); +- ocp_data &= ~(TEREDO_SEL | TEREDO_RS_EVENT_MASK | +- OOB_TEREDO_EN); +- ocp_write_word(tp, MCU_TYPE_PLA, PLA_TEREDO_CFG, ocp_data); ++ ocp_word_clr_bits(tp, MCU_TYPE_PLA, PLA_TEREDO_CFG, ++ TEREDO_SEL | TEREDO_RS_EVENT_MASK | ++ OOB_TEREDO_EN); + break; + + case RTL_VER_08: +@@ -4123,13 +4091,10 @@ static void r8153_teredo_off(struct r815 + + static void rtl_reset_bmu(struct r8152 *tp) + { +- u32 ocp_data; +- +- ocp_data = ocp_read_byte(tp, MCU_TYPE_USB, USB_BMU_RESET); +- ocp_data &= ~(BMU_RESET_EP_IN | BMU_RESET_EP_OUT); +- ocp_write_byte(tp, MCU_TYPE_USB, USB_BMU_RESET, ocp_data); +- ocp_data |= BMU_RESET_EP_IN | BMU_RESET_EP_OUT; +- ocp_write_byte(tp, MCU_TYPE_USB, USB_BMU_RESET, ocp_data); ++ ocp_byte_clr_bits(tp, MCU_TYPE_USB, USB_BMU_RESET, ++ BMU_RESET_EP_IN | BMU_RESET_EP_OUT); ++ ocp_byte_set_bits(tp, MCU_TYPE_USB, USB_BMU_RESET, ++ BMU_RESET_EP_IN | BMU_RESET_EP_OUT); + } + + /* Clear the bp to stop the firmware before loading a new one */ +@@ -4950,7 +4915,7 @@ static void rtl_ram_code_speed_up(struct + return; + + while (len) { +- u32 ocp_data, size; ++ u32 size; + int i; + + if (len < 2048) +@@ -4958,18 +4923,16 @@ static void rtl_ram_code_speed_up(struct + else + size = 2048; + +- ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_GPHY_CTRL); +- ocp_data |= GPHY_PATCH_DONE | BACKUP_RESTRORE; +- ocp_write_word(tp, MCU_TYPE_USB, USB_GPHY_CTRL, ocp_data); ++ ocp_word_set_bits(tp, MCU_TYPE_USB, USB_GPHY_CTRL, ++ GPHY_PATCH_DONE | BACKUP_RESTRORE); + + generic_ocp_write(tp, __le16_to_cpu(phy->fw_reg), 0xff, size, data, MCU_TYPE_USB); + + data += size; + len -= size; + +- ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_POL_GPIO_CTRL); +- ocp_data |= POL_GPHY_PATCH; +- ocp_write_word(tp, MCU_TYPE_PLA, PLA_POL_GPIO_CTRL, ocp_data); ++ ocp_word_set_bits(tp, MCU_TYPE_PLA, PLA_POL_GPIO_CTRL, ++ POL_GPHY_PATCH); + + for (i = 0; i < 1000; i++) { + if (!(ocp_read_word(tp, MCU_TYPE_PLA, PLA_POL_GPIO_CTRL) & POL_GPHY_PATCH)) +@@ -5343,21 +5306,21 @@ static void r8152_mmd_write(struct r8152 + static void r8152_eee_en(struct r8152 *tp, bool enable) + { + u16 config1, config2, config3; +- u32 ocp_data; + +- ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_EEE_CR); + config1 = ocp_reg_read(tp, OCP_EEE_CONFIG1) & ~sd_rise_time_mask; + config2 = ocp_reg_read(tp, OCP_EEE_CONFIG2); + config3 = ocp_reg_read(tp, OCP_EEE_CONFIG3) & ~fast_snr_mask; + + if (enable) { +- ocp_data |= EEE_RX_EN | EEE_TX_EN; ++ ocp_word_set_bits(tp, MCU_TYPE_PLA, PLA_EEE_CR, ++ EEE_RX_EN | EEE_TX_EN); + config1 |= EEE_10_CAP | EEE_NWAY_EN | TX_QUIET_EN | RX_QUIET_EN; + config1 |= sd_rise_time(1); + config2 |= RG_DACQUIET_EN | RG_LDVQUIET_EN; + config3 |= fast_snr(42); + } else { +- ocp_data &= ~(EEE_RX_EN | EEE_TX_EN); ++ ocp_word_clr_bits(tp, MCU_TYPE_PLA, PLA_EEE_CR, ++ EEE_RX_EN | EEE_TX_EN); + config1 &= ~(EEE_10_CAP | EEE_NWAY_EN | TX_QUIET_EN | + RX_QUIET_EN); + config1 |= sd_rise_time(7); +@@ -5365,7 +5328,6 @@ static void r8152_eee_en(struct r8152 *t + config3 |= fast_snr(511); + } + +- ocp_write_word(tp, MCU_TYPE_PLA, PLA_EEE_CR, ocp_data); + ocp_reg_write(tp, OCP_EEE_CONFIG1, config1); + ocp_reg_write(tp, OCP_EEE_CONFIG2, config2); + ocp_reg_write(tp, OCP_EEE_CONFIG3, config3); +@@ -5373,21 +5335,20 @@ static void r8152_eee_en(struct r8152 *t + + static void r8153_eee_en(struct r8152 *tp, bool enable) + { +- u32 ocp_data; + u16 config; + +- ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_EEE_CR); + config = ocp_reg_read(tp, OCP_EEE_CFG); + + if (enable) { +- ocp_data |= EEE_RX_EN | EEE_TX_EN; ++ ocp_word_set_bits(tp, MCU_TYPE_PLA, PLA_EEE_CR, ++ EEE_RX_EN | EEE_TX_EN); + config |= EEE10_EN; + } else { +- ocp_data &= ~(EEE_RX_EN | EEE_TX_EN); ++ ocp_word_clr_bits(tp, MCU_TYPE_PLA, PLA_EEE_CR, ++ EEE_RX_EN | EEE_TX_EN); + config &= ~EEE10_EN; + } + +- ocp_write_word(tp, MCU_TYPE_PLA, PLA_EEE_CR, ocp_data); + ocp_reg_write(tp, OCP_EEE_CFG, config); + + tp->ups_info.eee = enable; +@@ -5518,30 +5479,20 @@ static void r8156b_wait_loading_flash(st + + static void r8152b_exit_oob(struct r8152 *tp) + { +- u32 ocp_data; +- +- ocp_data = ocp_read_dword(tp, MCU_TYPE_PLA, PLA_RCR); +- ocp_data &= ~RCR_ACPT_ALL; +- ocp_write_dword(tp, MCU_TYPE_PLA, PLA_RCR, ocp_data); ++ ocp_dword_clr_bits(tp, MCU_TYPE_PLA, PLA_RCR, RCR_ACPT_ALL); + + rxdy_gated_en(tp, true); + r8153_teredo_off(tp); + ocp_write_byte(tp, MCU_TYPE_PLA, PLA_CRWECR, CRWECR_NORAML); + ocp_write_byte(tp, MCU_TYPE_PLA, PLA_CR, 0x00); + +- ocp_data = ocp_read_byte(tp, MCU_TYPE_PLA, PLA_OOB_CTRL); +- ocp_data &= ~NOW_IS_OOB; +- ocp_write_byte(tp, MCU_TYPE_PLA, PLA_OOB_CTRL, ocp_data); +- +- ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_SFF_STS_7); +- ocp_data &= ~MCU_BORW_EN; +- ocp_write_word(tp, MCU_TYPE_PLA, PLA_SFF_STS_7, ocp_data); ++ ocp_byte_clr_bits(tp, MCU_TYPE_PLA, PLA_OOB_CTRL, NOW_IS_OOB); ++ ++ ocp_word_clr_bits(tp, MCU_TYPE_PLA, PLA_SFF_STS_7, MCU_BORW_EN); + + wait_oob_link_list_ready(tp); + +- ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_SFF_STS_7); +- ocp_data |= RE_INIT_LL; +- ocp_write_word(tp, MCU_TYPE_PLA, PLA_SFF_STS_7, ocp_data); ++ ocp_word_set_bits(tp, MCU_TYPE_PLA, PLA_SFF_STS_7, RE_INIT_LL); + + wait_oob_link_list_ready(tp); + +@@ -5577,18 +5528,12 @@ static void r8152b_exit_oob(struct r8152 + + ocp_write_word(tp, MCU_TYPE_PLA, PLA_RMS, RTL8152_RMS); + +- ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_TCR0); +- ocp_data |= TCR0_AUTO_FIFO; +- ocp_write_word(tp, MCU_TYPE_PLA, PLA_TCR0, ocp_data); ++ ocp_word_set_bits(tp, MCU_TYPE_PLA, PLA_TCR0, TCR0_AUTO_FIFO); + } + + static void r8152b_enter_oob(struct r8152 *tp) + { +- u32 ocp_data; +- +- ocp_data = ocp_read_byte(tp, MCU_TYPE_PLA, PLA_OOB_CTRL); +- ocp_data &= ~NOW_IS_OOB; +- ocp_write_byte(tp, MCU_TYPE_PLA, PLA_OOB_CTRL, ocp_data); ++ ocp_byte_clr_bits(tp, MCU_TYPE_PLA, PLA_OOB_CTRL, NOW_IS_OOB); + + ocp_write_dword(tp, MCU_TYPE_PLA, PLA_RXFIFO_CTRL0, RXFIFO_THR1_OOB); + ocp_write_dword(tp, MCU_TYPE_PLA, PLA_RXFIFO_CTRL1, RXFIFO_THR2_OOB); +@@ -5598,9 +5543,7 @@ static void r8152b_enter_oob(struct r815 + + wait_oob_link_list_ready(tp); + +- ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_SFF_STS_7); +- ocp_data |= RE_INIT_LL; +- ocp_write_word(tp, MCU_TYPE_PLA, PLA_SFF_STS_7, ocp_data); ++ ocp_word_set_bits(tp, MCU_TYPE_PLA, PLA_SFF_STS_7, RE_INIT_LL); + + wait_oob_link_list_ready(tp); + +@@ -5608,19 +5551,15 @@ static void r8152b_enter_oob(struct r815 + + rtl_rx_vlan_en(tp, true); + +- ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_BDC_CR); +- ocp_data |= ALDPS_PROXY_MODE; +- ocp_write_word(tp, MCU_TYPE_PLA, PLA_BDC_CR, ocp_data); +- +- ocp_data = ocp_read_byte(tp, MCU_TYPE_PLA, PLA_OOB_CTRL); +- ocp_data |= NOW_IS_OOB | DIS_MCU_CLROOB; +- ocp_write_byte(tp, MCU_TYPE_PLA, PLA_OOB_CTRL, ocp_data); ++ 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); + + rxdy_gated_en(tp, false); + +- ocp_data = ocp_read_dword(tp, MCU_TYPE_PLA, PLA_RCR); +- ocp_data |= RCR_APM | RCR_AM | RCR_AB; +- ocp_write_dword(tp, MCU_TYPE_PLA, PLA_RCR, ocp_data); ++ ocp_dword_set_bits(tp, MCU_TYPE_PLA, PLA_RCR, ++ RCR_APM | RCR_AM | RCR_AB); + } + + static int r8153_pre_firmware_1(struct r8152 *tp) +@@ -5655,27 +5594,18 @@ static int r8153_post_firmware_1(struct + + static int r8153_pre_firmware_2(struct r8152 *tp) + { +- u32 ocp_data; +- + r8153_pre_firmware_1(tp); + +- ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_FW_FIX_EN0); +- ocp_data &= ~FW_FIX_SUSPEND; +- ocp_write_word(tp, MCU_TYPE_USB, USB_FW_FIX_EN0, ocp_data); ++ ocp_word_clr_bits(tp, MCU_TYPE_USB, USB_FW_FIX_EN0, FW_FIX_SUSPEND); + + return 0; + } + + static int r8153_post_firmware_2(struct r8152 *tp) + { +- u32 ocp_data; +- + /* enable bp0 if support USB_SPEED_SUPER only */ +- if (ocp_read_byte(tp, MCU_TYPE_USB, USB_CSTMR) & FORCE_SUPER) { +- ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_BP_EN); +- ocp_data |= BIT(0); +- ocp_write_word(tp, MCU_TYPE_PLA, PLA_BP_EN, ocp_data); +- } ++ if (ocp_read_byte(tp, MCU_TYPE_USB, USB_CSTMR) & FORCE_SUPER) ++ ocp_word_set_bits(tp, MCU_TYPE_PLA, PLA_BP_EN, BIT(0)); + + /* reset UPHY timer to 36 ms */ + ocp_write_word(tp, MCU_TYPE_PLA, PLA_UPHY_TIMER, 36000 / 16); +@@ -5683,28 +5613,20 @@ static int r8153_post_firmware_2(struct + /* enable U3P3 check, set the counter to 4 */ + ocp_write_word(tp, MCU_TYPE_PLA, PLA_EXTRA_STATUS, U3P3_CHECK_EN | 4); + +- ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_FW_FIX_EN0); +- ocp_data |= FW_FIX_SUSPEND; +- ocp_write_word(tp, MCU_TYPE_USB, USB_FW_FIX_EN0, ocp_data); +- +- ocp_data = ocp_read_byte(tp, MCU_TYPE_USB, USB_USB2PHY); +- ocp_data |= USB2PHY_L1 | USB2PHY_SUSPEND; +- ocp_write_byte(tp, MCU_TYPE_USB, USB_USB2PHY, ocp_data); ++ ocp_word_set_bits(tp, MCU_TYPE_USB, USB_FW_FIX_EN0, FW_FIX_SUSPEND); ++ ++ ocp_byte_set_bits(tp, MCU_TYPE_USB, USB_USB2PHY, ++ USB2PHY_L1 | USB2PHY_SUSPEND); + + return 0; + } + + static int r8153_post_firmware_3(struct r8152 *tp) + { +- u32 ocp_data; ++ ocp_byte_set_bits(tp, MCU_TYPE_USB, USB_USB2PHY, ++ USB2PHY_L1 | USB2PHY_SUSPEND); + +- ocp_data = ocp_read_byte(tp, MCU_TYPE_USB, USB_USB2PHY); +- ocp_data |= USB2PHY_L1 | USB2PHY_SUSPEND; +- ocp_write_byte(tp, MCU_TYPE_USB, USB_USB2PHY, ocp_data); +- +- ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_FW_FIX_EN1); +- ocp_data |= FW_IP_RESET_EN; +- ocp_write_word(tp, MCU_TYPE_USB, USB_FW_FIX_EN1, ocp_data); ++ ocp_word_set_bits(tp, MCU_TYPE_USB, USB_FW_FIX_EN1, FW_IP_RESET_EN); + + return 0; + } +@@ -5724,49 +5646,30 @@ static int r8153b_post_firmware_1(struct + + /* enable bp0 for RTL8153-BND */ + ocp_data = ocp_read_byte(tp, MCU_TYPE_USB, USB_MISC_1); +- if (ocp_data & BND_MASK) { +- ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_BP_EN); +- ocp_data |= BIT(0); +- ocp_write_word(tp, MCU_TYPE_PLA, PLA_BP_EN, ocp_data); +- } +- +- ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_FW_CTRL); +- ocp_data |= FLOW_CTRL_PATCH_OPT; +- ocp_write_word(tp, MCU_TYPE_USB, USB_FW_CTRL, ocp_data); +- +- ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_FW_TASK); +- ocp_data |= FC_PATCH_TASK; +- ocp_write_word(tp, MCU_TYPE_USB, USB_FW_TASK, ocp_data); +- +- ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_FW_FIX_EN1); +- ocp_data |= FW_IP_RESET_EN; +- ocp_write_word(tp, MCU_TYPE_USB, USB_FW_FIX_EN1, ocp_data); ++ if (ocp_data & BND_MASK) ++ ocp_word_set_bits(tp, MCU_TYPE_PLA, PLA_BP_EN, BIT(0)); ++ ++ 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); ++ ++ ocp_word_set_bits(tp, MCU_TYPE_USB, USB_FW_FIX_EN1, FW_IP_RESET_EN); + + return 0; + } + + static int r8153c_post_firmware_1(struct r8152 *tp) + { +- u32 ocp_data; ++ ocp_word_set_bits(tp, MCU_TYPE_USB, USB_FW_CTRL, FLOW_CTRL_PATCH_2); + +- ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_FW_CTRL); +- ocp_data |= FLOW_CTRL_PATCH_2; +- ocp_write_word(tp, MCU_TYPE_USB, USB_FW_CTRL, ocp_data); +- +- ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_FW_TASK); +- ocp_data |= FC_PATCH_TASK; +- ocp_write_word(tp, MCU_TYPE_USB, USB_FW_TASK, ocp_data); ++ ocp_word_set_bits(tp, MCU_TYPE_USB, USB_FW_TASK, FC_PATCH_TASK); + + return 0; + } + + static int r8156a_post_firmware_1(struct r8152 *tp) + { +- u32 ocp_data; +- +- ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_FW_FIX_EN1); +- ocp_data |= FW_IP_RESET_EN; +- ocp_write_word(tp, MCU_TYPE_USB, USB_FW_FIX_EN1, ocp_data); ++ ocp_word_set_bits(tp, MCU_TYPE_USB, USB_FW_FIX_EN1, FW_IP_RESET_EN); + + /* Modify U3PHY parameter for compatibility issue */ + ocp_write_dword(tp, MCU_TYPE_USB, USB_UPHY3_MDCMDIO, 0x4026840e); +@@ -5802,7 +5705,6 @@ static void r8153_aldps_en(struct r8152 + + static void r8153_hw_phy_cfg(struct r8152 *tp) + { +- u32 ocp_data; + u16 data; + + /* disable ALDPS before updating the PHY parameters */ +@@ -5829,11 +5731,10 @@ static void r8153_hw_phy_cfg(struct r815 + data = ocp_reg_read(tp, OCP_POWER_CFG); + data |= EN_10M_PLLOFF; + ocp_reg_write(tp, OCP_POWER_CFG, data); ++ + sram_write(tp, SRAM_IMPEDANCE, 0x0b13); + +- ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_PHY_PWR); +- ocp_data |= PFM_PWM_SWITCH; +- ocp_write_word(tp, MCU_TYPE_PLA, PLA_PHY_PWR, ocp_data); ++ ocp_word_set_bits(tp, MCU_TYPE_PLA, PLA_PHY_PWR, PFM_PWM_SWITCH); + + /* Enable LPF corner auto tune */ + sram_write(tp, SRAM_LPF_CFG, 0xf70f); +@@ -5879,11 +5780,7 @@ static void r8153b_hw_phy_cfg(struct r81 + u32 ocp_data; + u16 data; + +- ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_MISC_0); +- if (ocp_data & PCUT_STATUS) { +- ocp_data &= ~PCUT_STATUS; +- ocp_write_word(tp, MCU_TYPE_USB, USB_MISC_0, ocp_data); +- } ++ ocp_word_test_and_clr_bits(tp, MCU_TYPE_USB, USB_MISC_0, PCUT_STATUS); + + /* disable ALDPS before updating the PHY parameters */ + r8153_aldps_en(tp, false); +@@ -5940,14 +5837,11 @@ static void r8153b_hw_phy_cfg(struct r81 + u32 swr_cnt_1ms_ini; + + swr_cnt_1ms_ini = (16000000 / ocp_data) & SAW_CNT_1MS_MASK; +- ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_UPS_CFG); +- ocp_data = (ocp_data & ~SAW_CNT_1MS_MASK) | swr_cnt_1ms_ini; +- ocp_write_word(tp, MCU_TYPE_USB, USB_UPS_CFG, ocp_data); ++ ocp_word_w0w1(tp, MCU_TYPE_USB, USB_UPS_CFG, SAW_CNT_1MS_MASK, ++ swr_cnt_1ms_ini); + } + +- ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_PHY_PWR); +- ocp_data |= PFM_PWM_SWITCH; +- ocp_write_word(tp, MCU_TYPE_PLA, PLA_PHY_PWR, ocp_data); ++ ocp_word_set_bits(tp, MCU_TYPE_PLA, PLA_PHY_PWR, PFM_PWM_SWITCH); + + /* Advnace EEE */ + if (!rtl_phy_patch_request(tp, true, true)) { +@@ -5994,31 +5888,21 @@ static void rtl8153_change_mtu(struct r8 + + static void r8153_first_init(struct r8152 *tp) + { +- u32 ocp_data; +- + rxdy_gated_en(tp, true); + r8153_teredo_off(tp); + +- ocp_data = ocp_read_dword(tp, MCU_TYPE_PLA, PLA_RCR); +- ocp_data &= ~RCR_ACPT_ALL; +- ocp_write_dword(tp, MCU_TYPE_PLA, PLA_RCR, ocp_data); ++ ocp_dword_clr_bits(tp, MCU_TYPE_PLA, PLA_RCR, RCR_ACPT_ALL); + + rtl8152_nic_reset(tp); + rtl_reset_bmu(tp); + +- ocp_data = ocp_read_byte(tp, MCU_TYPE_PLA, PLA_OOB_CTRL); +- ocp_data &= ~NOW_IS_OOB; +- ocp_write_byte(tp, MCU_TYPE_PLA, PLA_OOB_CTRL, ocp_data); +- +- ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_SFF_STS_7); +- ocp_data &= ~MCU_BORW_EN; +- ocp_write_word(tp, MCU_TYPE_PLA, PLA_SFF_STS_7, ocp_data); ++ ocp_byte_clr_bits(tp, MCU_TYPE_PLA, PLA_OOB_CTRL, NOW_IS_OOB); ++ ++ ocp_word_clr_bits(tp, MCU_TYPE_PLA, PLA_SFF_STS_7, MCU_BORW_EN); + + wait_oob_link_list_ready(tp); + +- ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_SFF_STS_7); +- ocp_data |= RE_INIT_LL; +- ocp_write_word(tp, MCU_TYPE_PLA, PLA_SFF_STS_7, ocp_data); ++ ocp_word_set_bits(tp, MCU_TYPE_PLA, PLA_SFF_STS_7, RE_INIT_LL); + + wait_oob_link_list_ready(tp); + +@@ -6026,9 +5910,7 @@ static void r8153_first_init(struct r815 + + rtl8153_change_mtu(tp); + +- ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_TCR0); +- ocp_data |= TCR0_AUTO_FIFO; +- ocp_write_word(tp, MCU_TYPE_PLA, PLA_TCR0, ocp_data); ++ ocp_word_set_bits(tp, MCU_TYPE_PLA, PLA_TCR0, TCR0_AUTO_FIFO); + + rtl8152_nic_reset(tp); + +@@ -6042,11 +5924,7 @@ static void r8153_first_init(struct r815 + + static void r8153_enter_oob(struct r8152 *tp) + { +- u32 ocp_data; +- +- ocp_data = ocp_read_byte(tp, MCU_TYPE_PLA, PLA_OOB_CTRL); +- ocp_data &= ~NOW_IS_OOB; +- ocp_write_byte(tp, MCU_TYPE_PLA, PLA_OOB_CTRL, ocp_data); ++ ocp_byte_clr_bits(tp, MCU_TYPE_PLA, PLA_OOB_CTRL, NOW_IS_OOB); + + /* RX FIFO settings for OOB */ + ocp_write_dword(tp, MCU_TYPE_PLA, PLA_RXFIFO_CTRL0, RXFIFO_THR1_OOB); +@@ -6058,9 +5936,7 @@ static void r8153_enter_oob(struct r8152 + + wait_oob_link_list_ready(tp); + +- ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_SFF_STS_7); +- ocp_data |= RE_INIT_LL; +- ocp_write_word(tp, MCU_TYPE_PLA, PLA_SFF_STS_7, ocp_data); ++ ocp_word_set_bits(tp, MCU_TYPE_PLA, PLA_SFF_STS_7, RE_INIT_LL); + + wait_oob_link_list_ready(tp); + +@@ -6072,9 +5948,8 @@ static void r8153_enter_oob(struct r8152 + case RTL_VER_04: + case RTL_VER_05: + case RTL_VER_06: +- ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_TEREDO_CFG); +- ocp_data &= ~TEREDO_WAKE_MASK; +- ocp_write_word(tp, MCU_TYPE_PLA, PLA_TEREDO_CFG, ocp_data); ++ ocp_word_clr_bits(tp, MCU_TYPE_PLA, PLA_TEREDO_CFG, ++ TEREDO_WAKE_MASK); + break; + + case RTL_VER_08: +@@ -6093,23 +5968,17 @@ static void r8153_enter_oob(struct r8152 + + rtl_rx_vlan_en(tp, true); + +- ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_BDC_CR); +- ocp_data |= ALDPS_PROXY_MODE; +- ocp_write_word(tp, MCU_TYPE_PLA, PLA_BDC_CR, ocp_data); +- +- ocp_data = ocp_read_byte(tp, MCU_TYPE_PLA, PLA_OOB_CTRL); +- ocp_data |= NOW_IS_OOB | DIS_MCU_CLROOB; +- ocp_write_byte(tp, MCU_TYPE_PLA, PLA_OOB_CTRL, ocp_data); +- +- ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_SFF_STS_7); +- ocp_data |= MCU_BORW_EN; +- ocp_write_word(tp, MCU_TYPE_PLA, PLA_SFF_STS_7, ocp_data); ++ 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); + + rxdy_gated_en(tp, false); + +- ocp_data = ocp_read_dword(tp, MCU_TYPE_PLA, PLA_RCR); +- ocp_data |= RCR_APM | RCR_AM | RCR_AB; +- ocp_write_dword(tp, MCU_TYPE_PLA, PLA_RCR, ocp_data); ++ ocp_dword_set_bits(tp, MCU_TYPE_PLA, PLA_RCR, ++ RCR_APM | RCR_AM | RCR_AB); + } + + static void rtl8153_disable(struct r8152 *tp) +@@ -6141,7 +6010,6 @@ static void r8156_fc_parameter(struct r8 + + static int rtl8156_enable(struct r8152 *tp) + { +- u32 ocp_data; + u16 speed; + + if (test_bit(RTL8152_INACCESSIBLE, &tp->flags)) +@@ -6156,12 +6024,12 @@ static int rtl8156_enable(struct r8152 * + speed = rtl8152_get_speed(tp); + rtl_set_ifg(tp, speed); + +- ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL4); + if (speed & _2500bps) +- ocp_data &= ~IDLE_SPDWN_EN; ++ ocp_word_clr_bits(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL4, ++ IDLE_SPDWN_EN); + else +- ocp_data |= IDLE_SPDWN_EN; +- ocp_write_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL4, ocp_data); ++ ocp_word_set_bits(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL4, ++ IDLE_SPDWN_EN); + + if (speed & _1000bps) + ocp_write_word(tp, MCU_TYPE_PLA, PLA_EEE_TXTWSYS, 0x11); +@@ -6170,21 +6038,15 @@ static int rtl8156_enable(struct r8152 * + + if (tp->udev->speed == USB_SPEED_HIGH) { + /* USB 0xb45e[3:0] l1_nyet_hird */ +- ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_L1_CTRL); +- ocp_data &= ~0xf; + if (is_flow_control(speed)) +- ocp_data |= 0xf; ++ ocp_word_w0w1(tp, MCU_TYPE_USB, USB_L1_CTRL, 0xf, 0xf); + else +- ocp_data |= 0x1; +- ocp_write_word(tp, MCU_TYPE_USB, USB_L1_CTRL, ocp_data); ++ ocp_word_w0w1(tp, MCU_TYPE_USB, USB_L1_CTRL, 0xf, 0x1); + } + +- ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_FW_TASK); +- ocp_data &= ~FC_PATCH_TASK; +- ocp_write_word(tp, MCU_TYPE_USB, USB_FW_TASK, ocp_data); ++ ocp_word_clr_bits(tp, MCU_TYPE_USB, USB_FW_TASK, FC_PATCH_TASK); + usleep_range(1000, 2000); +- ocp_data |= FC_PATCH_TASK; +- ocp_write_word(tp, MCU_TYPE_USB, USB_FW_TASK, ocp_data); ++ ocp_word_set_bits(tp, MCU_TYPE_USB, USB_FW_TASK, FC_PATCH_TASK); + + return rtl_enable(tp); + } +@@ -6199,7 +6061,6 @@ static void rtl8156_disable(struct r8152 + + static int rtl8156b_enable(struct r8152 *tp) + { +- u32 ocp_data; + u16 speed; + + if (test_bit(RTL8152_INACCESSIBLE, &tp->flags)) +@@ -6208,9 +6069,7 @@ static int rtl8156b_enable(struct r8152 + set_tx_qlen(tp); + rtl_set_eee_plus(tp); + +- ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_RX_AGGR_NUM); +- ocp_data &= ~RX_AGGR_NUM_MASK; +- ocp_write_word(tp, MCU_TYPE_USB, USB_RX_AGGR_NUM, ocp_data); ++ 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); +@@ -6218,29 +6077,23 @@ static int rtl8156b_enable(struct r8152 + speed = rtl8152_get_speed(tp); + rtl_set_ifg(tp, speed); + +- ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL4); + if (speed & _2500bps) +- ocp_data &= ~IDLE_SPDWN_EN; ++ ocp_word_clr_bits(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL4, ++ IDLE_SPDWN_EN); + else +- ocp_data |= IDLE_SPDWN_EN; +- ocp_write_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL4, ocp_data); ++ ocp_word_set_bits(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL4, ++ IDLE_SPDWN_EN); + + if (tp->udev->speed == USB_SPEED_HIGH) { +- ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_L1_CTRL); +- ocp_data &= ~0xf; + if (is_flow_control(speed)) +- ocp_data |= 0xf; ++ ocp_word_w0w1(tp, MCU_TYPE_USB, USB_L1_CTRL, 0xf, 0xf); + else +- ocp_data |= 0x1; +- ocp_write_word(tp, MCU_TYPE_USB, USB_L1_CTRL, ocp_data); ++ ocp_word_w0w1(tp, MCU_TYPE_USB, USB_L1_CTRL, 0xf, 0x1); + } + +- ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_FW_TASK); +- ocp_data &= ~FC_PATCH_TASK; +- ocp_write_word(tp, MCU_TYPE_USB, USB_FW_TASK, ocp_data); ++ ocp_word_clr_bits(tp, MCU_TYPE_USB, USB_FW_TASK, FC_PATCH_TASK); + usleep_range(1000, 2000); +- ocp_data |= FC_PATCH_TASK; +- ocp_write_word(tp, MCU_TYPE_USB, USB_FW_TASK, ocp_data); ++ ocp_word_set_bits(tp, MCU_TYPE_USB, USB_FW_TASK, FC_PATCH_TASK); + + return rtl_enable(tp); + } +@@ -6411,8 +6264,6 @@ static void rtl8152_down(struct r8152 *t + + static void rtl8153_up(struct r8152 *tp) + { +- u32 ocp_data; +- + if (test_bit(RTL8152_INACCESSIBLE, &tp->flags)) + return; + +@@ -6421,17 +6272,11 @@ static void rtl8153_up(struct r8152 *tp) + r8153_aldps_en(tp, false); + r8153_first_init(tp); + +- ocp_data = ocp_read_byte(tp, MCU_TYPE_PLA, PLA_CONFIG6); +- ocp_data |= LANWAKE_CLR_EN; +- ocp_write_byte(tp, MCU_TYPE_PLA, PLA_CONFIG6, ocp_data); +- +- ocp_data = ocp_read_byte(tp, MCU_TYPE_PLA, PLA_LWAKE_CTRL_REG); +- ocp_data &= ~LANWAKE_PIN; +- ocp_write_byte(tp, MCU_TYPE_PLA, PLA_LWAKE_CTRL_REG, ocp_data); +- +- ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_SSPHYLINK1); +- ocp_data &= ~DELAY_PHY_PWR_CHG; +- ocp_write_word(tp, MCU_TYPE_USB, USB_SSPHYLINK1, ocp_data); ++ ocp_byte_set_bits(tp, MCU_TYPE_PLA, PLA_CONFIG6, LANWAKE_CLR_EN); ++ ++ ocp_byte_clr_bits(tp, MCU_TYPE_PLA, PLA_LWAKE_CTRL_REG, LANWAKE_PIN); ++ ++ ocp_word_clr_bits(tp, MCU_TYPE_USB, USB_SSPHYLINK1, DELAY_PHY_PWR_CHG); + + r8153_aldps_en(tp, true); + +@@ -6451,16 +6296,12 @@ static void rtl8153_up(struct r8152 *tp) + + static void rtl8153_down(struct r8152 *tp) + { +- u32 ocp_data; +- + if (test_bit(RTL8152_INACCESSIBLE, &tp->flags)) { + rtl_drop_queued_tx(tp); + return; + } + +- ocp_data = ocp_read_byte(tp, MCU_TYPE_PLA, PLA_CONFIG6); +- ocp_data &= ~LANWAKE_CLR_EN; +- ocp_write_byte(tp, MCU_TYPE_PLA, PLA_CONFIG6, ocp_data); ++ ocp_byte_clr_bits(tp, MCU_TYPE_PLA, PLA_CONFIG6, LANWAKE_CLR_EN); + + r8153_u1u2en(tp, false); + r8153_u2p3en(tp, false); +@@ -6472,8 +6313,6 @@ static void rtl8153_down(struct r8152 *t + + static void rtl8153b_up(struct r8152 *tp) + { +- u32 ocp_data; +- + if (test_bit(RTL8152_INACCESSIBLE, &tp->flags)) + return; + +@@ -6484,9 +6323,8 @@ static void rtl8153b_up(struct r8152 *tp + r8153_first_init(tp); + ocp_write_dword(tp, MCU_TYPE_USB, USB_RX_BUF_TH, RX_THR_B); + +- ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL3); +- ocp_data &= ~PLA_MCU_SPDWN_EN; +- ocp_write_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL3, ocp_data); ++ ocp_word_clr_bits(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL3, ++ PLA_MCU_SPDWN_EN); + + r8153_aldps_en(tp, true); + +@@ -6496,16 +6334,13 @@ static void rtl8153b_up(struct r8152 *tp + + static void rtl8153b_down(struct r8152 *tp) + { +- u32 ocp_data; +- + if (test_bit(RTL8152_INACCESSIBLE, &tp->flags)) { + rtl_drop_queued_tx(tp); + return; + } + +- ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL3); +- ocp_data |= PLA_MCU_SPDWN_EN; +- ocp_write_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL3, ocp_data); ++ ocp_word_set_bits(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL3, ++ PLA_MCU_SPDWN_EN); + + r8153b_u1u2en(tp, false); + r8153_u2p3en(tp, false); +@@ -6533,8 +6368,6 @@ static void rtl8153c_change_mtu(struct r + + static void rtl8153c_up(struct r8152 *tp) + { +- u32 ocp_data; +- + if (test_bit(RTL8152_INACCESSIBLE, &tp->flags)) + return; + +@@ -6545,26 +6378,18 @@ static void rtl8153c_up(struct r8152 *tp + rxdy_gated_en(tp, true); + r8153_teredo_off(tp); + +- ocp_data = ocp_read_dword(tp, MCU_TYPE_PLA, PLA_RCR); +- ocp_data &= ~RCR_ACPT_ALL; +- ocp_write_dword(tp, MCU_TYPE_PLA, PLA_RCR, ocp_data); ++ ocp_dword_clr_bits(tp, MCU_TYPE_PLA, PLA_RCR, RCR_ACPT_ALL); + + rtl8152_nic_reset(tp); + rtl_reset_bmu(tp); + +- ocp_data = ocp_read_byte(tp, MCU_TYPE_PLA, PLA_OOB_CTRL); +- ocp_data &= ~NOW_IS_OOB; +- ocp_write_byte(tp, MCU_TYPE_PLA, PLA_OOB_CTRL, ocp_data); +- +- ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_SFF_STS_7); +- ocp_data &= ~MCU_BORW_EN; +- ocp_write_word(tp, MCU_TYPE_PLA, PLA_SFF_STS_7, ocp_data); ++ ocp_byte_clr_bits(tp, MCU_TYPE_PLA, PLA_OOB_CTRL, NOW_IS_OOB); ++ ++ ocp_word_clr_bits(tp, MCU_TYPE_PLA, PLA_SFF_STS_7, MCU_BORW_EN); + + wait_oob_link_list_ready(tp); + +- ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_SFF_STS_7); +- ocp_data |= RE_INIT_LL; +- ocp_write_word(tp, MCU_TYPE_PLA, PLA_SFF_STS_7, ocp_data); ++ ocp_word_set_bits(tp, MCU_TYPE_PLA, PLA_SFF_STS_7, RE_INIT_LL); + + wait_oob_link_list_ready(tp); + +@@ -6584,15 +6409,12 @@ static void rtl8153c_up(struct r8152 *tp + + ocp_write_byte(tp, MCU_TYPE_PLA, PLA_CRWECR, CRWECR_CONFIG); + +- ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_CONFIG34); +- ocp_data |= BIT(8); +- ocp_write_word(tp, MCU_TYPE_PLA, PLA_CONFIG34, ocp_data); ++ ocp_word_set_bits(tp, MCU_TYPE_PLA, PLA_CONFIG34, BIT(8)); + + ocp_write_byte(tp, MCU_TYPE_PLA, PLA_CRWECR, CRWECR_NORAML); + +- ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL3); +- ocp_data &= ~PLA_MCU_SPDWN_EN; +- ocp_write_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL3, ocp_data); ++ ocp_word_clr_bits(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL3, ++ PLA_MCU_SPDWN_EN); + + r8153_aldps_en(tp, true); + r8153b_u1u2en(tp, true); +@@ -6614,8 +6436,6 @@ static void rtl8156_change_mtu(struct r8 + + static void rtl8156_up(struct r8152 *tp) + { +- u32 ocp_data; +- + if (test_bit(RTL8152_INACCESSIBLE, &tp->flags)) + return; + +@@ -6626,20 +6446,14 @@ static void rtl8156_up(struct r8152 *tp) + rxdy_gated_en(tp, true); + r8153_teredo_off(tp); + +- ocp_data = ocp_read_dword(tp, MCU_TYPE_PLA, PLA_RCR); +- ocp_data &= ~RCR_ACPT_ALL; +- ocp_write_dword(tp, MCU_TYPE_PLA, PLA_RCR, ocp_data); ++ ocp_dword_clr_bits(tp, MCU_TYPE_PLA, PLA_RCR, RCR_ACPT_ALL); + + rtl8152_nic_reset(tp); + rtl_reset_bmu(tp); + +- ocp_data = ocp_read_byte(tp, MCU_TYPE_PLA, PLA_OOB_CTRL); +- ocp_data &= ~NOW_IS_OOB; +- ocp_write_byte(tp, MCU_TYPE_PLA, PLA_OOB_CTRL, ocp_data); +- +- ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_SFF_STS_7); +- ocp_data &= ~MCU_BORW_EN; +- ocp_write_word(tp, MCU_TYPE_PLA, PLA_SFF_STS_7, ocp_data); ++ ocp_byte_clr_bits(tp, MCU_TYPE_PLA, PLA_OOB_CTRL, NOW_IS_OOB); ++ ++ 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); + +@@ -6649,27 +6463,21 @@ static void rtl8156_up(struct r8152 *tp) + case RTL_TEST_01: + case RTL_VER_10: + case RTL_VER_11: +- ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_BMU_CONFIG); +- ocp_data |= ACT_ODMA; +- ocp_write_word(tp, MCU_TYPE_USB, USB_BMU_CONFIG, ocp_data); ++ ocp_word_set_bits(tp, MCU_TYPE_USB, USB_BMU_CONFIG, ACT_ODMA); + break; + default: + break; + } + + /* share FIFO settings */ +- ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_RXFIFO_FULL); +- ocp_data &= ~RXFIFO_FULL_MASK; +- ocp_data |= 0x08; +- ocp_write_word(tp, MCU_TYPE_PLA, PLA_RXFIFO_FULL, ocp_data); +- +- ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL3); +- ocp_data &= ~PLA_MCU_SPDWN_EN; +- ocp_write_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL3, ocp_data); +- +- ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_SPEED_OPTION); +- ocp_data &= ~(RG_PWRDN_EN | ALL_SPEED_OFF); +- ocp_write_word(tp, MCU_TYPE_USB, USB_SPEED_OPTION, ocp_data); ++ ocp_word_w0w1(tp, MCU_TYPE_PLA, PLA_RXFIFO_FULL, RXFIFO_FULL_MASK, ++ 0x08); ++ ++ ocp_word_clr_bits(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL3, ++ PLA_MCU_SPDWN_EN); ++ ++ 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); + +@@ -6687,25 +6495,20 @@ static void rtl8156_up(struct r8152 *tp) + + static void rtl8156_down(struct r8152 *tp) + { +- u32 ocp_data; +- + if (test_bit(RTL8152_INACCESSIBLE, &tp->flags)) { + rtl_drop_queued_tx(tp); + return; + } + +- ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL3); +- ocp_data |= PLA_MCU_SPDWN_EN; +- ocp_write_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL3, ocp_data); ++ ocp_word_set_bits(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL3, ++ PLA_MCU_SPDWN_EN); + + r8153b_u1u2en(tp, false); + r8153_u2p3en(tp, false); + r8153b_power_cut_en(tp, false); + r8153_aldps_en(tp, false); + +- ocp_data = ocp_read_byte(tp, MCU_TYPE_PLA, PLA_OOB_CTRL); +- ocp_data &= ~NOW_IS_OOB; +- ocp_write_byte(tp, MCU_TYPE_PLA, PLA_OOB_CTRL, ocp_data); ++ 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); +@@ -6724,20 +6527,15 @@ static void rtl8156_down(struct r8152 *t + */ + ocp_write_word(tp, MCU_TYPE_PLA, PLA_TEREDO_WAKE_BASE, 0x00ff); + +- ocp_data = ocp_read_byte(tp, MCU_TYPE_PLA, PLA_OOB_CTRL); +- ocp_data |= NOW_IS_OOB; +- ocp_write_byte(tp, MCU_TYPE_PLA, PLA_OOB_CTRL, ocp_data); +- +- ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_SFF_STS_7); +- ocp_data |= MCU_BORW_EN; +- ocp_write_word(tp, MCU_TYPE_PLA, PLA_SFF_STS_7, ocp_data); ++ ocp_byte_set_bits(tp, MCU_TYPE_PLA, PLA_OOB_CTRL, NOW_IS_OOB); ++ ++ 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_data = ocp_read_dword(tp, MCU_TYPE_PLA, PLA_RCR); +- ocp_data |= RCR_APM | RCR_AM | RCR_AB; +- ocp_write_dword(tp, MCU_TYPE_PLA, PLA_RCR, ocp_data); ++ ocp_dword_set_bits(tp, MCU_TYPE_PLA, PLA_RCR, ++ RCR_APM | RCR_AM | RCR_AB); + + r8153_aldps_en(tp, true); + } +@@ -7014,11 +6812,7 @@ static int rtl8152_close(struct net_devi + + static void rtl_tally_reset(struct r8152 *tp) + { +- u32 ocp_data; +- +- ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_RSTTALLY); +- ocp_data |= TALLY_RESET; +- ocp_write_word(tp, MCU_TYPE_PLA, PLA_RSTTALLY, ocp_data); ++ ocp_word_set_bits(tp, MCU_TYPE_PLA, PLA_RSTTALLY, TALLY_RESET); + } + + static void r8152b_init(struct r8152 *tp) +@@ -7037,21 +6831,18 @@ static void r8152b_init(struct r8152 *tp + + r8152_aldps_en(tp, false); + +- if (tp->version == RTL_VER_01) { +- ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_LED_FEATURE); +- ocp_data &= ~LED_MODE_MASK; +- ocp_write_word(tp, MCU_TYPE_PLA, PLA_LED_FEATURE, ocp_data); +- } ++ if (tp->version == RTL_VER_01) ++ ocp_word_clr_bits(tp, MCU_TYPE_PLA, PLA_LED_FEATURE, ++ LED_MODE_MASK); + + r8152_power_cut_en(tp, false); + +- ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_PHY_PWR); +- ocp_data |= TX_10M_IDLE_EN | PFM_PWM_SWITCH; +- ocp_write_word(tp, MCU_TYPE_PLA, PLA_PHY_PWR, ocp_data); +- ocp_data = ocp_read_dword(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL); +- ocp_data &= ~MCU_CLK_RATIO_MASK; +- ocp_data |= MCU_CLK_RATIO | D3_CLK_GATED_EN; +- ocp_write_dword(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL, ocp_data); ++ ocp_word_set_bits(tp, MCU_TYPE_PLA, PLA_PHY_PWR, ++ TX_10M_IDLE_EN | PFM_PWM_SWITCH); ++ ++ ocp_dword_w0w1(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL, MCU_CLK_RATIO_MASK, ++ MCU_CLK_RATIO | D3_CLK_GATED_EN); ++ + ocp_data = GPHY_STS_MSK | SPEED_DOWN_MSK | + SPDWN_RXDV_MSK | SPDWN_LINKCHG_MSK; + ocp_write_word(tp, MCU_TYPE_PLA, PLA_GPHY_INTR_IMR, ocp_data); +@@ -7059,9 +6850,8 @@ static void r8152b_init(struct r8152 *tp + rtl_tally_reset(tp); + + /* enable rx aggregation */ +- ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_USB_CTRL); +- ocp_data &= ~(RX_AGG_DISABLE | RX_ZERO_EN); +- ocp_write_word(tp, MCU_TYPE_USB, USB_USB_CTRL, ocp_data); ++ ocp_word_clr_bits(tp, MCU_TYPE_USB, USB_USB_CTRL, ++ RX_AGG_DISABLE | RX_ZERO_EN); + } + + static void r8153_init(struct r8152 *tp) +@@ -7102,55 +6892,43 @@ static void r8153_init(struct r8152 *tp) + r8153_u2p3en(tp, false); + + if (tp->version == RTL_VER_04) { +- ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_SSPHYLINK2); +- ocp_data &= ~pwd_dn_scale_mask; +- ocp_data |= pwd_dn_scale(96); +- ocp_write_word(tp, MCU_TYPE_USB, USB_SSPHYLINK2, ocp_data); +- +- ocp_data = ocp_read_byte(tp, MCU_TYPE_USB, USB_USB2PHY); +- ocp_data |= USB2PHY_L1 | USB2PHY_SUSPEND; +- ocp_write_byte(tp, MCU_TYPE_USB, USB_USB2PHY, ocp_data); ++ ocp_word_w0w1(tp, MCU_TYPE_USB, USB_SSPHYLINK2, ++ pwd_dn_scale_mask, pwd_dn_scale(96)); ++ ++ ocp_byte_set_bits(tp, MCU_TYPE_USB, USB_USB2PHY, ++ USB2PHY_L1 | USB2PHY_SUSPEND); + } else if (tp->version == RTL_VER_05) { +- ocp_data = ocp_read_byte(tp, MCU_TYPE_PLA, PLA_DMY_REG0); +- ocp_data &= ~ECM_ALDPS; +- ocp_write_byte(tp, MCU_TYPE_PLA, PLA_DMY_REG0, ocp_data); ++ ocp_byte_clr_bits(tp, MCU_TYPE_PLA, PLA_DMY_REG0, ECM_ALDPS); + +- ocp_data = ocp_read_byte(tp, MCU_TYPE_USB, USB_CSR_DUMMY1); + if (ocp_read_word(tp, MCU_TYPE_USB, USB_BURST_SIZE) == 0) +- ocp_data &= ~DYNAMIC_BURST; ++ ocp_byte_clr_bits(tp, MCU_TYPE_USB, USB_CSR_DUMMY1, ++ DYNAMIC_BURST); + else +- ocp_data |= DYNAMIC_BURST; +- ocp_write_byte(tp, MCU_TYPE_USB, USB_CSR_DUMMY1, ocp_data); ++ ocp_byte_set_bits(tp, MCU_TYPE_USB, USB_CSR_DUMMY1, ++ DYNAMIC_BURST); + } else if (tp->version == RTL_VER_06) { +- ocp_data = ocp_read_byte(tp, MCU_TYPE_USB, USB_CSR_DUMMY1); + if (ocp_read_word(tp, MCU_TYPE_USB, USB_BURST_SIZE) == 0) +- ocp_data &= ~DYNAMIC_BURST; ++ ocp_byte_clr_bits(tp, MCU_TYPE_USB, USB_CSR_DUMMY1, ++ DYNAMIC_BURST); + else +- ocp_data |= DYNAMIC_BURST; +- ocp_write_byte(tp, MCU_TYPE_USB, USB_CSR_DUMMY1, ocp_data); ++ ocp_byte_set_bits(tp, MCU_TYPE_USB, USB_CSR_DUMMY1, ++ DYNAMIC_BURST); + + r8153_queue_wake(tp, false); + +- ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_EXTRA_STATUS); + if (rtl8152_get_speed(tp) & LINK_STATUS) +- ocp_data |= CUR_LINK_OK; ++ ocp_word_set_bits(tp, MCU_TYPE_PLA, PLA_EXTRA_STATUS, ++ CUR_LINK_OK | POLL_LINK_CHG); + else +- ocp_data &= ~CUR_LINK_OK; +- ocp_data |= POLL_LINK_CHG; +- ocp_write_word(tp, MCU_TYPE_PLA, PLA_EXTRA_STATUS, ocp_data); +- } +- +- ocp_data = ocp_read_byte(tp, MCU_TYPE_USB, USB_CSR_DUMMY2); +- ocp_data |= EP4_FULL_FC; +- ocp_write_byte(tp, MCU_TYPE_USB, USB_CSR_DUMMY2, ocp_data); +- +- ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_WDT11_CTRL); +- ocp_data &= ~TIMER11_EN; +- ocp_write_word(tp, MCU_TYPE_USB, USB_WDT11_CTRL, ocp_data); +- +- ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_LED_FEATURE); +- ocp_data &= ~LED_MODE_MASK; +- ocp_write_word(tp, MCU_TYPE_PLA, PLA_LED_FEATURE, ocp_data); ++ ocp_word_w0w1(tp, MCU_TYPE_PLA, PLA_EXTRA_STATUS, ++ CUR_LINK_OK, POLL_LINK_CHG); ++ } ++ ++ ocp_byte_set_bits(tp, MCU_TYPE_USB, USB_CSR_DUMMY2, EP4_FULL_FC); ++ ++ ocp_word_clr_bits(tp, MCU_TYPE_USB, USB_WDT11_CTRL, TIMER11_EN); ++ ++ ocp_word_clr_bits(tp, MCU_TYPE_PLA, PLA_LED_FEATURE, LED_MODE_MASK); + + ocp_data = FIFO_EMPTY_1FB | ROK_EXIT_LPM; + if (tp->version == RTL_VER_04 && tp->udev->speed < USB_SPEED_SUPER) +@@ -7159,10 +6937,8 @@ static void r8153_init(struct r8152 *tp) + ocp_data |= LPM_TIMER_500US; + ocp_write_byte(tp, MCU_TYPE_USB, USB_LPM_CTRL, ocp_data); + +- ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_AFE_CTRL2); +- ocp_data &= ~SEN_VAL_MASK; +- ocp_data |= SEN_VAL_NORMAL | SEL_RXIDLE; +- ocp_write_word(tp, MCU_TYPE_USB, USB_AFE_CTRL2, ocp_data); ++ ocp_word_w0w1(tp, MCU_TYPE_USB, USB_AFE_CTRL2, SEN_VAL_MASK, ++ SEN_VAL_NORMAL | SEL_RXIDLE); + + ocp_write_word(tp, MCU_TYPE_USB, USB_CONNECT_TIMER, 0x0001); + +@@ -7172,21 +6948,17 @@ static void r8153_init(struct r8152 *tp) + r8153_u1u2en(tp, true); + usb_enable_lpm(tp->udev); + +- ocp_data = ocp_read_byte(tp, MCU_TYPE_PLA, PLA_CONFIG6); +- ocp_data |= LANWAKE_CLR_EN; +- ocp_write_byte(tp, MCU_TYPE_PLA, PLA_CONFIG6, ocp_data); +- +- ocp_data = ocp_read_byte(tp, MCU_TYPE_PLA, PLA_LWAKE_CTRL_REG); +- ocp_data &= ~LANWAKE_PIN; +- ocp_write_byte(tp, MCU_TYPE_PLA, PLA_LWAKE_CTRL_REG, ocp_data); ++ ocp_byte_set_bits(tp, MCU_TYPE_PLA, PLA_CONFIG6, LANWAKE_CLR_EN); ++ ++ ocp_byte_clr_bits(tp, MCU_TYPE_PLA, PLA_LWAKE_CTRL_REG, LANWAKE_PIN); + + /* rx aggregation */ +- ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_USB_CTRL); +- ocp_data &= ~(RX_AGG_DISABLE | RX_ZERO_EN); + if (tp->dell_tb_rx_agg_bug) +- ocp_data |= RX_AGG_DISABLE; +- +- ocp_write_word(tp, MCU_TYPE_USB, USB_USB_CTRL, ocp_data); ++ ocp_word_w0w1(tp, MCU_TYPE_USB, USB_USB_CTRL, RX_ZERO_EN, ++ RX_AGG_DISABLE); ++ else ++ ocp_word_clr_bits(tp, MCU_TYPE_USB, USB_USB_CTRL, ++ RX_AGG_DISABLE | RX_ZERO_EN); + + rtl_tally_reset(tp); + +@@ -7206,7 +6978,6 @@ static void r8153_init(struct r8152 *tp) + + static void r8153b_init(struct r8152 *tp) + { +- u32 ocp_data; + u16 data; + int i; + +@@ -7245,13 +7016,12 @@ static void r8153b_init(struct r8152 *tp + r8153_queue_wake(tp, false); + rtl_runtime_suspend_enable(tp, false); + +- ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_EXTRA_STATUS); + if (rtl8152_get_speed(tp) & LINK_STATUS) +- ocp_data |= CUR_LINK_OK; ++ ocp_word_set_bits(tp, MCU_TYPE_PLA, PLA_EXTRA_STATUS, ++ CUR_LINK_OK | POLL_LINK_CHG); + else +- ocp_data &= ~CUR_LINK_OK; +- ocp_data |= 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); + + if (tp->udev->speed >= USB_SPEED_SUPER) + r8153b_u1u2en(tp, true); +@@ -7261,25 +7031,20 @@ static void r8153b_init(struct r8152 *tp + /* MAC clock speed down */ + r8153_mac_clk_speed_down(tp, true); + +- ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL3); +- ocp_data &= ~PLA_MCU_SPDWN_EN; +- ocp_write_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL3, ocp_data); ++ ocp_word_clr_bits(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL3, ++ PLA_MCU_SPDWN_EN); + +- if (tp->version == RTL_VER_09) { ++ if (tp->version == RTL_VER_09) + /* Disable Test IO for 32QFN */ +- if (ocp_read_byte(tp, MCU_TYPE_PLA, 0xdc00) & BIT(5)) { +- ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_PHY_PWR); +- ocp_data |= TEST_IO_OFF; +- ocp_write_word(tp, MCU_TYPE_PLA, PLA_PHY_PWR, ocp_data); +- } +- } ++ if (ocp_read_byte(tp, MCU_TYPE_PLA, 0xdc00) & BIT(5)) ++ ocp_word_set_bits(tp, MCU_TYPE_PLA, PLA_PHY_PWR, ++ TEST_IO_OFF); + + set_bit(GREEN_ETHERNET, &tp->flags); + + /* rx aggregation */ +- ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_USB_CTRL); +- ocp_data &= ~(RX_AGG_DISABLE | RX_ZERO_EN); +- ocp_write_word(tp, MCU_TYPE_USB, USB_USB_CTRL, ocp_data); ++ ocp_word_clr_bits(tp, MCU_TYPE_USB, USB_USB_CTRL, ++ RX_AGG_DISABLE | RX_ZERO_EN); + + rtl_tally_reset(tp); + +@@ -7288,7 +7053,6 @@ static void r8153b_init(struct r8152 *tp + + static void r8153c_init(struct r8152 *tp) + { +- u32 ocp_data; + u16 data; + int i; + +@@ -7299,12 +7063,10 @@ static void r8153c_init(struct r8152 *tp + + /* Disable spi_en */ + ocp_write_byte(tp, MCU_TYPE_PLA, PLA_CRWECR, CRWECR_CONFIG); +- ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_CONFIG5); +- ocp_data &= ~BIT(3); +- ocp_write_word(tp, MCU_TYPE_PLA, PLA_CONFIG5, ocp_data); +- ocp_data = ocp_read_word(tp, MCU_TYPE_USB, 0xcbf0); +- ocp_data |= BIT(1); +- ocp_write_word(tp, MCU_TYPE_USB, 0xcbf0, ocp_data); ++ ++ ocp_word_clr_bits(tp, MCU_TYPE_PLA, PLA_CONFIG5, BIT(3)); ++ ++ ocp_word_set_bits(tp, MCU_TYPE_USB, 0xcbf0, BIT(1)); + + for (i = 0; i < 500; i++) { + if (ocp_read_word(tp, MCU_TYPE_PLA, PLA_BOOT_CTRL) & +@@ -7336,14 +7098,12 @@ static void r8153c_init(struct r8152 *tp + r8153_queue_wake(tp, false); + rtl_runtime_suspend_enable(tp, false); + +- ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_EXTRA_STATUS); + if (rtl8152_get_speed(tp) & LINK_STATUS) +- ocp_data |= CUR_LINK_OK; ++ ocp_word_set_bits(tp, MCU_TYPE_PLA, PLA_EXTRA_STATUS, ++ CUR_LINK_OK | POLL_LINK_CHG); + else +- ocp_data &= ~CUR_LINK_OK; +- +- ocp_data |= 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); + + r8153b_u1u2en(tp, true); + +@@ -7352,16 +7112,13 @@ static void r8153c_init(struct r8152 *tp + /* MAC clock speed down */ + r8153_mac_clk_speed_down(tp, true); + +- ocp_data = ocp_read_byte(tp, MCU_TYPE_USB, USB_MISC_2); +- ocp_data &= ~BIT(7); +- ocp_write_byte(tp, MCU_TYPE_USB, USB_MISC_2, ocp_data); ++ ocp_byte_clr_bits(tp, MCU_TYPE_USB, USB_MISC_2, BIT(7)); + + set_bit(GREEN_ETHERNET, &tp->flags); + + /* rx aggregation */ +- ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_USB_CTRL); +- ocp_data &= ~(RX_AGG_DISABLE | RX_ZERO_EN); +- ocp_write_word(tp, MCU_TYPE_USB, USB_USB_CTRL, ocp_data); ++ ocp_word_clr_bits(tp, MCU_TYPE_USB, USB_USB_CTRL, ++ RX_AGG_DISABLE | RX_ZERO_EN); + + rtl_tally_reset(tp); + +@@ -7370,14 +7127,9 @@ static void r8153c_init(struct r8152 *tp + + static void r8156_hw_phy_cfg(struct r8152 *tp) + { +- u32 ocp_data; + u16 data; + +- ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_MISC_0); +- if (ocp_data & PCUT_STATUS) { +- ocp_data &= ~PCUT_STATUS; +- ocp_write_word(tp, MCU_TYPE_USB, USB_MISC_0, ocp_data); +- } ++ ocp_word_test_and_clr_bits(tp, MCU_TYPE_USB, USB_MISC_0, PCUT_STATUS); + + data = r8153_phy_status(tp, 0); + switch (data) { +@@ -7404,9 +7156,7 @@ static void r8156_hw_phy_cfg(struct r815 + data = r8153_phy_status(tp, PHY_STAT_LAN_ON); + WARN_ON_ONCE(data != PHY_STAT_LAN_ON); + +- ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_PHY_PWR); +- ocp_data |= PFM_PWM_SWITCH; +- ocp_write_word(tp, MCU_TYPE_PLA, PLA_PHY_PWR, ocp_data); ++ ocp_word_set_bits(tp, MCU_TYPE_PLA, PLA_PHY_PWR, PFM_PWM_SWITCH); + + switch (tp->version) { + case RTL_VER_10: +@@ -7567,9 +7317,8 @@ static void r8156_hw_phy_cfg(struct r815 + /* EEE parameter */ + ocp_write_word(tp, MCU_TYPE_PLA, PLA_EEE_TXTWSYS_2P5G, 0x0056); + +- ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_USB_CFG); +- ocp_data |= EN_XG_LIP | EN_G_LIP; +- ocp_write_word(tp, MCU_TYPE_PLA, PLA_USB_CFG, ocp_data); ++ ocp_word_set_bits(tp, MCU_TYPE_PLA, PLA_USB_CFG, ++ EN_XG_LIP | EN_G_LIP); + + sram_write(tp, 0x8257, 0x020f); /* XG PLL */ + sram_write(tp, 0x80ea, 0x7843); /* GIGA Master */ +@@ -7578,9 +7327,8 @@ static void r8156_hw_phy_cfg(struct r815 + return; + + /* Advance EEE */ +- ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL4); +- ocp_data |= EEE_SPDWN_EN; +- ocp_write_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL4, ocp_data); ++ ocp_word_set_bits(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL4, ++ EEE_SPDWN_EN); + + data = ocp_reg_read(tp, OCP_DOWN_SPEED); + data &= ~(EN_EEE_100 | EN_EEE_1000); +@@ -7720,7 +7468,6 @@ static void r8156_hw_phy_cfg(struct r815 + + static void r8156b_hw_phy_cfg(struct r8152 *tp) + { +- u32 ocp_data; + u16 data; + + switch (tp->version) { +@@ -7750,11 +7497,7 @@ static void r8156b_hw_phy_cfg(struct r81 + break; + } + +- ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_MISC_0); +- if (ocp_data & PCUT_STATUS) { +- ocp_data &= ~PCUT_STATUS; +- ocp_write_word(tp, MCU_TYPE_USB, USB_MISC_0, ocp_data); +- } ++ ocp_word_test_and_clr_bits(tp, MCU_TYPE_USB, USB_MISC_0, PCUT_STATUS); + + data = r8153_phy_status(tp, 0); + switch (data) { +@@ -7791,9 +7534,7 @@ static void r8156b_hw_phy_cfg(struct r81 + data = r8153_phy_status(tp, PHY_STAT_LAN_ON); + WARN_ON_ONCE(data != PHY_STAT_LAN_ON); + +- ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_PHY_PWR); +- ocp_data |= PFM_PWM_SWITCH; +- ocp_write_word(tp, MCU_TYPE_PLA, PLA_PHY_PWR, ocp_data); ++ ocp_word_set_bits(tp, MCU_TYPE_PLA, PLA_PHY_PWR, PFM_PWM_SWITCH); + + switch (tp->version) { + case RTL_VER_12: +@@ -7880,9 +7621,9 @@ static void r8156b_hw_phy_cfg(struct r81 + ocp_reg_write(tp, 0xb87c, 0x8fd8); + ocp_reg_write(tp, 0xb87e, 0xf600); + +- ocp_data = ocp_read_byte(tp, MCU_TYPE_PLA, PLA_USB_CFG); +- ocp_data |= EN_XG_LIP | EN_G_LIP; +- ocp_write_byte(tp, MCU_TYPE_PLA, PLA_USB_CFG, ocp_data); ++ ocp_byte_set_bits(tp, MCU_TYPE_PLA, PLA_USB_CFG, ++ EN_XG_LIP | EN_G_LIP); ++ + ocp_reg_write(tp, 0xb87c, 0x813d); + ocp_reg_write(tp, 0xb87e, 0x390e); + ocp_reg_write(tp, 0xb87c, 0x814f); +@@ -8096,9 +7837,7 @@ static void r8156b_hw_phy_cfg(struct r81 + if (rtl_phy_patch_request(tp, true, true)) + return; + +- ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL4); +- ocp_data |= EEE_SPDWN_EN; +- ocp_write_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL4, ocp_data); ++ ocp_word_set_bits(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL4, EEE_SPDWN_EN); + + data = ocp_reg_read(tp, OCP_DOWN_SPEED); + data &= ~(EN_EEE_100 | EN_EEE_1000); +@@ -8137,22 +7876,17 @@ static void r8156b_hw_phy_cfg(struct r81 + + static void r8156_init(struct r8152 *tp) + { +- u32 ocp_data; + u16 data; + int i; + + if (test_bit(RTL8152_INACCESSIBLE, &tp->flags)) + return; + +- ocp_data = ocp_read_byte(tp, MCU_TYPE_USB, USB_ECM_OP); +- ocp_data &= ~EN_ALL_SPEED; +- ocp_write_byte(tp, MCU_TYPE_USB, USB_ECM_OP, ocp_data); ++ ocp_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_data = ocp_read_word(tp, MCU_TYPE_USB, USB_ECM_OPTION); +- ocp_data |= BYPASS_MAC_RESET; +- ocp_write_word(tp, MCU_TYPE_USB, USB_ECM_OPTION, ocp_data); ++ ocp_word_set_bits(tp, MCU_TYPE_USB, USB_ECM_OPTION, BYPASS_MAC_RESET); + + r8153b_u1u2en(tp, false); + +@@ -8202,28 +7936,23 @@ static void r8156_init(struct r8152 *tp) + + r8156_mac_clk_spd(tp, true); + +- ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL3); +- ocp_data &= ~PLA_MCU_SPDWN_EN; +- ocp_write_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL3, ocp_data); ++ ocp_word_clr_bits(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL3, ++ PLA_MCU_SPDWN_EN); + +- ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_EXTRA_STATUS); + if (rtl8152_get_speed(tp) & LINK_STATUS) +- ocp_data |= CUR_LINK_OK; ++ ocp_word_set_bits(tp, MCU_TYPE_PLA, PLA_EXTRA_STATUS, ++ CUR_LINK_OK | POLL_LINK_CHG); + else +- ocp_data &= ~CUR_LINK_OK; +- ocp_data |= 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); + + set_bit(GREEN_ETHERNET, &tp->flags); + + /* rx aggregation */ +- ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_USB_CTRL); +- ocp_data &= ~(RX_AGG_DISABLE | RX_ZERO_EN); +- ocp_write_word(tp, MCU_TYPE_USB, USB_USB_CTRL, ocp_data); +- +- ocp_data = ocp_read_byte(tp, MCU_TYPE_USB, USB_BMU_CONFIG); +- ocp_data |= ACT_ODMA; +- ocp_write_byte(tp, MCU_TYPE_USB, USB_BMU_CONFIG, ocp_data); ++ 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); +@@ -8233,26 +7962,19 @@ static void r8156_init(struct r8152 *tp) + + static void r8156b_init(struct r8152 *tp) + { +- u32 ocp_data; + u16 data; + int i; + + if (test_bit(RTL8152_INACCESSIBLE, &tp->flags)) + return; + +- ocp_data = ocp_read_byte(tp, MCU_TYPE_USB, USB_ECM_OP); +- ocp_data &= ~EN_ALL_SPEED; +- ocp_write_byte(tp, MCU_TYPE_USB, USB_ECM_OP, ocp_data); ++ ocp_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_data = ocp_read_word(tp, MCU_TYPE_USB, USB_ECM_OPTION); +- ocp_data |= BYPASS_MAC_RESET; +- ocp_write_word(tp, MCU_TYPE_USB, USB_ECM_OPTION, ocp_data); +- +- ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_U2P3_CTRL); +- ocp_data |= RX_DETECT8; +- ocp_write_word(tp, MCU_TYPE_USB, USB_U2P3_CTRL, ocp_data); ++ ocp_word_set_bits(tp, MCU_TYPE_USB, USB_ECM_OPTION, BYPASS_MAC_RESET); ++ ++ ocp_word_set_bits(tp, MCU_TYPE_USB, USB_U2P3_CTRL, RX_DETECT8); + + r8153b_u1u2en(tp, false); + +@@ -8312,48 +8034,39 @@ static void r8156b_init(struct r8152 *tp + + usb_enable_lpm(tp->udev); + +- ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_RCR); +- ocp_data &= ~SLOT_EN; +- ocp_write_word(tp, MCU_TYPE_PLA, PLA_RCR, ocp_data); +- +- ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_CPCR); +- ocp_data |= FLOW_CTRL_EN; +- ocp_write_word(tp, MCU_TYPE_PLA, PLA_CPCR, ocp_data); ++ 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 = ocp_read_word(tp, MCU_TYPE_USB, USB_FW_CTRL); + if (!(ocp_read_word(tp, MCU_TYPE_PLA, PLA_POL_GPIO_CTRL) & DACK_DET_EN)) +- ocp_data |= FLOW_CTRL_PATCH_2; +- ocp_data &= ~AUTO_SPEEDUP; +- ocp_write_word(tp, MCU_TYPE_USB, USB_FW_CTRL, ocp_data); +- +- ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_FW_TASK); +- ocp_data |= FC_PATCH_TASK; +- ocp_write_word(tp, MCU_TYPE_USB, USB_FW_TASK, ocp_data); ++ ocp_word_w0w1(tp, MCU_TYPE_USB, USB_FW_CTRL, AUTO_SPEEDUP, ++ FLOW_CTRL_PATCH_2); ++ else ++ ocp_word_clr_bits(tp, MCU_TYPE_USB, USB_FW_CTRL, AUTO_SPEEDUP); ++ ++ ocp_word_set_bits(tp, MCU_TYPE_USB, USB_FW_TASK, FC_PATCH_TASK); + + r8156_mac_clk_spd(tp, true); + +- ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL3); +- ocp_data &= ~PLA_MCU_SPDWN_EN; +- ocp_write_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL3, ocp_data); ++ ocp_word_clr_bits(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL3, ++ PLA_MCU_SPDWN_EN); + +- ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_EXTRA_STATUS); + if (rtl8152_get_speed(tp) & LINK_STATUS) +- ocp_data |= CUR_LINK_OK; ++ ocp_word_set_bits(tp, MCU_TYPE_PLA, PLA_EXTRA_STATUS, ++ CUR_LINK_OK | POLL_LINK_CHG); + else +- ocp_data &= ~CUR_LINK_OK; +- ocp_data |= 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); + + set_bit(GREEN_ETHERNET, &tp->flags); + + /* rx aggregation */ +- ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_USB_CTRL); +- ocp_data &= ~(RX_AGG_DISABLE | RX_ZERO_EN); +- ocp_write_word(tp, MCU_TYPE_USB, USB_USB_CTRL, ocp_data); ++ ocp_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); diff --git a/target/linux/generic/backport-6.18/744-v7.1-r8152-add-helper-functions-for-PHY-OCP-registers.patch b/target/linux/generic/backport-6.18/744-v7.1-r8152-add-helper-functions-for-PHY-OCP-registers.patch new file mode 100644 index 00000000000..d0abdbef226 --- /dev/null +++ b/target/linux/generic/backport-6.18/744-v7.1-r8152-add-helper-functions-for-PHY-OCP-registers.patch @@ -0,0 +1,1127 @@ +From 7db154aa58e18bb663cc317f0b62631f8b3d2b87 Mon Sep 17 00:00:00 2001 +From: Chih Kai Hsu +Date: Thu, 26 Mar 2026 15:39:25 +0800 +Subject: [PATCH] r8152: add helper functions for PHY OCP registers + +Add the following bitwise operation functions for PHY OCP registers to +simplify the code. + +- ocp_reg_w0w1() +- ocp_reg_clr_bits() +- ocp_reg_set_bits() +- sram_write_w0w1() +- sram_clr_bits() +- sram_set_bits() +- r8152_mdio_clr_bit() +- r8152_mdio_set_bit() +- r8152_mdio_test_and_clr_bit() + +In addition, remove variable set but not used from r8153_init(), +r8153b_init() and r8153c_init(). + +Signed-off-by: Chih Kai Hsu +Reviewed-by: Hayes Wang +Link: https://patch.msgid.link/20260326073925.32976-456-nic_swsd@realtek.com +Signed-off-by: Paolo Abeni +--- + drivers/net/usb/r8152.c | 697 +++++++++++++--------------------------- + 1 file changed, 226 insertions(+), 471 deletions(-) + +--- a/drivers/net/usb/r8152.c ++++ b/drivers/net/usb/r8152.c +@@ -1732,6 +1732,71 @@ static void ocp_byte_set_bits(struct r81 + ocp_byte_w0w1(tp, type, index, 0, set); + } + ++static void ocp_reg_w0w1(struct r8152 *tp, u16 addr, u16 clear, u16 set) ++{ ++ u16 data; ++ ++ data = ocp_reg_read(tp, addr); ++ data = (data & ~clear) | set; ++ ocp_reg_write(tp, addr, data); ++} ++ ++static void ocp_reg_clr_bits(struct r8152 *tp, u16 addr, u16 clear) ++{ ++ ocp_reg_w0w1(tp, addr, clear, 0); ++} ++ ++static void ocp_reg_set_bits(struct r8152 *tp, u16 addr, u16 set) ++{ ++ ocp_reg_w0w1(tp, addr, 0, set); ++} ++ ++static void sram_write_w0w1(struct r8152 *tp, u16 addr, u16 clear, u16 set) ++{ ++ u16 data; ++ ++ data = sram_read(tp, addr); ++ data = (data & ~clear) | set; ++ ocp_reg_write(tp, OCP_SRAM_DATA, data); ++} ++ ++static void sram_clr_bits(struct r8152 *tp, u16 addr, u16 clear) ++{ ++ sram_write_w0w1(tp, addr, clear, 0); ++} ++ ++static void sram_set_bits(struct r8152 *tp, u16 addr, u16 set) ++{ ++ sram_write_w0w1(tp, addr, 0, set); ++} ++ ++static void r8152_mdio_clr_bit(struct r8152 *tp, u16 addr, u16 clear) ++{ ++ int data; ++ ++ data = r8152_mdio_read(tp, addr); ++ r8152_mdio_write(tp, addr, data & ~clear); ++} ++ ++static void r8152_mdio_set_bit(struct r8152 *tp, u16 addr, u16 set) ++{ ++ int data; ++ ++ data = r8152_mdio_read(tp, addr); ++ r8152_mdio_write(tp, addr, data | set); ++} ++ ++static int r8152_mdio_test_and_clr_bit(struct r8152 *tp, u16 addr, u16 clear) ++{ ++ int data; ++ ++ data = r8152_mdio_read(tp, addr); ++ if (data & clear) ++ r8152_mdio_write(tp, addr, data & ~clear); ++ ++ return data & clear; ++} ++ + static int + r8152_submit_rx(struct r8152 *tp, struct rx_agg *agg, gfp_t mem_flags); + +@@ -3746,14 +3811,10 @@ static void r8156_ups_flags(struct r8152 + + static void rtl_green_en(struct r8152 *tp, bool enable) + { +- u16 data; +- +- data = sram_read(tp, SRAM_GREEN_CFG); + if (enable) +- data |= GREEN_ETH_EN; ++ sram_set_bits(tp, SRAM_GREEN_CFG, GREEN_ETH_EN); + else +- data &= ~GREEN_ETH_EN; +- sram_write(tp, SRAM_GREEN_CFG, data); ++ sram_clr_bits(tp, SRAM_GREEN_CFG, GREEN_ETH_EN); + + tp->ups_info.green = enable; + } +@@ -4149,18 +4210,16 @@ static inline void rtl_reset_ocp_base(st + + static int rtl_phy_patch_request(struct r8152 *tp, bool request, bool wait) + { +- u16 data, check; ++ u16 check; + int i; + +- data = ocp_reg_read(tp, OCP_PHY_PATCH_CMD); + if (request) { +- data |= PATCH_REQUEST; ++ ocp_reg_set_bits(tp, OCP_PHY_PATCH_CMD, PATCH_REQUEST); + check = 0; + } else { +- data &= ~PATCH_REQUEST; ++ ocp_reg_clr_bits(tp, OCP_PHY_PATCH_CMD, PATCH_REQUEST); + check = PATCH_READY; + } +- ocp_reg_write(tp, OCP_PHY_PATCH_CMD, data); + + for (i = 0; wait && i < 5000; i++) { + u32 ocp_data; +@@ -4190,14 +4249,8 @@ static void rtl_patch_key_set(struct r81 + sram_write(tp, key_addr, patch_key); + sram_write(tp, SRAM_PHY_LOCK, PHY_PATCH_LOCK); + } else if (key_addr) { +- u16 data; +- + sram_write(tp, 0x0000, 0x0000); +- +- data = ocp_reg_read(tp, OCP_PHY_LOCK); +- data &= ~PATCH_LOCK; +- ocp_reg_write(tp, OCP_PHY_LOCK, data); +- ++ ocp_reg_clr_bits(tp, OCP_PHY_LOCK, PATCH_LOCK); + sram_write(tp, key_addr, 0x0000); + } else { + WARN_ON_ONCE(1); +@@ -5305,69 +5358,58 @@ static void r8152_mmd_write(struct r8152 + + static void r8152_eee_en(struct r8152 *tp, bool enable) + { +- u16 config1, config2, config3; +- +- config1 = ocp_reg_read(tp, OCP_EEE_CONFIG1) & ~sd_rise_time_mask; +- config2 = ocp_reg_read(tp, OCP_EEE_CONFIG2); +- config3 = ocp_reg_read(tp, OCP_EEE_CONFIG3) & ~fast_snr_mask; +- + if (enable) { + ocp_word_set_bits(tp, MCU_TYPE_PLA, PLA_EEE_CR, + EEE_RX_EN | EEE_TX_EN); +- config1 |= EEE_10_CAP | EEE_NWAY_EN | TX_QUIET_EN | RX_QUIET_EN; +- config1 |= sd_rise_time(1); +- config2 |= RG_DACQUIET_EN | RG_LDVQUIET_EN; +- config3 |= fast_snr(42); ++ ++ ocp_reg_w0w1(tp, OCP_EEE_CONFIG1, sd_rise_time_mask, ++ EEE_10_CAP | EEE_NWAY_EN | TX_QUIET_EN | ++ RX_QUIET_EN | sd_rise_time(1)); ++ ++ ocp_reg_set_bits(tp, OCP_EEE_CONFIG2, ++ RG_DACQUIET_EN | RG_LDVQUIET_EN); ++ ++ ocp_reg_w0w1(tp, OCP_EEE_CONFIG3, fast_snr_mask, fast_snr(42)); + } else { + ocp_word_clr_bits(tp, MCU_TYPE_PLA, PLA_EEE_CR, + EEE_RX_EN | EEE_TX_EN); +- config1 &= ~(EEE_10_CAP | EEE_NWAY_EN | TX_QUIET_EN | +- RX_QUIET_EN); +- config1 |= sd_rise_time(7); +- config2 &= ~(RG_DACQUIET_EN | RG_LDVQUIET_EN); +- config3 |= fast_snr(511); +- } + +- ocp_reg_write(tp, OCP_EEE_CONFIG1, config1); +- ocp_reg_write(tp, OCP_EEE_CONFIG2, config2); +- ocp_reg_write(tp, OCP_EEE_CONFIG3, config3); ++ ocp_reg_w0w1(tp, OCP_EEE_CONFIG1, sd_rise_time_mask | ++ EEE_10_CAP | EEE_NWAY_EN | TX_QUIET_EN | ++ RX_QUIET_EN, sd_rise_time(7)); ++ ++ ocp_reg_clr_bits(tp, OCP_EEE_CONFIG2, ++ RG_DACQUIET_EN | RG_LDVQUIET_EN); ++ ++ ocp_reg_w0w1(tp, OCP_EEE_CONFIG3, fast_snr_mask, fast_snr(511)); ++ } + } + + static void r8153_eee_en(struct r8152 *tp, bool enable) + { +- u16 config; +- +- config = ocp_reg_read(tp, OCP_EEE_CFG); +- + if (enable) { + ocp_word_set_bits(tp, MCU_TYPE_PLA, PLA_EEE_CR, + EEE_RX_EN | EEE_TX_EN); +- config |= EEE10_EN; ++ ++ ocp_reg_set_bits(tp, OCP_EEE_CFG, EEE10_EN); + } else { + ocp_word_clr_bits(tp, MCU_TYPE_PLA, PLA_EEE_CR, + EEE_RX_EN | EEE_TX_EN); +- config &= ~EEE10_EN; +- } + +- ocp_reg_write(tp, OCP_EEE_CFG, config); ++ ocp_reg_clr_bits(tp, OCP_EEE_CFG, EEE10_EN); ++ } + + tp->ups_info.eee = enable; + } + + static void r8156_eee_en(struct r8152 *tp, bool enable) + { +- u16 config; +- + r8153_eee_en(tp, enable); + +- config = ocp_reg_read(tp, OCP_EEE_ADV2); +- + if (enable && (tp->eee_adv2 & MDIO_EEE_2_5GT)) +- config |= MDIO_EEE_2_5GT; ++ ocp_reg_set_bits(tp, OCP_EEE_ADV2, MDIO_EEE_2_5GT); + else +- config &= ~MDIO_EEE_2_5GT; +- +- ocp_reg_write(tp, OCP_EEE_ADV2, config); ++ ocp_reg_clr_bits(tp, OCP_EEE_ADV2, MDIO_EEE_2_5GT); + } + + static void rtl_eee_enable(struct r8152 *tp, bool enable) +@@ -5420,11 +5462,8 @@ static void rtl_eee_enable(struct r8152 + + static void r8152b_enable_fc(struct r8152 *tp) + { +- u16 anar; +- +- anar = r8152_mdio_read(tp, MII_ADVERTISE); +- anar |= ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM; +- r8152_mdio_write(tp, MII_ADVERTISE, anar); ++ r8152_mdio_set_bit(tp, MII_ADVERTISE, ++ ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM); + + tp->ups_info.flow_control = true; + } +@@ -5680,17 +5719,12 @@ static int r8156a_post_firmware_1(struct + + static void r8153_aldps_en(struct r8152 *tp, bool enable) + { +- u16 data; +- +- data = ocp_reg_read(tp, OCP_POWER_CFG); + if (enable) { +- data |= EN_ALDPS; +- ocp_reg_write(tp, OCP_POWER_CFG, data); ++ ocp_reg_set_bits(tp, OCP_POWER_CFG, EN_ALDPS); + } else { + int i; + +- data &= ~EN_ALDPS; +- ocp_reg_write(tp, OCP_POWER_CFG, data); ++ ocp_reg_clr_bits(tp, OCP_POWER_CFG, EN_ALDPS); + for (i = 0; i < 20; i++) { + if (test_bit(RTL8152_INACCESSIBLE, &tp->flags)) + return; +@@ -5705,8 +5739,6 @@ static void r8153_aldps_en(struct r8152 + + static void r8153_hw_phy_cfg(struct r8152 *tp) + { +- u16 data; +- + /* disable ALDPS before updating the PHY parameters */ + r8153_aldps_en(tp, false); + +@@ -5715,22 +5747,14 @@ static void r8153_hw_phy_cfg(struct r815 + + rtl8152_apply_firmware(tp, false); + +- if (tp->version == RTL_VER_03) { +- data = ocp_reg_read(tp, OCP_EEE_CFG); +- data &= ~CTAP_SHORT_EN; +- ocp_reg_write(tp, OCP_EEE_CFG, data); +- } +- +- data = ocp_reg_read(tp, OCP_POWER_CFG); +- data |= EEE_CLKDIV_EN; +- ocp_reg_write(tp, OCP_POWER_CFG, data); +- +- data = ocp_reg_read(tp, OCP_DOWN_SPEED); +- data |= EN_10M_BGOFF; +- ocp_reg_write(tp, OCP_DOWN_SPEED, data); +- data = ocp_reg_read(tp, OCP_POWER_CFG); +- data |= EN_10M_PLLOFF; +- ocp_reg_write(tp, OCP_POWER_CFG, data); ++ if (tp->version == RTL_VER_03) ++ ocp_reg_clr_bits(tp, OCP_EEE_CFG, CTAP_SHORT_EN); ++ ++ ocp_reg_set_bits(tp, OCP_POWER_CFG, EEE_CLKDIV_EN); ++ ++ ocp_reg_set_bits(tp, OCP_DOWN_SPEED, EN_10M_BGOFF); ++ ++ ocp_reg_set_bits(tp, OCP_POWER_CFG, EN_10M_PLLOFF); + + sram_write(tp, SRAM_IMPEDANCE, 0x0b13); + +@@ -5798,9 +5822,7 @@ static void r8153b_hw_phy_cfg(struct r81 + case PHY_STAT_EXT_INIT: + rtl8152_apply_firmware(tp, true); + +- data = r8152_mdio_read(tp, MII_BMCR); +- data &= ~BMCR_PDOWN; +- r8152_mdio_write(tp, MII_BMCR, data); ++ r8152_mdio_clr_bit(tp, MII_BMCR, BMCR_PDOWN); + break; + case PHY_STAT_LAN_ON: + default: +@@ -5810,12 +5832,9 @@ static void r8153b_hw_phy_cfg(struct r81 + + r8153b_green_en(tp, test_bit(GREEN_ETHERNET, &tp->flags)); + +- data = sram_read(tp, SRAM_GREEN_CFG); +- data |= R_TUNE_EN; +- sram_write(tp, SRAM_GREEN_CFG, data); +- data = ocp_reg_read(tp, OCP_NCTL_CFG); +- data |= PGA_RETURN_EN; +- ocp_reg_write(tp, OCP_NCTL_CFG, data); ++ sram_set_bits(tp, SRAM_GREEN_CFG, R_TUNE_EN); ++ ++ ocp_reg_set_bits(tp, OCP_NCTL_CFG, PGA_RETURN_EN); + + /* ADC Bias Calibration: + * read efuse offset 0x7d to get a 17-bit data. Remove the dummy/fake +@@ -5845,14 +5864,11 @@ static void r8153b_hw_phy_cfg(struct r81 + + /* Advnace EEE */ + if (!rtl_phy_patch_request(tp, true, true)) { +- data = ocp_reg_read(tp, OCP_POWER_CFG); +- data |= EEE_CLKDIV_EN; +- ocp_reg_write(tp, OCP_POWER_CFG, data); ++ ocp_reg_set_bits(tp, OCP_POWER_CFG, EEE_CLKDIV_EN); + tp->ups_info.eee_ckdiv = true; + +- data = ocp_reg_read(tp, OCP_DOWN_SPEED); +- data |= EN_EEE_CMODE | EN_EEE_1000 | EN_10M_CLKDIV; +- ocp_reg_write(tp, OCP_DOWN_SPEED, data); ++ ocp_reg_set_bits(tp, OCP_DOWN_SPEED, ++ EN_EEE_CMODE | EN_EEE_1000 | EN_10M_CLKDIV); + tp->ups_info.eee_cmod_lv = true; + tp->ups_info._10m_ckdiv = true; + tp->ups_info.eee_plloff_giga = true; +@@ -6818,16 +6834,11 @@ static void rtl_tally_reset(struct r8152 + static void r8152b_init(struct r8152 *tp) + { + u32 ocp_data; +- u16 data; + + if (test_bit(RTL8152_INACCESSIBLE, &tp->flags)) + return; + +- data = r8152_mdio_read(tp, MII_BMCR); +- if (data & BMCR_PDOWN) { +- data &= ~BMCR_PDOWN; +- r8152_mdio_write(tp, MII_BMCR, data); +- } ++ r8152_mdio_test_and_clr_bit(tp, MII_BMCR, BMCR_PDOWN); + + r8152_aldps_en(tp, false); + +@@ -6857,7 +6868,6 @@ static void r8152b_init(struct r8152 *tp + static void r8153_init(struct r8152 *tp) + { + u32 ocp_data; +- u16 data; + int i; + + if (test_bit(RTL8152_INACCESSIBLE, &tp->flags)) +@@ -6875,19 +6885,15 @@ static void r8153_init(struct r8152 *tp) + break; + } + +- data = r8153_phy_status(tp, 0); ++ r8153_phy_status(tp, 0); + + if (tp->version == RTL_VER_03 || tp->version == RTL_VER_04 || + tp->version == RTL_VER_05) + ocp_reg_write(tp, OCP_ADC_CFG, CKADSEL_L | ADC_EN | EN_EMI_L); + +- data = r8152_mdio_read(tp, MII_BMCR); +- if (data & BMCR_PDOWN) { +- data &= ~BMCR_PDOWN; +- r8152_mdio_write(tp, MII_BMCR, data); +- } ++ r8152_mdio_test_and_clr_bit(tp, MII_BMCR, BMCR_PDOWN); + +- data = r8153_phy_status(tp, PHY_STAT_LAN_ON); ++ r8153_phy_status(tp, PHY_STAT_LAN_ON); + + r8153_u2p3en(tp, false); + +@@ -6978,7 +6984,6 @@ static void r8153_init(struct r8152 *tp) + + static void r8153b_init(struct r8152 *tp) + { +- u16 data; + int i; + + if (test_bit(RTL8152_INACCESSIBLE, &tp->flags)) +@@ -6996,15 +7001,11 @@ static void r8153b_init(struct r8152 *tp + break; + } + +- data = r8153_phy_status(tp, 0); ++ r8153_phy_status(tp, 0); + +- data = r8152_mdio_read(tp, MII_BMCR); +- if (data & BMCR_PDOWN) { +- data &= ~BMCR_PDOWN; +- r8152_mdio_write(tp, MII_BMCR, data); +- } ++ r8152_mdio_test_and_clr_bit(tp, MII_BMCR, BMCR_PDOWN); + +- data = r8153_phy_status(tp, PHY_STAT_LAN_ON); ++ r8153_phy_status(tp, PHY_STAT_LAN_ON); + + r8153_u2p3en(tp, false); + +@@ -7053,7 +7054,6 @@ static void r8153b_init(struct r8152 *tp + + static void r8153c_init(struct r8152 *tp) + { +- u16 data; + int i; + + if (test_bit(RTL8152_INACCESSIBLE, &tp->flags)) +@@ -7078,15 +7078,11 @@ static void r8153c_init(struct r8152 *tp + return; + } + +- data = r8153_phy_status(tp, 0); ++ r8153_phy_status(tp, 0); + +- data = r8152_mdio_read(tp, MII_BMCR); +- if (data & BMCR_PDOWN) { +- data &= ~BMCR_PDOWN; +- r8152_mdio_write(tp, MII_BMCR, data); +- } ++ r8152_mdio_test_and_clr_bit(tp, MII_BMCR, BMCR_PDOWN); + +- data = r8153_phy_status(tp, PHY_STAT_LAN_ON); ++ r8153_phy_status(tp, PHY_STAT_LAN_ON); + + r8153_u2p3en(tp, false); + +@@ -7136,9 +7132,7 @@ static void r8156_hw_phy_cfg(struct r815 + case PHY_STAT_EXT_INIT: + rtl8152_apply_firmware(tp, true); + +- data = ocp_reg_read(tp, 0xa468); +- data &= ~(BIT(3) | BIT(1)); +- ocp_reg_write(tp, 0xa468, data); ++ ocp_reg_clr_bits(tp, 0xa468, BIT(3) | BIT(1)); + break; + case PHY_STAT_LAN_ON: + case PHY_STAT_PWRDN: +@@ -7160,153 +7154,57 @@ static void r8156_hw_phy_cfg(struct r815 + + switch (tp->version) { + case RTL_VER_10: +- data = ocp_reg_read(tp, 0xad40); +- data &= ~0x3ff; +- data |= BIT(7) | BIT(2); +- ocp_reg_write(tp, 0xad40, data); +- +- data = ocp_reg_read(tp, 0xad4e); +- data |= BIT(4); +- ocp_reg_write(tp, 0xad4e, data); +- data = ocp_reg_read(tp, 0xad16); +- data &= ~0x3ff; +- data |= 0x6; +- ocp_reg_write(tp, 0xad16, data); +- data = ocp_reg_read(tp, 0xad32); +- data &= ~0x3f; +- data |= 6; +- ocp_reg_write(tp, 0xad32, data); +- data = ocp_reg_read(tp, 0xac08); +- data &= ~(BIT(12) | BIT(8)); +- ocp_reg_write(tp, 0xac08, data); +- data = ocp_reg_read(tp, 0xac8a); +- data |= BIT(12) | BIT(13) | BIT(14); +- data &= ~BIT(15); +- ocp_reg_write(tp, 0xac8a, data); +- data = ocp_reg_read(tp, 0xad18); +- data |= BIT(10); +- ocp_reg_write(tp, 0xad18, data); +- data = ocp_reg_read(tp, 0xad1a); +- data |= 0x3ff; +- ocp_reg_write(tp, 0xad1a, data); +- data = ocp_reg_read(tp, 0xad1c); +- data |= 0x3ff; +- ocp_reg_write(tp, 0xad1c, data); +- +- data = sram_read(tp, 0x80ea); +- data &= ~0xff00; +- data |= 0xc400; +- sram_write(tp, 0x80ea, data); +- data = sram_read(tp, 0x80eb); +- data &= ~0x0700; +- data |= 0x0300; +- sram_write(tp, 0x80eb, data); +- data = sram_read(tp, 0x80f8); +- data &= ~0xff00; +- data |= 0x1c00; +- sram_write(tp, 0x80f8, data); +- data = sram_read(tp, 0x80f1); +- data &= ~0xff00; +- data |= 0x3000; +- sram_write(tp, 0x80f1, data); +- +- data = sram_read(tp, 0x80fe); +- data &= ~0xff00; +- data |= 0xa500; +- sram_write(tp, 0x80fe, data); +- data = sram_read(tp, 0x8102); +- data &= ~0xff00; +- data |= 0x5000; +- sram_write(tp, 0x8102, data); +- data = sram_read(tp, 0x8015); +- data &= ~0xff00; +- data |= 0x3300; +- sram_write(tp, 0x8015, data); +- data = sram_read(tp, 0x8100); +- data &= ~0xff00; +- data |= 0x7000; +- sram_write(tp, 0x8100, data); +- data = sram_read(tp, 0x8014); +- data &= ~0xff00; +- data |= 0xf000; +- sram_write(tp, 0x8014, data); +- data = sram_read(tp, 0x8016); +- data &= ~0xff00; +- data |= 0x6500; +- sram_write(tp, 0x8016, data); +- data = sram_read(tp, 0x80dc); +- data &= ~0xff00; +- data |= 0xed00; +- sram_write(tp, 0x80dc, data); +- data = sram_read(tp, 0x80df); +- data |= BIT(8); +- sram_write(tp, 0x80df, data); +- data = sram_read(tp, 0x80e1); +- data &= ~BIT(8); +- sram_write(tp, 0x80e1, data); +- +- data = ocp_reg_read(tp, 0xbf06); +- data &= ~0x003f; +- data |= 0x0038; +- ocp_reg_write(tp, 0xbf06, data); ++ ocp_reg_w0w1(tp, 0xad40, 0x3ff, BIT(7) | BIT(2)); ++ ++ ocp_reg_set_bits(tp, 0xad4e, BIT(4)); ++ ocp_reg_w0w1(tp, 0xad16, 0x3ff, 0x6); ++ ocp_reg_w0w1(tp, 0xad32, 0x3f, 0x6); ++ ocp_reg_clr_bits(tp, 0xac08, BIT(12) | BIT(8)); ++ ocp_reg_w0w1(tp, 0xac8a, BIT(15), BIT(12) | BIT(13) | BIT(14)); ++ ocp_reg_set_bits(tp, 0xad18, BIT(10)); ++ ocp_reg_set_bits(tp, 0xad1a, 0x3ff); ++ ocp_reg_set_bits(tp, 0xad1c, 0x3ff); ++ ++ sram_write_w0w1(tp, 0x80ea, 0xff00, 0xc400); ++ sram_write_w0w1(tp, 0x80eb, 0x0700, 0x0300); ++ sram_write_w0w1(tp, 0x80f8, 0xff00, 0x1c00); ++ sram_write_w0w1(tp, 0x80f1, 0xff00, 0x3000); ++ ++ sram_write_w0w1(tp, 0x80fe, 0xff00, 0xa500); ++ sram_write_w0w1(tp, 0x8102, 0xff00, 0x5000); ++ sram_write_w0w1(tp, 0x8015, 0xff00, 0x3300); ++ sram_write_w0w1(tp, 0x8100, 0xff00, 0x7000); ++ sram_write_w0w1(tp, 0x8014, 0xff00, 0xf000); ++ sram_write_w0w1(tp, 0x8016, 0xff00, 0x6500); ++ sram_write_w0w1(tp, 0x80dc, 0xff00, 0xed00); ++ sram_set_bits(tp, 0x80df, BIT(8)); ++ sram_clr_bits(tp, 0x80e1, BIT(8)); ++ ++ ocp_reg_w0w1(tp, 0xbf06, 0x003f, 0x0038); + + sram_write(tp, 0x819f, 0xddb6); + + ocp_reg_write(tp, 0xbc34, 0x5555); +- data = ocp_reg_read(tp, 0xbf0a); +- data &= ~0x0e00; +- data |= 0x0a00; +- ocp_reg_write(tp, 0xbf0a, data); +- +- data = ocp_reg_read(tp, 0xbd2c); +- data &= ~BIT(13); +- ocp_reg_write(tp, 0xbd2c, data); ++ ocp_reg_w0w1(tp, 0xbf0a, 0x0e00, 0x0a00); ++ ++ ocp_reg_clr_bits(tp, 0xbd2c, BIT(13)); + break; + case RTL_VER_11: +- data = ocp_reg_read(tp, 0xad16); +- data |= 0x3ff; +- ocp_reg_write(tp, 0xad16, data); +- data = ocp_reg_read(tp, 0xad32); +- data &= ~0x3f; +- data |= 6; +- ocp_reg_write(tp, 0xad32, data); +- data = ocp_reg_read(tp, 0xac08); +- data &= ~(BIT(12) | BIT(8)); +- ocp_reg_write(tp, 0xac08, data); +- data = ocp_reg_read(tp, 0xacc0); +- data &= ~0x3; +- data |= BIT(1); +- ocp_reg_write(tp, 0xacc0, data); +- data = ocp_reg_read(tp, 0xad40); +- data &= ~0xe7; +- data |= BIT(6) | BIT(2); +- ocp_reg_write(tp, 0xad40, data); +- data = ocp_reg_read(tp, 0xac14); +- data &= ~BIT(7); +- ocp_reg_write(tp, 0xac14, data); +- data = ocp_reg_read(tp, 0xac80); +- data &= ~(BIT(8) | BIT(9)); +- ocp_reg_write(tp, 0xac80, data); +- data = ocp_reg_read(tp, 0xac5e); +- data &= ~0x7; +- data |= BIT(1); +- ocp_reg_write(tp, 0xac5e, data); ++ ocp_reg_set_bits(tp, 0xad16, 0x3ff); ++ ocp_reg_w0w1(tp, 0xad32, 0x3f, 0x6); ++ ocp_reg_clr_bits(tp, 0xac08, BIT(12) | BIT(8)); ++ ocp_reg_w0w1(tp, 0xacc0, 0x3, BIT(1)); ++ ocp_reg_w0w1(tp, 0xad40, 0xe7, BIT(6) | BIT(2)); ++ ocp_reg_clr_bits(tp, 0xac14, BIT(7)); ++ ocp_reg_clr_bits(tp, 0xac80, BIT(8) | BIT(9)); ++ ocp_reg_w0w1(tp, 0xac5e, 0x7, BIT(1)); + ocp_reg_write(tp, 0xad4c, 0x00a8); + ocp_reg_write(tp, 0xac5c, 0x01ff); +- data = ocp_reg_read(tp, 0xac8a); +- data &= ~0xf0; +- data |= BIT(4) | BIT(5); +- ocp_reg_write(tp, 0xac8a, data); ++ ocp_reg_w0w1(tp, 0xac8a, 0xf0, BIT(4) | BIT(5)); + ocp_reg_write(tp, 0xb87c, 0x8157); +- data = ocp_reg_read(tp, 0xb87e); +- data &= ~0xff00; +- data |= 0x0500; +- ocp_reg_write(tp, 0xb87e, data); ++ ocp_reg_w0w1(tp, 0xb87e, 0xff00, 0x0500); + ocp_reg_write(tp, 0xb87c, 0x8159); +- data = ocp_reg_read(tp, 0xb87e); +- data &= ~0xff00; +- data |= 0x0700; +- ocp_reg_write(tp, 0xb87e, data); ++ ocp_reg_w0w1(tp, 0xb87e, 0xff00, 0x0700); + + /* AAGC */ + ocp_reg_write(tp, 0xb87c, 0x80a2); +@@ -7330,17 +7228,13 @@ static void r8156_hw_phy_cfg(struct r815 + ocp_word_set_bits(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL4, + EEE_SPDWN_EN); + +- data = ocp_reg_read(tp, OCP_DOWN_SPEED); +- data &= ~(EN_EEE_100 | EN_EEE_1000); +- data |= EN_10M_CLKDIV; +- ocp_reg_write(tp, OCP_DOWN_SPEED, data); ++ ocp_reg_w0w1(tp, OCP_DOWN_SPEED, EN_EEE_100 | EN_EEE_1000, ++ EN_10M_CLKDIV); + tp->ups_info._10m_ckdiv = true; + tp->ups_info.eee_plloff_100 = false; + tp->ups_info.eee_plloff_giga = false; + +- data = ocp_reg_read(tp, OCP_POWER_CFG); +- data &= ~EEE_CLKDIV_EN; +- ocp_reg_write(tp, OCP_POWER_CFG, data); ++ ocp_reg_clr_bits(tp, OCP_POWER_CFG, EEE_CLKDIV_EN); + tp->ups_info.eee_ckdiv = false; + + ocp_reg_write(tp, OCP_SYSCLK_CFG, 0); +@@ -7350,34 +7244,19 @@ static void r8156_hw_phy_cfg(struct r815 + rtl_phy_patch_request(tp, false, true); + + /* enable ADC Ibias Cal */ +- data = ocp_reg_read(tp, 0xd068); +- data |= BIT(13); +- ocp_reg_write(tp, 0xd068, data); ++ ocp_reg_set_bits(tp, 0xd068, BIT(13)); + + /* enable Thermal Sensor */ +- data = sram_read(tp, 0x81a2); +- data &= ~BIT(8); +- sram_write(tp, 0x81a2, data); +- data = ocp_reg_read(tp, 0xb54c); +- data &= ~0xff00; +- data |= 0xdb00; +- ocp_reg_write(tp, 0xb54c, data); ++ sram_clr_bits(tp, 0x81a2, BIT(8)); ++ ocp_reg_w0w1(tp, 0xb54c, 0xff00, 0xdb00); + + /* Nway 2.5G Lite */ +- data = ocp_reg_read(tp, 0xa454); +- data &= ~BIT(0); +- ocp_reg_write(tp, 0xa454, data); ++ ocp_reg_clr_bits(tp, 0xa454, BIT(0)); + + /* CS DSP solution */ +- data = ocp_reg_read(tp, OCP_10GBT_CTRL); +- data |= RTL_ADV2_5G_F_R; +- ocp_reg_write(tp, OCP_10GBT_CTRL, data); +- data = ocp_reg_read(tp, 0xad4e); +- data &= ~BIT(4); +- ocp_reg_write(tp, 0xad4e, data); +- data = ocp_reg_read(tp, 0xa86a); +- data &= ~BIT(0); +- ocp_reg_write(tp, 0xa86a, data); ++ ocp_reg_set_bits(tp, OCP_10GBT_CTRL, RTL_ADV2_5G_F_R); ++ ocp_reg_clr_bits(tp, 0xad4e, BIT(4)); ++ ocp_reg_clr_bits(tp, 0xa86a, BIT(0)); + + /* MDI SWAP */ + if ((ocp_read_word(tp, MCU_TYPE_USB, USB_UPS_CFG) & MID_REVERSE) && +@@ -7438,9 +7317,7 @@ static void r8156_hw_phy_cfg(struct r815 + } + + /* Notify the MAC when the speed is changed to force mode. */ +- data = ocp_reg_read(tp, OCP_INTR_EN); +- data |= INTR_SPEED_FORCE; +- ocp_reg_write(tp, OCP_INTR_EN, data); ++ ocp_reg_set_bits(tp, OCP_INTR_EN, INTR_SPEED_FORCE); + break; + default: + break; +@@ -7448,12 +7325,8 @@ static void r8156_hw_phy_cfg(struct r815 + + rtl_green_en(tp, test_bit(GREEN_ETHERNET, &tp->flags)); + +- data = ocp_reg_read(tp, 0xa428); +- data &= ~BIT(9); +- ocp_reg_write(tp, 0xa428, data); +- data = ocp_reg_read(tp, 0xa5ea); +- data &= ~BIT(0); +- ocp_reg_write(tp, 0xa5ea, data); ++ ocp_reg_clr_bits(tp, 0xa428, BIT(9)); ++ ocp_reg_clr_bits(tp, 0xa5ea, BIT(0)); + tp->ups_info.lite_mode = 0; + + if (tp->eee_en) +@@ -7473,21 +7346,12 @@ static void r8156b_hw_phy_cfg(struct r81 + switch (tp->version) { + case RTL_VER_12: + ocp_reg_write(tp, 0xbf86, 0x9000); +- data = ocp_reg_read(tp, 0xc402); +- data |= BIT(10); +- ocp_reg_write(tp, 0xc402, data); +- data &= ~BIT(10); +- ocp_reg_write(tp, 0xc402, data); ++ ocp_reg_set_bits(tp, 0xc402, BIT(10)); ++ ocp_reg_clr_bits(tp, 0xc402, BIT(10)); + ocp_reg_write(tp, 0xbd86, 0x1010); + ocp_reg_write(tp, 0xbd88, 0x1010); +- data = ocp_reg_read(tp, 0xbd4e); +- data &= ~(BIT(10) | BIT(11)); +- data |= BIT(11); +- ocp_reg_write(tp, 0xbd4e, data); +- data = ocp_reg_read(tp, 0xbf46); +- data &= ~0xf00; +- data |= 0x700; +- ocp_reg_write(tp, 0xbf46, data); ++ ocp_reg_w0w1(tp, 0xbd4e, BIT(10) | BIT(11), BIT(11)); ++ ocp_reg_w0w1(tp, 0xbf46, 0xf00, 0x700); + break; + case RTL_VER_13: + case RTL_VER_15: +@@ -7504,13 +7368,8 @@ static void r8156b_hw_phy_cfg(struct r81 + case PHY_STAT_EXT_INIT: + rtl8152_apply_firmware(tp, true); + +- data = ocp_reg_read(tp, 0xa466); +- data &= ~BIT(0); +- ocp_reg_write(tp, 0xa466, data); +- +- data = ocp_reg_read(tp, 0xa468); +- data &= ~(BIT(3) | BIT(1)); +- ocp_reg_write(tp, 0xa468, data); ++ 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: +@@ -7519,11 +7378,7 @@ static void r8156b_hw_phy_cfg(struct r81 + break; + } + +- data = r8152_mdio_read(tp, MII_BMCR); +- if (data & BMCR_PDOWN) { +- data &= ~BMCR_PDOWN; +- r8152_mdio_write(tp, MII_BMCR, data); +- } ++ r8152_mdio_test_and_clr_bit(tp, MII_BMCR, BMCR_PDOWN); + + /* disable ALDPS before updating the PHY parameters */ + r8153_aldps_en(tp, false); +@@ -7538,21 +7393,12 @@ static void r8156b_hw_phy_cfg(struct r81 + + switch (tp->version) { + case RTL_VER_12: +- data = ocp_reg_read(tp, 0xbc08); +- data |= BIT(3) | BIT(2); +- ocp_reg_write(tp, 0xbc08, data); +- +- data = sram_read(tp, 0x8fff); +- data &= ~0xff00; +- data |= 0x0400; +- sram_write(tp, 0x8fff, data); +- +- data = ocp_reg_read(tp, 0xacda); +- data |= 0xff00; +- ocp_reg_write(tp, 0xacda, data); +- data = ocp_reg_read(tp, 0xacde); +- data |= 0xf000; +- ocp_reg_write(tp, 0xacde, data); ++ ocp_reg_set_bits(tp, 0xbc08, BIT(3) | BIT(2)); ++ ++ sram_write_w0w1(tp, 0x8fff, 0xff00, 0x0400); ++ ++ ocp_reg_set_bits(tp, 0xacda, 0xff00); ++ ocp_reg_set_bits(tp, 0xacde, 0xf000); + ocp_reg_write(tp, 0xac8c, 0x0ffc); + ocp_reg_write(tp, 0xac46, 0xb7b4); + ocp_reg_write(tp, 0xac50, 0x0fbc); +@@ -7630,21 +7476,15 @@ static void r8156b_hw_phy_cfg(struct r81 + ocp_reg_write(tp, 0xb87e, 0x790e); + ocp_reg_write(tp, 0xb87c, 0x80b0); + ocp_reg_write(tp, 0xb87e, 0x0f31); +- data = ocp_reg_read(tp, 0xbf4c); +- data |= BIT(1); +- ocp_reg_write(tp, 0xbf4c, data); +- data = ocp_reg_read(tp, 0xbcca); +- data |= BIT(9) | BIT(8); +- ocp_reg_write(tp, 0xbcca, data); ++ ocp_reg_set_bits(tp, 0xbf4c, BIT(1)); ++ ocp_reg_set_bits(tp, 0xbcca, BIT(9) | BIT(8)); + ocp_reg_write(tp, 0xb87c, 0x8141); + ocp_reg_write(tp, 0xb87e, 0x320e); + ocp_reg_write(tp, 0xb87c, 0x8153); + ocp_reg_write(tp, 0xb87e, 0x720e); + ocp_reg_write(tp, 0xb87c, 0x8529); + ocp_reg_write(tp, 0xb87e, 0x050e); +- data = ocp_reg_read(tp, OCP_EEE_CFG); +- data &= ~CTAP_SHORT_EN; +- ocp_reg_write(tp, OCP_EEE_CFG, data); ++ ocp_reg_clr_bits(tp, OCP_EEE_CFG, CTAP_SHORT_EN); + + sram_write(tp, 0x816c, 0xc4a0); + sram_write(tp, 0x8170, 0xc4a0); +@@ -7677,64 +7517,33 @@ static void r8156b_hw_phy_cfg(struct r81 + ocp_reg_write(tp, 0xb87c, 0x817b); + ocp_reg_write(tp, 0xb87e, 0x1d0a); + +- data = sram_read(tp, 0x8217); +- data &= ~0xff00; +- data |= 0x5000; +- sram_write(tp, 0x8217, data); +- data = sram_read(tp, 0x821a); +- data &= ~0xff00; +- data |= 0x5000; +- sram_write(tp, 0x821a, data); ++ sram_write_w0w1(tp, 0x8217, 0xff00, 0x5000); ++ sram_write_w0w1(tp, 0x821a, 0xff00, 0x5000); + sram_write(tp, 0x80da, 0x0403); +- data = sram_read(tp, 0x80dc); +- data &= ~0xff00; +- data |= 0x1000; +- sram_write(tp, 0x80dc, data); ++ sram_write_w0w1(tp, 0x80dc, 0xff00, 0x1000); + sram_write(tp, 0x80b3, 0x0384); + sram_write(tp, 0x80b7, 0x2007); +- data = sram_read(tp, 0x80ba); +- data &= ~0xff00; +- data |= 0x6c00; +- sram_write(tp, 0x80ba, data); ++ sram_write_w0w1(tp, 0x80ba, 0xff00, 0x6c00); + sram_write(tp, 0x80b5, 0xf009); +- data = sram_read(tp, 0x80bd); +- data &= ~0xff00; +- data |= 0x9f00; +- sram_write(tp, 0x80bd, data); ++ sram_write_w0w1(tp, 0x80bd, 0xff00, 0x9f00); + sram_write(tp, 0x80c7, 0xf083); + sram_write(tp, 0x80dd, 0x03f0); +- data = sram_read(tp, 0x80df); +- data &= ~0xff00; +- data |= 0x1000; +- sram_write(tp, 0x80df, data); ++ sram_write_w0w1(tp, 0x80df, 0xff00, 0x1000); + sram_write(tp, 0x80cb, 0x2007); +- data = sram_read(tp, 0x80ce); +- data &= ~0xff00; +- data |= 0x6c00; +- sram_write(tp, 0x80ce, data); ++ sram_write_w0w1(tp, 0x80ce, 0xff00, 0x6c00); + sram_write(tp, 0x80c9, 0x8009); +- data = sram_read(tp, 0x80d1); +- data &= ~0xff00; +- data |= 0x8000; +- sram_write(tp, 0x80d1, data); ++ sram_write_w0w1(tp, 0x80d1, 0xff00, 0x8000); + sram_write(tp, 0x80a3, 0x200a); + sram_write(tp, 0x80a5, 0xf0ad); + sram_write(tp, 0x809f, 0x6073); + sram_write(tp, 0x80a1, 0x000b); +- data = sram_read(tp, 0x80a9); +- data &= ~0xff00; +- data |= 0xc000; +- sram_write(tp, 0x80a9, data); ++ sram_write_w0w1(tp, 0x80a9, 0xff00, 0xc000); + + if (rtl_phy_patch_request(tp, true, true)) + return; + +- data = ocp_reg_read(tp, 0xb896); +- data &= ~BIT(0); +- ocp_reg_write(tp, 0xb896, data); +- data = ocp_reg_read(tp, 0xb892); +- data &= ~0xff00; +- ocp_reg_write(tp, 0xb892, data); ++ ocp_reg_clr_bits(tp, 0xb896, BIT(0)); ++ ocp_reg_clr_bits(tp, 0xb892, 0xff00); + ocp_reg_write(tp, 0xb88e, 0xc23e); + ocp_reg_write(tp, 0xb890, 0x0000); + ocp_reg_write(tp, 0xb88e, 0xc240); +@@ -7749,41 +7558,25 @@ static void r8156b_hw_phy_cfg(struct r81 + ocp_reg_write(tp, 0xb890, 0x1012); + ocp_reg_write(tp, 0xb88e, 0xc24a); + ocp_reg_write(tp, 0xb890, 0x1416); +- data = ocp_reg_read(tp, 0xb896); +- data |= BIT(0); +- ocp_reg_write(tp, 0xb896, data); ++ ocp_reg_set_bits(tp, 0xb896, BIT(0)); + + rtl_phy_patch_request(tp, false, true); + +- data = ocp_reg_read(tp, 0xa86a); +- data |= BIT(0); +- ocp_reg_write(tp, 0xa86a, data); +- data = ocp_reg_read(tp, 0xa6f0); +- data |= BIT(0); +- ocp_reg_write(tp, 0xa6f0, data); ++ ocp_reg_set_bits(tp, 0xa86a, BIT(0)); ++ ocp_reg_set_bits(tp, 0xa6f0, BIT(0)); + + ocp_reg_write(tp, 0xbfa0, 0xd70d); + ocp_reg_write(tp, 0xbfa2, 0x4100); + ocp_reg_write(tp, 0xbfa4, 0xe868); + ocp_reg_write(tp, 0xbfa6, 0xdc59); + ocp_reg_write(tp, 0xb54c, 0x3c18); +- data = ocp_reg_read(tp, 0xbfa4); +- data &= ~BIT(5); +- ocp_reg_write(tp, 0xbfa4, data); +- data = sram_read(tp, 0x817d); +- data |= BIT(12); +- sram_write(tp, 0x817d, data); ++ ocp_reg_clr_bits(tp, 0xbfa4, BIT(5)); ++ sram_set_bits(tp, 0x817d, BIT(12)); + break; + case RTL_VER_13: + /* 2.5G INRX */ +- data = ocp_reg_read(tp, 0xac46); +- data &= ~0x00f0; +- data |= 0x0090; +- ocp_reg_write(tp, 0xac46, data); +- data = ocp_reg_read(tp, 0xad30); +- data &= ~0x0003; +- data |= 0x0001; +- ocp_reg_write(tp, 0xad30, data); ++ ocp_reg_w0w1(tp, 0xac46, 0x00f0, 0x0090); ++ ocp_reg_w0w1(tp, 0xad30, 0x0003, 0x0001); + fallthrough; + case RTL_VER_15: + /* EEE parameter */ +@@ -7792,20 +7585,11 @@ static void r8156b_hw_phy_cfg(struct r81 + ocp_reg_write(tp, 0xb87c, 0x8107); + ocp_reg_write(tp, 0xb87e, 0x360e); + ocp_reg_write(tp, 0xb87c, 0x8551); +- data = ocp_reg_read(tp, 0xb87e); +- data &= ~0xff00; +- data |= 0x0800; +- ocp_reg_write(tp, 0xb87e, data); ++ ocp_reg_w0w1(tp, 0xb87e, 0xff00, 0x0800); + + /* ADC_PGA parameter */ +- data = ocp_reg_read(tp, 0xbf00); +- data &= ~0xe000; +- data |= 0xa000; +- ocp_reg_write(tp, 0xbf00, data); +- data = ocp_reg_read(tp, 0xbf46); +- data &= ~0x0f00; +- data |= 0x0300; +- ocp_reg_write(tp, 0xbf46, data); ++ ocp_reg_w0w1(tp, 0xbf00, 0xe000, 0xa000); ++ ocp_reg_w0w1(tp, 0xbf46, 0x0f00, 0x0300); + + /* Green Table-PGA, 1G full viterbi */ + sram_write(tp, 0x8044, 0x2417); +@@ -7820,48 +7604,35 @@ static void r8156b_hw_phy_cfg(struct r81 + sram_write(tp, 0x807a, 0x2417); + + /* XG PLL */ +- data = ocp_reg_read(tp, 0xbf84); +- data &= ~0xe000; +- data |= 0xa000; +- ocp_reg_write(tp, 0xbf84, data); ++ ocp_reg_w0w1(tp, 0xbf84, 0xe000, 0xa000); + break; + default: + break; + } + + /* Notify the MAC when the speed is changed to force mode. */ +- data = ocp_reg_read(tp, OCP_INTR_EN); +- data |= INTR_SPEED_FORCE; +- ocp_reg_write(tp, OCP_INTR_EN, data); ++ ocp_reg_set_bits(tp, OCP_INTR_EN, INTR_SPEED_FORCE); + + if (rtl_phy_patch_request(tp, true, true)) + return; + + ocp_word_set_bits(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL4, EEE_SPDWN_EN); + +- data = ocp_reg_read(tp, OCP_DOWN_SPEED); +- data &= ~(EN_EEE_100 | EN_EEE_1000); +- data |= EN_10M_CLKDIV; +- ocp_reg_write(tp, OCP_DOWN_SPEED, data); ++ ocp_reg_w0w1(tp, OCP_DOWN_SPEED, EN_EEE_100 | EN_EEE_1000, ++ EN_10M_CLKDIV); + tp->ups_info._10m_ckdiv = true; + tp->ups_info.eee_plloff_100 = false; + tp->ups_info.eee_plloff_giga = false; + +- data = ocp_reg_read(tp, OCP_POWER_CFG); +- data &= ~EEE_CLKDIV_EN; +- ocp_reg_write(tp, OCP_POWER_CFG, data); ++ ocp_reg_clr_bits(tp, OCP_POWER_CFG, EEE_CLKDIV_EN); + tp->ups_info.eee_ckdiv = false; + + rtl_phy_patch_request(tp, false, true); + + rtl_green_en(tp, test_bit(GREEN_ETHERNET, &tp->flags)); + +- data = ocp_reg_read(tp, 0xa428); +- data &= ~BIT(9); +- ocp_reg_write(tp, 0xa428, data); +- data = ocp_reg_read(tp, 0xa5ea); +- data &= ~BIT(0); +- ocp_reg_write(tp, 0xa5ea, data); ++ ocp_reg_clr_bits(tp, 0xa428, BIT(9)); ++ ocp_reg_clr_bits(tp, 0xa5ea, BIT(0)); + tp->ups_info.lite_mode = 0; + + if (tp->eee_en) +@@ -7901,17 +7672,10 @@ static void r8156_init(struct r8152 *tp) + } + + data = r8153_phy_status(tp, 0); +- if (data == PHY_STAT_EXT_INIT) { +- data = ocp_reg_read(tp, 0xa468); +- data &= ~(BIT(3) | BIT(1)); +- ocp_reg_write(tp, 0xa468, data); +- } ++ if (data == PHY_STAT_EXT_INIT) ++ ocp_reg_clr_bits(tp, 0xa468, BIT(3) | BIT(1)); + +- data = r8152_mdio_read(tp, MII_BMCR); +- if (data & BMCR_PDOWN) { +- data &= ~BMCR_PDOWN; +- r8152_mdio_write(tp, MII_BMCR, data); +- } ++ r8152_mdio_test_and_clr_bit(tp, MII_BMCR, BMCR_PDOWN); + + data = r8153_phy_status(tp, PHY_STAT_LAN_ON); + WARN_ON_ONCE(data != PHY_STAT_LAN_ON); +@@ -7999,20 +7763,11 @@ static void r8156b_init(struct r8152 *tp + + data = r8153_phy_status(tp, 0); + if (data == PHY_STAT_EXT_INIT) { +- data = ocp_reg_read(tp, 0xa468); +- data &= ~(BIT(3) | BIT(1)); +- ocp_reg_write(tp, 0xa468, data); +- +- data = ocp_reg_read(tp, 0xa466); +- data &= ~BIT(0); +- ocp_reg_write(tp, 0xa466, data); ++ ocp_reg_clr_bits(tp, 0xa468, BIT(3) | BIT(1)); ++ ocp_reg_clr_bits(tp, 0xa466, BIT(0)); + } + +- data = r8152_mdio_read(tp, MII_BMCR); +- if (data & BMCR_PDOWN) { +- data &= ~BMCR_PDOWN; +- r8152_mdio_write(tp, MII_BMCR, data); +- } ++ r8152_mdio_test_and_clr_bit(tp, MII_BMCR, BMCR_PDOWN); + + data = r8153_phy_status(tp, PHY_STAT_LAN_ON); + diff --git a/target/linux/generic/backport-6.18/745-v7.1-r8152-Add-helper-functions-for-SRAM2.patch b/target/linux/generic/backport-6.18/745-v7.1-r8152-Add-helper-functions-for-SRAM2.patch new file mode 100644 index 00000000000..c9d2b1c82d9 --- /dev/null +++ b/target/linux/generic/backport-6.18/745-v7.1-r8152-Add-helper-functions-for-SRAM2.patch @@ -0,0 +1,252 @@ +From 86f5dd4e0ff282a0acf1f058e947fd5f4ba58a9d Mon Sep 17 00:00:00 2001 +From: Chih Kai Hsu +Date: Wed, 1 Apr 2026 19:55:41 +0800 +Subject: [PATCH] r8152: Add helper functions for SRAM2 + +Add the following helper functions for SRAM2 access to simplify the code +and improve readability: + +- sram2_write() - write data to SRAM2 address +- sram2_read() - read data from SRAM2 address +- sram2_write_w0w1() - read-modify-write operation + +Signed-off-by: Chih Kai Hsu +Reviewed-by: Hayes Wang +Link: https://patch.msgid.link/20260401115542.34601-1-nic_swsd@realtek.com +Signed-off-by: Jakub Kicinski +--- + drivers/net/usb/r8152.c | 178 +++++++++++++++++----------------------- + 1 file changed, 75 insertions(+), 103 deletions(-) + +--- a/drivers/net/usb/r8152.c ++++ b/drivers/net/usb/r8152.c +@@ -219,6 +219,8 @@ + #define OCP_PHY_PATCH_STAT 0xb800 + #define OCP_PHY_PATCH_CMD 0xb820 + #define OCP_PHY_LOCK 0xb82e ++#define OCP_SRAM2_ADDR 0xb87c ++#define OCP_SRAM2_DATA 0xb87e + #define OCP_ADC_IOFFSET 0xbcfc + #define OCP_ADC_CFG 0xbc06 + #define OCP_SYSCLK_CFG 0xc416 +@@ -1770,6 +1772,27 @@ static void sram_set_bits(struct r8152 * + sram_write_w0w1(tp, addr, 0, set); + } + ++static void 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); ++} ++ ++static u16 sram2_read(struct r8152 *tp, u16 addr) ++{ ++ ocp_reg_write(tp, OCP_SRAM2_ADDR, addr); ++ return ocp_reg_read(tp, OCP_SRAM2_DATA); ++} ++ ++static void sram2_write_w0w1(struct r8152 *tp, u16 addr, u16 clear, u16 set) ++{ ++ u16 data; ++ ++ data = sram2_read(tp, addr); ++ data = (data & ~clear) | set; ++ ocp_reg_write(tp, OCP_SRAM2_DATA, data); ++} ++ + static void r8152_mdio_clr_bit(struct r8152 *tp, u16 addr, u16 clear) + { + int data; +@@ -7201,16 +7224,12 @@ static void r8156_hw_phy_cfg(struct r815 + ocp_reg_write(tp, 0xad4c, 0x00a8); + ocp_reg_write(tp, 0xac5c, 0x01ff); + ocp_reg_w0w1(tp, 0xac8a, 0xf0, BIT(4) | BIT(5)); +- ocp_reg_write(tp, 0xb87c, 0x8157); +- ocp_reg_w0w1(tp, 0xb87e, 0xff00, 0x0500); +- ocp_reg_write(tp, 0xb87c, 0x8159); +- ocp_reg_w0w1(tp, 0xb87e, 0xff00, 0x0700); ++ sram2_write_w0w1(tp, 0x8157, 0xff00, 0x0500); ++ sram2_write_w0w1(tp, 0x8159, 0xff00, 0x0700); + + /* AAGC */ +- ocp_reg_write(tp, 0xb87c, 0x80a2); +- ocp_reg_write(tp, 0xb87e, 0x0153); +- ocp_reg_write(tp, 0xb87c, 0x809c); +- ocp_reg_write(tp, 0xb87e, 0x0153); ++ sram2_write(tp, 0x80a2, 0x0153); ++ sram2_write(tp, 0x809c, 0x0153); + + /* EEE parameter */ + ocp_write_word(tp, MCU_TYPE_PLA, PLA_EEE_TXTWSYS_2P5G, 0x0056); +@@ -7408,82 +7427,48 @@ static void r8156b_hw_phy_cfg(struct r81 + ocp_reg_write(tp, 0xacc8, 0xa0d3); + ocp_reg_write(tp, 0xad08, 0x0007); + +- ocp_reg_write(tp, 0xb87c, 0x8560); +- ocp_reg_write(tp, 0xb87e, 0x19cc); +- ocp_reg_write(tp, 0xb87c, 0x8562); +- ocp_reg_write(tp, 0xb87e, 0x19cc); +- ocp_reg_write(tp, 0xb87c, 0x8564); +- ocp_reg_write(tp, 0xb87e, 0x19cc); +- ocp_reg_write(tp, 0xb87c, 0x8566); +- ocp_reg_write(tp, 0xb87e, 0x147d); +- ocp_reg_write(tp, 0xb87c, 0x8568); +- ocp_reg_write(tp, 0xb87e, 0x147d); +- ocp_reg_write(tp, 0xb87c, 0x856a); +- ocp_reg_write(tp, 0xb87e, 0x147d); +- ocp_reg_write(tp, 0xb87c, 0x8ffe); +- ocp_reg_write(tp, 0xb87e, 0x0907); +- ocp_reg_write(tp, 0xb87c, 0x80d6); +- ocp_reg_write(tp, 0xb87e, 0x2801); +- ocp_reg_write(tp, 0xb87c, 0x80f2); +- ocp_reg_write(tp, 0xb87e, 0x2801); +- ocp_reg_write(tp, 0xb87c, 0x80f4); +- ocp_reg_write(tp, 0xb87e, 0x6077); ++ sram2_write(tp, 0x8560, 0x19cc); ++ sram2_write(tp, 0x8562, 0x19cc); ++ sram2_write(tp, 0x8564, 0x19cc); ++ sram2_write(tp, 0x8566, 0x147d); ++ sram2_write(tp, 0x8568, 0x147d); ++ sram2_write(tp, 0x856a, 0x147d); ++ sram2_write(tp, 0x8ffe, 0x0907); ++ sram2_write(tp, 0x80d6, 0x2801); ++ sram2_write(tp, 0x80f2, 0x2801); ++ sram2_write(tp, 0x80f4, 0x6077); + ocp_reg_write(tp, 0xb506, 0x01e7); + +- ocp_reg_write(tp, 0xb87c, 0x8013); +- ocp_reg_write(tp, 0xb87e, 0x0700); +- ocp_reg_write(tp, 0xb87c, 0x8fb9); +- ocp_reg_write(tp, 0xb87e, 0x2801); +- ocp_reg_write(tp, 0xb87c, 0x8fba); +- ocp_reg_write(tp, 0xb87e, 0x0100); +- ocp_reg_write(tp, 0xb87c, 0x8fbc); +- ocp_reg_write(tp, 0xb87e, 0x1900); +- ocp_reg_write(tp, 0xb87c, 0x8fbe); +- ocp_reg_write(tp, 0xb87e, 0xe100); +- ocp_reg_write(tp, 0xb87c, 0x8fc0); +- ocp_reg_write(tp, 0xb87e, 0x0800); +- ocp_reg_write(tp, 0xb87c, 0x8fc2); +- ocp_reg_write(tp, 0xb87e, 0xe500); +- ocp_reg_write(tp, 0xb87c, 0x8fc4); +- ocp_reg_write(tp, 0xb87e, 0x0f00); +- ocp_reg_write(tp, 0xb87c, 0x8fc6); +- ocp_reg_write(tp, 0xb87e, 0xf100); +- ocp_reg_write(tp, 0xb87c, 0x8fc8); +- ocp_reg_write(tp, 0xb87e, 0x0400); +- ocp_reg_write(tp, 0xb87c, 0x8fca); +- ocp_reg_write(tp, 0xb87e, 0xf300); +- ocp_reg_write(tp, 0xb87c, 0x8fcc); +- ocp_reg_write(tp, 0xb87e, 0xfd00); +- ocp_reg_write(tp, 0xb87c, 0x8fce); +- ocp_reg_write(tp, 0xb87e, 0xff00); +- ocp_reg_write(tp, 0xb87c, 0x8fd0); +- ocp_reg_write(tp, 0xb87e, 0xfb00); +- ocp_reg_write(tp, 0xb87c, 0x8fd2); +- ocp_reg_write(tp, 0xb87e, 0x0100); +- ocp_reg_write(tp, 0xb87c, 0x8fd4); +- ocp_reg_write(tp, 0xb87e, 0xf400); +- ocp_reg_write(tp, 0xb87c, 0x8fd6); +- ocp_reg_write(tp, 0xb87e, 0xff00); +- ocp_reg_write(tp, 0xb87c, 0x8fd8); +- ocp_reg_write(tp, 0xb87e, 0xf600); ++ sram2_write(tp, 0x8013, 0x0700); ++ sram2_write(tp, 0x8fb9, 0x2801); ++ sram2_write(tp, 0x8fba, 0x0100); ++ sram2_write(tp, 0x8fbc, 0x1900); ++ sram2_write(tp, 0x8fbe, 0xe100); ++ sram2_write(tp, 0x8fc0, 0x0800); ++ sram2_write(tp, 0x8fc2, 0xe500); ++ sram2_write(tp, 0x8fc4, 0x0f00); ++ sram2_write(tp, 0x8fc6, 0xf100); ++ sram2_write(tp, 0x8fc8, 0x0400); ++ sram2_write(tp, 0x8fca, 0xf300); ++ sram2_write(tp, 0x8fcc, 0xfd00); ++ sram2_write(tp, 0x8fce, 0xff00); ++ sram2_write(tp, 0x8fd0, 0xfb00); ++ sram2_write(tp, 0x8fd2, 0x0100); ++ sram2_write(tp, 0x8fd4, 0xf400); ++ sram2_write(tp, 0x8fd6, 0xff00); ++ sram2_write(tp, 0x8fd8, 0xf600); + + ocp_byte_set_bits(tp, MCU_TYPE_PLA, PLA_USB_CFG, + EN_XG_LIP | EN_G_LIP); + +- ocp_reg_write(tp, 0xb87c, 0x813d); +- ocp_reg_write(tp, 0xb87e, 0x390e); +- ocp_reg_write(tp, 0xb87c, 0x814f); +- ocp_reg_write(tp, 0xb87e, 0x790e); +- ocp_reg_write(tp, 0xb87c, 0x80b0); +- ocp_reg_write(tp, 0xb87e, 0x0f31); ++ sram2_write(tp, 0x813d, 0x390e); ++ sram2_write(tp, 0x814f, 0x790e); ++ sram2_write(tp, 0x80b0, 0x0f31); + ocp_reg_set_bits(tp, 0xbf4c, BIT(1)); + ocp_reg_set_bits(tp, 0xbcca, BIT(9) | BIT(8)); +- ocp_reg_write(tp, 0xb87c, 0x8141); +- ocp_reg_write(tp, 0xb87e, 0x320e); +- ocp_reg_write(tp, 0xb87c, 0x8153); +- ocp_reg_write(tp, 0xb87e, 0x720e); +- ocp_reg_write(tp, 0xb87c, 0x8529); +- ocp_reg_write(tp, 0xb87e, 0x050e); ++ sram2_write(tp, 0x8141, 0x320e); ++ sram2_write(tp, 0x8153, 0x720e); ++ sram2_write(tp, 0x8529, 0x050e); + ocp_reg_clr_bits(tp, OCP_EEE_CFG, CTAP_SHORT_EN); + + sram_write(tp, 0x816c, 0xc4a0); +@@ -7495,27 +7480,17 @@ static void r8156b_hw_phy_cfg(struct r81 + sram_write(tp, 0x8ff1, 0x0404); + + ocp_reg_write(tp, 0xbf4a, 0x001b); +- ocp_reg_write(tp, 0xb87c, 0x8033); +- ocp_reg_write(tp, 0xb87e, 0x7c13); +- ocp_reg_write(tp, 0xb87c, 0x8037); +- ocp_reg_write(tp, 0xb87e, 0x7c13); +- ocp_reg_write(tp, 0xb87c, 0x803b); +- ocp_reg_write(tp, 0xb87e, 0xfc32); +- ocp_reg_write(tp, 0xb87c, 0x803f); +- ocp_reg_write(tp, 0xb87e, 0x7c13); +- ocp_reg_write(tp, 0xb87c, 0x8043); +- ocp_reg_write(tp, 0xb87e, 0x7c13); +- ocp_reg_write(tp, 0xb87c, 0x8047); +- ocp_reg_write(tp, 0xb87e, 0x7c13); +- +- ocp_reg_write(tp, 0xb87c, 0x8145); +- ocp_reg_write(tp, 0xb87e, 0x370e); +- ocp_reg_write(tp, 0xb87c, 0x8157); +- ocp_reg_write(tp, 0xb87e, 0x770e); +- ocp_reg_write(tp, 0xb87c, 0x8169); +- ocp_reg_write(tp, 0xb87e, 0x0d0a); +- ocp_reg_write(tp, 0xb87c, 0x817b); +- ocp_reg_write(tp, 0xb87e, 0x1d0a); ++ sram2_write(tp, 0x8033, 0x7c13); ++ sram2_write(tp, 0x8037, 0x7c13); ++ sram2_write(tp, 0x803b, 0xfc32); ++ sram2_write(tp, 0x803f, 0x7c13); ++ sram2_write(tp, 0x8043, 0x7c13); ++ sram2_write(tp, 0x8047, 0x7c13); ++ ++ sram2_write(tp, 0x8145, 0x370e); ++ sram2_write(tp, 0x8157, 0x770e); ++ sram2_write(tp, 0x8169, 0x0d0a); ++ sram2_write(tp, 0x817b, 0x1d0a); + + sram_write_w0w1(tp, 0x8217, 0xff00, 0x5000); + sram_write_w0w1(tp, 0x821a, 0xff00, 0x5000); +@@ -7580,12 +7555,9 @@ static void r8156b_hw_phy_cfg(struct r81 + fallthrough; + case RTL_VER_15: + /* EEE parameter */ +- ocp_reg_write(tp, 0xb87c, 0x80f5); +- ocp_reg_write(tp, 0xb87e, 0x760e); +- ocp_reg_write(tp, 0xb87c, 0x8107); +- ocp_reg_write(tp, 0xb87e, 0x360e); +- ocp_reg_write(tp, 0xb87c, 0x8551); +- ocp_reg_w0w1(tp, 0xb87e, 0xff00, 0x0800); ++ sram2_write(tp, 0x80f5, 0x760e); ++ sram2_write(tp, 0x8107, 0x360e); ++ sram2_write_w0w1(tp, 0x8551, 0xff00, 0x0800); + + /* ADC_PGA parameter */ + ocp_reg_w0w1(tp, 0xbf00, 0xe000, 0xa000); diff --git a/target/linux/generic/backport-6.18/746-v7.1-r8152-Add-support-for-5Gbit-Link-Speeds-and-EEE.patch b/target/linux/generic/backport-6.18/746-v7.1-r8152-Add-support-for-5Gbit-Link-Speeds-and-EEE.patch new file mode 100644 index 00000000000..49bac39bcfa --- /dev/null +++ b/target/linux/generic/backport-6.18/746-v7.1-r8152-Add-support-for-5Gbit-Link-Speeds-and-EEE.patch @@ -0,0 +1,235 @@ +From ebe5fd2ed20af5ae176dd41dd4a85a3cdc738b8a Mon Sep 17 00:00:00 2001 +From: Birger Koblitz +Date: Sat, 4 Apr 2026 09:57:42 +0200 +Subject: [PATCH] r8152: Add support for 5Gbit Link Speeds and EEE + +The RTL8157 supports 5GBit Link speeds. Add support for this speed +in the setup and setting/getting through ethtool. Also add 5GBit EEE. +Add functionality for setup and ethtool get/set methods. + +Signed-off-by: Birger Koblitz +Link: https://patch.msgid.link/20260404-rtl8157_next-v7-1-039121318f23@birger-koblitz.de +Signed-off-by: Paolo Abeni +--- + drivers/net/usb/r8152.c | 100 ++++++++++++++++++++++++++++++++-------- + 1 file changed, 82 insertions(+), 18 deletions(-) + +--- a/drivers/net/usb/r8152.c ++++ b/drivers/net/usb/r8152.c +@@ -612,6 +612,7 @@ enum spd_duplex { + FORCE_100M_FULL, + FORCE_1000M_FULL, + NWAY_2500M_FULL, ++ NWAY_5000M_FULL, + }; + + /* OCP_ALDPS_CONFIG */ +@@ -733,6 +734,7 @@ enum spd_duplex { + #define BP4_SUPER_ONLY 0x1578 /* RTL_VER_04 only */ + + enum rtl_register_content { ++ _5000bps = BIT(12), + _2500bps = BIT(10), + _1250bps = BIT(9), + _500bps = BIT(8), +@@ -746,6 +748,7 @@ enum rtl_register_content { + }; + + #define is_speed_2500(_speed) (((_speed) & (_2500bps | LINK_STATUS)) == (_2500bps | LINK_STATUS)) ++#define is_speed_5000(_speed) (((_speed) & (_5000bps | LINK_STATUS)) == (_5000bps | LINK_STATUS)) + #define is_flow_control(_speed) (((_speed) & (_tx_flow | _rx_flow)) == (_tx_flow | _rx_flow)) + + #define RTL8152_MAX_TX 4 +@@ -952,6 +955,7 @@ struct r8152 { + unsigned int pipe_in, pipe_out, pipe_intr, pipe_ctrl_in, pipe_ctrl_out; + + u32 support_2500full:1; ++ u32 support_5000full:1; + u32 lenovo_macpassthru:1; + u32 dell_tb_rx_agg_bug:1; + u16 ocp_base; +@@ -1202,6 +1206,7 @@ enum tx_csum_stat { + #define RTL_ADVERTISED_1000_HALF BIT(4) + #define RTL_ADVERTISED_1000_FULL BIT(5) + #define RTL_ADVERTISED_2500_FULL BIT(6) ++#define RTL_ADVERTISED_5000_FULL BIT(7) + + /* Maximum number of multicast addresses to filter (vs. Rx-all-multicast). + * The RTL chips use a 64 element hash table based on the Ethernet CRC. +@@ -5427,12 +5432,23 @@ static void r8153_eee_en(struct r8152 *t + + static void r8156_eee_en(struct r8152 *tp, bool enable) + { ++ u16 config; ++ + r8153_eee_en(tp, enable); + ++ config = ocp_reg_read(tp, OCP_EEE_ADV2); ++ + if (enable && (tp->eee_adv2 & MDIO_EEE_2_5GT)) +- ocp_reg_set_bits(tp, OCP_EEE_ADV2, MDIO_EEE_2_5GT); ++ config |= MDIO_EEE_2_5GT; + else +- ocp_reg_clr_bits(tp, OCP_EEE_ADV2, MDIO_EEE_2_5GT); ++ config &= ~MDIO_EEE_2_5GT; ++ ++ if (enable && (tp->eee_adv2 & MDIO_EEE_5GT)) ++ config |= MDIO_EEE_5GT; ++ else ++ config &= ~MDIO_EEE_5GT; ++ ++ ocp_reg_write(tp, OCP_EEE_ADV2, config); + } + + static void rtl_eee_enable(struct r8152 *tp, bool enable) +@@ -6196,9 +6212,13 @@ static int rtl8152_set_speed(struct r815 + + if (tp->support_2500full) + support |= RTL_ADVERTISED_2500_FULL; ++ ++ if (tp->support_5000full) ++ support |= RTL_ADVERTISED_5000_FULL; + } + +- if (!(advertising & support)) ++ advertising &= support; ++ if (!advertising) + return -EINVAL; + + orig = r8152_mdio_read(tp, MII_ADVERTISE); +@@ -6241,15 +6261,20 @@ static int rtl8152_set_speed(struct r815 + r8152_mdio_write(tp, MII_CTRL1000, new1); + } + +- if (tp->support_2500full) { ++ if (tp->support_2500full || tp->support_5000full) { + orig = ocp_reg_read(tp, OCP_10GBT_CTRL); +- new1 = orig & ~MDIO_AN_10GBT_CTRL_ADV2_5G; ++ new1 = orig & ~(MDIO_AN_10GBT_CTRL_ADV2_5G | MDIO_AN_10GBT_CTRL_ADV5G); + + if (advertising & RTL_ADVERTISED_2500_FULL) { + new1 |= MDIO_AN_10GBT_CTRL_ADV2_5G; + tp->ups_info.speed_duplex = NWAY_2500M_FULL; + } + ++ if (advertising & RTL_ADVERTISED_5000_FULL) { ++ new1 |= MDIO_AN_10GBT_CTRL_ADV5G; ++ tp->ups_info.speed_duplex = NWAY_5000M_FULL; ++ } ++ + if (orig != new1) + ocp_reg_write(tp, OCP_10GBT_CTRL, new1); + } +@@ -8227,17 +8252,38 @@ int rtl8152_get_link_ksettings(struct ne + linkmode_mod_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT, + cmd->link_modes.supported, tp->support_2500full); + +- if (tp->support_2500full) { +- linkmode_mod_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT, +- cmd->link_modes.advertising, +- ocp_reg_read(tp, OCP_10GBT_CTRL) & MDIO_AN_10GBT_CTRL_ADV2_5G); +- +- linkmode_mod_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT, +- cmd->link_modes.lp_advertising, +- ocp_reg_read(tp, OCP_10GBT_STAT) & MDIO_AN_10GBT_STAT_LP2_5G); ++ linkmode_mod_bit(ETHTOOL_LINK_MODE_5000baseT_Full_BIT, ++ cmd->link_modes.supported, tp->support_5000full); ++ ++ if (tp->support_2500full || tp->support_5000full) { ++ u16 ocp_10gbt_ctrl = ocp_reg_read(tp, OCP_10GBT_CTRL); ++ u16 ocp_10gbt_stat = ocp_reg_read(tp, OCP_10GBT_STAT); ++ ++ if (tp->support_2500full) { ++ linkmode_mod_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT, ++ cmd->link_modes.advertising, ++ ocp_10gbt_ctrl & MDIO_AN_10GBT_CTRL_ADV2_5G); ++ ++ linkmode_mod_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT, ++ cmd->link_modes.lp_advertising, ++ ocp_10gbt_stat & MDIO_AN_10GBT_STAT_LP2_5G); ++ ++ if (is_speed_2500(rtl8152_get_speed(tp))) ++ cmd->base.speed = SPEED_2500; ++ } ++ ++ if (tp->support_5000full) { ++ linkmode_mod_bit(ETHTOOL_LINK_MODE_5000baseT_Full_BIT, ++ cmd->link_modes.advertising, ++ ocp_10gbt_ctrl & MDIO_AN_10GBT_CTRL_ADV5G); + +- if (is_speed_2500(rtl8152_get_speed(tp))) +- cmd->base.speed = SPEED_2500; ++ linkmode_mod_bit(ETHTOOL_LINK_MODE_5000baseT_Full_BIT, ++ cmd->link_modes.lp_advertising, ++ ocp_10gbt_stat & MDIO_AN_10GBT_STAT_LP5G); ++ ++ if (is_speed_5000(rtl8152_get_speed(tp))) ++ cmd->base.speed = SPEED_5000; ++ } + } + + mutex_unlock(&tp->control); +@@ -8287,6 +8333,10 @@ static int rtl8152_set_link_ksettings(st + cmd->link_modes.advertising)) + advertising |= RTL_ADVERTISED_2500_FULL; + ++ if (test_bit(ETHTOOL_LINK_MODE_5000baseT_Full_BIT, ++ cmd->link_modes.advertising)) ++ advertising |= RTL_ADVERTISED_5000_FULL; ++ + mutex_lock(&tp->control); + + ret = rtl8152_set_speed(tp, cmd->base.autoneg, cmd->base.speed, +@@ -8404,7 +8454,7 @@ static int r8152_set_eee(struct r8152 *t + + tp->eee_en = eee->eee_enabled; + tp->eee_adv = val; +- if (tp->support_2500full) { ++ if (tp->support_2500full || tp->support_5000full) { + val = linkmode_to_mii_eee_cap2_t(eee->advertised); + tp->eee_adv2 = val; + } +@@ -8428,19 +8478,28 @@ static int r8153_get_eee(struct r8152 *t + val = ocp_reg_read(tp, OCP_EEE_LPABLE); + mii_eee_cap1_mod_linkmode_t(eee->lp_advertised, val); + +- if (tp->support_2500full) { +- linkmode_set_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT, eee->supported); +- ++ if (tp->support_2500full || tp->support_5000full) { + val = ocp_reg_read(tp, OCP_EEE_ADV2); + mii_eee_cap2_mod_linkmode_adv_t(eee->advertised, val); + + val = ocp_reg_read(tp, OCP_EEE_LPABLE2); + mii_eee_cap2_mod_linkmode_adv_t(eee->lp_advertised, val); ++ } ++ ++ if (tp->support_2500full) { ++ linkmode_set_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT, eee->supported); + + if (speed & _2500bps) + linkmode_set_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT, common); + } + ++ if (tp->support_5000full) { ++ linkmode_set_bit(ETHTOOL_LINK_MODE_5000baseT_Full_BIT, eee->supported); ++ ++ if (speed & _5000bps) ++ linkmode_set_bit(ETHTOOL_LINK_MODE_5000baseT_Full_BIT, common); ++ } ++ + eee->eee_enabled = tp->eee_en; + + if (speed & _1000bps) +@@ -9381,6 +9440,11 @@ static int rtl8152_probe_once(struct usb + } else { + tp->speed = SPEED_1000; + } ++ if (tp->support_5000full && ++ tp->udev->speed >= USB_SPEED_SUPER) { ++ tp->speed = SPEED_5000; ++ tp->advertising |= RTL_ADVERTISED_5000_FULL; ++ } + tp->advertising |= RTL_ADVERTISED_1000_FULL; + } + tp->duplex = DUPLEX_FULL; diff --git a/target/linux/generic/backport-6.18/747-v7.1-r8152-Add-support-for-the-RTL8157-hardware.patch b/target/linux/generic/backport-6.18/747-v7.1-r8152-Add-support-for-the-RTL8157-hardware.patch new file mode 100644 index 00000000000..459c2dba11e --- /dev/null +++ b/target/linux/generic/backport-6.18/747-v7.1-r8152-Add-support-for-the-RTL8157-hardware.patch @@ -0,0 +1,1553 @@ +From fd3c7d080df53136c7e7e37f753fb7bd4640ca42 Mon Sep 17 00:00:00 2001 +From: Birger Koblitz +Date: Sat, 4 Apr 2026 09:57:43 +0200 +Subject: [PATCH] r8152: Add support for the RTL8157 hardware + +The RTL8157 uses a different packet descriptor format compared to the +previous generation of chips. Add support for this format by adding a +descriptor format structure into the r8152 structure and corresponding +desc_ops functions which abstract the vlan-tag, tx/rx len and +tx/rx checksum algorithms. + +Also, add support for the ADV indirect access interface of the RTL8157 +and PHY setup. + +For initialization of the RTL8157, combine the existing RTL8156B and +RTL8156 init functions and add RTL8157-specific functinality in order +to improve code readability and maintainability. +r8156_init() is now called with RTL_VER_10 and RTL_VER_11 for the RTL8156, +with RTL_VER_12, RTL_VER_13 and RTL_VER_15 for the RTL8156B and with +RTL_VER_16 for the RTL8157 and checks the version for chip-specific code. +Also add USB power control functions for the RTL8157. + +Add support for the USB device ID of Realtek RTL8157-based adapters. Detect +the RTL8157 as RTL_VER_16 and set it up. + +Signed-off-by: Birger Koblitz +Link: https://patch.msgid.link/20260404-rtl8157_next-v7-2-039121318f23@birger-koblitz.de +Signed-off-by: Paolo Abeni +--- + drivers/net/usb/r8152.c | 913 ++++++++++++++++++++++++++++++++-------- + 1 file changed, 729 insertions(+), 184 deletions(-) + +--- a/drivers/net/usb/r8152.c ++++ b/drivers/net/usb/r8152.c +@@ -129,6 +129,7 @@ + #define USB_CSR_DUMMY1 0xb464 + #define USB_CSR_DUMMY2 0xb466 + #define USB_DEV_STAT 0xb808 ++#define USB_U2P3_V2_CTRL 0xc2c0 + #define USB_CONNECT_TIMER 0xcbf8 + #define USB_MSC_TIMER 0xcbfc + #define USB_BURST_SIZE 0xcfc0 +@@ -162,6 +163,9 @@ + #define USB_U1U2_TIMER 0xd4da + #define USB_FW_TASK 0xd4e8 /* RTL8153B */ + #define USB_RX_AGGR_NUM 0xd4ee ++#define USB_ADV_ADDR 0xd5d6 ++#define USB_ADV_DATA 0xd5d8 ++#define USB_ADV_CMD 0xd5dc + #define USB_UPS_CTRL 0xd800 + #define USB_POWER_CUT 0xd80a + #define USB_MISC_0 0xd81a +@@ -498,6 +502,12 @@ + /* USB_RX_AGGR_NUM */ + #define RX_AGGR_NUM_MASK 0x1ff + ++/* USB_ADV_CMD */ ++#define ADV_CMD_BMU 0 ++#define ADV_CMD_BUSY BIT(0) ++#define ADV_CMD_WR BIT(1) ++#define ADV_CMD_IP BIT(2) ++ + /* USB_UPS_CTRL */ + #define POWER_CUT 0x0100 + +@@ -537,11 +547,15 @@ + #define CDC_ECM_EN BIT(3) + #define RX_AGG_DISABLE 0x0010 + #define RX_ZERO_EN 0x0080 ++#define RX_DESC_16B 0x0400 + + /* USB_U2P3_CTRL */ + #define U2P3_ENABLE 0x0001 + #define RX_DETECT8 BIT(3) + ++/* USB_U2P3_V2_CTRL */ ++#define U2P3_V2_ENABLE BIT(29) ++ + /* USB_POWER_CUT */ + #define PWR_EN 0x0001 + #define PHASE2_EN 0x0008 +@@ -754,8 +768,6 @@ enum rtl_register_content { + #define RTL8152_MAX_TX 4 + #define RTL8152_MAX_RX 10 + #define INTBUFSIZE 2 +-#define TX_ALIGN 4 +-#define RX_ALIGN 8 + + #define RTL8152_RX_MAX_PENDING 4096 + #define RTL8152_RXFG_HEADSZ 256 +@@ -767,7 +779,6 @@ enum rtl_register_content { + #define RTL8152_TX_TIMEOUT (5 * HZ) + #define mtu_to_size(m) ((m) + VLAN_ETH_HLEN + ETH_FCS_LEN) + #define size_to_mtu(s) ((s) - VLAN_ETH_HLEN - ETH_FCS_LEN) +-#define rx_reserved_size(x) (mtu_to_size(x) + sizeof(struct rx_desc) + RX_ALIGN) + + /* rtl8152 flags */ + enum rtl8152_flags { +@@ -852,6 +863,40 @@ struct tx_desc { + #define TX_VLAN_TAG BIT(16) + }; + ++struct rx_desc_v2 { ++ __le32 opts1; ++#define RX_LEN_MASK_2 0xfffe0000 ++#define rx_v2_get_len(x) (((x) & RX_LEN_MASK_2) >> 17) ++#define RX_VLAN_TAG_2 BIT(3) ++#define RX_VER_MASK 0x3 ++ ++ __le32 opts2; ++ ++ __le32 opts3; ++#define IPF_2 BIT(26) /* IP checksum fail */ ++#define UDPF_2 BIT(25) /* UDP checksum fail */ ++#define TCPF_2 BIT(24) /* TCP checksum fail */ ++#define RD_IPV6_CS_2 BIT(15) ++#define RD_IPV4_CS_2 BIT(14) ++#define RD_UDP_CS_2 BIT(11) ++#define RD_TCP_CS_2 BIT(10) ++ ++ __le32 opts4; ++}; ++ ++struct tx_desc_v2 { ++ __le32 opts1; ++ ++ __le32 opts2; ++#define TCPHO_MAX_2 0x3ffU ++ ++ __le32 opts3; ++#define tx_v2_set_len(x) ((x) << 4) ++ ++ __le32 opts4; ++#define TX_SIG (0x15 << 27) ++}; ++ + struct r8152; + + struct rx_agg { +@@ -925,6 +970,19 @@ struct r8152 { + u32 ctap_short_off:1; + } ups_info; + ++ struct desc_info { ++ void (*vlan_tag)(void *desc, struct sk_buff *skb); ++ u8 align; ++ u8 size; ++ } rx_desc, tx_desc; ++ ++ struct desc_ops { ++ void (*tx_len)(struct r8152 *tp, void *desc, u32 len); ++ u32 (*rx_len)(struct r8152 *tp, void *desc); ++ u8 (*rx_csum)(struct r8152 *tp, void *desc); ++ int (*tx_csum)(struct r8152 *tp, void *desc, struct sk_buff *skb, u32 len); ++ } desc_ops; ++ + #define RTL_VER_SIZE 32 + + struct rtl_fw { +@@ -1189,6 +1247,7 @@ enum rtl_version { + RTL_VER_13, + RTL_VER_14, + RTL_VER_15, ++ RTL_VER_16, + + RTL_VER_MAX + }; +@@ -1214,7 +1273,7 @@ enum tx_csum_stat { + static const int multicast_filter_limit = 32; + static unsigned int agg_buf_sz = 16384; + +-#define RTL_LIMITED_TSO_SIZE (size_to_mtu(agg_buf_sz) - sizeof(struct tx_desc)) ++#define RTL_LIMITED_TSO_SIZE (size_to_mtu(agg_buf_sz) - tp->tx_desc.size) + + /* If register access fails then we block access and issue a reset. If this + * happens too many times in a row without a successful access then we stop +@@ -1625,6 +1684,122 @@ static inline int r8152_mdio_read(struct + return ocp_reg_read(tp, OCP_BASE_MII + reg_addr * 2); + } + ++static int wait_cmd_ready(struct r8152 *tp, u16 cmd) ++{ ++ return poll_timeout_us(u16 ocp_data = ocp_read_word(tp, MCU_TYPE_USB, cmd), ++ !(ocp_data & ADV_CMD_BUSY), 2000, 20000, false); ++} ++ ++static int ocp_adv_read(struct r8152 *tp, u16 cmd, u16 addr, u32 *data) ++{ ++ int ret; ++ ++ ret = wait_cmd_ready(tp, USB_ADV_CMD); ++ if (ret < 0) ++ goto out; ++ ++ ocp_write_word(tp, MCU_TYPE_USB, USB_ADV_ADDR, addr); ++ ++ cmd |= ADV_CMD_BUSY; ++ ocp_write_word(tp, MCU_TYPE_USB, USB_ADV_CMD, cmd); ++ ++ ret = wait_cmd_ready(tp, USB_ADV_CMD); ++ if (ret < 0) ++ goto out; ++ ++ *data = ocp_read_dword(tp, MCU_TYPE_USB, USB_ADV_DATA); ++ ++out: ++ return ret; ++} ++ ++static int ocp_adv_write(struct r8152 *tp, u16 cmd, u16 addr, u32 data) ++{ ++ int ret; ++ ++ ret = wait_cmd_ready(tp, USB_ADV_CMD); ++ if (ret < 0) ++ goto out; ++ ++ cmd |= ADV_CMD_WR; ++ ocp_write_dword(tp, MCU_TYPE_USB, USB_ADV_DATA, data); ++ ++ ocp_write_word(tp, MCU_TYPE_USB, USB_ADV_ADDR, addr); ++ ++ cmd |= ADV_CMD_BUSY; ++ ocp_write_word(tp, MCU_TYPE_USB, USB_ADV_CMD, cmd); ++ ++out: ++ return ret; ++} ++ ++static int rtl_bmu_read(struct r8152 *tp, u16 addr, u32 *data) ++{ ++ return ocp_adv_read(tp, ADV_CMD_BMU, addr, data); ++} ++ ++static int rtl_bmu_write(struct r8152 *tp, u16 addr, u32 data) ++{ ++ return ocp_adv_write(tp, ADV_CMD_BMU, addr, data); ++} ++ ++static int rtl_bmu_w0w1(struct r8152 *tp, u16 addr, u32 clear, u32 set) ++{ ++ u32 bmu; ++ int ret; ++ ++ ret = rtl_bmu_read(tp, addr, &bmu); ++ if (ret < 0) ++ goto out; ++ ++ bmu = (bmu & ~clear) | set; ++ ret = rtl_bmu_write(tp, addr, bmu); ++ ++out: ++ return ret; ++} ++ ++static int rtl_bmu_clr_bits(struct r8152 *tp, u16 addr, u32 clear) ++{ ++ return rtl_bmu_w0w1(tp, addr, clear, 0); ++} ++ ++static int rtl_ip_read(struct r8152 *tp, u16 addr, u32 *data) ++{ ++ return ocp_adv_read(tp, ADV_CMD_IP, addr, data); ++} ++ ++static int rtl_ip_write(struct r8152 *tp, u16 addr, u32 data) ++{ ++ return ocp_adv_write(tp, ADV_CMD_IP, addr, data); ++} ++ ++static int rtl_ip_w0w1(struct r8152 *tp, u16 addr, u32 clear, u32 set) ++{ ++ int ret; ++ u32 ip; ++ ++ ret = rtl_ip_read(tp, addr, &ip); ++ if (ret < 0) ++ goto out; ++ ++ ip = (ip & ~clear) | set; ++ ret = rtl_ip_write(tp, addr, ip); ++ ++out: ++ return ret; ++} ++ ++static int rtl_ip_clr_bits(struct r8152 *tp, u16 addr, u32 clear) ++{ ++ return rtl_ip_w0w1(tp, addr, clear, 0); ++} ++ ++static int rtl_ip_set_bits(struct r8152 *tp, u16 addr, u32 set) ++{ ++ return rtl_ip_w0w1(tp, addr, 0, set); ++} ++ + static void sram_write(struct r8152 *tp, u16 addr, u16 data) + { + ocp_reg_write(tp, OCP_SRAM_ADDR, addr); +@@ -2188,14 +2363,14 @@ resubmit: + } + } + +-static inline void *rx_agg_align(void *data) ++static void *rx_agg_align(struct r8152 *tp, void *data) + { +- return (void *)ALIGN((uintptr_t)data, RX_ALIGN); ++ return (void *)ALIGN((uintptr_t)data, tp->rx_desc.align); + } + +-static inline void *tx_agg_align(void *data) ++static void *tx_agg_align(struct r8152 *tp, void *data) + { +- return (void *)ALIGN((uintptr_t)data, TX_ALIGN); ++ return (void *)ALIGN((uintptr_t)data, tp->tx_desc.align); + } + + static void free_rx_agg(struct r8152 *tp, struct rx_agg *agg) +@@ -2313,9 +2488,9 @@ static int alloc_all_mem(struct r8152 *t + if (!buf) + goto err1; + +- if (buf != tx_agg_align(buf)) { ++ if (buf != tx_agg_align(tp, buf)) { + kfree(buf); +- buf = kmalloc_node(agg_buf_sz + TX_ALIGN, GFP_KERNEL, ++ buf = kmalloc_node(agg_buf_sz + tp->tx_desc.align, GFP_KERNEL, + node); + if (!buf) + goto err1; +@@ -2331,7 +2506,7 @@ static int alloc_all_mem(struct r8152 *t + tp->tx_info[i].context = tp; + tp->tx_info[i].urb = urb; + tp->tx_info[i].buffer = buf; +- tp->tx_info[i].head = tx_agg_align(buf); ++ tp->tx_info[i].head = tx_agg_align(tp, buf); + + list_add_tail(&tp->tx_info[i].list, &tp->tx_free); + } +@@ -2418,8 +2593,17 @@ drop: + } + } + +-static inline void rtl_tx_vlan_tag(struct tx_desc *desc, struct sk_buff *skb) ++static void r8152_tx_len(struct r8152 *tp, void *tx_desc, u32 len) + { ++ struct tx_desc *desc = tx_desc; ++ ++ desc->opts1 |= cpu_to_le32(len); ++} ++ ++static void r8152_tx_vlan_tag(void *d, struct sk_buff *skb) ++{ ++ struct tx_desc *desc = d; ++ + if (skb_vlan_tag_present(skb)) { + u32 opts2; + +@@ -2428,8 +2612,10 @@ static inline void rtl_tx_vlan_tag(struc + } + } + +-static inline void rtl_rx_vlan_tag(struct rx_desc *desc, struct sk_buff *skb) ++static void r8152_rx_vlan_tag(void *d, struct sk_buff *skb) + { ++ struct rx_desc *desc = d; ++ + u32 opts2 = le32_to_cpu(desc->opts2); + + if (opts2 & RX_VLAN_TAG) +@@ -2437,10 +2623,11 @@ static inline void rtl_rx_vlan_tag(struc + swab16(opts2 & 0xffff)); + } + +-static int r8152_tx_csum(struct r8152 *tp, struct tx_desc *desc, ++static int r8152_tx_csum(struct r8152 *tp, void *d, + struct sk_buff *skb, u32 len) + { + u32 mss = skb_shinfo(skb)->gso_size; ++ struct tx_desc *desc = d; + u32 opts1, opts2 = 0; + int ret = TX_CSUM_SUCCESS; + +@@ -2525,6 +2712,74 @@ unavailable: + return ret; + } + ++static u32 r8152_rx_len(struct r8152 *tp, void *d) ++{ ++ struct rx_desc *desc = d; ++ ++ return le32_to_cpu(desc->opts1) & RX_LEN_MASK; ++} ++ ++static u32 r8157_rx_len(struct r8152 *tp, void *d) ++{ ++ struct rx_desc_v2 *desc = d; ++ ++ return rx_v2_get_len(le32_to_cpu(desc->opts1)); ++} ++ ++static void r8157_rx_vlan_tag(void *desc, struct sk_buff *skb) ++{ ++ struct rx_desc_v2 *d = desc; ++ u32 opts1; ++ ++ opts1 = le32_to_cpu(d->opts1); ++ if (opts1 & RX_VLAN_TAG_2) { ++ u32 opts2 = le32_to_cpu(d->opts2); ++ ++ __vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q), ++ swab16((opts2 >> 16) & 0xffff)); ++ } ++} ++ ++static int r8157_tx_csum(struct r8152 *tp, void *tx_desc, struct sk_buff *skb, u32 len) ++{ ++ u32 mss = skb_shinfo(skb)->gso_size; ++ ++ if (!mss && skb->ip_summed == CHECKSUM_PARTIAL) { ++ u32 transport_offset = (u32)skb_transport_offset(skb); ++ ++ if (transport_offset > TCPHO_MAX_2) { ++ netif_warn(tp, tx_err, tp->netdev, ++ "Invalid transport offset 0x%x\n", ++ transport_offset); ++ return TX_CSUM_NONE; ++ } ++ } ++ ++ return r8152_tx_csum(tp, tx_desc, skb, len); ++} ++ ++static void r8157_tx_len(struct r8152 *tp, void *tx_desc, u32 len) ++{ ++ struct tx_desc_v2 *desc = tx_desc; ++ ++ desc->opts3 = cpu_to_le32(tx_v2_set_len(len)); ++ desc->opts4 = cpu_to_le32(TX_SIG); ++} ++ ++static int rtl_tx_csum(struct r8152 *tp, void *desc, struct sk_buff *skb, ++ u32 len) ++{ ++ int ret = TX_CSUM_SUCCESS; ++ ++ WARN_ON_ONCE(len > TX_LEN_MAX); ++ ++ ret = tp->desc_ops.tx_csum(tp, desc, skb, len); ++ if (!ret) ++ tp->desc_ops.tx_len(tp, desc, len); ++ ++ return ret; ++} ++ + static int r8152_tx_agg_fill(struct r8152 *tp, struct tx_agg *agg) + { + struct sk_buff_head skb_head, *tx_queue = &tp->tx_queue; +@@ -2541,33 +2796,33 @@ static int r8152_tx_agg_fill(struct r815 + agg->skb_len = 0; + remain = agg_buf_sz; + +- while (remain >= ETH_ZLEN + sizeof(struct tx_desc)) { +- struct tx_desc *tx_desc; ++ while (remain >= ETH_ZLEN + tp->tx_desc.size) { + struct sk_buff *skb; + unsigned int len; ++ void *tx_desc; + + skb = __skb_dequeue(&skb_head); + if (!skb) + break; + +- len = skb->len + sizeof(*tx_desc); ++ len = skb->len + tp->tx_desc.size; + + if (len > remain) { + __skb_queue_head(&skb_head, skb); + break; + } + +- tx_data = tx_agg_align(tx_data); +- tx_desc = (struct tx_desc *)tx_data; ++ tx_data = tx_agg_align(tp, tx_data); ++ tx_desc = (void *)tx_data; + +- if (r8152_tx_csum(tp, tx_desc, skb, skb->len)) { ++ if (rtl_tx_csum(tp, tx_desc, skb, skb->len)) { + r8152_csum_workaround(tp, skb, &skb_head); + continue; + } + +- rtl_tx_vlan_tag(tx_desc, skb); ++ tp->tx_desc.vlan_tag(tx_desc, skb); + +- tx_data += sizeof(*tx_desc); ++ tx_data += tp->tx_desc.size; + + len = skb->len; + if (skb_copy_bits(skb, 0, tx_data, len) < 0) { +@@ -2575,7 +2830,7 @@ static int r8152_tx_agg_fill(struct r815 + + stats->tx_dropped++; + dev_kfree_skb_any(skb); +- tx_data -= sizeof(*tx_desc); ++ tx_data -= tp->tx_desc.size; + continue; + } + +@@ -2585,7 +2840,7 @@ static int r8152_tx_agg_fill(struct r815 + + dev_kfree_skb_any(skb); + +- remain = agg_buf_sz - (int)(tx_agg_align(tx_data) - agg->head); ++ remain = agg_buf_sz - (int)(tx_agg_align(tp, tx_data) - agg->head); + + if (tp->dell_tb_rx_agg_bug) + break; +@@ -2623,8 +2878,9 @@ out_tx_fill: + return ret; + } + +-static u8 r8152_rx_csum(struct r8152 *tp, struct rx_desc *rx_desc) ++static u8 r8152_rx_csum(struct r8152 *tp, void *d) + { ++ struct rx_desc *rx_desc = d; + u8 checksum = CHECKSUM_NONE; + u32 opts2, opts3; + +@@ -2652,6 +2908,30 @@ return_result: + return checksum; + } + ++static u8 r8157_rx_csum(struct r8152 *tp, void *desc) ++{ ++ struct rx_desc_v2 *d = desc; ++ u8 checksum = CHECKSUM_NONE; ++ u32 opts3; ++ ++ if (!(tp->netdev->features & NETIF_F_RXCSUM)) ++ goto return_result; ++ ++ opts3 = le32_to_cpu(d->opts3); ++ ++ if ((opts3 & (RD_IPV4_CS_2 | IPF_2)) == (RD_IPV4_CS_2 | IPF_2)) { ++ checksum = CHECKSUM_NONE; ++ } else if (opts3 & (RD_IPV4_CS_2 | RD_IPV6_CS_2)) { ++ if ((opts3 & (RD_UDP_CS_2 | UDPF_2)) == RD_UDP_CS_2) ++ checksum = CHECKSUM_UNNECESSARY; ++ else if ((opts3 & (RD_TCP_CS_2 | TCPF_2)) == RD_TCP_CS_2) ++ checksum = CHECKSUM_UNNECESSARY; ++ } ++ ++return_result: ++ return checksum; ++} ++ + static inline bool rx_count_exceed(struct r8152 *tp) + { + return atomic_read(&tp->rx_count) > RTL8152_MAX_RX; +@@ -2727,10 +3007,10 @@ static int rx_bottom(struct r8152 *tp, i + spin_unlock_irqrestore(&tp->rx_lock, flags); + + list_for_each_safe(cursor, next, &rx_queue) { +- struct rx_desc *rx_desc; + struct rx_agg *agg, *agg_free; + int len_used = 0; + struct urb *urb; ++ void *rx_desc; + u8 *rx_data; + + /* A bulk transfer of USB may contain may packets, so the +@@ -2753,7 +3033,7 @@ static int rx_bottom(struct r8152 *tp, i + + rx_desc = agg->buffer; + rx_data = agg->buffer; +- len_used += sizeof(struct rx_desc); ++ len_used += tp->rx_desc.size; + + while (urb->actual_length > len_used) { + struct net_device *netdev = tp->netdev; +@@ -2764,7 +3044,7 @@ static int rx_bottom(struct r8152 *tp, i + + WARN_ON_ONCE(skb_queue_len(&tp->rx_queue) >= 1000); + +- pkt_len = le32_to_cpu(rx_desc->opts1) & RX_LEN_MASK; ++ pkt_len = tp->desc_ops.rx_len(tp, rx_desc); + if (pkt_len < ETH_ZLEN) + break; + +@@ -2774,7 +3054,7 @@ static int rx_bottom(struct r8152 *tp, i + + pkt_len -= ETH_FCS_LEN; + len = pkt_len; +- rx_data += sizeof(struct rx_desc); ++ rx_data += tp->rx_desc.size; + + if (!agg_free || tp->rx_copybreak > len) + use_frags = false; +@@ -2805,8 +3085,8 @@ static int rx_bottom(struct r8152 *tp, i + goto find_next_rx; + } + +- skb->ip_summed = r8152_rx_csum(tp, rx_desc); +- rtl_rx_vlan_tag(rx_desc, skb); ++ skb->ip_summed = tp->desc_ops.rx_csum(tp, rx_desc); ++ tp->rx_desc.vlan_tag(rx_desc, skb); + + if (use_frags) { + if (rx_frag_head_sz) { +@@ -2843,10 +3123,10 @@ static int rx_bottom(struct r8152 *tp, i + } + + find_next_rx: +- rx_data = rx_agg_align(rx_data + len + ETH_FCS_LEN); +- rx_desc = (struct rx_desc *)rx_data; ++ rx_data = rx_agg_align(tp, rx_data + len + ETH_FCS_LEN); ++ rx_desc = rx_data; + len_used = agg_offset(agg, rx_data); +- len_used += sizeof(struct rx_desc); ++ len_used += tp->rx_desc.size; + } + + WARN_ON(!agg_free && page_count(agg->page) > 1); +@@ -3089,13 +3369,19 @@ static netdev_features_t + rtl8152_features_check(struct sk_buff *skb, struct net_device *dev, + netdev_features_t features) + { ++ struct r8152 *tp = netdev_priv(dev); + u32 mss = skb_shinfo(skb)->gso_size; +- int max_offset = mss ? GTTCPHO_MAX : TCPHO_MAX; ++ int max_offset; ++ ++ if (tp->version < RTL_VER_16) ++ max_offset = mss ? GTTCPHO_MAX : TCPHO_MAX; ++ else ++ max_offset = mss ? GTTCPHO_MAX : TCPHO_MAX_2; + + if ((mss || skb->ip_summed == CHECKSUM_PARTIAL) && + skb_transport_offset(skb) > max_offset) + features &= ~(NETIF_F_CSUM_MASK | NETIF_F_GSO_MASK); +- else if ((skb->len + sizeof(struct tx_desc)) > agg_buf_sz) ++ else if ((skb->len + tp->tx_desc.size) > agg_buf_sz) + features &= ~NETIF_F_GSO_MASK; + + return features; +@@ -3133,31 +3419,26 @@ static void r8152b_reset_packet_filter(s + + static void rtl8152_nic_reset(struct r8152 *tp) + { +- int i; +- + switch (tp->version) { + case RTL_TEST_01: + case RTL_VER_10: + case RTL_VER_11: + ocp_byte_clr_bits(tp, MCU_TYPE_PLA, PLA_CR, CR_TE); +- +- ocp_word_clr_bits(tp, MCU_TYPE_USB, USB_BMU_RESET, +- BMU_RESET_EP_IN); +- ++ ocp_word_clr_bits(tp, MCU_TYPE_USB, USB_BMU_RESET, BMU_RESET_EP_IN); + ocp_word_set_bits(tp, MCU_TYPE_USB, USB_USB_CTRL, CDC_ECM_EN); +- + ocp_byte_clr_bits(tp, MCU_TYPE_PLA, PLA_CR, CR_RE); +- +- ocp_word_set_bits(tp, MCU_TYPE_USB, USB_BMU_RESET, +- BMU_RESET_EP_IN); +- ++ ocp_word_set_bits(tp, MCU_TYPE_USB, USB_BMU_RESET, BMU_RESET_EP_IN); + ocp_word_clr_bits(tp, MCU_TYPE_USB, USB_USB_CTRL, CDC_ECM_EN); + break; + ++ case RTL_VER_16: ++ ocp_byte_clr_bits(tp, MCU_TYPE_PLA, PLA_CR, CR_RE | CR_TE); ++ break; ++ + default: + ocp_write_byte(tp, MCU_TYPE_PLA, PLA_CR, CR_RST); + +- for (i = 0; i < 1000; i++) { ++ for (int i = 0; i < 1000; i++) { + if (test_bit(RTL8152_INACCESSIBLE, &tp->flags)) + break; + if (!(ocp_read_byte(tp, MCU_TYPE_PLA, PLA_CR) & CR_RST)) +@@ -3170,7 +3451,7 @@ static void rtl8152_nic_reset(struct r81 + + static void set_tx_qlen(struct r8152 *tp) + { +- tp->tx_qlen = agg_buf_sz / (mtu_to_size(tp->netdev->mtu) + sizeof(struct tx_desc)); ++ tp->tx_qlen = agg_buf_sz / (mtu_to_size(tp->netdev->mtu) + tp->tx_desc.size); + } + + static inline u16 rtl8152_get_speed(struct r8152 *tp) +@@ -3374,6 +3655,7 @@ static void r8153_set_rx_early_timeout(s + case RTL_VER_12: + case RTL_VER_13: + case RTL_VER_15: ++ case RTL_VER_16: + 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, +@@ -3385,9 +3667,14 @@ static void r8153_set_rx_early_timeout(s + } + } + ++static u32 rx_reserved_size(struct r8152 *tp, u32 mtu) ++{ ++ return mtu_to_size(mtu) + tp->rx_desc.size + tp->rx_desc.align; ++} ++ + static void r8153_set_rx_early_size(struct r8152 *tp) + { +- u32 ocp_data = tp->rx_buf_sz - rx_reserved_size(tp->netdev->mtu); ++ u32 ocp_data = tp->rx_buf_sz - rx_reserved_size(tp, tp->netdev->mtu); + + switch (tp->version) { + case RTL_VER_03: +@@ -3412,6 +3699,10 @@ static void r8153_set_rx_early_size(stru + ocp_write_word(tp, MCU_TYPE_USB, USB_RX_EARLY_SIZE, + ocp_data / 8); + break; ++ case RTL_VER_16: ++ ocp_write_word(tp, MCU_TYPE_USB, USB_RX_EARLY_SIZE, ++ ocp_data / 16); ++ break; + default: + WARN_ON_ONCE(1); + break; +@@ -3523,6 +3814,7 @@ static void rtl_rx_vlan_en(struct r8152 + case RTL_VER_12: + case RTL_VER_13: + case RTL_VER_15: ++ case RTL_VER_16: + default: + if (enable) + ocp_word_set_bits(tp, MCU_TYPE_PLA, PLA_RCR1, +@@ -3680,6 +3972,14 @@ static void r8153_u2p3en(struct r8152 *t + ocp_word_clr_bits(tp, MCU_TYPE_USB, USB_U2P3_CTRL, U2P3_ENABLE); + } + ++static int r8157_u2p3en(struct r8152 *tp, bool enable) ++{ ++ if (enable) ++ return rtl_ip_set_bits(tp, USB_U2P3_V2_CTRL, U2P3_V2_ENABLE); ++ else ++ return rtl_ip_clr_bits(tp, USB_U2P3_V2_CTRL, U2P3_V2_ENABLE); ++} ++ + static void r8153b_ups_flags(struct r8152 *tp) + { + u32 ups_flags = 0; +@@ -4025,6 +4325,18 @@ static void r8153b_power_cut_en(struct r + ocp_word_clr_bits(tp, MCU_TYPE_USB, USB_MISC_0, PCUT_STATUS); + } + ++static void r8157_power_cut_en(struct r8152 *tp, bool enable) ++{ ++ if (enable) { ++ ocp_word_set_bits(tp, MCU_TYPE_USB, USB_POWER_CUT, PWR_EN | PHASE2_EN); ++ ocp_byte_set_bits(tp, MCU_TYPE_USB, USB_MISC_2, BIT(1)); ++ } else { ++ ocp_word_clr_bits(tp, MCU_TYPE_USB, USB_POWER_CUT, PWR_EN); ++ ocp_word_clr_bits(tp, MCU_TYPE_USB, USB_MISC_0, PCUT_STATUS); ++ ocp_byte_clr_bits(tp, MCU_TYPE_USB, USB_MISC_2, BIT(1)); ++ } ++} ++ + static void r8153_queue_wake(struct r8152 *tp, bool enable) + { + if (enable) +@@ -4141,6 +4453,22 @@ static void rtl8156_runtime_enable(struc + } + } + ++static void rtl8157_runtime_enable(struct r8152 *tp, bool enable) ++{ ++ if (enable) { ++ r8153_queue_wake(tp, true); ++ r8153b_u1u2en(tp, false); ++ r8157_u2p3en(tp, false); ++ rtl_runtime_suspend_enable(tp, true); ++ } else { ++ r8153_queue_wake(tp, false); ++ rtl_runtime_suspend_enable(tp, false); ++ r8157_u2p3en(tp, true); ++ if (tp->udev->speed >= USB_SPEED_SUPER) ++ r8153b_u1u2en(tp, true); ++ } ++} ++ + static void r8153_teredo_off(struct r8152 *tp) + { + switch (tp->version) { +@@ -4165,6 +4493,7 @@ static void r8153_teredo_off(struct r815 + case RTL_VER_13: + case RTL_VER_14: + case RTL_VER_15: ++ case RTL_VER_16: + default: + /* The bit 0 ~ 7 are relative with teredo settings. They are + * W1C (write 1 to clear), so set all 1 to disable it. +@@ -4218,6 +4547,7 @@ static void rtl_clear_bp(struct r8152 *t + bp_num = 8; + break; + case RTL_VER_14: ++ case RTL_VER_16: + default: + ocp_write_word(tp, type, USB_BP2_EN, 0); + bp_num = 16; +@@ -4325,6 +4655,7 @@ static bool rtl8152_is_fw_phy_speed_up_o + case RTL_VER_11: + case RTL_VER_12: + case RTL_VER_14: ++ case RTL_VER_16: + goto out; + case RTL_VER_13: + case RTL_VER_15: +@@ -5486,6 +5817,7 @@ static void rtl_eee_enable(struct r8152 + case RTL_VER_12: + case RTL_VER_13: + case RTL_VER_15: ++ case RTL_VER_16: + if (enable) { + r8156_eee_en(tp, true); + ocp_reg_write(tp, OCP_EEE_ADV, tp->eee_adv); +@@ -6070,15 +6402,24 @@ static int rtl8156_enable(struct r8152 * + if (test_bit(RTL8152_INACCESSIBLE, &tp->flags)) + return -ENODEV; + +- r8156_fc_parameter(tp); ++ if (tp->version < RTL_VER_12) ++ r8156_fc_parameter(tp); ++ + set_tx_qlen(tp); + rtl_set_eee_plus(tp); ++ ++ if (tp->version >= RTL_VER_12 && tp->version <= RTL_VER_16) ++ 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 = rtl8152_get_speed(tp); + rtl_set_ifg(tp, speed); + ++ if (tp->version >= 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); +@@ -6086,10 +6427,12 @@ static int rtl8156_enable(struct r8152 * + ocp_word_set_bits(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL4, + IDLE_SPDWN_EN); + +- if (speed & _1000bps) +- ocp_write_word(tp, MCU_TYPE_PLA, PLA_EEE_TXTWSYS, 0x11); +- else if (speed & _500bps) +- ocp_write_word(tp, MCU_TYPE_PLA, PLA_EEE_TXTWSYS, 0x3d); ++ if (tp->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 (tp->udev->speed == USB_SPEED_HIGH) { + /* USB 0xb45e[3:0] l1_nyet_hird */ +@@ -6114,45 +6457,6 @@ static void rtl8156_disable(struct r8152 + rtl8153_disable(tp); + } + +-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 = 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 == USB_SPEED_HIGH) { +- 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 rtl8152_set_speed(struct r8152 *tp, u8 autoneg, u32 speed, u8 duplex, + u32 advertising) + { +@@ -6495,7 +6799,7 @@ static void rtl8156_change_mtu(struct r8 + /* TX share fifo free credit full threshold */ + ocp_write_word(tp, MCU_TYPE_PLA, PLA_TXFIFO_CTRL, 512 / 64); + ocp_write_word(tp, MCU_TYPE_PLA, PLA_TXFIFO_FULL, +- ALIGN(rx_max_size + sizeof(struct tx_desc), 1024) / 16); ++ ALIGN(rx_max_size + tp->tx_desc.size, 1024) / 16); + } + + static void rtl8156_up(struct r8152 *tp) +@@ -6504,7 +6808,8 @@ static void rtl8156_up(struct r8152 *tp) + return; + + r8153b_u1u2en(tp, false); +- r8153_u2p3en(tp, false); ++ if (tp->version != RTL_VER_16) ++ r8153_u2p3en(tp, false); + r8153_aldps_en(tp, false); + + rxdy_gated_en(tp, true); +@@ -6517,6 +6822,9 @@ static void rtl8156_up(struct r8152 *tp) + + ocp_byte_clr_bits(tp, MCU_TYPE_PLA, PLA_OOB_CTRL, NOW_IS_OOB); + ++ if (tp->version == RTL_VER_16) ++ 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); +@@ -6540,8 +6848,11 @@ static void rtl8156_up(struct r8152 *tp) + ocp_word_clr_bits(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL3, + PLA_MCU_SPDWN_EN); + +- ocp_word_clr_bits(tp, MCU_TYPE_USB, USB_SPEED_OPTION, +- RG_PWRDN_EN | ALL_SPEED_OFF); ++ ocp_word_clr_bits(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL3, PLA_MCU_SPDWN_EN); ++ ++ if (tp->version != RTL_VER_16) ++ 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); + +@@ -6551,9 +6862,10 @@ static void rtl8156_up(struct r8152 *tp) + } + + r8153_aldps_en(tp, true); +- r8153_u2p3en(tp, true); ++ if (tp->version != RTL_VER_16) ++ r8153_u2p3en(tp, true); + +- if (tp->udev->speed >= USB_SPEED_SUPER) ++ if (tp->version != RTL_VER_16 && tp->udev->speed >= USB_SPEED_SUPER) + r8153b_u1u2en(tp, true); + } + +@@ -6568,8 +6880,10 @@ static void rtl8156_down(struct r8152 *t + PLA_MCU_SPDWN_EN); + + r8153b_u1u2en(tp, false); +- r8153_u2p3en(tp, false); +- r8153b_power_cut_en(tp, false); ++ if (tp->version != RTL_VER_16) { ++ r8153_u2p3en(tp, false); ++ r8153b_power_cut_en(tp, false); ++ } + r8153_aldps_en(tp, false); + + ocp_byte_clr_bits(tp, MCU_TYPE_PLA, PLA_OOB_CTRL, NOW_IS_OOB); +@@ -7642,106 +7956,241 @@ static void r8156b_hw_phy_cfg(struct r81 + set_bit(PHY_RESET, &tp->flags); + } + +-static void r8156_init(struct r8152 *tp) ++static void r8157_hw_phy_cfg(struct r8152 *tp) + { ++ u32 ocp_data; + u16 data; +- int i; +- +- if (test_bit(RTL8152_INACCESSIBLE, &tp->flags)) +- return; +- +- 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); ++ int ret; + +- for (i = 0; i < 500; i++) { +- if (ocp_read_word(tp, MCU_TYPE_PLA, PLA_BOOT_CTRL) & +- AUTOLOAD_DONE) +- break; ++ r8156b_wait_loading_flash(tp); + +- msleep(20); +- if (test_bit(RTL8152_INACCESSIBLE, &tp->flags)) +- return; ++ ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_MISC_0); ++ if (ocp_data & PCUT_STATUS) { ++ ocp_data &= ~PCUT_STATUS; ++ ocp_write_word(tp, MCU_TYPE_USB, USB_MISC_0, ocp_data); + } + + data = r8153_phy_status(tp, 0); +- if (data == PHY_STAT_EXT_INIT) ++ switch (data) { ++ case PHY_STAT_EXT_INIT: ++ 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: ++ break; ++ } + +- r8152_mdio_test_and_clr_bit(tp, MII_BMCR, BMCR_PDOWN); ++ data = r8152_mdio_read(tp, MII_BMCR); ++ if (data & BMCR_PDOWN) { ++ data &= ~BMCR_PDOWN; ++ r8152_mdio_write(tp, MII_BMCR, data); ++ } + +- data = r8153_phy_status(tp, PHY_STAT_LAN_ON); +- WARN_ON_ONCE(data != PHY_STAT_LAN_ON); ++ r8153_aldps_en(tp, false); ++ rtl_eee_enable(tp, false); + +- r8153_u2p3en(tp, false); ++ ret = r8153_phy_status(tp, PHY_STAT_LAN_ON); ++ if (ret < 0) ++ return; ++ WARN_ON_ONCE(ret != PHY_STAT_LAN_ON); + +- /* MSC timer = 0xfff * 8ms = 32760 ms */ +- ocp_write_word(tp, MCU_TYPE_USB, USB_MSC_TIMER, 0x0fff); ++ /* PFM mode */ ++ ocp_word_clr_bits(tp, MCU_TYPE_PLA, PLA_PHY_PWR, PFM_PWM_SWITCH); + +- /* U1/U2/L1 idle timer. 500 us */ +- ocp_write_word(tp, MCU_TYPE_USB, USB_U1U2_TIMER, 500); ++ /* Advanced Power Saving parameter */ ++ ocp_reg_set_bits(tp, 0xa430, BIT(0) | BIT(1)); + +- r8153b_power_cut_en(tp, false); +- r8156_ups_en(tp, false); +- r8153_queue_wake(tp, false); +- rtl_runtime_suspend_enable(tp, false); ++ /* aldpsce force mode */ ++ ocp_reg_clr_bits(tp, 0xa44a, BIT(2)); + +- if (tp->udev->speed >= USB_SPEED_SUPER) +- r8153b_u1u2en(tp, true); ++ switch (tp->version) { ++ case RTL_VER_16: ++ /* XG_INRX parameter */ ++ sram_write_w0w1(tp, 0x8183, 0xff00, 0x5900); ++ ocp_reg_set_bits(tp, 0xa654, BIT(11)); ++ ocp_reg_set_bits(tp, 0xb648, BIT(14)); ++ ocp_reg_clr_bits(tp, 0xad2c, BIT(15)); ++ ocp_reg_set_bits(tp, 0xad94, BIT(5)); ++ ocp_reg_set_bits(tp, 0xada0, BIT(1)); ++ ocp_reg_w0w1(tp, 0xae06, 0xfc00, 0x7c00); ++ sram2_write_w0w1(tp, 0x8647, 0xff00, 0xe600); ++ sram2_write_w0w1(tp, 0x8036, 0xff00, 0x3000); ++ sram2_write_w0w1(tp, 0x8078, 0xff00, 0x3000); ++ ++ /* green mode */ ++ sram2_write_w0w1(tp, 0x89e9, 0xff00, 0); ++ sram2_write_w0w1(tp, 0x8ffd, 0xff00, 0x0100); ++ sram2_write_w0w1(tp, 0x8ffe, 0xff00, 0x0200); ++ sram2_write_w0w1(tp, 0x8fff, 0xff00, 0x0400); ++ ++ /* recognize AQC/Bcom function */ ++ sram_write_w0w1(tp, 0x8018, 0xff00, 0x7700); ++ ocp_reg_write(tp, OCP_SRAM_ADDR, 0x8f9c); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0005); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0000); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x00ed); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0502); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0b00); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd401); ++ sram_write_w0w1(tp, 0x8fa8, 0xff00, 0x2900); ++ ++ /* RFI_corr_thd 5g */ ++ sram2_write_w0w1(tp, 0x814b, 0xff00, 0x1100); ++ sram2_write_w0w1(tp, 0x814d, 0xff00, 0x1100); ++ sram2_write_w0w1(tp, 0x814f, 0xff00, 0x0b00); ++ sram2_write_w0w1(tp, 0x8142, 0xff00, 0x0100); ++ sram2_write_w0w1(tp, 0x8144, 0xff00, 0x0100); ++ sram2_write_w0w1(tp, 0x8150, 0xff00, 0x0100); ++ ++ /* RFI_corr_thd 2p5g */ ++ sram2_write_w0w1(tp, 0x8118, 0xff00, 0x0700); ++ sram2_write_w0w1(tp, 0x811a, 0xff00, 0x0700); ++ sram2_write_w0w1(tp, 0x811c, 0xff00, 0x0500); ++ sram2_write_w0w1(tp, 0x810f, 0xff00, 0x0100); ++ sram2_write_w0w1(tp, 0x8111, 0xff00, 0x0100); ++ sram2_write_w0w1(tp, 0x811d, 0xff00, 0x0100); ++ ++ /* RFI parameter */ ++ ocp_reg_clr_bits(tp, 0xad1c, BIT(8)); ++ ocp_reg_w0w1(tp, 0xade8, 0xffc0, 0x1400); ++ sram2_write_w0w1(tp, 0x864b, 0xff00, 0x9d00); ++ sram2_write_w0w1(tp, 0x862c, 0xff00, 0x1200); ++ ocp_reg_write(tp, OCP_SRAM_ADDR, 0x8566); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x003f); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x3f02); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x023c); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x3b0a); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1c00); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0000); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0000); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0000); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0000); ++ ++ /* RFI-color noise gen parameter 5g */ ++ ocp_reg_set_bits(tp, 0xad9c, BIT(5)); ++ sram2_write_w0w1(tp, 0x8122, 0xff00, 0x0c00); ++ ocp_reg_write(tp, OCP_SRAM2_ADDR, 0x82c8); ++ ocp_reg_write(tp, OCP_SRAM2_DATA, 0x03ed); ++ ocp_reg_write(tp, OCP_SRAM2_DATA, 0x03ff); ++ ocp_reg_write(tp, OCP_SRAM2_DATA, 0x0009); ++ ocp_reg_write(tp, OCP_SRAM2_DATA, 0x03fe); ++ ocp_reg_write(tp, OCP_SRAM2_DATA, 0x000b); ++ ocp_reg_write(tp, OCP_SRAM2_DATA, 0x0021); ++ ocp_reg_write(tp, OCP_SRAM2_DATA, 0x03f7); ++ ocp_reg_write(tp, OCP_SRAM2_DATA, 0x03b8); ++ ocp_reg_write(tp, OCP_SRAM2_DATA, 0x03e0); ++ ocp_reg_write(tp, OCP_SRAM2_DATA, 0x0049); ++ ocp_reg_write(tp, OCP_SRAM2_DATA, 0x0049); ++ ocp_reg_write(tp, OCP_SRAM2_DATA, 0x03e0); ++ ocp_reg_write(tp, OCP_SRAM2_DATA, 0x03b8); ++ ocp_reg_write(tp, OCP_SRAM2_DATA, 0x03f7); ++ ocp_reg_write(tp, OCP_SRAM2_DATA, 0x0021); ++ ocp_reg_write(tp, OCP_SRAM2_DATA, 0x000b); ++ ocp_reg_write(tp, OCP_SRAM2_DATA, 0x03fe); ++ ocp_reg_write(tp, OCP_SRAM2_DATA, 0x0009); ++ ocp_reg_write(tp, OCP_SRAM2_DATA, 0x03ff); ++ ocp_reg_write(tp, OCP_SRAM2_DATA, 0x03ed); ++ ++ /* RFI-color noise gen parameter 2p5g */ ++ sram2_write_w0w1(tp, 0x80ef, 0xff00, 0x0c00); ++ ocp_reg_write(tp, OCP_SRAM2_ADDR, 0x82a0); ++ ocp_reg_write(tp, OCP_SRAM2_DATA, 0x000e); ++ ocp_reg_write(tp, OCP_SRAM2_DATA, 0x03fe); ++ ocp_reg_write(tp, OCP_SRAM2_DATA, 0x03ed); ++ ocp_reg_write(tp, OCP_SRAM2_DATA, 0x0006); ++ ocp_reg_write(tp, OCP_SRAM2_DATA, 0x001a); ++ ocp_reg_write(tp, OCP_SRAM2_DATA, 0x03f1); ++ ocp_reg_write(tp, OCP_SRAM2_DATA, 0x03d8); ++ ocp_reg_write(tp, OCP_SRAM2_DATA, 0x0023); ++ ocp_reg_write(tp, OCP_SRAM2_DATA, 0x0054); ++ ocp_reg_write(tp, OCP_SRAM2_DATA, 0x0322); ++ ocp_reg_write(tp, OCP_SRAM2_DATA, 0x00dd); ++ ocp_reg_write(tp, OCP_SRAM2_DATA, 0x03ab); ++ ocp_reg_write(tp, OCP_SRAM2_DATA, 0x03dc); ++ ocp_reg_write(tp, OCP_SRAM2_DATA, 0x0027); ++ ocp_reg_write(tp, OCP_SRAM2_DATA, 0x000e); ++ ocp_reg_write(tp, OCP_SRAM2_DATA, 0x03e5); ++ ocp_reg_write(tp, OCP_SRAM2_DATA, 0x03f9); ++ ocp_reg_write(tp, OCP_SRAM2_DATA, 0x0012); ++ ocp_reg_write(tp, OCP_SRAM2_DATA, 0x0001); ++ ocp_reg_write(tp, OCP_SRAM2_DATA, 0x03f1); ++ ++ /* modify thermal speed down threshold */ ++ ocp_reg_w0w1(tp, 0xb54c, 0xffc0, 0x3700); ++ ++ /* XG compatibility modification */ ++ ocp_reg_set_bits(tp, 0xb648, BIT(6)); ++ sram2_write_w0w1(tp, 0x8082, 0xff00, 0x5d00); ++ sram2_write_w0w1(tp, 0x807c, 0xff00, 0x5000); ++ sram2_write_w0w1(tp, 0x809d, 0xff00, 0x5000); ++ break; ++ default: ++ break; ++ } + +- usb_enable_lpm(tp->udev); ++ if (rtl_phy_patch_request(tp, true, true)) ++ return; + +- r8156_mac_clk_spd(tp, true); ++ ocp_word_set_bits(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL4, EEE_SPDWN_EN); + +- ocp_word_clr_bits(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL3, +- PLA_MCU_SPDWN_EN); ++ ocp_reg_w0w1(tp, OCP_DOWN_SPEED, EN_EEE_100 | EN_EEE_1000, EN_10M_CLKDIV); + +- 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); ++ tp->ups_info._10m_ckdiv = true; ++ tp->ups_info.eee_plloff_100 = false; ++ tp->ups_info.eee_plloff_giga = false; + +- set_bit(GREEN_ETHERNET, &tp->flags); ++ ocp_reg_set_bits(tp, OCP_POWER_CFG, EEE_CLKDIV_EN); ++ tp->ups_info.eee_ckdiv = true; + +- /* rx aggregation */ +- ocp_word_clr_bits(tp, MCU_TYPE_USB, USB_USB_CTRL, +- RX_AGG_DISABLE | RX_ZERO_EN); ++ rtl_phy_patch_request(tp, false, true); + +- ocp_byte_set_bits(tp, MCU_TYPE_USB, USB_BMU_CONFIG, ACT_ODMA); ++ rtl_green_en(tp, test_bit(GREEN_ETHERNET, &tp->flags)); + +- r8156_mdio_force_mode(tp); +- rtl_tally_reset(tp); ++ ocp_reg_clr_bits(tp, 0xa428, BIT(9)); ++ ocp_reg_clr_bits(tp, 0xa5ea, BIT(0) | BIT(1)); ++ tp->ups_info.lite_mode = 0; + +- tp->coalesce = 15000; /* 15 us */ ++ 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 r8156b_init(struct r8152 *tp) ++static void r8156_init(struct r8152 *tp) + { ++ u32 ocp_data; + u16 data; + int i; + + if (test_bit(RTL8152_INACCESSIBLE, &tp->flags)) + return; + ++ if (tp->version == RTL_VER_16) { ++ 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_write_word(tp, MCU_TYPE_USB, USB_SPEED_OPTION, 0); ++ if (tp->version != RTL_VER_16) ++ 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); + +- ocp_word_set_bits(tp, MCU_TYPE_USB, USB_U2P3_CTRL, RX_DETECT8); ++ if (tp->version >= RTL_VER_12 && tp->version <= RTL_VER_15) ++ ocp_word_set_bits(tp, MCU_TYPE_USB, USB_U2P3_CTRL, RX_DETECT8); + + r8153b_u1u2en(tp, false); + + switch (tp->version) { + case RTL_VER_13: + case RTL_VER_15: ++ case RTL_VER_16: + r8156b_wait_loading_flash(tp); + break; + default: +@@ -7761,14 +8210,22 @@ static void r8156b_init(struct r8152 *tp + data = r8153_phy_status(tp, 0); + if (data == PHY_STAT_EXT_INIT) { + ocp_reg_clr_bits(tp, 0xa468, BIT(3) | BIT(1)); +- ocp_reg_clr_bits(tp, 0xa466, BIT(0)); ++ if (tp->version >= RTL_VER_12) ++ ocp_reg_clr_bits(tp, 0xa466, BIT(0)); + } + +- r8152_mdio_test_and_clr_bit(tp, MII_BMCR, BMCR_PDOWN); ++ data = r8152_mdio_read(tp, MII_BMCR); ++ if (data & BMCR_PDOWN) { ++ data &= ~BMCR_PDOWN; ++ r8152_mdio_write(tp, MII_BMCR, data); ++ } + + data = r8153_phy_status(tp, PHY_STAT_LAN_ON); + +- r8153_u2p3en(tp, false); ++ if (tp->version == RTL_VER_16) ++ r8157_u2p3en(tp, false); ++ else ++ r8153_u2p3en(tp, false); + + /* MSC timer = 0xfff * 8ms = 32760 ms */ + ocp_write_word(tp, MCU_TYPE_USB, USB_MSC_TIMER, 0x0fff); +@@ -7776,7 +8233,11 @@ static void r8156b_init(struct r8152 *tp + /* U1/U2/L1 idle timer. 500 us */ + ocp_write_word(tp, MCU_TYPE_USB, USB_U1U2_TIMER, 500); + +- r8153b_power_cut_en(tp, false); ++ if (tp->version == RTL_VER_16) ++ r8157_power_cut_en(tp, false); ++ else ++ r8153b_power_cut_en(tp, false); ++ + r8156_ups_en(tp, false); + r8153_queue_wake(tp, false); + rtl_runtime_suspend_enable(tp, false); +@@ -7786,39 +8247,53 @@ static void r8156b_init(struct r8152 *tp + + usb_enable_lpm(tp->udev); + +- ocp_word_clr_bits(tp, MCU_TYPE_PLA, PLA_RCR, SLOT_EN); ++ if (tp->version >= RTL_VER_12 && tp->version <= 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); ++ 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)); ++ /* enable fc timer and set timer to 600 ms. */ ++ ocp_write_word(tp, MCU_TYPE_USB, USB_FC_TIMER, CTRL_TIMER_EN | (600 / 8)); + +- if (!(ocp_read_word(tp, MCU_TYPE_PLA, PLA_POL_GPIO_CTRL) & DACK_DET_EN)) +- ocp_word_w0w1(tp, MCU_TYPE_USB, USB_FW_CTRL, AUTO_SPEEDUP, +- FLOW_CTRL_PATCH_2); +- else +- ocp_word_clr_bits(tp, MCU_TYPE_USB, USB_FW_CTRL, AUTO_SPEEDUP); ++ ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_FW_CTRL); ++ if (!(ocp_read_word(tp, MCU_TYPE_PLA, PLA_POL_GPIO_CTRL) & DACK_DET_EN)) ++ ocp_data |= FLOW_CTRL_PATCH_2; ++ ocp_data &= ~AUTO_SPEEDUP; ++ ocp_write_word(tp, MCU_TYPE_USB, USB_FW_CTRL, ocp_data); + +- ocp_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); ++ } + + r8156_mac_clk_spd(tp, true); + +- ocp_word_clr_bits(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL3, +- PLA_MCU_SPDWN_EN); ++ if (tp->version != RTL_VER_16) ++ ocp_word_clr_bits(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL3, PLA_MCU_SPDWN_EN); + ++ ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_EXTRA_STATUS); + if (rtl8152_get_speed(tp) & LINK_STATUS) +- ocp_word_set_bits(tp, MCU_TYPE_PLA, PLA_EXTRA_STATUS, +- CUR_LINK_OK | POLL_LINK_CHG); ++ ocp_data |= CUR_LINK_OK; + else +- ocp_word_w0w1(tp, MCU_TYPE_PLA, PLA_EXTRA_STATUS, CUR_LINK_OK, +- POLL_LINK_CHG); ++ ocp_data &= ~CUR_LINK_OK; ++ ocp_data |= POLL_LINK_CHG; ++ ocp_write_word(tp, MCU_TYPE_PLA, PLA_EXTRA_STATUS, ocp_data); + + set_bit(GREEN_ETHERNET, &tp->flags); + +- /* rx aggregation */ +- ocp_word_clr_bits(tp, MCU_TYPE_USB, USB_USB_CTRL, +- RX_AGG_DISABLE | RX_ZERO_EN); ++ /* rx aggregation / 16 bytes Rx descriptor */ ++ if (tp->version == RTL_VER_16) ++ ocp_word_clr_bits(tp, MCU_TYPE_USB, USB_USB_CTRL, RX_AGG_DISABLE | RX_DESC_16B); ++ else ++ ocp_word_clr_bits(tp, MCU_TYPE_USB, USB_USB_CTRL, RX_AGG_DISABLE | RX_ZERO_EN); ++ ++ if (tp->version < RTL_VER_12) ++ ocp_byte_set_bits(tp, MCU_TYPE_USB, USB_BMU_CONFIG, ACT_ODMA); ++ ++ if (tp->version == 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)); ++ } + + r8156_mdio_force_mode(tp); + rtl_tally_reset(tp); +@@ -8969,6 +9444,11 @@ static void rtl8153_unload(struct r8152 + return; + + r8153_power_cut_en(tp, false); ++ ++ if (tp->version >= RTL_VER_16) { ++ /* Disable Interrupt Mitigation */ ++ ocp_byte_clr_bits(tp, MCU_TYPE_USB, 0xcf04, BIT(0) | BIT(1) | BIT(2) | BIT(7)); ++ } + } + + static void rtl8153b_unload(struct r8152 *tp) +@@ -8979,6 +9459,38 @@ static void rtl8153b_unload(struct r8152 + r8153b_power_cut_en(tp, false); + } + ++static int r8152_desc_init(struct r8152 *tp) ++{ ++ tp->rx_desc.size = sizeof(struct rx_desc); ++ tp->rx_desc.align = 8; ++ tp->rx_desc.vlan_tag = r8152_rx_vlan_tag; ++ tp->desc_ops.rx_csum = r8152_rx_csum; ++ tp->desc_ops.rx_len = r8152_rx_len; ++ tp->tx_desc.size = sizeof(struct tx_desc); ++ tp->tx_desc.align = 4; ++ tp->tx_desc.vlan_tag = r8152_tx_vlan_tag; ++ tp->desc_ops.tx_csum = r8152_tx_csum; ++ tp->desc_ops.tx_len = r8152_tx_len; ++ ++ return 0; ++} ++ ++static int r8157_desc_init(struct r8152 *tp) ++{ ++ tp->rx_desc.size = sizeof(struct rx_desc_v2); ++ tp->rx_desc.align = 16; ++ tp->rx_desc.vlan_tag = r8157_rx_vlan_tag; ++ tp->desc_ops.rx_csum = r8157_rx_csum; ++ tp->desc_ops.rx_len = r8157_rx_len; ++ tp->tx_desc.size = sizeof(struct tx_desc_v2); ++ tp->tx_desc.align = 16; ++ tp->tx_desc.vlan_tag = r8152_tx_vlan_tag; ++ tp->desc_ops.tx_csum = r8157_tx_csum; ++ tp->desc_ops.tx_len = r8157_tx_len; ++ ++ return 0; ++} ++ + static int rtl_ops_init(struct r8152 *tp) + { + struct rtl_ops *ops = &tp->rtl_ops; +@@ -9002,6 +9514,7 @@ static int rtl_ops_init(struct r8152 *tp + tp->rx_buf_sz = 16 * 1024; + tp->eee_en = true; + tp->eee_adv = MDIO_EEE_100TX; ++ r8152_desc_init(tp); + break; + + case RTL_VER_03: +@@ -9026,6 +9539,7 @@ static int rtl_ops_init(struct r8152 *tp + tp->rx_buf_sz = 32 * 1024; + tp->eee_en = true; + tp->eee_adv = MDIO_EEE_1000T | MDIO_EEE_100TX; ++ r8152_desc_init(tp); + break; + + case RTL_VER_08: +@@ -9045,6 +9559,7 @@ static int rtl_ops_init(struct r8152 *tp + tp->rx_buf_sz = 32 * 1024; + tp->eee_en = true; + tp->eee_adv = MDIO_EEE_1000T | MDIO_EEE_100TX; ++ r8152_desc_init(tp); + break; + + case RTL_VER_11: +@@ -9067,6 +9582,7 @@ static int rtl_ops_init(struct r8152 *tp + ops->change_mtu = rtl8156_change_mtu; + tp->rx_buf_sz = 48 * 1024; + tp->support_2500full = 1; ++ r8152_desc_init(tp); + break; + + case RTL_VER_12: +@@ -9077,8 +9593,8 @@ static int rtl_ops_init(struct r8152 *tp + tp->eee_en = true; + tp->eee_adv = MDIO_EEE_1000T | MDIO_EEE_100TX; + tp->eee_adv2 = MDIO_EEE_2_5GT; +- ops->init = r8156b_init; +- ops->enable = rtl8156b_enable; ++ ops->init = r8156_init; ++ ops->enable = rtl8156_enable; + ops->disable = rtl8153_disable; + ops->up = rtl8156_up; + ops->down = rtl8156_down; +@@ -9090,6 +9606,7 @@ static int rtl_ops_init(struct r8152 *tp + ops->autosuspend_en = rtl8156_runtime_enable; + ops->change_mtu = rtl8156_change_mtu; + tp->rx_buf_sz = 48 * 1024; ++ r8152_desc_init(tp); + break; + + case RTL_VER_14: +@@ -9108,6 +9625,29 @@ static int rtl_ops_init(struct r8152 *tp + tp->rx_buf_sz = 32 * 1024; + tp->eee_en = true; + tp->eee_adv = MDIO_EEE_1000T | MDIO_EEE_100TX; ++ r8152_desc_init(tp); ++ break; ++ ++ case RTL_VER_16: ++ tp->eee_en = true; ++ tp->eee_adv = MDIO_EEE_1000T | MDIO_EEE_100TX; ++ tp->eee_adv2 = MDIO_EEE_2_5GT | MDIO_EEE_5GT; ++ ops->init = r8156_init; ++ ops->enable = rtl8156_enable; ++ ops->disable = rtl8153_disable; ++ ops->up = rtl8156_up; ++ ops->down = rtl8156_down; ++ ops->unload = rtl8153_unload; ++ ops->eee_get = r8153_get_eee; ++ ops->eee_set = r8152_set_eee; ++ ops->in_nway = rtl8153_in_nway; ++ ops->hw_phy_cfg = r8157_hw_phy_cfg; ++ ops->autosuspend_en = rtl8157_runtime_enable; ++ ops->change_mtu = rtl8156_change_mtu; ++ tp->rx_buf_sz = 32 * 1024; ++ tp->support_2500full = 1; ++ tp->support_5000full = 1; ++ r8157_desc_init(tp); + break; + + default: +@@ -9260,6 +9800,9 @@ static u8 __rtl_get_hw_ver(struct usb_de + case 0x7420: + version = RTL_VER_15; + break; ++ case 0x1030: ++ version = RTL_VER_16; ++ break; + default: + version = RTL_VER_UNKNOWN; + dev_info(&udev->dev, "Unknown version 0x%04x\n", ocp_data); +@@ -9411,6 +9954,7 @@ static int rtl8152_probe_once(struct usb + case RTL_VER_12: + case RTL_VER_13: + case RTL_VER_15: ++ case RTL_VER_16: + netdev->max_mtu = size_to_mtu(16 * 1024); + break; + case RTL_VER_01: +@@ -9571,6 +10115,7 @@ static const struct usb_device_id rtl815 + { USB_DEVICE(VENDOR_ID_REALTEK, 0x8153) }, + { USB_DEVICE(VENDOR_ID_REALTEK, 0x8155) }, + { USB_DEVICE(VENDOR_ID_REALTEK, 0x8156) }, ++ { USB_DEVICE(VENDOR_ID_REALTEK, 0x8157) }, + + /* Microsoft */ + { USB_DEVICE(VENDOR_ID_MICROSOFT, 0x07ab) }, diff --git a/target/linux/generic/hack-6.18/760-net-usb-r8152-add-LED-configuration-from-OF.patch b/target/linux/generic/hack-6.18/760-net-usb-r8152-add-LED-configuration-from-OF.patch index 1948457a1ed..fa8ddeca246 100644 --- a/target/linux/generic/hack-6.18/760-net-usb-r8152-add-LED-configuration-from-OF.patch +++ b/target/linux/generic/hack-6.18/760-net-usb-r8152-add-LED-configuration-from-OF.patch @@ -22,8 +22,8 @@ Signed-off-by: David Bauer #include #include #include -@@ -7019,6 +7020,22 @@ static void rtl_tally_reset(struct r8152 - ocp_write_word(tp, MCU_TYPE_PLA, PLA_RSTTALLY, ocp_data); +@@ -7193,6 +7194,22 @@ static void rtl_tally_reset(struct r8152 + ocp_word_set_bits(tp, MCU_TYPE_PLA, PLA_RSTTALLY, TALLY_RESET); } +static int r8152_led_configuration(struct r8152 *tp) @@ -45,16 +45,16 @@ Signed-off-by: David Bauer static void r8152b_init(struct r8152 *tp) { u32 ocp_data; -@@ -7060,6 +7077,8 @@ static void r8152b_init(struct r8152 *tp - ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_USB_CTRL); - ocp_data &= ~(RX_AGG_DISABLE | RX_ZERO_EN); - ocp_write_word(tp, MCU_TYPE_USB, USB_USB_CTRL, ocp_data); +@@ -7225,6 +7242,8 @@ static void r8152b_init(struct r8152 *tp + /* enable rx aggregation */ + ocp_word_clr_bits(tp, MCU_TYPE_USB, USB_USB_CTRL, + RX_AGG_DISABLE | RX_ZERO_EN); + + r8152_led_configuration(tp); } static void r8153_init(struct r8152 *tp) -@@ -7200,6 +7219,8 @@ static void r8153_init(struct r8152 *tp) +@@ -7342,6 +7361,8 @@ static void r8153_init(struct r8152 *tp) tp->coalesce = COALESCE_SLOW; break; } @@ -63,7 +63,7 @@ Signed-off-by: David Bauer } static void r8153b_init(struct r8152 *tp) -@@ -7282,6 +7303,8 @@ static void r8153b_init(struct r8152 *tp +@@ -7412,6 +7433,8 @@ static void r8153b_init(struct r8152 *tp rtl_tally_reset(tp); tp->coalesce = 15000; /* 15 us */