cnss2: notify wlan fw to stop trace collection
Cnss2 driver receives cnss_pci_smmu_fault_handler cb from smmu driver whenever wlan fw access illegal IOVA address. In cnss smmmu fault cb handler, cnss2 driver rings trace stop door bell register to stop tracing in wlan fw. This will help to get proper traces to debug where illegal access is happening in wlan fw. Change-Id: I953ced55d4d847ccaabad15f5f70150aec8aabd6 CRs-Fixed: 3459443
This commit is contained in:

committed by
Madan Koyyalamudi

parent
03a337ba78
commit
18a4f28a8d
4
Kbuild
4
Kbuild
@@ -60,6 +60,10 @@ ifeq ($(CONFIG_DISABLE_CNSS_SRAM_DUMP),y)
|
|||||||
KBUILD_CPPFLAGS += -DCONFIG_DISABLE_CNSS_SRAM_DUMP
|
KBUILD_CPPFLAGS += -DCONFIG_DISABLE_CNSS_SRAM_DUMP
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
ifeq ($(CONFIG_CNSS2_SMMU_DB_SUPPORT),y)
|
||||||
|
KBUILD_CPPFLAGS += -DCONFIG_CNSS2_SMMU_DB_SUPPORT
|
||||||
|
endif
|
||||||
|
|
||||||
obj-$(CONFIG_CNSS2) += cnss2/
|
obj-$(CONFIG_CNSS2) += cnss2/
|
||||||
obj-$(CONFIG_ICNSS2) += icnss2/
|
obj-$(CONFIG_ICNSS2) += icnss2/
|
||||||
obj-$(CONFIG_CNSS_GENL) += cnss_genl/
|
obj-$(CONFIG_CNSS_GENL) += cnss_genl/
|
||||||
|
@@ -126,3 +126,12 @@ config DISABLE_CNSS_SRAM_DUMP
|
|||||||
If enabled, CNSS plafrom driver will not dump sram when MHI power on
|
If enabled, CNSS plafrom driver will not dump sram when MHI power on
|
||||||
timeout for CNSS QCA6490 chipset only. Since this feature about
|
timeout for CNSS QCA6490 chipset only. Since this feature about
|
||||||
sram dump costs 4M memory.
|
sram dump costs 4M memory.
|
||||||
|
|
||||||
|
config CNSS2_SMMU_DB_SUPPORT
|
||||||
|
bool "Enable early trace stop support"
|
||||||
|
depends on CNSS2
|
||||||
|
help
|
||||||
|
If enabled, CNSS platform driver will notify wlan fw to stop
|
||||||
|
traces by ringing MHI host doorbell register. This feature helps
|
||||||
|
to get traces which contain smmu fault address and enables
|
||||||
|
debugging.
|
||||||
|
45
cnss2/pci.c
45
cnss2/pci.c
@@ -819,6 +819,13 @@ static int cnss_mhi_device_get_sync_atomic(struct cnss_pci_data *pci_priv,
|
|||||||
timeout_us, in_panic);
|
timeout_us, in_panic);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_CNSS2_SMMU_DB_SUPPORT
|
||||||
|
static int cnss_mhi_host_notify_db_disable_trace(struct cnss_pci_data *pci_priv)
|
||||||
|
{
|
||||||
|
return mhi_host_notify_db_disable_trace(pci_priv->mhi_ctrl);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static void
|
static void
|
||||||
cnss_mhi_controller_set_bw_scale_cb(struct cnss_pci_data *pci_priv,
|
cnss_mhi_controller_set_bw_scale_cb(struct cnss_pci_data *pci_priv,
|
||||||
int (*cb)(struct mhi_controller *mhi_ctrl,
|
int (*cb)(struct mhi_controller *mhi_ctrl,
|
||||||
@@ -875,6 +882,13 @@ static int cnss_mhi_device_get_sync_atomic(struct cnss_pci_data *pci_priv,
|
|||||||
return -EOPNOTSUPP;
|
return -EOPNOTSUPP;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_CNSS2_SMMU_DB_SUPPORT
|
||||||
|
static int cnss_mhi_host_notify_db_disable_trace(struct cnss_pci_data *pci_priv)
|
||||||
|
{
|
||||||
|
return -EOPNOTSUPP;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static void
|
static void
|
||||||
cnss_mhi_controller_set_bw_scale_cb(struct cnss_pci_data *pci_priv,
|
cnss_mhi_controller_set_bw_scale_cb(struct cnss_pci_data *pci_priv,
|
||||||
int (*cb)(struct mhi_controller *mhi_ctrl,
|
int (*cb)(struct mhi_controller *mhi_ctrl,
|
||||||
@@ -893,6 +907,37 @@ void cnss_mhi_controller_set_base(struct cnss_pci_data *pci_priv,
|
|||||||
}
|
}
|
||||||
#endif /* CONFIG_MHI_BUS_MISC */
|
#endif /* CONFIG_MHI_BUS_MISC */
|
||||||
|
|
||||||
|
#ifdef CONFIG_CNSS2_SMMU_DB_SUPPORT
|
||||||
|
#define CNSS_MHI_WAKE_TIMEOUT 500000
|
||||||
|
static void cnss_pci_smmu_fault_handler_irq(struct iommu_domain *domain,
|
||||||
|
void *handler_token)
|
||||||
|
{
|
||||||
|
struct cnss_pci_data *pci_priv = handler_token;
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
ret = cnss_mhi_device_get_sync_atomic(pci_priv,
|
||||||
|
CNSS_MHI_WAKE_TIMEOUT, true);
|
||||||
|
if (ret < 0) {
|
||||||
|
cnss_pr_err("Failed to bring mhi in M0 state, ret %d\n", ret);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = cnss_mhi_host_notify_db_disable_trace(pci_priv);
|
||||||
|
if (ret < 0)
|
||||||
|
cnss_pr_err("Fail to notify wlan fw to stop trace collection, ret %d\n", ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
void cnss_register_iommu_fault_handler_irq(struct cnss_pci_data *pci_priv)
|
||||||
|
{
|
||||||
|
qcom_iommu_set_fault_handler_irq(pci_priv->iommu_domain,
|
||||||
|
cnss_pci_smmu_fault_handler_irq, pci_priv);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
void cnss_register_iommu_fault_handler_irq(struct cnss_pci_data *pci_priv)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
int cnss_pci_check_link_status(struct cnss_pci_data *pci_priv)
|
int cnss_pci_check_link_status(struct cnss_pci_data *pci_priv)
|
||||||
{
|
{
|
||||||
u16 device_id;
|
u16 device_id;
|
||||||
|
@@ -9,6 +9,7 @@
|
|||||||
|
|
||||||
#include <linux/cma.h>
|
#include <linux/cma.h>
|
||||||
#include <linux/iommu.h>
|
#include <linux/iommu.h>
|
||||||
|
#include <linux/qcom-iommu-util.h>
|
||||||
#include <linux/mhi.h>
|
#include <linux/mhi.h>
|
||||||
#if IS_ENABLED(CONFIG_MHI_BUS_MISC)
|
#if IS_ENABLED(CONFIG_MHI_BUS_MISC)
|
||||||
#include <linux/mhi_misc.h>
|
#include <linux/mhi_misc.h>
|
||||||
@@ -313,4 +314,5 @@ int cnss_pci_get_user_msi_assignment(struct cnss_pci_data *pci_priv,
|
|||||||
int *num_vectors,
|
int *num_vectors,
|
||||||
u32 *user_base_data,
|
u32 *user_base_data,
|
||||||
u32 *base_vector);
|
u32 *base_vector);
|
||||||
|
void cnss_register_iommu_fault_handler_irq(struct cnss_pci_data *pci_priv);
|
||||||
#endif /* _CNSS_PCI_H */
|
#endif /* _CNSS_PCI_H */
|
||||||
|
@@ -579,6 +579,7 @@ int cnss_pci_init_smmu(struct cnss_pci_data *pci_priv)
|
|||||||
pci_priv->smmu_s1_enable = true;
|
pci_priv->smmu_s1_enable = true;
|
||||||
iommu_set_fault_handler(pci_priv->iommu_domain,
|
iommu_set_fault_handler(pci_priv->iommu_domain,
|
||||||
cnss_pci_smmu_fault_handler, pci_priv);
|
cnss_pci_smmu_fault_handler, pci_priv);
|
||||||
|
cnss_register_iommu_fault_handler_irq(pci_priv);
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = of_property_read_u32_array(of_node, "qcom,iommu-dma-addr-pool",
|
ret = of_property_read_u32_array(of_node, "qcom,iommu-dma-addr-pool",
|
||||||
|
Reference in New Issue
Block a user