aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJan Niehusmann <[email protected]>2022-09-06 11:38:33 +0000
committerJan Niehusmann <[email protected]>2022-09-06 12:40:22 +0000
commit95f3484b87d7ae829e14492a43d49a5a0a58f1b8 (patch)
treecc654fc77053f9325e0cd751e69d758cf1d55b14 /src
parent2bd7205c79968ba2121ece47a025ac1a90b30893 (diff)
Implement minimal tx flow control
The credit update code uses constants from https://github.com/Infineon/wifi-host-driver/blob/master/WiFi_Host_Driver/src/whd_sdpcm.c#L307-L317
Diffstat (limited to 'src')
-rw-r--r--src/lib.rs32
1 files changed, 26 insertions, 6 deletions
diff --git a/src/lib.rs b/src/lib.rs
index 34170a266..f818caf6b 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -525,6 +525,8 @@ pub struct Runner<'a, PWR, SPI> {
525 ioctl_id: u16, 525 ioctl_id: u16,
526 sdpcm_seq: u8, 526 sdpcm_seq: u8,
527 backplane_window: u32, 527 backplane_window: u32,
528
529 tx_seq_max: u8,
528} 530}
529 531
530pub async fn new<'a, PWR, SPI>( 532pub async fn new<'a, PWR, SPI>(
@@ -546,6 +548,8 @@ where
546 ioctl_id: 0, 548 ioctl_id: 0,
547 sdpcm_seq: 0, 549 sdpcm_seq: 0,
548 backplane_window: 0xAAAA_AAAA, 550 backplane_window: 0xAAAA_AAAA,
551
552 tx_seq_max: 1,
549 }; 553 };
550 554
551 runner.init(firmware).await; 555 runner.init(firmware).await;
@@ -670,13 +674,17 @@ where
670 loop { 674 loop {
671 // Send stuff 675 // Send stuff
672 // TODO flow control 676 // TODO flow control
673 if let IoctlState::Pending { kind, cmd, iface, buf } = self.state.ioctl_state.get() { 677 if self.sdpcm_seq == self.tx_seq_max || self.tx_seq_max.wrapping_sub(self.sdpcm_seq) & 0x80 != 0 {
674 self.send_ioctl(kind, cmd, iface, unsafe { &*buf }).await; 678 warn!("TX stalled");
675 self.state.ioctl_state.set(IoctlState::Sent { buf }); 679 } else {
676 } 680 if let IoctlState::Pending { kind, cmd, iface, buf } = self.state.ioctl_state.get() {
681 self.send_ioctl(kind, cmd, iface, unsafe { &*buf }).await;
682 self.state.ioctl_state.set(IoctlState::Sent { buf });
683 }
677 684
678 if let Ok(p) = self.state.tx_channel.try_recv() { 685 if let Ok(p) = self.state.tx_channel.try_recv() {
679 self.send_packet(&p).await; 686 self.send_packet(&p).await;
687 }
680 } 688 }
681 689
682 // Receive stuff 690 // Receive stuff
@@ -788,6 +796,8 @@ where
788 return; 796 return;
789 } 797 }
790 798
799 self.update_credit(&sdpcm_header);
800
791 let channel = sdpcm_header.channel_and_flags & 0x0f; 801 let channel = sdpcm_header.channel_and_flags & 0x0f;
792 802
793 let payload = &packet[sdpcm_header.header_length as _..]; 803 let payload = &packet[sdpcm_header.header_length as _..];
@@ -894,6 +904,16 @@ where
894 } 904 }
895 } 905 }
896 906
907 fn update_credit(&mut self, sdpcm_header: &SdpcmHeader) {
908 if sdpcm_header.channel_and_flags & 0xf < 3 {
909 let mut tx_seq_max = sdpcm_header.bus_data_credit;
910 if tx_seq_max - self.sdpcm_seq > 0x40 {
911 tx_seq_max = self.sdpcm_seq + 2;
912 }
913 self.tx_seq_max = tx_seq_max;
914 }
915 }
916
897 async fn send_ioctl(&mut self, kind: u32, cmd: u32, iface: u32, data: &[u8]) { 917 async fn send_ioctl(&mut self, kind: u32, cmd: u32, iface: u32, data: &[u8]) {
898 let mut buf = [0; 512]; 918 let mut buf = [0; 512];
899 let buf8 = slice8_mut(&mut buf); 919 let buf8 = slice8_mut(&mut buf);