aboutsummaryrefslogtreecommitdiff
path: root/src/runner.rs
diff options
context:
space:
mode:
authorDario Nieuwenhuis <[email protected]>2023-03-27 10:43:53 +0000
committerGitHub <[email protected]>2023-03-27 10:43:53 +0000
commitcde6f0f8628b50008df8cdeb52e80c186f63863a (patch)
treef4d0304ac729d9e4234f26b49b43f7e093c7f300 /src/runner.rs
parentfd3de78b43e1c3607c68a2e12987a28bf60888e2 (diff)
parentc7646eb699e194a7c692b95b49adc76d6d3295ea (diff)
Merge pull request #50 from kbleeke/async-ioctls
Rework Ioctls to an async state machine
Diffstat (limited to 'src/runner.rs')
-rw-r--r--src/runner.rs108
1 files changed, 64 insertions, 44 deletions
diff --git a/src/runner.rs b/src/runner.rs
index 9945af3fc..4abccf48b 100644
--- a/src/runner.rs
+++ b/src/runner.rs
@@ -1,6 +1,6 @@
1use core::cell::Cell;
2use core::slice; 1use core::slice;
3 2
3use embassy_futures::select::{select3, Either3};
4use embassy_futures::yield_now; 4use embassy_futures::yield_now;
5use embassy_net_driver_channel as ch; 5use embassy_net_driver_channel as ch;
6use embassy_sync::pubsub::PubSubBehavior; 6use embassy_sync::pubsub::PubSubBehavior;
@@ -12,9 +12,10 @@ pub use crate::bus::SpiBusCyw43;
12use crate::consts::*; 12use crate::consts::*;
13use crate::events::{EventQueue, EventStatus}; 13use crate::events::{EventQueue, EventStatus};
14use crate::fmt::Bytes; 14use crate::fmt::Bytes;
15use crate::ioctl::{IoctlState, IoctlType, PendingIoctl};
15use crate::nvram::NVRAM; 16use crate::nvram::NVRAM;
16use crate::structs::*; 17use crate::structs::*;
17use crate::{events, Core, IoctlState, IoctlType, CHIP, MTU}; 18use crate::{events, Core, CHIP, MTU};
18 19
19#[cfg(feature = "firmware-logs")] 20#[cfg(feature = "firmware-logs")]
20struct LogState { 21struct LogState {
@@ -40,7 +41,7 @@ pub struct Runner<'a, PWR, SPI> {
40 ch: ch::Runner<'a, MTU>, 41 ch: ch::Runner<'a, MTU>,
41 bus: Bus<PWR, SPI>, 42 bus: Bus<PWR, SPI>,
42 43
43 ioctl_state: &'a Cell<IoctlState>, 44 ioctl_state: &'a IoctlState,
44 ioctl_id: u16, 45 ioctl_id: u16,
45 sdpcm_seq: u8, 46 sdpcm_seq: u8,
46 sdpcm_seq_max: u8, 47 sdpcm_seq_max: u8,
@@ -59,7 +60,7 @@ where
59 pub(crate) fn new( 60 pub(crate) fn new(
60 ch: ch::Runner<'a, MTU>, 61 ch: ch::Runner<'a, MTU>,
61 bus: Bus<PWR, SPI>, 62 bus: Bus<PWR, SPI>,
62 ioctl_state: &'a Cell<IoctlState>, 63 ioctl_state: &'a IoctlState,
63 events: &'a EventQueue, 64 events: &'a EventQueue,
64 ) -> Self { 65 ) -> Self {
65 Self { 66 Self {
@@ -226,19 +227,22 @@ where
226 #[cfg(feature = "firmware-logs")] 227 #[cfg(feature = "firmware-logs")]
227 self.log_read().await; 228 self.log_read().await;
228 229
229 // Send stuff 230 let ev = || async {
230 // TODO flow control not yet complete 231 // TODO use IRQs
231 if !self.has_credit() { 232 yield_now().await;
232 warn!("TX stalled"); 233 };
233 } else { 234
234 if let IoctlState::Pending { kind, cmd, iface, buf } = self.ioctl_state.get() { 235 if self.has_credit() {
235 self.send_ioctl(kind, cmd, iface, unsafe { &*buf }).await; 236 let ioctl = self.ioctl_state.wait_pending();
236 self.ioctl_state.set(IoctlState::Sent { buf }); 237 let tx = self.ch.tx_buf();
237 } 238
238 if !self.has_credit() { 239 match select3(ioctl, tx, ev()).await {
239 warn!("TX stalled"); 240 Either3::First(PendingIoctl { buf, kind, cmd, iface }) => {
240 } else { 241 warn!("ioctl");
241 if let Some(packet) = self.ch.try_tx_buf() { 242 self.send_ioctl(kind, cmd, iface, unsafe { &*buf }).await;
243 }
244 Either3::Second(packet) => {
245 warn!("packet");
242 trace!("tx pkt {:02x}", Bytes(&packet[..packet.len().min(48)])); 246 trace!("tx pkt {:02x}", Bytes(&packet[..packet.len().min(48)]));
243 247
244 let mut buf = [0; 512]; 248 let mut buf = [0; 512];
@@ -281,28 +285,46 @@ where
281 self.bus.wlan_write(&buf[..(total_len / 4)]).await; 285 self.bus.wlan_write(&buf[..(total_len / 4)]).await;
282 self.ch.tx_done(); 286 self.ch.tx_done();
283 } 287 }
288 Either3::Third(()) => {
289 // Receive stuff
290 let irq = self.bus.read16(FUNC_BUS, REG_BUS_INTERRUPT).await;
291
292 if irq & IRQ_F2_PACKET_AVAILABLE != 0 {
293 let mut status = 0xFFFF_FFFF;
294 while status == 0xFFFF_FFFF {
295 status = self.bus.read32(FUNC_BUS, REG_BUS_STATUS).await;
296 }
297
298 if status & STATUS_F2_PKT_AVAILABLE != 0 {
299 let len = (status & STATUS_F2_PKT_LEN_MASK) >> STATUS_F2_PKT_LEN_SHIFT;
300 self.bus.wlan_read(&mut buf, len).await;
301 trace!("rx {:02x}", Bytes(&slice8_mut(&mut buf)[..(len as usize).min(48)]));
302 self.rx(&slice8_mut(&mut buf)[..len as usize]);
303 }
304 }
305 }
284 } 306 }
285 } 307 } else {
308 warn!("TX stalled");
309 ev().await;
286 310
287 // Receive stuff 311 // Receive stuff
288 let irq = self.bus.read16(FUNC_BUS, REG_BUS_INTERRUPT).await; 312 let irq = self.bus.read16(FUNC_BUS, REG_BUS_INTERRUPT).await;
289 313
290 if irq & IRQ_F2_PACKET_AVAILABLE != 0 { 314 if irq & IRQ_F2_PACKET_AVAILABLE != 0 {
291 let mut status = 0xFFFF_FFFF; 315 let mut status = 0xFFFF_FFFF;
292 while status == 0xFFFF_FFFF { 316 while status == 0xFFFF_FFFF {
293 status = self.bus.read32(FUNC_BUS, REG_BUS_STATUS).await; 317 status = self.bus.read32(FUNC_BUS, REG_BUS_STATUS).await;
294 } 318 }
295 319
296 if status & STATUS_F2_PKT_AVAILABLE != 0 { 320 if status & STATUS_F2_PKT_AVAILABLE != 0 {
297 let len = (status & STATUS_F2_PKT_LEN_MASK) >> STATUS_F2_PKT_LEN_SHIFT; 321 let len = (status & STATUS_F2_PKT_LEN_MASK) >> STATUS_F2_PKT_LEN_SHIFT;
298 self.bus.wlan_read(&mut buf, len).await; 322 self.bus.wlan_read(&mut buf, len).await;
299 trace!("rx {:02x}", Bytes(&slice8_mut(&mut buf)[..(len as usize).min(48)])); 323 trace!("rx {:02x}", Bytes(&slice8_mut(&mut buf)[..(len as usize).min(48)]));
300 self.rx(&slice8_mut(&mut buf)[..len as usize]); 324 self.rx(&slice8_mut(&mut buf)[..len as usize]);
325 }
301 } 326 }
302 } 327 }
303
304 // TODO use IRQs
305 yield_now().await;
306 } 328 }
307 } 329 }
308 330
@@ -340,19 +362,17 @@ where
340 let cdc_header = CdcHeader::from_bytes(payload[..CdcHeader::SIZE].try_into().unwrap()); 362 let cdc_header = CdcHeader::from_bytes(payload[..CdcHeader::SIZE].try_into().unwrap());
341 trace!(" {:?}", cdc_header); 363 trace!(" {:?}", cdc_header);
342 364
343 if let IoctlState::Sent { buf } = self.ioctl_state.get() { 365 if cdc_header.id == self.ioctl_id {
344 if cdc_header.id == self.ioctl_id { 366 if cdc_header.status != 0 {
345 if cdc_header.status != 0 { 367 // TODO: propagate error instead
346 // TODO: propagate error instead 368 panic!("IOCTL error {}", cdc_header.status as i32);
347 panic!("IOCTL error {}", cdc_header.status as i32); 369 }
348 }
349 370
350 let resp_len = cdc_header.len as usize; 371 let resp_len = cdc_header.len as usize;
351 info!("IOCTL Response: {:02x}", Bytes(&payload[CdcHeader::SIZE..][..resp_len])); 372 let response = &payload[CdcHeader::SIZE..][..resp_len];
373 info!("IOCTL Response: {:02x}", Bytes(response));
352 374
353 (unsafe { &mut *buf }[..resp_len]).copy_from_slice(&payload[CdcHeader::SIZE..][..resp_len]); 375 self.ioctl_state.ioctl_done(response);
354 self.ioctl_state.set(IoctlState::Done { resp_len });
355 }
356 } 376 }
357 } 377 }
358 CHANNEL_TYPE_EVENT => { 378 CHANNEL_TYPE_EVENT => {