From 89ebfe7d2cf218f72e9c4c8a15b06f6db3206a73 Mon Sep 17 00:00:00 2001 From: Balaji Pothunoori Date: Tue, 6 Jun 2023 12:29:56 +0530 Subject: [PATCH 1/6] icnss2: Enable icnss2 module for qcs405 target This change is to enable icnss2 module for qcs405 target. Change-Id: I9c7565b44a72145e11178fe360f413ff578142bb CRs-Fixed: 3551635 --- Makefile | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index f49b8e35c2..b9757ab27f 100644 --- a/Makefile +++ b/Makefile @@ -9,7 +9,17 @@ WLAN_PLATFORM_ROOT = $(shell pwd) # so enable all flags (including debug flag CONFIG_CNSS2_DEBUG) by # default. KBUILD_OPTIONS := WLAN_PLATFORM_ROOT=$(WLAN_PLATFORM_ROOT) -ifeq ($(USE_EXTERNAL_CONFIGS),) +ifeq ($(WLAN_BASEMACHINE),qcs40x) +KBUILD_OPTIONS += CONFIG_CNSS_OUT_OF_TREE=y +KBUILD_OPTIONS += CONFIG_ICNSS2=m +KBUILD_OPTIONS += CONFIG_ICNSS2_QMI=y +KBUILD_OPTIONS += CONFIG_ICNSS2_DEBUG=y +KBUILD_OPTIONS += CONFIG_CNSS_QMI_SVC=m +KBUILD_OPTIONS += CONFIG_WCNSS_MEM_PRE_ALLOC=m +KBUILD_OPTIONS += CONFIG_CNSS_UTILS=m +KBUILD_OPTIONS += CONFIG_CNSS_GENL=m +KBUILD_OPTIONS += CONFIG_CNSS_PLAT_IPC_QMI_SVC=m +else ifeq ($(USE_EXTERNAL_CONFIGS),) KBUILD_OPTIONS += CONFIG_CNSS_OUT_OF_TREE=y KBUILD_OPTIONS += CONFIG_CNSS2=m KBUILD_OPTIONS += CONFIG_ICNSS2=m From 89f8f5e0b260f5f68846ce99e24487239eb90d62 Mon Sep 17 00:00:00 2001 From: Balaji Pothunoori Date: Wed, 23 Aug 2023 18:50:04 +0530 Subject: [PATCH 2/6] icnss2: support to add new flag rproc fw download Currently wpss_supported variable which helps to download wlan FW binary using rproc channel and also includes SMP2P communication between platform and FW. Currently SMP2P is not required for QCS405 target, Hence introduced rproc_fw_download to download only wlan FW via rproc. Change-Id: If230e05fc6098d4ea017d8af74b2b1c7a7afce25 CRs-Fixed: 3596283 --- icnss2/main.c | 16 ++++++++++++---- icnss2/main.h | 1 + 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/icnss2/main.c b/icnss2/main.c index 856aa61141..caa1e8dbdd 100644 --- a/icnss2/main.c +++ b/icnss2/main.c @@ -162,7 +162,8 @@ static ssize_t icnss_sysfs_store(struct kobject *kobj, icnss_pr_dbg("Received shutdown indication"); atomic_set(&priv->is_shutdown, true); - if (priv->wpss_supported && priv->device_id == ADRASTEA_DEVICE_ID) + if ((priv->wpss_supported || priv->rproc_fw_download) && + priv->device_id == ADRASTEA_DEVICE_ID) icnss_wpss_unload(priv); return count; } @@ -2831,7 +2832,8 @@ static int icnss_enable_recovery(struct icnss_priv *priv) return 0; } - icnss_modem_ssr_register_notifier(priv); + if (!(priv->rproc_fw_download)) + icnss_modem_ssr_register_notifier(priv); if (priv->is_slate_rfa) { icnss_slate_ssr_register_notifier(priv); @@ -4069,7 +4071,7 @@ static ssize_t wpss_boot_store(struct device *dev, struct icnss_priv *priv = dev_get_drvdata(dev); int wpss_rproc = 0; - if (!priv->wpss_supported) + if (!priv->wpss_supported && !priv->rproc_fw_download) return count; if (sscanf(buf, "%du", &wpss_rproc) != 1) { @@ -4561,6 +4563,10 @@ static void icnss_init_control_params(struct icnss_priv *priv) "bdf-download-support")) priv->bdf_download_support = true; + if (of_property_read_bool(priv->pdev->dev.of_node, + "rproc-fw-download")) + priv->rproc_fw_download = true; + if (priv->bdf_download_support && priv->device_id == ADRASTEA_DEVICE_ID) priv->ctrl_params.bdf_type = ICNSS_BDF_BIN; } @@ -4766,9 +4772,11 @@ static int icnss_probe(struct platform_device *pdev) priv->use_nv_mac = icnss_use_nv_mac(priv); icnss_pr_dbg("NV MAC feature is %s\n", priv->use_nv_mac ? "Mandatory":"Not Mandatory"); - INIT_WORK(&wpss_loader, icnss_wpss_load); } + if (priv->wpss_supported || priv->rproc_fw_download) + INIT_WORK(&wpss_loader, icnss_wpss_load); + timer_setup(&priv->recovery_timer, icnss_recovery_timeout_hdlr, 0); diff --git a/icnss2/main.h b/icnss2/main.h index e6a91cbaab..a16aac0a2f 100644 --- a/icnss2/main.h +++ b/icnss2/main.h @@ -523,6 +523,7 @@ struct icnss_priv { enum icnss_rd_card_chain_cap rd_card_chain_cap; enum icnss_phy_he_channel_width_cap phy_he_channel_width_cap; enum icnss_phy_qam_cap phy_qam_cap; + bool rproc_fw_download; }; struct icnss_reg_info { From e9066ddd355b120bca3577a56eb27b42eb5a3bcd Mon Sep 17 00:00:00 2001 From: Naman Padhiar Date: Wed, 14 Jun 2023 18:13:40 +0530 Subject: [PATCH 3/6] cnss2: Add SMEM based Secure Peripheral check Check secure peripheral HW state using SMEM APIs instead of SCM APIs. Change-Id: I3e652859189221d3b9d26bd2e71e254edf6843b0 CRs-Fixed: 3601121 --- Kbuild | 4 +++ cnss2/Kconfig | 7 +++++ cnss2/main.c | 42 ++++++++++++++++++++++++++- cnss2/pineapple_consolidate_defconfig | 1 + cnss2/pineapple_gki_defconfig | 1 + 5 files changed, 54 insertions(+), 1 deletion(-) diff --git a/Kbuild b/Kbuild index f666f417b2..961e7eb296 100644 --- a/Kbuild +++ b/Kbuild @@ -38,6 +38,10 @@ ifeq ($(CONFIG_CNSS_HW_SECURE_DISABLE), y) KBUILD_CPPFLAGS += -DCONFIG_CNSS_HW_SECURE_DISABLE endif +ifeq ($(CONFIG_CNSS_HW_SECURE_SMEM), y) +KBUILD_CPPFLAGS += -DCONFIG_CNSS_HW_SECURE_SMEM +endif + ifeq ($(CONFIG_CNSS2_CONDITIONAL_POWEROFF),y) KBUILD_CPPFLAGS += -DCONFIG_CNSS2_CONDITIONAL_POWEROFF endif diff --git a/cnss2/Kconfig b/cnss2/Kconfig index 3b4c5e9f35..29787fc668 100644 --- a/cnss2/Kconfig +++ b/cnss2/Kconfig @@ -144,6 +144,13 @@ config CNSS_HW_SECURE_DISABLE handle WLAN cold boot initialization sequence changes if HW is disabled at boot and WLAN resume sequence after WLAN HW is enabled. +config CNSS_HW_SECURE_SMEM + bool "Enable SMEM API based HW peripheral security" + depends on CNSS2 + help + If enabled, CNSS platform driver will use SMEM APIs intead of SCM + APIs to check peripheral secure state of HW. + config CNSS2_SSR_DRIVER_DUMP bool "Enable Host SSR DRIVER DUMP Collection" depends on CNSS2 diff --git a/cnss2/main.c b/cnss2/main.c index 6f907be92f..15bca97b6b 100644 --- a/cnss2/main.c +++ b/cnss2/main.c @@ -35,16 +35,21 @@ #include "reg.h" #ifdef CONFIG_CNSS_HW_SECURE_DISABLE +#ifdef CONFIG_CNSS_HW_SECURE_SMEM +#include +#define PERISEC_SMEM_ID 651 +#define HW_WIFI_UID 0x508 +#else #include "smcinvoke.h" #include "smcinvoke_object.h" #include "IClientEnv.h" - #define HW_STATE_UID 0x108 #define HW_OP_GET_STATE 1 #define HW_WIFI_UID 0x508 #define FEATURE_NOT_SUPPORTED 12 #define PERIPHERAL_NOT_FOUND 10 #endif +#endif #define CNSS_DUMP_FORMAT_VER 0x11 #define CNSS_DUMP_FORMAT_VER_V2 0x22 @@ -4394,6 +4399,40 @@ static int cnss_reboot_notifier(struct notifier_block *nb, } #ifdef CONFIG_CNSS_HW_SECURE_DISABLE +#ifdef CONFIG_CNSS_HW_SECURE_SMEM +int cnss_wlan_hw_disable_check(struct cnss_plat_data *plat_priv) +{ + uint32_t *peripheralStateInfo = NULL; + size_t size = 0; + + /* Once this flag is set, secure peripheral feature + * will not be supported till next reboot + */ + if (plat_priv->sec_peri_feature_disable) + return 0; + + peripheralStateInfo = qcom_smem_get(QCOM_SMEM_HOST_ANY, PERISEC_SMEM_ID, &size); + if (IS_ERR_OR_NULL(peripheralStateInfo)) { + if (PTR_ERR(peripheralStateInfo) != -ENOENT) + CNSS_ASSERT(0); + + cnss_pr_dbg("Secure HW feature not enabled. ret = %d\n", + PTR_ERR(peripheralStateInfo)); + plat_priv->sec_peri_feature_disable = true; + return 0; + } + + cnss_pr_dbg("Secure HW state: %d\n", *peripheralStateInfo); + if ((*peripheralStateInfo >> (HW_WIFI_UID - 0x500)) & 0x1) + set_bit(CNSS_WLAN_HW_DISABLED, + &plat_priv->driver_state); + else + clear_bit(CNSS_WLAN_HW_DISABLED, + &plat_priv->driver_state); + + return 0; +} +#else int cnss_wlan_hw_disable_check(struct cnss_plat_data *plat_priv) { struct Object client_env; @@ -4459,6 +4498,7 @@ end: } return ret; } +#endif #else int cnss_wlan_hw_disable_check(struct cnss_plat_data *plat_priv) { diff --git a/cnss2/pineapple_consolidate_defconfig b/cnss2/pineapple_consolidate_defconfig index f2bc390235..cf4d1ad7bf 100644 --- a/cnss2/pineapple_consolidate_defconfig +++ b/cnss2/pineapple_consolidate_defconfig @@ -5,6 +5,7 @@ CONFIG_CNSS_QMI_SVC=m CONFIG_BUS_AUTO_SUSPEND=y CONFIG_CNSS2_SSR_DRIVER_DUMP=y CONFIG_CNSS_HW_SECURE_DISABLE=y +CONFIG_CNSS_HW_SECURE_SMEM=y CONFIG_CNSS2_SMMU_DB_SUPPORT=y CONFIG_CNSS_PLAT_IPC_QMI_SVC=m CONFIG_WCNSS_MEM_PRE_ALLOC=m diff --git a/cnss2/pineapple_gki_defconfig b/cnss2/pineapple_gki_defconfig index 800b39a03c..403fac6ea7 100644 --- a/cnss2/pineapple_gki_defconfig +++ b/cnss2/pineapple_gki_defconfig @@ -5,6 +5,7 @@ CONFIG_CNSS_QMI_SVC=m CONFIG_BUS_AUTO_SUSPEND=y CONFIG_CNSS2_SSR_DRIVER_DUMP=y CONFIG_CNSS_HW_SECURE_DISABLE=y +CONFIG_CNSS_HW_SECURE_SMEM=y CONFIG_CNSS2_SMMU_DB_SUPPORT=y CONFIG_CNSS_PLAT_IPC_QMI_SVC=m CONFIG_WCNSS_MEM_PRE_ALLOC=m From 2f4117dcd235d3e2887b05fad04e6d5cf6fabb2a Mon Sep 17 00:00:00 2001 From: Balaji Pothunoori Date: Tue, 22 Aug 2023 20:48:02 +0530 Subject: [PATCH 4/6] icnss2: send ICNSS_UEVENT_FW_DOWN uevent instead ICNSS_UEVENT_FW_CRASH PD restart triggered as part of host based SSR triggered, this will call PLD shutdown and HDD shutdown. While processing HDD shutdown host driver check CDS recovering state and then ASSERT if it is not set. To Avoid this ASSERT, fix introduced to set CDS recovering by sending ICNSS_UEVENT_FW_DOWN uevent to Host driver during firmware crash. Change-Id: I4f06404b02bb7ce0018b3f8e1e5253e0ba155095 CRs-Fixed: 3595285 --- icnss2/main.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/icnss2/main.c b/icnss2/main.c index caa1e8dbdd..f0898bc367 100644 --- a/icnss2/main.c +++ b/icnss2/main.c @@ -1590,15 +1590,22 @@ out: static int icnss_fw_crashed(struct icnss_priv *priv, struct icnss_event_pd_service_down_data *event_data) { + struct icnss_uevent_fw_down_data fw_down_data = {0}; + icnss_pr_dbg("FW crashed, state: 0x%lx\n", priv->state); set_bit(ICNSS_PD_RESTART, &priv->state); - clear_bit(ICNSS_FW_READY, &priv->state); icnss_pm_stay_awake(priv); - if (test_bit(ICNSS_DRIVER_PROBED, &priv->state)) - icnss_call_driver_uevent(priv, ICNSS_UEVENT_FW_CRASHED, NULL); + if (test_bit(ICNSS_DRIVER_PROBED, &priv->state) && + test_bit(ICNSS_FW_READY, &priv->state)) { + clear_bit(ICNSS_FW_READY, &priv->state); + fw_down_data.crashed = true; + icnss_call_driver_uevent(priv, + ICNSS_UEVENT_FW_DOWN, + &fw_down_data); + } if (event_data && event_data->fw_rejuvenate) wlfw_rejuvenate_ack_send_sync_msg(priv); From 5d5c769c2850018037efd9d007f9cbad1b5beb9c Mon Sep 17 00:00:00 2001 From: Prateek Patil Date: Thu, 31 Aug 2023 10:52:17 +0530 Subject: [PATCH 5/6] cnss2: include qcom_aoss.h file at correct place There may be multiple time inclusion of inline definition of the APIs defined in the header file qcom_aoss.h if config CONFIG_QCOM_AOSS_QMP is disabled for underlying target. This may result in linking error. Move the header file to the correct place in power.c. Change-Id: I5c79eff3be4c758db1ab313843b36a02ecccbef9 CRs-Fixed: 3603827 --- cnss2/main.h | 1 - cnss2/power.c | 3 +++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/cnss2/main.h b/cnss2/main.h index bd37abb29d..d2ccc1d97d 100644 --- a/cnss2/main.h +++ b/cnss2/main.h @@ -25,7 +25,6 @@ #include #if IS_ENABLED(CONFIG_MSM_QMP) #include -#include #endif #ifdef CONFIG_CNSS_OUT_OF_TREE #include "cnss2.h" diff --git a/cnss2/power.c b/cnss2/power.c index 7203f34688..fbd351f5fd 100644 --- a/cnss2/power.c +++ b/cnss2/power.c @@ -18,6 +18,9 @@ #include "main.h" #include "debug.h" #include "bus.h" +#if IS_ENABLED(CONFIG_MSM_QMP) +#include +#endif #if IS_ENABLED(CONFIG_ARCH_QCOM) static struct cnss_vreg_cfg cnss_vreg_list[] = { From 696ac36d112c9bc5427543aedeb75565feb21931 Mon Sep 17 00:00:00 2001 From: Alan Chen Date: Mon, 28 Aug 2023 14:42:13 -0700 Subject: [PATCH 6/6] cnss2: Create new infrastructure for removing sysfs group Up until kernel 6.1, devm_device_remove_group() was used when removing sysfs group. From kernel 6.2 onwards, devm_device_remove_group() is no longer supported. Thus, create new functions that replicate original functionality of devm_device_remove_group(). Change-Id: If3a7b380a03eec5a3f918b5a0813830c3136fd1f CRs-Fixed: 3601923 --- cnss2/main.c | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/cnss2/main.c b/cnss2/main.c index 15bca97b6b..3de5a70133 100644 --- a/cnss2/main.c +++ b/cnss2/main.c @@ -4354,11 +4354,39 @@ out: return ret; } +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(6, 2, 0)) +union cnss_device_group_devres { + const struct attribute_group *group; +}; + +static void devm_cnss_group_remove(struct device *dev, void *res) +{ + union cnss_device_group_devres *devres = res; + const struct attribute_group *group = devres->group; + + cnss_pr_dbg("%s: removing group %p\n", __func__, group); + sysfs_remove_group(&dev->kobj, group); +} + +static int devm_cnss_group_match(struct device *dev, void *res, void *data) +{ + return ((union cnss_device_group_devres *)res) == data; +} + +static void cnss_remove_sysfs(struct cnss_plat_data *plat_priv) +{ + cnss_remove_sysfs_link(plat_priv); + WARN_ON(devres_release(&plat_priv->plat_dev->dev, + devm_cnss_group_remove, devm_cnss_group_match, + (void *)&cnss_attr_group)); +} +#else static void cnss_remove_sysfs(struct cnss_plat_data *plat_priv) { cnss_remove_sysfs_link(plat_priv); devm_device_remove_group(&plat_priv->plat_dev->dev, &cnss_attr_group); } +#endif static int cnss_event_work_init(struct cnss_plat_data *plat_priv) {