From 1939a20df7ff659beea1ee8808979561eea774b4 Mon Sep 17 00:00:00 2001 From: bings Date: Thu, 30 Jul 2020 12:16:37 +0800 Subject: [PATCH] qcacld-3.0: Split wlan.ko into wlan_resident.ko and wlan.ko Module is saved in specified memory location when loading. In some third platform, after rmmod/insmod wlan.ko for a while, wlan.ko may fail to load due to memory fragmentation. Split wlan.ko into wlan_resident.ko and wlan.ko. Keep wlan_resident.ko in kernel all the while and trigger insmod/rmmod only on wlan.ko. wlan_resident.ko contains all the module realization while wlan.ko only contains module init/exit. Change-Id: Iaeb6d810293cc000de8d6ec1df5cd985cef0c317 CRs-Fixed: 2727941 --- Kbuild | 7 +++ core/hdd/inc/wlan_hdd_main.h | 26 ++++++++++++ core/hdd/src/wlan_hdd_main.c | 66 ++++++++++++++++++++--------- core/hdd/src/wlan_hdd_main_module.c | 50 ++++++++++++++++++++++ 4 files changed, 128 insertions(+), 21 deletions(-) create mode 100644 core/hdd/src/wlan_hdd_main_module.c diff --git a/Kbuild b/Kbuild index 1f5ad4040197..733f15eca6c4 100644 --- a/Kbuild +++ b/Kbuild @@ -2543,6 +2543,7 @@ cppflags-$(CONFIG_CM_ROAM_OFFLOAD) += -DROAM_OFFLOAD_V1 cppflags-$(CONFIG_PLD_IPCI_ICNSS_FLAG) += -DCONFIG_PLD_IPCI_ICNSS cppflags-$(CONFIG_PLD_SDIO_CNSS_FLAG) += -DCONFIG_PLD_SDIO_CNSS +cppflags-$(CONFIG_WLAN_RESIDENT_DRIVER) += -DFEATURE_WLAN_RESIDENT_DRIVER ifeq ($(CONFIG_IPCIE_FW_SIM), y) cppflags-y += -DCONFIG_PLD_IPCIE_FW_SIM @@ -3638,7 +3639,13 @@ endif # Module information used by KBuild framework obj-$(CONFIG_QCA_CLD_WLAN) += $(MODNAME).o +ifeq ($(CONFIG_WLAN_RESIDENT_DRIVER), y) +$(MODNAME)-y := $(HDD_SRC_DIR)/wlan_hdd_main_module.o +obj-$(CONFIG_QCA_CLD_WLAN) += wlan_resident.o +wlan_resident-y := $(OBJS) +else $(MODNAME)-y := $(OBJS) +endif OBJS_DIRS := $(dir $(OBJS)) \ $(WLAN_COMMON_ROOT)/$(HIF_CE_DIR)/ \ $(QDF_OBJ_DIR)/ \ diff --git a/core/hdd/inc/wlan_hdd_main.h b/core/hdd/inc/wlan_hdd_main.h index da277a7337e9..b54a30224334 100644 --- a/core/hdd/inc/wlan_hdd_main.h +++ b/core/hdd/inc/wlan_hdd_main.h @@ -4456,6 +4456,32 @@ static inline void hdd_sta_destroy_ctx_all(struct hdd_context *hdd_ctx) } #endif +#ifdef FEATURE_WLAN_RESIDENT_DRIVER +extern char *country_code; +extern int con_mode; +extern const struct kernel_param_ops con_mode_ops; +extern int con_mode_ftm; +extern const struct kernel_param_ops con_mode_ftm_ops; +#endif + +/** + * hdd_driver_load() - Perform the driver-level load operation + * + * Note: this is used in both static and DLKM driver builds + * + * Return: Errno + */ +int hdd_driver_load(void); + +/** + * hdd_driver_unload() - Performs the driver-level unload operation + * + * Note: this is used in both static and DLKM driver builds + * + * Return: None + */ +void hdd_driver_unload(void); + /** * hdd_init_start_completion() - Init the completion variable to wait on ON/OFF * diff --git a/core/hdd/src/wlan_hdd_main.c b/core/hdd/src/wlan_hdd_main.c index 3a2ce6f2aea5..a28b6c8b6af3 100644 --- a/core/hdd/src/wlan_hdd_main.c +++ b/core/hdd/src/wlan_hdd_main.c @@ -262,7 +262,10 @@ static struct kparam_string fwpath = { .maxlen = BUF_LEN, }; -static char *country_code; +char *country_code; +#ifdef FEATURE_WLAN_RESIDENT_DRIVER +EXPORT_SYMBOL(country_code); +#endif static int enable_11d = -1; static int enable_dfs_chan_scan = -1; static bool is_mode_change_psoc_idle_shutdown; @@ -1063,9 +1066,15 @@ struct notifier_block hdd_netdev_notifier = { }; /* variable to hold the insmod parameters */ -static int con_mode; +int con_mode; +#ifdef FEATURE_WLAN_RESIDENT_DRIVER +EXPORT_SYMBOL(con_mode); +#endif -static int con_mode_ftm; +int con_mode_ftm; +#ifdef FEATURE_WLAN_RESIDENT_DRIVER +EXPORT_SYMBOL(con_mode_ftm); +#endif int con_mode_epping; static int pcie_gen_speed; @@ -16038,14 +16047,7 @@ static int con_mode_handler(const char *kmessage, const struct kernel_param *kp) return hdd_set_con_mode_cb(mode); } -/** - * hdd_driver_load() - Perform the driver-level load operation - * - * Note: this is used in both static and DLKM driver builds - * - * Return: Errno - */ -static int hdd_driver_load(void) +int hdd_driver_load(void) { struct osif_driver_sync *driver_sync; QDF_STATUS status; @@ -16152,14 +16154,11 @@ exit: return errno; } -/** - * hdd_driver_unload() - Performs the driver-level unload operation - * - * Note: this is used in both static and DLKM driver builds - * - * Return: None - */ -static void hdd_driver_unload(void) +#ifdef FEATURE_WLAN_RESIDENT_DRIVER +EXPORT_SYMBOL(hdd_driver_load); +#endif + +void hdd_driver_unload(void) { struct osif_driver_sync *driver_sync; struct hdd_context *hdd_ctx; @@ -16240,6 +16239,10 @@ static void hdd_driver_unload(void) hdd_qdf_deinit(); } +#ifdef FEATURE_WLAN_RESIDENT_DRIVER +EXPORT_SYMBOL(hdd_driver_unload); +#endif + #ifndef MODULE /** * wlan_boot_cb() - Wlan boot callback @@ -16374,6 +16377,12 @@ static int wlan_deinit_sysfs(void) * * Return: 0 for success, errno on failure */ +#ifdef FEATURE_WLAN_RESIDENT_DRIVER +static int hdd_module_init(void) +{ + return 0; +} +#else static int hdd_module_init(void) { if (hdd_driver_load()) @@ -16381,6 +16390,7 @@ static int hdd_module_init(void) return 0; } +#endif #else static int __init hdd_module_init(void) { @@ -16403,10 +16413,16 @@ static int __init hdd_module_init(void) * * Return: None */ +#ifdef FEATURE_WLAN_RESIDENT_DRIVER +static void __exit hdd_module_exit(void) +{ +} +#else static void __exit hdd_module_exit(void) { hdd_driver_unload(); } +#endif #else static void __exit hdd_module_exit(void) { @@ -17815,16 +17831,24 @@ MODULE_LICENSE("Dual BSD/GPL"); MODULE_AUTHOR("Qualcomm Atheros, Inc."); MODULE_DESCRIPTION("WLAN HOST DEVICE DRIVER"); -static const struct kernel_param_ops con_mode_ops = { +const struct kernel_param_ops con_mode_ops = { .set = con_mode_handler, .get = param_get_int, }; -static const struct kernel_param_ops con_mode_ftm_ops = { +#ifdef FEATURE_WLAN_RESIDENT_DRIVER +EXPORT_SYMBOL(con_mode_ops); +#endif + +const struct kernel_param_ops con_mode_ftm_ops = { .set = con_mode_handler_ftm, .get = param_get_int, }; +#ifdef FEATURE_WLAN_RESIDENT_DRIVER +EXPORT_SYMBOL(con_mode_ftm_ops); +#endif + #ifdef WLAN_FEATURE_EPPING static const struct kernel_param_ops con_mode_epping_ops = { .set = con_mode_handler_epping, diff --git a/core/hdd/src/wlan_hdd_main_module.c b/core/hdd/src/wlan_hdd_main_module.c new file mode 100644 index 000000000000..3b0bb935b4bb --- /dev/null +++ b/core/hdd/src/wlan_hdd_main_module.c @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2020, The Linux Foundation. All rights reserved. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/** + * wlan_driver_resident: wlan_hdd_main_module.c + * + * wlan_driver_resident: WLAN Host Device Driver module interface implementation + * + */ + +#include +#include "qwlan_version.h" +#include "wlan_hdd_main.h" + +static int __init hdd_module_init(void) +{ + return hdd_driver_load(); +} + +static void __exit hdd_module_exit(void) +{ + hdd_driver_unload(); +} + +module_init(hdd_module_init); +module_exit(hdd_module_exit); + +MODULE_LICENSE("Dual BSD/GPL"); +MODULE_DESCRIPTION("WLAN HOST DEVICE DRIVER"); + +module_param_cb(con_mode, &con_mode_ops, &con_mode, + S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); + +module_param_cb(con_mode_ftm, &con_mode_ftm_ops, &con_mode_ftm, + S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); + +module_param(country_code, charp, S_IRUSR | S_IRGRP | S_IROTH);