netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH net-next v2 00/11] net: bcmgenet: PM and Wake-on-LAN
@ 2014-07-21 22:29 Florian Fainelli
  2014-07-21 22:29 ` [PATCH net-next v2 01/11] net: bcmgenet: remove wol_enabled conditional code Florian Fainelli
                   ` (12 more replies)
  0 siblings, 13 replies; 15+ messages in thread
From: Florian Fainelli @ 2014-07-21 22:29 UTC (permalink / raw)
  To: netdev; +Cc: davem, Florian Fainelli

Hi David,

This patchset brings S2/S3 Power Management support to the GENET driver
as well as Wake-on-LAN using Magic Packets with or without SecureOn
passwords.

Thanks!

Florian Fainelli (11):
  net: bcmgenet: remove wol_enabled conditional code
  net: bcmgenet: add umac_enable_set helper
  net: bcmgenet: modularize bcmgenet_{open,close}
  net: bcmgenet: add suspend/resume callbacks
  net: bcmgenet: request Wake-on-LAN interrupt
  net: bcmgenet: add Wake-on-LAN support code
  net: bcmgenet: handle GENET_POWER_WOL_MAGIC
  net: bcmgenet: handle UMAC_IRQ_MPD_R interrupt bit
  net: bcmgenet: fix bcmgenet_wol_resume
  net: bcmgenet: suspend and resume from Wake-on-LAN
  net: bcmgenet: hook ethtool set/get_wol operations

 drivers/net/ethernet/broadcom/genet/Makefile       |   2 +-
 drivers/net/ethernet/broadcom/genet/bcmgenet.c     | 270 ++++++++++++++++-----
 drivers/net/ethernet/broadcom/genet/bcmgenet.h     |  12 +-
 drivers/net/ethernet/broadcom/genet/bcmgenet_wol.c | 206 ++++++++++++++++
 4 files changed, 430 insertions(+), 60 deletions(-)
 create mode 100644 drivers/net/ethernet/broadcom/genet/bcmgenet_wol.c

-- 
1.9.1

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [PATCH net-next v2 01/11] net: bcmgenet: remove wol_enabled conditional code
  2014-07-21 22:29 [PATCH net-next v2 00/11] net: bcmgenet: PM and Wake-on-LAN Florian Fainelli
@ 2014-07-21 22:29 ` Florian Fainelli
  2014-07-21 22:29 ` [PATCH net-next v2 02/11] net: bcmgenet: add umac_enable_set helper Florian Fainelli
                   ` (11 subsequent siblings)
  12 siblings, 0 replies; 15+ messages in thread
From: Florian Fainelli @ 2014-07-21 22:29 UTC (permalink / raw)
  To: netdev; +Cc: davem, Florian Fainelli

Checking for wol_enabled in bcmgenet_close() is bogus, since no other
code places set priv->wol_enabled. Remove that as it will conflict with
the upcoming and functional Wake-on-LAN implementation.

Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
---
Changes in v2:
- remove one more call site which checked for wol_enabled

 drivers/net/ethernet/broadcom/genet/bcmgenet.c | 9 ---------
 drivers/net/ethernet/broadcom/genet/bcmgenet.h | 1 -
 2 files changed, 10 deletions(-)

diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.c b/drivers/net/ethernet/broadcom/genet/bcmgenet.c
index 16281ad2da12..3cbf29095257 100644
--- a/drivers/net/ethernet/broadcom/genet/bcmgenet.c
+++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.c
@@ -1994,12 +1994,6 @@ static int bcmgenet_open(struct net_device *dev)
 
 	bcmgenet_set_hw_addr(priv, dev->dev_addr);
 
-	if (priv->wol_enabled) {
-		ret = bcmgenet_wol_resume(priv);
-		if (ret)
-			return ret;
-	}
-
 	if (phy_is_internal(priv->phydev)) {
 		reg = bcmgenet_ext_readl(priv, EXT_EXT_PWR_MGMT);
 		reg |= EXT_ENERGY_DET_MASK;
@@ -2161,9 +2155,6 @@ static int bcmgenet_close(struct net_device *dev)
 	if (phy_is_internal(priv->phydev))
 		bcmgenet_power_down(priv, GENET_POWER_PASSIVE);
 
-	if (priv->wol_enabled)
-		clk_enable(priv->clk_wol);
-
 	if (!IS_ERR(priv->clk))
 		clk_disable_unprepare(priv->clk);
 
diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.h b/drivers/net/ethernet/broadcom/genet/bcmgenet.h
index e23c993b1362..f4891a1b6758 100644
--- a/drivers/net/ethernet/broadcom/genet/bcmgenet.h
+++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.h
@@ -583,7 +583,6 @@ struct bcmgenet_priv {
 	struct platform_device *pdev;
 
 	/* WOL */
-	unsigned long wol_enabled;
 	struct clk *clk_wol;
 	u32 wolopts;
 
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH net-next v2 02/11] net: bcmgenet: add umac_enable_set helper
  2014-07-21 22:29 [PATCH net-next v2 00/11] net: bcmgenet: PM and Wake-on-LAN Florian Fainelli
  2014-07-21 22:29 ` [PATCH net-next v2 01/11] net: bcmgenet: remove wol_enabled conditional code Florian Fainelli
@ 2014-07-21 22:29 ` Florian Fainelli
  2014-07-21 22:29 ` [PATCH net-next v2 03/11] net: bcmgenet: modularize bcmgenet_{open,close} Florian Fainelli
                   ` (10 subsequent siblings)
  12 siblings, 0 replies; 15+ messages in thread
From: Florian Fainelli @ 2014-07-21 22:29 UTC (permalink / raw)
  To: netdev; +Cc: davem, Florian Fainelli

Factor the code touching the UniMAC RX/TX enable bits since we are going
to re-use it for implementing suspend/resume.

Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
---
Changes in v2:
- make the 'enable' argument in umac_enable_set a real boolean type
  and update callers to use true/false

 drivers/net/ethernet/broadcom/genet/bcmgenet.c | 37 +++++++++++++++++---------
 1 file changed, 24 insertions(+), 13 deletions(-)

diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.c b/drivers/net/ethernet/broadcom/genet/bcmgenet.c
index 3cbf29095257..c037c888640d 100644
--- a/drivers/net/ethernet/broadcom/genet/bcmgenet.c
+++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.c
@@ -1437,6 +1437,25 @@ static void bcmgenet_free_rx_buffers(struct bcmgenet_priv *priv)
 	}
 }
 
+static void umac_enable_set(struct bcmgenet_priv *priv, u32 mask,
+				bool enable)
+{
+	u32 reg;
+
+	reg = bcmgenet_umac_readl(priv, UMAC_CMD);
+	if (enable)
+		reg |= mask;
+	else
+		reg &= ~mask;
+	bcmgenet_umac_writel(priv, reg, UMAC_CMD);
+
+	/* UniMAC stops on a packet boundary, wait for a full-size packet
+	 * to be processed
+	 */
+	if (enable == 0)
+		usleep_range(1000, 2000);
+}
+
 static int reset_umac(struct bcmgenet_priv *priv)
 {
 	struct device *kdev = &priv->pdev->dev;
@@ -1988,9 +2007,7 @@ static int bcmgenet_open(struct net_device *dev)
 		goto err_clk_disable;
 
 	/* disable ethernet MAC while updating its registers */
-	reg = bcmgenet_umac_readl(priv, UMAC_CMD);
-	reg &= ~(CMD_TX_EN | CMD_RX_EN);
-	bcmgenet_umac_writel(priv, reg, UMAC_CMD);
+	umac_enable_set(priv, CMD_TX_EN | CMD_RX_EN, false);
 
 	bcmgenet_set_hw_addr(priv, dev->dev_addr);
 
@@ -2030,11 +2047,10 @@ static int bcmgenet_open(struct net_device *dev)
 	/* Start the network engine */
 	napi_enable(&priv->napi);
 
-	reg = bcmgenet_umac_readl(priv, UMAC_CMD);
-	reg |= (CMD_TX_EN | CMD_RX_EN);
-	bcmgenet_umac_writel(priv, reg, UMAC_CMD);
+	umac_enable_set(priv, CMD_TX_EN | CMD_RX_EN, true);
 
 	/* Make sure we reflect the value of CRC_CMD_FWD */
+	reg = bcmgenet_umac_readl(priv, UMAC_CMD);
 	priv->crc_fwd_en = !!(reg & CMD_CRC_FWD);
 
 	device_set_wakeup_capable(&dev->dev, 1);
@@ -2115,16 +2131,13 @@ static int bcmgenet_close(struct net_device *dev)
 {
 	struct bcmgenet_priv *priv = netdev_priv(dev);
 	int ret;
-	u32 reg;
 
 	netif_dbg(priv, ifdown, dev, "bcmgenet_close\n");
 
 	phy_stop(priv->phydev);
 
 	/* Disable MAC receive */
-	reg = bcmgenet_umac_readl(priv, UMAC_CMD);
-	reg &= ~CMD_RX_EN;
-	bcmgenet_umac_writel(priv, reg, UMAC_CMD);
+	umac_enable_set(priv, CMD_RX_EN, false);
 
 	netif_tx_stop_all_queues(dev);
 
@@ -2133,9 +2146,7 @@ static int bcmgenet_close(struct net_device *dev)
 		return ret;
 
 	/* Disable MAC transmit. TX DMA disabled have to done before this */
-	reg = bcmgenet_umac_readl(priv, UMAC_CMD);
-	reg &= ~CMD_TX_EN;
-	bcmgenet_umac_writel(priv, reg, UMAC_CMD);
+	umac_enable_set(priv, CMD_TX_EN, false);
 
 	napi_disable(&priv->napi);
 
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH net-next v2 03/11] net: bcmgenet: modularize bcmgenet_{open,close}
  2014-07-21 22:29 [PATCH net-next v2 00/11] net: bcmgenet: PM and Wake-on-LAN Florian Fainelli
  2014-07-21 22:29 ` [PATCH net-next v2 01/11] net: bcmgenet: remove wol_enabled conditional code Florian Fainelli
  2014-07-21 22:29 ` [PATCH net-next v2 02/11] net: bcmgenet: add umac_enable_set helper Florian Fainelli
@ 2014-07-21 22:29 ` Florian Fainelli
  2014-07-21 22:29 ` [PATCH net-next v2 04/11] net: bcmgenet: add suspend/resume callbacks Florian Fainelli
                   ` (9 subsequent siblings)
  12 siblings, 0 replies; 15+ messages in thread
From: Florian Fainelli @ 2014-07-21 22:29 UTC (permalink / raw)
  To: netdev; +Cc: davem, Florian Fainelli

Introduce a bunch of helper functions: bcmgenet_netif_start,
bcmgenet_netif_stop and bcmgenet_intr_disable to help reuse code that is
going to be necessary for suspend/resume.

Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
---
 drivers/net/ethernet/broadcom/genet/bcmgenet.c | 86 ++++++++++++++++----------
 1 file changed, 53 insertions(+), 33 deletions(-)

diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.c b/drivers/net/ethernet/broadcom/genet/bcmgenet.c
index c037c888640d..5cab188ee323 100644
--- a/drivers/net/ethernet/broadcom/genet/bcmgenet.c
+++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.c
@@ -1488,6 +1488,17 @@ static int reset_umac(struct bcmgenet_priv *priv)
 	return 0;
 }
 
+static void bcmgenet_intr_disable(struct bcmgenet_priv *priv)
+{
+	/* Mask all interrupts.*/
+	bcmgenet_intrl2_0_writel(priv, 0xFFFFFFFF, INTRL2_CPU_MASK_SET);
+	bcmgenet_intrl2_0_writel(priv, 0xFFFFFFFF, INTRL2_CPU_CLEAR);
+	bcmgenet_intrl2_0_writel(priv, 0, INTRL2_CPU_MASK_CLEAR);
+	bcmgenet_intrl2_1_writel(priv, 0xFFFFFFFF, INTRL2_CPU_MASK_SET);
+	bcmgenet_intrl2_1_writel(priv, 0xFFFFFFFF, INTRL2_CPU_CLEAR);
+	bcmgenet_intrl2_1_writel(priv, 0, INTRL2_CPU_MASK_CLEAR);
+}
+
 static int init_umac(struct bcmgenet_priv *priv)
 {
 	struct device *kdev = &priv->pdev->dev;
@@ -1516,10 +1527,7 @@ static int init_umac(struct bcmgenet_priv *priv)
 	if (!GENET_IS_V1(priv) && !GENET_IS_V2(priv))
 		bcmgenet_rbuf_writel(priv, 1, RBUF_TBUF_SIZE_CTRL);
 
-	/* Mask all interrupts.*/
-	bcmgenet_intrl2_0_writel(priv, 0xFFFFFFFF, INTRL2_CPU_MASK_SET);
-	bcmgenet_intrl2_0_writel(priv, 0xFFFFFFFF, INTRL2_CPU_CLEAR);
-	bcmgenet_intrl2_0_writel(priv, 0, INTRL2_CPU_MASK_CLEAR);
+	bcmgenet_intr_disable(priv);
 
 	cpu_mask_clear = UMAC_IRQ_RXDMA_BDONE;
 
@@ -1986,6 +1994,23 @@ static void bcmgenet_enable_dma(struct bcmgenet_priv *priv, u32 dma_ctrl)
 	bcmgenet_tdma_writel(priv, reg, DMA_CTRL);
 }
 
+static void bcmgenet_netif_start(struct net_device *dev)
+{
+	struct bcmgenet_priv *priv = netdev_priv(dev);
+
+	/* Start the network engine */
+	napi_enable(&priv->napi);
+
+	umac_enable_set(priv, CMD_TX_EN | CMD_RX_EN, true);
+
+	if (phy_is_internal(priv->phydev))
+		bcmgenet_power_up(priv, GENET_POWER_PASSIVE);
+
+	netif_tx_start_all_queues(dev);
+
+	phy_start(priv->phydev);
+}
+
 static int bcmgenet_open(struct net_device *dev)
 {
 	struct bcmgenet_priv *priv = netdev_priv(dev);
@@ -2009,6 +2034,10 @@ static int bcmgenet_open(struct net_device *dev)
 	/* disable ethernet MAC while updating its registers */
 	umac_enable_set(priv, CMD_TX_EN | CMD_RX_EN, false);
 
+	/* Make sure we reflect the value of CRC_CMD_FWD */
+	reg = bcmgenet_umac_readl(priv, UMAC_CMD);
+	priv->crc_fwd_en = !!(reg & CMD_CRC_FWD);
+
 	bcmgenet_set_hw_addr(priv, dev->dev_addr);
 
 	if (phy_is_internal(priv->phydev)) {
@@ -2017,6 +2046,8 @@ static int bcmgenet_open(struct net_device *dev)
 		bcmgenet_ext_writel(priv, reg, EXT_EXT_PWR_MGMT);
 	}
 
+	device_set_wakeup_capable(&dev->dev, 1);
+
 	/* Disable RX/TX DMA and flush TX queues */
 	dma_ctrl = bcmgenet_dma_disable(priv);
 
@@ -2044,23 +2075,7 @@ static int bcmgenet_open(struct net_device *dev)
 		goto err_irq0;
 	}
 
-	/* Start the network engine */
-	napi_enable(&priv->napi);
-
-	umac_enable_set(priv, CMD_TX_EN | CMD_RX_EN, true);
-
-	/* Make sure we reflect the value of CRC_CMD_FWD */
-	reg = bcmgenet_umac_readl(priv, UMAC_CMD);
-	priv->crc_fwd_en = !!(reg & CMD_CRC_FWD);
-
-	device_set_wakeup_capable(&dev->dev, 1);
-
-	if (phy_is_internal(priv->phydev))
-		bcmgenet_power_up(priv, GENET_POWER_PASSIVE);
-
-	netif_tx_start_all_queues(dev);
-
-	phy_start(priv->phydev);
+	bcmgenet_netif_start(dev);
 
 	return 0;
 
@@ -2127,6 +2142,22 @@ static int bcmgenet_dma_teardown(struct bcmgenet_priv *priv)
 	return ret;
 }
 
+static void bcmgenet_netif_stop(struct net_device *dev)
+{
+	struct bcmgenet_priv *priv = netdev_priv(dev);
+
+	netif_tx_stop_all_queues(dev);
+	napi_disable(&priv->napi);
+	phy_stop(priv->phydev);
+
+	bcmgenet_intr_disable(priv);
+
+	/* Wait for pending work items to complete. Since interrupts are
+	 * disabled no new work will be scheduled.
+	 */
+	cancel_work_sync(&priv->bcmgenet_irq_work);
+}
+
 static int bcmgenet_close(struct net_device *dev)
 {
 	struct bcmgenet_priv *priv = netdev_priv(dev);
@@ -2134,13 +2165,11 @@ static int bcmgenet_close(struct net_device *dev)
 
 	netif_dbg(priv, ifdown, dev, "bcmgenet_close\n");
 
-	phy_stop(priv->phydev);
+	bcmgenet_netif_stop(dev);
 
 	/* Disable MAC receive */
 	umac_enable_set(priv, CMD_RX_EN, false);
 
-	netif_tx_stop_all_queues(dev);
-
 	ret = bcmgenet_dma_teardown(priv);
 	if (ret)
 		return ret;
@@ -2148,8 +2177,6 @@ static int bcmgenet_close(struct net_device *dev)
 	/* Disable MAC transmit. TX DMA disabled have to done before this */
 	umac_enable_set(priv, CMD_TX_EN, false);
 
-	napi_disable(&priv->napi);
-
 	/* tx reclaim */
 	bcmgenet_tx_reclaim_all(dev);
 	bcmgenet_fini_dma(priv);
@@ -2157,12 +2184,6 @@ static int bcmgenet_close(struct net_device *dev)
 	free_irq(priv->irq0, priv);
 	free_irq(priv->irq1, priv);
 
-	/* Wait for pending work items to complete - we are stopping
-	 * the clock now. Since interrupts are disabled, no new work
-	 * will be scheduled.
-	 */
-	cancel_work_sync(&priv->bcmgenet_irq_work);
-
 	if (phy_is_internal(priv->phydev))
 		bcmgenet_power_down(priv, GENET_POWER_PASSIVE);
 
@@ -2563,7 +2584,6 @@ static int bcmgenet_remove(struct platform_device *pdev)
 	return 0;
 }
 
-
 static struct platform_driver bcmgenet_driver = {
 	.probe	= bcmgenet_probe,
 	.remove	= bcmgenet_remove,
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH net-next v2 04/11] net: bcmgenet: add suspend/resume callbacks
  2014-07-21 22:29 [PATCH net-next v2 00/11] net: bcmgenet: PM and Wake-on-LAN Florian Fainelli
                   ` (2 preceding siblings ...)
  2014-07-21 22:29 ` [PATCH net-next v2 03/11] net: bcmgenet: modularize bcmgenet_{open,close} Florian Fainelli
@ 2014-07-21 22:29 ` Florian Fainelli
  2014-07-21 22:29 ` [PATCH net-next v2 05/11] net: bcmgenet: request Wake-on-LAN interrupt Florian Fainelli
                   ` (8 subsequent siblings)
  12 siblings, 0 replies; 15+ messages in thread
From: Florian Fainelli @ 2014-07-21 22:29 UTC (permalink / raw)
  To: netdev; +Cc: davem, Florian Fainelli

Implement suspend/resume callbacks in the GENET driver. This makes sure
that we de-initialize and re-initialize the hardware correctly before
entering suspend and when resuming.

Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
---
Changes in v2:
- update callers of umac_enable_set to use true/false

 drivers/net/ethernet/broadcom/genet/bcmgenet.c | 95 ++++++++++++++++++++++++++
 1 file changed, 95 insertions(+)

diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.c b/drivers/net/ethernet/broadcom/genet/bcmgenet.c
index 5cab188ee323..bbd8bf326a35 100644
--- a/drivers/net/ethernet/broadcom/genet/bcmgenet.c
+++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.c
@@ -2584,6 +2584,100 @@ static int bcmgenet_remove(struct platform_device *pdev)
 	return 0;
 }
 
+#ifdef CONFIG_PM_SLEEP
+static int bcmgenet_suspend(struct device *d)
+{
+	struct net_device *dev = dev_get_drvdata(d);
+	struct bcmgenet_priv *priv = netdev_priv(dev);
+	int ret;
+
+	if (!netif_running(dev))
+		return 0;
+
+	bcmgenet_netif_stop(dev);
+
+	netif_device_detach(dev);
+
+	/* Disable MAC receive */
+	umac_enable_set(priv, CMD_RX_EN, false);
+
+	ret = bcmgenet_dma_teardown(priv);
+	if (ret)
+		return ret;
+
+	/* Disable MAC transmit. TX DMA disabled have to done before this */
+	umac_enable_set(priv, CMD_TX_EN, false);
+
+	/* tx reclaim */
+	bcmgenet_tx_reclaim_all(dev);
+	bcmgenet_fini_dma(priv);
+
+	/* Turn off the clocks */
+	clk_disable_unprepare(priv->clk);
+
+	return 0;
+}
+
+static int bcmgenet_resume(struct device *d)
+{
+	struct net_device *dev = dev_get_drvdata(d);
+	struct bcmgenet_priv *priv = netdev_priv(dev);
+	unsigned long dma_ctrl;
+	int ret;
+	u32 reg;
+
+	if (!netif_running(dev))
+		return 0;
+
+	/* Turn on the clock */
+	ret = clk_prepare_enable(priv->clk);
+	if (ret)
+		return ret;
+
+	bcmgenet_umac_reset(priv);
+
+	ret = init_umac(priv);
+	if (ret)
+		goto out_clk_disable;
+
+	/* disable ethernet MAC while updating its registers */
+	umac_enable_set(priv, CMD_TX_EN | CMD_RX_EN, false);
+
+	bcmgenet_set_hw_addr(priv, dev->dev_addr);
+
+	if (phy_is_internal(priv->phydev)) {
+		reg = bcmgenet_ext_readl(priv, EXT_EXT_PWR_MGMT);
+		reg |= EXT_ENERGY_DET_MASK;
+		bcmgenet_ext_writel(priv, reg, EXT_EXT_PWR_MGMT);
+	}
+
+	/* Disable RX/TX DMA and flush TX queues */
+	dma_ctrl = bcmgenet_dma_disable(priv);
+
+	/* Reinitialize TDMA and RDMA and SW housekeeping */
+	ret = bcmgenet_init_dma(priv);
+	if (ret) {
+		netdev_err(dev, "failed to initialize DMA\n");
+		goto out_clk_disable;
+	}
+
+	/* Always enable ring 16 - descriptor ring */
+	bcmgenet_enable_dma(priv, dma_ctrl);
+
+	netif_device_attach(dev);
+
+	bcmgenet_netif_start(dev);
+
+	return 0;
+
+out_clk_disable:
+	clk_disable_unprepare(priv->clk);
+	return ret;
+}
+#endif /* CONFIG_PM_SLEEP */
+
+static SIMPLE_DEV_PM_OPS(bcmgenet_pm_ops, bcmgenet_suspend, bcmgenet_resume);
+
 static struct platform_driver bcmgenet_driver = {
 	.probe	= bcmgenet_probe,
 	.remove	= bcmgenet_remove,
@@ -2591,6 +2685,7 @@ static struct platform_driver bcmgenet_driver = {
 		.name	= "bcmgenet",
 		.owner	= THIS_MODULE,
 		.of_match_table = bcmgenet_match,
+		.pm	= &bcmgenet_pm_ops,
 	},
 };
 module_platform_driver(bcmgenet_driver);
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH net-next v2 05/11] net: bcmgenet: request Wake-on-LAN interrupt
  2014-07-21 22:29 [PATCH net-next v2 00/11] net: bcmgenet: PM and Wake-on-LAN Florian Fainelli
                   ` (3 preceding siblings ...)
  2014-07-21 22:29 ` [PATCH net-next v2 04/11] net: bcmgenet: add suspend/resume callbacks Florian Fainelli
@ 2014-07-21 22:29 ` Florian Fainelli
  2014-07-21 22:29 ` [PATCH net-next v2 06/11] net: bcmgenet: add Wake-on-LAN support code Florian Fainelli
                   ` (7 subsequent siblings)
  12 siblings, 0 replies; 15+ messages in thread
From: Florian Fainelli @ 2014-07-21 22:29 UTC (permalink / raw)
  To: netdev; +Cc: davem, Florian Fainelli

Attempt to the request the Wake-on-LAN interrupt bit, and if successful,
advertise wakeup capability instead of doing this unconditionnally.

Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
---
Changes in v2:
- update wol_irq_disabled to be a real boolean type

 drivers/net/ethernet/broadcom/genet/bcmgenet.c | 19 +++++++++++++++++--
 drivers/net/ethernet/broadcom/genet/bcmgenet.h |  2 ++
 2 files changed, 19 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.c b/drivers/net/ethernet/broadcom/genet/bcmgenet.c
index bbd8bf326a35..344a889deaaa 100644
--- a/drivers/net/ethernet/broadcom/genet/bcmgenet.c
+++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.c
@@ -1918,6 +1918,15 @@ static irqreturn_t bcmgenet_isr0(int irq, void *dev_id)
 	return IRQ_HANDLED;
 }
 
+static irqreturn_t bcmgenet_wol_isr(int irq, void *dev_id)
+{
+	struct bcmgenet_priv *priv = dev_id;
+
+	pm_wakeup_event(&priv->pdev->dev, 0);
+
+	return IRQ_HANDLED;
+}
+
 static void bcmgenet_umac_reset(struct bcmgenet_priv *priv)
 {
 	u32 reg;
@@ -2046,8 +2055,6 @@ static int bcmgenet_open(struct net_device *dev)
 		bcmgenet_ext_writel(priv, reg, EXT_EXT_PWR_MGMT);
 	}
 
-	device_set_wakeup_capable(&dev->dev, 1);
-
 	/* Disable RX/TX DMA and flush TX queues */
 	dma_ctrl = bcmgenet_dma_disable(priv);
 
@@ -2473,6 +2480,7 @@ static int bcmgenet_probe(struct platform_device *pdev)
 	priv = netdev_priv(dev);
 	priv->irq0 = platform_get_irq(pdev, 0);
 	priv->irq1 = platform_get_irq(pdev, 1);
+	priv->wol_irq = platform_get_irq(pdev, 2);
 	if (!priv->irq0 || !priv->irq1) {
 		dev_err(&pdev->dev, "can't find IRQs\n");
 		err = -EINVAL;
@@ -2507,6 +2515,13 @@ static int bcmgenet_probe(struct platform_device *pdev)
 	dev->hw_features |= NETIF_F_SG | NETIF_F_IP_CSUM |
 		NETIF_F_IPV6_CSUM | NETIF_F_RXCSUM;
 
+	/* Request the WOL interrupt and advertise suspend if available */
+	priv->wol_irq_disabled = true;
+	err = devm_request_irq(&pdev->dev, priv->wol_irq, bcmgenet_wol_isr, 0,
+			       dev->name, priv);
+	if (!err)
+		device_set_wakeup_capable(&pdev->dev, 1);
+
 	/* Set the needed headroom to account for any possible
 	 * features enabling/disabling at runtime
 	 */
diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.h b/drivers/net/ethernet/broadcom/genet/bcmgenet.h
index f4891a1b6758..64bc53d86480 100644
--- a/drivers/net/ethernet/broadcom/genet/bcmgenet.h
+++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.h
@@ -569,6 +569,8 @@ struct bcmgenet_priv {
 	int irq1;
 	unsigned int irq0_stat;
 	unsigned int irq1_stat;
+	int wol_irq;
+	bool wol_irq_disabled;
 
 	/* HW descriptors/checksum variables */
 	bool desc_64b_en;
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH net-next v2 06/11] net: bcmgenet: add Wake-on-LAN support code
  2014-07-21 22:29 [PATCH net-next v2 00/11] net: bcmgenet: PM and Wake-on-LAN Florian Fainelli
                   ` (4 preceding siblings ...)
  2014-07-21 22:29 ` [PATCH net-next v2 05/11] net: bcmgenet: request Wake-on-LAN interrupt Florian Fainelli
@ 2014-07-21 22:29 ` Florian Fainelli
  2014-07-21 22:29 ` [PATCH net-next v2 07/11] net: bcmgenet: handle GENET_POWER_WOL_MAGIC Florian Fainelli
                   ` (6 subsequent siblings)
  12 siblings, 0 replies; 15+ messages in thread
From: Florian Fainelli @ 2014-07-21 22:29 UTC (permalink / raw)
  To: netdev; +Cc: davem, Florian Fainelli

Add all the required code to program the GENET hardware to enter
Wake-on-LAN mode and wake using MagicPackets with or without SecureOn
password.

This code is hooked to the build system, but is not yet referenced from
ethtool or the main bcmgenet driver.

Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
---
Changes in v2:
- make wol_irq_disabled a real boolean by using true/false

 drivers/net/ethernet/broadcom/genet/Makefile       |   2 +-
 drivers/net/ethernet/broadcom/genet/bcmgenet.h     |   9 +
 drivers/net/ethernet/broadcom/genet/bcmgenet_wol.c | 206 +++++++++++++++++++++
 3 files changed, 216 insertions(+), 1 deletion(-)
 create mode 100644 drivers/net/ethernet/broadcom/genet/bcmgenet_wol.c

diff --git a/drivers/net/ethernet/broadcom/genet/Makefile b/drivers/net/ethernet/broadcom/genet/Makefile
index 31f55a90a197..9b6885efa9e7 100644
--- a/drivers/net/ethernet/broadcom/genet/Makefile
+++ b/drivers/net/ethernet/broadcom/genet/Makefile
@@ -1,2 +1,2 @@
 obj-$(CONFIG_BCMGENET) += genet.o
-genet-objs := bcmgenet.o bcmmii.o
+genet-objs := bcmgenet.o bcmmii.o bcmgenet_wol.o
diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.h b/drivers/net/ethernet/broadcom/genet/bcmgenet.h
index 64bc53d86480..c61cd98b662e 100644
--- a/drivers/net/ethernet/broadcom/genet/bcmgenet.h
+++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.h
@@ -456,6 +456,7 @@ struct enet_cb {
 enum bcmgenet_power_mode {
 	GENET_POWER_CABLE_SENSE = 0,
 	GENET_POWER_PASSIVE,
+	GENET_POWER_WOL_MAGIC,
 };
 
 struct bcmgenet_priv;
@@ -626,4 +627,12 @@ int bcmgenet_mii_config(struct net_device *dev);
 void bcmgenet_mii_exit(struct net_device *dev);
 void bcmgenet_mii_reset(struct net_device *dev);
 
+/* Wake-on-LAN routines */
+void bcmgenet_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol);
+int bcmgenet_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol);
+int bcmgenet_wol_power_down_cfg(struct bcmgenet_priv *priv,
+				enum bcmgenet_power_mode mode);
+void bcmgenet_wol_power_up_cfg(struct bcmgenet_priv *priv,
+			       enum bcmgenet_power_mode mode);
+
 #endif /* __BCMGENET_H__ */
diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet_wol.c b/drivers/net/ethernet/broadcom/genet/bcmgenet_wol.c
new file mode 100644
index 000000000000..b82b7e4e06b2
--- /dev/null
+++ b/drivers/net/ethernet/broadcom/genet/bcmgenet_wol.c
@@ -0,0 +1,206 @@
+/*
+ * Broadcom GENET (Gigabit Ethernet) Wake-on-LAN support
+ *
+ * Copyright (c) 2014 Broadcom Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#define pr_fmt(fmt)				"bcmgenet_wol: " fmt
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/sched.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/string.h>
+#include <linux/init.h>
+#include <linux/errno.h>
+#include <linux/delay.h>
+#include <linux/pm.h>
+#include <linux/clk.h>
+#include <linux/version.h>
+#include <linux/platform_device.h>
+#include <net/arp.h>
+
+#include <linux/mii.h>
+#include <linux/ethtool.h>
+#include <linux/netdevice.h>
+#include <linux/inetdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/skbuff.h>
+#include <linux/in.h>
+#include <linux/ip.h>
+#include <linux/ipv6.h>
+#include <linux/phy.h>
+
+#include "bcmgenet.h"
+
+/* ethtool function - get WOL (Wake on LAN) settings, Only Magic Packet
+ * Detection is supported through ethtool
+ */
+void bcmgenet_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
+{
+	struct bcmgenet_priv *priv = netdev_priv(dev);
+	u32 reg;
+
+	wol->supported = WAKE_MAGIC | WAKE_MAGICSECURE;
+	wol->wolopts = priv->wolopts;
+	memset(wol->sopass, 0, sizeof(wol->sopass));
+
+	if (wol->wolopts & WAKE_MAGICSECURE) {
+		reg = bcmgenet_umac_readl(priv, UMAC_MPD_PW_MS);
+		put_unaligned_be16(reg, &wol->sopass[0]);
+		reg = bcmgenet_umac_readl(priv, UMAC_MPD_PW_LS);
+		put_unaligned_be32(reg, &wol->sopass[2]);
+	}
+}
+
+/* ethtool function - set WOL (Wake on LAN) settings.
+ * Only for magic packet detection mode.
+ */
+int bcmgenet_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
+{
+	struct bcmgenet_priv *priv = netdev_priv(dev);
+	struct device *kdev = &priv->pdev->dev;
+	u32 reg;
+
+	if (!device_can_wakeup(kdev))
+		return -ENOTSUPP;
+
+	if (wol->wolopts & ~(WAKE_MAGIC | WAKE_MAGICSECURE))
+		return -EINVAL;
+
+	if (wol->wolopts & WAKE_MAGICSECURE) {
+		bcmgenet_umac_writel(priv, get_unaligned_be16(&wol->sopass[0]),
+				     UMAC_MPD_PW_MS);
+		bcmgenet_umac_writel(priv, get_unaligned_be32(&wol->sopass[2]),
+				     UMAC_MPD_PW_LS);
+		reg = bcmgenet_umac_readl(priv, UMAC_MPD_CTRL);
+		reg |= MPD_PW_EN;
+		bcmgenet_umac_writel(priv, reg, UMAC_MPD_CTRL);
+	}
+
+	/* Flag the device and relevant IRQ as wakeup capable */
+	if (wol->wolopts) {
+		device_set_wakeup_enable(kdev, 1);
+		enable_irq_wake(priv->wol_irq);
+		priv->wol_irq_disabled = false;
+	} else {
+		device_set_wakeup_enable(kdev, 0);
+		/* Avoid unbalanced disable_irq_wake calls */
+		if (!priv->wol_irq_disabled)
+			disable_irq_wake(priv->wol_irq);
+		priv->wol_irq_disabled = true;
+	}
+
+	priv->wolopts = wol->wolopts;
+
+	return 0;
+}
+
+static int bcmgenet_poll_wol_status(struct bcmgenet_priv *priv)
+{
+	struct net_device *dev = priv->dev;
+	int retries = 0;
+
+	while (!(bcmgenet_rbuf_readl(priv, RBUF_STATUS)
+		& RBUF_STATUS_WOL)) {
+		retries++;
+		if (retries > 5) {
+			netdev_crit(dev, "polling wol mode timeout\n");
+			return -ETIMEDOUT;
+		}
+		mdelay(1);
+	}
+
+	return retries;
+}
+
+int bcmgenet_wol_power_down_cfg(struct bcmgenet_priv *priv,
+				enum bcmgenet_power_mode mode)
+{
+	struct net_device *dev = priv->dev;
+	u32 cpu_mask_clear;
+	int retries = 0;
+	u32 reg;
+
+	if (mode != GENET_POWER_WOL_MAGIC) {
+		netif_err(priv, wol, dev, "unsupported mode: %d\n", mode);
+		return -EINVAL;
+	}
+
+	/* disable RX */
+	reg = bcmgenet_umac_readl(priv, UMAC_CMD);
+	reg &= ~CMD_RX_EN;
+	bcmgenet_umac_writel(priv, reg, UMAC_CMD);
+	mdelay(10);
+
+	reg = bcmgenet_umac_readl(priv, UMAC_MPD_CTRL);
+	reg |= MPD_EN;
+	bcmgenet_umac_writel(priv, reg, UMAC_MPD_CTRL);
+
+	/* Do not leave UniMAC in MPD mode only */
+	retries = bcmgenet_poll_wol_status(priv);
+	if (retries < 0) {
+		reg = bcmgenet_umac_readl(priv, UMAC_MPD_CTRL);
+		reg &= ~MPD_EN;
+		bcmgenet_umac_writel(priv, reg, UMAC_MPD_CTRL);
+		return retries;
+	}
+
+	netif_dbg(priv, wol, dev, "MPD WOL-ready status set after %d msec\n",
+		  retries);
+
+	/* Enable CRC forward */
+	reg = bcmgenet_umac_readl(priv, UMAC_CMD);
+	priv->crc_fwd_en = 1;
+	reg |= CMD_CRC_FWD;
+
+	/* Receiver must be enabled for WOL MP detection */
+	reg |= CMD_RX_EN;
+	bcmgenet_umac_writel(priv, reg, UMAC_CMD);
+
+	if (priv->hw_params->flags & GENET_HAS_EXT) {
+		reg = bcmgenet_ext_readl(priv, EXT_EXT_PWR_MGMT);
+		reg &= ~EXT_ENERGY_DET_MASK;
+		bcmgenet_ext_writel(priv, reg, EXT_EXT_PWR_MGMT);
+	}
+
+	/* Enable the MPD interrupt */
+	cpu_mask_clear = UMAC_IRQ_MPD_R;
+
+	bcmgenet_intrl2_0_writel(priv, cpu_mask_clear, INTRL2_CPU_MASK_CLEAR);
+
+	return 0;
+}
+
+void bcmgenet_wol_power_up_cfg(struct bcmgenet_priv *priv,
+			       enum bcmgenet_power_mode mode)
+{
+	u32 cpu_mask_set;
+	u32 reg;
+
+	if (mode != GENET_POWER_WOL_MAGIC) {
+		netif_err(priv, wol, priv->dev, "invalid mode: %d\n", mode);
+		return;
+	}
+
+	reg = bcmgenet_umac_readl(priv, UMAC_MPD_CTRL);
+	reg &= ~MPD_EN;
+	bcmgenet_umac_writel(priv, reg, UMAC_MPD_CTRL);
+
+	/* Disable CRC Forward */
+	reg = bcmgenet_umac_readl(priv, UMAC_CMD);
+	reg &= ~CMD_CRC_FWD;
+	bcmgenet_umac_writel(priv, reg, UMAC_CMD);
+	priv->crc_fwd_en = 0;
+
+	/* Stop monitoring magic packet IRQ */
+	cpu_mask_set = UMAC_IRQ_MPD_R;
+
+	/* Stop monitoring magic packet IRQ */
+	bcmgenet_intrl2_0_writel(priv, cpu_mask_set, INTRL2_CPU_MASK_SET);
+}
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH net-next v2 07/11] net: bcmgenet: handle GENET_POWER_WOL_MAGIC
  2014-07-21 22:29 [PATCH net-next v2 00/11] net: bcmgenet: PM and Wake-on-LAN Florian Fainelli
                   ` (5 preceding siblings ...)
  2014-07-21 22:29 ` [PATCH net-next v2 06/11] net: bcmgenet: add Wake-on-LAN support code Florian Fainelli
@ 2014-07-21 22:29 ` Florian Fainelli
  2014-07-21 22:29 ` [PATCH net-next v2 08/11] net: bcmgenet: handle UMAC_IRQ_MPD_R interrupt bit Florian Fainelli
                   ` (5 subsequent siblings)
  12 siblings, 0 replies; 15+ messages in thread
From: Florian Fainelli @ 2014-07-21 22:29 UTC (permalink / raw)
  To: netdev; +Cc: davem, Florian Fainelli

Update bcmgenet_power_{up,down} to handle the case where the adapter has
been suspend respectively resumed from Wake-on-LAN using MagicPackets.

Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
---
 drivers/net/ethernet/broadcom/genet/bcmgenet.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.c b/drivers/net/ethernet/broadcom/genet/bcmgenet.c
index 344a889deaaa..f5118f4cccf3 100644
--- a/drivers/net/ethernet/broadcom/genet/bcmgenet.c
+++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.c
@@ -743,6 +743,10 @@ static void bcmgenet_power_down(struct bcmgenet_priv *priv,
 		phy_detach(priv->phydev);
 		break;
 
+	case GENET_POWER_WOL_MAGIC:
+		bcmgenet_wol_power_down_cfg(priv, mode);
+		break;
+
 	case GENET_POWER_PASSIVE:
 		/* Power down LED */
 		bcmgenet_mii_reset(priv->dev);
@@ -777,6 +781,9 @@ static void bcmgenet_power_up(struct bcmgenet_priv *priv,
 		/* enable APD */
 		reg |= EXT_PWR_DN_EN_LD;
 		break;
+	case GENET_POWER_WOL_MAGIC:
+		bcmgenet_wol_power_up_cfg(priv, mode);
+		return;
 	default:
 		break;
 	}
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH net-next v2 08/11] net: bcmgenet: handle UMAC_IRQ_MPD_R interrupt bit
  2014-07-21 22:29 [PATCH net-next v2 00/11] net: bcmgenet: PM and Wake-on-LAN Florian Fainelli
                   ` (6 preceding siblings ...)
  2014-07-21 22:29 ` [PATCH net-next v2 07/11] net: bcmgenet: handle GENET_POWER_WOL_MAGIC Florian Fainelli
@ 2014-07-21 22:29 ` Florian Fainelli
  2014-07-21 22:29 ` [PATCH net-next v2 09/11] net: bcmgenet: fix bcmgenet_wol_resume Florian Fainelli
                   ` (4 subsequent siblings)
  12 siblings, 0 replies; 15+ messages in thread
From: Florian Fainelli @ 2014-07-21 22:29 UTC (permalink / raw)
  To: netdev; +Cc: davem, Florian Fainelli

Handle UMAC_IRQ_MPD_R interrupt bit in our workqueue to make sure that
we properly re-configure the GENET adapter from Wake-on-LAN.

bcmgenet_power_up() makes sure that we will not leave the UniMAC
hardware in MagicPacket matching mode, since that would prevent any
other packet from being received.

Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
---
 drivers/net/ethernet/broadcom/genet/bcmgenet.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.c b/drivers/net/ethernet/broadcom/genet/bcmgenet.c
index f5118f4cccf3..319b94381d2e 100644
--- a/drivers/net/ethernet/broadcom/genet/bcmgenet.c
+++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.c
@@ -1836,6 +1836,13 @@ static void bcmgenet_irq_task(struct work_struct *work)
 
 	netif_dbg(priv, intr, priv->dev, "%s\n", __func__);
 
+	if (priv->irq0_stat & UMAC_IRQ_MPD_R) {
+		priv->irq0_stat &= ~UMAC_IRQ_MPD_R;
+		netif_dbg(priv, wol, priv->dev,
+			  "magic packet detected, waking up\n");
+		bcmgenet_power_up(priv, GENET_POWER_WOL_MAGIC);
+	}
+
 	/* Link UP/DOWN event */
 	if ((priv->hw_params->flags & GENET_HAS_MDIO_INTR) &&
 		(priv->irq0_stat & (UMAC_IRQ_LINK_UP|UMAC_IRQ_LINK_DOWN))) {
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH net-next v2 09/11] net: bcmgenet: fix bcmgenet_wol_resume
  2014-07-21 22:29 [PATCH net-next v2 00/11] net: bcmgenet: PM and Wake-on-LAN Florian Fainelli
                   ` (7 preceding siblings ...)
  2014-07-21 22:29 ` [PATCH net-next v2 08/11] net: bcmgenet: handle UMAC_IRQ_MPD_R interrupt bit Florian Fainelli
@ 2014-07-21 22:29 ` Florian Fainelli
  2014-07-21 22:29 ` [PATCH net-next v2 10/11] net: bcmgenet: suspend and resume from Wake-on-LAN Florian Fainelli
                   ` (3 subsequent siblings)
  12 siblings, 0 replies; 15+ messages in thread
From: Florian Fainelli @ 2014-07-21 22:29 UTC (permalink / raw)
  To: netdev; +Cc: davem, Florian Fainelli

bcmgenet_wol_resume() will create an unbalanced clock state for the
wol_clk clock pointer since everywhere else in the code, we always call
clk_prepare_enable() and clk_disable_unprepare(). This function also
calls init_umac() which is neither correct nor necessary since
bcmgenet_resume() and bcmgenet_open() already does that.

Finally calling bcmgenet_wol_resume() in bcmgenet_open() is not correct,
since the interface would not have been able to put us in Wake-on-LAN
mode if it was not UP before.

Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
---
 drivers/net/ethernet/broadcom/genet/bcmgenet.c | 8 +-------
 1 file changed, 1 insertion(+), 7 deletions(-)

diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.c b/drivers/net/ethernet/broadcom/genet/bcmgenet.c
index 319b94381d2e..1925ae1dc1e6 100644
--- a/drivers/net/ethernet/broadcom/genet/bcmgenet.c
+++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.c
@@ -1965,14 +1965,8 @@ static void bcmgenet_set_hw_addr(struct bcmgenet_priv *priv,
 
 static int bcmgenet_wol_resume(struct bcmgenet_priv *priv)
 {
-	int ret;
-
 	/* From WOL-enabled suspend, switch to regular clock */
-	clk_disable(priv->clk_wol);
-	/* init umac registers to synchronize s/w with h/w */
-	ret = init_umac(priv);
-	if (ret)
-		return ret;
+	clk_disable_unprepare(priv->clk_wol);
 
 	phy_init_hw(priv->phydev);
 	/* Speed settings must be restored */
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH net-next v2 10/11] net: bcmgenet: suspend and resume from Wake-on-LAN
  2014-07-21 22:29 [PATCH net-next v2 00/11] net: bcmgenet: PM and Wake-on-LAN Florian Fainelli
                   ` (8 preceding siblings ...)
  2014-07-21 22:29 ` [PATCH net-next v2 09/11] net: bcmgenet: fix bcmgenet_wol_resume Florian Fainelli
@ 2014-07-21 22:29 ` Florian Fainelli
  2014-07-21 22:29 ` [PATCH net-next v2 11/11] net: bcmgenet: hook ethtool set/get_wol operations Florian Fainelli
                   ` (2 subsequent siblings)
  12 siblings, 0 replies; 15+ messages in thread
From: Florian Fainelli @ 2014-07-21 22:29 UTC (permalink / raw)
  To: netdev; +Cc: davem, Florian Fainelli

Update bcmgenet_suspend() to prepare the hardware for being put into
Wake-on-LAN mode if the device can wakeup the system, and Wake-on-LAN is
enabled. Whether we resume from Wake-on-LAN or not, make sure that
bcmgenet_resume() disables the UniMAC MagicPacket matching mode and puts
the hardware in a state where it can receive all incoming packets.

Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
---
 drivers/net/ethernet/broadcom/genet/bcmgenet.c | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.c b/drivers/net/ethernet/broadcom/genet/bcmgenet.c
index 1925ae1dc1e6..62ef49c85980 100644
--- a/drivers/net/ethernet/broadcom/genet/bcmgenet.c
+++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.c
@@ -2635,6 +2635,12 @@ static int bcmgenet_suspend(struct device *d)
 	bcmgenet_tx_reclaim_all(dev);
 	bcmgenet_fini_dma(priv);
 
+	/* Prepare the device for Wake-on-LAN and switch to the slow clock */
+	if (device_may_wakeup(d) && priv->wolopts) {
+		bcmgenet_power_down(priv, GENET_POWER_WOL_MAGIC);
+		clk_prepare_enable(priv->clk_wol);
+	}
+
 	/* Turn off the clocks */
 	clk_disable_unprepare(priv->clk);
 
@@ -2663,6 +2669,12 @@ static int bcmgenet_resume(struct device *d)
 	if (ret)
 		goto out_clk_disable;
 
+	if (priv->wolopts)
+		ret = bcmgenet_wol_resume(priv);
+
+	if (ret)
+		goto out_clk_disable;
+
 	/* disable ethernet MAC while updating its registers */
 	umac_enable_set(priv, CMD_TX_EN | CMD_RX_EN, false);
 
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH net-next v2 11/11] net: bcmgenet: hook ethtool set/get_wol operations
  2014-07-21 22:29 [PATCH net-next v2 00/11] net: bcmgenet: PM and Wake-on-LAN Florian Fainelli
                   ` (9 preceding siblings ...)
  2014-07-21 22:29 ` [PATCH net-next v2 10/11] net: bcmgenet: suspend and resume from Wake-on-LAN Florian Fainelli
@ 2014-07-21 22:29 ` Florian Fainelli
  2014-07-21 23:07 ` [PATCH net-next v2 00/11] net: bcmgenet: PM and Wake-on-LAN David Miller
  2014-07-22 20:20 ` Francois Romieu
  12 siblings, 0 replies; 15+ messages in thread
From: Florian Fainelli @ 2014-07-21 22:29 UTC (permalink / raw)
  To: netdev; +Cc: davem, Florian Fainelli

Now that Wake-on-LAN support mode is fully integrated into the driver,
allow an user to query and configure Wake-on-LAN in the driver.

Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
---
 drivers/net/ethernet/broadcom/genet/bcmgenet.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.c b/drivers/net/ethernet/broadcom/genet/bcmgenet.c
index 62ef49c85980..0173a6d355aa 100644
--- a/drivers/net/ethernet/broadcom/genet/bcmgenet.c
+++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.c
@@ -730,6 +730,8 @@ static struct ethtool_ops bcmgenet_ethtool_ops = {
 	.get_link		= ethtool_op_get_link,
 	.get_msglevel		= bcmgenet_get_msglevel,
 	.set_msglevel		= bcmgenet_set_msglevel,
+	.get_wol		= bcmgenet_get_wol,
+	.set_wol		= bcmgenet_set_wol,
 };
 
 /* Power down the unimac, based on mode. */
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* Re: [PATCH net-next v2 00/11] net: bcmgenet: PM and Wake-on-LAN
  2014-07-21 22:29 [PATCH net-next v2 00/11] net: bcmgenet: PM and Wake-on-LAN Florian Fainelli
                   ` (10 preceding siblings ...)
  2014-07-21 22:29 ` [PATCH net-next v2 11/11] net: bcmgenet: hook ethtool set/get_wol operations Florian Fainelli
@ 2014-07-21 23:07 ` David Miller
  2014-07-22 20:20 ` Francois Romieu
  12 siblings, 0 replies; 15+ messages in thread
From: David Miller @ 2014-07-21 23:07 UTC (permalink / raw)
  To: f.fainelli; +Cc: netdev

From: Florian Fainelli <f.fainelli@gmail.com>
Date: Mon, 21 Jul 2014 15:29:18 -0700

> This patchset brings S2/S3 Power Management support to the GENET driver
> as well as Wake-on-LAN using Magic Packets with or without SecureOn
> passwords.

Looks good, series applied, th anks Florian.

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH net-next v2 00/11] net: bcmgenet: PM and Wake-on-LAN
  2014-07-21 22:29 [PATCH net-next v2 00/11] net: bcmgenet: PM and Wake-on-LAN Florian Fainelli
                   ` (11 preceding siblings ...)
  2014-07-21 23:07 ` [PATCH net-next v2 00/11] net: bcmgenet: PM and Wake-on-LAN David Miller
@ 2014-07-22 20:20 ` Francois Romieu
  2014-07-22 20:29   ` Florian Fainelli
  12 siblings, 1 reply; 15+ messages in thread
From: Francois Romieu @ 2014-07-22 20:20 UTC (permalink / raw)
  To: Florian Fainelli; +Cc: netdev, davem

Florian Fainelli <f.fainelli@gmail.com> :
[...]
> This patchset brings S2/S3 Power Management support to the GENET driver
> as well as Wake-on-LAN using Magic Packets with or without SecureOn
> passwords.

Out of curiosity, do you have a plan to support runtime power suspend,
say through phy_driver.link_change_notify ?

-- 
Ueimor

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH net-next v2 00/11] net: bcmgenet: PM and Wake-on-LAN
  2014-07-22 20:20 ` Francois Romieu
@ 2014-07-22 20:29   ` Florian Fainelli
  0 siblings, 0 replies; 15+ messages in thread
From: Florian Fainelli @ 2014-07-22 20:29 UTC (permalink / raw)
  To: Francois Romieu; +Cc: netdev, David Miller

Hi,

2014-07-22 13:20 GMT-07:00 Francois Romieu <romieu@fr.zoreil.com>:
> Florian Fainelli <f.fainelli@gmail.com> :
> [...]
>> This patchset brings S2/S3 Power Management support to the GENET driver
>> as well as Wake-on-LAN using Magic Packets with or without SecureOn
>> passwords.
>
> Out of curiosity, do you have a plan to support runtime power suspend,
> say through phy_driver.link_change_notify ?

The internal PHY (drivers/net/phy/bcm7xxx.c) used in conjunction with
the GENET or SYSTEMPORT adapters features auto-power down on link
down, which is where we get most of the power savings.

The remaining digital logic is not too power hungry, but I like your
idea, and will do some testing whether we can save some more power.

Thanks!
-- 
Florian

^ permalink raw reply	[flat|nested] 15+ messages in thread

end of thread, other threads:[~2014-07-22 20:30 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-07-21 22:29 [PATCH net-next v2 00/11] net: bcmgenet: PM and Wake-on-LAN Florian Fainelli
2014-07-21 22:29 ` [PATCH net-next v2 01/11] net: bcmgenet: remove wol_enabled conditional code Florian Fainelli
2014-07-21 22:29 ` [PATCH net-next v2 02/11] net: bcmgenet: add umac_enable_set helper Florian Fainelli
2014-07-21 22:29 ` [PATCH net-next v2 03/11] net: bcmgenet: modularize bcmgenet_{open,close} Florian Fainelli
2014-07-21 22:29 ` [PATCH net-next v2 04/11] net: bcmgenet: add suspend/resume callbacks Florian Fainelli
2014-07-21 22:29 ` [PATCH net-next v2 05/11] net: bcmgenet: request Wake-on-LAN interrupt Florian Fainelli
2014-07-21 22:29 ` [PATCH net-next v2 06/11] net: bcmgenet: add Wake-on-LAN support code Florian Fainelli
2014-07-21 22:29 ` [PATCH net-next v2 07/11] net: bcmgenet: handle GENET_POWER_WOL_MAGIC Florian Fainelli
2014-07-21 22:29 ` [PATCH net-next v2 08/11] net: bcmgenet: handle UMAC_IRQ_MPD_R interrupt bit Florian Fainelli
2014-07-21 22:29 ` [PATCH net-next v2 09/11] net: bcmgenet: fix bcmgenet_wol_resume Florian Fainelli
2014-07-21 22:29 ` [PATCH net-next v2 10/11] net: bcmgenet: suspend and resume from Wake-on-LAN Florian Fainelli
2014-07-21 22:29 ` [PATCH net-next v2 11/11] net: bcmgenet: hook ethtool set/get_wol operations Florian Fainelli
2014-07-21 23:07 ` [PATCH net-next v2 00/11] net: bcmgenet: PM and Wake-on-LAN David Miller
2014-07-22 20:20 ` Francois Romieu
2014-07-22 20:29   ` Florian Fainelli

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).