aboutsummaryrefslogtreecommitdiff
path: root/embassy-net/src/driver_util.rs
diff options
context:
space:
mode:
Diffstat (limited to 'embassy-net/src/driver_util.rs')
-rw-r--r--embassy-net/src/driver_util.rs106
1 files changed, 106 insertions, 0 deletions
diff --git a/embassy-net/src/driver_util.rs b/embassy-net/src/driver_util.rs
new file mode 100644
index 000000000..b2af1d499
--- /dev/null
+++ b/embassy-net/src/driver_util.rs
@@ -0,0 +1,106 @@
1use core::task::Context;
2
3use embassy_net_driver::{Capabilities, Checksum, Driver, RxToken, TxToken};
4use smoltcp::phy::{self, Medium};
5use smoltcp::time::Instant;
6
7pub(crate) struct DriverAdapter<'d, 'c, T>
8where
9 T: Driver,
10{
11 // must be Some when actually using this to rx/tx
12 pub cx: Option<&'d mut Context<'c>>,
13 pub inner: &'d mut T,
14 pub medium: Medium,
15}
16
17impl<'d, 'c, T> phy::Device for DriverAdapter<'d, 'c, T>
18where
19 T: Driver,
20{
21 type RxToken<'a> = RxTokenAdapter<T::RxToken<'a>> where Self: 'a;
22 type TxToken<'a> = TxTokenAdapter<T::TxToken<'a>> where Self: 'a;
23
24 fn receive(&mut self, _timestamp: Instant) -> Option<(Self::RxToken<'_>, Self::TxToken<'_>)> {
25 self.inner
26 .receive(unwrap!(self.cx.as_deref_mut()))
27 .map(|(rx, tx)| (RxTokenAdapter(rx), TxTokenAdapter(tx)))
28 }
29
30 /// Construct a transmit token.
31 fn transmit(&mut self, _timestamp: Instant) -> Option<Self::TxToken<'_>> {
32 self.inner.transmit(unwrap!(self.cx.as_deref_mut())).map(TxTokenAdapter)
33 }
34
35 /// Get a description of device capabilities.
36 fn capabilities(&self) -> phy::DeviceCapabilities {
37 fn convert(c: Checksum) -> phy::Checksum {
38 match c {
39 Checksum::Both => phy::Checksum::Both,
40 Checksum::Tx => phy::Checksum::Tx,
41 Checksum::Rx => phy::Checksum::Rx,
42 Checksum::None => phy::Checksum::None,
43 }
44 }
45 let caps: Capabilities = self.inner.capabilities();
46 let mut smolcaps = phy::DeviceCapabilities::default();
47
48 smolcaps.max_transmission_unit = caps.max_transmission_unit;
49 smolcaps.max_burst_size = caps.max_burst_size;
50 smolcaps.medium = self.medium;
51 smolcaps.checksum.ipv4 = convert(caps.checksum.ipv4);
52 smolcaps.checksum.tcp = convert(caps.checksum.tcp);
53 smolcaps.checksum.udp = convert(caps.checksum.udp);
54 #[cfg(feature = "proto-ipv4")]
55 {
56 smolcaps.checksum.icmpv4 = convert(caps.checksum.icmpv4);
57 }
58 #[cfg(feature = "proto-ipv6")]
59 {
60 smolcaps.checksum.icmpv6 = convert(caps.checksum.icmpv6);
61 }
62
63 smolcaps
64 }
65}
66
67pub(crate) struct RxTokenAdapter<T>(T)
68where
69 T: RxToken;
70
71impl<T> phy::RxToken for RxTokenAdapter<T>
72where
73 T: RxToken,
74{
75 fn consume<R, F>(self, f: F) -> R
76 where
77 F: FnOnce(&[u8]) -> R,
78 {
79 self.0.consume(|buf| {
80 #[cfg(feature = "packet-trace")]
81 trace!("rx: {:?}", buf);
82 f(buf)
83 })
84 }
85}
86
87pub(crate) struct TxTokenAdapter<T>(T)
88where
89 T: TxToken;
90
91impl<T> phy::TxToken for TxTokenAdapter<T>
92where
93 T: TxToken,
94{
95 fn consume<R, F>(self, len: usize, f: F) -> R
96 where
97 F: FnOnce(&mut [u8]) -> R,
98 {
99 self.0.consume(len, |buf| {
100 let r = f(buf);
101 #[cfg(feature = "packet-trace")]
102 trace!("tx: {:?}", buf);
103 r
104 })
105 }
106}