--- /dev/null
+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)
--- /dev/null
+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;
--- /dev/null
+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;
--- /dev/null
+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);
--- /dev/null
+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);
+
--- /dev/null
+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);
--- /dev/null
+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;
--- /dev/null
+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) },
#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)
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;
}
}
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 */