blob: f0f4045d7195b2d5f30010a569c0e8148ee69f38 [file] [log] [blame]
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001/*
Kabilan Kannan973744a2018-01-03 10:28:50 -08002 * Copyright (c) 2012-2018 The Linux Foundation. All rights reserved.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003 *
4 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
5 *
6 *
7 * Permission to use, copy, modify, and/or distribute this software for
8 * any purpose with or without fee is hereby granted, provided that the
9 * above copyright notice and this permission notice appear in all
10 * copies.
11 *
12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
13 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
14 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
15 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
16 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
17 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
18 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
19 * PERFORMANCE OF THIS SOFTWARE.
20 */
21
22/*
23 * This file was originally distributed by Qualcomm Atheros, Inc.
24 * under proprietary terms before Copyright ownership was assigned
25 * to the Linux Foundation.
26 */
27
28/**
29 * DOC: cds_api.c
30 *
31 * Connectivity driver services APIs
32 */
33
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080034#include "cds_sched.h"
35#include <cds_api.h>
36#include "sir_types.h"
37#include "sir_api.h"
38#include "sir_mac_prot_def.h"
39#include "sme_api.h"
40#include "mac_init_api.h"
41#include "wlan_qct_sys.h"
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080042#include "i_cds_packet.h"
43#include "cds_reg_service.h"
44#include "wma_types.h"
45#include "wlan_hdd_main.h"
Yu Wang66a250b2017-07-19 11:46:40 +080046#include "wlan_hdd_tsf.h"
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080047#include <linux/vmalloc.h>
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080048
Yuanyuan Liu0e0aa932016-05-12 10:17:58 -070049#include "pld_common.h"
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080050#include "sap_api.h"
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +053051#include "qdf_trace.h"
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080052#include "bmi.h"
53#include "ol_fw.h"
54#include "ol_if_athvar.h"
55#include "hif.h"
Tushnim Bhattacharyya12b48742017-03-13 12:46:45 -070056#include "wlan_policy_mgr_api.h"
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080057#include "cds_utils.h"
58#include "wlan_logging_sock_svc.h"
59#include "wma.h"
Nirav Shah7f337db2016-05-25 10:49:02 +053060#include "pktlog_ac.h"
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080061#include "wlan_hdd_ipa.h"
Pramod Simha0d3b9362017-03-27 14:59:58 -070062#include "wlan_policy_mgr_api.h"
Leo Chang9b097032016-10-28 11:03:17 -070063
64#include <cdp_txrx_cmn_reg.h>
65#include <cdp_txrx_cfg.h>
66#include <cdp_txrx_misc.h>
Rajeev Kumar97767a02016-11-30 11:20:40 -080067#include <dispatcher_init_deinit.h>
Venkata Sharath Chandra Manchala0d44d452016-11-23 17:48:15 -080068#include <cdp_txrx_handle.h>
Dustin Browna2dcb5f2017-10-20 17:36:19 -070069#include "qdf_cpuhp.h"
Govind Singh27a74032017-11-10 15:08:19 +053070#include "target_type.h"
Zhang Qian47e22ce2018-01-04 15:38:38 +080071#include "wlan_ocb_ucfg_api.h"
Rajeev Kumara6268de2018-03-09 14:58:53 -080072#include "qdf_platform.h"
Venkata Sharath Chandra Manchala0d44d452016-11-23 17:48:15 -080073
Himanshu Agarwaledf30dc2017-06-05 15:54:27 +053074#ifdef ENABLE_SMMU_S1_TRANSLATION
75#include "pld_common.h"
76#include <asm/dma-iommu.h>
77#include <linux/iommu.h>
78#endif
79/* Preprocessor Definitions and Constants */
80
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080081/* Preprocessor Definitions and Constants */
82
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080083/* Data definitions */
84static cds_context_type g_cds_context;
85static p_cds_contextType gp_cds_context;
Anurag Chouhandf2b2682016-02-29 14:15:27 +053086static struct __qdf_device g_qdf_ctx;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080087
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080088static uint8_t cds_multicast_logging;
89
Leo Chang9b097032016-10-28 11:03:17 -070090static struct ol_if_ops dp_ol_if_ops = {
91 .peer_set_default_routing = wma_peer_set_default_routing,
92 .peer_rx_reorder_queue_setup = wma_peer_rx_reorder_queue_setup,
93 .peer_rx_reorder_queue_remove = wma_peer_rx_reorder_queue_remove,
Dhanashri Atref5e02122017-04-13 15:36:42 -070094 .is_hw_dbs_2x2_capable = policy_mgr_is_hw_dbs_2x2_capable,
jiadcd49ec72017-12-05 13:33:11 +080095 .lro_hash_config = wma_lro_config_cmd,
96 .rx_mic_error = wma_rx_mic_error_ind
Leo Chang9b097032016-10-28 11:03:17 -070097 /* TODO: Add any other control path calls required to OL_IF/WMA layer */
98};
99
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800100void cds_sys_probe_thread_cback(void *pUserData);
Srinivas Girigowda161b9f22017-07-24 17:38:09 -0700101static void cds_trigger_recovery_work(void *param);
102
103/**
104 * cds_recovery_work_init() - Initialize recovery work queue
105 *
106 * Return: none
107 */
108static QDF_STATUS cds_recovery_work_init(void)
109{
110 qdf_create_work(0, &gp_cds_context->cds_recovery_work,
111 cds_trigger_recovery_work, NULL);
112 gp_cds_context->cds_recovery_wq =
113 qdf_create_workqueue("cds_recovery_workqueue");
114 if (NULL == gp_cds_context->cds_recovery_wq) {
115 cds_err("Failed to create cds_recovery_workqueue");
116 return QDF_STATUS_E_FAILURE;
117 }
118
119 return QDF_STATUS_SUCCESS;
120}
121
122/**
123 * cds_recovery_work_deinit() - Initialize recovery work queue
124 *
125 * Return: none
126 */
127static void cds_recovery_work_deinit(void)
128{
129 if (gp_cds_context->cds_recovery_wq) {
130 qdf_flush_workqueue(0, gp_cds_context->cds_recovery_wq);
131 qdf_destroy_workqueue(0, gp_cds_context->cds_recovery_wq);
132 }
133}
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800134
Venkata Sharath Chandra Manchala83985632017-02-28 14:16:22 -0800135/** cds_get_datapath_handles - Initialize pdev, vdev and soc
136 * @soc - soc handle
137 * @vdev - virtual handle
138 * @pdev - physical handle
139 */
140uint8_t cds_get_datapath_handles(void **soc, struct cdp_pdev **pdev,
141 struct cdp_vdev **vdev, uint8_t sessionId)
142{
143
144 (*soc) = cds_get_context(QDF_MODULE_ID_SOC);
145
146 if (!(*soc)) {
147 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
148 "soc handle is invalid");
149 return -EINVAL;
150 }
151
152 (*pdev) = cds_get_context(QDF_MODULE_ID_TXRX);
153
154 if (!(*pdev)) {
155 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
156 "pdev handle is invalid");
157 return -EINVAL;
158 }
159
160 (*vdev) = cdp_get_vdev_from_vdev_id((*soc), (*pdev),
161 sessionId);
162
163 if (!(*vdev)) {
164 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
165 "vdev handle is invalid");
166 return -EINVAL;
167 }
168 return 0;
169}
170
171
Jeff Johnson7aaeeea2017-09-26 13:16:24 -0700172QDF_STATUS cds_init(void)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800173{
wadesongae4ffd12017-10-24 16:45:54 +0800174 QDF_STATUS ret;
175
176 ret = qdf_debugfs_init();
Rajeev Kumar3f5c5932018-03-09 13:14:46 -0800177 if (ret != QDF_STATUS_SUCCESS)
wadesongae4ffd12017-10-24 16:45:54 +0800178 cds_err("Failed to init debugfs");
wadesongae4ffd12017-10-24 16:45:54 +0800179
Houston Hoffman1a777572017-01-13 12:43:48 -0800180 qdf_lock_stats_init();
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530181 qdf_mem_init();
Houston Hoffman9e06e542016-12-12 12:06:26 -0800182 qdf_mc_timer_manager_init();
Nachiket Kukade0396b732017-11-14 16:35:16 +0530183 qdf_event_list_init();
Dustin Browna2dcb5f2017-10-20 17:36:19 -0700184 qdf_cpuhp_init();
Dustin Brown100201e2017-07-10 11:48:40 -0700185 qdf_register_self_recovery_callback(cds_trigger_recovery);
Rajeev Kumar807c5f52018-03-08 13:29:08 -0800186 qdf_register_fw_down_callback(cds_is_fw_down);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800187
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800188 gp_cds_context = &g_cds_context;
189
Anurag Chouhandf2b2682016-02-29 14:15:27 +0530190 gp_cds_context->qdf_ctx = &g_qdf_ctx;
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530191 qdf_mem_zero(&g_qdf_ctx, sizeof(g_qdf_ctx));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800192
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530193 qdf_trace_spin_lock_init();
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530194 qdf_trace_init();
Rachit Kankane0baf6e72018-01-19 15:01:50 +0530195
Padma, Santhosh Kumar9aba02f2016-08-11 16:30:25 +0530196 qdf_register_debugcb_init();
Prashanth Bhatta5da711e2015-11-30 14:28:52 -0800197
198 cds_ssr_protect_init();
199
wadesongae4ffd12017-10-24 16:45:54 +0800200 ret = cds_recovery_work_init();
201 if (ret != QDF_STATUS_SUCCESS) {
202 cds_err("Failed to init recovery work");
203 goto deinit;
204 }
Srinivas Girigowda161b9f22017-07-24 17:38:09 -0700205
wadesongae4ffd12017-10-24 16:45:54 +0800206 return QDF_STATUS_SUCCESS;
207deinit:
208 qdf_mc_timer_manager_exit();
209 qdf_mem_exit();
210 qdf_lock_stats_deinit();
211 qdf_debugfs_exit();
212 gp_cds_context->qdf_ctx = NULL;
213 gp_cds_context = NULL;
214 qdf_mem_zero(&g_cds_context, sizeof(g_cds_context));
wadesongae4ffd12017-10-24 16:45:54 +0800215 return ret;
Prashanth Bhatta5da711e2015-11-30 14:28:52 -0800216}
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800217
218/**
Prashanth Bhatta5da711e2015-11-30 14:28:52 -0800219 * cds_deinit() - Deinitialize CDS
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800220 *
Prashanth Bhatta5da711e2015-11-30 14:28:52 -0800221 * This function frees the CDS resources
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800222 */
Prashanth Bhatta5da711e2015-11-30 14:28:52 -0800223void cds_deinit(void)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800224{
Prashanth Bhatta5da711e2015-11-30 14:28:52 -0800225 if (gp_cds_context == NULL)
226 return;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800227
Srinivas Girigowda161b9f22017-07-24 17:38:09 -0700228 cds_recovery_work_deinit();
Dustin Browna2dcb5f2017-10-20 17:36:19 -0700229 qdf_cpuhp_deinit();
Arunk Khandavalli4cc97a92016-09-14 23:13:07 +0530230 qdf_mc_timer_manager_exit();
231 qdf_mem_exit();
Houston Hoffman1a777572017-01-13 12:43:48 -0800232 qdf_lock_stats_deinit();
Mahesh Kumar Kalikot Veetil319dbcd2016-10-27 15:03:48 -0700233 qdf_debugfs_exit();
Nachiket Kukade0396b732017-11-14 16:35:16 +0530234 qdf_event_list_destroy();
Arunk Khandavalli4cc97a92016-09-14 23:13:07 +0530235
Anurag Chouhan6d760662016-02-20 16:05:43 +0530236 gp_cds_context->qdf_ctx = NULL;
Prashanth Bhatta5da711e2015-11-30 14:28:52 -0800237 gp_cds_context = NULL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800238
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530239 qdf_mem_zero(&g_cds_context, sizeof(g_cds_context));
Prashanth Bhatta5da711e2015-11-30 14:28:52 -0800240 return;
241}
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800242
Abhishek Singh437606a2016-04-27 13:51:49 +0530243#ifdef FEATURE_WLAN_DIAG_SUPPORT
244/**
245 * cds_tdls_tx_rx_mgmt_event()- send tdls mgmt rx tx event
246 * @event_id: event id
247 * @tx_rx: tx or rx
248 * @type: type of frame
249 * @action_sub_type: action frame type
250 * @peer_mac: peer mac
251 *
252 * This Function sends tdls mgmt rx tx diag event
253 *
254 * Return: void.
255 */
256void cds_tdls_tx_rx_mgmt_event(uint8_t event_id, uint8_t tx_rx,
257 uint8_t type, uint8_t action_sub_type, uint8_t *peer_mac)
258{
259 WLAN_HOST_DIAG_EVENT_DEF(tdls_tx_rx_mgmt,
260 struct host_event_tdls_tx_rx_mgmt);
261
262 tdls_tx_rx_mgmt.event_id = event_id;
263 tdls_tx_rx_mgmt.tx_rx = tx_rx;
264 tdls_tx_rx_mgmt.type = type;
265 tdls_tx_rx_mgmt.action_sub_type = action_sub_type;
266 qdf_mem_copy(tdls_tx_rx_mgmt.peer_mac,
267 peer_mac, CDS_MAC_ADDRESS_LEN);
268 WLAN_HOST_DIAG_EVENT_REPORT(&tdls_tx_rx_mgmt,
269 EVENT_WLAN_TDLS_TX_RX_MGMT);
270}
271#endif
272
Leo Chang9b097032016-10-28 11:03:17 -0700273/**
gbian62edd7e2017-03-07 13:12:13 +0800274 * cds_cfg_update_ac_specs_params() - update ac_specs params
275 * @olcfg: cfg handle
276 * @mac_params: mac params
277 *
278 * Return: none
279 */
280static void
281cds_cfg_update_ac_specs_params(struct txrx_pdev_cfg_param_t *olcfg,
282 struct cds_config_info *cds_cfg)
283{
284 int i;
285
286 if (NULL == olcfg)
287 return;
288
289 if (NULL == cds_cfg)
290 return;
291
292 for (i = 0; i < OL_TX_NUM_WMM_AC; i++) {
293 olcfg->ac_specs[i].wrr_skip_weight =
294 cds_cfg->ac_specs[i].wrr_skip_weight;
295 olcfg->ac_specs[i].credit_threshold =
296 cds_cfg->ac_specs[i].credit_threshold;
297 olcfg->ac_specs[i].send_limit =
298 cds_cfg->ac_specs[i].send_limit;
299 olcfg->ac_specs[i].credit_reserve =
300 cds_cfg->ac_specs[i].credit_reserve;
301 olcfg->ac_specs[i].discard_weight =
302 cds_cfg->ac_specs[i].discard_weight;
303 }
304}
305
306/**
Leo Chang9b097032016-10-28 11:03:17 -0700307 * cds_cdp_cfg_attach() - attach data path config module
308 * @cds_cfg: generic platform level config instance
309 *
310 * Return: none
311 */
312static void cds_cdp_cfg_attach(struct cds_config_info *cds_cfg)
313{
314 struct txrx_pdev_cfg_param_t cdp_cfg = {0};
315 void *soc = cds_get_context(QDF_MODULE_ID_SOC);
316
Kiran Kumar Lokere52d8dc32016-12-05 19:20:40 -0800317 cdp_cfg.is_full_reorder_offload = cds_cfg->reorder_offload;
Leo Chang9b097032016-10-28 11:03:17 -0700318 cdp_cfg.is_uc_offload_enabled = cds_cfg->uc_offload_enabled;
319 cdp_cfg.uc_tx_buffer_count = cds_cfg->uc_txbuf_count;
320 cdp_cfg.uc_tx_buffer_size = cds_cfg->uc_txbuf_size;
321 cdp_cfg.uc_rx_indication_ring_count = cds_cfg->uc_rxind_ringcount;
322 cdp_cfg.uc_tx_partition_base = cds_cfg->uc_tx_partition_base;
323 cdp_cfg.enable_rxthread = cds_cfg->enable_rxthread;
324 cdp_cfg.ip_tcp_udp_checksum_offload =
325 cds_cfg->ip_tcp_udp_checksum_offload;
326 cdp_cfg.ce_classify_enabled = cds_cfg->ce_classify_enabled;
327
gbian62edd7e2017-03-07 13:12:13 +0800328 cds_cfg_update_ac_specs_params(&cdp_cfg, cds_cfg);
Kiran Kumar Lokere9aecfee2016-11-23 17:37:42 -0800329 gp_cds_context->cfg_ctx = cdp_cfg_attach(soc, gp_cds_context->qdf_ctx,
330 (void *)(&cdp_cfg));
331 if (!gp_cds_context->cfg_ctx) {
332 WMA_LOGP("%s: failed to init cfg handle", __func__);
333 return;
334 }
335
Leo Chang9b097032016-10-28 11:03:17 -0700336 /* Configure Receive flow steering */
Venkata Sharath Chandra Manchala0d44d452016-11-23 17:48:15 -0800337 cdp_cfg_set_flow_steering(soc, gp_cds_context->cfg_ctx,
Leo Chang9b097032016-10-28 11:03:17 -0700338 cds_cfg->flow_steering_enabled);
339
Venkata Sharath Chandra Manchala0d44d452016-11-23 17:48:15 -0800340 cdp_cfg_set_flow_control_parameters(soc, gp_cds_context->cfg_ctx,
341 (void *)&cdp_cfg);
Leo Chang9b097032016-10-28 11:03:17 -0700342
343 /* adjust the cfg_ctx default value based on setting */
344 cdp_cfg_set_rx_fwd_disabled(soc, gp_cds_context->cfg_ctx,
345 (uint8_t) cds_cfg->ap_disable_intrabss_fwd);
346
347 /*
348 * adjust the packet log enable default value
349 * based on CFG INI setting
350 */
351 cdp_cfg_set_packet_log_enabled(soc, gp_cds_context->cfg_ctx,
352 (uint8_t)cds_is_packet_log_enabled());
Yu Wang66a250b2017-07-19 11:46:40 +0800353
354 /* adjust the ptp rx option default value based on CFG INI setting */
355 cdp_cfg_set_ptp_rx_opt_enabled(soc, gp_cds_context->cfg_ctx,
356 (uint8_t)cds_is_ptp_rx_opt_enabled());
Leo Chang9b097032016-10-28 11:03:17 -0700357}
Krunal Sonid32c6bc2016-10-18 18:00:21 -0700358static QDF_STATUS cds_register_all_modules(void)
359{
360 QDF_STATUS status;
361
362 scheduler_register_wma_legacy_handler(&wma_mc_process_handler);
363 scheduler_register_sys_legacy_handler(&sys_mc_process_handler);
364
365 /* Register message queues in given order such that queue priority is
366 * intact:
367 * 1) QDF_MODULE_ID_SYS: Timer queue(legacy SYS queue)
368 * 2) QDF_MODULE_ID_TARGET_IF: Target interface queue
369 * 3) QDF_MODULE_ID_PE: Legacy PE message queue
370 * 4) QDF_MODULE_ID_SME: Legacy SME message queue
371 * 5) QDF_MODULE_ID_OS_IF: OS IF message queue for new components
372 */
373 status = scheduler_register_module(QDF_MODULE_ID_SYS,
374 &scheduler_timer_q_mq_handler);
375 status = scheduler_register_module(QDF_MODULE_ID_TARGET_IF,
376 &scheduler_target_if_mq_handler);
377 status = scheduler_register_module(QDF_MODULE_ID_PE,
378 &pe_mc_process_handler);
379 status = scheduler_register_module(QDF_MODULE_ID_SME,
380 &sme_mc_process_handler);
381 status = scheduler_register_module(QDF_MODULE_ID_OS_IF,
382 &scheduler_os_if_mq_handler);
383 return status;
384}
385
386static QDF_STATUS cds_deregister_all_modules(void)
387{
388 QDF_STATUS status;
Krunal Sonie3399902017-02-01 09:51:42 -0800389
390 scheduler_deregister_wma_legacy_handler();
391 scheduler_deregister_sys_legacy_handler();
Krunal Sonid32c6bc2016-10-18 18:00:21 -0700392 status = scheduler_deregister_module(QDF_MODULE_ID_SYS);
Rajeev Kumara88b2dc2017-01-30 16:35:14 -0800393 status = scheduler_deregister_module(QDF_MODULE_ID_TARGET_IF);
Krunal Sonid32c6bc2016-10-18 18:00:21 -0700394 status = scheduler_deregister_module(QDF_MODULE_ID_PE);
395 status = scheduler_deregister_module(QDF_MODULE_ID_SME);
396 status = scheduler_deregister_module(QDF_MODULE_ID_OS_IF);
Krunal Sonie3399902017-02-01 09:51:42 -0800397
Krunal Sonid32c6bc2016-10-18 18:00:21 -0700398 return status;
399}
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800400
401/**
gbian62edd7e2017-03-07 13:12:13 +0800402 * cds_set_ac_specs_params() - set ac_specs params in cds_config_info
403 * @cds_cfg: Pointer to cds_config_info
404 * @hdd_ctx: Pointer to hdd context
405 *
406 * Return: none
407 */
408static void
409cds_set_ac_specs_params(struct cds_config_info *cds_cfg)
410{
411 int i;
412 cds_context_type *cds_ctx;
413
414 if (NULL == cds_cfg)
415 return;
416
417 cds_ctx = cds_get_context(QDF_MODULE_ID_QDF);
418
419 if (!cds_ctx) {
420 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
421 "Invalid CDS Context");
422 return;
423 }
424
425 for (i = 0; i < OL_TX_NUM_WMM_AC; i++) {
426 cds_cfg->ac_specs[i] = cds_ctx->ac_specs[i];
427 }
428}
429
430/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800431 * cds_open() - open the CDS Module
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800432 *
433 * cds_open() function opens the CDS Scheduler
434 * Upon successful initialization:
435 * - All CDS submodules should have been initialized
436 *
437 * - The CDS scheduler should have opened
438 *
439 * - All the WLAN SW components should have been opened. This includes
440 * SYS, MAC, SME, WMA and TL.
441 *
Anurag Chouhanf04e84f2016-03-03 10:12:12 +0530442 * Return: QDF status
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800443 */
Selvaraj, Sridhar0672a122016-12-29 16:11:48 +0530444QDF_STATUS cds_open(struct wlan_objmgr_psoc *psoc)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800445{
Dustin Brownf7971192017-10-25 14:54:37 -0700446 QDF_STATUS status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800447 tSirRetStatus sirStatus = eSIR_SUCCESS;
Arun Khandavallic811dcc2016-06-26 07:37:21 +0530448 struct cds_config_info *cds_cfg;
Anurag Chouhan6d760662016-02-20 16:05:43 +0530449 qdf_device_t qdf_ctx;
Manikandan Mohan83c939c2017-04-13 20:23:07 -0700450 struct htc_init_info htcInfo;
Komal Seelamd9106492016-02-15 10:31:44 +0530451 struct ol_context *ol_ctx;
Komal Seelam3d202862016-02-24 18:43:24 +0530452 struct hif_opaque_softc *scn;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800453 void *HTCHandle;
Jeff Johnsonc18b26c2017-09-03 08:46:45 -0700454 struct hdd_context *hdd_ctx;
Arun Khandavallic811dcc2016-06-26 07:37:21 +0530455 cds_context_type *cds_ctx;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800456
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530457 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_INFO_HIGH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800458 "%s: Opening CDS", __func__);
459
Arun Khandavallic811dcc2016-06-26 07:37:21 +0530460 cds_ctx = cds_get_context(QDF_MODULE_ID_QDF);
461 if (!cds_ctx) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530462 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_FATAL,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800463 "%s: Trying to open CDS without a PreOpen", __func__);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530464 QDF_ASSERT(0);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530465 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800466 }
467
468 /* Initialize the timer module */
Anurag Chouhan210db072016-02-22 18:42:15 +0530469 qdf_timer_module_init();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800470
471 /* Initialize bug reporting structure */
472 cds_init_log_completion();
473
474 /* Initialize the probe event */
Dustin Brownf7971192017-10-25 14:54:37 -0700475 status = qdf_event_create(&gp_cds_context->ProbeEvent);
476 if (QDF_IS_STATUS_ERROR(status)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530477 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_FATAL,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800478 "%s: Unable to init probeEvent", __func__);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530479 QDF_ASSERT(0);
Dustin Brownf7971192017-10-25 14:54:37 -0700480 return status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800481 }
Dustin Brownf7971192017-10-25 14:54:37 -0700482
483 status = qdf_event_create(&gp_cds_context->wmaCompleteEvent);
484 if (QDF_IS_STATUS_ERROR(status)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530485 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_FATAL,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800486 "%s: Unable to init wmaCompleteEvent", __func__);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530487 QDF_ASSERT(0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800488 goto err_probe_event;
489 }
490
Dustin Brownf7971192017-10-25 14:54:37 -0700491 hdd_ctx = (struct hdd_context *)(gp_cds_context->pHDDContext);
492 if (!hdd_ctx || !hdd_ctx->config) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800493 /* Critical Error ... Cannot proceed further */
Arun Khandavallifae92942016-08-01 13:31:08 +0530494 cds_err("Hdd Context is Null");
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530495 QDF_ASSERT(0);
Dustin Brownf7971192017-10-25 14:54:37 -0700496
497 status = QDF_STATUS_E_FAILURE;
Rajeev Kumar3e5ef0d2017-01-03 14:45:31 -0800498 goto err_wma_complete_event;
Arun Khandavallifae92942016-08-01 13:31:08 +0530499 }
Kabilan Kannan15cc6ac2016-11-12 22:25:14 -0800500
Dustin Brown44cde352017-12-04 13:14:46 -0800501 status = dispatcher_enable();
502 if (QDF_IS_STATUS_ERROR(status)) {
503 cds_err("Failed to enable dispatcher; status:%d", status);
504 goto err_wma_complete_event;
505 }
506
Arun Khandavallifae92942016-08-01 13:31:08 +0530507 /* Now Open the CDS Scheduler */
Dustin Brown0707ddf2017-09-20 15:31:56 -0700508 status = cds_sched_open(gp_cds_context,
509 &gp_cds_context->qdf_sched,
510 sizeof(cds_sched_context));
Dustin Brown0707ddf2017-09-20 15:31:56 -0700511 if (QDF_IS_STATUS_ERROR(status)) {
512 /* Critical Error ... Cannot proceed further */
513 cds_alert("Failed to open CDS Scheduler");
514 QDF_ASSERT(0);
Dustin Brown44cde352017-12-04 13:14:46 -0800515 goto err_dispatcher_disable;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800516 }
517
Anurag Chouhan6d760662016-02-20 16:05:43 +0530518 scn = cds_get_context(QDF_MODULE_ID_HIF);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800519 if (!scn) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530520 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_FATAL,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800521 "%s: scn is null!", __func__);
Dustin Brownf7971192017-10-25 14:54:37 -0700522
523 status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800524 goto err_sched_close;
525 }
Arun Khandavallifae92942016-08-01 13:31:08 +0530526
Arun Khandavallifae92942016-08-01 13:31:08 +0530527 cds_cfg = cds_get_ini_config();
528 if (!cds_cfg) {
529 cds_err("Cds config is NULL");
530 QDF_ASSERT(0);
Dustin Brownf7971192017-10-25 14:54:37 -0700531
532 status = QDF_STATUS_E_FAILURE;
Arun Khandavallifae92942016-08-01 13:31:08 +0530533 goto err_sched_close;
534 }
Dustin Brownf7971192017-10-25 14:54:37 -0700535
Jeff Johnsonc18b26c2017-09-03 08:46:45 -0700536 hdd_enable_fastpath(hdd_ctx->config, scn);
Arun Khandavallifae92942016-08-01 13:31:08 +0530537
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800538 /* Initialize BMI and Download firmware */
Dustin Brownf7971192017-10-25 14:54:37 -0700539 ol_ctx = cds_get_context(QDF_MODULE_ID_BMI);
540 status = bmi_download_firmware(ol_ctx);
541 if (QDF_IS_STATUS_ERROR(status)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530542 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_FATAL,
Dustin Brownf7971192017-10-25 14:54:37 -0700543 "BMI FIALED status:%d", status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800544 goto err_bmi_close;
545 }
Tiger Yu086b6992017-11-20 16:33:43 +0800546
547 hdd_wlan_update_target_info(hdd_ctx, scn);
548
Komal Seelam08633492016-02-24 18:05:07 +0530549 htcInfo.pContext = ol_ctx;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800550 htcInfo.TargetFailure = ol_target_failure;
Mukul Sharma4c60a7e2017-03-06 19:42:18 +0530551 htcInfo.TargetSendSuspendComplete =
552 pmo_ucfg_psoc_target_suspend_acknowledge;
553 htcInfo.target_initial_wakeup_cb = pmo_ucfg_psoc_handle_initial_wake_up;
554 htcInfo.target_psoc = (void *)psoc;
Anurag Chouhan6d760662016-02-20 16:05:43 +0530555 qdf_ctx = cds_get_context(QDF_MODULE_ID_QDF_DEVICE);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800556
557 /* Create HTC */
558 gp_cds_context->htc_ctx =
Yue Ma1e11d792016-02-26 18:58:44 -0800559 htc_create(scn, &htcInfo, qdf_ctx, cds_get_conparam());
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800560 if (!gp_cds_context->htc_ctx) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530561 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_FATAL,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800562 "%s: Failed to Create HTC", __func__);
Dustin Brownf7971192017-10-25 14:54:37 -0700563
564 status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800565 goto err_bmi_close;
566 }
Mukul Sharma4c60a7e2017-03-06 19:42:18 +0530567 pmo_ucfg_psoc_update_htc_handle(psoc, (void *)gp_cds_context->htc_ctx);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800568
Dustin Brownf7971192017-10-25 14:54:37 -0700569 status = bmi_done(ol_ctx);
570 if (QDF_IS_STATUS_ERROR(status)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530571 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_FATAL,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800572 "%s: Failed to complete BMI phase", __func__);
573 goto err_htc_close;
574 }
575
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800576 /*Open the WMA module */
bings482bae22018-01-17 16:25:31 +0800577 status = wma_open(psoc, hdd_update_tgt_cfg, cds_cfg,
578 hdd_ctx->target_type);
Dustin Brownf7971192017-10-25 14:54:37 -0700579 if (QDF_IS_STATUS_ERROR(status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800580 /* Critical Error ... Cannot proceed further */
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530581 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_FATAL,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800582 "%s: Failed to open WMA module", __func__);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530583 QDF_ASSERT(0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800584 goto err_htc_close;
585 }
586
587 /* Number of peers limit differs in each chip version. If peer max
588 * limit configured in ini exceeds more than supported, WMA adjusts
Arun Khandavallic811dcc2016-06-26 07:37:21 +0530589 * and keeps correct limit in cds_cfg.max_station. So, make sure
Jeff Johnsonc18b26c2017-09-03 08:46:45 -0700590 * config entry hdd_ctx->config->maxNumberOfPeers has adjusted value
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800591 */
Hanumanth Reddy Pothula47d29262016-10-03 16:08:04 +0530592 /* In FTM mode cds_cfg->max_stations will be zero. On updating same
593 * into hdd context config entry, leads to pe_open() to fail, if
594 * con_mode change happens from FTM mode to any other mode.
595 */
Srinivas Girigowda35b00312017-06-27 21:52:03 -0700596 if (QDF_DRIVER_TYPE_PRODUCTION == cds_cfg->driver_type)
Jeff Johnsonc18b26c2017-09-03 08:46:45 -0700597 hdd_ctx->config->maxNumberOfPeers = cds_cfg->max_station;
Hanumanth Reddy Pothula47d29262016-10-03 16:08:04 +0530598
Anurag Chouhan6d760662016-02-20 16:05:43 +0530599 HTCHandle = cds_get_context(QDF_MODULE_ID_HTC);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800600 if (!HTCHandle) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530601 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_FATAL,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800602 "%s: HTCHandle is null!", __func__);
Dustin Brownf7971192017-10-25 14:54:37 -0700603
604 status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800605 goto err_wma_close;
606 }
Nachiket Kukadef44b33e2017-09-06 16:49:29 +0530607
Dustin Brownf7971192017-10-25 14:54:37 -0700608 status = htc_wait_target(HTCHandle);
609 if (QDF_IS_STATUS_ERROR(status)) {
610 cds_alert("Failed to complete BMI phase. status: %d", status);
Nachiket Kukade8003d252017-03-30 15:55:58 +0530611
Dustin Brownf7971192017-10-25 14:54:37 -0700612 if (status != QDF_STATUS_E_NOMEM && !cds_is_fw_down())
Nachiket Kukade8003d252017-03-30 15:55:58 +0530613 QDF_BUG(0);
614
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800615 goto err_wma_close;
616 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800617
Ravi Joshifc2ed782016-11-22 17:36:50 -0800618 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_DEBUG,
619 "%s: target_type %d 8074:%d 6290:%d",
Jeff Johnsonc18b26c2017-09-03 08:46:45 -0700620 __func__, hdd_ctx->target_type,
Ravi Joshifc2ed782016-11-22 17:36:50 -0800621 TARGET_TYPE_QCA8074, TARGET_TYPE_QCA6290);
622
Jeff Johnsonc18b26c2017-09-03 08:46:45 -0700623 if (TARGET_TYPE_QCA6290 == hdd_ctx->target_type)
Leo Chang9b097032016-10-28 11:03:17 -0700624 gp_cds_context->dp_soc = cdp_soc_attach(LITHIUM_DP,
Arunk Khandavallia6305a32018-01-25 11:19:18 +0530625 gp_cds_context->pHIFContext, psoc,
Leo Chang9b097032016-10-28 11:03:17 -0700626 gp_cds_context->htc_ctx, gp_cds_context->qdf_ctx,
Arunk Khandavallia6305a32018-01-25 11:19:18 +0530627 &dp_ol_if_ops);
Leo Chang9b097032016-10-28 11:03:17 -0700628 else
629 gp_cds_context->dp_soc = cdp_soc_attach(MOB_DRV_LEGACY_DP,
Arunk Khandavallia6305a32018-01-25 11:19:18 +0530630 gp_cds_context->pHIFContext, psoc,
Leo Chang9b097032016-10-28 11:03:17 -0700631 gp_cds_context->htc_ctx, gp_cds_context->qdf_ctx,
Arunk Khandavallia6305a32018-01-25 11:19:18 +0530632 &dp_ol_if_ops);
Leo Chang9b097032016-10-28 11:03:17 -0700633
Dustin Brownf7971192017-10-25 14:54:37 -0700634 if (!gp_cds_context->dp_soc) {
635 status = QDF_STATUS_E_FAILURE;
Manikandan Mohanfb9d2b52017-05-10 15:01:28 -0700636 goto err_wma_close;
Dustin Brownf7971192017-10-25 14:54:37 -0700637 }
Manikandan Mohanfb9d2b52017-05-10 15:01:28 -0700638
Sravan Kumar Kairam27296782017-04-21 22:04:18 +0530639 pmo_ucfg_psoc_update_dp_handle(psoc, gp_cds_context->dp_soc);
Zhang Qian47e22ce2018-01-04 15:38:38 +0800640 ucfg_ocb_update_dp_handle(psoc, gp_cds_context->dp_soc);
Sravan Kumar Kairam27296782017-04-21 22:04:18 +0530641
gbian62edd7e2017-03-07 13:12:13 +0800642 cds_set_ac_specs_params(cds_cfg);
643
Leo Chang9b097032016-10-28 11:03:17 -0700644 cds_cdp_cfg_attach(cds_cfg);
645
Nirav Shaheb017be2018-02-15 11:20:58 +0530646 bmi_target_ready(scn, gp_cds_context->cfg_ctx);
647
Jeff Johnsond9f08602016-12-02 11:31:30 -0800648 /* Now proceed to open the MAC */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800649 sirStatus =
Selvaraj, Sridhar0672a122016-12-29 16:11:48 +0530650 mac_open(psoc, &(gp_cds_context->pMACContext),
Arun Khandavallic811dcc2016-06-26 07:37:21 +0530651 gp_cds_context->pHDDContext, cds_cfg);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800652
653 if (eSIR_SUCCESS != sirStatus) {
654 /* Critical Error ... Cannot proceed further */
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530655 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_FATAL,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800656 "%s: Failed to open MAC", __func__);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530657 QDF_ASSERT(0);
Dustin Brownf7971192017-10-25 14:54:37 -0700658
659 status = QDF_STATUS_E_FAILURE;
Houston Hoffman59c9c912017-03-29 14:10:39 -0700660 goto err_soc_detach;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800661 }
662
663 /* Now proceed to open the SME */
Dustin Brownf7971192017-10-25 14:54:37 -0700664 status = sme_open(gp_cds_context->pMACContext);
665 if (QDF_IS_STATUS_ERROR(status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800666 /* Critical Error ... Cannot proceed further */
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530667 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_FATAL,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800668 "%s: Failed to open SME", __func__);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530669 QDF_ASSERT(0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800670 goto err_mac_close;
671 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800672
Krunal Sonid32c6bc2016-10-18 18:00:21 -0700673 cds_register_all_modules();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800674
Selvaraj, Sridhara7dc2382017-01-27 18:29:39 +0530675 return dispatcher_psoc_open(psoc);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800676
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800677err_mac_close:
678 mac_close(gp_cds_context->pMACContext);
679
Houston Hoffman59c9c912017-03-29 14:10:39 -0700680err_soc_detach:
681 /* todo: add propper error handling */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800682err_wma_close:
Rajeev Kumar662d75d2017-03-13 18:11:29 -0700683 cds_shutdown_notifier_purge();
Jeff Johnson542da352017-09-13 09:17:28 -0700684 wma_close();
Jeff Johnson7b3ddc22017-09-13 09:42:44 -0700685 wma_wmi_service_close();
Sravan Kumar Kairam27296782017-04-21 22:04:18 +0530686 pmo_ucfg_psoc_update_dp_handle(psoc, NULL);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800687
688err_htc_close:
689 if (gp_cds_context->htc_ctx) {
690 htc_destroy(gp_cds_context->htc_ctx);
691 gp_cds_context->htc_ctx = NULL;
Sravan Kumar Kairam27296782017-04-21 22:04:18 +0530692 pmo_ucfg_psoc_update_htc_handle(psoc, NULL);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800693 }
694
695err_bmi_close:
Komal Seelam5a6e5082016-02-24 17:59:09 +0530696 bmi_cleanup(ol_ctx);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800697
698err_sched_close:
Dustin Brown0707ddf2017-09-20 15:31:56 -0700699 if (QDF_IS_STATUS_ERROR(cds_sched_close())) {
700 cds_err("Failed to close CDS Scheduler");
701 QDF_ASSERT(false);
Hanumanth Reddy Pothula0b571432017-02-23 17:15:37 +0530702 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800703
Dustin Brown44cde352017-12-04 13:14:46 -0800704err_dispatcher_disable:
705 if (QDF_IS_STATUS_ERROR(dispatcher_disable()))
706 cds_err("Failed to disable dispatcher");
707
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800708err_wma_complete_event:
Anurag Chouhance0dc992016-02-16 18:18:03 +0530709 qdf_event_destroy(&gp_cds_context->wmaCompleteEvent);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800710
711err_probe_event:
Anurag Chouhance0dc992016-02-16 18:18:03 +0530712 qdf_event_destroy(&gp_cds_context->ProbeEvent);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800713
Dustin Brownf7971192017-10-25 14:54:37 -0700714 return status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800715} /* cds_open() */
716
Venkata Sharath Chandra Manchala4aaae0f2017-07-10 11:59:19 -0700717QDF_STATUS cds_dp_open(struct wlan_objmgr_psoc *psoc)
718{
719 if (cdp_txrx_intr_attach(gp_cds_context->dp_soc)
720 != QDF_STATUS_SUCCESS) {
721 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_FATAL,
722 "%s: Failed to attach interrupts", __func__);
723 goto close;
724 }
725
726 cds_set_context(QDF_MODULE_ID_TXRX,
727 cdp_pdev_attach(cds_get_context(QDF_MODULE_ID_SOC),
728 gp_cds_context->cfg_ctx,
729 gp_cds_context->htc_ctx,
730 gp_cds_context->qdf_ctx, 0));
731 if (!gp_cds_context->pdev_txrx_ctx) {
732 /* Critical Error ... Cannot proceed further */
733 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_FATAL,
734 "%s: Failed to open TXRX", __func__);
735 QDF_ASSERT(0);
736 goto intr_close;
737 }
738
739 pmo_ucfg_psoc_set_txrx_handle(psoc, gp_cds_context->pdev_txrx_ctx);
Zhang Qian47e22ce2018-01-04 15:38:38 +0800740 ucfg_ocb_set_txrx_handle(psoc, gp_cds_context->pdev_txrx_ctx);
Venkata Sharath Chandra Manchala4aaae0f2017-07-10 11:59:19 -0700741
742 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_INFO_HIGH,
743 "%s: CDS successfully Opened", __func__);
744
745 return 0;
746
747intr_close:
748 cdp_txrx_intr_detach(gp_cds_context->dp_soc);
749close:
750 return QDF_STATUS_E_FAILURE;
751}
752
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800753/**
754 * cds_pre_enable() - pre enable cds
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800755 *
Anurag Chouhanf04e84f2016-03-03 10:12:12 +0530756 * Return: QDF status
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800757 */
Jeff Johnson3a280122017-09-13 07:42:00 -0700758QDF_STATUS cds_pre_enable(void)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800759{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530760 QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800761 void *scn;
Jeff Johnson3a280122017-09-13 07:42:00 -0700762 void *soc;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800763
Srinivas Girigowdad395b892017-03-09 19:29:42 -0800764 QDF_TRACE(QDF_MODULE_ID_SYS, QDF_TRACE_LEVEL_DEBUG, "cds prestart");
Jeff Johnson3a280122017-09-13 07:42:00 -0700765
766 if (!gp_cds_context) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530767 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Jeff Johnson3a280122017-09-13 07:42:00 -0700768 "%s: NULL CDS context", __func__);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530769 QDF_ASSERT(0);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530770 return QDF_STATUS_E_INVAL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800771 }
772
Jeff Johnson3a280122017-09-13 07:42:00 -0700773 if (gp_cds_context->pMACContext == NULL) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530774 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800775 "%s: MAC NULL context", __func__);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530776 QDF_ASSERT(0);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530777 return QDF_STATUS_E_INVAL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800778 }
779
Jeff Johnson3a280122017-09-13 07:42:00 -0700780 if (gp_cds_context->pWMAContext == NULL) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530781 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800782 "%s: WMA NULL context", __func__);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530783 QDF_ASSERT(0);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530784 return QDF_STATUS_E_INVAL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800785 }
786
Anurag Chouhan6d760662016-02-20 16:05:43 +0530787 scn = cds_get_context(QDF_MODULE_ID_HIF);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800788 if (!scn) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530789 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_FATAL,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800790 "%s: scn is null!", __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530791 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800792 }
793
Jeff Johnson3a280122017-09-13 07:42:00 -0700794 soc = cds_get_context(QDF_MODULE_ID_SOC);
795 if (!soc) {
796 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_FATAL,
797 "%s: soc is null!", __func__);
798 return QDF_STATUS_E_FAILURE;
799 }
800
Nirav Shah7f337db2016-05-25 10:49:02 +0530801 /* call Packetlog connect service */
Arun Khandavallifae92942016-08-01 13:31:08 +0530802 if (QDF_GLOBAL_FTM_MODE != cds_get_conparam() &&
Leo Chang9b097032016-10-28 11:03:17 -0700803 QDF_GLOBAL_EPPING_MODE != cds_get_conparam())
804 cdp_pkt_log_con_service(soc,
Venkata Sharath Chandra Manchala0d44d452016-11-23 17:48:15 -0800805 gp_cds_context->pdev_txrx_ctx,
806 scn);
Nirav Shah7f337db2016-05-25 10:49:02 +0530807
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800808 /* Reset wma wait event */
Anurag Chouhance0dc992016-02-16 18:18:03 +0530809 qdf_event_reset(&gp_cds_context->wmaCompleteEvent);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800810
811 /*call WMA pre start */
Jeff Johnson8ad89c62017-09-13 08:55:55 -0700812 qdf_status = wma_pre_start();
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530813 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530814 QDF_TRACE(QDF_MODULE_ID_SYS, QDF_TRACE_LEVEL_FATAL,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800815 "Failed to WMA prestart");
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530816 QDF_ASSERT(0);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530817 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800818 }
819
820 /* Need to update time out of complete */
Nachiket Kukade0396b732017-11-14 16:35:16 +0530821 qdf_status = qdf_wait_for_event_completion(
822 &gp_cds_context->wmaCompleteEvent,
823 CDS_WMA_TIMEOUT);
Anurag Chouhance0dc992016-02-16 18:18:03 +0530824 if (qdf_status != QDF_STATUS_SUCCESS) {
825 if (qdf_status == QDF_STATUS_E_TIMEOUT) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530826 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800827 "%s: Timeout occurred before WMA complete",
828 __func__);
829 } else {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530830 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800831 "%s: wma_pre_start reporting other error",
832 __func__);
833 }
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530834 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800835 "%s: Test MC thread by posting a probe message to SYS",
836 __func__);
837 wlan_sys_probe();
838
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530839 QDF_ASSERT(0);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530840 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800841 }
842
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530843 qdf_status = htc_start(gp_cds_context->htc_ctx);
844 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530845 QDF_TRACE(QDF_MODULE_ID_SYS, QDF_TRACE_LEVEL_FATAL,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800846 "Failed to Start HTC");
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530847 QDF_ASSERT(0);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530848 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800849 }
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530850 qdf_status = wma_wait_for_ready_event(gp_cds_context->pWMAContext);
851 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530852 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_FATAL,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800853 "Failed to get ready event from target firmware");
Nachiket Kukade8003d252017-03-30 15:55:58 +0530854
Naveen Rawat91df30a2016-10-12 21:26:18 -0700855 /*
Nachiket Kukade8003d252017-03-30 15:55:58 +0530856 * Panic when the failure is not because the FW is down,
857 * fail gracefully if FW is down allowing re-probing from
858 * from the platform driver
Naveen Rawat91df30a2016-10-12 21:26:18 -0700859 */
Rajeev Kumar8b330492017-11-09 12:09:10 -0800860 if ((!cds_is_fw_down()) && (!cds_is_self_recovery_enabled()))
Naveen Rawat91df30a2016-10-12 21:26:18 -0700861 QDF_BUG(0);
862
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800863 htc_stop(gp_cds_context->htc_ctx);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530864 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800865 }
866
Leo Chang9b097032016-10-28 11:03:17 -0700867 if (cdp_pdev_post_attach(soc, gp_cds_context->pdev_txrx_ctx)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530868 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_FATAL,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800869 "Failed to attach pdev");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800870 htc_stop(gp_cds_context->htc_ctx);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530871 QDF_ASSERT(0);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530872 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800873 }
874
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530875 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800876}
877
878/**
879 * cds_enable() - start/enable cds module
Selvaraj, Sridhar0672a122016-12-29 16:11:48 +0530880 * @psoc: Psoc pointer
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800881 * @cds_context: CDS context
882 *
Anurag Chouhanf04e84f2016-03-03 10:12:12 +0530883 * Return: QDF status
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800884 */
Jeff Johnson8f9dd5f2017-09-13 14:16:08 -0700885QDF_STATUS cds_enable(struct wlan_objmgr_psoc *psoc)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800886{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530887 QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800888 tSirRetStatus sirStatus = eSIR_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800889 tHalMacStartParameters halStartParams;
890
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800891 /* We support only one instance for now ... */
Jeff Johnson8f9dd5f2017-09-13 14:16:08 -0700892 if (!gp_cds_context) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530893 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Jeff Johnson8f9dd5f2017-09-13 14:16:08 -0700894 "%s: Invalid CDS context", __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530895 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800896 }
897
Jeff Johnson8f9dd5f2017-09-13 14:16:08 -0700898 if ((gp_cds_context->pWMAContext == NULL) ||
899 (gp_cds_context->pMACContext == NULL)) {
900 if (gp_cds_context->pWMAContext == NULL)
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530901 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800902 "%s: WMA NULL context", __func__);
903 else
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530904 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800905 "%s: MAC NULL context", __func__);
906
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530907 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800908 }
909
910 /* Start the wma */
Jeff Johnsond4892552017-09-13 08:41:31 -0700911 qdf_status = wma_start();
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530912 if (qdf_status != QDF_STATUS_SUCCESS) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530913 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800914 "%s: Failed to start wma", __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530915 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800916 }
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530917 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_INFO,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800918 "%s: wma correctly started", __func__);
919
920 /* Start the MAC */
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530921 qdf_mem_zero(&halStartParams,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800922 sizeof(tHalMacStartParameters));
923
924 /* Start the MAC */
925 sirStatus =
Jeff Johnson8f9dd5f2017-09-13 14:16:08 -0700926 mac_start(gp_cds_context->pMACContext, &halStartParams);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800927
928 if (eSIR_SUCCESS != sirStatus) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530929 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_FATAL,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800930 "%s: Failed to start MAC", __func__);
931 goto err_wma_stop;
932 }
933
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530934 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_INFO,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800935 "%s: MAC correctly started", __func__);
936
937 /* START SME */
Jeff Johnson8f9dd5f2017-09-13 14:16:08 -0700938 qdf_status = sme_start(gp_cds_context->pMACContext);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800939
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530940 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530941 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_FATAL,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800942 "%s: Failed to start SME", __func__);
943 goto err_mac_stop;
944 }
945
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530946 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_INFO,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800947 "%s: SME correctly started", __func__);
948
Leo Chang9b097032016-10-28 11:03:17 -0700949 if (cdp_soc_attach_target(cds_get_context(QDF_MODULE_ID_SOC))) {
950 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_FATAL,
951 "%s: Failed to attach soc target", __func__);
952 goto err_sme_stop;
953 }
954
955 if (cdp_pdev_attach_target(cds_get_context(QDF_MODULE_ID_SOC),
Venkata Sharath Chandra Manchala0d44d452016-11-23 17:48:15 -0800956 (struct cdp_pdev *)cds_get_context(QDF_MODULE_ID_TXRX))) {
Leo Chang9b097032016-10-28 11:03:17 -0700957 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_FATAL,
958 "%s: Failed to attach pdev target", __func__);
959 goto err_soc_target_detach;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800960 }
961
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530962 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_INFO,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800963 "%s: CDS Start is successful!!", __func__);
964
Min Liu81f2ed32018-01-08 14:21:02 +0800965 qdf_status = dispatcher_psoc_enable(psoc);
966 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
967 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_FATAL,
968 "%s: dispatcher_psoc_enable failed", __func__);
969 goto err_soc_target_detach;
970 }
Rajeev Kumar97767a02016-11-30 11:20:40 -0800971
Nachiket Kukade98f562a2017-12-15 12:18:07 +0530972 /* Trigger psoc enable for CLD components */
973 hdd_component_psoc_enable(psoc);
974
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530975 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800976
Leo Chang9b097032016-10-28 11:03:17 -0700977err_soc_target_detach:
978 /* NOOP */
979
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800980err_sme_stop:
Jeff Johnson8f9dd5f2017-09-13 14:16:08 -0700981 sme_stop(gp_cds_context->pMACContext, HAL_STOP_TYPE_SYS_RESET);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800982
983err_mac_stop:
Jeff Johnson8f9dd5f2017-09-13 14:16:08 -0700984 mac_stop(gp_cds_context->pMACContext, HAL_STOP_TYPE_SYS_RESET);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800985
986err_wma_stop:
Anurag Chouhance0dc992016-02-16 18:18:03 +0530987 qdf_event_reset(&(gp_cds_context->wmaCompleteEvent));
Jeff Johnsonacc1cc72017-09-13 08:47:49 -0700988 qdf_status = wma_stop(HAL_STOP_TYPE_RF_KILL);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530989 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530990 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800991 "%s: Failed to stop wma", __func__);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530992 QDF_ASSERT(QDF_IS_STATUS_SUCCESS(qdf_status));
Jeff Johnson1f8d0a02017-09-13 08:09:05 -0700993 wma_setneedshutdown();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800994 } else {
Anurag Chouhance0dc992016-02-16 18:18:03 +0530995 qdf_status =
Nachiket Kukade0396b732017-11-14 16:35:16 +0530996 qdf_wait_for_event_completion(
997 &gp_cds_context->wmaCompleteEvent,
998 CDS_WMA_TIMEOUT);
Anurag Chouhance0dc992016-02-16 18:18:03 +0530999 if (qdf_status != QDF_STATUS_SUCCESS) {
1000 if (qdf_status == QDF_STATUS_E_TIMEOUT) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301001 QDF_TRACE(QDF_MODULE_ID_QDF,
1002 QDF_TRACE_LEVEL_FATAL,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001003 "%s: Timeout occurred before WMA_stop complete",
1004 __func__);
1005 } else {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301006 QDF_TRACE(QDF_MODULE_ID_QDF,
1007 QDF_TRACE_LEVEL_FATAL,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001008 "%s: WMA_stop reporting other error",
1009 __func__);
1010 }
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301011 QDF_ASSERT(0);
Jeff Johnson1f8d0a02017-09-13 08:09:05 -07001012 wma_setneedshutdown();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001013 }
1014 }
1015
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301016 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001017} /* cds_enable() */
1018
1019/**
1020 * cds_disable() - stop/disable cds module
Selvaraj, Sridhar0672a122016-12-29 16:11:48 +05301021 * @psoc: Psoc pointer
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001022 *
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05301023 * Return: QDF status
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001024 */
Jeff Johnsonea5c2aa12017-09-13 14:18:59 -07001025QDF_STATUS cds_disable(struct wlan_objmgr_psoc *psoc)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001026{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301027 QDF_STATUS qdf_status;
Arun Khandavallifae92942016-08-01 13:31:08 +05301028 void *handle;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001029
Rajeev Kumar97767a02016-11-30 11:20:40 -08001030 /* PSOC disable for all new components. It needs to happen before
1031 * target is PDEV suspended such that a component can abort all its
1032 * ongoing transaction with FW. Always keep it before wma_stop() as
1033 * wma_stop() does target PDEV suspend.
1034 */
Rajeev Kumar97767a02016-11-30 11:20:40 -08001035
Nachiket Kukade98f562a2017-12-15 12:18:07 +05301036 /* Trigger psoc disable for CLD components */
1037 if (psoc) {
1038 hdd_component_psoc_disable(psoc);
Jiachao Wu341d0752018-01-02 15:20:32 +08001039 dispatcher_psoc_disable(psoc);
Nachiket Kukade98f562a2017-12-15 12:18:07 +05301040 }
Rajeev Kumar97767a02016-11-30 11:20:40 -08001041
Jeff Johnsonacc1cc72017-09-13 08:47:49 -07001042 qdf_status = wma_stop(HAL_STOP_TYPE_RF_KILL);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001043
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301044 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Arun Khandavallifae92942016-08-01 13:31:08 +05301045 cds_err("Failed to stop wma");
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301046 QDF_ASSERT(QDF_IS_STATUS_SUCCESS(qdf_status));
Jeff Johnson1f8d0a02017-09-13 08:09:05 -07001047 wma_setneedshutdown();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001048 }
1049
Arun Khandavallifae92942016-08-01 13:31:08 +05301050 handle = cds_get_context(QDF_MODULE_ID_PE);
1051 if (!handle) {
1052 cds_err("Invalid PE context return!");
1053 return QDF_STATUS_E_INVAL;
1054 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001055
Naveen Rawatbcd3d012017-12-05 11:11:55 -08001056 umac_stop();
Arun Khandavalli55f890b2016-08-31 18:14:56 +05301057
Arun Khandavallifae92942016-08-01 13:31:08 +05301058 return qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001059}
1060
Govind Singhb048e872016-09-27 22:07:43 +05301061#ifdef HIF_USB
1062static inline void cds_suspend_target(tp_wma_handle wma_handle)
1063{
1064 QDF_STATUS status;
1065 /* Suspend the target and disable interrupt */
Mukul Sharma4c60a7e2017-03-06 19:42:18 +05301066 status = pmo_ucfg_psoc_suspend_target(wma_handle->psoc, 0);
Govind Singhb048e872016-09-27 22:07:43 +05301067 if (status)
1068 cds_err("Failed to suspend target, status = %d", status);
1069}
1070#else
1071static inline void cds_suspend_target(tp_wma_handle wma_handle)
1072{
1073 QDF_STATUS status;
1074 /* Suspend the target and disable interrupt */
Mukul Sharma4c60a7e2017-03-06 19:42:18 +05301075 status = pmo_ucfg_psoc_suspend_target(wma_handle->psoc, 1);
Govind Singhb048e872016-09-27 22:07:43 +05301076 if (status)
1077 cds_err("Failed to suspend target, status = %d", status);
1078}
1079#endif /* HIF_USB */
1080
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001081/**
Govind Singhb048e872016-09-27 22:07:43 +05301082 * cds_post_disable() - post disable cds module
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001083 *
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05301084 * Return: QDF status
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001085 */
Rajeev Kumarbe021242017-02-16 16:12:23 -08001086QDF_STATUS cds_post_disable(void)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001087{
Arun Khandavalli55f890b2016-08-31 18:14:56 +05301088 tp_wma_handle wma_handle;
Govind Singhb048e872016-09-27 22:07:43 +05301089 struct hif_opaque_softc *hif_ctx;
Himanshu Agarwal0b9bbc32017-02-23 16:23:05 +05301090 struct cdp_pdev *txrx_pdev;
1091
Arun Khandavalli55f890b2016-08-31 18:14:56 +05301092 wma_handle = cds_get_context(QDF_MODULE_ID_WMA);
1093 if (!wma_handle) {
1094 cds_err("Failed to get wma_handle!");
1095 return QDF_STATUS_E_INVAL;
1096 }
1097
Govind Singhb048e872016-09-27 22:07:43 +05301098 hif_ctx = cds_get_context(QDF_MODULE_ID_HIF);
1099 if (!hif_ctx) {
1100 cds_err("Failed to get hif_handle!");
1101 return QDF_STATUS_E_INVAL;
1102 }
1103
Himanshu Agarwal0b9bbc32017-02-23 16:23:05 +05301104 txrx_pdev = cds_get_context(QDF_MODULE_ID_TXRX);
1105 if (!txrx_pdev) {
1106 cds_err("Failed to get txrx pdev!");
1107 return QDF_STATUS_E_INVAL;
1108 }
1109
Arun Khandavalli55f890b2016-08-31 18:14:56 +05301110 /*
1111 * With new state machine changes cds_close can be invoked without
1112 * cds_disable. So, send the following clean up prerequisites to fw,
1113 * So Fw and host are in sync for cleanup indication:
1114 * - Send PDEV_SUSPEND indication to firmware
1115 * - Disable HIF Interrupts.
1116 * - Clean up CE tasklets.
1117 */
1118
Hanumanth Reddy Pothula2a8a7402017-07-03 14:06:11 +05301119 cds_info("send deinit sequence to firmware");
1120 if (!(cds_is_driver_recovering() || cds_is_driver_in_bad_state()))
Govind Singhb048e872016-09-27 22:07:43 +05301121 cds_suspend_target(wma_handle);
1122 hif_disable_isr(hif_ctx);
1123 hif_reset_soc(hif_ctx);
1124
Wu Gao9a24fa72017-07-28 18:32:22 +08001125 if (gp_cds_context->htc_ctx) {
1126 htc_stop(gp_cds_context->htc_ctx);
1127 }
1128
Himanshu Agarwal0b9bbc32017-02-23 16:23:05 +05301129 cdp_pdev_pre_detach(cds_get_context(QDF_MODULE_ID_SOC),
1130 (struct cdp_pdev *)txrx_pdev, 1);
1131
Govind Singhb048e872016-09-27 22:07:43 +05301132 return QDF_STATUS_SUCCESS;
1133}
1134
1135/**
1136 * cds_close() - close cds module
Selvaraj, Sridhar0672a122016-12-29 16:11:48 +05301137 * @psoc: Psoc pointer
Govind Singhb048e872016-09-27 22:07:43 +05301138 *
1139 * This API allows user to close modules registered
1140 * with connectivity device services.
1141 *
1142 * Return: QDF status
1143 */
Jeff Johnsone4b14592017-09-13 14:23:33 -07001144QDF_STATUS cds_close(struct wlan_objmgr_psoc *psoc)
Govind Singhb048e872016-09-27 22:07:43 +05301145{
1146 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001147
Dustin Brownd33276b2017-11-29 11:08:11 -08001148 qdf_status = cds_sched_close();
1149 QDF_ASSERT(QDF_IS_STATUS_SUCCESS(qdf_status));
1150 if (QDF_IS_STATUS_ERROR(qdf_status))
1151 cds_err("Failed to close CDS Scheduler");
1152
Dustin Brown44cde352017-12-04 13:14:46 -08001153 qdf_status = dispatcher_disable();
1154 QDF_ASSERT(QDF_IS_STATUS_SUCCESS(qdf_status));
1155 if (QDF_IS_STATUS_ERROR(qdf_status))
1156 cds_err("Failed to disable dispatcher; status:%d", qdf_status);
1157
Amar Singhal966397f2017-04-06 18:28:56 -07001158 dispatcher_psoc_close(psoc);
1159
Jeff Johnson6b8473d2017-09-13 09:20:53 -07001160 qdf_status = wma_wmi_work_close();
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301161 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,
Xun Luoa858a472015-11-10 08:24:45 -08001163 "%s: Failed to close wma_wmi_work", __func__);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301164 QDF_ASSERT(0);
Xun Luoa858a472015-11-10 08:24:45 -08001165 }
1166
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001167 if (gp_cds_context->htc_ctx) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001168 htc_destroy(gp_cds_context->htc_ctx);
Mukul Sharma4c60a7e2017-03-06 19:42:18 +05301169 pmo_ucfg_psoc_update_htc_handle(psoc, NULL);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001170 gp_cds_context->htc_ctx = NULL;
1171 }
1172
Jeff Johnsone4b14592017-09-13 14:23:33 -07001173 qdf_status = sme_close(gp_cds_context->pMACContext);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301174 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301175 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001176 "%s: Failed to close SME", __func__);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301177 QDF_ASSERT(QDF_IS_STATUS_SUCCESS(qdf_status));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001178 }
1179
Jeff Johnsone4b14592017-09-13 14:23:33 -07001180 qdf_status = mac_close(gp_cds_context->pMACContext);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301181 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301182 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001183 "%s: Failed to close MAC", __func__);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301184 QDF_ASSERT(QDF_IS_STATUS_SUCCESS(qdf_status));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001185 }
1186
Jeff Johnsone4b14592017-09-13 14:23:33 -07001187 gp_cds_context->pMACContext = NULL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001188
Houston Hoffmanbe58cc52016-12-19 16:26:44 -08001189 cdp_soc_detach(gp_cds_context->dp_soc);
Sravan Kumar Kairam27296782017-04-21 22:04:18 +05301190 pmo_ucfg_psoc_update_dp_handle(psoc, NULL);
Houston Hoffmanbe58cc52016-12-19 16:26:44 -08001191
Rajeev Kumar662d75d2017-03-13 18:11:29 -07001192 cds_shutdown_notifier_purge();
1193
Jeff Johnson1b5404e2017-09-13 08:04:46 -07001194 if (true == wma_needshutdown()) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301195 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001196 "%s: Failed to shutdown wma", __func__);
1197 } else {
Jeff Johnson542da352017-09-13 09:17:28 -07001198 qdf_status = wma_close();
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301199 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301200 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001201 "%s: Failed to close wma", __func__);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301202 QDF_ASSERT(QDF_IS_STATUS_SUCCESS(qdf_status));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001203 }
1204 }
1205
Jeff Johnson7b3ddc22017-09-13 09:42:44 -07001206 qdf_status = wma_wmi_service_close();
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301207 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301208 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001209 "%s: Failed to close wma_wmi_service", __func__);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301210 QDF_ASSERT(QDF_IS_STATUS_SUCCESS(qdf_status));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001211 }
1212
Anurag Chouhance0dc992016-02-16 18:18:03 +05301213 qdf_status = qdf_event_destroy(&gp_cds_context->wmaCompleteEvent);
1214 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
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: failed to destroy wmaCompleteEvent", __func__);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301217 QDF_ASSERT(QDF_IS_STATUS_SUCCESS(qdf_status));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001218 }
1219
Anurag Chouhance0dc992016-02-16 18:18:03 +05301220 qdf_status = qdf_event_destroy(&gp_cds_context->ProbeEvent);
1221 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301222 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001223 "%s: failed to destroy ProbeEvent", __func__);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301224 QDF_ASSERT(QDF_IS_STATUS_SUCCESS(qdf_status));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001225 }
1226
Arun Khandavallic811dcc2016-06-26 07:37:21 +05301227 cds_deinit_ini_config();
Arun Khandavallifae92942016-08-01 13:31:08 +05301228 qdf_timer_module_deinit();
1229
Krunal Sonid32c6bc2016-10-18 18:00:21 -07001230 cds_deregister_all_modules();
Rajeev Kumar97767a02016-11-30 11:20:40 -08001231
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301232 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001233}
1234
Venkata Sharath Chandra Manchala4aaae0f2017-07-10 11:59:19 -07001235QDF_STATUS cds_dp_close(struct wlan_objmgr_psoc *psoc)
1236{
1237 void *ctx;
1238
1239 cdp_txrx_intr_detach(gp_cds_context->dp_soc);
1240
1241 ctx = cds_get_context(QDF_MODULE_ID_TXRX);
Venkata Sharath Chandra Manchala4aaae0f2017-07-10 11:59:19 -07001242 cdp_pdev_detach(cds_get_context(QDF_MODULE_ID_SOC),
1243 (struct cdp_pdev *)ctx, 1);
psimhadeea0a12017-12-18 14:50:02 -08001244 cds_set_context(QDF_MODULE_ID_TXRX, NULL);
1245 pmo_ucfg_psoc_set_txrx_handle(psoc, NULL);
Venkata Sharath Chandra Manchala4aaae0f2017-07-10 11:59:19 -07001246
1247 return QDF_STATUS_SUCCESS;
1248}
1249
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001250/**
1251 * cds_get_context() - get context data area
1252 *
1253 * @moduleId: ID of the module who's context data is being retrived.
1254 *
1255 * Each module in the system has a context / data area that is allocated
1256 * and managed by CDS. This API allows any user to get a pointer to its
1257 * allocated context data area from the CDS global context.
1258 *
1259 * Return: pointer to the context data area of the module ID
1260 * specified, or NULL if the context data is not allocated for
1261 * the module ID specified
1262 */
Anurag Chouhan6d760662016-02-20 16:05:43 +05301263void *cds_get_context(QDF_MODULE_ID moduleId)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001264{
1265 void *pModContext = NULL;
1266
1267 if (gp_cds_context == NULL) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301268 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001269 "%s: cds context pointer is null", __func__);
1270 return NULL;
1271 }
1272
1273 switch (moduleId) {
Anurag Chouhan6d760662016-02-20 16:05:43 +05301274 case QDF_MODULE_ID_HDD:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001275 {
1276 pModContext = gp_cds_context->pHDDContext;
1277 break;
1278 }
1279
Anurag Chouhan6d760662016-02-20 16:05:43 +05301280 case QDF_MODULE_ID_SME:
1281 case QDF_MODULE_ID_PE:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001282 {
1283 /* In all these cases, we just return the MAC Context */
1284 pModContext = gp_cds_context->pMACContext;
1285 break;
1286 }
1287
Anurag Chouhan6d760662016-02-20 16:05:43 +05301288 case QDF_MODULE_ID_WMA:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001289 {
1290 /* For wma module */
1291 pModContext = gp_cds_context->pWMAContext;
1292 break;
1293 }
1294
Anurag Chouhan6d760662016-02-20 16:05:43 +05301295 case QDF_MODULE_ID_QDF:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001296 {
1297 /* For SYS this is CDS itself */
1298 pModContext = gp_cds_context;
1299 break;
1300 }
1301
Anurag Chouhan6d760662016-02-20 16:05:43 +05301302 case QDF_MODULE_ID_HIF:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001303 {
1304 pModContext = gp_cds_context->pHIFContext;
1305 break;
1306 }
1307
Anurag Chouhan6d760662016-02-20 16:05:43 +05301308 case QDF_MODULE_ID_HTC:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001309 {
1310 pModContext = gp_cds_context->htc_ctx;
1311 break;
1312 }
1313
Anurag Chouhan6d760662016-02-20 16:05:43 +05301314 case QDF_MODULE_ID_QDF_DEVICE:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001315 {
Anurag Chouhan6d760662016-02-20 16:05:43 +05301316 pModContext = gp_cds_context->qdf_ctx;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001317 break;
1318 }
1319
Anurag Chouhan6d760662016-02-20 16:05:43 +05301320 case QDF_MODULE_ID_BMI:
Komal Seelamd9106492016-02-15 10:31:44 +05301321 {
1322 pModContext = gp_cds_context->g_ol_context;
1323 break;
1324 }
1325
Anurag Chouhan6d760662016-02-20 16:05:43 +05301326 case QDF_MODULE_ID_TXRX:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001327 {
Venkata Sharath Chandra Manchala0d44d452016-11-23 17:48:15 -08001328 pModContext = (void *)gp_cds_context->pdev_txrx_ctx;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001329 break;
1330 }
1331
Anurag Chouhan6d760662016-02-20 16:05:43 +05301332 case QDF_MODULE_ID_CFG:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001333 {
1334 pModContext = gp_cds_context->cfg_ctx;
1335 break;
1336 }
1337
Leo Chang9b097032016-10-28 11:03:17 -07001338 case QDF_MODULE_ID_SOC:
1339 {
1340 pModContext = gp_cds_context->dp_soc;
1341 break;
1342 }
1343
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001344 default:
1345 {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301346 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001347 "%s: Module ID %i does not have its context maintained by CDS",
1348 __func__, moduleId);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301349 QDF_ASSERT(0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001350 return NULL;
1351 }
1352 }
1353
1354 if (pModContext == NULL) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301355 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001356 "%s: Module ID %i context is Null", __func__,
1357 moduleId);
1358 }
1359
1360 return pModContext;
1361} /* cds_get_context() */
1362
1363/**
1364 * cds_get_global_context() - get CDS global Context
1365 *
1366 * This API allows any user to get the CDS Global Context pointer from a
1367 * module context data area.
1368 *
1369 * Return: pointer to the CDS global context, NULL if the function is
1370 * unable to retreive the CDS context.
1371 */
Jeff Johnson31a67582017-09-26 14:54:28 -07001372void *cds_get_global_context(void)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001373{
1374 if (gp_cds_context == NULL) {
Ryan Hsuceddceb2016-04-28 10:20:14 -07001375 /*
1376 * To avoid recursive call, this should not change to
1377 * QDF_TRACE().
1378 */
1379 pr_err("%s: global cds context is NULL", __func__);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001380 }
1381
1382 return gp_cds_context;
1383} /* cds_get_global_context() */
1384
1385/**
Prashanth Bhatta9e143052015-12-04 11:56:47 -08001386 * cds_get_driver_state() - Get current driver state
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001387 *
Prashanth Bhatta9e143052015-12-04 11:56:47 -08001388 * This API returns current driver state stored in global context.
1389 *
1390 * Return: Driver state enum
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001391 */
Prashanth Bhatta9e143052015-12-04 11:56:47 -08001392enum cds_driver_state cds_get_driver_state(void)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001393{
1394 if (gp_cds_context == NULL) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301395 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001396 "%s: global cds context is NULL", __func__);
Prashanth Bhatta9e143052015-12-04 11:56:47 -08001397
1398 return CDS_DRIVER_STATE_UNINITIALIZED;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001399 }
1400
Prashanth Bhatta9e143052015-12-04 11:56:47 -08001401 return gp_cds_context->driver_state;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001402}
1403
1404/**
Prashanth Bhatta9e143052015-12-04 11:56:47 -08001405 * cds_set_driver_state() - Set current driver state
1406 * @state: Driver state to be set to.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001407 *
Prashanth Bhatta9e143052015-12-04 11:56:47 -08001408 * This API sets driver state to state. This API only sets the state and doesn't
1409 * clear states, please make sure to use cds_clear_driver_state to clear any
1410 * state if required.
1411 *
1412 * Return: None
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001413 */
Prashanth Bhatta9e143052015-12-04 11:56:47 -08001414void cds_set_driver_state(enum cds_driver_state state)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001415{
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001416 if (gp_cds_context == NULL) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301417 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prashanth Bhatta9e143052015-12-04 11:56:47 -08001418 "%s: global cds context is NULL: %x", __func__,
1419 state);
1420
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001421 return;
1422 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001423
Prashanth Bhatta9e143052015-12-04 11:56:47 -08001424 gp_cds_context->driver_state |= state;
1425}
1426
1427/**
1428 * cds_clear_driver_state() - Clear current driver state
1429 * @state: Driver state to be cleared.
1430 *
1431 * This API clears driver state. This API only clears the state, please make
1432 * sure to use cds_set_driver_state to set any new states.
1433 *
1434 * Return: None
1435 */
1436void cds_clear_driver_state(enum cds_driver_state state)
1437{
1438 if (gp_cds_context == NULL) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301439 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prashanth Bhatta9e143052015-12-04 11:56:47 -08001440 "%s: global cds context is NULL: %x", __func__,
1441 state);
1442
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001443 return;
1444 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001445
Prashanth Bhatta9e143052015-12-04 11:56:47 -08001446 gp_cds_context->driver_state &= ~state;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001447}
1448
Nachiket Kukade8003d252017-03-30 15:55:58 +05301449enum cds_fw_state cds_get_fw_state(void)
1450{
1451 if (gp_cds_context == NULL) {
1452 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
1453 "%s: global cds context is NULL", __func__);
1454
1455 return CDS_FW_STATE_UNINITIALIZED;
1456 }
1457
1458 return gp_cds_context->fw_state;
1459}
1460
1461void cds_set_fw_state(enum cds_fw_state state)
1462{
1463 if (gp_cds_context == NULL) {
1464 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
1465 "%s: global cds context is NULL: %d", __func__,
1466 state);
1467
1468 return;
1469 }
1470
1471 qdf_atomic_set_bit(state, &gp_cds_context->fw_state);
1472}
1473
1474void cds_clear_fw_state(enum cds_fw_state state)
1475{
1476 if (gp_cds_context == NULL) {
1477 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
1478 "%s: global cds context is NULL: %d", __func__,
1479 state);
1480
1481 return;
1482 }
1483
1484 qdf_atomic_clear_bit(state, &gp_cds_context->fw_state);
1485}
1486
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001487/**
1488 * cds_alloc_context() - allocate a context within the CDS global Context
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001489 * @moduleId: module ID who's context area is being allocated.
1490 * @ppModuleContext: pointer to location where the pointer to the
1491 * allocated context is returned. Note this output pointer
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301492 * is valid only if the API returns QDF_STATUS_SUCCESS
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001493 * @param size: size of the context area to be allocated.
1494 *
1495 * This API allows any user to allocate a user context area within the
1496 * CDS Global Context.
1497 *
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05301498 * Return: QDF status
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001499 */
Jeff Johnsonadb3b1c2017-09-13 10:42:36 -07001500QDF_STATUS cds_alloc_context(QDF_MODULE_ID moduleID,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001501 void **ppModuleContext, uint32_t size)
1502{
1503 void **pGpModContext = NULL;
1504
Jeff Johnsonadb3b1c2017-09-13 10:42:36 -07001505 if (!gp_cds_context) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301506 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001507 "%s: cds context is null", __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301508 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001509 }
1510
Jeff Johnsonadb3b1c2017-09-13 10:42:36 -07001511 if (!ppModuleContext) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301512 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Jeff Johnsonadb3b1c2017-09-13 10:42:36 -07001513 "%s: null param passed",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001514 __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301515 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001516 }
1517
1518 switch (moduleID) {
Anurag Chouhan6d760662016-02-20 16:05:43 +05301519 case QDF_MODULE_ID_WMA:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001520 pGpModContext = &(gp_cds_context->pWMAContext);
1521 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001522
Anurag Chouhan6d760662016-02-20 16:05:43 +05301523 case QDF_MODULE_ID_HIF:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001524 pGpModContext = &(gp_cds_context->pHIFContext);
1525 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001526
Anurag Chouhan6d760662016-02-20 16:05:43 +05301527 case QDF_MODULE_ID_BMI:
Komal Seelamd9106492016-02-15 10:31:44 +05301528 pGpModContext = &(gp_cds_context->g_ol_context);
1529 break;
Komal Seelamd9106492016-02-15 10:31:44 +05301530
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001531 default:
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301532 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Jeff Johnsonadb3b1c2017-09-13 10:42:36 -07001533 "%s: Module ID %i does not have its context allocated by CDS",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001534 __func__, moduleID);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301535 QDF_ASSERT(0);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301536 return QDF_STATUS_E_INVAL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001537 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001538
Jeff Johnsonadb3b1c2017-09-13 10:42:36 -07001539 if (*pGpModContext) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001540 /* Context has already been allocated!
1541 * Prevent double allocation
1542 */
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301543 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001544 "%s: Module ID %i context has already been allocated",
1545 __func__, moduleID);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301546 return QDF_STATUS_E_EXISTS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001547 }
1548
1549 /* Dynamically allocate the context for module */
1550
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301551 *ppModuleContext = qdf_mem_malloc(size);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001552
Jeff Johnsonadb3b1c2017-09-13 10:42:36 -07001553 if (!*ppModuleContext) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301554 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Jeff Johnsonadb3b1c2017-09-13 10:42:36 -07001555 "%s: Failed to allocate Context for module ID %i",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001556 __func__, moduleID);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301557 QDF_ASSERT(0);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301558 return QDF_STATUS_E_NOMEM;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001559 }
1560
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001561 *pGpModContext = *ppModuleContext;
1562
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301563 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001564} /* cds_alloc_context() */
1565
1566/**
Komal Seelamad5a90d2016-02-16 13:50:03 +05301567 * cds_set_context() - API to set context in global CDS Context
Komal Seelam1aac1982016-03-02 15:57:26 +05301568 * @module_id: Module ID
Komal Seelamad5a90d2016-02-16 13:50:03 +05301569 * @context: Pointer to the Module Context
1570 *
Komal Seelam1aac1982016-03-02 15:57:26 +05301571 * API to set a MODULE Context in global CDS Context
Komal Seelamad5a90d2016-02-16 13:50:03 +05301572 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301573 * Return: QDF_STATUS
Komal Seelamad5a90d2016-02-16 13:50:03 +05301574 */
Anurag Chouhan6d760662016-02-20 16:05:43 +05301575QDF_STATUS cds_set_context(QDF_MODULE_ID module_id, void *context)
Komal Seelamad5a90d2016-02-16 13:50:03 +05301576{
1577 p_cds_contextType p_cds_context = cds_get_global_context();
1578
1579 if (!p_cds_context) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301580 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Komal Seelam1aac1982016-03-02 15:57:26 +05301581 "cds context is Invalid");
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301582 return QDF_STATUS_NOT_INITIALIZED;
Komal Seelamad5a90d2016-02-16 13:50:03 +05301583 }
1584
1585 switch (module_id) {
Jeff Johnson3543fb22017-09-24 13:44:13 -07001586 case QDF_MODULE_ID_HDD:
1587 p_cds_context->pHDDContext = context;
1588 break;
Houston Hoffman57c36d72017-01-30 12:47:02 -08001589 case QDF_MODULE_ID_TXRX:
1590 p_cds_context->pdev_txrx_ctx = context;
1591 break;
Anurag Chouhan6d760662016-02-20 16:05:43 +05301592 case QDF_MODULE_ID_HIF:
Komal Seelamad5a90d2016-02-16 13:50:03 +05301593 p_cds_context->pHIFContext = context;
1594 break;
1595 default:
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301596 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Komal Seelam1aac1982016-03-02 15:57:26 +05301597 "%s: Module ID %i does not have its context managed by CDS",
1598 __func__, module_id);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301599 QDF_ASSERT(0);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301600 return QDF_STATUS_E_INVAL;
Komal Seelamad5a90d2016-02-16 13:50:03 +05301601 }
1602
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301603 return QDF_STATUS_SUCCESS;
Komal Seelamad5a90d2016-02-16 13:50:03 +05301604}
1605
1606/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001607 * cds_free_context() - free an allocated context within the
1608 * CDS global Context
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001609 * @moduleId: module ID who's context area is being free
1610 * @pModuleContext: pointer to module context area to be free'd.
1611 *
1612 * This API allows a user to free the user context area within the
1613 * CDS Global Context.
1614 *
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05301615 * Return: QDF status
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001616 */
Jeff Johnsonadb3b1c2017-09-13 10:42:36 -07001617QDF_STATUS cds_free_context(QDF_MODULE_ID moduleID, void *pModuleContext)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001618{
1619 void **pGpModContext = NULL;
1620
Jeff Johnsonadb3b1c2017-09-13 10:42:36 -07001621 if (!gp_cds_context) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301622 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Jeff Johnsonadb3b1c2017-09-13 10:42:36 -07001623 "%s: cds context is null", __func__);
1624 return QDF_STATUS_E_FAILURE;
1625 }
1626
1627 if (!pModuleContext) {
1628 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
1629 "%s: Null param", __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301630 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001631 }
1632
1633 switch (moduleID) {
Anurag Chouhan6d760662016-02-20 16:05:43 +05301634 case QDF_MODULE_ID_WMA:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001635 pGpModContext = &(gp_cds_context->pWMAContext);
1636 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001637
Anurag Chouhan6d760662016-02-20 16:05:43 +05301638 case QDF_MODULE_ID_HIF:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001639 pGpModContext = &(gp_cds_context->pHIFContext);
1640 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001641
Anurag Chouhan6d760662016-02-20 16:05:43 +05301642 case QDF_MODULE_ID_TXRX:
Venkata Sharath Chandra Manchala0d44d452016-11-23 17:48:15 -08001643 pGpModContext = (void **)&(gp_cds_context->pdev_txrx_ctx);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001644 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001645
Anurag Chouhan6d760662016-02-20 16:05:43 +05301646 case QDF_MODULE_ID_BMI:
Komal Seelamd9106492016-02-15 10:31:44 +05301647 pGpModContext = &(gp_cds_context->g_ol_context);
1648 break;
Komal Seelamd9106492016-02-15 10:31:44 +05301649
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001650 default:
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301651 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001652 "%s: Module ID %i "
1653 "does not have its context allocated by CDS",
1654 __func__, moduleID);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301655 QDF_ASSERT(0);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301656 return QDF_STATUS_E_INVAL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001657 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001658
1659 if (NULL == *pGpModContext) {
1660 /* Context has not been allocated or freed already! */
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301661 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Jeff Johnsonadb3b1c2017-09-13 10:42:36 -07001662 "%s: Module ID %i context has not been allocated or freed already",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001663 __func__, moduleID);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301664 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001665 }
1666
1667 if (*pGpModContext != pModuleContext) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301668 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001669 "%s: pGpModContext != pModuleContext", __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301670 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001671 }
1672
Jeff Johnsonadb3b1c2017-09-13 10:42:36 -07001673 qdf_mem_free(pModuleContext);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001674
1675 *pGpModContext = NULL;
1676
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301677 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001678} /* cds_free_context() */
1679
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001680/**
1681 * cds_sys_probe_thread_cback() - probe mc thread callback
1682 * @pUserData: pointer to user data
1683 *
1684 * Return: none
1685 */
1686void cds_sys_probe_thread_cback(void *pUserData)
1687{
1688 if (gp_cds_context != pUserData) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301689 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001690 "%s: gp_cds_context != pUserData", __func__);
1691 return;
1692 }
1693
Anurag Chouhance0dc992016-02-16 18:18:03 +05301694 if (qdf_event_set(&gp_cds_context->ProbeEvent) != QDF_STATUS_SUCCESS) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301695 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Anurag Chouhance0dc992016-02-16 18:18:03 +05301696 "%s: qdf_event_set failed", __func__);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001697 return;
1698 }
1699} /* cds_sys_probe_thread_cback() */
1700
1701/**
1702 * cds_wma_complete_cback() - wma complete callback
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001703 *
1704 * Return: none
1705 */
Jeff Johnsonf7ab8142017-09-13 09:04:23 -07001706void cds_wma_complete_cback(void)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001707{
Jeff Johnsonf7ab8142017-09-13 09:04:23 -07001708 if (!gp_cds_context) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301709 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Jeff Johnsonf7ab8142017-09-13 09:04:23 -07001710 "%s: invalid gp_cds_context", __func__);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001711 return;
1712 }
1713
Anurag Chouhance0dc992016-02-16 18:18:03 +05301714 if (qdf_event_set(&gp_cds_context->wmaCompleteEvent) !=
1715 QDF_STATUS_SUCCESS) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301716 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Anurag Chouhance0dc992016-02-16 18:18:03 +05301717 "%s: qdf_event_set failed", __func__);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001718 return;
1719 }
1720} /* cds_wma_complete_cback() */
1721
1722/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001723 * cds_get_vdev_types() - get vdev type
1724 * @mode: mode
1725 * @type: type
1726 * @sub_type: sub_type
1727 *
1728 * Return: WMI vdev type
1729 */
Jeff Johnsonc1e62782017-11-09 09:50:17 -08001730QDF_STATUS cds_get_vdev_types(enum QDF_OPMODE mode, uint32_t *type,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001731 uint32_t *sub_type)
1732{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301733 QDF_STATUS status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001734 *type = 0;
1735 *sub_type = 0;
1736
1737 switch (mode) {
Anurag Chouhan6d760662016-02-20 16:05:43 +05301738 case QDF_STA_MODE:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001739 *type = WMI_VDEV_TYPE_STA;
1740 break;
Anurag Chouhan6d760662016-02-20 16:05:43 +05301741 case QDF_SAP_MODE:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001742 *type = WMI_VDEV_TYPE_AP;
1743 break;
Anurag Chouhan6d760662016-02-20 16:05:43 +05301744 case QDF_P2P_DEVICE_MODE:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001745 *type = WMI_VDEV_TYPE_AP;
1746 *sub_type = WMI_UNIFIED_VDEV_SUBTYPE_P2P_DEVICE;
1747 break;
Anurag Chouhan6d760662016-02-20 16:05:43 +05301748 case QDF_P2P_CLIENT_MODE:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001749 *type = WMI_VDEV_TYPE_STA;
1750 *sub_type = WMI_UNIFIED_VDEV_SUBTYPE_P2P_CLIENT;
1751 break;
Anurag Chouhan6d760662016-02-20 16:05:43 +05301752 case QDF_P2P_GO_MODE:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001753 *type = WMI_VDEV_TYPE_AP;
1754 *sub_type = WMI_UNIFIED_VDEV_SUBTYPE_P2P_GO;
1755 break;
Anurag Chouhan6d760662016-02-20 16:05:43 +05301756 case QDF_OCB_MODE:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001757 *type = WMI_VDEV_TYPE_OCB;
1758 break;
Krunal Soni8c37e322016-02-03 16:08:37 -08001759 case QDF_IBSS_MODE:
1760 *type = WMI_VDEV_TYPE_IBSS;
1761 break;
Manjunathappa Prakashb7573722016-04-21 11:24:07 -07001762 case QDF_MONITOR_MODE:
1763 *type = WMI_VDEV_TYPE_MONITOR;
1764 break;
Deepak Dhamdheree2dd5442016-05-27 15:05:51 -07001765 case QDF_NDI_MODE:
1766 *type = WMI_VDEV_TYPE_NDI;
1767 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001768 default:
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301769 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Ryan Hsud7e6fc72015-12-07 17:26:14 -08001770 "Invalid device mode %d", mode);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301771 status = QDF_STATUS_E_INVAL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001772 break;
1773 }
1774 return status;
1775}
1776
1777/**
1778 * cds_flush_work() - flush pending works
1779 * @work: pointer to work
1780 *
1781 * Return: none
1782 */
1783void cds_flush_work(void *work)
1784{
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001785 cancel_work_sync(work);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001786}
1787
1788/**
1789 * cds_flush_delayed_work() - flush delayed works
1790 * @dwork: pointer to delayed work
1791 *
1792 * Return: none
1793 */
1794void cds_flush_delayed_work(void *dwork)
1795{
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001796 cancel_delayed_work_sync(dwork);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001797}
1798
1799/**
1800 * cds_is_packet_log_enabled() - check if packet log is enabled
1801 *
1802 * Return: true if packet log is enabled else false
1803 */
1804bool cds_is_packet_log_enabled(void)
1805{
Jeff Johnsonc18b26c2017-09-03 08:46:45 -07001806 struct hdd_context *hdd_ctx;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001807
Jeff Johnsonc18b26c2017-09-03 08:46:45 -07001808 hdd_ctx = (struct hdd_context *) (gp_cds_context->pHDDContext);
1809 if ((NULL == hdd_ctx) || (NULL == hdd_ctx->config)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301810 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_FATAL,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001811 "%s: Hdd Context is Null", __func__);
1812 return false;
1813 }
Jeff Johnsonc18b26c2017-09-03 08:46:45 -07001814 return hdd_ctx->config->enablePacketLog;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001815}
1816
Dustin Brown100201e2017-07-10 11:48:40 -07001817static int cds_force_assert_target_via_pld(qdf_device_t qdf)
Mukul Sharmab7b575b2016-10-02 23:37:07 +05301818{
Dustin Brown100201e2017-07-10 11:48:40 -07001819 int errno;
1820
1821 errno = pld_force_assert_target(qdf->dev);
1822 if (errno == -EOPNOTSUPP)
1823 cds_info("PLD does not support target force assert");
1824 else if (errno)
1825 cds_err("Failed PLD target force assert; errno %d", errno);
1826 else
1827 cds_info("Target force assert triggered via PLD");
1828
1829 return errno;
Mukul Sharmab7b575b2016-10-02 23:37:07 +05301830}
1831
Dustin Brown100201e2017-07-10 11:48:40 -07001832static QDF_STATUS cds_force_assert_target_via_wmi(qdf_device_t qdf)
Rajeev Kumardb60f162017-07-25 20:27:59 -07001833{
Dustin Brown100201e2017-07-10 11:48:40 -07001834 QDF_STATUS status;
1835 t_wma_handle *wma;
1836
1837 wma = cds_get_context(QDF_MODULE_ID_WMA);
1838 if (!wma) {
1839 cds_err("wma is null");
1840 return QDF_STATUS_E_INVAL;
1841 }
1842
1843 status = wma_crash_inject(wma, RECOVERY_SIM_SELF_RECOVERY, 0);
1844 if (QDF_IS_STATUS_ERROR(status)) {
1845 cds_err("Failed target force assert; status %d", status);
1846 return status;
1847 }
1848
Nachiket Kukade0396b732017-11-14 16:35:16 +05301849 status = qdf_wait_for_event_completion(&wma->recovery_event,
Dustin Brown100201e2017-07-10 11:48:40 -07001850 WMA_CRASH_INJECT_TIMEOUT);
1851 if (QDF_IS_STATUS_ERROR(status)) {
1852 cds_err("Failed target force assert wait; status %d", status);
1853 return status;
1854 }
1855
1856 return QDF_STATUS_SUCCESS;
1857}
1858
1859/**
1860 * cds_force_assert_target() - Send assert command to firmware
1861 * @qdf: QDF device instance to assert
1862 *
1863 * An out-of-band recovery mechanism will cleanup and restart the entire wlan
1864 * subsystem in the event of a firmware crash. This API injects a firmware
1865 * crash to start this process when the wlan driver is known to be in a bad
1866 * state. If a firmware assert inject fails, the wlan driver will schedule
1867 * the driver recovery anyway, as a best effort attempt to return to a working
1868 * state.
1869 *
1870 * Return: QDF_STATUS
1871 */
1872static QDF_STATUS cds_force_assert_target(qdf_device_t qdf)
1873{
1874 int errno;
1875 QDF_STATUS status;
1876
1877 /* first, try target assert inject via pld */
1878 errno = cds_force_assert_target_via_pld(qdf);
1879 if (!errno)
1880 return QDF_STATUS_SUCCESS;
1881 if (errno != -EOPNOTSUPP)
1882 return QDF_STATUS_E_FAILURE;
1883
1884 /* pld assert is not supported, try target assert inject via wmi */
1885 status = cds_force_assert_target_via_wmi(qdf);
1886 if (QDF_IS_STATUS_SUCCESS(status))
1887 return QDF_STATUS_SUCCESS;
1888
1889 /* wmi assert failed, start recovery without the firmware assert */
1890 cds_err("Scheduling recovery work without firmware assert");
1891 cds_set_recovery_in_progress(true);
1892 pld_schedule_recovery_work(qdf->dev, PLD_REASON_DEFAULT);
1893
1894 return status;
Rajeev Kumardb60f162017-07-25 20:27:59 -07001895}
1896
Mukul Sharmab7b575b2016-10-02 23:37:07 +05301897/**
Srinivas Girigowda161b9f22017-07-24 17:38:09 -07001898 * cds_trigger_recovery_work() - trigger self recovery work
Mukul Sharmab7b575b2016-10-02 23:37:07 +05301899 *
1900 * Return: none
1901 */
Srinivas Girigowda161b9f22017-07-24 17:38:09 -07001902static void cds_trigger_recovery_work(void *param)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001903{
Dustin Brown100201e2017-07-10 11:48:40 -07001904 QDF_STATUS status;
1905 qdf_runtime_lock_t rtl;
1906 qdf_device_t qdf;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001907
Kabilan Kannan973744a2018-01-03 10:28:50 -08001908 if (cds_is_driver_recovering()) {
1909 cds_err("Recovery in progress; ignoring recovery trigger");
Sameer Thalappilec2e9c72017-02-08 15:45:49 -08001910 return;
1911 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001912
Kabilan Kannan973744a2018-01-03 10:28:50 -08001913 if (cds_is_driver_in_bad_state()) {
1914 cds_err("Driver is in bad state; ignoring recovery trigger");
Houston Hoffmanc7c72a82015-12-07 15:30:48 -08001915 return;
1916 }
1917
Rajeev Kumar6dd45a82017-10-20 14:43:05 -07001918 if (cds_is_fw_down()) {
1919 cds_err("FW is down; ignoring recovery trigger");
1920 return;
1921 }
1922
Kabilan Kannan973744a2018-01-03 10:28:50 -08001923 if (!cds_is_self_recovery_enabled()) {
1924 cds_err("Recovery is not enabled");
1925 QDF_BUG(0);
1926 return;
1927 }
1928
Dustin Brown100201e2017-07-10 11:48:40 -07001929 qdf = cds_get_context(QDF_MODULE_ID_QDF_DEVICE);
1930 if (!qdf) {
1931 cds_err("Qdf context is null");
1932 return;
Sameer Thalappilac5d26e2017-01-10 15:32:58 -08001933 }
1934
Dustin Brown100201e2017-07-10 11:48:40 -07001935 status = qdf_runtime_lock_init(&rtl);
1936 if (QDF_IS_STATUS_ERROR(status)) {
Srinivas Girigowda161b9f22017-07-24 17:38:09 -07001937 cds_err("qdf_runtime_lock_init failed, status: %d", status);
Dustin Brown100201e2017-07-10 11:48:40 -07001938 return;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001939 }
Houston Hoffmanc7c72a82015-12-07 15:30:48 -08001940
Dustin Brown100201e2017-07-10 11:48:40 -07001941 status = qdf_runtime_pm_prevent_suspend(&rtl);
1942 if (QDF_IS_STATUS_ERROR(status)) {
1943 cds_err("Failed to acquire runtime pm lock");
1944 goto deinit_rtl;
1945 }
1946
1947 cds_force_assert_target(qdf);
1948
1949 status = qdf_runtime_pm_allow_suspend(&rtl);
1950 if (QDF_IS_STATUS_ERROR(status))
1951 cds_err("Failed to release runtime pm lock");
1952
1953deinit_rtl:
1954 qdf_runtime_lock_deinit(&rtl);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001955}
1956
1957/**
Anurag Chouhan4085ff72017-10-05 18:09:56 +05301958 * cds_get_recovery_reason() - get self recovery reason
1959 * @reason: recovery reason
1960 *
1961 * Return: None
1962 */
1963void cds_get_recovery_reason(enum qdf_hang_reason *reason)
1964{
1965 if (!gp_cds_context) {
1966 cds_err("gp_cds_context is null");
1967 return;
1968 }
1969
1970 *reason = gp_cds_context->recovery_reason;
1971}
1972
1973/**
1974 * cds_reset_recovery_reason() - reset the reason to unspecified
1975 *
1976 * Return: None
1977 */
1978void cds_reset_recovery_reason(void)
1979{
1980 if (!gp_cds_context) {
1981 cds_err("gp_cds_context is null");
1982 return;
1983 }
1984
1985 gp_cds_context->recovery_reason = QDF_REASON_UNSPECIFIED;
1986}
1987
1988/**
Srinivas Girigowda161b9f22017-07-24 17:38:09 -07001989 * cds_trigger_recovery() - trigger self recovery
Anurag Chouhan4085ff72017-10-05 18:09:56 +05301990 * @reason: recovery reason
Srinivas Girigowda161b9f22017-07-24 17:38:09 -07001991 *
1992 * Return: none
1993 */
Anurag Chouhan4085ff72017-10-05 18:09:56 +05301994void cds_trigger_recovery(enum qdf_hang_reason reason)
Srinivas Girigowda161b9f22017-07-24 17:38:09 -07001995{
Anurag Chouhan4085ff72017-10-05 18:09:56 +05301996 if (!gp_cds_context) {
1997 cds_err("gp_cds_context is null");
1998 return;
1999 }
2000
2001 gp_cds_context->recovery_reason = reason;
Srinivas Girigowda161b9f22017-07-24 17:38:09 -07002002 if (in_atomic()) {
2003 qdf_queue_work(0, gp_cds_context->cds_recovery_wq,
2004 &gp_cds_context->cds_recovery_work);
2005 return;
2006 }
2007 cds_trigger_recovery_work(NULL);
2008}
2009
2010/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002011 * cds_get_monotonic_boottime() - Get kernel boot time.
2012 *
2013 * Return: Time in microseconds
2014 */
2015
2016uint64_t cds_get_monotonic_boottime(void)
2017{
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002018 struct timespec ts;
2019
Yuanyuan Liu2e03b412016-04-06 14:36:15 -07002020 get_monotonic_boottime(&ts);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002021 return ((uint64_t) ts.tv_sec * 1000000) + (ts.tv_nsec / 1000);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002022}
2023
2024/**
2025 * cds_set_wakelock_logging() - Logging of wakelock enabled/disabled
2026 * @value: Boolean value
2027 *
2028 * This function is used to set the flag which will indicate whether
2029 * logging of wakelock is enabled or not
2030 *
2031 * Return: None
2032 */
2033void cds_set_wakelock_logging(bool value)
2034{
2035 p_cds_contextType p_cds_context;
2036
2037 p_cds_context = cds_get_global_context();
2038 if (!p_cds_context) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302039 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002040 "cds context is Invald");
2041 return;
2042 }
2043 p_cds_context->is_wakelock_log_enabled = value;
2044}
2045
2046/**
2047 * cds_is_wakelock_enabled() - Check if logging of wakelock is enabled/disabled
2048 * @value: Boolean value
2049 *
2050 * This function is used to check whether logging of wakelock is enabled or not
2051 *
2052 * Return: true if logging of wakelock is enabled
2053 */
2054bool cds_is_wakelock_enabled(void)
2055{
2056 p_cds_contextType p_cds_context;
2057
2058 p_cds_context = cds_get_global_context();
2059 if (!p_cds_context) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302060 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002061 "cds context is Invald");
2062 return false;
2063 }
2064 return p_cds_context->is_wakelock_log_enabled;
2065}
2066
2067/**
2068 * cds_set_ring_log_level() - Sets the log level of a particular ring
2069 * @ring_id: ring_id
2070 * @log_levelvalue: Log level specificed
2071 *
2072 * This function converts HLOS values to driver log levels and sets the log
2073 * level of a particular ring accordingly.
2074 *
2075 * Return: None
2076 */
2077void cds_set_ring_log_level(uint32_t ring_id, uint32_t log_level)
2078{
2079 p_cds_contextType p_cds_context;
2080 uint32_t log_val;
2081
2082 p_cds_context = cds_get_global_context();
2083 if (!p_cds_context) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302084 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002085 "%s: cds context is Invald", __func__);
2086 return;
2087 }
2088
2089 switch (log_level) {
2090 case LOG_LEVEL_NO_COLLECTION:
2091 log_val = WLAN_LOG_LEVEL_OFF;
2092 break;
2093 case LOG_LEVEL_NORMAL_COLLECT:
2094 log_val = WLAN_LOG_LEVEL_NORMAL;
2095 break;
2096 case LOG_LEVEL_ISSUE_REPRO:
2097 log_val = WLAN_LOG_LEVEL_REPRO;
2098 break;
2099 case LOG_LEVEL_ACTIVE:
2100 default:
2101 log_val = WLAN_LOG_LEVEL_ACTIVE;
2102 break;
2103 }
2104
2105 if (ring_id == RING_ID_WAKELOCK) {
2106 p_cds_context->wakelock_log_level = log_val;
2107 return;
2108 } else if (ring_id == RING_ID_CONNECTIVITY) {
2109 p_cds_context->connectivity_log_level = log_val;
2110 return;
2111 } else if (ring_id == RING_ID_PER_PACKET_STATS) {
2112 p_cds_context->packet_stats_log_level = log_val;
2113 return;
Chandrasekaran, Manishekar907c2af2015-11-13 12:50:04 +05302114 } else if (ring_id == RING_ID_DRIVER_DEBUG) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002115 p_cds_context->driver_debug_log_level = log_val;
2116 return;
2117 } else if (ring_id == RING_ID_FIRMWARE_DEBUG) {
2118 p_cds_context->fw_debug_log_level = log_val;
2119 return;
2120 }
2121}
2122
2123/**
2124 * cds_get_ring_log_level() - Get the a ring id's log level
2125 * @ring_id: Ring id
2126 *
2127 * Fetch and return the log level corresponding to a ring id
2128 *
2129 * Return: Log level corresponding to the ring ID
2130 */
2131enum wifi_driver_log_level cds_get_ring_log_level(uint32_t ring_id)
2132{
2133 p_cds_contextType p_cds_context;
2134
2135 p_cds_context = cds_get_global_context();
2136 if (!p_cds_context) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302137 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002138 "%s: cds context is Invald", __func__);
2139 return WLAN_LOG_LEVEL_OFF;
2140 }
2141
2142 if (ring_id == RING_ID_WAKELOCK)
2143 return p_cds_context->wakelock_log_level;
2144 else if (ring_id == RING_ID_CONNECTIVITY)
2145 return p_cds_context->connectivity_log_level;
2146 else if (ring_id == RING_ID_PER_PACKET_STATS)
2147 return p_cds_context->packet_stats_log_level;
Chandrasekaran, Manishekar907c2af2015-11-13 12:50:04 +05302148 else if (ring_id == RING_ID_DRIVER_DEBUG)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002149 return p_cds_context->driver_debug_log_level;
2150 else if (ring_id == RING_ID_FIRMWARE_DEBUG)
2151 return p_cds_context->fw_debug_log_level;
2152
2153 return WLAN_LOG_LEVEL_OFF;
2154}
2155
2156/**
2157 * cds_set_multicast_logging() - Set mutlicast logging value
2158 * @value: Value of multicast logging
2159 *
2160 * Set the multicast logging value which will indicate
2161 * whether to multicast host and fw messages even
2162 * without any registration by userspace entity
2163 *
2164 * Return: None
2165 */
2166void cds_set_multicast_logging(uint8_t value)
2167{
2168 cds_multicast_logging = value;
2169}
2170
2171/**
2172 * cds_is_multicast_logging() - Get multicast logging value
2173 *
2174 * Get the multicast logging value which will indicate
2175 * whether to multicast host and fw messages even
2176 * without any registration by userspace entity
2177 *
2178 * Return: 0 - Multicast logging disabled, 1 - Multicast logging enabled
2179 */
2180uint8_t cds_is_multicast_logging(void)
2181{
2182 return cds_multicast_logging;
2183}
2184
2185/*
2186 * cds_init_log_completion() - Initialize log param structure
2187 *
2188 * This function is used to initialize the logging related
2189 * parameters
2190 *
2191 * Return: None
2192 */
2193void cds_init_log_completion(void)
2194{
2195 p_cds_contextType p_cds_context;
2196
2197 p_cds_context = cds_get_global_context();
2198 if (!p_cds_context) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302199 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002200 "%s: cds context is Invalid", __func__);
2201 return;
2202 }
2203
2204 p_cds_context->log_complete.is_fatal = WLAN_LOG_TYPE_NON_FATAL;
2205 p_cds_context->log_complete.indicator = WLAN_LOG_INDICATOR_UNUSED;
2206 p_cds_context->log_complete.reason_code = WLAN_LOG_REASON_CODE_UNUSED;
2207 p_cds_context->log_complete.is_report_in_progress = false;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002208}
2209
2210/**
2211 * cds_set_log_completion() - Store the logging params
2212 * @is_fatal: Indicates if the event triggering bug report is fatal or not
2213 * @indicator: Source which trigerred the bug report
2214 * @reason_code: Reason for triggering bug report
Abhishek Singh5ea86532016-04-27 14:10:53 +05302215 * @recovery_needed: If recovery is needed after bug report
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002216 *
2217 * This function is used to set the logging parameters based on the
2218 * caller
2219 *
2220 * Return: 0 if setting of params is successful
2221 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302222QDF_STATUS cds_set_log_completion(uint32_t is_fatal,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002223 uint32_t indicator,
Abhishek Singh5ea86532016-04-27 14:10:53 +05302224 uint32_t reason_code,
2225 bool recovery_needed)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002226{
2227 p_cds_contextType p_cds_context;
2228
2229 p_cds_context = cds_get_global_context();
2230 if (!p_cds_context) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302231 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002232 "%s: cds context is Invalid", __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302233 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002234 }
2235
Anurag Chouhana37b5b72016-02-21 14:53:42 +05302236 qdf_spinlock_acquire(&p_cds_context->bug_report_lock);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002237 p_cds_context->log_complete.is_fatal = is_fatal;
2238 p_cds_context->log_complete.indicator = indicator;
2239 p_cds_context->log_complete.reason_code = reason_code;
Abhishek Singh5ea86532016-04-27 14:10:53 +05302240 p_cds_context->log_complete.recovery_needed = recovery_needed;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002241 p_cds_context->log_complete.is_report_in_progress = true;
Anurag Chouhana37b5b72016-02-21 14:53:42 +05302242 qdf_spinlock_release(&p_cds_context->bug_report_lock);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302243 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002244}
2245
2246/**
Abhishek Singh5ea86532016-04-27 14:10:53 +05302247 * cds_get_and_reset_log_completion() - Get and reset logging related params
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002248 * @is_fatal: Indicates if the event triggering bug report is fatal or not
2249 * @indicator: Source which trigerred the bug report
2250 * @reason_code: Reason for triggering bug report
Abhishek Singh5ea86532016-04-27 14:10:53 +05302251 * @recovery_needed: If recovery is needed after bug report
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002252 *
2253 * This function is used to get the logging related parameters
2254 *
2255 * Return: None
2256 */
Abhishek Singh5ea86532016-04-27 14:10:53 +05302257void cds_get_and_reset_log_completion(uint32_t *is_fatal,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002258 uint32_t *indicator,
Abhishek Singh5ea86532016-04-27 14:10:53 +05302259 uint32_t *reason_code,
2260 bool *recovery_needed)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002261{
2262 p_cds_contextType p_cds_context;
2263
2264 p_cds_context = cds_get_global_context();
2265 if (!p_cds_context) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302266 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002267 "%s: cds context is Invalid", __func__);
2268 return;
2269 }
2270
Anurag Chouhana37b5b72016-02-21 14:53:42 +05302271 qdf_spinlock_acquire(&p_cds_context->bug_report_lock);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002272 *is_fatal = p_cds_context->log_complete.is_fatal;
2273 *indicator = p_cds_context->log_complete.indicator;
2274 *reason_code = p_cds_context->log_complete.reason_code;
Abhishek Singh5ea86532016-04-27 14:10:53 +05302275 *recovery_needed = p_cds_context->log_complete.recovery_needed;
2276
2277 /* reset */
2278 p_cds_context->log_complete.indicator = WLAN_LOG_INDICATOR_UNUSED;
2279 p_cds_context->log_complete.is_fatal = WLAN_LOG_TYPE_NON_FATAL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002280 p_cds_context->log_complete.is_report_in_progress = false;
Abhishek Singh5ea86532016-04-27 14:10:53 +05302281 p_cds_context->log_complete.reason_code = WLAN_LOG_REASON_CODE_UNUSED;
2282 p_cds_context->log_complete.recovery_needed = false;
Anurag Chouhana37b5b72016-02-21 14:53:42 +05302283 qdf_spinlock_release(&p_cds_context->bug_report_lock);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002284}
2285
2286/**
2287 * cds_is_log_report_in_progress() - Check if bug reporting is in progress
2288 *
2289 * This function is used to check if the bug reporting is already in progress
2290 *
2291 * Return: true if the bug reporting is in progress
2292 */
2293bool cds_is_log_report_in_progress(void)
2294{
2295 p_cds_contextType p_cds_context;
2296
2297 p_cds_context = cds_get_global_context();
2298 if (!p_cds_context) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302299 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002300 "%s: cds context is Invalid", __func__);
2301 return true;
2302 }
2303 return p_cds_context->log_complete.is_report_in_progress;
2304}
2305
2306/**
Abhishek Singh5ea86532016-04-27 14:10:53 +05302307 * cds_is_fatal_event_enabled() - Return if fatal event is enabled
2308 *
2309 * Return true if fatal event is enabled.
2310 */
2311bool cds_is_fatal_event_enabled(void)
2312{
2313 p_cds_contextType p_cds_context;
2314
2315 p_cds_context = cds_get_global_context();
2316 if (!p_cds_context) {
2317 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
2318 "%s: cds context is Invalid", __func__);
2319 return false;
2320 }
2321
2322
2323 return p_cds_context->enable_fatal_event;
2324}
2325
Yu Wang66a250b2017-07-19 11:46:40 +08002326#ifdef WLAN_FEATURE_TSF_PLUS
2327bool cds_is_ptp_rx_opt_enabled(void)
2328{
2329 struct hdd_context *hdd_ctx;
2330 p_cds_contextType p_cds_context;
2331
2332 p_cds_context = cds_get_global_context();
2333 if (!p_cds_context) {
2334 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
2335 "%s: cds context is Invalid", __func__);
2336 return false;
2337 }
2338
2339 hdd_ctx = (struct hdd_context *)(p_cds_context->pHDDContext);
2340 if ((NULL == hdd_ctx) || (NULL == hdd_ctx->config)) {
2341 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
2342 "%s: Hdd Context is Null", __func__);
2343 return false;
2344 }
2345
2346 return HDD_TSF_IS_RX_SET(hdd_ctx);
2347}
2348
2349bool cds_is_ptp_tx_opt_enabled(void)
2350{
2351 struct hdd_context *hdd_ctx;
2352 p_cds_contextType p_cds_context;
2353
2354 p_cds_context = cds_get_global_context();
2355 if (!p_cds_context) {
2356 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
2357 "%s: cds context is Invalid", __func__);
2358 return false;
2359 }
2360
2361 hdd_ctx = (struct hdd_context *)(p_cds_context->pHDDContext);
2362 if ((NULL == hdd_ctx) || (NULL == hdd_ctx->config)) {
2363 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
2364 "%s: Hdd Context is Null", __func__);
2365 return false;
2366 }
2367
2368 return HDD_TSF_IS_TX_SET(hdd_ctx);
2369}
2370#endif
2371
Abhishek Singh5ea86532016-04-27 14:10:53 +05302372/**
2373 * cds_get_log_indicator() - Get the log flush indicator
2374 *
2375 * This function is used to get the log flush indicator
2376 *
2377 * Return: log indicator
2378 */
2379uint32_t cds_get_log_indicator(void)
2380{
2381 p_cds_contextType p_cds_context;
2382 uint32_t indicator;
2383
2384 p_cds_context = cds_get_global_context();
2385 if (!p_cds_context) {
2386 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
2387 "%s: cds context is Invalid", __func__);
2388 return WLAN_LOG_INDICATOR_UNUSED;
2389 }
2390
2391 if (cds_is_load_or_unload_in_progress() ||
Hanumanth Reddy Pothula2a8a7402017-07-03 14:06:11 +05302392 cds_is_driver_recovering() || cds_is_driver_in_bad_state()) {
Abhishek Singh5ea86532016-04-27 14:10:53 +05302393 return WLAN_LOG_INDICATOR_UNUSED;
2394 }
2395
2396 qdf_spinlock_acquire(&p_cds_context->bug_report_lock);
2397 indicator = p_cds_context->log_complete.indicator;
2398 qdf_spinlock_release(&p_cds_context->bug_report_lock);
2399 return indicator;
2400}
2401
2402/**
2403 * cds_wlan_flush_host_logs_for_fatal() - Wrapper to flush host logs
2404 *
2405 * This function is used to send signal to the logger thread to
2406 * flush the host logs.
2407 *
2408 * Return: None
2409 *
2410 */
2411void cds_wlan_flush_host_logs_for_fatal(void)
2412{
2413 wlan_flush_host_logs_for_fatal();
2414}
2415
2416/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002417 * cds_flush_logs() - Report fatal event to userspace
2418 * @is_fatal: Indicates if the event triggering bug report is fatal or not
2419 * @indicator: Source which trigerred the bug report
2420 * @reason_code: Reason for triggering bug report
Abhishek Singh5ea86532016-04-27 14:10:53 +05302421 * @dump_mac_trace: If mac trace are needed in logs.
2422 * @recovery_needed: If recovery is needed after bug report
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002423 *
2424 * This function sets the log related params and send the WMI command to the
2425 * FW to flush its logs. On receiving the flush completion event from the FW
2426 * the same will be conveyed to userspace
2427 *
2428 * Return: 0 on success
2429 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302430QDF_STATUS cds_flush_logs(uint32_t is_fatal,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002431 uint32_t indicator,
Abhishek Singh5ea86532016-04-27 14:10:53 +05302432 uint32_t reason_code,
2433 bool dump_mac_trace,
2434 bool recovery_needed)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002435{
2436 uint32_t ret;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302437 QDF_STATUS status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002438
2439 p_cds_contextType p_cds_context;
2440
2441 p_cds_context = cds_get_global_context();
2442 if (!p_cds_context) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302443 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002444 "%s: cds context is Invalid", __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302445 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002446 }
Abhishek Singh5ea86532016-04-27 14:10:53 +05302447 if (!p_cds_context->enable_fatal_event) {
2448 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
2449 "%s: Fatal event not enabled", __func__);
2450 return QDF_STATUS_E_FAILURE;
2451 }
2452 if (cds_is_load_or_unload_in_progress() ||
Hanumanth Reddy Pothula2a8a7402017-07-03 14:06:11 +05302453 cds_is_driver_recovering() || cds_is_driver_in_bad_state()) {
Abhishek Singh5ea86532016-04-27 14:10:53 +05302454 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
2455 "%s: un/Load/SSR in progress", __func__);
2456 return QDF_STATUS_E_FAILURE;
2457 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002458
2459 if (cds_is_log_report_in_progress() == true) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302460 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002461 "%s: Bug report already in progress - dropping! type:%d, indicator=%d reason_code=%d",
2462 __func__, is_fatal, indicator, reason_code);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302463 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002464 }
2465
Abhishek Singh5ea86532016-04-27 14:10:53 +05302466 status = cds_set_log_completion(is_fatal, indicator,
2467 reason_code, recovery_needed);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302468 if (QDF_STATUS_SUCCESS != status) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302469 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002470 "%s: Failed to set log trigger params", __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302471 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002472 }
2473
Srinivas Girigowda80213e52018-01-23 14:51:33 -08002474 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_INFO,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002475 "%s: Triggering bug report: type:%d, indicator=%d reason_code=%d",
2476 __func__, is_fatal, indicator, reason_code);
2477
Abhishek Singh5ea86532016-04-27 14:10:53 +05302478 if (dump_mac_trace)
2479 qdf_trace_dump_all(p_cds_context->pMACContext, 0, 0, 500, 0);
2480
2481 if (WLAN_LOG_INDICATOR_HOST_ONLY == indicator) {
2482 cds_wlan_flush_host_logs_for_fatal();
2483 return QDF_STATUS_SUCCESS;
2484 }
2485
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002486 ret = sme_send_flush_logs_cmd_to_fw(p_cds_context->pMACContext);
2487 if (0 != ret) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302488 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002489 "%s: Failed to send flush FW log", __func__);
2490 cds_init_log_completion();
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302491 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002492 }
2493
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302494 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002495}
2496
2497/**
2498 * cds_logging_set_fw_flush_complete() - Wrapper for FW log flush completion
2499 *
2500 * This function is used to send signal to the logger thread to indicate
2501 * that the flushing of FW logs is complete by the FW
2502 *
2503 * Return: None
2504 *
2505 */
2506void cds_logging_set_fw_flush_complete(void)
2507{
2508 wlan_logging_set_fw_flush_complete();
2509}
Abhishek Singh5ea86532016-04-27 14:10:53 +05302510
2511/**
2512 * cds_set_fatal_event() - set fatal event status
2513 * @value: pending statue to set
2514 *
2515 * Return: None
2516 */
2517void cds_set_fatal_event(bool value)
2518{
2519 p_cds_contextType p_cds_context;
2520
2521 p_cds_context = cds_get_global_context();
2522 if (!p_cds_context) {
2523 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
2524 "%s: cds context is Invalid", __func__);
2525 return;
2526 }
2527 p_cds_context->enable_fatal_event = value;
2528}
2529
Ryan Hsuceddceb2016-04-28 10:20:14 -07002530/**
2531 * cds_get_radio_index() - get radio index
2532 *
2533 * Return: radio index otherwise, -EINVAL
2534 */
2535int cds_get_radio_index(void)
2536{
2537 p_cds_contextType p_cds_context;
2538
2539 p_cds_context = cds_get_global_context();
2540 if (!p_cds_context) {
2541 /*
2542 * To avoid recursive call, this should not change to
2543 * QDF_TRACE().
2544 */
2545 pr_err("%s: cds context is invalid\n", __func__);
2546 return -EINVAL;
2547 }
2548
2549 return p_cds_context->radio_index;
2550}
2551
2552/**
2553 * cds_set_radio_index() - set radio index
2554 * @radio_index: the radio index to set
2555 *
2556 * Return: QDF status
2557 */
2558QDF_STATUS cds_set_radio_index(int radio_index)
2559{
2560 p_cds_contextType p_cds_context;
2561
2562 p_cds_context = cds_get_global_context();
2563 if (!p_cds_context) {
2564 pr_err("%s: cds context is invalid\n", __func__);
2565 return QDF_STATUS_E_FAILURE;
2566 }
2567
2568 p_cds_context->radio_index = radio_index;
2569
2570 return QDF_STATUS_SUCCESS;
2571}
Arun Khandavallic811dcc2016-06-26 07:37:21 +05302572
2573/**
2574 * cds_init_ini_config() - API to initialize CDS configuration parameters
2575 * @cfg: CDS Configuration
2576 *
2577 * Return: void
2578 */
2579
2580void cds_init_ini_config(struct cds_config_info *cfg)
2581{
2582 cds_context_type *cds_ctx;
2583
2584 cds_ctx = cds_get_context(QDF_MODULE_ID_QDF);
2585 if (!cds_ctx) {
2586 cds_err("Invalid CDS Context");
2587 return;
2588 }
2589
2590 cds_ctx->cds_cfg = cfg;
2591}
2592
2593/**
2594 * cds_deinit_ini_config() - API to free CDS configuration parameters
2595 *
2596 * Return: void
2597 */
2598void cds_deinit_ini_config(void)
2599{
2600 cds_context_type *cds_ctx;
2601
2602 cds_ctx = cds_get_context(QDF_MODULE_ID_QDF);
2603 if (!cds_ctx) {
2604 cds_err("Invalid CDS Context");
2605 return;
2606 }
2607
Arun Khandavallif6246632016-08-17 17:43:06 +05302608 if (cds_ctx->cds_cfg)
Arun Khandavallic811dcc2016-06-26 07:37:21 +05302609 qdf_mem_free(cds_ctx->cds_cfg);
2610
2611 cds_ctx->cds_cfg = NULL;
2612}
2613
2614/**
2615 * cds_get_ini_config() - API to get CDS configuration parameters
2616 *
2617 * Return: cds config structure
2618 */
2619struct cds_config_info *cds_get_ini_config(void)
2620{
2621 cds_context_type *cds_ctx;
2622
2623 cds_ctx = cds_get_context(QDF_MODULE_ID_QDF);
2624 if (!cds_ctx) {
2625 cds_err("Invalid CDS Context");
2626 return NULL;
2627 }
2628
2629 return cds_ctx->cds_cfg;
2630}
Naveen Rawat64e477e2016-05-20 10:34:56 -07002631
2632/**
2633 * cds_is_5_mhz_enabled() - API to get 5MHZ enabled
2634 *
2635 * Return: true if 5 mhz is enabled, false otherwise
2636 */
2637bool cds_is_5_mhz_enabled(void)
2638{
2639 p_cds_contextType p_cds_context;
2640
2641 p_cds_context = cds_get_context(QDF_MODULE_ID_QDF);
2642 if (!p_cds_context) {
2643 cds_err("%s: cds context is invalid", __func__);
2644 return false;
2645 }
2646
2647 if (p_cds_context->cds_cfg)
2648 return (p_cds_context->cds_cfg->sub_20_channel_width ==
2649 WLAN_SUB_20_CH_WIDTH_5);
2650
2651 return false;
2652}
2653
2654/**
2655 * cds_is_10_mhz_enabled() - API to get 10-MHZ enabled
2656 *
2657 * Return: true if 10 mhz is enabled, false otherwise
2658 */
2659bool cds_is_10_mhz_enabled(void)
2660{
2661 p_cds_contextType p_cds_context;
2662
2663 p_cds_context = cds_get_context(QDF_MODULE_ID_QDF);
2664 if (!p_cds_context) {
2665 cds_err("%s: cds context is invalid", __func__);
2666 return false;
2667 }
2668
2669 if (p_cds_context->cds_cfg)
2670 return (p_cds_context->cds_cfg->sub_20_channel_width ==
2671 WLAN_SUB_20_CH_WIDTH_10);
2672
2673 return false;
2674}
2675
2676/**
2677 * cds_is_sub_20_mhz_enabled() - API to get sub 20-MHZ enabled
2678 *
2679 * Return: true if 5 or 10 mhz is enabled, false otherwise
2680 */
2681bool cds_is_sub_20_mhz_enabled(void)
2682{
2683 p_cds_contextType p_cds_context;
2684
2685 p_cds_context = cds_get_context(QDF_MODULE_ID_QDF);
2686 if (!p_cds_context) {
2687 cds_err("%s: cds context is invalid", __func__);
2688 return false;
2689 }
2690
2691 if (p_cds_context->cds_cfg)
2692 return p_cds_context->cds_cfg->sub_20_channel_width;
2693
2694 return false;
2695}
2696
Komal Seelam78ff65a2016-08-18 15:25:24 +05302697/**
Naveen Rawat91df30a2016-10-12 21:26:18 -07002698 * cds_is_self_recovery_enabled() - API to get self recovery enabled
2699 *
2700 * Return: true if self recovery enabled, false otherwise
2701 */
2702bool cds_is_self_recovery_enabled(void)
2703{
2704 p_cds_contextType p_cds_context;
2705
2706 p_cds_context = cds_get_context(QDF_MODULE_ID_QDF);
2707 if (!p_cds_context) {
2708 cds_err("%s: cds context is invalid", __func__);
2709 return false;
2710 }
2711
2712 if (p_cds_context->cds_cfg)
2713 return p_cds_context->cds_cfg->self_recovery_enabled;
2714
2715 return false;
2716}
2717
2718/**
Komal Seelam78ff65a2016-08-18 15:25:24 +05302719 * cds_svc_fw_shutdown_ind() - API to send userspace about FW crash
2720 *
2721 * @dev: Device Pointer
2722 *
2723 * Return: None
2724 */
2725void cds_svc_fw_shutdown_ind(struct device *dev)
2726{
2727 hdd_svc_fw_shutdown_ind(dev);
2728}
Himanshu Agarwal46956a52016-07-26 19:46:25 +05302729
Nirav Shaheb017be2018-02-15 11:20:58 +05302730#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
Himanshu Agarwal46956a52016-07-26 19:46:25 +05302731/*
2732 * cds_pkt_stats_to_logger_thread() - send pktstats to user
2733 * @pl_hdr: Pointer to pl_hdr
2734 * @pkt_dump: Pointer to pkt_dump data structure.
2735 * @data: Pointer to data
2736 *
2737 * This function is used to send the pkt stats to SVC module.
2738 *
2739 * Return: None
2740 */
2741inline void cds_pkt_stats_to_logger_thread(void *pl_hdr, void *pkt_dump,
2742 void *data)
2743{
2744 if (cds_get_ring_log_level(RING_ID_PER_PACKET_STATS) !=
2745 WLAN_LOG_LEVEL_ACTIVE)
2746 return;
2747
2748 wlan_pkt_stats_to_logger_thread(pl_hdr, pkt_dump, data);
2749}
Nirav Shaheb017be2018-02-15 11:20:58 +05302750#endif
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -08002751
2752/**
2753 * cds_get_conparam() - Get the connection mode parameters
2754 *
2755 * Return the connection mode parameter set by insmod or set during statically
2756 * linked driver
2757 *
Jeff Johnson876c1a62017-12-12 10:43:07 -08002758 * Return: enum QDF_GLOBAL_MODE
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -08002759 */
Jeff Johnson876c1a62017-12-12 10:43:07 -08002760enum QDF_GLOBAL_MODE cds_get_conparam(void)
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -08002761{
Jeff Johnson876c1a62017-12-12 10:43:07 -08002762 enum QDF_GLOBAL_MODE con_mode;
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -08002763
2764 con_mode = hdd_get_conparam();
2765
2766 return con_mode;
2767}
Dustin Brown8d2d0f52017-04-03 17:02:08 -07002768
Rachit Kankaneb1035622018-01-24 18:41:35 +05302769#ifdef FEATURE_HTC_CREDIT_HISTORY
Dustin Brown8d2d0f52017-04-03 17:02:08 -07002770inline void
2771cds_print_htc_credit_history(uint32_t count, qdf_abstract_print *print,
2772 void *print_priv)
2773{
2774 htc_print_credit_history(gp_cds_context->htc_ctx, count,
2775 print, print_priv);
2776}
2777#endif
Sravan Kumar Kairamc1ae71c2017-02-24 12:27:27 +05302778
2779/**
2780 * cds_get_arp_stats_gw_ip() - get arp stats track IP
2781 *
2782 * Return: ARP stats IP to track
2783 */
2784uint32_t cds_get_arp_stats_gw_ip(void)
2785{
2786 struct hdd_context *hdd_ctx;
2787
2788 hdd_ctx = (struct hdd_context *) (gp_cds_context->pHDDContext);
2789 if (!hdd_ctx) {
2790 cds_err("Hdd Context is Null");
2791 return 0;
2792 }
2793
2794 return hdd_ctx->track_arp_ip;
2795}
2796
2797/**
2798 * cds_incr_arp_stats_tx_tgt_delivered() - increment ARP stats
2799 *
2800 * Return: none
2801 */
2802void cds_incr_arp_stats_tx_tgt_delivered(void)
2803{
2804 struct hdd_context *hdd_ctx;
2805 struct hdd_adapter *adapter = NULL;
2806
2807 hdd_ctx = (struct hdd_context *) (gp_cds_context->pHDDContext);
2808 if (!hdd_ctx) {
2809 cds_err("Hdd Context is Null");
2810 return;
2811 }
2812
2813 hdd_for_each_adapter(hdd_ctx, adapter) {
2814 if (QDF_STA_MODE == adapter->device_mode)
2815 break;
2816 }
2817
2818 if (adapter)
2819 adapter->hdd_stats.hdd_arp_stats.tx_host_fw_sent++;
2820}
2821
2822/**
2823 * cds_incr_arp_stats_tx_tgt_acked() - increment ARP stats
2824 *
2825 * Return: none
2826 */
2827void cds_incr_arp_stats_tx_tgt_acked(void)
2828{
2829 struct hdd_context *hdd_ctx;
2830 struct hdd_adapter *adapter = NULL;
2831
2832 hdd_ctx = (struct hdd_context *) (gp_cds_context->pHDDContext);
2833 if (!hdd_ctx) {
2834 cds_err("Hdd Context is Null");
2835 return;
2836 }
2837
2838 hdd_for_each_adapter(hdd_ctx, adapter) {
2839 if (QDF_STA_MODE == adapter->device_mode)
2840 break;
2841 }
2842
2843 if (adapter)
2844 adapter->hdd_stats.hdd_arp_stats.tx_ack_cnt++;
2845}
Himanshu Agarwaledf30dc2017-06-05 15:54:27 +05302846
2847#ifdef ENABLE_SMMU_S1_TRANSLATION
2848void cds_smmu_mem_map_setup(qdf_device_t osdev)
2849{
2850 int attr = 0;
2851 struct dma_iommu_mapping *mapping = pld_smmu_get_mapping(osdev->dev);
2852
2853 osdev->smmu_s1_enabled = false;
2854 if (!mapping) {
2855 cds_info("No SMMU mapping present");
2856 return;
2857 }
2858
2859 if ((iommu_domain_get_attr(mapping->domain,
2860 DOMAIN_ATTR_S1_BYPASS, &attr) == 0) &&
2861 !attr)
2862 osdev->smmu_s1_enabled = true;
2863}
2864
2865int cds_smmu_map_unmap(bool map, uint32_t num_buf, qdf_mem_info_t *buf_arr)
2866{
2867 return hdd_ipa_uc_smmu_map(map, num_buf, buf_arr);
2868}
2869#else
2870void cds_smmu_mem_map_setup(qdf_device_t osdev)
2871{
2872}
2873
2874int cds_smmu_map_unmap(bool map, uint32_t num_buf, qdf_mem_info_t *buf_arr)
2875{
2876 return 0;
2877}
2878#endif