aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.github/workflows/doc.yml1
-rw-r--r--.vscode/settings.json22
-rw-r--r--embassy-net-driver/Cargo.toml15
-rw-r--r--embassy-net-driver/src/lib.rs175
-rw-r--r--embassy-net/Cargo.toml3
-rw-r--r--embassy-net/src/device.rs117
-rw-r--r--embassy-net/src/lib.rs17
-rw-r--r--embassy-net/src/tcp.rs12
-rw-r--r--embassy-net/src/udp.rs5
-rw-r--r--embassy-stm32/Cargo.toml4
-rw-r--r--embassy-stm32/src/eth/mod.rs139
-rw-r--r--embassy-stm32/src/eth/v1/mod.rs4
-rw-r--r--embassy-usb/Cargo.toml2
-rw-r--r--embassy-usb/src/class/cdc_ncm/embassy_net.rs14
-rw-r--r--embassy-usb/src/class/cdc_ncm/mod.rs1
-rw-r--r--examples/nrf/Cargo.toml2
-rw-r--r--examples/rp/Cargo.toml2
-rw-r--r--examples/std/Cargo.toml1
-rw-r--r--examples/std/src/tuntap.rs12
-rw-r--r--examples/stm32f7/Cargo.toml2
-rw-r--r--examples/stm32h7/Cargo.toml2
-rw-r--r--examples/stm32l5/Cargo.toml2
22 files changed, 347 insertions, 207 deletions
diff --git a/.github/workflows/doc.yml b/.github/workflows/doc.yml
index eb460e738..8a341b8f7 100644
--- a/.github/workflows/doc.yml
+++ b/.github/workflows/doc.yml
@@ -69,6 +69,7 @@ jobs:
69 builder ./embassy-futures crates/embassy-futures/git.zup 69 builder ./embassy-futures crates/embassy-futures/git.zup
70 builder ./embassy-lora crates/embassy-lora/git.zup 70 builder ./embassy-lora crates/embassy-lora/git.zup
71 builder ./embassy-net crates/embassy-net/git.zup 71 builder ./embassy-net crates/embassy-net/git.zup
72 builder ./embassy-net-driver crates/embassy-net-driver/git.zup
72 builder ./embassy-nrf crates/embassy-nrf/git.zup 73 builder ./embassy-nrf crates/embassy-nrf/git.zup
73 builder ./embassy-rp crates/embassy-rp/git.zup 74 builder ./embassy-rp crates/embassy-rp/git.zup
74 builder ./embassy-sync crates/embassy-sync/git.zup 75 builder ./embassy-sync crates/embassy-sync/git.zup
diff --git a/.vscode/settings.json b/.vscode/settings.json
index 6b8183f89..086f435da 100644
--- a/.vscode/settings.json
+++ b/.vscode/settings.json
@@ -4,27 +4,21 @@
4 "rust-analyzer.checkOnSave.noDefaultFeatures": true, 4 "rust-analyzer.checkOnSave.noDefaultFeatures": true,
5 "rust-analyzer.cargo.noDefaultFeatures": true, 5 "rust-analyzer.cargo.noDefaultFeatures": true,
6 "rust-analyzer.procMacro.enable": true, 6 "rust-analyzer.procMacro.enable": true,
7 //"rust-analyzer.cargo.target": "thumbv7em-none-eabi", 7 "rust-analyzer.cargo.target": "thumbv7em-none-eabi",
8 "rust-analyzer.cargo.target": "thumbv8m.main-none-eabihf", 8 //"rust-analyzer.cargo.target": "thumbv8m.main-none-eabihf",
9 "rust-analyzer.cargo.features": [ 9 "rust-analyzer.cargo.features": [
10 // These are needed to prevent embassy-net from failing to build 10 "nightly",
11 //"embassy-net/medium-ethernet",
12 //"embassy-net/tcp",
13 //"time-tick-16mhz",
14 //"defmt-timestamp-uptime",
15 //"nightly",
16 //"unstable-traits",
17 ], 11 ],
18 "rust-analyzer.linkedProjects": [ 12 "rust-analyzer.linkedProjects": [
19 // Declare for the target you wish to develop 13 // Declare for the target you wish to develop
20 //"embassy-executor/Cargo.toml", 14 // "embassy-executor/Cargo.toml",
21 //"embassy-sync/Cargo.toml", 15 // "embassy-sync/Cargo.toml",
22 //"examples/nrf/Cargo.toml", 16 "examples/nrf/Cargo.toml",
23 // "examples/nrf-rtos-trace/Cargo.toml", 17 // "examples/nrf-rtos-trace/Cargo.toml",
24 // "examples/rp/Cargo.toml", 18 // "examples/rp/Cargo.toml",
25 // "examples/std/Cargo.toml", 19 // "examples/std/Cargo.toml",
26 // "examples/stm32f0/Cargo.toml", 20 // "examples/stm32f0/Cargo.toml",
27 //"examples/stm32f1/Cargo.toml", 21 // "examples/stm32f1/Cargo.toml",
28 // "examples/stm32f2/Cargo.toml", 22 // "examples/stm32f2/Cargo.toml",
29 // "examples/stm32f3/Cargo.toml", 23 // "examples/stm32f3/Cargo.toml",
30 // "examples/stm32f4/Cargo.toml", 24 // "examples/stm32f4/Cargo.toml",
@@ -35,7 +29,7 @@
35 // "examples/stm32l0/Cargo.toml", 29 // "examples/stm32l0/Cargo.toml",
36 // "examples/stm32l1/Cargo.toml", 30 // "examples/stm32l1/Cargo.toml",
37 // "examples/stm32l4/Cargo.toml", 31 // "examples/stm32l4/Cargo.toml",
38 "examples/stm32l5/Cargo.toml", 32 // "examples/stm32l5/Cargo.toml",
39 // "examples/stm32u5/Cargo.toml", 33 // "examples/stm32u5/Cargo.toml",
40 // "examples/stm32wb/Cargo.toml", 34 // "examples/stm32wb/Cargo.toml",
41 // "examples/stm32wb55/Cargo.toml", 35 // "examples/stm32wb55/Cargo.toml",
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}
diff --git a/embassy-net/Cargo.toml b/embassy-net/Cargo.toml
index 357f87922..9214fd17e 100644
--- a/embassy-net/Cargo.toml
+++ b/embassy-net/Cargo.toml
@@ -15,7 +15,7 @@ target = "thumbv7em-none-eabi"
15default = [] 15default = []
16std = [] 16std = []
17 17
18defmt = ["dep:defmt", "smoltcp/defmt"] 18defmt = ["dep:defmt", "smoltcp/defmt", "embassy-net-driver/defmt"]
19 19
20nightly = ["dep:embedded-io", "embedded-io?/async", "dep:embedded-nal-async"] 20nightly = ["dep:embedded-io", "embedded-io?/async", "dep:embedded-nal-async"]
21unstable-traits = [] 21unstable-traits = []
@@ -33,6 +33,7 @@ medium-ip = ["smoltcp/medium-ip"]
33defmt = { version = "0.3", optional = true } 33defmt = { version = "0.3", optional = true }
34log = { version = "0.4.14", optional = true } 34log = { version = "0.4.14", optional = true }
35 35
36embassy-net-driver = { version = "0.1.0", path = "../embassy-net-driver" }
36embassy-time = { version = "0.1.0", path = "../embassy-time" } 37embassy-time = { version = "0.1.0", path = "../embassy-time" }
37embassy-sync = { version = "0.1.0", path = "../embassy-sync" } 38embassy-sync = { version = "0.1.0", path = "../embassy-sync" }
38embedded-io = { version = "0.4.0", optional = true } 39embedded-io = { version = "0.4.0", optional = true }
diff --git a/embassy-net/src/device.rs b/embassy-net/src/device.rs
index 5d86ca91e..44f7dc7bd 100644
--- a/embassy-net/src/device.rs
+++ b/embassy-net/src/device.rs
@@ -1,93 +1,20 @@
1use core::task::Context; 1use core::task::Context;
2 2
3use embassy_net_driver::{Capabilities, Checksum, Driver, Medium, RxToken, TxToken};
3use smoltcp::phy; 4use smoltcp::phy;
4pub use smoltcp::phy::{Checksum, ChecksumCapabilities, DeviceCapabilities, Medium};
5 5
6#[derive(PartialEq, Eq, Clone, Copy)] 6pub(crate) struct DriverAdapter<'d, 'c, T>
7pub enum LinkState {
8 Down,
9 Up,
10}
11
12pub trait Device {
13 type RxToken<'a>: RxToken
14 where
15 Self: 'a;
16 type TxToken<'a>: TxToken
17 where
18 Self: 'a;
19
20 fn receive(&mut self, cx: &mut Context) -> Option<(Self::RxToken<'_>, Self::TxToken<'_>)>;
21 fn transmit(&mut self, cx: &mut Context) -> Option<Self::TxToken<'_>>;
22 fn link_state(&mut self, cx: &mut Context) -> LinkState;
23
24 fn capabilities(&self) -> phy::DeviceCapabilities;
25 fn ethernet_address(&self) -> [u8; 6];
26}
27
28impl<T: ?Sized + Device> Device for &mut T {
29 type RxToken<'a> = T::RxToken<'a>
30 where
31 Self: 'a;
32 type TxToken<'a> = T::TxToken<'a>
33 where
34 Self: 'a;
35
36 fn transmit(&mut self, cx: &mut Context) -> Option<Self::TxToken<'_>> {
37 T::transmit(self, cx)
38 }
39 fn receive(&mut self, cx: &mut Context) -> Option<(Self::RxToken<'_>, Self::TxToken<'_>)> {
40 T::receive(self, cx)
41 }
42 fn capabilities(&self) -> phy::DeviceCapabilities {
43 T::capabilities(self)
44 }
45 fn link_state(&mut self, cx: &mut Context) -> LinkState {
46 T::link_state(self, cx)
47 }
48 fn ethernet_address(&self) -> [u8; 6] {
49 T::ethernet_address(self)
50 }
51}
52
53/// A token to receive a single network packet.
54pub trait RxToken {
55 /// Consumes the token to receive a single network packet.
56 ///
57 /// This method receives a packet and then calls the given closure `f` with the raw
58 /// packet bytes as argument.
59 fn consume<R, F>(self, f: F) -> R
60 where
61 F: FnOnce(&mut [u8]) -> R;
62}
63
64/// A token to transmit a single network packet.
65pub trait TxToken {
66 /// Consumes the token to send a single network packet.
67 ///
68 /// This method constructs a transmit buffer of size `len` and calls the passed
69 /// closure `f` with a mutable reference to that buffer. The closure should construct
70 /// a valid network packet (e.g. an ethernet packet) in the buffer. When the closure
71 /// returns, the transmit buffer is sent out.
72 fn consume<R, F>(self, len: usize, f: F) -> R
73 where
74 F: FnOnce(&mut [u8]) -> R;
75}
76
77///////////////////////////
78
79pub(crate) struct DeviceAdapter<'d, 'c, T>
80where 7where
81 T: Device, 8 T: Driver,
82{ 9{
83 // must be Some when actually using this to rx/tx 10 // must be Some when actually using this to rx/tx
84 pub cx: Option<&'d mut Context<'c>>, 11 pub cx: Option<&'d mut Context<'c>>,
85 pub inner: &'d mut T, 12 pub inner: &'d mut T,
86} 13}
87 14
88impl<'d, 'c, T> phy::Device for DeviceAdapter<'d, 'c, T> 15impl<'d, 'c, T> phy::Device for DriverAdapter<'d, 'c, T>
89where 16where
90 T: Device, 17 T: Driver,
91{ 18{
92 type RxToken<'a> = RxTokenAdapter<T::RxToken<'a>> where Self: 'a; 19 type RxToken<'a> = RxTokenAdapter<T::RxToken<'a>> where Self: 'a;
93 type TxToken<'a> = TxTokenAdapter<T::TxToken<'a>> where Self: 'a; 20 type TxToken<'a> = TxTokenAdapter<T::TxToken<'a>> where Self: 'a;
@@ -105,7 +32,39 @@ where
105 32
106 /// Get a description of device capabilities. 33 /// Get a description of device capabilities.
107 fn capabilities(&self) -> phy::DeviceCapabilities { 34 fn capabilities(&self) -> phy::DeviceCapabilities {
108 self.inner.capabilities() 35 fn convert(c: Checksum) -> phy::Checksum {
36 match c {
37 Checksum::Both => phy::Checksum::Both,
38 Checksum::Tx => phy::Checksum::Tx,
39 Checksum::Rx => phy::Checksum::Rx,
40 Checksum::None => phy::Checksum::None,
41 }
42 }
43 let caps: Capabilities = self.inner.capabilities();
44 let mut smolcaps = phy::DeviceCapabilities::default();
45
46 smolcaps.max_transmission_unit = caps.max_transmission_unit;
47 smolcaps.max_burst_size = caps.max_burst_size;
48 smolcaps.medium = match caps.medium {
49 #[cfg(feature = "medium-ethernet")]
50 Medium::Ethernet => phy::Medium::Ethernet,
51 #[cfg(feature = "medium-ip")]
52 Medium::Ip => phy::Medium::Ip,
53 _ => panic!(
54 "Unsupported medium {:?}. MAke sure to enable it in embassy-net's Cargo features.",
55 caps.medium
56 ),
57 };
58 smolcaps.checksum.ipv4 = convert(caps.checksum.ipv4);
59 #[cfg(feature = "proto-ipv6")]
60 {
61 smolcaps.checksum.ipv6 = convert(caps.checksum.ipv6);
62 }
63 smolcaps.checksum.tcp = convert(caps.checksum.tcp);
64 smolcaps.checksum.udp = convert(caps.checksum.udp);
65 smolcaps.checksum.icmpv4 = convert(caps.checksum.icmpv4);
66
67 smolcaps
109 } 68 }
110} 69}
111 70
diff --git a/embassy-net/src/lib.rs b/embassy-net/src/lib.rs
index afe0d6da0..b58c9cf36 100644
--- a/embassy-net/src/lib.rs
+++ b/embassy-net/src/lib.rs
@@ -18,6 +18,7 @@ use core::cell::RefCell;
18use core::future::{poll_fn, Future}; 18use core::future::{poll_fn, Future};
19use core::task::{Context, Poll}; 19use core::task::{Context, Poll};
20 20
21use embassy_net_driver::{Driver, LinkState, Medium};
21use embassy_sync::waitqueue::WakerRegistration; 22use embassy_sync::waitqueue::WakerRegistration;
22use embassy_time::{Instant, Timer}; 23use embassy_time::{Instant, Timer};
23use futures::pin_mut; 24use futures::pin_mut;
@@ -27,8 +28,6 @@ use smoltcp::iface::SocketHandle;
27use smoltcp::iface::{Interface, InterfaceBuilder, SocketSet, SocketStorage}; 28use smoltcp::iface::{Interface, InterfaceBuilder, SocketSet, SocketStorage};
28#[cfg(feature = "medium-ethernet")] 29#[cfg(feature = "medium-ethernet")]
29use smoltcp::iface::{Neighbor, NeighborCache, Route, Routes}; 30use smoltcp::iface::{Neighbor, NeighborCache, Route, Routes};
30#[cfg(feature = "medium-ethernet")]
31use smoltcp::phy::Medium;
32#[cfg(feature = "dhcpv4")] 31#[cfg(feature = "dhcpv4")]
33use smoltcp::socket::dhcpv4; 32use smoltcp::socket::dhcpv4;
34// smoltcp reexports 33// smoltcp reexports
@@ -41,7 +40,7 @@ pub use smoltcp::wire::{Ipv6Address, Ipv6Cidr};
41#[cfg(feature = "udp")] 40#[cfg(feature = "udp")]
42pub use smoltcp::{socket::udp::PacketMetadata, wire::IpListenEndpoint}; 41pub use smoltcp::{socket::udp::PacketMetadata, wire::IpListenEndpoint};
43 42
44use crate::device::{Device, DeviceAdapter, LinkState}; 43use crate::device::DriverAdapter;
45 44
46const LOCAL_PORT_MIN: u16 = 1025; 45const LOCAL_PORT_MIN: u16 = 1025;
47const LOCAL_PORT_MAX: u16 = 65535; 46const LOCAL_PORT_MAX: u16 = 65535;
@@ -82,12 +81,12 @@ pub enum ConfigStrategy {
82 Dhcp, 81 Dhcp,
83} 82}
84 83
85pub struct Stack<D: Device> { 84pub struct Stack<D: Driver> {
86 pub(crate) socket: RefCell<SocketStack>, 85 pub(crate) socket: RefCell<SocketStack>,
87 inner: RefCell<Inner<D>>, 86 inner: RefCell<Inner<D>>,
88} 87}
89 88
90struct Inner<D: Device> { 89struct Inner<D: Driver> {
91 device: D, 90 device: D,
92 link_up: bool, 91 link_up: bool,
93 config: Option<Config>, 92 config: Option<Config>,
@@ -102,7 +101,7 @@ pub(crate) struct SocketStack {
102 next_local_port: u16, 101 next_local_port: u16,
103} 102}
104 103
105impl<D: Device + 'static> Stack<D> { 104impl<D: Driver + 'static> Stack<D> {
106 pub fn new<const ADDR: usize, const SOCK: usize, const NEIGH: usize>( 105 pub fn new<const ADDR: usize, const SOCK: usize, const NEIGH: usize>(
107 mut device: D, 106 mut device: D,
108 config: ConfigStrategy, 107 config: ConfigStrategy,
@@ -130,7 +129,7 @@ impl<D: Device + 'static> Stack<D> {
130 b = b.routes(Routes::new(&mut resources.routes[..])); 129 b = b.routes(Routes::new(&mut resources.routes[..]));
131 } 130 }
132 131
133 let iface = b.finalize(&mut DeviceAdapter { 132 let iface = b.finalize(&mut DriverAdapter {
134 inner: &mut device, 133 inner: &mut device,
135 cx: None, 134 cx: None,
136 }); 135 });
@@ -211,7 +210,7 @@ impl SocketStack {
211 } 210 }
212} 211}
213 212
214impl<D: Device + 'static> Inner<D> { 213impl<D: Driver + 'static> Inner<D> {
215 fn apply_config(&mut self, s: &mut SocketStack, config: Config) { 214 fn apply_config(&mut self, s: &mut SocketStack, config: Config) {
216 #[cfg(feature = "medium-ethernet")] 215 #[cfg(feature = "medium-ethernet")]
217 let medium = self.device.capabilities().medium; 216 let medium = self.device.capabilities().medium;
@@ -263,7 +262,7 @@ impl<D: Device + 'static> Inner<D> {
263 s.waker.register(cx.waker()); 262 s.waker.register(cx.waker());
264 263
265 let timestamp = instant_to_smoltcp(Instant::now()); 264 let timestamp = instant_to_smoltcp(Instant::now());
266 let mut smoldev = DeviceAdapter { 265 let mut smoldev = DriverAdapter {
267 cx: Some(cx), 266 cx: Some(cx),
268 inner: &mut self.device, 267 inner: &mut self.device,
269 }; 268 };
diff --git a/embassy-net/src/tcp.rs b/embassy-net/src/tcp.rs
index 0dc8da73a..0fbf0c91b 100644
--- a/embassy-net/src/tcp.rs
+++ b/embassy-net/src/tcp.rs
@@ -3,12 +3,12 @@ use core::future::poll_fn;
3use core::mem; 3use core::mem;
4use core::task::Poll; 4use core::task::Poll;
5 5
6use embassy_net_driver::Driver;
6use smoltcp::iface::{Interface, SocketHandle}; 7use smoltcp::iface::{Interface, SocketHandle};
7use smoltcp::socket::tcp; 8use smoltcp::socket::tcp;
8use smoltcp::time::Duration; 9use smoltcp::time::Duration;
9use smoltcp::wire::{IpEndpoint, IpListenEndpoint}; 10use smoltcp::wire::{IpEndpoint, IpListenEndpoint};
10 11
11use crate::device::Device;
12use crate::{SocketStack, Stack}; 12use crate::{SocketStack, Stack};
13 13
14#[derive(PartialEq, Eq, Clone, Copy, Debug)] 14#[derive(PartialEq, Eq, Clone, Copy, Debug)]
@@ -66,7 +66,7 @@ impl<'a> TcpWriter<'a> {
66} 66}
67 67
68impl<'a> TcpSocket<'a> { 68impl<'a> TcpSocket<'a> {
69 pub fn new<D: Device>(stack: &'a Stack<D>, rx_buffer: &'a mut [u8], tx_buffer: &'a mut [u8]) -> Self { 69 pub fn new<D: Driver>(stack: &'a Stack<D>, rx_buffer: &'a mut [u8], tx_buffer: &'a mut [u8]) -> Self {
70 let s = &mut *stack.socket.borrow_mut(); 70 let s = &mut *stack.socket.borrow_mut();
71 let rx_buffer: &'static mut [u8] = unsafe { mem::transmute(rx_buffer) }; 71 let rx_buffer: &'static mut [u8] = unsafe { mem::transmute(rx_buffer) };
72 let tx_buffer: &'static mut [u8] = unsafe { mem::transmute(tx_buffer) }; 72 let tx_buffer: &'static mut [u8] = unsafe { mem::transmute(tx_buffer) };
@@ -336,19 +336,19 @@ pub mod client {
336 use super::*; 336 use super::*;
337 337
338 /// TCP client capable of creating up to N multiple connections with tx and rx buffers according to TX_SZ and RX_SZ. 338 /// TCP client capable of creating up to N multiple connections with tx and rx buffers according to TX_SZ and RX_SZ.
339 pub struct TcpClient<'d, D: Device, const N: usize, const TX_SZ: usize = 1024, const RX_SZ: usize = 1024> { 339 pub struct TcpClient<'d, D: Driver, const N: usize, const TX_SZ: usize = 1024, const RX_SZ: usize = 1024> {
340 stack: &'d Stack<D>, 340 stack: &'d Stack<D>,
341 state: &'d TcpClientState<N, TX_SZ, RX_SZ>, 341 state: &'d TcpClientState<N, TX_SZ, RX_SZ>,
342 } 342 }
343 343
344 impl<'d, D: Device, const N: usize, const TX_SZ: usize, const RX_SZ: usize> TcpClient<'d, D, N, TX_SZ, RX_SZ> { 344 impl<'d, D: Driver, const N: usize, const TX_SZ: usize, const RX_SZ: usize> TcpClient<'d, D, N, TX_SZ, RX_SZ> {
345 /// Create a new TcpClient 345 /// Create a new TcpClient
346 pub fn new(stack: &'d Stack<D>, state: &'d TcpClientState<N, TX_SZ, RX_SZ>) -> Self { 346 pub fn new(stack: &'d Stack<D>, state: &'d TcpClientState<N, TX_SZ, RX_SZ>) -> Self {
347 Self { stack, state } 347 Self { stack, state }
348 } 348 }
349 } 349 }
350 350
351 impl<'d, D: Device, const N: usize, const TX_SZ: usize, const RX_SZ: usize> embedded_nal_async::TcpConnect 351 impl<'d, D: Driver, const N: usize, const TX_SZ: usize, const RX_SZ: usize> embedded_nal_async::TcpConnect
352 for TcpClient<'d, D, N, TX_SZ, RX_SZ> 352 for TcpClient<'d, D, N, TX_SZ, RX_SZ>
353 { 353 {
354 type Error = Error; 354 type Error = Error;
@@ -386,7 +386,7 @@ pub mod client {
386 } 386 }
387 387
388 impl<'d, const N: usize, const TX_SZ: usize, const RX_SZ: usize> TcpConnection<'d, N, TX_SZ, RX_SZ> { 388 impl<'d, const N: usize, const TX_SZ: usize, const RX_SZ: usize> TcpConnection<'d, N, TX_SZ, RX_SZ> {
389 fn new<D: Device>(stack: &'d Stack<D>, state: &'d TcpClientState<N, TX_SZ, RX_SZ>) -> Result<Self, Error> { 389 fn new<D: Driver>(stack: &'d Stack<D>, state: &'d TcpClientState<N, TX_SZ, RX_SZ>) -> Result<Self, Error> {
390 let mut bufs = state.pool.alloc().ok_or(Error::ConnectionReset)?; 390 let mut bufs = state.pool.alloc().ok_or(Error::ConnectionReset)?;
391 Ok(Self { 391 Ok(Self {
392 socket: unsafe { TcpSocket::new(stack, &mut bufs.as_mut().0, &mut bufs.as_mut().1) }, 392 socket: unsafe { TcpSocket::new(stack, &mut bufs.as_mut().0, &mut bufs.as_mut().1) },
diff --git a/embassy-net/src/udp.rs b/embassy-net/src/udp.rs
index 2f5334df3..0ee8c6e19 100644
--- a/embassy-net/src/udp.rs
+++ b/embassy-net/src/udp.rs
@@ -3,11 +3,12 @@ use core::future::poll_fn;
3use core::mem; 3use core::mem;
4use core::task::Poll; 4use core::task::Poll;
5 5
6use embassy_net_driver::Driver;
6use smoltcp::iface::{Interface, SocketHandle}; 7use smoltcp::iface::{Interface, SocketHandle};
7use smoltcp::socket::udp::{self, PacketMetadata}; 8use smoltcp::socket::udp::{self, PacketMetadata};
8use smoltcp::wire::{IpEndpoint, IpListenEndpoint}; 9use smoltcp::wire::{IpEndpoint, IpListenEndpoint};
9 10
10use crate::{Device, SocketStack, Stack}; 11use crate::{SocketStack, Stack};
11 12
12#[derive(PartialEq, Eq, Clone, Copy, Debug)] 13#[derive(PartialEq, Eq, Clone, Copy, Debug)]
13#[cfg_attr(feature = "defmt", derive(defmt::Format))] 14#[cfg_attr(feature = "defmt", derive(defmt::Format))]
@@ -31,7 +32,7 @@ pub struct UdpSocket<'a> {
31} 32}
32 33
33impl<'a> UdpSocket<'a> { 34impl<'a> UdpSocket<'a> {
34 pub fn new<D: Device>( 35 pub fn new<D: Driver>(
35 stack: &'a Stack<D>, 36 stack: &'a Stack<D>,
36 rx_meta: &'a mut [PacketMetadata], 37 rx_meta: &'a mut [PacketMetadata],
37 rx_buffer: &'a mut [u8], 38 rx_buffer: &'a mut [u8],
diff --git a/embassy-stm32/Cargo.toml b/embassy-stm32/Cargo.toml
index 0c491ee46..67996cca4 100644
--- a/embassy-stm32/Cargo.toml
+++ b/embassy-stm32/Cargo.toml
@@ -39,7 +39,7 @@ embassy-futures = { version = "0.1.0", path = "../embassy-futures" }
39embassy-cortex-m = { version = "0.1.0", path = "../embassy-cortex-m", features = ["prio-bits-4"]} 39embassy-cortex-m = { version = "0.1.0", path = "../embassy-cortex-m", features = ["prio-bits-4"]}
40embassy-hal-common = {version = "0.1.0", path = "../embassy-hal-common" } 40embassy-hal-common = {version = "0.1.0", path = "../embassy-hal-common" }
41embassy-embedded-hal = {version = "0.1.0", path = "../embassy-embedded-hal" } 41embassy-embedded-hal = {version = "0.1.0", path = "../embassy-embedded-hal" }
42embassy-net = { version = "0.1.0", path = "../embassy-net", optional = true } 42embassy-net-driver = { version = "0.1.0", path = "../embassy-net-driver" }
43embassy-usb-driver = {version = "0.1.0", path = "../embassy-usb-driver", optional = true } 43embassy-usb-driver = {version = "0.1.0", path = "../embassy-usb-driver", optional = true }
44 44
45embedded-hal-02 = { package = "embedded-hal", version = "0.2.6", features = ["unproven"] } 45embedded-hal-02 = { package = "embedded-hal", version = "0.2.6", features = ["unproven"] }
@@ -75,7 +75,7 @@ quote = "1.0.15"
75stm32-metapac = { version = "0.1.0", path = "../stm32-metapac", default-features = false, features = ["metadata"]} 75stm32-metapac = { version = "0.1.0", path = "../stm32-metapac", default-features = false, features = ["metadata"]}
76 76
77[features] 77[features]
78defmt = ["dep:defmt", "bxcan/unstable-defmt", "embassy-sync/defmt", "embassy-executor/defmt", "embassy-embedded-hal/defmt", "embassy-hal-common/defmt", "embedded-io?/defmt", "embassy-usb-driver?/defmt"] 78defmt = ["dep:defmt", "bxcan/unstable-defmt", "embassy-sync/defmt", "embassy-executor/defmt", "embassy-embedded-hal/defmt", "embassy-hal-common/defmt", "embedded-io?/defmt", "embassy-usb-driver?/defmt", "embassy-net-driver/defmt"]
79sdmmc-rs = ["embedded-sdmmc"] 79sdmmc-rs = ["embedded-sdmmc"]
80memory-x = ["stm32-metapac/memory-x"] 80memory-x = ["stm32-metapac/memory-x"]
81subghz = [] 81subghz = []
diff --git a/embassy-stm32/src/eth/mod.rs b/embassy-stm32/src/eth/mod.rs
index fd1b48530..9f62b61ee 100644
--- a/embassy-stm32/src/eth/mod.rs
+++ b/embassy-stm32/src/eth/mod.rs
@@ -1,14 +1,17 @@
1#![macro_use] 1#![macro_use]
2#![cfg_attr(not(feature = "embassy-net"), allow(unused))]
3 2
4#[cfg_attr(any(eth_v1a, eth_v1b, eth_v1c), path = "v1/mod.rs")] 3#[cfg_attr(any(eth_v1a, eth_v1b, eth_v1c), path = "v1/mod.rs")]
5#[cfg_attr(eth_v2, path = "v2/mod.rs")] 4#[cfg_attr(eth_v2, path = "v2/mod.rs")]
6mod _version; 5mod _version;
7pub mod generic_smi; 6pub mod generic_smi;
8 7
9pub use _version::*; 8use core::task::Context;
9
10use embassy_net_driver::{Capabilities, LinkState};
10use embassy_sync::waitqueue::AtomicWaker; 11use embassy_sync::waitqueue::AtomicWaker;
11 12
13pub use self::_version::*;
14
12#[allow(unused)] 15#[allow(unused)]
13const MTU: usize = 1514; 16const MTU: usize = 1514;
14const TX_BUFFER_SIZE: usize = 1514; 17const TX_BUFFER_SIZE: usize = 1514;
@@ -40,92 +43,84 @@ impl<const TX: usize, const RX: usize> PacketQueue<TX, RX> {
40 43
41static WAKER: AtomicWaker = AtomicWaker::new(); 44static WAKER: AtomicWaker = AtomicWaker::new();
42 45
43#[cfg(feature = "embassy-net")] 46impl<'d, T: Instance, P: PHY> embassy_net_driver::Driver for Ethernet<'d, T, P> {
44mod embassy_net_impl { 47 type RxToken<'a> = RxToken<'a, 'd> where Self: 'a;
45 use core::task::Context; 48 type TxToken<'a> = TxToken<'a, 'd> where Self: 'a;
46
47 use embassy_net::device::{Device, DeviceCapabilities, LinkState};
48
49 use super::*;
50
51 impl<'d, T: Instance, P: PHY> Device for Ethernet<'d, T, P> {
52 type RxToken<'a> = RxToken<'a, 'd> where Self: 'a;
53 type TxToken<'a> = TxToken<'a, 'd> where Self: 'a;
54 49
55 fn receive(&mut self, cx: &mut Context) -> Option<(Self::RxToken<'_>, Self::TxToken<'_>)> { 50 fn receive(&mut self, cx: &mut Context) -> Option<(Self::RxToken<'_>, Self::TxToken<'_>)> {
56 WAKER.register(cx.waker()); 51 WAKER.register(cx.waker());
57 if self.rx.available().is_some() && self.tx.available().is_some() { 52 if self.rx.available().is_some() && self.tx.available().is_some() {
58 Some((RxToken { rx: &mut self.rx }, TxToken { tx: &mut self.tx })) 53 Some((RxToken { rx: &mut self.rx }, TxToken { tx: &mut self.tx }))
59 } else { 54 } else {
60 None 55 None
61 }
62 }
63
64 fn transmit(&mut self, cx: &mut Context) -> Option<Self::TxToken<'_>> {
65 WAKER.register(cx.waker());
66 if self.tx.available().is_some() {
67 Some(TxToken { tx: &mut self.tx })
68 } else {
69 None
70 }
71 } 56 }
57 }
72 58
73 fn capabilities(&self) -> DeviceCapabilities { 59 fn transmit(&mut self, cx: &mut Context) -> Option<Self::TxToken<'_>> {
74 let mut caps = DeviceCapabilities::default(); 60 WAKER.register(cx.waker());
75 caps.max_transmission_unit = MTU; 61 if self.tx.available().is_some() {
76 caps.max_burst_size = Some(self.tx.len()); 62 Some(TxToken { tx: &mut self.tx })
77 caps 63 } else {
64 None
78 } 65 }
66 }
79 67
80 fn link_state(&mut self, cx: &mut Context) -> LinkState { 68 fn capabilities(&self) -> Capabilities {
81 // TODO: wake cx.waker on link state change 69 let mut caps = Capabilities::default();
82 cx.waker().wake_by_ref(); 70 caps.max_transmission_unit = MTU;
83 if P::poll_link(self) { 71 caps.max_burst_size = Some(self.tx.len());
84 LinkState::Up 72 caps
85 } else { 73 }
86 LinkState::Down
87 }
88 }
89 74
90 fn ethernet_address(&self) -> [u8; 6] { 75 fn link_state(&mut self, cx: &mut Context) -> LinkState {
91 self.mac_addr 76 // TODO: wake cx.waker on link state change
77 cx.waker().wake_by_ref();
78 if P::poll_link(self) {
79 LinkState::Up
80 } else {
81 LinkState::Down
92 } 82 }
93 } 83 }
94 84
95 pub struct RxToken<'a, 'd> { 85 fn ethernet_address(&self) -> [u8; 6] {
96 rx: &'a mut RDesRing<'d>, 86 self.mac_addr
97 } 87 }
88}
98 89
99 impl<'a, 'd> embassy_net::device::RxToken for RxToken<'a, 'd> { 90pub struct RxToken<'a, 'd> {
100 fn consume<R, F>(self, f: F) -> R 91 rx: &'a mut RDesRing<'d>,
101 where 92}
102 F: FnOnce(&mut [u8]) -> R,
103 {
104 // NOTE(unwrap): we checked the queue wasn't full when creating the token.
105 let pkt = unwrap!(self.rx.available());
106 let r = f(pkt);
107 self.rx.pop_packet();
108 r
109 }
110 }
111 93
112 pub struct TxToken<'a, 'd> { 94impl<'a, 'd> embassy_net_driver::RxToken for RxToken<'a, 'd> {
113 tx: &'a mut TDesRing<'d>, 95 fn consume<R, F>(self, f: F) -> R
96 where
97 F: FnOnce(&mut [u8]) -> R,
98 {
99 // NOTE(unwrap): we checked the queue wasn't full when creating the token.
100 let pkt = unwrap!(self.rx.available());
101 let r = f(pkt);
102 self.rx.pop_packet();
103 r
114 } 104 }
105}
115 106
116 impl<'a, 'd> embassy_net::device::TxToken for TxToken<'a, 'd> { 107pub struct TxToken<'a, 'd> {
117 fn consume<R, F>(self, len: usize, f: F) -> R 108 tx: &'a mut TDesRing<'d>,
118 where 109}
119 F: FnOnce(&mut [u8]) -> R, 110
120 { 111impl<'a, 'd> embassy_net_driver::TxToken for TxToken<'a, 'd> {
121 // NOTE(unwrap): we checked the queue wasn't full when creating the token. 112 fn consume<R, F>(self, len: usize, f: F) -> R
122 let pkt = unwrap!(self.tx.available()); 113 where
123 let r = f(&mut pkt[..len]); 114 F: FnOnce(&mut [u8]) -> R,
124 self.tx.transmit(len); 115 {
125 r 116 // NOTE(unwrap): we checked the queue wasn't full when creating the token.
126 } 117 let pkt = unwrap!(self.tx.available());
118 let r = f(&mut pkt[..len]);
119 self.tx.transmit(len);
120 r
127 } 121 }
128} 122}
123
129/// Station Management Interface (SMI) on an ethernet PHY 124/// Station Management Interface (SMI) on an ethernet PHY
130/// 125///
131/// # Safety 126/// # Safety
diff --git a/embassy-stm32/src/eth/v1/mod.rs b/embassy-stm32/src/eth/v1/mod.rs
index de36d3da1..9c0f4d66d 100644
--- a/embassy-stm32/src/eth/v1/mod.rs
+++ b/embassy-stm32/src/eth/v1/mod.rs
@@ -13,7 +13,7 @@ pub(crate) use self::rx_desc::{RDes, RDesRing};
13pub(crate) use self::tx_desc::{TDes, TDesRing}; 13pub(crate) use self::tx_desc::{TDes, TDesRing};
14use super::*; 14use super::*;
15use crate::gpio::sealed::{AFType, Pin as __GpioPin}; 15use crate::gpio::sealed::{AFType, Pin as __GpioPin};
16use crate::gpio::{AnyPin, Speed}; 16use crate::gpio::AnyPin;
17#[cfg(eth_v1a)] 17#[cfg(eth_v1a)]
18use crate::pac::AFIO; 18use crate::pac::AFIO;
19#[cfg(any(eth_v1b, eth_v1c))] 19#[cfg(any(eth_v1b, eth_v1c))]
@@ -66,7 +66,7 @@ macro_rules! config_pins {
66 critical_section::with(|_| { 66 critical_section::with(|_| {
67 $( 67 $(
68 $pin.set_as_af($pin.af_num(), AFType::OutputPushPull); 68 $pin.set_as_af($pin.af_num(), AFType::OutputPushPull);
69 $pin.set_speed(Speed::VeryHigh); 69 $pin.set_speed(crate::gpio::Speed::VeryHigh);
70 )* 70 )*
71 }) 71 })
72 }; 72 };
diff --git a/embassy-usb/Cargo.toml b/embassy-usb/Cargo.toml
index 1e72ce682..d0742ceb3 100644
--- a/embassy-usb/Cargo.toml
+++ b/embassy-usb/Cargo.toml
@@ -19,7 +19,7 @@ default = ["usbd-hid"]
19embassy-futures = { version = "0.1.0", path = "../embassy-futures" } 19embassy-futures = { version = "0.1.0", path = "../embassy-futures" }
20embassy-usb-driver = { version = "0.1.0", path = "../embassy-usb-driver" } 20embassy-usb-driver = { version = "0.1.0", path = "../embassy-usb-driver" }
21embassy-sync = { version = "0.1.0", path = "../embassy-sync" } 21embassy-sync = { version = "0.1.0", path = "../embassy-sync" }
22embassy-net = { version = "0.1.0", path = "../embassy-net", optional = true } 22embassy-net-driver = { version = "0.1.0", path = "../embassy-net-driver" }
23 23
24defmt = { version = "0.3", optional = true } 24defmt = { version = "0.3", optional = true }
25log = { version = "0.4.14", optional = true } 25log = { version = "0.4.14", optional = true }
diff --git a/embassy-usb/src/class/cdc_ncm/embassy_net.rs b/embassy-usb/src/class/cdc_ncm/embassy_net.rs
index 60bbfd8d4..093afeff9 100644
--- a/embassy-usb/src/class/cdc_ncm/embassy_net.rs
+++ b/embassy-usb/src/class/cdc_ncm/embassy_net.rs
@@ -3,7 +3,7 @@ use core::mem::MaybeUninit;
3use core::task::Context; 3use core::task::Context;
4 4
5use embassy_futures::select::{select, Either}; 5use embassy_futures::select::{select, Either};
6use embassy_net::device::{Device as DeviceTrait, DeviceCapabilities, LinkState, Medium}; 6use embassy_net_driver::{Capabilities, LinkState, Medium};
7use embassy_sync::blocking_mutex::raw::NoopRawMutex; 7use embassy_sync::blocking_mutex::raw::NoopRawMutex;
8use embassy_sync::blocking_mutex::Mutex; 8use embassy_sync::blocking_mutex::Mutex;
9use embassy_sync::waitqueue::WakerRegistration; 9use embassy_sync::waitqueue::WakerRegistration;
@@ -108,7 +108,7 @@ impl<'d, D: Driver<'d>> CdcNcmClass<'d, D> {
108 ) -> (Runner<'d, D, MTU>, Device<'d, MTU>) { 108 ) -> (Runner<'d, D, MTU>, Device<'d, MTU>) {
109 let (tx_usb, rx_usb) = self.split(); 109 let (tx_usb, rx_usb) = self.split();
110 110
111 let mut caps = DeviceCapabilities::default(); 111 let mut caps = Capabilities::default();
112 caps.max_transmission_unit = 1514; // 1500 IP + 14 ethernet header 112 caps.max_transmission_unit = 1514; // 1500 IP + 14 ethernet header
113 caps.medium = Medium::Ethernet; 113 caps.medium = Medium::Ethernet;
114 114
@@ -158,11 +158,11 @@ pub struct Device<'d, const MTU: usize> {
158 rx: zerocopy_channel::Receiver<'d, NoopRawMutex, PacketBuf<MTU>>, 158 rx: zerocopy_channel::Receiver<'d, NoopRawMutex, PacketBuf<MTU>>,
159 tx: zerocopy_channel::Sender<'d, NoopRawMutex, PacketBuf<MTU>>, 159 tx: zerocopy_channel::Sender<'d, NoopRawMutex, PacketBuf<MTU>>,
160 link_state: &'d Mutex<NoopRawMutex, RefCell<LinkStateState>>, 160 link_state: &'d Mutex<NoopRawMutex, RefCell<LinkStateState>>,
161 caps: DeviceCapabilities, 161 caps: Capabilities,
162 ethernet_address: [u8; 6], 162 ethernet_address: [u8; 6],
163} 163}
164 164
165impl<'d, const MTU: usize> DeviceTrait for Device<'d, MTU> { 165impl<'d, const MTU: usize> embassy_net_driver::Driver for Device<'d, MTU> {
166 type RxToken<'a> = RxToken<'a, MTU> where Self: 'a ; 166 type RxToken<'a> = RxToken<'a, MTU> where Self: 'a ;
167 type TxToken<'a> = TxToken<'a, MTU> where Self: 'a ; 167 type TxToken<'a> = TxToken<'a, MTU> where Self: 'a ;
168 168
@@ -184,7 +184,7 @@ impl<'d, const MTU: usize> DeviceTrait for Device<'d, MTU> {
184 } 184 }
185 185
186 /// Get a description of device capabilities. 186 /// Get a description of device capabilities.
187 fn capabilities(&self) -> DeviceCapabilities { 187 fn capabilities(&self) -> Capabilities {
188 self.caps.clone() 188 self.caps.clone()
189 } 189 }
190 190
@@ -205,7 +205,7 @@ pub struct RxToken<'a, const MTU: usize> {
205 rx: zerocopy_channel::Receiver<'a, NoopRawMutex, PacketBuf<MTU>>, 205 rx: zerocopy_channel::Receiver<'a, NoopRawMutex, PacketBuf<MTU>>,
206} 206}
207 207
208impl<'a, const MTU: usize> embassy_net::device::RxToken for RxToken<'a, MTU> { 208impl<'a, const MTU: usize> embassy_net_driver::RxToken for RxToken<'a, MTU> {
209 fn consume<R, F>(mut self, f: F) -> R 209 fn consume<R, F>(mut self, f: F) -> R
210 where 210 where
211 F: FnOnce(&mut [u8]) -> R, 211 F: FnOnce(&mut [u8]) -> R,
@@ -222,7 +222,7 @@ pub struct TxToken<'a, const MTU: usize> {
222 tx: zerocopy_channel::Sender<'a, NoopRawMutex, PacketBuf<MTU>>, 222 tx: zerocopy_channel::Sender<'a, NoopRawMutex, PacketBuf<MTU>>,
223} 223}
224 224
225impl<'a, const MTU: usize> embassy_net::device::TxToken for TxToken<'a, MTU> { 225impl<'a, const MTU: usize> embassy_net_driver::TxToken for TxToken<'a, MTU> {
226 fn consume<R, F>(mut self, len: usize, f: F) -> R 226 fn consume<R, F>(mut self, len: usize, f: F) -> R
227 where 227 where
228 F: FnOnce(&mut [u8]) -> R, 228 F: FnOnce(&mut [u8]) -> R,
diff --git a/embassy-usb/src/class/cdc_ncm/mod.rs b/embassy-usb/src/class/cdc_ncm/mod.rs
index 2ee47f68c..4954a65bc 100644
--- a/embassy-usb/src/class/cdc_ncm/mod.rs
+++ b/embassy-usb/src/class/cdc_ncm/mod.rs
@@ -21,7 +21,6 @@ use crate::driver::{Driver, Endpoint, EndpointError, EndpointIn, EndpointOut};
21use crate::types::*; 21use crate::types::*;
22use crate::Builder; 22use crate::Builder;
23 23
24#[cfg(feature = "embassy-net")]
25pub mod embassy_net; 24pub mod embassy_net;
26 25
27/// This should be used as `device_class` when building the `UsbDevice`. 26/// This should be used as `device_class` when building the `UsbDevice`.
diff --git a/examples/nrf/Cargo.toml b/examples/nrf/Cargo.toml
index 54a477b49..994823a9e 100644
--- a/examples/nrf/Cargo.toml
+++ b/examples/nrf/Cargo.toml
@@ -16,7 +16,7 @@ embassy-executor = { version = "0.1.0", path = "../../embassy-executor", feature
16embassy-time = { version = "0.1.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime"] } 16embassy-time = { version = "0.1.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime"] }
17embassy-nrf = { version = "0.1.0", path = "../../embassy-nrf", features = ["defmt", "nrf52840", "time-driver-rtc1", "gpiote", "unstable-pac"] } 17embassy-nrf = { version = "0.1.0", path = "../../embassy-nrf", features = ["defmt", "nrf52840", "time-driver-rtc1", "gpiote", "unstable-pac"] }
18embassy-net = { version = "0.1.0", path = "../../embassy-net", features = ["defmt", "tcp", "dhcpv4", "medium-ethernet"], optional = true } 18embassy-net = { version = "0.1.0", path = "../../embassy-net", features = ["defmt", "tcp", "dhcpv4", "medium-ethernet"], optional = true }
19embassy-usb = { version = "0.1.0", path = "../../embassy-usb", features = ["defmt", "embassy-net"], optional = true } 19embassy-usb = { version = "0.1.0", path = "../../embassy-usb", features = ["defmt"], optional = true }
20embedded-io = "0.4.0" 20embedded-io = "0.4.0"
21embassy-lora = { version = "0.1.0", path = "../../embassy-lora", features = ["sx126x", "time", "defmt"], optional = true } 21embassy-lora = { version = "0.1.0", path = "../../embassy-lora", features = ["sx126x", "time", "defmt"], optional = true }
22 22
diff --git a/examples/rp/Cargo.toml b/examples/rp/Cargo.toml
index 57cddd432..afd1042a1 100644
--- a/examples/rp/Cargo.toml
+++ b/examples/rp/Cargo.toml
@@ -10,7 +10,7 @@ embassy-sync = { version = "0.1.0", path = "../../embassy-sync", features = ["de
10embassy-executor = { version = "0.1.0", path = "../../embassy-executor", features = ["defmt", "integrated-timers"] } 10embassy-executor = { version = "0.1.0", path = "../../embassy-executor", features = ["defmt", "integrated-timers"] }
11embassy-time = { version = "0.1.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime"] } 11embassy-time = { version = "0.1.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime"] }
12embassy-rp = { version = "0.1.0", path = "../../embassy-rp", features = ["defmt", "unstable-traits", "nightly", "unstable-pac", "time-driver", "pio", "critical-section-impl"] } 12embassy-rp = { version = "0.1.0", path = "../../embassy-rp", features = ["defmt", "unstable-traits", "nightly", "unstable-pac", "time-driver", "pio", "critical-section-impl"] }
13embassy-usb = { version = "0.1.0", path = "../../embassy-usb", features = ["defmt", "embassy-net"] } 13embassy-usb = { version = "0.1.0", path = "../../embassy-usb", features = ["defmt"] }
14embassy-net = { version = "0.1.0", path = "../../embassy-net", features = ["defmt", "nightly", "tcp", "dhcpv4", "medium-ethernet"] } 14embassy-net = { version = "0.1.0", path = "../../embassy-net", features = ["defmt", "nightly", "tcp", "dhcpv4", "medium-ethernet"] }
15embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } 15embassy-futures = { version = "0.1.0", path = "../../embassy-futures" }
16embassy-usb-logger = { version = "0.1.0", path = "../../embassy-usb-logger" } 16embassy-usb-logger = { version = "0.1.0", path = "../../embassy-usb-logger" }
diff --git a/examples/std/Cargo.toml b/examples/std/Cargo.toml
index 649e39747..45b2a4a4f 100644
--- a/examples/std/Cargo.toml
+++ b/examples/std/Cargo.toml
@@ -9,6 +9,7 @@ embassy-sync = { version = "0.1.0", path = "../../embassy-sync", features = ["lo
9embassy-executor = { version = "0.1.0", path = "../../embassy-executor", features = ["log", "std", "nightly", "integrated-timers"] } 9embassy-executor = { version = "0.1.0", path = "../../embassy-executor", features = ["log", "std", "nightly", "integrated-timers"] }
10embassy-time = { version = "0.1.0", path = "../../embassy-time", features = ["log", "std", "nightly"] } 10embassy-time = { version = "0.1.0", path = "../../embassy-time", features = ["log", "std", "nightly"] }
11embassy-net = { version = "0.1.0", path = "../../embassy-net", features=[ "std", "nightly", "log", "medium-ethernet", "tcp", "udp", "dhcpv4"] } 11embassy-net = { version = "0.1.0", path = "../../embassy-net", features=[ "std", "nightly", "log", "medium-ethernet", "tcp", "udp", "dhcpv4"] }
12embassy-net-driver = { version = "0.1.0", path = "../../embassy-net-driver" }
12embedded-io = { version = "0.4.0", features = ["async", "std", "futures"] } 13embedded-io = { version = "0.4.0", features = ["async", "std", "futures"] }
13critical-section = { version = "1.1", features = ["std"] } 14critical-section = { version = "1.1", features = ["std"] }
14 15
diff --git a/examples/std/src/tuntap.rs b/examples/std/src/tuntap.rs
index bb3e194cc..d918a2e62 100644
--- a/examples/std/src/tuntap.rs
+++ b/examples/std/src/tuntap.rs
@@ -4,7 +4,7 @@ use std::os::unix::io::{AsRawFd, RawFd};
4use std::task::Context; 4use std::task::Context;
5 5
6use async_io::Async; 6use async_io::Async;
7use embassy_net::device::{self, Device, DeviceCapabilities, LinkState}; 7use embassy_net_driver::{self, Capabilities, Driver, LinkState};
8use log::*; 8use log::*;
9 9
10pub const SIOCGIFMTU: libc::c_ulong = 0x8921; 10pub const SIOCGIFMTU: libc::c_ulong = 0x8921;
@@ -137,7 +137,7 @@ impl TunTapDevice {
137 } 137 }
138} 138}
139 139
140impl Device for TunTapDevice { 140impl Driver for TunTapDevice {
141 type RxToken<'a> = RxToken where Self: 'a; 141 type RxToken<'a> = RxToken where Self: 'a;
142 type TxToken<'a> = TxToken<'a> where Self: 'a; 142 type TxToken<'a> = TxToken<'a> where Self: 'a;
143 143
@@ -170,8 +170,8 @@ impl Device for TunTapDevice {
170 }) 170 })
171 } 171 }
172 172
173 fn capabilities(&self) -> DeviceCapabilities { 173 fn capabilities(&self) -> Capabilities {
174 let mut caps = DeviceCapabilities::default(); 174 let mut caps = Capabilities::default();
175 caps.max_transmission_unit = self.device.get_ref().mtu; 175 caps.max_transmission_unit = self.device.get_ref().mtu;
176 caps 176 caps
177 } 177 }
@@ -190,7 +190,7 @@ pub struct RxToken {
190 buffer: Vec<u8>, 190 buffer: Vec<u8>,
191} 191}
192 192
193impl device::RxToken for RxToken { 193impl embassy_net_driver::RxToken for RxToken {
194 fn consume<R, F>(mut self, f: F) -> R 194 fn consume<R, F>(mut self, f: F) -> R
195 where 195 where
196 F: FnOnce(&mut [u8]) -> R, 196 F: FnOnce(&mut [u8]) -> R,
@@ -204,7 +204,7 @@ pub struct TxToken<'a> {
204 device: &'a mut Async<TunTap>, 204 device: &'a mut Async<TunTap>,
205} 205}
206 206
207impl<'a> device::TxToken for TxToken<'a> { 207impl<'a> embassy_net_driver::TxToken for TxToken<'a> {
208 fn consume<R, F>(self, len: usize, f: F) -> R 208 fn consume<R, F>(self, len: usize, f: F) -> R
209 where 209 where
210 F: FnOnce(&mut [u8]) -> R, 210 F: FnOnce(&mut [u8]) -> R,
diff --git a/examples/stm32f7/Cargo.toml b/examples/stm32f7/Cargo.toml
index a8b2baf29..b80dbbf9c 100644
--- a/examples/stm32f7/Cargo.toml
+++ b/examples/stm32f7/Cargo.toml
@@ -8,7 +8,7 @@ license = "MIT OR Apache-2.0"
8embassy-sync = { version = "0.1.0", path = "../../embassy-sync", features = ["defmt"] } 8embassy-sync = { version = "0.1.0", path = "../../embassy-sync", features = ["defmt"] }
9embassy-executor = { version = "0.1.0", path = "../../embassy-executor", features = ["defmt", "integrated-timers"] } 9embassy-executor = { version = "0.1.0", path = "../../embassy-executor", features = ["defmt", "integrated-timers"] }
10embassy-time = { version = "0.1.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } 10embassy-time = { version = "0.1.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] }
11embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "defmt", "embassy-net", "stm32f767zi", "unstable-pac", "time-driver-any", "exti"] } 11embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "defmt", "stm32f767zi", "unstable-pac", "time-driver-any", "exti"] }
12embassy-net = { path = "../../embassy-net", features = ["defmt", "nightly", "tcp", "dhcpv4", "medium-ethernet"] } 12embassy-net = { path = "../../embassy-net", features = ["defmt", "nightly", "tcp", "dhcpv4", "medium-ethernet"] }
13embedded-io = { version = "0.4.0", features = ["async"] } 13embedded-io = { version = "0.4.0", features = ["async"] }
14 14
diff --git a/examples/stm32h7/Cargo.toml b/examples/stm32h7/Cargo.toml
index 63e6caa77..d30c42b1f 100644
--- a/examples/stm32h7/Cargo.toml
+++ b/examples/stm32h7/Cargo.toml
@@ -8,7 +8,7 @@ license = "MIT OR Apache-2.0"
8embassy-sync = { version = "0.1.0", path = "../../embassy-sync", features = ["defmt"] } 8embassy-sync = { version = "0.1.0", path = "../../embassy-sync", features = ["defmt"] }
9embassy-executor = { version = "0.1.0", path = "../../embassy-executor", features = ["defmt", "integrated-timers"] } 9embassy-executor = { version = "0.1.0", path = "../../embassy-executor", features = ["defmt", "integrated-timers"] }
10embassy-time = { version = "0.1.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "unstable-traits", "tick-hz-32_768"] } 10embassy-time = { version = "0.1.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "unstable-traits", "tick-hz-32_768"] }
11embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "defmt", "stm32h743bi", "embassy-net", "time-driver-any", "exti", "unstable-pac", "unstable-traits"] } 11embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "defmt", "stm32h743bi", "time-driver-any", "exti", "unstable-pac", "unstable-traits"] }
12embassy-net = { path = "../../embassy-net", features = ["defmt", "nightly", "tcp", "dhcpv4", "medium-ethernet", "unstable-traits"] } 12embassy-net = { path = "../../embassy-net", features = ["defmt", "nightly", "tcp", "dhcpv4", "medium-ethernet", "unstable-traits"] }
13embedded-io = { version = "0.4.0", features = ["async"] } 13embedded-io = { version = "0.4.0", features = ["async"] }
14 14
diff --git a/examples/stm32l5/Cargo.toml b/examples/stm32l5/Cargo.toml
index ce999f67e..c0accb0d6 100644
--- a/examples/stm32l5/Cargo.toml
+++ b/examples/stm32l5/Cargo.toml
@@ -11,7 +11,7 @@ embassy-sync = { version = "0.1.0", path = "../../embassy-sync", features = ["de
11embassy-executor = { version = "0.1.0", path = "../../embassy-executor", features = ["defmt", "integrated-timers"] } 11embassy-executor = { version = "0.1.0", path = "../../embassy-executor", features = ["defmt", "integrated-timers"] }
12embassy-time = { version = "0.1.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } 12embassy-time = { version = "0.1.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] }
13embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "defmt", "unstable-pac", "stm32l552ze", "time-driver-any", "exti", "unstable-traits", "memory-x"] } 13embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "defmt", "unstable-pac", "stm32l552ze", "time-driver-any", "exti", "unstable-traits", "memory-x"] }
14embassy-usb = { version = "0.1.0", path = "../../embassy-usb", features = ["defmt", "embassy-net"] } 14embassy-usb = { version = "0.1.0", path = "../../embassy-usb", features = ["defmt"] }
15embassy-net = { version = "0.1.0", path = "../../embassy-net", features = ["defmt", "nightly", "tcp", "dhcpv4", "medium-ethernet"] } 15embassy-net = { version = "0.1.0", path = "../../embassy-net", features = ["defmt", "nightly", "tcp", "dhcpv4", "medium-ethernet"] }
16embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } 16embassy-futures = { version = "0.1.0", path = "../../embassy-futures" }
17usbd-hid = "0.6.0" 17usbd-hid = "0.6.0"