use crate::ethtool_const::{
EthtoolLinkModeBits, EthtoolPort, EthtoolPortBits, ETHTOOL_LINK_MODE_MASK_MAX_KERNEL_NBITS,
};
use enum_iterator::all;
pub struct SettingsParser<'a> {
port: u8,
supported_link_modes: &'a [u32],
advertised_link_modes: &'a [u32],
}
impl<'a> SettingsParser<'a> {
pub fn new(
port: u8,
supported_link_modes: &'a [u32],
advertised_link_modes: &'a [u32],
) -> SettingsParser<'a> {
SettingsParser {
port,
supported_link_modes,
advertised_link_modes,
}
}
pub fn supported_ports(&'a self) -> Vec<EthtoolPortBits> {
let mut modes = Vec::new();
for mode in all::<EthtoolPortBits>() {
if ethtool_link_mode_test_bit(mode as u32, self.supported_link_modes) {
modes.push(mode);
}
}
modes
}
pub fn supported_link_modes(&'a self) -> Vec<EthtoolLinkModeBits> {
let mut modes = Vec::new();
for mode in all::<EthtoolLinkModeBits>() {
if ethtool_link_mode_test_bit(mode as u32, self.supported_link_modes) {
modes.push(mode);
}
}
modes
}
pub fn advertised_link_modes(&'a self) -> Vec<EthtoolLinkModeBits> {
let mut modes = Vec::new();
for mode in all::<EthtoolLinkModeBits>() {
if ethtool_link_mode_test_bit(mode as u32, self.advertised_link_modes) {
modes.push(mode);
}
}
modes
}
pub fn port(&'a self) -> EthtoolPort {
let mode = EthtoolPort::default();
for mode in all::<EthtoolPort>() {
if mode as u8 == self.port {
return mode;
}
}
mode
}
}
fn ethtool_link_mode_test_bit(nr: u32, mask: &[u32]) -> bool {
if nr >= ETHTOOL_LINK_MODE_MASK_MAX_KERNEL_NBITS {
false
} else {
(mask[(nr / 32) as usize] & (1 << (nr % 32))) != 0
}
}