aboutsummaryrefslogtreecommitdiff
path: root/embassy-net-driver
diff options
context:
space:
mode:
authorDario Nieuwenhuis <[email protected]>2022-12-26 03:33:49 +0100
committerDario Nieuwenhuis <[email protected]>2022-12-26 04:49:08 +0100
commit1f033d509afb4e590a81896de66af683fda4e706 (patch)
tree5c10000e08d00de221a770c81fb9127a35dd0343 /embassy-net-driver
parent639b3f1d5b4b2897b326edc52f66f18caaa3bd3e (diff)
net: split driver trait to a separate crate.
Diffstat (limited to 'embassy-net-driver')
-rw-r--r--embassy-net-driver/Cargo.toml15
-rw-r--r--embassy-net-driver/src/lib.rs175
2 files changed, 190 insertions, 0 deletions
diff --git a/embassy-net-driver/Cargo.toml b/embassy-net-driver/Cargo.toml
new file mode 100644
index 000000000..7ab9d1194
--- /dev/null
+++ b/embassy-net-driver/Cargo.toml
@@ -0,0 +1,15 @@
1[package]
2name = "embassy-net-driver"
3version = "0.1.0"
4edition = "2021"
5license = "MIT OR Apache-2.0"
6
7
8[package.metadata.embassy_docs]
9src_base = "https://github.com/embassy-rs/embassy/blob/embassy-net-driver-v$VERSION/embassy-net/src/"
10src_base_git = "https://github.com/embassy-rs/embassy/blob/$COMMIT/embassy-net-driver/src/"
11features = ["defmt"]
12target = "thumbv7em-none-eabi"
13
14[dependencies]
15defmt = { version = "0.3", optional = true } \ No newline at end of file
diff --git a/embassy-net-driver/src/lib.rs b/embassy-net-driver/src/lib.rs
new file mode 100644
index 000000000..a39cfecc1
--- /dev/null
+++ b/embassy-net-driver/src/lib.rs
@@ -0,0 +1,175 @@
1#![no_std]
2
3use core::task::Context;
4
5pub trait Driver {
6 type RxToken<'a>: RxToken
7 where
8 Self: 'a;
9 type TxToken<'a>: TxToken
10 where
11 Self: 'a;
12
13 fn receive(&mut self, cx: &mut Context) -> Option<(Self::RxToken<'_>, Self::TxToken<'_>)>;
14 fn transmit(&mut self, cx: &mut Context) -> Option<Self::TxToken<'_>>;
15 fn link_state(&mut self, cx: &mut Context) -> LinkState;
16
17 fn capabilities(&self) -> Capabilities;
18 fn ethernet_address(&self) -> [u8; 6];
19}
20
21impl<T: ?Sized + Driver> Driver for &mut T {
22 type RxToken<'a> = T::RxToken<'a>
23 where
24 Self: 'a;
25 type TxToken<'a> = T::TxToken<'a>
26 where
27 Self: 'a;
28
29 fn transmit(&mut self, cx: &mut Context) -> Option<Self::TxToken<'_>> {
30 T::transmit(self, cx)
31 }
32 fn receive(&mut self, cx: &mut Context) -> Option<(Self::RxToken<'_>, Self::TxToken<'_>)> {
33 T::receive(self, cx)
34 }
35 fn capabilities(&self) -> Capabilities {
36 T::capabilities(self)
37 }
38 fn link_state(&mut self, cx: &mut Context) -> LinkState {
39 T::link_state(self, cx)
40 }
41 fn ethernet_address(&self) -> [u8; 6] {
42 T::ethernet_address(self)
43 }
44}
45
46/// A token to receive a single network packet.
47pub trait RxToken {
48 /// Consumes the token to receive a single network packet.
49 ///
50 /// This method receives a packet and then calls the given closure `f` with the raw
51 /// packet bytes as argument.
52 fn consume<R, F>(self, f: F) -> R
53 where
54 F: FnOnce(&mut [u8]) -> R;
55}
56
57/// A token to transmit a single network packet.
58pub trait TxToken {
59 /// Consumes the token to send a single network packet.
60 ///
61 /// This method constructs a transmit buffer of size `len` and calls the passed
62 /// closure `f` with a mutable reference to that buffer. The closure should construct
63 /// a valid network packet (e.g. an ethernet packet) in the buffer. When the closure
64 /// returns, the transmit buffer is sent out.
65 fn consume<R, F>(self, len: usize, f: F) -> R
66 where
67 F: FnOnce(&mut [u8]) -> R;
68}
69
70/// A description of device capabilities.
71///
72/// Higher-level protocols may achieve higher throughput or lower latency if they consider
73/// the bandwidth or packet size limitations.
74#[derive(Debug, Clone, Default)]
75#[cfg_attr(feature = "defmt", derive(defmt::Format))]
76#[non_exhaustive]
77pub struct Capabilities {
78 /// Medium of the device.
79 ///
80 /// This indicates what kind of packet the sent/received bytes are, and determines
81 /// some behaviors of Interface. For example, ARP/NDISC address resolution is only done
82 /// for Ethernet mediums.
83 pub medium: Medium,
84
85 /// Maximum transmission unit.
86 ///
87 /// The network device is unable to send or receive frames larger than the value returned
88 /// by this function.
89 ///
90 /// For Ethernet devices, this is the maximum Ethernet frame size, including the Ethernet header (14 octets), but
91 /// *not* including the Ethernet FCS (4 octets). Therefore, Ethernet MTU = IP MTU + 14.
92 ///
93 /// Note that in Linux and other OSes, "MTU" is the IP MTU, not the Ethernet MTU, even for Ethernet
94 /// devices. This is a common source of confusion.
95 ///
96 /// Most common IP MTU is 1500. Minimum is 576 (for IPv4) or 1280 (for IPv6). Maximum is 9216 octets.
97 pub max_transmission_unit: usize,
98
99 /// Maximum burst size, in terms of MTU.
100 ///
101 /// The network device is unable to send or receive bursts large than the value returned
102 /// by this function.
103 ///
104 /// If `None`, there is no fixed limit on burst size, e.g. if network buffers are
105 /// dynamically allocated.
106 pub max_burst_size: Option<usize>,
107
108 /// Checksum behavior.
109 ///
110 /// If the network device is capable of verifying or computing checksums for some protocols,
111 /// it can request that the stack not do so in software to improve performance.
112 pub checksum: ChecksumCapabilities,
113}
114
115/// Type of medium of a device.
116#[derive(Debug, Eq, PartialEq, Copy, Clone)]
117#[cfg_attr(feature = "defmt", derive(defmt::Format))]
118pub enum Medium {
119 /// Ethernet medium. Devices of this type send and receive Ethernet frames,
120 /// and interfaces using it must do neighbor discovery via ARP or NDISC.
121 ///
122 /// Examples of devices of this type are Ethernet, WiFi (802.11), Linux `tap`, and VPNs in tap (layer 2) mode.
123 Ethernet,
124
125 /// IP medium. Devices of this type send and receive IP frames, without an
126 /// Ethernet header. MAC addresses are not used, and no neighbor discovery (ARP, NDISC) is done.
127 ///
128 /// Examples of devices of this type are the Linux `tun`, PPP interfaces, VPNs in tun (layer 3) mode.
129 Ip,
130}
131
132impl Default for Medium {
133 fn default() -> Medium {
134 Medium::Ethernet
135 }
136}
137
138/// A description of checksum behavior for every supported protocol.
139#[derive(Debug, Clone, Default)]
140#[cfg_attr(feature = "defmt", derive(defmt::Format))]
141#[non_exhaustive]
142pub struct ChecksumCapabilities {
143 pub ipv4: Checksum,
144 pub udp: Checksum,
145 pub tcp: Checksum,
146 pub icmpv4: Checksum,
147 pub icmpv6: Checksum,
148}
149
150/// A description of checksum behavior for a particular protocol.
151#[derive(Debug, Clone, Copy)]
152#[cfg_attr(feature = "defmt", derive(defmt::Format))]
153pub enum Checksum {
154 /// Verify checksum when receiving and compute checksum when sending.
155 Both,
156 /// Verify checksum when receiving.
157 Rx,
158 /// Compute checksum before sending.
159 Tx,
160 /// Ignore checksum completely.
161 None,
162}
163
164impl Default for Checksum {
165 fn default() -> Checksum {
166 Checksum::Both
167 }
168}
169
170#[derive(PartialEq, Eq, Clone, Copy)]
171#[cfg_attr(feature = "defmt", derive(defmt::Format))]
172pub enum LinkState {
173 Down,
174 Up,
175}