//! PHY register interfaces. //! //! This module provides support for accessing PHY registers in the //! Ethernet management interface clauses 22 and 45 register namespaces, as //! defined in IEEE 802.3.
mod private { /// Marker that a trait cannot be implemented outside of this crate pubtrait Sealed {}
}
/// Accesses PHY registers. /// /// This trait is used to implement the unified interface to access /// C22 and C45 PHY registers. /// /// # Examples /// /// ```ignore /// fn link_change_notify(dev: &mut Device) { /// // read C22 BMCR register /// dev.read(C22::BMCR); /// // read C45 PMA/PMD control 1 register /// dev.read(C45::new(Mmd::PMAPMD, 0)); /// /// // Checks the link status as reported by registers in the C22 namespace /// // and updates current link state. /// dev.genphy_read_status::<phy::C22>(); /// // Checks the link status as reported by registers in the C45 namespace /// // and updates current link state. /// dev.genphy_read_status::<phy::C45>(); /// } /// ``` pubtrait Register: private::Sealed { /// Reads a PHY register. fn read(&self, dev: &mut Device) -> Result<u16>;
/// Creates a new instance of `C22` with a vendor specific register. pubconstfn vendor_specific<const N: u8>() -> Self {
build_assert!(
N > 0x0f && N < 0x20, "Vendor-specific register address must be between 16 and 31"
);
C22(N)
}
}
impl private::Sealed for C22 {}
impl Register for C22 { fn read(&self, dev: &mut Device) -> Result<u16> { let phydev = dev.0.get(); // SAFETY: `phydev` is pointing to a valid object by the type invariant of `Device`. // So it's just an FFI call, open code of `phy_read()` with a valid `phy_device` pointer // `phydev`. let ret = unsafe {
bindings::mdiobus_read((*phydev).mdio.bus, (*phydev).mdio.addr, self.0.into())
};
to_result(ret)?;
Ok(ret as u16)
}
fn write(&self, dev: &mut Device, val: u16) -> Result { let phydev = dev.0.get(); // SAFETY: `phydev` is pointing to a valid object by the type invariant of `Device`. // So it's just an FFI call, open code of `phy_write()` with a valid `phy_device` pointer // `phydev`.
to_result(unsafe {
bindings::mdiobus_write((*phydev).mdio.bus, (*phydev).mdio.addr, self.0.into(), val)
})
}
fn read_status(dev: &mut Device) -> Result<u16> { let phydev = dev.0.get(); // SAFETY: `phydev` is pointing to a valid object by the type invariant of `Self`. // So it's just an FFI call. let ret = unsafe { bindings::genphy_read_status(phydev) };
to_result(ret)?;
Ok(ret as u16)
}
}
/// A single MDIO clause 45 register device and address. #[derive(Copy, Clone, Debug)] pubstruct Mmd(u8);
impl Mmd { /// Physical Medium Attachment/Dependent. pubconst PMAPMD: Self = Mmd(uapi::MDIO_MMD_PMAPMD as u8); /// WAN interface sublayer. pubconst WIS: Self = Mmd(uapi::MDIO_MMD_WIS as u8); /// Physical coding sublayer. pubconst PCS: Self = Mmd(uapi::MDIO_MMD_PCS as u8); /// PHY Extender sublayer. pubconst PHYXS: Self = Mmd(uapi::MDIO_MMD_PHYXS as u8); /// DTE Extender sublayer. pubconst DTEXS: Self = Mmd(uapi::MDIO_MMD_DTEXS as u8); /// Transmission convergence. pubconst TC: Self = Mmd(uapi::MDIO_MMD_TC as u8); /// Auto negotiation. pubconst AN: Self = Mmd(uapi::MDIO_MMD_AN as u8); /// Separated PMA (1). pubconst SEPARATED_PMA1: Self = Mmd(8); /// Separated PMA (2). pubconst SEPARATED_PMA2: Self = Mmd(9); /// Separated PMA (3). pubconst SEPARATED_PMA3: Self = Mmd(10); /// Separated PMA (4). pubconst SEPARATED_PMA4: Self = Mmd(11); /// OFDM PMA/PMD. pubconst OFDM_PMAPMD: Self = Mmd(12); /// Power unit. pubconst POWER_UNIT: Self = Mmd(13); /// Clause 22 extension. pubconst C22_EXT: Self = Mmd(uapi::MDIO_MMD_C22EXT as u8); /// Vendor specific 1. pubconst VEND1: Self = Mmd(uapi::MDIO_MMD_VEND1 as u8); /// Vendor specific 2. pubconst VEND2: Self = Mmd(uapi::MDIO_MMD_VEND2 as u8);
}
/// A single MDIO clause 45 register device and address. /// /// Clause 45 uses a 5-bit device address to access a specific MMD within /// a port, then a 16-bit register address to access a location within /// that device. `C45` represents this by storing a [`Mmd`] and /// a register number. pubstruct C45 {
devad: Mmd,
regnum: u16,
}
impl C45 { /// Creates a new instance of `C45`. pubfn new(devad: Mmd, regnum: u16) -> Self { Self { devad, regnum }
}
}
impl private::Sealed for C45 {}
impl Register for C45 { fn read(&self, dev: &mut Device) -> Result<u16> { let phydev = dev.0.get(); // SAFETY: `phydev` is pointing to a valid object by the type invariant of `Device`. // So it's just an FFI call. let ret = unsafe { bindings::phy_read_mmd(phydev, self.devad.0.into(), self.regnum.into()) };
to_result(ret)?;
Ok(ret as u16)
}
fn write(&self, dev: &mut Device, val: u16) -> Result { let phydev = dev.0.get(); // SAFETY: `phydev` is pointing to a valid object by the type invariant of `Device`. // So it's just an FFI call.
to_result(unsafe {
bindings::phy_write_mmd(phydev, self.devad.0.into(), self.regnum.into(), val)
})
}
fn read_status(dev: &mut Device) -> Result<u16> { let phydev = dev.0.get(); // SAFETY: `phydev` is pointing to a valid object by the type invariant of `Self`. // So it's just an FFI call. let ret = unsafe { bindings::genphy_c45_read_status(phydev) };
to_result(ret)?;
Ok(ret as u16)
}
}
Messung V0.5 in Prozent
¤ Dauer der Verarbeitung: 0.10 Sekunden
(vorverarbeitet am 2026-06-19)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.