]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
net: txgbe: support CR modules for AML devices
authorJiawen Wu <jiawenwu@trustnetic.com>
Tue, 18 Nov 2025 08:02:55 +0000 (16:02 +0800)
committerPaolo Abeni <pabeni@redhat.com>
Thu, 20 Nov 2025 11:47:26 +0000 (12:47 +0100)
Support to identify 25G/10G CR modules for AML devices. Autoneg is
enbaled by default in CR mode.

Signed-off-by: Jiawen Wu <jiawenwu@trustnetic.com>
Link: https://patch.msgid.link/20251118080259.24676-2-jiawenwu@trustnetic.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
drivers/net/ethernet/wangxun/txgbe/txgbe_aml.c
drivers/net/ethernet/wangxun/txgbe/txgbe_ethtool.c

index 35eebdb0776168e21c9488b1926a03316046a404..a7650f548fa4d52b49c9e99457b68a5e69837a76 100644 (file)
@@ -104,7 +104,8 @@ static int txgbe_set_phy_link_hostif(struct wx *wx, int speed, int autoneg, int
                                         WX_HI_COMMAND_TIMEOUT, true);
 }
 
-static void txgbe_get_link_capabilities(struct wx *wx, int *speed, int *duplex)
+static void txgbe_get_link_capabilities(struct wx *wx, int *speed,
+                                       int *autoneg, int *duplex)
 {
        struct txgbe *txgbe = wx->priv;
 
@@ -115,6 +116,7 @@ static void txgbe_get_link_capabilities(struct wx *wx, int *speed, int *duplex)
        else
                *speed = SPEED_UNKNOWN;
 
+       *autoneg = phylink_test(txgbe->advertising, Autoneg);
        *duplex = *speed == SPEED_UNKNOWN ? DUPLEX_HALF : DUPLEX_FULL;
 }
 
@@ -135,11 +137,11 @@ static void txgbe_get_mac_link(struct wx *wx, int *speed)
 
 int txgbe_set_phy_link(struct wx *wx)
 {
-       int speed, duplex, err;
+       int speed, autoneg, duplex, err;
 
-       txgbe_get_link_capabilities(wx, &speed, &duplex);
+       txgbe_get_link_capabilities(wx, &speed, &autoneg, &duplex);
 
-       err = txgbe_set_phy_link_hostif(wx, speed, 0, duplex);
+       err = txgbe_set_phy_link_hostif(wx, speed, autoneg, duplex);
        if (err) {
                wx_err(wx, "Failed to setup link\n");
                return err;
@@ -154,19 +156,43 @@ static int txgbe_sfp_to_linkmodes(struct wx *wx, struct txgbe_sfp_id *id)
        DECLARE_PHY_INTERFACE_MASK(interfaces);
        struct txgbe *txgbe = wx->priv;
 
-       if (id->com_25g_code & (TXGBE_SFF_25GBASESR_CAPABLE |
-                               TXGBE_SFF_25GBASEER_CAPABLE |
-                               TXGBE_SFF_25GBASELR_CAPABLE)) {
-               phylink_set(modes, 25000baseSR_Full);
+       if (id->cable_tech & TXGBE_SFF_DA_PASSIVE_CABLE) {
+               txgbe->link_port = PORT_DA;
+               phylink_set(modes, Autoneg);
+               if (id->com_25g_code == TXGBE_SFF_25GBASECR_91FEC ||
+                   id->com_25g_code == TXGBE_SFF_25GBASECR_74FEC ||
+                   id->com_25g_code == TXGBE_SFF_25GBASECR_NOFEC) {
+                       phylink_set(modes, 25000baseCR_Full);
+                       phylink_set(modes, 10000baseCR_Full);
+                       __set_bit(PHY_INTERFACE_MODE_25GBASER, interfaces);
+                       __set_bit(PHY_INTERFACE_MODE_10GBASER, interfaces);
+               } else {
+                       phylink_set(modes, 10000baseCR_Full);
+                       __set_bit(PHY_INTERFACE_MODE_10GBASER, interfaces);
+               }
+       } else if (id->cable_tech & TXGBE_SFF_DA_ACTIVE_CABLE) {
+               txgbe->link_port = PORT_DA;
+               phylink_set(modes, Autoneg);
+               phylink_set(modes, 25000baseCR_Full);
                __set_bit(PHY_INTERFACE_MODE_25GBASER, interfaces);
-       }
-       if (id->com_10g_code & TXGBE_SFF_10GBASESR_CAPABLE) {
-               phylink_set(modes, 10000baseSR_Full);
-               __set_bit(PHY_INTERFACE_MODE_10GBASER, interfaces);
-       }
-       if (id->com_10g_code & TXGBE_SFF_10GBASELR_CAPABLE) {
-               phylink_set(modes, 10000baseLR_Full);
-               __set_bit(PHY_INTERFACE_MODE_10GBASER, interfaces);
+       } else {
+               if (id->com_25g_code == TXGBE_SFF_25GBASESR_CAPABLE ||
+                   id->com_25g_code == TXGBE_SFF_25GBASEER_CAPABLE ||
+                   id->com_25g_code == TXGBE_SFF_25GBASELR_CAPABLE) {
+                       txgbe->link_port = PORT_FIBRE;
+                       phylink_set(modes, 25000baseSR_Full);
+                       __set_bit(PHY_INTERFACE_MODE_25GBASER, interfaces);
+               }
+               if (id->com_10g_code & TXGBE_SFF_10GBASESR_CAPABLE) {
+                       txgbe->link_port = PORT_FIBRE;
+                       phylink_set(modes, 10000baseSR_Full);
+                       __set_bit(PHY_INTERFACE_MODE_10GBASER, interfaces);
+               }
+               if (id->com_10g_code & TXGBE_SFF_10GBASELR_CAPABLE) {
+                       txgbe->link_port = PORT_FIBRE;
+                       phylink_set(modes, 10000baseLR_Full);
+                       __set_bit(PHY_INTERFACE_MODE_10GBASER, interfaces);
+               }
        }
 
        if (phy_interface_empty(interfaces)) {
@@ -177,7 +203,6 @@ static int txgbe_sfp_to_linkmodes(struct wx *wx, struct txgbe_sfp_id *id)
        phylink_set(modes, Pause);
        phylink_set(modes, Asym_Pause);
        phylink_set(modes, FIBRE);
-       txgbe->link_port = PORT_FIBRE;
 
        if (!linkmode_equal(txgbe->sfp_support, modes)) {
                linkmode_copy(txgbe->sfp_support, modes);
index e285b088c7b267cab0b0582ffcde15f058ccf00d..e8dd277a35c7a42b37295eeaafefcb97f9c62774 100644 (file)
@@ -30,7 +30,8 @@ int txgbe_get_link_ksettings(struct net_device *netdev,
                return 0;
 
        cmd->base.port = txgbe->link_port;
-       cmd->base.autoneg = AUTONEG_DISABLE;
+       cmd->base.autoneg = phylink_test(txgbe->advertising, Autoneg) ?
+                           AUTONEG_ENABLE : AUTONEG_DISABLE;
        linkmode_copy(cmd->link_modes.supported, txgbe->sfp_support);
        linkmode_copy(cmd->link_modes.advertising, txgbe->advertising);