public inbox for netdev@vger.kernel.org
 help / color / mirror / Atom feed
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


  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