summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakub Kicinski <kuba@kernel.org>2026-05-07 04:54:17 +0300
committerJakub Kicinski <kuba@kernel.org>2026-05-07 04:54:17 +0300
commitc978803c5d4dc0501efcdb32df055b35bd81ba27 (patch)
treebc9d2c13a130231fa78e42a052591d7e2f1430af
parentaf770c4d44b0ebe2f1bd2628cf9fd2a8665574df (diff)
parenta51e171e176c21b91272ac44b57ef1a26aaf2222 (diff)
downloadlinux-c978803c5d4dc0501efcdb32df055b35bd81ba27.tar.xz
Merge branch 'r8152-add-support-for-the-rtl8159-10gbit-usb-ethernet-chip'
Birger Koblitz says: ==================== r8152: Add support for the RTL8159 10Gbit USB Ethernet chip 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. ==================== Link: https://patch.msgid.link/20260505-rtl8159_net_next-v4-0-1a648a9c4d8d@birger-koblitz.de Signed-off-by: Jakub Kicinski <kuba@kernel.org>
-rw-r--r--drivers/net/usb/r8152.c345
1 files changed, 325 insertions, 20 deletions
diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c
index ae834876aa1a..d281ad5ed78e 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;
@@ -1242,6 +1247,7 @@ enum rtl_version {
RTL_VER_14,
RTL_VER_15,
RTL_VER_16,
+ RTL_VER_17,
RTL_VER_MAX
};
@@ -1260,6 +1266,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.
@@ -3426,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;
@@ -3465,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
@@ -3650,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,
@@ -3694,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;
@@ -4542,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;
@@ -4649,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;
}
@@ -5812,6 +5827,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);
@@ -6402,7 +6418,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);
@@ -6513,6 +6529,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 +6578,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 +6593,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);
}
@@ -6802,7 +6827,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);
@@ -6816,7 +6841,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);
@@ -6841,7 +6866,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);
@@ -6853,10 +6878,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);
}
@@ -6871,7 +6896,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);
}
@@ -7958,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;
}
@@ -7981,7 +8008,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) {
@@ -8105,6 +8132,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);
+ /* normal 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 cable performance */
+ sram2_write_w0w1(tp, 0x88de, 0xff00, 0);
+ /* 5G slave compatibility issue */
+ 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;
}
@@ -8140,6 +8351,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;
@@ -8149,14 +8372,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);
@@ -8170,6 +8393,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:
@@ -8186,6 +8410,12 @@ static void r8156_init(struct r8152 *tp)
return;
}
+ if (tp->version == RTL_VER_17 && r8159_wait_backup_restore(tp)) {
+ rtl_set_inaccessible(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));
@@ -8201,7 +8431,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);
@@ -8212,7 +8442,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);
@@ -8245,7 +8475,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);
@@ -8258,8 +8488,13 @@ 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)
+ /* 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
ocp_word_clr_bits(tp, MCU_TYPE_USB, USB_USB_CTRL, RX_AGG_DISABLE | RX_ZERO_EN);
@@ -8267,7 +8502,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 */
@@ -8708,7 +8943,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 +8975,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 +9041,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 +9208,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)
@@ -9628,6 +9890,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");
@@ -9644,6 +9929,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);
@@ -9652,6 +9939,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)
{
@@ -9690,6 +9979,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;
}
@@ -9781,6 +10076,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);
@@ -9933,6 +10231,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:
@@ -9967,6 +10266,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;
@@ -10093,6 +10397,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) },