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  PHC 
Open Source and information security mailing list archives
 
Hash Suite for Android: free password hash cracker in your pocket
[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Date:	Mon, 28 Jul 2014 14:07:58 -0500
From:	Vince Bridgers <vbridgers2013@...il.com>
To:	netdev@...r.kernel.org, davem@...emloft.net, peppe.cavallaro@...com
Cc:	vbridgers2013@...il.com, vbridger@...era.com
Subject: [PATCH net-next v3] net: stmmac: add platform init/exit for Altera's ARM socfpga

This patch adds platform init/exit functions and modifications to support
suspend/resume for the Altera Cyclone 5 SOC Ethernet controller. The platform
exit function puts the controller into reset using the socfpga reset
controller driver. The platform init function sets up the Synopsys mac by
first making sure the Ethernet controller is held in reset, programming the
phy mode through external support logic, then deasserts reset through
the socfpga reset manager driver.

Signed-off-by: Vince Bridgers <vbridgers2013@...il.com>
---
V3: respin for net-next after phy_suspend was exported by libphy
    per suggestion from Florian. No changes to patch from V2 -> V3.
V2: Address review comments - add line break before structure decl
---
 .../net/ethernet/stmicro/stmmac/dwmac-socfpga.c    |   69 ++++++++++++++++++++
 drivers/net/ethernet/stmicro/stmmac/stmmac_main.c  |    4 ++
 2 files changed, 73 insertions(+)

diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c
index fd8a217..ec632e6 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c
@@ -20,7 +20,9 @@
 #include <linux/of_net.h>
 #include <linux/phy.h>
 #include <linux/regmap.h>
+#include <linux/reset.h>
 #include <linux/stmmac.h>
+#include "stmmac.h"
 
 #define SYSMGR_EMACGRP_CTRL_PHYSEL_ENUM_GMII_MII 0x0
 #define SYSMGR_EMACGRP_CTRL_PHYSEL_ENUM_RGMII 0x1
@@ -34,6 +36,7 @@ struct socfpga_dwmac {
 	u32	reg_shift;
 	struct	device *dev;
 	struct regmap *sys_mgr_base_addr;
+	struct reset_control *stmmac_rst;
 };
 
 static int socfpga_dwmac_parse_data(struct socfpga_dwmac *dwmac, struct device *dev)
@@ -43,6 +46,13 @@ static int socfpga_dwmac_parse_data(struct socfpga_dwmac *dwmac, struct device *
 	u32 reg_offset, reg_shift;
 	int ret;
 
+	dwmac->stmmac_rst = devm_reset_control_get(dev,
+						  STMMAC_RESOURCE_NAME);
+	if (IS_ERR(dwmac->stmmac_rst)) {
+		dev_info(dev, "Could not get reset control!\n");
+		return -EINVAL;
+	}
+
 	dwmac->interface = of_get_phy_mode(np);
 
 	sys_mgr_base_addr = syscon_regmap_lookup_by_phandle(np, "altr,sysmgr-syscon");
@@ -125,6 +135,65 @@ static void *socfpga_dwmac_probe(struct platform_device *pdev)
 	return dwmac;
 }
 
+static void socfpga_dwmac_exit(struct platform_device *pdev, void *priv)
+{
+	struct socfpga_dwmac	*dwmac = priv;
+
+	/* On socfpga platform exit, assert and hold reset to the
+	 * enet controller - the default state after a hard reset.
+	 */
+	if (dwmac->stmmac_rst)
+		reset_control_assert(dwmac->stmmac_rst);
+}
+
+static int socfpga_dwmac_init(struct platform_device *pdev, void *priv)
+{
+	struct socfpga_dwmac	*dwmac = priv;
+	struct net_device *ndev = platform_get_drvdata(pdev);
+	struct stmmac_priv *stpriv = NULL;
+	int ret = 0;
+
+	if (ndev)
+		stpriv = netdev_priv(ndev);
+
+	/* Assert reset to the enet controller before changing the phy mode */
+	if (dwmac->stmmac_rst)
+		reset_control_assert(dwmac->stmmac_rst);
+
+	/* Setup the phy mode in the system manager registers according to
+	 * devicetree configuration
+	 */
+	ret = socfpga_dwmac_setup(dwmac);
+
+	/* Deassert reset for the phy configuration to be sampled by
+	 * the enet controller, and operation to start in requested mode
+	 */
+	if (dwmac->stmmac_rst)
+		reset_control_deassert(dwmac->stmmac_rst);
+
+	/* Before the enet controller is suspended, the phy is suspended.
+	 * This causes the phy clock to be gated. The enet controller is
+	 * resumed before the phy, so the clock is still gated "off" when
+	 * the enet controller is resumed. This code makes sure the phy
+	 * is "resumed" before reinitializing the enet controller since
+	 * the enet controller depends on an active phy clock to complete
+	 * a DMA reset. A DMA reset will "time out" if executed
+	 * with no phy clock input on the Synopsys enet controller.
+	 * Verified through Synopsys Case #8000711656.
+	 *
+	 * Note that the phy clock is also gated when the phy is isolated.
+	 * Phy "suspend" and "isolate" controls are located in phy basic
+	 * control register 0, and can be modified by the phy driver
+	 * framework.
+	 */
+	if (stpriv && stpriv->phydev)
+		phy_resume(stpriv->phydev);
+
+	return ret;
+}
+
 const struct stmmac_of_data socfpga_gmac_data = {
 	.setup = socfpga_dwmac_probe,
+	.init = socfpga_dwmac_init,
+	.exit = socfpga_dwmac_exit,
 };
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index 057a120..18315f3 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -2878,6 +2878,10 @@ int stmmac_suspend(struct net_device *ndev)
 		clk_disable_unprepare(priv->stmmac_clk);
 	}
 	spin_unlock_irqrestore(&priv->lock, flags);
+
+	priv->oldlink = 0;
+	priv->speed = 0;
+	priv->oldduplex = -1;
 	return 0;
 }
 
-- 
1.7.9.5

--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Powered by blists - more mailing lists