All of lore.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.