aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--embassy-net-esp-hosted/src/control.rs16
-rw-r--r--embassy-net-esp-hosted/src/ioctl.rs91
-rw-r--r--embassy-net-esp-hosted/src/lib.rs16
3 files changed, 52 insertions, 71 deletions
diff --git a/embassy-net-esp-hosted/src/control.rs b/embassy-net-esp-hosted/src/control.rs
index ec51933b3..c98d0ebf4 100644
--- a/embassy-net-esp-hosted/src/control.rs
+++ b/embassy-net-esp-hosted/src/control.rs
@@ -3,7 +3,7 @@ use defmt::Debug2Format;
3use embassy_net_driver_channel as ch; 3use embassy_net_driver_channel as ch;
4use heapless::String; 4use heapless::String;
5 5
6use crate::ioctl::IoctlState; 6use crate::ioctl::Shared;
7use crate::proto::{self, CtrlMsg}; 7use crate::proto::{self, CtrlMsg};
8 8
9#[derive(Debug)] 9#[derive(Debug)]
@@ -13,7 +13,7 @@ pub struct Error {
13 13
14pub struct Control<'a> { 14pub struct Control<'a> {
15 state_ch: ch::StateRunner<'a>, 15 state_ch: ch::StateRunner<'a>,
16 ioctl_state: &'a IoctlState, 16 shared: &'a Shared,
17} 17}
18 18
19enum WifiMode { 19enum WifiMode {
@@ -24,8 +24,8 @@ enum WifiMode {
24} 24}
25 25
26impl<'a> Control<'a> { 26impl<'a> Control<'a> {
27 pub(crate) fn new(state_ch: ch::StateRunner<'a>, ioctl_state: &'a IoctlState) -> Self { 27 pub(crate) fn new(state_ch: ch::StateRunner<'a>, shared: &'a Shared) -> Self {
28 Self { state_ch, ioctl_state } 28 Self { state_ch, shared }
29 } 29 }
30 30
31 pub async fn init(&mut self) { 31 pub async fn init(&mut self) {
@@ -118,7 +118,7 @@ impl<'a> Control<'a> {
118 118
119 let req_len = noproto::write(&req, &mut buf).unwrap(); 119 let req_len = noproto::write(&req, &mut buf).unwrap();
120 120
121 struct CancelOnDrop<'a>(&'a IoctlState); 121 struct CancelOnDrop<'a>(&'a Shared);
122 122
123 impl CancelOnDrop<'_> { 123 impl CancelOnDrop<'_> {
124 fn defuse(self) { 124 fn defuse(self) {
@@ -128,13 +128,13 @@ impl<'a> Control<'a> {
128 128
129 impl Drop for CancelOnDrop<'_> { 129 impl Drop for CancelOnDrop<'_> {
130 fn drop(&mut self) { 130 fn drop(&mut self) {
131 self.0.cancel_ioctl(); 131 self.0.ioctl_cancel();
132 } 132 }
133 } 133 }
134 134
135 let ioctl = CancelOnDrop(self.ioctl_state); 135 let ioctl = CancelOnDrop(self.shared);
136 136
137 let resp_len = ioctl.0.do_ioctl(&mut buf, req_len).await; 137 let resp_len = ioctl.0.ioctl(&mut buf, req_len).await;
138 138
139 ioctl.defuse(); 139 ioctl.defuse();
140 140
diff --git a/embassy-net-esp-hosted/src/ioctl.rs b/embassy-net-esp-hosted/src/ioctl.rs
index 689dd2a88..7cbe80b2a 100644
--- a/embassy-net-esp-hosted/src/ioctl.rs
+++ b/embassy-net-esp-hosted/src/ioctl.rs
@@ -13,105 +13,86 @@ pub struct PendingIoctl {
13} 13}
14 14
15#[derive(Clone, Copy)] 15#[derive(Clone, Copy)]
16enum IoctlStateInner { 16enum IoctlState {
17 Pending(PendingIoctl), 17 Pending(PendingIoctl),
18 Sent { buf: *mut [u8] }, 18 Sent { buf: *mut [u8] },
19 Done { resp_len: usize }, 19 Done { resp_len: usize },
20} 20}
21 21
22struct Wakers { 22pub struct Shared(RefCell<SharedInner>);
23 control: WakerRegistration,
24 runner: WakerRegistration,
25}
26
27impl Default for Wakers {
28 fn default() -> Self {
29 Self {
30 control: WakerRegistration::new(),
31 runner: WakerRegistration::new(),
32 }
33 }
34}
35 23
36pub struct IoctlState { 24struct SharedInner {
37 state: Cell<IoctlStateInner>, 25 ioctl: IoctlState,
38 wakers: RefCell<Wakers>, 26 control_waker: WakerRegistration,
27 runner_waker: WakerRegistration,
39} 28}
40 29
41impl IoctlState { 30impl Shared {
42 pub fn new() -> Self { 31 pub fn new() -> Self {
43 Self { 32 Self(RefCell::new(SharedInner {
44 state: Cell::new(IoctlStateInner::Done { resp_len: 0 }), 33 ioctl: IoctlState::Done { resp_len: 0 },
45 wakers: Default::default(), 34 control_waker: WakerRegistration::new(),
46 } 35 runner_waker: WakerRegistration::new(),
47 } 36 }))
48
49 fn wake_control(&self) {
50 self.wakers.borrow_mut().control.wake();
51 } 37 }
52 38
53 fn register_control(&self, waker: &Waker) { 39 pub async fn ioctl_wait_complete(&self) -> usize {
54 self.wakers.borrow_mut().control.register(waker);
55 }
56
57 fn wake_runner(&self) {
58 self.wakers.borrow_mut().runner.wake();
59 }
60
61 fn register_runner(&self, waker: &Waker) {
62 self.wakers.borrow_mut().runner.register(waker);
63 }
64
65 pub async fn wait_complete(&self) -> usize {
66 poll_fn(|cx| { 40 poll_fn(|cx| {
67 if let IoctlStateInner::Done { resp_len } = self.state.get() { 41 let mut this = self.0.borrow_mut();
42 if let IoctlState::Done { resp_len } = this.ioctl {
68 Poll::Ready(resp_len) 43 Poll::Ready(resp_len)
69 } else { 44 } else {
70 self.register_control(cx.waker()); 45 this.control_waker.register(cx.waker());
71 Poll::Pending 46 Poll::Pending
72 } 47 }
73 }) 48 })
74 .await 49 .await
75 } 50 }
76 51
77 pub async fn wait_pending(&self) -> PendingIoctl { 52 pub async fn ioctl_wait_pending(&self) -> PendingIoctl {
78 let pending = poll_fn(|cx| { 53 let pending = poll_fn(|cx| {
79 if let IoctlStateInner::Pending(pending) = self.state.get() { 54 let mut this = self.0.borrow_mut();
55 if let IoctlState::Pending(pending) = this.ioctl {
80 Poll::Ready(pending) 56 Poll::Ready(pending)
81 } else { 57 } else {
82 self.register_runner(cx.waker()); 58 this.runner_waker.register(cx.waker());
83 Poll::Pending 59 Poll::Pending
84 } 60 }
85 }) 61 })
86 .await; 62 .await;
87 63
88 self.state.set(IoctlStateInner::Sent { buf: pending.buf }); 64 self.0.borrow_mut().ioctl = IoctlState::Sent { buf: pending.buf };
89 pending 65 pending
90 } 66 }
91 67
92 pub fn cancel_ioctl(&self) { 68 pub fn ioctl_cancel(&self) {
93 self.state.set(IoctlStateInner::Done { resp_len: 0 }); 69 self.0.borrow_mut().ioctl = IoctlState::Done { resp_len: 0 };
94 } 70 }
95 71
96 pub async fn do_ioctl(&self, buf: &mut [u8], req_len: usize) -> usize { 72 pub async fn ioctl(&self, buf: &mut [u8], req_len: usize) -> usize {
97 trace!("ioctl req bytes: {:02x}", Bytes(&buf[..req_len])); 73 trace!("ioctl req bytes: {:02x}", Bytes(&buf[..req_len]));
98 74
99 self.state.set(IoctlStateInner::Pending(PendingIoctl { buf, req_len })); 75 {
100 self.wake_runner(); 76 let mut this = self.0.borrow_mut();
101 self.wait_complete().await 77 this.ioctl = IoctlState::Pending(PendingIoctl { buf, req_len });
78 this.runner_waker.wake();
79 }
80
81 self.ioctl_wait_complete().await
102 } 82 }
103 83
104 pub fn ioctl_done(&self, response: &[u8]) { 84 pub fn ioctl_done(&self, response: &[u8]) {
105 if let IoctlStateInner::Sent { buf } = self.state.get() { 85 let mut this = self.0.borrow_mut();
86 if let IoctlState::Sent { buf } = this.ioctl {
106 trace!("ioctl resp bytes: {:02x}", Bytes(response)); 87 trace!("ioctl resp bytes: {:02x}", Bytes(response));
107 88
108 // TODO fix this 89 // TODO fix this
109 (unsafe { &mut *buf }[..response.len()]).copy_from_slice(response); 90 (unsafe { &mut *buf }[..response.len()]).copy_from_slice(response);
110 91
111 self.state.set(IoctlStateInner::Done { 92 this.ioctl = IoctlState::Done {
112 resp_len: response.len(), 93 resp_len: response.len(),
113 }); 94 };
114 self.wake_control(); 95 this.control_waker.wake();
115 } else { 96 } else {
116 warn!("IOCTL Response but no pending Ioctl"); 97 warn!("IOCTL Response but no pending Ioctl");
117 } 98 }
diff --git a/embassy-net-esp-hosted/src/lib.rs b/embassy-net-esp-hosted/src/lib.rs
index 084009966..700a5221c 100644
--- a/embassy-net-esp-hosted/src/lib.rs
+++ b/embassy-net-esp-hosted/src/lib.rs
@@ -7,7 +7,7 @@ use embassy_time::{Duration, Instant, Timer};
7use embedded_hal::digital::{InputPin, OutputPin}; 7use embedded_hal::digital::{InputPin, OutputPin};
8use embedded_hal_async::digital::Wait; 8use embedded_hal_async::digital::Wait;
9use embedded_hal_async::spi::SpiDevice; 9use embedded_hal_async::spi::SpiDevice;
10use ioctl::IoctlState; 10use ioctl::Shared;
11use proto::CtrlMsg; 11use proto::CtrlMsg;
12 12
13use crate::ioctl::PendingIoctl; 13use crate::ioctl::PendingIoctl;
@@ -95,14 +95,14 @@ enum InterfaceType {
95const MAX_SPI_BUFFER_SIZE: usize = 1600; 95const MAX_SPI_BUFFER_SIZE: usize = 1600;
96 96
97pub struct State { 97pub struct State {
98 ioctl_state: IoctlState, 98 shared: Shared,
99 ch: ch::State<MTU, 4, 4>, 99 ch: ch::State<MTU, 4, 4>,
100} 100}
101 101
102impl State { 102impl State {
103 pub fn new() -> Self { 103 pub fn new() -> Self {
104 Self { 104 Self {
105 ioctl_state: IoctlState::new(), 105 shared: Shared::new(),
106 ch: ch::State::new(), 106 ch: ch::State::new(),
107 } 107 }
108 } 108 }
@@ -127,7 +127,7 @@ where
127 127
128 let mut runner = Runner { 128 let mut runner = Runner {
129 ch: ch_runner, 129 ch: ch_runner,
130 ioctl_state: &state.ioctl_state, 130 shared: &state.shared,
131 next_seq: 1, 131 next_seq: 1,
132 handshake, 132 handshake,
133 ready, 133 ready,
@@ -136,12 +136,12 @@ where
136 }; 136 };
137 runner.init().await; 137 runner.init().await;
138 138
139 (device, Control::new(state_ch, &state.ioctl_state), runner) 139 (device, Control::new(state_ch, &state.shared), runner)
140} 140}
141 141
142pub struct Runner<'a, SPI, IN, OUT> { 142pub struct Runner<'a, SPI, IN, OUT> {
143 ch: ch::Runner<'a, MTU>, 143 ch: ch::Runner<'a, MTU>,
144 ioctl_state: &'a IoctlState, 144 shared: &'a Shared,
145 145
146 next_seq: u16, 146 next_seq: u16,
147 147
@@ -172,7 +172,7 @@ where
172 loop { 172 loop {
173 self.handshake.wait_for_high().await.unwrap(); 173 self.handshake.wait_for_high().await.unwrap();
174 174
175 let ioctl = self.ioctl_state.wait_pending(); 175 let ioctl = self.shared.ioctl_wait_pending();
176 let tx = self.ch.tx_buf(); 176 let tx = self.ch.tx_buf();
177 let ev = async { self.ready.wait_for_high().await.unwrap() }; 177 let ev = async { self.ready.wait_for_high().await.unwrap() };
178 178
@@ -294,7 +294,7 @@ where
294 if isEvent { 294 if isEvent {
295 self.handle_event(data); 295 self.handle_event(data);
296 } else { 296 } else {
297 self.ioctl_state.ioctl_done(data); 297 self.shared.ioctl_done(data);
298 } 298 }
299 } 299 }
300 _ => warn!("unknown iftype {}", if_type_and_num), 300 _ => warn!("unknown iftype {}", if_type_and_num),