summaryrefslogtreecommitdiff
path: root/rust/kernel/net/phy.rs
diff options
context:
space:
mode:
Diffstat (limited to 'rust/kernel/net/phy.rs')
-rw-r--r--rust/kernel/net/phy.rs108
1 files changed, 53 insertions, 55 deletions
diff --git a/rust/kernel/net/phy.rs b/rust/kernel/net/phy.rs
index 32ea43ece646..95bd17d3e927 100644
--- a/rust/kernel/net/phy.rs
+++ b/rust/kernel/net/phy.rs
@@ -6,7 +6,7 @@
//!
//! C headers: [`include/linux/phy.h`](srctree/include/linux/phy.h).
-use crate::{error::*, prelude::*, types::Opaque};
+use crate::{device_id::RawDeviceId, error::*, prelude::*, types::Opaque};
use core::{marker::PhantomData, ptr::addr_of_mut};
pub mod reg;
@@ -285,7 +285,7 @@ impl AsRef<kernel::device::Device> for Device {
fn as_ref(&self) -> &kernel::device::Device {
let phydev = self.0.get();
// SAFETY: The struct invariant ensures that `mdio.dev` is valid.
- unsafe { kernel::device::Device::as_ref(addr_of_mut!((*phydev).mdio.dev)) }
+ unsafe { kernel::device::Device::from_raw(addr_of_mut!((*phydev).mdio.dev)) }
}
}
@@ -507,7 +507,7 @@ pub const fn create_phy_driver<T: Driver>() -> DriverVTable {
DriverVTable(Opaque::new(bindings::phy_driver {
name: T::NAME.as_char_ptr().cast_mut(),
flags: T::FLAGS,
- phy_id: T::PHY_DEVICE_ID.id,
+ phy_id: T::PHY_DEVICE_ID.id(),
phy_id_mask: T::PHY_DEVICE_ID.mask_as_int(),
soft_reset: if T::HAS_SOFT_RESET {
Some(Adapter::<T>::soft_reset_callback)
@@ -691,42 +691,41 @@ impl Drop for Registration {
///
/// Represents the kernel's `struct mdio_device_id`. This is used to find an appropriate
/// PHY driver.
-pub struct DeviceId {
- id: u32,
- mask: DeviceMask,
-}
+#[repr(transparent)]
+#[derive(Clone, Copy)]
+pub struct DeviceId(bindings::mdio_device_id);
impl DeviceId {
/// Creates a new instance with the exact match mask.
pub const fn new_with_exact_mask(id: u32) -> Self {
- DeviceId {
- id,
- mask: DeviceMask::Exact,
- }
+ Self(bindings::mdio_device_id {
+ phy_id: id,
+ phy_id_mask: DeviceMask::Exact.as_int(),
+ })
}
/// Creates a new instance with the model match mask.
pub const fn new_with_model_mask(id: u32) -> Self {
- DeviceId {
- id,
- mask: DeviceMask::Model,
- }
+ Self(bindings::mdio_device_id {
+ phy_id: id,
+ phy_id_mask: DeviceMask::Model.as_int(),
+ })
}
/// Creates a new instance with the vendor match mask.
pub const fn new_with_vendor_mask(id: u32) -> Self {
- DeviceId {
- id,
- mask: DeviceMask::Vendor,
- }
+ Self(bindings::mdio_device_id {
+ phy_id: id,
+ phy_id_mask: DeviceMask::Vendor.as_int(),
+ })
}
/// Creates a new instance with a custom match mask.
pub const fn new_with_custom_mask(id: u32, mask: u32) -> Self {
- DeviceId {
- id,
- mask: DeviceMask::Custom(mask),
- }
+ Self(bindings::mdio_device_id {
+ phy_id: id,
+ phy_id_mask: DeviceMask::Custom(mask).as_int(),
+ })
}
/// Creates a new instance from [`Driver`].
@@ -734,21 +733,29 @@ impl DeviceId {
T::PHY_DEVICE_ID
}
- /// Get a `mask` as u32.
+ /// Get the MDIO device's PHY ID.
+ pub const fn id(&self) -> u32 {
+ self.0.phy_id
+ }
+
+ /// Get the MDIO device's match mask.
pub const fn mask_as_int(&self) -> u32 {
- self.mask.as_int()
+ self.0.phy_id_mask
}
// macro use only
#[doc(hidden)]
pub const fn mdio_device_id(&self) -> bindings::mdio_device_id {
- bindings::mdio_device_id {
- phy_id: self.id,
- phy_id_mask: self.mask.as_int(),
- }
+ self.0
}
}
+// SAFETY: `DeviceId` is a `#[repr(transparent)]` wrapper of `struct mdio_device_id`
+// and does not add additional invariants, so it's safe to transmute to `RawType`.
+unsafe impl RawDeviceId for DeviceId {
+ type RawType = bindings::mdio_device_id;
+}
+
enum DeviceMask {
Exact,
Model,
@@ -849,19 +856,18 @@ impl DeviceMask {
/// }
/// };
///
-/// const _DEVICE_TABLE: [::kernel::bindings::mdio_device_id; 2] = [
-/// ::kernel::bindings::mdio_device_id {
-/// phy_id: 0x00000001,
-/// phy_id_mask: 0xffffffff,
-/// },
-/// ::kernel::bindings::mdio_device_id {
-/// phy_id: 0,
-/// phy_id_mask: 0,
-/// },
-/// ];
-/// #[cfg(MODULE)]
-/// #[no_mangle]
-/// static __mod_device_table__mdio__phydev: [::kernel::bindings::mdio_device_id; 2] = _DEVICE_TABLE;
+/// const N: usize = 1;
+///
+/// const TABLE: ::kernel::device_id::IdArray<::kernel::net::phy::DeviceId, (), N> =
+/// ::kernel::device_id::IdArray::new_without_index([
+/// ::kernel::net::phy::DeviceId(
+/// ::kernel::bindings::mdio_device_id {
+/// phy_id: 0x00000001,
+/// phy_id_mask: 0xffffffff,
+/// }),
+/// ]);
+///
+/// ::kernel::module_device_table!("mdio", phydev, TABLE);
/// ```
#[macro_export]
macro_rules! module_phy_driver {
@@ -872,20 +878,12 @@ macro_rules! module_phy_driver {
};
(@device_table [$($dev:expr),+]) => {
- // SAFETY: C will not read off the end of this constant since the last element is zero.
- const _DEVICE_TABLE: [$crate::bindings::mdio_device_id;
- $crate::module_phy_driver!(@count_devices $($dev),+) + 1] = [
- $($dev.mdio_device_id()),+,
- $crate::bindings::mdio_device_id {
- phy_id: 0,
- phy_id_mask: 0
- }
- ];
+ const N: usize = $crate::module_phy_driver!(@count_devices $($dev),+);
+
+ const TABLE: $crate::device_id::IdArray<$crate::net::phy::DeviceId, (), N> =
+ $crate::device_id::IdArray::new_without_index([ $(($dev,())),+, ]);
- #[cfg(MODULE)]
- #[no_mangle]
- static __mod_device_table__mdio__phydev: [$crate::bindings::mdio_device_id;
- $crate::module_phy_driver!(@count_devices $($dev),+) + 1] = _DEVICE_TABLE;
+ $crate::module_device_table!("mdio", phydev, TABLE);
};
(drivers: [$($driver:ident),+ $(,)?], device_table: [$($dev:expr),+ $(,)?], $($f:tt)*) => {