Replace the proprietary airoha,pnswap-rx / airoha,pnswap-tx boolean
device tree properties with the standard rx-polarity and tx-polarity
properties defined in phy-common-props.yaml.

The driver first tries the standard properties; if absent it falls back
to the legacy ones for backward compatibility. The legacy properties are
marked deprecated in the bindings.

Link: https://git.kernel.org/linus/66d8a334b57e64e43810623b3d88f0ce9745270b
Signed-off-by: Lucien.Jheng <[email protected]>
---
The log below demonstrates the usage of the legacy and common PHY properties 
newly implemented in this version.
You could choose one of method to configure polarity of EN8811H.

1. EN8811H DTS using common PHY properties
        phy14: eth-phy@14 {
                compatible = "ethernet-phy-id03a2.a411";
                reg = <14>;
                //phy-supply = <&en8811_a>;
                pinctrl-names = "default";
                pinctrl-0 = <&en8811_pwr_a>;
                // airoha,pnswap-rx;
                rx-polarity = <PHY_POL_INVERT>;
                tx-polarity = <PHY_POL_NORMAL>;

                reset-gpios = <&pio 49 GPIO_ACTIVE_LOW>;
                reset-assert-us = <10000>;
                reset-deassert-us = <20000>;
        };

UBoot log:
mtk-eth ethernet@15100000: MD32 firmware version: 24112802
phy_get_polarity_for_mode: querying 'rx-polarity' for mode '2500base-x' 
(supported=0x3, default=0)
ofnode_get_u32_prop_for_name: looking up '2500base-x' in props='rx-polarity' 
names='rx-polarity-names' default=0
ofnode_read_prop: rx-polarity: ofnode_count_u32_prop: property 'rx-polarity' 
has 4 bytes (1 elements)
ofnode_get_u32_prop_for_name: 'rx-polarity' has 1 elements, 'rx-polarity-names' 
has -1 entries
ofnode_get_u32_prop_for_name: '2500base-x' not found in 'rx-polarity-names', 
trying 'default'
ofnode_get_u32_prop_for_name: 'default' entry not found in 'rx-polarity-names'
ofnode_get_u32_prop_for_name: single-element 'rx-polarity', reading directly
ofnode_read_u32_index: rx-polarity: 0x1 (1)
ofnode_get_u32_prop_for_name: resolved value 1 for name '2500base-x' from 
'rx-polarity'
phy_get_polarity_for_mode: 'rx-polarity' for mode '2500base-x' = 1
mtk-eth ethernet@15100000: EN8811H: RX polarity = inverted
phy_get_polarity_for_mode: querying 'tx-polarity' for mode '2500base-x' 
(supported=0x3, default=0)
ofnode_get_u32_prop_for_name: looking up '2500base-x' in props='tx-polarity' 
names='tx-polarity-names' default=0
ofnode_read_prop: tx-polarity: ofnode_count_u32_prop: property 'tx-polarity' 
has 4 bytes (1 elements)
ofnode_get_u32_prop_for_name: 'tx-polarity' has 1 elements, 'tx-polarity-names' 
has -1 entries
ofnode_get_u32_prop_for_name: '2500base-x' not found in 'tx-polarity-names', 
trying 'default'
ofnode_get_u32_prop_for_name: 'default' entry not found in 'tx-polarity-names'
ofnode_get_u32_prop_for_name: single-element 'tx-polarity', reading directly
ofnode_read_u32_index: tx-polarity: 0x0 (0)
ofnode_get_u32_prop_for_name: resolved value 0 for name '2500base-x' from 
'tx-polarity'
phy_get_polarity_for_mode: 'tx-polarity' for mode '2500base-x' = 0
mtk-eth ethernet@15100000: EN8811H: TX polarity = normal
eth0: ethernet@15100000
Hit any key to stop autoboot: 0
BPI-R3M>

2. EN8811H DTS using legacy configuration
        phy14: eth-phy@14 {
                compatible = "ethernet-phy-id03a2.a411";
                reg = <14>;
                //phy-supply = <&en8811_a>;
                pinctrl-names = "default";
                pinctrl-0 = <&en8811_pwr_a>;
                airoha,pnswap-rx;

                reset-gpios = <&pio 49 GPIO_ACTIVE_LOW>;
                reset-assert-us = <10000>;
                reset-deassert-us = <20000>;
        };

UBoot log:
mtk-eth ethernet@15100000: MD32 firmware version: 24112802
phy_get_polarity_for_mode: querying 'rx-polarity' for mode '2500base-x' 
(supported=0x3, default=0)
ofnode_get_u32_prop_for_name: looking up '2500base-x' in props='rx-polarity' 
names='rx-polarity-names' default=0
ofnode_read_prop: rx-polarity: <not found>
ofnode_count_u32_prop: property 'rx-polarity' not found (err=-22)
ofnode_get_u32_prop_for_name: 'rx-polarity' is absent, returning -ENOENT
phy_get_polarity_for_mode: 'rx-polarity' lookup failed for mode '2500base-x' 
(err=-2)
mtk-eth ethernet@15100000: EN8811H: Legacy RX polarity
ofnode_read_bool: airoha,pnswap-rx: true
phy_get_polarity_for_mode: querying 'tx-polarity' for mode '2500base-x' 
(supported=0x3, default=0)
ofnode_get_u32_prop_for_name: looking up '2500base-x' in props='tx-polarity' 
names='tx-polarity-names' default=0
ofnode_read_prop: tx-polarity: <not found>
ofnode_count_u32_prop: property 'tx-polarity' not found (err=-22)
ofnode_get_u32_prop_for_name: 'tx-polarity' is absent, returning -ENOENT
phy_get_polarity_for_mode: 'tx-polarity' lookup failed for mode '2500base-x' 
(err=-2)
mtk-eth ethernet@15100000: EN8811H: Legacy TX polarity
ofnode_read_bool: airoha,pnswap-tx: false
eth0: ethernet@15100000
Hit any key to stop autoboot: 0
BPI-R3M>

 drivers/net/phy/airoha/Kconfig      |  1 +
 drivers/net/phy/airoha/air_en8811.c | 91 ++++++++++++++++++++++++-----
 2 files changed, 77 insertions(+), 15 deletions(-)

diff --git a/drivers/net/phy/airoha/Kconfig b/drivers/net/phy/airoha/Kconfig
index 999564e4848..efe3c0f485b 100644
--- a/drivers/net/phy/airoha/Kconfig
+++ b/drivers/net/phy/airoha/Kconfig
@@ -6,6 +6,7 @@ config PHY_AIROHA_EN8811
        bool "Airoha Ethernet EN8811H support"
        depends on PHY_AIROHA
        select FW_LOADER
+       select PHY_COMMON_PROPS
        help
          AIROHA EN8811H supported.

diff --git a/drivers/net/phy/airoha/air_en8811.c 
b/drivers/net/phy/airoha/air_en8811.c
index 1a628ede82b..0ec11ba5231 100644
--- a/drivers/net/phy/airoha/air_en8811.c
+++ b/drivers/net/phy/airoha/air_en8811.c
@@ -23,6 +23,7 @@
 #include <linux/compat.h>
 #include <dm/device_compat.h>
 #include <u-boot/crc.h>
+#include <linux/phy/phy-common-props.h>

 #define EN8811H_PHY_ID         0x03a2a411

@@ -660,11 +661,82 @@ static int air_leds_init(struct phy_device *phydev, int 
num, u16 dur, int mode)
        return 0;
 }

-static int en8811h_config(struct phy_device *phydev)
+static int en8811h_config_polarity(struct phy_device *phydev)
 {
-       struct en8811h_priv *priv = phydev->priv;
        ofnode node = phy_get_ofnode(phydev);
+       unsigned int rx_pol, tx_pol;
        u32 pbus_value = 0;
+       int ret;
+       bool use_legacy = false;
+
+       if (!ofnode_valid(node))
+               return 0;
+
+       /* Try standard rx-polarity property first */
+       ret = phy_get_manual_rx_polarity(node,
+                                        
phy_interface_strings[phydev->interface],
+                                        &rx_pol);
+       if (ret == 0) {
+               dev_info(phydev->dev, "EN8811H: RX polarity = %s\n",
+                        rx_pol == PHY_POL_INVERT ? "inverted" : "normal");
+               if (rx_pol == PHY_POL_INVERT)
+                       pbus_value |= EN8811H_POLARITY_RX_REVERSE;
+               else
+                       pbus_value &= ~EN8811H_POLARITY_RX_REVERSE;
+       } else if (ret == -ENOENT) {
+               /* Fall back to legacy airoha,pnswap-rx property */
+               use_legacy = true;
+               dev_info(phydev->dev, "EN8811H: Legacy RX polarity\n");
+
+               if (ofnode_read_bool(node, "airoha,pnswap-rx"))
+                       pbus_value |= EN8811H_POLARITY_RX_REVERSE;
+               else
+                       pbus_value &= ~EN8811H_POLARITY_RX_REVERSE;
+       } else {
+               dev_err(phydev->dev, "EN8811H: Error reading rx-polarity: 
%d\n", ret);
+               return ret;
+       }
+
+       /* Try standard tx-polarity property first */
+       ret = phy_get_manual_tx_polarity(node,
+                                        
phy_interface_strings[phydev->interface],
+                                        &tx_pol);
+       if (ret == 0) {
+               dev_info(phydev->dev, "EN8811H: TX polarity = %s\n",
+                        tx_pol == PHY_POL_INVERT ? "inverted" : "normal");
+               if (tx_pol == PHY_POL_INVERT)
+                       pbus_value &= ~EN8811H_POLARITY_TX_NORMAL;
+               else
+                       pbus_value |= EN8811H_POLARITY_TX_NORMAL;
+       } else if (ret == -ENOENT) {
+               /* Fall back to legacy airoha,pnswap-tx property */
+               if (!use_legacy)
+                       dev_err(phydev->dev, "EN8811H: Mixing standard and 
legacy polarity properties\n");
+
+               dev_info(phydev->dev, "EN8811H: Legacy TX polarity\n");
+
+               if (ofnode_read_bool(node, "airoha,pnswap-tx"))
+                       pbus_value &= ~EN8811H_POLARITY_TX_NORMAL;
+               else
+                       pbus_value |= EN8811H_POLARITY_TX_NORMAL;
+       } else {
+               dev_err(phydev->dev, "EN8811H: Error reading tx-polarity: 
%d\n", ret);
+               return ret;
+       }
+
+       /* Apply polarity configuration to hardware */
+       ret = air_buckpbus_reg_modify(phydev, EN8811H_POLARITY,
+                                     EN8811H_POLARITY_RX_REVERSE |
+                                     EN8811H_POLARITY_TX_NORMAL, pbus_value);
+       if (ret < 0)
+               return ret;
+
+       return 0;
+}
+
+static int en8811h_config(struct phy_device *phydev)
+{
+       struct en8811h_priv *priv = phydev->priv;
        int ret = 0;

        /* If restart happened in .probe(), no need to restart now */
@@ -695,19 +767,8 @@ static int en8811h_config(struct phy_device *phydev)
        if (ret < 0)
                return ret;

-       /* Serdes polarity */
-       pbus_value = 0;
-       if (ofnode_read_bool(node, "airoha,pnswap-rx"))
-               pbus_value |=  EN8811H_POLARITY_RX_REVERSE;
-       else
-               pbus_value &= ~EN8811H_POLARITY_RX_REVERSE;
-       if (ofnode_read_bool(node, "airoha,pnswap-tx"))
-               pbus_value &= ~EN8811H_POLARITY_TX_NORMAL;
-       else
-               pbus_value |=  EN8811H_POLARITY_TX_NORMAL;
-       ret = air_buckpbus_reg_modify(phydev, EN8811H_POLARITY,
-                                     EN8811H_POLARITY_RX_REVERSE |
-                                     EN8811H_POLARITY_TX_NORMAL, pbus_value);
+       /* Configure Serdes polarity from device tree */
+       ret = en8811h_config_polarity(phydev);
        if (ret < 0)
                return ret;

--
2.34.1

Reply via email to