We are seeing a corner case where host receiving copy completion for WMI
command though copy engine is processing it. Once host receives the
copy completion, host is unmapping corresponding memory which results
in SMMU fault. To avoid such conditions though host receives copy
completion, as a work around we are adding a delay to unmap the memory
for WMI end point.

Tested-on: WCN3990 hw1.0 SNOC WLAN.HL.2.0-01387-QCAHLSWMTPLZ-1

Tested-by: Douglas Anderson <diand...@chromium.org>
Signed-off-by: Youghandhar Chintala <quic_yough...@quicinc.com>
---
 drivers/net/wireless/ath/ath10k/core.c | 15 +++++++++++++++
 drivers/net/wireless/ath/ath10k/htc.c  |  8 ++++++++
 drivers/net/wireless/ath/ath10k/hw.h   |  2 ++
 3 files changed, 25 insertions(+)

diff --git a/drivers/net/wireless/ath/ath10k/core.c 
b/drivers/net/wireless/ath/ath10k/core.c
index d1ac64026cb3..c2fda8deb9ef 100644
--- a/drivers/net/wireless/ath/ath10k/core.c
+++ b/drivers/net/wireless/ath/ath10k/core.c
@@ -99,6 +99,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] 
= {
                .dynamic_sar_support = false,
                .hw_restart_disconnect = false,
                .use_fw_tx_credits = true,
+               .delay_unmap_buffer = false,
        },
        {
                .id = QCA988X_HW_2_0_VERSION,
@@ -138,6 +139,7 @@ static const struct ath10k_hw_params 
ath10k_hw_params_list[] = {
                .dynamic_sar_support = false,
                .hw_restart_disconnect = false,
                .use_fw_tx_credits = true,
+               .delay_unmap_buffer = false,
        },
        {
                .id = QCA9887_HW_1_0_VERSION,
@@ -178,6 +180,7 @@ static const struct ath10k_hw_params 
ath10k_hw_params_list[] = {
                .dynamic_sar_support = false,
                .hw_restart_disconnect = false,
                .use_fw_tx_credits = true,
+               .delay_unmap_buffer = false,
        },
        {
                .id = QCA6174_HW_3_2_VERSION,
@@ -252,6 +255,7 @@ static const struct ath10k_hw_params 
ath10k_hw_params_list[] = {
                .dynamic_sar_support = false,
                .hw_restart_disconnect = false,
                .use_fw_tx_credits = true,
+               .delay_unmap_buffer = false,
        },
        {
                .id = QCA6174_HW_2_1_VERSION,
@@ -291,6 +295,7 @@ static const struct ath10k_hw_params 
ath10k_hw_params_list[] = {
                .dynamic_sar_support = false,
                .hw_restart_disconnect = false,
                .use_fw_tx_credits = true,
+               .delay_unmap_buffer = false,
        },
        {
                .id = QCA6174_HW_3_0_VERSION,
@@ -330,6 +335,7 @@ static const struct ath10k_hw_params 
ath10k_hw_params_list[] = {
                .dynamic_sar_support = false,
                .hw_restart_disconnect = false,
                .use_fw_tx_credits = true,
+               .delay_unmap_buffer = false,
        },
        {
                .id = QCA6174_HW_3_2_VERSION,
@@ -373,6 +379,7 @@ static const struct ath10k_hw_params 
ath10k_hw_params_list[] = {
                .dynamic_sar_support = true,
                .hw_restart_disconnect = false,
                .use_fw_tx_credits = true,
+               .delay_unmap_buffer = false,
        },
        {
                .id = QCA99X0_HW_2_0_DEV_VERSION,
@@ -418,6 +425,7 @@ static const struct ath10k_hw_params 
ath10k_hw_params_list[] = {
                .dynamic_sar_support = false,
                .hw_restart_disconnect = false,
                .use_fw_tx_credits = true,
+               .delay_unmap_buffer = false,
        },
        {
                .id = QCA9984_HW_1_0_DEV_VERSION,
@@ -470,6 +478,7 @@ static const struct ath10k_hw_params 
ath10k_hw_params_list[] = {
                .dynamic_sar_support = false,
                .hw_restart_disconnect = false,
                .use_fw_tx_credits = true,
+               .delay_unmap_buffer = false,
        },
        {
                .id = QCA9888_HW_2_0_DEV_VERSION,
@@ -519,6 +528,7 @@ static const struct ath10k_hw_params 
ath10k_hw_params_list[] = {
                .dynamic_sar_support = false,
                .hw_restart_disconnect = false,
                .use_fw_tx_credits = true,
+               .delay_unmap_buffer = false,
        },
        {
                .id = QCA9377_HW_1_0_DEV_VERSION,
@@ -558,6 +568,7 @@ static const struct ath10k_hw_params 
ath10k_hw_params_list[] = {
                .dynamic_sar_support = false,
                .hw_restart_disconnect = false,
                .use_fw_tx_credits = true,
+               .delay_unmap_buffer = false,
        },
        {
                .id = QCA9377_HW_1_1_DEV_VERSION,
@@ -599,6 +610,7 @@ static const struct ath10k_hw_params 
ath10k_hw_params_list[] = {
                .dynamic_sar_support = false,
                .hw_restart_disconnect = false,
                .use_fw_tx_credits = true,
+               .delay_unmap_buffer = false,
        },
        {
                .id = QCA9377_HW_1_1_DEV_VERSION,
@@ -631,6 +643,7 @@ static const struct ath10k_hw_params 
ath10k_hw_params_list[] = {
                .dynamic_sar_support = false,
                .hw_restart_disconnect = false,
                .use_fw_tx_credits = true,
+               .delay_unmap_buffer = false,
        },
        {
                .id = QCA4019_HW_1_0_DEV_VERSION,
@@ -677,6 +690,7 @@ static const struct ath10k_hw_params 
ath10k_hw_params_list[] = {
                .dynamic_sar_support = false,
                .hw_restart_disconnect = false,
                .use_fw_tx_credits = true,
+               .delay_unmap_buffer = false,
        },
        {
                .id = WCN3990_HW_1_0_DEV_VERSION,
@@ -709,6 +723,7 @@ static const struct ath10k_hw_params 
ath10k_hw_params_list[] = {
                .dynamic_sar_support = true,
                .hw_restart_disconnect = true,
                .use_fw_tx_credits = false,
+               .delay_unmap_buffer = true,
        },
 };
 
diff --git a/drivers/net/wireless/ath/ath10k/htc.c 
b/drivers/net/wireless/ath/ath10k/htc.c
index 6d1784f74bea..e04b9545cca6 100644
--- a/drivers/net/wireless/ath/ath10k/htc.c
+++ b/drivers/net/wireless/ath/ath10k/htc.c
@@ -56,6 +56,14 @@ void ath10k_htc_notify_tx_completion(struct ath10k_htc_ep 
*ep,
        ath10k_dbg(ar, ATH10K_DBG_HTC, "%s: ep %d skb %pK\n", __func__,
                   ep->eid, skb);
 
+       /* A corner case where the copy completion is reaching to host but still
+        * copy engine is processing it due to which host unmaps corresponding
+        * memory and causes SMMU fault, hence as workaround adding delay
+        * the unmapping memory to avoid SMMU faults.
+        */
+       if (ar->hw_params.delay_unmap_buffer &&
+           ep->ul_pipe_id == 3)
+               mdelay(2);
        hdr = (struct ath10k_htc_hdr *)skb->data;
        ath10k_htc_restore_tx_skb(ep->htc, skb);
 
diff --git a/drivers/net/wireless/ath/ath10k/hw.h 
b/drivers/net/wireless/ath/ath10k/hw.h
index 1b99f3a39a11..9643031a4427 100644
--- a/drivers/net/wireless/ath/ath10k/hw.h
+++ b/drivers/net/wireless/ath/ath10k/hw.h
@@ -637,6 +637,8 @@ struct ath10k_hw_params {
        bool hw_restart_disconnect;
 
        bool use_fw_tx_credits;
+
+       bool delay_unmap_buffer;
 };
 
 struct htt_resp;
-- 
2.37.0


_______________________________________________
ath10k mailing list
ath10k@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/ath10k

Reply via email to