The RTL8157 supports 5GBit Link speeds. Add support for this speed
in the setup and setting/getting through ethool. Also add 5GBit EEE.
Add functionality for setup and ethtool get/set methods.
Signed-off-by: Birger Koblitz <mail@birger-koblitz.de>
---
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
Hi Birger,
W dniu 17.03.2026 o 19:07, Birger Koblitz pisze:
> The RTL8157 supports 5GBit Link speeds. Add support for this speed
> in the setup and setting/getting through ethool. Also add 5GBit EEE.
> Add functionality for setup and ethtool get/set methods.
>
> Signed-off-by: Birger Koblitz <mail@birger-koblitz.de>
> ---
> 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),
Based on other Realtek chips, I guess that BIT(11_ corresponds to 2500 Mbps
over two twisted pairs. Realtek calls this 5G Lite. Similarly, there are
2.5G Lite and 1G Lite, offering 1250 Mbps and 500 Mbps, respectively, over
two pairs of wires.
> _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;
Best regards,
Aleksander
> > @@ -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),
>
> Based on other Realtek chips, I guess that BIT(11_ corresponds to 2500 Mbps
> over two twisted pairs. Realtek calls this 5G Lite. Similarly, there are
> 2.5G Lite and 1G Lite, offering 1250 Mbps and 500 Mbps, respectively, over
> two pairs of wires.
Oh, that is different. Normally for a -T2 link, you double the clock
frequency, so you keep the normal bandwidth. But you are saying it
does 500Base-T2, 1250Base-T2, 2500Base-T2?
Can it select these modes on its own, if the link partner is another
Realtek device? Many 1G PHYs will detect if a pair is broken and
downshift to 100Mbps, which only require two working pairs. But this
device has the option of downshifting to 500M.
Andrew
Hi Andrew,
On 19/03/2026 23:46, Andrew Lunn wrote:
>>> @@ -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),
>> Based on other Realtek chips, I guess that BIT(11_ corresponds to 2500 Mbps
>> over two twisted pairs. Realtek calls this 5G Lite. Similarly, there are
>> 2.5G Lite and 1G Lite, offering 1250 Mbps and 500 Mbps, respectively, over
>> two pairs of wires.
> Oh, that is different. Normally for a -T2 link, you double the clock
> frequency, so you keep the normal bandwidth. But you are saying it
> does 500Base-T2, 1250Base-T2, 2500Base-T2?
It works exactly like you describe. It’s described in the RTL8156B
datasheet[1] if your interested. To be honest, I’ve never used Lite Mode.
I think it’s disabled by default in the driver.
1. https://www.lcsc.com/datasheet/C41376388.pdf
>
> Can it select these modes on its own, if the link partner is another
> Realtek device? Many 1G PHYs will detect if a pair is broken and
> downshift to 100Mbps, which only require two working pairs. But this
> device has the option of downshifting to 500M.
>
> Andrew
Best regards,
Aleksander
This is an AI-generated review of your patch. The human sending this
email has considered the AI review valid, or at least plausible.
For local reproduction steps see https://netdev-ai.bots.linux.dev/ai-local.html
---
r8152: Add support for 5Gbit Link Speeds and EEE
The RTL8157 supports 5GBit Link speeds. This commit adds support for this
speed in the setup and setting/getting through ethtool, along with 5GBit
EEE functionality for setup and ethtool get/set methods.
> The RTL8157 supports 5GBit Link speeds. Add support for this speed
> in the setup and setting/getting through ethool. Also add 5GBit EEE.
^^^^^^
This isn't a bug, but there's a typo: 'ethool' should be 'ethtool'.
> diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c
> index 3b6d4252d34c..bab8e10e5f99 100644
> --- a/drivers/net/usb/r8152.c
> +++ b/drivers/net/usb/r8152.c
[ ... ]
> @@ -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);
> }
Does r8156_ups_flags() handle the new NWAY_5000M_FULL value?
Looking at r8156_ups_flags() in drivers/net/usb/r8152.c, the function
switches on tp->ups_info.speed_duplex:
static u16 r8156_ups_flags(struct r8152 *tp)
{
u16 ups_flags = 0;
if (tp->ups_info.green)
ups_flags |= UPS_FLAGS_EN_GREEN;
if (tp->ups_info.aldps)
ups_flags |= UPS_FLAGS_EN_ALDPS;
if (tp->ups_info.eee)
ups_flags |= UPS_FLAGS_EN_EEE;
if (tp->ups_info.flow_control)
ups_flags |= UPS_FLAGS_EN_FLOW_CONTROL;
if (tp->ups_info.eee_ckdiv)
ups_flags |= UPS_FLAGS_EN_EEE_CKDIV;
if (tp->ups_info._10m_ckdiv)
ups_flags |= UPS_FLAGS_EN_10M_CKDIV;
if (tp->ups_info.eee_cmod_lv)
ups_flags |= UPS_FLAGS_EEE_CMOD_LV_EN;
if (tp->ups_info._250m_ckdiv)
ups_flags |= UPS_FLAGS_250M_CKDIV;
switch (tp->ups_info.speed_duplex) {
case FORCE_10M_HALF:
ups_flags |= ups_flags_speed(0);
break;
case FORCE_10M_FULL:
ups_flags |= ups_flags_speed(1);
break;
case FORCE_100M_HALF:
ups_flags |= ups_flags_speed(2);
break;
case FORCE_100M_FULL:
ups_flags |= ups_flags_speed(3);
break;
case NWAY_10M_HALF:
ups_flags |= ups_flags_speed(4);
break;
case NWAY_10M_FULL:
ups_flags |= ups_flags_speed(5);
break;
case NWAY_100M_HALF:
ups_flags |= ups_flags_speed(6);
break;
case NWAY_100M_FULL:
ups_flags |= ups_flags_speed(7);
break;
case NWAY_1000M_FULL:
ups_flags |= ups_flags_speed(8);
break;
case NWAY_2500M_FULL:
ups_flags |= ups_flags_speed(9);
break;
default:
break;
}
return ups_flags;
}
When rtl8152_set_speed() sets tp->ups_info.speed_duplex = NWAY_5000M_FULL
and r8156_ups_en(enable=true) subsequently calls r8156_ups_flags(), the
switch falls through to the default case and no speed bits are set in the
UPS flags word.
Is the UPS power management configuration incorrect for 5Gbit link speeds
without a case for NWAY_5000M_FULL in r8156_ups_flags()?
This path is activated by the next commit in the series (58ba3b6c476d
'r8152: Add support for the RTL8157 hardware') which sets
support_5000full = 1.
[ ... ]
Hi Simon, thanks a lot for reviewing this patch! On 19/03/2026 5:51 pm, Simon Horman wrote: >> The RTL8157 supports 5GBit Link speeds. Add support for this speed >> in the setup and setting/getting through ethool. Also add 5GBit EEE. > ^^^^^^ > This isn't a bug, but there's a typo: 'ethool' should be 'ethtool'. Will be fixed in v3. > When rtl8152_set_speed() sets tp->ups_info.speed_duplex = NWAY_5000M_FULL > and r8156_ups_en(enable=true) subsequently calls r8156_ups_flags(), the > switch falls through to the default case and no speed bits are set in the > UPS flags word. Yes, this analysis is correct. > > Is the UPS power management configuration incorrect for 5Gbit link speeds > without a case for NWAY_5000M_FULL in r8156_ups_flags()? The out-of-tree driver also does not set any flags in USB_UPS_FLAGS in the 5000M case. Maybe this is an oversight in that driver, but according to my tests, the power management works. In any case, I would not be able to guess the correct register value with any confidence for the NWAY_5000M_FULL case: the bits are different from the speed bits in PLA_PHYSTATUS. The RTL8157 also has other differences in USB power management compared to previous generations, such as introducing register USB_U2P3_V2_CTRL. So, to the best of my knowledge, the proposed patch is correct. > > This path is activated by the next commit in the series (58ba3b6c476d > 'r8152: Add support for the RTL8157 hardware') which sets > support_5000full = 1. > > [ ... ]
On Fri, Mar 20, 2026 at 06:29:20AM +0100, Birger Koblitz wrote: > Hi Simon, thanks a lot for reviewing this patch! ... > > Is the UPS power management configuration incorrect for 5Gbit link speeds > > without a case for NWAY_5000M_FULL in r8156_ups_flags()? > The out-of-tree driver also does not set any flags in USB_UPS_FLAGS in the > 5000M case. Maybe this is an oversight in that driver, but according to my > tests, the power management works. In any case, I would not be able to guess > the correct register value with any confidence for the NWAY_5000M_FULL case: > the bits are different from the speed bits in PLA_PHYSTATUS. The RTL8157 > also has other differences in USB power management compared to previous > generations, such as introducing register USB_U2P3_V2_CTRL. So, to the best > of my knowledge, the proposed patch is correct. Thanks for the clarification. Perhaps someone can provide insight here. But in lieu of that I agree with your approach. > > > > > This path is activated by the next commit in the series (58ba3b6c476d > > 'r8152: Add support for the RTL8157 hardware') which sets > > support_5000full = 1. > > > > [ ... ] >
On Tue, Mar 17, 2026 at 07:07:14PM +0100, Birger Koblitz wrote:
> The RTL8157 supports 5GBit Link speeds. Add support for this speed
> in the setup and setting/getting through ethool. Also add 5GBit EEE.
> Add functionality for setup and ethtool get/set methods.
>
> Signed-off-by: Birger Koblitz <mail@birger-koblitz.de>
> ---
> 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),
Any idea what bit 11 is for? There is not normally any speed between
2.5G and 5G.
> @@ -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;
> + }
Let me check i understand this.
ethtool supported will indicate 5G, independent of the USB speed? But
it will only advertise 5G if the USB bus is USB 3.0 or higher, which
can do 5G. The user can however use ethtool to advertise 5G, for USB
2.0?
I suppose the question is, are there any link partners which do 2.5G
and/or 5G, but not 1G? I guess not.
Andrew
On 19/03/2026 5:29 pm, Andrew Lunn wrote:
> On Tue, Mar 17, 2026 at 07:07:14PM +0100, Birger Koblitz wrote:
>> The RTL8157 supports 5GBit Link speeds. Add support for this speed
>> in the setup and setting/getting through ethool. Also add 5GBit EEE.
>> Add functionality for setup and ethtool get/set methods.
>>
>> Signed-off-by: Birger Koblitz <mail@birger-koblitz.de>
>> ---
>> 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),
>
> Any idea what bit 11 is for? There is not normally any speed between
> 2.5G and 5G.
No, I have no idea, and I puzzled about this, too, plus triple checked
it. But this reflects a hardware register, hardware engineers sometimes
leave bits out. _10000bps will be bit 14 for the RTL8159.
>
>> @@ -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;
>> + }
>
> Let me check i understand this.
>
> ethtool supported will indicate 5G, independent of the USB speed? But
> it will only advertise 5G if the USB bus is USB 3.0 or higher, which
> can do 5G. The user can however use ethtool to advertise 5G, for USB
> 2.0?
I puzzled about this, too and then decided to leave it like this. The
support for 5GBit is a hardware feature, so it is OK to state it is
supported. But my tests with slower USB connections really show that it
is better to rely on throttling the link speed itself, since flow
control will do a rather bad job if the Ethernet connection can handle
much more than the USB connection behind. However, if the user insists,
they can advertise a higher speed.
>
> I suppose the question is, are there any link partners which do 2.5G
> and/or 5G, but not 1G? I guess not.
That was my rationale, too.
Birger
© 2016 - 2026 Red Hat, Inc.