diff options
| author | Jan Niehusmann <[email protected]> | 2022-09-06 11:38:33 +0000 |
|---|---|---|
| committer | Jan Niehusmann <[email protected]> | 2022-09-06 12:40:22 +0000 |
| commit | 95f3484b87d7ae829e14492a43d49a5a0a58f1b8 (patch) | |
| tree | cc654fc77053f9325e0cd751e69d758cf1d55b14 /src | |
| parent | 2bd7205c79968ba2121ece47a025ac1a90b30893 (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.rs | 32 |
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 | ||
| 530 | pub async fn new<'a, PWR, SPI>( | 532 | pub 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); |
