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/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/main.c b/drivers/net/wireless/cnss2/main.c index 111dd924b918..c3de567f036f 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/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..557b3c2787b4 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; @@ -602,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; @@ -1011,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);