[PATCH net-next v3 1/2] r8152: Add support for 5Gbit Link Speeds and EEE
From: Birger Koblitz <hidden>
Date: 2026-03-20 11:14:41
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
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 <redacted> --- drivers/net/usb/r8152.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 53 insertions(+), 3 deletions(-)
diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c
index 3b6d4252d34c63ead8f11a120e212325a5f7d505..bab8e10e5f99afcb332e333c2739ed7509b03419 100644
--- a/drivers/net/usb/r8152.c
+++ b/drivers/net/usb/r8152.c@@ -604,6 +604,7 @@ enum spd_duplex { FORCE_100M_FULL, FORCE_1000M_FULL, NWAY_2500M_FULL, + NWAY_5000M_FULL, }; /* OCP_ALDPS_CONFIG */
@@ -725,6 +726,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),
@@ -738,6 +740,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
@@ -944,6 +947,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;
@@ -1194,6 +1198,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.
@@ -5400,6 +5405,11 @@ static void r8156_eee_en(struct r8152 *tp, bool enable) else 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); }
@@ -6298,6 +6308,9 @@ static int rtl8152_set_speed(struct r8152 *tp, u8 autoneg, u32 speed, u8 duplex, if (tp->support_2500full) support |= RTL_ADVERTISED_2500_FULL; + + if (tp->support_5000full) + support |= RTL_ADVERTISED_5000_FULL; } if (!(advertising & support))
@@ -6343,15 +6356,20 @@ 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) { + 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); }
@@ -8780,6 +8798,9 @@ int rtl8152_get_link_ksettings(struct net_device *netdev, linkmode_mod_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT, cmd->link_modes.supported, tp->support_2500full); + linkmode_mod_bit(ETHTOOL_LINK_MODE_5000baseT_Full_BIT, + cmd->link_modes.supported, tp->support_5000full); + if (tp->support_2500full) { linkmode_mod_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT, cmd->link_modes.advertising,
@@ -8793,6 +8814,19 @@ int rtl8152_get_link_ksettings(struct net_device *netdev, cmd->base.speed = SPEED_2500; } + if (tp->support_5000full) { + linkmode_mod_bit(ETHTOOL_LINK_MODE_5000baseT_Full_BIT, + cmd->link_modes.advertising, + ocp_reg_read(tp, OCP_10GBT_CTRL) & MDIO_AN_10GBT_CTRL_ADV5G); + + linkmode_mod_bit(ETHTOOL_LINK_MODE_5000baseT_Full_BIT, + cmd->link_modes.lp_advertising, + ocp_reg_read(tp, 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); usb_autopm_put_interface(tp->intf);
@@ -8840,6 +8874,10 @@ static int rtl8152_set_link_ksettings(struct net_device *dev, 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,
@@ -8957,7 +8995,7 @@ static int r8152_set_eee(struct r8152 *tp, struct ethtool_keee *eee) 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; }
@@ -8994,6 +9032,13 @@ static int r8153_get_eee(struct r8152 *tp, struct ethtool_keee *eee) 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)
@@ -9934,6 +9979,11 @@ static int rtl8152_probe_once(struct usb_interface *intf, } 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;
--
2.47.3