zynq7000_hal/eth/
embassy_net.rs1use core::sync::atomic::AtomicBool;
3
4pub use crate::eth::smoltcp::DescriptorsAndBuffers;
5use crate::eth::smoltcp::{SmoltcpRxToken, SmoltcpTxToken};
6pub use crate::eth::{EthernetId, InterruptResult};
7use embassy_sync::waitqueue::AtomicWaker;
8
9pub(crate) static TX_WAKER: AtomicWaker = AtomicWaker::new();
10pub(crate) static RX_WAKER: AtomicWaker = AtomicWaker::new();
11
12static LINK_WAKER: AtomicWaker = AtomicWaker::new();
13static LINK_STATE: AtomicBool = AtomicBool::new(false);
14
15pub fn on_interrupt(eth_id: EthernetId) -> InterruptResult {
19 super::on_interrupt(eth_id, true, true)
20}
21
22#[inline]
23pub fn link_state() -> embassy_net_driver::LinkState {
24 match LINK_STATE.load(core::sync::atomic::Ordering::Relaxed) {
25 true => embassy_net_driver::LinkState::Up,
26 false => embassy_net_driver::LinkState::Down,
27 }
28}
29
30pub fn update_link_state(new_state: embassy_net_driver::LinkState) {
31 let new_value = match new_state {
32 embassy_net_driver::LinkState::Up => true,
33 embassy_net_driver::LinkState::Down => false,
34 };
35 if LINK_STATE.swap(new_value, core::sync::atomic::Ordering::Relaxed) != new_value {
36 LINK_WAKER.wake();
37 }
38}
39
40pub struct Driver(super::smoltcp::CommonSmoltcpDriver);
41
42impl Driver {
43 pub fn new(eth: &super::Ethernet, mac_addr: [u8; 6], bufs: DescriptorsAndBuffers) -> Self {
44 let tx_burst_len = bufs.tx_burst_len();
45 Self(super::smoltcp::CommonSmoltcpDriver::new(
46 eth.id(),
47 mac_addr,
48 bufs,
49 tx_burst_len,
50 ))
51 }
52}
53
54impl embassy_net_driver::Driver for Driver {
55 type RxToken<'a>
56 = SmoltcpRxToken<'a>
57 where
58 Self: 'a;
59
60 type TxToken<'a>
61 = SmoltcpTxToken<'a>
62 where
63 Self: 'a;
64
65 fn receive(
66 &mut self,
67 cx: &mut core::task::Context,
68 ) -> Option<(Self::RxToken<'_>, Self::TxToken<'_>)> {
69 RX_WAKER.register(cx.waker());
70 TX_WAKER.register(cx.waker());
71 self.0.receive()
72 }
73
74 fn transmit(&mut self, cx: &mut core::task::Context) -> Option<Self::TxToken<'_>> {
75 TX_WAKER.register(cx.waker());
76 self.0.transmit()
77 }
78
79 fn link_state(&mut self, cx: &mut core::task::Context) -> embassy_net_driver::LinkState {
80 LINK_WAKER.register(cx.waker());
81 link_state()
82 }
83
84 fn capabilities(&self) -> embassy_net_driver::Capabilities {
85 let mut capabilities = embassy_net_driver::Capabilities::default();
86 capabilities.max_transmission_unit = super::MTU;
87 capabilities.max_burst_size = Some(self.0.burst_size);
88 capabilities.checksum.ipv4 = embassy_net_driver::Checksum::Both;
89 capabilities.checksum.udp = embassy_net_driver::Checksum::Both;
90 capabilities.checksum.tcp = embassy_net_driver::Checksum::Both;
91 capabilities.checksum.icmpv4 = embassy_net_driver::Checksum::None;
92 capabilities.checksum.icmpv6 = embassy_net_driver::Checksum::None;
93 capabilities
94 }
95
96 fn hardware_address(&self) -> embassy_net_driver::HardwareAddress {
97 embassy_net_driver::HardwareAddress::Ethernet(self.0.mac_addr)
98 }
99}