mirror of
git://git.openwrt.org/openwrt/openwrt.git
synced 2025-12-06 12:44:00 -05:00
kernel: backport upstream Realtek PHY patches
Backport of the latest upstream Realtek PHY patches. WoL uses devm_pm_set_wake_irq(), so the patch that adds this function has also been backported. Changelog: 4465ae435ddc net: phy: realtek: create rtl8211f_config_phy_eee() helper bb78b71faf60 net: phy: realtek: eliminate priv->phycr1 variable e1a31c41bef6 net: phy: realtek: allow CLKOUT to be disabled on RTL8211F(D)(I)-VD-CG 910ac7bfb1af net: phy: realtek: eliminate has_phycr2 variable 27033d069177 net: phy: realtek: eliminate priv->phycr2 variable 8e982441ba60 net: phy: realtek: create rtl8211f_config_rgmii_delay() b826bf795564 net: phy: realtek: fix RTL8211F wake-on-lan support Tested on Netgear WAX206 with RTL8221B-VB-CG. Signed-off-by: Aleksander Jan Bajkowski <olek2@wp.pl> Link: https://github.com/openwrt/openwrt/pull/20987 Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
This commit is contained in:
parent
c9e7f32c4c
commit
48c9e55094
@ -0,0 +1,74 @@
|
||||
From fd8318a32573d73eb20637a0c80689de0dc98169 Mon Sep 17 00:00:00 2001
|
||||
From: Peng Fan <peng.fan@nxp.com>
|
||||
Date: Fri, 3 Jan 2025 16:41:13 +0800
|
||||
Subject: [PATCH] PM: sleep: wakeirq: Introduce device-managed variant of
|
||||
dev_pm_set_wake_irq()
|
||||
|
||||
Add device-managed variant of dev_pm_set_wake_irq which automatically
|
||||
clear the wake irq on device destruction to simplify error handling
|
||||
and resource management in drivers.
|
||||
|
||||
Signed-off-by: Peng Fan <peng.fan@nxp.com>
|
||||
Link: https://patch.msgid.link/20250103-wake_irq-v2-1-e3aeff5e9966@nxp.com
|
||||
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
|
||||
---
|
||||
drivers/base/power/wakeirq.c | 26 ++++++++++++++++++++++++++
|
||||
include/linux/pm_wakeirq.h | 6 ++++++
|
||||
2 files changed, 32 insertions(+)
|
||||
|
||||
--- a/drivers/base/power/wakeirq.c
|
||||
+++ b/drivers/base/power/wakeirq.c
|
||||
@@ -103,6 +103,32 @@ void dev_pm_clear_wake_irq(struct device
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(dev_pm_clear_wake_irq);
|
||||
|
||||
+static void devm_pm_clear_wake_irq(void *dev)
|
||||
+{
|
||||
+ dev_pm_clear_wake_irq(dev);
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * devm_pm_set_wake_irq - device-managed variant of dev_pm_set_wake_irq
|
||||
+ * @dev: Device entry
|
||||
+ * @irq: Device IO interrupt
|
||||
+ *
|
||||
+ *
|
||||
+ * Attach a device IO interrupt as a wake IRQ, same with dev_pm_set_wake_irq,
|
||||
+ * but the device will be auto clear wake capability on driver detach.
|
||||
+ */
|
||||
+int devm_pm_set_wake_irq(struct device *dev, int irq)
|
||||
+{
|
||||
+ int ret;
|
||||
+
|
||||
+ ret = dev_pm_set_wake_irq(dev, irq);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ return devm_add_action_or_reset(dev, devm_pm_clear_wake_irq, dev);
|
||||
+}
|
||||
+EXPORT_SYMBOL_GPL(devm_pm_set_wake_irq);
|
||||
+
|
||||
/**
|
||||
* handle_threaded_wake_irq - Handler for dedicated wake-up interrupts
|
||||
* @irq: Device specific dedicated wake-up interrupt
|
||||
--- a/include/linux/pm_wakeirq.h
|
||||
+++ b/include/linux/pm_wakeirq.h
|
||||
@@ -10,6 +10,7 @@ extern int dev_pm_set_wake_irq(struct de
|
||||
extern int dev_pm_set_dedicated_wake_irq(struct device *dev, int irq);
|
||||
extern int dev_pm_set_dedicated_wake_irq_reverse(struct device *dev, int irq);
|
||||
extern void dev_pm_clear_wake_irq(struct device *dev);
|
||||
+extern int devm_pm_set_wake_irq(struct device *dev, int irq);
|
||||
|
||||
#else /* !CONFIG_PM */
|
||||
|
||||
@@ -32,5 +33,10 @@ static inline void dev_pm_clear_wake_irq
|
||||
{
|
||||
}
|
||||
|
||||
+static inline int devm_pm_set_wake_irq(struct device *dev, int irq)
|
||||
+{
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
#endif /* CONFIG_PM */
|
||||
#endif /* _LINUX_PM_WAKEIRQ_H */
|
||||
@ -0,0 +1,352 @@
|
||||
From b826bf795564ddef6402cf2cb522ae035bd117ae Mon Sep 17 00:00:00 2001
|
||||
From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
|
||||
Date: Wed, 13 Aug 2025 11:04:45 +0100
|
||||
Subject: [PATCH] net: phy: realtek: fix RTL8211F wake-on-lan support
|
||||
|
||||
Implement Wake-on-Lan for RTL8211F correctly. The existing
|
||||
implementation has multiple issues:
|
||||
|
||||
1. It assumes that Wake-on-Lan can always be used, whether or not the
|
||||
interrupt is wired, and whether or not the interrupt is capable of
|
||||
waking the system. This breaks the ability for MAC drivers to detect
|
||||
whether the PHY WoL is functional.
|
||||
2. switching the interrupt pin in the .set_wol() method to PMEB mode
|
||||
immediately silences link-state interrupts, which breaks phylib
|
||||
when interrupts are being used rather than polling mode.
|
||||
3. the code claiming to "reset WOL status" was doing nothing of the
|
||||
sort. Bit 15 in page 0xd8a register 17 controls WoL reset, and
|
||||
needs to be pulsed low to reset the WoL state. This bit was always
|
||||
written as '1', resulting in no reset.
|
||||
4. not resetting WoL state results in the PMEB pin remaining asserted,
|
||||
which in turn leads to an interrupt storm. Only resetting the WoL
|
||||
state in .set_wol() is not sufficient.
|
||||
5. PMEB mode does not allow software detection of the wake-up event as
|
||||
there is no status bit to indicate we received the WoL packet.
|
||||
6. across reboots of at least the Jetson Xavier NX system, the WoL
|
||||
configuration is preserved.
|
||||
|
||||
Fix all of these issues by essentially rewriting the support. We:
|
||||
1. clear the WoL event enable register at probe time.
|
||||
2. detect whether we can support wake-up by having a valid interrupt,
|
||||
and the "wakeup-source" property in DT. If we can, then we mark
|
||||
the MDIO device as wakeup capable, and associate the interrupt
|
||||
with the wakeup source.
|
||||
3. arrange for the get_wol() and set_wol() implementations to handle
|
||||
the case where the MDIO device has not been marked as wakeup
|
||||
capable (thereby returning no WoL support, and refusing to enable
|
||||
WoL support.)
|
||||
4. avoid switching to PMEB mode, instead using INTB mode with the
|
||||
interrupt enable, reconfiguring the interrupt enables at suspend
|
||||
time, and restoring their original state at resume time (we track
|
||||
the state of the interrupt enable register in .config_intr()
|
||||
register.)
|
||||
5. move WoL reset from .set_wol() to the suspend function to ensure
|
||||
that WoL state is cleared prior to suspend. This is necessary
|
||||
after the PME interrupt has been enabled as a second WoL packet
|
||||
will not re-raise a previously cleared PME interrupt.
|
||||
6. when a PME interrupt (for wakeup) is asserted, pass this to the
|
||||
PM wakeup so it knows which device woke the system.
|
||||
|
||||
This fixes WoL support in the Realtek RTL8211F driver when used on the
|
||||
nVidia Jetson Xavier NX platform, and needs to be applied before stmmac
|
||||
patches which allow these platforms to forward the ethtool WoL commands
|
||||
to the Realtek PHY.
|
||||
|
||||
Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
|
||||
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
|
||||
Link: https://patch.msgid.link/E1um8Ld-008jxD-Mc@rmk-PC.armlinux.org.uk
|
||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
---
|
||||
drivers/net/phy/realtek/realtek_main.c | 172 ++++++++++++++++++++-----
|
||||
1 file changed, 140 insertions(+), 32 deletions(-)
|
||||
|
||||
--- a/drivers/net/phy/realtek/realtek_main.c
|
||||
+++ b/drivers/net/phy/realtek/realtek_main.c
|
||||
@@ -10,6 +10,7 @@
|
||||
#include <linux/bitops.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/phy.h>
|
||||
+#include <linux/pm_wakeirq.h>
|
||||
#include <linux/netdevice.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/delay.h>
|
||||
@@ -31,6 +32,7 @@
|
||||
#define RTL821x_INER 0x12
|
||||
#define RTL8211B_INER_INIT 0x6400
|
||||
#define RTL8211E_INER_LINK_STATUS BIT(10)
|
||||
+#define RTL8211F_INER_PME BIT(7)
|
||||
#define RTL8211F_INER_LINK_STATUS BIT(4)
|
||||
|
||||
#define RTL821x_INSR 0x13
|
||||
@@ -96,17 +98,13 @@
|
||||
#define RTL8211F_RXCR 0x15
|
||||
#define RTL8211F_RX_DELAY BIT(3)
|
||||
|
||||
-/* RTL8211F WOL interrupt configuration */
|
||||
-#define RTL8211F_INTBCR_PAGE 0xd40
|
||||
-#define RTL8211F_INTBCR 0x16
|
||||
-#define RTL8211F_INTBCR_INTB_PMEB BIT(5)
|
||||
-
|
||||
/* RTL8211F WOL settings */
|
||||
-#define RTL8211F_WOL_SETTINGS_PAGE 0xd8a
|
||||
+#define RTL8211F_WOL_PAGE 0xd8a
|
||||
#define RTL8211F_WOL_SETTINGS_EVENTS 16
|
||||
#define RTL8211F_WOL_EVENT_MAGIC BIT(12)
|
||||
-#define RTL8211F_WOL_SETTINGS_STATUS 17
|
||||
-#define RTL8211F_WOL_STATUS_RESET (BIT(15) | 0x1fff)
|
||||
+#define RTL8211F_WOL_RST_RMSQ 17
|
||||
+#define RTL8211F_WOL_RG_RSTB BIT(15)
|
||||
+#define RTL8211F_WOL_RMSQ 0x1fff
|
||||
|
||||
/* RTL8211F Unique phyiscal and multicast address (WOL) */
|
||||
#define RTL8211F_PHYSICAL_ADDR_PAGE 0xd8c
|
||||
@@ -172,7 +170,8 @@ struct rtl821x_priv {
|
||||
u16 phycr2;
|
||||
bool has_phycr2;
|
||||
struct clk *clk;
|
||||
- u32 saved_wolopts;
|
||||
+ /* rtl8211f */
|
||||
+ u16 iner;
|
||||
};
|
||||
|
||||
static int rtl821x_read_page(struct phy_device *phydev)
|
||||
@@ -255,6 +254,34 @@ static int rtl821x_probe(struct phy_devi
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static int rtl8211f_probe(struct phy_device *phydev)
|
||||
+{
|
||||
+ struct device *dev = &phydev->mdio.dev;
|
||||
+ int ret;
|
||||
+
|
||||
+ ret = rtl821x_probe(phydev);
|
||||
+ if (ret < 0)
|
||||
+ return ret;
|
||||
+
|
||||
+ /* Disable all PME events */
|
||||
+ ret = phy_write_paged(phydev, RTL8211F_WOL_PAGE,
|
||||
+ RTL8211F_WOL_SETTINGS_EVENTS, 0);
|
||||
+ if (ret < 0)
|
||||
+ return ret;
|
||||
+
|
||||
+ /* Mark this PHY as wakeup capable and register the interrupt as a
|
||||
+ * wakeup IRQ if the PHY is marked as a wakeup source in firmware,
|
||||
+ * and the interrupt is valid.
|
||||
+ */
|
||||
+ if (device_property_read_bool(dev, "wakeup-source") &&
|
||||
+ phy_interrupt_is_valid(phydev)) {
|
||||
+ device_set_wakeup_capable(dev, true);
|
||||
+ devm_pm_set_wake_irq(dev, phydev->irq);
|
||||
+ }
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
static int rtl8201_ack_interrupt(struct phy_device *phydev)
|
||||
{
|
||||
int err;
|
||||
@@ -352,6 +379,7 @@ static int rtl8211e_config_intr(struct p
|
||||
|
||||
static int rtl8211f_config_intr(struct phy_device *phydev)
|
||||
{
|
||||
+ struct rtl821x_priv *priv = phydev->priv;
|
||||
u16 val;
|
||||
int err;
|
||||
|
||||
@@ -362,8 +390,10 @@ static int rtl8211f_config_intr(struct p
|
||||
|
||||
val = RTL8211F_INER_LINK_STATUS;
|
||||
err = phy_write_paged(phydev, 0xa42, RTL821x_INER, val);
|
||||
+ if (err == 0)
|
||||
+ priv->iner = val;
|
||||
} else {
|
||||
- val = 0;
|
||||
+ priv->iner = val = 0;
|
||||
err = phy_write_paged(phydev, 0xa42, RTL821x_INER, val);
|
||||
if (err)
|
||||
return err;
|
||||
@@ -426,21 +456,34 @@ static irqreturn_t rtl8211f_handle_inter
|
||||
return IRQ_NONE;
|
||||
}
|
||||
|
||||
- if (!(irq_status & RTL8211F_INER_LINK_STATUS))
|
||||
- return IRQ_NONE;
|
||||
+ if (irq_status & RTL8211F_INER_LINK_STATUS) {
|
||||
+ phy_trigger_machine(phydev);
|
||||
+ return IRQ_HANDLED;
|
||||
+ }
|
||||
|
||||
- phy_trigger_machine(phydev);
|
||||
+ if (irq_status & RTL8211F_INER_PME) {
|
||||
+ pm_wakeup_event(&phydev->mdio.dev, 0);
|
||||
+ return IRQ_HANDLED;
|
||||
+ }
|
||||
|
||||
- return IRQ_HANDLED;
|
||||
+ return IRQ_NONE;
|
||||
}
|
||||
|
||||
static void rtl8211f_get_wol(struct phy_device *dev, struct ethtool_wolinfo *wol)
|
||||
{
|
||||
int wol_events;
|
||||
|
||||
+ /* If the PHY is not capable of waking the system, then WoL can not
|
||||
+ * be supported.
|
||||
+ */
|
||||
+ if (!device_can_wakeup(&dev->mdio.dev)) {
|
||||
+ wol->supported = 0;
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
wol->supported = WAKE_MAGIC;
|
||||
|
||||
- wol_events = phy_read_paged(dev, RTL8211F_WOL_SETTINGS_PAGE, RTL8211F_WOL_SETTINGS_EVENTS);
|
||||
+ wol_events = phy_read_paged(dev, RTL8211F_WOL_PAGE, RTL8211F_WOL_SETTINGS_EVENTS);
|
||||
if (wol_events < 0)
|
||||
return;
|
||||
|
||||
@@ -453,6 +496,9 @@ static int rtl8211f_set_wol(struct phy_d
|
||||
const u8 *mac_addr = dev->attached_dev->dev_addr;
|
||||
int oldpage;
|
||||
|
||||
+ if (!device_can_wakeup(&dev->mdio.dev))
|
||||
+ return -EOPNOTSUPP;
|
||||
+
|
||||
oldpage = phy_save_page(dev);
|
||||
if (oldpage < 0)
|
||||
goto err;
|
||||
@@ -464,25 +510,23 @@ static int rtl8211f_set_wol(struct phy_d
|
||||
__phy_write(dev, RTL8211F_PHYSICAL_ADDR_WORD1, mac_addr[3] << 8 | (mac_addr[2]));
|
||||
__phy_write(dev, RTL8211F_PHYSICAL_ADDR_WORD2, mac_addr[5] << 8 | (mac_addr[4]));
|
||||
|
||||
- /* Enable magic packet matching and reset WOL status */
|
||||
- rtl821x_write_page(dev, RTL8211F_WOL_SETTINGS_PAGE);
|
||||
+ /* Enable magic packet matching */
|
||||
+ rtl821x_write_page(dev, RTL8211F_WOL_PAGE);
|
||||
__phy_write(dev, RTL8211F_WOL_SETTINGS_EVENTS, RTL8211F_WOL_EVENT_MAGIC);
|
||||
- __phy_write(dev, RTL8211F_WOL_SETTINGS_STATUS, RTL8211F_WOL_STATUS_RESET);
|
||||
-
|
||||
- /* Enable the WOL interrupt */
|
||||
- rtl821x_write_page(dev, RTL8211F_INTBCR_PAGE);
|
||||
- __phy_set_bits(dev, RTL8211F_INTBCR, RTL8211F_INTBCR_INTB_PMEB);
|
||||
+ /* Set the maximum packet size, and assert WoL reset */
|
||||
+ __phy_write(dev, RTL8211F_WOL_RST_RMSQ, RTL8211F_WOL_RMSQ);
|
||||
} else {
|
||||
- /* Disable the WOL interrupt */
|
||||
- rtl821x_write_page(dev, RTL8211F_INTBCR_PAGE);
|
||||
- __phy_clear_bits(dev, RTL8211F_INTBCR, RTL8211F_INTBCR_INTB_PMEB);
|
||||
-
|
||||
- /* Disable magic packet matching and reset WOL status */
|
||||
- rtl821x_write_page(dev, RTL8211F_WOL_SETTINGS_PAGE);
|
||||
+ /* Disable magic packet matching */
|
||||
+ rtl821x_write_page(dev, RTL8211F_WOL_PAGE);
|
||||
__phy_write(dev, RTL8211F_WOL_SETTINGS_EVENTS, 0);
|
||||
- __phy_write(dev, RTL8211F_WOL_SETTINGS_STATUS, RTL8211F_WOL_STATUS_RESET);
|
||||
+
|
||||
+ /* Place WoL in reset */
|
||||
+ __phy_clear_bits(dev, RTL8211F_WOL_RST_RMSQ,
|
||||
+ RTL8211F_WOL_RG_RSTB);
|
||||
}
|
||||
|
||||
+ device_set_wakeup_enable(&dev->mdio.dev, !!(wol->wolopts & WAKE_MAGIC));
|
||||
+
|
||||
err:
|
||||
return phy_restore_page(dev, oldpage, 0);
|
||||
}
|
||||
@@ -627,6 +671,52 @@ static int rtl821x_suspend(struct phy_de
|
||||
return ret;
|
||||
}
|
||||
|
||||
+static int rtl8211f_suspend(struct phy_device *phydev)
|
||||
+{
|
||||
+ u16 wol_rst;
|
||||
+ int ret;
|
||||
+
|
||||
+ ret = rtl821x_suspend(phydev);
|
||||
+ if (ret < 0)
|
||||
+ return ret;
|
||||
+
|
||||
+ /* If a PME event is enabled, then configure the interrupt for
|
||||
+ * PME events only, disabling link interrupt. We avoid switching
|
||||
+ * to PMEB mode as we don't have a status bit for that.
|
||||
+ */
|
||||
+ if (device_may_wakeup(&phydev->mdio.dev)) {
|
||||
+ ret = phy_write_paged(phydev, 0xa42, RTL821x_INER,
|
||||
+ RTL8211F_INER_PME);
|
||||
+ if (ret < 0)
|
||||
+ goto err;
|
||||
+
|
||||
+ /* Read the INSR to clear any pending interrupt */
|
||||
+ phy_read_paged(phydev, RTL8211F_INSR_PAGE, RTL8211F_INSR);
|
||||
+
|
||||
+ /* Reset the WoL to ensure that an event is picked up.
|
||||
+ * Unless we do this, even if we receive another packet,
|
||||
+ * we may not have a PME interrupt raised.
|
||||
+ */
|
||||
+ ret = phy_read_paged(phydev, RTL8211F_WOL_PAGE,
|
||||
+ RTL8211F_WOL_RST_RMSQ);
|
||||
+ if (ret < 0)
|
||||
+ goto err;
|
||||
+
|
||||
+ wol_rst = ret & ~RTL8211F_WOL_RG_RSTB;
|
||||
+ ret = phy_write_paged(phydev, RTL8211F_WOL_PAGE,
|
||||
+ RTL8211F_WOL_RST_RMSQ, wol_rst);
|
||||
+ if (ret < 0)
|
||||
+ goto err;
|
||||
+
|
||||
+ wol_rst |= RTL8211F_WOL_RG_RSTB;
|
||||
+ ret = phy_write_paged(phydev, RTL8211F_WOL_PAGE,
|
||||
+ RTL8211F_WOL_RST_RMSQ, wol_rst);
|
||||
+ }
|
||||
+
|
||||
+err:
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
static int rtl821x_resume(struct phy_device *phydev)
|
||||
{
|
||||
struct rtl821x_priv *priv = phydev->priv;
|
||||
@@ -644,6 +734,24 @@ static int rtl821x_resume(struct phy_dev
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static int rtl8211f_resume(struct phy_device *phydev)
|
||||
+{
|
||||
+ struct rtl821x_priv *priv = phydev->priv;
|
||||
+ int ret;
|
||||
+
|
||||
+ ret = rtl821x_resume(phydev);
|
||||
+ if (ret < 0)
|
||||
+ return ret;
|
||||
+
|
||||
+ /* If the device was programmed for a PME event, restore the interrupt
|
||||
+ * enable so phylib can receive link state interrupts.
|
||||
+ */
|
||||
+ if (device_may_wakeup(&phydev->mdio.dev))
|
||||
+ ret = phy_write_paged(phydev, 0xa42, RTL821x_INER, priv->iner);
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
static int rtl8211x_led_hw_is_supported(struct phy_device *phydev, u8 index,
|
||||
unsigned long rules)
|
||||
{
|
||||
@@ -1639,15 +1747,15 @@ static struct phy_driver realtek_drvs[]
|
||||
}, {
|
||||
PHY_ID_MATCH_EXACT(0x001cc916),
|
||||
.name = "RTL8211F Gigabit Ethernet",
|
||||
- .probe = rtl821x_probe,
|
||||
+ .probe = rtl8211f_probe,
|
||||
.config_init = &rtl8211f_config_init,
|
||||
.read_status = rtlgen_read_status,
|
||||
.config_intr = &rtl8211f_config_intr,
|
||||
.handle_interrupt = rtl8211f_handle_interrupt,
|
||||
.set_wol = rtl8211f_set_wol,
|
||||
.get_wol = rtl8211f_get_wol,
|
||||
- .suspend = rtl821x_suspend,
|
||||
- .resume = rtl821x_resume,
|
||||
+ .suspend = rtl8211f_suspend,
|
||||
+ .resume = rtl8211f_resume,
|
||||
.read_page = rtl821x_read_page,
|
||||
.write_page = rtl821x_write_page,
|
||||
.flags = PHY_ALWAYS_CALL_SUSPEND,
|
||||
@ -18,7 +18,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
|
||||
--- a/drivers/net/phy/realtek/realtek_main.c
|
||||
+++ b/drivers/net/phy/realtek/realtek_main.c
|
||||
@@ -156,7 +156,7 @@
|
||||
@@ -154,7 +154,7 @@
|
||||
#define RTL_8211FVD_PHYID 0x001cc878
|
||||
#define RTL_8221B 0x001cc840
|
||||
#define RTL_8221B_VB_CG 0x001cc849
|
||||
@ -27,7 +27,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
#define RTL_8251B 0x001cc862
|
||||
#define RTL_8261C 0x001cc890
|
||||
|
||||
@@ -1415,16 +1415,16 @@ static int rtl8221b_vb_cg_c45_match_phy_
|
||||
@@ -1498,16 +1498,16 @@ static int rtl8221b_vb_cg_c45_match_phy_
|
||||
return rtlgen_is_c45_match(phydev, RTL_8221B_VB_CG, true);
|
||||
}
|
||||
|
||||
@ -48,7 +48,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
}
|
||||
|
||||
static int rtl_internal_nbaset_match_phy_device(struct phy_device *phydev,
|
||||
@@ -1771,7 +1771,7 @@ static struct phy_driver realtek_drvs[]
|
||||
@@ -1854,7 +1854,7 @@ static struct phy_driver realtek_drvs[]
|
||||
.suspend = genphy_c45_pma_suspend,
|
||||
.resume = rtlgen_c45_resume,
|
||||
}, {
|
||||
@ -57,7 +57,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
.name = "RTL8221B-VM-CG 2.5Gbps PHY (C22)",
|
||||
.probe = rtl822x_probe,
|
||||
.get_features = rtl822x_get_features,
|
||||
@@ -1784,8 +1784,8 @@ static struct phy_driver realtek_drvs[]
|
||||
@@ -1867,8 +1867,8 @@ static struct phy_driver realtek_drvs[]
|
||||
.read_page = rtl821x_read_page,
|
||||
.write_page = rtl821x_write_page,
|
||||
}, {
|
||||
@ -19,7 +19,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
|
||||
--- a/drivers/net/phy/realtek/realtek_main.c
|
||||
+++ b/drivers/net/phy/realtek/realtek_main.c
|
||||
@@ -648,7 +648,8 @@ static int rtl821x_resume(struct phy_dev
|
||||
@@ -755,7 +755,8 @@ static int rtl8211f_resume(struct phy_de
|
||||
static int rtl8211x_led_hw_is_supported(struct phy_device *phydev, u8 index,
|
||||
unsigned long rules)
|
||||
{
|
||||
@ -29,7 +29,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
BIT(TRIGGER_NETDEV_LINK_100) |
|
||||
BIT(TRIGGER_NETDEV_LINK_1000) |
|
||||
BIT(TRIGGER_NETDEV_RX) |
|
||||
@@ -706,6 +707,12 @@ static int rtl8211f_led_hw_control_get(s
|
||||
@@ -813,6 +814,12 @@ static int rtl8211f_led_hw_control_get(s
|
||||
if (val & RTL8211F_LEDCR_LINK_1000)
|
||||
__set_bit(TRIGGER_NETDEV_LINK_1000, rules);
|
||||
|
||||
@ -42,7 +42,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
if (val & RTL8211F_LEDCR_ACT_TXRX) {
|
||||
__set_bit(TRIGGER_NETDEV_RX, rules);
|
||||
__set_bit(TRIGGER_NETDEV_TX, rules);
|
||||
@@ -723,14 +730,20 @@ static int rtl8211f_led_hw_control_set(s
|
||||
@@ -830,14 +837,20 @@ static int rtl8211f_led_hw_control_set(s
|
||||
if (index >= RTL8211x_LED_COUNT)
|
||||
return -EINVAL;
|
||||
|
||||
@ -66,7 +66,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
|
||||
if (test_bit(TRIGGER_NETDEV_RX, &rules) ||
|
||||
test_bit(TRIGGER_NETDEV_TX, &rules)) {
|
||||
@@ -778,6 +791,12 @@ static int rtl8211e_led_hw_control_get(s
|
||||
@@ -885,6 +898,12 @@ static int rtl8211e_led_hw_control_get(s
|
||||
if (cr2 & RTL8211E_LEDCR2_LINK_1000)
|
||||
__set_bit(TRIGGER_NETDEV_LINK_1000, rules);
|
||||
|
||||
@ -79,7 +79,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -805,14 +824,20 @@ static int rtl8211e_led_hw_control_set(s
|
||||
@@ -912,14 +931,20 @@ static int rtl8211e_led_hw_control_set(s
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
@ -57,8 +57,8 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
+#include <linux/ethtool_netlink.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/phy.h>
|
||||
#include <linux/netdevice.h>
|
||||
@@ -129,6 +130,27 @@
|
||||
#include <linux/pm_wakeirq.h>
|
||||
@@ -127,6 +128,27 @@
|
||||
*/
|
||||
#define RTL822X_VND2_C22_REG(reg) (0xa400 + 2 * (reg))
|
||||
|
||||
@ -86,7 +86,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
#define RTL8366RB_POWER_SAVE 0x15
|
||||
#define RTL8366RB_POWER_SAVE_ON BIT(12)
|
||||
|
||||
@@ -1345,6 +1367,168 @@ static int rtl822xb_c45_read_status(stru
|
||||
@@ -1453,6 +1475,168 @@ static int rtl822xb_c45_read_status(stru
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -255,7 +255,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
static bool rtlgen_supports_2_5gbps(struct phy_device *phydev)
|
||||
{
|
||||
int val;
|
||||
@@ -1822,11 +2006,14 @@ static struct phy_driver realtek_drvs[]
|
||||
@@ -1930,11 +2114,14 @@ static struct phy_driver realtek_drvs[]
|
||||
}, {
|
||||
PHY_ID_MATCH_EXACT(0x001ccad0),
|
||||
.name = "RTL8224 2.5Gbps PHY",
|
||||
@ -19,7 +19,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
|
||||
--- a/drivers/net/phy/realtek/realtek_main.c
|
||||
+++ b/drivers/net/phy/realtek/realtek_main.c
|
||||
@@ -130,6 +130,11 @@
|
||||
@@ -128,6 +128,11 @@
|
||||
*/
|
||||
#define RTL822X_VND2_C22_REG(reg) (0xa400 + 2 * (reg))
|
||||
|
||||
@ -31,7 +31,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
#define RTL8224_MII_RTCT 0x11
|
||||
#define RTL8224_MII_RTCT_ENABLE BIT(0)
|
||||
#define RTL8224_MII_RTCT_PAIR_A BIT(4)
|
||||
@@ -1772,6 +1777,53 @@ static irqreturn_t rtl9000a_handle_inter
|
||||
@@ -1880,6 +1885,53 @@ static irqreturn_t rtl9000a_handle_inter
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
@ -85,7 +85,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
static struct phy_driver realtek_drvs[] = {
|
||||
{
|
||||
PHY_ID_MATCH_EXACT(0x00008201),
|
||||
@@ -1946,6 +1998,8 @@ static struct phy_driver realtek_drvs[]
|
||||
@@ -2054,6 +2106,8 @@ static struct phy_driver realtek_drvs[]
|
||||
}, {
|
||||
.match_phy_device = rtl8221b_vb_cg_c45_match_phy_device,
|
||||
.name = "RTL8221B-VB-CG 2.5Gbps PHY (C45)",
|
||||
@ -94,7 +94,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
.probe = rtl822x_probe,
|
||||
.config_init = rtl822xb_config_init,
|
||||
.get_rate_matching = rtl822xb_get_rate_matching,
|
||||
@@ -1970,6 +2024,8 @@ static struct phy_driver realtek_drvs[]
|
||||
@@ -2078,6 +2132,8 @@ static struct phy_driver realtek_drvs[]
|
||||
}, {
|
||||
.match_phy_device = rtl8221b_vm_cg_c45_match_phy_device,
|
||||
.name = "RTL8221B-VM-CG 2.5Gbps PHY (C45)",
|
||||
@ -0,0 +1,128 @@
|
||||
From 8e982441ba601d982dd0739972115d85ae01d99b Mon Sep 17 00:00:00 2001
|
||||
From: Vladimir Oltean <vladimir.oltean@nxp.com>
|
||||
Date: Tue, 18 Nov 2025 01:40:28 +0200
|
||||
Subject: [PATCH] net: phy: realtek: create rtl8211f_config_rgmii_delay()
|
||||
|
||||
The control flow in rtl8211f_config_init() has some pitfalls which were
|
||||
probably unintended. Specifically it has an early return:
|
||||
|
||||
switch (phydev->interface) {
|
||||
...
|
||||
default: /* the rest of the modes imply leaving delay as is. */
|
||||
return 0;
|
||||
}
|
||||
|
||||
which exits the entire config_init() function. This means it also skips
|
||||
doing things such as disabling CLKOUT or disabling PHY-mode EEE.
|
||||
|
||||
For the RTL8211FS, which uses PHY_INTERFACE_MODE_SGMII, this might be a
|
||||
problem. However, I don't know that it is, so there is no Fixes: tag.
|
||||
The issue was observed through code inspection.
|
||||
|
||||
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
|
||||
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
|
||||
Link: https://patch.msgid.link/20251117234033.345679-2-vladimir.oltean@nxp.com
|
||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
---
|
||||
drivers/net/phy/realtek/realtek_main.c | 65 +++++++++++++++-----------
|
||||
1 file changed, 39 insertions(+), 26 deletions(-)
|
||||
|
||||
--- a/drivers/net/phy/realtek/realtek_main.c
|
||||
+++ b/drivers/net/phy/realtek/realtek_main.c
|
||||
@@ -587,22 +587,11 @@ static int rtl8211c_config_init(struct p
|
||||
CTL1000_ENABLE_MASTER | CTL1000_AS_MASTER);
|
||||
}
|
||||
|
||||
-static int rtl8211f_config_init(struct phy_device *phydev)
|
||||
+static int rtl8211f_config_rgmii_delay(struct phy_device *phydev)
|
||||
{
|
||||
- struct rtl821x_priv *priv = phydev->priv;
|
||||
- struct device *dev = &phydev->mdio.dev;
|
||||
u16 val_txdly, val_rxdly;
|
||||
int ret;
|
||||
|
||||
- ret = phy_modify_paged_changed(phydev, RTL8211F_PHYCR_PAGE, RTL8211F_PHYCR1,
|
||||
- RTL8211F_ALDPS_PLL_OFF | RTL8211F_ALDPS_ENABLE | RTL8211F_ALDPS_XTAL_OFF,
|
||||
- priv->phycr1);
|
||||
- if (ret < 0) {
|
||||
- dev_err(dev, "aldps mode configuration failed: %pe\n",
|
||||
- ERR_PTR(ret));
|
||||
- return ret;
|
||||
- }
|
||||
-
|
||||
switch (phydev->interface) {
|
||||
case PHY_INTERFACE_MODE_RGMII:
|
||||
val_txdly = 0;
|
||||
@@ -632,34 +621,58 @@ static int rtl8211f_config_init(struct p
|
||||
RTL8211F_TXCR, RTL8211F_TX_DELAY,
|
||||
val_txdly);
|
||||
if (ret < 0) {
|
||||
- dev_err(dev, "Failed to update the TX delay register\n");
|
||||
+ phydev_err(phydev, "Failed to update the TX delay register: %pe\n",
|
||||
+ ERR_PTR(ret));
|
||||
return ret;
|
||||
} else if (ret) {
|
||||
- dev_dbg(dev,
|
||||
- "%s 2ns TX delay (and changing the value from pin-strapping RXD1 or the bootloader)\n",
|
||||
- str_enable_disable(val_txdly));
|
||||
+ phydev_dbg(phydev,
|
||||
+ "%s 2ns TX delay (and changing the value from pin-strapping RXD1 or the bootloader)\n",
|
||||
+ str_enable_disable(val_txdly));
|
||||
} else {
|
||||
- dev_dbg(dev,
|
||||
- "2ns TX delay was already %s (by pin-strapping RXD1 or bootloader configuration)\n",
|
||||
- str_enabled_disabled(val_txdly));
|
||||
+ phydev_dbg(phydev,
|
||||
+ "2ns TX delay was already %s (by pin-strapping RXD1 or bootloader configuration)\n",
|
||||
+ str_enabled_disabled(val_txdly));
|
||||
}
|
||||
|
||||
ret = phy_modify_paged_changed(phydev, RTL8211F_RGMII_PAGE,
|
||||
RTL8211F_RXCR, RTL8211F_RX_DELAY,
|
||||
val_rxdly);
|
||||
if (ret < 0) {
|
||||
- dev_err(dev, "Failed to update the RX delay register\n");
|
||||
+ phydev_err(phydev, "Failed to update the RX delay register: %pe\n",
|
||||
+ ERR_PTR(ret));
|
||||
return ret;
|
||||
} else if (ret) {
|
||||
- dev_dbg(dev,
|
||||
- "%s 2ns RX delay (and changing the value from pin-strapping RXD0 or the bootloader)\n",
|
||||
- str_enable_disable(val_rxdly));
|
||||
+ phydev_dbg(phydev,
|
||||
+ "%s 2ns RX delay (and changing the value from pin-strapping RXD0 or the bootloader)\n",
|
||||
+ str_enable_disable(val_rxdly));
|
||||
} else {
|
||||
- dev_dbg(dev,
|
||||
- "2ns RX delay was already %s (by pin-strapping RXD0 or bootloader configuration)\n",
|
||||
- str_enabled_disabled(val_rxdly));
|
||||
+ phydev_dbg(phydev,
|
||||
+ "2ns RX delay was already %s (by pin-strapping RXD0 or bootloader configuration)\n",
|
||||
+ str_enabled_disabled(val_rxdly));
|
||||
}
|
||||
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int rtl8211f_config_init(struct phy_device *phydev)
|
||||
+{
|
||||
+ struct rtl821x_priv *priv = phydev->priv;
|
||||
+ struct device *dev = &phydev->mdio.dev;
|
||||
+ int ret;
|
||||
+
|
||||
+ ret = phy_modify_paged_changed(phydev, RTL8211F_PHYCR_PAGE, RTL8211F_PHYCR1,
|
||||
+ RTL8211F_ALDPS_PLL_OFF | RTL8211F_ALDPS_ENABLE | RTL8211F_ALDPS_XTAL_OFF,
|
||||
+ priv->phycr1);
|
||||
+ if (ret < 0) {
|
||||
+ dev_err(dev, "aldps mode configuration failed: %pe\n",
|
||||
+ ERR_PTR(ret));
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ ret = rtl8211f_config_rgmii_delay(phydev);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
if (!priv->has_phycr2)
|
||||
return 0;
|
||||
|
||||
@ -0,0 +1,101 @@
|
||||
From 27033d06917758d47162581da7e9de8004049dee Mon Sep 17 00:00:00 2001
|
||||
From: Vladimir Oltean <vladimir.oltean@nxp.com>
|
||||
Date: Tue, 18 Nov 2025 01:40:29 +0200
|
||||
Subject: [PATCH] net: phy: realtek: eliminate priv->phycr2 variable
|
||||
|
||||
The RTL8211F(D)(I)-VD-CG PHY also has support for disabling the CLKOUT,
|
||||
and we'd like to introduce the "realtek,clkout-disable" property for
|
||||
that.
|
||||
|
||||
But it isn't done through the PHYCR2 register, and it becomes awkward to
|
||||
have the driver pretend that it is. So just replace the machine-level
|
||||
"u16 phycr2" variable with a logical "bool disable_clk_out", which
|
||||
scales better to the other PHY as well.
|
||||
|
||||
The change is a complete functional equivalent. Before, if the device
|
||||
tree property was absent, priv->phycr2 would contain the RTL8211F_CLKOUT_EN
|
||||
bit as read from hardware. Now, we don't save priv->phycr2, but we just
|
||||
don't call phy_modify_paged() on it. Also, we can simply call
|
||||
phy_modify_paged() with the "set" argument to 0.
|
||||
|
||||
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
|
||||
Link: https://patch.msgid.link/20251117234033.345679-3-vladimir.oltean@nxp.com
|
||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
---
|
||||
drivers/net/phy/realtek/realtek_main.c | 38 ++++++++++++++++----------
|
||||
1 file changed, 23 insertions(+), 15 deletions(-)
|
||||
|
||||
--- a/drivers/net/phy/realtek/realtek_main.c
|
||||
+++ b/drivers/net/phy/realtek/realtek_main.c
|
||||
@@ -194,8 +194,8 @@ MODULE_LICENSE("GPL");
|
||||
|
||||
struct rtl821x_priv {
|
||||
u16 phycr1;
|
||||
- u16 phycr2;
|
||||
bool has_phycr2;
|
||||
+ bool disable_clk_out;
|
||||
struct clk *clk;
|
||||
/* rtl8211f */
|
||||
u16 iner;
|
||||
@@ -266,15 +266,8 @@ static int rtl821x_probe(struct phy_devi
|
||||
priv->phycr1 |= RTL8211F_ALDPS_PLL_OFF | RTL8211F_ALDPS_ENABLE | RTL8211F_ALDPS_XTAL_OFF;
|
||||
|
||||
priv->has_phycr2 = !(phy_id == RTL_8211FVD_PHYID);
|
||||
- if (priv->has_phycr2) {
|
||||
- ret = phy_read_paged(phydev, RTL8211F_PHYCR_PAGE, RTL8211F_PHYCR2);
|
||||
- if (ret < 0)
|
||||
- return ret;
|
||||
-
|
||||
- priv->phycr2 = ret & RTL8211F_CLKOUT_EN;
|
||||
- if (of_property_read_bool(dev->of_node, "realtek,clkout-disable"))
|
||||
- priv->phycr2 &= ~RTL8211F_CLKOUT_EN;
|
||||
- }
|
||||
+ priv->disable_clk_out = of_property_read_bool(dev->of_node,
|
||||
+ "realtek,clkout-disable");
|
||||
|
||||
phydev->priv = priv;
|
||||
|
||||
@@ -654,6 +647,23 @@ static int rtl8211f_config_rgmii_delay(s
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static int rtl8211f_config_clk_out(struct phy_device *phydev)
|
||||
+{
|
||||
+ struct rtl821x_priv *priv = phydev->priv;
|
||||
+ int ret;
|
||||
+
|
||||
+ /* The value is preserved if the device tree property is absent */
|
||||
+ if (!priv->disable_clk_out)
|
||||
+ return 0;
|
||||
+
|
||||
+ ret = phy_modify_paged(phydev, RTL8211F_PHYCR_PAGE,
|
||||
+ RTL8211F_PHYCR2, RTL8211F_CLKOUT_EN, 0);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ return genphy_soft_reset(phydev);
|
||||
+}
|
||||
+
|
||||
static int rtl8211f_config_init(struct phy_device *phydev)
|
||||
{
|
||||
struct rtl821x_priv *priv = phydev->priv;
|
||||
@@ -682,16 +692,14 @@ static int rtl8211f_config_init(struct p
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
- ret = phy_modify_paged(phydev, RTL8211F_PHYCR_PAGE,
|
||||
- RTL8211F_PHYCR2, RTL8211F_CLKOUT_EN,
|
||||
- priv->phycr2);
|
||||
- if (ret < 0) {
|
||||
+ ret = rtl8211f_config_clk_out(phydev);
|
||||
+ if (ret) {
|
||||
dev_err(dev, "clkout configuration failed: %pe\n",
|
||||
ERR_PTR(ret));
|
||||
return ret;
|
||||
}
|
||||
|
||||
- return genphy_soft_reset(phydev);
|
||||
+ return 0;
|
||||
}
|
||||
|
||||
static int rtl821x_suspend(struct phy_device *phydev)
|
||||
@ -0,0 +1,55 @@
|
||||
From 910ac7bfb1af1ae4cd141ef80e03a6729213c189 Mon Sep 17 00:00:00 2001
|
||||
From: Vladimir Oltean <vladimir.oltean@nxp.com>
|
||||
Date: Tue, 18 Nov 2025 01:40:30 +0200
|
||||
Subject: [PATCH] net: phy: realtek: eliminate has_phycr2 variable
|
||||
|
||||
This variable is assigned in rtl821x_probe() and used in
|
||||
rtl8211f_config_init(), which is more complex than it needs to be.
|
||||
Simply testing the same condition from rtl821x_probe() in
|
||||
rtl8211f_config_init() yields the same result (the PHY driver ID is a
|
||||
runtime invariant), but with one temporary variable less.
|
||||
|
||||
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
|
||||
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
|
||||
Link: https://patch.msgid.link/20251117234033.345679-4-vladimir.oltean@nxp.com
|
||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
---
|
||||
drivers/net/phy/realtek/realtek_main.c | 6 ++----
|
||||
1 file changed, 2 insertions(+), 4 deletions(-)
|
||||
|
||||
--- a/drivers/net/phy/realtek/realtek_main.c
|
||||
+++ b/drivers/net/phy/realtek/realtek_main.c
|
||||
@@ -194,7 +194,6 @@ MODULE_LICENSE("GPL");
|
||||
|
||||
struct rtl821x_priv {
|
||||
u16 phycr1;
|
||||
- bool has_phycr2;
|
||||
bool disable_clk_out;
|
||||
struct clk *clk;
|
||||
/* rtl8211f */
|
||||
@@ -245,7 +244,6 @@ static int rtl821x_probe(struct phy_devi
|
||||
{
|
||||
struct device *dev = &phydev->mdio.dev;
|
||||
struct rtl821x_priv *priv;
|
||||
- u32 phy_id = phydev->drv->phy_id;
|
||||
int ret;
|
||||
|
||||
priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
|
||||
@@ -265,7 +263,6 @@ static int rtl821x_probe(struct phy_devi
|
||||
if (of_property_read_bool(dev->of_node, "realtek,aldps-enable"))
|
||||
priv->phycr1 |= RTL8211F_ALDPS_PLL_OFF | RTL8211F_ALDPS_ENABLE | RTL8211F_ALDPS_XTAL_OFF;
|
||||
|
||||
- priv->has_phycr2 = !(phy_id == RTL_8211FVD_PHYID);
|
||||
priv->disable_clk_out = of_property_read_bool(dev->of_node,
|
||||
"realtek,clkout-disable");
|
||||
|
||||
@@ -683,7 +680,8 @@ static int rtl8211f_config_init(struct p
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
- if (!priv->has_phycr2)
|
||||
+ /* RTL8211FVD has no PHYCR2 register */
|
||||
+ if (phydev->drv->phy_id == RTL_8211FVD_PHYID)
|
||||
return 0;
|
||||
|
||||
/* Disable PHY-mode EEE so LPI is passed to the MAC */
|
||||
@ -0,0 +1,101 @@
|
||||
From e1a31c41bef678afe0d99b7f0dc3711a80c68447 Mon Sep 17 00:00:00 2001
|
||||
From: Vladimir Oltean <vladimir.oltean@nxp.com>
|
||||
Date: Tue, 18 Nov 2025 01:40:31 +0200
|
||||
Subject: [PATCH] net: phy: realtek: allow CLKOUT to be disabled on
|
||||
RTL8211F(D)(I)-VD-CG
|
||||
|
||||
Add CLKOUT disable support for RTL8211F(D)(I)-VD-CG. Like with other PHY
|
||||
variants, this feature might be requested by customers when the clock
|
||||
output is not used, in order to reduce electromagnetic interference (EMI).
|
||||
|
||||
In the common driver, the CLKOUT configuration is done through PHYCR2.
|
||||
The RTL_8211FVD_PHYID is singled out as not having that register, and
|
||||
execution in rtl8211f_config_init() returns early after commit
|
||||
2c67301584f2 ("net: phy: realtek: Avoid PHYCR2 access if PHYCR2 not
|
||||
present").
|
||||
|
||||
But actually CLKOUT is configured through a different register for this
|
||||
PHY. Instead of pretending this is PHYCR2 (which it is not), just add
|
||||
some code for modifying this register inside the rtl8211f_disable_clk_out()
|
||||
function, and move that outside the code portion that runs only if
|
||||
PHYCR2 exists.
|
||||
|
||||
In practice this reorders the PHYCR2 writes to disable PHY-mode EEE and
|
||||
to disable the CLKOUT for the normal RTL8211F variants, but this should
|
||||
be perfectly fine.
|
||||
|
||||
It was not noted that RTL8211F(D)(I)-VD-CG would need a genphy_soft_reset()
|
||||
call after disabling the CLKOUT. Despite that, we do it out of caution
|
||||
and for symmetry with the other RTL8211F models.
|
||||
|
||||
Co-developed-by: Clark Wang <xiaoning.wang@nxp.com>
|
||||
Signed-off-by: Clark Wang <xiaoning.wang@nxp.com>
|
||||
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
|
||||
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
|
||||
Link: https://patch.msgid.link/20251117234033.345679-5-vladimir.oltean@nxp.com
|
||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
---
|
||||
drivers/net/phy/realtek/realtek_main.c | 31 ++++++++++++++++++--------
|
||||
1 file changed, 22 insertions(+), 9 deletions(-)
|
||||
|
||||
--- a/drivers/net/phy/realtek/realtek_main.c
|
||||
+++ b/drivers/net/phy/realtek/realtek_main.c
|
||||
@@ -90,6 +90,14 @@
|
||||
#define RTL8211F_LEDCR_MASK GENMASK(4, 0)
|
||||
#define RTL8211F_LEDCR_SHIFT 5
|
||||
|
||||
+/* RTL8211F(D)(I)-VD-CG CLKOUT configuration is specified via magic values
|
||||
+ * to undocumented register pages. The names here do not reflect the datasheet.
|
||||
+ * Unlike other PHY models, CLKOUT configuration does not go through PHYCR2.
|
||||
+ */
|
||||
+#define RTL8211FVD_CLKOUT_PAGE 0xd05
|
||||
+#define RTL8211FVD_CLKOUT_REG 0x11
|
||||
+#define RTL8211FVD_CLKOUT_EN BIT(8)
|
||||
+
|
||||
/* RTL8211F RGMII configuration */
|
||||
#define RTL8211F_RGMII_PAGE 0xd08
|
||||
|
||||
@@ -653,8 +661,13 @@ static int rtl8211f_config_clk_out(struc
|
||||
if (!priv->disable_clk_out)
|
||||
return 0;
|
||||
|
||||
- ret = phy_modify_paged(phydev, RTL8211F_PHYCR_PAGE,
|
||||
- RTL8211F_PHYCR2, RTL8211F_CLKOUT_EN, 0);
|
||||
+ if (phydev->drv->phy_id == RTL_8211FVD_PHYID)
|
||||
+ ret = phy_modify_paged(phydev, RTL8211FVD_CLKOUT_PAGE,
|
||||
+ RTL8211FVD_CLKOUT_REG,
|
||||
+ RTL8211FVD_CLKOUT_EN, 0);
|
||||
+ else
|
||||
+ ret = phy_modify_paged(phydev, RTL8211F_PHYCR_PAGE,
|
||||
+ RTL8211F_PHYCR2, RTL8211F_CLKOUT_EN, 0);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
@@ -680,6 +693,13 @@ static int rtl8211f_config_init(struct p
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
+ ret = rtl8211f_config_clk_out(phydev);
|
||||
+ if (ret) {
|
||||
+ dev_err(dev, "clkout configuration failed: %pe\n",
|
||||
+ ERR_PTR(ret));
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
/* RTL8211FVD has no PHYCR2 register */
|
||||
if (phydev->drv->phy_id == RTL_8211FVD_PHYID)
|
||||
return 0;
|
||||
@@ -690,13 +710,6 @@ static int rtl8211f_config_init(struct p
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
- ret = rtl8211f_config_clk_out(phydev);
|
||||
- if (ret) {
|
||||
- dev_err(dev, "clkout configuration failed: %pe\n",
|
||||
- ERR_PTR(ret));
|
||||
- return ret;
|
||||
- }
|
||||
-
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -0,0 +1,107 @@
|
||||
From bb78b71faf60d11a15f07e3390fcfd31e5e523bb Mon Sep 17 00:00:00 2001
|
||||
From: Vladimir Oltean <vladimir.oltean@nxp.com>
|
||||
Date: Tue, 18 Nov 2025 01:40:32 +0200
|
||||
Subject: [PATCH] net: phy: realtek: eliminate priv->phycr1 variable
|
||||
|
||||
Previous changes have replaced the machine-level priv->phycr2 with a
|
||||
high-level priv->disable_clk_out. This created a discrepancy with
|
||||
priv->phycr1 which is resolved here, for uniformity.
|
||||
|
||||
One advantage of this new implementation is that we don't read
|
||||
priv->phycr1 in rtl821x_probe() if we're never going to modify it.
|
||||
|
||||
We never test the positive return code from phy_modify_mmd_changed(), so
|
||||
we could just as well use phy_modify_mmd().
|
||||
|
||||
I took the ALDPS feature description from commit d90db36a9e74 ("net:
|
||||
phy: realtek: add dt property to enable ALDPS mode") and transformed it
|
||||
into a function comment - the feature is sufficiently non-obvious to
|
||||
deserve that.
|
||||
|
||||
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
|
||||
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
|
||||
Link: https://patch.msgid.link/20251117234033.345679-6-vladimir.oltean@nxp.com
|
||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
---
|
||||
drivers/net/phy/realtek/realtek_main.c | 44 ++++++++++++++++----------
|
||||
1 file changed, 28 insertions(+), 16 deletions(-)
|
||||
|
||||
--- a/drivers/net/phy/realtek/realtek_main.c
|
||||
+++ b/drivers/net/phy/realtek/realtek_main.c
|
||||
@@ -201,7 +201,7 @@ MODULE_AUTHOR("Johnson Leung");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
||||
struct rtl821x_priv {
|
||||
- u16 phycr1;
|
||||
+ bool enable_aldps;
|
||||
bool disable_clk_out;
|
||||
struct clk *clk;
|
||||
/* rtl8211f */
|
||||
@@ -252,7 +252,6 @@ static int rtl821x_probe(struct phy_devi
|
||||
{
|
||||
struct device *dev = &phydev->mdio.dev;
|
||||
struct rtl821x_priv *priv;
|
||||
- int ret;
|
||||
|
||||
priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
|
||||
if (!priv)
|
||||
@@ -263,14 +262,8 @@ static int rtl821x_probe(struct phy_devi
|
||||
return dev_err_probe(dev, PTR_ERR(priv->clk),
|
||||
"failed to get phy clock\n");
|
||||
|
||||
- ret = phy_read_paged(phydev, RTL8211F_PHYCR_PAGE, RTL8211F_PHYCR1);
|
||||
- if (ret < 0)
|
||||
- return ret;
|
||||
-
|
||||
- priv->phycr1 = ret & (RTL8211F_ALDPS_PLL_OFF | RTL8211F_ALDPS_ENABLE | RTL8211F_ALDPS_XTAL_OFF);
|
||||
- if (of_property_read_bool(dev->of_node, "realtek,aldps-enable"))
|
||||
- priv->phycr1 |= RTL8211F_ALDPS_PLL_OFF | RTL8211F_ALDPS_ENABLE | RTL8211F_ALDPS_XTAL_OFF;
|
||||
-
|
||||
+ priv->enable_aldps = of_property_read_bool(dev->of_node,
|
||||
+ "realtek,aldps-enable");
|
||||
priv->disable_clk_out = of_property_read_bool(dev->of_node,
|
||||
"realtek,clkout-disable");
|
||||
|
||||
@@ -674,17 +667,36 @@ static int rtl8211f_config_clk_out(struc
|
||||
return genphy_soft_reset(phydev);
|
||||
}
|
||||
|
||||
-static int rtl8211f_config_init(struct phy_device *phydev)
|
||||
+/* Advance Link Down Power Saving (ALDPS) mode changes crystal/clock behaviour,
|
||||
+ * which causes the RXC clock signal to stop for tens to hundreds of
|
||||
+ * milliseconds.
|
||||
+ *
|
||||
+ * Some MACs need the RXC clock to support their internal RX logic, so ALDPS is
|
||||
+ * only enabled based on an opt-in device tree property.
|
||||
+ */
|
||||
+static int rtl8211f_config_aldps(struct phy_device *phydev)
|
||||
{
|
||||
struct rtl821x_priv *priv = phydev->priv;
|
||||
+ u16 mask = RTL8211F_ALDPS_PLL_OFF |
|
||||
+ RTL8211F_ALDPS_ENABLE |
|
||||
+ RTL8211F_ALDPS_XTAL_OFF;
|
||||
+
|
||||
+ /* The value is preserved if the device tree property is absent */
|
||||
+ if (!priv->enable_aldps)
|
||||
+ return 0;
|
||||
+
|
||||
+ return phy_modify_paged(phydev, RTL8211F_PHYCR_PAGE, RTL8211F_PHYCR1,
|
||||
+ mask, mask);
|
||||
+}
|
||||
+
|
||||
+static int rtl8211f_config_init(struct phy_device *phydev)
|
||||
+{
|
||||
struct device *dev = &phydev->mdio.dev;
|
||||
int ret;
|
||||
|
||||
- ret = phy_modify_paged_changed(phydev, RTL8211F_PHYCR_PAGE, RTL8211F_PHYCR1,
|
||||
- RTL8211F_ALDPS_PLL_OFF | RTL8211F_ALDPS_ENABLE | RTL8211F_ALDPS_XTAL_OFF,
|
||||
- priv->phycr1);
|
||||
- if (ret < 0) {
|
||||
- dev_err(dev, "aldps mode configuration failed: %pe\n",
|
||||
+ ret = rtl8211f_config_aldps(phydev);
|
||||
+ if (ret) {
|
||||
+ dev_err(dev, "aldps mode configuration failed: %pe\n",
|
||||
ERR_PTR(ret));
|
||||
return ret;
|
||||
}
|
||||
@ -0,0 +1,58 @@
|
||||
From 4465ae435ddc0162d5033a543658449d53d46d08 Mon Sep 17 00:00:00 2001
|
||||
From: Vladimir Oltean <vladimir.oltean@nxp.com>
|
||||
Date: Tue, 18 Nov 2025 01:40:33 +0200
|
||||
Subject: [PATCH] net: phy: realtek: create rtl8211f_config_phy_eee() helper
|
||||
|
||||
To simplify the rtl8211f_config_init() control flow and get rid of
|
||||
"early" returns for PHYs where the PHYCR2 register is absent, move the
|
||||
entire logic sub-block that deals with disabling PHY-mode EEE to a
|
||||
separate function. There, it is much more obvious what the early
|
||||
"return 0" skips, and it becomes more difficult to accidentally skip
|
||||
unintended stuff.
|
||||
|
||||
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
|
||||
Link: https://patch.msgid.link/20251117234033.345679-7-vladimir.oltean@nxp.com
|
||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
---
|
||||
drivers/net/phy/realtek/realtek_main.c | 23 ++++++++++++-----------
|
||||
1 file changed, 12 insertions(+), 11 deletions(-)
|
||||
|
||||
--- a/drivers/net/phy/realtek/realtek_main.c
|
||||
+++ b/drivers/net/phy/realtek/realtek_main.c
|
||||
@@ -689,6 +689,17 @@ static int rtl8211f_config_aldps(struct
|
||||
mask, mask);
|
||||
}
|
||||
|
||||
+static int rtl8211f_config_phy_eee(struct phy_device *phydev)
|
||||
+{
|
||||
+ /* RTL8211FVD has no PHYCR2 register */
|
||||
+ if (phydev->drv->phy_id == RTL_8211FVD_PHYID)
|
||||
+ return 0;
|
||||
+
|
||||
+ /* Disable PHY-mode EEE so LPI is passed to the MAC */
|
||||
+ return phy_modify_paged(phydev, RTL8211F_PHYCR_PAGE, RTL8211F_PHYCR2,
|
||||
+ RTL8211F_PHYCR2_PHY_EEE_ENABLE, 0);
|
||||
+}
|
||||
+
|
||||
static int rtl8211f_config_init(struct phy_device *phydev)
|
||||
{
|
||||
struct device *dev = &phydev->mdio.dev;
|
||||
@@ -712,17 +723,7 @@ static int rtl8211f_config_init(struct p
|
||||
return ret;
|
||||
}
|
||||
|
||||
- /* RTL8211FVD has no PHYCR2 register */
|
||||
- if (phydev->drv->phy_id == RTL_8211FVD_PHYID)
|
||||
- return 0;
|
||||
-
|
||||
- /* Disable PHY-mode EEE so LPI is passed to the MAC */
|
||||
- ret = phy_modify_paged(phydev, RTL8211F_PHYCR_PAGE, RTL8211F_PHYCR2,
|
||||
- RTL8211F_PHYCR2_PHY_EEE_ENABLE, 0);
|
||||
- if (ret)
|
||||
- return ret;
|
||||
-
|
||||
- return 0;
|
||||
+ return rtl8211f_config_phy_eee(phydev);
|
||||
}
|
||||
|
||||
static int rtl821x_suspend(struct phy_device *phydev)
|
||||
@ -15,7 +15,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
|
||||
--- a/drivers/net/phy/realtek/realtek_main.c
|
||||
+++ b/drivers/net/phy/realtek/realtek_main.c
|
||||
@@ -1941,6 +1941,7 @@ static struct phy_driver realtek_drvs[]
|
||||
@@ -2094,6 +2094,7 @@ static struct phy_driver realtek_drvs[]
|
||||
}, {
|
||||
.name = "RTL8226 2.5Gbps PHY",
|
||||
.match_phy_device = rtl8226_match_phy_device,
|
||||
@ -23,7 +23,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
.get_features = rtl822x_get_features,
|
||||
.config_aneg = rtl822x_config_aneg,
|
||||
.read_status = rtl822x_read_status,
|
||||
@@ -1951,6 +1952,7 @@ static struct phy_driver realtek_drvs[]
|
||||
@@ -2104,6 +2105,7 @@ static struct phy_driver realtek_drvs[]
|
||||
}, {
|
||||
.match_phy_device = rtl8221b_match_phy_device,
|
||||
.name = "RTL8226B_RTL8221B 2.5Gbps PHY",
|
||||
@ -31,7 +31,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
.get_features = rtl822x_get_features,
|
||||
.config_aneg = rtl822x_config_aneg,
|
||||
.config_init = rtl822xb_config_init,
|
||||
@@ -1973,6 +1975,7 @@ static struct phy_driver realtek_drvs[]
|
||||
@@ -2126,6 +2128,7 @@ static struct phy_driver realtek_drvs[]
|
||||
}, {
|
||||
PHY_ID_MATCH_EXACT(0x001cc848),
|
||||
.name = "RTL8226B-CG_RTL8221B-CG 2.5Gbps PHY",
|
||||
@ -39,7 +39,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
.get_features = rtl822x_get_features,
|
||||
.config_aneg = rtl822x_config_aneg,
|
||||
.config_init = rtl822xb_config_init,
|
||||
@@ -1985,6 +1988,7 @@ static struct phy_driver realtek_drvs[]
|
||||
@@ -2138,6 +2141,7 @@ static struct phy_driver realtek_drvs[]
|
||||
}, {
|
||||
.match_phy_device = rtl8221b_vb_cg_c22_match_phy_device,
|
||||
.name = "RTL8221B-VB-CG 2.5Gbps PHY (C22)",
|
||||
@ -47,7 +47,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
.probe = rtl822x_probe,
|
||||
.get_features = rtl822x_get_features,
|
||||
.config_aneg = rtl822x_config_aneg,
|
||||
@@ -2000,6 +2004,7 @@ static struct phy_driver realtek_drvs[]
|
||||
@@ -2153,6 +2157,7 @@ static struct phy_driver realtek_drvs[]
|
||||
.name = "RTL8221B-VB-CG 2.5Gbps PHY (C45)",
|
||||
.config_intr = rtl8221b_config_intr,
|
||||
.handle_interrupt = rtl8221b_handle_interrupt,
|
||||
@ -55,7 +55,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
.probe = rtl822x_probe,
|
||||
.config_init = rtl822xb_config_init,
|
||||
.get_rate_matching = rtl822xb_get_rate_matching,
|
||||
@@ -2011,6 +2016,7 @@ static struct phy_driver realtek_drvs[]
|
||||
@@ -2164,6 +2169,7 @@ static struct phy_driver realtek_drvs[]
|
||||
}, {
|
||||
.match_phy_device = rtl8221b_vm_cg_c22_match_phy_device,
|
||||
.name = "RTL8221B-VM-CG 2.5Gbps PHY (C22)",
|
||||
@ -63,7 +63,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
.probe = rtl822x_probe,
|
||||
.get_features = rtl822x_get_features,
|
||||
.config_aneg = rtl822x_config_aneg,
|
||||
@@ -2026,6 +2032,7 @@ static struct phy_driver realtek_drvs[]
|
||||
@@ -2179,6 +2185,7 @@ static struct phy_driver realtek_drvs[]
|
||||
.name = "RTL8221B-VM-CG 2.5Gbps PHY (C45)",
|
||||
.config_intr = rtl8221b_config_intr,
|
||||
.handle_interrupt = rtl8221b_handle_interrupt,
|
||||
|
||||
@ -20,7 +20,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
|
||||
--- a/drivers/net/phy/realtek/realtek_main.c
|
||||
+++ b/drivers/net/phy/realtek/realtek_main.c
|
||||
@@ -1092,8 +1092,8 @@ static int rtl822x_probe(struct phy_devi
|
||||
@@ -1245,8 +1245,8 @@ static int rtl822x_probe(struct phy_devi
|
||||
static int rtl822x_set_serdes_option_mode(struct phy_device *phydev, bool gen1)
|
||||
{
|
||||
bool has_2500, has_sgmii;
|
||||
@ -30,7 +30,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
|
||||
has_2500 = test_bit(PHY_INTERFACE_MODE_2500BASEX,
|
||||
phydev->host_interfaces) ||
|
||||
@@ -1135,18 +1135,42 @@ static int rtl822x_set_serdes_option_mod
|
||||
@@ -1288,18 +1288,42 @@ static int rtl822x_set_serdes_option_mod
|
||||
RTL822X_VND1_SERDES_OPTION,
|
||||
RTL822X_VND1_SERDES_OPTION_MODE_MASK,
|
||||
mode);
|
||||
|
||||
@ -18,7 +18,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
|
||||
--- a/drivers/net/phy/realtek/realtek_main.c
|
||||
+++ b/drivers/net/phy/realtek/realtek_main.c
|
||||
@@ -1562,9 +1562,11 @@ static bool rtlgen_supports_2_5gbps(stru
|
||||
@@ -1715,9 +1715,11 @@ static bool rtlgen_supports_2_5gbps(stru
|
||||
{
|
||||
int val;
|
||||
|
||||
|
||||
@ -13,7 +13,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
|
||||
--- a/drivers/net/phy/realtek/realtek_main.c
|
||||
+++ b/drivers/net/phy/realtek/realtek_main.c
|
||||
@@ -156,6 +156,10 @@
|
||||
@@ -162,6 +162,10 @@
|
||||
|
||||
#define RTL8224_SRAM_RTCT_LEN(pair) (0x8028 + (pair) * 4)
|
||||
|
||||
@ -24,7 +24,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
#define RTL8366RB_POWER_SAVE 0x15
|
||||
#define RTL8366RB_POWER_SAVE_ON BIT(12)
|
||||
|
||||
@@ -1152,6 +1156,15 @@ static int rtl822x_set_serdes_option_mod
|
||||
@@ -1305,6 +1309,15 @@ static int rtl822x_set_serdes_option_mod
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
@ -14,7 +14,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
Signed-off-by: Mieczyslaw Nalewaj <namiltd@yahoo.com>
|
||||
--- a/drivers/net/phy/realtek/realtek_main.c
|
||||
+++ b/drivers/net/phy/realtek/realtek_main.c
|
||||
@@ -1619,10 +1619,32 @@ static int rtl8226_match_phy_device(stru
|
||||
@@ -1772,10 +1772,32 @@ static int rtl8226_match_phy_device(stru
|
||||
static int rtlgen_is_c45_match(struct phy_device *phydev, unsigned int id,
|
||||
bool is_c45)
|
||||
{
|
||||
|
||||
@ -15,7 +15,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
|
||||
--- a/drivers/net/phy/realtek/realtek_main.c
|
||||
+++ b/drivers/net/phy/realtek/realtek_main.c
|
||||
@@ -1316,6 +1316,9 @@ static int rtl822x_c45_get_features(stru
|
||||
@@ -1469,6 +1469,9 @@ static int rtl822x_c45_get_features(stru
|
||||
linkmode_set_bit(ETHTOOL_LINK_MODE_TP_BIT,
|
||||
phydev->supported);
|
||||
|
||||
|
||||
@ -15,7 +15,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
---
|
||||
--- a/drivers/net/phy/realtek/realtek_main.c
|
||||
+++ b/drivers/net/phy/realtek/realtek_main.c
|
||||
@@ -1196,6 +1196,22 @@ static int rtl822xb_config_init(struct p
|
||||
@@ -1349,6 +1349,22 @@ static int rtl822xb_config_init(struct p
|
||||
return rtl822x_set_serdes_option_mode(phydev, false);
|
||||
}
|
||||
|
||||
@ -38,7 +38,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
static int rtl822xb_get_rate_matching(struct phy_device *phydev,
|
||||
phy_interface_t iface)
|
||||
{
|
||||
@@ -2070,7 +2086,7 @@ static struct phy_driver realtek_drvs[]
|
||||
@@ -2223,7 +2239,7 @@ static struct phy_driver realtek_drvs[]
|
||||
.handle_interrupt = rtl8221b_handle_interrupt,
|
||||
.soft_reset = rtl822x_c45_soft_reset,
|
||||
.probe = rtl822x_probe,
|
||||
@ -47,7 +47,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
.get_rate_matching = rtl822xb_get_rate_matching,
|
||||
.get_features = rtl822x_c45_get_features,
|
||||
.config_aneg = rtl822x_c45_config_aneg,
|
||||
@@ -2098,7 +2114,7 @@ static struct phy_driver realtek_drvs[]
|
||||
@@ -2251,7 +2267,7 @@ static struct phy_driver realtek_drvs[]
|
||||
.handle_interrupt = rtl8221b_handle_interrupt,
|
||||
.soft_reset = rtl822x_c45_soft_reset,
|
||||
.probe = rtl822x_probe,
|
||||
|
||||
@ -13,7 +13,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
---
|
||||
--- a/drivers/net/phy/realtek/realtek_main.c
|
||||
+++ b/drivers/net/phy/realtek/realtek_main.c
|
||||
@@ -1107,6 +1107,11 @@ static int rtl822x_set_serdes_option_mod
|
||||
@@ -1260,6 +1260,11 @@ static int rtl822x_set_serdes_option_mod
|
||||
phydev->host_interfaces) ||
|
||||
phydev->interface == PHY_INTERFACE_MODE_SGMII;
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user