diff options
| author | Dario Nieuwenhuis <[email protected]> | 2022-07-12 03:34:27 +0200 |
|---|---|---|
| committer | Dario Nieuwenhuis <[email protected]> | 2022-07-12 03:34:27 +0200 |
| commit | 18b11e7417e1338fb18e6ceda609f2a0841d7a57 (patch) | |
| tree | 5b22789672b7170e771e629264f2c57ffed81be6 | |
| parent | d96ad248b33d8ca89daf88c5878cb24d6566cc6d (diff) | |
check clmload_status.
| -rw-r--r-- | src/lib.rs | 85 | ||||
| -rw-r--r-- | src/structs.rs | 3 |
2 files changed, 64 insertions, 24 deletions
diff --git a/src/lib.rs b/src/lib.rs index 271917971..6a1b7970c 100644 --- a/src/lib.rs +++ b/src/lib.rs | |||
| @@ -184,10 +184,14 @@ enum IoctlState { | |||
| 184 | kind: u32, | 184 | kind: u32, |
| 185 | cmd: u32, | 185 | cmd: u32, |
| 186 | iface: u32, | 186 | iface: u32, |
| 187 | buf: *const [u8], | 187 | buf: *mut [u8], |
| 188 | }, | ||
| 189 | Sent { | ||
| 190 | buf: *mut [u8], | ||
| 191 | }, | ||
| 192 | Done { | ||
| 193 | resp_len: usize, | ||
| 188 | }, | 194 | }, |
| 189 | Sent, | ||
| 190 | Done, | ||
| 191 | } | 195 | } |
| 192 | 196 | ||
| 193 | pub struct State { | 197 | pub struct State { |
| @@ -237,9 +241,12 @@ impl<'a> Control<'a> { | |||
| 237 | buf[0..8].copy_from_slice(b"clmload\x00"); | 241 | buf[0..8].copy_from_slice(b"clmload\x00"); |
| 238 | buf[8..20].copy_from_slice(&header.to_bytes()); | 242 | buf[8..20].copy_from_slice(&header.to_bytes()); |
| 239 | buf[20..][..chunk.len()].copy_from_slice(&chunk); | 243 | buf[20..][..chunk.len()].copy_from_slice(&chunk); |
| 240 | self.ioctl(2, 263, 0, &buf[..8 + 12 + chunk.len()]).await; | 244 | self.ioctl(2, 263, 0, &mut buf[..8 + 12 + chunk.len()]).await; |
| 241 | } | 245 | } |
| 242 | 246 | ||
| 247 | // check clmload ok | ||
| 248 | assert_eq!(self.get_iovar_u32("clmload_status").await, 0); | ||
| 249 | |||
| 243 | info!("Configuring misc stuff..."); | 250 | info!("Configuring misc stuff..."); |
| 244 | 251 | ||
| 245 | self.set_iovar_u32("bus:txglom", 0).await; | 252 | self.set_iovar_u32("bus:txglom", 0).await; |
| @@ -275,7 +282,7 @@ impl<'a> Control<'a> { | |||
| 275 | self.set_iovar("bsscfg:event_msgs", &evts.to_bytes()).await; | 282 | self.set_iovar("bsscfg:event_msgs", &evts.to_bytes()).await; |
| 276 | 283 | ||
| 277 | // set wifi up | 284 | // set wifi up |
| 278 | self.ioctl(2, 2, 0, &[]).await; | 285 | self.ioctl(2, 2, 0, &mut []).await; |
| 279 | 286 | ||
| 280 | Timer::after(Duration::from_millis(100)).await; | 287 | Timer::after(Duration::from_millis(100)).await; |
| 281 | 288 | ||
| @@ -299,7 +306,7 @@ impl<'a> Control<'a> { | |||
| 299 | ssid: [0; 32], | 306 | ssid: [0; 32], |
| 300 | }; | 307 | }; |
| 301 | i.ssid[..ssid.len()].copy_from_slice(ssid.as_bytes()); | 308 | i.ssid[..ssid.len()].copy_from_slice(ssid.as_bytes()); |
| 302 | self.ioctl(2, 26, 0, &i.to_bytes()).await; // set_ssid | 309 | self.ioctl(2, 26, 0, &mut i.to_bytes()).await; // set_ssid |
| 303 | 310 | ||
| 304 | info!("JOINED"); | 311 | info!("JOINED"); |
| 305 | } | 312 | } |
| @@ -310,10 +317,18 @@ impl<'a> Control<'a> { | |||
| 310 | buf[4..8].copy_from_slice(&val2.to_le_bytes()); | 317 | buf[4..8].copy_from_slice(&val2.to_le_bytes()); |
| 311 | self.set_iovar(name, &buf).await | 318 | self.set_iovar(name, &buf).await |
| 312 | } | 319 | } |
| 320 | |||
| 313 | async fn set_iovar_u32(&mut self, name: &str, val: u32) { | 321 | async fn set_iovar_u32(&mut self, name: &str, val: u32) { |
| 314 | self.set_iovar(name, &val.to_le_bytes()).await | 322 | self.set_iovar(name, &val.to_le_bytes()).await |
| 315 | } | 323 | } |
| 316 | 324 | ||
| 325 | async fn get_iovar_u32(&mut self, name: &str) -> u32 { | ||
| 326 | let mut buf = [0; 4]; | ||
| 327 | let len = self.get_iovar(name, &mut buf).await; | ||
| 328 | assert_eq!(len, 4); | ||
| 329 | u32::from_le_bytes(buf) | ||
| 330 | } | ||
| 331 | |||
| 317 | async fn set_iovar(&mut self, name: &str, val: &[u8]) { | 332 | async fn set_iovar(&mut self, name: &str, val: &[u8]) { |
| 318 | info!("set {} = {:02x}", name, val); | 333 | info!("set {} = {:02x}", name, val); |
| 319 | 334 | ||
| @@ -323,14 +338,28 @@ impl<'a> Control<'a> { | |||
| 323 | buf[name.len() + 1..][..val.len()].copy_from_slice(val); | 338 | buf[name.len() + 1..][..val.len()].copy_from_slice(val); |
| 324 | 339 | ||
| 325 | let total_len = name.len() + 1 + val.len(); | 340 | let total_len = name.len() + 1 + val.len(); |
| 326 | self.ioctl(2, 263, 0, &buf[..total_len]).await; | 341 | self.ioctl(2, 263, 0, &mut buf).await; |
| 342 | } | ||
| 343 | |||
| 344 | async fn get_iovar(&mut self, name: &str, res: &mut [u8]) -> usize { | ||
| 345 | info!("get {}", name); | ||
| 346 | |||
| 347 | let mut buf = [0; 64]; | ||
| 348 | buf[..name.len()].copy_from_slice(name.as_bytes()); | ||
| 349 | buf[name.len()] = 0; | ||
| 350 | |||
| 351 | let total_len = name.len() + 1 + res.len(); | ||
| 352 | let res_len = self.ioctl(2, 262, 0, &mut buf[..total_len]).await - name.len() - 1; | ||
| 353 | res[..res_len].copy_from_slice(&buf[name.len() + 1..][..res_len]); | ||
| 354 | res_len | ||
| 327 | } | 355 | } |
| 328 | 356 | ||
| 329 | async fn ioctl_set_u32(&mut self, cmd: u32, iface: u32, val: u32) { | 357 | async fn ioctl_set_u32(&mut self, cmd: u32, iface: u32, val: u32) { |
| 330 | self.ioctl(2, cmd, 0, &val.to_le_bytes()).await | 358 | let mut buf = val.to_le_bytes(); |
| 359 | self.ioctl(2, cmd, 0, &mut buf).await; | ||
| 331 | } | 360 | } |
| 332 | 361 | ||
| 333 | async fn ioctl(&mut self, kind: u32, cmd: u32, iface: u32, buf: &[u8]) { | 362 | async fn ioctl(&mut self, kind: u32, cmd: u32, iface: u32, buf: &mut [u8]) -> usize { |
| 334 | // TODO cancel ioctl on future drop. | 363 | // TODO cancel ioctl on future drop. |
| 335 | 364 | ||
| 336 | while !matches!(self.state.ioctl_state.get(), IoctlState::Idle) { | 365 | while !matches!(self.state.ioctl_state.get(), IoctlState::Idle) { |
| @@ -343,11 +372,16 @@ impl<'a> Control<'a> { | |||
| 343 | .ioctl_state | 372 | .ioctl_state |
| 344 | .set(IoctlState::Pending { kind, cmd, iface, buf }); | 373 | .set(IoctlState::Pending { kind, cmd, iface, buf }); |
| 345 | 374 | ||
| 346 | while !matches!(self.state.ioctl_state.get(), IoctlState::Done) { | 375 | let resp_len = loop { |
| 376 | if let IoctlState::Done { resp_len } = self.state.ioctl_state.get() { | ||
| 377 | break resp_len; | ||
| 378 | } | ||
| 347 | yield_now().await; | 379 | yield_now().await; |
| 348 | } | 380 | }; |
| 349 | 381 | ||
| 350 | self.state.ioctl_state.set(IoctlState::Idle); | 382 | self.state.ioctl_state.set(IoctlState::Idle); |
| 383 | |||
| 384 | resp_len | ||
| 351 | } | 385 | } |
| 352 | } | 386 | } |
| 353 | 387 | ||
| @@ -519,7 +553,7 @@ impl<'a, PWR: Pin, CS: Pin, CLK: Pin, DIO: Pin> Runner<'a, PWR, CS, CLK, DIO> { | |||
| 519 | // Send stuff | 553 | // Send stuff |
| 520 | if let IoctlState::Pending { kind, cmd, iface, buf } = self.state.ioctl_state.get() { | 554 | if let IoctlState::Pending { kind, cmd, iface, buf } = self.state.ioctl_state.get() { |
| 521 | self.send_ioctl(kind, cmd, iface, unsafe { &*buf }, self.state.ioctl_id.get()); | 555 | self.send_ioctl(kind, cmd, iface, unsafe { &*buf }, self.state.ioctl_id.get()); |
| 522 | self.state.ioctl_state.set(IoctlState::Sent); | 556 | self.state.ioctl_state.set(IoctlState::Sent { buf }); |
| 523 | } | 557 | } |
| 524 | 558 | ||
| 525 | // Receive stuff | 559 | // Receive stuff |
| @@ -546,7 +580,7 @@ impl<'a, PWR: Pin, CS: Pin, CLK: Pin, DIO: Pin> Runner<'a, PWR, CS, CLK, DIO> { | |||
| 546 | } | 580 | } |
| 547 | self.cs.set_high(); | 581 | self.cs.set_high(); |
| 548 | 582 | ||
| 549 | //info!("rx {:02x}", &buf[..(len as usize).min(36)]); | 583 | trace!("rx {:02x}", &buf[..(len as usize).min(48)]); |
| 550 | 584 | ||
| 551 | self.rx(&buf[..len as usize]); | 585 | self.rx(&buf[..len as usize]); |
| 552 | } | 586 | } |
| @@ -564,7 +598,7 @@ impl<'a, PWR: Pin, CS: Pin, CLK: Pin, DIO: Pin> Runner<'a, PWR, CS, CLK, DIO> { | |||
| 564 | } | 598 | } |
| 565 | 599 | ||
| 566 | let sdpcm_header = SdpcmHeader::from_bytes(packet[..SdpcmHeader::SIZE].try_into().unwrap()); | 600 | let sdpcm_header = SdpcmHeader::from_bytes(packet[..SdpcmHeader::SIZE].try_into().unwrap()); |
| 567 | 601 | trace!("rx {:?}", sdpcm_header); | |
| 568 | if sdpcm_header.len != !sdpcm_header.len_inv { | 602 | if sdpcm_header.len != !sdpcm_header.len_inv { |
| 569 | warn!("len inv mismatch"); | 603 | warn!("len inv mismatch"); |
| 570 | return; | 604 | return; |
| @@ -587,15 +621,21 @@ impl<'a, PWR: Pin, CS: Pin, CLK: Pin, DIO: Pin> Runner<'a, PWR, CS, CLK, DIO> { | |||
| 587 | } | 621 | } |
| 588 | 622 | ||
| 589 | let cdc_header = CdcHeader::from_bytes(payload[..CdcHeader::SIZE].try_into().unwrap()); | 623 | let cdc_header = CdcHeader::from_bytes(payload[..CdcHeader::SIZE].try_into().unwrap()); |
| 624 | trace!(" {:?}", cdc_header); | ||
| 590 | 625 | ||
| 591 | if cdc_header.id == self.state.ioctl_id.get() { | 626 | if let IoctlState::Sent { buf } = self.state.ioctl_state.get() { |
| 592 | assert_eq!(cdc_header.status, 0); // todo propagate error | 627 | if cdc_header.id == self.state.ioctl_id.get() { |
| 593 | self.state.ioctl_state.set(IoctlState::Done); | 628 | assert_eq!(cdc_header.status, 0); // todo propagate error instead |
| 629 | |||
| 630 | let resp_len = cdc_header.len as usize; | ||
| 631 | (unsafe { &mut *buf }[..resp_len]).copy_from_slice(&payload[CdcHeader::SIZE..][..resp_len]); | ||
| 632 | self.state.ioctl_state.set(IoctlState::Done { resp_len }); | ||
| 633 | } | ||
| 594 | } | 634 | } |
| 595 | } | 635 | } |
| 596 | 1 => { | 636 | 1 => { |
| 597 | let bcd_header = BcdHeader::from_bytes(&payload[..BcdHeader::SIZE].try_into().unwrap()); | 637 | let bcd_header = BcdHeader::from_bytes(&payload[..BcdHeader::SIZE].try_into().unwrap()); |
| 598 | //info!("{}", bcd_header); | 638 | trace!(" {:?}", bcd_header); |
| 599 | 639 | ||
| 600 | let packet_start = BcdHeader::SIZE + 4 * bcd_header.data_offset as usize; | 640 | let packet_start = BcdHeader::SIZE + 4 * bcd_header.data_offset as usize; |
| 601 | if packet_start > payload.len() { | 641 | if packet_start > payload.len() { |
| @@ -603,7 +643,7 @@ impl<'a, PWR: Pin, CS: Pin, CLK: Pin, DIO: Pin> Runner<'a, PWR, CS, CLK, DIO> { | |||
| 603 | return; | 643 | return; |
| 604 | } | 644 | } |
| 605 | let packet = &payload[packet_start..]; | 645 | let packet = &payload[packet_start..]; |
| 606 | //info!("rx {:02x}", &packet[..(packet.len() as usize).min(36)]); | 646 | trace!(" {:02x}", &packet[..(packet.len() as usize).min(36)]); |
| 607 | 647 | ||
| 608 | let mut evt = EventHeader::from_bytes(&packet[24..][..EventHeader::SIZE].try_into().unwrap()); | 648 | let mut evt = EventHeader::from_bytes(&packet[24..][..EventHeader::SIZE].try_into().unwrap()); |
| 609 | evt.byteswap(); | 649 | evt.byteswap(); |
| @@ -642,12 +682,13 @@ impl<'a, PWR: Pin, CS: Pin, CLK: Pin, DIO: Pin> Runner<'a, PWR, CS, CLK, DIO> { | |||
| 642 | 682 | ||
| 643 | let cdc_header = CdcHeader { | 683 | let cdc_header = CdcHeader { |
| 644 | cmd: cmd, | 684 | cmd: cmd, |
| 645 | out_len: data.len() as _, | 685 | len: data.len() as _, |
| 646 | in_len: 0, | ||
| 647 | flags: kind as u16 | (iface as u16) << 12, | 686 | flags: kind as u16 | (iface as u16) << 12, |
| 648 | id, | 687 | id, |
| 649 | status: 0, | 688 | status: 0, |
| 650 | }; | 689 | }; |
| 690 | trace!("tx {:?}", sdpcm_header); | ||
| 691 | trace!(" {:?}", cdc_header); | ||
| 651 | 692 | ||
| 652 | buf[0..SdpcmHeader::SIZE].copy_from_slice(&sdpcm_header.to_bytes()); | 693 | buf[0..SdpcmHeader::SIZE].copy_from_slice(&sdpcm_header.to_bytes()); |
| 653 | buf[SdpcmHeader::SIZE..][..CdcHeader::SIZE].copy_from_slice(&cdc_header.to_bytes()); | 694 | buf[SdpcmHeader::SIZE..][..CdcHeader::SIZE].copy_from_slice(&cdc_header.to_bytes()); |
| @@ -655,7 +696,7 @@ impl<'a, PWR: Pin, CS: Pin, CLK: Pin, DIO: Pin> Runner<'a, PWR, CS, CLK, DIO> { | |||
| 655 | 696 | ||
| 656 | let total_len = (total_len + 3) & !3; // round up to 4byte | 697 | let total_len = (total_len + 3) & !3; // round up to 4byte |
| 657 | 698 | ||
| 658 | //info!("tx {:02x}", &buf[..total_len.min(48)]); | 699 | trace!(" {:02x}", &buf[..total_len.min(48)]); |
| 659 | 700 | ||
| 660 | let cmd = cmd_word(true, true, FUNC_WLAN, 0, total_len as _); | 701 | let cmd = cmd_word(true, true, FUNC_WLAN, 0, total_len as _); |
| 661 | self.cs.set_low(); | 702 | self.cs.set_low(); |
diff --git a/src/structs.rs b/src/structs.rs index beda9f364..91df616ad 100644 --- a/src/structs.rs +++ b/src/structs.rs | |||
| @@ -42,8 +42,7 @@ impl_bytes!(SdpcmHeader); | |||
| 42 | #[repr(C)] | 42 | #[repr(C)] |
| 43 | pub struct CdcHeader { | 43 | pub struct CdcHeader { |
| 44 | pub cmd: u32, | 44 | pub cmd: u32, |
| 45 | pub out_len: u16, | 45 | pub len: u32, |
| 46 | pub in_len: u16, | ||
| 47 | pub flags: u16, | 46 | pub flags: u16, |
| 48 | pub id: u16, | 47 | pub id: u16, |
| 49 | pub status: u32, | 48 | pub status: u32, |
