wifi: ath11k: do not process consecutive RDDM event
authorBaochen Qiang <quic_bqiang@quicinc.com>
Thu, 11 Jan 2024 07:14:06 +0000 (15:14 +0800)
committerKalle Valo <quic_kvalo@quicinc.com>
Thu, 21 Mar 2024 11:40:18 +0000 (13:40 +0200)
Currently we do reset for each RDDM event from MHI, however there are
cases, see below log, that we get two or more consecutive events, and
it is pointless to do reset for the subsequent ones. What's more, it
makes reset process more likely to fail.

[ 1502.115876] ath11k_pci 0000:04:00.0: boot notify status reason MHI_CB_EE_RDDM
[ 1502.115884] ath11k_pci 0000:04:00.0: firmware crashed: MHI_CB_EE_RDDM
[ 1502.224041] ath11k_pci 0000:04:00.0: boot notify status reason MHI_CB_EE_RDDM
[ 1502.224050] ath11k_pci 0000:04:00.0: firmware crashed: MHI_CB_EE_RDDM

Add a check to avoid reset again and again. This is done by tracking previous
MHI status: if we receive a new RDDM event while the previous one is
also the same, we treat it as duplicate and ignore it, because normally
we should receive a MHI_CB_EE_MISSION_MODE event between them.

Tested-on: WCN6855 hw2.1 PCI WLAN.HSP.1.1-03125-QCAHSPSWPL_V1_V2_SILICONZ_LITE-3.6510.23

Signed-off-by: Baochen Qiang <quic_bqiang@quicinc.com>
Acked-by: Jeff Johnson <quic_jjohnson@quicinc.com>
Signed-off-by: Kalle Valo <quic_kvalo@quicinc.com>
Link: https://msgid.link/20240111071406.14053-1-quic_bqiang@quicinc.com
drivers/net/wireless/ath/ath11k/mhi.c
drivers/net/wireless/ath/ath11k/pci.h

index ffc4c11111fc4238771726251bfd939455ce8cce..6974a551883fcb4cddf9b97ac692eaea43499c7f 100644 (file)
@@ -19,6 +19,7 @@
 
 #define MHI_TIMEOUT_DEFAULT_MS 20000
 #define RDDM_DUMP_SIZE 0x420000
+#define MHI_CB_INVALID 0xff
 
 static const struct mhi_channel_config ath11k_mhi_channels_qca6390[] = {
        {
@@ -268,6 +269,7 @@ static void ath11k_mhi_op_status_cb(struct mhi_controller *mhi_cntrl,
                                    enum mhi_callback cb)
 {
        struct ath11k_base *ab = dev_get_drvdata(mhi_cntrl->cntrl_dev);
+       struct ath11k_pci *ab_pci = ath11k_pci_priv(ab);
 
        ath11k_dbg(ab, ATH11K_DBG_BOOT, "notify status reason %s\n",
                   ath11k_mhi_op_callback_to_str(cb));
@@ -278,12 +280,21 @@ static void ath11k_mhi_op_status_cb(struct mhi_controller *mhi_cntrl,
                break;
        case MHI_CB_EE_RDDM:
                ath11k_warn(ab, "firmware crashed: MHI_CB_EE_RDDM\n");
+               if (ab_pci->mhi_pre_cb == MHI_CB_EE_RDDM) {
+                       ath11k_dbg(ab, ATH11K_DBG_BOOT,
+                                  "do not queue again for consecutive RDDM event\n");
+                       break;
+               }
+
                if (!(test_bit(ATH11K_FLAG_UNREGISTERING, &ab->dev_flags)))
                        queue_work(ab->workqueue_aux, &ab->reset_work);
+
                break;
        default:
                break;
        }
+
+       ab_pci->mhi_pre_cb = cb;
 }
 
 static int ath11k_mhi_op_read_reg(struct mhi_controller *mhi_cntrl,
@@ -396,6 +407,7 @@ int ath11k_mhi_register(struct ath11k_pci *ab_pci)
                goto free_controller;
        }
 
+       ab_pci->mhi_pre_cb = MHI_CB_INVALID;
        ret = mhi_register_controller(mhi_ctrl, ath11k_mhi_config);
        if (ret) {
                ath11k_err(ab, "failed to register to mhi bus, err = %d\n", ret);
index 6be73333d90be6c090802ba55899e0546db256d2..c33c7865145cc666394135e7fd8e10dd4462e5df 100644 (file)
@@ -64,6 +64,7 @@ struct ath11k_pci {
        char amss_path[100];
        struct mhi_controller *mhi_ctrl;
        const struct ath11k_msi_config *msi_config;
+       enum mhi_callback mhi_pre_cb;
        u32 register_window;
 
        /* protects register_window above */