From d00e6c6b346906df4dec45973e6754580a35b01b Mon Sep 17 00:00:00 2001 From: Lin Bai Date: Tue, 24 Nov 2020 11:27:02 +0800 Subject: [PATCH 1/2] cnss2: Only send host IOVA range to firmware when SMMU enabled Only when SMMU S1 enabled, CNSS driver will send IOVA range in HOST_CAP message, and let firmware to configure ATU. Change-Id: Idd19063da975c0105d91e0e31575d0b0d1edd8e2 Signed-off-by: Lin Bai --- drivers/net/wireless/cnss2/bus.c | 15 +++++++++++++++ drivers/net/wireless/cnss2/bus.h | 1 + drivers/net/wireless/cnss2/pci.c | 8 ++++++++ drivers/net/wireless/cnss2/pci.h | 1 + drivers/net/wireless/cnss2/qmi.c | 3 ++- 5 files changed, 27 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/cnss2/bus.c b/drivers/net/wireless/cnss2/bus.c index 4a42a75f8b8f..c7f7d92050c0 100644 --- a/drivers/net/wireless/cnss2/bus.c +++ b/drivers/net/wireless/cnss2/bus.c @@ -588,3 +588,18 @@ int cnss_bus_get_msi_assignment(struct cnss_plat_data *plat_priv, return -EINVAL; } } + +bool cnss_bus_is_smmu_s1_enabled(struct cnss_plat_data *plat_priv) +{ + if (!plat_priv) + return false; + + switch (plat_priv->bus_type) { + case CNSS_BUS_PCI: + return cnss_pci_is_smmu_s1_enabled(plat_priv->bus_priv); + default: + cnss_pr_err("Unsupported bus type: %d\n", + plat_priv->bus_type); + return false; + } +} diff --git a/drivers/net/wireless/cnss2/bus.h b/drivers/net/wireless/cnss2/bus.h index 6c0cec926ad9..09346b088cda 100644 --- a/drivers/net/wireless/cnss2/bus.h +++ b/drivers/net/wireless/cnss2/bus.h @@ -69,4 +69,5 @@ int cnss_bus_get_msi_assignment(struct cnss_plat_data *plat_priv, int *num_vectors, u32 *user_base_data, u32 *base_vector); +bool cnss_bus_is_smmu_s1_enabled(struct cnss_plat_data *plat_priv); #endif /* _CNSS_BUS_H */ diff --git a/drivers/net/wireless/cnss2/pci.c b/drivers/net/wireless/cnss2/pci.c index a0b3ad1d1855..e651190de6d3 100644 --- a/drivers/net/wireless/cnss2/pci.c +++ b/drivers/net/wireless/cnss2/pci.c @@ -4099,6 +4099,14 @@ int cnss_pci_get_iova_ipa(struct cnss_pci_data *pci_priv, u64 *addr, u64 *size) return 0; } +bool cnss_pci_is_smmu_s1_enabled(struct cnss_pci_data *pci_priv) +{ + if (pci_priv) + return pci_priv->smmu_s1_enable; + + return false; +} + struct iommu_domain *cnss_smmu_get_domain(struct device *dev) { struct cnss_pci_data *pci_priv = cnss_get_pci_priv(to_pci_dev(dev)); diff --git a/drivers/net/wireless/cnss2/pci.h b/drivers/net/wireless/cnss2/pci.h index acd323bad6b8..0effa8a5e5f9 100644 --- a/drivers/net/wireless/cnss2/pci.h +++ b/drivers/net/wireless/cnss2/pci.h @@ -253,4 +253,5 @@ int cnss_pci_get_user_msi_assignment(struct cnss_pci_data *pci_priv, int *num_vectors, u32 *user_base_data, u32 *base_vector); +bool cnss_pci_is_smmu_s1_enabled(struct cnss_pci_data *pci_priv); #endif /* _CNSS_PCI_H */ diff --git a/drivers/net/wireless/cnss2/qmi.c b/drivers/net/wireless/cnss2/qmi.c index f683ca607040..6831ea5eee29 100644 --- a/drivers/net/wireless/cnss2/qmi.c +++ b/drivers/net/wireless/cnss2/qmi.c @@ -226,7 +226,8 @@ static int cnss_wlfw_host_cap_send_sync(struct cnss_plat_data *plat_priv) req->cal_done = plat_priv->cal_done; cnss_pr_dbg("Calibration done is %d\n", plat_priv->cal_done); - if (!cnss_bus_get_iova(plat_priv, &iova_start, &iova_size) && + if (cnss_bus_is_smmu_s1_enabled(plat_priv) && + !cnss_bus_get_iova(plat_priv, &iova_start, &iova_size) && !cnss_bus_get_iova_ipa(plat_priv, &iova_ipa_start, &iova_ipa_size)) { req->ddr_range_valid = 1; From 75e8fd3e51c583371f585e218c3eecad29fd3181 Mon Sep 17 00:00:00 2001 From: Chaoli Zhou Date: Tue, 26 Jan 2021 11:04:30 +0800 Subject: [PATCH 2/2] cnss2: Fix 60s timeout while search regdb.bin failure Since for the Genoa or the SP that doesn't need regdb.bin for Hasting, it should happen search regdb.bin failure issue that cause 60s timeout. So add one compile macro CNSS_REQ_FW_DIRECT to replace request_firmware_direct with request_ firmware for regdb.bin and only search the folder that set by fw_path, which can avoid 60s timeout while search file failure in the user space. static const char * const fw_path[] = { fw_path_para, "/lib/firmware/updates/" UTS_RELEASE, "/lib/firmware/updates", "/lib/firmware/" UTS_RELEASE, "/lib/firmware" }; Above piece of code is the definition of fw_path from drivers/base/firmware_loader/main.c. Change-Id: I79c2fce33a8befecb0242a70b7eee1eef9a76e9b Signed-off-by: Chaoli Zhou Signed-off-by: Kuichu Ni --- drivers/net/wireless/cnss2/Kconfig | 8 ++++++++ drivers/net/wireless/cnss2/main.c | 12 ++++++++++++ drivers/net/wireless/cnss2/main.h | 3 +++ drivers/net/wireless/cnss2/qmi.c | 12 +++++++++--- 4 files changed, 32 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/cnss2/Kconfig b/drivers/net/wireless/cnss2/Kconfig index 2619722b2354..35395ea33aeb 100644 --- a/drivers/net/wireless/cnss2/Kconfig +++ b/drivers/net/wireless/cnss2/Kconfig @@ -96,3 +96,11 @@ config CNSS_WCN7850 CNSS WCN7850 chipset. These changes are needed to support the new hardware architecture for CNSS WCN7850 chipset. + +config CNSS_REQ_FW_DIRECT + bool "Enable request_firmware_direct for firmware or configuration file" + depends on CNSS2 + help + This enables calling request_firmware_direct for firmware or + configuration file to avoid 60s timeout while search file under user + space failure. diff --git a/drivers/net/wireless/cnss2/main.c b/drivers/net/wireless/cnss2/main.c index 83f5021a780b..5a49ce0590d5 100644 --- a/drivers/net/wireless/cnss2/main.c +++ b/drivers/net/wireless/cnss2/main.c @@ -2485,6 +2485,18 @@ int cnss_minidump_remove_region(struct cnss_plat_data *plat_priv, } #endif /* CONFIG_QCOM_MINIDUMP */ +int cnss_request_firmware_direct(struct cnss_plat_data *plat_priv, + const struct firmware **fw_entry, + const char *filename) +{ + if (IS_ENABLED(CONFIG_CNSS_REQ_FW_DIRECT)) + return request_firmware_direct(fw_entry, filename, + &plat_priv->plat_dev->dev); + else + return request_firmware(fw_entry, filename, + &plat_priv->plat_dev->dev); +} + #if IS_ENABLED(CONFIG_INTERCONNECT) /** * cnss_register_bus_scale() - Setup interconnect voting data diff --git a/drivers/net/wireless/cnss2/main.h b/drivers/net/wireless/cnss2/main.h index 4c0e2e9ee098..255174389fd0 100644 --- a/drivers/net/wireless/cnss2/main.h +++ b/drivers/net/wireless/cnss2/main.h @@ -562,4 +562,7 @@ int cnss_get_tcs_info(struct cnss_plat_data *plat_priv); unsigned int cnss_get_timeout(struct cnss_plat_data *plat_priv, enum cnss_timeout_type); int cnss_dev_specific_power_on(struct cnss_plat_data *plat_priv); +int cnss_request_firmware_direct(struct cnss_plat_data *plat_priv, + const struct firmware **fw_entry, + const char *filename); #endif /* _CNSS_MAIN_H */ diff --git a/drivers/net/wireless/cnss2/qmi.c b/drivers/net/wireless/cnss2/qmi.c index 6831ea5eee29..557b3c2787b4 100644 --- a/drivers/net/wireless/cnss2/qmi.c +++ b/drivers/net/wireless/cnss2/qmi.c @@ -603,7 +603,13 @@ int cnss_wlfw_bdf_dnld_send_sync(struct cnss_plat_data *plat_priv, goto err_req_fw; } - ret = request_firmware(&fw_entry, filename, &plat_priv->plat_dev->dev); + if (bdf_type == CNSS_BDF_REGDB) + ret = cnss_request_firmware_direct(plat_priv, &fw_entry, + filename); + else + ret = request_firmware(&fw_entry, filename, + &plat_priv->plat_dev->dev); + if (ret) { cnss_pr_err("Failed to load BDF: %s\n", filename); goto err_req_fw; @@ -1012,8 +1018,8 @@ int cnss_wlfw_qdss_dnld_send_sync(struct cnss_plat_data *plat_priv) } cnss_get_qdss_cfg_filename(plat_priv, qdss_cfg_filename, sizeof(qdss_cfg_filename)); - ret = request_firmware(&fw_entry, qdss_cfg_filename, - &plat_priv->plat_dev->dev); + ret = cnss_request_firmware_direct(plat_priv, &fw_entry, + qdss_cfg_filename); if (ret) { cnss_pr_err("Failed to load QDSS: %s\n", qdss_cfg_filename);