use core::task::Context;
use crate::ethernet::mac::{EmacRegs, LinkState};
pub mod generic;
pub const BMCR: u8 = 0x00;
pub const BMSR: u8 = 0x01;
pub const PHYIDR1: u8 = 0x02;
pub const PHYIDR2: u8 = 0x03;
pub const ANAR: u8 = 0x04;
pub const ANLPAR: u8 = 0x05;
pub const ANER: u8 = 0x06;
pub mod bmcr {
pub const RESET: u16 = 1 << 15;
pub const SPEED_100: u16 = 1 << 13;
pub const ANEN: u16 = 1 << 12;
pub const RESTART_AN: u16 = 1 << 9;
pub const FULL_DUPLEX: u16 = 1 << 8;
}
pub mod bmsr {
pub const LINK_STATUS: u16 = 1 << 2;
pub const AN_COMPLETE: u16 = 1 << 5;
pub const AN_ABILITY: u16 = 1 << 3;
}
pub mod an {
pub const BASE_10_HALF: u16 = 1 << 5;
pub const BASE_10_FULL: u16 = 1 << 6;
pub const BASE_100_HALF: u16 = 1 << 7;
pub const BASE_100_FULL: u16 = 1 << 8;
}
pub trait MdioBus {
fn read(&mut self, phy_addr: u8, reg_addr: u8) -> u16;
fn write(&mut self, phy_addr: u8, reg_addr: u8, value: u16);
}
pub struct MdioDriver<'a> {
regs: &'a EmacRegs,
}
impl<'a> MdioDriver<'a> {
pub(super) fn new(regs: &'a EmacRegs) -> Self {
Self { regs }
}
pub fn read(&mut self, phy_addr: u8, reg: u8) -> u16 {
debug_assert!(phy_addr < 32, "Clause 22 PHY address must be < 32");
debug_assert!(reg < 32, "Clause 22 register address must be < 32");
self.regs.mdio_read(phy_addr, reg)
}
pub fn write(&mut self, phy_addr: u8, reg: u8, data: u16) {
debug_assert!(phy_addr < 32, "Clause 22 PHY address must be < 32");
debug_assert!(reg < 32, "Clause 22 register address must be < 32");
self.regs.mdio_write(phy_addr, reg, data)
}
}
impl<'a> MdioBus for MdioDriver<'a> {
fn read(&mut self, phy_addr: u8, reg_addr: u8) -> u16 {
MdioDriver::read(self, phy_addr, reg_addr)
}
fn write(&mut self, phy_addr: u8, reg_addr: u8, value: u16) {
MdioDriver::write(self, phy_addr, reg_addr, value);
}
}
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub enum PhyError {
Timeout,
NotFound,
}
pub trait Phy {
fn init<M: MdioBus>(&mut self, mdio: &mut M) -> Result<(), PhyError>;
fn poll_link<M: MdioBus>(&mut self, mdio: &mut M, _cx: Option<&mut Context<'_>>) -> LinkState;
fn address(&self) -> u8;
}