net: phy: meson-gxl: fix interrupt handling in forced mode
authorHeiner Kallweit <hkallweit1@gmail.com>
Thu, 3 Mar 2022 07:54:15 +0000 (08:54 +0100)
committerJakub Kicinski <kuba@kernel.org>
Sat, 5 Mar 2022 05:03:45 +0000 (21:03 -0800)
This PHY doesn't support a link-up interrupt source. If aneg is enabled
we use the "aneg complete" interrupt for this purpose, but if aneg is
disabled link-up isn't signaled currently.
According to a vendor driver there's an additional "energy detect"
interrupt source that can be used to signal link-up if aneg is disabled.
We can safely ignore this interrupt source if aneg is enabled.

This patch was tested on a TX3 Mini TV box with S905W (even though
boot message says it's a S905D).

This issue has been existing longer, but due to changes in phylib and
the driver the patch applies only from the commit marked as fixed.

Fixes: 84c8f773d2dc ("net: phy: meson-gxl: remove the use of .ack_callback()")
Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
Link: https://lore.kernel.org/r/04cac530-ea1b-850e-6cfa-144a55c4d75d@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
drivers/net/phy/meson-gxl.c

index 7e7904f..c49062a 100644 (file)
 #define  INTSRC_LINK_DOWN      BIT(4)
 #define  INTSRC_REMOTE_FAULT   BIT(5)
 #define  INTSRC_ANEG_COMPLETE  BIT(6)
+#define  INTSRC_ENERGY_DETECT  BIT(7)
 #define INTSRC_MASK    30
 
+#define INT_SOURCES (INTSRC_LINK_DOWN | INTSRC_ANEG_COMPLETE | \
+                    INTSRC_ENERGY_DETECT)
+
 #define BANK_ANALOG_DSP                0
 #define BANK_WOL               1
 #define BANK_BIST              3
@@ -200,7 +204,6 @@ static int meson_gxl_ack_interrupt(struct phy_device *phydev)
 
 static int meson_gxl_config_intr(struct phy_device *phydev)
 {
-       u16 val;
        int ret;
 
        if (phydev->interrupts == PHY_INTERRUPT_ENABLED) {
@@ -209,16 +212,9 @@ static int meson_gxl_config_intr(struct phy_device *phydev)
                if (ret)
                        return ret;
 
-               val = INTSRC_ANEG_PR
-                       | INTSRC_PARALLEL_FAULT
-                       | INTSRC_ANEG_LP_ACK
-                       | INTSRC_LINK_DOWN
-                       | INTSRC_REMOTE_FAULT
-                       | INTSRC_ANEG_COMPLETE;
-               ret = phy_write(phydev, INTSRC_MASK, val);
+               ret = phy_write(phydev, INTSRC_MASK, INT_SOURCES);
        } else {
-               val = 0;
-               ret = phy_write(phydev, INTSRC_MASK, val);
+               ret = phy_write(phydev, INTSRC_MASK, 0);
 
                /* Ack any pending IRQ */
                ret = meson_gxl_ack_interrupt(phydev);
@@ -237,9 +233,16 @@ static irqreturn_t meson_gxl_handle_interrupt(struct phy_device *phydev)
                return IRQ_NONE;
        }
 
+       irq_status &= INT_SOURCES;
+
        if (irq_status == 0)
                return IRQ_NONE;
 
+       /* Aneg-complete interrupt is used for link-up detection */
+       if (phydev->autoneg == AUTONEG_ENABLE &&
+           irq_status == INTSRC_ENERGY_DETECT)
+               return IRQ_HANDLED;
+
        phy_trigger_machine(phydev);
 
        return IRQ_HANDLED;