linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] net: stmicro: implement basic Wake-On-LAN support
@ 2022-05-24 12:39 Qiang Yang
  2022-05-24 12:52 ` Andrew Lunn
  0 siblings, 1 reply; 2+ messages in thread
From: Qiang Yang @ 2022-05-24 12:39 UTC (permalink / raw)
  To: peppe.cavallaro, alexandre.torgue, joabreu
  Cc: davem, netdev, linux-kernel, Qiang Yang, Weiqiang Su

This patch implements basic Wake-On-LAN support in stmicro driver,
including adding wakeup filter configuration and implementation of
stmmac suspend/resume/wakeup callbacks. Currently only magic packet can
trigger the Wake-On-LAN function.

Signed-off-by: Qiang Yang <line_walker2016@163.com>
Signed-off-by: Weiqiang Su <David.suwq@outlook.com>
---
 .../net/ethernet/stmicro/stmmac/dwmac1000.h   | 26 +++++++++++++++++++
 .../ethernet/stmicro/stmmac/dwmac1000_core.c  |  9 ++++++-
 .../net/ethernet/stmicro/stmmac/stmmac_main.c |  2 ++
 .../net/ethernet/stmicro/stmmac/stmmac_pci.c  |  1 +
 4 files changed, 37 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac1000.h b/drivers/net/ethernet/stmicro/stmmac/dwmac1000.h
index 1a84cf459e40..b84765831715 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac1000.h
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac1000.h
@@ -66,6 +66,32 @@ enum power_event {
 	power_down = 0x00000001,
 };
 
+#define WAKEUP_REG_LENGTH 8
+static u32 stmmac_wakeup_filter_config[] = {
+	/* For Filter0 CRC is not computed may be it is 0x0000 */
+	0x00000000,
+	/* For Filter1 CRC is computed on 0,1,2,3,4,5,6,7 bytes from offset */
+	0x000000FF,
+	/* For Filter2 CRC is not computed may be it is 0x0000 */
+	0x00000000,
+	/* For Filter3 CRC is not computed may be it is 0x0000 */
+	0x00000000,
+	/**
+	 * Filter 0,2,3 are disabled, Filter 1 is enabled and
+	 * filtering applies to only unicast packets
+	 */
+	0x00000100,
+	/**
+	 * Filter 0,2,3 (no significance), filter 1 offset is
+	 * 50 bytes from start of Destination MAC address
+	 */
+	0x00003200,
+	/* No significance of CRC for Filter0, Filter1 CRC is 0x7EED */
+	0x7eED0000,
+	/* No significance of CRC for Filter2 and Filter3 */
+	0x00000000,
+};
+
 /* Energy Efficient Ethernet (EEE)
  *
  * LPI status, timer and control register offset
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c b/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c
index 4d617ba11ecb..adea2346102e 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c
@@ -267,7 +267,14 @@ static void dwmac1000_flow_ctrl(struct mac_device_info *hw, unsigned int duplex,
 static void dwmac1000_pmt(struct mac_device_info *hw, unsigned long mode)
 {
 	void __iomem *ioaddr = hw->pcsr;
-	unsigned int pmt = 0;
+	unsigned int pmt = 0, i = 0;
+
+	writel(pointer_reset, ioaddr + GMAC_PMT);
+	mdelay(100);
+
+	for (i = 0; i < WAKEUP_REG_LENGTH; i++)
+		writel(*(stmmac_wakeup_filter_config + i),
+		       ioaddr + GMAC_WAKEUP_FILTER);
 
 	if (mode & WAKE_MAGIC) {
 		pr_debug("GMAC: WOL Magic frame\n");
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index 0a4d093adfc9..7866f3ec5ef6 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -4513,6 +4513,7 @@ int stmmac_suspend(struct device *dev)
 
 	/* Enable Power down mode by programming the PMT regs */
 	if (device_may_wakeup(priv->device)) {
+		priv->wolopts |= WAKE_MAGIC;
 		stmmac_pmt(priv, priv->hw, priv->wolopts);
 		priv->irq_wake = 1;
 	} else {
@@ -4598,6 +4599,7 @@ int stmmac_resume(struct device *dev)
 			stmmac_mdio_reset(priv->mii);
 	}
 
+	device_set_wakeup_enable(dev, 0);
 	netif_device_attach(ndev);
 
 	mutex_lock(&priv->lock);
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c
index cc1e887e47b5..ec69521f061c 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c
@@ -322,6 +322,7 @@ static int __maybe_unused stmmac_pci_suspend(struct device *dev)
 	struct pci_dev *pdev = to_pci_dev(dev);
 	int ret;
 
+	device_set_wakeup_enable(dev, 1);
 	ret = stmmac_suspend(dev);
 	if (ret)
 		return ret;
-- 
2.17.1


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

* Re: [PATCH] net: stmicro: implement basic Wake-On-LAN support
  2022-05-24 12:39 [PATCH] net: stmicro: implement basic Wake-On-LAN support Qiang Yang
@ 2022-05-24 12:52 ` Andrew Lunn
  0 siblings, 0 replies; 2+ messages in thread
From: Andrew Lunn @ 2022-05-24 12:52 UTC (permalink / raw)
  To: Qiang Yang
  Cc: peppe.cavallaro, alexandre.torgue, joabreu, davem, netdev,
	linux-kernel, Weiqiang Su

> --- a/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c
> +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c
> @@ -267,7 +267,14 @@ static void dwmac1000_flow_ctrl(struct mac_device_info *hw, unsigned int duplex,
>  static void dwmac1000_pmt(struct mac_device_info *hw, unsigned long mode)
>  {
>  	void __iomem *ioaddr = hw->pcsr;
> -	unsigned int pmt = 0;
> +	unsigned int pmt = 0, i = 0;
> +
> +	writel(pointer_reset, ioaddr + GMAC_PMT);
> +	mdelay(100);

That is quite a long delay. Is there a bit which can be polled to let
you know it is ready?

> +
> +	for (i = 0; i < WAKEUP_REG_LENGTH; i++)
> +		writel(*(stmmac_wakeup_filter_config + i),
> +		       ioaddr + GMAC_WAKEUP_FILTER);
>  
>  	if (mode & WAKE_MAGIC) {
>  		pr_debug("GMAC: WOL Magic frame\n");
> diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
> index 0a4d093adfc9..7866f3ec5ef6 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
> +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
> @@ -4513,6 +4513,7 @@ int stmmac_suspend(struct device *dev)
>  
>  	/* Enable Power down mode by programming the PMT regs */
>  	if (device_may_wakeup(priv->device)) {
> +		priv->wolopts |= WAKE_MAGIC;
>  		stmmac_pmt(priv, priv->hw, priv->wolopts);
>  		priv->irq_wake = 1;
>  	} else {
> @@ -4598,6 +4599,7 @@ int stmmac_resume(struct device *dev)
>  			stmmac_mdio_reset(priv->mii);
>  	}
>  
> +	device_set_wakeup_enable(dev, 0);
>  	netif_device_attach(ndev);
>  
>  	mutex_lock(&priv->lock);
> diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c
> index cc1e887e47b5..ec69521f061c 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c
> +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c
> @@ -322,6 +322,7 @@ static int __maybe_unused stmmac_pci_suspend(struct device *dev)
>  	struct pci_dev *pdev = to_pci_dev(dev);
>  	int ret;
>  
> +	device_set_wakeup_enable(dev, 1);
>  	ret = stmmac_suspend(dev);
>  	if (ret)
>  		return ret;

This looks too minimum. I would expect there to be code in set_wol and
get_wol, to indicate WAKE_MAGIC is available, and to turn it
on/off. You also need to deal with when the PHY also implements
WAKE_MAGIC. Ideally, the PHY should implement it, since it can do it
with less power. But when the PHY does not have support, then the MAC
should implement it.

Maybe some of this code already exists, i've not looked.

       Andrew

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

end of thread, other threads:[~2022-05-24 12:53 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-05-24 12:39 [PATCH] net: stmicro: implement basic Wake-On-LAN support Qiang Yang
2022-05-24 12:52 ` Andrew Lunn

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).