esp_hal/ethernet/
xarxa.rs1use core::{
17 any::TypeId,
18 task::{Context, Waker},
19};
20
21use xarxa_driver::{
22 Capabilities,
23 ChecksumOffload,
24 Driver,
25 HardwareAddress,
26 LinkState,
27 NotSupported,
28 PacketBuf,
29 config::PACKET_BUF_SIZE,
30};
31
32use super::{Ethernet, RX_WAKER, TX_WAKER, mac::EmacRegs};
33use crate::{Async, DriverMode, ethernet::phy::Phy};
34
35const MTU: usize = if 1514 < PACKET_BUF_SIZE {
40 1514
41} else {
42 PACKET_BUF_SIZE
43};
44
45impl<'d, Dm: DriverMode + 'static, P: Phy> Driver for Ethernet<'d, Dm, P> {
46 fn capabilities(&self) -> Capabilities {
47 let mut caps = Capabilities::default();
48 caps.max_transmission_unit = MTU;
49 let checksum = ChecksumOffload {
52 tx: property!("ethernet.tx_checksum_offload"),
53 rx: property!("ethernet.rx_checksum_offload"),
54 };
55 caps.checksum.ipv4 = checksum;
56 caps.checksum.tcp = checksum;
57 caps.checksum.udp = checksum;
58 caps.checksum.icmpv4 = checksum;
59 caps.checksum.icmpv6 = checksum;
60 caps
61 }
62
63 fn hardware_address(&self) -> HardwareAddress {
64 HardwareAddress::Ethernet(self.mac_addr())
65 }
66
67 fn link_state(&mut self) -> LinkState {
68 let state = self.poll_link(None);
69 if state.up {
70 self.set_speed(state.speed);
71 self.set_duplex(state.duplex);
72 LinkState::Up
73 } else {
74 LinkState::Down
75 }
76 }
77
78 fn register_waker(&mut self, waker: &Waker) -> Result<(), NotSupported> {
79 if TypeId::of::<Dm>() == TypeId::of::<Async>() {
80 RX_WAKER.register(waker);
82 TX_WAKER.register(waker);
83 self.poll_link(Some(&mut Context::from_waker(waker)));
86 Ok(())
87 } else {
88 Err(NotSupported)
89 }
90 }
91
92 fn receive(&mut self) -> Option<PacketBuf> {
93 let Some(frame) = self.rx.receive() else {
94 EmacRegs.demand_rx_poll();
97 return None;
98 };
99
100 let buffer = if frame.len() > PACKET_BUF_SIZE {
101 warn!(
102 "Dropping a {} byte frame, the packet buffer holds {} bytes",
103 frame.len(),
104 PACKET_BUF_SIZE
105 );
106 None
107 } else if let Some(mut buffer) = PacketBuf::try_new() {
108 buffer.set_len(frame.len());
109 buffer.copy_from_slice(frame);
110 Some(buffer)
111 } else {
112 None
115 };
116
117 self.rx.pop();
118 EmacRegs.demand_rx_poll();
119
120 buffer
121 }
122
123 fn can_transmit(&mut self) -> bool {
124 self.tx.available_buf().is_some()
125 }
126
127 fn transmit(&mut self, buffer: PacketBuf) -> Result<(), PacketBuf> {
128 let Some(slot) = self.tx.available_buf() else {
129 return Err(buffer);
130 };
131
132 let len = buffer.len().min(MTU);
133 slot[..len].copy_from_slice(&buffer[..len]);
134
135 self.tx.commit(len);
136 EmacRegs.demand_tx_poll();
137
138 Ok(())
139 }
140}