public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH net-next v3 0/3] r8152: Add support for the RTL8159 10Gbit USB Ethernet chip
@ 2026-05-02  4:50 Birger Koblitz
  2026-05-02  4:50 ` [PATCH net-next v3 1/3] r8152: Add support for 10Gbit Link Speeds and EEE Birger Koblitz
                   ` (2 more replies)
  0 siblings, 3 replies; 6+ messages in thread
From: Birger Koblitz @ 2026-05-02  4:50 UTC (permalink / raw)
  To: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni
  Cc: linux-usb, netdev, linux-kernel, Chih Kai Hsu, Birger Koblitz,
	Andrew Lunn, Aleksander Jan Bajkowski

Add support for the RTL8159, which is a 10GBit USB-Ethernet adapter
chip in the RTL815x family of chips.

The RTL8159 re-uses the frame descriptor format and SRAM2 access introduced
with the RTL8157 as well as most of the setup and PM logic of the RTL8157.

The module was tested with a Lekuo DR59R11 USB-C 10GbE Ethernet Adapter:
[ 2502.906947] usb 2-1: new SuperSpeed USB device number 3 using xhci_hcd
[ 2502.927859] usb 2-1: New USB device found, idVendor=0bda, idProduct=815a, bcdDevice=30.00
[ 2502.927867] usb 2-1: New USB device strings: Mfr=1, Product=2, SerialNumber=7
[ 2502.927871] usb 2-1: Product: USB 10/100/1G/2.5G/5G/10G LAN
[ 2502.927873] usb 2-1: Manufacturer: Realtek
[ 2502.927875] usb 2-1: SerialNumber: 000388C9B3B5XXXX
[ 2503.063745] r8152-cfgselector 2-1: reset SuperSpeed USB device number 3 using xhci_hcd
[ 2503.123876] r8152 2-1:1.0: Requesting firmware: rtl_nic/rtl8159-1.fw
[ 2503.126267] r8152 2-1:1.0: PHY firmware installed 0 to be loaded: 20
[ 2503.156265] r8152 2-1:1.0: load rtl8159-1 v1 2026/01/01 successfully
[ 2503.270729] r8152 2-1:1.0 eth0: v1.12.13
[ 2503.289349] r8152 2-1:1.0 enx88c9b3b5xxxx: renamed from eth0
[ 2507.777055] r8152 2-1:1.0 enx88c9b3b5xxxx: carrier on

The RTL8159 adapter was tested against an AQC107 PCIe-card supporting
10GBit/s and an RTL8157 5Gbit USB-Ethernet adapter supporting 5GBit/s for
performance, link speed and EEE negotiation. Using USB3.2 Gen 2 (20GBit) with
the RTL8159 USB adapter and running iperf3 against the AQC107 PCIe
card resulted in 8.96 Gbits/sec transfer speed.

The code is based on the out-of-tree r8152 driver published by Realtek under
the GPL.

The RTL8159 requires firmware for the PHY in order to achieve a 10GBit link
speed. Without firmware, only 5GBit were achieved. The firmware can be
extracted from the out-of-tree r8152 driver-code where it is stored in the
ram17 u8-array. Code is added to use the existing firmware upload mechanism
of the driver for the RTL8157/9 PHY firmware code. The firmware will be
submitted separately to linux-firmware.

Signed-off-by: Birger Koblitz <mail@birger-koblitz.de>
---
Changes in v3:
- Various references to RTL8157 in the commit description changed
  to RTL8159
- Fix incorrect use of OCP_EEE_ADV2 register for 10GBit 
- Fix various instances where a gate on RTL_VER_16 was not extended
  to RTL_VER_17, although RTL8159 needs the same code-path as RTL8157
- Explain use of 0x815a device-ID for RTL8159 in commit message
- Extend poll-timeout for backup-restore to 20ms
- Drop patch for IRQ mitigation 
- Link to v2: https://lore.kernel.org/r/20260429-rtl8159_net_next-v2-0-bab3cd4e4c66@birger-koblitz.de

Changes in v2:
- Correct formatting of comments
- Order case statement values correctly
- Add error message when backup-restore fails
- Correct commit message of support for firmware upload
- Link to v1: https://lore.kernel.org/r/20260428-rtl8159_net_next-v1-0-52d03927b46f@birger-koblitz.de

---
Birger Koblitz (3):
      r8152: Add support for 10Gbit Link Speeds and EEE
      r8152: Add support for the RTL8159 chip
      r8152: Add firmware upload capability for RTL8157/RTL8159

 drivers/net/usb/r8152.c | 340 +++++++++++++++++++++++++++++++++++++++++++++---
 1 file changed, 321 insertions(+), 19 deletions(-)
---
base-commit: 0f19519fdd22bc0f5429377da3a52327c5eee166
change-id: 20260427-rtl8159_net_next-4f778a614fa7

Best regards,
-- 
Birger Koblitz <mail@birger-koblitz.de>


^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH net-next v3 1/3] r8152: Add support for 10Gbit Link Speeds and EEE
  2026-05-02  4:50 [PATCH net-next v3 0/3] r8152: Add support for the RTL8159 10Gbit USB Ethernet chip Birger Koblitz
@ 2026-05-02  4:50 ` Birger Koblitz
  2026-05-02  4:50 ` [PATCH net-next v3 2/3] r8152: Add support for the RTL8159 chip Birger Koblitz
  2026-05-02  4:50 ` [PATCH net-next v3 3/3] r8152: Add firmware upload capability for RTL8157/RTL8159 Birger Koblitz
  2 siblings, 0 replies; 6+ messages in thread
From: Birger Koblitz @ 2026-05-02  4:50 UTC (permalink / raw)
  To: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni
  Cc: linux-usb, netdev, linux-kernel, Chih Kai Hsu, Birger Koblitz,
	Andrew Lunn, Aleksander Jan Bajkowski

The RTL8159 supports 10GBit Link speeds. Add support for this speed
in the setup and setting/getting through ethtool. Also add 10GBit EEE.
Add functionality for setup and ethtool get/set methods.

Signed-off-by: Birger Koblitz <mail@birger-koblitz.de>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Tested-by: Aleksander Jan Bajkowski <olek2@wp.pl>
---
 drivers/net/usb/r8152.c | 53 ++++++++++++++++++++++++++++++++++++++++++++++---
 1 file changed, 50 insertions(+), 3 deletions(-)

diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c
index ae834876aa1acc7a9af08a4c01b7a984c4ab8433..05abfab1df94a571347196bfce7c232865e1058e 100644
--- a/drivers/net/usb/r8152.c
+++ b/drivers/net/usb/r8152.c
@@ -621,6 +621,7 @@ enum spd_duplex {
 	FORCE_1000M_FULL,
 	NWAY_2500M_FULL,
 	NWAY_5000M_FULL,
+	NWAY_10000M_FULL,
 };
 
 /* OCP_ALDPS_CONFIG */
@@ -742,6 +743,7 @@ enum spd_duplex {
 #define BP4_SUPER_ONLY		0x1578	/* RTL_VER_04 only */
 
 enum rtl_register_content {
+	_10000bps	= BIT(14),
 	_5000bps	= BIT(12),
 	_2500bps	= BIT(10),
 	_1250bps	= BIT(9),
@@ -757,6 +759,8 @@ 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_speed_10000(_speed)	(((_speed) & (_10000bps | LINK_STATUS)) \
+				 == (_10000bps | LINK_STATUS))
 #define is_flow_control(_speed)	(((_speed) & (_tx_flow | _rx_flow)) == (_tx_flow | _rx_flow))
 
 #define RTL8152_MAX_TX		4
@@ -1008,6 +1012,7 @@ struct r8152 {
 
 	u32 support_2500full:1;
 	u32 support_5000full:1;
+	u32 support_10000full:1;
 	u32 lenovo_macpassthru:1;
 	u32 dell_tb_rx_agg_bug:1;
 	u16 ocp_base;
@@ -1260,6 +1265,7 @@ enum tx_csum_stat {
 #define RTL_ADVERTISED_1000_FULL		BIT(5)
 #define RTL_ADVERTISED_2500_FULL		BIT(6)
 #define RTL_ADVERTISED_5000_FULL		BIT(7)
+#define RTL_ADVERTISED_10000_FULL		BIT(8)
 
 /* 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.
@@ -6513,6 +6519,9 @@ static int rtl8152_set_speed(struct r8152 *tp, u8 autoneg, u32 speed, u8 duplex,
 
 			if (tp->support_5000full)
 				support |= RTL_ADVERTISED_5000_FULL;
+
+			if (tp->support_10000full)
+				support |= RTL_ADVERTISED_10000_FULL;
 		}
 
 		advertising &= support;
@@ -6559,9 +6568,10 @@ static int rtl8152_set_speed(struct r8152 *tp, u8 autoneg, u32 speed, u8 duplex,
 				r8152_mdio_write(tp, MII_CTRL1000, new1);
 		}
 
-		if (tp->support_2500full || tp->support_5000full) {
+		if (tp->support_2500full || tp->support_5000full || tp->support_10000full) {
 			orig = ocp_reg_read(tp, OCP_10GBT_CTRL);
-			new1 = orig & ~(MDIO_AN_10GBT_CTRL_ADV2_5G | MDIO_AN_10GBT_CTRL_ADV5G);
+			new1 = orig & ~(MDIO_AN_10GBT_CTRL_ADV2_5G | MDIO_AN_10GBT_CTRL_ADV5G
+					| MDIO_AN_10GBT_CTRL_ADV10G);
 
 			if (advertising & RTL_ADVERTISED_2500_FULL) {
 				new1 |= MDIO_AN_10GBT_CTRL_ADV2_5G;
@@ -6573,6 +6583,11 @@ static int rtl8152_set_speed(struct r8152 *tp, u8 autoneg, u32 speed, u8 duplex,
 				tp->ups_info.speed_duplex = NWAY_5000M_FULL;
 			}
 
+			if (advertising & RTL_ADVERTISED_10000_FULL) {
+				new1 |= MDIO_AN_10GBT_CTRL_ADV10G;
+				tp->ups_info.speed_duplex = NWAY_10000M_FULL;
+			}
+
 			if (orig != new1)
 				ocp_reg_write(tp, OCP_10GBT_CTRL, new1);
 		}
@@ -8708,7 +8723,10 @@ int rtl8152_get_link_ksettings(struct net_device *netdev,
 	linkmode_mod_bit(ETHTOOL_LINK_MODE_5000baseT_Full_BIT,
 			 cmd->link_modes.supported, tp->support_5000full);
 
-	if (tp->support_2500full || tp->support_5000full) {
+	linkmode_mod_bit(ETHTOOL_LINK_MODE_10000baseT_Full_BIT,
+			 cmd->link_modes.supported, tp->support_10000full);
+
+	if (tp->support_2500full || tp->support_5000full || tp->support_10000full) {
 		u16 ocp_10gbt_ctrl = ocp_reg_read(tp, OCP_10GBT_CTRL);
 		u16 ocp_10gbt_stat = ocp_reg_read(tp, OCP_10GBT_STAT);
 
@@ -8737,6 +8755,19 @@ int rtl8152_get_link_ksettings(struct net_device *netdev,
 			if (is_speed_5000(rtl8152_get_speed(tp)))
 				cmd->base.speed = SPEED_5000;
 		}
+
+		if (tp->support_10000full) {
+			linkmode_mod_bit(ETHTOOL_LINK_MODE_10000baseT_Full_BIT,
+					 cmd->link_modes.advertising,
+					 ocp_10gbt_ctrl & MDIO_AN_10GBT_CTRL_ADV10G);
+
+			linkmode_mod_bit(ETHTOOL_LINK_MODE_10000baseT_Full_BIT,
+					 cmd->link_modes.lp_advertising,
+					 ocp_10gbt_stat & MDIO_AN_10GBT_STAT_LP10G);
+
+			if (is_speed_10000(rtl8152_get_speed(tp)))
+				cmd->base.speed = SPEED_10000;
+		}
 	}
 
 	mutex_unlock(&tp->control);
@@ -8790,6 +8821,10 @@ static int rtl8152_set_link_ksettings(struct net_device *dev,
 		     cmd->link_modes.advertising))
 		advertising |= RTL_ADVERTISED_5000_FULL;
 
+	if (test_bit(ETHTOOL_LINK_MODE_10000baseT_Full_BIT,
+		     cmd->link_modes.advertising))
+		advertising |= RTL_ADVERTISED_10000_FULL;
+
 	mutex_lock(&tp->control);
 
 	ret = rtl8152_set_speed(tp, cmd->base.autoneg, cmd->base.speed,
@@ -8953,6 +8988,13 @@ static int r8153_get_eee(struct r8152 *tp, struct ethtool_keee *eee)
 			linkmode_set_bit(ETHTOOL_LINK_MODE_5000baseT_Full_BIT, common);
 	}
 
+	if (tp->support_10000full) {
+		linkmode_set_bit(ETHTOOL_LINK_MODE_10000baseT_Full_BIT, eee->supported);
+
+		if (speed & _10000bps)
+			linkmode_set_bit(ETHTOOL_LINK_MODE_10000baseT_Full_BIT, common);
+	}
+
 	eee->eee_enabled = tp->eee_en;
 
 	if (speed & _1000bps)
@@ -9967,6 +10009,11 @@ static int rtl8152_probe_once(struct usb_interface *intf,
 			tp->speed = SPEED_5000;
 			tp->advertising |= RTL_ADVERTISED_5000_FULL;
 		}
+		if (tp->support_10000full &&
+		    tp->udev->speed >= USB_SPEED_SUPER) {
+			tp->speed = SPEED_10000;
+			tp->advertising |= RTL_ADVERTISED_10000_FULL;
+		}
 		tp->advertising |= RTL_ADVERTISED_1000_FULL;
 	}
 	tp->duplex = DUPLEX_FULL;

-- 
2.47.3


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH net-next v3 2/3] r8152: Add support for the RTL8159 chip
  2026-05-02  4:50 [PATCH net-next v3 0/3] r8152: Add support for the RTL8159 10Gbit USB Ethernet chip Birger Koblitz
  2026-05-02  4:50 ` [PATCH net-next v3 1/3] r8152: Add support for 10Gbit Link Speeds and EEE Birger Koblitz
@ 2026-05-02  4:50 ` Birger Koblitz
  2026-05-05  2:30   ` Jakub Kicinski
  2026-05-02  4:50 ` [PATCH net-next v3 3/3] r8152: Add firmware upload capability for RTL8157/RTL8159 Birger Koblitz
  2 siblings, 1 reply; 6+ messages in thread
From: Birger Koblitz @ 2026-05-02  4:50 UTC (permalink / raw)
  To: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni
  Cc: linux-usb, netdev, linux-kernel, Chih Kai Hsu, Birger Koblitz,
	Aleksander Jan Bajkowski

The RTL8159 re-uses the packet descriptor format introduced with the
RTL8157 and other hardware features of the RTL8157 (RTL_VER_16) such
as the SRAM access. The support therefore consists in expanding the
existing RTL8157 code for initialization and USB power management
to also be used for the RTL8159 (RTL_VER_17).

Most of the additional code is added in r8157_hw_phy_cfg() to configure
the RTL8159 PHY.

Add support for the USB device ID of Realtek RTL8159-based adapters,
for which the product ID is 0x815a. Detect the RTL8159 as RTL_VER_17
and set it up.

Signed-off-by: Birger Koblitz <mail@birger-koblitz.de>
Tested-by: Aleksander Jan Bajkowski <olek2@wp.pl>
---
 drivers/net/usb/r8152.c | 272 +++++++++++++++++++++++++++++++++++++++++++++---
 1 file changed, 257 insertions(+), 15 deletions(-)

diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c
index 05abfab1df94a571347196bfce7c232865e1058e..a2cdd57558c78b025ea61d33b99eca72c19f535f 100644
--- a/drivers/net/usb/r8152.c
+++ b/drivers/net/usb/r8152.c
@@ -1247,6 +1247,7 @@ enum rtl_version {
 	RTL_VER_14,
 	RTL_VER_15,
 	RTL_VER_16,
+	RTL_VER_17,
 
 	RTL_VER_MAX
 };
@@ -3432,6 +3433,7 @@ static void rtl8152_nic_reset(struct r8152 *tp)
 		break;
 
 	case RTL_VER_16:
+	case RTL_VER_17:
 		ocp_byte_clr_bits(tp, MCU_TYPE_PLA, PLA_CR, CR_RE | CR_TE);
 		break;
 
@@ -3471,6 +3473,9 @@ static void rtl_eee_plus_en(struct r8152 *tp, bool enable)
 
 static void rtl_set_eee_plus(struct r8152 *tp)
 {
+	if (tp->version == RTL_VER_17)
+		return rtl_eee_plus_en(tp, false);
+
 	if (rtl8152_get_speed(tp) & _10bps)
 		rtl_eee_plus_en(tp, true);
 	else
@@ -3656,6 +3661,7 @@ static void r8153_set_rx_early_timeout(struct r8152 *tp)
 	case RTL_VER_13:
 	case RTL_VER_15:
 	case RTL_VER_16:
+	case RTL_VER_17:
 		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,
@@ -3700,6 +3706,7 @@ static void r8153_set_rx_early_size(struct r8152 *tp)
 			       ocp_data / 8);
 		break;
 	case RTL_VER_16:
+	case RTL_VER_17:
 		ocp_write_word(tp, MCU_TYPE_USB, USB_RX_EARLY_SIZE,
 			       ocp_data / 16);
 		break;
@@ -4548,6 +4555,7 @@ static void rtl_clear_bp(struct r8152 *tp, u16 type)
 		break;
 	case RTL_VER_14:
 	case RTL_VER_16:
+	case RTL_VER_17:
 	default:
 		ocp_write_word(tp, type, USB_BP2_EN, 0);
 		bp_num = 16;
@@ -5818,6 +5826,7 @@ static void rtl_eee_enable(struct r8152 *tp, bool enable)
 	case RTL_VER_13:
 	case RTL_VER_15:
 	case RTL_VER_16:
+	case RTL_VER_17:
 		if (enable) {
 			r8156_eee_en(tp, true);
 			ocp_reg_write(tp, OCP_EEE_ADV, tp->eee_adv);
@@ -6408,7 +6417,7 @@ static int rtl8156_enable(struct r8152 *tp)
 	set_tx_qlen(tp);
 	rtl_set_eee_plus(tp);
 
-	if (tp->version >= RTL_VER_12 && tp->version <= RTL_VER_16)
+	if (tp->version >= RTL_VER_12 && tp->version <= RTL_VER_17)
 		ocp_word_clr_bits(tp, MCU_TYPE_USB, USB_RX_AGGR_NUM, RX_AGGR_NUM_MASK);
 
 	r8153_set_rx_early_timeout(tp);
@@ -6817,7 +6826,7 @@ static void rtl8156_up(struct r8152 *tp)
 		return;
 
 	r8153b_u1u2en(tp, false);
-	if (tp->version != RTL_VER_16)
+	if (tp->version < RTL_VER_16)
 		r8153_u2p3en(tp, false);
 	r8153_aldps_en(tp, false);
 
@@ -6831,7 +6840,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)
+	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);
@@ -6856,7 +6865,7 @@ static void rtl8156_up(struct r8152 *tp)
 
 	ocp_word_clr_bits(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL3, PLA_MCU_SPDWN_EN);
 
-	if (tp->version != RTL_VER_16)
+	if (tp->version < RTL_VER_16)
 		ocp_word_clr_bits(tp, MCU_TYPE_USB, USB_SPEED_OPTION,
 				  RG_PWRDN_EN | ALL_SPEED_OFF);
 
@@ -6868,10 +6877,10 @@ static void rtl8156_up(struct r8152 *tp)
 	}
 
 	r8153_aldps_en(tp, true);
-	if (tp->version != RTL_VER_16)
+	if (tp->version < RTL_VER_16)
 		r8153_u2p3en(tp, true);
 
-	if (tp->version != RTL_VER_16 && tp->udev->speed >= USB_SPEED_SUPER)
+	if (tp->version < RTL_VER_16 && tp->udev->speed >= USB_SPEED_SUPER)
 		r8153b_u1u2en(tp, true);
 }
 
@@ -6886,7 +6895,7 @@ static void rtl8156_down(struct r8152 *tp)
 			  PLA_MCU_SPDWN_EN);
 
 	r8153b_u1u2en(tp, false);
-	if (tp->version != RTL_VER_16) {
+	if (tp->version < RTL_VER_16) {
 		r8153_u2p3en(tp, false);
 		r8153b_power_cut_en(tp, false);
 	}
@@ -7996,7 +8005,7 @@ static void r8157_hw_phy_cfg(struct r8152 *tp)
 	/* Advanced Power Saving parameter */
 	ocp_reg_set_bits(tp, 0xa430, BIT(0) | BIT(1));
 
-	/* aldpsce force mode */
+	/* Disable ALDPS force mode */
 	ocp_reg_clr_bits(tp, 0xa44a, BIT(2));
 
 	switch (tp->version) {
@@ -8120,6 +8129,190 @@ static void r8157_hw_phy_cfg(struct r8152 *tp)
 		sram2_write_w0w1(tp, 0x807c, 0xff00, 0x5000);
 		sram2_write_w0w1(tp, 0x809d, 0xff00, 0x5000);
 		break;
+
+	case RTL_VER_17:
+		/* Disable bypass turn off clk in ALDPS */
+		 ocp_byte_clr_bits(tp, MCU_TYPE_PLA, 0xd3c8, BIT(0));
+
+		/* Power level tuning
+		 * test mode power level
+		 */
+		sram_write_w0w1(tp, 0x8415, 0xff00, 0x9300);
+		/* normal link power level 10G, 5G, 2.5G */
+		sram_write_w0w1(tp, 0x81a3, 0xff00, 0x0f00);
+		sram_write_w0w1(tp, 0x81ae, 0xff00, 0x0f00);
+		sram_write_w0w1(tp, 0x81b9, 0xff00, 0xb900);
+		/* nomal link TX filter */
+		sram2_write_w0w1(tp, 0x83b0, 0x0e00, 0);
+		sram2_write_w0w1(tp, 0x83c5, 0x0e00, 0);
+		sram2_write_w0w1(tp, 0x83da, 0x0e00, 0);
+		sram2_write_w0w1(tp, 0x83ef, 0x0e00, 0);
+
+		/* AFE power saving for 2.5G & 5G */
+		sram_write(tp, 0x8173, 0x8620);
+		sram_write(tp, 0x8175, 0x8671);
+
+		sram_write_w0w1(tp, 0x817c, 0, BIT(13));
+		sram_write_w0w1(tp, 0x8187, 0, BIT(13));
+		sram_write_w0w1(tp, 0x8192, 0, BIT(13));
+		sram_write_w0w1(tp, 0x819d, 0, BIT(13));
+		sram_write_w0w1(tp, 0x81a8, BIT(13), 0);
+		sram_write_w0w1(tp, 0x81b3, BIT(13), 0);
+		sram_write_w0w1(tp, 0x81be, 0, BIT(13));
+
+		sram_write_w0w1(tp, 0x817d, 0xff00, 0xa600);
+		sram_write_w0w1(tp, 0x8188, 0xff00, 0xa600);
+		sram_write_w0w1(tp, 0x8193, 0xff00, 0xa600);
+		sram_write_w0w1(tp, 0x819e, 0xff00, 0xa600);
+		sram_write_w0w1(tp, 0x81a9, 0xff00, 0x1400);
+		sram_write_w0w1(tp, 0x81b4, 0xff00, 0x1400);
+		sram_write_w0w1(tp, 0x81bf, 0xff00, 0xa600);
+
+		/* RFI parameter
+		 * disable preset FBE
+		 */
+		ocp_reg_clr_bits(tp, 0xaeaa, BIT(5) | BIT(3));
+		/* modify PGA for 5G&10G */
+		sram2_write(tp, 0x84f0, 0x201c);
+		sram2_write(tp, 0x84f2, 0x3117);
+		/* RFI parameter */
+		ocp_reg_write(tp, 0xaec6, 0x0000);
+		ocp_reg_write(tp, 0xae20, 0xffff);
+		ocp_reg_write(tp, 0xaece, 0xffff);
+		ocp_reg_write(tp, 0xaed2, 0xffff);
+		ocp_reg_write(tp, 0xaec8, 0x0000);
+		ocp_reg_clr_bits(tp, 0xaed0, BIT(0));
+		ocp_reg_write(tp, 0xadb8, 0x0150);
+		sram2_write_w0w1(tp, 0x8197, 0xff00, 0x5000);
+		sram2_write_w0w1(tp, 0x8231, 0xff00, 0x5000);
+		sram2_write_w0w1(tp, 0x82cb, 0xff00, 0x5000);
+		sram2_write_w0w1(tp, 0x82cd, 0xff00, 0x5700);
+		sram2_write_w0w1(tp, 0x8233, 0xff00, 0x5700);
+		sram2_write_w0w1(tp, 0x8199, 0xff00, 0x5700);
+
+		sram2_write(tp, 0x815a, 0x0150);
+		sram2_write(tp, 0x81f4, 0x0150);
+		sram2_write(tp, 0x828e, 0x0150);
+		sram2_write(tp, 0x81b1, 0x0000);
+		sram2_write(tp, 0x824b, 0x0000);
+		sram2_write(tp, 0x82e5, 0x0000);
+
+		sram2_write_w0w1(tp, 0x84f7, 0xff00, 0x2800);
+		ocp_reg_set_bits(tp, 0xaec2, BIT(12));
+		sram2_write_w0w1(tp, 0x81b3, 0xff00, 0xad00);
+		sram2_write_w0w1(tp, 0x824d, 0xff00, 0xad00);
+		sram2_write_w0w1(tp, 0x82e7, 0xff00, 0xad00);
+		ocp_reg_w0w1(tp, 0xae4e, 0x000f, 0x0001);
+		sram2_write_w0w1(tp, 0x82ce, 0xf000, 0x4000);
+
+		/* 5G shift sel, default = '04'
+		 * 10G shift sel, default = '03'
+		 */
+		sram2_write_w0w1(tp, 0x83a5, 0xff00, 0x0400);
+		sram2_write_w0w1(tp, 0x83a6, 0xff00, 0x0400);
+		sram2_write_w0w1(tp, 0x83a7, 0xff00, 0x0400);
+		sram2_write_w0w1(tp, 0x83a8, 0xff00, 0x0400);
+
+		/* XG INRX parameters
+		 * RC coefficients
+		 */
+		sram2_write(tp, 0x84ac, 0x0000);
+		sram2_write(tp, 0x84ae, 0x0000);
+		sram2_write(tp, 0x84b0, 0xf818);
+		sram2_write_w0w1(tp, 0x84b2, 0xff00, 0x6000);
+		/* Training AAGC PAR (with uc2 patch) */
+		sram2_write(tp, 0x8ffc, 0x6008);
+		sram2_write(tp, 0x8ffe, 0xf450);
+		/* DAC BGK */
+		sram2_write_w0w1(tp, 0x8015, 0, BIT(9));
+		sram2_write_w0w1(tp, 0x8016, 0, BIT(11));
+		sram2_write_w0w1(tp, 0x8fe6, 0xff00, 0x0800);
+		sram2_write(tp, 0x8fe4, 0x2114);
+		/* 10G PBO table */
+		sram2_write(tp, 0x8647, 0xa7b1);
+		sram2_write(tp, 0x8649, 0xbbca);
+		sram2_write_w0w1(tp, 0x864b, 0xff00, 0xdc00);
+		/* 2.5G ado power window size */
+		sram2_write_w0w1(tp, 0x8154, 0xc000, 0x4000);
+		sram2_write_w0w1(tp, 0x8158, 0xc000, 0);
+		/* 10G lock far */
+		sram2_write(tp, 0x826c, 0xffff);
+		sram2_write(tp, 0x826e, 0xffff);
+		/* XG INRX parameter */
+		sram2_write_w0w1(tp, 0x8872, 0xff00, 0x0e00);
+		sram_write_w0w1(tp, 0x8012, 0, BIT(11));
+		sram_write_w0w1(tp, 0x8012, 0, BIT(14));
+		ocp_reg_set_bits(tp, 0xb576, BIT(0));
+		sram_write_w0w1(tp, 0x834a, 0xff00, 0x0700);
+		sram2_write_w0w1(tp, 0x8217, 0x3f00, 0x2a00);
+		sram_write_w0w1(tp, 0x81b1, 0xff00, 0x0b00);
+		sram2_write_w0w1(tp, 0x8fed, 0xff00, 0x4e00);
+		/* Slave about EC mu of datamode AAGC  and DAC BG */
+		sram2_write_w0w1(tp, 0x88ac, 0xff00, 0x2300);
+		/* improve UBE */
+		ocp_reg_set_bits(tp, 0xbf0c, 0x7 << 11);
+		/* close Sparse NEC, improve connect 5EUU calble performace */
+		sram2_write_w0w1(tp, 0x88de, 0xff00, 0);
+		/* 5G slave compatibility issue (will include in v10) */
+		sram2_write(tp, 0x80b4, 0x5195);
+
+		/* XG Test Mode
+		 * xgtstm_map_tbl for mdi_cap_sel
+		 */
+		sram_write(tp, 0x8370, 0x8671);
+		sram_write(tp, 0x8372, 0x86c8);
+		/* xgtstm_amp_map_tbl for  REG_IBX_UP_SHIFT_L */
+		sram_write(tp, 0x8401, 0x86c8);
+		sram_write(tp, 0x8403, 0x86da);
+		sram_write_w0w1(tp, 0x8406, 0x1800, 0x1000);
+		sram_write_w0w1(tp, 0x8408, 0x1800, 0x1000);
+		sram_write_w0w1(tp, 0x840a, 0x1800, 0x1000);
+		sram_write_w0w1(tp, 0x840c, 0x1800, 0x1000);
+		sram_write_w0w1(tp, 0x840e, 0x1800, 0x1000);
+		sram_write_w0w1(tp, 0x8410, 0x1800, 0x1000);
+		sram_write_w0w1(tp, 0x8412, 0x1800, 0x1000);
+		sram_write_w0w1(tp, 0x8414, 0x1800, 0x1000);
+		sram_write_w0w1(tp, 0x8416, 0x1800, 0x1000);
+
+		/* Cable Test Patch */
+		sram_write(tp, 0x82bd, 0x1f40);
+
+		/* Thermal sensor parameters */
+		ocp_reg_w0w1(tp, 0xbfb4, 0x07ff, 0x0328);
+		ocp_reg_write(tp, 0xbfb6, 0x3e14);
+
+		/* spdchg_gtx_shape_100M */
+		ocp_reg_write(tp, OCP_SRAM_ADDR, 0x81c4);
+		ocp_reg_write(tp, OCP_SRAM_DATA, 0x003b);
+		ocp_reg_write(tp, OCP_SRAM_DATA, 0x0086);
+		ocp_reg_write(tp, OCP_SRAM_DATA, 0x00b7);
+		ocp_reg_write(tp, OCP_SRAM_DATA, 0x00db);
+		ocp_reg_write(tp, OCP_SRAM_DATA, 0x00fe);
+		ocp_reg_write(tp, OCP_SRAM_DATA, 0x00fe);
+		ocp_reg_write(tp, OCP_SRAM_DATA, 0x00fe);
+		ocp_reg_write(tp, OCP_SRAM_DATA, 0x00fe);
+		ocp_reg_write(tp, OCP_SRAM_DATA, 0x00c3);
+		ocp_reg_write(tp, OCP_SRAM_DATA, 0x0078);
+		ocp_reg_write(tp, OCP_SRAM_DATA, 0x0047);
+		ocp_reg_write(tp, OCP_SRAM_DATA, 0x0023);
+
+		/* lsbmsk_parameters
+		 * RL6961_lsbmsk_parameter_250207
+		 */
+		sram2_write(tp, 0x88d7, 0x01a0);
+		sram2_write(tp, 0x88d9, 0x01a0);
+		sram2_write(tp, 0x8ffa, 0x002a);
+
+		sram2_write(tp, 0x8fee, 0xffdf);
+		sram2_write(tp, 0x8ff0, 0xffff);
+		sram2_write(tp, 0x8ff2, 0x0a4a);
+		sram2_write(tp, 0x8ff4, 0xaa5a);
+		sram2_write(tp, 0x8ff6, 0x0a4a);
+		sram2_write(tp, 0x8ff8, 0xaa5a);
+
+		sram2_write_w0w1(tp, 0x88d5, 0xff00, 0x0200);
+		break;
+
 	default:
 		break;
 	}
@@ -8155,6 +8348,18 @@ static void r8157_hw_phy_cfg(struct r8152 *tp)
 	set_bit(PHY_RESET, &tp->flags);
 }
 
+static int r8159_wait_backup_restore(struct r8152 *tp)
+{
+	u32 ocp_data;
+
+	ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_MISC_0);
+	if (!(ocp_data & PCUT_STATUS))
+		return 0;
+
+	return poll_timeout_us(ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_GPHY_CTRL),
+			       ocp_data & BACKUP_RESTRORE, 200, 20000, false);
+}
+
 static void r8156_init(struct r8152 *tp)
 {
 	u32 ocp_data;
@@ -8164,14 +8369,14 @@ static void r8156_init(struct r8152 *tp)
 	if (test_bit(RTL8152_INACCESSIBLE, &tp->flags))
 		return;
 
-	if (tp->version == RTL_VER_16) {
+	if (tp->version == RTL_VER_16 || tp->version == RTL_VER_17) {
 		ocp_byte_set_bits(tp, MCU_TYPE_USB, 0xcffe, BIT(3));
 		ocp_byte_clr_bits(tp, MCU_TYPE_USB, 0xd3ca, BIT(0));
 	}
 
 	ocp_byte_clr_bits(tp, MCU_TYPE_USB, USB_ECM_OP, EN_ALL_SPEED);
 
-	if (tp->version != RTL_VER_16)
+	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);
@@ -8185,6 +8390,7 @@ static void r8156_init(struct r8152 *tp)
 	case RTL_VER_13:
 	case RTL_VER_15:
 	case RTL_VER_16:
+	case RTL_VER_17:
 		r8156b_wait_loading_flash(tp);
 		break;
 	default:
@@ -8201,6 +8407,11 @@ static void r8156_init(struct r8152 *tp)
 			return;
 	}
 
+	if (tp->version == RTL_VER_17 && r8159_wait_backup_restore(tp)) {
+		dev_err(&tp->intf->dev, "init failed, backup-restore timed out\n");
+		return;
+	}
+
 	data = r8153_phy_status(tp, 0);
 	if (data == PHY_STAT_EXT_INIT) {
 		ocp_reg_clr_bits(tp, 0xa468, BIT(3) | BIT(1));
@@ -8216,7 +8427,7 @@ static void r8156_init(struct r8152 *tp)
 
 	data = r8153_phy_status(tp, PHY_STAT_LAN_ON);
 
-	if (tp->version == RTL_VER_16)
+	if (tp->version >= RTL_VER_16)
 		r8157_u2p3en(tp, false);
 	else
 		r8153_u2p3en(tp, false);
@@ -8227,7 +8438,7 @@ static void r8156_init(struct r8152 *tp)
 	/* U1/U2/L1 idle timer. 500 us */
 	ocp_write_word(tp, MCU_TYPE_USB, USB_U1U2_TIMER, 500);
 
-	if (tp->version == RTL_VER_16)
+	if (tp->version >= RTL_VER_16)
 		r8157_power_cut_en(tp, false);
 	else
 		r8153b_power_cut_en(tp, false);
@@ -8260,7 +8471,7 @@ static void r8156_init(struct r8152 *tp)
 
 	r8156_mac_clk_spd(tp, true);
 
-	if (tp->version != RTL_VER_16)
+	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);
@@ -8274,7 +8485,10 @@ static void r8156_init(struct r8152 *tp)
 	set_bit(GREEN_ETHERNET, &tp->flags);
 
 	/* rx aggregation / 16 bytes Rx descriptor */
-	if (tp->version == RTL_VER_16)
+	if (tp->version == RTL_VER_17)
+		ocp_word_clr_bits(tp, MCU_TYPE_USB, USB_USB_CTRL,
+				  RX_AGG_DISABLE | RX_DESC_16B | BIT(11));
+	else if (tp->version == 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);
@@ -8282,7 +8496,7 @@ static void r8156_init(struct r8152 *tp)
 	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) {
+	if (tp->version >= RTL_VER_16) {
 		/* Disable Rx Zero Len */
 		rtl_bmu_clr_bits(tp, 0x2300, BIT(3));
 		/* TX descriptor Signature */
@@ -9670,6 +9884,29 @@ static int rtl_ops_init(struct r8152 *tp)
 		r8157_desc_init(tp);
 		break;
 
+	case RTL_VER_17:
+		tp->eee_en		= true;
+		tp->eee_adv		= MDIO_EEE_100TX | MDIO_EEE_1000T | MDIO_EEE_10GT;
+		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		= 48 * 1024;
+		tp->support_2500full	= 1;
+		tp->support_5000full	= 1;
+		tp->support_10000full	= 1;
+		r8157_desc_init(tp);
+		break;
+
 	default:
 		ret = -ENODEV;
 		dev_err(&tp->intf->dev, "Unknown Device\n");
@@ -9823,6 +10060,9 @@ static u8 __rtl_get_hw_ver(struct usb_device *udev)
 	case 0x1030:
 		version = RTL_VER_16;
 		break;
+	case 0x2020:
+		version = RTL_VER_17;
+		break;
 	default:
 		version = RTL_VER_UNKNOWN;
 		dev_info(&udev->dev, "Unknown version 0x%04x\n", ocp_data);
@@ -9975,6 +10215,7 @@ static int rtl8152_probe_once(struct usb_interface *intf,
 	case RTL_VER_13:
 	case RTL_VER_15:
 	case RTL_VER_16:
+	case RTL_VER_17:
 		netdev->max_mtu = size_to_mtu(16 * 1024);
 		break;
 	case RTL_VER_01:
@@ -10140,6 +10381,7 @@ static const struct usb_device_id rtl8152_table[] = {
 	{ USB_DEVICE(VENDOR_ID_REALTEK, 0x8155) },
 	{ USB_DEVICE(VENDOR_ID_REALTEK, 0x8156) },
 	{ USB_DEVICE(VENDOR_ID_REALTEK, 0x8157) },
+	{ USB_DEVICE(VENDOR_ID_REALTEK, 0x815a) },
 
 	/* Microsoft */
 	{ USB_DEVICE(VENDOR_ID_MICROSOFT, 0x07ab) },

-- 
2.47.3


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH net-next v3 3/3] r8152: Add firmware upload capability for RTL8157/RTL8159
  2026-05-02  4:50 [PATCH net-next v3 0/3] r8152: Add support for the RTL8159 10Gbit USB Ethernet chip Birger Koblitz
  2026-05-02  4:50 ` [PATCH net-next v3 1/3] r8152: Add support for 10Gbit Link Speeds and EEE Birger Koblitz
  2026-05-02  4:50 ` [PATCH net-next v3 2/3] r8152: Add support for the RTL8159 chip Birger Koblitz
@ 2026-05-02  4:50 ` Birger Koblitz
  2 siblings, 0 replies; 6+ messages in thread
From: Birger Koblitz @ 2026-05-02  4:50 UTC (permalink / raw)
  To: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni
  Cc: linux-usb, netdev, linux-kernel, Chih Kai Hsu, Birger Koblitz,
	Aleksander Jan Bajkowski

The RTL8159 (RTL_VER_17) requires firmware for its PHY in order to work
at connection speeds > 5GBit. Add support for uploading firmware for
the PHY using the existing rtl8152_apply_firmware() function
in r8157_hw_phy_cfg() and set up the correct names for the firmware
files.

This also adds support for uploading firmware for the RTL8157
(RTL_VER_16) PHY, for which firmware is however not strictly necessary
to work. Still, this allows to upload newer versions of the firmware used
by this chip, e.g. to improve interoperability.

If no firmware is found, both the RTL8157 and the RTL8159 will continue
to work.

Signed-off-by: Birger Koblitz <mail@birger-koblitz.de>
Tested-by: Aleksander Jan Bajkowski <olek2@wp.pl>
---
 drivers/net/usb/r8152.c | 15 ++++++++++++++-
 1 file changed, 14 insertions(+), 1 deletion(-)

diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c
index a2cdd57558c78b025ea61d33b99eca72c19f535f..7efba20de03deb06ac75c3b57a0d0e27b30b8e3a 100644
--- a/drivers/net/usb/r8152.c
+++ b/drivers/net/usb/r8152.c
@@ -4663,10 +4663,11 @@ static bool rtl8152_is_fw_phy_speed_up_ok(struct r8152 *tp, struct fw_phy_speed_
 	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:
+	case RTL_VER_16:
+	case RTL_VER_17:
 	default:
 		break;
 	}
@@ -7982,12 +7983,14 @@ static void r8157_hw_phy_cfg(struct r8152 *tp)
 	data = r8153_phy_status(tp, 0);
 	switch (data) {
 	case PHY_STAT_EXT_INIT:
+		rtl8152_apply_firmware(tp, true);
 		ocp_reg_clr_bits(tp, 0xa466, BIT(0));
 		ocp_reg_clr_bits(tp, 0xa468, BIT(3) | BIT(1));
 		break;
 	case PHY_STAT_LAN_ON:
 	case PHY_STAT_PWRDN:
 	default:
+		rtl8152_apply_firmware(tp, false);
 		break;
 	}
 
@@ -9923,6 +9926,8 @@ static int rtl_ops_init(struct r8152 *tp)
 #define FIRMWARE_8153C_1	"rtl_nic/rtl8153c-1.fw"
 #define FIRMWARE_8156A_2	"rtl_nic/rtl8156a-2.fw"
 #define FIRMWARE_8156B_2	"rtl_nic/rtl8156b-2.fw"
+#define FIRMWARE_8157_1		"rtl_nic/rtl8157-1.fw"
+#define FIRMWARE_8159_1		"rtl_nic/rtl8159-1.fw"
 
 MODULE_FIRMWARE(FIRMWARE_8153A_2);
 MODULE_FIRMWARE(FIRMWARE_8153A_3);
@@ -9931,6 +9936,8 @@ MODULE_FIRMWARE(FIRMWARE_8153B_2);
 MODULE_FIRMWARE(FIRMWARE_8153C_1);
 MODULE_FIRMWARE(FIRMWARE_8156A_2);
 MODULE_FIRMWARE(FIRMWARE_8156B_2);
+MODULE_FIRMWARE(FIRMWARE_8157_1);
+MODULE_FIRMWARE(FIRMWARE_8159_1);
 
 static int rtl_fw_init(struct r8152 *tp)
 {
@@ -9969,6 +9976,12 @@ static int rtl_fw_init(struct r8152 *tp)
 		rtl_fw->pre_fw		= r8153b_pre_firmware_1;
 		rtl_fw->post_fw		= r8153c_post_firmware_1;
 		break;
+	case RTL_VER_16:
+		rtl_fw->fw_name		= FIRMWARE_8157_1;
+		break;
+	case RTL_VER_17:
+		rtl_fw->fw_name		= FIRMWARE_8159_1;
+		break;
 	default:
 		break;
 	}

-- 
2.47.3


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: [PATCH net-next v3 2/3] r8152: Add support for the RTL8159 chip
  2026-05-02  4:50 ` [PATCH net-next v3 2/3] r8152: Add support for the RTL8159 chip Birger Koblitz
@ 2026-05-05  2:30   ` Jakub Kicinski
  2026-05-05 15:54     ` Birger Koblitz
  0 siblings, 1 reply; 6+ messages in thread
From: Jakub Kicinski @ 2026-05-05  2:30 UTC (permalink / raw)
  To: mail
  Cc: Jakub Kicinski, andrew+netdev, davem, edumazet, pabeni, linux-usb,
	netdev, linux-kernel, hsu.chih.kai, olek2

This is an AI-generated review of your patch. The human sending this
email has considered the AI review valid, or at least plausible.
---
r8152: Add support for the RTL8159 chip

This patch adds support for the RTL8159 chip as RTL_VER_17, reusing the
RTL8157 initialization and USB power management paths. The bulk of the
new code lives in r8157_hw_phy_cfg() to configure the RTL8159 PHY, and
the USB product ID 0x815a is added to the device table.

> diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c
> index 05abfab1df94..a2cdd57558c7 100644
> --- a/drivers/net/usb/r8152.c
> +++ b/drivers/net/usb/r8152.c

[ ... ]

> @@ -7996,7 +8005,7 @@ static void r8157_hw_phy_cfg(struct r8152 *tp)
>  	/* Advanced Power Saving parameter */
>  	ocp_reg_set_bits(tp, 0xa430, BIT(0) | BIT(1));
>  
> -	/* aldpsce force mode */
> +	/* Disable ALDPS force mode */
>  	ocp_reg_clr_bits(tp, 0xa44a, BIT(2));
>  
>  	switch (tp->version) {
> @@ -8120,6 +8129,190 @@ static void r8157_hw_phy_cfg(struct r8152 *tp)
>  		sram2_write_w0w1(tp, 0x807c, 0xff00, 0x5000);
>  		sram2_write_w0w1(tp, 0x809d, 0xff00, 0x5000);
>  		break;
> +
> +	case RTL_VER_17:
> +		/* Disable bypass turn off clk in ALDPS */
> +		 ocp_byte_clr_bits(tp, MCU_TYPE_PLA, 0xd3c8, BIT(0));
         ^

Is the leading space before ocp_byte_clr_bits here intentional?  The rest
of the switch statement uses a single tab for indentation.  checkpatch.pl
should catch this.

> +
> +		/* Power level tuning
> +		 * test mode power level
> +		 */
> +		sram_write_w0w1(tp, 0x8415, 0xff00, 0x9300);
> +		/* normal link power level 10G, 5G, 2.5G */
> +		sram_write_w0w1(tp, 0x81a3, 0xff00, 0x0f00);
> +		sram_write_w0w1(tp, 0x81ae, 0xff00, 0x0f00);
> +		sram_write_w0w1(tp, 0x81b9, 0xff00, 0xb900);
> +		/* nomal link TX filter */
              ^^^^^

Small typo, "nomal" -> "normal".

> +		sram2_write_w0w1(tp, 0x83b0, 0x0e00, 0);
> +		sram2_write_w0w1(tp, 0x83c5, 0x0e00, 0);
> +		sram2_write_w0w1(tp, 0x83da, 0x0e00, 0);
> +		sram2_write_w0w1(tp, 0x83ef, 0x0e00, 0);

[ ... ]

> +		/* Slave about EC mu of datamode AAGC  and DAC BG */
> +		sram2_write_w0w1(tp, 0x88ac, 0xff00, 0x2300);
> +		/* improve UBE */
> +		ocp_reg_set_bits(tp, 0xbf0c, 0x7 << 11);
> +		/* close Sparse NEC, improve connect 5EUU calble performace */
                                                      ^^^^^  ^^^^^^^^^

Two typos here, "calble" -> "cable" and "performace" -> "performance".

> +		sram2_write_w0w1(tp, 0x88de, 0xff00, 0);
> +		/* 5G slave compatibility issue (will include in v10) */
                                                 ^^^^^^^^^^^^^^^^^^

Is this "will include in v10" comment a reference to an internal Realtek
source-tree revision?  It does not appear to have meaning in the upstream
tree and could be dropped or rephrased.

> +		sram2_write(tp, 0x80b4, 0x5195);

[ ... ]

> +		sram2_write_w0w1(tp, 0x88d5, 0xff00, 0x0200);
> +		break;
> +
>  	default:
>  		break;
>  	}

[ ... ]

> @@ -8155,6 +8348,18 @@ static void r8157_hw_phy_cfg(struct r8152 *tp)
>  	set_bit(PHY_RESET, &tp->flags);
>  }
>  
> +static int r8159_wait_backup_restore(struct r8152 *tp)
> +{
> +	u32 ocp_data;
> +
> +	ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_MISC_0);
> +	if (!(ocp_data & PCUT_STATUS))
> +		return 0;
> +
> +	return poll_timeout_us(ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_GPHY_CTRL),
> +			       ocp_data & BACKUP_RESTRORE, 200, 20000, false);
> +}
> +
>  static void r8156_init(struct r8152 *tp)
>  {
>  	u32 ocp_data;

[ ... ]

> @@ -8201,6 +8407,11 @@ static void r8156_init(struct r8152 *tp)
>  			return;
>  	}
>  
> +	if (tp->version == RTL_VER_17 && r8159_wait_backup_restore(tp)) {
> +		dev_err(&tp->intf->dev, "init failed, backup-restore timed out\n");
> +		return;
> +	}
> +

On timeout this returns early from r8156_init() and skips the remainder of
the init sequence, including r8157_u2p3en()/r8157_power_cut_en(),
r8156_ups_en(), r8153_queue_wake(), rtl_runtime_suspend_enable(),
r8156_mac_clk_spd(), the rx aggregation / 16-byte Rx descriptor
configuration, r8156_mdio_force_mode(), rtl_tally_reset() and the
tp->coalesce assignment.

r8156_init() is void and rtl8152_probe_once() does not check init status,
so probe continues and register_netdev() runs after this early return.

Should this path also set RTL8152_INACCESSIBLE on tp->flags, or should the
init callback be changed to return an error that probe can honor, so that
a half-initialized device is not exposed to userspace?

>  	data = r8153_phy_status(tp, 0);
>  	if (data == PHY_STAT_EXT_INIT) {
>  		ocp_reg_clr_bits(tp, 0xa468, BIT(3) | BIT(1));

[ ... ]

> @@ -8274,7 +8485,10 @@ static void r8156_init(struct r8152 *tp)
>  	set_bit(GREEN_ETHERNET, &tp->flags);
>  
>  	/* rx aggregation / 16 bytes Rx descriptor */
> -	if (tp->version == RTL_VER_16)
> +	if (tp->version == RTL_VER_17)
> +		ocp_word_clr_bits(tp, MCU_TYPE_USB, USB_USB_CTRL,
> +				  RX_AGG_DISABLE | RX_DESC_16B | BIT(11));
                                                                 ^^^^^^

What does BIT(11) in USB_USB_CTRL correspond to here, and is it
RTL8159-specific?

The commit message says the RTL8159 "reuses hardware features of the
RTL8157 (RTL_VER_16)", but this path clears an extra bit that the
RTL_VER_16 path does not.  Since there is no symbolic name or comment,
it is hard to tell whether RTL_VER_16 is missing this clear, whether
RTL_VER_17 should not be clearing it, or whether it really is an
RTL8159-only quirk.

Could a named define and/or a short comment be added to describe what
this bit does?

> +	else 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);

[ ... ]

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH net-next v3 2/3] r8152: Add support for the RTL8159 chip
  2026-05-05  2:30   ` Jakub Kicinski
@ 2026-05-05 15:54     ` Birger Koblitz
  0 siblings, 0 replies; 6+ messages in thread
From: Birger Koblitz @ 2026-05-05 15:54 UTC (permalink / raw)
  To: Jakub Kicinski
  Cc: andrew+netdev, davem, edumazet, pabeni, linux-usb, netdev,
	linux-kernel, hsu.chih.kai, olek2

On 05/05/2026 4:30 am, Jakub Kicinski wrote:
> This is an AI-generated review of your patch. The human sending this
> email has considered the AI review valid, or at least plausible.
> ---
> r8152: Add support for the RTL8159 chip
> 
> This patch adds support for the RTL8159 chip as RTL_VER_17, reusing the
> RTL8157 initialization and USB power management paths. The bulk of the
> new code lives in r8157_hw_phy_cfg() to configure the RTL8159 PHY, and
> the USB product ID 0x815a is added to the device table.

> Is the leading space before ocp_byte_clr_bits here intentional?  The rest
> of the switch statement uses a single tab for indentation.  checkpatch.pl
> should catch this.
No, will fix in v4. Interesting, that checkpatch does not find this. I 
am very sure I ran b4 prep --check before, it is near impossible to omit 
that step before sending.

> 
> Small typo, "nomal" -> "normal".
Will fix.

>> +		/* close Sparse NEC, improve connect 5EUU calble performace */
>                                                        ^^^^^  ^^^^^^^^^
> 
> Two typos here, "calble" -> "cable" and "performace" -> "performance".
Will fix.

> Is this "will include in v10" comment a reference to an internal Realtek
> source-tree revision?  It does not appear to have meaning in the upstream
> tree and could be dropped or rephrased.
I will drop this.

>> @@ -8201,6 +8407,11 @@ static void r8156_init(struct r8152 *tp)
>>   			return;
>>   	}
>>   
>> +	if (tp->version == RTL_VER_17 && r8159_wait_backup_restore(tp)) {
>> +		dev_err(&tp->intf->dev, "init failed, backup-restore timed out\n");
>> +		return;
>> +	}
>> +
> 
> Should this path also set RTL8152_INACCESSIBLE on tp->flags, or should the
> init callback be changed to return an error that probe can honor, so that
> a half-initialized device is not exposed to userspace?

I'll set RTL8152_INACCESSIBLE in line with what is done already in the 
rest of r8156_init()


>> @@ -8274,7 +8485,10 @@ static void r8156_init(struct r8152 *tp)
>>   	set_bit(GREEN_ETHERNET, &tp->flags);
>>   
>>   	/* rx aggregation / 16 bytes Rx descriptor */
>> -	if (tp->version == RTL_VER_16)
>> +	if (tp->version == RTL_VER_17)
>> +		ocp_word_clr_bits(tp, MCU_TYPE_USB, USB_USB_CTRL,
>> +				  RX_AGG_DISABLE | RX_DESC_16B | BIT(11));
>                                                                   ^^^^^^
> 
> What does BIT(11) in USB_USB_CTRL correspond to here, and is it
> RTL8159-specific?
> 
> The commit message says the RTL8159 "reuses hardware features of the
> RTL8157 (RTL_VER_16)", but this path clears an extra bit that the
> RTL_VER_16 path does not.  Since there is no symbolic name or comment,
> it is hard to tell whether RTL_VER_16 is missing this clear, whether
> RTL_VER_17 should not be clearing it, or whether it really is an
> RTL8159-only quirk.
> 
> Could a named define and/or a short comment be added to describe what
> this bit does?


This was brought up before, and unfortunately, there is no documentation
whatsoever for this bit. Any guess at a name may turn out to be misleading.
But I will change the comment to read:

/* RX aggregation / 16 bytes RX descriptor
  * BIT(11) is specific to RTL8159, with unknown meaning
  */
if (tp->version == RTL_VER_17)
	ocp_word_clr_bits(tp, MCU_TYPE_USB, USB_USB_CTRL,
			  RX_AGG_DISABLE | RX_DESC_16B | BIT(11));
else if (tp->version == RTL_VER_16)
	ocp_word_clr_bits(tp, MCU_TYPE_USB, USB_USB_CTRL, RX_AGG_DISABLE | 
RX_DESC_16B);
else ...

Birger


^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2026-05-05 15:54 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-05-02  4:50 [PATCH net-next v3 0/3] r8152: Add support for the RTL8159 10Gbit USB Ethernet chip Birger Koblitz
2026-05-02  4:50 ` [PATCH net-next v3 1/3] r8152: Add support for 10Gbit Link Speeds and EEE Birger Koblitz
2026-05-02  4:50 ` [PATCH net-next v3 2/3] r8152: Add support for the RTL8159 chip Birger Koblitz
2026-05-05  2:30   ` Jakub Kicinski
2026-05-05 15:54     ` Birger Koblitz
2026-05-02  4:50 ` [PATCH net-next v3 3/3] r8152: Add firmware upload capability for RTL8157/RTL8159 Birger Koblitz

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox