pci_free_irq_vectors(ab_pci->pdev);
 }
 
+static int ath11k_pci_config_msi_data(struct ath11k_pci *ab_pci)
+{
+       struct msi_desc *msi_desc;
+
+       msi_desc = irq_get_msi_desc(ab_pci->pdev->irq);
+       if (!msi_desc) {
+               ath11k_err(ab_pci->ab, "msi_desc is NULL!\n");
+               pci_free_irq_vectors(ab_pci->pdev);
+               return -EINVAL;
+       }
+
+       ab_pci->msi_ep_base_data = msi_desc->msg.data;
+
+       ath11k_dbg(ab_pci->ab, ATH11K_DBG_PCI, "pci after request_irq msi_ep_base_data %d\n",
+                  ab_pci->msi_ep_base_data);
+
+       return 0;
+}
+
 static int ath11k_pci_claim(struct ath11k_pci *ab_pci, struct pci_dev *pdev)
 {
        struct ath11k_base *ab = ab_pci->ab;
                goto err_ce_free;
        }
 
+       /* kernel may allocate a dummy vector before request_irq and
+        * then allocate a real vector when request_irq is called.
+        * So get msi_data here again to avoid spurious interrupt
+        * as msi_data will configured to srngs.
+        */
+       ret = ath11k_pci_config_msi_data(ab_pci);
+       if (ret) {
+               ath11k_err(ab, "failed to config msi_data: %d\n", ret);
+               goto err_free_irq;
+       }
+
        ret = ath11k_core_init(ab);
        if (ret) {
                ath11k_err(ab, "failed to init core: %d\n", ret);