blob: 6e3fdf258ed9841b69f77bc27b93c9d51510c222 [file] [log] [blame]
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001/*
Kabilan Kannan973744a2018-01-03 10:28:50 -08002 * Copyright (c) 2012-2018 The Linux Foundation. All rights reserved.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003 *
4 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
5 *
6 *
7 * Permission to use, copy, modify, and/or distribute this software for
8 * any purpose with or without fee is hereby granted, provided that the
9 * above copyright notice and this permission notice appear in all
10 * copies.
11 *
12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
13 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
14 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
15 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
16 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
17 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
18 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
19 * PERFORMANCE OF THIS SOFTWARE.
20 */
21
22/*
23 * This file was originally distributed by Qualcomm Atheros, Inc.
24 * under proprietary terms before Copyright ownership was assigned
25 * to the Linux Foundation.
26 */
27
28/**
29 * DOC: cds_api.c
30 *
31 * Connectivity driver services APIs
32 */
33
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080034#include "cds_sched.h"
35#include <cds_api.h>
36#include "sir_types.h"
37#include "sir_api.h"
38#include "sir_mac_prot_def.h"
39#include "sme_api.h"
40#include "mac_init_api.h"
41#include "wlan_qct_sys.h"
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080042#include "i_cds_packet.h"
43#include "cds_reg_service.h"
44#include "wma_types.h"
45#include "wlan_hdd_main.h"
Yu Wang66a250b2017-07-19 11:46:40 +080046#include "wlan_hdd_tsf.h"
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080047#include <linux/vmalloc.h>
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080048
Yuanyuan Liu0e0aa932016-05-12 10:17:58 -070049#include "pld_common.h"
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080050#include "sap_api.h"
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +053051#include "qdf_trace.h"
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080052#include "bmi.h"
53#include "ol_fw.h"
54#include "ol_if_athvar.h"
55#include "hif.h"
Tushnim Bhattacharyya12b48742017-03-13 12:46:45 -070056#include "wlan_policy_mgr_api.h"
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080057#include "cds_utils.h"
58#include "wlan_logging_sock_svc.h"
59#include "wma.h"
Nirav Shah7f337db2016-05-25 10:49:02 +053060#include "pktlog_ac.h"
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080061#include "wlan_hdd_ipa.h"
Pramod Simha0d3b9362017-03-27 14:59:58 -070062#include "wlan_policy_mgr_api.h"
Leo Chang9b097032016-10-28 11:03:17 -070063
64#include <cdp_txrx_cmn_reg.h>
65#include <cdp_txrx_cfg.h>
66#include <cdp_txrx_misc.h>
Rajeev Kumar97767a02016-11-30 11:20:40 -080067#include <dispatcher_init_deinit.h>
Venkata Sharath Chandra Manchala0d44d452016-11-23 17:48:15 -080068#include <cdp_txrx_handle.h>
Dustin Browna2dcb5f2017-10-20 17:36:19 -070069#include "qdf_cpuhp.h"
Govind Singh27a74032017-11-10 15:08:19 +053070#include "target_type.h"
Zhang Qian47e22ce2018-01-04 15:38:38 +080071#include "wlan_ocb_ucfg_api.h"
Venkata Sharath Chandra Manchala0d44d452016-11-23 17:48:15 -080072
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080073/* Preprocessor Definitions and Constants */
74
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080075/* Data definitions */
76static cds_context_type g_cds_context;
77static p_cds_contextType gp_cds_context;
Anurag Chouhandf2b2682016-02-29 14:15:27 +053078static struct __qdf_device g_qdf_ctx;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080079
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080080static uint8_t cds_multicast_logging;
81
Leo Chang9b097032016-10-28 11:03:17 -070082static struct ol_if_ops dp_ol_if_ops = {
83 .peer_set_default_routing = wma_peer_set_default_routing,
84 .peer_rx_reorder_queue_setup = wma_peer_rx_reorder_queue_setup,
85 .peer_rx_reorder_queue_remove = wma_peer_rx_reorder_queue_remove,
Dhanashri Atref5e02122017-04-13 15:36:42 -070086 .is_hw_dbs_2x2_capable = policy_mgr_is_hw_dbs_2x2_capable,
jiadcd49ec72017-12-05 13:33:11 +080087 .lro_hash_config = wma_lro_config_cmd,
88 .rx_mic_error = wma_rx_mic_error_ind
Leo Chang9b097032016-10-28 11:03:17 -070089 /* TODO: Add any other control path calls required to OL_IF/WMA layer */
90};
91
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080092void cds_sys_probe_thread_cback(void *pUserData);
Srinivas Girigowda161b9f22017-07-24 17:38:09 -070093static void cds_trigger_recovery_work(void *param);
94
95/**
96 * cds_recovery_work_init() - Initialize recovery work queue
97 *
98 * Return: none
99 */
100static QDF_STATUS cds_recovery_work_init(void)
101{
102 qdf_create_work(0, &gp_cds_context->cds_recovery_work,
103 cds_trigger_recovery_work, NULL);
104 gp_cds_context->cds_recovery_wq =
105 qdf_create_workqueue("cds_recovery_workqueue");
106 if (NULL == gp_cds_context->cds_recovery_wq) {
107 cds_err("Failed to create cds_recovery_workqueue");
108 return QDF_STATUS_E_FAILURE;
109 }
110
111 return QDF_STATUS_SUCCESS;
112}
113
114/**
115 * cds_recovery_work_deinit() - Initialize recovery work queue
116 *
117 * Return: none
118 */
119static void cds_recovery_work_deinit(void)
120{
121 if (gp_cds_context->cds_recovery_wq) {
122 qdf_flush_workqueue(0, gp_cds_context->cds_recovery_wq);
123 qdf_destroy_workqueue(0, gp_cds_context->cds_recovery_wq);
124 }
125}
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800126
Venkata Sharath Chandra Manchala83985632017-02-28 14:16:22 -0800127/** cds_get_datapath_handles - Initialize pdev, vdev and soc
128 * @soc - soc handle
129 * @vdev - virtual handle
130 * @pdev - physical handle
131 */
132uint8_t cds_get_datapath_handles(void **soc, struct cdp_pdev **pdev,
133 struct cdp_vdev **vdev, uint8_t sessionId)
134{
135
136 (*soc) = cds_get_context(QDF_MODULE_ID_SOC);
137
138 if (!(*soc)) {
139 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
140 "soc handle is invalid");
141 return -EINVAL;
142 }
143
144 (*pdev) = cds_get_context(QDF_MODULE_ID_TXRX);
145
146 if (!(*pdev)) {
147 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
148 "pdev handle is invalid");
149 return -EINVAL;
150 }
151
152 (*vdev) = cdp_get_vdev_from_vdev_id((*soc), (*pdev),
153 sessionId);
154
155 if (!(*vdev)) {
156 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
157 "vdev handle is invalid");
158 return -EINVAL;
159 }
160 return 0;
161}
162
163
Jeff Johnson7aaeeea2017-09-26 13:16:24 -0700164QDF_STATUS cds_init(void)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800165{
wadesongae4ffd12017-10-24 16:45:54 +0800166 QDF_STATUS ret;
167
168 ret = qdf_debugfs_init();
169 if (ret != QDF_STATUS_SUCCESS) {
170 cds_err("Failed to init debugfs");
171 goto err_ret;
172 }
173
Houston Hoffman1a777572017-01-13 12:43:48 -0800174 qdf_lock_stats_init();
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530175 qdf_mem_init();
Houston Hoffman9e06e542016-12-12 12:06:26 -0800176 qdf_mc_timer_manager_init();
Nachiket Kukade0396b732017-11-14 16:35:16 +0530177 qdf_event_list_init();
Dustin Browna2dcb5f2017-10-20 17:36:19 -0700178 qdf_cpuhp_init();
Dustin Brown100201e2017-07-10 11:48:40 -0700179 qdf_register_self_recovery_callback(cds_trigger_recovery);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800180
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800181 gp_cds_context = &g_cds_context;
182
Anurag Chouhandf2b2682016-02-29 14:15:27 +0530183 gp_cds_context->qdf_ctx = &g_qdf_ctx;
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530184 qdf_mem_zero(&g_qdf_ctx, sizeof(g_qdf_ctx));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800185
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530186 qdf_trace_spin_lock_init();
Prashanth Bhatta5da711e2015-11-30 14:28:52 -0800187
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800188#if defined(TRACE_RECORD)
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530189 qdf_trace_init();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800190#endif
Padma, Santhosh Kumar9aba02f2016-08-11 16:30:25 +0530191 qdf_register_debugcb_init();
Prashanth Bhatta5da711e2015-11-30 14:28:52 -0800192
193 cds_ssr_protect_init();
194
wadesongae4ffd12017-10-24 16:45:54 +0800195 ret = cds_recovery_work_init();
196 if (ret != QDF_STATUS_SUCCESS) {
197 cds_err("Failed to init recovery work");
198 goto deinit;
199 }
Srinivas Girigowda161b9f22017-07-24 17:38:09 -0700200
wadesongae4ffd12017-10-24 16:45:54 +0800201 return QDF_STATUS_SUCCESS;
202deinit:
203 qdf_mc_timer_manager_exit();
204 qdf_mem_exit();
205 qdf_lock_stats_deinit();
206 qdf_debugfs_exit();
207 gp_cds_context->qdf_ctx = NULL;
208 gp_cds_context = NULL;
209 qdf_mem_zero(&g_cds_context, sizeof(g_cds_context));
210err_ret:
211 return ret;
Prashanth Bhatta5da711e2015-11-30 14:28:52 -0800212}
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800213
214/**
Prashanth Bhatta5da711e2015-11-30 14:28:52 -0800215 * cds_deinit() - Deinitialize CDS
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800216 *
Prashanth Bhatta5da711e2015-11-30 14:28:52 -0800217 * This function frees the CDS resources
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800218 */
Prashanth Bhatta5da711e2015-11-30 14:28:52 -0800219void cds_deinit(void)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800220{
Prashanth Bhatta5da711e2015-11-30 14:28:52 -0800221 if (gp_cds_context == NULL)
222 return;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800223
Srinivas Girigowda161b9f22017-07-24 17:38:09 -0700224 cds_recovery_work_deinit();
Dustin Browna2dcb5f2017-10-20 17:36:19 -0700225 qdf_cpuhp_deinit();
Arunk Khandavalli4cc97a92016-09-14 23:13:07 +0530226 qdf_mc_timer_manager_exit();
227 qdf_mem_exit();
Houston Hoffman1a777572017-01-13 12:43:48 -0800228 qdf_lock_stats_deinit();
Mahesh Kumar Kalikot Veetil319dbcd2016-10-27 15:03:48 -0700229 qdf_debugfs_exit();
Nachiket Kukade0396b732017-11-14 16:35:16 +0530230 qdf_event_list_destroy();
Arunk Khandavalli4cc97a92016-09-14 23:13:07 +0530231
Anurag Chouhan6d760662016-02-20 16:05:43 +0530232 gp_cds_context->qdf_ctx = NULL;
Prashanth Bhatta5da711e2015-11-30 14:28:52 -0800233 gp_cds_context = NULL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800234
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530235 qdf_mem_zero(&g_cds_context, sizeof(g_cds_context));
Prashanth Bhatta5da711e2015-11-30 14:28:52 -0800236 return;
237}
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800238
Abhishek Singh437606a2016-04-27 13:51:49 +0530239#ifdef FEATURE_WLAN_DIAG_SUPPORT
240/**
241 * cds_tdls_tx_rx_mgmt_event()- send tdls mgmt rx tx event
242 * @event_id: event id
243 * @tx_rx: tx or rx
244 * @type: type of frame
245 * @action_sub_type: action frame type
246 * @peer_mac: peer mac
247 *
248 * This Function sends tdls mgmt rx tx diag event
249 *
250 * Return: void.
251 */
252void cds_tdls_tx_rx_mgmt_event(uint8_t event_id, uint8_t tx_rx,
253 uint8_t type, uint8_t action_sub_type, uint8_t *peer_mac)
254{
255 WLAN_HOST_DIAG_EVENT_DEF(tdls_tx_rx_mgmt,
256 struct host_event_tdls_tx_rx_mgmt);
257
258 tdls_tx_rx_mgmt.event_id = event_id;
259 tdls_tx_rx_mgmt.tx_rx = tx_rx;
260 tdls_tx_rx_mgmt.type = type;
261 tdls_tx_rx_mgmt.action_sub_type = action_sub_type;
262 qdf_mem_copy(tdls_tx_rx_mgmt.peer_mac,
263 peer_mac, CDS_MAC_ADDRESS_LEN);
264 WLAN_HOST_DIAG_EVENT_REPORT(&tdls_tx_rx_mgmt,
265 EVENT_WLAN_TDLS_TX_RX_MGMT);
266}
267#endif
268
Leo Chang9b097032016-10-28 11:03:17 -0700269/**
gbian62edd7e2017-03-07 13:12:13 +0800270 * cds_cfg_update_ac_specs_params() - update ac_specs params
271 * @olcfg: cfg handle
272 * @mac_params: mac params
273 *
274 * Return: none
275 */
276static void
277cds_cfg_update_ac_specs_params(struct txrx_pdev_cfg_param_t *olcfg,
278 struct cds_config_info *cds_cfg)
279{
280 int i;
281
282 if (NULL == olcfg)
283 return;
284
285 if (NULL == cds_cfg)
286 return;
287
288 for (i = 0; i < OL_TX_NUM_WMM_AC; i++) {
289 olcfg->ac_specs[i].wrr_skip_weight =
290 cds_cfg->ac_specs[i].wrr_skip_weight;
291 olcfg->ac_specs[i].credit_threshold =
292 cds_cfg->ac_specs[i].credit_threshold;
293 olcfg->ac_specs[i].send_limit =
294 cds_cfg->ac_specs[i].send_limit;
295 olcfg->ac_specs[i].credit_reserve =
296 cds_cfg->ac_specs[i].credit_reserve;
297 olcfg->ac_specs[i].discard_weight =
298 cds_cfg->ac_specs[i].discard_weight;
299 }
300}
301
302/**
Leo Chang9b097032016-10-28 11:03:17 -0700303 * cds_cdp_cfg_attach() - attach data path config module
304 * @cds_cfg: generic platform level config instance
305 *
306 * Return: none
307 */
308static void cds_cdp_cfg_attach(struct cds_config_info *cds_cfg)
309{
310 struct txrx_pdev_cfg_param_t cdp_cfg = {0};
311 void *soc = cds_get_context(QDF_MODULE_ID_SOC);
312
Kiran Kumar Lokere52d8dc32016-12-05 19:20:40 -0800313 cdp_cfg.is_full_reorder_offload = cds_cfg->reorder_offload;
Leo Chang9b097032016-10-28 11:03:17 -0700314 cdp_cfg.is_uc_offload_enabled = cds_cfg->uc_offload_enabled;
315 cdp_cfg.uc_tx_buffer_count = cds_cfg->uc_txbuf_count;
316 cdp_cfg.uc_tx_buffer_size = cds_cfg->uc_txbuf_size;
317 cdp_cfg.uc_rx_indication_ring_count = cds_cfg->uc_rxind_ringcount;
318 cdp_cfg.uc_tx_partition_base = cds_cfg->uc_tx_partition_base;
319 cdp_cfg.enable_rxthread = cds_cfg->enable_rxthread;
320 cdp_cfg.ip_tcp_udp_checksum_offload =
321 cds_cfg->ip_tcp_udp_checksum_offload;
322 cdp_cfg.ce_classify_enabled = cds_cfg->ce_classify_enabled;
323
gbian62edd7e2017-03-07 13:12:13 +0800324 cds_cfg_update_ac_specs_params(&cdp_cfg, cds_cfg);
Kiran Kumar Lokere9aecfee2016-11-23 17:37:42 -0800325 gp_cds_context->cfg_ctx = cdp_cfg_attach(soc, gp_cds_context->qdf_ctx,
326 (void *)(&cdp_cfg));
327 if (!gp_cds_context->cfg_ctx) {
328 WMA_LOGP("%s: failed to init cfg handle", __func__);
329 return;
330 }
331
Leo Chang9b097032016-10-28 11:03:17 -0700332 /* Configure Receive flow steering */
Venkata Sharath Chandra Manchala0d44d452016-11-23 17:48:15 -0800333 cdp_cfg_set_flow_steering(soc, gp_cds_context->cfg_ctx,
Leo Chang9b097032016-10-28 11:03:17 -0700334 cds_cfg->flow_steering_enabled);
335
Venkata Sharath Chandra Manchala0d44d452016-11-23 17:48:15 -0800336 cdp_cfg_set_flow_control_parameters(soc, gp_cds_context->cfg_ctx,
337 (void *)&cdp_cfg);
Leo Chang9b097032016-10-28 11:03:17 -0700338
339 /* adjust the cfg_ctx default value based on setting */
340 cdp_cfg_set_rx_fwd_disabled(soc, gp_cds_context->cfg_ctx,
341 (uint8_t) cds_cfg->ap_disable_intrabss_fwd);
342
343 /*
344 * adjust the packet log enable default value
345 * based on CFG INI setting
346 */
347 cdp_cfg_set_packet_log_enabled(soc, gp_cds_context->cfg_ctx,
348 (uint8_t)cds_is_packet_log_enabled());
Yu Wang66a250b2017-07-19 11:46:40 +0800349
350 /* adjust the ptp rx option default value based on CFG INI setting */
351 cdp_cfg_set_ptp_rx_opt_enabled(soc, gp_cds_context->cfg_ctx,
352 (uint8_t)cds_is_ptp_rx_opt_enabled());
Leo Chang9b097032016-10-28 11:03:17 -0700353}
Krunal Sonid32c6bc2016-10-18 18:00:21 -0700354static QDF_STATUS cds_register_all_modules(void)
355{
356 QDF_STATUS status;
357
358 scheduler_register_wma_legacy_handler(&wma_mc_process_handler);
359 scheduler_register_sys_legacy_handler(&sys_mc_process_handler);
360
361 /* Register message queues in given order such that queue priority is
362 * intact:
363 * 1) QDF_MODULE_ID_SYS: Timer queue(legacy SYS queue)
364 * 2) QDF_MODULE_ID_TARGET_IF: Target interface queue
365 * 3) QDF_MODULE_ID_PE: Legacy PE message queue
366 * 4) QDF_MODULE_ID_SME: Legacy SME message queue
367 * 5) QDF_MODULE_ID_OS_IF: OS IF message queue for new components
368 */
369 status = scheduler_register_module(QDF_MODULE_ID_SYS,
370 &scheduler_timer_q_mq_handler);
371 status = scheduler_register_module(QDF_MODULE_ID_TARGET_IF,
372 &scheduler_target_if_mq_handler);
373 status = scheduler_register_module(QDF_MODULE_ID_PE,
374 &pe_mc_process_handler);
375 status = scheduler_register_module(QDF_MODULE_ID_SME,
376 &sme_mc_process_handler);
377 status = scheduler_register_module(QDF_MODULE_ID_OS_IF,
378 &scheduler_os_if_mq_handler);
379 return status;
380}
381
382static QDF_STATUS cds_deregister_all_modules(void)
383{
384 QDF_STATUS status;
Krunal Sonie3399902017-02-01 09:51:42 -0800385
386 scheduler_deregister_wma_legacy_handler();
387 scheduler_deregister_sys_legacy_handler();
Krunal Sonid32c6bc2016-10-18 18:00:21 -0700388 status = scheduler_deregister_module(QDF_MODULE_ID_SYS);
Rajeev Kumara88b2dc2017-01-30 16:35:14 -0800389 status = scheduler_deregister_module(QDF_MODULE_ID_TARGET_IF);
Krunal Sonid32c6bc2016-10-18 18:00:21 -0700390 status = scheduler_deregister_module(QDF_MODULE_ID_PE);
391 status = scheduler_deregister_module(QDF_MODULE_ID_SME);
392 status = scheduler_deregister_module(QDF_MODULE_ID_OS_IF);
Krunal Sonie3399902017-02-01 09:51:42 -0800393
Krunal Sonid32c6bc2016-10-18 18:00:21 -0700394 return status;
395}
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800396
397/**
gbian62edd7e2017-03-07 13:12:13 +0800398 * cds_set_ac_specs_params() - set ac_specs params in cds_config_info
399 * @cds_cfg: Pointer to cds_config_info
400 * @hdd_ctx: Pointer to hdd context
401 *
402 * Return: none
403 */
404static void
405cds_set_ac_specs_params(struct cds_config_info *cds_cfg)
406{
407 int i;
408 cds_context_type *cds_ctx;
409
410 if (NULL == cds_cfg)
411 return;
412
413 cds_ctx = cds_get_context(QDF_MODULE_ID_QDF);
414
415 if (!cds_ctx) {
416 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
417 "Invalid CDS Context");
418 return;
419 }
420
421 for (i = 0; i < OL_TX_NUM_WMM_AC; i++) {
422 cds_cfg->ac_specs[i] = cds_ctx->ac_specs[i];
423 }
424}
425
426/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800427 * cds_open() - open the CDS Module
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800428 *
429 * cds_open() function opens the CDS Scheduler
430 * Upon successful initialization:
431 * - All CDS submodules should have been initialized
432 *
433 * - The CDS scheduler should have opened
434 *
435 * - All the WLAN SW components should have been opened. This includes
436 * SYS, MAC, SME, WMA and TL.
437 *
Anurag Chouhanf04e84f2016-03-03 10:12:12 +0530438 * Return: QDF status
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800439 */
Selvaraj, Sridhar0672a122016-12-29 16:11:48 +0530440QDF_STATUS cds_open(struct wlan_objmgr_psoc *psoc)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800441{
Dustin Brownf7971192017-10-25 14:54:37 -0700442 QDF_STATUS status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800443 tSirRetStatus sirStatus = eSIR_SUCCESS;
Arun Khandavallic811dcc2016-06-26 07:37:21 +0530444 struct cds_config_info *cds_cfg;
Anurag Chouhan6d760662016-02-20 16:05:43 +0530445 qdf_device_t qdf_ctx;
Manikandan Mohan83c939c2017-04-13 20:23:07 -0700446 struct htc_init_info htcInfo;
Komal Seelamd9106492016-02-15 10:31:44 +0530447 struct ol_context *ol_ctx;
Komal Seelam3d202862016-02-24 18:43:24 +0530448 struct hif_opaque_softc *scn;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800449 void *HTCHandle;
Jeff Johnsonc18b26c2017-09-03 08:46:45 -0700450 struct hdd_context *hdd_ctx;
Arun Khandavallic811dcc2016-06-26 07:37:21 +0530451 cds_context_type *cds_ctx;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800452
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530453 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_INFO_HIGH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800454 "%s: Opening CDS", __func__);
455
Arun Khandavallic811dcc2016-06-26 07:37:21 +0530456 cds_ctx = cds_get_context(QDF_MODULE_ID_QDF);
457 if (!cds_ctx) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530458 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_FATAL,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800459 "%s: Trying to open CDS without a PreOpen", __func__);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530460 QDF_ASSERT(0);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530461 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800462 }
463
464 /* Initialize the timer module */
Anurag Chouhan210db072016-02-22 18:42:15 +0530465 qdf_timer_module_init();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800466
467 /* Initialize bug reporting structure */
468 cds_init_log_completion();
469
470 /* Initialize the probe event */
Dustin Brownf7971192017-10-25 14:54:37 -0700471 status = qdf_event_create(&gp_cds_context->ProbeEvent);
472 if (QDF_IS_STATUS_ERROR(status)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530473 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_FATAL,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800474 "%s: Unable to init probeEvent", __func__);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530475 QDF_ASSERT(0);
Dustin Brownf7971192017-10-25 14:54:37 -0700476 return status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800477 }
Dustin Brownf7971192017-10-25 14:54:37 -0700478
479 status = qdf_event_create(&gp_cds_context->wmaCompleteEvent);
480 if (QDF_IS_STATUS_ERROR(status)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530481 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_FATAL,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800482 "%s: Unable to init wmaCompleteEvent", __func__);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530483 QDF_ASSERT(0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800484 goto err_probe_event;
485 }
486
Dustin Brownf7971192017-10-25 14:54:37 -0700487 hdd_ctx = (struct hdd_context *)(gp_cds_context->pHDDContext);
488 if (!hdd_ctx || !hdd_ctx->config) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800489 /* Critical Error ... Cannot proceed further */
Arun Khandavallifae92942016-08-01 13:31:08 +0530490 cds_err("Hdd Context is Null");
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530491 QDF_ASSERT(0);
Dustin Brownf7971192017-10-25 14:54:37 -0700492
493 status = QDF_STATUS_E_FAILURE;
Rajeev Kumar3e5ef0d2017-01-03 14:45:31 -0800494 goto err_wma_complete_event;
Arun Khandavallifae92942016-08-01 13:31:08 +0530495 }
Kabilan Kannan15cc6ac2016-11-12 22:25:14 -0800496
Dustin Brown44cde352017-12-04 13:14:46 -0800497 status = dispatcher_enable();
498 if (QDF_IS_STATUS_ERROR(status)) {
499 cds_err("Failed to enable dispatcher; status:%d", status);
500 goto err_wma_complete_event;
501 }
502
Arun Khandavallifae92942016-08-01 13:31:08 +0530503 /* Now Open the CDS Scheduler */
Dustin Brown0707ddf2017-09-20 15:31:56 -0700504 status = cds_sched_open(gp_cds_context,
505 &gp_cds_context->qdf_sched,
506 sizeof(cds_sched_context));
Dustin Brown0707ddf2017-09-20 15:31:56 -0700507 if (QDF_IS_STATUS_ERROR(status)) {
508 /* Critical Error ... Cannot proceed further */
509 cds_alert("Failed to open CDS Scheduler");
510 QDF_ASSERT(0);
Dustin Brown44cde352017-12-04 13:14:46 -0800511 goto err_dispatcher_disable;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800512 }
513
Anurag Chouhan6d760662016-02-20 16:05:43 +0530514 scn = cds_get_context(QDF_MODULE_ID_HIF);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800515 if (!scn) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530516 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_FATAL,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800517 "%s: scn is null!", __func__);
Dustin Brownf7971192017-10-25 14:54:37 -0700518
519 status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800520 goto err_sched_close;
521 }
Arun Khandavallifae92942016-08-01 13:31:08 +0530522
Arun Khandavallifae92942016-08-01 13:31:08 +0530523 cds_cfg = cds_get_ini_config();
524 if (!cds_cfg) {
525 cds_err("Cds config is NULL");
526 QDF_ASSERT(0);
Dustin Brownf7971192017-10-25 14:54:37 -0700527
528 status = QDF_STATUS_E_FAILURE;
Arun Khandavallifae92942016-08-01 13:31:08 +0530529 goto err_sched_close;
530 }
Dustin Brownf7971192017-10-25 14:54:37 -0700531
Jeff Johnsonc18b26c2017-09-03 08:46:45 -0700532 hdd_enable_fastpath(hdd_ctx->config, scn);
Arun Khandavallifae92942016-08-01 13:31:08 +0530533
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800534 /* Initialize BMI and Download firmware */
Dustin Brownf7971192017-10-25 14:54:37 -0700535 ol_ctx = cds_get_context(QDF_MODULE_ID_BMI);
536 status = bmi_download_firmware(ol_ctx);
537 if (QDF_IS_STATUS_ERROR(status)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530538 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_FATAL,
Dustin Brownf7971192017-10-25 14:54:37 -0700539 "BMI FIALED status:%d", status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800540 goto err_bmi_close;
541 }
Tiger Yu086b6992017-11-20 16:33:43 +0800542
543 hdd_wlan_update_target_info(hdd_ctx, scn);
544
Komal Seelam08633492016-02-24 18:05:07 +0530545 htcInfo.pContext = ol_ctx;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800546 htcInfo.TargetFailure = ol_target_failure;
Mukul Sharma4c60a7e2017-03-06 19:42:18 +0530547 htcInfo.TargetSendSuspendComplete =
548 pmo_ucfg_psoc_target_suspend_acknowledge;
549 htcInfo.target_initial_wakeup_cb = pmo_ucfg_psoc_handle_initial_wake_up;
550 htcInfo.target_psoc = (void *)psoc;
Anurag Chouhan6d760662016-02-20 16:05:43 +0530551 qdf_ctx = cds_get_context(QDF_MODULE_ID_QDF_DEVICE);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800552
553 /* Create HTC */
554 gp_cds_context->htc_ctx =
Yue Ma1e11d792016-02-26 18:58:44 -0800555 htc_create(scn, &htcInfo, qdf_ctx, cds_get_conparam());
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800556 if (!gp_cds_context->htc_ctx) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530557 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_FATAL,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800558 "%s: Failed to Create HTC", __func__);
Dustin Brownf7971192017-10-25 14:54:37 -0700559
560 status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800561 goto err_bmi_close;
562 }
Mukul Sharma4c60a7e2017-03-06 19:42:18 +0530563 pmo_ucfg_psoc_update_htc_handle(psoc, (void *)gp_cds_context->htc_ctx);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800564
Dustin Brownf7971192017-10-25 14:54:37 -0700565 status = bmi_done(ol_ctx);
566 if (QDF_IS_STATUS_ERROR(status)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530567 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_FATAL,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800568 "%s: Failed to complete BMI phase", __func__);
569 goto err_htc_close;
570 }
571
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800572 /*Open the WMA module */
bings482bae22018-01-17 16:25:31 +0800573 status = wma_open(psoc, hdd_update_tgt_cfg, cds_cfg,
574 hdd_ctx->target_type);
Dustin Brownf7971192017-10-25 14:54:37 -0700575 if (QDF_IS_STATUS_ERROR(status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800576 /* Critical Error ... Cannot proceed further */
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530577 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_FATAL,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800578 "%s: Failed to open WMA module", __func__);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530579 QDF_ASSERT(0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800580 goto err_htc_close;
581 }
582
583 /* Number of peers limit differs in each chip version. If peer max
584 * limit configured in ini exceeds more than supported, WMA adjusts
Arun Khandavallic811dcc2016-06-26 07:37:21 +0530585 * and keeps correct limit in cds_cfg.max_station. So, make sure
Jeff Johnsonc18b26c2017-09-03 08:46:45 -0700586 * config entry hdd_ctx->config->maxNumberOfPeers has adjusted value
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800587 */
Hanumanth Reddy Pothula47d29262016-10-03 16:08:04 +0530588 /* In FTM mode cds_cfg->max_stations will be zero. On updating same
589 * into hdd context config entry, leads to pe_open() to fail, if
590 * con_mode change happens from FTM mode to any other mode.
591 */
Srinivas Girigowda35b00312017-06-27 21:52:03 -0700592 if (QDF_DRIVER_TYPE_PRODUCTION == cds_cfg->driver_type)
Jeff Johnsonc18b26c2017-09-03 08:46:45 -0700593 hdd_ctx->config->maxNumberOfPeers = cds_cfg->max_station;
Hanumanth Reddy Pothula47d29262016-10-03 16:08:04 +0530594
Anurag Chouhan6d760662016-02-20 16:05:43 +0530595 HTCHandle = cds_get_context(QDF_MODULE_ID_HTC);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800596 if (!HTCHandle) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530597 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_FATAL,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800598 "%s: HTCHandle is null!", __func__);
Dustin Brownf7971192017-10-25 14:54:37 -0700599
600 status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800601 goto err_wma_close;
602 }
Nachiket Kukadef44b33e2017-09-06 16:49:29 +0530603
Dustin Brownf7971192017-10-25 14:54:37 -0700604 status = htc_wait_target(HTCHandle);
605 if (QDF_IS_STATUS_ERROR(status)) {
606 cds_alert("Failed to complete BMI phase. status: %d", status);
Nachiket Kukade8003d252017-03-30 15:55:58 +0530607
Dustin Brownf7971192017-10-25 14:54:37 -0700608 if (status != QDF_STATUS_E_NOMEM && !cds_is_fw_down())
Nachiket Kukade8003d252017-03-30 15:55:58 +0530609 QDF_BUG(0);
610
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800611 goto err_wma_close;
612 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800613
Ravi Joshifc2ed782016-11-22 17:36:50 -0800614 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_DEBUG,
615 "%s: target_type %d 8074:%d 6290:%d",
Jeff Johnsonc18b26c2017-09-03 08:46:45 -0700616 __func__, hdd_ctx->target_type,
Ravi Joshifc2ed782016-11-22 17:36:50 -0800617 TARGET_TYPE_QCA8074, TARGET_TYPE_QCA6290);
618
Jeff Johnsonc18b26c2017-09-03 08:46:45 -0700619 if (TARGET_TYPE_QCA6290 == hdd_ctx->target_type)
Leo Chang9b097032016-10-28 11:03:17 -0700620 gp_cds_context->dp_soc = cdp_soc_attach(LITHIUM_DP,
Arunk Khandavallia6305a32018-01-25 11:19:18 +0530621 gp_cds_context->pHIFContext, psoc,
Leo Chang9b097032016-10-28 11:03:17 -0700622 gp_cds_context->htc_ctx, gp_cds_context->qdf_ctx,
Arunk Khandavallia6305a32018-01-25 11:19:18 +0530623 &dp_ol_if_ops);
Leo Chang9b097032016-10-28 11:03:17 -0700624 else
625 gp_cds_context->dp_soc = cdp_soc_attach(MOB_DRV_LEGACY_DP,
Arunk Khandavallia6305a32018-01-25 11:19:18 +0530626 gp_cds_context->pHIFContext, psoc,
Leo Chang9b097032016-10-28 11:03:17 -0700627 gp_cds_context->htc_ctx, gp_cds_context->qdf_ctx,
Arunk Khandavallia6305a32018-01-25 11:19:18 +0530628 &dp_ol_if_ops);
Leo Chang9b097032016-10-28 11:03:17 -0700629
Dustin Brownf7971192017-10-25 14:54:37 -0700630 if (!gp_cds_context->dp_soc) {
631 status = QDF_STATUS_E_FAILURE;
Manikandan Mohanfb9d2b52017-05-10 15:01:28 -0700632 goto err_wma_close;
Dustin Brownf7971192017-10-25 14:54:37 -0700633 }
Manikandan Mohanfb9d2b52017-05-10 15:01:28 -0700634
Sravan Kumar Kairam27296782017-04-21 22:04:18 +0530635 pmo_ucfg_psoc_update_dp_handle(psoc, gp_cds_context->dp_soc);
Zhang Qian47e22ce2018-01-04 15:38:38 +0800636 ucfg_ocb_update_dp_handle(psoc, gp_cds_context->dp_soc);
Sravan Kumar Kairam27296782017-04-21 22:04:18 +0530637
gbian62edd7e2017-03-07 13:12:13 +0800638 cds_set_ac_specs_params(cds_cfg);
639
Leo Chang9b097032016-10-28 11:03:17 -0700640 cds_cdp_cfg_attach(cds_cfg);
641
Nirav Shaheb017be2018-02-15 11:20:58 +0530642 bmi_target_ready(scn, gp_cds_context->cfg_ctx);
643
Jeff Johnsond9f08602016-12-02 11:31:30 -0800644 /* Now proceed to open the MAC */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800645 sirStatus =
Selvaraj, Sridhar0672a122016-12-29 16:11:48 +0530646 mac_open(psoc, &(gp_cds_context->pMACContext),
Arun Khandavallic811dcc2016-06-26 07:37:21 +0530647 gp_cds_context->pHDDContext, cds_cfg);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800648
649 if (eSIR_SUCCESS != sirStatus) {
650 /* Critical Error ... Cannot proceed further */
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530651 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_FATAL,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800652 "%s: Failed to open MAC", __func__);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530653 QDF_ASSERT(0);
Dustin Brownf7971192017-10-25 14:54:37 -0700654
655 status = QDF_STATUS_E_FAILURE;
Houston Hoffman59c9c912017-03-29 14:10:39 -0700656 goto err_soc_detach;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800657 }
658
659 /* Now proceed to open the SME */
Dustin Brownf7971192017-10-25 14:54:37 -0700660 status = sme_open(gp_cds_context->pMACContext);
661 if (QDF_IS_STATUS_ERROR(status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800662 /* Critical Error ... Cannot proceed further */
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530663 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_FATAL,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800664 "%s: Failed to open SME", __func__);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530665 QDF_ASSERT(0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800666 goto err_mac_close;
667 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800668
Krunal Sonid32c6bc2016-10-18 18:00:21 -0700669 cds_register_all_modules();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800670
Selvaraj, Sridhara7dc2382017-01-27 18:29:39 +0530671 return dispatcher_psoc_open(psoc);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800672
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800673err_mac_close:
674 mac_close(gp_cds_context->pMACContext);
675
Houston Hoffman59c9c912017-03-29 14:10:39 -0700676err_soc_detach:
677 /* todo: add propper error handling */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800678err_wma_close:
Rajeev Kumar662d75d2017-03-13 18:11:29 -0700679 cds_shutdown_notifier_purge();
Jeff Johnson542da352017-09-13 09:17:28 -0700680 wma_close();
Jeff Johnson7b3ddc22017-09-13 09:42:44 -0700681 wma_wmi_service_close();
Sravan Kumar Kairam27296782017-04-21 22:04:18 +0530682 pmo_ucfg_psoc_update_dp_handle(psoc, NULL);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800683
684err_htc_close:
685 if (gp_cds_context->htc_ctx) {
686 htc_destroy(gp_cds_context->htc_ctx);
687 gp_cds_context->htc_ctx = NULL;
Sravan Kumar Kairam27296782017-04-21 22:04:18 +0530688 pmo_ucfg_psoc_update_htc_handle(psoc, NULL);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800689 }
690
691err_bmi_close:
Komal Seelam5a6e5082016-02-24 17:59:09 +0530692 bmi_cleanup(ol_ctx);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800693
694err_sched_close:
Dustin Brown0707ddf2017-09-20 15:31:56 -0700695 if (QDF_IS_STATUS_ERROR(cds_sched_close())) {
696 cds_err("Failed to close CDS Scheduler");
697 QDF_ASSERT(false);
Hanumanth Reddy Pothula0b571432017-02-23 17:15:37 +0530698 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800699
Dustin Brown44cde352017-12-04 13:14:46 -0800700err_dispatcher_disable:
701 if (QDF_IS_STATUS_ERROR(dispatcher_disable()))
702 cds_err("Failed to disable dispatcher");
703
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800704err_wma_complete_event:
Anurag Chouhance0dc992016-02-16 18:18:03 +0530705 qdf_event_destroy(&gp_cds_context->wmaCompleteEvent);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800706
707err_probe_event:
Anurag Chouhance0dc992016-02-16 18:18:03 +0530708 qdf_event_destroy(&gp_cds_context->ProbeEvent);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800709
Dustin Brownf7971192017-10-25 14:54:37 -0700710 return status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800711} /* cds_open() */
712
Venkata Sharath Chandra Manchala4aaae0f2017-07-10 11:59:19 -0700713QDF_STATUS cds_dp_open(struct wlan_objmgr_psoc *psoc)
714{
715 if (cdp_txrx_intr_attach(gp_cds_context->dp_soc)
716 != QDF_STATUS_SUCCESS) {
717 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_FATAL,
718 "%s: Failed to attach interrupts", __func__);
719 goto close;
720 }
721
722 cds_set_context(QDF_MODULE_ID_TXRX,
723 cdp_pdev_attach(cds_get_context(QDF_MODULE_ID_SOC),
724 gp_cds_context->cfg_ctx,
725 gp_cds_context->htc_ctx,
726 gp_cds_context->qdf_ctx, 0));
727 if (!gp_cds_context->pdev_txrx_ctx) {
728 /* Critical Error ... Cannot proceed further */
729 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_FATAL,
730 "%s: Failed to open TXRX", __func__);
731 QDF_ASSERT(0);
732 goto intr_close;
733 }
734
735 pmo_ucfg_psoc_set_txrx_handle(psoc, gp_cds_context->pdev_txrx_ctx);
Zhang Qian47e22ce2018-01-04 15:38:38 +0800736 ucfg_ocb_set_txrx_handle(psoc, gp_cds_context->pdev_txrx_ctx);
Venkata Sharath Chandra Manchala4aaae0f2017-07-10 11:59:19 -0700737
738 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_INFO_HIGH,
739 "%s: CDS successfully Opened", __func__);
740
741 return 0;
742
743intr_close:
744 cdp_txrx_intr_detach(gp_cds_context->dp_soc);
745close:
746 return QDF_STATUS_E_FAILURE;
747}
748
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800749/**
750 * cds_pre_enable() - pre enable cds
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800751 *
Anurag Chouhanf04e84f2016-03-03 10:12:12 +0530752 * Return: QDF status
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800753 */
Jeff Johnson3a280122017-09-13 07:42:00 -0700754QDF_STATUS cds_pre_enable(void)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800755{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530756 QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800757 void *scn;
Jeff Johnson3a280122017-09-13 07:42:00 -0700758 void *soc;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800759
Srinivas Girigowdad395b892017-03-09 19:29:42 -0800760 QDF_TRACE(QDF_MODULE_ID_SYS, QDF_TRACE_LEVEL_DEBUG, "cds prestart");
Jeff Johnson3a280122017-09-13 07:42:00 -0700761
762 if (!gp_cds_context) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530763 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Jeff Johnson3a280122017-09-13 07:42:00 -0700764 "%s: NULL CDS context", __func__);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530765 QDF_ASSERT(0);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530766 return QDF_STATUS_E_INVAL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800767 }
768
Jeff Johnson3a280122017-09-13 07:42:00 -0700769 if (gp_cds_context->pMACContext == NULL) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530770 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800771 "%s: MAC NULL context", __func__);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530772 QDF_ASSERT(0);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530773 return QDF_STATUS_E_INVAL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800774 }
775
Jeff Johnson3a280122017-09-13 07:42:00 -0700776 if (gp_cds_context->pWMAContext == NULL) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530777 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800778 "%s: WMA NULL context", __func__);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530779 QDF_ASSERT(0);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530780 return QDF_STATUS_E_INVAL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800781 }
782
Anurag Chouhan6d760662016-02-20 16:05:43 +0530783 scn = cds_get_context(QDF_MODULE_ID_HIF);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800784 if (!scn) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530785 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_FATAL,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800786 "%s: scn is null!", __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530787 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800788 }
789
Jeff Johnson3a280122017-09-13 07:42:00 -0700790 soc = cds_get_context(QDF_MODULE_ID_SOC);
791 if (!soc) {
792 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_FATAL,
793 "%s: soc is null!", __func__);
794 return QDF_STATUS_E_FAILURE;
795 }
796
Nirav Shah7f337db2016-05-25 10:49:02 +0530797 /* call Packetlog connect service */
Arun Khandavallifae92942016-08-01 13:31:08 +0530798 if (QDF_GLOBAL_FTM_MODE != cds_get_conparam() &&
Leo Chang9b097032016-10-28 11:03:17 -0700799 QDF_GLOBAL_EPPING_MODE != cds_get_conparam())
800 cdp_pkt_log_con_service(soc,
Venkata Sharath Chandra Manchala0d44d452016-11-23 17:48:15 -0800801 gp_cds_context->pdev_txrx_ctx,
802 scn);
Nirav Shah7f337db2016-05-25 10:49:02 +0530803
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800804 /* Reset wma wait event */
Anurag Chouhance0dc992016-02-16 18:18:03 +0530805 qdf_event_reset(&gp_cds_context->wmaCompleteEvent);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800806
807 /*call WMA pre start */
Jeff Johnson8ad89c62017-09-13 08:55:55 -0700808 qdf_status = wma_pre_start();
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530809 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530810 QDF_TRACE(QDF_MODULE_ID_SYS, QDF_TRACE_LEVEL_FATAL,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800811 "Failed to WMA prestart");
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530812 QDF_ASSERT(0);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530813 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800814 }
815
816 /* Need to update time out of complete */
Nachiket Kukade0396b732017-11-14 16:35:16 +0530817 qdf_status = qdf_wait_for_event_completion(
818 &gp_cds_context->wmaCompleteEvent,
819 CDS_WMA_TIMEOUT);
Anurag Chouhance0dc992016-02-16 18:18:03 +0530820 if (qdf_status != QDF_STATUS_SUCCESS) {
821 if (qdf_status == QDF_STATUS_E_TIMEOUT) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530822 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800823 "%s: Timeout occurred before WMA complete",
824 __func__);
825 } else {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530826 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800827 "%s: wma_pre_start reporting other error",
828 __func__);
829 }
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530830 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800831 "%s: Test MC thread by posting a probe message to SYS",
832 __func__);
833 wlan_sys_probe();
834
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530835 QDF_ASSERT(0);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530836 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800837 }
838
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530839 qdf_status = htc_start(gp_cds_context->htc_ctx);
840 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530841 QDF_TRACE(QDF_MODULE_ID_SYS, QDF_TRACE_LEVEL_FATAL,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800842 "Failed to Start HTC");
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530843 QDF_ASSERT(0);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530844 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800845 }
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530846 qdf_status = wma_wait_for_ready_event(gp_cds_context->pWMAContext);
847 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530848 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_FATAL,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800849 "Failed to get ready event from target firmware");
Nachiket Kukade8003d252017-03-30 15:55:58 +0530850
Naveen Rawat91df30a2016-10-12 21:26:18 -0700851 /*
Nachiket Kukade8003d252017-03-30 15:55:58 +0530852 * Panic when the failure is not because the FW is down,
853 * fail gracefully if FW is down allowing re-probing from
854 * from the platform driver
Naveen Rawat91df30a2016-10-12 21:26:18 -0700855 */
Rajeev Kumar8b330492017-11-09 12:09:10 -0800856 if ((!cds_is_fw_down()) && (!cds_is_self_recovery_enabled()))
Naveen Rawat91df30a2016-10-12 21:26:18 -0700857 QDF_BUG(0);
858
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800859 htc_stop(gp_cds_context->htc_ctx);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530860 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800861 }
862
Leo Chang9b097032016-10-28 11:03:17 -0700863 if (cdp_pdev_post_attach(soc, gp_cds_context->pdev_txrx_ctx)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530864 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_FATAL,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800865 "Failed to attach pdev");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800866 htc_stop(gp_cds_context->htc_ctx);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530867 QDF_ASSERT(0);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530868 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800869 }
870
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530871 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800872}
873
874/**
875 * cds_enable() - start/enable cds module
Selvaraj, Sridhar0672a122016-12-29 16:11:48 +0530876 * @psoc: Psoc pointer
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800877 * @cds_context: CDS context
878 *
Anurag Chouhanf04e84f2016-03-03 10:12:12 +0530879 * Return: QDF status
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800880 */
Jeff Johnson8f9dd5f2017-09-13 14:16:08 -0700881QDF_STATUS cds_enable(struct wlan_objmgr_psoc *psoc)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800882{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530883 QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800884 tSirRetStatus sirStatus = eSIR_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800885 tHalMacStartParameters halStartParams;
886
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800887 /* We support only one instance for now ... */
Jeff Johnson8f9dd5f2017-09-13 14:16:08 -0700888 if (!gp_cds_context) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530889 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Jeff Johnson8f9dd5f2017-09-13 14:16:08 -0700890 "%s: Invalid CDS context", __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530891 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800892 }
893
Jeff Johnson8f9dd5f2017-09-13 14:16:08 -0700894 if ((gp_cds_context->pWMAContext == NULL) ||
895 (gp_cds_context->pMACContext == NULL)) {
896 if (gp_cds_context->pWMAContext == NULL)
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530897 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800898 "%s: WMA NULL context", __func__);
899 else
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530900 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800901 "%s: MAC NULL context", __func__);
902
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530903 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800904 }
905
906 /* Start the wma */
Jeff Johnsond4892552017-09-13 08:41:31 -0700907 qdf_status = wma_start();
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530908 if (qdf_status != QDF_STATUS_SUCCESS) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530909 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800910 "%s: Failed to start wma", __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530911 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800912 }
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530913 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_INFO,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800914 "%s: wma correctly started", __func__);
915
916 /* Start the MAC */
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530917 qdf_mem_zero(&halStartParams,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800918 sizeof(tHalMacStartParameters));
919
920 /* Start the MAC */
921 sirStatus =
Jeff Johnson8f9dd5f2017-09-13 14:16:08 -0700922 mac_start(gp_cds_context->pMACContext, &halStartParams);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800923
924 if (eSIR_SUCCESS != sirStatus) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530925 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_FATAL,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800926 "%s: Failed to start MAC", __func__);
927 goto err_wma_stop;
928 }
929
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530930 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_INFO,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800931 "%s: MAC correctly started", __func__);
932
933 /* START SME */
Jeff Johnson8f9dd5f2017-09-13 14:16:08 -0700934 qdf_status = sme_start(gp_cds_context->pMACContext);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800935
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530936 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530937 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_FATAL,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800938 "%s: Failed to start SME", __func__);
939 goto err_mac_stop;
940 }
941
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530942 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_INFO,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800943 "%s: SME correctly started", __func__);
944
Leo Chang9b097032016-10-28 11:03:17 -0700945 if (cdp_soc_attach_target(cds_get_context(QDF_MODULE_ID_SOC))) {
946 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_FATAL,
947 "%s: Failed to attach soc target", __func__);
948 goto err_sme_stop;
949 }
950
951 if (cdp_pdev_attach_target(cds_get_context(QDF_MODULE_ID_SOC),
Venkata Sharath Chandra Manchala0d44d452016-11-23 17:48:15 -0800952 (struct cdp_pdev *)cds_get_context(QDF_MODULE_ID_TXRX))) {
Leo Chang9b097032016-10-28 11:03:17 -0700953 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_FATAL,
954 "%s: Failed to attach pdev target", __func__);
955 goto err_soc_target_detach;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800956 }
957
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530958 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_INFO,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800959 "%s: CDS Start is successful!!", __func__);
960
Min Liu81f2ed32018-01-08 14:21:02 +0800961 qdf_status = dispatcher_psoc_enable(psoc);
962 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
963 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_FATAL,
964 "%s: dispatcher_psoc_enable failed", __func__);
965 goto err_soc_target_detach;
966 }
Rajeev Kumar97767a02016-11-30 11:20:40 -0800967
Nachiket Kukade98f562a2017-12-15 12:18:07 +0530968 /* Trigger psoc enable for CLD components */
969 hdd_component_psoc_enable(psoc);
970
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530971 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800972
Leo Chang9b097032016-10-28 11:03:17 -0700973err_soc_target_detach:
974 /* NOOP */
975
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800976err_sme_stop:
Jeff Johnson8f9dd5f2017-09-13 14:16:08 -0700977 sme_stop(gp_cds_context->pMACContext, HAL_STOP_TYPE_SYS_RESET);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800978
979err_mac_stop:
Jeff Johnson8f9dd5f2017-09-13 14:16:08 -0700980 mac_stop(gp_cds_context->pMACContext, HAL_STOP_TYPE_SYS_RESET);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800981
982err_wma_stop:
Anurag Chouhance0dc992016-02-16 18:18:03 +0530983 qdf_event_reset(&(gp_cds_context->wmaCompleteEvent));
Jeff Johnsonacc1cc72017-09-13 08:47:49 -0700984 qdf_status = wma_stop(HAL_STOP_TYPE_RF_KILL);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530985 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530986 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800987 "%s: Failed to stop wma", __func__);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530988 QDF_ASSERT(QDF_IS_STATUS_SUCCESS(qdf_status));
Jeff Johnson1f8d0a02017-09-13 08:09:05 -0700989 wma_setneedshutdown();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800990 } else {
Anurag Chouhance0dc992016-02-16 18:18:03 +0530991 qdf_status =
Nachiket Kukade0396b732017-11-14 16:35:16 +0530992 qdf_wait_for_event_completion(
993 &gp_cds_context->wmaCompleteEvent,
994 CDS_WMA_TIMEOUT);
Anurag Chouhance0dc992016-02-16 18:18:03 +0530995 if (qdf_status != QDF_STATUS_SUCCESS) {
996 if (qdf_status == QDF_STATUS_E_TIMEOUT) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530997 QDF_TRACE(QDF_MODULE_ID_QDF,
998 QDF_TRACE_LEVEL_FATAL,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800999 "%s: Timeout occurred before WMA_stop complete",
1000 __func__);
1001 } else {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301002 QDF_TRACE(QDF_MODULE_ID_QDF,
1003 QDF_TRACE_LEVEL_FATAL,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001004 "%s: WMA_stop reporting other error",
1005 __func__);
1006 }
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301007 QDF_ASSERT(0);
Jeff Johnson1f8d0a02017-09-13 08:09:05 -07001008 wma_setneedshutdown();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001009 }
1010 }
1011
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301012 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001013} /* cds_enable() */
1014
1015/**
1016 * cds_disable() - stop/disable cds module
Selvaraj, Sridhar0672a122016-12-29 16:11:48 +05301017 * @psoc: Psoc pointer
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001018 *
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05301019 * Return: QDF status
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001020 */
Jeff Johnsonea5c2aa12017-09-13 14:18:59 -07001021QDF_STATUS cds_disable(struct wlan_objmgr_psoc *psoc)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001022{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301023 QDF_STATUS qdf_status;
Arun Khandavallifae92942016-08-01 13:31:08 +05301024 void *handle;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001025
Rajeev Kumar97767a02016-11-30 11:20:40 -08001026 /* PSOC disable for all new components. It needs to happen before
1027 * target is PDEV suspended such that a component can abort all its
1028 * ongoing transaction with FW. Always keep it before wma_stop() as
1029 * wma_stop() does target PDEV suspend.
1030 */
Rajeev Kumar97767a02016-11-30 11:20:40 -08001031
Nachiket Kukade98f562a2017-12-15 12:18:07 +05301032 /* Trigger psoc disable for CLD components */
1033 if (psoc) {
1034 hdd_component_psoc_disable(psoc);
Jiachao Wu341d0752018-01-02 15:20:32 +08001035 dispatcher_psoc_disable(psoc);
Nachiket Kukade98f562a2017-12-15 12:18:07 +05301036 }
Rajeev Kumar97767a02016-11-30 11:20:40 -08001037
Jeff Johnsonacc1cc72017-09-13 08:47:49 -07001038 qdf_status = wma_stop(HAL_STOP_TYPE_RF_KILL);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001039
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301040 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Arun Khandavallifae92942016-08-01 13:31:08 +05301041 cds_err("Failed to stop wma");
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301042 QDF_ASSERT(QDF_IS_STATUS_SUCCESS(qdf_status));
Jeff Johnson1f8d0a02017-09-13 08:09:05 -07001043 wma_setneedshutdown();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001044 }
1045
Arun Khandavallifae92942016-08-01 13:31:08 +05301046 handle = cds_get_context(QDF_MODULE_ID_PE);
1047 if (!handle) {
1048 cds_err("Invalid PE context return!");
1049 return QDF_STATUS_E_INVAL;
1050 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001051
Naveen Rawatbcd3d012017-12-05 11:11:55 -08001052 umac_stop();
Arun Khandavalli55f890b2016-08-31 18:14:56 +05301053
Arun Khandavallifae92942016-08-01 13:31:08 +05301054 return qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001055}
1056
Govind Singhb048e872016-09-27 22:07:43 +05301057#ifdef HIF_USB
1058static inline void cds_suspend_target(tp_wma_handle wma_handle)
1059{
1060 QDF_STATUS status;
1061 /* Suspend the target and disable interrupt */
Mukul Sharma4c60a7e2017-03-06 19:42:18 +05301062 status = pmo_ucfg_psoc_suspend_target(wma_handle->psoc, 0);
Govind Singhb048e872016-09-27 22:07:43 +05301063 if (status)
1064 cds_err("Failed to suspend target, status = %d", status);
1065}
1066#else
1067static inline void cds_suspend_target(tp_wma_handle wma_handle)
1068{
1069 QDF_STATUS status;
1070 /* Suspend the target and disable interrupt */
Mukul Sharma4c60a7e2017-03-06 19:42:18 +05301071 status = pmo_ucfg_psoc_suspend_target(wma_handle->psoc, 1);
Govind Singhb048e872016-09-27 22:07:43 +05301072 if (status)
1073 cds_err("Failed to suspend target, status = %d", status);
1074}
1075#endif /* HIF_USB */
1076
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001077/**
Govind Singhb048e872016-09-27 22:07:43 +05301078 * cds_post_disable() - post disable cds module
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001079 *
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05301080 * Return: QDF status
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001081 */
Rajeev Kumarbe021242017-02-16 16:12:23 -08001082QDF_STATUS cds_post_disable(void)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001083{
Arun Khandavalli55f890b2016-08-31 18:14:56 +05301084 tp_wma_handle wma_handle;
Govind Singhb048e872016-09-27 22:07:43 +05301085 struct hif_opaque_softc *hif_ctx;
Himanshu Agarwal0b9bbc32017-02-23 16:23:05 +05301086 struct cdp_pdev *txrx_pdev;
1087
Arun Khandavalli55f890b2016-08-31 18:14:56 +05301088 wma_handle = cds_get_context(QDF_MODULE_ID_WMA);
1089 if (!wma_handle) {
1090 cds_err("Failed to get wma_handle!");
1091 return QDF_STATUS_E_INVAL;
1092 }
1093
Govind Singhb048e872016-09-27 22:07:43 +05301094 hif_ctx = cds_get_context(QDF_MODULE_ID_HIF);
1095 if (!hif_ctx) {
1096 cds_err("Failed to get hif_handle!");
1097 return QDF_STATUS_E_INVAL;
1098 }
1099
Himanshu Agarwal0b9bbc32017-02-23 16:23:05 +05301100 txrx_pdev = cds_get_context(QDF_MODULE_ID_TXRX);
1101 if (!txrx_pdev) {
1102 cds_err("Failed to get txrx pdev!");
1103 return QDF_STATUS_E_INVAL;
1104 }
1105
Arun Khandavalli55f890b2016-08-31 18:14:56 +05301106 /*
1107 * With new state machine changes cds_close can be invoked without
1108 * cds_disable. So, send the following clean up prerequisites to fw,
1109 * So Fw and host are in sync for cleanup indication:
1110 * - Send PDEV_SUSPEND indication to firmware
1111 * - Disable HIF Interrupts.
1112 * - Clean up CE tasklets.
1113 */
1114
Hanumanth Reddy Pothula2a8a7402017-07-03 14:06:11 +05301115 cds_info("send deinit sequence to firmware");
1116 if (!(cds_is_driver_recovering() || cds_is_driver_in_bad_state()))
Govind Singhb048e872016-09-27 22:07:43 +05301117 cds_suspend_target(wma_handle);
1118 hif_disable_isr(hif_ctx);
1119 hif_reset_soc(hif_ctx);
1120
Wu Gao9a24fa72017-07-28 18:32:22 +08001121 if (gp_cds_context->htc_ctx) {
1122 htc_stop(gp_cds_context->htc_ctx);
1123 }
1124
Himanshu Agarwal0b9bbc32017-02-23 16:23:05 +05301125 cdp_pdev_pre_detach(cds_get_context(QDF_MODULE_ID_SOC),
1126 (struct cdp_pdev *)txrx_pdev, 1);
1127
Govind Singhb048e872016-09-27 22:07:43 +05301128 return QDF_STATUS_SUCCESS;
1129}
1130
1131/**
1132 * cds_close() - close cds module
Selvaraj, Sridhar0672a122016-12-29 16:11:48 +05301133 * @psoc: Psoc pointer
Govind Singhb048e872016-09-27 22:07:43 +05301134 *
1135 * This API allows user to close modules registered
1136 * with connectivity device services.
1137 *
1138 * Return: QDF status
1139 */
Jeff Johnsone4b14592017-09-13 14:23:33 -07001140QDF_STATUS cds_close(struct wlan_objmgr_psoc *psoc)
Govind Singhb048e872016-09-27 22:07:43 +05301141{
1142 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001143
Dustin Brownd33276b2017-11-29 11:08:11 -08001144 qdf_status = cds_sched_close();
1145 QDF_ASSERT(QDF_IS_STATUS_SUCCESS(qdf_status));
1146 if (QDF_IS_STATUS_ERROR(qdf_status))
1147 cds_err("Failed to close CDS Scheduler");
1148
Dustin Brown44cde352017-12-04 13:14:46 -08001149 qdf_status = dispatcher_disable();
1150 QDF_ASSERT(QDF_IS_STATUS_SUCCESS(qdf_status));
1151 if (QDF_IS_STATUS_ERROR(qdf_status))
1152 cds_err("Failed to disable dispatcher; status:%d", qdf_status);
1153
Amar Singhal966397f2017-04-06 18:28:56 -07001154 dispatcher_psoc_close(psoc);
1155
Jeff Johnson6b8473d2017-09-13 09:20:53 -07001156 qdf_status = wma_wmi_work_close();
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301157 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301158 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Xun Luoa858a472015-11-10 08:24:45 -08001159 "%s: Failed to close wma_wmi_work", __func__);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301160 QDF_ASSERT(0);
Xun Luoa858a472015-11-10 08:24:45 -08001161 }
1162
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001163 if (gp_cds_context->htc_ctx) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001164 htc_destroy(gp_cds_context->htc_ctx);
Mukul Sharma4c60a7e2017-03-06 19:42:18 +05301165 pmo_ucfg_psoc_update_htc_handle(psoc, NULL);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001166 gp_cds_context->htc_ctx = NULL;
1167 }
1168
Jeff Johnsone4b14592017-09-13 14:23:33 -07001169 qdf_status = sme_close(gp_cds_context->pMACContext);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301170 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301171 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001172 "%s: Failed to close SME", __func__);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301173 QDF_ASSERT(QDF_IS_STATUS_SUCCESS(qdf_status));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001174 }
1175
Jeff Johnsone4b14592017-09-13 14:23:33 -07001176 qdf_status = mac_close(gp_cds_context->pMACContext);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301177 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301178 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001179 "%s: Failed to close MAC", __func__);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301180 QDF_ASSERT(QDF_IS_STATUS_SUCCESS(qdf_status));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001181 }
1182
Jeff Johnsone4b14592017-09-13 14:23:33 -07001183 gp_cds_context->pMACContext = NULL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001184
Houston Hoffmanbe58cc52016-12-19 16:26:44 -08001185 cdp_soc_detach(gp_cds_context->dp_soc);
Sravan Kumar Kairam27296782017-04-21 22:04:18 +05301186 pmo_ucfg_psoc_update_dp_handle(psoc, NULL);
Houston Hoffmanbe58cc52016-12-19 16:26:44 -08001187
Rajeev Kumar662d75d2017-03-13 18:11:29 -07001188 cds_shutdown_notifier_purge();
1189
Jeff Johnson1b5404e2017-09-13 08:04:46 -07001190 if (true == wma_needshutdown()) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301191 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001192 "%s: Failed to shutdown wma", __func__);
1193 } else {
Jeff Johnson542da352017-09-13 09:17:28 -07001194 qdf_status = wma_close();
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301195 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301196 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001197 "%s: Failed to close wma", __func__);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301198 QDF_ASSERT(QDF_IS_STATUS_SUCCESS(qdf_status));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001199 }
1200 }
1201
Jeff Johnson7b3ddc22017-09-13 09:42:44 -07001202 qdf_status = wma_wmi_service_close();
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301203 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301204 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001205 "%s: Failed to close wma_wmi_service", __func__);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301206 QDF_ASSERT(QDF_IS_STATUS_SUCCESS(qdf_status));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001207 }
1208
Anurag Chouhance0dc992016-02-16 18:18:03 +05301209 qdf_status = qdf_event_destroy(&gp_cds_context->wmaCompleteEvent);
1210 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301211 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001212 "%s: failed to destroy wmaCompleteEvent", __func__);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301213 QDF_ASSERT(QDF_IS_STATUS_SUCCESS(qdf_status));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001214 }
1215
Anurag Chouhance0dc992016-02-16 18:18:03 +05301216 qdf_status = qdf_event_destroy(&gp_cds_context->ProbeEvent);
1217 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301218 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001219 "%s: failed to destroy ProbeEvent", __func__);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301220 QDF_ASSERT(QDF_IS_STATUS_SUCCESS(qdf_status));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001221 }
1222
Arun Khandavallic811dcc2016-06-26 07:37:21 +05301223 cds_deinit_ini_config();
Arun Khandavallifae92942016-08-01 13:31:08 +05301224 qdf_timer_module_deinit();
1225
Krunal Sonid32c6bc2016-10-18 18:00:21 -07001226 cds_deregister_all_modules();
Rajeev Kumar97767a02016-11-30 11:20:40 -08001227
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301228 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001229}
1230
Venkata Sharath Chandra Manchala4aaae0f2017-07-10 11:59:19 -07001231QDF_STATUS cds_dp_close(struct wlan_objmgr_psoc *psoc)
1232{
1233 void *ctx;
1234
1235 cdp_txrx_intr_detach(gp_cds_context->dp_soc);
1236
1237 ctx = cds_get_context(QDF_MODULE_ID_TXRX);
Venkata Sharath Chandra Manchala4aaae0f2017-07-10 11:59:19 -07001238 cdp_pdev_detach(cds_get_context(QDF_MODULE_ID_SOC),
1239 (struct cdp_pdev *)ctx, 1);
psimhadeea0a12017-12-18 14:50:02 -08001240 cds_set_context(QDF_MODULE_ID_TXRX, NULL);
1241 pmo_ucfg_psoc_set_txrx_handle(psoc, NULL);
Venkata Sharath Chandra Manchala4aaae0f2017-07-10 11:59:19 -07001242
1243 return QDF_STATUS_SUCCESS;
1244}
1245
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001246/**
1247 * cds_get_context() - get context data area
1248 *
1249 * @moduleId: ID of the module who's context data is being retrived.
1250 *
1251 * Each module in the system has a context / data area that is allocated
1252 * and managed by CDS. This API allows any user to get a pointer to its
1253 * allocated context data area from the CDS global context.
1254 *
1255 * Return: pointer to the context data area of the module ID
1256 * specified, or NULL if the context data is not allocated for
1257 * the module ID specified
1258 */
Anurag Chouhan6d760662016-02-20 16:05:43 +05301259void *cds_get_context(QDF_MODULE_ID moduleId)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001260{
1261 void *pModContext = NULL;
1262
1263 if (gp_cds_context == NULL) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301264 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001265 "%s: cds context pointer is null", __func__);
1266 return NULL;
1267 }
1268
1269 switch (moduleId) {
Anurag Chouhan6d760662016-02-20 16:05:43 +05301270 case QDF_MODULE_ID_HDD:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001271 {
1272 pModContext = gp_cds_context->pHDDContext;
1273 break;
1274 }
1275
Anurag Chouhan6d760662016-02-20 16:05:43 +05301276 case QDF_MODULE_ID_SME:
1277 case QDF_MODULE_ID_PE:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001278 {
1279 /* In all these cases, we just return the MAC Context */
1280 pModContext = gp_cds_context->pMACContext;
1281 break;
1282 }
1283
Anurag Chouhan6d760662016-02-20 16:05:43 +05301284 case QDF_MODULE_ID_WMA:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001285 {
1286 /* For wma module */
1287 pModContext = gp_cds_context->pWMAContext;
1288 break;
1289 }
1290
Anurag Chouhan6d760662016-02-20 16:05:43 +05301291 case QDF_MODULE_ID_QDF:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001292 {
1293 /* For SYS this is CDS itself */
1294 pModContext = gp_cds_context;
1295 break;
1296 }
1297
Anurag Chouhan6d760662016-02-20 16:05:43 +05301298 case QDF_MODULE_ID_HIF:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001299 {
1300 pModContext = gp_cds_context->pHIFContext;
1301 break;
1302 }
1303
Anurag Chouhan6d760662016-02-20 16:05:43 +05301304 case QDF_MODULE_ID_HTC:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001305 {
1306 pModContext = gp_cds_context->htc_ctx;
1307 break;
1308 }
1309
Anurag Chouhan6d760662016-02-20 16:05:43 +05301310 case QDF_MODULE_ID_QDF_DEVICE:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001311 {
Anurag Chouhan6d760662016-02-20 16:05:43 +05301312 pModContext = gp_cds_context->qdf_ctx;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001313 break;
1314 }
1315
Anurag Chouhan6d760662016-02-20 16:05:43 +05301316 case QDF_MODULE_ID_BMI:
Komal Seelamd9106492016-02-15 10:31:44 +05301317 {
1318 pModContext = gp_cds_context->g_ol_context;
1319 break;
1320 }
1321
Anurag Chouhan6d760662016-02-20 16:05:43 +05301322 case QDF_MODULE_ID_TXRX:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001323 {
Venkata Sharath Chandra Manchala0d44d452016-11-23 17:48:15 -08001324 pModContext = (void *)gp_cds_context->pdev_txrx_ctx;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001325 break;
1326 }
1327
Anurag Chouhan6d760662016-02-20 16:05:43 +05301328 case QDF_MODULE_ID_CFG:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001329 {
1330 pModContext = gp_cds_context->cfg_ctx;
1331 break;
1332 }
1333
Leo Chang9b097032016-10-28 11:03:17 -07001334 case QDF_MODULE_ID_SOC:
1335 {
1336 pModContext = gp_cds_context->dp_soc;
1337 break;
1338 }
1339
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001340 default:
1341 {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301342 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001343 "%s: Module ID %i does not have its context maintained by CDS",
1344 __func__, moduleId);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301345 QDF_ASSERT(0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001346 return NULL;
1347 }
1348 }
1349
1350 if (pModContext == NULL) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301351 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001352 "%s: Module ID %i context is Null", __func__,
1353 moduleId);
1354 }
1355
1356 return pModContext;
1357} /* cds_get_context() */
1358
1359/**
1360 * cds_get_global_context() - get CDS global Context
1361 *
1362 * This API allows any user to get the CDS Global Context pointer from a
1363 * module context data area.
1364 *
1365 * Return: pointer to the CDS global context, NULL if the function is
1366 * unable to retreive the CDS context.
1367 */
Jeff Johnson31a67582017-09-26 14:54:28 -07001368void *cds_get_global_context(void)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001369{
1370 if (gp_cds_context == NULL) {
Ryan Hsuceddceb2016-04-28 10:20:14 -07001371 /*
1372 * To avoid recursive call, this should not change to
1373 * QDF_TRACE().
1374 */
1375 pr_err("%s: global cds context is NULL", __func__);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001376 }
1377
1378 return gp_cds_context;
1379} /* cds_get_global_context() */
1380
1381/**
Prashanth Bhatta9e143052015-12-04 11:56:47 -08001382 * cds_get_driver_state() - Get current driver state
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001383 *
Prashanth Bhatta9e143052015-12-04 11:56:47 -08001384 * This API returns current driver state stored in global context.
1385 *
1386 * Return: Driver state enum
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001387 */
Prashanth Bhatta9e143052015-12-04 11:56:47 -08001388enum cds_driver_state cds_get_driver_state(void)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001389{
1390 if (gp_cds_context == NULL) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301391 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001392 "%s: global cds context is NULL", __func__);
Prashanth Bhatta9e143052015-12-04 11:56:47 -08001393
1394 return CDS_DRIVER_STATE_UNINITIALIZED;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001395 }
1396
Prashanth Bhatta9e143052015-12-04 11:56:47 -08001397 return gp_cds_context->driver_state;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001398}
1399
1400/**
Prashanth Bhatta9e143052015-12-04 11:56:47 -08001401 * cds_set_driver_state() - Set current driver state
1402 * @state: Driver state to be set to.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001403 *
Prashanth Bhatta9e143052015-12-04 11:56:47 -08001404 * This API sets driver state to state. This API only sets the state and doesn't
1405 * clear states, please make sure to use cds_clear_driver_state to clear any
1406 * state if required.
1407 *
1408 * Return: None
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001409 */
Prashanth Bhatta9e143052015-12-04 11:56:47 -08001410void cds_set_driver_state(enum cds_driver_state state)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001411{
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001412 if (gp_cds_context == NULL) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301413 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prashanth Bhatta9e143052015-12-04 11:56:47 -08001414 "%s: global cds context is NULL: %x", __func__,
1415 state);
1416
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001417 return;
1418 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001419
Prashanth Bhatta9e143052015-12-04 11:56:47 -08001420 gp_cds_context->driver_state |= state;
1421}
1422
1423/**
1424 * cds_clear_driver_state() - Clear current driver state
1425 * @state: Driver state to be cleared.
1426 *
1427 * This API clears driver state. This API only clears the state, please make
1428 * sure to use cds_set_driver_state to set any new states.
1429 *
1430 * Return: None
1431 */
1432void cds_clear_driver_state(enum cds_driver_state state)
1433{
1434 if (gp_cds_context == NULL) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301435 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prashanth Bhatta9e143052015-12-04 11:56:47 -08001436 "%s: global cds context is NULL: %x", __func__,
1437 state);
1438
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001439 return;
1440 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001441
Prashanth Bhatta9e143052015-12-04 11:56:47 -08001442 gp_cds_context->driver_state &= ~state;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001443}
1444
Nachiket Kukade8003d252017-03-30 15:55:58 +05301445enum cds_fw_state cds_get_fw_state(void)
1446{
1447 if (gp_cds_context == NULL) {
1448 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
1449 "%s: global cds context is NULL", __func__);
1450
1451 return CDS_FW_STATE_UNINITIALIZED;
1452 }
1453
1454 return gp_cds_context->fw_state;
1455}
1456
1457void cds_set_fw_state(enum cds_fw_state state)
1458{
1459 if (gp_cds_context == NULL) {
1460 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
1461 "%s: global cds context is NULL: %d", __func__,
1462 state);
1463
1464 return;
1465 }
1466
1467 qdf_atomic_set_bit(state, &gp_cds_context->fw_state);
1468}
1469
1470void cds_clear_fw_state(enum cds_fw_state state)
1471{
1472 if (gp_cds_context == NULL) {
1473 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
1474 "%s: global cds context is NULL: %d", __func__,
1475 state);
1476
1477 return;
1478 }
1479
1480 qdf_atomic_clear_bit(state, &gp_cds_context->fw_state);
1481}
1482
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001483/**
1484 * cds_alloc_context() - allocate a context within the CDS global Context
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001485 * @moduleId: module ID who's context area is being allocated.
1486 * @ppModuleContext: pointer to location where the pointer to the
1487 * allocated context is returned. Note this output pointer
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301488 * is valid only if the API returns QDF_STATUS_SUCCESS
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001489 * @param size: size of the context area to be allocated.
1490 *
1491 * This API allows any user to allocate a user context area within the
1492 * CDS Global Context.
1493 *
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05301494 * Return: QDF status
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001495 */
Jeff Johnsonadb3b1c2017-09-13 10:42:36 -07001496QDF_STATUS cds_alloc_context(QDF_MODULE_ID moduleID,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001497 void **ppModuleContext, uint32_t size)
1498{
1499 void **pGpModContext = NULL;
1500
Jeff Johnsonadb3b1c2017-09-13 10:42:36 -07001501 if (!gp_cds_context) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301502 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001503 "%s: cds context is null", __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301504 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001505 }
1506
Jeff Johnsonadb3b1c2017-09-13 10:42:36 -07001507 if (!ppModuleContext) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301508 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Jeff Johnsonadb3b1c2017-09-13 10:42:36 -07001509 "%s: null param passed",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001510 __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301511 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001512 }
1513
1514 switch (moduleID) {
Anurag Chouhan6d760662016-02-20 16:05:43 +05301515 case QDF_MODULE_ID_WMA:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001516 pGpModContext = &(gp_cds_context->pWMAContext);
1517 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001518
Anurag Chouhan6d760662016-02-20 16:05:43 +05301519 case QDF_MODULE_ID_HIF:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001520 pGpModContext = &(gp_cds_context->pHIFContext);
1521 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001522
Anurag Chouhan6d760662016-02-20 16:05:43 +05301523 case QDF_MODULE_ID_BMI:
Komal Seelamd9106492016-02-15 10:31:44 +05301524 pGpModContext = &(gp_cds_context->g_ol_context);
1525 break;
Komal Seelamd9106492016-02-15 10:31:44 +05301526
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001527 default:
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301528 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Jeff Johnsonadb3b1c2017-09-13 10:42:36 -07001529 "%s: Module ID %i does not have its context allocated by CDS",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001530 __func__, moduleID);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301531 QDF_ASSERT(0);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301532 return QDF_STATUS_E_INVAL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001533 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001534
Jeff Johnsonadb3b1c2017-09-13 10:42:36 -07001535 if (*pGpModContext) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001536 /* Context has already been allocated!
1537 * Prevent double allocation
1538 */
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301539 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001540 "%s: Module ID %i context has already been allocated",
1541 __func__, moduleID);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301542 return QDF_STATUS_E_EXISTS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001543 }
1544
1545 /* Dynamically allocate the context for module */
1546
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301547 *ppModuleContext = qdf_mem_malloc(size);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001548
Jeff Johnsonadb3b1c2017-09-13 10:42:36 -07001549 if (!*ppModuleContext) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301550 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Jeff Johnsonadb3b1c2017-09-13 10:42:36 -07001551 "%s: Failed to allocate Context for module ID %i",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001552 __func__, moduleID);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301553 QDF_ASSERT(0);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301554 return QDF_STATUS_E_NOMEM;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001555 }
1556
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001557 *pGpModContext = *ppModuleContext;
1558
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301559 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001560} /* cds_alloc_context() */
1561
1562/**
Komal Seelamad5a90d2016-02-16 13:50:03 +05301563 * cds_set_context() - API to set context in global CDS Context
Komal Seelam1aac1982016-03-02 15:57:26 +05301564 * @module_id: Module ID
Komal Seelamad5a90d2016-02-16 13:50:03 +05301565 * @context: Pointer to the Module Context
1566 *
Komal Seelam1aac1982016-03-02 15:57:26 +05301567 * API to set a MODULE Context in global CDS Context
Komal Seelamad5a90d2016-02-16 13:50:03 +05301568 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301569 * Return: QDF_STATUS
Komal Seelamad5a90d2016-02-16 13:50:03 +05301570 */
Anurag Chouhan6d760662016-02-20 16:05:43 +05301571QDF_STATUS cds_set_context(QDF_MODULE_ID module_id, void *context)
Komal Seelamad5a90d2016-02-16 13:50:03 +05301572{
1573 p_cds_contextType p_cds_context = cds_get_global_context();
1574
1575 if (!p_cds_context) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301576 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Komal Seelam1aac1982016-03-02 15:57:26 +05301577 "cds context is Invalid");
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301578 return QDF_STATUS_NOT_INITIALIZED;
Komal Seelamad5a90d2016-02-16 13:50:03 +05301579 }
1580
1581 switch (module_id) {
Jeff Johnson3543fb22017-09-24 13:44:13 -07001582 case QDF_MODULE_ID_HDD:
1583 p_cds_context->pHDDContext = context;
1584 break;
Houston Hoffman57c36d72017-01-30 12:47:02 -08001585 case QDF_MODULE_ID_TXRX:
1586 p_cds_context->pdev_txrx_ctx = context;
1587 break;
Anurag Chouhan6d760662016-02-20 16:05:43 +05301588 case QDF_MODULE_ID_HIF:
Komal Seelamad5a90d2016-02-16 13:50:03 +05301589 p_cds_context->pHIFContext = context;
1590 break;
1591 default:
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301592 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Komal Seelam1aac1982016-03-02 15:57:26 +05301593 "%s: Module ID %i does not have its context managed by CDS",
1594 __func__, module_id);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301595 QDF_ASSERT(0);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301596 return QDF_STATUS_E_INVAL;
Komal Seelamad5a90d2016-02-16 13:50:03 +05301597 }
1598
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301599 return QDF_STATUS_SUCCESS;
Komal Seelamad5a90d2016-02-16 13:50:03 +05301600}
1601
1602/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001603 * cds_free_context() - free an allocated context within the
1604 * CDS global Context
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001605 * @moduleId: module ID who's context area is being free
1606 * @pModuleContext: pointer to module context area to be free'd.
1607 *
1608 * This API allows a user to free the user context area within the
1609 * CDS Global Context.
1610 *
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05301611 * Return: QDF status
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001612 */
Jeff Johnsonadb3b1c2017-09-13 10:42:36 -07001613QDF_STATUS cds_free_context(QDF_MODULE_ID moduleID, void *pModuleContext)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001614{
1615 void **pGpModContext = NULL;
1616
Jeff Johnsonadb3b1c2017-09-13 10:42:36 -07001617 if (!gp_cds_context) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301618 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Jeff Johnsonadb3b1c2017-09-13 10:42:36 -07001619 "%s: cds context is null", __func__);
1620 return QDF_STATUS_E_FAILURE;
1621 }
1622
1623 if (!pModuleContext) {
1624 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
1625 "%s: Null param", __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301626 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001627 }
1628
1629 switch (moduleID) {
Anurag Chouhan6d760662016-02-20 16:05:43 +05301630 case QDF_MODULE_ID_WMA:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001631 pGpModContext = &(gp_cds_context->pWMAContext);
1632 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001633
Anurag Chouhan6d760662016-02-20 16:05:43 +05301634 case QDF_MODULE_ID_HIF:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001635 pGpModContext = &(gp_cds_context->pHIFContext);
1636 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001637
Anurag Chouhan6d760662016-02-20 16:05:43 +05301638 case QDF_MODULE_ID_TXRX:
Venkata Sharath Chandra Manchala0d44d452016-11-23 17:48:15 -08001639 pGpModContext = (void **)&(gp_cds_context->pdev_txrx_ctx);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001640 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001641
Anurag Chouhan6d760662016-02-20 16:05:43 +05301642 case QDF_MODULE_ID_BMI:
Komal Seelamd9106492016-02-15 10:31:44 +05301643 pGpModContext = &(gp_cds_context->g_ol_context);
1644 break;
Komal Seelamd9106492016-02-15 10:31:44 +05301645
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001646 default:
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301647 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001648 "%s: Module ID %i "
1649 "does not have its context allocated by CDS",
1650 __func__, moduleID);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301651 QDF_ASSERT(0);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301652 return QDF_STATUS_E_INVAL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001653 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001654
1655 if (NULL == *pGpModContext) {
1656 /* Context has not been allocated or freed already! */
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301657 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Jeff Johnsonadb3b1c2017-09-13 10:42:36 -07001658 "%s: Module ID %i context has not been allocated or freed already",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001659 __func__, moduleID);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301660 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001661 }
1662
1663 if (*pGpModContext != pModuleContext) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301664 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001665 "%s: pGpModContext != pModuleContext", __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301666 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001667 }
1668
Jeff Johnsonadb3b1c2017-09-13 10:42:36 -07001669 qdf_mem_free(pModuleContext);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001670
1671 *pGpModContext = NULL;
1672
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301673 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001674} /* cds_free_context() */
1675
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001676/**
1677 * cds_sys_probe_thread_cback() - probe mc thread callback
1678 * @pUserData: pointer to user data
1679 *
1680 * Return: none
1681 */
1682void cds_sys_probe_thread_cback(void *pUserData)
1683{
1684 if (gp_cds_context != pUserData) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301685 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001686 "%s: gp_cds_context != pUserData", __func__);
1687 return;
1688 }
1689
Anurag Chouhance0dc992016-02-16 18:18:03 +05301690 if (qdf_event_set(&gp_cds_context->ProbeEvent) != QDF_STATUS_SUCCESS) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301691 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Anurag Chouhance0dc992016-02-16 18:18:03 +05301692 "%s: qdf_event_set failed", __func__);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001693 return;
1694 }
1695} /* cds_sys_probe_thread_cback() */
1696
1697/**
1698 * cds_wma_complete_cback() - wma complete callback
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001699 *
1700 * Return: none
1701 */
Jeff Johnsonf7ab8142017-09-13 09:04:23 -07001702void cds_wma_complete_cback(void)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001703{
Jeff Johnsonf7ab8142017-09-13 09:04:23 -07001704 if (!gp_cds_context) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301705 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Jeff Johnsonf7ab8142017-09-13 09:04:23 -07001706 "%s: invalid gp_cds_context", __func__);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001707 return;
1708 }
1709
Anurag Chouhance0dc992016-02-16 18:18:03 +05301710 if (qdf_event_set(&gp_cds_context->wmaCompleteEvent) !=
1711 QDF_STATUS_SUCCESS) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301712 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Anurag Chouhance0dc992016-02-16 18:18:03 +05301713 "%s: qdf_event_set failed", __func__);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001714 return;
1715 }
1716} /* cds_wma_complete_cback() */
1717
1718/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001719 * cds_get_vdev_types() - get vdev type
1720 * @mode: mode
1721 * @type: type
1722 * @sub_type: sub_type
1723 *
1724 * Return: WMI vdev type
1725 */
Jeff Johnsonc1e62782017-11-09 09:50:17 -08001726QDF_STATUS cds_get_vdev_types(enum QDF_OPMODE mode, uint32_t *type,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001727 uint32_t *sub_type)
1728{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301729 QDF_STATUS status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001730 *type = 0;
1731 *sub_type = 0;
1732
1733 switch (mode) {
Anurag Chouhan6d760662016-02-20 16:05:43 +05301734 case QDF_STA_MODE:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001735 *type = WMI_VDEV_TYPE_STA;
1736 break;
Anurag Chouhan6d760662016-02-20 16:05:43 +05301737 case QDF_SAP_MODE:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001738 *type = WMI_VDEV_TYPE_AP;
1739 break;
Anurag Chouhan6d760662016-02-20 16:05:43 +05301740 case QDF_P2P_DEVICE_MODE:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001741 *type = WMI_VDEV_TYPE_AP;
1742 *sub_type = WMI_UNIFIED_VDEV_SUBTYPE_P2P_DEVICE;
1743 break;
Anurag Chouhan6d760662016-02-20 16:05:43 +05301744 case QDF_P2P_CLIENT_MODE:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001745 *type = WMI_VDEV_TYPE_STA;
1746 *sub_type = WMI_UNIFIED_VDEV_SUBTYPE_P2P_CLIENT;
1747 break;
Anurag Chouhan6d760662016-02-20 16:05:43 +05301748 case QDF_P2P_GO_MODE:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001749 *type = WMI_VDEV_TYPE_AP;
1750 *sub_type = WMI_UNIFIED_VDEV_SUBTYPE_P2P_GO;
1751 break;
Anurag Chouhan6d760662016-02-20 16:05:43 +05301752 case QDF_OCB_MODE:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001753 *type = WMI_VDEV_TYPE_OCB;
1754 break;
Krunal Soni8c37e322016-02-03 16:08:37 -08001755 case QDF_IBSS_MODE:
1756 *type = WMI_VDEV_TYPE_IBSS;
1757 break;
Manjunathappa Prakashb7573722016-04-21 11:24:07 -07001758 case QDF_MONITOR_MODE:
1759 *type = WMI_VDEV_TYPE_MONITOR;
1760 break;
Deepak Dhamdheree2dd5442016-05-27 15:05:51 -07001761 case QDF_NDI_MODE:
1762 *type = WMI_VDEV_TYPE_NDI;
1763 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001764 default:
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301765 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Ryan Hsud7e6fc72015-12-07 17:26:14 -08001766 "Invalid device mode %d", mode);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301767 status = QDF_STATUS_E_INVAL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001768 break;
1769 }
1770 return status;
1771}
1772
1773/**
1774 * cds_flush_work() - flush pending works
1775 * @work: pointer to work
1776 *
1777 * Return: none
1778 */
1779void cds_flush_work(void *work)
1780{
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001781 cancel_work_sync(work);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001782}
1783
1784/**
1785 * cds_flush_delayed_work() - flush delayed works
1786 * @dwork: pointer to delayed work
1787 *
1788 * Return: none
1789 */
1790void cds_flush_delayed_work(void *dwork)
1791{
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001792 cancel_delayed_work_sync(dwork);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001793}
1794
1795/**
1796 * cds_is_packet_log_enabled() - check if packet log is enabled
1797 *
1798 * Return: true if packet log is enabled else false
1799 */
1800bool cds_is_packet_log_enabled(void)
1801{
Jeff Johnsonc18b26c2017-09-03 08:46:45 -07001802 struct hdd_context *hdd_ctx;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001803
Jeff Johnsonc18b26c2017-09-03 08:46:45 -07001804 hdd_ctx = (struct hdd_context *) (gp_cds_context->pHDDContext);
1805 if ((NULL == hdd_ctx) || (NULL == hdd_ctx->config)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301806 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_FATAL,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001807 "%s: Hdd Context is Null", __func__);
1808 return false;
1809 }
Jeff Johnsonc18b26c2017-09-03 08:46:45 -07001810 return hdd_ctx->config->enablePacketLog;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001811}
1812
Dustin Brown100201e2017-07-10 11:48:40 -07001813static int cds_force_assert_target_via_pld(qdf_device_t qdf)
Mukul Sharmab7b575b2016-10-02 23:37:07 +05301814{
Dustin Brown100201e2017-07-10 11:48:40 -07001815 int errno;
1816
1817 errno = pld_force_assert_target(qdf->dev);
1818 if (errno == -EOPNOTSUPP)
1819 cds_info("PLD does not support target force assert");
1820 else if (errno)
1821 cds_err("Failed PLD target force assert; errno %d", errno);
1822 else
1823 cds_info("Target force assert triggered via PLD");
1824
1825 return errno;
Mukul Sharmab7b575b2016-10-02 23:37:07 +05301826}
1827
Dustin Brown100201e2017-07-10 11:48:40 -07001828static QDF_STATUS cds_force_assert_target_via_wmi(qdf_device_t qdf)
Rajeev Kumardb60f162017-07-25 20:27:59 -07001829{
Dustin Brown100201e2017-07-10 11:48:40 -07001830 QDF_STATUS status;
1831 t_wma_handle *wma;
1832
1833 wma = cds_get_context(QDF_MODULE_ID_WMA);
1834 if (!wma) {
1835 cds_err("wma is null");
1836 return QDF_STATUS_E_INVAL;
1837 }
1838
1839 status = wma_crash_inject(wma, RECOVERY_SIM_SELF_RECOVERY, 0);
1840 if (QDF_IS_STATUS_ERROR(status)) {
1841 cds_err("Failed target force assert; status %d", status);
1842 return status;
1843 }
1844
Nachiket Kukade0396b732017-11-14 16:35:16 +05301845 status = qdf_wait_for_event_completion(&wma->recovery_event,
Dustin Brown100201e2017-07-10 11:48:40 -07001846 WMA_CRASH_INJECT_TIMEOUT);
1847 if (QDF_IS_STATUS_ERROR(status)) {
1848 cds_err("Failed target force assert wait; status %d", status);
1849 return status;
1850 }
1851
1852 return QDF_STATUS_SUCCESS;
1853}
1854
1855/**
1856 * cds_force_assert_target() - Send assert command to firmware
1857 * @qdf: QDF device instance to assert
1858 *
1859 * An out-of-band recovery mechanism will cleanup and restart the entire wlan
1860 * subsystem in the event of a firmware crash. This API injects a firmware
1861 * crash to start this process when the wlan driver is known to be in a bad
1862 * state. If a firmware assert inject fails, the wlan driver will schedule
1863 * the driver recovery anyway, as a best effort attempt to return to a working
1864 * state.
1865 *
1866 * Return: QDF_STATUS
1867 */
1868static QDF_STATUS cds_force_assert_target(qdf_device_t qdf)
1869{
1870 int errno;
1871 QDF_STATUS status;
1872
1873 /* first, try target assert inject via pld */
1874 errno = cds_force_assert_target_via_pld(qdf);
1875 if (!errno)
1876 return QDF_STATUS_SUCCESS;
1877 if (errno != -EOPNOTSUPP)
1878 return QDF_STATUS_E_FAILURE;
1879
1880 /* pld assert is not supported, try target assert inject via wmi */
1881 status = cds_force_assert_target_via_wmi(qdf);
1882 if (QDF_IS_STATUS_SUCCESS(status))
1883 return QDF_STATUS_SUCCESS;
1884
1885 /* wmi assert failed, start recovery without the firmware assert */
1886 cds_err("Scheduling recovery work without firmware assert");
1887 cds_set_recovery_in_progress(true);
1888 pld_schedule_recovery_work(qdf->dev, PLD_REASON_DEFAULT);
1889
1890 return status;
Rajeev Kumardb60f162017-07-25 20:27:59 -07001891}
1892
Mukul Sharmab7b575b2016-10-02 23:37:07 +05301893/**
Srinivas Girigowda161b9f22017-07-24 17:38:09 -07001894 * cds_trigger_recovery_work() - trigger self recovery work
Mukul Sharmab7b575b2016-10-02 23:37:07 +05301895 *
1896 * Return: none
1897 */
Srinivas Girigowda161b9f22017-07-24 17:38:09 -07001898static void cds_trigger_recovery_work(void *param)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001899{
Dustin Brown100201e2017-07-10 11:48:40 -07001900 QDF_STATUS status;
1901 qdf_runtime_lock_t rtl;
1902 qdf_device_t qdf;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001903
Kabilan Kannan973744a2018-01-03 10:28:50 -08001904 if (cds_is_driver_recovering()) {
1905 cds_err("Recovery in progress; ignoring recovery trigger");
Sameer Thalappilec2e9c72017-02-08 15:45:49 -08001906 return;
1907 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001908
Kabilan Kannan973744a2018-01-03 10:28:50 -08001909 if (cds_is_driver_in_bad_state()) {
1910 cds_err("Driver is in bad state; ignoring recovery trigger");
Houston Hoffmanc7c72a82015-12-07 15:30:48 -08001911 return;
1912 }
1913
Rajeev Kumar6dd45a82017-10-20 14:43:05 -07001914 if (cds_is_fw_down()) {
1915 cds_err("FW is down; ignoring recovery trigger");
1916 return;
1917 }
1918
Kabilan Kannan973744a2018-01-03 10:28:50 -08001919 if (!cds_is_self_recovery_enabled()) {
1920 cds_err("Recovery is not enabled");
1921 QDF_BUG(0);
1922 return;
1923 }
1924
Dustin Brown100201e2017-07-10 11:48:40 -07001925 qdf = cds_get_context(QDF_MODULE_ID_QDF_DEVICE);
1926 if (!qdf) {
1927 cds_err("Qdf context is null");
1928 return;
Sameer Thalappilac5d26e2017-01-10 15:32:58 -08001929 }
1930
Dustin Brown100201e2017-07-10 11:48:40 -07001931 status = qdf_runtime_lock_init(&rtl);
1932 if (QDF_IS_STATUS_ERROR(status)) {
Srinivas Girigowda161b9f22017-07-24 17:38:09 -07001933 cds_err("qdf_runtime_lock_init failed, status: %d", status);
Dustin Brown100201e2017-07-10 11:48:40 -07001934 return;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001935 }
Houston Hoffmanc7c72a82015-12-07 15:30:48 -08001936
Dustin Brown100201e2017-07-10 11:48:40 -07001937 status = qdf_runtime_pm_prevent_suspend(&rtl);
1938 if (QDF_IS_STATUS_ERROR(status)) {
1939 cds_err("Failed to acquire runtime pm lock");
1940 goto deinit_rtl;
1941 }
1942
1943 cds_force_assert_target(qdf);
1944
1945 status = qdf_runtime_pm_allow_suspend(&rtl);
1946 if (QDF_IS_STATUS_ERROR(status))
1947 cds_err("Failed to release runtime pm lock");
1948
1949deinit_rtl:
1950 qdf_runtime_lock_deinit(&rtl);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001951}
1952
1953/**
Anurag Chouhan4085ff72017-10-05 18:09:56 +05301954 * cds_get_recovery_reason() - get self recovery reason
1955 * @reason: recovery reason
1956 *
1957 * Return: None
1958 */
1959void cds_get_recovery_reason(enum qdf_hang_reason *reason)
1960{
1961 if (!gp_cds_context) {
1962 cds_err("gp_cds_context is null");
1963 return;
1964 }
1965
1966 *reason = gp_cds_context->recovery_reason;
1967}
1968
1969/**
1970 * cds_reset_recovery_reason() - reset the reason to unspecified
1971 *
1972 * Return: None
1973 */
1974void cds_reset_recovery_reason(void)
1975{
1976 if (!gp_cds_context) {
1977 cds_err("gp_cds_context is null");
1978 return;
1979 }
1980
1981 gp_cds_context->recovery_reason = QDF_REASON_UNSPECIFIED;
1982}
1983
1984/**
Srinivas Girigowda161b9f22017-07-24 17:38:09 -07001985 * cds_trigger_recovery() - trigger self recovery
Anurag Chouhan4085ff72017-10-05 18:09:56 +05301986 * @reason: recovery reason
Srinivas Girigowda161b9f22017-07-24 17:38:09 -07001987 *
1988 * Return: none
1989 */
Anurag Chouhan4085ff72017-10-05 18:09:56 +05301990void cds_trigger_recovery(enum qdf_hang_reason reason)
Srinivas Girigowda161b9f22017-07-24 17:38:09 -07001991{
Anurag Chouhan4085ff72017-10-05 18:09:56 +05301992 if (!gp_cds_context) {
1993 cds_err("gp_cds_context is null");
1994 return;
1995 }
1996
1997 gp_cds_context->recovery_reason = reason;
Srinivas Girigowda161b9f22017-07-24 17:38:09 -07001998 if (in_atomic()) {
1999 qdf_queue_work(0, gp_cds_context->cds_recovery_wq,
2000 &gp_cds_context->cds_recovery_work);
2001 return;
2002 }
2003 cds_trigger_recovery_work(NULL);
2004}
2005
2006/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002007 * cds_get_monotonic_boottime() - Get kernel boot time.
2008 *
2009 * Return: Time in microseconds
2010 */
2011
2012uint64_t cds_get_monotonic_boottime(void)
2013{
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002014 struct timespec ts;
2015
Yuanyuan Liu2e03b412016-04-06 14:36:15 -07002016 get_monotonic_boottime(&ts);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002017 return ((uint64_t) ts.tv_sec * 1000000) + (ts.tv_nsec / 1000);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002018}
2019
2020/**
2021 * cds_set_wakelock_logging() - Logging of wakelock enabled/disabled
2022 * @value: Boolean value
2023 *
2024 * This function is used to set the flag which will indicate whether
2025 * logging of wakelock is enabled or not
2026 *
2027 * Return: None
2028 */
2029void cds_set_wakelock_logging(bool value)
2030{
2031 p_cds_contextType p_cds_context;
2032
2033 p_cds_context = cds_get_global_context();
2034 if (!p_cds_context) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302035 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002036 "cds context is Invald");
2037 return;
2038 }
2039 p_cds_context->is_wakelock_log_enabled = value;
2040}
2041
2042/**
2043 * cds_is_wakelock_enabled() - Check if logging of wakelock is enabled/disabled
2044 * @value: Boolean value
2045 *
2046 * This function is used to check whether logging of wakelock is enabled or not
2047 *
2048 * Return: true if logging of wakelock is enabled
2049 */
2050bool cds_is_wakelock_enabled(void)
2051{
2052 p_cds_contextType p_cds_context;
2053
2054 p_cds_context = cds_get_global_context();
2055 if (!p_cds_context) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302056 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002057 "cds context is Invald");
2058 return false;
2059 }
2060 return p_cds_context->is_wakelock_log_enabled;
2061}
2062
2063/**
2064 * cds_set_ring_log_level() - Sets the log level of a particular ring
2065 * @ring_id: ring_id
2066 * @log_levelvalue: Log level specificed
2067 *
2068 * This function converts HLOS values to driver log levels and sets the log
2069 * level of a particular ring accordingly.
2070 *
2071 * Return: None
2072 */
2073void cds_set_ring_log_level(uint32_t ring_id, uint32_t log_level)
2074{
2075 p_cds_contextType p_cds_context;
2076 uint32_t log_val;
2077
2078 p_cds_context = cds_get_global_context();
2079 if (!p_cds_context) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302080 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002081 "%s: cds context is Invald", __func__);
2082 return;
2083 }
2084
2085 switch (log_level) {
2086 case LOG_LEVEL_NO_COLLECTION:
2087 log_val = WLAN_LOG_LEVEL_OFF;
2088 break;
2089 case LOG_LEVEL_NORMAL_COLLECT:
2090 log_val = WLAN_LOG_LEVEL_NORMAL;
2091 break;
2092 case LOG_LEVEL_ISSUE_REPRO:
2093 log_val = WLAN_LOG_LEVEL_REPRO;
2094 break;
2095 case LOG_LEVEL_ACTIVE:
2096 default:
2097 log_val = WLAN_LOG_LEVEL_ACTIVE;
2098 break;
2099 }
2100
2101 if (ring_id == RING_ID_WAKELOCK) {
2102 p_cds_context->wakelock_log_level = log_val;
2103 return;
2104 } else if (ring_id == RING_ID_CONNECTIVITY) {
2105 p_cds_context->connectivity_log_level = log_val;
2106 return;
2107 } else if (ring_id == RING_ID_PER_PACKET_STATS) {
2108 p_cds_context->packet_stats_log_level = log_val;
2109 return;
Chandrasekaran, Manishekar907c2af2015-11-13 12:50:04 +05302110 } else if (ring_id == RING_ID_DRIVER_DEBUG) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002111 p_cds_context->driver_debug_log_level = log_val;
2112 return;
2113 } else if (ring_id == RING_ID_FIRMWARE_DEBUG) {
2114 p_cds_context->fw_debug_log_level = log_val;
2115 return;
2116 }
2117}
2118
2119/**
2120 * cds_get_ring_log_level() - Get the a ring id's log level
2121 * @ring_id: Ring id
2122 *
2123 * Fetch and return the log level corresponding to a ring id
2124 *
2125 * Return: Log level corresponding to the ring ID
2126 */
2127enum wifi_driver_log_level cds_get_ring_log_level(uint32_t ring_id)
2128{
2129 p_cds_contextType p_cds_context;
2130
2131 p_cds_context = cds_get_global_context();
2132 if (!p_cds_context) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302133 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002134 "%s: cds context is Invald", __func__);
2135 return WLAN_LOG_LEVEL_OFF;
2136 }
2137
2138 if (ring_id == RING_ID_WAKELOCK)
2139 return p_cds_context->wakelock_log_level;
2140 else if (ring_id == RING_ID_CONNECTIVITY)
2141 return p_cds_context->connectivity_log_level;
2142 else if (ring_id == RING_ID_PER_PACKET_STATS)
2143 return p_cds_context->packet_stats_log_level;
Chandrasekaran, Manishekar907c2af2015-11-13 12:50:04 +05302144 else if (ring_id == RING_ID_DRIVER_DEBUG)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002145 return p_cds_context->driver_debug_log_level;
2146 else if (ring_id == RING_ID_FIRMWARE_DEBUG)
2147 return p_cds_context->fw_debug_log_level;
2148
2149 return WLAN_LOG_LEVEL_OFF;
2150}
2151
2152/**
2153 * cds_set_multicast_logging() - Set mutlicast logging value
2154 * @value: Value of multicast logging
2155 *
2156 * Set the multicast logging value which will indicate
2157 * whether to multicast host and fw messages even
2158 * without any registration by userspace entity
2159 *
2160 * Return: None
2161 */
2162void cds_set_multicast_logging(uint8_t value)
2163{
2164 cds_multicast_logging = value;
2165}
2166
2167/**
2168 * cds_is_multicast_logging() - Get multicast logging value
2169 *
2170 * Get the multicast logging value which will indicate
2171 * whether to multicast host and fw messages even
2172 * without any registration by userspace entity
2173 *
2174 * Return: 0 - Multicast logging disabled, 1 - Multicast logging enabled
2175 */
2176uint8_t cds_is_multicast_logging(void)
2177{
2178 return cds_multicast_logging;
2179}
2180
2181/*
2182 * cds_init_log_completion() - Initialize log param structure
2183 *
2184 * This function is used to initialize the logging related
2185 * parameters
2186 *
2187 * Return: None
2188 */
2189void cds_init_log_completion(void)
2190{
2191 p_cds_contextType p_cds_context;
2192
2193 p_cds_context = cds_get_global_context();
2194 if (!p_cds_context) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302195 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002196 "%s: cds context is Invalid", __func__);
2197 return;
2198 }
2199
2200 p_cds_context->log_complete.is_fatal = WLAN_LOG_TYPE_NON_FATAL;
2201 p_cds_context->log_complete.indicator = WLAN_LOG_INDICATOR_UNUSED;
2202 p_cds_context->log_complete.reason_code = WLAN_LOG_REASON_CODE_UNUSED;
2203 p_cds_context->log_complete.is_report_in_progress = false;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002204}
2205
2206/**
2207 * cds_set_log_completion() - Store the logging params
2208 * @is_fatal: Indicates if the event triggering bug report is fatal or not
2209 * @indicator: Source which trigerred the bug report
2210 * @reason_code: Reason for triggering bug report
Abhishek Singh5ea86532016-04-27 14:10:53 +05302211 * @recovery_needed: If recovery is needed after bug report
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002212 *
2213 * This function is used to set the logging parameters based on the
2214 * caller
2215 *
2216 * Return: 0 if setting of params is successful
2217 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302218QDF_STATUS cds_set_log_completion(uint32_t is_fatal,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002219 uint32_t indicator,
Abhishek Singh5ea86532016-04-27 14:10:53 +05302220 uint32_t reason_code,
2221 bool recovery_needed)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002222{
2223 p_cds_contextType p_cds_context;
2224
2225 p_cds_context = cds_get_global_context();
2226 if (!p_cds_context) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302227 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002228 "%s: cds context is Invalid", __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302229 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002230 }
2231
Anurag Chouhana37b5b72016-02-21 14:53:42 +05302232 qdf_spinlock_acquire(&p_cds_context->bug_report_lock);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002233 p_cds_context->log_complete.is_fatal = is_fatal;
2234 p_cds_context->log_complete.indicator = indicator;
2235 p_cds_context->log_complete.reason_code = reason_code;
Abhishek Singh5ea86532016-04-27 14:10:53 +05302236 p_cds_context->log_complete.recovery_needed = recovery_needed;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002237 p_cds_context->log_complete.is_report_in_progress = true;
Anurag Chouhana37b5b72016-02-21 14:53:42 +05302238 qdf_spinlock_release(&p_cds_context->bug_report_lock);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302239 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002240}
2241
2242/**
Abhishek Singh5ea86532016-04-27 14:10:53 +05302243 * cds_get_and_reset_log_completion() - Get and reset logging related params
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002244 * @is_fatal: Indicates if the event triggering bug report is fatal or not
2245 * @indicator: Source which trigerred the bug report
2246 * @reason_code: Reason for triggering bug report
Abhishek Singh5ea86532016-04-27 14:10:53 +05302247 * @recovery_needed: If recovery is needed after bug report
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002248 *
2249 * This function is used to get the logging related parameters
2250 *
2251 * Return: None
2252 */
Abhishek Singh5ea86532016-04-27 14:10:53 +05302253void cds_get_and_reset_log_completion(uint32_t *is_fatal,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002254 uint32_t *indicator,
Abhishek Singh5ea86532016-04-27 14:10:53 +05302255 uint32_t *reason_code,
2256 bool *recovery_needed)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002257{
2258 p_cds_contextType p_cds_context;
2259
2260 p_cds_context = cds_get_global_context();
2261 if (!p_cds_context) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302262 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002263 "%s: cds context is Invalid", __func__);
2264 return;
2265 }
2266
Anurag Chouhana37b5b72016-02-21 14:53:42 +05302267 qdf_spinlock_acquire(&p_cds_context->bug_report_lock);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002268 *is_fatal = p_cds_context->log_complete.is_fatal;
2269 *indicator = p_cds_context->log_complete.indicator;
2270 *reason_code = p_cds_context->log_complete.reason_code;
Abhishek Singh5ea86532016-04-27 14:10:53 +05302271 *recovery_needed = p_cds_context->log_complete.recovery_needed;
2272
2273 /* reset */
2274 p_cds_context->log_complete.indicator = WLAN_LOG_INDICATOR_UNUSED;
2275 p_cds_context->log_complete.is_fatal = WLAN_LOG_TYPE_NON_FATAL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002276 p_cds_context->log_complete.is_report_in_progress = false;
Abhishek Singh5ea86532016-04-27 14:10:53 +05302277 p_cds_context->log_complete.reason_code = WLAN_LOG_REASON_CODE_UNUSED;
2278 p_cds_context->log_complete.recovery_needed = false;
Anurag Chouhana37b5b72016-02-21 14:53:42 +05302279 qdf_spinlock_release(&p_cds_context->bug_report_lock);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002280}
2281
2282/**
2283 * cds_is_log_report_in_progress() - Check if bug reporting is in progress
2284 *
2285 * This function is used to check if the bug reporting is already in progress
2286 *
2287 * Return: true if the bug reporting is in progress
2288 */
2289bool cds_is_log_report_in_progress(void)
2290{
2291 p_cds_contextType p_cds_context;
2292
2293 p_cds_context = cds_get_global_context();
2294 if (!p_cds_context) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302295 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002296 "%s: cds context is Invalid", __func__);
2297 return true;
2298 }
2299 return p_cds_context->log_complete.is_report_in_progress;
2300}
2301
2302/**
Abhishek Singh5ea86532016-04-27 14:10:53 +05302303 * cds_is_fatal_event_enabled() - Return if fatal event is enabled
2304 *
2305 * Return true if fatal event is enabled.
2306 */
2307bool cds_is_fatal_event_enabled(void)
2308{
2309 p_cds_contextType p_cds_context;
2310
2311 p_cds_context = cds_get_global_context();
2312 if (!p_cds_context) {
2313 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
2314 "%s: cds context is Invalid", __func__);
2315 return false;
2316 }
2317
2318
2319 return p_cds_context->enable_fatal_event;
2320}
2321
Yu Wang66a250b2017-07-19 11:46:40 +08002322#ifdef WLAN_FEATURE_TSF_PLUS
2323bool cds_is_ptp_rx_opt_enabled(void)
2324{
2325 struct hdd_context *hdd_ctx;
2326 p_cds_contextType p_cds_context;
2327
2328 p_cds_context = cds_get_global_context();
2329 if (!p_cds_context) {
2330 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
2331 "%s: cds context is Invalid", __func__);
2332 return false;
2333 }
2334
2335 hdd_ctx = (struct hdd_context *)(p_cds_context->pHDDContext);
2336 if ((NULL == hdd_ctx) || (NULL == hdd_ctx->config)) {
2337 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
2338 "%s: Hdd Context is Null", __func__);
2339 return false;
2340 }
2341
2342 return HDD_TSF_IS_RX_SET(hdd_ctx);
2343}
2344
2345bool cds_is_ptp_tx_opt_enabled(void)
2346{
2347 struct hdd_context *hdd_ctx;
2348 p_cds_contextType p_cds_context;
2349
2350 p_cds_context = cds_get_global_context();
2351 if (!p_cds_context) {
2352 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
2353 "%s: cds context is Invalid", __func__);
2354 return false;
2355 }
2356
2357 hdd_ctx = (struct hdd_context *)(p_cds_context->pHDDContext);
2358 if ((NULL == hdd_ctx) || (NULL == hdd_ctx->config)) {
2359 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
2360 "%s: Hdd Context is Null", __func__);
2361 return false;
2362 }
2363
2364 return HDD_TSF_IS_TX_SET(hdd_ctx);
2365}
2366#endif
2367
Abhishek Singh5ea86532016-04-27 14:10:53 +05302368/**
2369 * cds_get_log_indicator() - Get the log flush indicator
2370 *
2371 * This function is used to get the log flush indicator
2372 *
2373 * Return: log indicator
2374 */
2375uint32_t cds_get_log_indicator(void)
2376{
2377 p_cds_contextType p_cds_context;
2378 uint32_t indicator;
2379
2380 p_cds_context = cds_get_global_context();
2381 if (!p_cds_context) {
2382 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
2383 "%s: cds context is Invalid", __func__);
2384 return WLAN_LOG_INDICATOR_UNUSED;
2385 }
2386
2387 if (cds_is_load_or_unload_in_progress() ||
Hanumanth Reddy Pothula2a8a7402017-07-03 14:06:11 +05302388 cds_is_driver_recovering() || cds_is_driver_in_bad_state()) {
Abhishek Singh5ea86532016-04-27 14:10:53 +05302389 return WLAN_LOG_INDICATOR_UNUSED;
2390 }
2391
2392 qdf_spinlock_acquire(&p_cds_context->bug_report_lock);
2393 indicator = p_cds_context->log_complete.indicator;
2394 qdf_spinlock_release(&p_cds_context->bug_report_lock);
2395 return indicator;
2396}
2397
2398/**
2399 * cds_wlan_flush_host_logs_for_fatal() - Wrapper to flush host logs
2400 *
2401 * This function is used to send signal to the logger thread to
2402 * flush the host logs.
2403 *
2404 * Return: None
2405 *
2406 */
2407void cds_wlan_flush_host_logs_for_fatal(void)
2408{
2409 wlan_flush_host_logs_for_fatal();
2410}
2411
2412/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002413 * cds_flush_logs() - Report fatal event to userspace
2414 * @is_fatal: Indicates if the event triggering bug report is fatal or not
2415 * @indicator: Source which trigerred the bug report
2416 * @reason_code: Reason for triggering bug report
Abhishek Singh5ea86532016-04-27 14:10:53 +05302417 * @dump_mac_trace: If mac trace are needed in logs.
2418 * @recovery_needed: If recovery is needed after bug report
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002419 *
2420 * This function sets the log related params and send the WMI command to the
2421 * FW to flush its logs. On receiving the flush completion event from the FW
2422 * the same will be conveyed to userspace
2423 *
2424 * Return: 0 on success
2425 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302426QDF_STATUS cds_flush_logs(uint32_t is_fatal,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002427 uint32_t indicator,
Abhishek Singh5ea86532016-04-27 14:10:53 +05302428 uint32_t reason_code,
2429 bool dump_mac_trace,
2430 bool recovery_needed)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002431{
2432 uint32_t ret;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302433 QDF_STATUS status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002434
2435 p_cds_contextType p_cds_context;
2436
2437 p_cds_context = cds_get_global_context();
2438 if (!p_cds_context) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302439 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002440 "%s: cds context is Invalid", __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302441 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002442 }
Abhishek Singh5ea86532016-04-27 14:10:53 +05302443 if (!p_cds_context->enable_fatal_event) {
2444 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
2445 "%s: Fatal event not enabled", __func__);
2446 return QDF_STATUS_E_FAILURE;
2447 }
2448 if (cds_is_load_or_unload_in_progress() ||
Hanumanth Reddy Pothula2a8a7402017-07-03 14:06:11 +05302449 cds_is_driver_recovering() || cds_is_driver_in_bad_state()) {
Abhishek Singh5ea86532016-04-27 14:10:53 +05302450 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
2451 "%s: un/Load/SSR in progress", __func__);
2452 return QDF_STATUS_E_FAILURE;
2453 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002454
2455 if (cds_is_log_report_in_progress() == true) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302456 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002457 "%s: Bug report already in progress - dropping! type:%d, indicator=%d reason_code=%d",
2458 __func__, is_fatal, indicator, reason_code);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302459 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002460 }
2461
Abhishek Singh5ea86532016-04-27 14:10:53 +05302462 status = cds_set_log_completion(is_fatal, indicator,
2463 reason_code, recovery_needed);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302464 if (QDF_STATUS_SUCCESS != status) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302465 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002466 "%s: Failed to set log trigger params", __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302467 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002468 }
2469
Srinivas Girigowda80213e52018-01-23 14:51:33 -08002470 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_INFO,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002471 "%s: Triggering bug report: type:%d, indicator=%d reason_code=%d",
2472 __func__, is_fatal, indicator, reason_code);
2473
Abhishek Singh5ea86532016-04-27 14:10:53 +05302474 if (dump_mac_trace)
2475 qdf_trace_dump_all(p_cds_context->pMACContext, 0, 0, 500, 0);
2476
2477 if (WLAN_LOG_INDICATOR_HOST_ONLY == indicator) {
2478 cds_wlan_flush_host_logs_for_fatal();
2479 return QDF_STATUS_SUCCESS;
2480 }
2481
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002482 ret = sme_send_flush_logs_cmd_to_fw(p_cds_context->pMACContext);
2483 if (0 != ret) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302484 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002485 "%s: Failed to send flush FW log", __func__);
2486 cds_init_log_completion();
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302487 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002488 }
2489
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302490 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002491}
2492
2493/**
2494 * cds_logging_set_fw_flush_complete() - Wrapper for FW log flush completion
2495 *
2496 * This function is used to send signal to the logger thread to indicate
2497 * that the flushing of FW logs is complete by the FW
2498 *
2499 * Return: None
2500 *
2501 */
2502void cds_logging_set_fw_flush_complete(void)
2503{
2504 wlan_logging_set_fw_flush_complete();
2505}
Abhishek Singh5ea86532016-04-27 14:10:53 +05302506
2507/**
2508 * cds_set_fatal_event() - set fatal event status
2509 * @value: pending statue to set
2510 *
2511 * Return: None
2512 */
2513void cds_set_fatal_event(bool value)
2514{
2515 p_cds_contextType p_cds_context;
2516
2517 p_cds_context = cds_get_global_context();
2518 if (!p_cds_context) {
2519 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
2520 "%s: cds context is Invalid", __func__);
2521 return;
2522 }
2523 p_cds_context->enable_fatal_event = value;
2524}
2525
Ryan Hsuceddceb2016-04-28 10:20:14 -07002526/**
2527 * cds_get_radio_index() - get radio index
2528 *
2529 * Return: radio index otherwise, -EINVAL
2530 */
2531int cds_get_radio_index(void)
2532{
2533 p_cds_contextType p_cds_context;
2534
2535 p_cds_context = cds_get_global_context();
2536 if (!p_cds_context) {
2537 /*
2538 * To avoid recursive call, this should not change to
2539 * QDF_TRACE().
2540 */
2541 pr_err("%s: cds context is invalid\n", __func__);
2542 return -EINVAL;
2543 }
2544
2545 return p_cds_context->radio_index;
2546}
2547
2548/**
2549 * cds_set_radio_index() - set radio index
2550 * @radio_index: the radio index to set
2551 *
2552 * Return: QDF status
2553 */
2554QDF_STATUS cds_set_radio_index(int radio_index)
2555{
2556 p_cds_contextType p_cds_context;
2557
2558 p_cds_context = cds_get_global_context();
2559 if (!p_cds_context) {
2560 pr_err("%s: cds context is invalid\n", __func__);
2561 return QDF_STATUS_E_FAILURE;
2562 }
2563
2564 p_cds_context->radio_index = radio_index;
2565
2566 return QDF_STATUS_SUCCESS;
2567}
Arun Khandavallic811dcc2016-06-26 07:37:21 +05302568
2569/**
2570 * cds_init_ini_config() - API to initialize CDS configuration parameters
2571 * @cfg: CDS Configuration
2572 *
2573 * Return: void
2574 */
2575
2576void cds_init_ini_config(struct cds_config_info *cfg)
2577{
2578 cds_context_type *cds_ctx;
2579
2580 cds_ctx = cds_get_context(QDF_MODULE_ID_QDF);
2581 if (!cds_ctx) {
2582 cds_err("Invalid CDS Context");
2583 return;
2584 }
2585
2586 cds_ctx->cds_cfg = cfg;
2587}
2588
2589/**
2590 * cds_deinit_ini_config() - API to free CDS configuration parameters
2591 *
2592 * Return: void
2593 */
2594void cds_deinit_ini_config(void)
2595{
2596 cds_context_type *cds_ctx;
2597
2598 cds_ctx = cds_get_context(QDF_MODULE_ID_QDF);
2599 if (!cds_ctx) {
2600 cds_err("Invalid CDS Context");
2601 return;
2602 }
2603
Arun Khandavallif6246632016-08-17 17:43:06 +05302604 if (cds_ctx->cds_cfg)
Arun Khandavallic811dcc2016-06-26 07:37:21 +05302605 qdf_mem_free(cds_ctx->cds_cfg);
2606
2607 cds_ctx->cds_cfg = NULL;
2608}
2609
2610/**
2611 * cds_get_ini_config() - API to get CDS configuration parameters
2612 *
2613 * Return: cds config structure
2614 */
2615struct cds_config_info *cds_get_ini_config(void)
2616{
2617 cds_context_type *cds_ctx;
2618
2619 cds_ctx = cds_get_context(QDF_MODULE_ID_QDF);
2620 if (!cds_ctx) {
2621 cds_err("Invalid CDS Context");
2622 return NULL;
2623 }
2624
2625 return cds_ctx->cds_cfg;
2626}
Naveen Rawat64e477e2016-05-20 10:34:56 -07002627
2628/**
2629 * cds_is_5_mhz_enabled() - API to get 5MHZ enabled
2630 *
2631 * Return: true if 5 mhz is enabled, false otherwise
2632 */
2633bool cds_is_5_mhz_enabled(void)
2634{
2635 p_cds_contextType p_cds_context;
2636
2637 p_cds_context = cds_get_context(QDF_MODULE_ID_QDF);
2638 if (!p_cds_context) {
2639 cds_err("%s: cds context is invalid", __func__);
2640 return false;
2641 }
2642
2643 if (p_cds_context->cds_cfg)
2644 return (p_cds_context->cds_cfg->sub_20_channel_width ==
2645 WLAN_SUB_20_CH_WIDTH_5);
2646
2647 return false;
2648}
2649
2650/**
2651 * cds_is_10_mhz_enabled() - API to get 10-MHZ enabled
2652 *
2653 * Return: true if 10 mhz is enabled, false otherwise
2654 */
2655bool cds_is_10_mhz_enabled(void)
2656{
2657 p_cds_contextType p_cds_context;
2658
2659 p_cds_context = cds_get_context(QDF_MODULE_ID_QDF);
2660 if (!p_cds_context) {
2661 cds_err("%s: cds context is invalid", __func__);
2662 return false;
2663 }
2664
2665 if (p_cds_context->cds_cfg)
2666 return (p_cds_context->cds_cfg->sub_20_channel_width ==
2667 WLAN_SUB_20_CH_WIDTH_10);
2668
2669 return false;
2670}
2671
2672/**
2673 * cds_is_sub_20_mhz_enabled() - API to get sub 20-MHZ enabled
2674 *
2675 * Return: true if 5 or 10 mhz is enabled, false otherwise
2676 */
2677bool cds_is_sub_20_mhz_enabled(void)
2678{
2679 p_cds_contextType p_cds_context;
2680
2681 p_cds_context = cds_get_context(QDF_MODULE_ID_QDF);
2682 if (!p_cds_context) {
2683 cds_err("%s: cds context is invalid", __func__);
2684 return false;
2685 }
2686
2687 if (p_cds_context->cds_cfg)
2688 return p_cds_context->cds_cfg->sub_20_channel_width;
2689
2690 return false;
2691}
2692
Komal Seelam78ff65a2016-08-18 15:25:24 +05302693/**
Naveen Rawat91df30a2016-10-12 21:26:18 -07002694 * cds_is_self_recovery_enabled() - API to get self recovery enabled
2695 *
2696 * Return: true if self recovery enabled, false otherwise
2697 */
2698bool cds_is_self_recovery_enabled(void)
2699{
2700 p_cds_contextType p_cds_context;
2701
2702 p_cds_context = cds_get_context(QDF_MODULE_ID_QDF);
2703 if (!p_cds_context) {
2704 cds_err("%s: cds context is invalid", __func__);
2705 return false;
2706 }
2707
2708 if (p_cds_context->cds_cfg)
2709 return p_cds_context->cds_cfg->self_recovery_enabled;
2710
2711 return false;
2712}
2713
2714/**
Komal Seelam78ff65a2016-08-18 15:25:24 +05302715 * cds_svc_fw_shutdown_ind() - API to send userspace about FW crash
2716 *
2717 * @dev: Device Pointer
2718 *
2719 * Return: None
2720 */
2721void cds_svc_fw_shutdown_ind(struct device *dev)
2722{
2723 hdd_svc_fw_shutdown_ind(dev);
2724}
Himanshu Agarwal46956a52016-07-26 19:46:25 +05302725
Nirav Shaheb017be2018-02-15 11:20:58 +05302726#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
Himanshu Agarwal46956a52016-07-26 19:46:25 +05302727/*
2728 * cds_pkt_stats_to_logger_thread() - send pktstats to user
2729 * @pl_hdr: Pointer to pl_hdr
2730 * @pkt_dump: Pointer to pkt_dump data structure.
2731 * @data: Pointer to data
2732 *
2733 * This function is used to send the pkt stats to SVC module.
2734 *
2735 * Return: None
2736 */
2737inline void cds_pkt_stats_to_logger_thread(void *pl_hdr, void *pkt_dump,
2738 void *data)
2739{
2740 if (cds_get_ring_log_level(RING_ID_PER_PACKET_STATS) !=
2741 WLAN_LOG_LEVEL_ACTIVE)
2742 return;
2743
2744 wlan_pkt_stats_to_logger_thread(pl_hdr, pkt_dump, data);
2745}
Nirav Shaheb017be2018-02-15 11:20:58 +05302746#endif
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -08002747
2748/**
2749 * cds_get_conparam() - Get the connection mode parameters
2750 *
2751 * Return the connection mode parameter set by insmod or set during statically
2752 * linked driver
2753 *
Jeff Johnson876c1a62017-12-12 10:43:07 -08002754 * Return: enum QDF_GLOBAL_MODE
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -08002755 */
Jeff Johnson876c1a62017-12-12 10:43:07 -08002756enum QDF_GLOBAL_MODE cds_get_conparam(void)
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -08002757{
Jeff Johnson876c1a62017-12-12 10:43:07 -08002758 enum QDF_GLOBAL_MODE con_mode;
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -08002759
2760 con_mode = hdd_get_conparam();
2761
2762 return con_mode;
2763}
Dustin Brown8d2d0f52017-04-03 17:02:08 -07002764
2765#ifdef WMI_INTERFACE_EVENT_LOGGING
2766inline void
2767cds_print_htc_credit_history(uint32_t count, qdf_abstract_print *print,
2768 void *print_priv)
2769{
2770 htc_print_credit_history(gp_cds_context->htc_ctx, count,
2771 print, print_priv);
2772}
2773#endif
Sravan Kumar Kairamc1ae71c2017-02-24 12:27:27 +05302774
2775/**
2776 * cds_get_arp_stats_gw_ip() - get arp stats track IP
2777 *
2778 * Return: ARP stats IP to track
2779 */
2780uint32_t cds_get_arp_stats_gw_ip(void)
2781{
2782 struct hdd_context *hdd_ctx;
2783
2784 hdd_ctx = (struct hdd_context *) (gp_cds_context->pHDDContext);
2785 if (!hdd_ctx) {
2786 cds_err("Hdd Context is Null");
2787 return 0;
2788 }
2789
2790 return hdd_ctx->track_arp_ip;
2791}
2792
2793/**
2794 * cds_incr_arp_stats_tx_tgt_delivered() - increment ARP stats
2795 *
2796 * Return: none
2797 */
2798void cds_incr_arp_stats_tx_tgt_delivered(void)
2799{
2800 struct hdd_context *hdd_ctx;
2801 struct hdd_adapter *adapter = NULL;
2802
2803 hdd_ctx = (struct hdd_context *) (gp_cds_context->pHDDContext);
2804 if (!hdd_ctx) {
2805 cds_err("Hdd Context is Null");
2806 return;
2807 }
2808
2809 hdd_for_each_adapter(hdd_ctx, adapter) {
2810 if (QDF_STA_MODE == adapter->device_mode)
2811 break;
2812 }
2813
2814 if (adapter)
2815 adapter->hdd_stats.hdd_arp_stats.tx_host_fw_sent++;
2816}
2817
2818/**
2819 * cds_incr_arp_stats_tx_tgt_acked() - increment ARP stats
2820 *
2821 * Return: none
2822 */
2823void cds_incr_arp_stats_tx_tgt_acked(void)
2824{
2825 struct hdd_context *hdd_ctx;
2826 struct hdd_adapter *adapter = NULL;
2827
2828 hdd_ctx = (struct hdd_context *) (gp_cds_context->pHDDContext);
2829 if (!hdd_ctx) {
2830 cds_err("Hdd Context is Null");
2831 return;
2832 }
2833
2834 hdd_for_each_adapter(hdd_ctx, adapter) {
2835 if (QDF_STA_MODE == adapter->device_mode)
2836 break;
2837 }
2838
2839 if (adapter)
2840 adapter->hdd_stats.hdd_arp_stats.tx_ack_cnt++;
2841}