]> git.ipfire.org Git - thirdparty/openwrt.git/commitdiff
kernel: backport RTL8157 support to 6.18 23088/head
authorAleksander Jan Bajkowski <olek2@wp.pl>
Fri, 24 Apr 2026 20:35:44 +0000 (22:35 +0200)
committerHauke Mehrtens <hauke@hauke-m.de>
Sun, 26 Apr 2026 07:57:50 +0000 (09:57 +0200)
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 <olek2@wp.pl>
Link: https://github.com/openwrt/openwrt/pull/23088
Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
target/linux/generic/backport-6.18/740-v6.19-r8152-Advertise-software-timestamp-information.patch [new file with mode: 0644]
target/linux/generic/backport-6.18/741-v7.1-r8152-Add-2500baseT-EEE-status-configuration-support.patch [new file with mode: 0644]
target/linux/generic/backport-6.18/742-v7.1-r8152-fix-incorrect-register-write-to-USB_UPHY_XTAL.patch [new file with mode: 0644]
target/linux/generic/backport-6.18/743-v7.1-r8152-add-helper-functions-for-PLA-USB-OCP-registers.patch [new file with mode: 0644]
target/linux/generic/backport-6.18/744-v7.1-r8152-add-helper-functions-for-PHY-OCP-registers.patch [new file with mode: 0644]
target/linux/generic/backport-6.18/745-v7.1-r8152-Add-helper-functions-for-SRAM2.patch [new file with mode: 0644]
target/linux/generic/backport-6.18/746-v7.1-r8152-Add-support-for-5Gbit-Link-Speeds-and-EEE.patch [new file with mode: 0644]
target/linux/generic/backport-6.18/747-v7.1-r8152-Add-support-for-the-RTL8157-hardware.patch [new file with mode: 0644]
target/linux/generic/hack-6.18/760-net-usb-r8152-add-LED-configuration-from-OF.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 (file)
index 0000000..5fe99fe
--- /dev/null
@@ -0,0 +1,27 @@
+From a8e846b8d93de748485653dd8a6a8efd8f5d7613 Mon Sep 17 00:00:00 2001
+From: Abhishek Rawal <rawal.abhishek92@gmail.com>
+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 <rawal.abhishek92@gmail.com>
+Reviewed-by: Jamie Bainbridge <jamie.bainbridge@gmail.com>
+Reviewed-by: Vadim Fedorenko <vadim.fedorenko@linux.dev>
+Link: https://patch.msgid.link/20251014055234.46527-1-rawal.abhishek92@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ 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 (file)
index 0000000..39c573a
--- /dev/null
@@ -0,0 +1,148 @@
+From e8e83b67960c20a9e60d4181631509d59f03488b Mon Sep 17 00:00:00 2001
+From: Birger Koblitz <mail@birger-koblitz.de>
+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 <mail@birger-koblitz.de>
+Link: https://patch.msgid.link/20260224-b4-eee2g5-v2-1-cf5c83df036e@birger-koblitz.de
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ 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 (file)
index 0000000..1dee906
--- /dev/null
@@ -0,0 +1,31 @@
+From 48afd5124fd6129c46fd12cb06155384b1c4a0c4 Mon Sep 17 00:00:00 2001
+From: Chih Kai Hsu <hsu.chih.kai@realtek.com>
+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 <hsu.chih.kai@realtek.com>
+Reviewed-by: Hayes Wang <hayeswang@realtek.com>
+Link: https://patch.msgid.link/20260326073925.32976-454-nic_swsd@realtek.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+---
+ 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 (file)
index 0000000..1d6d9f6
--- /dev/null
@@ -0,0 +1,2182 @@
+From d16133f177fea620d6b413990683b6a8b2641be5 Mon Sep 17 00:00:00 2001
+From: Chih Kai Hsu <hsu.chih.kai@realtek.com>
+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 <hsu.chih.kai@realtek.com>
+Reviewed-by: Hayes Wang <hayeswang@realtek.com>
+Link: https://patch.msgid.link/20260326073925.32976-455-nic_swsd@realtek.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+---
+ 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 (file)
index 0000000..d0abdbe
--- /dev/null
@@ -0,0 +1,1127 @@
+From 7db154aa58e18bb663cc317f0b62631f8b3d2b87 Mon Sep 17 00:00:00 2001
+From: Chih Kai Hsu <hsu.chih.kai@realtek.com>
+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 <hsu.chih.kai@realtek.com>
+Reviewed-by: Hayes Wang <hayeswang@realtek.com>
+Link: https://patch.msgid.link/20260326073925.32976-456-nic_swsd@realtek.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+---
+ 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 (file)
index 0000000..c9d2b1c
--- /dev/null
@@ -0,0 +1,252 @@
+From 86f5dd4e0ff282a0acf1f058e947fd5f4ba58a9d Mon Sep 17 00:00:00 2001
+From: Chih Kai Hsu <hsu.chih.kai@realtek.com>
+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 <hsu.chih.kai@realtek.com>
+Reviewed-by: Hayes Wang <hayeswang@realtek.com>
+Link: https://patch.msgid.link/20260401115542.34601-1-nic_swsd@realtek.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ 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 (file)
index 0000000..49bac39
--- /dev/null
@@ -0,0 +1,235 @@
+From ebe5fd2ed20af5ae176dd41dd4a85a3cdc738b8a Mon Sep 17 00:00:00 2001
+From: Birger Koblitz <mail@birger-koblitz.de>
+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 <mail@birger-koblitz.de>
+Link: https://patch.msgid.link/20260404-rtl8157_next-v7-1-039121318f23@birger-koblitz.de
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+---
+ 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 (file)
index 0000000..459c2db
--- /dev/null
@@ -0,0 +1,1553 @@
+From fd3c7d080df53136c7e7e37f753fb7bd4640ca42 Mon Sep 17 00:00:00 2001
+From: Birger Koblitz <mail@birger-koblitz.de>
+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 <mail@birger-koblitz.de>
+Link: https://patch.msgid.link/20260404-rtl8157_next-v7-2-039121318f23@birger-koblitz.de
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+---
+ 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) },
index 1948457a1ed0db0eff3dede64ffb447f25306b09..fa8ddeca24653ed0de02083614820d3d1ee5d08d 100644 (file)
@@ -22,8 +22,8 @@ Signed-off-by: David Bauer <mail@david-bauer.net>
  #include <linux/crc32.h>
  #include <linux/if_vlan.h>
  #include <linux/uaccess.h>
-@@ -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 <mail@david-bauer.net>
  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 <mail@david-bauer.net>
  }
  
  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 */