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 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
>
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
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
© 2016 - 2026 Red Hat, Inc.