[PATCH net-next 3/8] r8152: refactor rtl8156_enable, rtl8156_up, and rtl8156_down
From: Chih Kai Hsu <hidden>
Date: 2026-09-02 09:07:15
Also in:
linux-usb, lkml
Subsystem:
networking drivers, the rest, usb networking drivers · Maintainers:
Andrew Lunn, "David S. Miller", Eric Dumazet, Jakub Kicinski, Paolo Abeni, Linus Torvalds
Signed-off-by: Chih Kai Hsu <redacted> --- drivers/net/usb/r8152.c | 235 ++++++++++++++++++++++++++++++++-------- 1 file changed, 189 insertions(+), 46 deletions(-)
diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c
index 38e78b0f20b30..53835453913c8 100644
--- a/drivers/net/usb/r8152.c
+++ b/drivers/net/usb/r8152.c@@ -6440,31 +6440,16 @@ static int rtl8156_enable(struct r8152 *tp) if (test_bit(RTL8152_INACCESSIBLE, &tp->flags)) return -ENODEV; - if (tp->version < RTL_VER_12) - r8156_fc_parameter(tp); - + r8156_fc_parameter(tp); set_tx_qlen(tp); rtl_set_eee_plus(tp); - switch (tp->version) { - case RTL_VER_10: - case RTL_VER_11: - break; - default: - ocp_word_clr_bits(tp, MCU_TYPE_USB, USB_RX_AGGR_NUM, - RX_AGGR_NUM_MASK); - break; - } - r8153_set_rx_early_timeout(tp); r8153_set_rx_early_size(tp); 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);
@@ -6472,12 +6457,10 @@ static int rtl8156_enable(struct r8152 *tp) ocp_word_set_bits(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL4, IDLE_SPDWN_EN); - if (tp->version < RTL_VER_12) { - if (speed & _1000bps) - ocp_write_word(tp, MCU_TYPE_PLA, PLA_EEE_TXTWSYS, 0x11); - else if (speed & _500bps) - ocp_write_word(tp, MCU_TYPE_PLA, PLA_EEE_TXTWSYS, 0x3d); - } + if (speed & _1000bps) + ocp_write_word(tp, MCU_TYPE_PLA, PLA_EEE_TXTWSYS, 0x11); + else if (speed & _500bps) + ocp_write_word(tp, MCU_TYPE_PLA, PLA_EEE_TXTWSYS, 0x3d); if (tp->udev->speed == USB_SPEED_HIGH) { /* USB 0xb45e[3:0] l1_nyet_hird */
@@ -6502,6 +6485,67 @@ static void rtl8156_disable(struct r8152 *tp) 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) { + /* USB 0xb45e[3:0] l1_nyet_hird */ + if (is_flow_control(speed)) + ocp_word_w0w1(tp, MCU_TYPE_USB, USB_L1_CTRL, 0xf, 0xf); + else + ocp_word_w0w1(tp, MCU_TYPE_USB, USB_L1_CTRL, 0xf, 0x1); + } + + ocp_word_clr_bits(tp, MCU_TYPE_USB, USB_FW_TASK, FC_PATCH_TASK); + usleep_range(1000, 2000); + ocp_word_set_bits(tp, MCU_TYPE_USB, USB_FW_TASK, FC_PATCH_TASK); + + return rtl_enable(tp); +} + +static int rtl8157_enable(struct r8152 *tp) +{ + u16 speed; + + if (test_bit(RTL8152_INACCESSIBLE, &tp->flags)) + return -ENODEV; + + set_tx_qlen(tp); + rtl_set_eee_plus(tp); + + ocp_word_clr_bits(tp, MCU_TYPE_USB, USB_RX_AGGR_NUM, RX_AGGR_NUM_MASK); + + r8153_set_rx_early_timeout(tp); + r8153_set_rx_early_size(tp); + + speed = rtl8152_get_speed(tp); + rtl_set_ifg(tp, speed); + + return rtl_enable(tp); +} + static int rtl8152_set_speed(struct r8152 *tp, u8 autoneg, u32 speed, u8 duplex, u32 advertising) {
@@ -6862,8 +6906,7 @@ static void rtl8156_up(struct r8152 *tp) return; r8153b_u1u2en(tp, false); - if (tp->version < RTL_VER_16) - r8153_u2p3en(tp, false); + r8153_u2p3en(tp, false); r8153_aldps_en(tp, false); rxdy_gated_en(tp, true);
@@ -6876,8 +6919,7 @@ 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_RCR1, BIT(3)); ocp_word_clr_bits(tp, MCU_TYPE_PLA, PLA_SFF_STS_7, MCU_BORW_EN);
@@ -6899,11 +6941,11 @@ static void rtl8156_up(struct r8152 *tp) 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_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_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);
@@ -6913,10 +6955,19 @@ static void rtl8156_up(struct r8152 *tp) } r8153_aldps_en(tp, true); - if (tp->version < RTL_VER_16) - r8153_u2p3en(tp, true); + r8153_u2p3en(tp, true); - if (tp->version < RTL_VER_16 && tp->udev->speed >= USB_SPEED_SUPER) + switch (tp->version) { + case RTL_VER_13: + case RTL_VER_15: + /* Enable Clear_SDR */ + ocp_word_set_bits(tp, MCU_TYPE_USB, 0xd3ca, BIT(15)); + break; + default: + break; + } + + if (tp->udev->speed >= USB_SPEED_SUPER) r8153b_u1u2en(tp, true); }
@@ -6929,12 +6980,9 @@ static void rtl8156_down(struct r8152 *tp) ocp_word_set_bits(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL3, PLA_MCU_SPDWN_EN); - r8153b_u1u2en(tp, false); - if (tp->version < RTL_VER_16) { - r8153_u2p3en(tp, false); - r8153b_power_cut_en(tp, false); - } + r8153_u2p3en(tp, false); + r8153b_power_cut_en(tp, false); r8153_aldps_en(tp, false); ocp_byte_clr_bits(tp, MCU_TYPE_PLA, PLA_OOB_CTRL, NOW_IS_OOB);
@@ -6956,7 +7004,102 @@ static void rtl8156_down(struct r8152 *tp) */ ocp_write_word(tp, MCU_TYPE_PLA, PLA_TEREDO_WAKE_BASE, 0x00ff); - ocp_byte_set_bits(tp, MCU_TYPE_PLA, PLA_OOB_CTRL, NOW_IS_OOB); + ocp_word_set_bits(tp, MCU_TYPE_PLA, PLA_BDC_CR, ALDPS_PROXY_MODE); + + ocp_byte_set_bits(tp, MCU_TYPE_PLA, PLA_OOB_CTRL, + NOW_IS_OOB | DIS_MCU_CLROOB); + + ocp_word_set_bits(tp, MCU_TYPE_PLA, PLA_SFF_STS_7, MCU_BORW_EN); + + rtl_rx_vlan_en(tp, true); + rxdy_gated_en(tp, false); + + ocp_dword_set_bits(tp, MCU_TYPE_PLA, PLA_RCR, + RCR_APM | RCR_AM | RCR_AB); + + r8153_aldps_en(tp, true); +} + +static void rtl8157_up(struct r8152 *tp) +{ + if (test_bit(RTL8152_INACCESSIBLE, &tp->flags)) + return; + + r8153b_u1u2en(tp, false); + r8153_aldps_en(tp, false); + + rxdy_gated_en(tp, true); + r8153_teredo_off(tp); + + ocp_dword_clr_bits(tp, MCU_TYPE_PLA, PLA_RCR, RCR_ACPT_ALL); + + rtl8152_nic_reset(tp); + rtl_reset_bmu(tp); + + ocp_byte_clr_bits(tp, MCU_TYPE_PLA, PLA_OOB_CTRL, NOW_IS_OOB); + + ocp_word_clr_bits(tp, MCU_TYPE_PLA, PLA_RCR1, BIT(3)); + + ocp_word_clr_bits(tp, MCU_TYPE_PLA, PLA_SFF_STS_7, MCU_BORW_EN); + + rtl_rx_vlan_en(tp, tp->netdev->features & NETIF_F_HW_VLAN_CTAG_RX); + + rtl8156_change_mtu(tp); + + /* share FIFO settings */ + ocp_word_w0w1(tp, MCU_TYPE_PLA, PLA_RXFIFO_FULL, RXFIFO_FULL_MASK, + 0x08); + + ocp_word_clr_bits(tp, MCU_TYPE_USB, USB_SPEED_OPTION, + RG_PWRDN_EN | ALL_SPEED_OFF); + + ocp_write_dword(tp, MCU_TYPE_USB, USB_RX_BUF_TH, 0x00600400); + + if (tp->saved_wolopts != __rtl_get_wol(tp)) { + netif_warn(tp, ifup, tp->netdev, "wol setting is changed\n"); + __rtl_set_wol(tp, tp->saved_wolopts); + } + + r8153_aldps_en(tp, true); + + /* Clear_SDR */ + ocp_byte_set_bits(tp, MCU_TYPE_USB, 0xd378, BIT(7)); + ocp_word_clr_bits(tp, MCU_TYPE_USB, 0xcd06, BIT(15)); +} + +static void rtl8157_down(struct r8152 *tp) +{ + if (test_bit(RTL8152_INACCESSIBLE, &tp->flags)) { + rtl_drop_queued_tx(tp); + return; + } + + r8153b_u1u2en(tp, false); + r8153_aldps_en(tp, false); + + ocp_byte_clr_bits(tp, MCU_TYPE_PLA, PLA_OOB_CTRL, NOW_IS_OOB); + + /* RX FIFO settings for OOB */ + ocp_write_word(tp, MCU_TYPE_PLA, PLA_RXFIFO_FULL, 64 / 16); + ocp_write_word(tp, MCU_TYPE_PLA, PLA_RX_FIFO_FULL, 1024 / 16); + ocp_write_word(tp, MCU_TYPE_PLA, PLA_RX_FIFO_EMPTY, 4096 / 16); + + rtl_disable(tp); + rtl_reset_bmu(tp); + + ocp_write_word(tp, MCU_TYPE_PLA, PLA_RMS, 1526); + ocp_write_byte(tp, MCU_TYPE_PLA, PLA_MTPS, 10 * 1024 / 64); + + /* Clear teredo wake event. bit[15:8] is the teredo wakeup + * type. Set it to zero. bits[7:0] are the W1C bits about + * the events. Set them to all 1 to clear them. + */ + ocp_write_word(tp, MCU_TYPE_PLA, PLA_TEREDO_WAKE_BASE, 0x00ff); + + ocp_word_set_bits(tp, MCU_TYPE_PLA, PLA_BDC_CR, ALDPS_PROXY_MODE); + + ocp_byte_set_bits(tp, MCU_TYPE_PLA, PLA_OOB_CTRL, + NOW_IS_OOB | DIS_MCU_CLROOB); ocp_word_set_bits(tp, MCU_TYPE_PLA, PLA_SFF_STS_7, MCU_BORW_EN);
@@ -10142,7 +10285,7 @@ static int rtl_ops_init(struct r8152 *tp) tp->eee_adv = MDIO_EEE_1000T | MDIO_EEE_100TX; tp->eee_adv2 = MDIO_EEE_2_5GT; ops->init = r8156b_init; - ops->enable = rtl8156_enable; + ops->enable = rtl8156b_enable; ops->disable = rtl8153_disable; ops->up = rtl8156_up; ops->down = rtl8156_down;
@@ -10181,10 +10324,10 @@ static int rtl_ops_init(struct r8152 *tp) tp->eee_adv = MDIO_EEE_1000T | MDIO_EEE_100TX; tp->eee_adv2 = MDIO_EEE_2_5GT | MDIO_EEE_5GT; ops->init = r8157_init; - ops->enable = rtl8156_enable; + ops->enable = rtl8157_enable; ops->disable = rtl8153_disable; - ops->up = rtl8156_up; - ops->down = rtl8156_down; + ops->up = rtl8157_up; + ops->down = rtl8157_down; ops->unload = rtl8153_unload; ops->eee_get = r8153_get_eee; ops->eee_set = r8152_set_eee;
@@ -10204,10 +10347,10 @@ static int rtl_ops_init(struct r8152 *tp) tp->eee_adv = MDIO_EEE_100TX | MDIO_EEE_1000T | MDIO_EEE_10GT; tp->eee_adv2 = MDIO_EEE_2_5GT | MDIO_EEE_5GT; ops->init = r8159_init; - ops->enable = rtl8156_enable; + ops->enable = rtl8157_enable; ops->disable = rtl8153_disable; - ops->up = rtl8156_up; - ops->down = rtl8156_down; + ops->up = rtl8157_up; + ops->down = rtl8157_down; ops->unload = rtl8153_unload; ops->eee_get = r8153_get_eee; ops->eee_set = r8152_set_eee;
--
2.34.1