1. 23 Apr, 2024 3 commits
    • Baochen Qiang's avatar
      wifi: ath12k: remove MHI LOOPBACK channels · b8b50a48
      Baochen Qiang authored
      There is no driver to match these two channels, so
      remove them. This fixes warnings from MHI subsystem during suspend:
      
      mhi mhi0_LOOPBACK: 1: Failed to reset channel, still resetting
      mhi mhi0_LOOPBACK: 0: Failed to reset channel, still resetting
      
      Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0-03427-QCAHMTSWPL_V1.0_V2.0_SILICONZ-1.15378.4
      Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.0.1-00029-QCAHKSWPL_SILICONZ-1
      Signed-off-by: default avatarBaochen Qiang <quic_bqiang@quicinc.com>
      Signed-off-by: default avatarKalle Valo <quic_kvalo@quicinc.com>
      Link: https://msgid.link/20240412060620.27519-3-quic_bqiang@quicinc.com
      b8b50a48
    • Baochen Qiang's avatar
      wifi: ath12k: rearrange IRQ enable/disable in reset path · c7b2da3c
      Baochen Qiang authored
      For non-WoW suspend/resume, ath12k host powers down whole hardware
      when suspend and powers up it when resume, the code path it goes
      through is very like the ath12k reset logic.
      
      In order to reuse that logic, rearrange IRQ handling in the reset
      path.
      
      Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0-03427-QCAHMTSWPL_V1.0_V2.0_SILICONZ-1.15378.4
      Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.0.1-00029-QCAHKSWPL_SILICONZ-1
      Signed-off-by: default avatarBaochen Qiang <quic_bqiang@quicinc.com>
      Signed-off-by: default avatarKalle Valo <quic_kvalo@quicinc.com>
      Link: https://msgid.link/20240412060620.27519-2-quic_bqiang@quicinc.com
      c7b2da3c
    • Baochen Qiang's avatar
      wifi: ath12k: fix kernel crash during resume · 303c0178
      Baochen Qiang authored
      Currently during resume, QMI target memory is not properly handled, resulting
      in kernel crash in case DMA remap is not supported:
      
      BUG: Bad page state in process kworker/u16:54  pfn:36e80
      page: refcount:1 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x36e80
      page dumped because: nonzero _refcount
      Call Trace:
       bad_page
       free_page_is_bad_report
       __free_pages_ok
       __free_pages
       dma_direct_free
       dma_free_attrs
       ath12k_qmi_free_target_mem_chunk
       ath12k_qmi_msg_mem_request_cb
      
      The reason is:
      Once ath12k module is loaded, firmware sends memory request to host. In case
      DMA remap not supported, ath12k refuses the first request due to failure in
      allocating with large segment size:
      
      ath12k_pci 0000:04:00.0: qmi firmware request memory request
      ath12k_pci 0000:04:00.0: qmi mem seg type 1 size 7077888
      ath12k_pci 0000:04:00.0: qmi mem seg type 4 size 8454144
      ath12k_pci 0000:04:00.0: qmi dma allocation failed (7077888 B type 1), will try later with small size
      ath12k_pci 0000:04:00.0: qmi delays mem_request 2
      ath12k_pci 0000:04:00.0: qmi firmware request memory request
      
      Later firmware comes back with more but small segments and allocation
      succeeds:
      
      ath12k_pci 0000:04:00.0: qmi mem seg type 1 size 524288
      ath12k_pci 0000:04:00.0: qmi mem seg type 1 size 524288
      ath12k_pci 0000:04:00.0: qmi mem seg type 1 size 524288
      ath12k_pci 0000:04:00.0: qmi mem seg type 1 size 524288
      ath12k_pci 0000:04:00.0: qmi mem seg type 1 size 524288
      ath12k_pci 0000:04:00.0: qmi mem seg type 1 size 524288
      ath12k_pci 0000:04:00.0: qmi mem seg type 1 size 524288
      ath12k_pci 0000:04:00.0: qmi mem seg type 1 size 262144
      ath12k_pci 0000:04:00.0: qmi mem seg type 1 size 524288
      ath12k_pci 0000:04:00.0: qmi mem seg type 1 size 524288
      ath12k_pci 0000:04:00.0: qmi mem seg type 1 size 524288
      ath12k_pci 0000:04:00.0: qmi mem seg type 1 size 524288
      ath12k_pci 0000:04:00.0: qmi mem seg type 1 size 524288
      ath12k_pci 0000:04:00.0: qmi mem seg type 4 size 524288
      ath12k_pci 0000:04:00.0: qmi mem seg type 4 size 524288
      ath12k_pci 0000:04:00.0: qmi mem seg type 4 size 524288
      ath12k_pci 0000:04:00.0: qmi mem seg type 4 size 524288
      ath12k_pci 0000:04:00.0: qmi mem seg type 4 size 524288
      ath12k_pci 0000:04:00.0: qmi mem seg type 4 size 524288
      ath12k_pci 0000:04:00.0: qmi mem seg type 4 size 524288
      ath12k_pci 0000:04:00.0: qmi mem seg type 4 size 524288
      ath12k_pci 0000:04:00.0: qmi mem seg type 4 size 524288
      ath12k_pci 0000:04:00.0: qmi mem seg type 4 size 524288
      ath12k_pci 0000:04:00.0: qmi mem seg type 4 size 524288
      ath12k_pci 0000:04:00.0: qmi mem seg type 4 size 524288
      ath12k_pci 0000:04:00.0: qmi mem seg type 4 size 524288
      ath12k_pci 0000:04:00.0: qmi mem seg type 4 size 524288
      ath12k_pci 0000:04:00.0: qmi mem seg type 4 size 524288
      ath12k_pci 0000:04:00.0: qmi mem seg type 4 size 524288
      ath12k_pci 0000:04:00.0: qmi mem seg type 4 size 65536
      ath12k_pci 0000:04:00.0: qmi mem seg type 1 size 524288
      
      Now ath12k is working. If suspend is triggered, firmware will be reloaded
      during resume. As same as before, firmware requests two large segments at
      first. In ath12k_qmi_msg_mem_request_cb() segment count and size are
      assigned:
      
      	ab->qmi.mem_seg_count == 2
      	ab->qmi.target_mem[0].size == 7077888
      	ab->qmi.target_mem[1].size == 8454144
      
      Then allocation failed like before and ath12k_qmi_free_target_mem_chunk()
      is called to free all allocated segments. Note the first segment is skipped
      because its v.addr is cleared due to allocation failure:
      
      	chunk->v.addr = dma_alloc_coherent()
      
      Also note that this leaks that segment because it has not been freed.
      
      While freeing the second segment, a size of 8454144 is passed to
      dma_free_coherent(). However remember that this segment is allocated at
      the first time firmware is loaded, before suspend. So its real size is
      524288, much smaller than 8454144. As a result kernel found we are freeing
      some memory which is in use and thus crashed.
      
      So one possible fix would be to free those segments during suspend. This
      works because with them freed, ath12k_qmi_free_target_mem_chunk() does
      nothing: all segment addresses are NULL so dma_free_coherent() is not called.
      
      But note that ath11k has similar logic but never hits this issue. Reviewing
      code there shows the luck comes from QMI memory reuse logic. So the decision
      is to port it to ath12k. Like in ath11k, the crash is avoided by adding
      prev_size to target_mem_chunk structure and caching real segment size in it,
      then prev_size instead of current size is passed to dma_free_coherent(),
      no unexpected memory is freed now.
      
      Also reuse m3 buffer.
      
      Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0-03427-QCAHMTSWPL_V1.0_V2.0_SILICONZ-1.15378.4
      Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3
      Signed-off-by: default avatarBaochen Qiang <quic_bqiang@quicinc.com>
      Signed-off-by: default avatarKalle Valo <quic_kvalo@quicinc.com>
      Link: https://msgid.link/20240419034034.2842-1-quic_bqiang@quicinc.com
      303c0178
  2. 22 Apr, 2024 5 commits
  3. 18 Apr, 2024 6 commits
  4. 16 Apr, 2024 2 commits
  5. 10 Apr, 2024 12 commits
  6. 09 Apr, 2024 3 commits
    • Karthikeyan Periyasamy's avatar
      wifi: ath12k: correct the capital word typo · df1f2b94
      Karthikeyan Periyasamy authored
      Rename the "ATH12k" word to "ATH12K" for consistent capitalization in the
      word.
      Signed-off-by: default avatarKarthikeyan Periyasamy <quic_periyasa@quicinc.com>
      Acked-by: default avatarJeff Johnson <quic_jjohnson@quicinc.com>
      Signed-off-by: default avatarKalle Valo <quic_kvalo@quicinc.com>
      Link: https://msgid.link/20240405144524.1157122-1-quic_periyasa@quicinc.com
      df1f2b94
    • Baochen Qiang's avatar
      wifi: ath11k: support hibernation · 166a490f
      Baochen Qiang authored
      Now that all infrastructure is in place and ath11k is fixed to handle all the
      corner cases, power down the ath11k firmware during suspend and power it back
      up during resume. This fixes the problem when using hibernation with ath11k PCI
      devices.
      
      For suspend, two conditions needs to be satisfied:
              1. since MHI channel unprepare would be done in late suspend stage,
                 ath11k needs to get all QMI-dependent things done before that stage.
              2. and because unprepare MHI channels requires a working MHI stack,
                 ath11k is not allowed to call mhi_power_down() until that finishes.
      So the original suspend callback is separated into two parts: the first part
      handles all QMI-dependent things in suspend callback; while the second part
      powers down MHI in suspend_late callback. This is valid because kernel calls
      ath11k's suspend callback before all suspend_late callbacks, making the first
      condition happy. And because MHI devices are children of ath11k device
      (ab->dev), kernel guarantees that ath11k's suspend_late callback is called
      after QRTR's suspend_late callback, this satisfies the second condition.
      
      Above analysis also applies to resume process. so the original resume
      callback is separated into two parts: the first part powers up MHI stack
      in resume_early callback, this guarantees MHI stack is working when
      QRTR tries to prepare MHI channels (kernel calls QRTR's resume_early callback
      after ath11k's resume_early callback, due to the child-father relationship);
      the second part waits for the completion of restart, which won't fail now
      since MHI channels are ready for use by QMI.
      
      Another notable change is in power down path, we tell mhi_power_down() to not
      to destroy MHI devices, making it possible for QRTR to help unprepare/prepare
      MHI channels, and finally get us rid of the probe-defer issue when resume.
      
      Also change related code due to interface changes.
      
      Tested-on: WCN6855 hw2.0 PCI WLAN.HSP.1.1-03125-QCAHSPSWPL_V1_V2_SILICONZ_LITE-3.6510.30
      Tested-by: default avatarTakashi Iwai <tiwai@suse.de>
      Signed-off-by: default avatarBaochen Qiang <quic_bqiang@quicinc.com>
      Acked-by: default avatarJeff Johnson <quic_jjohnson@quicinc.com>
      Signed-off-by: default avatarKalle Valo <quic_kvalo@quicinc.com>
      Link: https://msgid.link/20240305021320.3367-4-quic_bqiang@quicinc.com
      166a490f
    • Baochen Qiang's avatar
      net: qrtr: support suspend/hibernation · e0cd1185
      Baochen Qiang authored
      MHI devices may not be destroyed during suspend/hibernation, so need
      to unprepare/prepare MHI channels throughout the transition, this is
      done by adding suspend/resume callbacks.
      
      The suspend callback is called in the late suspend stage, this means
      MHI channels are still alive at suspend stage, and that makes it
      possible for an MHI controller driver to communicate with others over
      those channels at suspend stage. While the resume callback is called
      in the early resume stage, for a similar reason.
      
      Also note that we won't do unprepare/prepare when MHI device is in
      suspend state because it's pointless if MHI is only meant to go through
      a suspend/resume transition, instead of a complete power cycle.
      
      Tested-on: WCN6855 hw2.0 PCI WLAN.HSP.1.1-03125-QCAHSPSWPL_V1_V2_SILICONZ_LITE-3.6510.30
      Signed-off-by: default avatarBaochen Qiang <quic_bqiang@quicinc.com>
      Reviewed-by: default avatarManivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
      Reviewed-by: default avatarJeff Johnson <quic_jjohnson@quicinc.com>
      Signed-off-by: default avatarKalle Valo <quic_kvalo@quicinc.com>
      Link: https://msgid.link/20240305021320.3367-3-quic_bqiang@quicinc.com
      e0cd1185
  7. 08 Apr, 2024 2 commits
  8. 05 Apr, 2024 3 commits
  9. 04 Apr, 2024 4 commits