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-next>] [day] [month] [year] [list]
Message-ID: <1537174546-34642-1-git-send-email-dongsheng.wang@hxt-semitech.com>
Date:   Mon, 17 Sep 2018 16:55:45 +0800
From:   Wang Dongsheng <dongsheng.wang@...-semitech.com>
To:     <timur@...nel.org>, <andrew@...n.ch>
CC:     <davem@...emloft.net>,
        Wang Dongsheng <dongsheng.wang@...-semitech.com>,
        <yu.zheng@...-semitech.com>, <netdev@...r.kernel.org>
Subject: [PATCH v2 3/4] net: qcom/emac: add of shared mdio bus support

Share the mii_bus for others MAC device because EMAC include MDIO,
and the motherboard has more than one PHY connected to an MDIO bus.

Signed-off-by: Wang Dongsheng <dongsheng.wang@...-semitech.com>
---
 drivers/net/ethernet/qualcomm/emac/emac-phy.c | 63 ++++++++++++++++++-
 drivers/net/ethernet/qualcomm/emac/emac.c     |  8 ++-
 2 files changed, 66 insertions(+), 5 deletions(-)

diff --git a/drivers/net/ethernet/qualcomm/emac/emac-phy.c b/drivers/net/ethernet/qualcomm/emac/emac-phy.c
index 2d16c6b9ef49..4f98f9a0ed54 100644
--- a/drivers/net/ethernet/qualcomm/emac/emac-phy.c
+++ b/drivers/net/ethernet/qualcomm/emac/emac-phy.c
@@ -13,6 +13,7 @@
 /* Qualcomm Technologies, Inc. EMAC PHY Controller driver.
  */
 
+#include <linux/of_platform.h>
 #include <linux/of_mdio.h>
 #include <linux/phy.h>
 #include <linux/iopoll.h>
@@ -96,8 +97,51 @@ static int emac_mdio_write(struct mii_bus *bus, int addr, int regnum, u16 val)
 	return 0;
 }
 
-static int emac_mdio_bus_create(struct platform_device *pdev,
-				struct emac_adapter *adpt)
+static int emac_of_get_shared_bus(struct platform_device *pdev,
+				  struct mii_bus **bus)
+{
+	struct device_node *shared_node;
+	struct platform_device *shared_pdev;
+	struct net_device *shared_netdev;
+	struct emac_adapter *shared_adpt;
+	struct device_node *np = pdev->dev.of_node;
+
+	const phandle *prop;
+
+	prop = of_get_property(np, "mdio-device", NULL);
+	if (!prop) {
+		dev_err(&pdev->dev, "Missing mdio-device property\n");
+		return -ENODEV;
+	}
+
+	shared_node = of_find_node_by_phandle(*prop);
+	if (!shared_node)
+		return -ENODEV;
+
+	shared_pdev = of_find_device_by_node(shared_node);
+	if (!shared_pdev)
+		return -ENODEV;
+
+	shared_netdev = dev_get_drvdata(&shared_pdev->dev);
+	if (!shared_netdev)
+		return -EPROBE_DEFER;
+
+	shared_adpt = netdev_priv(shared_netdev);
+	if (!shared_adpt->mii_bus)
+		return -EPROBE_DEFER;
+
+	*bus = shared_adpt->mii_bus;
+	return 0;
+}
+
+static int __do_get_emac_mido_shared_bus(struct platform_device *pdev,
+					 struct emac_adapter *adpt)
+{
+	return emac_of_get_shared_bus(pdev, &adpt->mii_bus);
+}
+
+static int __do_emac_mido_bus_create(struct platform_device *pdev,
+				     struct emac_adapter *adpt)
 {
 	struct device_node *np = pdev->dev.of_node;
 	struct mii_bus *mii_bus;
@@ -125,6 +169,17 @@ static int emac_mdio_bus_create(struct platform_device *pdev,
 	return 0;
 }
 
+static int emac_mdio_bus_create(struct platform_device *pdev,
+				struct emac_adapter *adpt)
+{
+	bool shared_mdio;
+
+	shared_mdio = device_property_read_bool(&pdev->dev, "mdio-device");
+	if (shared_mdio)
+		return __do_get_emac_mido_shared_bus(pdev, adpt);
+	return __do_emac_mido_bus_create(pdev, adpt);
+}
+
 static void emac_get_phydev(struct platform_device *pdev,
 			    struct emac_adapter *adpt)
 {
@@ -174,6 +229,8 @@ int emac_phy_config(struct platform_device *pdev, struct emac_adapter *adpt)
 		return 0;
 
 	dev_err(&pdev->dev, "Could not find external phy\n");
-	mdiobus_unregister(adpt->mii_bus);
+	/* Only the bus creator can unregister mdio bus */
+	if (&pdev->dev == adpt->mii_bus->parent)
+		mdiobus_unregister(adpt->mii_bus);
 	return -ENODEV;
 }
diff --git a/drivers/net/ethernet/qualcomm/emac/emac.c b/drivers/net/ethernet/qualcomm/emac/emac.c
index 2a0cbc535a2e..6e566b4c5a6b 100644
--- a/drivers/net/ethernet/qualcomm/emac/emac.c
+++ b/drivers/net/ethernet/qualcomm/emac/emac.c
@@ -727,7 +727,9 @@ static int emac_probe(struct platform_device *pdev)
 	netif_napi_del(&adpt->rx_q.napi);
 err_undo_mdiobus:
 	put_device(&adpt->phydev->mdio.dev);
-	mdiobus_unregister(adpt->mii_bus);
+	/* Only the bus creator can unregister mdio bus */
+	if (&pdev->dev == adpt->mii_bus->parent)
+		mdiobus_unregister(adpt->mii_bus);
 err_undo_clocks:
 	emac_clks_teardown(adpt);
 err_undo_netdev:
@@ -747,7 +749,9 @@ static int emac_remove(struct platform_device *pdev)
 	emac_clks_teardown(adpt);
 
 	put_device(&adpt->phydev->mdio.dev);
-	mdiobus_unregister(adpt->mii_bus);
+	/* Only the bus creator can unregister mdio bus */
+	if (&pdev->dev == adpt->mii_bus->parent)
+		mdiobus_unregister(adpt->mii_bus);
 	free_netdev(netdev);
 
 	if (adpt->phy.digital)
-- 
2.18.0

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ