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