stm32/eth: refactor genericsmi
This commit is contained in:
		@@ -1,5 +1,7 @@
 | 
				
			|||||||
//! Generic SMI Ethernet PHY
 | 
					//! Generic SMI Ethernet PHY
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use futures::task::Context;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use super::{StationManagement, PHY};
 | 
					use super::{StationManagement, PHY};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#[allow(dead_code)]
 | 
					#[allow(dead_code)]
 | 
				
			||||||
@@ -40,13 +42,13 @@ pub struct GenericSMI;
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
unsafe impl PHY for GenericSMI {
 | 
					unsafe impl PHY for GenericSMI {
 | 
				
			||||||
    /// Reset PHY and wait for it to come out of reset.
 | 
					    /// Reset PHY and wait for it to come out of reset.
 | 
				
			||||||
    fn phy_reset<S: StationManagement>(sm: &mut S) {
 | 
					    fn phy_reset<S: StationManagement>(&mut self, sm: &mut S) {
 | 
				
			||||||
        sm.smi_write(PHY_REG_BCR, PHY_REG_BCR_RESET);
 | 
					        sm.smi_write(PHY_REG_BCR, PHY_REG_BCR_RESET);
 | 
				
			||||||
        while sm.smi_read(PHY_REG_BCR) & PHY_REG_BCR_RESET == PHY_REG_BCR_RESET {}
 | 
					        while sm.smi_read(PHY_REG_BCR) & PHY_REG_BCR_RESET == PHY_REG_BCR_RESET {}
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /// PHY initialisation.
 | 
					    /// PHY initialisation.
 | 
				
			||||||
    fn phy_init<S: StationManagement>(sm: &mut S) {
 | 
					    fn phy_init<S: StationManagement>(&mut self, sm: &mut S) {
 | 
				
			||||||
        // Clear WU CSR
 | 
					        // Clear WU CSR
 | 
				
			||||||
        Self::smi_write_ext(sm, PHY_REG_WUCSR, 0);
 | 
					        Self::smi_write_ext(sm, PHY_REG_WUCSR, 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -54,7 +56,9 @@ unsafe impl PHY for GenericSMI {
 | 
				
			|||||||
        sm.smi_write(PHY_REG_BCR, PHY_REG_BCR_AN | PHY_REG_BCR_ANRST | PHY_REG_BCR_100M);
 | 
					        sm.smi_write(PHY_REG_BCR, PHY_REG_BCR_AN | PHY_REG_BCR_ANRST | PHY_REG_BCR_100M);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    fn poll_link<S: StationManagement>(sm: &mut S) -> bool {
 | 
					    fn poll_link<S: StationManagement>(&mut self, sm: &mut S, cx: &mut Context) -> bool {
 | 
				
			||||||
 | 
					        cx.waker().wake_by_ref();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        let bsr = sm.smi_read(PHY_REG_BSR);
 | 
					        let bsr = sm.smi_read(PHY_REG_BSR);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // No link without autonegotiate
 | 
					        // No link without autonegotiate
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -81,9 +81,7 @@ impl<'d, T: Instance, P: PHY> embassy_net_driver::Driver for Ethernet<'d, T, P>
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    fn link_state(&mut self, cx: &mut Context) -> LinkState {
 | 
					    fn link_state(&mut self, cx: &mut Context) -> LinkState {
 | 
				
			||||||
        // TODO: wake cx.waker on link state change
 | 
					        if self.phy.poll_link(&mut self.station_management, cx) {
 | 
				
			||||||
        cx.waker().wake_by_ref();
 | 
					 | 
				
			||||||
        if P::poll_link(self) {
 | 
					 | 
				
			||||||
            LinkState::Up
 | 
					            LinkState::Up
 | 
				
			||||||
        } else {
 | 
					        } else {
 | 
				
			||||||
            LinkState::Down
 | 
					            LinkState::Down
 | 
				
			||||||
@@ -148,11 +146,11 @@ pub unsafe trait StationManagement {
 | 
				
			|||||||
/// The methods cannot move S
 | 
					/// The methods cannot move S
 | 
				
			||||||
pub unsafe trait PHY {
 | 
					pub unsafe trait PHY {
 | 
				
			||||||
    /// Reset PHY and wait for it to come out of reset.
 | 
					    /// Reset PHY and wait for it to come out of reset.
 | 
				
			||||||
    fn phy_reset<S: StationManagement>(sm: &mut S);
 | 
					    fn phy_reset<S: StationManagement>(&mut self, sm: &mut S);
 | 
				
			||||||
    /// PHY initialisation.
 | 
					    /// PHY initialisation.
 | 
				
			||||||
    fn phy_init<S: StationManagement>(sm: &mut S);
 | 
					    fn phy_init<S: StationManagement>(&mut self, sm: &mut S);
 | 
				
			||||||
    /// Poll link to see if it is up and FD with 100Mbps
 | 
					    /// Poll link to see if it is up and FD with 100Mbps
 | 
				
			||||||
    fn poll_link<S: StationManagement>(sm: &mut S) -> bool;
 | 
					    fn poll_link<S: StationManagement>(&mut self, sm: &mut S, cx: &mut Context) -> bool;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pub(crate) mod sealed {
 | 
					pub(crate) mod sealed {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -3,6 +3,7 @@
 | 
				
			|||||||
mod rx_desc;
 | 
					mod rx_desc;
 | 
				
			||||||
mod tx_desc;
 | 
					mod tx_desc;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use core::marker::PhantomData;
 | 
				
			||||||
use core::sync::atomic::{fence, Ordering};
 | 
					use core::sync::atomic::{fence, Ordering};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use embassy_hal_common::{into_ref, PeripheralRef};
 | 
					use embassy_hal_common::{into_ref, PeripheralRef};
 | 
				
			||||||
@@ -48,9 +49,8 @@ pub struct Ethernet<'d, T: Instance, P: PHY> {
 | 
				
			|||||||
    pub(crate) rx: RDesRing<'d>,
 | 
					    pub(crate) rx: RDesRing<'d>,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    pins: [PeripheralRef<'d, AnyPin>; 9],
 | 
					    pins: [PeripheralRef<'d, AnyPin>; 9],
 | 
				
			||||||
    _phy: P,
 | 
					    pub(crate) phy: P,
 | 
				
			||||||
    clock_range: Cr,
 | 
					    pub(crate) station_management: EthernetStationManagement<T>,
 | 
				
			||||||
    phy_addr: u8,
 | 
					 | 
				
			||||||
    pub(crate) mac_addr: [u8; 6],
 | 
					    pub(crate) mac_addr: [u8; 6],
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -224,9 +224,12 @@ impl<'d, T: Instance, P: PHY> Ethernet<'d, T, P> {
 | 
				
			|||||||
        let mut this = Self {
 | 
					        let mut this = Self {
 | 
				
			||||||
            _peri: peri,
 | 
					            _peri: peri,
 | 
				
			||||||
            pins,
 | 
					            pins,
 | 
				
			||||||
            _phy: phy,
 | 
					            phy: phy,
 | 
				
			||||||
            clock_range,
 | 
					            station_management: EthernetStationManagement {
 | 
				
			||||||
            phy_addr,
 | 
					                peri: PhantomData,
 | 
				
			||||||
 | 
					                clock_range: clock_range,
 | 
				
			||||||
 | 
					                phy_addr: phy_addr,
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
            mac_addr,
 | 
					            mac_addr,
 | 
				
			||||||
            tx: TDesRing::new(&mut queue.tx_desc, &mut queue.tx_buf),
 | 
					            tx: TDesRing::new(&mut queue.tx_desc, &mut queue.tx_buf),
 | 
				
			||||||
            rx: RDesRing::new(&mut queue.rx_desc, &mut queue.rx_buf),
 | 
					            rx: RDesRing::new(&mut queue.rx_desc, &mut queue.rx_buf),
 | 
				
			||||||
@@ -256,8 +259,8 @@ impl<'d, T: Instance, P: PHY> Ethernet<'d, T, P> {
 | 
				
			|||||||
            w.set_tie(true);
 | 
					            w.set_tie(true);
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        P::phy_reset(&mut this);
 | 
					        this.phy.phy_reset(&mut this.station_management);
 | 
				
			||||||
        P::phy_init(&mut this);
 | 
					        this.phy.phy_init(&mut this.station_management);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        interrupt::ETH.unpend();
 | 
					        interrupt::ETH.unpend();
 | 
				
			||||||
        unsafe { interrupt::ETH.enable() };
 | 
					        unsafe { interrupt::ETH.enable() };
 | 
				
			||||||
@@ -266,7 +269,13 @@ impl<'d, T: Instance, P: PHY> Ethernet<'d, T, P> {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
unsafe impl<'d, T: Instance, P: PHY> StationManagement for Ethernet<'d, T, P> {
 | 
					pub struct EthernetStationManagement<T: Instance> {
 | 
				
			||||||
 | 
					    peri: PhantomData<T>,
 | 
				
			||||||
 | 
					    clock_range: Cr,
 | 
				
			||||||
 | 
					    phy_addr: u8,
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					unsafe impl<T: Instance> StationManagement for EthernetStationManagement<T> {
 | 
				
			||||||
    fn smi_read(&mut self, reg: u8) -> u16 {
 | 
					    fn smi_read(&mut self, reg: u8) -> u16 {
 | 
				
			||||||
        let mac = ETH.ethernet_mac();
 | 
					        let mac = ETH.ethernet_mac();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,5 +1,6 @@
 | 
				
			|||||||
mod descriptors;
 | 
					mod descriptors;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use core::marker::PhantomData;
 | 
				
			||||||
use core::sync::atomic::{fence, Ordering};
 | 
					use core::sync::atomic::{fence, Ordering};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use embassy_hal_common::{into_ref, PeripheralRef};
 | 
					use embassy_hal_common::{into_ref, PeripheralRef};
 | 
				
			||||||
@@ -40,9 +41,8 @@ pub struct Ethernet<'d, T: Instance, P: PHY> {
 | 
				
			|||||||
    pub(crate) tx: TDesRing<'d>,
 | 
					    pub(crate) tx: TDesRing<'d>,
 | 
				
			||||||
    pub(crate) rx: RDesRing<'d>,
 | 
					    pub(crate) rx: RDesRing<'d>,
 | 
				
			||||||
    pins: [PeripheralRef<'d, AnyPin>; 9],
 | 
					    pins: [PeripheralRef<'d, AnyPin>; 9],
 | 
				
			||||||
    _phy: P,
 | 
					    pub(crate) phy: P,
 | 
				
			||||||
    clock_range: u8,
 | 
					    pub(crate) station_management: EthernetStationManagement<T>,
 | 
				
			||||||
    phy_addr: u8,
 | 
					 | 
				
			||||||
    pub(crate) mac_addr: [u8; 6],
 | 
					    pub(crate) mac_addr: [u8; 6],
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -201,9 +201,12 @@ impl<'d, T: Instance, P: PHY> Ethernet<'d, T, P> {
 | 
				
			|||||||
            tx: TDesRing::new(&mut queue.tx_desc, &mut queue.tx_buf),
 | 
					            tx: TDesRing::new(&mut queue.tx_desc, &mut queue.tx_buf),
 | 
				
			||||||
            rx: RDesRing::new(&mut queue.rx_desc, &mut queue.rx_buf),
 | 
					            rx: RDesRing::new(&mut queue.rx_desc, &mut queue.rx_buf),
 | 
				
			||||||
            pins,
 | 
					            pins,
 | 
				
			||||||
            _phy: phy,
 | 
					            phy: phy,
 | 
				
			||||||
            clock_range,
 | 
					            station_management: EthernetStationManagement {
 | 
				
			||||||
            phy_addr,
 | 
					                peri: PhantomData,
 | 
				
			||||||
 | 
					                clock_range: clock_range,
 | 
				
			||||||
 | 
					                phy_addr: phy_addr,
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
            mac_addr,
 | 
					            mac_addr,
 | 
				
			||||||
        };
 | 
					        };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -229,8 +232,8 @@ impl<'d, T: Instance, P: PHY> Ethernet<'d, T, P> {
 | 
				
			|||||||
            w.set_tie(true);
 | 
					            w.set_tie(true);
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        P::phy_reset(&mut this);
 | 
					        this.phy.phy_reset(&mut this.station_management);
 | 
				
			||||||
        P::phy_init(&mut this);
 | 
					        this.phy.phy_init(&mut this.station_management);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        interrupt::ETH.unpend();
 | 
					        interrupt::ETH.unpend();
 | 
				
			||||||
        unsafe { interrupt::ETH.enable() };
 | 
					        unsafe { interrupt::ETH.enable() };
 | 
				
			||||||
@@ -239,7 +242,13 @@ impl<'d, T: Instance, P: PHY> Ethernet<'d, T, P> {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
unsafe impl<'d, T: Instance, P: PHY> StationManagement for Ethernet<'d, T, P> {
 | 
					pub struct EthernetStationManagement<T: Instance> {
 | 
				
			||||||
 | 
					    peri: PhantomData<T>,
 | 
				
			||||||
 | 
					    clock_range: u8,
 | 
				
			||||||
 | 
					    phy_addr: u8,
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					unsafe impl<T: Instance> StationManagement for EthernetStationManagement<T> {
 | 
				
			||||||
    fn smi_read(&mut self, reg: u8) -> u16 {
 | 
					    fn smi_read(&mut self, reg: u8) -> u16 {
 | 
				
			||||||
        let mac = ETH.ethernet_mac();
 | 
					        let mac = ETH.ethernet_mac();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user