summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/cds/inc/cds_sched.h1
-rw-r--r--core/cds/src/cds_api.c91
-rw-r--r--core/cds/src/cds_concurrency.c7
-rw-r--r--core/cds/src/cds_sched.c1
-rw-r--r--core/hdd/inc/wlan_hdd_cfg.h11
-rw-r--r--core/hdd/inc/wlan_hdd_driver_ops.h5
-rw-r--r--core/hdd/inc/wlan_hdd_ftm.h6
-rw-r--r--core/hdd/inc/wlan_hdd_main.h37
-rw-r--r--core/hdd/inc/wlan_hdd_memdump.h5
-rw-r--r--core/hdd/inc/wlan_hdd_power.h2
-rw-r--r--core/hdd/src/wlan_hdd_cfg.c11
-rw-r--r--core/hdd/src/wlan_hdd_cfg80211.c100
-rw-r--r--core/hdd/src/wlan_hdd_driver_ops.c89
-rw-r--r--core/hdd/src/wlan_hdd_ftm.c667
-rw-r--r--core/hdd/src/wlan_hdd_main.c1324
-rw-r--r--core/hdd/src/wlan_hdd_memdump.c8
-rw-r--r--core/hdd/src/wlan_hdd_power.c243
17 files changed, 1112 insertions, 1496 deletions
diff --git a/core/cds/inc/cds_sched.h b/core/cds/inc/cds_sched.h
index 83cf40316412..0a269007a4fc 100644
--- a/core/cds/inc/cds_sched.h
+++ b/core/cds/inc/cds_sched.h
@@ -539,6 +539,7 @@ void cds_sched_deinit_mqs(p_cds_sched_context pSchedContext);
void cds_sched_flush_mc_mqs(p_cds_sched_context pSchedContext);
void qdf_timer_module_init(void);
+void qdf_timer_module_deinit(void);
void cds_ssr_protect_init(void);
void cds_ssr_protect(const char *caller_func);
void cds_ssr_unprotect(const char *caller_func);
diff --git a/core/cds/src/cds_api.c b/core/cds/src/cds_api.c
index 4fd6f9a07e20..82ef025f51c5 100644
--- a/core/cds/src/cds_api.c
+++ b/core/cds/src/cds_api.c
@@ -198,13 +198,6 @@ QDF_STATUS cds_open(void)
return QDF_STATUS_E_FAILURE;
}
- cds_cfg = cds_get_ini_config();
- if (!cds_cfg) {
- cds_err("Cds config is NULL");
- QDF_ASSERT(0);
- return QDF_STATUS_E_FAILURE;
- }
-
/* Initialize the timer module */
qdf_timer_module_init();
@@ -245,25 +238,27 @@ QDF_STATUS cds_open(void)
&(gp_cds_context->aMsgWrappers[iter]));
}
- /* Now Open the CDS Scheduler */
- qdf_status = cds_sched_open(gp_cds_context, &gp_cds_context->qdf_sched,
- sizeof(cds_sched_context));
-
- if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
+ pHddCtx = (hdd_context_t *) (gp_cds_context->pHDDContext);
+ if ((NULL == pHddCtx) || (NULL == pHddCtx->config)) {
/* Critical Error ... Cannot proceed further */
- QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_FATAL,
- "%s: Failed to open CDS Scheduler", __func__);
+ cds_err("Hdd Context is Null");
QDF_ASSERT(0);
goto err_msg_queue;
}
+ /* Now Open the CDS Scheduler */
- pHddCtx = (hdd_context_t *) (gp_cds_context->pHDDContext);
- if ((NULL == pHddCtx) || (NULL == pHddCtx->config)) {
- /* Critical Error ... Cannot proceed further */
- QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_FATAL,
- "%s: Hdd Context is Null", __func__);
- QDF_ASSERT(0);
- goto err_sched_close;
+ if (pHddCtx->driver_status == DRIVER_MODULES_UNINITIALIZED) {
+ qdf_status = cds_sched_open(gp_cds_context,
+ &gp_cds_context->qdf_sched,
+ sizeof(cds_sched_context));
+
+ if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
+ /* Critical Error ... Cannot proceed further */
+ QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_FATAL,
+ "%s: Failed to open CDS Scheduler", __func__);
+ QDF_ASSERT(0);
+ goto err_msg_queue;
+ }
}
scn = cds_get_context(QDF_MODULE_ID_HIF);
@@ -272,6 +267,17 @@ QDF_STATUS cds_open(void)
"%s: scn is null!", __func__);
goto err_sched_close;
}
+
+ hdd_update_config(pHddCtx);
+ cds_cfg = cds_get_ini_config();
+ if (!cds_cfg) {
+ cds_err("Cds config is NULL");
+ QDF_ASSERT(0);
+ goto err_sched_close;
+ }
+ hdd_enable_fastpath(pHddCtx->config, scn);
+ hdd_wlan_update_target_info(pHddCtx, scn);
+
ol_ctx = cds_get_context(QDF_MODULE_ID_BMI);
/* Initialize BMI and Download firmware */
qdf_status = bmi_download_firmware(ol_ctx);
@@ -280,7 +286,6 @@ QDF_STATUS cds_open(void)
"BMI FIALED status:%d", qdf_status);
goto err_bmi_close;
}
-
htcInfo.pContext = ol_ctx;
htcInfo.TargetFailure = ol_target_failure;
htcInfo.TargetSendSuspendComplete = wma_target_suspend_acknowledge;
@@ -338,6 +343,8 @@ QDF_STATUS cds_open(void)
/* UMA is supported in hardware for performing the
* frame translation 802.11 <-> 802.3
*/
+ cds_cfg->frame_xln_reqd = 1;
+
sirStatus =
mac_open(&(gp_cds_context->pMACContext),
gp_cds_context->pHDDContext, cds_cfg);
@@ -454,8 +461,11 @@ QDF_STATUS cds_pre_enable(v_CONTEXT_t cds_context)
}
/* call Packetlog connect service */
- htt_pkt_log_init(gp_cds_context->pdev_txrx_ctx, scn);
- pktlog_htc_attach();
+ if (QDF_GLOBAL_FTM_MODE != cds_get_conparam() &&
+ QDF_GLOBAL_EPPING_MODE != cds_get_conparam()) {
+ htt_pkt_log_init(gp_cds_context->pdev_txrx_ctx, scn);
+ pktlog_htc_attach();
+ }
/* Reset wma wait event */
qdf_event_reset(&gp_cds_context->wmaCompleteEvent);
@@ -653,18 +663,12 @@ err_wma_stop:
QDF_STATUS cds_disable(v_CONTEXT_t cds_context)
{
QDF_STATUS qdf_status;
-
- /* wma_stop is called before the SYS so that the processing of target
- * pending responses will not be handled during uninitialization of
- * WLAN driver
- */
- qdf_event_reset(&(gp_cds_context->wmaCompleteEvent));
+ void *handle;
qdf_status = wma_stop(cds_context, HAL_STOP_TYPE_RF_KILL);
if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
- QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
- "%s: Failed to stop wma", __func__);
+ cds_err("Failed to stop wma");
QDF_ASSERT(QDF_IS_STATUS_SUCCESS(qdf_status));
wma_setneedshutdown(cds_context);
}
@@ -672,15 +676,23 @@ QDF_STATUS cds_disable(v_CONTEXT_t cds_context)
hif_disable_isr(((cds_context_type *) cds_context)->pHIFContext);
hif_reset_soc(((cds_context_type *) cds_context)->pHIFContext);
- /* SYS STOP will stop SME and MAC */
- qdf_status = sys_stop(cds_context);
+ handle = cds_get_context(QDF_MODULE_ID_PE);
+ if (!handle) {
+ cds_err("Invalid PE context return!");
+ return QDF_STATUS_E_INVAL;
+ }
+ qdf_status = sme_stop(handle, HAL_STOP_TYPE_SYS_DEEP_SLEEP);
if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
- QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
- "%s: Failed to stop SYS", __func__);
+ cds_err("Failed to stop SME: %d", qdf_status);
QDF_ASSERT(QDF_IS_STATUS_SUCCESS(qdf_status));
}
+ qdf_status = mac_stop(handle, HAL_STOP_TYPE_SYS_DEEP_SLEEP);
- return QDF_STATUS_SUCCESS;
+ if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
+ cds_err("Failed to stop MAC");
+ QDF_ASSERT(QDF_IS_STATUS_SUCCESS(qdf_status));
+ }
+ return qdf_status;
}
/**
@@ -762,10 +774,9 @@ QDF_STATUS cds_close(v_CONTEXT_t cds_context)
}
cds_deinit_log_completion();
-
- gp_cds_context->pHDDContext = NULL;
-
cds_deinit_ini_config();
+ qdf_timer_module_deinit();
+
return QDF_STATUS_SUCCESS;
}
diff --git a/core/cds/src/cds_concurrency.c b/core/cds/src/cds_concurrency.c
index ad89f6df623f..de14e62b8e56 100644
--- a/core/cds/src/cds_concurrency.c
+++ b/core/cds/src/cds_concurrency.c
@@ -3918,6 +3918,13 @@ QDF_STATUS cds_deinit_policy_mgr(void)
cds_err("Invalid CDS Context");
return QDF_STATUS_E_FAILURE;
}
+
+ if (!QDF_IS_STATUS_SUCCESS(qdf_event_destroy
+ (&cds_ctx->connection_update_done_evt))) {
+ cds_err("Failed to destroy connection_update_done_evt");
+ return QDF_STATUS_E_FAILURE;
+ }
+
if (!QDF_IS_STATUS_SUCCESS(qdf_mutex_destroy(
&cds_ctx->qdf_conc_list_lock))) {
cds_err("Failed to destroy qdf_conc_list_lock");
diff --git a/core/cds/src/cds_sched.c b/core/cds/src/cds_sched.c
index d452b7ede1b2..08cebb9feb53 100644
--- a/core/cds/src/cds_sched.c
+++ b/core/cds/src/cds_sched.c
@@ -1176,6 +1176,7 @@ QDF_STATUS cds_sched_close(void *p_cds_context)
cds_drop_rxpkt_by_staid(gp_cds_sched_context, WLAN_MAX_STA_COUNT);
cds_free_ol_rx_pkt_freeq(gp_cds_sched_context);
unregister_hotcpu_notifier(&cds_cpu_hotplug_notifier);
+ gp_cds_sched_context->cpu_hot_plug_notifier = NULL;
#endif
return QDF_STATUS_SUCCESS;
} /* cds_sched_close() */
diff --git a/core/hdd/inc/wlan_hdd_cfg.h b/core/hdd/inc/wlan_hdd_cfg.h
index 788827a0a760..c8c4ccea759e 100644
--- a/core/hdd/inc/wlan_hdd_cfg.h
+++ b/core/hdd/inc/wlan_hdd_cfg.h
@@ -248,6 +248,16 @@ typedef enum {
#define CFG_ROAM_PREFER_5GHZ_DEFAULT (1)
/*
+ * Timer waiting for interface up from the upper layer. If
+ * this timer expires all the cds modules shall be closed.
+ * Time Units: ms
+ */
+#define CFG_INTERFACE_CHANGE_WAIT_NAME "gInterfaceChangeWait"
+#define CFG_INTERFACE_CHANGE_WAIT_MIN (10)
+#define CFG_INTERFACE_CHANGE_WAIT_MAX (10000)
+#define CFG_INTERFACE_CHANGE_WAIT_DEFAULT (50)
+
+/*
To enable, set gRoamIntraBand=1 (Roaming within band)
To disable, set gRoamIntraBand=0 (Roaming across band)
*/
@@ -4047,6 +4057,7 @@ struct hdd_config {
bool enable_nan_datapath;
uint8_t nan_datapath_ndi_channel;
#endif
+ uint32_t iface_change_wait_time;
};
#define VAR_OFFSET(_Struct, _Var) (offsetof(_Struct, _Var))
diff --git a/core/hdd/inc/wlan_hdd_driver_ops.h b/core/hdd/inc/wlan_hdd_driver_ops.h
index 70e2b7d8f393..3ea44449b55c 100644
--- a/core/hdd/inc/wlan_hdd_driver_ops.h
+++ b/core/hdd/inc/wlan_hdd_driver_ops.h
@@ -28,6 +28,8 @@
#ifndef __WLAN_HDD_DRIVER_OPS_H__
#define __WLAN_HDD_DRIVER_OPS_H__
+#include "hif.h"
+
/**
* DOC: wlan_hdd_driver_ops.h
*
@@ -37,4 +39,7 @@ int wlan_hdd_register_driver(void);
void wlan_hdd_unregister_driver(void);
int wlan_hdd_bus_suspend(pm_message_t state);
int wlan_hdd_bus_resume(void);
+void hdd_hif_close(void *hif_ctx);
+int hdd_hif_open(struct device *dev, void *bdev, const hif_bus_id *bid,
+ enum qdf_bus_type bus_type, bool reinit);
#endif /* __WLAN_HDD_DRIVER_OPS_H__ */
diff --git a/core/hdd/inc/wlan_hdd_ftm.h b/core/hdd/inc/wlan_hdd_ftm.h
index eddce28f6131..878a22e08d53 100644
--- a/core/hdd/inc/wlan_hdd_ftm.h
+++ b/core/hdd/inc/wlan_hdd_ftm.h
@@ -55,15 +55,11 @@ struct wlan_hdd_ftm_status {
enum wlan_hdd_ftm_state ftm_state;
};
-int wlan_hdd_ftm_open(hdd_context_t *hdd_ctx);
-int wlan_hdd_ftm_close(hdd_context_t *hdd_ctx);
int hdd_update_cds_config_ftm(hdd_context_t *hdd_ctx);
-
+void hdd_ftm_mc_process_msg(void *message);
#if defined(QCA_WIFI_FTM)
QDF_STATUS wlan_hdd_ftm_testmode_cmd(void *data, int len);
int wlan_hdd_qcmbr_unified_ioctl(hdd_adapter_t *adapter, struct ifreq *ifr);
-int hdd_ftm_start(hdd_context_t *hdd_ctx);
-int hdd_ftm_stop(hdd_context_t *hdd_ctx);
#endif
#endif
diff --git a/core/hdd/inc/wlan_hdd_main.h b/core/hdd/inc/wlan_hdd_main.h
index cffdf54cb6e4..4fbec9b7dfbc 100644
--- a/core/hdd/inc/wlan_hdd_main.h
+++ b/core/hdd/inc/wlan_hdd_main.h
@@ -1184,6 +1184,20 @@ struct hdd_bpf_context {
struct sir_bpf_get_offload capability_response;
};
+/**
+ * enum driver_status: Driver Modules status
+ * @DRIVER_MODULES_UNINITIALIZED: Driver CDS modules uninitialized
+ * @DRIVER_MODULES_OPENED: Driver CDS modules opened
+ * @DRIVER_MODULES_ENABLED: Driver CDS modules opened
+ * @DRIVER_MODULES_CLOSED: Driver CDS modules closed
+ */
+enum driver_modules_status {
+ DRIVER_MODULES_UNINITIALIZED,
+ DRIVER_MODULES_OPENED,
+ DRIVER_MODULES_ENABLED,
+ DRIVER_MODULES_CLOSED
+};
+
/** Adapter structure definition */
struct hdd_context_s {
@@ -1435,6 +1449,12 @@ struct hdd_context_s {
#ifdef WLAN_FEATURE_NAN_DATAPATH
bool nan_datapath_enabled;
#endif
+ /* Present state of driver cds modules */
+ enum driver_modules_status driver_status;
+ /* MC timer interface change */
+ qdf_mc_timer_t iface_change_timer;
+ /* Interface change lock */
+ struct mutex iface_change_lock;
};
/*---------------------------------------------------------------------------
@@ -1539,7 +1559,7 @@ static inline void hdd_stop_bus_bw_computer_timer(hdd_adapter_t *pAdapter)
int hdd_init(void);
void hdd_deinit(void);
-int hdd_wlan_startup(struct device *dev, void *hif_sc);
+int hdd_wlan_startup(struct device *dev);
void __hdd_wlan_exit(void);
int hdd_wlan_notify_modem_power_state(int state);
#ifdef QCA_HT_2040_COEX
@@ -1746,6 +1766,21 @@ int hdd_register_cb(hdd_context_t *hdd_ctx);
void hdd_deregister_cb(hdd_context_t *hdd_ctx);
int hdd_start_station_adapter(hdd_adapter_t *adapter);
int hdd_start_ap_adapter(hdd_adapter_t *adapter);
+int hdd_configure_cds(hdd_context_t *hdd_ctx, hdd_adapter_t *adapter);
int hdd_start_ftm_adapter(hdd_adapter_t *adapter);
int hdd_set_fw_params(hdd_adapter_t *adapter);
+int hdd_wlan_start_modules(hdd_context_t *hdd_ctx, hdd_adapter_t *adapter,
+ bool reinit);
+int hdd_wlan_stop_modules(hdd_context_t *hdd_ctx, bool shutdown);
+int hdd_start_adapter(hdd_adapter_t *adapter);
+#ifdef WLAN_FEATURE_FASTPATH
+void hdd_enable_fastpath(struct hdd_config *hdd_cfg,
+ void *context);
+#else
+static inline void hdd_enable_fastpath(struct hdd_config *hdd_cfg,
+ void *context)
+{
+}
+#endif
+void hdd_wlan_update_target_info(hdd_context_t *hdd_ctx, void *context);
#endif /* end #if !defined(WLAN_HDD_MAIN_H) */
diff --git a/core/hdd/inc/wlan_hdd_memdump.h b/core/hdd/inc/wlan_hdd_memdump.h
index 2100768ef69b..48a609396bce 100644
--- a/core/hdd/inc/wlan_hdd_memdump.h
+++ b/core/hdd/inc/wlan_hdd_memdump.h
@@ -88,8 +88,11 @@ static inline int wlan_hdd_cfg80211_get_fw_mem_dump(struct wiphy *wiphy,
{
return -ENOTSUPP;
}
+
+
static inline void wlan_hdd_cfg80211_fw_mem_dump_cb(void *ctx,
- struct fw_dump_rsp *dump_rsp)
+ struct fw_dump_rsp
+ *dump_rsp)
{
}
#endif
diff --git a/core/hdd/inc/wlan_hdd_power.h b/core/hdd/inc/wlan_hdd_power.h
index d872fae107ac..a57e9b6eec7f 100644
--- a/core/hdd/inc/wlan_hdd_power.h
+++ b/core/hdd/inc/wlan_hdd_power.h
@@ -145,7 +145,7 @@ enum suspend_resume_state {
/* SSR shutdown & re-init functions */
QDF_STATUS hdd_wlan_shutdown(void);
-QDF_STATUS hdd_wlan_re_init(void *hif_sc);
+QDF_STATUS hdd_wlan_re_init(void);
void hdd_conf_mcastbcast_filter(hdd_context_t *pHddCtx, bool setfilter);
QDF_STATUS hdd_conf_arp_offload(hdd_adapter_t *pAdapter, bool fenable);
diff --git a/core/hdd/src/wlan_hdd_cfg.c b/core/hdd/src/wlan_hdd_cfg.c
index 4647ae303e3a..d214ef603e84 100644
--- a/core/hdd/src/wlan_hdd_cfg.c
+++ b/core/hdd/src/wlan_hdd_cfg.c
@@ -3981,8 +3981,14 @@ REG_TABLE_ENTRY g_registry_table[] = {
CFG_ADAPT_DWELL_WIFI_THRESH_DEFAULT,
CFG_ADAPT_DWELL_WIFI_THRESH_MIN,
CFG_ADAPT_DWELL_WIFI_THRESH_MAX),
-};
+ REG_VARIABLE(CFG_INTERFACE_CHANGE_WAIT_NAME, WLAN_PARAM_Integer,
+ struct hdd_config, iface_change_wait_time,
+ VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK,
+ CFG_INTERFACE_CHANGE_WAIT_DEFAULT,
+ CFG_INTERFACE_CHANGE_WAIT_MIN,
+ CFG_INTERFACE_CHANGE_WAIT_MAX),
+};
/**
* get_next_line() - find and locate the new line pointer
@@ -5583,6 +5589,9 @@ void hdd_cfg_print(hdd_context_t *pHddCtx)
hdd_info("Name = [%s] Value = [%u]",
CFG_IDLE_TIME_NAME,
pHddCtx->config->idle_time_conc);
+ hdd_info("Name = [%s] Value = [%u]",
+ CFG_INTERFACE_CHANGE_WAIT_NAME,
+ pHddCtx->config->iface_change_wait_time);
hdd_info("Name = [%s] Value = [%u]",
CFG_ENABLE_EDCA_INI_NAME,
diff --git a/core/hdd/src/wlan_hdd_cfg80211.c b/core/hdd/src/wlan_hdd_cfg80211.c
index 400fbe4320e4..0c6807b0ddee 100644
--- a/core/hdd/src/wlan_hdd_cfg80211.c
+++ b/core/hdd/src/wlan_hdd_cfg80211.c
@@ -481,16 +481,6 @@ static const struct ieee80211_iface_limit
};
static struct ieee80211_iface_combination
- wlan_hdd_mon_iface[] = {
- {
- .limits = wlan_hdd_mon_iface_limit,
- .max_interfaces = 3,
- .num_different_channels = 2,
- .n_limits = ARRAY_SIZE(wlan_hdd_mon_iface_limit),
- },
-};
-
-static struct ieee80211_iface_combination
wlan_hdd_iface_combination[] = {
/* STA */
{
@@ -567,6 +557,13 @@ static struct ieee80211_iface_combination
.n_limits = ARRAY_SIZE(wlan_hdd_p2p_p2p_iface_limit),
.beacon_int_infra_match = true,
},
+ /* Monitor */
+ {
+ .limits = wlan_hdd_mon_iface_limit,
+ .max_interfaces = 3,
+ .num_different_channels = 2,
+ .n_limits = ARRAY_SIZE(wlan_hdd_mon_iface_limit),
+ },
};
static struct cfg80211_ops wlan_hdd_cfg80211_ops;
@@ -6965,35 +6962,28 @@ int wlan_hdd_cfg80211_init(struct device *dev,
wiphy->max_acl_mac_addrs = MAX_ACL_MAC_ADDRESS;
- if (cds_get_conparam() != QDF_GLOBAL_MONITOR_MODE) {
- /* Supports STATION & AD-HOC modes right now */
- wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION)
- | BIT(NL80211_IFTYPE_ADHOC)
- | BIT(NL80211_IFTYPE_P2P_CLIENT)
- | BIT(NL80211_IFTYPE_P2P_GO)
- | BIT(NL80211_IFTYPE_AP);
-
- if (pCfg->advertiseConcurrentOperation) {
- if (pCfg->enableMCC) {
- int i;
-
- for (i = 0;
- i < ARRAY_SIZE(wlan_hdd_iface_combination);
- i++) {
- if (!pCfg->allowMCCGODiffBI)
- wlan_hdd_iface_combination[i].
- beacon_int_infra_match = true;
- }
+ wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION)
+ | BIT(NL80211_IFTYPE_ADHOC)
+ | BIT(NL80211_IFTYPE_P2P_CLIENT)
+ | BIT(NL80211_IFTYPE_P2P_GO)
+ | BIT(NL80211_IFTYPE_AP)
+ | BIT(NL80211_IFTYPE_MONITOR);
+
+ if (pCfg->advertiseConcurrentOperation) {
+ if (pCfg->enableMCC) {
+ int i;
+
+ for (i = 0;
+ i < ARRAY_SIZE(wlan_hdd_iface_combination);
+ i++) {
+ if (!pCfg->allowMCCGODiffBI)
+ wlan_hdd_iface_combination[i].
+ beacon_int_infra_match = true;
}
- wiphy->n_iface_combinations =
- ARRAY_SIZE(wlan_hdd_iface_combination);
- wiphy->iface_combinations = wlan_hdd_iface_combination;
}
- } else {
- wiphy->interface_modes = BIT(NL80211_IFTYPE_MONITOR);
wiphy->n_iface_combinations =
- ARRAY_SIZE(wlan_hdd_mon_iface);
- wiphy->iface_combinations = wlan_hdd_mon_iface;
+ ARRAY_SIZE(wlan_hdd_iface_combination);
+ wiphy->iface_combinations = wlan_hdd_iface_combination;
}
/* Before registering we need to update the ht capabilitied based
@@ -7648,6 +7638,12 @@ static int __wlan_hdd_cfg80211_change_iface(struct wiphy *wiphy,
hdd_notice("Device_mode = %d, IFTYPE = 0x%x",
pAdapter->device_mode, type);
+ status = hdd_wlan_start_modules(pHddCtx, pAdapter, false);
+ if (status) {
+ hdd_err("Failed to start modules");
+ return -EINVAL;
+ }
+
if (!cds_allow_concurrency(
wlan_hdd_convert_nl_iftype_to_hdd_type(type),
0, HW_MODE_20_MHZ)) {
@@ -7687,15 +7683,6 @@ static int __wlan_hdd_cfg80211_change_iface(struct wiphy *wiphy,
if (vstatus != QDF_STATUS_SUCCESS)
return -EINVAL;
- /*
- * for ibss interface type flow control is not required
- * so don't register tx flow control
- */
- if (type != NL80211_IFTYPE_ADHOC)
- hdd_register_tx_flow_control(pAdapter,
- hdd_tx_resume_timer_expired_handler,
- hdd_tx_resume_cb);
-
goto done;
case NL80211_IFTYPE_AP:
case NL80211_IFTYPE_P2P_GO:
@@ -7710,8 +7697,8 @@ static int __wlan_hdd_cfg80211_change_iface(struct wiphy *wiphy,
wlan_hdd_cancel_existing_remain_on_channel
(pAdapter);
}
- hdd_stop_adapter(pHddCtx, pAdapter, true);
+ hdd_stop_adapter(pHddCtx, pAdapter, true);
/* De-init the adapter */
hdd_deinit_adapter(pHddCtx, pAdapter, true);
memset(&pAdapter->sessionCtx, 0,
@@ -7744,16 +7731,10 @@ static int __wlan_hdd_cfg80211_change_iface(struct wiphy *wiphy,
hdd_set_ap_ops(pAdapter->dev);
- vstatus = hdd_init_ap_mode(pAdapter);
- if (vstatus != QDF_STATUS_SUCCESS) {
- hdd_alert("Error initializing the ap mode");
+ if (hdd_start_adapter(pAdapter)) {
+ hdd_err("Error initializing the ap mode");
return -EINVAL;
}
-
- hdd_register_tx_flow_control(pAdapter,
- hdd_softap_tx_resume_timer_expired_handler,
- hdd_softap_tx_resume_cb);
-
/* Interface type changed update in wiphy structure */
if (wdev) {
wdev->iftype = type;
@@ -7780,13 +7761,6 @@ static int __wlan_hdd_cfg80211_change_iface(struct wiphy *wiphy,
if (status != QDF_STATUS_SUCCESS)
return status;
- if ((NL80211_IFTYPE_P2P_CLIENT == type) ||
- (NL80211_IFTYPE_STATION == type)) {
-
- hdd_register_tx_flow_control(pAdapter,
- hdd_tx_resume_timer_expired_handler,
- hdd_tx_resume_cb);
- }
goto done;
case NL80211_IFTYPE_AP:
@@ -7794,10 +7768,6 @@ static int __wlan_hdd_cfg80211_change_iface(struct wiphy *wiphy,
wdev->iftype = type;
pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
QDF_SAP_MODE : QDF_P2P_GO_MODE;
-
- hdd_register_tx_flow_control(pAdapter,
- hdd_softap_tx_resume_timer_expired_handler,
- hdd_softap_tx_resume_cb);
goto done;
default:
diff --git a/core/hdd/src/wlan_hdd_driver_ops.c b/core/hdd/src/wlan_hdd_driver_ops.c
index e1843e831519..2f9ef28f03fb 100644
--- a/core/hdd/src/wlan_hdd_driver_ops.c
+++ b/core/hdd/src/wlan_hdd_driver_ops.c
@@ -210,7 +210,7 @@ static enum qdf_bus_type to_bus_type(enum pld_bus_type bus_type)
*
* Return: 0 on success and errno on failure.
*/
-static int hdd_hif_open(struct device *dev, void *bdev, const hif_bus_id *bid,
+int hdd_hif_open(struct device *dev, void *bdev, const hif_bus_id *bid,
enum qdf_bus_type bus_type, bool reinit)
{
QDF_STATUS status;
@@ -255,6 +255,8 @@ static int hdd_hif_open(struct device *dev, void *bdev, const hif_bus_id *bid,
}
}
+ hif_enable_power_management(hif_ctx, cds_is_packet_log_enabled());
+
return 0;
err_hif_close:
@@ -269,11 +271,13 @@ err_hif_close:
*
* Helper function to close HIF
*/
-static void hdd_hif_close(void *hif_ctx)
+void hdd_hif_close(void *hif_ctx)
{
if (hif_ctx == NULL)
return;
+ hif_disable_power_management(hif_ctx);
+
hif_disable(hif_ctx, HIF_DISABLE_TYPE_REMOVE);
hdd_napi_destroy(true);
@@ -286,11 +290,13 @@ static void hdd_hif_close(void *hif_ctx)
* hdd_init_qdf_ctx() - API to initialize global QDF Device structure
* @dev: Device Pointer
* @bdev: Bus Device pointer
+ * @bus_type: Underlying bus type
+ * @bid: Bus id passed by platform driver
*
* Return: void
*/
void hdd_init_qdf_ctx(struct device *dev, void *bdev,
- enum qdf_bus_type bus_type)
+ enum qdf_bus_type bus_type, const struct hif_bus_id *bid)
{
qdf_device_t qdf_dev = cds_get_context(QDF_MODULE_ID_QDF_DEVICE);
@@ -302,6 +308,7 @@ void hdd_init_qdf_ctx(struct device *dev, void *bdev,
qdf_dev->dev = dev;
qdf_dev->drv_hdl = bdev;
qdf_dev->bus_type = bus_type;
+ qdf_dev->bid = bid;
}
/**
@@ -320,11 +327,7 @@ void hdd_init_qdf_ctx(struct device *dev, void *bdev,
static int wlan_hdd_probe(struct device *dev, void *bdev, const hif_bus_id *bid,
enum qdf_bus_type bus_type, bool reinit)
{
- void *hif_ctx;
- QDF_STATUS status;
int ret = 0;
- qdf_device_t qdf_dev;
- uint32_t mode = cds_get_conparam();
pr_info("%s: %sprobing driver v%s\n", WLAN_MODULE_NAME,
reinit ? "re-" : "", QWLAN_VERSIONSTR);
@@ -349,42 +352,16 @@ static int wlan_hdd_probe(struct device *dev, void *bdev, const hif_bus_id *bid,
cds_set_load_in_progress(true);
}
- if (QDF_IS_EPPING_ENABLED(mode)) {
- status = epping_open();
- if (status != QDF_STATUS_SUCCESS)
- goto err_hdd_deinit;
- }
-
- hdd_init_qdf_ctx(dev, bdev, bus_type);
-
- ret = hdd_hif_open(dev, bdev, bid, bus_type, reinit);
-
- if (ret)
- goto err_epping_close;
-
- hif_ctx = cds_get_context(QDF_MODULE_ID_HIF);
-
- if (NULL == hif_ctx)
- goto err_epping_close;
-
- qdf_dev = cds_get_context(QDF_MODULE_ID_QDF_DEVICE);
-
- status = ol_cds_init(qdf_dev, hif_ctx);
-
- if (status != QDF_STATUS_SUCCESS) {
- pr_err("%s No Memory to Create BMI Context\n", __func__);
- goto err_hif_close;
- }
+ hdd_init_qdf_ctx(dev, bdev, bus_type, (const struct hif_bus_id *)bid);
if (reinit)
- ret = hdd_wlan_re_init(hif_ctx);
+ ret = hdd_wlan_re_init();
else
- ret = hdd_wlan_startup(dev, hif_ctx);
+ ret = hdd_wlan_startup(dev);
if (ret)
- goto err_bmi_close;
+ goto err_hdd_deinit;
- hif_enable_power_management(hif_ctx, cds_is_packet_log_enabled());
if (reinit) {
cds_set_recovery_in_progress(false);
@@ -398,15 +375,12 @@ static int wlan_hdd_probe(struct device *dev, void *bdev, const hif_bus_id *bid,
return 0;
-err_bmi_close:
- ol_cds_free();
-err_hif_close:
- hdd_hif_close(hif_ctx);
-err_epping_close:
- if (QDF_IS_EPPING_ENABLED(mode))
- epping_close();
+
err_hdd_deinit:
- cds_set_load_in_progress(false);
+ if (reinit)
+ cds_set_recovery_in_progress(false);
+ else
+ cds_set_load_in_progress(false);
hdd_deinit();
out:
hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_INIT);
@@ -431,6 +405,7 @@ static void wlan_hdd_remove(struct device *dev)
{
void *hif_ctx;
+
pr_info("%s: Removing driver v%s\n", WLAN_MODULE_NAME,
QWLAN_VERSIONSTR);
@@ -453,8 +428,6 @@ static void wlan_hdd_remove(struct device *dev)
if (NULL == hif_ctx)
return;
- hif_disable_power_management(hif_ctx);
-
if (QDF_IS_EPPING_ENABLED(cds_get_conparam())) {
epping_disable();
epping_close();
@@ -462,8 +435,6 @@ static void wlan_hdd_remove(struct device *dev)
__hdd_wlan_exit();
}
- ol_cds_free();
- hdd_hif_close(hif_ctx);
hdd_deinit();
pr_info("%s: Driver Removed\n", WLAN_MODULE_NAME);
@@ -495,9 +466,6 @@ static void wlan_hdd_shutdown(void)
hif_disable_isr(hif_ctx);
hdd_wlan_shutdown();
}
-
- ol_cds_free();
- hdd_hif_close(hif_ctx);
}
/**
@@ -549,7 +517,7 @@ void wlan_hdd_notify_handler(int state)
*/
static int __wlan_hdd_bus_suspend(pm_message_t state)
{
- void *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
+ hdd_context_t *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
void *hif_ctx;
int err = wlan_hdd_validate_context(hdd_ctx);
int status;
@@ -564,6 +532,12 @@ static int __wlan_hdd_bus_suspend(pm_message_t state)
err = -EINVAL;
goto done;
}
+
+ if (hdd_ctx->driver_status != DRIVER_MODULES_ENABLED) {
+ hdd_info("Driver Module closed return success");
+ return 0;
+ }
+
err = qdf_status_to_os_return(
ol_txrx_bus_suspend());
if (err)
@@ -627,13 +601,18 @@ int wlan_hdd_bus_suspend(pm_message_t state)
*/
static int __wlan_hdd_bus_resume(void)
{
- void *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
+ hdd_context_t *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
void *hif_ctx;
int status = wlan_hdd_validate_context(hdd_ctx);
if (status)
return status;
+ if (hdd_ctx->driver_status != DRIVER_MODULES_ENABLED) {
+ hdd_info("Driver Module closed return success");
+ return 0;
+ }
+
hif_ctx = cds_get_context(QDF_MODULE_ID_HIF);
if (NULL == hif_ctx)
return -EINVAL;
@@ -682,7 +661,7 @@ int wlan_hdd_bus_resume(void)
*/
static int __wlan_hdd_runtime_suspend(struct device *dev)
{
- void *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
+ hdd_context_t *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
void *hif_ctx = cds_get_context(QDF_MODULE_ID_HIF);
void *txrx_pdev = cds_get_context(QDF_MODULE_ID_TXRX);
void *htc_ctx = cds_get_context(QDF_MODULE_ID_HTC);
diff --git a/core/hdd/src/wlan_hdd_ftm.c b/core/hdd/src/wlan_hdd_ftm.c
index 97a0cd2754d6..a96090e35033 100644
--- a/core/hdd/src/wlan_hdd_ftm.c
+++ b/core/hdd/src/wlan_hdd_ftm.c
@@ -111,32 +111,6 @@ static uint32_t wlan_ftm_postmsg(uint8_t *cmd_ptr, uint16_t cmd_len)
return QDF_STATUS_SUCCESS;
}
-/**
- * wlan_hdd_ftm_update_tgt_cfg() - Update target configuration
- * @context: context registered with WMA
- * @param: target configuration
- *
- * This function is registered with WMA via wma_open(), and is
- * invoked via callback when target parameters are received
- * from firmware.
- *
- * Return: None
- */
-static void wlan_hdd_ftm_update_tgt_cfg(void *context, void *param)
-{
- hdd_context_t *hdd_ctx = (hdd_context_t *) context;
- struct wma_tgt_cfg *cfg = (struct wma_tgt_cfg *)param;
-
- if (!qdf_is_macaddr_zero(&cfg->hw_macaddr)) {
- hdd_update_macaddr(hdd_ctx->config, cfg->hw_macaddr);
- } else {
- hddLog(QDF_TRACE_LEVEL_ERROR,
- "%s: Invalid MAC passed from target, using MAC from ini file"
- MAC_ADDRESS_STR, __func__,
- MAC_ADDR_ARRAY(hdd_ctx->config->intfMacAddr[0].bytes));
- }
-}
-
#ifdef WLAN_FEATURE_LPSS
static inline void hdd_is_lpass_supported(struct cds_config_info *cds_cfg,
hdd_context_t *hdd_ctx)
@@ -180,544 +154,6 @@ int hdd_update_cds_config_ftm(hdd_context_t *hdd_ctx)
return 0;
}
-/**
- * wlan_ftm_cds_open() - Open the CDS Module in FTM mode
- * @p_cds_context: pointer to the global CDS context
- * @hddContextSize: Size of the HDD context to allocate.
- *
- * The wlan_ftm_cds_open() function opens the QDF Scheduler
- * Upon successful initialization:
- * - All CDS submodules should have been initialized
- * - The CDS scheduler should have opened
- * - All the WLAN SW components should have been opened. This includes MAC.
- *
- * Returns:
- * QDF_STATUS_SUCCESS - Scheduler was successfully initialized and
- * is ready to be used.
- * QDF_STATUS_E_RESOURCES - System resources (other than memory)
- * are unavailable to initialize the scheduler
- * QDF_STATUS_E_FAILURE - Failure to initialize the scheduler
- */
-static QDF_STATUS wlan_ftm_cds_open(v_CONTEXT_t p_cds_context,
- uint32_t hddContextSize)
-{
- QDF_STATUS vStatus = QDF_STATUS_SUCCESS;
- int iter = 0;
- tSirRetStatus sirStatus = eSIR_SUCCESS;
- p_cds_contextType gp_cds_context = (p_cds_contextType) p_cds_context;
- struct cds_config_info *cds_cfg;
-#if defined(QCA_WIFI_FTM)
- qdf_device_t qdf_ctx;
- HTC_INIT_INFO htcInfo;
- void *pHifContext = NULL;
- void *pHtcContext = NULL;
- struct ol_context *ol_ctx;
-#endif
- cds_context_type *cds_ctx;
- hdd_context_t *hdd_ctx;
-
- QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_INFO_HIGH,
- "%s: Opening CDS", __func__);
-
- cds_ctx = cds_get_context(QDF_MODULE_ID_QDF);
- if (!cds_ctx) {
- QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
- "%s: Trying to open CDS without a PreOpen", __func__);
- QDF_ASSERT(0);
- return QDF_STATUS_E_FAILURE;
- }
-
- cds_cfg = cds_ctx->cds_cfg;
-
- /* Initialize the probe event */
- if (qdf_event_create(&gp_cds_context->ProbeEvent) != QDF_STATUS_SUCCESS) {
- QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
- "%s: Unable to init probeEvent", __func__);
- QDF_ASSERT(0);
- return QDF_STATUS_E_FAILURE;
- }
-
- if (qdf_event_create(&(gp_cds_context->wmaCompleteEvent)) !=
- QDF_STATUS_SUCCESS) {
- QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
- "%s: Unable to init wmaCompleteEvent", __func__);
- QDF_ASSERT(0);
-
- goto err_probe_event;
- }
-
- /* Initialize the free message queue */
- vStatus = cds_mq_init(&gp_cds_context->freeVosMq);
- if (!QDF_IS_STATUS_SUCCESS(vStatus)) {
-
- /* Critical Error ... Cannot proceed further */
- QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
- "%s: Failed to initialize CDS free message queue %d",
- __func__, vStatus);
- QDF_ASSERT(0);
- goto err_wma_complete_event;
- }
-
- for (iter = 0; iter < CDS_CORE_MAX_MESSAGES; iter++) {
- (gp_cds_context->aMsgWrappers[iter]).pVosMsg =
- &(gp_cds_context->aMsgBuffers[iter]);
- INIT_LIST_HEAD(&gp_cds_context->aMsgWrappers[iter].msgNode);
- cds_mq_put(&gp_cds_context->freeVosMq,
- &(gp_cds_context->aMsgWrappers[iter]));
- }
-
- /* Now Open the CDS Scheduler */
- vStatus = cds_sched_open(gp_cds_context, &gp_cds_context->qdf_sched,
- sizeof(cds_sched_context));
-
- if (!QDF_IS_STATUS_SUCCESS(vStatus)) {
- /* Critical Error ... Cannot proceed further */
- QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
- "%s: Failed to open CDS Scheduler %d", __func__,
- vStatus);
- QDF_ASSERT(0);
- goto err_msg_queue;
- }
-#if defined(QCA_WIFI_FTM)
- /* Initialize BMI and Download firmware */
- pHifContext = cds_get_context(QDF_MODULE_ID_HIF);
- if (!pHifContext) {
- QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_FATAL,
- "%s: failed to get HIF context", __func__);
- goto err_sched_close;
- }
-
- ol_ctx = cds_get_context(QDF_MODULE_ID_BMI);
- if (bmi_download_firmware(ol_ctx)) {
- QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_FATAL,
- "%s: BMI failed to download target", __func__);
- goto err_bmi_close;
- }
-
- htcInfo.pContext = ol_ctx;
- htcInfo.TargetFailure = ol_target_failure;
- htcInfo.TargetSendSuspendComplete = wma_target_suspend_acknowledge;
- qdf_ctx = cds_get_context(QDF_MODULE_ID_QDF_DEVICE);
-
- /* Create HTC */
- gp_cds_context->htc_ctx =
- htc_create(pHifContext, &htcInfo, qdf_ctx, hdd_get_conparam());
- if (!gp_cds_context->htc_ctx) {
- QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_FATAL,
- "%s: Failed to Create HTC", __func__);
- goto err_bmi_close;
- }
-
- if (bmi_done(ol_ctx)) {
- QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_FATAL,
- "%s: Failed to complete BMI phase", __func__);
- goto err_htc_close;
- }
-#endif /* QCA_WIFI_FTM */
-
- hdd_ctx = (hdd_context_t *) (gp_cds_context->pHDDContext);
- if ((NULL == hdd_ctx) || (NULL == hdd_ctx->config)) {
- /* Critical Error ... Cannot proceed further */
- QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
- "%s: Hdd Context is Null", __func__);
- QDF_ASSERT(0);
- goto err_htc_close;
- }
- vStatus = wma_open(gp_cds_context,
- wlan_hdd_ftm_update_tgt_cfg, NULL, cds_cfg);
- if (!QDF_IS_STATUS_SUCCESS(vStatus)) {
- /* Critical Error ... Cannot proceed further */
- QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
- "%s: Failed to open WMA module %d", __func__,
- vStatus);
- QDF_ASSERT(0);
- goto err_htc_close;
- }
-#if defined(QCA_WIFI_FTM)
- hdd_update_config(hdd_ctx);
- pHtcContext = cds_get_context(QDF_MODULE_ID_HTC);
- if (!pHtcContext) {
- QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_FATAL,
- "%s: failed to get HTC context", __func__);
- goto err_wma_close;
- }
- if (htc_wait_target(pHtcContext)) {
- QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_FATAL,
- "%s: Failed to complete BMI phase", __func__);
- goto err_wma_close;
- }
-#endif
-
- /* Now proceed to open the MAC */
- sirStatus =
- mac_open(&(gp_cds_context->pMACContext),
- gp_cds_context->pHDDContext, cds_cfg);
-
- if (eSIR_SUCCESS != sirStatus) {
- /* Critical Error ... Cannot proceed further */
- QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
- "%s: Failed to open MAC %d", __func__, sirStatus);
- QDF_ASSERT(0);
- goto err_wma_close;
- }
-#ifndef QCA_WIFI_FTM
- /* Now proceed to open the SME */
- vStatus = sme_open(gp_cds_context->pMACContext);
- if (!QDF_IS_STATUS_SUCCESS(vStatus)) {
- /* Critical Error ... Cannot proceed further */
- QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
- "%s: Failed to open SME %d", __func__, vStatus);
- goto err_mac_close;
- }
-
- vStatus = sme_init_chan_list(gp_cds_context->pMACContext,
- hdd_ctx->reg.alpha2, hdd_ctx->reg.cc_src);
- if (!QDF_IS_STATUS_SUCCESS(vStatus)) {
- QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
- "%s: Failed to init sme channel list", __func__);
- } else {
- QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_INFO_HIGH,
- "%s: CDS successfully Opened", __func__);
- return QDF_STATUS_SUCCESS;
- }
-#else
- return QDF_STATUS_SUCCESS;
-#endif
-
-#ifndef QCA_WIFI_FTM
-err_mac_close:
-#endif
- mac_close(gp_cds_context->pMACContext);
-
-err_wma_close:
- wma_close(gp_cds_context);
-
-err_htc_close:
-#if defined(QCA_WIFI_FTM)
- if (gp_cds_context->htc_ctx) {
- htc_destroy(gp_cds_context->htc_ctx);
- gp_cds_context->htc_ctx = NULL;
- }
-
-err_bmi_close:
- bmi_cleanup(ol_ctx);
-#endif /* QCA_WIFI_FTM */
-
-err_sched_close:
- cds_sched_close(gp_cds_context);
-err_msg_queue:
- cds_mq_deinit(&gp_cds_context->freeVosMq);
-
-err_wma_complete_event:
- qdf_event_destroy(&gp_cds_context->wmaCompleteEvent);
-
-err_probe_event:
- qdf_event_destroy(&gp_cds_context->ProbeEvent);
-
- return QDF_STATUS_E_FAILURE;
-
-} /* wlan_ftm_cds_open() */
-
-/**
- * wlan_ftm_cds_close() - Close the QDF Module in FTM mode
- * @cds_context: context of cds
- *
- * The wlan_ftm_cds_close() function closes the QDF Module
- *
- * Return: QDF_STATUS_SUCCESS - successfully closed
- */
-static QDF_STATUS wlan_ftm_cds_close(v_CONTEXT_t cds_context)
-{
- QDF_STATUS qdf_status;
- p_cds_contextType gp_cds_context = (p_cds_contextType) cds_context;
-
-#ifndef QCA_WIFI_FTM
- qdf_status = sme_close(((p_cds_contextType) cds_context)->pMACContext);
- if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
- QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
- "%s: Failed to close SME %d", __func__, qdf_status);
- QDF_ASSERT(QDF_IS_STATUS_SUCCESS(qdf_status));
- }
-#endif
-
- qdf_status = mac_close(((p_cds_contextType) cds_context)->pMACContext);
- if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
- QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
- "%s: Failed to close MAC %d", __func__, qdf_status);
- QDF_ASSERT(QDF_IS_STATUS_SUCCESS(qdf_status));
- }
-
- ((p_cds_contextType) cds_context)->pMACContext = NULL;
-
-
- qdf_status = wma_close(cds_context);
- if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
- QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
- "%s: Failed to close WMA %d", __func__, qdf_status);
- QDF_ASSERT(QDF_IS_STATUS_SUCCESS(qdf_status));
- }
-#if defined(QCA_WIFI_FTM)
- if (gp_cds_context->htc_ctx) {
- htc_stop(gp_cds_context->htc_ctx);
- htc_destroy(gp_cds_context->htc_ctx);
- gp_cds_context->htc_ctx = NULL;
- }
- qdf_status = wma_wmi_service_close(cds_context);
- if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
- QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
- "%s: Failed to close wma_wmi_service", __func__);
- QDF_ASSERT(QDF_IS_STATUS_SUCCESS(qdf_status));
- }
-
- hif_disable_isr(gp_cds_context->pHIFContext);
-#endif
-
- cds_mq_deinit(&((p_cds_contextType) cds_context)->freeVosMq);
-
- qdf_status = qdf_event_destroy(&gp_cds_context->ProbeEvent);
- if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
- QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
- "%s: Failed to destroy ProbeEvent %d", __func__,
- qdf_status);
- QDF_ASSERT(QDF_IS_STATUS_SUCCESS(qdf_status));
- }
-
- qdf_status = qdf_event_destroy(&gp_cds_context->wmaCompleteEvent);
- if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
- QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
- "%s: Failed to destroy wmaCompleteEvent %d", __func__,
- qdf_status);
- QDF_ASSERT(QDF_IS_STATUS_SUCCESS(qdf_status));
- }
-
- return QDF_STATUS_SUCCESS;
-}
-
-/**
- * cds_ftm_pre_start() - Pre-start CDS Module in FTM Mode
- * @cds_context: The CDS context
- *
- * The cds_ftm_pre_start() function performs all pre-start activities
- * in FTM mode.
- *
- * Return: QDF_STATUS_SUCCESS if pre-start was successful, an
- * appropriate QDF_STATUS_E_** error code otherwise
- */
-static QDF_STATUS cds_ftm_pre_start(v_CONTEXT_t cds_context)
-{
- QDF_STATUS vStatus = QDF_STATUS_SUCCESS;
- QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
- p_cds_contextType p_cds_context = (p_cds_contextType) cds_context;
-#if defined(QCA_WIFI_FTM)
- p_cds_contextType gp_cds_context =
- cds_get_global_context();
-#endif
-
- QDF_TRACE(QDF_MODULE_ID_SYS, QDF_TRACE_LEVEL_INFO, "cds prestart");
- if (NULL == p_cds_context->pWMAContext) {
- QDF_ASSERT(0);
- QDF_TRACE(QDF_MODULE_ID_SYS, QDF_TRACE_LEVEL_ERROR,
- "%s: WMA NULL context", __func__);
- return QDF_STATUS_E_FAILURE;
- }
-
- /* Reset WMA wait event */
- qdf_event_reset(&p_cds_context->wmaCompleteEvent);
-
- /*call WMA pre start */
- vStatus = wma_pre_start(p_cds_context);
- if (!QDF_IS_STATUS_SUCCESS(vStatus)) {
- QDF_TRACE(QDF_MODULE_ID_SYS, QDF_TRACE_LEVEL_ERROR,
- "Failed to WMA prestart ");
- QDF_ASSERT(0);
- return QDF_STATUS_E_FAILURE;
- }
-
- /* Need to update time out of complete */
- qdf_status = qdf_wait_single_event(&p_cds_context->wmaCompleteEvent,
- HDD_FTM_WMA_PRE_START_TIMEOUT);
- if (qdf_status != QDF_STATUS_SUCCESS) {
- if (qdf_status == QDF_STATUS_E_TIMEOUT) {
- QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
- "%s: Timeout occurred before WMA complete",
- __func__);
- } else {
- QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
- "%s: wma_pre_start reporting other error",
- __func__);
- }
- QDF_ASSERT(0);
- return QDF_STATUS_E_FAILURE;
- }
-#if defined(QCA_WIFI_FTM)
- vStatus = htc_start(gp_cds_context->htc_ctx);
- if (!QDF_IS_STATUS_SUCCESS(vStatus)) {
- QDF_TRACE(QDF_MODULE_ID_SYS, QDF_TRACE_LEVEL_FATAL,
- "Failed to Start HTC");
- QDF_ASSERT(0);
- return QDF_STATUS_E_FAILURE;
- }
- wma_wait_for_ready_event(gp_cds_context->pWMAContext);
-#endif /* QCA_WIFI_FTM */
-
- return QDF_STATUS_SUCCESS;
-}
-
-/**
- * wlan_hdd_ftm_open() - Open HDD in FTM Mode
- * @hdd_ctx: global HDD context
- *
- * The function hdd_wlan_startup calls this function to initialize the
- * FTM specific modules.
- *
- * Return: 0 on success, non-zero on error
- */
-int wlan_hdd_ftm_open(hdd_context_t *hdd_ctx)
-{
- QDF_STATUS vStatus = QDF_STATUS_SUCCESS;
- p_cds_contextType p_cds_context = NULL;
-
- QDF_TRACE(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_INFO_HIGH,
- "%s: Opening CDS", __func__);
-
- p_cds_context = cds_get_global_context();
-
- if (NULL == p_cds_context) {
- QDF_TRACE(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_ERROR,
- "%s: Trying to open CDS without a PreOpen", __func__);
- QDF_ASSERT(0);
- goto err_qdf_status_failure;
- }
-
- vStatus = wlan_ftm_cds_open(p_cds_context, 0);
-
- if (!QDF_IS_STATUS_SUCCESS(vStatus)) {
- hddLog(QDF_TRACE_LEVEL_FATAL, "%s: cds_open failed", __func__);
- goto err_qdf_status_failure;
- }
-
- /*
- * only needed to start WMA, which happens in wlan_hdd_ftm_start()
- */
-
- /* Save the hal context in Adapter */
- hdd_ctx->hHal =
- (tHalHandle) cds_get_context(QDF_MODULE_ID_SME);
-
- if (NULL == hdd_ctx->hHal) {
- hddLog(QDF_TRACE_LEVEL_ERROR, "%s: HAL context is null",
- __func__);
- goto err_ftm_close;
- }
-
- return 0;
-
-err_ftm_close:
- wlan_ftm_cds_close(p_cds_context);
-
-err_qdf_status_failure:
- return -EPERM;
-}
-
-/**
- * hdd_ftm_service_registration() - Register FTM service
- * @hdd_ctx: global HDD context
- *
- * Return: 0 on success, non-zero on failure
- */
-static int hdd_ftm_service_registration(hdd_context_t *hdd_ctx)
-{
- hdd_adapter_t *adapter;
- adapter = hdd_open_adapter(hdd_ctx, QDF_FTM_MODE, "wlan%d",
- wlan_hdd_get_intf_addr(hdd_ctx),
- NET_NAME_UNKNOWN, false);
- if (NULL == adapter) {
- hddLog(QDF_TRACE_LEVEL_ERROR, "%s: hdd_open_adapter failed",
- __func__);
- goto err_adapter_open_failure;
- }
-
- hdd_ctx->ftm.ftm_state = WLAN_FTM_INITIALIZED;
-
- return 0;
-
-err_adapter_open_failure:
-
- return -EPERM;
-}
-
-/**
- * wlan_ftm_stop() - Stop HDD in FTM mode
- * @hdd_ctx: pointer to HDD context
- *
- * This function stops the following modules
- * WMA
- *
- * Return: 0 on success, non-zero on failure
- */
-static int wlan_ftm_stop(hdd_context_t *hdd_ctx)
-{
- if (hdd_ctx->ftm.ftm_state != WLAN_FTM_STARTED) {
- hddLog(LOGP, FL("FTM has not started. No need to stop"));
- return -EPERM;
- }
- wma_stop(hdd_ctx->pcds_context, HAL_STOP_TYPE_RF_KILL);
- return 0;
-}
-
-/**
- * wlan_hdd_ftm_close() - Close HDD in FTM mode
- * @hdd_ctx: pointer to HDD context
- *
- * Return: 0 on success, non-zero on failure
- */
-int wlan_hdd_ftm_close(hdd_context_t *hdd_ctx)
-{
- QDF_STATUS qdf_status;
- v_CONTEXT_t cds_context = hdd_ctx->pcds_context;
-
- hdd_adapter_t *adapter = hdd_get_adapter(hdd_ctx, QDF_FTM_MODE);
- ENTER();
- if (adapter == NULL) {
- QDF_TRACE(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_FATAL,
- "%s:adapter is NULL", __func__);
- return -ENXIO;
- }
-
- if (WLAN_FTM_STARTED == hdd_ctx->ftm.ftm_state) {
- QDF_TRACE(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_FATAL,
- "%s: Ftm has been started. stopping ftm", __func__);
- wlan_ftm_stop(hdd_ctx);
- }
-
- hdd_close_all_adapters(hdd_ctx, false);
-
- qdf_status = cds_sched_close(cds_context);
- if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
- QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
- "%s: Failed to close CDS Scheduler", __func__);
- QDF_ASSERT(QDF_IS_STATUS_SUCCESS(qdf_status));
- }
- /* Close CDS */
- wlan_ftm_cds_close(cds_context);
-
-#if defined(QCA_WIFI_FTM) && defined(LINUX_QCMBR)
- spin_lock_bh(&qcmbr_queue_lock);
- if (!list_empty(&qcmbr_queue_head)) {
- qcmbr_queue_t *msg_buf, *tmp_buf;
- list_for_each_entry_safe(msg_buf, tmp_buf, &qcmbr_queue_head,
- list) {
- list_del(&msg_buf->list);
- kfree(msg_buf);
- }
- }
- spin_unlock_bh(&qcmbr_queue_lock);
-#endif
-
- return 0;
-
-}
-
/**
* hdd_ftm_mc_process_msg() - Process FTM mailbox message
@@ -727,7 +163,7 @@ int wlan_hdd_ftm_close(hdd_context_t *hdd_ctx)
*
* Return: void
*/
-static void hdd_ftm_mc_process_msg(void *message)
+void hdd_ftm_mc_process_msg(void *message)
{
void *data;
uint32_t data_len;
@@ -750,107 +186,6 @@ static void hdd_ftm_mc_process_msg(void *message)
return;
}
-/**
- * wlan_hdd_ftm_start() - Start HDD in FTM mode
- * @hdd_ctx: Global HDD context
- *
- * This function starts the following modules.
- * 1) WMA Start.
- * 2) HTC Start.
- * 3) MAC Start to download the firmware.
- *
- * Return: 0 for success, non zero for failure
- */
-static int wlan_hdd_ftm_start(hdd_context_t *hdd_ctx)
-{
- QDF_STATUS vStatus = QDF_STATUS_SUCCESS;
- p_cds_contextType p_cds_context =
- (p_cds_contextType) (hdd_ctx->pcds_context);
-
- if (WLAN_FTM_STARTED == hdd_ctx->ftm.ftm_state) {
- return 0;
- }
-
- QDF_TRACE(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_INFO,
- "%s: Starting CLD SW", __func__);
-
- /* We support only one instance for now ... */
- if (p_cds_context == NULL) {
- QDF_TRACE(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_ERROR,
- "%s: mismatch in context", __func__);
- goto err_status_failure;
- }
-
- if (p_cds_context->pMACContext == NULL) {
- QDF_TRACE(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_ERROR,
- "%s: MAC NULL context", __func__);
- goto err_status_failure;
- }
-
- /* Vos preStart is calling */
- if (!QDF_IS_STATUS_SUCCESS(cds_ftm_pre_start(hdd_ctx->pcds_context))) {
- hddLog(QDF_TRACE_LEVEL_FATAL, "%s: cds_pre_enable failed",
- __func__);
- goto err_status_failure;
- }
-
- sme_register_ftm_msg_processor(hdd_ctx->hHal, hdd_ftm_mc_process_msg);
-
- vStatus = wma_start(p_cds_context);
- if (vStatus != QDF_STATUS_SUCCESS) {
- QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
- "%s: Failed to start WMA", __func__);
- goto err_status_failure;
- }
-
- QDF_TRACE(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_INFO,
- "%s: MAC correctly started", __func__);
-
- if (hdd_ftm_service_registration(hdd_ctx)) {
- QDF_TRACE(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_ERROR,
- "%s: failed", __func__);
- goto err_ftm_service_reg;
- }
-
- hdd_ctx->ftm.ftm_state = WLAN_FTM_STARTED;
-
- return 0;
-
-err_ftm_service_reg:
- wlan_hdd_ftm_close(hdd_ctx);
-
-err_status_failure:
-
- return -EPERM;
-
-}
-
-#if defined(QCA_WIFI_FTM)
-/**
- * hdd_ftm_start() - Start HDD in FTM mode
- * @hdd_ctx: Global HDD context
- *
- * Return: 0 for success, non zero for failure
- */
-int hdd_ftm_start(hdd_context_t *hdd_ctx)
-{
- return wlan_hdd_ftm_start(hdd_ctx);
-}
-#endif
-
-#if defined(QCA_WIFI_FTM)
-/**
- * hdd_ftm_stop() - Stop HDD in FTM mode
- * @hdd_ctx: Global HDD context
- *
- * Return: 0 for success, non zero for failure
- */
-int hdd_ftm_stop(hdd_context_t *hdd_ctx)
-{
- return wlan_ftm_stop(hdd_ctx);
-}
-#endif
-
#if defined(QCA_WIFI_FTM)
#if defined(LINUX_QCMBR)
/**
diff --git a/core/hdd/src/wlan_hdd_main.c b/core/hdd/src/wlan_hdd_main.c
index c2f2666f95d0..73fc47efc146 100644
--- a/core/hdd/src/wlan_hdd_main.c
+++ b/core/hdd/src/wlan_hdd_main.c
@@ -36,6 +36,7 @@
#include <wlan_hdd_includes.h>
#include <cds_api.h>
#include <cds_sched.h>
+#include <linux/cpu.h>
#ifdef WLAN_FEATURE_LPSS
#include <cds_utils.h>
#endif
@@ -124,6 +125,28 @@
#define MEMORY_DEBUG_STR ""
#endif
+#ifndef MODULE
+static struct gwlan_loader *wlan_loader;
+static ssize_t wlan_boot_cb(struct kobject *kobj,
+ struct kobj_attribute *attr,
+ const char *buf, size_t count);
+struct gwlan_loader {
+ bool loaded_state;
+ struct kobject *boot_wlan_obj;
+ struct attribute_group *attr_group;
+};
+
+static struct kobj_attribute wlan_boot_attribute =
+ __ATTR(boot_wlan, 0220, NULL, wlan_boot_cb);
+
+static struct attribute *attrs[] = {
+ &wlan_boot_attribute.attr,
+ NULL,
+};
+
+#define MODULE_INITIALIZED 1
+#endif
+
/* the Android framework expects this param even though we don't use it */
#define BUF_LEN 20
static char fwpath_buffer[BUF_LEN];
@@ -136,10 +159,6 @@ static char *country_code;
static int enable_11d = -1;
static int enable_dfs_chan_scan = -1;
-#ifndef MODULE
-static int wlan_hdd_inited;
-#endif
-
/*
* spinlock for synchronizing asynchronous request/response
* (full description of use in wlan_hdd_main.h)
@@ -1526,6 +1545,208 @@ int hdd_mon_open(struct net_device *dev)
}
/**
+ * hdd_start_adapter() - Wrapper function for device specific adapter
+ * @adapter: pointer to HDD adapter
+ *
+ * This function is called to start the device specific adapter for
+ * the mode passed in the adapter's device_mode.
+ *
+ * Return: 0 for success; non-zero for failure
+ */
+int hdd_start_adapter(hdd_adapter_t *adapter)
+{
+
+ int ret;
+ enum tQDF_ADAPTER_MODE device_mode = adapter->device_mode;
+
+ ENTER_DEV(adapter->dev);
+ hdd_info("Start_adapter for mode : %d", adapter->device_mode);
+
+ switch (device_mode) {
+ case QDF_P2P_CLIENT_MODE:
+ case QDF_P2P_DEVICE_MODE:
+ case QDF_OCB_MODE:
+ case QDF_STA_MODE:
+ case QDF_MONITOR_MODE:
+ ret = hdd_start_station_adapter(adapter);
+ if (ret)
+ goto err_start_adapter;
+ break;
+ case QDF_P2P_GO_MODE:
+ case QDF_SAP_MODE:
+ ret = hdd_start_ap_adapter(adapter);
+ if (ret)
+ goto err_start_adapter;
+ break;
+ case QDF_FTM_MODE:
+ ret = hdd_start_ftm_adapter(adapter);
+ if (ret)
+ goto err_start_adapter;
+ break;
+ default:
+ hdd_err("Invalid session type %d", device_mode);
+ QDF_ASSERT(0);
+ goto err_start_adapter;
+ }
+ if (hdd_set_fw_params(adapter))
+ hdd_err("Failed to set the FW params for the adapter!");
+
+ /*
+ * Action frame registered in one adapter which will
+ * applicable to all interfaces
+ */
+ wlan_hdd_cfg80211_register_frames(adapter);
+ EXIT();
+ return 0;
+err_start_adapter:
+ return -EINVAL;
+}
+
+/**
+ * hdd_wlan_start_modules() - Single driver state machine for starting modules
+ * @hdd_ctx: HDD context
+ * @adapter: HDD adapter
+ * @reinit: flag to indicate from SSR or normal path
+ *
+ * This function maintains the driver state machine it will be invoked from
+ * startup, reinit and change interface. Depending on the driver state shall
+ * perform the opening of the modules.
+ *
+ * Return: 0 for success; non-zero for failure
+ */
+int hdd_wlan_start_modules(hdd_context_t *hdd_ctx, hdd_adapter_t *adapter,
+ bool reinit)
+{
+ int ret;
+ qdf_device_t qdf_dev;
+ QDF_STATUS status;
+ p_cds_contextType p_cds_context;
+ bool unint = false;
+ void *hif_ctx;
+
+ ENTER();
+
+ p_cds_context = cds_get_global_context();
+ if (!p_cds_context) {
+ hdd_err("Global Context is NULL");
+ QDF_ASSERT(0);
+ return -EINVAL;
+ }
+
+ hdd_info("start modules called in state! :%d reinit: %d",
+ hdd_ctx->driver_status, reinit);
+
+ qdf_dev = cds_get_context(QDF_MODULE_ID_QDF_DEVICE);
+ if (!qdf_dev) {
+ hdd_err("QDF Device Context is Invalid return");
+ return -EINVAL;
+ }
+
+ mutex_lock(&hdd_ctx->iface_change_lock);
+
+ if (QDF_TIMER_STATE_RUNNING ==
+ qdf_mc_timer_get_current_state(&hdd_ctx->iface_change_timer)) {
+
+ hdd_set_idle_ps_config(hdd_ctx, false);
+ hdd_info("Interface change Timer running Stop timer");
+ qdf_mc_timer_stop(&hdd_ctx->iface_change_timer);
+ }
+
+ switch (hdd_ctx->driver_status) {
+ case DRIVER_MODULES_UNINITIALIZED:
+ unint = true;
+ /* Fall through dont add break here */
+ case DRIVER_MODULES_CLOSED:
+ if (!reinit && !unint) {
+ ret = pld_power_on(qdf_dev->dev);
+ if (ret) {
+ hdd_err("Failed to Powerup the device: %d", ret);
+ goto release_lock;
+ }
+ }
+ ret = hdd_hif_open(qdf_dev->dev, qdf_dev->drv_hdl, qdf_dev->bid,
+ qdf_dev->bus_type,
+ (reinit == true) ? HIF_ENABLE_TYPE_REINIT :
+ HIF_ENABLE_TYPE_PROBE);
+ if (ret) {
+ hdd_err("Failed to open hif: %d", ret);
+ goto power_down;
+ }
+
+ hif_ctx = cds_get_context(QDF_MODULE_ID_HIF);
+ status = ol_cds_init(qdf_dev, hif_ctx);
+ if (status != QDF_STATUS_SUCCESS) {
+ hdd_err("No Memory to Create BMI Context :%d", status);
+ goto hif_close;
+ }
+
+ status = cds_open();
+ if (!QDF_IS_STATUS_SUCCESS(status)) {
+ hdd_err("Failed to Open CDS: %d", status);
+ goto ol_cds_free;
+ }
+
+ hdd_ctx->driver_status = DRIVER_MODULES_OPENED;
+
+ hdd_ctx->hHal = cds_get_context(QDF_MODULE_ID_SME);
+
+ status = cds_pre_enable(hdd_ctx->pcds_context);
+ if (!QDF_IS_STATUS_SUCCESS(status)) {
+ hdd_err("Failed to pre-enable CDS: %d", status);
+ goto close;
+ }
+
+ if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
+ sme_register_ftm_msg_processor(hdd_ctx->hHal,
+ hdd_ftm_mc_process_msg);
+ break;
+ }
+ if (unint) {
+ hdd_info("In phase-1 initialization don't enable modules");
+ break;
+ }
+ /* Fall through dont add break here */
+ case DRIVER_MODULES_OPENED:
+ if (!adapter) {
+ hdd_alert("adapter is Null");
+ goto close;
+ }
+ if (hdd_configure_cds(hdd_ctx, adapter)) {
+ hdd_err("Failed to Enable cds modules");
+ goto close;
+ }
+ hdd_info("Driver Modules Successfully Enabled");
+ hdd_ctx->driver_status = DRIVER_MODULES_ENABLED;
+ break;
+ case DRIVER_MODULES_ENABLED:
+ hdd_info("Driver modules already Enabled");
+ break;
+ default:
+ hdd_err("WLAN start invoked in wrong state! :%d\n",
+ hdd_ctx->driver_status);
+ goto release_lock;
+ }
+ mutex_unlock(&hdd_ctx->iface_change_lock);
+ EXIT();
+ return 0;
+
+close:
+ cds_close(p_cds_context);
+
+ol_cds_free:
+ ol_cds_free();
+
+hif_close:
+ hdd_hif_close(p_cds_context->pHIFContext);
+power_down:
+ if (!reinit && !unint)
+ pld_power_off(qdf_dev->dev);
+release_lock:
+ mutex_unlock(&hdd_ctx->iface_change_lock);
+ return -EINVAL;
+}
+
+/**
* __hdd_open() - HDD Open function
* @dev: Pointer to net_device structure
*
@@ -1542,25 +1763,42 @@ static int __hdd_open(struct net_device *dev)
ENTER_DEV(dev);
MTRACE(qdf_trace(QDF_MODULE_ID_HDD, TRACE_CODE_HDD_OPEN_REQUEST,
- adapter->sessionId, adapter->device_mode));
+ adapter->sessionId, adapter->device_mode));
ret = wlan_hdd_validate_context(hdd_ctx);
if (ret)
return ret;
+ ret = hdd_wlan_start_modules(hdd_ctx, adapter, false);
+ if (ret) {
+ hdd_err("Failed to start WLAN modules return");
+ return -ret;
+ }
+
+
+ if (!test_bit(SME_SESSION_OPENED, &adapter->event_flags)) {
+ ret = hdd_start_adapter(adapter);
+ if (ret) {
+ hdd_err("Failed to start adapter :%d",
+ adapter->device_mode);
+ return ret;
+ }
+ }
+
set_bit(DEVICE_IFACE_OPENED, &adapter->event_flags);
if (hdd_conn_is_connected(WLAN_HDD_GET_STATION_CTX_PTR(adapter))) {
- hddLog(LOG1, FL("Enabling Tx Queues"));
+ hdd_info("Enabling Tx Queues");
/* Enable TX queues only when we are connected */
wlan_hdd_netif_queue_control(adapter,
- WLAN_START_ALL_NETIF_QUEUE,
- WLAN_CONTROL_PATH);
+ WLAN_START_ALL_NETIF_QUEUE,
+ WLAN_CONTROL_PATH);
}
return ret;
}
+
/**
* hdd_open() - Wrapper function for __hdd_open to protect it from SSR
* @dev: Pointer to net_device structure
@@ -1592,7 +1830,10 @@ static int __hdd_stop(struct net_device *dev)
{
hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+ hdd_adapter_list_node_t *adapternode = NULL, *next = NULL;
int ret;
+ bool close_modules = true;
+ QDF_STATUS status;
ENTER_DEV(dev);
@@ -1632,11 +1873,36 @@ static int __hdd_stop(struct net_device *dev)
* Notice that the hdd_stop_adapter is requested not to close the session
* That is intentional to be able to scan if it is a STA/P2P interface
*/
- hdd_stop_adapter(hdd_ctx, adapter, false);
+ hdd_stop_adapter(hdd_ctx, adapter, true);
/* DeInit the adapter. This ensures datapath cleanup as well */
hdd_deinit_adapter(hdd_ctx, adapter, true);
+
+ /*
+ * Find if any iface is up. If any iface is up then can't put device to
+ * sleep/power save mode
+ */
+ status = hdd_get_front_adapter(hdd_ctx, &adapternode);
+ while ((NULL != adapternode) && (QDF_STATUS_SUCCESS == status)) {
+ if (test_bit(DEVICE_IFACE_OPENED,
+ &adapternode->pAdapter->event_flags)) {
+ hdd_info("Still other ifaces are up cannot close modules");
+ close_modules = false;
+ break;
+ }
+ status = hdd_get_next_adapter(hdd_ctx, adapternode, &next);
+ adapternode = next;
+
+ }
+
+ if (close_modules) {
+ hdd_info("Closing all modules from the hdd_stop");
+ qdf_mc_timer_start(&hdd_ctx->iface_change_timer,
+ hdd_ctx->config->iface_change_wait_time
+ * 50000);
+ }
+
EXIT();
return 0;
}
@@ -2537,30 +2803,32 @@ static void hdd_set_fw_log_params(hdd_context_t *hdd_ctx,
uint32_t value = 0;
int ret;
- /* Enable FW logs based on INI configuration */
- if ((QDF_GLOBAL_FTM_MODE == cds_get_conparam() ||
- (!hdd_ctx->config->enable_fw_log))) {
+ if (QDF_GLOBAL_FTM_MODE == cds_get_conparam() ||
+ (!hdd_ctx->config->enable_fw_log)) {
hdd_info("enable_fw_log not enabled in INI or in FTM mode return");
return;
}
+ /* Enable FW logs based on INI configuration */
hdd_ctx->fw_log_settings.dl_type =
hdd_ctx->config->enableFwLogType;
ret = wma_cli_set_command(adapter->sessionId,
- WMI_DBGLOG_TYPE,
- hdd_ctx->config->enableFwLogType,
- DBG_CMD);
- if (ret)
- hdd_err("Failed to enable FW log type ret %d", ret);
+ WMI_DBGLOG_TYPE,
+ hdd_ctx->config->enableFwLogType,
+ DBG_CMD);
+ if (ret != 0)
+ hdd_err("Failed to enable FW log type ret %d",
+ ret);
hdd_ctx->fw_log_settings.dl_loglevel =
- hdd_ctx->config->enableFwLogLevel;
+ hdd_ctx->config->enableFwLogLevel;
ret = wma_cli_set_command(adapter->sessionId,
- WMI_DBGLOG_LOG_LEVEL,
- hdd_ctx->config->enableFwLogLevel,
- DBG_CMD);
- if (ret)
- hdd_err("Failed to enable FW log level ret %d", ret);
+ WMI_DBGLOG_LOG_LEVEL,
+ hdd_ctx->config->enableFwLogLevel,
+ DBG_CMD);
+ if (ret != 0)
+ hdd_err("Failed to enable FW log level ret %d",
+ ret);
hdd_string_to_u8_array(
hdd_ctx->config->enableFwModuleLogLevel,
@@ -2587,21 +2855,21 @@ static void hdd_set_fw_log_params(hdd_context_t *hdd_ctx,
* For FW module ID 7 enable log level 6
*/
- /*
- * FW expects WMI command value =
+ /* FW expects WMI command value =
* Module ID * 10 + Module Log level
*/
value = ((moduleloglevel[count] * 10) +
moduleloglevel[count + 1]);
ret = wma_cli_set_command(adapter->sessionId,
- WMI_DBGLOG_MOD_LOG_LEVEL,
- value, DBG_CMD);
- if (ret)
+ WMI_DBGLOG_MOD_LOG_LEVEL,
+ value, DBG_CMD);
+ if (ret != 0)
hdd_err("Failed to enable FW module log level %d ret %d",
value, ret);
count += 2;
}
+
}
#else
static void hdd_set_fw_log_params(hdd_context_t *hdd_ctx,
@@ -2631,12 +2899,11 @@ int hdd_set_fw_params(hdd_adapter_t *adapter)
if (!hdd_ctx)
return -EINVAL;
- if ((QDF_GLOBAL_FTM_MODE == cds_get_conparam() ||
- (!hdd_ctx->config->enable2x2))) {
+ if ((cds_get_conparam() != QDF_GLOBAL_FTM_MODE) ||
+ (!hdd_ctx->config->enable2x2)) {
hdd_info("enable2x2 not enabled in INI or in FTM mode return");
return 0;
}
-
#define HDD_DTIM_1CHAIN_RX_ID 0x5
#define HDD_SMPS_PARAM_VALUE_S 29
@@ -2677,22 +2944,24 @@ int hdd_set_fw_params(hdd_adapter_t *adapter)
}
#undef HDD_DTIM_1CHAIN_RX_ID
#undef HDD_SMPS_PARAM_VALUE_S
-
- ret = wma_cli_set_command(adapter->sessionId,
- WMI_PDEV_PARAM_HYST_EN,
- hdd_ctx->config->enableMemDeepSleep,
- PDEV_CMD);
-
- if (ret != 0) {
- hdd_err("WMI_PDEV_PARAM_HYST_EN set failed %d",
- ret);
- goto error;
+ if (QDF_GLOBAL_FTM_MODE != cds_get_conparam()) {
+ ret = wma_cli_set_command(adapter->sessionId,
+ WMI_PDEV_PARAM_HYST_EN,
+ hdd_ctx->config->enableMemDeepSleep,
+ PDEV_CMD);
+
+ if (ret) {
+ hdd_err("WMI_PDEV_PARAM_HYST_EN set failed %d",
+ ret);
+ goto error;
+ }
}
hdd_set_fw_log_params(hdd_ctx, adapter);
EXIT();
return 0;
+
error:
return -EINVAL;
}
@@ -2721,37 +2990,29 @@ hdd_adapter_t *hdd_open_adapter(hdd_context_t *hdd_ctx, uint8_t session_type,
hdd_adapter_list_node_t *pHddAdapterNode = NULL;
QDF_STATUS status = QDF_STATUS_E_FAILURE;
hdd_cfg80211_state_t *cfgState;
- int ret;
- hddLog(LOG2, FL("iface(%s) type(%d)"), iface_name, session_type);
+ hdd_info("iface(%s) type(%d)", iface_name, session_type);
if (hdd_ctx->current_intf_count >= hdd_ctx->max_intf_count) {
/*
* Max limit reached on the number of vdevs configured by the
* host. Return error
*/
- hddLog(QDF_TRACE_LEVEL_ERROR,
- FL(
- "Unable to add virtual intf: currentVdevCnt=%d,hostConfiguredVdevCnt=%d"
- ),
- hdd_ctx->current_intf_count, hdd_ctx->max_intf_count);
+ hdd_err("Unable to add virtual intf: currentVdevCnt=%d,hostConfiguredVdevCnt=%d",
+ hdd_ctx->current_intf_count, hdd_ctx->max_intf_count);
return NULL;
}
if (macAddr == NULL) {
/* Not received valid macAddr */
- hddLog(QDF_TRACE_LEVEL_ERROR,
- FL(
- "Unable to add virtual intf: Not able to get valid mac address"
- ));
+ hdd_err("Unable to add virtual intf: Not able to get valid mac address");
return NULL;
}
status = hdd_check_for_existing_macaddr(hdd_ctx, macAddr);
if (QDF_STATUS_E_FAILURE == status) {
- hddLog(QDF_TRACE_LEVEL_ERROR,
- "Duplicate MAC addr: " MAC_ADDRESS_STR
- " already exists",
- MAC_ADDR_ARRAY(macAddr));
+ hdd_err("Duplicate MAC addr: " MAC_ADDRESS_STR
+ " already exists",
+ MAC_ADDR_ARRAY(macAddr));
return NULL;
}
@@ -2763,17 +3024,14 @@ hdd_adapter_t *hdd_open_adapter(hdd_context_t *hdd_ctx, uint8_t session_type,
case QDF_P2P_CLIENT_MODE:
case QDF_P2P_DEVICE_MODE:
case QDF_OCB_MODE:
- case QDF_MONITOR_MODE:
case QDF_NDI_MODE:
- {
adapter = hdd_alloc_station_adapter(hdd_ctx, macAddr,
name_assign_type,
iface_name);
if (NULL == adapter) {
- hddLog(QDF_TRACE_LEVEL_FATAL,
- FL("failed to allocate adapter for session %d"),
- session_type);
+ hdd_err("failed to allocate adapter for session %d",
+ session_type);
return NULL;
}
@@ -2781,8 +3039,6 @@ hdd_adapter_t *hdd_open_adapter(hdd_context_t *hdd_ctx, uint8_t session_type,
adapter->wdev.iftype = NL80211_IFTYPE_P2P_CLIENT;
else if (QDF_P2P_DEVICE_MODE == session_type)
adapter->wdev.iftype = NL80211_IFTYPE_P2P_DEVICE;
- else if (QDF_MONITOR_MODE == session_type)
- adapter->wdev.iftype = NL80211_IFTYPE_MONITOR;
else
adapter->wdev.iftype = NL80211_IFTYPE_STATION;
@@ -2792,10 +3048,6 @@ hdd_adapter_t *hdd_open_adapter(hdd_context_t *hdd_ctx, uint8_t session_type,
status = hdd_init_nan_data_mode(adapter);
if (QDF_STATUS_SUCCESS != status)
goto err_free_netdev;
- } else {
- ret = hdd_start_station_adapter(adapter);
- if (ret)
- goto err_free_netdev;
}
hdd_lro_enable(hdd_ctx, adapter);
@@ -2822,28 +3074,21 @@ hdd_adapter_t *hdd_open_adapter(hdd_context_t *hdd_ctx, uint8_t session_type,
}
/* Stop the Interface TX queue. */
- hddLog(LOG1, FL("Disabling queues"));
+ hdd_info("Disabling queues");
wlan_hdd_netif_queue_control(adapter,
- WLAN_NETIF_TX_DISABLE_N_CARRIER,
- WLAN_CONTROL_PATH);
-
- hdd_register_tx_flow_control(adapter,
- hdd_tx_resume_timer_expired_handler,
- hdd_tx_resume_cb);
-
+ WLAN_NETIF_TX_DISABLE_N_CARRIER,
+ WLAN_CONTROL_PATH);
break;
- }
+
case QDF_P2P_GO_MODE:
case QDF_SAP_MODE:
- {
adapter = hdd_wlan_create_ap_dev(hdd_ctx, macAddr,
name_assign_type,
(uint8_t *) iface_name);
if (NULL == adapter) {
- hddLog(QDF_TRACE_LEVEL_FATAL,
- FL("failed to allocate adapter for session %d"),
- session_type);
+ hdd_alert("failed to allocate adapter for session %d",
+ session_type);
return NULL;
}
@@ -2853,64 +3098,21 @@ hdd_adapter_t *hdd_open_adapter(hdd_context_t *hdd_ctx, uint8_t session_type,
NL80211_IFTYPE_P2P_GO;
adapter->device_mode = session_type;
- ret = hdd_start_ap_adapter(adapter);
- if (ret)
- goto err_free_netdev;
-
status = hdd_register_hostapd(adapter, rtnl_held);
if (QDF_STATUS_SUCCESS != status) {
hdd_deinit_adapter(hdd_ctx, adapter, rtnl_held);
goto err_free_netdev;
}
-
- hddLog(LOG1, FL("Disabling queues"));
+ hdd_info("Disabling queues");
wlan_hdd_netif_queue_control(adapter,
- WLAN_NETIF_TX_DISABLE_N_CARRIER,
- WLAN_CONTROL_PATH);
-
+ WLAN_NETIF_TX_DISABLE_N_CARRIER,
+ WLAN_CONTROL_PATH);
break;
- }
- case QDF_FTM_MODE:
- {
- adapter = hdd_alloc_station_adapter(hdd_ctx, macAddr,
- name_assign_type,
- iface_name);
-
- if (NULL == adapter) {
- hddLog(QDF_TRACE_LEVEL_FATAL,
- FL("failed to allocate adapter for session %d"),
- session_type);
- return NULL;
- }
-
- /*
- * Assign NL80211_IFTYPE_STATION as interface type to resolve
- * Kernel Warning message while loading driver in FTM mode.
- */
- adapter->wdev.iftype = NL80211_IFTYPE_STATION;
- adapter->device_mode = session_type;
- status = hdd_register_interface(adapter, rtnl_held);
-
- ret = hdd_start_ftm_adapter(adapter);
- if (ret)
- goto err_free_netdev;
-
- /* Stop the Interface TX queue. */
- hddLog(LOG1, FL("Disabling queues"));
- wlan_hdd_netif_queue_control(adapter,
- WLAN_NETIF_TX_DISABLE_N_CARRIER,
- WLAN_CONTROL_PATH);
- }
- break;
default:
- {
- hddLog(QDF_TRACE_LEVEL_FATAL,
- FL("Invalid session type %d"),
- session_type);
+ hdd_alert("Invalid session type %d", session_type);
QDF_ASSERT(0);
return NULL;
}
- }
cfgState = WLAN_HDD_GET_CFG_STATE_PTR(adapter);
mutex_init(&cfgState->remain_on_chan_ctx_lock);
@@ -2957,11 +3159,6 @@ hdd_adapter_t *hdd_open_adapter(hdd_context_t *hdd_ctx, uint8_t session_type,
cds_check_and_restart_sap_with_non_dfs_acs();
}
- if (hdd_set_fw_params(adapter)) {
- hdd_err("Failed to set the fw parameters");
- goto err_lro_cleanup;
- }
-
if (QDF_STATUS_SUCCESS != hdd_debugfs_init(adapter))
hdd_err("Interface %s wow debug_fs init failed", iface_name);
@@ -3386,6 +3583,23 @@ QDF_STATUS hdd_reset_all_adapters(hdd_context_t *hdd_ctx)
return QDF_STATUS_SUCCESS;
}
+/**
+ * hdd_is_interface_up()- Checkfor interface up before ssr
+ * @hdd_ctx: HDD context
+ *
+ * check if there are any wlan interfaces before SSR accordingly start
+ * the interface.
+ *
+ * Return: 0 if interface was opened else false
+ */
+static bool hdd_is_interface_up(hdd_adapter_t *adapter)
+{
+ if (test_bit(DEVICE_IFACE_OPENED, &adapter->event_flags))
+ return true;
+ else
+ return false;
+}
+
QDF_STATUS hdd_start_all_adapters(hdd_context_t *hdd_ctx)
{
hdd_adapter_list_node_t *adapterNode = NULL, *pNext = NULL;
@@ -3399,10 +3613,12 @@ QDF_STATUS hdd_start_all_adapters(hdd_context_t *hdd_ctx)
ENTER();
status = hdd_get_front_adapter(hdd_ctx, &adapterNode);
-
while (NULL != adapterNode && QDF_STATUS_SUCCESS == status) {
adapter = adapterNode->pAdapter;
+ if (!hdd_is_interface_up(adapter))
+ continue;
+
hdd_wmm_init(adapter);
switch (adapter->device_mode) {
@@ -3867,85 +4083,6 @@ static int hdd_wlan_register_ip6_notifier(hdd_context_t *hdd_ctx)
}
#endif
-#ifdef QCA_WIFI_FTM
-/**
- * hdd_disable_ftm() - Disable FTM mode
- * @hdd_ctx: HDD context
- *
- * Helper function to disable FTM mode.
- *
- * Return: None.
- */
-static void hdd_disable_ftm(hdd_context_t *hdd_ctx)
-{
- hdd_notice("Disabling FTM mode");
-
- if (hdd_ftm_stop(hdd_ctx)) {
- hdd_alert("hdd_ftm_stop Failed!");
- QDF_ASSERT(0);
- }
-
- hdd_ctx->ftm.ftm_state = WLAN_FTM_STOPPED;
-
- wlan_hdd_ftm_close(hdd_ctx);
-
- return;
-}
-
-/**
- * hdd_enable_ftm() - Enable FTM mode
- * @hdd_ctx: HDD context
- *
- * Helper function to enable FTM mode.
- *
- * Return: 0 on success and errno on failure.
- */
-int hdd_enable_ftm(hdd_context_t *hdd_ctx)
-{
- int ret;
-
- ret = wlan_hdd_ftm_open(hdd_ctx);
- if (ret) {
- hdd_alert("wlan_hdd_ftm_open Failed: %d", ret);
- goto err_out;
- }
-
- ret = hdd_ftm_start(hdd_ctx);
-
- if (ret) {
- hdd_alert("hdd_ftm_start Failed: %d", ret);
- goto err_ftm_close;
- }
-
- ret = wiphy_register(hdd_ctx->wiphy);
- if (ret) {
- hdd_alert("wiphy register failed: %d", ret);
- goto err_ftm_stop;
- }
-
- hdd_err("FTM driver loaded");
-
- return 0;
-
-err_ftm_stop:
- hdd_ftm_stop(hdd_ctx);
-err_ftm_close:
- wlan_hdd_ftm_close(hdd_ctx);
-err_out:
- return ret;
-
-}
-#else
-int hdd_enable_ftm(hdd_context_t *hdd_ctx)
-{
- hdd_err("Driver built without FTM feature enabled!");
-
- return -ENOTSUPP;
-}
-
-static inline void hdd_disable_ftm(hdd_context_t *hdd_ctx) { }
-#endif
-
#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
/**
* hdd_logging_sock_activate_svc() - Activate logging
@@ -4232,39 +4369,23 @@ void hdd_wlan_exit(hdd_context_t *hdd_ctx)
v_CONTEXT_t p_cds_context = hdd_ctx->pcds_context;
QDF_STATUS qdf_status;
struct wiphy *wiphy = hdd_ctx->wiphy;
+ int driver_status;
ENTER();
- hdd_unregister_wext_all_adapters(hdd_ctx);
-
- hdd_exit_netlink_services(hdd_ctx);
+ if (QDF_TIMER_STATE_RUNNING ==
+ qdf_mc_timer_get_current_state(&hdd_ctx->iface_change_timer)) {
+ hdd_info("Stpp interface change timer");
+ qdf_mc_timer_stop(&hdd_ctx->iface_change_timer);
+ }
- if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
- hdd_disable_ftm(hdd_ctx);
+ if (!QDF_IS_STATUS_SUCCESS
+ (qdf_mc_timer_destroy(&hdd_ctx->iface_change_timer)))
+ hdd_err("Cannot delete interface change timer");
- hdd_alert("FTM driver unloaded");
- goto free_hdd_ctx;
- }
hdd_unregister_notifiers(hdd_ctx);
- /*
- * Cancel any outstanding scan requests. We are about to close all
- * of our adapters, but an adapter structure is what SME passes back
- * to our callback function. Hence if there are any outstanding scan
- * requests then there is a race condition between when the adapter
- * is closed and when the callback is invoked. We try to resolve that
- * race condition here by canceling any outstanding scans before we
- * close the adapters.
- * Note that the scans may be cancelled in an asynchronous manner, so
- * ideally there needs to be some kind of synchronization. Rather than
- * introduce a new synchronization here, we will utilize the fact that
- * we are about to Request Full Power, and since that is synchronized,
- * the expectation is that by the time Request Full Power has completed,
- * all scans will be cancelled
- */
- hdd_abort_mac_scan_all_adapters(hdd_ctx);
-
#ifdef MSM_PLATFORM
if (QDF_TIMER_STATE_RUNNING ==
qdf_mc_timer_get_current_state(&hdd_ctx->bus_bw_timer)) {
@@ -4291,33 +4412,40 @@ void hdd_wlan_exit(hdd_context_t *hdd_ctx)
}
#endif
+ mutex_lock(&hdd_ctx->iface_change_lock);
+ driver_status = hdd_ctx->driver_status;
+ mutex_unlock(&hdd_ctx->iface_change_lock);
+
/*
* Powersave Offload Case
* Disable Idle Power Save Mode
*/
hdd_set_idle_ps_config(hdd_ctx, false);
- /* Unregister the Net Device Notifier */
- unregister_netdevice_notifier(&hdd_netdev_notifier);
-
- /*
- * Stop all adapters, this will ensure the termination of active
- * connections on the interface. Make sure the cds_scheduler is
- * still available to handle those control messages
- */
- hdd_stop_all_adapters(hdd_ctx);
-
- /* De-register the SME callbacks */
- hdd_deregister_cb(hdd_ctx);
-
- /* Stop all the modules */
- qdf_status = cds_disable(p_cds_context);
- if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
- hddLog(QDF_TRACE_LEVEL_FATAL,
- FL("Failed to stop CDS"));
- QDF_ASSERT(QDF_IS_STATUS_SUCCESS(qdf_status));
+ if (driver_status != DRIVER_MODULES_CLOSED) {
+ hdd_unregister_wext_all_adapters(hdd_ctx);
+ /*
+ * Cancel any outstanding scan requests. We are about to close
+ * all of our adapters, but an adapter structure is what SME
+ * passes back to our callback function. Hence if there
+ * are any outstanding scan requests then there is a
+ * race condition between when the adapter is closed and
+ * when the callback is invoked. We try to resolve that
+ * race condition here by canceling any outstanding scans
+ * before we close the adapters.
+ * Note that the scans may be cancelled in an asynchronous
+ * manner, so ideally there needs to be some kind of
+ * synchronization. Rather than introduce a new
+ * synchronization here, we will utilize the fact that we are
+ * about to Request Full Power, and since that is synchronized,
+ * the expectation is that by the time Request Full Power has
+ * completed, all scans will be cancelled
+ */
+ hdd_abort_mac_scan_all_adapters(hdd_ctx);
+ hdd_stop_all_adapters(hdd_ctx);
}
+ hdd_wlan_stop_modules(hdd_ctx, false);
/*
* Close the scheduler before calling cds_close to make sure no thread
* is scheduled after the each module close is called i.e after all the
@@ -4339,7 +4467,6 @@ void hdd_wlan_exit(hdd_context_t *hdd_ctx)
* This frees pMac(HAL) context. There should not be any call
* that requires pMac access after this.
*/
- cds_close(p_cds_context);
hdd_wlan_green_ap_deinit(hdd_ctx);
@@ -4350,19 +4477,15 @@ void hdd_wlan_exit(hdd_context_t *hdd_ctx)
/* Free up RoC request queue and flush workqueue */
cds_flush_work(&hdd_ctx->roc_req_work);
- if (!QDF_IS_STATUS_SUCCESS(cds_deinit_policy_mgr())) {
- hdd_err("Failed to deinit policy manager");
- /* Proceed and complete the clean up */
- }
- wlansap_global_deinit();
-
-free_hdd_ctx:
+ wlansap_global_deinit();
wlan_hdd_deinit_tx_rx_histogram(hdd_ctx);
wiphy_unregister(wiphy);
wlan_hdd_cfg80211_deinit(wiphy);
+ hdd_exit_netlink_services(hdd_ctx);
+ mutex_destroy(&hdd_ctx->iface_change_lock);
hdd_context_destroy(hdd_ctx);
}
@@ -5236,17 +5359,12 @@ static void hdd_init_offloaded_packets_ctx(hdd_context_t *hdd_ctx)
*
* Return: none
*/
-static void hdd_enable_fastpath(struct hdd_config *hdd_cfg,
+void hdd_enable_fastpath(struct hdd_config *hdd_cfg,
void *context)
{
if (hdd_cfg->fastpath_enable)
hif_enable_fastpath(context);
}
-#else
-static void hdd_enable_fastpath(struct hdd_config *hdd_cfg,
- void *context)
-{
-}
#endif
#if defined(FEATURE_WLAN_CH_AVOID)
@@ -5909,21 +6027,19 @@ list_destroy:
/**
* hdd_context_create() - Allocate and inialize HDD context.
- * @dev: Pointer to the underlying device
- * @hif_sc: HIF context
+ * @dev: Device Pointer to the underlying device
*
* Allocate and initialize HDD context. HDD context is allocated as part of
* wiphy allocation and then context is initialized.
*
* Return: HDD context on success and ERR_PTR on failure
*/
-hdd_context_t *hdd_context_create(struct device *dev, void *hif_sc)
+hdd_context_t *hdd_context_create(struct device *dev)
{
QDF_STATUS status;
int ret = 0;
hdd_context_t *hdd_ctx;
v_CONTEXT_t p_cds_context;
- struct hif_target_info *tgt_info = hif_get_target_info_handle(hif_sc);
ENTER();
@@ -5954,7 +6070,7 @@ hdd_context_t *hdd_context_create(struct device *dev, void *hif_sc)
/* Read and parse the qcom_cfg.ini file */
status = hdd_parse_config_ini(hdd_ctx);
if (QDF_STATUS_SUCCESS != status) {
- hdd_alert("Error (status: %d) parsing INI file: %s", status,
+ hdd_err("Error (status: %d) parsing INI file: %s", status,
WLAN_INI_FILE);
ret = -EINVAL;
goto err_free_config;
@@ -5977,12 +6093,10 @@ hdd_context_t *hdd_context_create(struct device *dev, void *hif_sc)
if (ret)
goto err_free_config;
- hdd_ctx->target_type = tgt_info->target_type;
pld_set_fw_debug_mode(hdd_ctx->parent_dev,
hdd_ctx->config->enable_fw_log);
- hdd_enable_fastpath(hdd_ctx->config, hif_sc);
/* Uses to enabled logging after SSR */
hdd_ctx->fw_log_settings.enable = hdd_ctx->config->enable_fw_log;
@@ -6086,27 +6200,6 @@ static inline int hdd_open_p2p_interface(struct hdd_context_t *hdd_ctx,
#endif
/**
- * hdd_open_monitor_interface() - Open monitor mode interface
- * @hdd_ctx: HDD context
- * @rtnl_held: True if RTNL lock is held
- *
- * Return: Primary adapter on success and PTR_ERR on failure
- */
-static hdd_adapter_t *hdd_open_monitor_interface(hdd_context_t *hdd_ctx,
- bool rtnl_held)
-{
- hdd_adapter_t *adapter;
-
- adapter = hdd_open_adapter(hdd_ctx, QDF_MONITOR_MODE, "wlan%d",
- wlan_hdd_get_intf_addr(hdd_ctx),
- NET_NAME_UNKNOWN, rtnl_held);
- if (adapter == NULL)
- return ERR_PTR(-ENOSPC);
-
- return adapter;
-}
-
-/**
* hdd_start_station_adapter()- Start the Station Adapter
* @adapter: HDD adapter
*
@@ -6127,6 +6220,10 @@ int hdd_start_station_adapter(hdd_adapter_t *adapter)
return qdf_status_to_os_return(status);
}
+ hdd_register_tx_flow_control(adapter,
+ hdd_tx_resume_timer_expired_handler,
+ hdd_tx_resume_cb);
+
EXIT();
return 0;
}
@@ -6152,6 +6249,10 @@ int hdd_start_ap_adapter(hdd_adapter_t *adapter)
return qdf_status_to_os_return(status);
}
+ hdd_register_tx_flow_control(adapter,
+ hdd_softap_tx_resume_timer_expired_handler,
+ hdd_softap_tx_resume_cb);
+
EXIT();
return 0;
}
@@ -6197,8 +6298,8 @@ static hdd_adapter_t *hdd_open_interfaces(hdd_context_t *hdd_ctx,
hdd_adapter_t *adapter_11p = NULL;
int ret;
- /* Create only 802.11p interface */
if (hdd_ctx->config->dot11p_mode == WLAN_HDD_11P_STANDALONE) {
+ /* Create only 802.11p interface */
adapter = hdd_open_adapter(hdd_ctx, QDF_OCB_MODE, "wlanocb%d",
wlan_hdd_get_intf_addr(hdd_ctx),
NET_NAME_UNKNOWN, rtnl_held);
@@ -6208,7 +6309,6 @@ static hdd_adapter_t *hdd_open_interfaces(hdd_context_t *hdd_ctx,
return adapter;
}
-
adapter = hdd_open_adapter(hdd_ctx, QDF_STA_MODE, "wlan%d",
wlan_hdd_get_intf_addr(hdd_ctx),
NET_NAME_UNKNOWN, rtnl_held);
@@ -6912,11 +7012,6 @@ static int hdd_features_init(hdd_context_t *hdd_ctx, hdd_adapter_t *adapter)
/* FW capabilities received, Set the Dot11 mode */
sme_setdef_dot11mode(hdd_ctx->hHal);
- /*
- * Action frame registered in one adapter which will
- * applicable to all interfaces
- */
- wlan_hdd_cfg80211_register_frames(adapter);
if (hdd_ctx->config->fIsImpsEnabled)
hdd_set_idle_ps_config(hdd_ctx, true);
@@ -6989,6 +7084,218 @@ out:
/**
+ * hdd_configure_cds() - Configure cds modules
+ * @hdd_ctx: HDD context
+ * @adapter: Primary adapter context
+ *
+ * Enable Cds modules after WLAN firmware is up.
+ *
+ * Return: 0 on success and errno on failure.
+ */
+int hdd_configure_cds(hdd_context_t *hdd_ctx, hdd_adapter_t *adapter)
+{
+ int ret;
+ QDF_STATUS status;
+ /* structure of function pointers to be used by CDS */
+ struct cds_sme_cbacks sme_cbacks;
+
+ ret = hdd_pre_enable_configure(hdd_ctx);
+ if (ret) {
+ hdd_err("Failed to pre-configure cds");
+ goto out;
+ }
+
+ /*
+ * Start CDS which starts up the SME/MAC/HAL modules and everything
+ * else
+ */
+ status = cds_enable(hdd_ctx->pcds_context);
+
+ if (!QDF_IS_STATUS_SUCCESS(status)) {
+ hdd_alert("cds_enable failed");
+ goto out;
+ }
+
+ status = hdd_post_cds_enable_config(hdd_ctx);
+ if (!QDF_IS_STATUS_SUCCESS(status)) {
+ hdd_alert("hdd_post_cds_enable_config failed");
+ goto out;
+ }
+
+ ret = hdd_features_init(hdd_ctx, adapter);
+ if (ret)
+ goto out;
+
+ sme_cbacks.sme_get_valid_channels = sme_get_cfg_valid_channels;
+ sme_cbacks.sme_get_nss_for_vdev = sme_get_vdev_type_nss;
+ status = cds_init_policy_mgr(&sme_cbacks);
+ if (!QDF_IS_STATUS_SUCCESS(status)) {
+ hdd_err("Policy manager initialization failed");
+ goto out;
+ }
+
+ return 0;
+out:
+ return -EINVAL;
+}
+
+/**
+ * hdd_deconfigure_cds() -De-Configure cds
+ * @hdd_ctx: HDD context
+ *
+ * Deconfigure Cds modules before WLAN firmware is down.
+ *
+ * Return: 0 on success and errno on failure.
+ */
+int hdd_deconfigure_cds(hdd_context_t *hdd_ctx)
+{
+ QDF_STATUS qdf_status;
+
+ ENTER();
+ /* De-register the SME callbacks */
+ hdd_deregister_cb(hdd_ctx);
+
+ /* De-init Policy Manager */
+ if (!QDF_IS_STATUS_SUCCESS(cds_deinit_policy_mgr())) {
+ hdd_err("Failed to deinit policy manager");
+ /* Proceed and complete the clean up */
+ return -EINVAL;
+ }
+
+ qdf_status = cds_disable(hdd_ctx->pcds_context);
+ if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
+ hdd_err("Failed to Disable the CDS Modules! :%d",
+ qdf_status);
+ return -EINVAL;
+ }
+
+ EXIT();
+ return 0;
+}
+
+
+/**
+ * hdd_wlan_stop_modules - Single driver state machine for stoping modules
+ * @hdd_ctx: HDD context
+ * @shutdown: flag to indicate from SSR or normal path
+ *
+ * This function maintains the driver state machine it will be invoked from
+ * exit, shutdown and con_mode change handler. Depending on the driver state
+ * shall perform the stopping/closing of the modules.
+ *
+ * Return: 0 for success; non-zero for failure
+ */
+int hdd_wlan_stop_modules(hdd_context_t *hdd_ctx, bool shutdown)
+{
+ void *hif_ctx;
+ qdf_device_t qdf_ctx;
+ QDF_STATUS qdf_status;
+ int ret;
+ p_cds_sched_context cds_sched_context = NULL;
+
+ ENTER();
+
+ qdf_ctx = cds_get_context(QDF_MODULE_ID_QDF_DEVICE);
+ if (!qdf_ctx) {
+ hdd_err("QDF device context NULL");
+ return -EINVAL;
+ }
+
+ cds_sched_context = get_cds_sched_ctxt();
+ if (!cds_sched_context) {
+ hdd_err("cds scheduler context NULL");
+ return -EINVAL;
+ }
+
+ hdd_info("Present Driver Status: %d", hdd_ctx->driver_status);
+
+ switch (hdd_ctx->driver_status) {
+ case DRIVER_MODULES_UNINITIALIZED:
+ hdd_info("Modules not initialized just return");
+ return 0;
+ case DRIVER_MODULES_CLOSED:
+ hdd_info("Modules already closed");
+ return 0;
+ case DRIVER_MODULES_ENABLED:
+ if (hdd_deconfigure_cds(hdd_ctx)) {
+ hdd_alert("Failed to de-configure CDS");
+ QDF_ASSERT(0);
+ return -EINVAL;
+ }
+ hdd_info("successfully Disabled the CDS modules!");
+ hdd_ctx->driver_status = DRIVER_MODULES_OPENED;
+ break;
+ case DRIVER_MODULES_OPENED:
+ hdd_info("Closing CDS modules!");
+ break;
+ default:
+ hdd_err("Trying to stop wlan in a wrong state: %d",
+ hdd_ctx->driver_status);
+ QDF_ASSERT(0);
+ return -EINVAL;
+ }
+
+ qdf_status = cds_close(hdd_ctx->pcds_context);
+ if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
+ hdd_warn("Failed to stop CDS:%d", qdf_status);
+ QDF_ASSERT(0);
+ }
+ /* Clean up message queues of TX, RX and MC thread */
+ cds_sched_flush_mc_mqs(cds_sched_context);
+
+ hif_ctx = cds_get_context(QDF_MODULE_ID_HIF);
+ if (!hif_ctx) {
+ hdd_err("Hif context is Null");
+ return -EINVAL;
+ }
+
+ hdd_hif_close(hif_ctx);
+
+ ol_cds_free();
+
+ if (!shutdown) {
+ ret = pld_power_off(qdf_ctx->dev);
+ if (ret)
+ hdd_err("CNSS power down failed put device into Low power mode:%d",
+ ret);
+ }
+ hdd_ctx->driver_status = DRIVER_MODULES_CLOSED;
+
+ EXIT();
+
+ return 0;
+
+}
+
+/**
+ * hdd_iface_change_callback() - Function invoked when stop modules expires
+ * @priv: pointer to hdd context
+ *
+ * This function is invoked when the timer waiting for the interface change
+ * expires, it shall cut-down the power to wlan and stop all the modules.
+ *
+ * Return: void
+ */
+static void hdd_iface_change_callback(void *priv)
+{
+ hdd_context_t *hdd_ctx = (hdd_context_t *) priv;
+ int ret;
+ int status = wlan_hdd_validate_context(hdd_ctx);
+
+ if (status)
+ return;
+
+ ENTER();
+ hdd_info("Interface change timer expired close the modules!");
+ mutex_lock(&hdd_ctx->iface_change_lock);
+ ret = hdd_wlan_stop_modules(hdd_ctx, false);
+ if (ret)
+ hdd_alert("Failed to stop modules");
+ mutex_unlock(&hdd_ctx->iface_change_lock);
+ EXIT();
+}
+
+/**
* hdd_wlan_startup() - HDD init function
* @dev: Pointer to the underlying device
*
@@ -6996,49 +7303,40 @@ out:
*
* Return: 0 for success, < 0 for failure
*/
-int hdd_wlan_startup(struct device *dev, void *hif_sc)
+int hdd_wlan_startup(struct device *dev)
{
QDF_STATUS status;
hdd_adapter_t *adapter = NULL;
hdd_context_t *hdd_ctx = NULL;
int ret;
+ void *hif_sc;
bool rtnl_held;
- /* structure of function pointers to be used by CDS */
- struct cds_sme_cbacks sme_cbacks;
ENTER();
- if (QDF_IS_EPPING_ENABLED(con_mode)) {
- ret = epping_enable(dev);
- EXIT();
- return ret;
- }
-
- hdd_ctx = hdd_context_create(dev, hif_sc);
+ hdd_ctx = hdd_context_create(dev);
if (IS_ERR(hdd_ctx))
return PTR_ERR(hdd_ctx);
+ qdf_mc_timer_init(&hdd_ctx->iface_change_timer, QDF_TIMER_TYPE_SW,
+ hdd_iface_change_callback, (void *)hdd_ctx);
+
+ mutex_init(&hdd_ctx->iface_change_lock);
+
ret = hdd_init_netlink_services(hdd_ctx);
if (ret)
goto err_hdd_free_context;
+ hdd_wlan_green_ap_init(hdd_ctx);
+
ret = hdd_update_config(hdd_ctx);
if (ret)
- goto err_hdd_free_context;
-
- if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
- ret = hdd_enable_ftm(hdd_ctx);
- if (ret)
- goto err_exit_nl_srv;
-
- goto success;
- }
+ goto err_exit_nl_srv;
- hdd_wlan_green_ap_init(hdd_ctx);
- status = cds_open();
- if (!QDF_IS_STATUS_SUCCESS(status)) {
- hddLog(QDF_TRACE_LEVEL_FATAL, FL("cds_open failed"));
+ ret = hdd_wlan_start_modules(hdd_ctx, adapter, false);
+ if (ret) {
+ hdd_alert("Failed to start modules: %d", ret);
goto err_exit_nl_srv;
}
@@ -7048,62 +7346,35 @@ int hdd_wlan_startup(struct device *dev, void *hif_sc)
if (NULL == hdd_ctx->hHal) {
hddLog(QDF_TRACE_LEVEL_FATAL, FL("HAL context is null"));
- goto err_cds_close;
- }
-
- status = cds_pre_enable(hdd_ctx->pcds_context);
- if (!QDF_IS_STATUS_SUCCESS(status)) {
- hddLog(QDF_TRACE_LEVEL_FATAL, FL("cds_pre_enable failed"));
- goto err_cds_close;
+ goto err_stop_modules;
}
ret = hdd_wiphy_init(hdd_ctx);
if (ret) {
hdd_alert("Failed to initialize wiphy: %d", ret);
- goto err_cds_close;
+ goto err_stop_modules;
}
- ret = hdd_pre_enable_configure(hdd_ctx);
- if (ret)
- goto err_wiphy_unregister;
-
if (hdd_ctx->config->enable_dp_trace)
qdf_dp_trace_init();
if (hdd_ipa_init(hdd_ctx) == QDF_STATUS_E_FAILURE)
goto err_wiphy_unregister;
- /*
- * Start CDS which starts up the SME/MAC/HAL modules and everything
- * else
- */
- status = cds_enable(hdd_ctx->pcds_context);
- if (!QDF_IS_STATUS_SUCCESS(status)) {
- hddLog(QDF_TRACE_LEVEL_FATAL, FL("cds_enable failed"));
- goto err_ipa_cleanup;
- }
-
- status = hdd_post_cds_enable_config(hdd_ctx);
- if (!QDF_IS_STATUS_SUCCESS(status)) {
- hddLog(QDF_TRACE_LEVEL_FATAL,
- FL("hdd_post_cds_enable_config failed"));
- goto err_cds_disable;
- }
rtnl_held = hdd_hold_rtnl_lock();
- if (QDF_GLOBAL_MONITOR_MODE == hdd_get_conparam())
- adapter = hdd_open_monitor_interface(hdd_ctx, rtnl_held);
- else
- adapter = hdd_open_interfaces(hdd_ctx, rtnl_held);
+
+ adapter = hdd_open_interfaces(hdd_ctx, rtnl_held);
if (IS_ERR(adapter)) {
hddLog(QDF_TRACE_LEVEL_FATAL,
FL("Failed to open interface, adapter is NULL"));
ret = PTR_ERR(adapter);
- goto err_cds_disable;
+ goto err_ipa_cleanup;
}
+ hif_sc = cds_get_context(QDF_MODULE_ID_HIF);
/*
* target hw version/revision would only be retrieved after firmware
* donwload
@@ -7127,15 +7398,6 @@ int hdd_wlan_startup(struct device *dev, void *hif_sc)
hddLog(LOGE, FL("Failed to init ACS Skip timer"));
#endif
- sme_cbacks.sme_get_valid_channels = sme_get_cfg_valid_channels;
- sme_cbacks.sme_get_nss_for_vdev = sme_get_vdev_type_nss;
- status = cds_init_policy_mgr(&sme_cbacks);
- if (!QDF_IS_STATUS_SUCCESS(status)) {
- hdd_err("Policy manager initialization failed");
- goto err_debugfs_exit;
- }
-
-
#ifdef MSM_PLATFORM
spin_lock_init(&hdd_ctx->bus_bw_lock);
qdf_mc_timer_init(&hdd_ctx->bus_bw_timer,
@@ -7159,37 +7421,38 @@ int hdd_wlan_startup(struct device *dev, void *hif_sc)
memdump_init();
- if (hdd_features_init(hdd_ctx, adapter)) {
- hdd_err("Error Configuring the CDS!");
- goto err_exit_nl_srv;
- }
+ if (hdd_ctx->config->fIsImpsEnabled)
+ hdd_set_idle_ps_config(hdd_ctx, true);
+ qdf_mc_timer_start(&hdd_ctx->iface_change_timer,
+ hdd_ctx->config->iface_change_wait_time * 5000);
goto success;
err_debugfs_exit:
hdd_debugfs_exit(adapter);
hdd_close_all_adapters(hdd_ctx, false);
-err_cds_disable:
if (rtnl_held)
hdd_release_rtnl_lock();
- cds_disable(hdd_ctx->pcds_context);
-err_ipa_cleanup:
- hdd_ipa_cleanup(hdd_ctx);
err_wiphy_unregister:
wiphy_unregister(hdd_ctx->wiphy);
wlan_hdd_cfg80211_deinit(hdd_ctx->wiphy);
-err_cds_close:
+err_ipa_cleanup:
+ hdd_ipa_cleanup(hdd_ctx);
+
+err_stop_modules:
+ hdd_wlan_stop_modules(hdd_ctx, false);
+
+
status = cds_sched_close(hdd_ctx->pcds_context);
if (!QDF_IS_STATUS_SUCCESS(status)) {
hddLog(QDF_TRACE_LEVEL_FATAL,
FL("Failed to close CDS Scheduler"));
QDF_ASSERT(QDF_IS_STATUS_SUCCESS(status));
}
- cds_close(hdd_ctx->pcds_context);
err_exit_nl_srv:
hdd_exit_netlink_services(hdd_ctx);
@@ -7200,6 +7463,8 @@ err_exit_nl_srv:
}
cds_deinit_ini_config();
err_hdd_free_context:
+ qdf_mc_timer_destroy(&hdd_ctx->iface_change_timer);
+ mutex_destroy(&hdd_ctx->iface_change_lock);
hdd_context_destroy(hdd_ctx);
QDF_BUG(1);
@@ -7211,7 +7476,28 @@ success:
}
/**
- * hdd_register_cb() - Register HDD callbacks.
+ * hdd_wlan_update_target_info() - update target type info
+ * @hdd_ctx: HDD context
+ * @context: hif context
+ *
+ * Update target info received from firmware in hdd context
+ * Return:None
+ */
+
+void hdd_wlan_update_target_info(hdd_context_t *hdd_ctx, void *context)
+{
+ struct hif_target_info *tgt_info = hif_get_target_info_handle(context);
+
+ if (!tgt_info) {
+ hdd_err("Target info is Null");
+ return;
+ }
+
+ hdd_ctx->target_type = tgt_info->target_type;
+}
+
+/**
+ * hdd_register_cb - Register HDD callbacks.
* @hdd_ctx: HDD context
*
* Register the HDD callbacks to CDS/SME.
@@ -8112,7 +8398,7 @@ static int __hdd_module_init(void)
{
int ret = 0;
- pr_info("%s: Loading driver v%s\n", WLAN_MODULE_NAME,
+ pr_err("%s: Loading driver v%s\n", WLAN_MODULE_NAME,
QWLAN_VERSIONSTR TIMER_MANAGER_STR MEMORY_DEBUG_STR);
pld_init();
@@ -8155,96 +8441,192 @@ static void __hdd_module_exit(void)
return;
}
+#ifndef MODULE
/**
- * hdd_module_init() - Init Function
+ * wlan_boot_cb() - Wlan boot callback
+ * @kobj: object whose directory we're creating the link in.
+ * @attr: attribute the user is interacting with
+ * @buff: the buffer containing the user data
+ * @count: number of bytes in the buffer
*
- * This is the driver entry point (invoked when module is loaded using insmod)
+ * This callback is invoked when the fs is ready to start the
+ * wlan driver initialization.
*
- * Return: 0 for success, non zero for failure
+ * Return: 'count' on success or a negative error code in case of failure
*/
-#ifdef MODULE
-static int __init hdd_module_init(void)
-{
- return __hdd_module_init();
-}
-#else /* #ifdef MODULE */
-static int __init hdd_module_init(void)
+static ssize_t wlan_boot_cb(struct kobject *kobj,
+ struct kobj_attribute *attr,
+ const char *buf,
+ size_t count)
{
- /* Driver initialization is delayed to fwpath_changed_handler */
- return 0;
+
+ int ret = 0;
+
+ if (wlan_loader->loaded_state) {
+ pr_info("Wlan driver already initialized");
+ return 0;
+ }
+
+
+ pr_err("%s: Loading driver v%s\n", WLAN_MODULE_NAME,
+ QWLAN_VERSIONSTR TIMER_MANAGER_STR MEMORY_DEBUG_STR);
+
+ if (__hdd_module_init()) {
+ pr_err("%s: Failed to register handler\n", __func__);
+ ret = -EINVAL;
+ } else
+ wlan_loader->loaded_state = MODULE_INITIALIZED;
+
+ return count;
+
}
-#endif /* #ifdef MODULE */
/**
- * hdd_module_exit() - Exit function
+ * wlan_init_sysfs() - Creates the sysfs to be invoked when the fs is
+ * ready
*
- * This is the driver exit point (invoked when module is unloaded using rmmod)
+ * This is creates the syfs entry boot_wlan. Which shall be invoked
+ * when the filesystem is ready.
*
* Return: None
*/
-static void __exit hdd_module_exit(void)
+static int wlan_init_sysfs(void)
{
- __hdd_module_exit();
+ int ret = -EINVAL;
+
+ wlan_loader = kzalloc(sizeof(*wlan_loader), GFP_KERNEL);
+ if (!wlan_loader) {
+ pr_err("%s: memory alloc failed\n", __func__);
+ ret = -ENOMEM;
+ return ret;
+ }
+
+ wlan_loader->boot_wlan_obj = NULL;
+ wlan_loader->attr_group = kzalloc(sizeof(*(wlan_loader->attr_group)),
+ GFP_KERNEL);
+ if (!wlan_loader->attr_group) {
+ pr_err("%s: malloc attr_group failed\n", __func__);
+ ret = -ENOMEM;
+ goto error_return;
+ }
+
+ wlan_loader->loaded_state = 0;
+ wlan_loader->attr_group->attrs = attrs;
+
+ wlan_loader->boot_wlan_obj = kobject_create_and_add("boot_wlan",
+ kernel_kobj);
+ if (!wlan_loader->boot_wlan_obj) {
+ pr_err("%s: sysfs create and add failed\n", __func__);
+ ret = -ENOMEM;
+ goto error_return;
+ }
+
+ ret = sysfs_create_group(wlan_loader->boot_wlan_obj,
+ wlan_loader->attr_group);
+ if (ret) {
+ pr_err("%s: sysfs create group failed %d\n", __func__, ret);
+ goto error_return;
+ }
+
+ return 0;
+
+error_return:
+
+ if (wlan_loader->boot_wlan_obj) {
+ kobject_del(wlan_loader->boot_wlan_obj);
+ wlan_loader->boot_wlan_obj = NULL;
+ }
+
+ return ret;
}
-#ifdef MODULE
-static int fwpath_changed_handler(const char *kmessage, struct kernel_param *kp)
+/**
+ * wlan_deinit_sysfs() - Removes the sysfs created to initialize the wlan
+ *
+ * Return: 0 on success or errno on failure
+ */
+static int wlan_deinit_sysfs(void)
{
- return param_set_copystring(kmessage, kp);
+
+ if (!wlan_loader) {
+ hdd_alert("wlan loader context is Null!");
+ return -EINVAL;
+ }
+
+ if (wlan_loader->boot_wlan_obj) {
+ sysfs_remove_group(wlan_loader->boot_wlan_obj,
+ wlan_loader->attr_group);
+ kobject_del(wlan_loader->boot_wlan_obj);
+ wlan_loader->boot_wlan_obj = NULL;
+ }
+
+ return 0;
}
-#else /* #ifdef MODULE */
+#endif
+
+#ifdef MODULE
/**
- * kickstart_driver() - driver entry point
+ * __hdd_module_init - Module init helper
*
- * This is the driver entry point
- * - delayed driver initialization when driver is statically linked
- * - invoked when module parameter fwpath is modified from userspace to signal
- * initializing the WLAN driver or when con_mode is modified from userspace
- * to signal a switch in operating mode
+ * Module init helper function used by both module and static driver.
*
- * Return: 0 for success, non zero for failure
+ * Return: 0 for success, errno on failure
*/
-static int kickstart_driver(void)
+static int hdd_module_init(void)
{
int ret = 0;
- if (!wlan_hdd_inited) {
- ret = __hdd_module_init();
- wlan_hdd_inited = ret ? 0 : 1;
+ pr_err("%s: Loading driver v%s\n", WLAN_MODULE_NAME,
+ QWLAN_VERSIONSTR TIMER_MANAGER_STR MEMORY_DEBUG_STR);
- return ret;
+ if (__hdd_module_init()) {
+ pr_err("%s: Failed to register handler\n", __func__);
+ ret = -EINVAL;
}
- __hdd_module_exit();
-
- msleep(200);
-
- ret = __hdd_module_init();
+ return ret;
+}
+#else
+static int __init hdd_module_init(void)
+{
+ int ret = -EINVAL;
- wlan_hdd_inited = ret ? 0 : 1;
+ ret = wlan_init_sysfs();
+ if (!ret)
+ pr_err("Failed to create sysfs entry for loading wlan");
return ret;
}
+#endif
+
+#ifdef MODULE
/**
- * fwpath_changed_handler() - Handler Function
+ * hdd_module_exit() - Exit function
*
- * Handle changes to the fwpath parameter
+ * This is the driver exit point (invoked when module is unloaded using rmmod)
*
- * Return: 0 for success, non zero for failure
+ * Return: None
*/
-static int fwpath_changed_handler(const char *kmessage, struct kernel_param *kp)
+static void __exit hdd_module_exit(void)
{
- int ret;
+ __hdd_module_exit();
+}
+#else
+static void __exit hdd_module_exit(void)
+{
+ __hdd_module_exit();
+ wlan_deinit_sysfs();
+}
+#endif
- ret = param_set_copystring(kmessage, kp);
- if (0 == ret)
- ret = kickstart_driver();
- return ret;
+static int fwpath_changed_handler(const char *kmessage, struct kernel_param *kp)
+{
+ return param_set_copystring(kmessage, kp);
}
-#ifdef QCA_WIFI_FTM
+
/**
* con_mode_handler() - Handles module param con_mode change
*
@@ -8257,14 +8639,82 @@ static int fwpath_changed_handler(const char *kmessage, struct kernel_param *kp)
static int con_mode_handler(const char *kmessage, struct kernel_param *kp)
{
int ret;
+ hdd_context_t *hdd_ctx;
+ hdd_adapter_t *adapter;
+ qdf_device_t qdf_dev = cds_get_context(QDF_MODULE_ID_QDF_DEVICE);
+ QDF_STATUS status;
+ hdd_info("con_mode handler: %s", kmessage);
ret = param_set_int(kmessage, kp);
- if (0 == ret)
- ret = kickstart_driver();
+
+ if (!qdf_dev) {
+ hdd_err("qdf device context is Null return!");
+ return -EINVAL;
+ }
+
+ hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
+ if (!hdd_ctx) {
+ hdd_err("Hdd context Null return!");
+ return -EINVAL;
+ }
+ mutex_lock(&hdd_ctx->iface_change_lock);
+ ret = hdd_wlan_stop_modules(hdd_ctx, false);
+ mutex_unlock(&hdd_ctx->iface_change_lock);
+ if (ret) {
+ hdd_err("Stop wlan modules failed");
+ return -EINVAL;
+ }
+
+ adapter = hdd_get_adapter(hdd_ctx, QDF_STA_MODE);
+ if (!adapter) {
+ hdd_err("Failed to get station adapter");
+ return -EINVAL;
+ }
+
+ if (con_mode == QDF_GLOBAL_FTM_MODE) {
+ adapter->device_mode = QDF_FTM_MODE;
+ hdd_set_conparam(QDF_GLOBAL_FTM_MODE);
+ } else if (con_mode == QDF_GLOBAL_MONITOR_MODE) {
+ adapter->wdev.iftype = NL80211_IFTYPE_MONITOR;
+ adapter->device_mode = QDF_MONITOR_MODE;
+ hdd_set_conparam(QDF_GLOBAL_MONITOR_MODE);
+ hdd_set_station_ops(adapter->dev);
+ } else if (con_mode == QDF_GLOBAL_EPPING_MODE) {
+ hdd_set_conparam(QDF_GLOBAL_EPPING_MODE);
+ status = epping_open();
+ if (status != QDF_STATUS_SUCCESS) {
+ hdd_err("Failed to open in eeping mode: %d", status);
+ return -EINVAL;
+ }
+ ret = epping_enable(qdf_dev->dev);
+ if (ret) {
+ hdd_err("Failed to enable in epping mode : %d", ret);
+ epping_close();
+ return -EINVAL;
+ }
+ hdd_info("epping mode successfully enabled");
+ return 0;
+ } else {
+ hdd_info("Con mode not supported");
+ return -EINVAL;
+ }
+
+ ret = hdd_wlan_start_modules(hdd_ctx, adapter, false);
+ if (ret) {
+ hdd_err("Start wlan modules failed: %d", ret);
+ return -EINVAL;
+ }
+
+ if (hdd_start_adapter(adapter)) {
+ hdd_err("Failed to start %s adapter", kmessage);
+ return -EINVAL;
+ } else {
+ hdd_info("Mode successfully changed to %s", kmessage);
+ ret = 0;
+ }
+
return ret;
}
-#endif /* QCA_WIFI_FTM */
-#endif /* #ifdef MODULE */
/**
* hdd_get_conparam() - driver exit point
@@ -8387,12 +8837,8 @@ MODULE_LICENSE("Dual BSD/GPL");
MODULE_AUTHOR("Qualcomm Atheros, Inc.");
MODULE_DESCRIPTION("WLAN HOST DEVICE DRIVER");
-#if !defined(MODULE) && defined(QCA_WIFI_FTM)
module_param_call(con_mode, con_mode_handler, param_get_int, &con_mode,
S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
-#else
-module_param(con_mode, int, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
-#endif
module_param_call(fwpath, fwpath_changed_handler, param_get_string, &fwpath,
S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
diff --git a/core/hdd/src/wlan_hdd_memdump.c b/core/hdd/src/wlan_hdd_memdump.c
index 2e13649614fd..cf35c4857f0f 100644
--- a/core/hdd/src/wlan_hdd_memdump.c
+++ b/core/hdd/src/wlan_hdd_memdump.c
@@ -536,7 +536,6 @@ int memdump_init(void)
{
hdd_context_t *hdd_ctx;
int status = 0;
- QDF_STATUS cb_status;
QDF_STATUS qdf_status;
hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
@@ -550,13 +549,6 @@ int memdump_init(void)
return -EINVAL;
}
- cb_status = sme_fw_mem_dump_register_cb(hdd_ctx->hHal,
- wlan_hdd_cfg80211_fw_mem_dump_cb);
- if (QDF_STATUS_SUCCESS != cb_status) {
- hddLog(LOGE , FL("Failed to register the callback"));
- return -EINVAL;
- }
-
status = memdump_procfs_init();
if (status) {
hddLog(LOGE , FL("Failed to create proc file"));
diff --git a/core/hdd/src/wlan_hdd_power.c b/core/hdd/src/wlan_hdd_power.c
index b6cb8024f589..a1df43603409 100644
--- a/core/hdd/src/wlan_hdd_power.c
+++ b/core/hdd/src/wlan_hdd_power.c
@@ -1299,7 +1299,6 @@ static void hdd_ssr_timer_start(int msec)
*/
QDF_STATUS hdd_wlan_shutdown(void)
{
- QDF_STATUS qdf_status;
v_CONTEXT_t p_cds_context = NULL;
hdd_context_t *pHddCtx;
p_cds_sched_context cds_sched_context = NULL;
@@ -1350,76 +1349,8 @@ QDF_STATUS hdd_wlan_shutdown(void)
}
#endif
- /* Stop all the threads; we do not want any messages to be a processed,
- * any more and the best way to ensure that is to terminate the threads
- * gracefully.
- */
- /* Wait for MC to exit */
- hdd_alert("Shutting down MC thread");
- set_bit(MC_SHUTDOWN_EVENT_MASK, &cds_sched_context->mcEventFlag);
- set_bit(MC_POST_EVENT_MASK, &cds_sched_context->mcEventFlag);
- wake_up_interruptible(&cds_sched_context->mcWaitQueue);
- wait_for_completion(&cds_sched_context->McShutdown);
-
-#ifdef QCA_CONFIG_SMP
- /* Wait for OL RX to exit */
- hdd_alert("Shutting down OL RX thread");
- unregister_hotcpu_notifier(cds_sched_context->cpu_hot_plug_notifier);
- set_bit(RX_SHUTDOWN_EVENT_MASK, &cds_sched_context->ol_rx_event_flag);
- set_bit(RX_POST_EVENT_MASK, &cds_sched_context->ol_rx_event_flag);
- wake_up_interruptible(&cds_sched_context->ol_rx_wait_queue);
- wait_for_completion(&cds_sched_context->ol_rx_shutdown);
- cds_sched_context->ol_rx_thread = NULL;
- cds_drop_rxpkt_by_staid(cds_sched_context, WLAN_MAX_STA_COUNT);
- cds_free_ol_rx_pkt_freeq(cds_sched_context);
-#endif
-
- hdd_alert("Doing WMA STOP");
- qdf_status = wma_stop(p_cds_context, HAL_STOP_TYPE_RF_KILL);
-
- if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
- QDF_TRACE(QDF_MODULE_ID_QDF, LOGE,
- "%s: Failed to stop WMA", __func__);
- QDF_ASSERT(QDF_IS_STATUS_SUCCESS(qdf_status));
- wma_setneedshutdown(p_cds_context);
- }
-
- hdd_alert("Doing SME STOP");
- /* Stop SME - Cannot invoke cds_disable as cds_disable relies
- * on threads being running to process the SYS Stop
- */
- qdf_status = sme_stop(pHddCtx->hHal, HAL_STOP_TYPE_SYS_RESET);
- if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
- QDF_TRACE(QDF_MODULE_ID_QDF, LOGE,
- "%s: Failed to stop sme %d", __func__, qdf_status);
- QDF_ASSERT(0);
- }
-
- hdd_alert("Doing MAC STOP");
- /* Stop MAC (PE and HAL) */
- qdf_status = mac_stop(pHddCtx->hHal, HAL_STOP_TYPE_SYS_RESET);
- if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
- QDF_TRACE(QDF_MODULE_ID_QDF, LOGE,
- "%s: Failed to stop mac %d", __func__, qdf_status);
- QDF_ASSERT(0);
- }
-
- hdd_notice("Flush Queues");
- /* Clean up message queues of TX, RX and MC thread */
- cds_sched_flush_mc_mqs(cds_sched_context);
-
- /* Deinit all the TX, RX and MC queues */
- cds_sched_deinit_mqs(cds_sched_context);
-
- hdd_notice("Doing CDS Shutdown");
- /* shutdown CDS */
- cds_shutdown(p_cds_context);
-
- /*mac context has already been released in mac_close call
- so setting it to NULL in hdd context */
- pHddCtx->hHal = (tHalHandle) NULL;
-
wlansap_global_deinit();
+ hdd_wlan_stop_modules(pHddCtx, true);
hdd_alert("WLAN driver shutdown complete");
return QDF_STATUS_SUCCESS;
@@ -1433,14 +1364,14 @@ QDF_STATUS hdd_wlan_shutdown(void)
* Return: QDF_STATUS_SUCCESS if the driver was re-initialized,
* or an error status otherwise
*/
-QDF_STATUS hdd_wlan_re_init(void *hif_sc)
+QDF_STATUS hdd_wlan_re_init(void)
{
- QDF_STATUS qdf_status;
+
v_CONTEXT_t p_cds_context = NULL;
hdd_context_t *pHddCtx = NULL;
- QDF_STATUS qdf_ret_status;
hdd_adapter_t *pAdapter;
- int i, ret;
+ QDF_STATUS qdf_status;
+ int ret;
hdd_prevent_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_REINIT);
@@ -1458,93 +1389,8 @@ QDF_STATUS hdd_wlan_re_init(void *hif_sc)
goto err_re_init;
}
- if (!hif_sc) {
- hdd_alert("hif_sc is NULL");
- goto err_re_init;
- }
-
- ((cds_context_type *) p_cds_context)->pHIFContext = hif_sc;
-
/* The driver should always be initialized in STA mode after SSR */
hdd_set_conparam(0);
-
- ret = hdd_update_config(pHddCtx);
- if (ret)
- goto err_re_init;
-
- /* Re-open CDS, it is a re-open b'se control transport was never closed. */
- qdf_status = cds_open();
- if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
- hdd_alert("cds_open failed");
- goto err_re_init;
- }
-
- /* Save the hal context in Adapter */
- pHddCtx->hHal = cds_get_context(QDF_MODULE_ID_SME);
- if (NULL == pHddCtx->hHal) {
- hdd_alert("HAL context is null");
- goto err_cds_close;
- }
-
- qdf_status = cds_pre_enable(pHddCtx->pcds_context);
- if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
- hdd_alert("cds_pre_enable failed");
- goto err_cds_close;
- }
-
- /*
- * Note that the cds_pre_enable() sequence triggers the cfg download.
- * The cfg download must occur before we update the SME config
- * since the SME config operation must access the cfg database.
- * Set the SME configuration parameters.
- */
- qdf_status = hdd_set_sme_config(pHddCtx);
- if (QDF_STATUS_SUCCESS != qdf_status) {
- hdd_alert("Failed hdd_set_sme_config");
- goto err_cds_close;
- }
-
- ol_txrx_register_pause_cb(wlan_hdd_txrx_pause_cb);
-
- qdf_status = hdd_set_sme_chan_list(pHddCtx);
- if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
- hdd_alert("Failed to init channel list");
- goto err_cds_close;
- }
-
- /* Apply the cfg.ini to cfg.dat */
- if (false == hdd_update_config_dat(pHddCtx)) {
- hdd_alert("config update failed");
- goto err_cds_close;
- }
-
- /* Set the MAC Address, currently this is used by HAL to add self sta.
- * Remove this once self sta is added as part of session open. */
- qdf_ret_status = cfg_set_str(pHddCtx->hHal, WNI_CFG_STA_ID,
- (uint8_t *) &pHddCtx->config->
- intfMacAddr[0],
- sizeof(pHddCtx->config->intfMacAddr[0]));
- if (!QDF_IS_STATUS_SUCCESS(qdf_ret_status)) {
- hdd_err("Failed to set MAC Address. "
- "HALStatus is %08d [x%08x]", qdf_ret_status,
- qdf_ret_status);
- goto err_cds_close;
- }
-
- /* Start CDS which starts up the SME/MAC/HAL modules and everything else
- Note: Firmware image will be read and downloaded inside cds_enable API */
- qdf_status = cds_enable(p_cds_context);
- if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
- hdd_alert("cds_enable failed");
- goto err_cds_close;
- }
-
- qdf_status = hdd_post_cds_enable_config(pHddCtx);
- if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
- hdd_alert("hdd_post_cds_enable_config failed");
- goto err_cds_disable;
- }
-
/* Try to get an adapter from mode ID */
pAdapter = hdd_get_adapter(pHddCtx, QDF_STA_MODE);
if (!pAdapter) {
@@ -1560,6 +1406,12 @@ QDF_STATUS hdd_wlan_re_init(void *hif_sc)
if (pHddCtx->config->enable_dp_trace)
qdf_dp_trace_init();
+ ret = hdd_wlan_start_modules(pHddCtx, pAdapter, true);
+ if (ret) {
+ hdd_err("Failed to start wlan after error");
+ goto err_wiphy_unregister;
+ }
+
if (hdd_ipa_uc_ssr_reinit())
hdd_err("HDD IPA UC reinit failed");
@@ -1568,50 +1420,6 @@ QDF_STATUS hdd_wlan_re_init(void *hif_sc)
/* Restart all adapters */
hdd_start_all_adapters(pHddCtx);
- /* Reconfigure FW logs after SSR */
- if (pAdapter) {
- if (pHddCtx->fw_log_settings.enable != 0) {
- wma_cli_set_command(pAdapter->sessionId,
- WMI_DBGLOG_MODULE_ENABLE,
- pHddCtx->fw_log_settings.enable,
- DBG_CMD);
- } else {
- wma_cli_set_command(pAdapter->sessionId,
- WMI_DBGLOG_MODULE_DISABLE,
- pHddCtx->fw_log_settings.enable,
- DBG_CMD);
- }
-
- if (pHddCtx->fw_log_settings.dl_report != 0) {
- wma_cli_set_command(pAdapter->sessionId,
- WMI_DBGLOG_REPORT_ENABLE,
- pHddCtx->fw_log_settings.
- dl_report, DBG_CMD);
-
- wma_cli_set_command(pAdapter->sessionId,
- WMI_DBGLOG_TYPE,
- pHddCtx->fw_log_settings.
- dl_type, DBG_CMD);
-
- wma_cli_set_command(pAdapter->sessionId,
- WMI_DBGLOG_LOG_LEVEL,
- pHddCtx->fw_log_settings.
- dl_loglevel, DBG_CMD);
-
- for (i = 0; i < MAX_MOD_LOGLEVEL; i++) {
- if (pHddCtx->fw_log_settings.
- dl_mod_loglevel[i] != 0) {
- wma_cli_set_command(
- pAdapter->sessionId,
- WMI_DBGLOG_MOD_LOG_LEVEL,
- pHddCtx->fw_log_settings.
- dl_mod_loglevel[i],
- DBG_CMD);
- }
- }
- }
- }
-
pHddCtx->hdd_mcastbcast_filter_set = false;
pHddCtx->btCoexModeSet = false;
hdd_ssr_timer_del();
@@ -1639,16 +1447,13 @@ QDF_STATUS hdd_wlan_re_init(void *hif_sc)
goto success;
err_cds_disable:
- cds_disable(p_cds_context);
+ hdd_wlan_stop_modules(pHddCtx, true);
-err_cds_close:
- cds_close(p_cds_context);
- cds_sched_close(p_cds_context);
+err_wiphy_unregister:
if (pHddCtx) {
/* Unregister the Net Device Notifier */
unregister_netdevice_notifier(&hdd_netdev_notifier);
ptt_sock_deactivate_svc();
-
nl_srv_exit();
/* Free up dynamically allocated members inside HDD Adapter */
@@ -1656,13 +1461,7 @@ err_cds_close:
pHddCtx->config = NULL;
wlan_hdd_deinit_tx_rx_histogram(pHddCtx);
wiphy_unregister(pHddCtx->wiphy);
- wlan_hdd_cfg80211_deinit(pHddCtx->wiphy);
wiphy_free(pHddCtx->wiphy);
-
- if (!QDF_IS_STATUS_SUCCESS(cds_deinit_policy_mgr())) {
- hdd_err("Failed to deinit policy manager");
- /* Proceed and complete the clean up */
- }
}
err_re_init:
@@ -1763,6 +1562,14 @@ static int __wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
result = wlan_hdd_validate_context(pHddCtx);
if (0 != result)
return result;
+
+ mutex_lock(&pHddCtx->iface_change_lock);
+ if (pHddCtx->driver_status != DRIVER_MODULES_ENABLED) {
+ mutex_unlock(&pHddCtx->iface_change_lock);
+ hdd_info("Driver Module not enabled return success");
+ return 0;
+ }
+ mutex_unlock(&pHddCtx->iface_change_lock);
pld_request_bus_bandwidth(pHddCtx->parent_dev, PLD_BUS_WIDTH_MEDIUM);
/* Resume MC thread */
@@ -1897,6 +1704,14 @@ static int __wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
if (0 != rc)
return rc;
+ mutex_lock(&pHddCtx->iface_change_lock);
+ if (pHddCtx->driver_status != DRIVER_MODULES_ENABLED) {
+ mutex_unlock(&pHddCtx->iface_change_lock);
+ hdd_info("Driver Modules not Enabled ");
+ return 0;
+ }
+ mutex_unlock(&pHddCtx->iface_change_lock);
+
/* If RADAR detection is in progress (HDD), prevent suspend. The flag
* "dfs_cac_block_tx" is set to true when RADAR is found and stay true
* until CAC is done for a SoftAP which is in started state.