114 lines
3.3 KiB
Diff
114 lines
3.3 KiB
Diff
From 0595f01e280d1f0943ab1dc88e5d16f2ba435426 Mon Sep 17 00:00:00 2001
|
|
From: Dongjin Kim <tobetter@gmail.com>
|
|
Date: Thu, 15 Jul 2021 19:32:42 +0900
|
|
Subject: [PATCH 64/75] ODROID-COMMON: phy/realtek: add Wake-on-Lan to Realtek
|
|
PHY
|
|
|
|
Wake-On-Lan can set with 'ethtool'
|
|
$ sudo ethtool -s eth0 wol g
|
|
|
|
Check if 'Wake-on' is set with 'g'
|
|
$ sudo ethtool eth0 | grep Wake
|
|
Supports Wake-on: ug
|
|
Wake-on: g
|
|
|
|
In order to wake from remote, run 'wakeonlan' with IP address:
|
|
$ wakeonlan 00:1e:06:42:45:32
|
|
|
|
Change-Id: Ida2e9ac5ce623fceecc7d00c712f173bca16e322
|
|
Signed-off-by: Dongjin Kim <tobetter@gmail.com>
|
|
---
|
|
.../ethernet/stmicro/stmmac/stmmac_ethtool.c | 2 +
|
|
drivers/net/phy/realtek.c | 48 +++++++++++++++++++
|
|
2 files changed, 50 insertions(+)
|
|
|
|
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
|
|
index d89455803bed..439be5b6590d 100644
|
|
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
|
|
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
|
|
@@ -749,6 +749,8 @@ static int stmmac_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
|
|
disable_irq_wake(priv->wol_irq);
|
|
}
|
|
|
|
+ phylink_ethtool_set_wol(priv->phylink, wol);
|
|
+
|
|
mutex_lock(&priv->lock);
|
|
priv->wolopts = wol->wolopts;
|
|
mutex_unlock(&priv->lock);
|
|
diff --git a/drivers/net/phy/realtek.c b/drivers/net/phy/realtek.c
|
|
index 11be60333fa8..dd82045b5ef3 100644
|
|
--- a/drivers/net/phy/realtek.c
|
|
+++ b/drivers/net/phy/realtek.c
|
|
@@ -12,6 +12,8 @@
|
|
#include <linux/phy.h>
|
|
#include <linux/module.h>
|
|
#include <linux/delay.h>
|
|
+#include <linux/etherdevice.h>
|
|
+#include <linux/netdevice.h>
|
|
|
|
#define RTL821x_PHYSR 0x11
|
|
#define RTL821x_PHYSR_DUPLEX BIT(13)
|
|
@@ -300,6 +302,51 @@ static irqreturn_t rtl8211f_handle_interrupt(struct phy_device *phydev)
|
|
return IRQ_HANDLED;
|
|
}
|
|
|
|
+static int rtl8211f_set_wol(struct phy_device *phydev,
|
|
+ struct ethtool_wolinfo *wol)
|
|
+{
|
|
+ struct net_device *ndev = phydev->attached_dev;
|
|
+ const u8 *mac;
|
|
+ int val;
|
|
+
|
|
+ if (wol->wolopts & WAKE_MAGIC) {
|
|
+ mac = (const u8 *)ndev->dev_addr;
|
|
+
|
|
+ if (!is_valid_ether_addr(mac))
|
|
+ return -EINVAL;
|
|
+
|
|
+ /* Set MAC address */
|
|
+ phy_write(phydev, RTL821x_PAGE_SELECT, 0xd8c);
|
|
+ phy_write(phydev, 0x10, (mac[1] << 8) | mac[0]);
|
|
+ phy_write(phydev, 0x11, (mac[3] << 8) | mac[2]);
|
|
+ phy_write(phydev, 0x12, (mac[5] << 8) | mac[4]);
|
|
+
|
|
+ phy_write(phydev, RTL821x_PAGE_SELECT, 0xd8a);
|
|
+
|
|
+ /* Set magic packet for WOL */
|
|
+ phy_write(phydev, 0x10, 0x1000);
|
|
+ phy_write(phydev, 0x11, 0x9fff);
|
|
+
|
|
+ /* PIN31 - pull high */
|
|
+ phy_write(phydev, RTL821x_PAGE_SELECT, 0xd40);
|
|
+ val = phy_read(phydev, 0x16);
|
|
+ phy_write(phydev, 0x16, val | BIT(5));
|
|
+
|
|
+ phy_write(phydev, RTL821x_PAGE_SELECT, 0);
|
|
+ } else {
|
|
+ phy_write(phydev, RTL821x_PAGE_SELECT, 0xd8a);
|
|
+
|
|
+ /* Reset magic packet for WOL */
|
|
+ phy_write(phydev, 0x10, 0x0);
|
|
+ val = phy_read(phydev, 0x11);
|
|
+ phy_write(phydev, 0x11, val & ~BIT(15));
|
|
+
|
|
+ phy_write(phydev, RTL821x_PAGE_SELECT, 0);
|
|
+ }
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
static int rtl8211_config_aneg(struct phy_device *phydev)
|
|
{
|
|
int ret;
|
|
@@ -909,6 +956,7 @@ static struct phy_driver realtek_drvs[] = {
|
|
.handle_interrupt = rtl821x_handle_interrupt,
|
|
.suspend = genphy_suspend,
|
|
.resume = genphy_resume,
|
|
+ .set_wol = rtl8211f_set_wol,
|
|
.read_page = rtl821x_read_page,
|
|
.write_page = rtl821x_write_page,
|
|
}, {
|
|
--
|
|
2.25.1
|
|
|