[PATCH net-next 0/2] net: phy: add Rust reference driver for ET1011C

Artem Lytkin posted 2 patches 1 month, 3 weeks ago
There is a newer version of this series
drivers/net/phy/Kconfig         |  9 +++++
drivers/net/phy/Makefile        |  6 ++-
drivers/net/phy/et1011c_rust.rs | 70 +++++++++++++++++++++++++++++++++
rust/kernel/net/phy.rs          |  9 +++++
4 files changed, 93 insertions(+), 1 deletion(-)
create mode 100644 drivers/net/phy/et1011c_rust.rs
[PATCH net-next 0/2] net: phy: add Rust reference driver for ET1011C
Posted by Artem Lytkin 1 month, 3 weeks ago
This series adds a Rust reference driver for the LSI ET1011C PHY,
following the pattern established by the existing Rust Asix PHY driver
(ax88796b_rust.rs).

Patch 1 exposes genphy_config_aneg() in the Rust PHY abstraction,
which is needed by PHY drivers that perform custom BMCR configuration
before calling the generic auto-negotiation setup.

Patch 2 adds the Rust ET1011C driver itself, implementing config_aneg
and read_status callbacks. It is a feature-equivalent port of the C
driver at drivers/net/phy/et1011c.c.

Artem Lytkin (2):
  rust: net: phy: expose genphy_config_aneg()
  net: phy: add Rust reference driver for ET1011C

 drivers/net/phy/Kconfig         |  9 +++++
 drivers/net/phy/Makefile        |  6 ++-
 drivers/net/phy/et1011c_rust.rs | 70 +++++++++++++++++++++++++++++++++
 rust/kernel/net/phy.rs          |  9 +++++
 4 files changed, 93 insertions(+), 1 deletion(-)
 create mode 100644 drivers/net/phy/et1011c_rust.rs

-- 
2.43.0
[PATCH net-next v2 0/3] net: phy: add Rust reference driver for ET1011C
Posted by Artem Lytkin 1 month, 3 weeks ago
This series adds a Rust reference driver for the LSI ET1011C PHY,
following the pattern established by the existing Rust Asix PHY driver
(ax88796b_rust.rs).

Patch 1 adds a speed() getter to phy::Device, needed to detect speed
changes in read_status.

Patch 2 exposes genphy_config_aneg() in the Rust PHY abstraction,
needed by PHY drivers that perform custom BMCR configuration before
calling the generic auto-negotiation setup.

Patch 3 adds the Rust ET1011C driver itself, implementing config_aneg
and read_status callbacks. It is a feature-equivalent port of the C
driver at drivers/net/phy/et1011c.c.

Changes since v1:
  - Added speed() getter to properly detect speed changes (Andrew Lunn)
  - read_status now only reconfigures registers when speed changes,
    matching the C driver behavior (Andrew Lunn)
  - Removed unrelated dim2 staging patches from the series

Artem Lytkin (3):
  rust: net: phy: add speed() getter to Device
  rust: net: phy: expose genphy_config_aneg()
  net: phy: add Rust reference driver for ET1011C

 drivers/net/phy/Kconfig         |  9 ++++
 drivers/net/phy/Makefile        |  6 ++-
 drivers/net/phy/et1011c_rust.rs | 75 +++++++++++++++++++++++++++++++++
 rust/kernel/net/phy.rs          | 17 ++++++++
 4 files changed, 106 insertions(+), 1 deletion(-)
 create mode 100644 drivers/net/phy/et1011c_rust.rs

-- 
2.43.0
[PATCH net-next v3 0/2] net: phy: add Rust reference driver for ET1011C
Posted by Artem Lytkin 1 month, 3 weeks ago
This series adds a Rust reference driver for the LSI ET1011C PHY,
following the pattern established by the existing Rust Asix PHY driver
(ax88796b_rust.rs).

Patch 1 adds a speed() getter to phy::Device, needed to detect speed
changes in read_status.

Patch 2 adds the Rust ET1011C driver itself, implementing soft_reset
and read_status callbacks.

Changes since v2:
  - Replaced custom config_aneg with soft_reset callback using
    genphy_soft_reset(), which properly polls the self-clearing
    BMCR_RESET bit and handles autoneg/forced mode (Andrew Lunn)
  - Removed all BMCR constant definitions (no longer needed)
  - Dropped genphy_config_aneg() abstraction patch (no longer used)

Changes since v1:
  - Added speed() getter to properly detect speed changes (Andrew Lunn)
  - read_status now only reconfigures registers when speed changes,
    matching the C driver behavior (Andrew Lunn)

Artem Lytkin (2):
  rust: net: phy: add speed() getter to Device
  net: phy: add Rust reference driver for ET1011C

 drivers/net/phy/Kconfig         |  9 +++++
 drivers/net/phy/Makefile        |  6 ++-
 drivers/net/phy/et1011c_rust.rs | 69 +++++++++++++++++++++++++++++++++
 rust/kernel/net/phy.rs          |  8 ++++
 4 files changed, 91 insertions(+), 1 deletion(-)
 create mode 100644 drivers/net/phy/et1011c_rust.rs

-- 
2.43.0
Re: [PATCH net-next v3 0/2] net: phy: add Rust reference driver for ET1011C
Posted by Andrew Lunn 1 month, 3 weeks ago
On Tue, Feb 24, 2026 at 04:49:24PM +0000, Artem Lytkin wrote:
> This series adds a Rust reference driver for the LSI ET1011C PHY,
> following the pattern established by the existing Rust Asix PHY driver
> (ax88796b_rust.rs).
> 
> Patch 1 adds a speed() getter to phy::Device, needed to detect speed
> changes in read_status.
> 
> Patch 2 adds the Rust ET1011C driver itself, implementing soft_reset
> and read_status callbacks.

Please don't post a new version within 24 hours.

https://www.kernel.org/doc/html/latest/process/maintainer-netdev.html

Also, each version should be in a thread of its own.

Yes, the code is the easy bit, getting the processes correct is
hard. But given the volume of patches, you need to follow the
processes otherwise it does not scale.

There are also some unanswered questions from the last version. Please
don't post a new version until the discussion has come to a
conclusion.

	Andrew
[PATCH net-next v3 1/2] rust: net: phy: add speed() getter to Device
Posted by Artem Lytkin 1 month, 3 weeks ago
Add a speed() getter to phy::Device that reads the current link speed
from the phy_device struct. This is needed by PHY drivers that must
detect speed changes in their read_status callback.

Signed-off-by: Artem Lytkin <iprintercanon@gmail.com>
---
 rust/kernel/net/phy.rs | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/rust/kernel/net/phy.rs b/rust/kernel/net/phy.rs
index 3ca99db5cccf..3812f8fd3e49 100644
--- a/rust/kernel/net/phy.rs
+++ b/rust/kernel/net/phy.rs
@@ -158,6 +158,14 @@ pub fn is_autoneg_completed(&self) -> bool {
         bit_field.get(15, 1) == AUTONEG_COMPLETED
     }
 
+    /// Gets the current link speed.
+    pub fn speed(&self) -> i32 {
+        let phydev = self.0.get();
+        // SAFETY: The struct invariant ensures that we may access
+        // this field without additional synchronization.
+        unsafe { (*phydev).speed }
+    }
+
     /// Sets the speed of the PHY.
     pub fn set_speed(&mut self, speed: u32) {
         let phydev = self.0.get();
-- 
2.43.0
[PATCH net-next v3 2/2] net: phy: add Rust reference driver for ET1011C
Posted by Artem Lytkin 1 month, 3 weeks ago
Add a Rust reference driver for the LSI ET1011C PHY, following the
pattern established by the existing Rust Asix PHY driver
(ax88796b_rust.rs).

Unlike the C driver which uses a custom config_aneg that manually
clears BMCR bits and writes BMCR_RESET without polling, this driver
uses the soft_reset callback with genphy_soft_reset(). This properly
polls the self-clearing BMCR_RESET bit and handles both autoneg and
forced mode, following current best practices.

The read_status callback detects speed changes and reconfigures the
GMII interface and TX FIFO when switching to gigabit, matching the C
driver's functionality.

Signed-off-by: Artem Lytkin <iprintercanon@gmail.com>
---
 drivers/net/phy/Kconfig         |  9 +++++
 drivers/net/phy/Makefile        |  6 ++-
 drivers/net/phy/et1011c_rust.rs | 69 +++++++++++++++++++++++++++++++++
 3 files changed, 83 insertions(+), 1 deletion(-)
 create mode 100644 drivers/net/phy/et1011c_rust.rs

diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig
index 7b73332a13d9..41abf13662e6 100644
--- a/drivers/net/phy/Kconfig
+++ b/drivers/net/phy/Kconfig
@@ -254,6 +254,15 @@ config LSI_ET1011C_PHY
 	help
 	  Supports the LSI ET1011C PHY.
 
+config ET1011C_RUST_PHY
+	bool "Rust reference driver for LSI ET1011C PHY"
+	depends on RUST_PHYLIB_ABSTRACTIONS && LSI_ET1011C_PHY
+	help
+	  Uses the Rust reference driver for LSI ET1011C PHY
+	  (et1011c_rust.ko). The features are equivalent.
+	  It supports the LSI ET1011C PHY. If unsure,
+	  say N.
+
 config MARVELL_PHY
 	tristate "Marvell Alaska PHYs"
 	help
diff --git a/drivers/net/phy/Makefile b/drivers/net/phy/Makefile
index 3a34917adea7..491469457a67 100644
--- a/drivers/net/phy/Makefile
+++ b/drivers/net/phy/Makefile
@@ -62,7 +62,11 @@ obj-$(CONFIG_DP83TG720_PHY)	+= dp83tg720.o
 obj-$(CONFIG_FIXED_PHY)		+= fixed_phy.o
 obj-$(CONFIG_ICPLUS_PHY)	+= icplus.o
 obj-$(CONFIG_INTEL_XWAY_PHY)	+= intel-xway.o
-obj-$(CONFIG_LSI_ET1011C_PHY)	+= et1011c.o
+ifdef CONFIG_ET1011C_RUST_PHY
+  obj-$(CONFIG_LSI_ET1011C_PHY)	+= et1011c_rust.o
+else
+  obj-$(CONFIG_LSI_ET1011C_PHY)	+= et1011c.o
+endif
 obj-$(CONFIG_LXT_PHY)		+= lxt.o
 obj-$(CONFIG_MARVELL_10G_PHY)	+= marvell10g.o
 obj-$(CONFIG_MARVELL_PHY)	+= marvell.o
diff --git a/drivers/net/phy/et1011c_rust.rs b/drivers/net/phy/et1011c_rust.rs
new file mode 100644
index 000000000000..93dbf9586da3
--- /dev/null
+++ b/drivers/net/phy/et1011c_rust.rs
@@ -0,0 +1,69 @@
+// SPDX-License-Identifier: GPL-2.0+
+// Copyright (C) 2026 Artem Lytkin <iprintercanon@gmail.com>
+
+//! Rust LSI ET1011C PHY driver
+//!
+//! C version of this driver: [`drivers/net/phy/et1011c.c`](./et1011c.c)
+
+use kernel::{
+    net::phy::{self, reg::C22, DeviceId, Driver},
+    prelude::*,
+};
+
+kernel::module_phy_driver! {
+    drivers: [PhyET1011C],
+    device_table: [
+        DeviceId::new_with_driver::<PhyET1011C>()
+    ],
+    name: "rust_et1011c_phy",
+    authors: ["Artem Lytkin <iprintercanon@gmail.com>"],
+    description: "Rust LSI ET1011C PHY driver",
+    license: "GPL",
+}
+
+// Vendor-specific registers
+const ET1011C_STATUS_REG: C22 = C22::vendor_specific::<0x1A>();
+const ET1011C_CONFIG_REG: C22 = C22::vendor_specific::<0x16>();
+
+// ET1011C status register fields
+const ET1011C_SPEED_MASK: u16 = 0x0300;
+const ET1011C_GIGABIT_SPEED: u16 = 0x0200;
+
+// ET1011C config register fields
+const ET1011C_TX_FIFO_MASK: u16 = 0x3000;
+const ET1011C_TX_FIFO_DEPTH_16: u16 = 0x1000;
+const ET1011C_GMII_INTERFACE: u16 = 0x0002;
+const ET1011C_SYS_CLK_EN: u16 = 0x0010;
+
+struct PhyET1011C;
+
+#[vtable]
+impl Driver for PhyET1011C {
+    const NAME: &'static CStr = c"ET1011C";
+    const PHY_DEVICE_ID: DeviceId = DeviceId::new_with_model_mask(0x0282f014);
+
+    fn soft_reset(dev: &mut phy::Device) -> Result {
+        dev.genphy_soft_reset()
+    }
+
+    fn read_status(dev: &mut phy::Device) -> Result<u16> {
+        let old_speed = dev.speed();
+        dev.genphy_read_status::<C22>()?;
+
+        if old_speed != dev.speed() {
+            let val = dev.read(ET1011C_STATUS_REG)?;
+            if (val & ET1011C_SPEED_MASK) == ET1011C_GIGABIT_SPEED {
+                let cfg = dev.read(ET1011C_CONFIG_REG)?;
+                let cfg = cfg & !ET1011C_TX_FIFO_MASK;
+                dev.write(
+                    ET1011C_CONFIG_REG,
+                    cfg | ET1011C_GMII_INTERFACE
+                        | ET1011C_SYS_CLK_EN
+                        | ET1011C_TX_FIFO_DEPTH_16,
+                )?;
+            }
+        }
+
+        Ok(0)
+    }
+}
-- 
2.43.0
Re: [PATCH net-next v3 2/2] net: phy: add Rust reference driver for ET1011C
Posted by Принтер Принтеров 1 month, 3 weeks ago
Re: [PATCH net-next v3 0/2] net: phy: add Rust reference driver for ET1011C
  On Mon, Feb 24, 2026 at ... Miguel Ojeda <ojeda@kernel.org> wrote:
  > Since there is already a PHY one, is this meant to bootstrap the two
  > new APIs? Or something else?

Thank you for the feedback, Miguel. You raise a fair point.

  Honestly, the new abstraction here (speed() getter) is quite minor --
  it just reads a struct field. The driver itself doesn't bootstrap
  anything significant beyond what ax88796b_rust already covers.

  I'm looking to contribute to Rust in the kernel and started with PHY
  drivers because the abstraction is well established. But I understand
  now that duplicating C drivers isn't the goal.

  Could you point me toward areas where Rust work would be most
  valuable? I'm happy to work on new abstractions or drivers that
  actually need bootstrapping, rather than adding another reference
  driver to an area that's already covered.

  Thanks,
  Artem


вт, 24 февр. 2026 г. в 19:49, Artem Lytkin <iprintercanon@gmail.com>:
>
> Add a Rust reference driver for the LSI ET1011C PHY, following the
> pattern established by the existing Rust Asix PHY driver
> (ax88796b_rust.rs).
>
> Unlike the C driver which uses a custom config_aneg that manually
> clears BMCR bits and writes BMCR_RESET without polling, this driver
> uses the soft_reset callback with genphy_soft_reset(). This properly
> polls the self-clearing BMCR_RESET bit and handles both autoneg and
> forced mode, following current best practices.
>
> The read_status callback detects speed changes and reconfigures the
> GMII interface and TX FIFO when switching to gigabit, matching the C
> driver's functionality.
>
> Signed-off-by: Artem Lytkin <iprintercanon@gmail.com>
> ---
>  drivers/net/phy/Kconfig         |  9 +++++
>  drivers/net/phy/Makefile        |  6 ++-
>  drivers/net/phy/et1011c_rust.rs | 69 +++++++++++++++++++++++++++++++++
>  3 files changed, 83 insertions(+), 1 deletion(-)
>  create mode 100644 drivers/net/phy/et1011c_rust.rs
>
> diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig
> index 7b73332a13d9..41abf13662e6 100644
> --- a/drivers/net/phy/Kconfig
> +++ b/drivers/net/phy/Kconfig
> @@ -254,6 +254,15 @@ config LSI_ET1011C_PHY
>         help
>           Supports the LSI ET1011C PHY.
>
> +config ET1011C_RUST_PHY
> +       bool "Rust reference driver for LSI ET1011C PHY"
> +       depends on RUST_PHYLIB_ABSTRACTIONS && LSI_ET1011C_PHY
> +       help
> +         Uses the Rust reference driver for LSI ET1011C PHY
> +         (et1011c_rust.ko). The features are equivalent.
> +         It supports the LSI ET1011C PHY. If unsure,
> +         say N.
> +
>  config MARVELL_PHY
>         tristate "Marvell Alaska PHYs"
>         help
> diff --git a/drivers/net/phy/Makefile b/drivers/net/phy/Makefile
> index 3a34917adea7..491469457a67 100644
> --- a/drivers/net/phy/Makefile
> +++ b/drivers/net/phy/Makefile
> @@ -62,7 +62,11 @@ obj-$(CONFIG_DP83TG720_PHY)  += dp83tg720.o
>  obj-$(CONFIG_FIXED_PHY)                += fixed_phy.o
>  obj-$(CONFIG_ICPLUS_PHY)       += icplus.o
>  obj-$(CONFIG_INTEL_XWAY_PHY)   += intel-xway.o
> -obj-$(CONFIG_LSI_ET1011C_PHY)  += et1011c.o
> +ifdef CONFIG_ET1011C_RUST_PHY
> +  obj-$(CONFIG_LSI_ET1011C_PHY)        += et1011c_rust.o
> +else
> +  obj-$(CONFIG_LSI_ET1011C_PHY)        += et1011c.o
> +endif
>  obj-$(CONFIG_LXT_PHY)          += lxt.o
>  obj-$(CONFIG_MARVELL_10G_PHY)  += marvell10g.o
>  obj-$(CONFIG_MARVELL_PHY)      += marvell.o
> diff --git a/drivers/net/phy/et1011c_rust.rs b/drivers/net/phy/et1011c_rust.rs
> new file mode 100644
> index 000000000000..93dbf9586da3
> --- /dev/null
> +++ b/drivers/net/phy/et1011c_rust.rs
> @@ -0,0 +1,69 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +// Copyright (C) 2026 Artem Lytkin <iprintercanon@gmail.com>
> +
> +//! Rust LSI ET1011C PHY driver
> +//!
> +//! C version of this driver: [`drivers/net/phy/et1011c.c`](./et1011c.c)
> +
> +use kernel::{
> +    net::phy::{self, reg::C22, DeviceId, Driver},
> +    prelude::*,
> +};
> +
> +kernel::module_phy_driver! {
> +    drivers: [PhyET1011C],
> +    device_table: [
> +        DeviceId::new_with_driver::<PhyET1011C>()
> +    ],
> +    name: "rust_et1011c_phy",
> +    authors: ["Artem Lytkin <iprintercanon@gmail.com>"],
> +    description: "Rust LSI ET1011C PHY driver",
> +    license: "GPL",
> +}
> +
> +// Vendor-specific registers
> +const ET1011C_STATUS_REG: C22 = C22::vendor_specific::<0x1A>();
> +const ET1011C_CONFIG_REG: C22 = C22::vendor_specific::<0x16>();
> +
> +// ET1011C status register fields
> +const ET1011C_SPEED_MASK: u16 = 0x0300;
> +const ET1011C_GIGABIT_SPEED: u16 = 0x0200;
> +
> +// ET1011C config register fields
> +const ET1011C_TX_FIFO_MASK: u16 = 0x3000;
> +const ET1011C_TX_FIFO_DEPTH_16: u16 = 0x1000;
> +const ET1011C_GMII_INTERFACE: u16 = 0x0002;
> +const ET1011C_SYS_CLK_EN: u16 = 0x0010;
> +
> +struct PhyET1011C;
> +
> +#[vtable]
> +impl Driver for PhyET1011C {
> +    const NAME: &'static CStr = c"ET1011C";
> +    const PHY_DEVICE_ID: DeviceId = DeviceId::new_with_model_mask(0x0282f014);
> +
> +    fn soft_reset(dev: &mut phy::Device) -> Result {
> +        dev.genphy_soft_reset()
> +    }
> +
> +    fn read_status(dev: &mut phy::Device) -> Result<u16> {
> +        let old_speed = dev.speed();
> +        dev.genphy_read_status::<C22>()?;
> +
> +        if old_speed != dev.speed() {
> +            let val = dev.read(ET1011C_STATUS_REG)?;
> +            if (val & ET1011C_SPEED_MASK) == ET1011C_GIGABIT_SPEED {
> +                let cfg = dev.read(ET1011C_CONFIG_REG)?;
> +                let cfg = cfg & !ET1011C_TX_FIFO_MASK;
> +                dev.write(
> +                    ET1011C_CONFIG_REG,
> +                    cfg | ET1011C_GMII_INTERFACE
> +                        | ET1011C_SYS_CLK_EN
> +                        | ET1011C_TX_FIFO_DEPTH_16,
> +                )?;
> +            }
> +        }
> +
> +        Ok(0)
> +    }
> +}
> --
> 2.43.0
>
Re: [PATCH net-next v3 2/2] net: phy: add Rust reference driver for ET1011C
Posted by Miguel Ojeda 1 month, 3 weeks ago
On Tue, Feb 24, 2026 at 6:04 PM Принтер Принтеров
<iprintercanon@gmail.com> wrote:
>
> Thank you for the feedback, Miguel. You raise a fair point.
>
>   Honestly, the new abstraction here (speed() getter) is quite minor --
>   it just reads a struct field. The driver itself doesn't bootstrap
>   anything significant beyond what ax88796b_rust already covers.
>
>   I'm looking to contribute to Rust in the kernel and started with PHY
>   drivers because the abstraction is well established. But I understand
>   now that duplicating C drivers isn't the goal.
>
>   Could you point me toward areas where Rust work would be most
>   valuable? I'm happy to work on new abstractions or drivers that
>   actually need bootstrapping, rather than adding another reference
>   driver to an area that's already covered.

To clarify, if the netdev maintainers want to have more reference
drivers, it is up to them, i.e. please do not feel discouraged by what
I said. :) I just thought I should mention it in case there was some
confusion.

Regarding new drivers, if you want to work around networking, then
probably the maintainers can tell you what is needed. In general, I
would suggest looking for hardware that is unsupported currently --
that is usually way easier to justify and land, and there is no
concern about duplication (and possibly arch support is not a worry
too, since there is no other driver anyway).

Regarding new abstractions or other kinds of work, you may want to
look into existing driver's lists like:

  - https://docs.kernel.org/next/gpu/nova/core/todo.html
  - https://gitlab.freedesktop.org/panfrost/linux/-/issues/?label_name%5B%5D=tyr

We have also threads in Zulip about looking for things to work on --
in case you haven't seen them, you may want to take a look at e.g.

  https://rust-for-linux.zulipchat.com/#narrow/channel/291565-Help/topic/Looking.20for.20open.20issue

Finally, you probably know this, but you can always help not just by
writing code, but by reviewing patches and testing them -- that is
very needed, gets you credit in the Git log, and by doing so you will
likely realize what other things you could work on around the same
areas you start to review.

I hope that helps!

Cheers,
Miguel
Re: [PATCH net-next v3 2/2] net: phy: add Rust reference driver for ET1011C
Posted by Принтер Принтеров 1 month, 3 weeks ago
 Thank you, Miguel! I appreciate the encouragement and the pointers.

  I'll look into the Nova and Panfrost/Tyr task lists, and check the
  Zulip threads for open work. The suggestion about unsupported hardware
  is a good one -- I'll look for something that could use a new Rust
  driver.

  I'll also start reviewing patches in the areas I'm interested in.
  That seems like a good way to learn and contribute at the same time.

  Thanks again for taking the time to reply.

  Artem

вт, 24 февр. 2026 г. в 20:54, Miguel Ojeda <miguel.ojeda.sandonis@gmail.com>:
>
> On Tue, Feb 24, 2026 at 6:04 PM Принтер Принтеров
> <iprintercanon@gmail.com> wrote:
> >
> > Thank you for the feedback, Miguel. You raise a fair point.
> >
> >   Honestly, the new abstraction here (speed() getter) is quite minor --
> >   it just reads a struct field. The driver itself doesn't bootstrap
> >   anything significant beyond what ax88796b_rust already covers.
> >
> >   I'm looking to contribute to Rust in the kernel and started with PHY
> >   drivers because the abstraction is well established. But I understand
> >   now that duplicating C drivers isn't the goal.
> >
> >   Could you point me toward areas where Rust work would be most
> >   valuable? I'm happy to work on new abstractions or drivers that
> >   actually need bootstrapping, rather than adding another reference
> >   driver to an area that's already covered.
>
> To clarify, if the netdev maintainers want to have more reference
> drivers, it is up to them, i.e. please do not feel discouraged by what
> I said. :) I just thought I should mention it in case there was some
> confusion.
>
> Regarding new drivers, if you want to work around networking, then
> probably the maintainers can tell you what is needed. In general, I
> would suggest looking for hardware that is unsupported currently --
> that is usually way easier to justify and land, and there is no
> concern about duplication (and possibly arch support is not a worry
> too, since there is no other driver anyway).
>
> Regarding new abstractions or other kinds of work, you may want to
> look into existing driver's lists like:
>
>   - https://docs.kernel.org/next/gpu/nova/core/todo.html
>   - https://gitlab.freedesktop.org/panfrost/linux/-/issues/?label_name%5B%5D=tyr
>
> We have also threads in Zulip about looking for things to work on --
> in case you haven't seen them, you may want to take a look at e.g.
>
>   https://rust-for-linux.zulipchat.com/#narrow/channel/291565-Help/topic/Looking.20for.20open.20issue
>
> Finally, you probably know this, but you can always help not just by
> writing code, but by reviewing patches and testing them -- that is
> very needed, gets you credit in the Git log, and by doing so you will
> likely realize what other things you could work on around the same
> areas you start to review.
>
> I hope that helps!
>
> Cheers,
> Miguel
Re: [PATCH net-next v2 0/3] net: phy: add Rust reference driver for ET1011C
Posted by Miguel Ojeda 1 month, 3 weeks ago
On Tue, Feb 24, 2026 at 5:32 AM Artem Lytkin <iprintercanon@gmail.com> wrote:
>
> This series adds a Rust reference driver for the LSI ET1011C PHY,
> following the pattern established by the existing Rust Asix PHY driver
> (ax88796b_rust.rs).

It is great to see more Rust code, and I am glad the "Rust reference
driver" model is useful here. But reference drivers, in principle, are
meant to bootstrap the abstractions and so on. The cover letter says
"following the pattern established", but the idea is not to duplicate
every C driver.

Since there is already a PHY one, is this meant to bootstrap the two
new APIs? Or something else?

Of course, it is up to the maintainers, i.e. if they want/need to have
more reference drivers, that is great. But I think it would be good to
clarify.

Thanks!

Cheers,
Miguel
[PATCH net-next v2 1/3] rust: net: phy: add speed() getter to Device
Posted by Artem Lytkin 1 month, 3 weeks ago
Add a speed() method to phy::Device as a getter counterpart to the
existing set_speed(). This is needed by PHY drivers that need to
detect speed changes, such as drivers that must reconfigure hardware
registers when the link speed changes.

Signed-off-by: Artem Lytkin <iprintercanon@gmail.com>
---
 rust/kernel/net/phy.rs | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/rust/kernel/net/phy.rs b/rust/kernel/net/phy.rs
index 3ca99db5cccf..b86939b163e3 100644
--- a/rust/kernel/net/phy.rs
+++ b/rust/kernel/net/phy.rs
@@ -158,6 +158,14 @@ pub fn is_autoneg_completed(&self) -> bool {
         bit_field.get(15, 1) == AUTONEG_COMPLETED
     }
 
+    /// Gets the negotiated speed of the PHY.
+    pub fn speed(&self) -> i32 {
+        let phydev = self.0.get();
+        // SAFETY: The struct invariant ensures that we may access
+        // this field without additional synchronization.
+        unsafe { (*phydev).speed }
+    }
+
     /// Sets the speed of the PHY.
     pub fn set_speed(&mut self, speed: u32) {
         let phydev = self.0.get();
-- 
2.43.0
[PATCH net-next v2 2/3] rust: net: phy: expose genphy_config_aneg()
Posted by Artem Lytkin 1 month, 3 weeks ago
Add genphy_config_aneg() method to phy::Device, wrapping the C
function __genphy_config_aneg(). This is needed by PHY drivers that
perform custom BMCR configuration before calling the generic
auto-negotiation setup.

The wrapper calls __genphy_config_aneg(phydev, false) directly since
genphy_config_aneg() is a static inline function not visible to
bindgen.

Signed-off-by: Artem Lytkin <iprintercanon@gmail.com>
---
 rust/kernel/net/phy.rs | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/rust/kernel/net/phy.rs b/rust/kernel/net/phy.rs
index b86939b163e3..01597f2616fd 100644
--- a/rust/kernel/net/phy.rs
+++ b/rust/kernel/net/phy.rs
@@ -284,6 +284,15 @@ pub fn genphy_read_abilities(&mut self) -> Result {
         // So it's just an FFI call.
         to_result(unsafe { bindings::genphy_read_abilities(phydev) })
     }
+
+    /// Configures the advertisement and resets auto-negotiation
+    /// if auto-negotiation is enabled.
+    pub fn genphy_config_aneg(&mut self) -> Result {
+        let phydev = self.0.get();
+        // SAFETY: `phydev` is pointing to a valid object by the type invariant of `Self`.
+        // So it's just an FFI call.
+        to_result(unsafe { bindings::__genphy_config_aneg(phydev, false) })
+    }
 }
 
 impl AsRef<kernel::device::Device> for Device {
-- 
2.43.0
[PATCH net-next v2 3/3] net: phy: add Rust reference driver for ET1011C
Posted by Artem Lytkin 1 month, 3 weeks ago
Add a Rust implementation of the LSI ET1011C PHY driver, equivalent
to the existing C driver in drivers/net/phy/et1011c.c. The driver
implements config_aneg and read_status callbacks using the Rust PHY
abstraction.

The Rust driver uses the new speed() getter to detect speed changes,
only reconfiguring the TX FIFO depth and GMII interface when the
negotiated speed actually changes. This matches the C driver behavior.

The Rust driver can be selected via the ET1011C_RUST_PHY Kconfig
option, following the same pattern as AX88796B_RUST_PHY.

Signed-off-by: Artem Lytkin <iprintercanon@gmail.com>
---
 drivers/net/phy/Kconfig         |  9 ++++
 drivers/net/phy/Makefile        |  6 ++-
 drivers/net/phy/et1011c_rust.rs | 75 +++++++++++++++++++++++++++++++++
 3 files changed, 89 insertions(+), 1 deletion(-)
 create mode 100644 drivers/net/phy/et1011c_rust.rs

diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig
index 7b73332a13d9..5271898a38f7 100644
--- a/drivers/net/phy/Kconfig
+++ b/drivers/net/phy/Kconfig
@@ -254,6 +254,15 @@ config LSI_ET1011C_PHY
 	help
 	  Supports the LSI ET1011C PHY.
 
+config ET1011C_RUST_PHY
+	bool "Rust reference driver for LSI ET1011C PHY"
+	depends on RUST_PHYLIB_ABSTRACTIONS && LSI_ET1011C_PHY
+	help
+	  Uses the Rust reference driver for LSI ET1011C PHY
+	  (et1011c_rust.ko). The features and behavior are
+	  equivalent to the C driver. Selecting this option builds
+	  the Rust version instead of the C version.
+
 config MARVELL_PHY
 	tristate "Marvell Alaska PHYs"
 	help
diff --git a/drivers/net/phy/Makefile b/drivers/net/phy/Makefile
index 3a34917adea7..491469457a67 100644
--- a/drivers/net/phy/Makefile
+++ b/drivers/net/phy/Makefile
@@ -62,7 +62,11 @@ obj-$(CONFIG_DP83TG720_PHY)	+= dp83tg720.o
 obj-$(CONFIG_FIXED_PHY)		+= fixed_phy.o
 obj-$(CONFIG_ICPLUS_PHY)	+= icplus.o
 obj-$(CONFIG_INTEL_XWAY_PHY)	+= intel-xway.o
-obj-$(CONFIG_LSI_ET1011C_PHY)	+= et1011c.o
+ifdef CONFIG_ET1011C_RUST_PHY
+  obj-$(CONFIG_LSI_ET1011C_PHY)	+= et1011c_rust.o
+else
+  obj-$(CONFIG_LSI_ET1011C_PHY)	+= et1011c.o
+endif
 obj-$(CONFIG_LXT_PHY)		+= lxt.o
 obj-$(CONFIG_MARVELL_10G_PHY)	+= marvell10g.o
 obj-$(CONFIG_MARVELL_PHY)	+= marvell.o
diff --git a/drivers/net/phy/et1011c_rust.rs b/drivers/net/phy/et1011c_rust.rs
new file mode 100644
index 000000000000..7b8ae3bf492c
--- /dev/null
+++ b/drivers/net/phy/et1011c_rust.rs
@@ -0,0 +1,75 @@
+// SPDX-License-Identifier: GPL-2.0+
+// Copyright (C) 2026 Artem Lytkin <iprintercanon@gmail.com>
+
+//! Rust LSI ET1011C PHY driver
+//!
+//! C version of this driver: [`drivers/net/phy/et1011c.c`](./et1011c.c)
+
+use kernel::{
+    net::phy::{self, reg::C22, DeviceId, Driver},
+    prelude::*,
+    uapi,
+};
+
+kernel::module_phy_driver! {
+    drivers: [PhyET1011C],
+    device_table: [
+        DeviceId::new_with_driver::<PhyET1011C>()
+    ],
+    name: "rust_et1011c_phy",
+    authors: ["Artem Lytkin <iprintercanon@gmail.com>"],
+    description: "Rust LSI ET1011C PHY driver",
+    license: "GPL",
+}
+
+const ET1011C_STATUS_REG: C22 = C22::vendor_specific::<0x1A>();
+const ET1011C_CONFIG_REG: C22 = C22::vendor_specific::<0x16>();
+
+const ET1011C_SPEED_MASK: u16 = 0x0300;
+const ET1011C_GIGABIT_SPEED: u16 = 0x0200;
+const ET1011C_TX_FIFO_MASK: u16 = 0x3000;
+const ET1011C_TX_FIFO_DEPTH_16: u16 = 0x1000;
+const ET1011C_GMII_INTERFACE: u16 = 0x0002;
+const ET1011C_SYS_CLK_EN: u16 = 0x0010;
+
+const BMCR_FULLDPLX: u16 = uapi::BMCR_FULLDPLX as u16;
+const BMCR_SPEED100: u16 = uapi::BMCR_SPEED100 as u16;
+const BMCR_SPEED1000: u16 = uapi::BMCR_SPEED1000 as u16;
+const BMCR_ANENABLE: u16 = uapi::BMCR_ANENABLE as u16;
+const BMCR_RESET: u16 = uapi::BMCR_RESET as u16;
+
+struct PhyET1011C;
+
+#[vtable]
+impl Driver for PhyET1011C {
+    const NAME: &'static CStr = c"ET1011C";
+    const PHY_DEVICE_ID: DeviceId = DeviceId::new_with_model_mask(0x0282f014);
+
+    fn config_aneg(dev: &mut phy::Device) -> Result {
+        let ctl = dev.read(C22::BMCR)?;
+        let ctl = ctl & !(BMCR_FULLDPLX | BMCR_SPEED100 | BMCR_SPEED1000 | BMCR_ANENABLE);
+        dev.write(C22::BMCR, ctl | BMCR_RESET)?;
+        dev.genphy_config_aneg()
+    }
+
+    fn read_status(dev: &mut phy::Device) -> Result<u16> {
+        let old_speed = dev.speed();
+        dev.genphy_read_status::<C22>()?;
+
+        if old_speed != dev.speed() {
+            let val = dev.read(ET1011C_STATUS_REG)?;
+            if (val & ET1011C_SPEED_MASK) == ET1011C_GIGABIT_SPEED {
+                let cfg = dev.read(ET1011C_CONFIG_REG)?;
+                let cfg = cfg & !ET1011C_TX_FIFO_MASK;
+                dev.write(
+                    ET1011C_CONFIG_REG,
+                    cfg | ET1011C_GMII_INTERFACE
+                        | ET1011C_SYS_CLK_EN
+                        | ET1011C_TX_FIFO_DEPTH_16,
+                )?;
+            }
+        }
+
+        Ok(0)
+    }
+}
-- 
2.43.0
Re: [PATCH net-next v2 3/3] net: phy: add Rust reference driver for ET1011C
Posted by Andrew Lunn 1 month, 3 weeks ago
What board are you testing this on? This is a pretty old PHY, and
nobody has done anything with it for a long time.

> +const BMCR_FULLDPLX: u16 = uapi::BMCR_FULLDPLX as u16;
> +const BMCR_SPEED100: u16 = uapi::BMCR_SPEED100 as u16;
> +const BMCR_SPEED1000: u16 = uapi::BMCR_SPEED1000 as u16;
> +const BMCR_ANENABLE: u16 = uapi::BMCR_ANENABLE as u16;
> +const BMCR_RESET: u16 = uapi::BMCR_RESET as u16;

ax88796b_rust.rs also has:

const BMCR_SPEED100: u16 = uapi::BMCR_SPEED100 as u16;
const BMCR_FULLDPLX: u16 = uapi::BMCR_FULLDPLX as u16;

Can these be shared somehow?

> +impl Driver for PhyET1011C {
> +    const NAME: &'static CStr = c"ET1011C";
> +    const PHY_DEVICE_ID: DeviceId = DeviceId::new_with_model_mask(0x0282f014);
> +
> +    fn config_aneg(dev: &mut phy::Device) -> Result {
> +        let ctl = dev.read(C22::BMCR)?;
> +        let ctl = ctl & !(BMCR_FULLDPLX | BMCR_SPEED100 | BMCR_SPEED1000 | BMCR_ANENABLE);

It is pretty unusual to clear these bits in BMCR. BMCR_FULLDPLX,
BMCR_SPEED100, BMCR_SPEED1000 are only used when autoneg is
disabled. genphy_setup_forced() will set them, if
needed. BMCR_ANENABLE will be set when auto-neg is restarted.

Is there any hint in the datasheet why this is needed?


> +        dev.write(C22::BMCR, ctl | BMCR_RESET)?;

BMCR_RESET is a self clearly bit, and you should wait for it to
clear. genphy_soft_reset() does the polling. But before you can swap
to this, you need to understand why the other bits are being cleared.

Given how old this C driver is, i'm not sure it is using best
practices. So you really should be looking at every line, is it
correct in todays phylib framework? Should it be done differently in a
modern driver? We don't want a 1:1 copy in rust, we want something
which is up to date.

     Andrew