lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20231214094813.24690-10-quic_luoj@quicinc.com>
Date:   Thu, 14 Dec 2023 17:48:08 +0800
From:   Luo Jie <quic_luoj@...cinc.com>
To:     <andrew@...n.ch>, <davem@...emloft.net>, <edumazet@...gle.com>,
        <kuba@...nel.org>, <pabeni@...hat.com>, <robh+dt@...nel.org>,
        <krzysztof.kozlowski+dt@...aro.org>, <conor+dt@...nel.org>,
        <hkallweit1@...il.com>, <linux@...linux.org.uk>, <corbet@....net>,
        <p.zabel@...gutronix.de>, <f.fainelli@...il.com>
CC:     <netdev@...r.kernel.org>, <devicetree@...r.kernel.org>,
        <linux-kernel@...r.kernel.org>, <linux-doc@...r.kernel.org>
Subject: [PATCH v7 09/14] net: phy: at803x: set MDIO address of qca8084 PHY

Program the MDIO address of qca8084 PHY and PCS device
in the PHY probe function.

The MDIO address of qca8084 device is configured according
to the property "qcom,phy-addr-fixup" of phy node, which
defines the MDIO address for 4 PHYs and 3 PCSes, each MDIO
address occupies 5 bits in the config register.

The MDIO address of qca8084 should be configured correctly
before doing the clock initialization in the PHY probe function,
so the property "reg" can't be used to configure the MDIO address
of phy device one by one, the clock initialization will be configured
with all 4 PHY devices in one PHY probe function.

Signed-off-by: Luo Jie <quic_luoj@...cinc.com>
---
 drivers/net/phy/at803x.c | 61 ++++++++++++++++++++++++++++++++++++++++
 1 file changed, 61 insertions(+)

diff --git a/drivers/net/phy/at803x.c b/drivers/net/phy/at803x.c
index 016e40e32982..a00c5950683c 100644
--- a/drivers/net/phy/at803x.c
+++ b/drivers/net/phy/at803x.c
@@ -303,6 +303,18 @@
 #define QCA8084_HIGH_ADDR_PREFIX		0x18
 #define QCA8084_LOW_ADDR_PREFIX			0x10
 
+#define QCA8084_PCS_CFG				0xc90f014
+#define QCA8084_PCS_ADDR0_MASK			GENMASK(4, 0)
+#define QCA8084_PCS_ADDR1_MASK			GENMASK(9, 5)
+#define QCA8084_PCS_ADDR2_MASK			GENMASK(14, 10)
+
+#define QCA8084_EPHY_CFG			0xc90f018
+#define QCA8084_EPHY_ADDR0_MASK			GENMASK(4, 0)
+#define QCA8084_EPHY_ADDR1_MASK			GENMASK(9, 5)
+#define QCA8084_EPHY_ADDR2_MASK			GENMASK(14, 10)
+#define QCA8084_EPHY_ADDR3_MASK			GENMASK(19, 15)
+#define QCA8084_EPHY_LDO_EN			GENMASK(21, 20)
+
 MODULE_DESCRIPTION("Qualcomm Atheros AR803x and QCA808X PHY driver");
 MODULE_AUTHOR("Matus Ujhelyi");
 MODULE_LICENSE("GPL");
@@ -955,6 +967,51 @@ static int at803x_parse_dt(struct phy_device *phydev)
 	return 0;
 }
 
+static int qca8084_parse_and_set_phyaddr(struct phy_device *phydev)
+{
+	struct device_node *node;
+	u32 addr[7];
+	int ret;
+
+	node = phydev->mdio.dev.of_node;
+
+	/* The property "qcom,phy-addr-fixup" is only defined in one
+	 * PHY device tree node.
+	 */
+	ret = of_property_read_u32_array(node, "qcom,phy-addr-fixup",
+					 addr, ARRAY_SIZE(addr));
+	if (ret)
+		return ret == -EINVAL ? 0 : ret;
+
+	/* There are 4 PHYs and 3 PCSes on qca8084 chip, each device address
+	 * occupies 5 bits of the config register to customize the MDIO address.
+	 */
+	ret = qca8084_mii_modify(phydev, QCA8084_EPHY_CFG,
+				 QCA8084_EPHY_ADDR0_MASK |
+				 QCA8084_EPHY_ADDR1_MASK |
+				 QCA8084_EPHY_ADDR2_MASK |
+				 QCA8084_EPHY_ADDR3_MASK,
+				 FIELD_PREP(QCA8084_EPHY_ADDR0_MASK, addr[0]) |
+				 FIELD_PREP(QCA8084_EPHY_ADDR1_MASK, addr[1]) |
+				 FIELD_PREP(QCA8084_EPHY_ADDR2_MASK, addr[2]) |
+				 FIELD_PREP(QCA8084_EPHY_ADDR3_MASK, addr[3]));
+	if (ret)
+		return ret;
+
+	return qca8084_mii_modify(phydev, QCA8084_PCS_CFG,
+				  QCA8084_PCS_ADDR0_MASK |
+				  QCA8084_PCS_ADDR1_MASK |
+				  QCA8084_PCS_ADDR2_MASK,
+				  FIELD_PREP(QCA8084_PCS_ADDR0_MASK, addr[4]) |
+				  FIELD_PREP(QCA8084_PCS_ADDR1_MASK, addr[5]) |
+				  FIELD_PREP(QCA8084_PCS_ADDR2_MASK, addr[6]));
+}
+
+static int qca8084_probe(struct phy_device *phydev)
+{
+	return qca8084_parse_and_set_phyaddr(phydev);
+}
+
 static int at803x_probe(struct phy_device *phydev)
 {
 	struct device *dev = &phydev->mdio.dev;
@@ -967,6 +1024,9 @@ static int at803x_probe(struct phy_device *phydev)
 
 	phydev->priv = priv;
 
+	if (phydev_id_compare(phydev, QCA8084_PHY_ID))
+		return qca8084_probe(phydev);
+
 	ret = at803x_parse_dt(phydev);
 	if (ret)
 		return ret;
@@ -2434,6 +2494,7 @@ static struct phy_driver at803x_driver[] = {
 	PHY_ID_MATCH_MODEL(QCA8084_PHY_ID),
 	.name			= "Qualcomm QCA8084",
 	.flags			= PHY_POLL_CABLE_TEST,
+	.probe			= at803x_probe,
 	.config_intr		= at803x_config_intr,
 	.handle_interrupt	= at803x_handle_interrupt,
 	.get_tunable		= at803x_get_tunable,
-- 
2.42.0

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ