1#![macro_use]
3
4#[cfg_attr(any(eth_v1a, eth_v1b, eth_v1c), path = "v1/mod.rs")]
5#[cfg_attr(eth_v2, path = "v2/mod.rs")]
6mod _version;
7pub mod generic_smi;
8
9use core::mem::MaybeUninit;
10use core::task::Context;
11
12use embassy_net_driver::{Capabilities, HardwareAddress, LinkState};
13use embassy_sync::waitqueue::AtomicWaker;
14
15pub use self::_version::{InterruptHandler, *};
16use crate::rcc::RccPeripheral;
17
18#[allow(unused)]
19const MTU: usize = 1514;
20const TX_BUFFER_SIZE: usize = 1514;
21const RX_BUFFER_SIZE: usize = 1536;
22
23#[repr(C, align(8))]
24#[derive(Copy, Clone)]
25pub(crate) struct Packet<const N: usize>([u8; N]);
26
27pub struct PacketQueue<const TX: usize, const RX: usize> {
36 tx_desc: [TDes; TX],
37 rx_desc: [RDes; RX],
38 tx_buf: [Packet<TX_BUFFER_SIZE>; TX],
39 rx_buf: [Packet<RX_BUFFER_SIZE>; RX],
40}
41
42impl<const TX: usize, const RX: usize> PacketQueue<TX, RX> {
43 pub const fn new() -> Self {
45 Self {
46 tx_desc: [const { TDes::new() }; TX],
47 rx_desc: [const { RDes::new() }; RX],
48 tx_buf: [Packet([0; TX_BUFFER_SIZE]); TX],
49 rx_buf: [Packet([0; RX_BUFFER_SIZE]); RX],
50 }
51 }
52
53 pub fn init(this: &mut MaybeUninit<Self>) {
66 unsafe {
67 this.as_mut_ptr().write_bytes(0u8, 1);
68 }
69 }
70}
71
72static WAKER: AtomicWaker = AtomicWaker::new();
73
74impl<'d, T: Instance, P: PHY> embassy_net_driver::Driver for Ethernet<'d, T, P> {
75 type RxToken<'a>
76 = RxToken<'a, 'd>
77 where
78 Self: 'a;
79 type TxToken<'a>
80 = TxToken<'a, 'd>
81 where
82 Self: 'a;
83
84 fn receive(&mut self, cx: &mut Context) -> Option<(Self::RxToken<'_>, Self::TxToken<'_>)> {
85 WAKER.register(cx.waker());
86 if self.rx.available().is_some() && self.tx.available().is_some() {
87 Some((RxToken { rx: &mut self.rx }, TxToken { tx: &mut self.tx }))
88 } else {
89 None
90 }
91 }
92
93 fn transmit(&mut self, cx: &mut Context) -> Option<Self::TxToken<'_>> {
94 WAKER.register(cx.waker());
95 if self.tx.available().is_some() {
96 Some(TxToken { tx: &mut self.tx })
97 } else {
98 None
99 }
100 }
101
102 fn capabilities(&self) -> Capabilities {
103 let mut caps = Capabilities::default();
104 caps.max_transmission_unit = MTU;
105 caps.max_burst_size = Some(self.tx.len());
106 caps
107 }
108
109 fn link_state(&mut self, cx: &mut Context) -> LinkState {
110 if self.phy.poll_link(&mut self.station_management, cx) {
111 LinkState::Up
112 } else {
113 LinkState::Down
114 }
115 }
116
117 fn hardware_address(&self) -> HardwareAddress {
118 HardwareAddress::Ethernet(self.mac_addr)
119 }
120}
121
122pub struct RxToken<'a, 'd> {
124 rx: &'a mut RDesRing<'d>,
125}
126
127impl<'a, 'd> embassy_net_driver::RxToken for RxToken<'a, 'd> {
128 fn consume<R, F>(self, f: F) -> R
129 where
130 F: FnOnce(&mut [u8]) -> R,
131 {
132 let pkt = unwrap!(self.rx.available());
134 let r = f(pkt);
135 self.rx.pop_packet();
136 r
137 }
138}
139
140pub struct TxToken<'a, 'd> {
142 tx: &'a mut TDesRing<'d>,
143}
144
145impl<'a, 'd> embassy_net_driver::TxToken for TxToken<'a, 'd> {
146 fn consume<R, F>(self, len: usize, f: F) -> R
147 where
148 F: FnOnce(&mut [u8]) -> R,
149 {
150 let pkt = unwrap!(self.tx.available());
152 let r = f(&mut pkt[..len]);
153 self.tx.transmit(len);
154 r
155 }
156}
157
158pub unsafe trait StationManagement {
164 fn smi_read(&mut self, phy_addr: u8, reg: u8) -> u16;
166 fn smi_write(&mut self, phy_addr: u8, reg: u8, val: u16);
168}
169
170pub unsafe trait PHY {
176 fn phy_reset<S: StationManagement>(&mut self, sm: &mut S);
178 fn phy_init<S: StationManagement>(&mut self, sm: &mut S);
180 fn poll_link<S: StationManagement>(&mut self, sm: &mut S, cx: &mut Context) -> bool;
182}
183
184impl<'d, T: Instance, P: PHY> Ethernet<'d, T, P> {
185 pub unsafe fn station_management(&mut self) -> &mut impl StationManagement {
194 &mut self.station_management
195 }
196}
197
198trait SealedInstance {
199 fn regs() -> crate::pac::eth::Eth;
200}
201
202#[allow(private_bounds)]
204pub trait Instance: SealedInstance + RccPeripheral + Send + 'static {}
205
206impl SealedInstance for crate::peripherals::ETH {
207 fn regs() -> crate::pac::eth::Eth {
208 crate::pac::ETH
209 }
210}
211impl Instance for crate::peripherals::ETH {}
212
213pin_trait!(RXClkPin, Instance);
214pin_trait!(TXClkPin, Instance);
215pin_trait!(RefClkPin, Instance);
216pin_trait!(MDIOPin, Instance);
217pin_trait!(MDCPin, Instance);
218pin_trait!(RXDVPin, Instance);
219pin_trait!(CRSPin, Instance);
220pin_trait!(RXD0Pin, Instance);
221pin_trait!(RXD1Pin, Instance);
222pin_trait!(RXD2Pin, Instance);
223pin_trait!(RXD3Pin, Instance);
224pin_trait!(TXD0Pin, Instance);
225pin_trait!(TXD1Pin, Instance);
226pin_trait!(TXD2Pin, Instance);
227pin_trait!(TXD3Pin, Instance);
228pin_trait!(TXEnPin, Instance);