1 // SPDX-License-Identifier: GPL-2.0 1 // SPDX-License-Identifier: GPL-2.0 2 2 3 // Copyright (C) 2023 FUJITA Tomonori <fujita.t 3 // Copyright (C) 2023 FUJITA Tomonori <fujita.tomonori@gmail.com> 4 4 5 //! Network PHY device. 5 //! Network PHY device. 6 //! 6 //! 7 //! C headers: [`include/linux/phy.h`](srctree 7 //! C headers: [`include/linux/phy.h`](srctree/include/linux/phy.h). 8 8 9 use crate::{error::*, prelude::*, types::Opaqu 9 use crate::{error::*, prelude::*, types::Opaque}; 10 use core::{marker::PhantomData, ptr::addr_of_m << 11 10 12 pub mod reg; !! 11 use core::marker::PhantomData; 13 12 14 /// PHY state machine states. 13 /// PHY state machine states. 15 /// 14 /// 16 /// Corresponds to the kernel's [`enum phy_sta 15 /// Corresponds to the kernel's [`enum phy_state`]. 17 /// 16 /// 18 /// Some of PHY drivers access to the state of 17 /// Some of PHY drivers access to the state of PHY's software state machine. 19 /// 18 /// 20 /// [`enum phy_state`]: srctree/include/linux/ 19 /// [`enum phy_state`]: srctree/include/linux/phy.h 21 #[derive(PartialEq, Eq)] 20 #[derive(PartialEq, Eq)] 22 pub enum DeviceState { 21 pub enum DeviceState { 23 /// PHY device and driver are not ready fo 22 /// PHY device and driver are not ready for anything. 24 Down, 23 Down, 25 /// PHY is ready to send and receive packe 24 /// PHY is ready to send and receive packets. 26 Ready, 25 Ready, 27 /// PHY is up, but no polling or interrupt 26 /// PHY is up, but no polling or interrupts are done. 28 Halted, 27 Halted, 29 /// PHY is up, but is in an error state. 28 /// PHY is up, but is in an error state. 30 Error, 29 Error, 31 /// PHY and attached device are ready to d 30 /// PHY and attached device are ready to do work. 32 Up, 31 Up, 33 /// PHY is currently running. 32 /// PHY is currently running. 34 Running, 33 Running, 35 /// PHY is up, but not currently plugged i 34 /// PHY is up, but not currently plugged in. 36 NoLink, 35 NoLink, 37 /// PHY is performing a cable test. 36 /// PHY is performing a cable test. 38 CableTest, 37 CableTest, 39 } 38 } 40 39 41 /// A mode of Ethernet communication. 40 /// A mode of Ethernet communication. 42 /// 41 /// 43 /// PHY drivers get duplex information from ha 42 /// PHY drivers get duplex information from hardware and update the current state. 44 pub enum DuplexMode { 43 pub enum DuplexMode { 45 /// PHY is in full-duplex mode. 44 /// PHY is in full-duplex mode. 46 Full, 45 Full, 47 /// PHY is in half-duplex mode. 46 /// PHY is in half-duplex mode. 48 Half, 47 Half, 49 /// PHY is in unknown duplex mode. 48 /// PHY is in unknown duplex mode. 50 Unknown, 49 Unknown, 51 } 50 } 52 51 53 /// An instance of a PHY device. 52 /// An instance of a PHY device. 54 /// 53 /// 55 /// Wraps the kernel's [`struct phy_device`]. 54 /// Wraps the kernel's [`struct phy_device`]. 56 /// 55 /// 57 /// A [`Device`] instance is created when a ca 56 /// A [`Device`] instance is created when a callback in [`Driver`] is executed. A PHY driver 58 /// executes [`Driver`]'s methods during the c 57 /// executes [`Driver`]'s methods during the callback. 59 /// 58 /// 60 /// # Invariants 59 /// # Invariants 61 /// 60 /// 62 /// - Referencing a `phy_device` using this st !! 61 /// Referencing a `phy_device` using this struct asserts that you are in 63 /// a context where all methods defined on t !! 62 /// a context where all methods defined on this struct are safe to call. 64 /// - This struct always has a valid `self.0.m << 65 /// 63 /// 66 /// [`struct phy_device`]: srctree/include/lin 64 /// [`struct phy_device`]: srctree/include/linux/phy.h 67 // During the calls to most functions in [`Dri 65 // During the calls to most functions in [`Driver`], the C side (`PHYLIB`) holds a lock that is 68 // unique for every instance of [`Device`]. `P 66 // unique for every instance of [`Device`]. `PHYLIB` uses a different serialization technique for 69 // [`Driver::resume`] and [`Driver::suspend`]: 67 // [`Driver::resume`] and [`Driver::suspend`]: `PHYLIB` updates `phy_device`'s state with 70 // the lock held, thus guaranteeing that [`Dri 68 // the lock held, thus guaranteeing that [`Driver::resume`] has exclusive access to the instance. 71 // [`Driver::resume`] and [`Driver::suspend`] 69 // [`Driver::resume`] and [`Driver::suspend`] also are called where only one thread can access 72 // to the instance. 70 // to the instance. 73 #[repr(transparent)] 71 #[repr(transparent)] 74 pub struct Device(Opaque<bindings::phy_device> 72 pub struct Device(Opaque<bindings::phy_device>); 75 73 76 impl Device { 74 impl Device { 77 /// Creates a new [`Device`] instance from 75 /// Creates a new [`Device`] instance from a raw pointer. 78 /// 76 /// 79 /// # Safety 77 /// # Safety 80 /// 78 /// 81 /// For the duration of `'a`, !! 79 /// For the duration of 'a, the pointer must point at a valid `phy_device`, 82 /// - the pointer must point at a valid `p !! 80 /// and the caller must be in a context where all methods defined on this struct 83 /// must be in a context where all metho !! 81 /// are safe to call. 84 /// are safe to call. << 85 /// - `(*ptr).mdio.dev` must be a valid. << 86 unsafe fn from_raw<'a>(ptr: *mut bindings: 82 unsafe fn from_raw<'a>(ptr: *mut bindings::phy_device) -> &'a mut Self { 87 // CAST: `Self` is a `repr(transparent 83 // CAST: `Self` is a `repr(transparent)` wrapper around `bindings::phy_device`. 88 let ptr = ptr.cast::<Self>(); 84 let ptr = ptr.cast::<Self>(); 89 // SAFETY: by the function requirement 85 // SAFETY: by the function requirements the pointer is valid and we have unique access for 90 // the duration of `'a`. 86 // the duration of `'a`. 91 unsafe { &mut *ptr } 87 unsafe { &mut *ptr } 92 } 88 } 93 89 94 /// Gets the id of the PHY. 90 /// Gets the id of the PHY. 95 pub fn phy_id(&self) -> u32 { 91 pub fn phy_id(&self) -> u32 { 96 let phydev = self.0.get(); 92 let phydev = self.0.get(); 97 // SAFETY: The struct invariant ensure 93 // SAFETY: The struct invariant ensures that we may access 98 // this field without additional synch 94 // this field without additional synchronization. 99 unsafe { (*phydev).phy_id } 95 unsafe { (*phydev).phy_id } 100 } 96 } 101 97 102 /// Gets the state of PHY state machine st 98 /// Gets the state of PHY state machine states. 103 pub fn state(&self) -> DeviceState { 99 pub fn state(&self) -> DeviceState { 104 let phydev = self.0.get(); 100 let phydev = self.0.get(); 105 // SAFETY: The struct invariant ensure 101 // SAFETY: The struct invariant ensures that we may access 106 // this field without additional synch 102 // this field without additional synchronization. 107 let state = unsafe { (*phydev).state } 103 let state = unsafe { (*phydev).state }; 108 // TODO: this conversion code will be 104 // TODO: this conversion code will be replaced with automatically generated code by bindgen 109 // when it becomes possible. 105 // when it becomes possible. 110 match state { 106 match state { 111 bindings::phy_state_PHY_DOWN => De 107 bindings::phy_state_PHY_DOWN => DeviceState::Down, 112 bindings::phy_state_PHY_READY => D 108 bindings::phy_state_PHY_READY => DeviceState::Ready, 113 bindings::phy_state_PHY_HALTED => 109 bindings::phy_state_PHY_HALTED => DeviceState::Halted, 114 bindings::phy_state_PHY_ERROR => D 110 bindings::phy_state_PHY_ERROR => DeviceState::Error, 115 bindings::phy_state_PHY_UP => Devi 111 bindings::phy_state_PHY_UP => DeviceState::Up, 116 bindings::phy_state_PHY_RUNNING => 112 bindings::phy_state_PHY_RUNNING => DeviceState::Running, 117 bindings::phy_state_PHY_NOLINK => 113 bindings::phy_state_PHY_NOLINK => DeviceState::NoLink, 118 bindings::phy_state_PHY_CABLETEST 114 bindings::phy_state_PHY_CABLETEST => DeviceState::CableTest, 119 _ => DeviceState::Error, 115 _ => DeviceState::Error, 120 } 116 } 121 } 117 } 122 118 123 /// Gets the current link state. 119 /// Gets the current link state. 124 /// 120 /// 125 /// It returns true if the link is up. 121 /// It returns true if the link is up. 126 pub fn is_link_up(&self) -> bool { 122 pub fn is_link_up(&self) -> bool { 127 const LINK_IS_UP: u64 = 1; 123 const LINK_IS_UP: u64 = 1; 128 // TODO: the code to access to the bit 124 // TODO: the code to access to the bit field will be replaced with automatically 129 // generated code by bindgen when it b 125 // generated code by bindgen when it becomes possible. 130 // SAFETY: The struct invariant ensure 126 // SAFETY: The struct invariant ensures that we may access 131 // this field without additional synch 127 // this field without additional synchronization. 132 let bit_field = unsafe { &(*self.0.get 128 let bit_field = unsafe { &(*self.0.get())._bitfield_1 }; 133 bit_field.get(14, 1) == LINK_IS_UP 129 bit_field.get(14, 1) == LINK_IS_UP 134 } 130 } 135 131 136 /// Gets the current auto-negotiation conf 132 /// Gets the current auto-negotiation configuration. 137 /// 133 /// 138 /// It returns true if auto-negotiation is 134 /// It returns true if auto-negotiation is enabled. 139 pub fn is_autoneg_enabled(&self) -> bool { 135 pub fn is_autoneg_enabled(&self) -> bool { 140 // TODO: the code to access to the bit 136 // TODO: the code to access to the bit field will be replaced with automatically 141 // generated code by bindgen when it b 137 // generated code by bindgen when it becomes possible. 142 // SAFETY: The struct invariant ensure 138 // SAFETY: The struct invariant ensures that we may access 143 // this field without additional synch 139 // this field without additional synchronization. 144 let bit_field = unsafe { &(*self.0.get 140 let bit_field = unsafe { &(*self.0.get())._bitfield_1 }; 145 bit_field.get(13, 1) == bindings::AUTO 141 bit_field.get(13, 1) == bindings::AUTONEG_ENABLE as u64 146 } 142 } 147 143 148 /// Gets the current auto-negotiation stat 144 /// Gets the current auto-negotiation state. 149 /// 145 /// 150 /// It returns true if auto-negotiation is 146 /// It returns true if auto-negotiation is completed. 151 pub fn is_autoneg_completed(&self) -> bool 147 pub fn is_autoneg_completed(&self) -> bool { 152 const AUTONEG_COMPLETED: u64 = 1; 148 const AUTONEG_COMPLETED: u64 = 1; 153 // TODO: the code to access to the bit 149 // TODO: the code to access to the bit field will be replaced with automatically 154 // generated code by bindgen when it b 150 // generated code by bindgen when it becomes possible. 155 // SAFETY: The struct invariant ensure 151 // SAFETY: The struct invariant ensures that we may access 156 // this field without additional synch 152 // this field without additional synchronization. 157 let bit_field = unsafe { &(*self.0.get 153 let bit_field = unsafe { &(*self.0.get())._bitfield_1 }; 158 bit_field.get(15, 1) == AUTONEG_COMPLE 154 bit_field.get(15, 1) == AUTONEG_COMPLETED 159 } 155 } 160 156 161 /// Sets the speed of the PHY. 157 /// Sets the speed of the PHY. 162 pub fn set_speed(&mut self, speed: u32) { 158 pub fn set_speed(&mut self, speed: u32) { 163 let phydev = self.0.get(); 159 let phydev = self.0.get(); 164 // SAFETY: The struct invariant ensure 160 // SAFETY: The struct invariant ensures that we may access 165 // this field without additional synch 161 // this field without additional synchronization. 166 unsafe { (*phydev).speed = speed as i3 162 unsafe { (*phydev).speed = speed as i32 }; 167 } 163 } 168 164 169 /// Sets duplex mode. 165 /// Sets duplex mode. 170 pub fn set_duplex(&mut self, mode: DuplexM 166 pub fn set_duplex(&mut self, mode: DuplexMode) { 171 let phydev = self.0.get(); 167 let phydev = self.0.get(); 172 let v = match mode { 168 let v = match mode { 173 DuplexMode::Full => bindings::DUPL 169 DuplexMode::Full => bindings::DUPLEX_FULL as i32, 174 DuplexMode::Half => bindings::DUPL 170 DuplexMode::Half => bindings::DUPLEX_HALF as i32, 175 DuplexMode::Unknown => bindings::D 171 DuplexMode::Unknown => bindings::DUPLEX_UNKNOWN as i32, 176 }; 172 }; 177 // SAFETY: The struct invariant ensure 173 // SAFETY: The struct invariant ensures that we may access 178 // this field without additional synch 174 // this field without additional synchronization. 179 unsafe { (*phydev).duplex = v }; 175 unsafe { (*phydev).duplex = v }; 180 } 176 } 181 177 182 /// Reads a PHY register. !! 178 /// Reads a given C22 PHY register. 183 // This function reads a hardware register 179 // This function reads a hardware register and updates the stats so takes `&mut self`. 184 pub fn read<R: reg::Register>(&mut self, r !! 180 pub fn read(&mut self, regnum: u16) -> Result<u16> { 185 reg.read(self) !! 181 let phydev = self.0.get(); >> 182 // SAFETY: `phydev` is pointing to a valid object by the type invariant of `Self`. >> 183 // So it's just an FFI call, open code of `phy_read()` with a valid `phy_device` pointer >> 184 // `phydev`. >> 185 let ret = unsafe { >> 186 bindings::mdiobus_read((*phydev).mdio.bus, (*phydev).mdio.addr, regnum.into()) >> 187 }; >> 188 if ret < 0 { >> 189 Err(Error::from_errno(ret)) >> 190 } else { >> 191 Ok(ret as u16) >> 192 } 186 } 193 } 187 194 188 /// Writes a PHY register. !! 195 /// Writes a given C22 PHY register. 189 pub fn write<R: reg::Register>(&mut self, !! 196 pub fn write(&mut self, regnum: u16, val: u16) -> Result { 190 reg.write(self, val) !! 197 let phydev = self.0.get(); >> 198 // SAFETY: `phydev` is pointing to a valid object by the type invariant of `Self`. >> 199 // So it's just an FFI call, open code of `phy_write()` with a valid `phy_device` pointer >> 200 // `phydev`. >> 201 to_result(unsafe { >> 202 bindings::mdiobus_write((*phydev).mdio.bus, (*phydev).mdio.addr, regnum.into(), val) >> 203 }) 191 } 204 } 192 205 193 /// Reads a paged register. 206 /// Reads a paged register. 194 pub fn read_paged(&mut self, page: u16, re 207 pub fn read_paged(&mut self, page: u16, regnum: u16) -> Result<u16> { 195 let phydev = self.0.get(); 208 let phydev = self.0.get(); 196 // SAFETY: `phydev` is pointing to a v 209 // SAFETY: `phydev` is pointing to a valid object by the type invariant of `Self`. 197 // So it's just an FFI call. 210 // So it's just an FFI call. 198 let ret = unsafe { bindings::phy_read_ 211 let ret = unsafe { bindings::phy_read_paged(phydev, page.into(), regnum.into()) }; 199 if ret < 0 { 212 if ret < 0 { 200 Err(Error::from_errno(ret)) 213 Err(Error::from_errno(ret)) 201 } else { 214 } else { 202 Ok(ret as u16) 215 Ok(ret as u16) 203 } 216 } 204 } 217 } 205 218 206 /// Resolves the advertisements into PHY s 219 /// Resolves the advertisements into PHY settings. 207 pub fn resolve_aneg_linkmode(&mut self) { 220 pub fn resolve_aneg_linkmode(&mut self) { 208 let phydev = self.0.get(); 221 let phydev = self.0.get(); 209 // SAFETY: `phydev` is pointing to a v 222 // SAFETY: `phydev` is pointing to a valid object by the type invariant of `Self`. 210 // So it's just an FFI call. 223 // So it's just an FFI call. 211 unsafe { bindings::phy_resolve_aneg_li 224 unsafe { bindings::phy_resolve_aneg_linkmode(phydev) }; 212 } 225 } 213 226 214 /// Executes software reset the PHY via `B 227 /// Executes software reset the PHY via `BMCR_RESET` bit. 215 pub fn genphy_soft_reset(&mut self) -> Res 228 pub fn genphy_soft_reset(&mut self) -> Result { 216 let phydev = self.0.get(); 229 let phydev = self.0.get(); 217 // SAFETY: `phydev` is pointing to a v 230 // SAFETY: `phydev` is pointing to a valid object by the type invariant of `Self`. 218 // So it's just an FFI call. 231 // So it's just an FFI call. 219 to_result(unsafe { bindings::genphy_so 232 to_result(unsafe { bindings::genphy_soft_reset(phydev) }) 220 } 233 } 221 234 222 /// Initializes the PHY. 235 /// Initializes the PHY. 223 pub fn init_hw(&mut self) -> Result { 236 pub fn init_hw(&mut self) -> Result { 224 let phydev = self.0.get(); 237 let phydev = self.0.get(); 225 // SAFETY: `phydev` is pointing to a v 238 // SAFETY: `phydev` is pointing to a valid object by the type invariant of `Self`. 226 // So it's just an FFI call. 239 // So it's just an FFI call. 227 to_result(unsafe { bindings::phy_init_ 240 to_result(unsafe { bindings::phy_init_hw(phydev) }) 228 } 241 } 229 242 230 /// Starts auto-negotiation. 243 /// Starts auto-negotiation. 231 pub fn start_aneg(&mut self) -> Result { 244 pub fn start_aneg(&mut self) -> Result { 232 let phydev = self.0.get(); 245 let phydev = self.0.get(); 233 // SAFETY: `phydev` is pointing to a v 246 // SAFETY: `phydev` is pointing to a valid object by the type invariant of `Self`. 234 // So it's just an FFI call. 247 // So it's just an FFI call. 235 to_result(unsafe { bindings::_phy_star 248 to_result(unsafe { bindings::_phy_start_aneg(phydev) }) 236 } 249 } 237 250 238 /// Resumes the PHY via `BMCR_PDOWN` bit. 251 /// Resumes the PHY via `BMCR_PDOWN` bit. 239 pub fn genphy_resume(&mut self) -> Result 252 pub fn genphy_resume(&mut self) -> Result { 240 let phydev = self.0.get(); 253 let phydev = self.0.get(); 241 // SAFETY: `phydev` is pointing to a v 254 // SAFETY: `phydev` is pointing to a valid object by the type invariant of `Self`. 242 // So it's just an FFI call. 255 // So it's just an FFI call. 243 to_result(unsafe { bindings::genphy_re 256 to_result(unsafe { bindings::genphy_resume(phydev) }) 244 } 257 } 245 258 246 /// Suspends the PHY via `BMCR_PDOWN` bit. 259 /// Suspends the PHY via `BMCR_PDOWN` bit. 247 pub fn genphy_suspend(&mut self) -> Result 260 pub fn genphy_suspend(&mut self) -> Result { 248 let phydev = self.0.get(); 261 let phydev = self.0.get(); 249 // SAFETY: `phydev` is pointing to a v 262 // SAFETY: `phydev` is pointing to a valid object by the type invariant of `Self`. 250 // So it's just an FFI call. 263 // So it's just an FFI call. 251 to_result(unsafe { bindings::genphy_su 264 to_result(unsafe { bindings::genphy_suspend(phydev) }) 252 } 265 } 253 266 254 /// Checks the link status and updates cur 267 /// Checks the link status and updates current link state. 255 pub fn genphy_read_status<R: reg::Register !! 268 pub fn genphy_read_status(&mut self) -> Result<u16> { 256 R::read_status(self) !! 269 let phydev = self.0.get(); >> 270 // SAFETY: `phydev` is pointing to a valid object by the type invariant of `Self`. >> 271 // So it's just an FFI call. >> 272 let ret = unsafe { bindings::genphy_read_status(phydev) }; >> 273 if ret < 0 { >> 274 Err(Error::from_errno(ret)) >> 275 } else { >> 276 Ok(ret as u16) >> 277 } 257 } 278 } 258 279 259 /// Updates the link status. 280 /// Updates the link status. 260 pub fn genphy_update_link(&mut self) -> Re 281 pub fn genphy_update_link(&mut self) -> Result { 261 let phydev = self.0.get(); 282 let phydev = self.0.get(); 262 // SAFETY: `phydev` is pointing to a v 283 // SAFETY: `phydev` is pointing to a valid object by the type invariant of `Self`. 263 // So it's just an FFI call. 284 // So it's just an FFI call. 264 to_result(unsafe { bindings::genphy_up 285 to_result(unsafe { bindings::genphy_update_link(phydev) }) 265 } 286 } 266 287 267 /// Reads link partner ability. 288 /// Reads link partner ability. 268 pub fn genphy_read_lpa(&mut self) -> Resul 289 pub fn genphy_read_lpa(&mut self) -> Result { 269 let phydev = self.0.get(); 290 let phydev = self.0.get(); 270 // SAFETY: `phydev` is pointing to a v 291 // SAFETY: `phydev` is pointing to a valid object by the type invariant of `Self`. 271 // So it's just an FFI call. 292 // So it's just an FFI call. 272 to_result(unsafe { bindings::genphy_re 293 to_result(unsafe { bindings::genphy_read_lpa(phydev) }) 273 } 294 } 274 295 275 /// Reads PHY abilities. 296 /// Reads PHY abilities. 276 pub fn genphy_read_abilities(&mut self) -> 297 pub fn genphy_read_abilities(&mut self) -> Result { 277 let phydev = self.0.get(); 298 let phydev = self.0.get(); 278 // SAFETY: `phydev` is pointing to a v 299 // SAFETY: `phydev` is pointing to a valid object by the type invariant of `Self`. 279 // So it's just an FFI call. 300 // So it's just an FFI call. 280 to_result(unsafe { bindings::genphy_re 301 to_result(unsafe { bindings::genphy_read_abilities(phydev) }) 281 } 302 } 282 } 303 } 283 304 284 impl AsRef<kernel::device::Device> for Device << 285 fn as_ref(&self) -> &kernel::device::Devic << 286 let phydev = self.0.get(); << 287 // SAFETY: The struct invariant ensure << 288 unsafe { kernel::device::Device::as_re << 289 } << 290 } << 291 << 292 /// Defines certain other features this PHY su 305 /// Defines certain other features this PHY supports (like interrupts). 293 /// 306 /// 294 /// These flag values are used in [`Driver::FL 307 /// These flag values are used in [`Driver::FLAGS`]. 295 pub mod flags { 308 pub mod flags { 296 /// PHY is internal. 309 /// PHY is internal. 297 pub const IS_INTERNAL: u32 = bindings::PHY 310 pub const IS_INTERNAL: u32 = bindings::PHY_IS_INTERNAL; 298 /// PHY needs to be reset after the refclk 311 /// PHY needs to be reset after the refclk is enabled. 299 pub const RST_AFTER_CLK_EN: u32 = bindings 312 pub const RST_AFTER_CLK_EN: u32 = bindings::PHY_RST_AFTER_CLK_EN; 300 /// Polling is used to detect PHY status c 313 /// Polling is used to detect PHY status changes. 301 pub const POLL_CABLE_TEST: u32 = bindings: 314 pub const POLL_CABLE_TEST: u32 = bindings::PHY_POLL_CABLE_TEST; 302 /// Don't suspend. 315 /// Don't suspend. 303 pub const ALWAYS_CALL_SUSPEND: u32 = bindi 316 pub const ALWAYS_CALL_SUSPEND: u32 = bindings::PHY_ALWAYS_CALL_SUSPEND; 304 } 317 } 305 318 306 /// An adapter for the registration of a PHY d 319 /// An adapter for the registration of a PHY driver. 307 struct Adapter<T: Driver> { 320 struct Adapter<T: Driver> { 308 _p: PhantomData<T>, 321 _p: PhantomData<T>, 309 } 322 } 310 323 311 impl<T: Driver> Adapter<T> { 324 impl<T: Driver> Adapter<T> { 312 /// # Safety 325 /// # Safety 313 /// 326 /// 314 /// `phydev` must be passed by the corresp 327 /// `phydev` must be passed by the corresponding callback in `phy_driver`. 315 unsafe extern "C" fn soft_reset_callback( 328 unsafe extern "C" fn soft_reset_callback( 316 phydev: *mut bindings::phy_device, 329 phydev: *mut bindings::phy_device, 317 ) -> core::ffi::c_int { 330 ) -> core::ffi::c_int { 318 from_result(|| { 331 from_result(|| { 319 // SAFETY: This callback is called 332 // SAFETY: This callback is called only in contexts 320 // where we hold `phy_device->lock 333 // where we hold `phy_device->lock`, so the accessors on 321 // `Device` are okay to call. 334 // `Device` are okay to call. 322 let dev = unsafe { Device::from_ra 335 let dev = unsafe { Device::from_raw(phydev) }; 323 T::soft_reset(dev)?; 336 T::soft_reset(dev)?; 324 Ok(0) 337 Ok(0) 325 }) 338 }) 326 } 339 } 327 340 328 /// # Safety 341 /// # Safety 329 /// 342 /// 330 /// `phydev` must be passed by the corresp 343 /// `phydev` must be passed by the corresponding callback in `phy_driver`. 331 unsafe extern "C" fn probe_callback(phydev << 332 from_result(|| { << 333 // SAFETY: This callback is called << 334 // where we can exclusively access << 335 // it's not published yet, so the << 336 // to call. << 337 let dev = unsafe { Device::from_ra << 338 T::probe(dev)?; << 339 Ok(0) << 340 }) << 341 } << 342 << 343 /// # Safety << 344 /// << 345 /// `phydev` must be passed by the corresp << 346 unsafe extern "C" fn get_features_callback 344 unsafe extern "C" fn get_features_callback( 347 phydev: *mut bindings::phy_device, 345 phydev: *mut bindings::phy_device, 348 ) -> core::ffi::c_int { 346 ) -> core::ffi::c_int { 349 from_result(|| { 347 from_result(|| { 350 // SAFETY: This callback is called 348 // SAFETY: This callback is called only in contexts 351 // where we hold `phy_device->lock 349 // where we hold `phy_device->lock`, so the accessors on 352 // `Device` are okay to call. 350 // `Device` are okay to call. 353 let dev = unsafe { Device::from_ra 351 let dev = unsafe { Device::from_raw(phydev) }; 354 T::get_features(dev)?; 352 T::get_features(dev)?; 355 Ok(0) 353 Ok(0) 356 }) 354 }) 357 } 355 } 358 356 359 /// # Safety 357 /// # Safety 360 /// 358 /// 361 /// `phydev` must be passed by the corresp 359 /// `phydev` must be passed by the corresponding callback in `phy_driver`. 362 unsafe extern "C" fn suspend_callback(phyd 360 unsafe extern "C" fn suspend_callback(phydev: *mut bindings::phy_device) -> core::ffi::c_int { 363 from_result(|| { 361 from_result(|| { 364 // SAFETY: The C core code ensures 362 // SAFETY: The C core code ensures that the accessors on 365 // `Device` are okay to call even 363 // `Device` are okay to call even though `phy_device->lock` 366 // might not be held. 364 // might not be held. 367 let dev = unsafe { Device::from_ra 365 let dev = unsafe { Device::from_raw(phydev) }; 368 T::suspend(dev)?; 366 T::suspend(dev)?; 369 Ok(0) 367 Ok(0) 370 }) 368 }) 371 } 369 } 372 370 373 /// # Safety 371 /// # Safety 374 /// 372 /// 375 /// `phydev` must be passed by the corresp 373 /// `phydev` must be passed by the corresponding callback in `phy_driver`. 376 unsafe extern "C" fn resume_callback(phyde 374 unsafe extern "C" fn resume_callback(phydev: *mut bindings::phy_device) -> core::ffi::c_int { 377 from_result(|| { 375 from_result(|| { 378 // SAFETY: The C core code ensures 376 // SAFETY: The C core code ensures that the accessors on 379 // `Device` are okay to call even 377 // `Device` are okay to call even though `phy_device->lock` 380 // might not be held. 378 // might not be held. 381 let dev = unsafe { Device::from_ra 379 let dev = unsafe { Device::from_raw(phydev) }; 382 T::resume(dev)?; 380 T::resume(dev)?; 383 Ok(0) 381 Ok(0) 384 }) 382 }) 385 } 383 } 386 384 387 /// # Safety 385 /// # Safety 388 /// 386 /// 389 /// `phydev` must be passed by the corresp 387 /// `phydev` must be passed by the corresponding callback in `phy_driver`. 390 unsafe extern "C" fn config_aneg_callback( 388 unsafe extern "C" fn config_aneg_callback( 391 phydev: *mut bindings::phy_device, 389 phydev: *mut bindings::phy_device, 392 ) -> core::ffi::c_int { 390 ) -> core::ffi::c_int { 393 from_result(|| { 391 from_result(|| { 394 // SAFETY: This callback is called 392 // SAFETY: This callback is called only in contexts 395 // where we hold `phy_device->lock 393 // where we hold `phy_device->lock`, so the accessors on 396 // `Device` are okay to call. 394 // `Device` are okay to call. 397 let dev = unsafe { Device::from_ra 395 let dev = unsafe { Device::from_raw(phydev) }; 398 T::config_aneg(dev)?; 396 T::config_aneg(dev)?; 399 Ok(0) 397 Ok(0) 400 }) 398 }) 401 } 399 } 402 400 403 /// # Safety 401 /// # Safety 404 /// 402 /// 405 /// `phydev` must be passed by the corresp 403 /// `phydev` must be passed by the corresponding callback in `phy_driver`. 406 unsafe extern "C" fn read_status_callback( 404 unsafe extern "C" fn read_status_callback( 407 phydev: *mut bindings::phy_device, 405 phydev: *mut bindings::phy_device, 408 ) -> core::ffi::c_int { 406 ) -> core::ffi::c_int { 409 from_result(|| { 407 from_result(|| { 410 // SAFETY: This callback is called 408 // SAFETY: This callback is called only in contexts 411 // where we hold `phy_device->lock 409 // where we hold `phy_device->lock`, so the accessors on 412 // `Device` are okay to call. 410 // `Device` are okay to call. 413 let dev = unsafe { Device::from_ra 411 let dev = unsafe { Device::from_raw(phydev) }; 414 T::read_status(dev)?; 412 T::read_status(dev)?; 415 Ok(0) 413 Ok(0) 416 }) 414 }) 417 } 415 } 418 416 419 /// # Safety 417 /// # Safety 420 /// 418 /// 421 /// `phydev` must be passed by the corresp 419 /// `phydev` must be passed by the corresponding callback in `phy_driver`. 422 unsafe extern "C" fn match_phy_device_call 420 unsafe extern "C" fn match_phy_device_callback( 423 phydev: *mut bindings::phy_device, 421 phydev: *mut bindings::phy_device, 424 ) -> core::ffi::c_int { 422 ) -> core::ffi::c_int { 425 // SAFETY: This callback is called onl 423 // SAFETY: This callback is called only in contexts 426 // where we hold `phy_device->lock`, s 424 // where we hold `phy_device->lock`, so the accessors on 427 // `Device` are okay to call. 425 // `Device` are okay to call. 428 let dev = unsafe { Device::from_raw(ph 426 let dev = unsafe { Device::from_raw(phydev) }; 429 T::match_phy_device(dev) as i32 427 T::match_phy_device(dev) as i32 430 } 428 } 431 429 432 /// # Safety 430 /// # Safety 433 /// 431 /// 434 /// `phydev` must be passed by the corresp 432 /// `phydev` must be passed by the corresponding callback in `phy_driver`. 435 unsafe extern "C" fn read_mmd_callback( 433 unsafe extern "C" fn read_mmd_callback( 436 phydev: *mut bindings::phy_device, 434 phydev: *mut bindings::phy_device, 437 devnum: i32, 435 devnum: i32, 438 regnum: u16, 436 regnum: u16, 439 ) -> i32 { 437 ) -> i32 { 440 from_result(|| { 438 from_result(|| { 441 // SAFETY: This callback is called 439 // SAFETY: This callback is called only in contexts 442 // where we hold `phy_device->lock 440 // where we hold `phy_device->lock`, so the accessors on 443 // `Device` are okay to call. 441 // `Device` are okay to call. 444 let dev = unsafe { Device::from_ra 442 let dev = unsafe { Device::from_raw(phydev) }; 445 // CAST: the C side verifies devnu 443 // CAST: the C side verifies devnum < 32. 446 let ret = T::read_mmd(dev, devnum 444 let ret = T::read_mmd(dev, devnum as u8, regnum)?; 447 Ok(ret.into()) 445 Ok(ret.into()) 448 }) 446 }) 449 } 447 } 450 448 451 /// # Safety 449 /// # Safety 452 /// 450 /// 453 /// `phydev` must be passed by the corresp 451 /// `phydev` must be passed by the corresponding callback in `phy_driver`. 454 unsafe extern "C" fn write_mmd_callback( 452 unsafe extern "C" fn write_mmd_callback( 455 phydev: *mut bindings::phy_device, 453 phydev: *mut bindings::phy_device, 456 devnum: i32, 454 devnum: i32, 457 regnum: u16, 455 regnum: u16, 458 val: u16, 456 val: u16, 459 ) -> i32 { 457 ) -> i32 { 460 from_result(|| { 458 from_result(|| { 461 // SAFETY: This callback is called 459 // SAFETY: This callback is called only in contexts 462 // where we hold `phy_device->lock 460 // where we hold `phy_device->lock`, so the accessors on 463 // `Device` are okay to call. 461 // `Device` are okay to call. 464 let dev = unsafe { Device::from_ra 462 let dev = unsafe { Device::from_raw(phydev) }; 465 T::write_mmd(dev, devnum as u8, re 463 T::write_mmd(dev, devnum as u8, regnum, val)?; 466 Ok(0) 464 Ok(0) 467 }) 465 }) 468 } 466 } 469 467 470 /// # Safety 468 /// # Safety 471 /// 469 /// 472 /// `phydev` must be passed by the corresp 470 /// `phydev` must be passed by the corresponding callback in `phy_driver`. 473 unsafe extern "C" fn link_change_notify_ca 471 unsafe extern "C" fn link_change_notify_callback(phydev: *mut bindings::phy_device) { 474 // SAFETY: This callback is called onl 472 // SAFETY: This callback is called only in contexts 475 // where we hold `phy_device->lock`, s 473 // where we hold `phy_device->lock`, so the accessors on 476 // `Device` are okay to call. 474 // `Device` are okay to call. 477 let dev = unsafe { Device::from_raw(ph 475 let dev = unsafe { Device::from_raw(phydev) }; 478 T::link_change_notify(dev); 476 T::link_change_notify(dev); 479 } 477 } 480 } 478 } 481 479 482 /// Driver structure for a particular PHY type 480 /// Driver structure for a particular PHY type. 483 /// 481 /// 484 /// Wraps the kernel's [`struct phy_driver`]. 482 /// Wraps the kernel's [`struct phy_driver`]. 485 /// This is used to register a driver for a pa 483 /// This is used to register a driver for a particular PHY type with the kernel. 486 /// 484 /// 487 /// # Invariants 485 /// # Invariants 488 /// 486 /// 489 /// `self.0` is always in a valid state. 487 /// `self.0` is always in a valid state. 490 /// 488 /// 491 /// [`struct phy_driver`]: srctree/include/lin 489 /// [`struct phy_driver`]: srctree/include/linux/phy.h 492 #[repr(transparent)] 490 #[repr(transparent)] 493 pub struct DriverVTable(Opaque<bindings::phy_d 491 pub struct DriverVTable(Opaque<bindings::phy_driver>); 494 492 495 // SAFETY: `DriverVTable` doesn't expose any & 493 // SAFETY: `DriverVTable` doesn't expose any &self method to access internal data, so it's safe to 496 // share `&DriverVTable` across execution cont !! 494 // share `&DriverVTable` across execution context boundries. 497 unsafe impl Sync for DriverVTable {} 495 unsafe impl Sync for DriverVTable {} 498 496 499 /// Creates a [`DriverVTable`] instance from [ 497 /// Creates a [`DriverVTable`] instance from [`Driver`]. 500 /// 498 /// 501 /// This is used by [`module_phy_driver`] macr 499 /// This is used by [`module_phy_driver`] macro to create a static array of `phy_driver`. 502 /// 500 /// 503 /// [`module_phy_driver`]: crate::module_phy_d 501 /// [`module_phy_driver`]: crate::module_phy_driver 504 pub const fn create_phy_driver<T: Driver>() -> 502 pub const fn create_phy_driver<T: Driver>() -> DriverVTable { 505 // INVARIANT: All the fields of `struct ph 503 // INVARIANT: All the fields of `struct phy_driver` are initialized properly. 506 DriverVTable(Opaque::new(bindings::phy_dri 504 DriverVTable(Opaque::new(bindings::phy_driver { 507 name: T::NAME.as_char_ptr().cast_mut() 505 name: T::NAME.as_char_ptr().cast_mut(), 508 flags: T::FLAGS, 506 flags: T::FLAGS, 509 phy_id: T::PHY_DEVICE_ID.id, 507 phy_id: T::PHY_DEVICE_ID.id, 510 phy_id_mask: T::PHY_DEVICE_ID.mask_as_ 508 phy_id_mask: T::PHY_DEVICE_ID.mask_as_int(), 511 soft_reset: if T::HAS_SOFT_RESET { 509 soft_reset: if T::HAS_SOFT_RESET { 512 Some(Adapter::<T>::soft_reset_call 510 Some(Adapter::<T>::soft_reset_callback) 513 } else { 511 } else { 514 None 512 None 515 }, 513 }, 516 probe: if T::HAS_PROBE { << 517 Some(Adapter::<T>::probe_callback) << 518 } else { << 519 None << 520 }, << 521 get_features: if T::HAS_GET_FEATURES { 514 get_features: if T::HAS_GET_FEATURES { 522 Some(Adapter::<T>::get_features_ca 515 Some(Adapter::<T>::get_features_callback) 523 } else { 516 } else { 524 None 517 None 525 }, 518 }, 526 match_phy_device: if T::HAS_MATCH_PHY_ 519 match_phy_device: if T::HAS_MATCH_PHY_DEVICE { 527 Some(Adapter::<T>::match_phy_devic 520 Some(Adapter::<T>::match_phy_device_callback) 528 } else { 521 } else { 529 None 522 None 530 }, 523 }, 531 suspend: if T::HAS_SUSPEND { 524 suspend: if T::HAS_SUSPEND { 532 Some(Adapter::<T>::suspend_callbac 525 Some(Adapter::<T>::suspend_callback) 533 } else { 526 } else { 534 None 527 None 535 }, 528 }, 536 resume: if T::HAS_RESUME { 529 resume: if T::HAS_RESUME { 537 Some(Adapter::<T>::resume_callback 530 Some(Adapter::<T>::resume_callback) 538 } else { 531 } else { 539 None 532 None 540 }, 533 }, 541 config_aneg: if T::HAS_CONFIG_ANEG { 534 config_aneg: if T::HAS_CONFIG_ANEG { 542 Some(Adapter::<T>::config_aneg_cal 535 Some(Adapter::<T>::config_aneg_callback) 543 } else { 536 } else { 544 None 537 None 545 }, 538 }, 546 read_status: if T::HAS_READ_STATUS { 539 read_status: if T::HAS_READ_STATUS { 547 Some(Adapter::<T>::read_status_cal 540 Some(Adapter::<T>::read_status_callback) 548 } else { 541 } else { 549 None 542 None 550 }, 543 }, 551 read_mmd: if T::HAS_READ_MMD { 544 read_mmd: if T::HAS_READ_MMD { 552 Some(Adapter::<T>::read_mmd_callba 545 Some(Adapter::<T>::read_mmd_callback) 553 } else { 546 } else { 554 None 547 None 555 }, 548 }, 556 write_mmd: if T::HAS_WRITE_MMD { 549 write_mmd: if T::HAS_WRITE_MMD { 557 Some(Adapter::<T>::write_mmd_callb 550 Some(Adapter::<T>::write_mmd_callback) 558 } else { 551 } else { 559 None 552 None 560 }, 553 }, 561 link_change_notify: if T::HAS_LINK_CHA 554 link_change_notify: if T::HAS_LINK_CHANGE_NOTIFY { 562 Some(Adapter::<T>::link_change_not 555 Some(Adapter::<T>::link_change_notify_callback) 563 } else { 556 } else { 564 None 557 None 565 }, 558 }, 566 // SAFETY: The rest is zeroed out to i 559 // SAFETY: The rest is zeroed out to initialize `struct phy_driver`, 567 // sets `Option<&F>` to be `None`. 560 // sets `Option<&F>` to be `None`. 568 ..unsafe { core::mem::MaybeUninit::<bi 561 ..unsafe { core::mem::MaybeUninit::<bindings::phy_driver>::zeroed().assume_init() } 569 })) 562 })) 570 } 563 } 571 564 572 /// Driver implementation for a particular PHY 565 /// Driver implementation for a particular PHY type. 573 /// 566 /// 574 /// This trait is used to create a [`DriverVTa 567 /// This trait is used to create a [`DriverVTable`]. 575 #[vtable] 568 #[vtable] 576 pub trait Driver { 569 pub trait Driver { 577 /// Defines certain other features this PH 570 /// Defines certain other features this PHY supports. 578 /// It is a combination of the flags in th 571 /// It is a combination of the flags in the [`flags`] module. 579 const FLAGS: u32 = 0; 572 const FLAGS: u32 = 0; 580 573 581 /// The friendly name of this PHY type. 574 /// The friendly name of this PHY type. 582 const NAME: &'static CStr; 575 const NAME: &'static CStr; 583 576 584 /// This driver only works for PHYs with I 577 /// This driver only works for PHYs with IDs which match this field. 585 /// The default id and mask are zero. 578 /// The default id and mask are zero. 586 const PHY_DEVICE_ID: DeviceId = DeviceId:: 579 const PHY_DEVICE_ID: DeviceId = DeviceId::new_with_custom_mask(0, 0); 587 580 588 /// Issues a PHY software reset. 581 /// Issues a PHY software reset. 589 fn soft_reset(_dev: &mut Device) -> Result 582 fn soft_reset(_dev: &mut Device) -> Result { 590 kernel::build_error(VTABLE_DEFAULT_ERR << 591 } << 592 << 593 /// Sets up device-specific structures dur << 594 fn probe(_dev: &mut Device) -> Result { << 595 kernel::build_error(VTABLE_DEFAULT_ERR 583 kernel::build_error(VTABLE_DEFAULT_ERROR) 596 } 584 } 597 585 598 /// Probes the hardware to determine what 586 /// Probes the hardware to determine what abilities it has. 599 fn get_features(_dev: &mut Device) -> Resu 587 fn get_features(_dev: &mut Device) -> Result { 600 kernel::build_error(VTABLE_DEFAULT_ERR 588 kernel::build_error(VTABLE_DEFAULT_ERROR) 601 } 589 } 602 590 603 /// Returns true if this is a suitable dri 591 /// Returns true if this is a suitable driver for the given phydev. 604 /// If not implemented, matching is based 592 /// If not implemented, matching is based on [`Driver::PHY_DEVICE_ID`]. 605 fn match_phy_device(_dev: &Device) -> bool 593 fn match_phy_device(_dev: &Device) -> bool { 606 false 594 false 607 } 595 } 608 596 609 /// Configures the advertisement and reset 597 /// Configures the advertisement and resets auto-negotiation 610 /// if auto-negotiation is enabled. 598 /// if auto-negotiation is enabled. 611 fn config_aneg(_dev: &mut Device) -> Resul 599 fn config_aneg(_dev: &mut Device) -> Result { 612 kernel::build_error(VTABLE_DEFAULT_ERR 600 kernel::build_error(VTABLE_DEFAULT_ERROR) 613 } 601 } 614 602 615 /// Determines the negotiated speed and du 603 /// Determines the negotiated speed and duplex. 616 fn read_status(_dev: &mut Device) -> Resul 604 fn read_status(_dev: &mut Device) -> Result<u16> { 617 kernel::build_error(VTABLE_DEFAULT_ERR 605 kernel::build_error(VTABLE_DEFAULT_ERROR) 618 } 606 } 619 607 620 /// Suspends the hardware, saving state if 608 /// Suspends the hardware, saving state if needed. 621 fn suspend(_dev: &mut Device) -> Result { 609 fn suspend(_dev: &mut Device) -> Result { 622 kernel::build_error(VTABLE_DEFAULT_ERR 610 kernel::build_error(VTABLE_DEFAULT_ERROR) 623 } 611 } 624 612 625 /// Resumes the hardware, restoring state 613 /// Resumes the hardware, restoring state if needed. 626 fn resume(_dev: &mut Device) -> Result { 614 fn resume(_dev: &mut Device) -> Result { 627 kernel::build_error(VTABLE_DEFAULT_ERR 615 kernel::build_error(VTABLE_DEFAULT_ERROR) 628 } 616 } 629 617 630 /// Overrides the default MMD read functio 618 /// Overrides the default MMD read function for reading a MMD register. 631 fn read_mmd(_dev: &mut Device, _devnum: u8 619 fn read_mmd(_dev: &mut Device, _devnum: u8, _regnum: u16) -> Result<u16> { 632 kernel::build_error(VTABLE_DEFAULT_ERR 620 kernel::build_error(VTABLE_DEFAULT_ERROR) 633 } 621 } 634 622 635 /// Overrides the default MMD write functi 623 /// Overrides the default MMD write function for writing a MMD register. 636 fn write_mmd(_dev: &mut Device, _devnum: u 624 fn write_mmd(_dev: &mut Device, _devnum: u8, _regnum: u16, _val: u16) -> Result { 637 kernel::build_error(VTABLE_DEFAULT_ERR 625 kernel::build_error(VTABLE_DEFAULT_ERROR) 638 } 626 } 639 627 640 /// Callback for notification of link chan 628 /// Callback for notification of link change. 641 fn link_change_notify(_dev: &mut Device) { 629 fn link_change_notify(_dev: &mut Device) {} 642 } 630 } 643 631 644 /// Registration structure for PHY drivers. 632 /// Registration structure for PHY drivers. 645 /// 633 /// 646 /// Registers [`DriverVTable`] instances with 634 /// Registers [`DriverVTable`] instances with the kernel. They will be unregistered when dropped. 647 /// 635 /// 648 /// # Invariants 636 /// # Invariants 649 /// 637 /// 650 /// The `drivers` slice are currently register 638 /// The `drivers` slice are currently registered to the kernel via `phy_drivers_register`. 651 pub struct Registration { 639 pub struct Registration { 652 drivers: Pin<&'static mut [DriverVTable]>, 640 drivers: Pin<&'static mut [DriverVTable]>, 653 } 641 } 654 642 655 // SAFETY: The only action allowed in a `Regis 643 // SAFETY: The only action allowed in a `Registration` instance is dropping it, which is safe to do 656 // from any thread because `phy_drivers_unregi 644 // from any thread because `phy_drivers_unregister` can be called from any thread context. 657 unsafe impl Send for Registration {} 645 unsafe impl Send for Registration {} 658 646 659 impl Registration { 647 impl Registration { 660 /// Registers a PHY driver. 648 /// Registers a PHY driver. 661 pub fn register( 649 pub fn register( 662 module: &'static crate::ThisModule, 650 module: &'static crate::ThisModule, 663 drivers: Pin<&'static mut [DriverVTabl 651 drivers: Pin<&'static mut [DriverVTable]>, 664 ) -> Result<Self> { 652 ) -> Result<Self> { 665 if drivers.is_empty() { 653 if drivers.is_empty() { 666 return Err(code::EINVAL); 654 return Err(code::EINVAL); 667 } 655 } 668 // SAFETY: The type invariants of [`Dr 656 // SAFETY: The type invariants of [`DriverVTable`] ensure that all elements of 669 // the `drivers` slice are initialized 657 // the `drivers` slice are initialized properly. `drivers` will not be moved. 670 // So it's just an FFI call. 658 // So it's just an FFI call. 671 to_result(unsafe { 659 to_result(unsafe { 672 bindings::phy_drivers_register(dri 660 bindings::phy_drivers_register(drivers[0].0.get(), drivers.len().try_into()?, module.0) 673 })?; 661 })?; 674 // INVARIANT: The `drivers` slice is s 662 // INVARIANT: The `drivers` slice is successfully registered to the kernel via `phy_drivers_register`. 675 Ok(Registration { drivers }) 663 Ok(Registration { drivers }) 676 } 664 } 677 } 665 } 678 666 679 impl Drop for Registration { 667 impl Drop for Registration { 680 fn drop(&mut self) { 668 fn drop(&mut self) { 681 // SAFETY: The type invariants guarant 669 // SAFETY: The type invariants guarantee that `self.drivers` is valid. 682 // So it's just an FFI call. 670 // So it's just an FFI call. 683 unsafe { 671 unsafe { 684 bindings::phy_drivers_unregister(s 672 bindings::phy_drivers_unregister(self.drivers[0].0.get(), self.drivers.len() as i32) 685 }; 673 }; 686 } 674 } 687 } 675 } 688 676 689 /// An identifier for PHY devices on an MDIO/M 677 /// An identifier for PHY devices on an MDIO/MII bus. 690 /// 678 /// 691 /// Represents the kernel's `struct mdio_devic 679 /// Represents the kernel's `struct mdio_device_id`. This is used to find an appropriate 692 /// PHY driver. 680 /// PHY driver. 693 pub struct DeviceId { 681 pub struct DeviceId { 694 id: u32, 682 id: u32, 695 mask: DeviceMask, 683 mask: DeviceMask, 696 } 684 } 697 685 698 impl DeviceId { 686 impl DeviceId { 699 /// Creates a new instance with the exact 687 /// Creates a new instance with the exact match mask. 700 pub const fn new_with_exact_mask(id: u32) 688 pub const fn new_with_exact_mask(id: u32) -> Self { 701 DeviceId { 689 DeviceId { 702 id, 690 id, 703 mask: DeviceMask::Exact, 691 mask: DeviceMask::Exact, 704 } 692 } 705 } 693 } 706 694 707 /// Creates a new instance with the model 695 /// Creates a new instance with the model match mask. 708 pub const fn new_with_model_mask(id: u32) 696 pub const fn new_with_model_mask(id: u32) -> Self { 709 DeviceId { 697 DeviceId { 710 id, 698 id, 711 mask: DeviceMask::Model, 699 mask: DeviceMask::Model, 712 } 700 } 713 } 701 } 714 702 715 /// Creates a new instance with the vendor 703 /// Creates a new instance with the vendor match mask. 716 pub const fn new_with_vendor_mask(id: u32) 704 pub const fn new_with_vendor_mask(id: u32) -> Self { 717 DeviceId { 705 DeviceId { 718 id, 706 id, 719 mask: DeviceMask::Vendor, 707 mask: DeviceMask::Vendor, 720 } 708 } 721 } 709 } 722 710 723 /// Creates a new instance with a custom m 711 /// Creates a new instance with a custom match mask. 724 pub const fn new_with_custom_mask(id: u32, 712 pub const fn new_with_custom_mask(id: u32, mask: u32) -> Self { 725 DeviceId { 713 DeviceId { 726 id, 714 id, 727 mask: DeviceMask::Custom(mask), 715 mask: DeviceMask::Custom(mask), 728 } 716 } 729 } 717 } 730 718 731 /// Creates a new instance from [`Driver`] 719 /// Creates a new instance from [`Driver`]. 732 pub const fn new_with_driver<T: Driver>() 720 pub const fn new_with_driver<T: Driver>() -> Self { 733 T::PHY_DEVICE_ID 721 T::PHY_DEVICE_ID 734 } 722 } 735 723 736 /// Get a `mask` as u32. 724 /// Get a `mask` as u32. 737 pub const fn mask_as_int(&self) -> u32 { 725 pub const fn mask_as_int(&self) -> u32 { 738 self.mask.as_int() 726 self.mask.as_int() 739 } 727 } 740 728 741 // macro use only 729 // macro use only 742 #[doc(hidden)] 730 #[doc(hidden)] 743 pub const fn mdio_device_id(&self) -> bind 731 pub const fn mdio_device_id(&self) -> bindings::mdio_device_id { 744 bindings::mdio_device_id { 732 bindings::mdio_device_id { 745 phy_id: self.id, 733 phy_id: self.id, 746 phy_id_mask: self.mask.as_int(), 734 phy_id_mask: self.mask.as_int(), 747 } 735 } 748 } 736 } 749 } 737 } 750 738 751 enum DeviceMask { 739 enum DeviceMask { 752 Exact, 740 Exact, 753 Model, 741 Model, 754 Vendor, 742 Vendor, 755 Custom(u32), 743 Custom(u32), 756 } 744 } 757 745 758 impl DeviceMask { 746 impl DeviceMask { 759 const MASK_EXACT: u32 = !0; 747 const MASK_EXACT: u32 = !0; 760 const MASK_MODEL: u32 = !0 << 4; 748 const MASK_MODEL: u32 = !0 << 4; 761 const MASK_VENDOR: u32 = !0 << 10; 749 const MASK_VENDOR: u32 = !0 << 10; 762 750 763 const fn as_int(&self) -> u32 { 751 const fn as_int(&self) -> u32 { 764 match self { 752 match self { 765 DeviceMask::Exact => Self::MASK_EX 753 DeviceMask::Exact => Self::MASK_EXACT, 766 DeviceMask::Model => Self::MASK_MO 754 DeviceMask::Model => Self::MASK_MODEL, 767 DeviceMask::Vendor => Self::MASK_V 755 DeviceMask::Vendor => Self::MASK_VENDOR, 768 DeviceMask::Custom(mask) => *mask, 756 DeviceMask::Custom(mask) => *mask, 769 } 757 } 770 } 758 } 771 } 759 } 772 760 773 /// Declares a kernel module for PHYs drivers. 761 /// Declares a kernel module for PHYs drivers. 774 /// 762 /// 775 /// This creates a static array of kernel's `s 763 /// This creates a static array of kernel's `struct phy_driver` and registers it. 776 /// This also corresponds to the kernel's `MOD 764 /// This also corresponds to the kernel's `MODULE_DEVICE_TABLE` macro, which embeds the information 777 /// for module loading into the module binary 765 /// for module loading into the module binary file. Every driver needs an entry in `device_table`. 778 /// 766 /// 779 /// # Examples 767 /// # Examples 780 /// 768 /// 781 /// ``` 769 /// ``` 782 /// # mod module_phy_driver_sample { 770 /// # mod module_phy_driver_sample { 783 /// use kernel::c_str; 771 /// use kernel::c_str; 784 /// use kernel::net::phy::{self, DeviceId}; 772 /// use kernel::net::phy::{self, DeviceId}; 785 /// use kernel::prelude::*; 773 /// use kernel::prelude::*; 786 /// 774 /// 787 /// kernel::module_phy_driver! { 775 /// kernel::module_phy_driver! { 788 /// drivers: [PhySample], 776 /// drivers: [PhySample], 789 /// device_table: [ 777 /// device_table: [ 790 /// DeviceId::new_with_driver::<PhySam 778 /// DeviceId::new_with_driver::<PhySample>() 791 /// ], 779 /// ], 792 /// name: "rust_sample_phy", 780 /// name: "rust_sample_phy", 793 /// author: "Rust for Linux Contributors", 781 /// author: "Rust for Linux Contributors", 794 /// description: "Rust sample PHYs driver" 782 /// description: "Rust sample PHYs driver", 795 /// license: "GPL", 783 /// license: "GPL", 796 /// } 784 /// } 797 /// 785 /// 798 /// struct PhySample; 786 /// struct PhySample; 799 /// 787 /// 800 /// #[vtable] 788 /// #[vtable] 801 /// impl phy::Driver for PhySample { 789 /// impl phy::Driver for PhySample { 802 /// const NAME: &'static CStr = c_str!("Ph 790 /// const NAME: &'static CStr = c_str!("PhySample"); 803 /// const PHY_DEVICE_ID: phy::DeviceId = p 791 /// const PHY_DEVICE_ID: phy::DeviceId = phy::DeviceId::new_with_exact_mask(0x00000001); 804 /// } 792 /// } 805 /// # } 793 /// # } 806 /// ``` 794 /// ``` 807 /// 795 /// 808 /// This expands to the following code: 796 /// This expands to the following code: 809 /// 797 /// 810 /// ```ignore 798 /// ```ignore 811 /// use kernel::c_str; 799 /// use kernel::c_str; 812 /// use kernel::net::phy::{self, DeviceId}; 800 /// use kernel::net::phy::{self, DeviceId}; 813 /// use kernel::prelude::*; 801 /// use kernel::prelude::*; 814 /// 802 /// 815 /// struct Module { 803 /// struct Module { 816 /// _reg: ::kernel::net::phy::Registration 804 /// _reg: ::kernel::net::phy::Registration, 817 /// } 805 /// } 818 /// 806 /// 819 /// module! { 807 /// module! { 820 /// type: Module, 808 /// type: Module, 821 /// name: "rust_sample_phy", 809 /// name: "rust_sample_phy", 822 /// author: "Rust for Linux Contributors", 810 /// author: "Rust for Linux Contributors", 823 /// description: "Rust sample PHYs driver" 811 /// description: "Rust sample PHYs driver", 824 /// license: "GPL", 812 /// license: "GPL", 825 /// } 813 /// } 826 /// 814 /// 827 /// struct PhySample; 815 /// struct PhySample; 828 /// 816 /// 829 /// #[vtable] 817 /// #[vtable] 830 /// impl phy::Driver for PhySample { 818 /// impl phy::Driver for PhySample { 831 /// const NAME: &'static CStr = c_str!("Ph 819 /// const NAME: &'static CStr = c_str!("PhySample"); 832 /// const PHY_DEVICE_ID: phy::DeviceId = p 820 /// const PHY_DEVICE_ID: phy::DeviceId = phy::DeviceId::new_with_exact_mask(0x00000001); 833 /// } 821 /// } 834 /// 822 /// 835 /// const _: () = { 823 /// const _: () = { 836 /// static mut DRIVERS: [::kernel::net::ph 824 /// static mut DRIVERS: [::kernel::net::phy::DriverVTable; 1] = 837 /// [::kernel::net::phy::create_phy_dr 825 /// [::kernel::net::phy::create_phy_driver::<PhySample>()]; 838 /// 826 /// 839 /// impl ::kernel::Module for Module { 827 /// impl ::kernel::Module for Module { 840 /// fn init(module: &'static ThisModul 828 /// fn init(module: &'static ThisModule) -> Result<Self> { 841 /// let drivers = unsafe { &mut DR 829 /// let drivers = unsafe { &mut DRIVERS }; 842 /// let mut reg = ::kernel::net::p 830 /// let mut reg = ::kernel::net::phy::Registration::register( 843 /// module, 831 /// module, 844 /// ::core::pin::Pin::static_m 832 /// ::core::pin::Pin::static_mut(drivers), 845 /// )?; 833 /// )?; 846 /// Ok(Module { _reg: reg }) 834 /// Ok(Module { _reg: reg }) 847 /// } 835 /// } 848 /// } 836 /// } 849 /// }; 837 /// }; 850 /// 838 /// 851 /// #[cfg(MODULE)] 839 /// #[cfg(MODULE)] 852 /// #[no_mangle] 840 /// #[no_mangle] 853 /// static __mod_mdio__phydev_device_table: [: 841 /// static __mod_mdio__phydev_device_table: [::kernel::bindings::mdio_device_id; 2] = [ 854 /// ::kernel::bindings::mdio_device_id { 842 /// ::kernel::bindings::mdio_device_id { 855 /// phy_id: 0x00000001, 843 /// phy_id: 0x00000001, 856 /// phy_id_mask: 0xffffffff, 844 /// phy_id_mask: 0xffffffff, 857 /// }, 845 /// }, 858 /// ::kernel::bindings::mdio_device_id { 846 /// ::kernel::bindings::mdio_device_id { 859 /// phy_id: 0, 847 /// phy_id: 0, 860 /// phy_id_mask: 0, 848 /// phy_id_mask: 0, 861 /// }, 849 /// }, 862 /// ]; 850 /// ]; 863 /// ``` 851 /// ``` 864 #[macro_export] 852 #[macro_export] 865 macro_rules! module_phy_driver { 853 macro_rules! module_phy_driver { 866 (@replace_expr $_t:tt $sub:expr) => {$sub} 854 (@replace_expr $_t:tt $sub:expr) => {$sub}; 867 855 868 (@count_devices $($x:expr),*) => { 856 (@count_devices $($x:expr),*) => { 869 0usize $(+ $crate::module_phy_driver!( 857 0usize $(+ $crate::module_phy_driver!(@replace_expr $x 1usize))* 870 }; 858 }; 871 859 872 (@device_table [$($dev:expr),+]) => { 860 (@device_table [$($dev:expr),+]) => { 873 // SAFETY: C will not read off the end 861 // SAFETY: C will not read off the end of this constant since the last element is zero. 874 #[cfg(MODULE)] 862 #[cfg(MODULE)] 875 #[no_mangle] 863 #[no_mangle] 876 static __mod_mdio__phydev_device_table 864 static __mod_mdio__phydev_device_table: [$crate::bindings::mdio_device_id; 877 $crate::module_phy_driver!(@count_ 865 $crate::module_phy_driver!(@count_devices $($dev),+) + 1] = [ 878 $($dev.mdio_device_id()),+, 866 $($dev.mdio_device_id()),+, 879 $crate::bindings::mdio_device_id { 867 $crate::bindings::mdio_device_id { 880 phy_id: 0, 868 phy_id: 0, 881 phy_id_mask: 0 869 phy_id_mask: 0 882 } 870 } 883 ]; 871 ]; 884 }; 872 }; 885 873 886 (drivers: [$($driver:ident),+ $(,)?], devi 874 (drivers: [$($driver:ident),+ $(,)?], device_table: [$($dev:expr),+ $(,)?], $($f:tt)*) => { 887 struct Module { 875 struct Module { 888 _reg: $crate::net::phy::Registrati 876 _reg: $crate::net::phy::Registration, 889 } 877 } 890 878 891 $crate::prelude::module! { 879 $crate::prelude::module! { 892 type: Module, 880 type: Module, 893 $($f)* 881 $($f)* 894 } 882 } 895 883 896 const _: () = { 884 const _: () = { 897 static mut DRIVERS: [$crate::net:: 885 static mut DRIVERS: [$crate::net::phy::DriverVTable; 898 $crate::module_phy_driver!(@co 886 $crate::module_phy_driver!(@count_devices $($driver),+)] = 899 [$($crate::net::phy::create_ph 887 [$($crate::net::phy::create_phy_driver::<$driver>()),+]; 900 888 901 impl $crate::Module for Module { 889 impl $crate::Module for Module { 902 fn init(module: &'static ThisM 890 fn init(module: &'static ThisModule) -> Result<Self> { 903 // SAFETY: The anonymous c 891 // SAFETY: The anonymous constant guarantees that nobody else can access 904 // the `DRIVERS` static. T 892 // the `DRIVERS` static. The array is used only in the C side. 905 let drivers = unsafe { &mu 893 let drivers = unsafe { &mut DRIVERS }; 906 let mut reg = $crate::net: 894 let mut reg = $crate::net::phy::Registration::register( 907 module, 895 module, 908 ::core::pin::Pin::stat 896 ::core::pin::Pin::static_mut(drivers), 909 )?; 897 )?; 910 Ok(Module { _reg: reg }) 898 Ok(Module { _reg: reg }) 911 } 899 } 912 } 900 } 913 }; 901 }; 914 902 915 $crate::module_phy_driver!(@device_tab 903 $crate::module_phy_driver!(@device_table [$($dev),+]); 916 } 904 } 917 } 905 }
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.