From: Artem Lytkin <iprintercanon@gmail.com>
To: netdev@vger.kernel.org, rust-for-linux@vger.kernel.org
Cc: fujita.tomonori@gmail.com, andrew@lunn.ch, hkallweit1@gmail.com,
tmgross@umich.edu, ojeda@kernel.org, dakr@kernel.org
Subject: [PATCH net-next v2 5/5] net: phy: realtek: add Rust RTL8211F PHY driver
Date: Tue, 24 Mar 2026 18:52:49 +0300 [thread overview]
Message-ID: <20260324155249.15098-6-iprintercanon@gmail.com> (raw)
In-Reply-To: <20260324155249.15098-1-iprintercanon@gmail.com>
Add a Rust implementation of the Realtek RTL8211F Gigabit Ethernet PHY
driver. This exercises the extended Rust PHY abstraction with
config_init, read_page/write_page, and interrupt support callbacks.
The driver implements:
- config_init: Configures RGMII TX/RX internal delays based on the
PHY interface mode, and disables PHY-level EEE so LPI is passed
to the MAC. This matches the C driver's essential initialization.
ALDPS and CLKOUT are left at hardware defaults since they depend
on device tree properties and per-device private data not yet
supported by the Rust PHY abstraction.
- read_page / write_page: Standard RTL821x page select register.
- config_intr: Enables/disables link status change interrupts.
- handle_interrupt: Reads INSR and triggers the state machine on
link change. PME/WoL interrupts are documented as unsupported.
The PHY ID 0x001cc916 matches the RTL8211F specifically.
Signed-off-by: Artem Lytkin <iprintercanon@gmail.com>
---
drivers/net/phy/realtek/Kconfig | 12 +++
drivers/net/phy/realtek/Makefile | 1 +
drivers/net/phy/realtek/rtl8211f_rust.rs | 127 +++++++++++++++++++++++
3 files changed, 140 insertions(+)
create mode 100644 drivers/net/phy/realtek/rtl8211f_rust.rs
diff --git a/drivers/net/phy/realtek/Kconfig b/drivers/net/phy/realtek/Kconfig
index b05c2a1e90243..4cc880683367d 100644
--- a/drivers/net/phy/realtek/Kconfig
+++ b/drivers/net/phy/realtek/Kconfig
@@ -13,3 +13,15 @@ config REALTEK_PHY_HWMON
Optional hwmon support for the temperature sensor
endif # REALTEK_PHY
+
+config REALTEK_RTL8211F_RUST_PHY
+ tristate "Rust Realtek RTL8211F PHY driver"
+ depends on RUST && RUST_PHYLIB_ABSTRACTIONS && !REALTEK_PHY
+ help
+ Rust driver for the Realtek RTL8211F Gigabit Ethernet PHY.
+ This is a Rust implementation demonstrating the extended PHY
+ abstraction with config_init, paged register access, and
+ interrupt support.
+
+ To compile this driver as a module, choose M here: the
+ module will be called rtl8211f_rust.
diff --git a/drivers/net/phy/realtek/Makefile b/drivers/net/phy/realtek/Makefile
index dd21cf87f2f18..56ae5d2e39f65 100644
--- a/drivers/net/phy/realtek/Makefile
+++ b/drivers/net/phy/realtek/Makefile
@@ -2,3 +2,4 @@
realtek-y += realtek_main.o
realtek-$(CONFIG_REALTEK_PHY_HWMON) += realtek_hwmon.o
obj-$(CONFIG_REALTEK_PHY) += realtek.o
+obj-$(CONFIG_REALTEK_RTL8211F_RUST_PHY) += rtl8211f_rust.o
diff --git a/drivers/net/phy/realtek/rtl8211f_rust.rs b/drivers/net/phy/realtek/rtl8211f_rust.rs
new file mode 100644
index 0000000000000..f89f2fa55c677
--- /dev/null
+++ b/drivers/net/phy/realtek/rtl8211f_rust.rs
@@ -0,0 +1,127 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2026 Artem Lytkin <iprintercanon@gmail.com>
+
+//! Rust Realtek RTL8211F Gigabit Ethernet PHY driver.
+
+use kernel::irq::IrqReturn;
+use kernel::net::phy::{self, reg::C22, DeviceId};
+use kernel::prelude::*;
+
+// Page select register (vendor-specific, register 0x1f).
+const PAGE_SELECT: C22 = C22::vendor_specific::<0x1f>();
+
+// Interrupt status register (vendor-specific, register 0x1d).
+const INSR: C22 = C22::vendor_specific::<0x1d>();
+
+// Interrupt enable register number (used with paged access on page 0xa42).
+const INER_REG: u16 = 0x12;
+const INER_LINK_STATUS: u16 = 1 << 4;
+
+// RGMII TX delay register on page 0xd08.
+const TX_DELAY_REG: u16 = 0x11;
+const TX_DELAY_EN: u16 = 1 << 8;
+
+// RGMII RX delay register on page 0xd08.
+const RX_DELAY_REG: u16 = 0x15;
+const RX_DELAY_EN: u16 = 1 << 3;
+
+// PHY EEE enable bit in PHYCR2 (default page, register 0x19).
+const PHYCR2: u16 = 0x19;
+const PHYCR2_PHY_EEE_ENABLE: u16 = 1 << 5;
+
+kernel::module_phy_driver! {
+ drivers: [Rtl8211f],
+ device_table: [
+ DeviceId::new_with_driver::<Rtl8211f>(),
+ ],
+ name: "rtl8211f_rust",
+ authors: ["Artem Lytkin"],
+ description: "Rust Realtek RTL8211F PHY driver",
+ license: "GPL",
+}
+
+struct Rtl8211f;
+
+#[vtable]
+impl phy::Driver for Rtl8211f {
+ const NAME: &'static CStr = c"RTL8211F Gigabit Ethernet (Rust)";
+ const PHY_DEVICE_ID: DeviceId = DeviceId::new_with_exact_mask(0x001cc916);
+
+ fn config_init(dev: &mut phy::Device) -> Result {
+ // Configure RGMII delays based on the PHY interface mode.
+ // This matches the C driver's rtl8211f_config_rgmii_delay().
+ let iface = dev.interface();
+ let tx_delay = iface == bindings::phy_interface_t_PHY_INTERFACE_MODE_RGMII_ID
+ || iface == bindings::phy_interface_t_PHY_INTERFACE_MODE_RGMII_TXID;
+ let rx_delay = iface == bindings::phy_interface_t_PHY_INTERFACE_MODE_RGMII_ID
+ || iface == bindings::phy_interface_t_PHY_INTERFACE_MODE_RGMII_RXID;
+
+ dev.modify_paged(
+ 0xd08,
+ TX_DELAY_REG,
+ TX_DELAY_EN,
+ if tx_delay { TX_DELAY_EN } else { 0 },
+ )?;
+ dev.modify_paged(
+ 0xd08,
+ RX_DELAY_REG,
+ RX_DELAY_EN,
+ if rx_delay { RX_DELAY_EN } else { 0 },
+ )?;
+
+ // Disable PHY-level EEE so LPI is passed up to the MAC layer.
+ // PHYCR2 is on the default page, no page switch needed.
+ dev.modify(PHYCR2, PHYCR2_PHY_EEE_ENABLE, 0)?;
+
+ // Note: ALDPS and CLKOUT configuration are omitted because they
+ // depend on device tree properties and per-device private data,
+ // which are not yet supported by the Rust PHY abstraction.
+ // The hardware defaults are preserved for these settings.
+
+ Ok(())
+ }
+
+ fn read_page(dev: &mut phy::Device) -> Result<u16> {
+ dev.read(PAGE_SELECT)
+ }
+
+ fn write_page(dev: &mut phy::Device, page: u16) -> Result {
+ dev.write(PAGE_SELECT, page)
+ }
+
+ fn config_intr(dev: &mut phy::Device) -> Result {
+ if dev.is_interrupts_enabled() {
+ // Acknowledge any pending interrupt.
+ dev.read(INSR)?;
+ // Enable link status change interrupt.
+ dev.write_paged(0xa42, INER_REG, INER_LINK_STATUS)?;
+ } else {
+ // Disable all interrupts.
+ dev.write_paged(0xa42, INER_REG, 0)?;
+ // Acknowledge any pending interrupt.
+ dev.read(INSR)?;
+ }
+ Ok(())
+ }
+
+ fn handle_interrupt(dev: &mut phy::Device) -> IrqReturn {
+ let irq_status = match dev.read(INSR) {
+ Ok(val) => val,
+ Err(_) => {
+ dev.phy_error();
+ return IrqReturn::None;
+ }
+ };
+
+ if irq_status & INER_LINK_STATUS != 0 {
+ dev.trigger_machine();
+ return IrqReturn::Handled;
+ }
+
+ // Note: PME/Wake-on-LAN interrupt (bit 7) is not handled because
+ // WoL support requires pm_wakeup_event() binding and per-device
+ // private data, which are not yet available.
+
+ IrqReturn::None
+ }
+}
--
2.43.0
next prev parent reply other threads:[~2026-03-24 15:53 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-03-24 15:52 [PATCH net-next v2 0/5] rust: phy: extend abstractions for real-world PHY drivers Artem Lytkin
2026-03-24 15:52 ` [PATCH net-next v2 1/5] rust: phy: add read-only device field accessors Artem Lytkin
2026-03-24 15:52 ` [PATCH net-next v2 2/5] rust: phy: add paged register access and bit manipulation helpers Artem Lytkin
2026-03-24 15:52 ` [PATCH net-next v2 3/5] rust: phy: add config_init, read_page, and write_page callbacks Artem Lytkin
2026-03-24 15:52 ` [PATCH net-next v2 4/5] rust: phy: add interrupt support Artem Lytkin
2026-03-24 15:52 ` Artem Lytkin [this message]
2026-03-24 15:57 ` [PATCH net-next v2 5/5] net: phy: realtek: add Rust RTL8211F PHY driver Andrew Lunn
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260324155249.15098-6-iprintercanon@gmail.com \
--to=iprintercanon@gmail.com \
--cc=andrew@lunn.ch \
--cc=dakr@kernel.org \
--cc=fujita.tomonori@gmail.com \
--cc=hkallweit1@gmail.com \
--cc=netdev@vger.kernel.org \
--cc=ojeda@kernel.org \
--cc=rust-for-linux@vger.kernel.org \
--cc=tmgross@umich.edu \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox