]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
net: phy: Add helper for getting tx amplitude gain
authorDimitri Fedrau <dimitri.fedrau@liebherr.com>
Fri, 14 Feb 2025 14:14:10 +0000 (15:14 +0100)
committerJakub Kicinski <kuba@kernel.org>
Tue, 18 Feb 2025 00:40:42 +0000 (16:40 -0800)
Add helper which returns the tx amplitude gain defined in device tree.
Modifying it can be necessary to compensate losses on the PCB and
connector, so the voltages measured on the RJ45 pins are conforming.

Signed-off-by: Dimitri Fedrau <dimitri.fedrau@liebherr.com>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Link: https://patch.msgid.link/20250214-dp83822-tx-swing-v5-2-02ca72620599@liebherr.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
drivers/net/phy/phy_device.c
include/linux/phy.h

index 35ec99b4dc5102b96106c06268dc83f6ea998e47..0d56e7c7f98cd661fc85df38bcd30f953f01aaf8 100644 (file)
@@ -3096,19 +3096,12 @@ void phy_get_pause(struct phy_device *phydev, bool *tx_pause, bool *rx_pause)
 EXPORT_SYMBOL(phy_get_pause);
 
 #if IS_ENABLED(CONFIG_OF_MDIO)
-static int phy_get_int_delay_property(struct device *dev, const char *name)
+static int phy_get_u32_property(struct device *dev, const char *name, u32 *val)
 {
-       s32 int_delay;
-       int ret;
-
-       ret = device_property_read_u32(dev, name, &int_delay);
-       if (ret)
-               return ret;
-
-       return int_delay;
+       return device_property_read_u32(dev, name, val);
 }
 #else
-static int phy_get_int_delay_property(struct device *dev, const char *name)
+static int phy_get_u32_property(struct device *dev, const char *name, u32 *val)
 {
        return -EINVAL;
 }
@@ -3133,12 +3126,12 @@ static int phy_get_int_delay_property(struct device *dev, const char *name)
 s32 phy_get_internal_delay(struct phy_device *phydev, struct device *dev,
                           const int *delay_values, int size, bool is_rx)
 {
-       s32 delay;
-       int i;
+       int i, ret;
+       u32 delay;
 
        if (is_rx) {
-               delay = phy_get_int_delay_property(dev, "rx-internal-delay-ps");
-               if (delay < 0 && size == 0) {
+               ret = phy_get_u32_property(dev, "rx-internal-delay-ps", &delay);
+               if (ret < 0 && size == 0) {
                        if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID ||
                            phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID)
                                return 1;
@@ -3147,8 +3140,8 @@ s32 phy_get_internal_delay(struct phy_device *phydev, struct device *dev,
                }
 
        } else {
-               delay = phy_get_int_delay_property(dev, "tx-internal-delay-ps");
-               if (delay < 0 && size == 0) {
+               ret = phy_get_u32_property(dev, "tx-internal-delay-ps", &delay);
+               if (ret < 0 && size == 0) {
                        if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID ||
                            phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID)
                                return 1;
@@ -3157,8 +3150,8 @@ s32 phy_get_internal_delay(struct phy_device *phydev, struct device *dev,
                }
        }
 
-       if (delay < 0)
-               return delay;
+       if (ret < 0)
+               return ret;
 
        if (size == 0)
                return delay;
@@ -3193,6 +3186,30 @@ s32 phy_get_internal_delay(struct phy_device *phydev, struct device *dev,
 }
 EXPORT_SYMBOL(phy_get_internal_delay);
 
+/**
+ * phy_get_tx_amplitude_gain - stores tx amplitude gain in @val
+ * @phydev: phy_device struct
+ * @dev: pointer to the devices device struct
+ * @linkmode: linkmode for which the tx amplitude gain should be retrieved
+ * @val: tx amplitude gain
+ *
+ * Returns: 0 on success, < 0 on failure
+ */
+int phy_get_tx_amplitude_gain(struct phy_device *phydev, struct device *dev,
+                             enum ethtool_link_mode_bit_indices linkmode,
+                             u32 *val)
+{
+       switch (linkmode) {
+       case ETHTOOL_LINK_MODE_100baseT_Full_BIT:
+               return phy_get_u32_property(dev,
+                                           "tx-amplitude-100base-tx-percent",
+                                           val);
+       default:
+               return -EINVAL;
+       }
+}
+EXPORT_SYMBOL_GPL(phy_get_tx_amplitude_gain);
+
 static int phy_led_set_brightness(struct led_classdev *led_cdev,
                                  enum led_brightness value)
 {
index 3665cdd610a3dc0b979b4f53f8edbb8d224e2797..70c632799082e6c3a4ccb976cba0321f65e42f28 100644 (file)
@@ -2097,6 +2097,10 @@ void phy_get_pause(struct phy_device *phydev, bool *tx_pause, bool *rx_pause);
 s32 phy_get_internal_delay(struct phy_device *phydev, struct device *dev,
                           const int *delay_values, int size, bool is_rx);
 
+int phy_get_tx_amplitude_gain(struct phy_device *phydev, struct device *dev,
+                             enum ethtool_link_mode_bit_indices linkmode,
+                             u32 *val);
+
 void phy_resolve_pause(unsigned long *local_adv, unsigned long *partner_adv,
                       bool *tx_pause, bool *rx_pause);