-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
FUJITA Tomonori says: ==================== Rust abstractions for network PHY drivers No functional change since v10; only comment and commit log updates. This patchset adds Rust abstractions for phylib. It doesn't fully cover the C APIs yet but I think that it's already useful. I implement two PHY drivers (Asix AX88772A PHYs and Realtek Generic FE-GE). Seems they work well with real hardware. The first patch introduces Rust bindings for phylib. The second patch adds a macro to declare a kernel module for PHYs drivers. The third adds the Rust ETHERNET PHY LIBRARY entry to MAINTAINERS file; adds the binding file and me as a maintainer (as Andrew Lunn suggested) with Trevor Gross as a reviewer. The last patch introduces the Rust version of Asix PHY driver, drivers/net/phy/ax88796b.c. The features are equivalent to the C version. You can choose C (by default) or Rust version on kernel configuration. v11: - adds Andrew, Alice, and Trevor's Reviewed-by - comment update v10: https://lore.kernel.org/netdev/20231210234924.1453917-1-fujita.tomonori@gmail.com/T/ - adds Trevor's SoB to the third patch - adds Benno's Reviewed-by to the second patch v9: https://lore.kernel.org/netdev/20231205.124531.842372711631366729.fujita.tomonori@gmail.com/T/ - adds a workaround to access to a bit field in phy_device - fixes a comment typo v8: https://lore.kernel.org/netdev/20231123050412.1012252-1-fujita.tomonori@gmail.com/ - updates the safety comments on Device and its related code - uses _phy_start_aneg instead of phy_start_aneg - drops the patch for enum synchronization - moves Sync From Registration to DriverVTable - fixes doctest errors - minor cleanups v7: https://lore.kernel.org/netdev/20231026001050.1720612-1-fujita.tomonori@gmail.com/T/ - renames get_link() to is_link_up() - improves the macro format - improves the commit log in the third patch - improves comments v6: https://lore.kernel.org/netdev/20231025.090243.1437967503809186729.fujita.tomonori@gmail.com/T/ - improves comments - makes the requirement of phy_drivers_register clear - fixes Makefile of the third patch v5: https://lore.kernel.org/all/20231019.094147.1808345526469629486.fujita.tomonori@gmail.com/T/ - drops the rustified-enum option, writes match by hand; no *risk* of UB - adds Miguel's patch for enum checking - moves CONFIG_RUST_PHYLIB_ABSTRACTIONS to drivers/net/phy/Kconfig - adds a new entry for this abstractions in MAINTAINERS - changes some of Device's methods to take &mut self - comment improvment v4: https://lore.kernel.org/netdev/20231012125349.2702474-1-fujita.tomonori@gmail.com/T/ - split the core patch - making Device::from_raw() private - comment improvement with code update - commit message improvement - avoiding using bindings::phy_driver in public functions - using an anonymous constant in module_phy_driver macro v3: https://lore.kernel.org/netdev/20231011.231607.1747074555988728415.fujita.tomonori@gmail.com/T/ - changes the base tree to net-next from rust-next - makes this feature optional; only enabled with CONFIG_RUST_PHYLIB_BINDINGS=y - cosmetic code and comment improvement - adds copyright v2: https://lore.kernel.org/netdev/20231006094911.3305152-2-fujita.tomonori@gmail.com/T/ - build failure fix - function renaming v1: https://lore.kernel.org/netdev/20231002085302.2274260-3-fujita.tomonori@gmail.com/T/ ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
- Loading branch information
Showing
9 changed files
with
1,087 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,135 @@ | ||
// SPDX-License-Identifier: GPL-2.0 | ||
// Copyright (C) 2023 FUJITA Tomonori <fujita.tomonori@gmail.com> | ||
|
||
//! Rust Asix PHYs driver | ||
//! | ||
//! C version of this driver: [`drivers/net/phy/ax88796b.c`](./ax88796b.c) | ||
use kernel::{ | ||
c_str, | ||
net::phy::{self, DeviceId, Driver}, | ||
prelude::*, | ||
uapi, | ||
}; | ||
|
||
kernel::module_phy_driver! { | ||
drivers: [PhyAX88772A, PhyAX88772C, PhyAX88796B], | ||
device_table: [ | ||
DeviceId::new_with_driver::<PhyAX88772A>(), | ||
DeviceId::new_with_driver::<PhyAX88772C>(), | ||
DeviceId::new_with_driver::<PhyAX88796B>() | ||
], | ||
name: "rust_asix_phy", | ||
author: "FUJITA Tomonori <fujita.tomonori@gmail.com>", | ||
description: "Rust Asix PHYs driver", | ||
license: "GPL", | ||
} | ||
|
||
const MII_BMCR: u16 = uapi::MII_BMCR as u16; | ||
const BMCR_SPEED100: u16 = uapi::BMCR_SPEED100 as u16; | ||
const BMCR_FULLDPLX: u16 = uapi::BMCR_FULLDPLX as u16; | ||
|
||
// Performs a software PHY reset using the standard | ||
// BMCR_RESET bit and poll for the reset bit to be cleared. | ||
// Toggle BMCR_RESET bit off to accommodate broken AX8796B PHY implementation | ||
// such as used on the Individual Computers' X-Surf 100 Zorro card. | ||
fn asix_soft_reset(dev: &mut phy::Device) -> Result { | ||
dev.write(uapi::MII_BMCR as u16, 0)?; | ||
dev.genphy_soft_reset() | ||
} | ||
|
||
struct PhyAX88772A; | ||
|
||
#[vtable] | ||
impl Driver for PhyAX88772A { | ||
const FLAGS: u32 = phy::flags::IS_INTERNAL; | ||
const NAME: &'static CStr = c_str!("Asix Electronics AX88772A"); | ||
const PHY_DEVICE_ID: DeviceId = DeviceId::new_with_exact_mask(0x003b1861); | ||
|
||
// AX88772A is not working properly with some old switches (NETGEAR EN 108TP): | ||
// after autoneg is done and the link status is reported as active, the MII_LPA | ||
// register is 0. This issue is not reproducible on AX88772C. | ||
fn read_status(dev: &mut phy::Device) -> Result<u16> { | ||
dev.genphy_update_link()?; | ||
if !dev.is_link_up() { | ||
return Ok(0); | ||
} | ||
// If MII_LPA is 0, phy_resolve_aneg_linkmode() will fail to resolve | ||
// linkmode so use MII_BMCR as default values. | ||
let ret = dev.read(MII_BMCR)?; | ||
|
||
if ret & BMCR_SPEED100 != 0 { | ||
dev.set_speed(uapi::SPEED_100); | ||
} else { | ||
dev.set_speed(uapi::SPEED_10); | ||
} | ||
|
||
let duplex = if ret & BMCR_FULLDPLX != 0 { | ||
phy::DuplexMode::Full | ||
} else { | ||
phy::DuplexMode::Half | ||
}; | ||
dev.set_duplex(duplex); | ||
|
||
dev.genphy_read_lpa()?; | ||
|
||
if dev.is_autoneg_enabled() && dev.is_autoneg_completed() { | ||
dev.resolve_aneg_linkmode(); | ||
} | ||
|
||
Ok(0) | ||
} | ||
|
||
fn suspend(dev: &mut phy::Device) -> Result { | ||
dev.genphy_suspend() | ||
} | ||
|
||
fn resume(dev: &mut phy::Device) -> Result { | ||
dev.genphy_resume() | ||
} | ||
|
||
fn soft_reset(dev: &mut phy::Device) -> Result { | ||
asix_soft_reset(dev) | ||
} | ||
|
||
fn link_change_notify(dev: &mut phy::Device) { | ||
// Reset PHY, otherwise MII_LPA will provide outdated information. | ||
// This issue is reproducible only with some link partner PHYs. | ||
if dev.state() == phy::DeviceState::NoLink { | ||
let _ = dev.init_hw(); | ||
let _ = dev.start_aneg(); | ||
} | ||
} | ||
} | ||
|
||
struct PhyAX88772C; | ||
|
||
#[vtable] | ||
impl Driver for PhyAX88772C { | ||
const FLAGS: u32 = phy::flags::IS_INTERNAL; | ||
const NAME: &'static CStr = c_str!("Asix Electronics AX88772C"); | ||
const PHY_DEVICE_ID: DeviceId = DeviceId::new_with_exact_mask(0x003b1881); | ||
|
||
fn suspend(dev: &mut phy::Device) -> Result { | ||
dev.genphy_suspend() | ||
} | ||
|
||
fn resume(dev: &mut phy::Device) -> Result { | ||
dev.genphy_resume() | ||
} | ||
|
||
fn soft_reset(dev: &mut phy::Device) -> Result { | ||
asix_soft_reset(dev) | ||
} | ||
} | ||
|
||
struct PhyAX88796B; | ||
|
||
#[vtable] | ||
impl Driver for PhyAX88796B { | ||
const NAME: &'static CStr = c_str!("Asix Electronics AX88796B"); | ||
const PHY_DEVICE_ID: DeviceId = DeviceId::new_with_model_mask(0x003b1841); | ||
|
||
fn soft_reset(dev: &mut phy::Device) -> Result { | ||
asix_soft_reset(dev) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
// SPDX-License-Identifier: GPL-2.0 | ||
|
||
//! Networking. | ||
|
||
#[cfg(CONFIG_RUST_PHYLIB_ABSTRACTIONS)] | ||
pub mod phy; |
Oops, something went wrong.