wlan: Enable statically linked driver to switch modes.
Enable statically linked driver to switch modes based on module param
'con_mode'. add handler function to unload and reload driver when
con_mode is changed by userspace
FTM mode can be entered: echo 5 > /sys/module/wlan/parameters/con_mode
fix a problem where module_init and module_exit functions can't be
called repeatedly
Change-Id: Ief88c09de270df82f11019658876cf0f5a6d5bb7
CRs-Fixed: 394953
diff --git a/CORE/HDD/src/wlan_hdd_main.c b/CORE/HDD/src/wlan_hdd_main.c
index 0abe528..9fa3ed3 100644
--- a/CORE/HDD/src/wlan_hdd_main.c
+++ b/CORE/HDD/src/wlan_hdd_main.c
@@ -141,6 +141,7 @@
/* the Android framework expects this param even though we don't use it */
#define BUF_LEN 20
static char fwpath[BUF_LEN];
+static int wlan_hdd_inited = 0;
/*
* The rate at which the driver sends RESTART event to supplicant
@@ -288,9 +289,17 @@
void hdd_unregister_mcast_bcast_filter(hdd_context_t *pHddCtx);
void hdd_register_mcast_bcast_filter(hdd_context_t *pHddCtx);
#endif
-#ifdef WLAN_SOFTAP_FEATURE
//variable to hold the insmod parameters
static int con_mode = 0;
+#ifndef MODULE
+/* current con_mode - used only for statically linked driver
+ * con_mode is changed by userspace to indicate a mode change which will
+ * result in calling the module exit and init functions. The module
+ * exit function will clean up based on the value of con_mode prior to it
+ * being changed by userspace. So curr_con_mode records the current con_mode
+ * for exit when con_mode becomes the next mode for init
+ */
+static int curr_con_mode = 0;
#endif
#ifdef FEATURE_WLAN_INTEGRATED_SOC
@@ -4078,12 +4087,11 @@
}
#endif // ANI_BUS_TYPE_SDIO
-#if defined(FEATURE_WLAN_INTEGRATED_SOC) && defined(ANI_MANF_DIAG)
- if(5 == con_mode)
- {
- hdd_set_conparam(VOS_FTM_MODE);
- }
-#endif /* FEATURE_WLAN_INTEGRATED_SOC && ANI_MANF_DIAG */
+#ifndef MODULE
+ /* For statically linked driver, call hdd_set_conparam to update curr_con_mode
+ */
+ hdd_set_conparam((v_UINT_t)con_mode);
+#endif
// Call our main init function
if(hdd_wlan_startup(dev)) {
@@ -4190,13 +4198,11 @@
static int fwpath_changed_handler(const char *kmessage,
struct kernel_param *kp)
{
- static int drv_inited = 0;
-
- if (drv_inited) {
+ if (wlan_hdd_inited) {
return 0;
}
- drv_inited = 1;
+ wlan_hdd_inited = 1;
return hdd_driver_init();
}
@@ -4205,16 +4211,17 @@
/**---------------------------------------------------------------------------
- \brief hdd_module_exit() - Exit function
+ \brief hdd_driver_exit() - Exit function
- This is the driver exit point (invoked when module is unloaded using rmmod)
+ This is the driver exit point (invoked when module is unloaded using rmmod
+ or con_mode was changed by userspace)
\param - None
\return - None
--------------------------------------------------------------------------*/
-static void __exit hdd_module_exit(void)
+static void hdd_driver_exit(void)
{
hdd_context_t *pHddCtx = NULL;
v_CONTEXT_t pVosContext = NULL;
@@ -4272,9 +4279,66 @@
pr_info("%s: driver unloaded\n", WLAN_MODULE_NAME);
}
+/**---------------------------------------------------------------------------
+
+ \brief hdd_module_exit() - Exit function
+
+ This is the driver exit point (invoked when module is unloaded using rmmod)
+
+ \param - None
+
+ \return - None
+
+ --------------------------------------------------------------------------*/
+static void __exit hdd_module_exit(void)
+{
+ hdd_driver_exit();
+}
+
#if defined(WLAN_SOFTAP_FEATURE) || defined(ANI_MANF_DIAG)
/**---------------------------------------------------------------------------
+ \brief con_mode_handler() -
+
+ Handler function for module param con_mode when it is changed by userspace
+ Dynamically linked - do nothing
+ Statically linked - exit and init driver, as in rmmod and insmod
+
+ \param -
+
+ \return -
+
+ --------------------------------------------------------------------------*/
+#ifdef MODULE
+static int con_mode_handler(const char *kmessage,
+ struct kernel_param *kp)
+{
+ return 0;
+}
+#else /* #ifdef MODULE */
+static int con_mode_handler(const char *kmessage,
+ struct kernel_param *kp)
+{
+ int ret = param_set_int(kmessage, kp);
+
+ if (ret)
+ return ret;
+
+ if (!wlan_hdd_inited) {
+ wlan_hdd_inited = 1;
+ return hdd_driver_init();
+ }
+
+ hdd_driver_exit();
+
+ msleep(200);
+
+ return hdd_driver_init();
+}
+#endif /* #ifdef MODULE */
+
+/**---------------------------------------------------------------------------
+
\brief hdd_get_conparam() -
This is the driver exit point (invoked when module is unloaded using rmmod)
@@ -4286,12 +4350,18 @@
--------------------------------------------------------------------------*/
tVOS_CON_MODE hdd_get_conparam ( void )
{
+#ifdef MODULE
return (tVOS_CON_MODE)con_mode;
-
+#else
+ return (tVOS_CON_MODE)curr_con_mode;
+#endif
}
void hdd_set_conparam ( v_UINT_t newParam )
{
con_mode = newParam;
+#ifndef MODULE
+ curr_con_mode = con_mode;
+#endif
}
/**---------------------------------------------------------------------------
@@ -4687,9 +4757,8 @@
MODULE_AUTHOR("Qualcomm Atheros, Inc.");
MODULE_DESCRIPTION("WLAN HOST DEVICE DRIVER");
-#if defined(WLAN_SOFTAP_FEATURE) || defined(ANI_MANF_DIAG)
-module_param(con_mode, int, 0);
-#endif
+module_param_call(con_mode, con_mode_handler, param_get_int, &con_mode,
+ S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
module_param_call(fwpath, fwpath_changed_handler, param_get_string, fwpath,
S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);