wlan-ap-Telecominfraproject/feeds/wifi-ax/mac80211/patches/qca/223-fix-rmmod-failure-on-qmi-sequence-failure.patch
John Crispin 528a778e38 open-converged-wireless: Import 21.02 based uCentral tree
Signed-off-by: John Crispin <john@phrozen.org>
2021-03-25 12:19:47 +01:00

223 lines
6.4 KiB
Diff

From 26ef325b70eee001a8ae24bc0604dd4cd1c5e559 Mon Sep 17 00:00:00 2001
From: Sowmiya Sree Elavalagan <ssreeela@codeaurora.org>
Date: Thu, 15 Oct 2020 12:47:47 +0530
Subject: [PATCH] ath11k: fix rmmod failure on qmi sequence failure
QMI sequence fails if caldata file is not available.
Handled return value in order to process various qmi
failures.
Signed-off-by: Anilkumar Kolli <akolli@codeaurora.org>
Signed-off-by: Sowmiya Sree Elavalagan <ssreeela@codeaurora.org>
---
drivers/net/wireless/ath/ath11k/ahb.c | 9 ++++++-
drivers/net/wireless/ath/ath11k/core.h | 1 +
drivers/net/wireless/ath/ath11k/debug.c | 1 +
drivers/net/wireless/ath/ath11k/qmi.c | 42 +++++++++++++++++++++------------
4 files changed, 37 insertions(+), 16 deletions(-)
--- a/drivers/net/wireless/ath/ath11k/ahb.c
+++ b/drivers/net/wireless/ath/ath11k/ahb.c
@@ -774,6 +774,13 @@ static int ath11k_ahb_remove(struct plat
reinit_completion(&ab->driver_recovery);
+ if (test_bit(ATH11K_FLAG_QMI_FAIL, &ab->dev_flags)) {
+ ath11k_ahb_power_down(ab);
+ ath11k_debug_pdev_destroy(ab);
+ ath11k_qmi_deinit_service(ab);
+ goto qmi_fail;
+ }
+
if (test_bit(ATH11K_FLAG_RECOVERY, &ab->dev_flags))
wait_for_completion_timeout(&ab->driver_recovery,
ATH11K_AHB_RECOVERY_TIMEOUT);
@@ -782,8 +789,8 @@ static int ath11k_ahb_remove(struct plat
cancel_work_sync(&ab->restart_work);
ath11k_core_deinit(ab);
+qmi_fail:
ath11k_ahb_free_irq(ab);
-
ath11k_hal_srng_deinit(ab);
ath11k_ce_free_pipes(ab);
--- a/drivers/net/wireless/ath/ath11k/core.h
+++ b/drivers/net/wireless/ath/ath11k/core.h
@@ -197,6 +197,7 @@ enum ath11k_dev_flags {
ATH11K_FLAG_UNREGISTERING,
ATH11K_FLAG_REGISTERED,
ATH11K_FLAG_FW_RESTART_FOR_HOST,
+ ATH11K_FLAG_QMI_FAIL,
};
#define ATH11K_STATS_MGMT_FRM_TYPE_MAX 16
--- a/drivers/net/wireless/ath/ath11k/debug.c
+++ b/drivers/net/wireless/ath/ath11k/debug.c
@@ -1274,6 +1274,7 @@ int ath11k_debug_pdev_create(struct ath1
void ath11k_debug_pdev_destroy(struct ath11k_base *ab)
{
}
+EXPORT_SYMBOL(ath11k_debug_pdev_destroy);
int ath11k_debug_soc_create(struct ath11k_base *ab)
{
--- a/drivers/net/wireless/ath/ath11k/qmi.c
+++ b/drivers/net/wireless/ath/ath11k/qmi.c
@@ -3238,34 +3238,38 @@ ath11k_qmi_driver_event_post(struct ath1
return 0;
}
-static void ath11k_qmi_event_server_arrive(struct ath11k_qmi *qmi)
+static int ath11k_qmi_event_server_arrive(struct ath11k_qmi *qmi)
{
struct ath11k_base *ab = qmi->ab;
- int ret;
+ int ret = 0;
ret = ath11k_qmi_fw_ind_register_send(ab);
if (ret < 0) {
ath11k_warn(ab, "qmi failed to send FW indication QMI:%d\n", ret);
- return;
+ return ret;
}
ret = ath11k_qmi_host_cap_send(ab);
if (ret < 0) {
ath11k_warn(ab, "qmi failed to send host cap QMI:%d\n", ret);
- return;
+ return ret;
}
+
+ return 0;
}
-static void ath11k_qmi_event_mem_request(struct ath11k_qmi *qmi)
+static int ath11k_qmi_event_mem_request(struct ath11k_qmi *qmi)
{
struct ath11k_base *ab = qmi->ab;
- int ret;
+ int ret = 0;
ret = ath11k_qmi_respond_fw_mem_request(ab);
if (ret < 0) {
ath11k_warn(ab, "qmi failed to respond fw mem req:%d\n", ret);
- return;
+ return ret;
}
+
+ return 0;
}
int ath11k_qmi_pci_alloc_qdss_mem(struct ath11k_qmi *qmi)
@@ -3435,28 +3439,29 @@ static void ath11k_qmi_event_qdss_trace_
ath11k_dbg(ab, ATH11K_DBG_QMI, "QDSS configuration is completed and trace started\n");
}
-static void ath11k_qmi_event_load_bdf(struct ath11k_qmi *qmi)
+static int ath11k_qmi_event_load_bdf(struct ath11k_qmi *qmi)
{
struct ath11k_base *ab = qmi->ab;
- int ret;
+ int ret = 0;
ret = ath11k_qmi_request_target_cap(ab);
if (ret < 0) {
ath11k_warn(ab, "qmi failed to req target capabilities:%d\n", ret);
- return;
+ return ret;
}
ret = ath11k_qmi_load_bdf_qmi(ab);
if (ret < 0) {
ath11k_warn(ab, "qmi failed to load board data file:%d\n", ret);
- return;
+ return ret;
}
ret = ath11k_qmi_wlanfw_m3_info_send(ab);
if (ret < 0) {
ath11k_warn(ab, "qmi failed to send m3 info req:%d\n", ret);
- return;
+ return ret;
}
+ return 0;
}
static void ath11k_qmi_msg_mem_request_cb(struct qmi_handle *qmi_hdl,
@@ -3745,6 +3750,7 @@ static void ath11k_qmi_driver_event_work
event_work);
struct ath11k_qmi_driver_event *event;
struct ath11k_base *ab = qmi->ab;
+ int ret = 0;
spin_lock(&qmi->event_lock);
while (!list_empty(&qmi->event_list)) {
@@ -3758,17 +3764,17 @@ static void ath11k_qmi_driver_event_work
switch (event->type) {
case ATH11K_QMI_EVENT_SERVER_ARRIVE:
- ath11k_qmi_event_server_arrive(qmi);
+ ret = ath11k_qmi_event_server_arrive(qmi);
break;
case ATH11K_QMI_EVENT_SERVER_EXIT:
set_bit(ATH11K_FLAG_CRASH_FLUSH, &ab->dev_flags);
set_bit(ATH11K_FLAG_RECOVERY, &ab->dev_flags);
break;
case ATH11K_QMI_EVENT_REQUEST_MEM:
- ath11k_qmi_event_mem_request(qmi);
+ ret = ath11k_qmi_event_mem_request(qmi);
break;
case ATH11K_QMI_EVENT_FW_MEM_READY:
- ath11k_qmi_event_load_bdf(qmi);
+ ret = ath11k_qmi_event_load_bdf(qmi);
break;
case ATH11K_QMI_EVENT_FW_READY:
if (test_bit(ATH11K_FLAG_REGISTERED, &ab->dev_flags)) {
@@ -3783,6 +3789,7 @@ static void ath11k_qmi_driver_event_work
clear_bit(ATH11K_FLAG_RECOVERY, &ab->dev_flags);
ath11k_core_qmi_firmware_ready(ab);
set_bit(ATH11K_FLAG_REGISTERED, &ab->dev_flags);
+ clear_bit(ATH11K_FLAG_QMI_FAIL, &ab->dev_flags);
}
break;
case ATH11K_QMI_EVENT_COLD_BOOT_CAL_DONE:
@@ -3801,6 +3808,9 @@ static void ath11k_qmi_driver_event_work
break;
}
kfree(event);
+ if (ret < 0)
+ set_bit(ATH11K_FLAG_QMI_FAIL, &ab->dev_flags);
+
spin_lock(&qmi->event_lock);
}
spin_unlock(&qmi->event_lock);
@@ -3854,6 +3864,7 @@ out:
kfree(req);
return ret;
}
+EXPORT_SYMBOL(ath11k_qmi_deinit_service);
int ath11k_qmi_init_service(struct ath11k_base *ab)
{
--- a/drivers/net/wireless/ath/ath11k/pci.c
+++ b/drivers/net/wireless/ath/ath11k/pci.c
@@ -1107,9 +1107,17 @@ static void ath11k_pci_remove(struct pci
struct ath11k_base *ab = pci_get_drvdata(pdev);
struct ath11k_pci *ab_pci = ath11k_pci_priv(ab);
+ if (test_bit(ATH11K_FLAG_QMI_FAIL, &ab->dev_flags)) {
+ ath11k_pci_power_down(ab);
+ ath11k_debug_pdev_destroy(ab);
+ ath11k_qmi_deinit_service(ab);
+ goto qmi_fail;
+ }
+
set_bit(ATH11K_FLAG_UNREGISTERING, &ab->dev_flags);
cancel_work_sync(&ab->reset_work);
ath11k_core_deinit(ab);
+qmi_fail:
ath11k_mhi_unregister(ab_pci);
ath11k_pci_free_irq(ab);