2020-11-11 06:40:05

by Anilkumar Kolli

[permalink] [raw]
Subject: [PATCH v2] ath11k: fix rmmod failure if qmi sequence fails

QMI sequence fails if caldata file is not available.
It is observed that 'rmmod ath11k' fails if qmi message fails.
With this patch rmmod/insmod is working.

Logs:
Direct firmware load for IPQ8074/caldata.bin failed with error -2
Falling back to user helper
qmi failed to load CAL: IPQ8074/caldata.bin
qmi failed to load board data file:-11

Tested-on: IPQ8074 hw2.0 AHB WLAN.HK.2.4.0.1-00009-QCAHKSWPL_SILICONZ-1

Signed-off-by: Anilkumar Kolli <[email protected]>
---
V2:
- Rebased on latest tree

drivers/net/wireless/ath/ath11k/ahb.c | 9 +++++++-
drivers/net/wireless/ath/ath11k/core.h | 1 +
drivers/net/wireless/ath/ath11k/debugfs.c | 1 +
drivers/net/wireless/ath/ath11k/pci.c | 8 +++++++
drivers/net/wireless/ath/ath11k/qmi.c | 37 ++++++++++++++++++++-----------
5 files changed, 42 insertions(+), 14 deletions(-)

diff --git a/drivers/net/wireless/ath/ath11k/ahb.c b/drivers/net/wireless/ath/ath11k/ahb.c
index c7843f461dd2..d4ef45cd0685 100644
--- a/drivers/net/wireless/ath/ath11k/ahb.c
+++ b/drivers/net/wireless/ath/ath11k/ahb.c
@@ -747,6 +747,13 @@ static int ath11k_ahb_remove(struct platform_device *pdev)
struct ath11k_base *ab = platform_get_drvdata(pdev);
unsigned long left;

+ if (test_bit(ATH11K_FLAG_QMI_FAIL, &ab->dev_flags)) {
+ ath11k_ahb_power_down(ab);
+ ath11k_debugfs_soc_destroy(ab);
+ ath11k_qmi_deinit_service(ab);
+ goto qmi_fail;
+ }
+
reinit_completion(&ab->driver_recovery);

if (test_bit(ATH11K_FLAG_RECOVERY, &ab->dev_flags)) {
@@ -760,8 +767,8 @@ static int ath11k_ahb_remove(struct platform_device *pdev)
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);
ath11k_core_free(ab);
diff --git a/drivers/net/wireless/ath/ath11k/core.h b/drivers/net/wireless/ath/ath11k/core.h
index 79224ed703db..b40ce9f3ebac 100644
--- a/drivers/net/wireless/ath/ath11k/core.h
+++ b/drivers/net/wireless/ath/ath11k/core.h
@@ -183,6 +183,7 @@ enum ath11k_dev_flags {
ATH11K_FLAG_RECOVERY,
ATH11K_FLAG_UNREGISTERING,
ATH11K_FLAG_REGISTERED,
+ ATH11K_FLAG_QMI_FAIL,
};

enum ath11k_monitor_flags {
diff --git a/drivers/net/wireless/ath/ath11k/debugfs.c b/drivers/net/wireless/ath/ath11k/debugfs.c
index 1b914e67d314..554feaf1ed5c 100644
--- a/drivers/net/wireless/ath/ath11k/debugfs.c
+++ b/drivers/net/wireless/ath/ath11k/debugfs.c
@@ -867,6 +867,7 @@ void ath11k_debugfs_soc_destroy(struct ath11k_base *ab)
debugfs_remove_recursive(ab->debugfs_ath11k);
ab->debugfs_ath11k = NULL;
}
+EXPORT_SYMBOL(ath11k_debugfs_soc_destroy);

void ath11k_debugfs_fw_stats_init(struct ath11k *ar)
{
diff --git a/drivers/net/wireless/ath/ath11k/pci.c b/drivers/net/wireless/ath/ath11k/pci.c
index b75f47dc36de..e535215e53b6 100644
--- a/drivers/net/wireless/ath/ath11k/pci.c
+++ b/drivers/net/wireless/ath/ath11k/pci.c
@@ -1007,10 +1007,18 @@ static void ath11k_pci_remove(struct pci_dev *pdev)
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_debugfs_soc_destroy(ab);
+ ath11k_qmi_deinit_service(ab);
+ goto qmi_fail;
+ }
+
set_bit(ATH11K_FLAG_UNREGISTERING, &ab->dev_flags);

ath11k_core_deinit(ab);

+qmi_fail:
ath11k_mhi_unregister(ab_pci);

ath11k_pci_free_irq(ab);
diff --git a/drivers/net/wireless/ath/ath11k/qmi.c b/drivers/net/wireless/ath/ath11k/qmi.c
index 8529b3328d24..619b6ec727e3 100644
--- a/drivers/net/wireless/ath/ath11k/qmi.c
+++ b/drivers/net/wireless/ath/ath11k/qmi.c
@@ -2419,7 +2419,7 @@ ath11k_qmi_driver_event_post(struct ath11k_qmi *qmi,
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;
@@ -2427,17 +2427,19 @@ static void ath11k_qmi_event_server_arrive(struct ath11k_qmi *qmi)
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 ret;
}

-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;
@@ -2445,11 +2447,13 @@ static void ath11k_qmi_event_mem_request(struct ath11k_qmi *qmi)
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 ret;
}

-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;
@@ -2457,7 +2461,7 @@ static void ath11k_qmi_event_load_bdf(struct ath11k_qmi *qmi)
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;
}

if (ab->bus_params.fixed_bdf_addr)
@@ -2466,14 +2470,16 @@ static void ath11k_qmi_event_load_bdf(struct ath11k_qmi *qmi)
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 ret;
}

static void ath11k_qmi_msg_mem_request_cb(struct qmi_handle *qmi_hdl,
@@ -2613,7 +2619,7 @@ static int ath11k_qmi_ops_new_server(struct qmi_handle *qmi_hdl,
ath11k_dbg(ab, ATH11K_DBG_QMI, "qmi wifi fw qmi service connected\n");
ath11k_qmi_driver_event_post(qmi, ATH11K_QMI_EVENT_SERVER_ARRIVE, NULL);

- return 0;
+ return ret;
}

static void ath11k_qmi_ops_del_server(struct qmi_handle *qmi_hdl,
@@ -2637,6 +2643,7 @@ static void ath11k_qmi_driver_event_work(struct work_struct *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)) {
@@ -2650,17 +2657,17 @@ static void ath11k_qmi_driver_event_work(struct work_struct *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)) {
@@ -2688,6 +2695,9 @@ static void ath11k_qmi_driver_event_work(struct work_struct *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);
@@ -2740,4 +2750,5 @@ void ath11k_qmi_deinit_service(struct ath11k_base *ab)
ath11k_qmi_m3_free(ab);
ath11k_qmi_free_target_mem_chunk(ab);
}
+EXPORT_SYMBOL(ath11k_qmi_deinit_service);

--
2.7.4


2020-11-25 14:06:43

by Kalle Valo

[permalink] [raw]
Subject: Re: [PATCH v2] ath11k: fix rmmod failure if qmi sequence fails

Anilkumar Kolli <[email protected]> writes:

> QMI sequence fails if caldata file is not available.
> It is observed that 'rmmod ath11k' fails if qmi message fails.
> With this patch rmmod/insmod is working.
>
> Logs:
> Direct firmware load for IPQ8074/caldata.bin failed with error -2
> Falling back to user helper
> qmi failed to load CAL: IPQ8074/caldata.bin
> qmi failed to load board data file:-11
>
> Tested-on: IPQ8074 hw2.0 AHB WLAN.HK.2.4.0.1-00009-QCAHKSWPL_SILICONZ-1
>
> Signed-off-by: Anilkumar Kolli <[email protected]>

With this patch reloading ath11k (which has worked fine before) crashes
the kernel on QCA6390 hw2.0:

Nov 25 16:00:52 nuc1 [ 393.188277] BUG: unable to handle page fault for address: ffffffffc05b8e38
Nov 25 16:00:52 nuc1 [ 393.188300] #PF: supervisor read access in kernel mode
Nov 25 16:00:52 nuc1 [ 393.188312] #PF: error_code(0x0000) - not-present page

--
https://patchwork.kernel.org/project/linux-wireless/list/

https://wireless.wiki.kernel.org/en/developers/documentation/submittingpatches

2020-11-30 13:58:54

by Anilkumar Kolli

[permalink] [raw]
Subject: Re: [PATCH v2] ath11k: fix rmmod failure if qmi sequence fails

On 2020-11-25 19:33, Kalle Valo wrote:
> Anilkumar Kolli <[email protected]> writes:
>
>> QMI sequence fails if caldata file is not available.
>> It is observed that 'rmmod ath11k' fails if qmi message fails.
>> With this patch rmmod/insmod is working.
>>
>> Logs:
>> Direct firmware load for IPQ8074/caldata.bin failed with error -2
>> Falling back to user helper
>> qmi failed to load CAL: IPQ8074/caldata.bin
>> qmi failed to load board data file:-11
>>
>> Tested-on: IPQ8074 hw2.0 AHB
>> WLAN.HK.2.4.0.1-00009-QCAHKSWPL_SILICONZ-1
>>
>> Signed-off-by: Anilkumar Kolli <[email protected]>
>
> With this patch reloading ath11k (which has worked fine before) crashes
> the kernel on QCA6390 hw2.0:
>
> Nov 25 16:00:52 nuc1 [ 393.188277] BUG: unable to handle page fault
> for address: ffffffffc05b8e38
> Nov 25 16:00:52 nuc1 [ 393.188300] #PF: supervisor read access in
> kernel mode
> Nov 25 16:00:52 nuc1 [ 393.188312] #PF: error_code(0x0000) -
> not-present page

I will test this in QCA6390 and update.
Which branch should I use for testing. master or ath11k-qca6390-bringup
?

Thanks
Anil

2020-11-30 16:29:50

by Kalle Valo

[permalink] [raw]
Subject: Re: [PATCH v2] ath11k: fix rmmod failure if qmi sequence fails

[email protected] writes:

> On 2020-11-25 19:33, Kalle Valo wrote:
>> Anilkumar Kolli <[email protected]> writes:
>>
>>> QMI sequence fails if caldata file is not available.
>>> It is observed that 'rmmod ath11k' fails if qmi message fails.
>>> With this patch rmmod/insmod is working.
>>>
>>> Logs:
>>> Direct firmware load for IPQ8074/caldata.bin failed with error -2
>>> Falling back to user helper
>>> qmi failed to load CAL: IPQ8074/caldata.bin
>>> qmi failed to load board data file:-11
>>>
>>> Tested-on: IPQ8074 hw2.0 AHB
>>> WLAN.HK.2.4.0.1-00009-QCAHKSWPL_SILICONZ-1
>>>
>>> Signed-off-by: Anilkumar Kolli <[email protected]>
>>
>> With this patch reloading ath11k (which has worked fine before) crashes
>> the kernel on QCA6390 hw2.0:
>>
>> Nov 25 16:00:52 nuc1 [ 393.188277] BUG: unable to handle page fault
>> for address: ffffffffc05b8e38
>> Nov 25 16:00:52 nuc1 [ 393.188300] #PF: supervisor read access in
>> kernel mode
>> Nov 25 16:00:52 nuc1 [ 393.188312] #PF: error_code(0x0000) -
>> not-present page
>
> I will test this in QCA6390 and update.
> Which branch should I use for testing. master or
> ath11k-qca6390-bringup ?

Please use master branch.

ath11k-qca6390-bringup is just a temporary branch for collecting all
important QCA6390 patches in one place.

--
https://patchwork.kernel.org/project/linux-wireless/list/

https://wireless.wiki.kernel.org/en/developers/documentation/submittingpatches