]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
net: txgbe: optimize the flow to setup PHY for AML devices
authorJiawen Wu <jiawenwu@trustnetic.com>
Tue, 14 Oct 2025 06:17:25 +0000 (14:17 +0800)
committerPaolo Abeni <pabeni@redhat.com>
Thu, 16 Oct 2025 13:41:34 +0000 (15:41 +0200)
To adapt to new firmware for AML devices, the driver should send the
"SET_LINK_CMD" to the firmware only once when switching PHY interface
mode, and no longer needs to re-trigger PHY configuration based on the
RX signal interrupt (TXGBE_GPIOBIT_3).

In previous firmware versions, the PHY was configured only after receiving
"SET_LINK_CMD", and might remain incomplete if the RX signal was lost.
To handle this case, the driver used TXGBE_GPIOBIT_3 interrupt to resend
the command. This workaround is no longer necessary with the new firmware.

And the unknown link speed is permitted in the mailbox buffer.

Signed-off-by: Jiawen Wu <jiawenwu@trustnetic.com>
Link: https://patch.msgid.link/20251014061726.36660-3-jiawenwu@trustnetic.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
drivers/net/ethernet/wangxun/libwx/wx_type.h
drivers/net/ethernet/wangxun/txgbe/txgbe_aml.c
drivers/net/ethernet/wangxun/txgbe/txgbe_type.h

index d89b9b8a0a2ce06a6762d6c597ba3808fe29b43a..4880268b620e1b35e7c8748dbf7d23450c25beaa 100644 (file)
@@ -1271,8 +1271,6 @@ struct wx {
 
        /* PHY stuff */
        bool notify_down;
-       int adv_speed;
-       int adv_duplex;
        unsigned int link;
        int speed;
        int duplex;
index dc87ccad965240c57e66e1729968dbed5e7ceb4b..1da92431c32428d74d9ada00139dc50aaa11c4aa 100644 (file)
@@ -19,8 +19,8 @@ void txgbe_gpio_init_aml(struct wx *wx)
 {
        u32 status;
 
-       wr32(wx, WX_GPIO_INTTYPE_LEVEL, TXGBE_GPIOBIT_2 | TXGBE_GPIOBIT_3);
-       wr32(wx, WX_GPIO_INTEN, TXGBE_GPIOBIT_2 | TXGBE_GPIOBIT_3);
+       wr32(wx, WX_GPIO_INTTYPE_LEVEL, TXGBE_GPIOBIT_2);
+       wr32(wx, WX_GPIO_INTEN, TXGBE_GPIOBIT_2);
 
        status = rd32(wx, WX_GPIO_INTSTATUS);
        for (int i = 0; i < 6; i++) {
@@ -42,11 +42,6 @@ irqreturn_t txgbe_gpio_irq_handler_aml(int irq, void *data)
                wr32(wx, WX_GPIO_EOI, TXGBE_GPIOBIT_2);
                wx_service_event_schedule(wx);
        }
-       if (status & TXGBE_GPIOBIT_3) {
-               set_bit(WX_FLAG_NEED_LINK_CONFIG, wx->flags);
-               wx_service_event_schedule(wx);
-               wr32(wx, WX_GPIO_EOI, TXGBE_GPIOBIT_3);
-       }
 
        wr32(wx, WX_GPIO_INTMASK, 0);
        return IRQ_HANDLED;
@@ -96,6 +91,9 @@ static int txgbe_set_phy_link_hostif(struct wx *wx, int speed, int autoneg, int
        case SPEED_10000:
                buffer.speed = TXGBE_LINK_SPEED_10GB_FULL;
                break;
+       default:
+               buffer.speed = TXGBE_LINK_SPEED_UNKNOWN;
+               break;
        }
 
        buffer.fec_mode = TXGBE_PHY_FEC_AUTO;
@@ -106,19 +104,18 @@ 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)
+static void txgbe_get_link_capabilities(struct wx *wx, int *speed, int *duplex)
 {
        struct txgbe *txgbe = wx->priv;
 
        if (test_bit(PHY_INTERFACE_MODE_25GBASER, txgbe->sfp_interfaces))
-               wx->adv_speed = SPEED_25000;
+               *speed = SPEED_25000;
        else if (test_bit(PHY_INTERFACE_MODE_10GBASER, txgbe->sfp_interfaces))
-               wx->adv_speed = SPEED_10000;
+               *speed = SPEED_10000;
        else
-               wx->adv_speed = SPEED_UNKNOWN;
+               *speed = SPEED_UNKNOWN;
 
-       wx->adv_duplex = wx->adv_speed == SPEED_UNKNOWN ?
-                        DUPLEX_HALF : DUPLEX_FULL;
+       *duplex = *speed == SPEED_UNKNOWN ? DUPLEX_HALF : DUPLEX_FULL;
 }
 
 static void txgbe_get_phy_link(struct wx *wx, int *speed)
@@ -138,23 +135,11 @@ static void txgbe_get_phy_link(struct wx *wx, int *speed)
 
 int txgbe_set_phy_link(struct wx *wx)
 {
-       int speed, err;
-       u32 gpio;
+       int speed, duplex, err;
 
-       /* Check RX signal */
-       gpio = rd32(wx, WX_GPIO_EXT);
-       if (gpio & TXGBE_GPIOBIT_3)
-               return -ENODEV;
+       txgbe_get_link_capabilities(wx, &speed, &duplex);
 
-       txgbe_get_link_capabilities(wx);
-       if (wx->adv_speed == SPEED_UNKNOWN)
-               return -ENODEV;
-
-       txgbe_get_phy_link(wx, &speed);
-       if (speed == wx->adv_speed)
-               return 0;
-
-       err = txgbe_set_phy_link_hostif(wx, wx->adv_speed, 0, wx->adv_duplex);
+       err = txgbe_set_phy_link_hostif(wx, speed, 0, duplex);
        if (err) {
                wx_err(wx, "Failed to setup link\n");
                return err;
@@ -230,14 +215,7 @@ int txgbe_identify_sfp(struct wx *wx)
                return -ENODEV;
        }
 
-       err = txgbe_sfp_to_linkmodes(wx, id);
-       if (err)
-               return err;
-
-       if (gpio & TXGBE_GPIOBIT_3)
-               set_bit(WX_FLAG_NEED_LINK_CONFIG, wx->flags);
-
-       return 0;
+       return txgbe_sfp_to_linkmodes(wx, id);
 }
 
 void txgbe_setup_link(struct wx *wx)
index 9d53c7413f7b00e1f369cd64fbb4915cc5a1837c..b9a4ba48f5b99f8d6aa8fe567663184c651c4765 100644 (file)
@@ -314,6 +314,7 @@ void txgbe_up(struct wx *wx);
 int txgbe_setup_tc(struct net_device *dev, u8 tc);
 void txgbe_do_reset(struct net_device *netdev);
 
+#define TXGBE_LINK_SPEED_UNKNOWN        0
 #define TXGBE_LINK_SPEED_10GB_FULL      4
 #define TXGBE_LINK_SPEED_25GB_FULL      0x10