blob: 3fbfb0fdc6e31f7d9e7eb67706da9b11753dc39d [file] [log] [blame]
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001/*
Rajeev Kumar08ef0d62016-12-28 21:26:55 -08002 * Copyright (c) 2012-2017 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"
Venkata Sharath Chandra Manchala0d44d452016-11-23 17:48:15 -080070
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080071/* Preprocessor Definitions and Constants */
72
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080073/* Data definitions */
74static cds_context_type g_cds_context;
75static p_cds_contextType gp_cds_context;
Anurag Chouhandf2b2682016-02-29 14:15:27 +053076static struct __qdf_device g_qdf_ctx;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080077
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080078static uint8_t cds_multicast_logging;
79
Leo Chang9b097032016-10-28 11:03:17 -070080static struct ol_if_ops dp_ol_if_ops = {
81 .peer_set_default_routing = wma_peer_set_default_routing,
82 .peer_rx_reorder_queue_setup = wma_peer_rx_reorder_queue_setup,
83 .peer_rx_reorder_queue_remove = wma_peer_rx_reorder_queue_remove,
Dhanashri Atref5e02122017-04-13 15:36:42 -070084 .is_hw_dbs_2x2_capable = policy_mgr_is_hw_dbs_2x2_capable,
85 .lro_hash_config = wma_lro_config_cmd
Leo Chang9b097032016-10-28 11:03:17 -070086 /* TODO: Add any other control path calls required to OL_IF/WMA layer */
87};
88
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080089void cds_sys_probe_thread_cback(void *pUserData);
Srinivas Girigowda161b9f22017-07-24 17:38:09 -070090static void cds_trigger_recovery_work(void *param);
91
92/**
93 * cds_recovery_work_init() - Initialize recovery work queue
94 *
95 * Return: none
96 */
97static QDF_STATUS cds_recovery_work_init(void)
98{
99 qdf_create_work(0, &gp_cds_context->cds_recovery_work,
100 cds_trigger_recovery_work, NULL);
101 gp_cds_context->cds_recovery_wq =
102 qdf_create_workqueue("cds_recovery_workqueue");
103 if (NULL == gp_cds_context->cds_recovery_wq) {
104 cds_err("Failed to create cds_recovery_workqueue");
105 return QDF_STATUS_E_FAILURE;
106 }
107
108 return QDF_STATUS_SUCCESS;
109}
110
111/**
112 * cds_recovery_work_deinit() - Initialize recovery work queue
113 *
114 * Return: none
115 */
116static void cds_recovery_work_deinit(void)
117{
118 if (gp_cds_context->cds_recovery_wq) {
119 qdf_flush_workqueue(0, gp_cds_context->cds_recovery_wq);
120 qdf_destroy_workqueue(0, gp_cds_context->cds_recovery_wq);
121 }
122}
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800123
Venkata Sharath Chandra Manchala83985632017-02-28 14:16:22 -0800124/** cds_get_datapath_handles - Initialize pdev, vdev and soc
125 * @soc - soc handle
126 * @vdev - virtual handle
127 * @pdev - physical handle
128 */
129uint8_t cds_get_datapath_handles(void **soc, struct cdp_pdev **pdev,
130 struct cdp_vdev **vdev, uint8_t sessionId)
131{
132
133 (*soc) = cds_get_context(QDF_MODULE_ID_SOC);
134
135 if (!(*soc)) {
136 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
137 "soc handle is invalid");
138 return -EINVAL;
139 }
140
141 (*pdev) = cds_get_context(QDF_MODULE_ID_TXRX);
142
143 if (!(*pdev)) {
144 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
145 "pdev handle is invalid");
146 return -EINVAL;
147 }
148
149 (*vdev) = cdp_get_vdev_from_vdev_id((*soc), (*pdev),
150 sessionId);
151
152 if (!(*vdev)) {
153 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
154 "vdev handle is invalid");
155 return -EINVAL;
156 }
157 return 0;
158}
159
160
Jeff Johnson7aaeeea2017-09-26 13:16:24 -0700161QDF_STATUS cds_init(void)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800162{
Mahesh Kumar Kalikot Veetil319dbcd2016-10-27 15:03:48 -0700163 qdf_debugfs_init();
Houston Hoffman1a777572017-01-13 12:43:48 -0800164 qdf_lock_stats_init();
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530165 qdf_mem_init();
Houston Hoffman9e06e542016-12-12 12:06:26 -0800166 qdf_mc_timer_manager_init();
Dustin Browna2dcb5f2017-10-20 17:36:19 -0700167 qdf_cpuhp_init();
Dustin Brown100201e2017-07-10 11:48:40 -0700168 qdf_register_self_recovery_callback(cds_trigger_recovery);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800169
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800170 gp_cds_context = &g_cds_context;
171
Anurag Chouhandf2b2682016-02-29 14:15:27 +0530172 gp_cds_context->qdf_ctx = &g_qdf_ctx;
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530173 qdf_mem_zero(&g_qdf_ctx, sizeof(g_qdf_ctx));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800174
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530175 qdf_trace_spin_lock_init();
Prashanth Bhatta5da711e2015-11-30 14:28:52 -0800176
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800177#if defined(TRACE_RECORD)
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530178 qdf_trace_init();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800179#endif
Padma, Santhosh Kumar9aba02f2016-08-11 16:30:25 +0530180 qdf_register_debugcb_init();
Prashanth Bhatta5da711e2015-11-30 14:28:52 -0800181
182 cds_ssr_protect_init();
183
Srinivas Girigowda161b9f22017-07-24 17:38:09 -0700184 cds_recovery_work_init();
185
Jeff Johnson7aaeeea2017-09-26 13:16:24 -0700186 return gp_cds_context ? QDF_STATUS_SUCCESS : QDF_STATUS_E_FAILURE;
Prashanth Bhatta5da711e2015-11-30 14:28:52 -0800187}
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800188
189/**
Prashanth Bhatta5da711e2015-11-30 14:28:52 -0800190 * cds_deinit() - Deinitialize CDS
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800191 *
Prashanth Bhatta5da711e2015-11-30 14:28:52 -0800192 * This function frees the CDS resources
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800193 */
Prashanth Bhatta5da711e2015-11-30 14:28:52 -0800194void cds_deinit(void)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800195{
Prashanth Bhatta5da711e2015-11-30 14:28:52 -0800196 if (gp_cds_context == NULL)
197 return;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800198
Srinivas Girigowda161b9f22017-07-24 17:38:09 -0700199 cds_recovery_work_deinit();
Dustin Browna2dcb5f2017-10-20 17:36:19 -0700200 qdf_cpuhp_deinit();
Arunk Khandavalli4cc97a92016-09-14 23:13:07 +0530201 qdf_mc_timer_manager_exit();
202 qdf_mem_exit();
Houston Hoffman1a777572017-01-13 12:43:48 -0800203 qdf_lock_stats_deinit();
Mahesh Kumar Kalikot Veetil319dbcd2016-10-27 15:03:48 -0700204 qdf_debugfs_exit();
Arunk Khandavalli4cc97a92016-09-14 23:13:07 +0530205
Anurag Chouhan6d760662016-02-20 16:05:43 +0530206 gp_cds_context->qdf_ctx = NULL;
Prashanth Bhatta5da711e2015-11-30 14:28:52 -0800207 gp_cds_context = NULL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800208
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530209 qdf_mem_zero(&g_cds_context, sizeof(g_cds_context));
Prashanth Bhatta5da711e2015-11-30 14:28:52 -0800210 return;
211}
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800212
Abhishek Singh437606a2016-04-27 13:51:49 +0530213#ifdef FEATURE_WLAN_DIAG_SUPPORT
214/**
215 * cds_tdls_tx_rx_mgmt_event()- send tdls mgmt rx tx event
216 * @event_id: event id
217 * @tx_rx: tx or rx
218 * @type: type of frame
219 * @action_sub_type: action frame type
220 * @peer_mac: peer mac
221 *
222 * This Function sends tdls mgmt rx tx diag event
223 *
224 * Return: void.
225 */
226void cds_tdls_tx_rx_mgmt_event(uint8_t event_id, uint8_t tx_rx,
227 uint8_t type, uint8_t action_sub_type, uint8_t *peer_mac)
228{
229 WLAN_HOST_DIAG_EVENT_DEF(tdls_tx_rx_mgmt,
230 struct host_event_tdls_tx_rx_mgmt);
231
232 tdls_tx_rx_mgmt.event_id = event_id;
233 tdls_tx_rx_mgmt.tx_rx = tx_rx;
234 tdls_tx_rx_mgmt.type = type;
235 tdls_tx_rx_mgmt.action_sub_type = action_sub_type;
236 qdf_mem_copy(tdls_tx_rx_mgmt.peer_mac,
237 peer_mac, CDS_MAC_ADDRESS_LEN);
238 WLAN_HOST_DIAG_EVENT_REPORT(&tdls_tx_rx_mgmt,
239 EVENT_WLAN_TDLS_TX_RX_MGMT);
240}
241#endif
242
Leo Chang9b097032016-10-28 11:03:17 -0700243/**
gbian62edd7e2017-03-07 13:12:13 +0800244 * cds_cfg_update_ac_specs_params() - update ac_specs params
245 * @olcfg: cfg handle
246 * @mac_params: mac params
247 *
248 * Return: none
249 */
250static void
251cds_cfg_update_ac_specs_params(struct txrx_pdev_cfg_param_t *olcfg,
252 struct cds_config_info *cds_cfg)
253{
254 int i;
255
256 if (NULL == olcfg)
257 return;
258
259 if (NULL == cds_cfg)
260 return;
261
262 for (i = 0; i < OL_TX_NUM_WMM_AC; i++) {
263 olcfg->ac_specs[i].wrr_skip_weight =
264 cds_cfg->ac_specs[i].wrr_skip_weight;
265 olcfg->ac_specs[i].credit_threshold =
266 cds_cfg->ac_specs[i].credit_threshold;
267 olcfg->ac_specs[i].send_limit =
268 cds_cfg->ac_specs[i].send_limit;
269 olcfg->ac_specs[i].credit_reserve =
270 cds_cfg->ac_specs[i].credit_reserve;
271 olcfg->ac_specs[i].discard_weight =
272 cds_cfg->ac_specs[i].discard_weight;
273 }
274}
275
276/**
Leo Chang9b097032016-10-28 11:03:17 -0700277 * cds_cdp_cfg_attach() - attach data path config module
278 * @cds_cfg: generic platform level config instance
279 *
280 * Return: none
281 */
282static void cds_cdp_cfg_attach(struct cds_config_info *cds_cfg)
283{
284 struct txrx_pdev_cfg_param_t cdp_cfg = {0};
285 void *soc = cds_get_context(QDF_MODULE_ID_SOC);
286
Kiran Kumar Lokere52d8dc32016-12-05 19:20:40 -0800287 cdp_cfg.is_full_reorder_offload = cds_cfg->reorder_offload;
Leo Chang9b097032016-10-28 11:03:17 -0700288 cdp_cfg.is_uc_offload_enabled = cds_cfg->uc_offload_enabled;
289 cdp_cfg.uc_tx_buffer_count = cds_cfg->uc_txbuf_count;
290 cdp_cfg.uc_tx_buffer_size = cds_cfg->uc_txbuf_size;
291 cdp_cfg.uc_rx_indication_ring_count = cds_cfg->uc_rxind_ringcount;
292 cdp_cfg.uc_tx_partition_base = cds_cfg->uc_tx_partition_base;
293 cdp_cfg.enable_rxthread = cds_cfg->enable_rxthread;
294 cdp_cfg.ip_tcp_udp_checksum_offload =
295 cds_cfg->ip_tcp_udp_checksum_offload;
296 cdp_cfg.ce_classify_enabled = cds_cfg->ce_classify_enabled;
297
gbian62edd7e2017-03-07 13:12:13 +0800298 cds_cfg_update_ac_specs_params(&cdp_cfg, cds_cfg);
Kiran Kumar Lokere9aecfee2016-11-23 17:37:42 -0800299 gp_cds_context->cfg_ctx = cdp_cfg_attach(soc, gp_cds_context->qdf_ctx,
300 (void *)(&cdp_cfg));
301 if (!gp_cds_context->cfg_ctx) {
302 WMA_LOGP("%s: failed to init cfg handle", __func__);
303 return;
304 }
305
Leo Chang9b097032016-10-28 11:03:17 -0700306 /* Configure Receive flow steering */
Venkata Sharath Chandra Manchala0d44d452016-11-23 17:48:15 -0800307 cdp_cfg_set_flow_steering(soc, gp_cds_context->cfg_ctx,
Leo Chang9b097032016-10-28 11:03:17 -0700308 cds_cfg->flow_steering_enabled);
309
Venkata Sharath Chandra Manchala0d44d452016-11-23 17:48:15 -0800310 cdp_cfg_set_flow_control_parameters(soc, gp_cds_context->cfg_ctx,
311 (void *)&cdp_cfg);
Leo Chang9b097032016-10-28 11:03:17 -0700312
313 /* adjust the cfg_ctx default value based on setting */
314 cdp_cfg_set_rx_fwd_disabled(soc, gp_cds_context->cfg_ctx,
315 (uint8_t) cds_cfg->ap_disable_intrabss_fwd);
316
317 /*
318 * adjust the packet log enable default value
319 * based on CFG INI setting
320 */
321 cdp_cfg_set_packet_log_enabled(soc, gp_cds_context->cfg_ctx,
322 (uint8_t)cds_is_packet_log_enabled());
Yu Wang66a250b2017-07-19 11:46:40 +0800323
324 /* adjust the ptp rx option default value based on CFG INI setting */
325 cdp_cfg_set_ptp_rx_opt_enabled(soc, gp_cds_context->cfg_ctx,
326 (uint8_t)cds_is_ptp_rx_opt_enabled());
Leo Chang9b097032016-10-28 11:03:17 -0700327}
Krunal Sonid32c6bc2016-10-18 18:00:21 -0700328static QDF_STATUS cds_register_all_modules(void)
329{
330 QDF_STATUS status;
331
332 scheduler_register_wma_legacy_handler(&wma_mc_process_handler);
333 scheduler_register_sys_legacy_handler(&sys_mc_process_handler);
334
335 /* Register message queues in given order such that queue priority is
336 * intact:
337 * 1) QDF_MODULE_ID_SYS: Timer queue(legacy SYS queue)
338 * 2) QDF_MODULE_ID_TARGET_IF: Target interface queue
339 * 3) QDF_MODULE_ID_PE: Legacy PE message queue
340 * 4) QDF_MODULE_ID_SME: Legacy SME message queue
341 * 5) QDF_MODULE_ID_OS_IF: OS IF message queue for new components
342 */
343 status = scheduler_register_module(QDF_MODULE_ID_SYS,
344 &scheduler_timer_q_mq_handler);
345 status = scheduler_register_module(QDF_MODULE_ID_TARGET_IF,
346 &scheduler_target_if_mq_handler);
347 status = scheduler_register_module(QDF_MODULE_ID_PE,
348 &pe_mc_process_handler);
349 status = scheduler_register_module(QDF_MODULE_ID_SME,
350 &sme_mc_process_handler);
351 status = scheduler_register_module(QDF_MODULE_ID_OS_IF,
352 &scheduler_os_if_mq_handler);
353 return status;
354}
355
356static QDF_STATUS cds_deregister_all_modules(void)
357{
358 QDF_STATUS status;
Krunal Sonie3399902017-02-01 09:51:42 -0800359
360 scheduler_deregister_wma_legacy_handler();
361 scheduler_deregister_sys_legacy_handler();
Krunal Sonid32c6bc2016-10-18 18:00:21 -0700362 status = scheduler_deregister_module(QDF_MODULE_ID_SYS);
Rajeev Kumara88b2dc2017-01-30 16:35:14 -0800363 status = scheduler_deregister_module(QDF_MODULE_ID_TARGET_IF);
Krunal Sonid32c6bc2016-10-18 18:00:21 -0700364 status = scheduler_deregister_module(QDF_MODULE_ID_PE);
365 status = scheduler_deregister_module(QDF_MODULE_ID_SME);
366 status = scheduler_deregister_module(QDF_MODULE_ID_OS_IF);
Krunal Sonie3399902017-02-01 09:51:42 -0800367
Krunal Sonid32c6bc2016-10-18 18:00:21 -0700368 return status;
369}
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800370
371/**
gbian62edd7e2017-03-07 13:12:13 +0800372 * cds_set_ac_specs_params() - set ac_specs params in cds_config_info
373 * @cds_cfg: Pointer to cds_config_info
374 * @hdd_ctx: Pointer to hdd context
375 *
376 * Return: none
377 */
378static void
379cds_set_ac_specs_params(struct cds_config_info *cds_cfg)
380{
381 int i;
382 cds_context_type *cds_ctx;
383
384 if (NULL == cds_cfg)
385 return;
386
387 cds_ctx = cds_get_context(QDF_MODULE_ID_QDF);
388
389 if (!cds_ctx) {
390 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
391 "Invalid CDS Context");
392 return;
393 }
394
395 for (i = 0; i < OL_TX_NUM_WMM_AC; i++) {
396 cds_cfg->ac_specs[i] = cds_ctx->ac_specs[i];
397 }
398}
399
400/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800401 * cds_open() - open the CDS Module
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800402 *
403 * cds_open() function opens the CDS Scheduler
404 * Upon successful initialization:
405 * - All CDS submodules should have been initialized
406 *
407 * - The CDS scheduler should have opened
408 *
409 * - All the WLAN SW components should have been opened. This includes
410 * SYS, MAC, SME, WMA and TL.
411 *
Anurag Chouhanf04e84f2016-03-03 10:12:12 +0530412 * Return: QDF status
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800413 */
Selvaraj, Sridhar0672a122016-12-29 16:11:48 +0530414QDF_STATUS cds_open(struct wlan_objmgr_psoc *psoc)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800415{
Dustin Brownf7971192017-10-25 14:54:37 -0700416 QDF_STATUS status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800417 tSirRetStatus sirStatus = eSIR_SUCCESS;
Arun Khandavallic811dcc2016-06-26 07:37:21 +0530418 struct cds_config_info *cds_cfg;
Anurag Chouhan6d760662016-02-20 16:05:43 +0530419 qdf_device_t qdf_ctx;
Manikandan Mohan83c939c2017-04-13 20:23:07 -0700420 struct htc_init_info htcInfo;
Komal Seelamd9106492016-02-15 10:31:44 +0530421 struct ol_context *ol_ctx;
Komal Seelam3d202862016-02-24 18:43:24 +0530422 struct hif_opaque_softc *scn;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800423 void *HTCHandle;
Jeff Johnsonc18b26c2017-09-03 08:46:45 -0700424 struct hdd_context *hdd_ctx;
Arun Khandavallic811dcc2016-06-26 07:37:21 +0530425 cds_context_type *cds_ctx;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800426
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530427 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_INFO_HIGH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800428 "%s: Opening CDS", __func__);
429
Arun Khandavallic811dcc2016-06-26 07:37:21 +0530430 cds_ctx = cds_get_context(QDF_MODULE_ID_QDF);
431 if (!cds_ctx) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530432 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_FATAL,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800433 "%s: Trying to open CDS without a PreOpen", __func__);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530434 QDF_ASSERT(0);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530435 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800436 }
437
438 /* Initialize the timer module */
Anurag Chouhan210db072016-02-22 18:42:15 +0530439 qdf_timer_module_init();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800440
441 /* Initialize bug reporting structure */
442 cds_init_log_completion();
443
444 /* Initialize the probe event */
Dustin Brownf7971192017-10-25 14:54:37 -0700445 status = qdf_event_create(&gp_cds_context->ProbeEvent);
446 if (QDF_IS_STATUS_ERROR(status)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530447 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_FATAL,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800448 "%s: Unable to init probeEvent", __func__);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530449 QDF_ASSERT(0);
Dustin Brownf7971192017-10-25 14:54:37 -0700450 return status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800451 }
Dustin Brownf7971192017-10-25 14:54:37 -0700452
453 status = qdf_event_create(&gp_cds_context->wmaCompleteEvent);
454 if (QDF_IS_STATUS_ERROR(status)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530455 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_FATAL,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800456 "%s: Unable to init wmaCompleteEvent", __func__);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530457 QDF_ASSERT(0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800458 goto err_probe_event;
459 }
460
Dustin Brownf7971192017-10-25 14:54:37 -0700461 hdd_ctx = (struct hdd_context *)(gp_cds_context->pHDDContext);
462 if (!hdd_ctx || !hdd_ctx->config) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800463 /* Critical Error ... Cannot proceed further */
Arun Khandavallifae92942016-08-01 13:31:08 +0530464 cds_err("Hdd Context is Null");
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530465 QDF_ASSERT(0);
Dustin Brownf7971192017-10-25 14:54:37 -0700466
467 status = QDF_STATUS_E_FAILURE;
Rajeev Kumar3e5ef0d2017-01-03 14:45:31 -0800468 goto err_wma_complete_event;
Arun Khandavallifae92942016-08-01 13:31:08 +0530469 }
Kabilan Kannan15cc6ac2016-11-12 22:25:14 -0800470
Arun Khandavallifae92942016-08-01 13:31:08 +0530471 /* Now Open the CDS Scheduler */
Jeff Johnsonc18b26c2017-09-03 08:46:45 -0700472 if (hdd_ctx->driver_status == DRIVER_MODULES_UNINITIALIZED ||
Prashanth Bhatta2ac92bd2016-10-11 16:08:00 -0700473 cds_is_driver_recovering()) {
Dustin Brownf7971192017-10-25 14:54:37 -0700474 status = cds_sched_open(gp_cds_context,
475 &gp_cds_context->qdf_sched,
476 sizeof(cds_sched_context));
Arun Khandavallifae92942016-08-01 13:31:08 +0530477
Dustin Brownf7971192017-10-25 14:54:37 -0700478 if (QDF_IS_STATUS_ERROR(status)) {
Arun Khandavallifae92942016-08-01 13:31:08 +0530479 /* Critical Error ... Cannot proceed further */
480 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_FATAL,
481 "%s: Failed to open CDS Scheduler", __func__);
482 QDF_ASSERT(0);
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -0800483 goto err_wma_complete_event;
Arun Khandavallifae92942016-08-01 13:31:08 +0530484 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800485 }
486
Anurag Chouhan6d760662016-02-20 16:05:43 +0530487 scn = cds_get_context(QDF_MODULE_ID_HIF);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800488 if (!scn) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530489 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_FATAL,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800490 "%s: scn is null!", __func__);
Dustin Brownf7971192017-10-25 14:54:37 -0700491
492 status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800493 goto err_sched_close;
494 }
Arun Khandavallifae92942016-08-01 13:31:08 +0530495
Arun Khandavallifae92942016-08-01 13:31:08 +0530496 cds_cfg = cds_get_ini_config();
497 if (!cds_cfg) {
498 cds_err("Cds config is NULL");
499 QDF_ASSERT(0);
Dustin Brownf7971192017-10-25 14:54:37 -0700500
501 status = QDF_STATUS_E_FAILURE;
Arun Khandavallifae92942016-08-01 13:31:08 +0530502 goto err_sched_close;
503 }
Dustin Brownf7971192017-10-25 14:54:37 -0700504
Jeff Johnsonc18b26c2017-09-03 08:46:45 -0700505 hdd_enable_fastpath(hdd_ctx->config, scn);
506 hdd_wlan_update_target_info(hdd_ctx, scn);
Arun Khandavallifae92942016-08-01 13:31:08 +0530507
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800508 /* Initialize BMI and Download firmware */
Dustin Brownf7971192017-10-25 14:54:37 -0700509 ol_ctx = cds_get_context(QDF_MODULE_ID_BMI);
510 status = bmi_download_firmware(ol_ctx);
511 if (QDF_IS_STATUS_ERROR(status)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530512 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_FATAL,
Dustin Brownf7971192017-10-25 14:54:37 -0700513 "BMI FIALED status:%d", status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800514 goto err_bmi_close;
515 }
Komal Seelam08633492016-02-24 18:05:07 +0530516 htcInfo.pContext = ol_ctx;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800517 htcInfo.TargetFailure = ol_target_failure;
Mukul Sharma4c60a7e2017-03-06 19:42:18 +0530518 htcInfo.TargetSendSuspendComplete =
519 pmo_ucfg_psoc_target_suspend_acknowledge;
520 htcInfo.target_initial_wakeup_cb = pmo_ucfg_psoc_handle_initial_wake_up;
521 htcInfo.target_psoc = (void *)psoc;
Anurag Chouhan6d760662016-02-20 16:05:43 +0530522 qdf_ctx = cds_get_context(QDF_MODULE_ID_QDF_DEVICE);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800523
524 /* Create HTC */
525 gp_cds_context->htc_ctx =
Yue Ma1e11d792016-02-26 18:58:44 -0800526 htc_create(scn, &htcInfo, qdf_ctx, cds_get_conparam());
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800527 if (!gp_cds_context->htc_ctx) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530528 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_FATAL,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800529 "%s: Failed to Create HTC", __func__);
Dustin Brownf7971192017-10-25 14:54:37 -0700530
531 status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800532 goto err_bmi_close;
533 }
Mukul Sharma4c60a7e2017-03-06 19:42:18 +0530534 pmo_ucfg_psoc_update_htc_handle(psoc, (void *)gp_cds_context->htc_ctx);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800535
Dustin Brownf7971192017-10-25 14:54:37 -0700536 status = bmi_done(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,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800539 "%s: Failed to complete BMI phase", __func__);
540 goto err_htc_close;
541 }
542
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800543 /*Open the WMA module */
Dustin Brownf7971192017-10-25 14:54:37 -0700544 status = wma_open(psoc, hdd_update_tgt_cfg, cds_cfg);
545 if (QDF_IS_STATUS_ERROR(status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800546 /* Critical Error ... Cannot proceed further */
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530547 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_FATAL,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800548 "%s: Failed to open WMA module", __func__);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530549 QDF_ASSERT(0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800550 goto err_htc_close;
551 }
552
553 /* Number of peers limit differs in each chip version. If peer max
554 * limit configured in ini exceeds more than supported, WMA adjusts
Arun Khandavallic811dcc2016-06-26 07:37:21 +0530555 * and keeps correct limit in cds_cfg.max_station. So, make sure
Jeff Johnsonc18b26c2017-09-03 08:46:45 -0700556 * config entry hdd_ctx->config->maxNumberOfPeers has adjusted value
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800557 */
Hanumanth Reddy Pothula47d29262016-10-03 16:08:04 +0530558 /* In FTM mode cds_cfg->max_stations will be zero. On updating same
559 * into hdd context config entry, leads to pe_open() to fail, if
560 * con_mode change happens from FTM mode to any other mode.
561 */
Srinivas Girigowda35b00312017-06-27 21:52:03 -0700562 if (QDF_DRIVER_TYPE_PRODUCTION == cds_cfg->driver_type)
Jeff Johnsonc18b26c2017-09-03 08:46:45 -0700563 hdd_ctx->config->maxNumberOfPeers = cds_cfg->max_station;
Hanumanth Reddy Pothula47d29262016-10-03 16:08:04 +0530564
Anurag Chouhan6d760662016-02-20 16:05:43 +0530565 HTCHandle = cds_get_context(QDF_MODULE_ID_HTC);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800566 if (!HTCHandle) {
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: HTCHandle is null!", __func__);
Dustin Brownf7971192017-10-25 14:54:37 -0700569
570 status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800571 goto err_wma_close;
572 }
Nachiket Kukadef44b33e2017-09-06 16:49:29 +0530573
Dustin Brownf7971192017-10-25 14:54:37 -0700574 status = htc_wait_target(HTCHandle);
575 if (QDF_IS_STATUS_ERROR(status)) {
576 cds_alert("Failed to complete BMI phase. status: %d", status);
Nachiket Kukade8003d252017-03-30 15:55:58 +0530577
Dustin Brownf7971192017-10-25 14:54:37 -0700578 if (status != QDF_STATUS_E_NOMEM && !cds_is_fw_down())
Nachiket Kukade8003d252017-03-30 15:55:58 +0530579 QDF_BUG(0);
580
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800581 goto err_wma_close;
582 }
Poddar, Siddarthef1f3022016-05-10 20:10:43 +0530583 bmi_target_ready(scn, gp_cds_context->cfg_ctx);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800584
Ravi Joshifc2ed782016-11-22 17:36:50 -0800585 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_DEBUG,
586 "%s: target_type %d 8074:%d 6290:%d",
Jeff Johnsonc18b26c2017-09-03 08:46:45 -0700587 __func__, hdd_ctx->target_type,
Ravi Joshifc2ed782016-11-22 17:36:50 -0800588 TARGET_TYPE_QCA8074, TARGET_TYPE_QCA6290);
589
Jeff Johnsonc18b26c2017-09-03 08:46:45 -0700590 if (TARGET_TYPE_QCA6290 == hdd_ctx->target_type)
Leo Chang9b097032016-10-28 11:03:17 -0700591 gp_cds_context->dp_soc = cdp_soc_attach(LITHIUM_DP,
592 gp_cds_context->pHIFContext, scn,
593 gp_cds_context->htc_ctx, gp_cds_context->qdf_ctx,
Pramod Simha0d3b9362017-03-27 14:59:58 -0700594 &dp_ol_if_ops, psoc);
Leo Chang9b097032016-10-28 11:03:17 -0700595 else
596 gp_cds_context->dp_soc = cdp_soc_attach(MOB_DRV_LEGACY_DP,
597 gp_cds_context->pHIFContext, scn,
598 gp_cds_context->htc_ctx, gp_cds_context->qdf_ctx,
Pramod Simha0d3b9362017-03-27 14:59:58 -0700599 &dp_ol_if_ops, psoc);
Leo Chang9b097032016-10-28 11:03:17 -0700600
Dustin Brownf7971192017-10-25 14:54:37 -0700601 if (!gp_cds_context->dp_soc) {
602 status = QDF_STATUS_E_FAILURE;
Manikandan Mohanfb9d2b52017-05-10 15:01:28 -0700603 goto err_wma_close;
Dustin Brownf7971192017-10-25 14:54:37 -0700604 }
Manikandan Mohanfb9d2b52017-05-10 15:01:28 -0700605
Sravan Kumar Kairam27296782017-04-21 22:04:18 +0530606 pmo_ucfg_psoc_update_dp_handle(psoc, gp_cds_context->dp_soc);
607
gbian62edd7e2017-03-07 13:12:13 +0800608 cds_set_ac_specs_params(cds_cfg);
609
Leo Chang9b097032016-10-28 11:03:17 -0700610 cds_cdp_cfg_attach(cds_cfg);
611
Jeff Johnsond9f08602016-12-02 11:31:30 -0800612 /* Now proceed to open the MAC */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800613 sirStatus =
Selvaraj, Sridhar0672a122016-12-29 16:11:48 +0530614 mac_open(psoc, &(gp_cds_context->pMACContext),
Arun Khandavallic811dcc2016-06-26 07:37:21 +0530615 gp_cds_context->pHDDContext, cds_cfg);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800616
617 if (eSIR_SUCCESS != sirStatus) {
618 /* Critical Error ... Cannot proceed further */
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530619 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_FATAL,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800620 "%s: Failed to open MAC", __func__);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530621 QDF_ASSERT(0);
Dustin Brownf7971192017-10-25 14:54:37 -0700622
623 status = QDF_STATUS_E_FAILURE;
Houston Hoffman59c9c912017-03-29 14:10:39 -0700624 goto err_soc_detach;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800625 }
626
627 /* Now proceed to open the SME */
Dustin Brownf7971192017-10-25 14:54:37 -0700628 status = sme_open(gp_cds_context->pMACContext);
629 if (QDF_IS_STATUS_ERROR(status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800630 /* Critical Error ... Cannot proceed further */
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530631 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_FATAL,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800632 "%s: Failed to open SME", __func__);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530633 QDF_ASSERT(0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800634 goto err_mac_close;
635 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800636
Krunal Sonid32c6bc2016-10-18 18:00:21 -0700637 cds_register_all_modules();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800638
Selvaraj, Sridhara7dc2382017-01-27 18:29:39 +0530639 return dispatcher_psoc_open(psoc);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800640
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800641err_mac_close:
642 mac_close(gp_cds_context->pMACContext);
643
Houston Hoffman59c9c912017-03-29 14:10:39 -0700644err_soc_detach:
645 /* todo: add propper error handling */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800646err_wma_close:
Rajeev Kumar662d75d2017-03-13 18:11:29 -0700647 cds_shutdown_notifier_purge();
Jeff Johnson542da352017-09-13 09:17:28 -0700648 wma_close();
Jeff Johnson7b3ddc22017-09-13 09:42:44 -0700649 wma_wmi_service_close();
Sravan Kumar Kairam27296782017-04-21 22:04:18 +0530650 pmo_ucfg_psoc_update_dp_handle(psoc, NULL);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800651
652err_htc_close:
653 if (gp_cds_context->htc_ctx) {
654 htc_destroy(gp_cds_context->htc_ctx);
655 gp_cds_context->htc_ctx = NULL;
Sravan Kumar Kairam27296782017-04-21 22:04:18 +0530656 pmo_ucfg_psoc_update_htc_handle(psoc, NULL);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800657 }
658
659err_bmi_close:
Komal Seelam5a6e5082016-02-24 17:59:09 +0530660 bmi_cleanup(ol_ctx);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800661
662err_sched_close:
Dustin Brown46a15a32017-10-19 16:21:22 -0700663 if (hdd_ctx->driver_status == DRIVER_MODULES_UNINITIALIZED ||
664 cds_is_driver_recovering()) {
665 if (QDF_IS_STATUS_ERROR(cds_sched_close())) {
666 cds_err("Failed to close CDS Scheduler");
Hanumanth Reddy Pothula0b571432017-02-23 17:15:37 +0530667 QDF_ASSERT(false);
668 }
669 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800670
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800671err_wma_complete_event:
Anurag Chouhance0dc992016-02-16 18:18:03 +0530672 qdf_event_destroy(&gp_cds_context->wmaCompleteEvent);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800673
674err_probe_event:
Anurag Chouhance0dc992016-02-16 18:18:03 +0530675 qdf_event_destroy(&gp_cds_context->ProbeEvent);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800676
Dustin Brownf7971192017-10-25 14:54:37 -0700677 return status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800678} /* cds_open() */
679
Venkata Sharath Chandra Manchala4aaae0f2017-07-10 11:59:19 -0700680QDF_STATUS cds_dp_open(struct wlan_objmgr_psoc *psoc)
681{
682 if (cdp_txrx_intr_attach(gp_cds_context->dp_soc)
683 != QDF_STATUS_SUCCESS) {
684 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_FATAL,
685 "%s: Failed to attach interrupts", __func__);
686 goto close;
687 }
688
689 cds_set_context(QDF_MODULE_ID_TXRX,
690 cdp_pdev_attach(cds_get_context(QDF_MODULE_ID_SOC),
691 gp_cds_context->cfg_ctx,
692 gp_cds_context->htc_ctx,
693 gp_cds_context->qdf_ctx, 0));
694 if (!gp_cds_context->pdev_txrx_ctx) {
695 /* Critical Error ... Cannot proceed further */
696 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_FATAL,
697 "%s: Failed to open TXRX", __func__);
698 QDF_ASSERT(0);
699 goto intr_close;
700 }
701
702 pmo_ucfg_psoc_set_txrx_handle(psoc, gp_cds_context->pdev_txrx_ctx);
703
704 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_INFO_HIGH,
705 "%s: CDS successfully Opened", __func__);
706
707 return 0;
708
709intr_close:
710 cdp_txrx_intr_detach(gp_cds_context->dp_soc);
711close:
712 return QDF_STATUS_E_FAILURE;
713}
714
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800715/**
716 * cds_pre_enable() - pre enable cds
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800717 *
Anurag Chouhanf04e84f2016-03-03 10:12:12 +0530718 * Return: QDF status
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800719 */
Jeff Johnson3a280122017-09-13 07:42:00 -0700720QDF_STATUS cds_pre_enable(void)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800721{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530722 QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800723 void *scn;
Jeff Johnson3a280122017-09-13 07:42:00 -0700724 void *soc;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800725
Srinivas Girigowdad395b892017-03-09 19:29:42 -0800726 QDF_TRACE(QDF_MODULE_ID_SYS, QDF_TRACE_LEVEL_DEBUG, "cds prestart");
Jeff Johnson3a280122017-09-13 07:42:00 -0700727
728 if (!gp_cds_context) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530729 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Jeff Johnson3a280122017-09-13 07:42:00 -0700730 "%s: NULL CDS context", __func__);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530731 QDF_ASSERT(0);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530732 return QDF_STATUS_E_INVAL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800733 }
734
Jeff Johnson3a280122017-09-13 07:42:00 -0700735 if (gp_cds_context->pMACContext == NULL) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530736 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800737 "%s: MAC NULL context", __func__);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530738 QDF_ASSERT(0);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530739 return QDF_STATUS_E_INVAL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800740 }
741
Jeff Johnson3a280122017-09-13 07:42:00 -0700742 if (gp_cds_context->pWMAContext == NULL) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530743 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800744 "%s: WMA NULL context", __func__);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530745 QDF_ASSERT(0);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530746 return QDF_STATUS_E_INVAL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800747 }
748
Anurag Chouhan6d760662016-02-20 16:05:43 +0530749 scn = cds_get_context(QDF_MODULE_ID_HIF);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800750 if (!scn) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530751 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_FATAL,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800752 "%s: scn is null!", __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530753 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800754 }
755
Jeff Johnson3a280122017-09-13 07:42:00 -0700756 soc = cds_get_context(QDF_MODULE_ID_SOC);
757 if (!soc) {
758 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_FATAL,
759 "%s: soc is null!", __func__);
760 return QDF_STATUS_E_FAILURE;
761 }
762
Nirav Shah7f337db2016-05-25 10:49:02 +0530763 /* call Packetlog connect service */
Arun Khandavallifae92942016-08-01 13:31:08 +0530764 if (QDF_GLOBAL_FTM_MODE != cds_get_conparam() &&
Leo Chang9b097032016-10-28 11:03:17 -0700765 QDF_GLOBAL_EPPING_MODE != cds_get_conparam())
766 cdp_pkt_log_con_service(soc,
Venkata Sharath Chandra Manchala0d44d452016-11-23 17:48:15 -0800767 gp_cds_context->pdev_txrx_ctx,
768 scn);
Nirav Shah7f337db2016-05-25 10:49:02 +0530769
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800770 /* Reset wma wait event */
Anurag Chouhance0dc992016-02-16 18:18:03 +0530771 qdf_event_reset(&gp_cds_context->wmaCompleteEvent);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800772
773 /*call WMA pre start */
Jeff Johnson8ad89c62017-09-13 08:55:55 -0700774 qdf_status = wma_pre_start();
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530775 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530776 QDF_TRACE(QDF_MODULE_ID_SYS, QDF_TRACE_LEVEL_FATAL,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800777 "Failed to WMA prestart");
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530778 QDF_ASSERT(0);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530779 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800780 }
781
782 /* Need to update time out of complete */
Anurag Chouhance0dc992016-02-16 18:18:03 +0530783 qdf_status = qdf_wait_single_event(&gp_cds_context->wmaCompleteEvent,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800784 CDS_WMA_TIMEOUT);
Anurag Chouhance0dc992016-02-16 18:18:03 +0530785 if (qdf_status != QDF_STATUS_SUCCESS) {
786 if (qdf_status == QDF_STATUS_E_TIMEOUT) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530787 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800788 "%s: Timeout occurred before WMA complete",
789 __func__);
790 } else {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530791 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800792 "%s: wma_pre_start reporting other error",
793 __func__);
794 }
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530795 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800796 "%s: Test MC thread by posting a probe message to SYS",
797 __func__);
798 wlan_sys_probe();
799
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530800 QDF_ASSERT(0);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530801 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800802 }
803
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530804 qdf_status = htc_start(gp_cds_context->htc_ctx);
805 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530806 QDF_TRACE(QDF_MODULE_ID_SYS, QDF_TRACE_LEVEL_FATAL,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800807 "Failed to Start HTC");
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530808 QDF_ASSERT(0);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530809 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800810 }
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530811 qdf_status = wma_wait_for_ready_event(gp_cds_context->pWMAContext);
812 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530813 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_FATAL,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800814 "Failed to get ready event from target firmware");
Nachiket Kukade8003d252017-03-30 15:55:58 +0530815
Naveen Rawat91df30a2016-10-12 21:26:18 -0700816 /*
Nachiket Kukade8003d252017-03-30 15:55:58 +0530817 * Panic when the failure is not because the FW is down,
818 * fail gracefully if FW is down allowing re-probing from
819 * from the platform driver
Naveen Rawat91df30a2016-10-12 21:26:18 -0700820 */
Nachiket Kukade8003d252017-03-30 15:55:58 +0530821 if (!cds_is_fw_down())
Naveen Rawat91df30a2016-10-12 21:26:18 -0700822 QDF_BUG(0);
823
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800824 htc_stop(gp_cds_context->htc_ctx);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530825 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800826 }
827
Leo Chang9b097032016-10-28 11:03:17 -0700828 if (cdp_pdev_post_attach(soc, gp_cds_context->pdev_txrx_ctx)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530829 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_FATAL,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800830 "Failed to attach pdev");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800831 htc_stop(gp_cds_context->htc_ctx);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530832 QDF_ASSERT(0);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530833 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800834 }
835
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530836 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800837}
838
839/**
840 * cds_enable() - start/enable cds module
Selvaraj, Sridhar0672a122016-12-29 16:11:48 +0530841 * @psoc: Psoc pointer
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800842 * @cds_context: CDS context
843 *
Anurag Chouhanf04e84f2016-03-03 10:12:12 +0530844 * Return: QDF status
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800845 */
Jeff Johnson8f9dd5f2017-09-13 14:16:08 -0700846QDF_STATUS cds_enable(struct wlan_objmgr_psoc *psoc)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800847{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530848 QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800849 tSirRetStatus sirStatus = eSIR_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800850 tHalMacStartParameters halStartParams;
851
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800852 /* We support only one instance for now ... */
Jeff Johnson8f9dd5f2017-09-13 14:16:08 -0700853 if (!gp_cds_context) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530854 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Jeff Johnson8f9dd5f2017-09-13 14:16:08 -0700855 "%s: Invalid CDS context", __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530856 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800857 }
858
Jeff Johnson8f9dd5f2017-09-13 14:16:08 -0700859 if ((gp_cds_context->pWMAContext == NULL) ||
860 (gp_cds_context->pMACContext == NULL)) {
861 if (gp_cds_context->pWMAContext == NULL)
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530862 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800863 "%s: WMA NULL context", __func__);
864 else
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530865 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800866 "%s: MAC NULL context", __func__);
867
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530868 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800869 }
870
871 /* Start the wma */
Jeff Johnsond4892552017-09-13 08:41:31 -0700872 qdf_status = wma_start();
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530873 if (qdf_status != QDF_STATUS_SUCCESS) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530874 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800875 "%s: Failed to start wma", __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530876 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800877 }
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530878 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_INFO,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800879 "%s: wma correctly started", __func__);
880
881 /* Start the MAC */
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530882 qdf_mem_zero(&halStartParams,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800883 sizeof(tHalMacStartParameters));
884
885 /* Start the MAC */
886 sirStatus =
Jeff Johnson8f9dd5f2017-09-13 14:16:08 -0700887 mac_start(gp_cds_context->pMACContext, &halStartParams);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800888
889 if (eSIR_SUCCESS != sirStatus) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530890 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_FATAL,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800891 "%s: Failed to start MAC", __func__);
892 goto err_wma_stop;
893 }
894
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530895 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_INFO,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800896 "%s: MAC correctly started", __func__);
897
898 /* START SME */
Jeff Johnson8f9dd5f2017-09-13 14:16:08 -0700899 qdf_status = sme_start(gp_cds_context->pMACContext);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800900
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530901 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530902 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_FATAL,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800903 "%s: Failed to start SME", __func__);
904 goto err_mac_stop;
905 }
906
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530907 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_INFO,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800908 "%s: SME correctly started", __func__);
909
Leo Chang9b097032016-10-28 11:03:17 -0700910 if (cdp_soc_attach_target(cds_get_context(QDF_MODULE_ID_SOC))) {
911 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_FATAL,
912 "%s: Failed to attach soc target", __func__);
913 goto err_sme_stop;
914 }
915
916 if (cdp_pdev_attach_target(cds_get_context(QDF_MODULE_ID_SOC),
Venkata Sharath Chandra Manchala0d44d452016-11-23 17:48:15 -0800917 (struct cdp_pdev *)cds_get_context(QDF_MODULE_ID_TXRX))) {
Leo Chang9b097032016-10-28 11:03:17 -0700918 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_FATAL,
919 "%s: Failed to attach pdev target", __func__);
920 goto err_soc_target_detach;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800921 }
922
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530923 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_INFO,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800924 "%s: CDS Start is successful!!", __func__);
925
Selvaraj, Sridhar0672a122016-12-29 16:11:48 +0530926 dispatcher_psoc_enable(psoc);
Rajeev Kumar97767a02016-11-30 11:20:40 -0800927
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530928 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800929
Leo Chang9b097032016-10-28 11:03:17 -0700930err_soc_target_detach:
931 /* NOOP */
932
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800933err_sme_stop:
Jeff Johnson8f9dd5f2017-09-13 14:16:08 -0700934 sme_stop(gp_cds_context->pMACContext, HAL_STOP_TYPE_SYS_RESET);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800935
936err_mac_stop:
Jeff Johnson8f9dd5f2017-09-13 14:16:08 -0700937 mac_stop(gp_cds_context->pMACContext, HAL_STOP_TYPE_SYS_RESET);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800938
939err_wma_stop:
Anurag Chouhance0dc992016-02-16 18:18:03 +0530940 qdf_event_reset(&(gp_cds_context->wmaCompleteEvent));
Jeff Johnsonacc1cc72017-09-13 08:47:49 -0700941 qdf_status = wma_stop(HAL_STOP_TYPE_RF_KILL);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530942 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530943 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800944 "%s: Failed to stop wma", __func__);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530945 QDF_ASSERT(QDF_IS_STATUS_SUCCESS(qdf_status));
Jeff Johnson1f8d0a02017-09-13 08:09:05 -0700946 wma_setneedshutdown();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800947 } else {
Anurag Chouhance0dc992016-02-16 18:18:03 +0530948 qdf_status =
949 qdf_wait_single_event(&(gp_cds_context->wmaCompleteEvent),
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800950 CDS_WMA_TIMEOUT);
Anurag Chouhance0dc992016-02-16 18:18:03 +0530951 if (qdf_status != QDF_STATUS_SUCCESS) {
952 if (qdf_status == QDF_STATUS_E_TIMEOUT) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530953 QDF_TRACE(QDF_MODULE_ID_QDF,
954 QDF_TRACE_LEVEL_FATAL,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800955 "%s: Timeout occurred before WMA_stop complete",
956 __func__);
957 } else {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530958 QDF_TRACE(QDF_MODULE_ID_QDF,
959 QDF_TRACE_LEVEL_FATAL,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800960 "%s: WMA_stop reporting other error",
961 __func__);
962 }
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530963 QDF_ASSERT(0);
Jeff Johnson1f8d0a02017-09-13 08:09:05 -0700964 wma_setneedshutdown();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800965 }
966 }
967
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530968 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800969} /* cds_enable() */
970
971/**
972 * cds_disable() - stop/disable cds module
Selvaraj, Sridhar0672a122016-12-29 16:11:48 +0530973 * @psoc: Psoc pointer
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800974 *
Anurag Chouhanf04e84f2016-03-03 10:12:12 +0530975 * Return: QDF status
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800976 */
Jeff Johnsonea5c2aa12017-09-13 14:18:59 -0700977QDF_STATUS cds_disable(struct wlan_objmgr_psoc *psoc)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800978{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530979 QDF_STATUS qdf_status;
Arun Khandavallifae92942016-08-01 13:31:08 +0530980 void *handle;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800981
Rajeev Kumar97767a02016-11-30 11:20:40 -0800982 /* PSOC disable for all new components. It needs to happen before
983 * target is PDEV suspended such that a component can abort all its
984 * ongoing transaction with FW. Always keep it before wma_stop() as
985 * wma_stop() does target PDEV suspend.
986 */
Rajeev Kumar97767a02016-11-30 11:20:40 -0800987
Selvaraj, Sridhar0672a122016-12-29 16:11:48 +0530988 dispatcher_psoc_disable(psoc);
Rajeev Kumar97767a02016-11-30 11:20:40 -0800989
Jeff Johnsonacc1cc72017-09-13 08:47:49 -0700990 qdf_status = wma_stop(HAL_STOP_TYPE_RF_KILL);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800991
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530992 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Arun Khandavallifae92942016-08-01 13:31:08 +0530993 cds_err("Failed to stop wma");
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530994 QDF_ASSERT(QDF_IS_STATUS_SUCCESS(qdf_status));
Jeff Johnson1f8d0a02017-09-13 08:09:05 -0700995 wma_setneedshutdown();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800996 }
997
Arun Khandavallifae92942016-08-01 13:31:08 +0530998 handle = cds_get_context(QDF_MODULE_ID_PE);
999 if (!handle) {
1000 cds_err("Invalid PE context return!");
1001 return QDF_STATUS_E_INVAL;
1002 }
1003 qdf_status = sme_stop(handle, HAL_STOP_TYPE_SYS_DEEP_SLEEP);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301004 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Arun Khandavallifae92942016-08-01 13:31:08 +05301005 cds_err("Failed to stop SME: %d", qdf_status);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301006 QDF_ASSERT(QDF_IS_STATUS_SUCCESS(qdf_status));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001007 }
Arun Khandavallifae92942016-08-01 13:31:08 +05301008 qdf_status = mac_stop(handle, HAL_STOP_TYPE_SYS_DEEP_SLEEP);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001009
Arun Khandavallifae92942016-08-01 13:31:08 +05301010 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
1011 cds_err("Failed to stop MAC");
1012 QDF_ASSERT(QDF_IS_STATUS_SUCCESS(qdf_status));
1013 }
Arun Khandavalli55f890b2016-08-31 18:14:56 +05301014
Arun Khandavallifae92942016-08-01 13:31:08 +05301015 return qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001016}
1017
Govind Singhb048e872016-09-27 22:07:43 +05301018#ifdef HIF_USB
1019static inline void cds_suspend_target(tp_wma_handle wma_handle)
1020{
1021 QDF_STATUS status;
1022 /* Suspend the target and disable interrupt */
Mukul Sharma4c60a7e2017-03-06 19:42:18 +05301023 status = pmo_ucfg_psoc_suspend_target(wma_handle->psoc, 0);
Govind Singhb048e872016-09-27 22:07:43 +05301024 if (status)
1025 cds_err("Failed to suspend target, status = %d", status);
1026}
1027#else
1028static inline void cds_suspend_target(tp_wma_handle wma_handle)
1029{
1030 QDF_STATUS status;
1031 /* Suspend the target and disable interrupt */
Mukul Sharma4c60a7e2017-03-06 19:42:18 +05301032 status = pmo_ucfg_psoc_suspend_target(wma_handle->psoc, 1);
Govind Singhb048e872016-09-27 22:07:43 +05301033 if (status)
1034 cds_err("Failed to suspend target, status = %d", status);
1035}
1036#endif /* HIF_USB */
1037
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001038/**
Govind Singhb048e872016-09-27 22:07:43 +05301039 * cds_post_disable() - post disable cds module
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001040 *
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05301041 * Return: QDF status
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001042 */
Rajeev Kumarbe021242017-02-16 16:12:23 -08001043QDF_STATUS cds_post_disable(void)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001044{
Arun Khandavalli55f890b2016-08-31 18:14:56 +05301045 tp_wma_handle wma_handle;
Govind Singhb048e872016-09-27 22:07:43 +05301046 struct hif_opaque_softc *hif_ctx;
Himanshu Agarwal0b9bbc32017-02-23 16:23:05 +05301047 struct cdp_pdev *txrx_pdev;
1048
Arun Khandavalli55f890b2016-08-31 18:14:56 +05301049 wma_handle = cds_get_context(QDF_MODULE_ID_WMA);
1050 if (!wma_handle) {
1051 cds_err("Failed to get wma_handle!");
1052 return QDF_STATUS_E_INVAL;
1053 }
1054
Govind Singhb048e872016-09-27 22:07:43 +05301055 hif_ctx = cds_get_context(QDF_MODULE_ID_HIF);
1056 if (!hif_ctx) {
1057 cds_err("Failed to get hif_handle!");
1058 return QDF_STATUS_E_INVAL;
1059 }
1060
Himanshu Agarwal0b9bbc32017-02-23 16:23:05 +05301061 txrx_pdev = cds_get_context(QDF_MODULE_ID_TXRX);
1062 if (!txrx_pdev) {
1063 cds_err("Failed to get txrx pdev!");
1064 return QDF_STATUS_E_INVAL;
1065 }
1066
Arun Khandavalli55f890b2016-08-31 18:14:56 +05301067 /*
1068 * With new state machine changes cds_close can be invoked without
1069 * cds_disable. So, send the following clean up prerequisites to fw,
1070 * So Fw and host are in sync for cleanup indication:
1071 * - Send PDEV_SUSPEND indication to firmware
1072 * - Disable HIF Interrupts.
1073 * - Clean up CE tasklets.
1074 */
1075
Hanumanth Reddy Pothula2a8a7402017-07-03 14:06:11 +05301076 cds_info("send deinit sequence to firmware");
1077 if (!(cds_is_driver_recovering() || cds_is_driver_in_bad_state()))
Govind Singhb048e872016-09-27 22:07:43 +05301078 cds_suspend_target(wma_handle);
1079 hif_disable_isr(hif_ctx);
1080 hif_reset_soc(hif_ctx);
1081
Wu Gao9a24fa72017-07-28 18:32:22 +08001082 if (gp_cds_context->htc_ctx) {
1083 htc_stop(gp_cds_context->htc_ctx);
1084 }
1085
Himanshu Agarwal0b9bbc32017-02-23 16:23:05 +05301086 cdp_pdev_pre_detach(cds_get_context(QDF_MODULE_ID_SOC),
1087 (struct cdp_pdev *)txrx_pdev, 1);
1088
Govind Singhb048e872016-09-27 22:07:43 +05301089 return QDF_STATUS_SUCCESS;
1090}
1091
1092/**
1093 * cds_close() - close cds module
Selvaraj, Sridhar0672a122016-12-29 16:11:48 +05301094 * @psoc: Psoc pointer
Govind Singhb048e872016-09-27 22:07:43 +05301095 *
1096 * This API allows user to close modules registered
1097 * with connectivity device services.
1098 *
1099 * Return: QDF status
1100 */
Jeff Johnsone4b14592017-09-13 14:23:33 -07001101QDF_STATUS cds_close(struct wlan_objmgr_psoc *psoc)
Govind Singhb048e872016-09-27 22:07:43 +05301102{
1103 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001104
Amar Singhal966397f2017-04-06 18:28:56 -07001105 dispatcher_psoc_close(psoc);
1106
Jeff Johnson6b8473d2017-09-13 09:20:53 -07001107 qdf_status = wma_wmi_work_close();
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301108 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301109 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Xun Luoa858a472015-11-10 08:24:45 -08001110 "%s: Failed to close wma_wmi_work", __func__);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301111 QDF_ASSERT(0);
Xun Luoa858a472015-11-10 08:24:45 -08001112 }
1113
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001114 if (gp_cds_context->htc_ctx) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001115 htc_destroy(gp_cds_context->htc_ctx);
Mukul Sharma4c60a7e2017-03-06 19:42:18 +05301116 pmo_ucfg_psoc_update_htc_handle(psoc, NULL);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001117 gp_cds_context->htc_ctx = NULL;
1118 }
1119
Jeff Johnsone4b14592017-09-13 14:23:33 -07001120 qdf_status = sme_close(gp_cds_context->pMACContext);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301121 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301122 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001123 "%s: Failed to close SME", __func__);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301124 QDF_ASSERT(QDF_IS_STATUS_SUCCESS(qdf_status));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001125 }
1126
Jeff Johnsone4b14592017-09-13 14:23:33 -07001127 qdf_status = mac_close(gp_cds_context->pMACContext);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301128 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301129 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001130 "%s: Failed to close MAC", __func__);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301131 QDF_ASSERT(QDF_IS_STATUS_SUCCESS(qdf_status));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001132 }
1133
Jeff Johnsone4b14592017-09-13 14:23:33 -07001134 gp_cds_context->pMACContext = NULL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001135
Houston Hoffmanbe58cc52016-12-19 16:26:44 -08001136 cdp_soc_detach(gp_cds_context->dp_soc);
Sravan Kumar Kairam27296782017-04-21 22:04:18 +05301137 pmo_ucfg_psoc_update_dp_handle(psoc, NULL);
Houston Hoffmanbe58cc52016-12-19 16:26:44 -08001138
Rajeev Kumar662d75d2017-03-13 18:11:29 -07001139 cds_shutdown_notifier_purge();
1140
Jeff Johnson1b5404e2017-09-13 08:04:46 -07001141 if (true == wma_needshutdown()) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301142 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001143 "%s: Failed to shutdown wma", __func__);
1144 } else {
Jeff Johnson542da352017-09-13 09:17:28 -07001145 qdf_status = wma_close();
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301146 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301147 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001148 "%s: Failed to close wma", __func__);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301149 QDF_ASSERT(QDF_IS_STATUS_SUCCESS(qdf_status));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001150 }
1151 }
1152
Jeff Johnson7b3ddc22017-09-13 09:42:44 -07001153 qdf_status = wma_wmi_service_close();
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301154 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301155 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001156 "%s: Failed to close wma_wmi_service", __func__);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301157 QDF_ASSERT(QDF_IS_STATUS_SUCCESS(qdf_status));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001158 }
1159
Anurag Chouhance0dc992016-02-16 18:18:03 +05301160 qdf_status = qdf_event_destroy(&gp_cds_context->wmaCompleteEvent);
1161 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301162 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001163 "%s: failed to destroy wmaCompleteEvent", __func__);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301164 QDF_ASSERT(QDF_IS_STATUS_SUCCESS(qdf_status));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001165 }
1166
Anurag Chouhance0dc992016-02-16 18:18:03 +05301167 qdf_status = qdf_event_destroy(&gp_cds_context->ProbeEvent);
1168 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301169 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001170 "%s: failed to destroy ProbeEvent", __func__);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301171 QDF_ASSERT(QDF_IS_STATUS_SUCCESS(qdf_status));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001172 }
1173
Arun Khandavallic811dcc2016-06-26 07:37:21 +05301174 cds_deinit_ini_config();
Arun Khandavallifae92942016-08-01 13:31:08 +05301175 qdf_timer_module_deinit();
1176
Krunal Sonid32c6bc2016-10-18 18:00:21 -07001177 cds_deregister_all_modules();
Rajeev Kumar97767a02016-11-30 11:20:40 -08001178
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301179 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001180}
1181
Venkata Sharath Chandra Manchala4aaae0f2017-07-10 11:59:19 -07001182QDF_STATUS cds_dp_close(struct wlan_objmgr_psoc *psoc)
1183{
1184 void *ctx;
1185
1186 cdp_txrx_intr_detach(gp_cds_context->dp_soc);
1187
1188 ctx = cds_get_context(QDF_MODULE_ID_TXRX);
1189 cds_set_context(QDF_MODULE_ID_TXRX, NULL);
1190 pmo_ucfg_psoc_set_txrx_handle(psoc, NULL);
1191 cdp_pdev_detach(cds_get_context(QDF_MODULE_ID_SOC),
1192 (struct cdp_pdev *)ctx, 1);
1193
1194 return QDF_STATUS_SUCCESS;
1195}
1196
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001197/**
1198 * cds_get_context() - get context data area
1199 *
1200 * @moduleId: ID of the module who's context data is being retrived.
1201 *
1202 * Each module in the system has a context / data area that is allocated
1203 * and managed by CDS. This API allows any user to get a pointer to its
1204 * allocated context data area from the CDS global context.
1205 *
1206 * Return: pointer to the context data area of the module ID
1207 * specified, or NULL if the context data is not allocated for
1208 * the module ID specified
1209 */
Anurag Chouhan6d760662016-02-20 16:05:43 +05301210void *cds_get_context(QDF_MODULE_ID moduleId)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001211{
1212 void *pModContext = NULL;
1213
1214 if (gp_cds_context == NULL) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301215 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001216 "%s: cds context pointer is null", __func__);
1217 return NULL;
1218 }
1219
1220 switch (moduleId) {
Anurag Chouhan6d760662016-02-20 16:05:43 +05301221 case QDF_MODULE_ID_HDD:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001222 {
1223 pModContext = gp_cds_context->pHDDContext;
1224 break;
1225 }
1226
Anurag Chouhan6d760662016-02-20 16:05:43 +05301227 case QDF_MODULE_ID_SME:
1228 case QDF_MODULE_ID_PE:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001229 {
1230 /* In all these cases, we just return the MAC Context */
1231 pModContext = gp_cds_context->pMACContext;
1232 break;
1233 }
1234
Anurag Chouhan6d760662016-02-20 16:05:43 +05301235 case QDF_MODULE_ID_WMA:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001236 {
1237 /* For wma module */
1238 pModContext = gp_cds_context->pWMAContext;
1239 break;
1240 }
1241
Anurag Chouhan6d760662016-02-20 16:05:43 +05301242 case QDF_MODULE_ID_QDF:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001243 {
1244 /* For SYS this is CDS itself */
1245 pModContext = gp_cds_context;
1246 break;
1247 }
1248
Anurag Chouhan6d760662016-02-20 16:05:43 +05301249 case QDF_MODULE_ID_HIF:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001250 {
1251 pModContext = gp_cds_context->pHIFContext;
1252 break;
1253 }
1254
Anurag Chouhan6d760662016-02-20 16:05:43 +05301255 case QDF_MODULE_ID_HTC:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001256 {
1257 pModContext = gp_cds_context->htc_ctx;
1258 break;
1259 }
1260
Anurag Chouhan6d760662016-02-20 16:05:43 +05301261 case QDF_MODULE_ID_QDF_DEVICE:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001262 {
Anurag Chouhan6d760662016-02-20 16:05:43 +05301263 pModContext = gp_cds_context->qdf_ctx;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001264 break;
1265 }
1266
Anurag Chouhan6d760662016-02-20 16:05:43 +05301267 case QDF_MODULE_ID_BMI:
Komal Seelamd9106492016-02-15 10:31:44 +05301268 {
1269 pModContext = gp_cds_context->g_ol_context;
1270 break;
1271 }
1272
Anurag Chouhan6d760662016-02-20 16:05:43 +05301273 case QDF_MODULE_ID_TXRX:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001274 {
Venkata Sharath Chandra Manchala0d44d452016-11-23 17:48:15 -08001275 pModContext = (void *)gp_cds_context->pdev_txrx_ctx;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001276 break;
1277 }
1278
Anurag Chouhan6d760662016-02-20 16:05:43 +05301279 case QDF_MODULE_ID_CFG:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001280 {
1281 pModContext = gp_cds_context->cfg_ctx;
1282 break;
1283 }
1284
Leo Chang9b097032016-10-28 11:03:17 -07001285 case QDF_MODULE_ID_SOC:
1286 {
1287 pModContext = gp_cds_context->dp_soc;
1288 break;
1289 }
1290
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001291 default:
1292 {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301293 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001294 "%s: Module ID %i does not have its context maintained by CDS",
1295 __func__, moduleId);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301296 QDF_ASSERT(0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001297 return NULL;
1298 }
1299 }
1300
1301 if (pModContext == NULL) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301302 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001303 "%s: Module ID %i context is Null", __func__,
1304 moduleId);
1305 }
1306
1307 return pModContext;
1308} /* cds_get_context() */
1309
1310/**
1311 * cds_get_global_context() - get CDS global Context
1312 *
1313 * This API allows any user to get the CDS Global Context pointer from a
1314 * module context data area.
1315 *
1316 * Return: pointer to the CDS global context, NULL if the function is
1317 * unable to retreive the CDS context.
1318 */
Jeff Johnson31a67582017-09-26 14:54:28 -07001319void *cds_get_global_context(void)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001320{
1321 if (gp_cds_context == NULL) {
Ryan Hsuceddceb2016-04-28 10:20:14 -07001322 /*
1323 * To avoid recursive call, this should not change to
1324 * QDF_TRACE().
1325 */
1326 pr_err("%s: global cds context is NULL", __func__);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001327 }
1328
1329 return gp_cds_context;
1330} /* cds_get_global_context() */
1331
1332/**
Prashanth Bhatta9e143052015-12-04 11:56:47 -08001333 * cds_get_driver_state() - Get current driver state
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001334 *
Prashanth Bhatta9e143052015-12-04 11:56:47 -08001335 * This API returns current driver state stored in global context.
1336 *
1337 * Return: Driver state enum
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001338 */
Prashanth Bhatta9e143052015-12-04 11:56:47 -08001339enum cds_driver_state cds_get_driver_state(void)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001340{
1341 if (gp_cds_context == NULL) {
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: global cds context is NULL", __func__);
Prashanth Bhatta9e143052015-12-04 11:56:47 -08001344
1345 return CDS_DRIVER_STATE_UNINITIALIZED;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001346 }
1347
Prashanth Bhatta9e143052015-12-04 11:56:47 -08001348 return gp_cds_context->driver_state;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001349}
1350
1351/**
Prashanth Bhatta9e143052015-12-04 11:56:47 -08001352 * cds_set_driver_state() - Set current driver state
1353 * @state: Driver state to be set to.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001354 *
Prashanth Bhatta9e143052015-12-04 11:56:47 -08001355 * This API sets driver state to state. This API only sets the state and doesn't
1356 * clear states, please make sure to use cds_clear_driver_state to clear any
1357 * state if required.
1358 *
1359 * Return: None
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001360 */
Prashanth Bhatta9e143052015-12-04 11:56:47 -08001361void cds_set_driver_state(enum cds_driver_state state)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001362{
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001363 if (gp_cds_context == NULL) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301364 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prashanth Bhatta9e143052015-12-04 11:56:47 -08001365 "%s: global cds context is NULL: %x", __func__,
1366 state);
1367
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001368 return;
1369 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001370
Prashanth Bhatta9e143052015-12-04 11:56:47 -08001371 gp_cds_context->driver_state |= state;
1372}
1373
1374/**
1375 * cds_clear_driver_state() - Clear current driver state
1376 * @state: Driver state to be cleared.
1377 *
1378 * This API clears driver state. This API only clears the state, please make
1379 * sure to use cds_set_driver_state to set any new states.
1380 *
1381 * Return: None
1382 */
1383void cds_clear_driver_state(enum cds_driver_state state)
1384{
1385 if (gp_cds_context == NULL) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301386 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prashanth Bhatta9e143052015-12-04 11:56:47 -08001387 "%s: global cds context is NULL: %x", __func__,
1388 state);
1389
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001390 return;
1391 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001392
Prashanth Bhatta9e143052015-12-04 11:56:47 -08001393 gp_cds_context->driver_state &= ~state;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001394}
1395
Nachiket Kukade8003d252017-03-30 15:55:58 +05301396enum cds_fw_state cds_get_fw_state(void)
1397{
1398 if (gp_cds_context == NULL) {
1399 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
1400 "%s: global cds context is NULL", __func__);
1401
1402 return CDS_FW_STATE_UNINITIALIZED;
1403 }
1404
1405 return gp_cds_context->fw_state;
1406}
1407
1408void cds_set_fw_state(enum cds_fw_state state)
1409{
1410 if (gp_cds_context == NULL) {
1411 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
1412 "%s: global cds context is NULL: %d", __func__,
1413 state);
1414
1415 return;
1416 }
1417
1418 qdf_atomic_set_bit(state, &gp_cds_context->fw_state);
1419}
1420
1421void cds_clear_fw_state(enum cds_fw_state state)
1422{
1423 if (gp_cds_context == NULL) {
1424 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
1425 "%s: global cds context is NULL: %d", __func__,
1426 state);
1427
1428 return;
1429 }
1430
1431 qdf_atomic_clear_bit(state, &gp_cds_context->fw_state);
1432}
1433
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001434/**
1435 * cds_alloc_context() - allocate a context within the CDS global Context
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001436 * @moduleId: module ID who's context area is being allocated.
1437 * @ppModuleContext: pointer to location where the pointer to the
1438 * allocated context is returned. Note this output pointer
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301439 * is valid only if the API returns QDF_STATUS_SUCCESS
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001440 * @param size: size of the context area to be allocated.
1441 *
1442 * This API allows any user to allocate a user context area within the
1443 * CDS Global Context.
1444 *
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05301445 * Return: QDF status
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001446 */
Jeff Johnsonadb3b1c2017-09-13 10:42:36 -07001447QDF_STATUS cds_alloc_context(QDF_MODULE_ID moduleID,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001448 void **ppModuleContext, uint32_t size)
1449{
1450 void **pGpModContext = NULL;
1451
Jeff Johnsonadb3b1c2017-09-13 10:42:36 -07001452 if (!gp_cds_context) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301453 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001454 "%s: cds context is null", __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301455 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001456 }
1457
Jeff Johnsonadb3b1c2017-09-13 10:42:36 -07001458 if (!ppModuleContext) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301459 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Jeff Johnsonadb3b1c2017-09-13 10:42:36 -07001460 "%s: null param passed",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001461 __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301462 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001463 }
1464
1465 switch (moduleID) {
Anurag Chouhan6d760662016-02-20 16:05:43 +05301466 case QDF_MODULE_ID_WMA:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001467 pGpModContext = &(gp_cds_context->pWMAContext);
1468 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001469
Anurag Chouhan6d760662016-02-20 16:05:43 +05301470 case QDF_MODULE_ID_HIF:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001471 pGpModContext = &(gp_cds_context->pHIFContext);
1472 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001473
Anurag Chouhan6d760662016-02-20 16:05:43 +05301474 case QDF_MODULE_ID_BMI:
Komal Seelamd9106492016-02-15 10:31:44 +05301475 pGpModContext = &(gp_cds_context->g_ol_context);
1476 break;
Komal Seelamd9106492016-02-15 10:31:44 +05301477
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001478 default:
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301479 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Jeff Johnsonadb3b1c2017-09-13 10:42:36 -07001480 "%s: Module ID %i does not have its context allocated by CDS",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001481 __func__, moduleID);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301482 QDF_ASSERT(0);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301483 return QDF_STATUS_E_INVAL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001484 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001485
Jeff Johnsonadb3b1c2017-09-13 10:42:36 -07001486 if (*pGpModContext) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001487 /* Context has already been allocated!
1488 * Prevent double allocation
1489 */
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301490 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001491 "%s: Module ID %i context has already been allocated",
1492 __func__, moduleID);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301493 return QDF_STATUS_E_EXISTS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001494 }
1495
1496 /* Dynamically allocate the context for module */
1497
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301498 *ppModuleContext = qdf_mem_malloc(size);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001499
Jeff Johnsonadb3b1c2017-09-13 10:42:36 -07001500 if (!*ppModuleContext) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301501 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Jeff Johnsonadb3b1c2017-09-13 10:42:36 -07001502 "%s: Failed to allocate Context for module ID %i",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001503 __func__, moduleID);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301504 QDF_ASSERT(0);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301505 return QDF_STATUS_E_NOMEM;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001506 }
1507
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001508 *pGpModContext = *ppModuleContext;
1509
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301510 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001511} /* cds_alloc_context() */
1512
1513/**
Komal Seelamad5a90d2016-02-16 13:50:03 +05301514 * cds_set_context() - API to set context in global CDS Context
Komal Seelam1aac1982016-03-02 15:57:26 +05301515 * @module_id: Module ID
Komal Seelamad5a90d2016-02-16 13:50:03 +05301516 * @context: Pointer to the Module Context
1517 *
Komal Seelam1aac1982016-03-02 15:57:26 +05301518 * API to set a MODULE Context in global CDS Context
Komal Seelamad5a90d2016-02-16 13:50:03 +05301519 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301520 * Return: QDF_STATUS
Komal Seelamad5a90d2016-02-16 13:50:03 +05301521 */
Anurag Chouhan6d760662016-02-20 16:05:43 +05301522QDF_STATUS cds_set_context(QDF_MODULE_ID module_id, void *context)
Komal Seelamad5a90d2016-02-16 13:50:03 +05301523{
1524 p_cds_contextType p_cds_context = cds_get_global_context();
1525
1526 if (!p_cds_context) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301527 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Komal Seelam1aac1982016-03-02 15:57:26 +05301528 "cds context is Invalid");
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301529 return QDF_STATUS_NOT_INITIALIZED;
Komal Seelamad5a90d2016-02-16 13:50:03 +05301530 }
1531
1532 switch (module_id) {
Jeff Johnson3543fb22017-09-24 13:44:13 -07001533 case QDF_MODULE_ID_HDD:
1534 p_cds_context->pHDDContext = context;
1535 break;
Houston Hoffman57c36d72017-01-30 12:47:02 -08001536 case QDF_MODULE_ID_TXRX:
1537 p_cds_context->pdev_txrx_ctx = context;
1538 break;
Anurag Chouhan6d760662016-02-20 16:05:43 +05301539 case QDF_MODULE_ID_HIF:
Komal Seelamad5a90d2016-02-16 13:50:03 +05301540 p_cds_context->pHIFContext = context;
1541 break;
1542 default:
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301543 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Komal Seelam1aac1982016-03-02 15:57:26 +05301544 "%s: Module ID %i does not have its context managed by CDS",
1545 __func__, module_id);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301546 QDF_ASSERT(0);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301547 return QDF_STATUS_E_INVAL;
Komal Seelamad5a90d2016-02-16 13:50:03 +05301548 }
1549
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301550 return QDF_STATUS_SUCCESS;
Komal Seelamad5a90d2016-02-16 13:50:03 +05301551}
1552
1553/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001554 * cds_free_context() - free an allocated context within the
1555 * CDS global Context
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001556 * @moduleId: module ID who's context area is being free
1557 * @pModuleContext: pointer to module context area to be free'd.
1558 *
1559 * This API allows a user to free the user context area within the
1560 * CDS Global Context.
1561 *
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05301562 * Return: QDF status
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001563 */
Jeff Johnsonadb3b1c2017-09-13 10:42:36 -07001564QDF_STATUS cds_free_context(QDF_MODULE_ID moduleID, void *pModuleContext)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001565{
1566 void **pGpModContext = NULL;
1567
Jeff Johnsonadb3b1c2017-09-13 10:42:36 -07001568 if (!gp_cds_context) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301569 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Jeff Johnsonadb3b1c2017-09-13 10:42:36 -07001570 "%s: cds context is null", __func__);
1571 return QDF_STATUS_E_FAILURE;
1572 }
1573
1574 if (!pModuleContext) {
1575 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
1576 "%s: Null param", __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301577 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001578 }
1579
1580 switch (moduleID) {
Anurag Chouhan6d760662016-02-20 16:05:43 +05301581 case QDF_MODULE_ID_WMA:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001582 pGpModContext = &(gp_cds_context->pWMAContext);
1583 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001584
Anurag Chouhan6d760662016-02-20 16:05:43 +05301585 case QDF_MODULE_ID_HIF:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001586 pGpModContext = &(gp_cds_context->pHIFContext);
1587 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001588
Anurag Chouhan6d760662016-02-20 16:05:43 +05301589 case QDF_MODULE_ID_TXRX:
Venkata Sharath Chandra Manchala0d44d452016-11-23 17:48:15 -08001590 pGpModContext = (void **)&(gp_cds_context->pdev_txrx_ctx);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001591 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001592
Anurag Chouhan6d760662016-02-20 16:05:43 +05301593 case QDF_MODULE_ID_BMI:
Komal Seelamd9106492016-02-15 10:31:44 +05301594 pGpModContext = &(gp_cds_context->g_ol_context);
1595 break;
Komal Seelamd9106492016-02-15 10:31:44 +05301596
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001597 default:
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301598 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001599 "%s: Module ID %i "
1600 "does not have its context allocated by CDS",
1601 __func__, moduleID);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301602 QDF_ASSERT(0);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301603 return QDF_STATUS_E_INVAL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001604 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001605
1606 if (NULL == *pGpModContext) {
1607 /* Context has not been allocated or freed already! */
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301608 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Jeff Johnsonadb3b1c2017-09-13 10:42:36 -07001609 "%s: Module ID %i context has not been allocated or freed already",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001610 __func__, moduleID);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301611 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001612 }
1613
1614 if (*pGpModContext != pModuleContext) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301615 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001616 "%s: pGpModContext != pModuleContext", __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301617 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001618 }
1619
Jeff Johnsonadb3b1c2017-09-13 10:42:36 -07001620 qdf_mem_free(pModuleContext);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001621
1622 *pGpModContext = NULL;
1623
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301624 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001625} /* cds_free_context() */
1626
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001627/**
1628 * cds_sys_probe_thread_cback() - probe mc thread callback
1629 * @pUserData: pointer to user data
1630 *
1631 * Return: none
1632 */
1633void cds_sys_probe_thread_cback(void *pUserData)
1634{
1635 if (gp_cds_context != pUserData) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301636 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001637 "%s: gp_cds_context != pUserData", __func__);
1638 return;
1639 }
1640
Anurag Chouhance0dc992016-02-16 18:18:03 +05301641 if (qdf_event_set(&gp_cds_context->ProbeEvent) != QDF_STATUS_SUCCESS) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301642 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Anurag Chouhance0dc992016-02-16 18:18:03 +05301643 "%s: qdf_event_set failed", __func__);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001644 return;
1645 }
1646} /* cds_sys_probe_thread_cback() */
1647
1648/**
1649 * cds_wma_complete_cback() - wma complete callback
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001650 *
1651 * Return: none
1652 */
Jeff Johnsonf7ab8142017-09-13 09:04:23 -07001653void cds_wma_complete_cback(void)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001654{
Jeff Johnsonf7ab8142017-09-13 09:04:23 -07001655 if (!gp_cds_context) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301656 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Jeff Johnsonf7ab8142017-09-13 09:04:23 -07001657 "%s: invalid gp_cds_context", __func__);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001658 return;
1659 }
1660
Anurag Chouhance0dc992016-02-16 18:18:03 +05301661 if (qdf_event_set(&gp_cds_context->wmaCompleteEvent) !=
1662 QDF_STATUS_SUCCESS) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301663 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Anurag Chouhance0dc992016-02-16 18:18:03 +05301664 "%s: qdf_event_set failed", __func__);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001665 return;
1666 }
1667} /* cds_wma_complete_cback() */
1668
1669/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001670 * cds_get_vdev_types() - get vdev type
1671 * @mode: mode
1672 * @type: type
1673 * @sub_type: sub_type
1674 *
1675 * Return: WMI vdev type
1676 */
Anurag Chouhan6d760662016-02-20 16:05:43 +05301677QDF_STATUS cds_get_vdev_types(enum tQDF_ADAPTER_MODE mode, uint32_t *type,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001678 uint32_t *sub_type)
1679{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301680 QDF_STATUS status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001681 *type = 0;
1682 *sub_type = 0;
1683
1684 switch (mode) {
Anurag Chouhan6d760662016-02-20 16:05:43 +05301685 case QDF_STA_MODE:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001686 *type = WMI_VDEV_TYPE_STA;
1687 break;
Anurag Chouhan6d760662016-02-20 16:05:43 +05301688 case QDF_SAP_MODE:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001689 *type = WMI_VDEV_TYPE_AP;
1690 break;
Anurag Chouhan6d760662016-02-20 16:05:43 +05301691 case QDF_P2P_DEVICE_MODE:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001692 *type = WMI_VDEV_TYPE_AP;
1693 *sub_type = WMI_UNIFIED_VDEV_SUBTYPE_P2P_DEVICE;
1694 break;
Anurag Chouhan6d760662016-02-20 16:05:43 +05301695 case QDF_P2P_CLIENT_MODE:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001696 *type = WMI_VDEV_TYPE_STA;
1697 *sub_type = WMI_UNIFIED_VDEV_SUBTYPE_P2P_CLIENT;
1698 break;
Anurag Chouhan6d760662016-02-20 16:05:43 +05301699 case QDF_P2P_GO_MODE:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001700 *type = WMI_VDEV_TYPE_AP;
1701 *sub_type = WMI_UNIFIED_VDEV_SUBTYPE_P2P_GO;
1702 break;
Anurag Chouhan6d760662016-02-20 16:05:43 +05301703 case QDF_OCB_MODE:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001704 *type = WMI_VDEV_TYPE_OCB;
1705 break;
Krunal Soni8c37e322016-02-03 16:08:37 -08001706 case QDF_IBSS_MODE:
1707 *type = WMI_VDEV_TYPE_IBSS;
1708 break;
Manjunathappa Prakashb7573722016-04-21 11:24:07 -07001709 case QDF_MONITOR_MODE:
1710 *type = WMI_VDEV_TYPE_MONITOR;
1711 break;
Deepak Dhamdheree2dd5442016-05-27 15:05:51 -07001712 case QDF_NDI_MODE:
1713 *type = WMI_VDEV_TYPE_NDI;
1714 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001715 default:
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301716 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Ryan Hsud7e6fc72015-12-07 17:26:14 -08001717 "Invalid device mode %d", mode);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301718 status = QDF_STATUS_E_INVAL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001719 break;
1720 }
1721 return status;
1722}
1723
1724/**
1725 * cds_flush_work() - flush pending works
1726 * @work: pointer to work
1727 *
1728 * Return: none
1729 */
1730void cds_flush_work(void *work)
1731{
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001732 cancel_work_sync(work);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001733}
1734
1735/**
1736 * cds_flush_delayed_work() - flush delayed works
1737 * @dwork: pointer to delayed work
1738 *
1739 * Return: none
1740 */
1741void cds_flush_delayed_work(void *dwork)
1742{
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001743 cancel_delayed_work_sync(dwork);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001744}
1745
1746/**
1747 * cds_is_packet_log_enabled() - check if packet log is enabled
1748 *
1749 * Return: true if packet log is enabled else false
1750 */
1751bool cds_is_packet_log_enabled(void)
1752{
Jeff Johnsonc18b26c2017-09-03 08:46:45 -07001753 struct hdd_context *hdd_ctx;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001754
Jeff Johnsonc18b26c2017-09-03 08:46:45 -07001755 hdd_ctx = (struct hdd_context *) (gp_cds_context->pHDDContext);
1756 if ((NULL == hdd_ctx) || (NULL == hdd_ctx->config)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301757 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_FATAL,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001758 "%s: Hdd Context is Null", __func__);
1759 return false;
1760 }
1761
Jeff Johnsonc18b26c2017-09-03 08:46:45 -07001762 return hdd_ctx->config->enablePacketLog;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001763}
1764
Dustin Brown100201e2017-07-10 11:48:40 -07001765static int cds_force_assert_target_via_pld(qdf_device_t qdf)
Mukul Sharmab7b575b2016-10-02 23:37:07 +05301766{
Dustin Brown100201e2017-07-10 11:48:40 -07001767 int errno;
1768
1769 errno = pld_force_assert_target(qdf->dev);
1770 if (errno == -EOPNOTSUPP)
1771 cds_info("PLD does not support target force assert");
1772 else if (errno)
1773 cds_err("Failed PLD target force assert; errno %d", errno);
1774 else
1775 cds_info("Target force assert triggered via PLD");
1776
1777 return errno;
Mukul Sharmab7b575b2016-10-02 23:37:07 +05301778}
1779
Dustin Brown100201e2017-07-10 11:48:40 -07001780static QDF_STATUS cds_force_assert_target_via_wmi(qdf_device_t qdf)
Rajeev Kumardb60f162017-07-25 20:27:59 -07001781{
Dustin Brown100201e2017-07-10 11:48:40 -07001782 QDF_STATUS status;
1783 t_wma_handle *wma;
1784
1785 wma = cds_get_context(QDF_MODULE_ID_WMA);
1786 if (!wma) {
1787 cds_err("wma is null");
1788 return QDF_STATUS_E_INVAL;
1789 }
1790
1791 status = wma_crash_inject(wma, RECOVERY_SIM_SELF_RECOVERY, 0);
1792 if (QDF_IS_STATUS_ERROR(status)) {
1793 cds_err("Failed target force assert; status %d", status);
1794 return status;
1795 }
1796
1797 status = qdf_wait_single_event(&wma->recovery_event,
1798 WMA_CRASH_INJECT_TIMEOUT);
1799 if (QDF_IS_STATUS_ERROR(status)) {
1800 cds_err("Failed target force assert wait; status %d", status);
1801 return status;
1802 }
1803
1804 return QDF_STATUS_SUCCESS;
1805}
1806
1807/**
1808 * cds_force_assert_target() - Send assert command to firmware
1809 * @qdf: QDF device instance to assert
1810 *
1811 * An out-of-band recovery mechanism will cleanup and restart the entire wlan
1812 * subsystem in the event of a firmware crash. This API injects a firmware
1813 * crash to start this process when the wlan driver is known to be in a bad
1814 * state. If a firmware assert inject fails, the wlan driver will schedule
1815 * the driver recovery anyway, as a best effort attempt to return to a working
1816 * state.
1817 *
1818 * Return: QDF_STATUS
1819 */
1820static QDF_STATUS cds_force_assert_target(qdf_device_t qdf)
1821{
1822 int errno;
1823 QDF_STATUS status;
1824
1825 /* first, try target assert inject via pld */
1826 errno = cds_force_assert_target_via_pld(qdf);
1827 if (!errno)
1828 return QDF_STATUS_SUCCESS;
1829 if (errno != -EOPNOTSUPP)
1830 return QDF_STATUS_E_FAILURE;
1831
1832 /* pld assert is not supported, try target assert inject via wmi */
1833 status = cds_force_assert_target_via_wmi(qdf);
1834 if (QDF_IS_STATUS_SUCCESS(status))
1835 return QDF_STATUS_SUCCESS;
1836
1837 /* wmi assert failed, start recovery without the firmware assert */
1838 cds_err("Scheduling recovery work without firmware assert");
1839 cds_set_recovery_in_progress(true);
1840 pld_schedule_recovery_work(qdf->dev, PLD_REASON_DEFAULT);
1841
1842 return status;
Rajeev Kumardb60f162017-07-25 20:27:59 -07001843}
1844
Mukul Sharmab7b575b2016-10-02 23:37:07 +05301845/**
Srinivas Girigowda161b9f22017-07-24 17:38:09 -07001846 * cds_trigger_recovery_work() - trigger self recovery work
Mukul Sharmab7b575b2016-10-02 23:37:07 +05301847 *
1848 * Return: none
1849 */
Srinivas Girigowda161b9f22017-07-24 17:38:09 -07001850static void cds_trigger_recovery_work(void *param)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001851{
Dustin Brown100201e2017-07-10 11:48:40 -07001852 QDF_STATUS status;
1853 qdf_runtime_lock_t rtl;
1854 qdf_device_t qdf;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001855
Dustin Brown100201e2017-07-10 11:48:40 -07001856 if (!cds_is_self_recovery_enabled()) {
1857 cds_err("Recovery is not enabled");
1858 QDF_BUG(0);
Sameer Thalappilec2e9c72017-02-08 15:45:49 -08001859 return;
1860 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001861
Dustin Brown100201e2017-07-10 11:48:40 -07001862 if (cds_is_driver_recovering() || cds_is_driver_in_bad_state()) {
1863 cds_err("Recovery in progress; ignoring recovery trigger");
Houston Hoffmanc7c72a82015-12-07 15:30:48 -08001864 return;
1865 }
1866
Rajeev Kumar6dd45a82017-10-20 14:43:05 -07001867 if (cds_is_fw_down()) {
1868 cds_err("FW is down; ignoring recovery trigger");
1869 return;
1870 }
1871
Dustin Brown100201e2017-07-10 11:48:40 -07001872 qdf = cds_get_context(QDF_MODULE_ID_QDF_DEVICE);
1873 if (!qdf) {
1874 cds_err("Qdf context is null");
1875 return;
Sameer Thalappilac5d26e2017-01-10 15:32:58 -08001876 }
1877
Dustin Brown100201e2017-07-10 11:48:40 -07001878 status = qdf_runtime_lock_init(&rtl);
1879 if (QDF_IS_STATUS_ERROR(status)) {
Srinivas Girigowda161b9f22017-07-24 17:38:09 -07001880 cds_err("qdf_runtime_lock_init failed, status: %d", status);
Dustin Brown100201e2017-07-10 11:48:40 -07001881 return;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001882 }
Houston Hoffmanc7c72a82015-12-07 15:30:48 -08001883
Dustin Brown100201e2017-07-10 11:48:40 -07001884 status = qdf_runtime_pm_prevent_suspend(&rtl);
1885 if (QDF_IS_STATUS_ERROR(status)) {
1886 cds_err("Failed to acquire runtime pm lock");
1887 goto deinit_rtl;
1888 }
1889
1890 cds_force_assert_target(qdf);
1891
1892 status = qdf_runtime_pm_allow_suspend(&rtl);
1893 if (QDF_IS_STATUS_ERROR(status))
1894 cds_err("Failed to release runtime pm lock");
1895
1896deinit_rtl:
1897 qdf_runtime_lock_deinit(&rtl);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001898}
1899
1900/**
Anurag Chouhan4085ff72017-10-05 18:09:56 +05301901 * cds_get_recovery_reason() - get self recovery reason
1902 * @reason: recovery reason
1903 *
1904 * Return: None
1905 */
1906void cds_get_recovery_reason(enum qdf_hang_reason *reason)
1907{
1908 if (!gp_cds_context) {
1909 cds_err("gp_cds_context is null");
1910 return;
1911 }
1912
1913 *reason = gp_cds_context->recovery_reason;
1914}
1915
1916/**
1917 * cds_reset_recovery_reason() - reset the reason to unspecified
1918 *
1919 * Return: None
1920 */
1921void cds_reset_recovery_reason(void)
1922{
1923 if (!gp_cds_context) {
1924 cds_err("gp_cds_context is null");
1925 return;
1926 }
1927
1928 gp_cds_context->recovery_reason = QDF_REASON_UNSPECIFIED;
1929}
1930
1931/**
Srinivas Girigowda161b9f22017-07-24 17:38:09 -07001932 * cds_trigger_recovery() - trigger self recovery
Anurag Chouhan4085ff72017-10-05 18:09:56 +05301933 * @reason: recovery reason
Srinivas Girigowda161b9f22017-07-24 17:38:09 -07001934 *
1935 * Return: none
1936 */
Anurag Chouhan4085ff72017-10-05 18:09:56 +05301937void cds_trigger_recovery(enum qdf_hang_reason reason)
Srinivas Girigowda161b9f22017-07-24 17:38:09 -07001938{
Anurag Chouhan4085ff72017-10-05 18:09:56 +05301939 if (!gp_cds_context) {
1940 cds_err("gp_cds_context is null");
1941 return;
1942 }
1943
1944 gp_cds_context->recovery_reason = reason;
Srinivas Girigowda161b9f22017-07-24 17:38:09 -07001945 if (in_atomic()) {
1946 qdf_queue_work(0, gp_cds_context->cds_recovery_wq,
1947 &gp_cds_context->cds_recovery_work);
1948 return;
1949 }
1950 cds_trigger_recovery_work(NULL);
1951}
1952
1953/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001954 * cds_get_monotonic_boottime() - Get kernel boot time.
1955 *
1956 * Return: Time in microseconds
1957 */
1958
1959uint64_t cds_get_monotonic_boottime(void)
1960{
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001961 struct timespec ts;
1962
Yuanyuan Liu2e03b412016-04-06 14:36:15 -07001963 get_monotonic_boottime(&ts);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001964 return ((uint64_t) ts.tv_sec * 1000000) + (ts.tv_nsec / 1000);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001965}
1966
1967/**
1968 * cds_set_wakelock_logging() - Logging of wakelock enabled/disabled
1969 * @value: Boolean value
1970 *
1971 * This function is used to set the flag which will indicate whether
1972 * logging of wakelock is enabled or not
1973 *
1974 * Return: None
1975 */
1976void cds_set_wakelock_logging(bool value)
1977{
1978 p_cds_contextType p_cds_context;
1979
1980 p_cds_context = cds_get_global_context();
1981 if (!p_cds_context) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301982 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001983 "cds context is Invald");
1984 return;
1985 }
1986 p_cds_context->is_wakelock_log_enabled = value;
1987}
1988
1989/**
1990 * cds_is_wakelock_enabled() - Check if logging of wakelock is enabled/disabled
1991 * @value: Boolean value
1992 *
1993 * This function is used to check whether logging of wakelock is enabled or not
1994 *
1995 * Return: true if logging of wakelock is enabled
1996 */
1997bool cds_is_wakelock_enabled(void)
1998{
1999 p_cds_contextType p_cds_context;
2000
2001 p_cds_context = cds_get_global_context();
2002 if (!p_cds_context) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302003 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002004 "cds context is Invald");
2005 return false;
2006 }
2007 return p_cds_context->is_wakelock_log_enabled;
2008}
2009
2010/**
2011 * cds_set_ring_log_level() - Sets the log level of a particular ring
2012 * @ring_id: ring_id
2013 * @log_levelvalue: Log level specificed
2014 *
2015 * This function converts HLOS values to driver log levels and sets the log
2016 * level of a particular ring accordingly.
2017 *
2018 * Return: None
2019 */
2020void cds_set_ring_log_level(uint32_t ring_id, uint32_t log_level)
2021{
2022 p_cds_contextType p_cds_context;
2023 uint32_t log_val;
2024
2025 p_cds_context = cds_get_global_context();
2026 if (!p_cds_context) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302027 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002028 "%s: cds context is Invald", __func__);
2029 return;
2030 }
2031
2032 switch (log_level) {
2033 case LOG_LEVEL_NO_COLLECTION:
2034 log_val = WLAN_LOG_LEVEL_OFF;
2035 break;
2036 case LOG_LEVEL_NORMAL_COLLECT:
2037 log_val = WLAN_LOG_LEVEL_NORMAL;
2038 break;
2039 case LOG_LEVEL_ISSUE_REPRO:
2040 log_val = WLAN_LOG_LEVEL_REPRO;
2041 break;
2042 case LOG_LEVEL_ACTIVE:
2043 default:
2044 log_val = WLAN_LOG_LEVEL_ACTIVE;
2045 break;
2046 }
2047
2048 if (ring_id == RING_ID_WAKELOCK) {
2049 p_cds_context->wakelock_log_level = log_val;
2050 return;
2051 } else if (ring_id == RING_ID_CONNECTIVITY) {
2052 p_cds_context->connectivity_log_level = log_val;
2053 return;
2054 } else if (ring_id == RING_ID_PER_PACKET_STATS) {
2055 p_cds_context->packet_stats_log_level = log_val;
2056 return;
Chandrasekaran, Manishekar907c2af2015-11-13 12:50:04 +05302057 } else if (ring_id == RING_ID_DRIVER_DEBUG) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002058 p_cds_context->driver_debug_log_level = log_val;
2059 return;
2060 } else if (ring_id == RING_ID_FIRMWARE_DEBUG) {
2061 p_cds_context->fw_debug_log_level = log_val;
2062 return;
2063 }
2064}
2065
2066/**
2067 * cds_get_ring_log_level() - Get the a ring id's log level
2068 * @ring_id: Ring id
2069 *
2070 * Fetch and return the log level corresponding to a ring id
2071 *
2072 * Return: Log level corresponding to the ring ID
2073 */
2074enum wifi_driver_log_level cds_get_ring_log_level(uint32_t ring_id)
2075{
2076 p_cds_contextType p_cds_context;
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 WLAN_LOG_LEVEL_OFF;
2083 }
2084
2085 if (ring_id == RING_ID_WAKELOCK)
2086 return p_cds_context->wakelock_log_level;
2087 else if (ring_id == RING_ID_CONNECTIVITY)
2088 return p_cds_context->connectivity_log_level;
2089 else if (ring_id == RING_ID_PER_PACKET_STATS)
2090 return p_cds_context->packet_stats_log_level;
Chandrasekaran, Manishekar907c2af2015-11-13 12:50:04 +05302091 else if (ring_id == RING_ID_DRIVER_DEBUG)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002092 return p_cds_context->driver_debug_log_level;
2093 else if (ring_id == RING_ID_FIRMWARE_DEBUG)
2094 return p_cds_context->fw_debug_log_level;
2095
2096 return WLAN_LOG_LEVEL_OFF;
2097}
2098
2099/**
2100 * cds_set_multicast_logging() - Set mutlicast logging value
2101 * @value: Value of multicast logging
2102 *
2103 * Set the multicast logging value which will indicate
2104 * whether to multicast host and fw messages even
2105 * without any registration by userspace entity
2106 *
2107 * Return: None
2108 */
2109void cds_set_multicast_logging(uint8_t value)
2110{
2111 cds_multicast_logging = value;
2112}
2113
2114/**
2115 * cds_is_multicast_logging() - Get multicast logging value
2116 *
2117 * Get the multicast logging value which will indicate
2118 * whether to multicast host and fw messages even
2119 * without any registration by userspace entity
2120 *
2121 * Return: 0 - Multicast logging disabled, 1 - Multicast logging enabled
2122 */
2123uint8_t cds_is_multicast_logging(void)
2124{
2125 return cds_multicast_logging;
2126}
2127
2128/*
2129 * cds_init_log_completion() - Initialize log param structure
2130 *
2131 * This function is used to initialize the logging related
2132 * parameters
2133 *
2134 * Return: None
2135 */
2136void cds_init_log_completion(void)
2137{
2138 p_cds_contextType p_cds_context;
2139
2140 p_cds_context = cds_get_global_context();
2141 if (!p_cds_context) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302142 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002143 "%s: cds context is Invalid", __func__);
2144 return;
2145 }
2146
2147 p_cds_context->log_complete.is_fatal = WLAN_LOG_TYPE_NON_FATAL;
2148 p_cds_context->log_complete.indicator = WLAN_LOG_INDICATOR_UNUSED;
2149 p_cds_context->log_complete.reason_code = WLAN_LOG_REASON_CODE_UNUSED;
2150 p_cds_context->log_complete.is_report_in_progress = false;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002151}
2152
2153/**
2154 * cds_set_log_completion() - Store the logging params
2155 * @is_fatal: Indicates if the event triggering bug report is fatal or not
2156 * @indicator: Source which trigerred the bug report
2157 * @reason_code: Reason for triggering bug report
Abhishek Singh5ea86532016-04-27 14:10:53 +05302158 * @recovery_needed: If recovery is needed after bug report
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002159 *
2160 * This function is used to set the logging parameters based on the
2161 * caller
2162 *
2163 * Return: 0 if setting of params is successful
2164 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302165QDF_STATUS cds_set_log_completion(uint32_t is_fatal,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002166 uint32_t indicator,
Abhishek Singh5ea86532016-04-27 14:10:53 +05302167 uint32_t reason_code,
2168 bool recovery_needed)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002169{
2170 p_cds_contextType p_cds_context;
2171
2172 p_cds_context = cds_get_global_context();
2173 if (!p_cds_context) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302174 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002175 "%s: cds context is Invalid", __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302176 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002177 }
2178
Anurag Chouhana37b5b72016-02-21 14:53:42 +05302179 qdf_spinlock_acquire(&p_cds_context->bug_report_lock);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002180 p_cds_context->log_complete.is_fatal = is_fatal;
2181 p_cds_context->log_complete.indicator = indicator;
2182 p_cds_context->log_complete.reason_code = reason_code;
Abhishek Singh5ea86532016-04-27 14:10:53 +05302183 p_cds_context->log_complete.recovery_needed = recovery_needed;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002184 p_cds_context->log_complete.is_report_in_progress = true;
Anurag Chouhana37b5b72016-02-21 14:53:42 +05302185 qdf_spinlock_release(&p_cds_context->bug_report_lock);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302186 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002187}
2188
2189/**
Abhishek Singh5ea86532016-04-27 14:10:53 +05302190 * cds_get_and_reset_log_completion() - Get and reset logging related params
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002191 * @is_fatal: Indicates if the event triggering bug report is fatal or not
2192 * @indicator: Source which trigerred the bug report
2193 * @reason_code: Reason for triggering bug report
Abhishek Singh5ea86532016-04-27 14:10:53 +05302194 * @recovery_needed: If recovery is needed after bug report
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002195 *
2196 * This function is used to get the logging related parameters
2197 *
2198 * Return: None
2199 */
Abhishek Singh5ea86532016-04-27 14:10:53 +05302200void cds_get_and_reset_log_completion(uint32_t *is_fatal,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002201 uint32_t *indicator,
Abhishek Singh5ea86532016-04-27 14:10:53 +05302202 uint32_t *reason_code,
2203 bool *recovery_needed)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002204{
2205 p_cds_contextType p_cds_context;
2206
2207 p_cds_context = cds_get_global_context();
2208 if (!p_cds_context) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302209 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002210 "%s: cds context is Invalid", __func__);
2211 return;
2212 }
2213
Anurag Chouhana37b5b72016-02-21 14:53:42 +05302214 qdf_spinlock_acquire(&p_cds_context->bug_report_lock);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002215 *is_fatal = p_cds_context->log_complete.is_fatal;
2216 *indicator = p_cds_context->log_complete.indicator;
2217 *reason_code = p_cds_context->log_complete.reason_code;
Abhishek Singh5ea86532016-04-27 14:10:53 +05302218 *recovery_needed = p_cds_context->log_complete.recovery_needed;
2219
2220 /* reset */
2221 p_cds_context->log_complete.indicator = WLAN_LOG_INDICATOR_UNUSED;
2222 p_cds_context->log_complete.is_fatal = WLAN_LOG_TYPE_NON_FATAL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002223 p_cds_context->log_complete.is_report_in_progress = false;
Abhishek Singh5ea86532016-04-27 14:10:53 +05302224 p_cds_context->log_complete.reason_code = WLAN_LOG_REASON_CODE_UNUSED;
2225 p_cds_context->log_complete.recovery_needed = false;
Anurag Chouhana37b5b72016-02-21 14:53:42 +05302226 qdf_spinlock_release(&p_cds_context->bug_report_lock);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002227}
2228
2229/**
2230 * cds_is_log_report_in_progress() - Check if bug reporting is in progress
2231 *
2232 * This function is used to check if the bug reporting is already in progress
2233 *
2234 * Return: true if the bug reporting is in progress
2235 */
2236bool cds_is_log_report_in_progress(void)
2237{
2238 p_cds_contextType p_cds_context;
2239
2240 p_cds_context = cds_get_global_context();
2241 if (!p_cds_context) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302242 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002243 "%s: cds context is Invalid", __func__);
2244 return true;
2245 }
2246 return p_cds_context->log_complete.is_report_in_progress;
2247}
2248
2249/**
Abhishek Singh5ea86532016-04-27 14:10:53 +05302250 * cds_is_fatal_event_enabled() - Return if fatal event is enabled
2251 *
2252 * Return true if fatal event is enabled.
2253 */
2254bool cds_is_fatal_event_enabled(void)
2255{
2256 p_cds_contextType p_cds_context;
2257
2258 p_cds_context = cds_get_global_context();
2259 if (!p_cds_context) {
2260 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
2261 "%s: cds context is Invalid", __func__);
2262 return false;
2263 }
2264
2265
2266 return p_cds_context->enable_fatal_event;
2267}
2268
Yu Wang66a250b2017-07-19 11:46:40 +08002269#ifdef WLAN_FEATURE_TSF_PLUS
2270bool cds_is_ptp_rx_opt_enabled(void)
2271{
2272 struct hdd_context *hdd_ctx;
2273 p_cds_contextType p_cds_context;
2274
2275 p_cds_context = cds_get_global_context();
2276 if (!p_cds_context) {
2277 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
2278 "%s: cds context is Invalid", __func__);
2279 return false;
2280 }
2281
2282 hdd_ctx = (struct hdd_context *)(p_cds_context->pHDDContext);
2283 if ((NULL == hdd_ctx) || (NULL == hdd_ctx->config)) {
2284 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
2285 "%s: Hdd Context is Null", __func__);
2286 return false;
2287 }
2288
2289 return HDD_TSF_IS_RX_SET(hdd_ctx);
2290}
2291
2292bool cds_is_ptp_tx_opt_enabled(void)
2293{
2294 struct hdd_context *hdd_ctx;
2295 p_cds_contextType p_cds_context;
2296
2297 p_cds_context = cds_get_global_context();
2298 if (!p_cds_context) {
2299 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
2300 "%s: cds context is Invalid", __func__);
2301 return false;
2302 }
2303
2304 hdd_ctx = (struct hdd_context *)(p_cds_context->pHDDContext);
2305 if ((NULL == hdd_ctx) || (NULL == hdd_ctx->config)) {
2306 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
2307 "%s: Hdd Context is Null", __func__);
2308 return false;
2309 }
2310
2311 return HDD_TSF_IS_TX_SET(hdd_ctx);
2312}
2313#endif
2314
Abhishek Singh5ea86532016-04-27 14:10:53 +05302315/**
2316 * cds_get_log_indicator() - Get the log flush indicator
2317 *
2318 * This function is used to get the log flush indicator
2319 *
2320 * Return: log indicator
2321 */
2322uint32_t cds_get_log_indicator(void)
2323{
2324 p_cds_contextType p_cds_context;
2325 uint32_t indicator;
2326
2327 p_cds_context = cds_get_global_context();
2328 if (!p_cds_context) {
2329 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
2330 "%s: cds context is Invalid", __func__);
2331 return WLAN_LOG_INDICATOR_UNUSED;
2332 }
2333
2334 if (cds_is_load_or_unload_in_progress() ||
Hanumanth Reddy Pothula2a8a7402017-07-03 14:06:11 +05302335 cds_is_driver_recovering() || cds_is_driver_in_bad_state()) {
Abhishek Singh5ea86532016-04-27 14:10:53 +05302336 return WLAN_LOG_INDICATOR_UNUSED;
2337 }
2338
2339 qdf_spinlock_acquire(&p_cds_context->bug_report_lock);
2340 indicator = p_cds_context->log_complete.indicator;
2341 qdf_spinlock_release(&p_cds_context->bug_report_lock);
2342 return indicator;
2343}
2344
2345/**
2346 * cds_wlan_flush_host_logs_for_fatal() - Wrapper to flush host logs
2347 *
2348 * This function is used to send signal to the logger thread to
2349 * flush the host logs.
2350 *
2351 * Return: None
2352 *
2353 */
2354void cds_wlan_flush_host_logs_for_fatal(void)
2355{
2356 wlan_flush_host_logs_for_fatal();
2357}
2358
2359/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002360 * cds_flush_logs() - Report fatal event to userspace
2361 * @is_fatal: Indicates if the event triggering bug report is fatal or not
2362 * @indicator: Source which trigerred the bug report
2363 * @reason_code: Reason for triggering bug report
Abhishek Singh5ea86532016-04-27 14:10:53 +05302364 * @dump_mac_trace: If mac trace are needed in logs.
2365 * @recovery_needed: If recovery is needed after bug report
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002366 *
2367 * This function sets the log related params and send the WMI command to the
2368 * FW to flush its logs. On receiving the flush completion event from the FW
2369 * the same will be conveyed to userspace
2370 *
2371 * Return: 0 on success
2372 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302373QDF_STATUS cds_flush_logs(uint32_t is_fatal,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002374 uint32_t indicator,
Abhishek Singh5ea86532016-04-27 14:10:53 +05302375 uint32_t reason_code,
2376 bool dump_mac_trace,
2377 bool recovery_needed)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002378{
2379 uint32_t ret;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302380 QDF_STATUS status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002381
2382 p_cds_contextType p_cds_context;
2383
2384 p_cds_context = cds_get_global_context();
2385 if (!p_cds_context) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302386 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002387 "%s: cds context is Invalid", __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302388 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002389 }
Abhishek Singh5ea86532016-04-27 14:10:53 +05302390 if (!p_cds_context->enable_fatal_event) {
2391 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
2392 "%s: Fatal event not enabled", __func__);
2393 return QDF_STATUS_E_FAILURE;
2394 }
2395 if (cds_is_load_or_unload_in_progress() ||
Hanumanth Reddy Pothula2a8a7402017-07-03 14:06:11 +05302396 cds_is_driver_recovering() || cds_is_driver_in_bad_state()) {
Abhishek Singh5ea86532016-04-27 14:10:53 +05302397 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
2398 "%s: un/Load/SSR in progress", __func__);
2399 return QDF_STATUS_E_FAILURE;
2400 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002401
2402 if (cds_is_log_report_in_progress() == true) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302403 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002404 "%s: Bug report already in progress - dropping! type:%d, indicator=%d reason_code=%d",
2405 __func__, is_fatal, indicator, reason_code);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302406 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002407 }
2408
Abhishek Singh5ea86532016-04-27 14:10:53 +05302409 status = cds_set_log_completion(is_fatal, indicator,
2410 reason_code, recovery_needed);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302411 if (QDF_STATUS_SUCCESS != status) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302412 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002413 "%s: Failed to set log trigger params", __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302414 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002415 }
2416
Abhishek Singh5ea86532016-04-27 14:10:53 +05302417 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002418 "%s: Triggering bug report: type:%d, indicator=%d reason_code=%d",
2419 __func__, is_fatal, indicator, reason_code);
2420
Abhishek Singh5ea86532016-04-27 14:10:53 +05302421 if (dump_mac_trace)
2422 qdf_trace_dump_all(p_cds_context->pMACContext, 0, 0, 500, 0);
2423
2424 if (WLAN_LOG_INDICATOR_HOST_ONLY == indicator) {
2425 cds_wlan_flush_host_logs_for_fatal();
2426 return QDF_STATUS_SUCCESS;
2427 }
2428
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002429 ret = sme_send_flush_logs_cmd_to_fw(p_cds_context->pMACContext);
2430 if (0 != ret) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302431 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002432 "%s: Failed to send flush FW log", __func__);
2433 cds_init_log_completion();
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302434 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002435 }
2436
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302437 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002438}
2439
2440/**
2441 * cds_logging_set_fw_flush_complete() - Wrapper for FW log flush completion
2442 *
2443 * This function is used to send signal to the logger thread to indicate
2444 * that the flushing of FW logs is complete by the FW
2445 *
2446 * Return: None
2447 *
2448 */
2449void cds_logging_set_fw_flush_complete(void)
2450{
2451 wlan_logging_set_fw_flush_complete();
2452}
Abhishek Singh5ea86532016-04-27 14:10:53 +05302453
2454/**
2455 * cds_set_fatal_event() - set fatal event status
2456 * @value: pending statue to set
2457 *
2458 * Return: None
2459 */
2460void cds_set_fatal_event(bool value)
2461{
2462 p_cds_contextType p_cds_context;
2463
2464 p_cds_context = cds_get_global_context();
2465 if (!p_cds_context) {
2466 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
2467 "%s: cds context is Invalid", __func__);
2468 return;
2469 }
2470 p_cds_context->enable_fatal_event = value;
2471}
2472
Ryan Hsuceddceb2016-04-28 10:20:14 -07002473/**
2474 * cds_get_radio_index() - get radio index
2475 *
2476 * Return: radio index otherwise, -EINVAL
2477 */
2478int cds_get_radio_index(void)
2479{
2480 p_cds_contextType p_cds_context;
2481
2482 p_cds_context = cds_get_global_context();
2483 if (!p_cds_context) {
2484 /*
2485 * To avoid recursive call, this should not change to
2486 * QDF_TRACE().
2487 */
2488 pr_err("%s: cds context is invalid\n", __func__);
2489 return -EINVAL;
2490 }
2491
2492 return p_cds_context->radio_index;
2493}
2494
2495/**
2496 * cds_set_radio_index() - set radio index
2497 * @radio_index: the radio index to set
2498 *
2499 * Return: QDF status
2500 */
2501QDF_STATUS cds_set_radio_index(int radio_index)
2502{
2503 p_cds_contextType p_cds_context;
2504
2505 p_cds_context = cds_get_global_context();
2506 if (!p_cds_context) {
2507 pr_err("%s: cds context is invalid\n", __func__);
2508 return QDF_STATUS_E_FAILURE;
2509 }
2510
2511 p_cds_context->radio_index = radio_index;
2512
2513 return QDF_STATUS_SUCCESS;
2514}
Arun Khandavallic811dcc2016-06-26 07:37:21 +05302515
2516/**
2517 * cds_init_ini_config() - API to initialize CDS configuration parameters
2518 * @cfg: CDS Configuration
2519 *
2520 * Return: void
2521 */
2522
2523void cds_init_ini_config(struct cds_config_info *cfg)
2524{
2525 cds_context_type *cds_ctx;
2526
2527 cds_ctx = cds_get_context(QDF_MODULE_ID_QDF);
2528 if (!cds_ctx) {
2529 cds_err("Invalid CDS Context");
2530 return;
2531 }
2532
2533 cds_ctx->cds_cfg = cfg;
2534}
2535
2536/**
2537 * cds_deinit_ini_config() - API to free CDS configuration parameters
2538 *
2539 * Return: void
2540 */
2541void cds_deinit_ini_config(void)
2542{
2543 cds_context_type *cds_ctx;
2544
2545 cds_ctx = cds_get_context(QDF_MODULE_ID_QDF);
2546 if (!cds_ctx) {
2547 cds_err("Invalid CDS Context");
2548 return;
2549 }
2550
Arun Khandavallif6246632016-08-17 17:43:06 +05302551 if (cds_ctx->cds_cfg)
Arun Khandavallic811dcc2016-06-26 07:37:21 +05302552 qdf_mem_free(cds_ctx->cds_cfg);
2553
2554 cds_ctx->cds_cfg = NULL;
2555}
2556
2557/**
2558 * cds_get_ini_config() - API to get CDS configuration parameters
2559 *
2560 * Return: cds config structure
2561 */
2562struct cds_config_info *cds_get_ini_config(void)
2563{
2564 cds_context_type *cds_ctx;
2565
2566 cds_ctx = cds_get_context(QDF_MODULE_ID_QDF);
2567 if (!cds_ctx) {
2568 cds_err("Invalid CDS Context");
2569 return NULL;
2570 }
2571
2572 return cds_ctx->cds_cfg;
2573}
Naveen Rawat64e477e2016-05-20 10:34:56 -07002574
2575/**
2576 * cds_is_5_mhz_enabled() - API to get 5MHZ enabled
2577 *
2578 * Return: true if 5 mhz is enabled, false otherwise
2579 */
2580bool cds_is_5_mhz_enabled(void)
2581{
2582 p_cds_contextType p_cds_context;
2583
2584 p_cds_context = cds_get_context(QDF_MODULE_ID_QDF);
2585 if (!p_cds_context) {
2586 cds_err("%s: cds context is invalid", __func__);
2587 return false;
2588 }
2589
2590 if (p_cds_context->cds_cfg)
2591 return (p_cds_context->cds_cfg->sub_20_channel_width ==
2592 WLAN_SUB_20_CH_WIDTH_5);
2593
2594 return false;
2595}
2596
2597/**
2598 * cds_is_10_mhz_enabled() - API to get 10-MHZ enabled
2599 *
2600 * Return: true if 10 mhz is enabled, false otherwise
2601 */
2602bool cds_is_10_mhz_enabled(void)
2603{
2604 p_cds_contextType p_cds_context;
2605
2606 p_cds_context = cds_get_context(QDF_MODULE_ID_QDF);
2607 if (!p_cds_context) {
2608 cds_err("%s: cds context is invalid", __func__);
2609 return false;
2610 }
2611
2612 if (p_cds_context->cds_cfg)
2613 return (p_cds_context->cds_cfg->sub_20_channel_width ==
2614 WLAN_SUB_20_CH_WIDTH_10);
2615
2616 return false;
2617}
2618
2619/**
2620 * cds_is_sub_20_mhz_enabled() - API to get sub 20-MHZ enabled
2621 *
2622 * Return: true if 5 or 10 mhz is enabled, false otherwise
2623 */
2624bool cds_is_sub_20_mhz_enabled(void)
2625{
2626 p_cds_contextType p_cds_context;
2627
2628 p_cds_context = cds_get_context(QDF_MODULE_ID_QDF);
2629 if (!p_cds_context) {
2630 cds_err("%s: cds context is invalid", __func__);
2631 return false;
2632 }
2633
2634 if (p_cds_context->cds_cfg)
2635 return p_cds_context->cds_cfg->sub_20_channel_width;
2636
2637 return false;
2638}
2639
Komal Seelam78ff65a2016-08-18 15:25:24 +05302640/**
Naveen Rawat91df30a2016-10-12 21:26:18 -07002641 * cds_is_self_recovery_enabled() - API to get self recovery enabled
2642 *
2643 * Return: true if self recovery enabled, false otherwise
2644 */
2645bool cds_is_self_recovery_enabled(void)
2646{
2647 p_cds_contextType p_cds_context;
2648
2649 p_cds_context = cds_get_context(QDF_MODULE_ID_QDF);
2650 if (!p_cds_context) {
2651 cds_err("%s: cds context is invalid", __func__);
2652 return false;
2653 }
2654
2655 if (p_cds_context->cds_cfg)
2656 return p_cds_context->cds_cfg->self_recovery_enabled;
2657
2658 return false;
2659}
2660
2661/**
Komal Seelam78ff65a2016-08-18 15:25:24 +05302662 * cds_svc_fw_shutdown_ind() - API to send userspace about FW crash
2663 *
2664 * @dev: Device Pointer
2665 *
2666 * Return: None
2667 */
2668void cds_svc_fw_shutdown_ind(struct device *dev)
2669{
2670 hdd_svc_fw_shutdown_ind(dev);
2671}
Himanshu Agarwal46956a52016-07-26 19:46:25 +05302672
2673/*
2674 * cds_pkt_stats_to_logger_thread() - send pktstats to user
2675 * @pl_hdr: Pointer to pl_hdr
2676 * @pkt_dump: Pointer to pkt_dump data structure.
2677 * @data: Pointer to data
2678 *
2679 * This function is used to send the pkt stats to SVC module.
2680 *
2681 * Return: None
2682 */
2683inline void cds_pkt_stats_to_logger_thread(void *pl_hdr, void *pkt_dump,
2684 void *data)
2685{
2686 if (cds_get_ring_log_level(RING_ID_PER_PACKET_STATS) !=
2687 WLAN_LOG_LEVEL_ACTIVE)
2688 return;
2689
2690 wlan_pkt_stats_to_logger_thread(pl_hdr, pkt_dump, data);
2691}
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -08002692
2693/**
2694 * cds_get_conparam() - Get the connection mode parameters
2695 *
2696 * Return the connection mode parameter set by insmod or set during statically
2697 * linked driver
2698 *
2699 * Return: enum tQDF_GLOBAL_CON_MODE
2700 */
2701enum tQDF_GLOBAL_CON_MODE cds_get_conparam(void)
2702{
2703 enum tQDF_GLOBAL_CON_MODE con_mode;
2704
2705 con_mode = hdd_get_conparam();
2706
2707 return con_mode;
2708}
Dustin Brown8d2d0f52017-04-03 17:02:08 -07002709
2710#ifdef WMI_INTERFACE_EVENT_LOGGING
2711inline void
2712cds_print_htc_credit_history(uint32_t count, qdf_abstract_print *print,
2713 void *print_priv)
2714{
2715 htc_print_credit_history(gp_cds_context->htc_ctx, count,
2716 print, print_priv);
2717}
2718#endif