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