stm32_eth/dma/
smoltcp_phy.rs1use super::rx::RxRing;
2use super::tx::TxRing;
3use super::EthernetDMA;
4
5#[cfg(feature = "ptp")]
6use super::PacketId;
7
8use smoltcp::phy::{ChecksumCapabilities, Device, DeviceCapabilities, RxToken, TxToken};
9use smoltcp::time::Instant;
10
11impl<'a, 'rx, 'tx> Device for &'a mut EthernetDMA<'rx, 'tx> {
13 type RxToken<'token>
14 = EthRxToken<'token, 'rx>
15 where
16 Self: 'token;
17 type TxToken<'token>
18 = EthTxToken<'token, 'tx>
19 where
20 Self: 'token;
21
22 fn capabilities(&self) -> DeviceCapabilities {
23 let mut caps = DeviceCapabilities::default();
24 caps.max_transmission_unit = crate::dma::MTU;
25 caps.max_burst_size = Some(1);
26 caps.checksum = ChecksumCapabilities::ignored();
27 caps
28 }
29
30 fn receive(&mut self, _timestamp: Instant) -> Option<(Self::RxToken<'_>, Self::TxToken<'_>)> {
31 if self.tx_available() && self.rx_available() {
32 #[cfg(feature = "ptp")]
33 let rx_packet_id = self.next_packet_id();
34
35 let EthernetDMA {
36 rx_ring, tx_ring, ..
37 } = self;
38
39 let rx = EthRxToken {
40 rx_ring,
41 #[cfg(feature = "ptp")]
42 meta: rx_packet_id,
43 };
44
45 let tx = EthTxToken {
46 tx_ring,
47 #[cfg(feature = "ptp")]
48 meta: None,
49 };
50 Some((rx, tx))
51 } else {
52 None
53 }
54 }
55
56 fn transmit(&mut self, _timestamp: Instant) -> Option<Self::TxToken<'_>> {
57 if self.tx_available() {
58 let EthernetDMA { tx_ring, .. } = self;
59 Some(EthTxToken {
60 tx_ring,
61 #[cfg(feature = "ptp")]
62 meta: None,
63 })
64 } else {
65 None
66 }
67 }
68}
69
70pub struct EthRxToken<'a, 'rx> {
73 rx_ring: &'a mut RxRing<'rx>,
74 #[cfg(feature = "ptp")]
75 meta: PacketId,
76}
77
78impl<'dma, 'rx> RxToken for EthRxToken<'dma, 'rx> {
79 fn consume<R, F>(self, f: F) -> R
80 where
81 F: FnOnce(&[u8]) -> R,
82 {
83 #[cfg(feature = "ptp")]
84 let meta = Some(self.meta.into());
85
86 #[cfg(not(feature = "ptp"))]
87 let meta = None;
88
89 let packet = self.rx_ring.recv_next(meta).ok().unwrap();
91 let result = f(&packet);
92 packet.free();
93 result
94 }
95
96 #[cfg(feature = "ptp")]
97 fn meta(&self) -> smoltcp::phy::PacketMeta {
98 self.meta.clone().into()
99 }
100}
101
102pub struct EthTxToken<'a, 'tx> {
105 tx_ring: &'a mut TxRing<'tx>,
106 #[cfg(feature = "ptp")]
107 meta: Option<PacketId>,
108}
109
110impl<'dma, 'tx> TxToken for EthTxToken<'dma, 'tx> {
111 fn consume<R, F>(self, len: usize, f: F) -> R
112 where
113 F: FnOnce(&mut [u8]) -> R,
114 {
115 #[cfg(feature = "ptp")]
116 let meta = self.meta.map(Into::into);
117 #[cfg(not(feature = "ptp"))]
118 let meta = None;
119
120 let mut tx_packet = self.tx_ring.send_next(len, meta).ok().unwrap();
123 let res = f(&mut tx_packet);
124 tx_packet.send();
125 res
126 }
127
128 #[cfg(feature = "ptp")]
129 fn set_meta(&mut self, meta: smoltcp::phy::PacketMeta) {
130 self.meta = Some(meta.into());
131 }
132}