diff options
author | Jakub Kicinski <kuba@kernel.org> | 2020-12-22 19:43:32 -0800 |
---|---|---|
committer | Jakub Kicinski <kuba@kernel.org> | 2020-12-22 19:43:33 -0800 |
commit | e77c725a445ac07c95c666b3bfb5b4105e9b0068 (patch) | |
tree | f51860d6b1af7791a602aadac6fd637b28977bf0 /drivers/net/wireless/ath/ath11k/qmi.c | |
parent | 5d5647dad259bb416fd5d3d87012760386d97530 (diff) | |
parent | bfe55584713b4d4d518ffe9cf2dab1129eba6321 (diff) |
Merge tag 'wireless-drivers-2020-12-22' of git://git.kernel.org/pub/scm/linux/kernel/git/kvalo/wireless-drivers
Kalle Valo says:
====================
wireless-drivers fixes for v5.11
First set of fixes for v5.11, more fixes than usual this time. For
ath11k we have several fixes for QCA6390 PCI support and mt76 has
several. Also one build fix for mt76.
mt76
* fix two NULL pointer dereference
* fix build error when CONFIG_MAC80211_MESH is disabled
rtlwifi
* fix use-after-free in firmware handling code
ath11k
* error handling fixes
* fix crash found during connect and disconnect test
* handle HT disable better
* avoid printing qmi memory failure during firmware bootup
* disable ASPM during firmware bootup
* tag 'wireless-drivers-2020-12-22' of git://git.kernel.org/pub/scm/linux/kernel/git/kvalo/wireless-drivers:
MAINTAINERS: switch to different email address
mt76: mt7915: fix MESH ifdef block
mt76: mt76s: fix NULL pointer dereference in mt76s_process_tx_queue
mt76: sdio: remove wake logic in mt76s_process_tx_queue
mt76: usb: remove wake logic in mt76u_status_worker
ath11k: pci: disable ASPM L0sLs before downloading firmware
ath11k: qmi: try to allocate a big block of DMA memory first
rtlwifi: rise completion at the last step of firmware callback
mt76: mt76u: fix NULL pointer dereference in mt76u_status_worker
ath11k: Fix ath11k_pci_fix_l1ss()
ath11k: Fix error code in ath11k_core_suspend()
ath11k: start vdev if a bss peer is already created
ath11k: fix crash caused by NULL rx_channel
ath11k: add missing null check on allocated skb
====================
Link: https://lore.kernel.org/r/20201222163727.D4336C433C6@smtp.codeaurora.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Diffstat (limited to 'drivers/net/wireless/ath/ath11k/qmi.c')
-rw-r--r-- | drivers/net/wireless/ath/ath11k/qmi.c | 24 |
1 files changed, 22 insertions, 2 deletions
diff --git a/drivers/net/wireless/ath/ath11k/qmi.c b/drivers/net/wireless/ath/ath11k/qmi.c index f0b5c50974f3..0db623ff4bb9 100644 --- a/drivers/net/wireless/ath/ath11k/qmi.c +++ b/drivers/net/wireless/ath/ath11k/qmi.c @@ -1660,6 +1660,7 @@ static int ath11k_qmi_respond_fw_mem_request(struct ath11k_base *ab) struct qmi_wlanfw_respond_mem_resp_msg_v01 resp; struct qmi_txn txn = {}; int ret = 0, i; + bool delayed; req = kzalloc(sizeof(*req), GFP_KERNEL); if (!req) @@ -1672,11 +1673,13 @@ static int ath11k_qmi_respond_fw_mem_request(struct ath11k_base *ab) * failure to FW and FW will then request mulitple blocks of small * chunk size memory. */ - if (!ab->bus_params.fixed_mem_region && ab->qmi.mem_seg_count <= 2) { + if (!ab->bus_params.fixed_mem_region && ab->qmi.target_mem_delayed) { + delayed = true; ath11k_dbg(ab, ATH11K_DBG_QMI, "qmi delays mem_request %d\n", ab->qmi.mem_seg_count); memset(req, 0, sizeof(*req)); } else { + delayed = false; req->mem_seg_len = ab->qmi.mem_seg_count; for (i = 0; i < req->mem_seg_len ; i++) { @@ -1708,6 +1711,12 @@ static int ath11k_qmi_respond_fw_mem_request(struct ath11k_base *ab) } if (resp.resp.result != QMI_RESULT_SUCCESS_V01) { + /* the error response is expected when + * target_mem_delayed is true. + */ + if (delayed && resp.resp.error == 0) + goto out; + ath11k_warn(ab, "Respond mem req failed, result: %d, err: %d\n", resp.resp.result, resp.resp.error); ret = -EINVAL; @@ -1742,6 +1751,8 @@ static int ath11k_qmi_alloc_target_mem_chunk(struct ath11k_base *ab) int i; struct target_mem_chunk *chunk; + ab->qmi.target_mem_delayed = false; + for (i = 0; i < ab->qmi.mem_seg_count; i++) { chunk = &ab->qmi.target_mem[i]; chunk->vaddr = dma_alloc_coherent(ab->dev, @@ -1749,6 +1760,15 @@ static int ath11k_qmi_alloc_target_mem_chunk(struct ath11k_base *ab) &chunk->paddr, GFP_KERNEL); if (!chunk->vaddr) { + if (ab->qmi.mem_seg_count <= 2) { + ath11k_dbg(ab, ATH11K_DBG_QMI, + "qmi dma allocation failed (%d B type %u), will try later with small size\n", + chunk->size, + chunk->type); + ath11k_qmi_free_target_mem_chunk(ab); + ab->qmi.target_mem_delayed = true; + return 0; + } ath11k_err(ab, "failed to alloc memory, size: 0x%x, type: %u\n", chunk->size, chunk->type); @@ -2517,7 +2537,7 @@ static void ath11k_qmi_msg_mem_request_cb(struct qmi_handle *qmi_hdl, ret); return; } - } else if (msg->mem_seg_len > 2) { + } else { ret = ath11k_qmi_alloc_target_mem_chunk(ab); if (ret) { ath11k_warn(ab, "qmi failed to alloc target memory: %d\n", |