107 lines
3.3 KiB
Diff
107 lines
3.3 KiB
Diff
From eec2539ec9efc8a4f50c68204c01c113c39f2976 Mon Sep 17 00:00:00 2001
|
|
From: Dongjin Kim <tobetter@gmail.com>
|
|
Date: Wed, 17 Nov 2021 13:17:51 +0900
|
|
Subject: [PATCH 07/16] ODROID-COMMON: phy/realtek: add Wake-on-Lan to Realtek
|
|
PHY
|
|
|
|
Wake-On-Lan can set with 'ethtool'
|
|
$ sudo ethtool -s eth0 wol u
|
|
|
|
Check if 'Wake-on' is set with 'u'
|
|
$ sudo ethtool eth0 | grep Wake
|
|
Supports Wake-on: ug
|
|
Wake-on: u
|
|
|
|
In order to wake from remote, run 'wakeonlan' with IP address:
|
|
$ wakeonlan 00:1e:06:42:45:32
|
|
|
|
Signed-off-by: Dongjin Kim <tobetter@gmail.com>
|
|
Change-Id: I8ade81ab50d8d886e2908b9cec543e3bf8cc7abd
|
|
---
|
|
.../ethernet/stmicro/stmmac/stmmac_ethtool.c | 2 ++
|
|
drivers/net/phy/realtek.c | 34 +++++++++++++++++++
|
|
2 files changed, 36 insertions(+)
|
|
|
|
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
|
|
index d89455803bed..98f3913b7ae5 100644
|
|
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
|
|
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
|
|
@@ -753,6 +753,8 @@ static int stmmac_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
|
|
priv->wolopts = wol->wolopts;
|
|
mutex_unlock(&priv->lock);
|
|
|
|
+ phy_ethtool_set_wol(dev->phydev, wol);
|
|
+
|
|
return 0;
|
|
}
|
|
|
|
diff --git a/drivers/net/phy/realtek.c b/drivers/net/phy/realtek.c
|
|
index a5671ab896b3..f832992d80fd 100644
|
|
--- a/drivers/net/phy/realtek.c
|
|
+++ b/drivers/net/phy/realtek.c
|
|
@@ -12,6 +12,7 @@
|
|
#include <linux/phy.h>
|
|
#include <linux/module.h>
|
|
#include <linux/delay.h>
|
|
+#include <linux/etherdevice.h>
|
|
|
|
#define RTL821x_PHYSR 0x11
|
|
#define RTL821x_PHYSR_DUPLEX BIT(13)
|
|
@@ -228,7 +229,11 @@ static int rtl8211f_config_intr(struct phy_device *phydev)
|
|
|
|
val = RTL8211F_INER_LINK_STATUS;
|
|
err = phy_write_paged(phydev, 0xa42, RTL821x_INER, val);
|
|
+
|
|
+ phy_modify_paged(phydev, 0xd40, 0x16, BIT(5), 0);
|
|
} else {
|
|
+ phy_modify_paged(phydev, 0xd40, 0x16, 0, BIT(5));
|
|
+
|
|
val = 0;
|
|
err = phy_write_paged(phydev, 0xa42, RTL821x_INER, val);
|
|
if (err)
|
|
@@ -329,6 +334,34 @@ static int rtl8211c_config_init(struct phy_device *phydev)
|
|
CTL1000_ENABLE_MASTER | CTL1000_AS_MASTER);
|
|
}
|
|
|
|
+static int rtl8211f_set_wol(struct phy_device *phydev,
|
|
+ struct ethtool_wolinfo *wol)
|
|
+{
|
|
+ struct net_device *netdev = phydev->attached_dev;
|
|
+ const u8 *mac = (const u8 *)netdev->dev_addr;
|
|
+
|
|
+ if ((wol->wolopts & (WAKE_MAGIC | WAKE_UCAST)) == 0) {
|
|
+ disable_irq_wake(phydev->irq);
|
|
+ return 0;
|
|
+ }
|
|
+
|
|
+ if ((wol->wolopts & WAKE_UCAST)
|
|
+ && is_valid_ether_addr(mac)) {
|
|
+ phy_write_paged(phydev, 0xd8c, 0x10, (mac[1] << 8) | mac[0]);
|
|
+ phy_write_paged(phydev, 0xd8c, 0x11, (mac[3] << 8) | mac[2]);
|
|
+ phy_write_paged(phydev, 0xd8c, 0x12, (mac[5] << 8) | mac[4]);
|
|
+ }
|
|
+
|
|
+ if (wol->wolopts & WAKE_MAGIC) {
|
|
+ phy_write_paged(phydev, 0xd8a, 0x10, 0x1000);
|
|
+ phy_write_paged(phydev, 0xd8a, 0x11, 0x9fff);
|
|
+ }
|
|
+
|
|
+ enable_irq_wake(phydev->irq);
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
static int rtl8211f_config_init(struct phy_device *phydev)
|
|
{
|
|
struct rtl821x_priv *priv = phydev->priv;
|
|
@@ -921,6 +954,7 @@ static struct phy_driver realtek_drvs[] = {
|
|
.handle_interrupt = rtl8211f_handle_interrupt,
|
|
.suspend = genphy_suspend,
|
|
.resume = rtl821x_resume,
|
|
+ .set_wol = rtl8211f_set_wol,
|
|
.read_page = rtl821x_read_page,
|
|
.write_page = rtl821x_write_page,
|
|
}, {
|
|
--
|
|
2.34.1
|
|
|