openwrt/target/linux/generic/pending-6.6/999-net-phy-move-LED-polarity-to-phy_init_hw.patch
Robert Marko f04e377a50 generic: backport QCA808x possible interfaces fix
QCA808x does not currently fill in the possible_interfaces.

This leads to Phylink not being aware that it supports 2500Base-X as well
so in cases where it is connected to a DSA switch like MV88E6393 it will
limit that port to phy-mode set in the DTS.

That means that if SGMII is used you are limited to 1G only while if
2500Base-X was set you are limited to 2.5G only.

Populating the possible_interfaces fixes this, so lets backport the patches
from kernel 6.9.

This also includes a backport of the Phylink PHY validation series from
kernel 6.8 that allows the use of possible_interfaces.

Link: https://github.com/openwrt/openwrt/pull/15765
Signed-off-by: Robert Marko <robimarko@gmail.com>
2024-06-24 09:46:19 +02:00

101 lines
2.7 KiB
Diff

From 6e6fff51ae5e54092611d174fa45fa78c237a415 Mon Sep 17 00:00:00 2001
From: Christian Marangi <ansuelsmth@gmail.com>
Date: Tue, 21 May 2024 20:01:46 +0200
Subject: [PATCH] net: phy: move LED polarity to phy_init_hw
Some PHY reset the polarity on reset and this cause the LED to
malfunction as LED polarity is configured only when LED is
registered.
To better handle this, move the LED polarity configuration in
phy_init_hw to reconfigure it after PHY reset.
Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
---
drivers/net/phy/phy_device.c | 53 +++++++++++++++++++++++++-----------
1 file changed, 37 insertions(+), 16 deletions(-)
--- a/drivers/net/phy/phy_device.c
+++ b/drivers/net/phy/phy_device.c
@@ -1223,6 +1223,37 @@ static int phy_poll_reset(struct phy_dev
return 0;
}
+static int of_phy_led_init(struct phy_device *phydev)
+{
+ struct phy_led *phyled;
+
+ list_for_each_entry(phyled, &phydev->leds, list) {
+ struct led_classdev *cdev = &phyled->led_cdev;
+ struct device_node *np = cdev->dev->of_node;
+ unsigned long modes = 0;
+ int err;
+
+ if (of_property_read_bool(np, "active-low"))
+ set_bit(PHY_LED_ACTIVE_LOW, &modes);
+ if (of_property_read_bool(np, "inactive-high-impedance"))
+ set_bit(PHY_LED_INACTIVE_HIGH_IMPEDANCE, &modes);
+
+ if (!modes)
+ continue;
+
+ /* Return error if asked to set polarity modes but not supported */
+ if (!phydev->drv->led_polarity_set)
+ return -EINVAL;
+
+ err = phydev->drv->led_polarity_set(phydev, phyled->index,
+ modes);
+ if (err)
+ return err;
+ }
+
+ return 0;
+}
+
int phy_init_hw(struct phy_device *phydev)
{
int ret = 0;
@@ -1261,6 +1292,12 @@ int phy_init_hw(struct phy_device *phyde
return ret;
}
+ if (IS_ENABLED(CONFIG_PHYLIB_LEDS)) {
+ ret = of_phy_led_init(phydev);
+ if (ret < 0)
+ return ret;
+ }
+
return 0;
}
EXPORT_SYMBOL(phy_init_hw);
@@ -3206,7 +3243,6 @@ static int of_phy_led(struct phy_device
struct device *dev = &phydev->mdio.dev;
struct led_init_data init_data = {};
struct led_classdev *cdev;
- unsigned long modes = 0;
struct phy_led *phyled;
u32 index;
int err;
@@ -3224,21 +3260,6 @@ static int of_phy_led(struct phy_device
if (index > U8_MAX)
return -EINVAL;
- if (of_property_read_bool(led, "active-low"))
- set_bit(PHY_LED_ACTIVE_LOW, &modes);
- if (of_property_read_bool(led, "inactive-high-impedance"))
- set_bit(PHY_LED_INACTIVE_HIGH_IMPEDANCE, &modes);
-
- if (modes) {
- /* Return error if asked to set polarity modes but not supported */
- if (!phydev->drv->led_polarity_set)
- return -EINVAL;
-
- err = phydev->drv->led_polarity_set(phydev, index, modes);
- if (err)
- return err;
- }
-
phyled->index = index;
if (phydev->drv->led_brightness_set)
cdev->brightness_set_blocking = phy_led_set_brightness;