summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBirger Koblitz <mail@birger-koblitz.de>2026-02-24 18:40:14 +0100
committerJakub Kicinski <kuba@kernel.org>2026-02-27 18:42:22 -0800
commite8e83b67960c20a9e60d4181631509d59f03488b (patch)
tree676414d18a20fd2acaf99804720b4a7102185ad3
parentc31770c49348fb019167fa95119f330597c99193 (diff)
r8152: Add 2500baseT EEE status/configuration support
The r8152 driver supports the RTL8156, which is a 2.5Gbit Ethernet controller for USB 3.0, for which support is added for configuring and displaying the EEE advertisement status for 2.5GBit connections. The patch also corrects the determination of whether EEE is active to include the 2.5GBit connection status and make the determination dependent not on the desired speed configuration (tp->speed), but on the actual speed used by the controller. For consistency, this is corrected also for the RTL8152/3. This was tested on an Edimax EU-4307 V1.0 USB-Ethernet adapter with RTL8156, and a SECOMP Value 12.99.1115 USB-C 3.1 Ethernet converter with RTL8153. Signed-off-by: Birger Koblitz <mail@birger-koblitz.de> Link: https://patch.msgid.link/20260224-b4-eee2g5-v2-1-cf5c83df036e@birger-koblitz.de Signed-off-by: Jakub Kicinski <kuba@kernel.org>
-rw-r--r--drivers/net/usb/r8152.c50
1 files changed, 42 insertions, 8 deletions
diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c
index 4af85728ac4f..ea7c1eadc864 100644
--- a/drivers/net/usb/r8152.c
+++ b/drivers/net/usb/r8152.c
@@ -207,6 +207,7 @@
#define OCP_EEE_LPABLE 0xa5d2
#define OCP_10GBT_CTRL 0xa5d4
#define OCP_10GBT_STAT 0xa5d6
+#define OCP_EEE_LPABLE2 0xa6d0
#define OCP_EEE_ADV2 0xa6d4
#define OCP_PHY_STATE 0xa708 /* nway state for 8153 */
#define OCP_PHY_PATCH_STAT 0xb800
@@ -948,6 +949,7 @@ struct r8152 {
u16 ocp_base;
u16 speed;
u16 eee_adv;
+ u16 eee_adv2;
u8 *intr_buff;
u8 version;
u8 duplex;
@@ -5393,7 +5395,7 @@ static void r8156_eee_en(struct r8152 *tp, bool enable)
config = ocp_reg_read(tp, OCP_EEE_ADV2);
- if (enable)
+ if (enable && (tp->eee_adv2 & MDIO_EEE_2_5GT))
config |= MDIO_EEE_2_5GT;
else
config &= ~MDIO_EEE_2_5GT;
@@ -8922,7 +8924,8 @@ static void rtl8152_get_strings(struct net_device *dev, u32 stringset, u8 *data)
static int r8152_get_eee(struct r8152 *tp, struct ethtool_keee *eee)
{
- __ETHTOOL_DECLARE_LINK_MODE_MASK(common);
+ __ETHTOOL_DECLARE_LINK_MODE_MASK(common) = {};
+ u16 speed = rtl8152_get_speed(tp);
u16 val;
val = r8152_mmd_read(tp, MDIO_MMD_PCS, MDIO_PCS_EEE_ABLE);
@@ -8936,8 +8939,14 @@ static int r8152_get_eee(struct r8152 *tp, struct ethtool_keee *eee)
eee->eee_enabled = tp->eee_en;
- linkmode_and(common, eee->advertised, eee->lp_advertised);
- eee->eee_active = phy_check_valid(tp->speed, tp->duplex, common);
+ if (speed & _1000bps)
+ linkmode_set_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT, common);
+ if (speed & _100bps)
+ linkmode_set_bit(ETHTOOL_LINK_MODE_100baseT_Full_BIT, common);
+
+ linkmode_and(common, common, eee->advertised);
+ linkmode_and(common, common, eee->lp_advertised);
+ eee->eee_active = !linkmode_empty(common);
return 0;
}
@@ -8948,7 +8957,10 @@ 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) {
+ val = linkmode_to_mii_eee_cap2_t(eee->advertised);
+ tp->eee_adv2 = val;
+ }
rtl_eee_enable(tp, tp->eee_en);
return 0;
@@ -8956,7 +8968,8 @@ static int r8152_set_eee(struct r8152 *tp, struct ethtool_keee *eee)
static int r8153_get_eee(struct r8152 *tp, struct ethtool_keee *eee)
{
- __ETHTOOL_DECLARE_LINK_MODE_MASK(common);
+ __ETHTOOL_DECLARE_LINK_MODE_MASK(common) = {};
+ u16 speed = rtl8152_get_speed(tp);
u16 val;
val = ocp_reg_read(tp, OCP_EEE_ABLE);
@@ -8968,10 +8981,29 @@ static int r8153_get_eee(struct r8152 *tp, struct ethtool_keee *eee)
val = ocp_reg_read(tp, OCP_EEE_LPABLE);
mii_eee_cap1_mod_linkmode_t(eee->lp_advertised, val);
+ if (tp->support_2500full) {
+ linkmode_set_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT, eee->supported);
+
+ val = ocp_reg_read(tp, OCP_EEE_ADV2);
+ mii_eee_cap2_mod_linkmode_adv_t(eee->advertised, val);
+
+ val = ocp_reg_read(tp, OCP_EEE_LPABLE2);
+ mii_eee_cap2_mod_linkmode_adv_t(eee->lp_advertised, val);
+
+ if (speed & _2500bps)
+ linkmode_set_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT, common);
+ }
+
eee->eee_enabled = tp->eee_en;
- linkmode_and(common, eee->advertised, eee->lp_advertised);
- eee->eee_active = phy_check_valid(tp->speed, tp->duplex, common);
+ if (speed & _1000bps)
+ linkmode_set_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT, common);
+ if (speed & _100bps)
+ linkmode_set_bit(ETHTOOL_LINK_MODE_100baseT_Full_BIT, common);
+
+ linkmode_and(common, common, eee->advertised);
+ linkmode_and(common, common, eee->lp_advertised);
+ eee->eee_active = !linkmode_empty(common);
return 0;
}
@@ -9512,6 +9544,7 @@ static int rtl_ops_init(struct r8152 *tp)
case RTL_VER_11:
tp->eee_en = true;
tp->eee_adv = MDIO_EEE_1000T | MDIO_EEE_100TX;
+ tp->eee_adv2 = MDIO_EEE_2_5GT;
fallthrough;
case RTL_VER_10:
ops->init = r8156_init;
@@ -9537,6 +9570,7 @@ static int rtl_ops_init(struct r8152 *tp)
case RTL_VER_15:
tp->eee_en = true;
tp->eee_adv = MDIO_EEE_1000T | MDIO_EEE_100TX;
+ tp->eee_adv2 = MDIO_EEE_2_5GT;
ops->init = r8156b_init;
ops->enable = rtl8156b_enable;
ops->disable = rtl8153_disable;