blob: 3517a4fa44ea1054f1ee223be35f863b660bb4fa [file] [log] [blame]
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001/*
Rajeev Kumar08ef0d62016-12-28 21:26:55 -08002 * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003 *
4 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
5 *
6 *
7 * Permission to use, copy, modify, and/or distribute this software for
8 * any purpose with or without fee is hereby granted, provided that the
9 * above copyright notice and this permission notice appear in all
10 * copies.
11 *
12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
13 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
14 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
15 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
16 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
17 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
18 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
19 * PERFORMANCE OF THIS SOFTWARE.
20 */
21
22/*
23 * This file was originally distributed by Qualcomm Atheros, Inc.
24 * under proprietary terms before Copyright ownership was assigned
25 * to the Linux Foundation.
26 */
27
28/**
29 * DOC: cds_api.c
30 *
31 * Connectivity driver services APIs
32 */
33
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080034#include "cds_sched.h"
35#include <cds_api.h>
36#include "sir_types.h"
37#include "sir_api.h"
38#include "sir_mac_prot_def.h"
39#include "sme_api.h"
40#include "mac_init_api.h"
41#include "wlan_qct_sys.h"
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080042#include "i_cds_packet.h"
43#include "cds_reg_service.h"
44#include "wma_types.h"
45#include "wlan_hdd_main.h"
Yu Wang66a250b2017-07-19 11:46:40 +080046#include "wlan_hdd_tsf.h"
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080047#include <linux/vmalloc.h>
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080048
Yuanyuan Liu0e0aa932016-05-12 10:17:58 -070049#include "pld_common.h"
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080050#include "sap_api.h"
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +053051#include "qdf_trace.h"
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080052#include "bmi.h"
53#include "ol_fw.h"
54#include "ol_if_athvar.h"
55#include "hif.h"
Tushnim Bhattacharyya12b48742017-03-13 12:46:45 -070056#include "wlan_policy_mgr_api.h"
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080057#include "cds_utils.h"
58#include "wlan_logging_sock_svc.h"
59#include "wma.h"
Nirav Shah7f337db2016-05-25 10:49:02 +053060#include "pktlog_ac.h"
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080061#include "wlan_hdd_ipa.h"
Pramod Simha0d3b9362017-03-27 14:59:58 -070062#include "wlan_policy_mgr_api.h"
Leo Chang9b097032016-10-28 11:03:17 -070063
64#include <cdp_txrx_cmn_reg.h>
65#include <cdp_txrx_cfg.h>
66#include <cdp_txrx_misc.h>
Rajeev Kumar97767a02016-11-30 11:20:40 -080067#include <dispatcher_init_deinit.h>
Venkata Sharath Chandra Manchala0d44d452016-11-23 17:48:15 -080068#include <cdp_txrx_handle.h>
69
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080070/* Preprocessor Definitions and Constants */
71
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080072/* Data definitions */
73static cds_context_type g_cds_context;
74static p_cds_contextType gp_cds_context;
Anurag Chouhandf2b2682016-02-29 14:15:27 +053075static struct __qdf_device g_qdf_ctx;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080076
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080077static uint8_t cds_multicast_logging;
78
Leo Chang9b097032016-10-28 11:03:17 -070079static struct ol_if_ops dp_ol_if_ops = {
80 .peer_set_default_routing = wma_peer_set_default_routing,
81 .peer_rx_reorder_queue_setup = wma_peer_rx_reorder_queue_setup,
82 .peer_rx_reorder_queue_remove = wma_peer_rx_reorder_queue_remove,
Dhanashri Atref5e02122017-04-13 15:36:42 -070083 .is_hw_dbs_2x2_capable = policy_mgr_is_hw_dbs_2x2_capable,
84 .lro_hash_config = wma_lro_config_cmd
Leo Chang9b097032016-10-28 11:03:17 -070085 /* TODO: Add any other control path calls required to OL_IF/WMA layer */
86};
87
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080088void cds_sys_probe_thread_cback(void *pUserData);
Srinivas Girigowda161b9f22017-07-24 17:38:09 -070089static void cds_trigger_recovery_work(void *param);
90
91/**
92 * cds_recovery_work_init() - Initialize recovery work queue
93 *
94 * Return: none
95 */
96static QDF_STATUS cds_recovery_work_init(void)
97{
98 qdf_create_work(0, &gp_cds_context->cds_recovery_work,
99 cds_trigger_recovery_work, NULL);
100 gp_cds_context->cds_recovery_wq =
101 qdf_create_workqueue("cds_recovery_workqueue");
102 if (NULL == gp_cds_context->cds_recovery_wq) {
103 cds_err("Failed to create cds_recovery_workqueue");
104 return QDF_STATUS_E_FAILURE;
105 }
106
107 return QDF_STATUS_SUCCESS;
108}
109
110/**
111 * cds_recovery_work_deinit() - Initialize recovery work queue
112 *
113 * Return: none
114 */
115static void cds_recovery_work_deinit(void)
116{
117 if (gp_cds_context->cds_recovery_wq) {
118 qdf_flush_workqueue(0, gp_cds_context->cds_recovery_wq);
119 qdf_destroy_workqueue(0, gp_cds_context->cds_recovery_wq);
120 }
121}
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800122
Venkata Sharath Chandra Manchala83985632017-02-28 14:16:22 -0800123/** cds_get_datapath_handles - Initialize pdev, vdev and soc
124 * @soc - soc handle
125 * @vdev - virtual handle
126 * @pdev - physical handle
127 */
128uint8_t cds_get_datapath_handles(void **soc, struct cdp_pdev **pdev,
129 struct cdp_vdev **vdev, uint8_t sessionId)
130{
131
132 (*soc) = cds_get_context(QDF_MODULE_ID_SOC);
133
134 if (!(*soc)) {
135 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
136 "soc handle is invalid");
137 return -EINVAL;
138 }
139
140 (*pdev) = cds_get_context(QDF_MODULE_ID_TXRX);
141
142 if (!(*pdev)) {
143 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
144 "pdev handle is invalid");
145 return -EINVAL;
146 }
147
148 (*vdev) = cdp_get_vdev_from_vdev_id((*soc), (*pdev),
149 sessionId);
150
151 if (!(*vdev)) {
152 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
153 "vdev handle is invalid");
154 return -EINVAL;
155 }
156 return 0;
157}
158
159
Jeff Johnson7aaeeea2017-09-26 13:16:24 -0700160QDF_STATUS cds_init(void)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800161{
Mahesh Kumar Kalikot Veetil319dbcd2016-10-27 15:03:48 -0700162 qdf_debugfs_init();
Houston Hoffman1a777572017-01-13 12:43:48 -0800163 qdf_lock_stats_init();
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530164 qdf_mem_init();
Houston Hoffman9e06e542016-12-12 12:06:26 -0800165 qdf_mc_timer_manager_init();
Dustin Brown100201e2017-07-10 11:48:40 -0700166 qdf_register_self_recovery_callback(cds_trigger_recovery);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800167
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800168 gp_cds_context = &g_cds_context;
169
Anurag Chouhandf2b2682016-02-29 14:15:27 +0530170 gp_cds_context->qdf_ctx = &g_qdf_ctx;
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530171 qdf_mem_zero(&g_qdf_ctx, sizeof(g_qdf_ctx));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800172
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530173 qdf_trace_spin_lock_init();
Prashanth Bhatta5da711e2015-11-30 14:28:52 -0800174
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800175#if defined(TRACE_RECORD)
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530176 qdf_trace_init();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800177#endif
Padma, Santhosh Kumar9aba02f2016-08-11 16:30:25 +0530178 qdf_register_debugcb_init();
Prashanth Bhatta5da711e2015-11-30 14:28:52 -0800179
180 cds_ssr_protect_init();
181
Srinivas Girigowda161b9f22017-07-24 17:38:09 -0700182 cds_recovery_work_init();
183
Jeff Johnson7aaeeea2017-09-26 13:16:24 -0700184 return gp_cds_context ? QDF_STATUS_SUCCESS : QDF_STATUS_E_FAILURE;
Prashanth Bhatta5da711e2015-11-30 14:28:52 -0800185}
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800186
187/**
Prashanth Bhatta5da711e2015-11-30 14:28:52 -0800188 * cds_deinit() - Deinitialize CDS
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800189 *
Prashanth Bhatta5da711e2015-11-30 14:28:52 -0800190 * This function frees the CDS resources
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800191 */
Prashanth Bhatta5da711e2015-11-30 14:28:52 -0800192void cds_deinit(void)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800193{
Prashanth Bhatta5da711e2015-11-30 14:28:52 -0800194 if (gp_cds_context == NULL)
195 return;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800196
Srinivas Girigowda161b9f22017-07-24 17:38:09 -0700197 cds_recovery_work_deinit();
Arunk Khandavalli4cc97a92016-09-14 23:13:07 +0530198 qdf_mc_timer_manager_exit();
199 qdf_mem_exit();
Houston Hoffman1a777572017-01-13 12:43:48 -0800200 qdf_lock_stats_deinit();
Mahesh Kumar Kalikot Veetil319dbcd2016-10-27 15:03:48 -0700201 qdf_debugfs_exit();
Arunk Khandavalli4cc97a92016-09-14 23:13:07 +0530202
Anurag Chouhan6d760662016-02-20 16:05:43 +0530203 gp_cds_context->qdf_ctx = NULL;
Prashanth Bhatta5da711e2015-11-30 14:28:52 -0800204 gp_cds_context = NULL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800205
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530206 qdf_mem_zero(&g_cds_context, sizeof(g_cds_context));
Prashanth Bhatta5da711e2015-11-30 14:28:52 -0800207 return;
208}
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800209
Abhishek Singh437606a2016-04-27 13:51:49 +0530210#ifdef FEATURE_WLAN_DIAG_SUPPORT
211/**
212 * cds_tdls_tx_rx_mgmt_event()- send tdls mgmt rx tx event
213 * @event_id: event id
214 * @tx_rx: tx or rx
215 * @type: type of frame
216 * @action_sub_type: action frame type
217 * @peer_mac: peer mac
218 *
219 * This Function sends tdls mgmt rx tx diag event
220 *
221 * Return: void.
222 */
223void cds_tdls_tx_rx_mgmt_event(uint8_t event_id, uint8_t tx_rx,
224 uint8_t type, uint8_t action_sub_type, uint8_t *peer_mac)
225{
226 WLAN_HOST_DIAG_EVENT_DEF(tdls_tx_rx_mgmt,
227 struct host_event_tdls_tx_rx_mgmt);
228
229 tdls_tx_rx_mgmt.event_id = event_id;
230 tdls_tx_rx_mgmt.tx_rx = tx_rx;
231 tdls_tx_rx_mgmt.type = type;
232 tdls_tx_rx_mgmt.action_sub_type = action_sub_type;
233 qdf_mem_copy(tdls_tx_rx_mgmt.peer_mac,
234 peer_mac, CDS_MAC_ADDRESS_LEN);
235 WLAN_HOST_DIAG_EVENT_REPORT(&tdls_tx_rx_mgmt,
236 EVENT_WLAN_TDLS_TX_RX_MGMT);
237}
238#endif
239
Leo Chang9b097032016-10-28 11:03:17 -0700240/**
gbian62edd7e2017-03-07 13:12:13 +0800241 * cds_cfg_update_ac_specs_params() - update ac_specs params
242 * @olcfg: cfg handle
243 * @mac_params: mac params
244 *
245 * Return: none
246 */
247static void
248cds_cfg_update_ac_specs_params(struct txrx_pdev_cfg_param_t *olcfg,
249 struct cds_config_info *cds_cfg)
250{
251 int i;
252
253 if (NULL == olcfg)
254 return;
255
256 if (NULL == cds_cfg)
257 return;
258
259 for (i = 0; i < OL_TX_NUM_WMM_AC; i++) {
260 olcfg->ac_specs[i].wrr_skip_weight =
261 cds_cfg->ac_specs[i].wrr_skip_weight;
262 olcfg->ac_specs[i].credit_threshold =
263 cds_cfg->ac_specs[i].credit_threshold;
264 olcfg->ac_specs[i].send_limit =
265 cds_cfg->ac_specs[i].send_limit;
266 olcfg->ac_specs[i].credit_reserve =
267 cds_cfg->ac_specs[i].credit_reserve;
268 olcfg->ac_specs[i].discard_weight =
269 cds_cfg->ac_specs[i].discard_weight;
270 }
271}
272
273/**
Leo Chang9b097032016-10-28 11:03:17 -0700274 * cds_cdp_cfg_attach() - attach data path config module
275 * @cds_cfg: generic platform level config instance
276 *
277 * Return: none
278 */
279static void cds_cdp_cfg_attach(struct cds_config_info *cds_cfg)
280{
281 struct txrx_pdev_cfg_param_t cdp_cfg = {0};
282 void *soc = cds_get_context(QDF_MODULE_ID_SOC);
283
Kiran Kumar Lokere52d8dc32016-12-05 19:20:40 -0800284 cdp_cfg.is_full_reorder_offload = cds_cfg->reorder_offload;
Leo Chang9b097032016-10-28 11:03:17 -0700285 cdp_cfg.is_uc_offload_enabled = cds_cfg->uc_offload_enabled;
286 cdp_cfg.uc_tx_buffer_count = cds_cfg->uc_txbuf_count;
287 cdp_cfg.uc_tx_buffer_size = cds_cfg->uc_txbuf_size;
288 cdp_cfg.uc_rx_indication_ring_count = cds_cfg->uc_rxind_ringcount;
289 cdp_cfg.uc_tx_partition_base = cds_cfg->uc_tx_partition_base;
290 cdp_cfg.enable_rxthread = cds_cfg->enable_rxthread;
291 cdp_cfg.ip_tcp_udp_checksum_offload =
292 cds_cfg->ip_tcp_udp_checksum_offload;
293 cdp_cfg.ce_classify_enabled = cds_cfg->ce_classify_enabled;
294
gbian62edd7e2017-03-07 13:12:13 +0800295 cds_cfg_update_ac_specs_params(&cdp_cfg, cds_cfg);
Kiran Kumar Lokere9aecfee2016-11-23 17:37:42 -0800296 gp_cds_context->cfg_ctx = cdp_cfg_attach(soc, gp_cds_context->qdf_ctx,
297 (void *)(&cdp_cfg));
298 if (!gp_cds_context->cfg_ctx) {
299 WMA_LOGP("%s: failed to init cfg handle", __func__);
300 return;
301 }
302
Leo Chang9b097032016-10-28 11:03:17 -0700303 /* Configure Receive flow steering */
Venkata Sharath Chandra Manchala0d44d452016-11-23 17:48:15 -0800304 cdp_cfg_set_flow_steering(soc, gp_cds_context->cfg_ctx,
Leo Chang9b097032016-10-28 11:03:17 -0700305 cds_cfg->flow_steering_enabled);
306
Venkata Sharath Chandra Manchala0d44d452016-11-23 17:48:15 -0800307 cdp_cfg_set_flow_control_parameters(soc, gp_cds_context->cfg_ctx,
308 (void *)&cdp_cfg);
Leo Chang9b097032016-10-28 11:03:17 -0700309
310 /* adjust the cfg_ctx default value based on setting */
311 cdp_cfg_set_rx_fwd_disabled(soc, gp_cds_context->cfg_ctx,
312 (uint8_t) cds_cfg->ap_disable_intrabss_fwd);
313
314 /*
315 * adjust the packet log enable default value
316 * based on CFG INI setting
317 */
318 cdp_cfg_set_packet_log_enabled(soc, gp_cds_context->cfg_ctx,
319 (uint8_t)cds_is_packet_log_enabled());
Yu Wang66a250b2017-07-19 11:46:40 +0800320
321 /* adjust the ptp rx option default value based on CFG INI setting */
322 cdp_cfg_set_ptp_rx_opt_enabled(soc, gp_cds_context->cfg_ctx,
323 (uint8_t)cds_is_ptp_rx_opt_enabled());
Leo Chang9b097032016-10-28 11:03:17 -0700324}
Krunal Sonid32c6bc2016-10-18 18:00:21 -0700325static QDF_STATUS cds_register_all_modules(void)
326{
327 QDF_STATUS status;
328
329 scheduler_register_wma_legacy_handler(&wma_mc_process_handler);
330 scheduler_register_sys_legacy_handler(&sys_mc_process_handler);
331
332 /* Register message queues in given order such that queue priority is
333 * intact:
334 * 1) QDF_MODULE_ID_SYS: Timer queue(legacy SYS queue)
335 * 2) QDF_MODULE_ID_TARGET_IF: Target interface queue
336 * 3) QDF_MODULE_ID_PE: Legacy PE message queue
337 * 4) QDF_MODULE_ID_SME: Legacy SME message queue
338 * 5) QDF_MODULE_ID_OS_IF: OS IF message queue for new components
339 */
340 status = scheduler_register_module(QDF_MODULE_ID_SYS,
341 &scheduler_timer_q_mq_handler);
342 status = scheduler_register_module(QDF_MODULE_ID_TARGET_IF,
343 &scheduler_target_if_mq_handler);
344 status = scheduler_register_module(QDF_MODULE_ID_PE,
345 &pe_mc_process_handler);
346 status = scheduler_register_module(QDF_MODULE_ID_SME,
347 &sme_mc_process_handler);
348 status = scheduler_register_module(QDF_MODULE_ID_OS_IF,
349 &scheduler_os_if_mq_handler);
350 return status;
351}
352
353static QDF_STATUS cds_deregister_all_modules(void)
354{
355 QDF_STATUS status;
Krunal Sonie3399902017-02-01 09:51:42 -0800356
357 scheduler_deregister_wma_legacy_handler();
358 scheduler_deregister_sys_legacy_handler();
Krunal Sonid32c6bc2016-10-18 18:00:21 -0700359 status = scheduler_deregister_module(QDF_MODULE_ID_SYS);
Rajeev Kumara88b2dc2017-01-30 16:35:14 -0800360 status = scheduler_deregister_module(QDF_MODULE_ID_TARGET_IF);
Krunal Sonid32c6bc2016-10-18 18:00:21 -0700361 status = scheduler_deregister_module(QDF_MODULE_ID_PE);
362 status = scheduler_deregister_module(QDF_MODULE_ID_SME);
363 status = scheduler_deregister_module(QDF_MODULE_ID_OS_IF);
Krunal Sonie3399902017-02-01 09:51:42 -0800364
Krunal Sonid32c6bc2016-10-18 18:00:21 -0700365 return status;
366}
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800367
368/**
gbian62edd7e2017-03-07 13:12:13 +0800369 * cds_set_ac_specs_params() - set ac_specs params in cds_config_info
370 * @cds_cfg: Pointer to cds_config_info
371 * @hdd_ctx: Pointer to hdd context
372 *
373 * Return: none
374 */
375static void
376cds_set_ac_specs_params(struct cds_config_info *cds_cfg)
377{
378 int i;
379 cds_context_type *cds_ctx;
380
381 if (NULL == cds_cfg)
382 return;
383
384 cds_ctx = cds_get_context(QDF_MODULE_ID_QDF);
385
386 if (!cds_ctx) {
387 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
388 "Invalid CDS Context");
389 return;
390 }
391
392 for (i = 0; i < OL_TX_NUM_WMM_AC; i++) {
393 cds_cfg->ac_specs[i] = cds_ctx->ac_specs[i];
394 }
395}
396
397/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800398 * cds_open() - open the CDS Module
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800399 *
400 * cds_open() function opens the CDS Scheduler
401 * Upon successful initialization:
402 * - All CDS submodules should have been initialized
403 *
404 * - The CDS scheduler should have opened
405 *
406 * - All the WLAN SW components should have been opened. This includes
407 * SYS, MAC, SME, WMA and TL.
408 *
Anurag Chouhanf04e84f2016-03-03 10:12:12 +0530409 * Return: QDF status
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800410 */
Selvaraj, Sridhar0672a122016-12-29 16:11:48 +0530411QDF_STATUS cds_open(struct wlan_objmgr_psoc *psoc)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800412{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530413 QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800414 tSirRetStatus sirStatus = eSIR_SUCCESS;
Arun Khandavallic811dcc2016-06-26 07:37:21 +0530415 struct cds_config_info *cds_cfg;
Anurag Chouhan6d760662016-02-20 16:05:43 +0530416 qdf_device_t qdf_ctx;
Manikandan Mohan83c939c2017-04-13 20:23:07 -0700417 struct htc_init_info htcInfo;
Komal Seelamd9106492016-02-15 10:31:44 +0530418 struct ol_context *ol_ctx;
Komal Seelam3d202862016-02-24 18:43:24 +0530419 struct hif_opaque_softc *scn;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800420 void *HTCHandle;
Jeff Johnsonc18b26c2017-09-03 08:46:45 -0700421 struct hdd_context *hdd_ctx;
Arun Khandavallic811dcc2016-06-26 07:37:21 +0530422 cds_context_type *cds_ctx;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800423
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530424 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_INFO_HIGH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800425 "%s: Opening CDS", __func__);
426
Arun Khandavallic811dcc2016-06-26 07:37:21 +0530427 cds_ctx = cds_get_context(QDF_MODULE_ID_QDF);
428 if (!cds_ctx) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530429 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_FATAL,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800430 "%s: Trying to open CDS without a PreOpen", __func__);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530431 QDF_ASSERT(0);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530432 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800433 }
434
435 /* Initialize the timer module */
Anurag Chouhan210db072016-02-22 18:42:15 +0530436 qdf_timer_module_init();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800437
438 /* Initialize bug reporting structure */
439 cds_init_log_completion();
440
441 /* Initialize the probe event */
Anurag Chouhance0dc992016-02-16 18:18:03 +0530442 if (qdf_event_create(&gp_cds_context->ProbeEvent) != QDF_STATUS_SUCCESS) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530443 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_FATAL,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800444 "%s: Unable to init probeEvent", __func__);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530445 QDF_ASSERT(0);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530446 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800447 }
Anurag Chouhance0dc992016-02-16 18:18:03 +0530448 if (qdf_event_create(&(gp_cds_context->wmaCompleteEvent)) !=
449 QDF_STATUS_SUCCESS) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530450 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_FATAL,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800451 "%s: Unable to init wmaCompleteEvent", __func__);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530452 QDF_ASSERT(0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800453 goto err_probe_event;
454 }
455
Jeff Johnsonc18b26c2017-09-03 08:46:45 -0700456 hdd_ctx = (struct hdd_context *) (gp_cds_context->pHDDContext);
457 if ((NULL == hdd_ctx) || (NULL == hdd_ctx->config)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800458 /* Critical Error ... Cannot proceed further */
Arun Khandavallifae92942016-08-01 13:31:08 +0530459 cds_err("Hdd Context is Null");
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530460 QDF_ASSERT(0);
Rajeev Kumar3e5ef0d2017-01-03 14:45:31 -0800461 goto err_wma_complete_event;
Arun Khandavallifae92942016-08-01 13:31:08 +0530462 }
Kabilan Kannan15cc6ac2016-11-12 22:25:14 -0800463
Arun Khandavallifae92942016-08-01 13:31:08 +0530464 /* Now Open the CDS Scheduler */
465
Jeff Johnsonc18b26c2017-09-03 08:46:45 -0700466 if (hdd_ctx->driver_status == DRIVER_MODULES_UNINITIALIZED ||
Prashanth Bhatta2ac92bd2016-10-11 16:08:00 -0700467 cds_is_driver_recovering()) {
Arun Khandavallifae92942016-08-01 13:31:08 +0530468 qdf_status = cds_sched_open(gp_cds_context,
469 &gp_cds_context->qdf_sched,
470 sizeof(cds_sched_context));
471
472 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
473 /* Critical Error ... Cannot proceed further */
474 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_FATAL,
475 "%s: Failed to open CDS Scheduler", __func__);
476 QDF_ASSERT(0);
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -0800477 goto err_wma_complete_event;
Arun Khandavallifae92942016-08-01 13:31:08 +0530478 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800479 }
480
Anurag Chouhan6d760662016-02-20 16:05:43 +0530481 scn = cds_get_context(QDF_MODULE_ID_HIF);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800482 if (!scn) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530483 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_FATAL,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800484 "%s: scn is null!", __func__);
485 goto err_sched_close;
486 }
Arun Khandavallifae92942016-08-01 13:31:08 +0530487
Arun Khandavallifae92942016-08-01 13:31:08 +0530488 cds_cfg = cds_get_ini_config();
489 if (!cds_cfg) {
490 cds_err("Cds config is NULL");
491 QDF_ASSERT(0);
492 goto err_sched_close;
493 }
Jeff Johnsonc18b26c2017-09-03 08:46:45 -0700494 hdd_enable_fastpath(hdd_ctx->config, scn);
495 hdd_wlan_update_target_info(hdd_ctx, scn);
Arun Khandavallifae92942016-08-01 13:31:08 +0530496
Anurag Chouhan6d760662016-02-20 16:05:43 +0530497 ol_ctx = cds_get_context(QDF_MODULE_ID_BMI);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800498 /* Initialize BMI and Download firmware */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530499 qdf_status = bmi_download_firmware(ol_ctx);
500 if (qdf_status != QDF_STATUS_SUCCESS) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530501 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_FATAL,
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530502 "BMI FIALED status:%d", qdf_status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800503 goto err_bmi_close;
504 }
Komal Seelam08633492016-02-24 18:05:07 +0530505 htcInfo.pContext = ol_ctx;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800506 htcInfo.TargetFailure = ol_target_failure;
Mukul Sharma4c60a7e2017-03-06 19:42:18 +0530507 htcInfo.TargetSendSuspendComplete =
508 pmo_ucfg_psoc_target_suspend_acknowledge;
509 htcInfo.target_initial_wakeup_cb = pmo_ucfg_psoc_handle_initial_wake_up;
510 htcInfo.target_psoc = (void *)psoc;
Anurag Chouhan6d760662016-02-20 16:05:43 +0530511 qdf_ctx = cds_get_context(QDF_MODULE_ID_QDF_DEVICE);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800512
513 /* Create HTC */
514 gp_cds_context->htc_ctx =
Yue Ma1e11d792016-02-26 18:58:44 -0800515 htc_create(scn, &htcInfo, qdf_ctx, cds_get_conparam());
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800516 if (!gp_cds_context->htc_ctx) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530517 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_FATAL,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800518 "%s: Failed to Create HTC", __func__);
519 goto err_bmi_close;
520 }
Mukul Sharma4c60a7e2017-03-06 19:42:18 +0530521 pmo_ucfg_psoc_update_htc_handle(psoc, (void *)gp_cds_context->htc_ctx);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800522
Komal Seelamd9106492016-02-15 10:31:44 +0530523 if (bmi_done(ol_ctx)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530524 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_FATAL,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800525 "%s: Failed to complete BMI phase", __func__);
526 goto err_htc_close;
527 }
528
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800529 /*Open the WMA module */
Jeff Johnsonff6addf2017-09-13 10:06:03 -0700530 qdf_status = wma_open(psoc, hdd_update_tgt_cfg, cds_cfg);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800531
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530532 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800533 /* Critical Error ... Cannot proceed further */
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530534 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_FATAL,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800535 "%s: Failed to open WMA module", __func__);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530536 QDF_ASSERT(0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800537 goto err_htc_close;
538 }
539
540 /* Number of peers limit differs in each chip version. If peer max
541 * limit configured in ini exceeds more than supported, WMA adjusts
Arun Khandavallic811dcc2016-06-26 07:37:21 +0530542 * and keeps correct limit in cds_cfg.max_station. So, make sure
Jeff Johnsonc18b26c2017-09-03 08:46:45 -0700543 * config entry hdd_ctx->config->maxNumberOfPeers has adjusted value
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800544 */
Hanumanth Reddy Pothula47d29262016-10-03 16:08:04 +0530545 /* In FTM mode cds_cfg->max_stations will be zero. On updating same
546 * into hdd context config entry, leads to pe_open() to fail, if
547 * con_mode change happens from FTM mode to any other mode.
548 */
Srinivas Girigowda35b00312017-06-27 21:52:03 -0700549 if (QDF_DRIVER_TYPE_PRODUCTION == cds_cfg->driver_type)
Jeff Johnsonc18b26c2017-09-03 08:46:45 -0700550 hdd_ctx->config->maxNumberOfPeers = cds_cfg->max_station;
Hanumanth Reddy Pothula47d29262016-10-03 16:08:04 +0530551
Anurag Chouhan6d760662016-02-20 16:05:43 +0530552 HTCHandle = cds_get_context(QDF_MODULE_ID_HTC);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800553 if (!HTCHandle) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530554 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_FATAL,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800555 "%s: HTCHandle is null!", __func__);
556 goto err_wma_close;
557 }
Nachiket Kukadef44b33e2017-09-06 16:49:29 +0530558
559 qdf_status = htc_wait_target(HTCHandle);
560 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowdabafb8b72017-10-11 17:52:32 -0700561 cds_alert("Complete BMI phase failed. status: %d", qdf_status);
Nachiket Kukade8003d252017-03-30 15:55:58 +0530562
Nachiket Kukadef44b33e2017-09-06 16:49:29 +0530563 if (qdf_status != QDF_STATUS_E_NOMEM
564 && !cds_is_fw_down())
Nachiket Kukade8003d252017-03-30 15:55:58 +0530565 QDF_BUG(0);
566
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800567 goto err_wma_close;
568 }
Poddar, Siddarthef1f3022016-05-10 20:10:43 +0530569 bmi_target_ready(scn, gp_cds_context->cfg_ctx);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800570
Ravi Joshifc2ed782016-11-22 17:36:50 -0800571 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_DEBUG,
572 "%s: target_type %d 8074:%d 6290:%d",
Jeff Johnsonc18b26c2017-09-03 08:46:45 -0700573 __func__, hdd_ctx->target_type,
Ravi Joshifc2ed782016-11-22 17:36:50 -0800574 TARGET_TYPE_QCA8074, TARGET_TYPE_QCA6290);
575
Jeff Johnsonc18b26c2017-09-03 08:46:45 -0700576 if (TARGET_TYPE_QCA6290 == hdd_ctx->target_type)
Leo Chang9b097032016-10-28 11:03:17 -0700577 gp_cds_context->dp_soc = cdp_soc_attach(LITHIUM_DP,
578 gp_cds_context->pHIFContext, scn,
579 gp_cds_context->htc_ctx, gp_cds_context->qdf_ctx,
Pramod Simha0d3b9362017-03-27 14:59:58 -0700580 &dp_ol_if_ops, psoc);
Leo Chang9b097032016-10-28 11:03:17 -0700581 else
582 gp_cds_context->dp_soc = cdp_soc_attach(MOB_DRV_LEGACY_DP,
583 gp_cds_context->pHIFContext, scn,
584 gp_cds_context->htc_ctx, gp_cds_context->qdf_ctx,
Pramod Simha0d3b9362017-03-27 14:59:58 -0700585 &dp_ol_if_ops, psoc);
Leo Chang9b097032016-10-28 11:03:17 -0700586
Manikandan Mohanfb9d2b52017-05-10 15:01:28 -0700587 if (!gp_cds_context->dp_soc)
588 goto err_wma_close;
589
Sravan Kumar Kairam27296782017-04-21 22:04:18 +0530590 pmo_ucfg_psoc_update_dp_handle(psoc, gp_cds_context->dp_soc);
591
Houston Hoffman59c9c912017-03-29 14:10:39 -0700592 if (gp_cds_context->dp_soc == NULL)
593 goto err_wma_close;
594
gbian62edd7e2017-03-07 13:12:13 +0800595 cds_set_ac_specs_params(cds_cfg);
596
Leo Chang9b097032016-10-28 11:03:17 -0700597 cds_cdp_cfg_attach(cds_cfg);
598
Jeff Johnsond9f08602016-12-02 11:31:30 -0800599 /* Now proceed to open the MAC */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800600 sirStatus =
Selvaraj, Sridhar0672a122016-12-29 16:11:48 +0530601 mac_open(psoc, &(gp_cds_context->pMACContext),
Arun Khandavallic811dcc2016-06-26 07:37:21 +0530602 gp_cds_context->pHDDContext, cds_cfg);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800603
604 if (eSIR_SUCCESS != sirStatus) {
605 /* Critical Error ... Cannot proceed further */
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530606 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_FATAL,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800607 "%s: Failed to open MAC", __func__);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530608 QDF_ASSERT(0);
Houston Hoffman59c9c912017-03-29 14:10:39 -0700609 goto err_soc_detach;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800610 }
611
612 /* Now proceed to open the SME */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530613 qdf_status = sme_open(gp_cds_context->pMACContext);
614 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800615 /* Critical Error ... Cannot proceed further */
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530616 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_FATAL,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800617 "%s: Failed to open SME", __func__);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530618 QDF_ASSERT(0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800619 goto err_mac_close;
620 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800621
Krunal Sonid32c6bc2016-10-18 18:00:21 -0700622 cds_register_all_modules();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800623
Selvaraj, Sridhara7dc2382017-01-27 18:29:39 +0530624 return dispatcher_psoc_open(psoc);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800625
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800626err_mac_close:
627 mac_close(gp_cds_context->pMACContext);
628
Houston Hoffman59c9c912017-03-29 14:10:39 -0700629err_soc_detach:
630 /* todo: add propper error handling */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800631err_wma_close:
Rajeev Kumar662d75d2017-03-13 18:11:29 -0700632 cds_shutdown_notifier_purge();
Jeff Johnson542da352017-09-13 09:17:28 -0700633 wma_close();
Jeff Johnson7b3ddc22017-09-13 09:42:44 -0700634 wma_wmi_service_close();
Sravan Kumar Kairam27296782017-04-21 22:04:18 +0530635 pmo_ucfg_psoc_update_dp_handle(psoc, NULL);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800636
637err_htc_close:
638 if (gp_cds_context->htc_ctx) {
639 htc_destroy(gp_cds_context->htc_ctx);
640 gp_cds_context->htc_ctx = NULL;
Sravan Kumar Kairam27296782017-04-21 22:04:18 +0530641 pmo_ucfg_psoc_update_htc_handle(psoc, NULL);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800642 }
643
644err_bmi_close:
Komal Seelam5a6e5082016-02-24 17:59:09 +0530645 bmi_cleanup(ol_ctx);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800646
647err_sched_close:
Dustin Brown46a15a32017-10-19 16:21:22 -0700648 if (hdd_ctx->driver_status == DRIVER_MODULES_UNINITIALIZED ||
649 cds_is_driver_recovering()) {
650 if (QDF_IS_STATUS_ERROR(cds_sched_close())) {
651 cds_err("Failed to close CDS Scheduler");
Hanumanth Reddy Pothula0b571432017-02-23 17:15:37 +0530652 QDF_ASSERT(false);
653 }
654 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800655
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800656err_wma_complete_event:
Anurag Chouhance0dc992016-02-16 18:18:03 +0530657 qdf_event_destroy(&gp_cds_context->wmaCompleteEvent);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800658
659err_probe_event:
Anurag Chouhance0dc992016-02-16 18:18:03 +0530660 qdf_event_destroy(&gp_cds_context->ProbeEvent);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800661
Srinivas Girigowdabafb8b72017-10-11 17:52:32 -0700662 return qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800663} /* cds_open() */
664
Venkata Sharath Chandra Manchala4aaae0f2017-07-10 11:59:19 -0700665QDF_STATUS cds_dp_open(struct wlan_objmgr_psoc *psoc)
666{
667 if (cdp_txrx_intr_attach(gp_cds_context->dp_soc)
668 != QDF_STATUS_SUCCESS) {
669 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_FATAL,
670 "%s: Failed to attach interrupts", __func__);
671 goto close;
672 }
673
674 cds_set_context(QDF_MODULE_ID_TXRX,
675 cdp_pdev_attach(cds_get_context(QDF_MODULE_ID_SOC),
676 gp_cds_context->cfg_ctx,
677 gp_cds_context->htc_ctx,
678 gp_cds_context->qdf_ctx, 0));
679 if (!gp_cds_context->pdev_txrx_ctx) {
680 /* Critical Error ... Cannot proceed further */
681 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_FATAL,
682 "%s: Failed to open TXRX", __func__);
683 QDF_ASSERT(0);
684 goto intr_close;
685 }
686
687 pmo_ucfg_psoc_set_txrx_handle(psoc, gp_cds_context->pdev_txrx_ctx);
688
689 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_INFO_HIGH,
690 "%s: CDS successfully Opened", __func__);
691
692 return 0;
693
694intr_close:
695 cdp_txrx_intr_detach(gp_cds_context->dp_soc);
696close:
697 return QDF_STATUS_E_FAILURE;
698}
699
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800700/**
701 * cds_pre_enable() - pre enable cds
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800702 *
Anurag Chouhanf04e84f2016-03-03 10:12:12 +0530703 * Return: QDF status
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800704 */
Jeff Johnson3a280122017-09-13 07:42:00 -0700705QDF_STATUS cds_pre_enable(void)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800706{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530707 QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800708 void *scn;
Jeff Johnson3a280122017-09-13 07:42:00 -0700709 void *soc;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800710
Srinivas Girigowdad395b892017-03-09 19:29:42 -0800711 QDF_TRACE(QDF_MODULE_ID_SYS, QDF_TRACE_LEVEL_DEBUG, "cds prestart");
Jeff Johnson3a280122017-09-13 07:42:00 -0700712
713 if (!gp_cds_context) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530714 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Jeff Johnson3a280122017-09-13 07:42:00 -0700715 "%s: NULL CDS context", __func__);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530716 QDF_ASSERT(0);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530717 return QDF_STATUS_E_INVAL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800718 }
719
Jeff Johnson3a280122017-09-13 07:42:00 -0700720 if (gp_cds_context->pMACContext == NULL) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530721 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800722 "%s: MAC NULL context", __func__);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530723 QDF_ASSERT(0);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530724 return QDF_STATUS_E_INVAL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800725 }
726
Jeff Johnson3a280122017-09-13 07:42:00 -0700727 if (gp_cds_context->pWMAContext == NULL) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530728 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800729 "%s: WMA NULL context", __func__);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530730 QDF_ASSERT(0);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530731 return QDF_STATUS_E_INVAL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800732 }
733
Anurag Chouhan6d760662016-02-20 16:05:43 +0530734 scn = cds_get_context(QDF_MODULE_ID_HIF);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800735 if (!scn) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530736 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_FATAL,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800737 "%s: scn is null!", __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530738 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800739 }
740
Jeff Johnson3a280122017-09-13 07:42:00 -0700741 soc = cds_get_context(QDF_MODULE_ID_SOC);
742 if (!soc) {
743 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_FATAL,
744 "%s: soc is null!", __func__);
745 return QDF_STATUS_E_FAILURE;
746 }
747
Nirav Shah7f337db2016-05-25 10:49:02 +0530748 /* call Packetlog connect service */
Arun Khandavallifae92942016-08-01 13:31:08 +0530749 if (QDF_GLOBAL_FTM_MODE != cds_get_conparam() &&
Leo Chang9b097032016-10-28 11:03:17 -0700750 QDF_GLOBAL_EPPING_MODE != cds_get_conparam())
751 cdp_pkt_log_con_service(soc,
Venkata Sharath Chandra Manchala0d44d452016-11-23 17:48:15 -0800752 gp_cds_context->pdev_txrx_ctx,
753 scn);
Nirav Shah7f337db2016-05-25 10:49:02 +0530754
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800755 /* Reset wma wait event */
Anurag Chouhance0dc992016-02-16 18:18:03 +0530756 qdf_event_reset(&gp_cds_context->wmaCompleteEvent);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800757
758 /*call WMA pre start */
Jeff Johnson8ad89c62017-09-13 08:55:55 -0700759 qdf_status = wma_pre_start();
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530760 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530761 QDF_TRACE(QDF_MODULE_ID_SYS, QDF_TRACE_LEVEL_FATAL,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800762 "Failed to WMA prestart");
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530763 QDF_ASSERT(0);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530764 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800765 }
766
767 /* Need to update time out of complete */
Anurag Chouhance0dc992016-02-16 18:18:03 +0530768 qdf_status = qdf_wait_single_event(&gp_cds_context->wmaCompleteEvent,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800769 CDS_WMA_TIMEOUT);
Anurag Chouhance0dc992016-02-16 18:18:03 +0530770 if (qdf_status != QDF_STATUS_SUCCESS) {
771 if (qdf_status == QDF_STATUS_E_TIMEOUT) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530772 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800773 "%s: Timeout occurred before WMA complete",
774 __func__);
775 } else {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530776 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800777 "%s: wma_pre_start reporting other error",
778 __func__);
779 }
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530780 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800781 "%s: Test MC thread by posting a probe message to SYS",
782 __func__);
783 wlan_sys_probe();
784
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530785 QDF_ASSERT(0);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530786 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800787 }
788
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530789 qdf_status = htc_start(gp_cds_context->htc_ctx);
790 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530791 QDF_TRACE(QDF_MODULE_ID_SYS, QDF_TRACE_LEVEL_FATAL,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800792 "Failed to Start HTC");
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530793 QDF_ASSERT(0);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530794 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800795 }
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530796 qdf_status = wma_wait_for_ready_event(gp_cds_context->pWMAContext);
797 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530798 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_FATAL,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800799 "Failed to get ready event from target firmware");
Nachiket Kukade8003d252017-03-30 15:55:58 +0530800
Naveen Rawat91df30a2016-10-12 21:26:18 -0700801 /*
Nachiket Kukade8003d252017-03-30 15:55:58 +0530802 * Panic when the failure is not because the FW is down,
803 * fail gracefully if FW is down allowing re-probing from
804 * from the platform driver
Naveen Rawat91df30a2016-10-12 21:26:18 -0700805 */
Nachiket Kukade8003d252017-03-30 15:55:58 +0530806 if (!cds_is_fw_down())
Naveen Rawat91df30a2016-10-12 21:26:18 -0700807 QDF_BUG(0);
808
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800809 htc_stop(gp_cds_context->htc_ctx);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530810 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800811 }
812
Leo Chang9b097032016-10-28 11:03:17 -0700813 if (cdp_pdev_post_attach(soc, gp_cds_context->pdev_txrx_ctx)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530814 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_FATAL,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800815 "Failed to attach pdev");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800816 htc_stop(gp_cds_context->htc_ctx);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530817 QDF_ASSERT(0);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530818 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800819 }
820
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530821 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800822}
823
824/**
825 * cds_enable() - start/enable cds module
Selvaraj, Sridhar0672a122016-12-29 16:11:48 +0530826 * @psoc: Psoc pointer
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800827 * @cds_context: CDS context
828 *
Anurag Chouhanf04e84f2016-03-03 10:12:12 +0530829 * Return: QDF status
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800830 */
Jeff Johnson8f9dd5f2017-09-13 14:16:08 -0700831QDF_STATUS cds_enable(struct wlan_objmgr_psoc *psoc)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800832{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530833 QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800834 tSirRetStatus sirStatus = eSIR_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800835 tHalMacStartParameters halStartParams;
836
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800837 /* We support only one instance for now ... */
Jeff Johnson8f9dd5f2017-09-13 14:16:08 -0700838 if (!gp_cds_context) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530839 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Jeff Johnson8f9dd5f2017-09-13 14:16:08 -0700840 "%s: Invalid CDS context", __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530841 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800842 }
843
Jeff Johnson8f9dd5f2017-09-13 14:16:08 -0700844 if ((gp_cds_context->pWMAContext == NULL) ||
845 (gp_cds_context->pMACContext == NULL)) {
846 if (gp_cds_context->pWMAContext == NULL)
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530847 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800848 "%s: WMA NULL context", __func__);
849 else
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530850 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800851 "%s: MAC NULL context", __func__);
852
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530853 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800854 }
855
856 /* Start the wma */
Jeff Johnsond4892552017-09-13 08:41:31 -0700857 qdf_status = wma_start();
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530858 if (qdf_status != QDF_STATUS_SUCCESS) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530859 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800860 "%s: Failed to start wma", __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530861 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800862 }
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530863 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_INFO,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800864 "%s: wma correctly started", __func__);
865
866 /* Start the MAC */
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530867 qdf_mem_zero(&halStartParams,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800868 sizeof(tHalMacStartParameters));
869
870 /* Start the MAC */
871 sirStatus =
Jeff Johnson8f9dd5f2017-09-13 14:16:08 -0700872 mac_start(gp_cds_context->pMACContext, &halStartParams);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800873
874 if (eSIR_SUCCESS != sirStatus) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530875 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_FATAL,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800876 "%s: Failed to start MAC", __func__);
877 goto err_wma_stop;
878 }
879
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530880 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_INFO,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800881 "%s: MAC correctly started", __func__);
882
883 /* START SME */
Jeff Johnson8f9dd5f2017-09-13 14:16:08 -0700884 qdf_status = sme_start(gp_cds_context->pMACContext);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800885
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530886 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530887 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_FATAL,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800888 "%s: Failed to start SME", __func__);
889 goto err_mac_stop;
890 }
891
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530892 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_INFO,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800893 "%s: SME correctly started", __func__);
894
Leo Chang9b097032016-10-28 11:03:17 -0700895 if (cdp_soc_attach_target(cds_get_context(QDF_MODULE_ID_SOC))) {
896 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_FATAL,
897 "%s: Failed to attach soc target", __func__);
898 goto err_sme_stop;
899 }
900
901 if (cdp_pdev_attach_target(cds_get_context(QDF_MODULE_ID_SOC),
Venkata Sharath Chandra Manchala0d44d452016-11-23 17:48:15 -0800902 (struct cdp_pdev *)cds_get_context(QDF_MODULE_ID_TXRX))) {
Leo Chang9b097032016-10-28 11:03:17 -0700903 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_FATAL,
904 "%s: Failed to attach pdev target", __func__);
905 goto err_soc_target_detach;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800906 }
907
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530908 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_INFO,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800909 "%s: CDS Start is successful!!", __func__);
910
Selvaraj, Sridhar0672a122016-12-29 16:11:48 +0530911 dispatcher_psoc_enable(psoc);
Rajeev Kumar97767a02016-11-30 11:20:40 -0800912
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530913 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800914
Leo Chang9b097032016-10-28 11:03:17 -0700915err_soc_target_detach:
916 /* NOOP */
917
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800918err_sme_stop:
Jeff Johnson8f9dd5f2017-09-13 14:16:08 -0700919 sme_stop(gp_cds_context->pMACContext, HAL_STOP_TYPE_SYS_RESET);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800920
921err_mac_stop:
Jeff Johnson8f9dd5f2017-09-13 14:16:08 -0700922 mac_stop(gp_cds_context->pMACContext, HAL_STOP_TYPE_SYS_RESET);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800923
924err_wma_stop:
Anurag Chouhance0dc992016-02-16 18:18:03 +0530925 qdf_event_reset(&(gp_cds_context->wmaCompleteEvent));
Jeff Johnsonacc1cc72017-09-13 08:47:49 -0700926 qdf_status = wma_stop(HAL_STOP_TYPE_RF_KILL);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530927 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530928 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800929 "%s: Failed to stop wma", __func__);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530930 QDF_ASSERT(QDF_IS_STATUS_SUCCESS(qdf_status));
Jeff Johnson1f8d0a02017-09-13 08:09:05 -0700931 wma_setneedshutdown();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800932 } else {
Anurag Chouhance0dc992016-02-16 18:18:03 +0530933 qdf_status =
934 qdf_wait_single_event(&(gp_cds_context->wmaCompleteEvent),
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800935 CDS_WMA_TIMEOUT);
Anurag Chouhance0dc992016-02-16 18:18:03 +0530936 if (qdf_status != QDF_STATUS_SUCCESS) {
937 if (qdf_status == QDF_STATUS_E_TIMEOUT) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530938 QDF_TRACE(QDF_MODULE_ID_QDF,
939 QDF_TRACE_LEVEL_FATAL,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800940 "%s: Timeout occurred before WMA_stop complete",
941 __func__);
942 } else {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530943 QDF_TRACE(QDF_MODULE_ID_QDF,
944 QDF_TRACE_LEVEL_FATAL,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800945 "%s: WMA_stop reporting other error",
946 __func__);
947 }
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530948 QDF_ASSERT(0);
Jeff Johnson1f8d0a02017-09-13 08:09:05 -0700949 wma_setneedshutdown();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800950 }
951 }
952
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530953 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800954} /* cds_enable() */
955
956/**
957 * cds_disable() - stop/disable cds module
Selvaraj, Sridhar0672a122016-12-29 16:11:48 +0530958 * @psoc: Psoc pointer
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800959 *
Anurag Chouhanf04e84f2016-03-03 10:12:12 +0530960 * Return: QDF status
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800961 */
Jeff Johnsonea5c2aa12017-09-13 14:18:59 -0700962QDF_STATUS cds_disable(struct wlan_objmgr_psoc *psoc)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800963{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530964 QDF_STATUS qdf_status;
Arun Khandavallifae92942016-08-01 13:31:08 +0530965 void *handle;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800966
Rajeev Kumar97767a02016-11-30 11:20:40 -0800967 /* PSOC disable for all new components. It needs to happen before
968 * target is PDEV suspended such that a component can abort all its
969 * ongoing transaction with FW. Always keep it before wma_stop() as
970 * wma_stop() does target PDEV suspend.
971 */
Rajeev Kumar97767a02016-11-30 11:20:40 -0800972
Selvaraj, Sridhar0672a122016-12-29 16:11:48 +0530973 dispatcher_psoc_disable(psoc);
Rajeev Kumar97767a02016-11-30 11:20:40 -0800974
Jeff Johnsonacc1cc72017-09-13 08:47:49 -0700975 qdf_status = wma_stop(HAL_STOP_TYPE_RF_KILL);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800976
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530977 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Arun Khandavallifae92942016-08-01 13:31:08 +0530978 cds_err("Failed to stop wma");
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530979 QDF_ASSERT(QDF_IS_STATUS_SUCCESS(qdf_status));
Jeff Johnson1f8d0a02017-09-13 08:09:05 -0700980 wma_setneedshutdown();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800981 }
982
Arun Khandavallifae92942016-08-01 13:31:08 +0530983 handle = cds_get_context(QDF_MODULE_ID_PE);
984 if (!handle) {
985 cds_err("Invalid PE context return!");
986 return QDF_STATUS_E_INVAL;
987 }
988 qdf_status = sme_stop(handle, HAL_STOP_TYPE_SYS_DEEP_SLEEP);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530989 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Arun Khandavallifae92942016-08-01 13:31:08 +0530990 cds_err("Failed to stop SME: %d", qdf_status);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530991 QDF_ASSERT(QDF_IS_STATUS_SUCCESS(qdf_status));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800992 }
Arun Khandavallifae92942016-08-01 13:31:08 +0530993 qdf_status = mac_stop(handle, HAL_STOP_TYPE_SYS_DEEP_SLEEP);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800994
Arun Khandavallifae92942016-08-01 13:31:08 +0530995 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
996 cds_err("Failed to stop MAC");
997 QDF_ASSERT(QDF_IS_STATUS_SUCCESS(qdf_status));
998 }
Arun Khandavalli55f890b2016-08-31 18:14:56 +0530999
Arun Khandavallifae92942016-08-01 13:31:08 +05301000 return qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001001}
1002
Govind Singhb048e872016-09-27 22:07:43 +05301003#ifdef HIF_USB
1004static inline void cds_suspend_target(tp_wma_handle wma_handle)
1005{
1006 QDF_STATUS status;
1007 /* Suspend the target and disable interrupt */
Mukul Sharma4c60a7e2017-03-06 19:42:18 +05301008 status = pmo_ucfg_psoc_suspend_target(wma_handle->psoc, 0);
Govind Singhb048e872016-09-27 22:07:43 +05301009 if (status)
1010 cds_err("Failed to suspend target, status = %d", status);
1011}
1012#else
1013static inline void cds_suspend_target(tp_wma_handle wma_handle)
1014{
1015 QDF_STATUS status;
1016 /* Suspend the target and disable interrupt */
Mukul Sharma4c60a7e2017-03-06 19:42:18 +05301017 status = pmo_ucfg_psoc_suspend_target(wma_handle->psoc, 1);
Govind Singhb048e872016-09-27 22:07:43 +05301018 if (status)
1019 cds_err("Failed to suspend target, status = %d", status);
1020}
1021#endif /* HIF_USB */
1022
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001023/**
Govind Singhb048e872016-09-27 22:07:43 +05301024 * cds_post_disable() - post disable cds module
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001025 *
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05301026 * Return: QDF status
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001027 */
Rajeev Kumarbe021242017-02-16 16:12:23 -08001028QDF_STATUS cds_post_disable(void)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001029{
Arun Khandavalli55f890b2016-08-31 18:14:56 +05301030 tp_wma_handle wma_handle;
Govind Singhb048e872016-09-27 22:07:43 +05301031 struct hif_opaque_softc *hif_ctx;
Himanshu Agarwal0b9bbc32017-02-23 16:23:05 +05301032 struct cdp_pdev *txrx_pdev;
1033
Arun Khandavalli55f890b2016-08-31 18:14:56 +05301034 wma_handle = cds_get_context(QDF_MODULE_ID_WMA);
1035 if (!wma_handle) {
1036 cds_err("Failed to get wma_handle!");
1037 return QDF_STATUS_E_INVAL;
1038 }
1039
Govind Singhb048e872016-09-27 22:07:43 +05301040 hif_ctx = cds_get_context(QDF_MODULE_ID_HIF);
1041 if (!hif_ctx) {
1042 cds_err("Failed to get hif_handle!");
1043 return QDF_STATUS_E_INVAL;
1044 }
1045
Himanshu Agarwal0b9bbc32017-02-23 16:23:05 +05301046 txrx_pdev = cds_get_context(QDF_MODULE_ID_TXRX);
1047 if (!txrx_pdev) {
1048 cds_err("Failed to get txrx pdev!");
1049 return QDF_STATUS_E_INVAL;
1050 }
1051
Arun Khandavalli55f890b2016-08-31 18:14:56 +05301052 /*
1053 * With new state machine changes cds_close can be invoked without
1054 * cds_disable. So, send the following clean up prerequisites to fw,
1055 * So Fw and host are in sync for cleanup indication:
1056 * - Send PDEV_SUSPEND indication to firmware
1057 * - Disable HIF Interrupts.
1058 * - Clean up CE tasklets.
1059 */
1060
Hanumanth Reddy Pothula2a8a7402017-07-03 14:06:11 +05301061 cds_info("send deinit sequence to firmware");
1062 if (!(cds_is_driver_recovering() || cds_is_driver_in_bad_state()))
Govind Singhb048e872016-09-27 22:07:43 +05301063 cds_suspend_target(wma_handle);
1064 hif_disable_isr(hif_ctx);
1065 hif_reset_soc(hif_ctx);
1066
Wu Gao9a24fa72017-07-28 18:32:22 +08001067 if (gp_cds_context->htc_ctx) {
1068 htc_stop(gp_cds_context->htc_ctx);
1069 }
1070
Himanshu Agarwal0b9bbc32017-02-23 16:23:05 +05301071 cdp_pdev_pre_detach(cds_get_context(QDF_MODULE_ID_SOC),
1072 (struct cdp_pdev *)txrx_pdev, 1);
1073
Govind Singhb048e872016-09-27 22:07:43 +05301074 return QDF_STATUS_SUCCESS;
1075}
1076
1077/**
1078 * cds_close() - close cds module
Selvaraj, Sridhar0672a122016-12-29 16:11:48 +05301079 * @psoc: Psoc pointer
Govind Singhb048e872016-09-27 22:07:43 +05301080 *
1081 * This API allows user to close modules registered
1082 * with connectivity device services.
1083 *
1084 * Return: QDF status
1085 */
Jeff Johnsone4b14592017-09-13 14:23:33 -07001086QDF_STATUS cds_close(struct wlan_objmgr_psoc *psoc)
Govind Singhb048e872016-09-27 22:07:43 +05301087{
1088 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001089
Amar Singhal966397f2017-04-06 18:28:56 -07001090 dispatcher_psoc_close(psoc);
1091
Jeff Johnson6b8473d2017-09-13 09:20:53 -07001092 qdf_status = wma_wmi_work_close();
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301093 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301094 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Xun Luoa858a472015-11-10 08:24:45 -08001095 "%s: Failed to close wma_wmi_work", __func__);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301096 QDF_ASSERT(0);
Xun Luoa858a472015-11-10 08:24:45 -08001097 }
1098
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001099 if (gp_cds_context->htc_ctx) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001100 htc_destroy(gp_cds_context->htc_ctx);
Mukul Sharma4c60a7e2017-03-06 19:42:18 +05301101 pmo_ucfg_psoc_update_htc_handle(psoc, NULL);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001102 gp_cds_context->htc_ctx = NULL;
1103 }
1104
Jeff Johnsone4b14592017-09-13 14:23:33 -07001105 qdf_status = sme_close(gp_cds_context->pMACContext);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301106 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301107 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001108 "%s: Failed to close SME", __func__);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301109 QDF_ASSERT(QDF_IS_STATUS_SUCCESS(qdf_status));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001110 }
1111
Jeff Johnsone4b14592017-09-13 14:23:33 -07001112 qdf_status = mac_close(gp_cds_context->pMACContext);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301113 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301114 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001115 "%s: Failed to close MAC", __func__);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301116 QDF_ASSERT(QDF_IS_STATUS_SUCCESS(qdf_status));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001117 }
1118
Jeff Johnsone4b14592017-09-13 14:23:33 -07001119 gp_cds_context->pMACContext = NULL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001120
Houston Hoffmanbe58cc52016-12-19 16:26:44 -08001121 cdp_soc_detach(gp_cds_context->dp_soc);
Sravan Kumar Kairam27296782017-04-21 22:04:18 +05301122 pmo_ucfg_psoc_update_dp_handle(psoc, NULL);
Houston Hoffmanbe58cc52016-12-19 16:26:44 -08001123
Rajeev Kumar662d75d2017-03-13 18:11:29 -07001124 cds_shutdown_notifier_purge();
1125
Jeff Johnson1b5404e2017-09-13 08:04:46 -07001126 if (true == wma_needshutdown()) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301127 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001128 "%s: Failed to shutdown wma", __func__);
1129 } else {
Jeff Johnson542da352017-09-13 09:17:28 -07001130 qdf_status = wma_close();
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301131 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301132 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001133 "%s: Failed to close wma", __func__);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301134 QDF_ASSERT(QDF_IS_STATUS_SUCCESS(qdf_status));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001135 }
1136 }
1137
Jeff Johnson7b3ddc22017-09-13 09:42:44 -07001138 qdf_status = wma_wmi_service_close();
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301139 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301140 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001141 "%s: Failed to close wma_wmi_service", __func__);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301142 QDF_ASSERT(QDF_IS_STATUS_SUCCESS(qdf_status));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001143 }
1144
Anurag Chouhance0dc992016-02-16 18:18:03 +05301145 qdf_status = qdf_event_destroy(&gp_cds_context->wmaCompleteEvent);
1146 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301147 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001148 "%s: failed to destroy wmaCompleteEvent", __func__);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301149 QDF_ASSERT(QDF_IS_STATUS_SUCCESS(qdf_status));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001150 }
1151
Anurag Chouhance0dc992016-02-16 18:18:03 +05301152 qdf_status = qdf_event_destroy(&gp_cds_context->ProbeEvent);
1153 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301154 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001155 "%s: failed to destroy ProbeEvent", __func__);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301156 QDF_ASSERT(QDF_IS_STATUS_SUCCESS(qdf_status));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001157 }
1158
Arun Khandavallic811dcc2016-06-26 07:37:21 +05301159 cds_deinit_ini_config();
Arun Khandavallifae92942016-08-01 13:31:08 +05301160 qdf_timer_module_deinit();
1161
Krunal Sonid32c6bc2016-10-18 18:00:21 -07001162 cds_deregister_all_modules();
Rajeev Kumar97767a02016-11-30 11:20:40 -08001163
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301164 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001165}
1166
Venkata Sharath Chandra Manchala4aaae0f2017-07-10 11:59:19 -07001167QDF_STATUS cds_dp_close(struct wlan_objmgr_psoc *psoc)
1168{
1169 void *ctx;
1170
1171 cdp_txrx_intr_detach(gp_cds_context->dp_soc);
1172
1173 ctx = cds_get_context(QDF_MODULE_ID_TXRX);
1174 cds_set_context(QDF_MODULE_ID_TXRX, NULL);
1175 pmo_ucfg_psoc_set_txrx_handle(psoc, NULL);
1176 cdp_pdev_detach(cds_get_context(QDF_MODULE_ID_SOC),
1177 (struct cdp_pdev *)ctx, 1);
1178
1179 return QDF_STATUS_SUCCESS;
1180}
1181
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001182/**
1183 * cds_get_context() - get context data area
1184 *
1185 * @moduleId: ID of the module who's context data is being retrived.
1186 *
1187 * Each module in the system has a context / data area that is allocated
1188 * and managed by CDS. This API allows any user to get a pointer to its
1189 * allocated context data area from the CDS global context.
1190 *
1191 * Return: pointer to the context data area of the module ID
1192 * specified, or NULL if the context data is not allocated for
1193 * the module ID specified
1194 */
Anurag Chouhan6d760662016-02-20 16:05:43 +05301195void *cds_get_context(QDF_MODULE_ID moduleId)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001196{
1197 void *pModContext = NULL;
1198
1199 if (gp_cds_context == NULL) {
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: cds context pointer is null", __func__);
1202 return NULL;
1203 }
1204
1205 switch (moduleId) {
Anurag Chouhan6d760662016-02-20 16:05:43 +05301206 case QDF_MODULE_ID_HDD:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001207 {
1208 pModContext = gp_cds_context->pHDDContext;
1209 break;
1210 }
1211
Anurag Chouhan6d760662016-02-20 16:05:43 +05301212 case QDF_MODULE_ID_SME:
1213 case QDF_MODULE_ID_PE:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001214 {
1215 /* In all these cases, we just return the MAC Context */
1216 pModContext = gp_cds_context->pMACContext;
1217 break;
1218 }
1219
Anurag Chouhan6d760662016-02-20 16:05:43 +05301220 case QDF_MODULE_ID_WMA:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001221 {
1222 /* For wma module */
1223 pModContext = gp_cds_context->pWMAContext;
1224 break;
1225 }
1226
Anurag Chouhan6d760662016-02-20 16:05:43 +05301227 case QDF_MODULE_ID_QDF:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001228 {
1229 /* For SYS this is CDS itself */
1230 pModContext = gp_cds_context;
1231 break;
1232 }
1233
Anurag Chouhan6d760662016-02-20 16:05:43 +05301234 case QDF_MODULE_ID_HIF:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001235 {
1236 pModContext = gp_cds_context->pHIFContext;
1237 break;
1238 }
1239
Anurag Chouhan6d760662016-02-20 16:05:43 +05301240 case QDF_MODULE_ID_HTC:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001241 {
1242 pModContext = gp_cds_context->htc_ctx;
1243 break;
1244 }
1245
Anurag Chouhan6d760662016-02-20 16:05:43 +05301246 case QDF_MODULE_ID_QDF_DEVICE:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001247 {
Anurag Chouhan6d760662016-02-20 16:05:43 +05301248 pModContext = gp_cds_context->qdf_ctx;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001249 break;
1250 }
1251
Anurag Chouhan6d760662016-02-20 16:05:43 +05301252 case QDF_MODULE_ID_BMI:
Komal Seelamd9106492016-02-15 10:31:44 +05301253 {
1254 pModContext = gp_cds_context->g_ol_context;
1255 break;
1256 }
1257
Anurag Chouhan6d760662016-02-20 16:05:43 +05301258 case QDF_MODULE_ID_TXRX:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001259 {
Venkata Sharath Chandra Manchala0d44d452016-11-23 17:48:15 -08001260 pModContext = (void *)gp_cds_context->pdev_txrx_ctx;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001261 break;
1262 }
1263
Anurag Chouhan6d760662016-02-20 16:05:43 +05301264 case QDF_MODULE_ID_CFG:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001265 {
1266 pModContext = gp_cds_context->cfg_ctx;
1267 break;
1268 }
1269
Leo Chang9b097032016-10-28 11:03:17 -07001270 case QDF_MODULE_ID_SOC:
1271 {
1272 pModContext = gp_cds_context->dp_soc;
1273 break;
1274 }
1275
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001276 default:
1277 {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301278 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001279 "%s: Module ID %i does not have its context maintained by CDS",
1280 __func__, moduleId);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301281 QDF_ASSERT(0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001282 return NULL;
1283 }
1284 }
1285
1286 if (pModContext == NULL) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301287 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001288 "%s: Module ID %i context is Null", __func__,
1289 moduleId);
1290 }
1291
1292 return pModContext;
1293} /* cds_get_context() */
1294
1295/**
1296 * cds_get_global_context() - get CDS global Context
1297 *
1298 * This API allows any user to get the CDS Global Context pointer from a
1299 * module context data area.
1300 *
1301 * Return: pointer to the CDS global context, NULL if the function is
1302 * unable to retreive the CDS context.
1303 */
Jeff Johnson31a67582017-09-26 14:54:28 -07001304void *cds_get_global_context(void)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001305{
1306 if (gp_cds_context == NULL) {
Ryan Hsuceddceb2016-04-28 10:20:14 -07001307 /*
1308 * To avoid recursive call, this should not change to
1309 * QDF_TRACE().
1310 */
1311 pr_err("%s: global cds context is NULL", __func__);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001312 }
1313
1314 return gp_cds_context;
1315} /* cds_get_global_context() */
1316
1317/**
Prashanth Bhatta9e143052015-12-04 11:56:47 -08001318 * cds_get_driver_state() - Get current driver state
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001319 *
Prashanth Bhatta9e143052015-12-04 11:56:47 -08001320 * This API returns current driver state stored in global context.
1321 *
1322 * Return: Driver state enum
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001323 */
Prashanth Bhatta9e143052015-12-04 11:56:47 -08001324enum cds_driver_state cds_get_driver_state(void)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001325{
1326 if (gp_cds_context == NULL) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301327 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001328 "%s: global cds context is NULL", __func__);
Prashanth Bhatta9e143052015-12-04 11:56:47 -08001329
1330 return CDS_DRIVER_STATE_UNINITIALIZED;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001331 }
1332
Prashanth Bhatta9e143052015-12-04 11:56:47 -08001333 return gp_cds_context->driver_state;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001334}
1335
1336/**
Prashanth Bhatta9e143052015-12-04 11:56:47 -08001337 * cds_set_driver_state() - Set current driver state
1338 * @state: Driver state to be set to.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001339 *
Prashanth Bhatta9e143052015-12-04 11:56:47 -08001340 * This API sets driver state to state. This API only sets the state and doesn't
1341 * clear states, please make sure to use cds_clear_driver_state to clear any
1342 * state if required.
1343 *
1344 * Return: None
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001345 */
Prashanth Bhatta9e143052015-12-04 11:56:47 -08001346void cds_set_driver_state(enum cds_driver_state state)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001347{
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001348 if (gp_cds_context == NULL) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301349 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prashanth Bhatta9e143052015-12-04 11:56:47 -08001350 "%s: global cds context is NULL: %x", __func__,
1351 state);
1352
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001353 return;
1354 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001355
Prashanth Bhatta9e143052015-12-04 11:56:47 -08001356 gp_cds_context->driver_state |= state;
1357}
1358
1359/**
1360 * cds_clear_driver_state() - Clear current driver state
1361 * @state: Driver state to be cleared.
1362 *
1363 * This API clears driver state. This API only clears the state, please make
1364 * sure to use cds_set_driver_state to set any new states.
1365 *
1366 * Return: None
1367 */
1368void cds_clear_driver_state(enum cds_driver_state state)
1369{
1370 if (gp_cds_context == NULL) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301371 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prashanth Bhatta9e143052015-12-04 11:56:47 -08001372 "%s: global cds context is NULL: %x", __func__,
1373 state);
1374
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001375 return;
1376 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001377
Prashanth Bhatta9e143052015-12-04 11:56:47 -08001378 gp_cds_context->driver_state &= ~state;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001379}
1380
Nachiket Kukade8003d252017-03-30 15:55:58 +05301381enum cds_fw_state cds_get_fw_state(void)
1382{
1383 if (gp_cds_context == NULL) {
1384 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
1385 "%s: global cds context is NULL", __func__);
1386
1387 return CDS_FW_STATE_UNINITIALIZED;
1388 }
1389
1390 return gp_cds_context->fw_state;
1391}
1392
1393void cds_set_fw_state(enum cds_fw_state state)
1394{
1395 if (gp_cds_context == NULL) {
1396 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
1397 "%s: global cds context is NULL: %d", __func__,
1398 state);
1399
1400 return;
1401 }
1402
1403 qdf_atomic_set_bit(state, &gp_cds_context->fw_state);
1404}
1405
1406void cds_clear_fw_state(enum cds_fw_state state)
1407{
1408 if (gp_cds_context == NULL) {
1409 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
1410 "%s: global cds context is NULL: %d", __func__,
1411 state);
1412
1413 return;
1414 }
1415
1416 qdf_atomic_clear_bit(state, &gp_cds_context->fw_state);
1417}
1418
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001419/**
1420 * cds_alloc_context() - allocate a context within the CDS global Context
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001421 * @moduleId: module ID who's context area is being allocated.
1422 * @ppModuleContext: pointer to location where the pointer to the
1423 * allocated context is returned. Note this output pointer
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301424 * is valid only if the API returns QDF_STATUS_SUCCESS
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001425 * @param size: size of the context area to be allocated.
1426 *
1427 * This API allows any user to allocate a user context area within the
1428 * CDS Global Context.
1429 *
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05301430 * Return: QDF status
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001431 */
Jeff Johnsonadb3b1c2017-09-13 10:42:36 -07001432QDF_STATUS cds_alloc_context(QDF_MODULE_ID moduleID,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001433 void **ppModuleContext, uint32_t size)
1434{
1435 void **pGpModContext = NULL;
1436
Jeff Johnsonadb3b1c2017-09-13 10:42:36 -07001437 if (!gp_cds_context) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301438 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001439 "%s: cds context is null", __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301440 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001441 }
1442
Jeff Johnsonadb3b1c2017-09-13 10:42:36 -07001443 if (!ppModuleContext) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301444 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Jeff Johnsonadb3b1c2017-09-13 10:42:36 -07001445 "%s: null param passed",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001446 __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301447 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001448 }
1449
1450 switch (moduleID) {
Anurag Chouhan6d760662016-02-20 16:05:43 +05301451 case QDF_MODULE_ID_WMA:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001452 pGpModContext = &(gp_cds_context->pWMAContext);
1453 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001454
Anurag Chouhan6d760662016-02-20 16:05:43 +05301455 case QDF_MODULE_ID_HIF:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001456 pGpModContext = &(gp_cds_context->pHIFContext);
1457 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001458
Anurag Chouhan6d760662016-02-20 16:05:43 +05301459 case QDF_MODULE_ID_BMI:
Komal Seelamd9106492016-02-15 10:31:44 +05301460 pGpModContext = &(gp_cds_context->g_ol_context);
1461 break;
Komal Seelamd9106492016-02-15 10:31:44 +05301462
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001463 default:
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301464 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Jeff Johnsonadb3b1c2017-09-13 10:42:36 -07001465 "%s: Module ID %i does not have its context allocated by CDS",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001466 __func__, moduleID);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301467 QDF_ASSERT(0);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301468 return QDF_STATUS_E_INVAL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001469 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001470
Jeff Johnsonadb3b1c2017-09-13 10:42:36 -07001471 if (*pGpModContext) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001472 /* Context has already been allocated!
1473 * Prevent double allocation
1474 */
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301475 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001476 "%s: Module ID %i context has already been allocated",
1477 __func__, moduleID);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301478 return QDF_STATUS_E_EXISTS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001479 }
1480
1481 /* Dynamically allocate the context for module */
1482
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301483 *ppModuleContext = qdf_mem_malloc(size);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001484
Jeff Johnsonadb3b1c2017-09-13 10:42:36 -07001485 if (!*ppModuleContext) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301486 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Jeff Johnsonadb3b1c2017-09-13 10:42:36 -07001487 "%s: Failed to allocate Context for module ID %i",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001488 __func__, moduleID);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301489 QDF_ASSERT(0);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301490 return QDF_STATUS_E_NOMEM;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001491 }
1492
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001493 *pGpModContext = *ppModuleContext;
1494
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301495 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001496} /* cds_alloc_context() */
1497
1498/**
Komal Seelamad5a90d2016-02-16 13:50:03 +05301499 * cds_set_context() - API to set context in global CDS Context
Komal Seelam1aac1982016-03-02 15:57:26 +05301500 * @module_id: Module ID
Komal Seelamad5a90d2016-02-16 13:50:03 +05301501 * @context: Pointer to the Module Context
1502 *
Komal Seelam1aac1982016-03-02 15:57:26 +05301503 * API to set a MODULE Context in global CDS Context
Komal Seelamad5a90d2016-02-16 13:50:03 +05301504 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301505 * Return: QDF_STATUS
Komal Seelamad5a90d2016-02-16 13:50:03 +05301506 */
Anurag Chouhan6d760662016-02-20 16:05:43 +05301507QDF_STATUS cds_set_context(QDF_MODULE_ID module_id, void *context)
Komal Seelamad5a90d2016-02-16 13:50:03 +05301508{
1509 p_cds_contextType p_cds_context = cds_get_global_context();
1510
1511 if (!p_cds_context) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301512 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Komal Seelam1aac1982016-03-02 15:57:26 +05301513 "cds context is Invalid");
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301514 return QDF_STATUS_NOT_INITIALIZED;
Komal Seelamad5a90d2016-02-16 13:50:03 +05301515 }
1516
1517 switch (module_id) {
Jeff Johnson3543fb22017-09-24 13:44:13 -07001518 case QDF_MODULE_ID_HDD:
1519 p_cds_context->pHDDContext = context;
1520 break;
Houston Hoffman57c36d72017-01-30 12:47:02 -08001521 case QDF_MODULE_ID_TXRX:
1522 p_cds_context->pdev_txrx_ctx = context;
1523 break;
Anurag Chouhan6d760662016-02-20 16:05:43 +05301524 case QDF_MODULE_ID_HIF:
Komal Seelamad5a90d2016-02-16 13:50:03 +05301525 p_cds_context->pHIFContext = context;
1526 break;
1527 default:
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301528 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Komal Seelam1aac1982016-03-02 15:57:26 +05301529 "%s: Module ID %i does not have its context managed by CDS",
1530 __func__, module_id);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301531 QDF_ASSERT(0);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301532 return QDF_STATUS_E_INVAL;
Komal Seelamad5a90d2016-02-16 13:50:03 +05301533 }
1534
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301535 return QDF_STATUS_SUCCESS;
Komal Seelamad5a90d2016-02-16 13:50:03 +05301536}
1537
1538/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001539 * cds_free_context() - free an allocated context within the
1540 * CDS global Context
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001541 * @moduleId: module ID who's context area is being free
1542 * @pModuleContext: pointer to module context area to be free'd.
1543 *
1544 * This API allows a user to free the user context area within the
1545 * CDS Global Context.
1546 *
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05301547 * Return: QDF status
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001548 */
Jeff Johnsonadb3b1c2017-09-13 10:42:36 -07001549QDF_STATUS cds_free_context(QDF_MODULE_ID moduleID, void *pModuleContext)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001550{
1551 void **pGpModContext = NULL;
1552
Jeff Johnsonadb3b1c2017-09-13 10:42:36 -07001553 if (!gp_cds_context) {
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: cds context is null", __func__);
1556 return QDF_STATUS_E_FAILURE;
1557 }
1558
1559 if (!pModuleContext) {
1560 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
1561 "%s: Null param", __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301562 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001563 }
1564
1565 switch (moduleID) {
Anurag Chouhan6d760662016-02-20 16:05:43 +05301566 case QDF_MODULE_ID_WMA:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001567 pGpModContext = &(gp_cds_context->pWMAContext);
1568 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001569
Anurag Chouhan6d760662016-02-20 16:05:43 +05301570 case QDF_MODULE_ID_HIF:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001571 pGpModContext = &(gp_cds_context->pHIFContext);
1572 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001573
Anurag Chouhan6d760662016-02-20 16:05:43 +05301574 case QDF_MODULE_ID_TXRX:
Venkata Sharath Chandra Manchala0d44d452016-11-23 17:48:15 -08001575 pGpModContext = (void **)&(gp_cds_context->pdev_txrx_ctx);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001576 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001577
Anurag Chouhan6d760662016-02-20 16:05:43 +05301578 case QDF_MODULE_ID_BMI:
Komal Seelamd9106492016-02-15 10:31:44 +05301579 pGpModContext = &(gp_cds_context->g_ol_context);
1580 break;
Komal Seelamd9106492016-02-15 10:31:44 +05301581
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001582 default:
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301583 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001584 "%s: Module ID %i "
1585 "does not have its context allocated by CDS",
1586 __func__, moduleID);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301587 QDF_ASSERT(0);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301588 return QDF_STATUS_E_INVAL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001589 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001590
1591 if (NULL == *pGpModContext) {
1592 /* Context has not been allocated or freed already! */
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301593 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Jeff Johnsonadb3b1c2017-09-13 10:42:36 -07001594 "%s: Module ID %i context has not been allocated or freed already",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001595 __func__, moduleID);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301596 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001597 }
1598
1599 if (*pGpModContext != pModuleContext) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301600 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001601 "%s: pGpModContext != pModuleContext", __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301602 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001603 }
1604
Jeff Johnsonadb3b1c2017-09-13 10:42:36 -07001605 qdf_mem_free(pModuleContext);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001606
1607 *pGpModContext = NULL;
1608
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301609 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001610} /* cds_free_context() */
1611
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001612/**
1613 * cds_sys_probe_thread_cback() - probe mc thread callback
1614 * @pUserData: pointer to user data
1615 *
1616 * Return: none
1617 */
1618void cds_sys_probe_thread_cback(void *pUserData)
1619{
1620 if (gp_cds_context != pUserData) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301621 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001622 "%s: gp_cds_context != pUserData", __func__);
1623 return;
1624 }
1625
Anurag Chouhance0dc992016-02-16 18:18:03 +05301626 if (qdf_event_set(&gp_cds_context->ProbeEvent) != QDF_STATUS_SUCCESS) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301627 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Anurag Chouhance0dc992016-02-16 18:18:03 +05301628 "%s: qdf_event_set failed", __func__);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001629 return;
1630 }
1631} /* cds_sys_probe_thread_cback() */
1632
1633/**
1634 * cds_wma_complete_cback() - wma complete callback
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001635 *
1636 * Return: none
1637 */
Jeff Johnsonf7ab8142017-09-13 09:04:23 -07001638void cds_wma_complete_cback(void)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001639{
Jeff Johnsonf7ab8142017-09-13 09:04:23 -07001640 if (!gp_cds_context) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301641 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Jeff Johnsonf7ab8142017-09-13 09:04:23 -07001642 "%s: invalid gp_cds_context", __func__);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001643 return;
1644 }
1645
Anurag Chouhance0dc992016-02-16 18:18:03 +05301646 if (qdf_event_set(&gp_cds_context->wmaCompleteEvent) !=
1647 QDF_STATUS_SUCCESS) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301648 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Anurag Chouhance0dc992016-02-16 18:18:03 +05301649 "%s: qdf_event_set failed", __func__);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001650 return;
1651 }
1652} /* cds_wma_complete_cback() */
1653
1654/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001655 * cds_get_vdev_types() - get vdev type
1656 * @mode: mode
1657 * @type: type
1658 * @sub_type: sub_type
1659 *
1660 * Return: WMI vdev type
1661 */
Anurag Chouhan6d760662016-02-20 16:05:43 +05301662QDF_STATUS cds_get_vdev_types(enum tQDF_ADAPTER_MODE mode, uint32_t *type,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001663 uint32_t *sub_type)
1664{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301665 QDF_STATUS status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001666 *type = 0;
1667 *sub_type = 0;
1668
1669 switch (mode) {
Anurag Chouhan6d760662016-02-20 16:05:43 +05301670 case QDF_STA_MODE:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001671 *type = WMI_VDEV_TYPE_STA;
1672 break;
Anurag Chouhan6d760662016-02-20 16:05:43 +05301673 case QDF_SAP_MODE:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001674 *type = WMI_VDEV_TYPE_AP;
1675 break;
Anurag Chouhan6d760662016-02-20 16:05:43 +05301676 case QDF_P2P_DEVICE_MODE:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001677 *type = WMI_VDEV_TYPE_AP;
1678 *sub_type = WMI_UNIFIED_VDEV_SUBTYPE_P2P_DEVICE;
1679 break;
Anurag Chouhan6d760662016-02-20 16:05:43 +05301680 case QDF_P2P_CLIENT_MODE:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001681 *type = WMI_VDEV_TYPE_STA;
1682 *sub_type = WMI_UNIFIED_VDEV_SUBTYPE_P2P_CLIENT;
1683 break;
Anurag Chouhan6d760662016-02-20 16:05:43 +05301684 case QDF_P2P_GO_MODE:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001685 *type = WMI_VDEV_TYPE_AP;
1686 *sub_type = WMI_UNIFIED_VDEV_SUBTYPE_P2P_GO;
1687 break;
Anurag Chouhan6d760662016-02-20 16:05:43 +05301688 case QDF_OCB_MODE:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001689 *type = WMI_VDEV_TYPE_OCB;
1690 break;
Krunal Soni8c37e322016-02-03 16:08:37 -08001691 case QDF_IBSS_MODE:
1692 *type = WMI_VDEV_TYPE_IBSS;
1693 break;
Manjunathappa Prakashb7573722016-04-21 11:24:07 -07001694 case QDF_MONITOR_MODE:
1695 *type = WMI_VDEV_TYPE_MONITOR;
1696 break;
Deepak Dhamdheree2dd5442016-05-27 15:05:51 -07001697 case QDF_NDI_MODE:
1698 *type = WMI_VDEV_TYPE_NDI;
1699 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001700 default:
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301701 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Ryan Hsud7e6fc72015-12-07 17:26:14 -08001702 "Invalid device mode %d", mode);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301703 status = QDF_STATUS_E_INVAL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001704 break;
1705 }
1706 return status;
1707}
1708
1709/**
1710 * cds_flush_work() - flush pending works
1711 * @work: pointer to work
1712 *
1713 * Return: none
1714 */
1715void cds_flush_work(void *work)
1716{
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001717 cancel_work_sync(work);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001718}
1719
1720/**
1721 * cds_flush_delayed_work() - flush delayed works
1722 * @dwork: pointer to delayed work
1723 *
1724 * Return: none
1725 */
1726void cds_flush_delayed_work(void *dwork)
1727{
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001728 cancel_delayed_work_sync(dwork);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001729}
1730
1731/**
1732 * cds_is_packet_log_enabled() - check if packet log is enabled
1733 *
1734 * Return: true if packet log is enabled else false
1735 */
1736bool cds_is_packet_log_enabled(void)
1737{
Jeff Johnsonc18b26c2017-09-03 08:46:45 -07001738 struct hdd_context *hdd_ctx;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001739
Jeff Johnsonc18b26c2017-09-03 08:46:45 -07001740 hdd_ctx = (struct hdd_context *) (gp_cds_context->pHDDContext);
1741 if ((NULL == hdd_ctx) || (NULL == hdd_ctx->config)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301742 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_FATAL,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001743 "%s: Hdd Context is Null", __func__);
1744 return false;
1745 }
1746
Jeff Johnsonc18b26c2017-09-03 08:46:45 -07001747 return hdd_ctx->config->enablePacketLog;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001748}
1749
Dustin Brown100201e2017-07-10 11:48:40 -07001750static int cds_force_assert_target_via_pld(qdf_device_t qdf)
Mukul Sharmab7b575b2016-10-02 23:37:07 +05301751{
Dustin Brown100201e2017-07-10 11:48:40 -07001752 int errno;
1753
1754 errno = pld_force_assert_target(qdf->dev);
1755 if (errno == -EOPNOTSUPP)
1756 cds_info("PLD does not support target force assert");
1757 else if (errno)
1758 cds_err("Failed PLD target force assert; errno %d", errno);
1759 else
1760 cds_info("Target force assert triggered via PLD");
1761
1762 return errno;
Mukul Sharmab7b575b2016-10-02 23:37:07 +05301763}
1764
Dustin Brown100201e2017-07-10 11:48:40 -07001765static QDF_STATUS cds_force_assert_target_via_wmi(qdf_device_t qdf)
Rajeev Kumardb60f162017-07-25 20:27:59 -07001766{
Dustin Brown100201e2017-07-10 11:48:40 -07001767 QDF_STATUS status;
1768 t_wma_handle *wma;
1769
1770 wma = cds_get_context(QDF_MODULE_ID_WMA);
1771 if (!wma) {
1772 cds_err("wma is null");
1773 return QDF_STATUS_E_INVAL;
1774 }
1775
1776 status = wma_crash_inject(wma, RECOVERY_SIM_SELF_RECOVERY, 0);
1777 if (QDF_IS_STATUS_ERROR(status)) {
1778 cds_err("Failed target force assert; status %d", status);
1779 return status;
1780 }
1781
1782 status = qdf_wait_single_event(&wma->recovery_event,
1783 WMA_CRASH_INJECT_TIMEOUT);
1784 if (QDF_IS_STATUS_ERROR(status)) {
1785 cds_err("Failed target force assert wait; status %d", status);
1786 return status;
1787 }
1788
1789 return QDF_STATUS_SUCCESS;
1790}
1791
1792/**
1793 * cds_force_assert_target() - Send assert command to firmware
1794 * @qdf: QDF device instance to assert
1795 *
1796 * An out-of-band recovery mechanism will cleanup and restart the entire wlan
1797 * subsystem in the event of a firmware crash. This API injects a firmware
1798 * crash to start this process when the wlan driver is known to be in a bad
1799 * state. If a firmware assert inject fails, the wlan driver will schedule
1800 * the driver recovery anyway, as a best effort attempt to return to a working
1801 * state.
1802 *
1803 * Return: QDF_STATUS
1804 */
1805static QDF_STATUS cds_force_assert_target(qdf_device_t qdf)
1806{
1807 int errno;
1808 QDF_STATUS status;
1809
1810 /* first, try target assert inject via pld */
1811 errno = cds_force_assert_target_via_pld(qdf);
1812 if (!errno)
1813 return QDF_STATUS_SUCCESS;
1814 if (errno != -EOPNOTSUPP)
1815 return QDF_STATUS_E_FAILURE;
1816
1817 /* pld assert is not supported, try target assert inject via wmi */
1818 status = cds_force_assert_target_via_wmi(qdf);
1819 if (QDF_IS_STATUS_SUCCESS(status))
1820 return QDF_STATUS_SUCCESS;
1821
1822 /* wmi assert failed, start recovery without the firmware assert */
1823 cds_err("Scheduling recovery work without firmware assert");
1824 cds_set_recovery_in_progress(true);
1825 pld_schedule_recovery_work(qdf->dev, PLD_REASON_DEFAULT);
1826
1827 return status;
Rajeev Kumardb60f162017-07-25 20:27:59 -07001828}
1829
Mukul Sharmab7b575b2016-10-02 23:37:07 +05301830/**
Srinivas Girigowda161b9f22017-07-24 17:38:09 -07001831 * cds_trigger_recovery_work() - trigger self recovery work
Mukul Sharmab7b575b2016-10-02 23:37:07 +05301832 *
1833 * Return: none
1834 */
Srinivas Girigowda161b9f22017-07-24 17:38:09 -07001835static void cds_trigger_recovery_work(void *param)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001836{
Dustin Brown100201e2017-07-10 11:48:40 -07001837 QDF_STATUS status;
1838 qdf_runtime_lock_t rtl;
1839 qdf_device_t qdf;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001840
Dustin Brown100201e2017-07-10 11:48:40 -07001841 if (!cds_is_self_recovery_enabled()) {
1842 cds_err("Recovery is not enabled");
1843 QDF_BUG(0);
Sameer Thalappilec2e9c72017-02-08 15:45:49 -08001844 return;
1845 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001846
Dustin Brown100201e2017-07-10 11:48:40 -07001847 if (cds_is_driver_recovering() || cds_is_driver_in_bad_state()) {
1848 cds_err("Recovery in progress; ignoring recovery trigger");
Houston Hoffmanc7c72a82015-12-07 15:30:48 -08001849 return;
1850 }
1851
Rajeev Kumar6dd45a82017-10-20 14:43:05 -07001852 if (cds_is_fw_down()) {
1853 cds_err("FW is down; ignoring recovery trigger");
1854 return;
1855 }
1856
Dustin Brown100201e2017-07-10 11:48:40 -07001857 qdf = cds_get_context(QDF_MODULE_ID_QDF_DEVICE);
1858 if (!qdf) {
1859 cds_err("Qdf context is null");
1860 return;
Sameer Thalappilac5d26e2017-01-10 15:32:58 -08001861 }
1862
Dustin Brown100201e2017-07-10 11:48:40 -07001863 status = qdf_runtime_lock_init(&rtl);
1864 if (QDF_IS_STATUS_ERROR(status)) {
Srinivas Girigowda161b9f22017-07-24 17:38:09 -07001865 cds_err("qdf_runtime_lock_init failed, status: %d", status);
Dustin Brown100201e2017-07-10 11:48:40 -07001866 return;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001867 }
Houston Hoffmanc7c72a82015-12-07 15:30:48 -08001868
Dustin Brown100201e2017-07-10 11:48:40 -07001869 status = qdf_runtime_pm_prevent_suspend(&rtl);
1870 if (QDF_IS_STATUS_ERROR(status)) {
1871 cds_err("Failed to acquire runtime pm lock");
1872 goto deinit_rtl;
1873 }
1874
1875 cds_force_assert_target(qdf);
1876
1877 status = qdf_runtime_pm_allow_suspend(&rtl);
1878 if (QDF_IS_STATUS_ERROR(status))
1879 cds_err("Failed to release runtime pm lock");
1880
1881deinit_rtl:
1882 qdf_runtime_lock_deinit(&rtl);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001883}
1884
1885/**
Anurag Chouhan4085ff72017-10-05 18:09:56 +05301886 * cds_get_recovery_reason() - get self recovery reason
1887 * @reason: recovery reason
1888 *
1889 * Return: None
1890 */
1891void cds_get_recovery_reason(enum qdf_hang_reason *reason)
1892{
1893 if (!gp_cds_context) {
1894 cds_err("gp_cds_context is null");
1895 return;
1896 }
1897
1898 *reason = gp_cds_context->recovery_reason;
1899}
1900
1901/**
1902 * cds_reset_recovery_reason() - reset the reason to unspecified
1903 *
1904 * Return: None
1905 */
1906void cds_reset_recovery_reason(void)
1907{
1908 if (!gp_cds_context) {
1909 cds_err("gp_cds_context is null");
1910 return;
1911 }
1912
1913 gp_cds_context->recovery_reason = QDF_REASON_UNSPECIFIED;
1914}
1915
1916/**
Srinivas Girigowda161b9f22017-07-24 17:38:09 -07001917 * cds_trigger_recovery() - trigger self recovery
Anurag Chouhan4085ff72017-10-05 18:09:56 +05301918 * @reason: recovery reason
Srinivas Girigowda161b9f22017-07-24 17:38:09 -07001919 *
1920 * Return: none
1921 */
Anurag Chouhan4085ff72017-10-05 18:09:56 +05301922void cds_trigger_recovery(enum qdf_hang_reason reason)
Srinivas Girigowda161b9f22017-07-24 17:38:09 -07001923{
Anurag Chouhan4085ff72017-10-05 18:09:56 +05301924 if (!gp_cds_context) {
1925 cds_err("gp_cds_context is null");
1926 return;
1927 }
1928
1929 gp_cds_context->recovery_reason = reason;
Srinivas Girigowda161b9f22017-07-24 17:38:09 -07001930 if (in_atomic()) {
1931 qdf_queue_work(0, gp_cds_context->cds_recovery_wq,
1932 &gp_cds_context->cds_recovery_work);
1933 return;
1934 }
1935 cds_trigger_recovery_work(NULL);
1936}
1937
1938/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001939 * cds_get_monotonic_boottime() - Get kernel boot time.
1940 *
1941 * Return: Time in microseconds
1942 */
1943
1944uint64_t cds_get_monotonic_boottime(void)
1945{
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001946 struct timespec ts;
1947
Yuanyuan Liu2e03b412016-04-06 14:36:15 -07001948 get_monotonic_boottime(&ts);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001949 return ((uint64_t) ts.tv_sec * 1000000) + (ts.tv_nsec / 1000);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001950}
1951
1952/**
1953 * cds_set_wakelock_logging() - Logging of wakelock enabled/disabled
1954 * @value: Boolean value
1955 *
1956 * This function is used to set the flag which will indicate whether
1957 * logging of wakelock is enabled or not
1958 *
1959 * Return: None
1960 */
1961void cds_set_wakelock_logging(bool value)
1962{
1963 p_cds_contextType p_cds_context;
1964
1965 p_cds_context = cds_get_global_context();
1966 if (!p_cds_context) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301967 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001968 "cds context is Invald");
1969 return;
1970 }
1971 p_cds_context->is_wakelock_log_enabled = value;
1972}
1973
1974/**
1975 * cds_is_wakelock_enabled() - Check if logging of wakelock is enabled/disabled
1976 * @value: Boolean value
1977 *
1978 * This function is used to check whether logging of wakelock is enabled or not
1979 *
1980 * Return: true if logging of wakelock is enabled
1981 */
1982bool cds_is_wakelock_enabled(void)
1983{
1984 p_cds_contextType p_cds_context;
1985
1986 p_cds_context = cds_get_global_context();
1987 if (!p_cds_context) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301988 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001989 "cds context is Invald");
1990 return false;
1991 }
1992 return p_cds_context->is_wakelock_log_enabled;
1993}
1994
1995/**
1996 * cds_set_ring_log_level() - Sets the log level of a particular ring
1997 * @ring_id: ring_id
1998 * @log_levelvalue: Log level specificed
1999 *
2000 * This function converts HLOS values to driver log levels and sets the log
2001 * level of a particular ring accordingly.
2002 *
2003 * Return: None
2004 */
2005void cds_set_ring_log_level(uint32_t ring_id, uint32_t log_level)
2006{
2007 p_cds_contextType p_cds_context;
2008 uint32_t log_val;
2009
2010 p_cds_context = cds_get_global_context();
2011 if (!p_cds_context) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302012 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002013 "%s: cds context is Invald", __func__);
2014 return;
2015 }
2016
2017 switch (log_level) {
2018 case LOG_LEVEL_NO_COLLECTION:
2019 log_val = WLAN_LOG_LEVEL_OFF;
2020 break;
2021 case LOG_LEVEL_NORMAL_COLLECT:
2022 log_val = WLAN_LOG_LEVEL_NORMAL;
2023 break;
2024 case LOG_LEVEL_ISSUE_REPRO:
2025 log_val = WLAN_LOG_LEVEL_REPRO;
2026 break;
2027 case LOG_LEVEL_ACTIVE:
2028 default:
2029 log_val = WLAN_LOG_LEVEL_ACTIVE;
2030 break;
2031 }
2032
2033 if (ring_id == RING_ID_WAKELOCK) {
2034 p_cds_context->wakelock_log_level = log_val;
2035 return;
2036 } else if (ring_id == RING_ID_CONNECTIVITY) {
2037 p_cds_context->connectivity_log_level = log_val;
2038 return;
2039 } else if (ring_id == RING_ID_PER_PACKET_STATS) {
2040 p_cds_context->packet_stats_log_level = log_val;
2041 return;
Chandrasekaran, Manishekar907c2af2015-11-13 12:50:04 +05302042 } else if (ring_id == RING_ID_DRIVER_DEBUG) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002043 p_cds_context->driver_debug_log_level = log_val;
2044 return;
2045 } else if (ring_id == RING_ID_FIRMWARE_DEBUG) {
2046 p_cds_context->fw_debug_log_level = log_val;
2047 return;
2048 }
2049}
2050
2051/**
2052 * cds_get_ring_log_level() - Get the a ring id's log level
2053 * @ring_id: Ring id
2054 *
2055 * Fetch and return the log level corresponding to a ring id
2056 *
2057 * Return: Log level corresponding to the ring ID
2058 */
2059enum wifi_driver_log_level cds_get_ring_log_level(uint32_t ring_id)
2060{
2061 p_cds_contextType p_cds_context;
2062
2063 p_cds_context = cds_get_global_context();
2064 if (!p_cds_context) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302065 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002066 "%s: cds context is Invald", __func__);
2067 return WLAN_LOG_LEVEL_OFF;
2068 }
2069
2070 if (ring_id == RING_ID_WAKELOCK)
2071 return p_cds_context->wakelock_log_level;
2072 else if (ring_id == RING_ID_CONNECTIVITY)
2073 return p_cds_context->connectivity_log_level;
2074 else if (ring_id == RING_ID_PER_PACKET_STATS)
2075 return p_cds_context->packet_stats_log_level;
Chandrasekaran, Manishekar907c2af2015-11-13 12:50:04 +05302076 else if (ring_id == RING_ID_DRIVER_DEBUG)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002077 return p_cds_context->driver_debug_log_level;
2078 else if (ring_id == RING_ID_FIRMWARE_DEBUG)
2079 return p_cds_context->fw_debug_log_level;
2080
2081 return WLAN_LOG_LEVEL_OFF;
2082}
2083
2084/**
2085 * cds_set_multicast_logging() - Set mutlicast logging value
2086 * @value: Value of multicast logging
2087 *
2088 * Set the multicast logging value which will indicate
2089 * whether to multicast host and fw messages even
2090 * without any registration by userspace entity
2091 *
2092 * Return: None
2093 */
2094void cds_set_multicast_logging(uint8_t value)
2095{
2096 cds_multicast_logging = value;
2097}
2098
2099/**
2100 * cds_is_multicast_logging() - Get multicast logging value
2101 *
2102 * Get the multicast logging value which will indicate
2103 * whether to multicast host and fw messages even
2104 * without any registration by userspace entity
2105 *
2106 * Return: 0 - Multicast logging disabled, 1 - Multicast logging enabled
2107 */
2108uint8_t cds_is_multicast_logging(void)
2109{
2110 return cds_multicast_logging;
2111}
2112
2113/*
2114 * cds_init_log_completion() - Initialize log param structure
2115 *
2116 * This function is used to initialize the logging related
2117 * parameters
2118 *
2119 * Return: None
2120 */
2121void cds_init_log_completion(void)
2122{
2123 p_cds_contextType p_cds_context;
2124
2125 p_cds_context = cds_get_global_context();
2126 if (!p_cds_context) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302127 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002128 "%s: cds context is Invalid", __func__);
2129 return;
2130 }
2131
2132 p_cds_context->log_complete.is_fatal = WLAN_LOG_TYPE_NON_FATAL;
2133 p_cds_context->log_complete.indicator = WLAN_LOG_INDICATOR_UNUSED;
2134 p_cds_context->log_complete.reason_code = WLAN_LOG_REASON_CODE_UNUSED;
2135 p_cds_context->log_complete.is_report_in_progress = false;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002136}
2137
2138/**
2139 * cds_set_log_completion() - Store the logging params
2140 * @is_fatal: Indicates if the event triggering bug report is fatal or not
2141 * @indicator: Source which trigerred the bug report
2142 * @reason_code: Reason for triggering bug report
Abhishek Singh5ea86532016-04-27 14:10:53 +05302143 * @recovery_needed: If recovery is needed after bug report
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002144 *
2145 * This function is used to set the logging parameters based on the
2146 * caller
2147 *
2148 * Return: 0 if setting of params is successful
2149 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302150QDF_STATUS cds_set_log_completion(uint32_t is_fatal,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002151 uint32_t indicator,
Abhishek Singh5ea86532016-04-27 14:10:53 +05302152 uint32_t reason_code,
2153 bool recovery_needed)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002154{
2155 p_cds_contextType p_cds_context;
2156
2157 p_cds_context = cds_get_global_context();
2158 if (!p_cds_context) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302159 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002160 "%s: cds context is Invalid", __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302161 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002162 }
2163
Anurag Chouhana37b5b72016-02-21 14:53:42 +05302164 qdf_spinlock_acquire(&p_cds_context->bug_report_lock);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002165 p_cds_context->log_complete.is_fatal = is_fatal;
2166 p_cds_context->log_complete.indicator = indicator;
2167 p_cds_context->log_complete.reason_code = reason_code;
Abhishek Singh5ea86532016-04-27 14:10:53 +05302168 p_cds_context->log_complete.recovery_needed = recovery_needed;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002169 p_cds_context->log_complete.is_report_in_progress = true;
Anurag Chouhana37b5b72016-02-21 14:53:42 +05302170 qdf_spinlock_release(&p_cds_context->bug_report_lock);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302171 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002172}
2173
2174/**
Abhishek Singh5ea86532016-04-27 14:10:53 +05302175 * cds_get_and_reset_log_completion() - Get and reset logging related params
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002176 * @is_fatal: Indicates if the event triggering bug report is fatal or not
2177 * @indicator: Source which trigerred the bug report
2178 * @reason_code: Reason for triggering bug report
Abhishek Singh5ea86532016-04-27 14:10:53 +05302179 * @recovery_needed: If recovery is needed after bug report
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002180 *
2181 * This function is used to get the logging related parameters
2182 *
2183 * Return: None
2184 */
Abhishek Singh5ea86532016-04-27 14:10:53 +05302185void cds_get_and_reset_log_completion(uint32_t *is_fatal,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002186 uint32_t *indicator,
Abhishek Singh5ea86532016-04-27 14:10:53 +05302187 uint32_t *reason_code,
2188 bool *recovery_needed)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002189{
2190 p_cds_contextType p_cds_context;
2191
2192 p_cds_context = cds_get_global_context();
2193 if (!p_cds_context) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302194 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002195 "%s: cds context is Invalid", __func__);
2196 return;
2197 }
2198
Anurag Chouhana37b5b72016-02-21 14:53:42 +05302199 qdf_spinlock_acquire(&p_cds_context->bug_report_lock);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002200 *is_fatal = p_cds_context->log_complete.is_fatal;
2201 *indicator = p_cds_context->log_complete.indicator;
2202 *reason_code = p_cds_context->log_complete.reason_code;
Abhishek Singh5ea86532016-04-27 14:10:53 +05302203 *recovery_needed = p_cds_context->log_complete.recovery_needed;
2204
2205 /* reset */
2206 p_cds_context->log_complete.indicator = WLAN_LOG_INDICATOR_UNUSED;
2207 p_cds_context->log_complete.is_fatal = WLAN_LOG_TYPE_NON_FATAL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002208 p_cds_context->log_complete.is_report_in_progress = false;
Abhishek Singh5ea86532016-04-27 14:10:53 +05302209 p_cds_context->log_complete.reason_code = WLAN_LOG_REASON_CODE_UNUSED;
2210 p_cds_context->log_complete.recovery_needed = false;
Anurag Chouhana37b5b72016-02-21 14:53:42 +05302211 qdf_spinlock_release(&p_cds_context->bug_report_lock);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002212}
2213
2214/**
2215 * cds_is_log_report_in_progress() - Check if bug reporting is in progress
2216 *
2217 * This function is used to check if the bug reporting is already in progress
2218 *
2219 * Return: true if the bug reporting is in progress
2220 */
2221bool cds_is_log_report_in_progress(void)
2222{
2223 p_cds_contextType p_cds_context;
2224
2225 p_cds_context = cds_get_global_context();
2226 if (!p_cds_context) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302227 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002228 "%s: cds context is Invalid", __func__);
2229 return true;
2230 }
2231 return p_cds_context->log_complete.is_report_in_progress;
2232}
2233
2234/**
Abhishek Singh5ea86532016-04-27 14:10:53 +05302235 * cds_is_fatal_event_enabled() - Return if fatal event is enabled
2236 *
2237 * Return true if fatal event is enabled.
2238 */
2239bool cds_is_fatal_event_enabled(void)
2240{
2241 p_cds_contextType p_cds_context;
2242
2243 p_cds_context = cds_get_global_context();
2244 if (!p_cds_context) {
2245 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
2246 "%s: cds context is Invalid", __func__);
2247 return false;
2248 }
2249
2250
2251 return p_cds_context->enable_fatal_event;
2252}
2253
Yu Wang66a250b2017-07-19 11:46:40 +08002254#ifdef WLAN_FEATURE_TSF_PLUS
2255bool cds_is_ptp_rx_opt_enabled(void)
2256{
2257 struct hdd_context *hdd_ctx;
2258 p_cds_contextType p_cds_context;
2259
2260 p_cds_context = cds_get_global_context();
2261 if (!p_cds_context) {
2262 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
2263 "%s: cds context is Invalid", __func__);
2264 return false;
2265 }
2266
2267 hdd_ctx = (struct hdd_context *)(p_cds_context->pHDDContext);
2268 if ((NULL == hdd_ctx) || (NULL == hdd_ctx->config)) {
2269 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
2270 "%s: Hdd Context is Null", __func__);
2271 return false;
2272 }
2273
2274 return HDD_TSF_IS_RX_SET(hdd_ctx);
2275}
2276
2277bool cds_is_ptp_tx_opt_enabled(void)
2278{
2279 struct hdd_context *hdd_ctx;
2280 p_cds_contextType p_cds_context;
2281
2282 p_cds_context = cds_get_global_context();
2283 if (!p_cds_context) {
2284 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
2285 "%s: cds context is Invalid", __func__);
2286 return false;
2287 }
2288
2289 hdd_ctx = (struct hdd_context *)(p_cds_context->pHDDContext);
2290 if ((NULL == hdd_ctx) || (NULL == hdd_ctx->config)) {
2291 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
2292 "%s: Hdd Context is Null", __func__);
2293 return false;
2294 }
2295
2296 return HDD_TSF_IS_TX_SET(hdd_ctx);
2297}
2298#endif
2299
Abhishek Singh5ea86532016-04-27 14:10:53 +05302300/**
2301 * cds_get_log_indicator() - Get the log flush indicator
2302 *
2303 * This function is used to get the log flush indicator
2304 *
2305 * Return: log indicator
2306 */
2307uint32_t cds_get_log_indicator(void)
2308{
2309 p_cds_contextType p_cds_context;
2310 uint32_t indicator;
2311
2312 p_cds_context = cds_get_global_context();
2313 if (!p_cds_context) {
2314 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
2315 "%s: cds context is Invalid", __func__);
2316 return WLAN_LOG_INDICATOR_UNUSED;
2317 }
2318
2319 if (cds_is_load_or_unload_in_progress() ||
Hanumanth Reddy Pothula2a8a7402017-07-03 14:06:11 +05302320 cds_is_driver_recovering() || cds_is_driver_in_bad_state()) {
Abhishek Singh5ea86532016-04-27 14:10:53 +05302321 return WLAN_LOG_INDICATOR_UNUSED;
2322 }
2323
2324 qdf_spinlock_acquire(&p_cds_context->bug_report_lock);
2325 indicator = p_cds_context->log_complete.indicator;
2326 qdf_spinlock_release(&p_cds_context->bug_report_lock);
2327 return indicator;
2328}
2329
2330/**
2331 * cds_wlan_flush_host_logs_for_fatal() - Wrapper to flush host logs
2332 *
2333 * This function is used to send signal to the logger thread to
2334 * flush the host logs.
2335 *
2336 * Return: None
2337 *
2338 */
2339void cds_wlan_flush_host_logs_for_fatal(void)
2340{
2341 wlan_flush_host_logs_for_fatal();
2342}
2343
2344/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002345 * cds_flush_logs() - Report fatal event to userspace
2346 * @is_fatal: Indicates if the event triggering bug report is fatal or not
2347 * @indicator: Source which trigerred the bug report
2348 * @reason_code: Reason for triggering bug report
Abhishek Singh5ea86532016-04-27 14:10:53 +05302349 * @dump_mac_trace: If mac trace are needed in logs.
2350 * @recovery_needed: If recovery is needed after bug report
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002351 *
2352 * This function sets the log related params and send the WMI command to the
2353 * FW to flush its logs. On receiving the flush completion event from the FW
2354 * the same will be conveyed to userspace
2355 *
2356 * Return: 0 on success
2357 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302358QDF_STATUS cds_flush_logs(uint32_t is_fatal,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002359 uint32_t indicator,
Abhishek Singh5ea86532016-04-27 14:10:53 +05302360 uint32_t reason_code,
2361 bool dump_mac_trace,
2362 bool recovery_needed)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002363{
2364 uint32_t ret;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302365 QDF_STATUS status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002366
2367 p_cds_contextType p_cds_context;
2368
2369 p_cds_context = cds_get_global_context();
2370 if (!p_cds_context) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302371 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002372 "%s: cds context is Invalid", __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302373 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002374 }
Abhishek Singh5ea86532016-04-27 14:10:53 +05302375 if (!p_cds_context->enable_fatal_event) {
2376 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
2377 "%s: Fatal event not enabled", __func__);
2378 return QDF_STATUS_E_FAILURE;
2379 }
2380 if (cds_is_load_or_unload_in_progress() ||
Hanumanth Reddy Pothula2a8a7402017-07-03 14:06:11 +05302381 cds_is_driver_recovering() || cds_is_driver_in_bad_state()) {
Abhishek Singh5ea86532016-04-27 14:10:53 +05302382 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
2383 "%s: un/Load/SSR in progress", __func__);
2384 return QDF_STATUS_E_FAILURE;
2385 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002386
2387 if (cds_is_log_report_in_progress() == true) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302388 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002389 "%s: Bug report already in progress - dropping! type:%d, indicator=%d reason_code=%d",
2390 __func__, is_fatal, indicator, reason_code);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302391 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002392 }
2393
Abhishek Singh5ea86532016-04-27 14:10:53 +05302394 status = cds_set_log_completion(is_fatal, indicator,
2395 reason_code, recovery_needed);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302396 if (QDF_STATUS_SUCCESS != status) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302397 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002398 "%s: Failed to set log trigger params", __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302399 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002400 }
2401
Abhishek Singh5ea86532016-04-27 14:10:53 +05302402 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002403 "%s: Triggering bug report: type:%d, indicator=%d reason_code=%d",
2404 __func__, is_fatal, indicator, reason_code);
2405
Abhishek Singh5ea86532016-04-27 14:10:53 +05302406 if (dump_mac_trace)
2407 qdf_trace_dump_all(p_cds_context->pMACContext, 0, 0, 500, 0);
2408
2409 if (WLAN_LOG_INDICATOR_HOST_ONLY == indicator) {
2410 cds_wlan_flush_host_logs_for_fatal();
2411 return QDF_STATUS_SUCCESS;
2412 }
2413
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002414 ret = sme_send_flush_logs_cmd_to_fw(p_cds_context->pMACContext);
2415 if (0 != ret) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302416 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002417 "%s: Failed to send flush FW log", __func__);
2418 cds_init_log_completion();
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302419 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002420 }
2421
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302422 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002423}
2424
2425/**
2426 * cds_logging_set_fw_flush_complete() - Wrapper for FW log flush completion
2427 *
2428 * This function is used to send signal to the logger thread to indicate
2429 * that the flushing of FW logs is complete by the FW
2430 *
2431 * Return: None
2432 *
2433 */
2434void cds_logging_set_fw_flush_complete(void)
2435{
2436 wlan_logging_set_fw_flush_complete();
2437}
Abhishek Singh5ea86532016-04-27 14:10:53 +05302438
2439/**
2440 * cds_set_fatal_event() - set fatal event status
2441 * @value: pending statue to set
2442 *
2443 * Return: None
2444 */
2445void cds_set_fatal_event(bool value)
2446{
2447 p_cds_contextType p_cds_context;
2448
2449 p_cds_context = cds_get_global_context();
2450 if (!p_cds_context) {
2451 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
2452 "%s: cds context is Invalid", __func__);
2453 return;
2454 }
2455 p_cds_context->enable_fatal_event = value;
2456}
2457
Ryan Hsuceddceb2016-04-28 10:20:14 -07002458/**
2459 * cds_get_radio_index() - get radio index
2460 *
2461 * Return: radio index otherwise, -EINVAL
2462 */
2463int cds_get_radio_index(void)
2464{
2465 p_cds_contextType p_cds_context;
2466
2467 p_cds_context = cds_get_global_context();
2468 if (!p_cds_context) {
2469 /*
2470 * To avoid recursive call, this should not change to
2471 * QDF_TRACE().
2472 */
2473 pr_err("%s: cds context is invalid\n", __func__);
2474 return -EINVAL;
2475 }
2476
2477 return p_cds_context->radio_index;
2478}
2479
2480/**
2481 * cds_set_radio_index() - set radio index
2482 * @radio_index: the radio index to set
2483 *
2484 * Return: QDF status
2485 */
2486QDF_STATUS cds_set_radio_index(int radio_index)
2487{
2488 p_cds_contextType p_cds_context;
2489
2490 p_cds_context = cds_get_global_context();
2491 if (!p_cds_context) {
2492 pr_err("%s: cds context is invalid\n", __func__);
2493 return QDF_STATUS_E_FAILURE;
2494 }
2495
2496 p_cds_context->radio_index = radio_index;
2497
2498 return QDF_STATUS_SUCCESS;
2499}
Arun Khandavallic811dcc2016-06-26 07:37:21 +05302500
2501/**
2502 * cds_init_ini_config() - API to initialize CDS configuration parameters
2503 * @cfg: CDS Configuration
2504 *
2505 * Return: void
2506 */
2507
2508void cds_init_ini_config(struct cds_config_info *cfg)
2509{
2510 cds_context_type *cds_ctx;
2511
2512 cds_ctx = cds_get_context(QDF_MODULE_ID_QDF);
2513 if (!cds_ctx) {
2514 cds_err("Invalid CDS Context");
2515 return;
2516 }
2517
2518 cds_ctx->cds_cfg = cfg;
2519}
2520
2521/**
2522 * cds_deinit_ini_config() - API to free CDS configuration parameters
2523 *
2524 * Return: void
2525 */
2526void cds_deinit_ini_config(void)
2527{
2528 cds_context_type *cds_ctx;
2529
2530 cds_ctx = cds_get_context(QDF_MODULE_ID_QDF);
2531 if (!cds_ctx) {
2532 cds_err("Invalid CDS Context");
2533 return;
2534 }
2535
Arun Khandavallif6246632016-08-17 17:43:06 +05302536 if (cds_ctx->cds_cfg)
Arun Khandavallic811dcc2016-06-26 07:37:21 +05302537 qdf_mem_free(cds_ctx->cds_cfg);
2538
2539 cds_ctx->cds_cfg = NULL;
2540}
2541
2542/**
2543 * cds_get_ini_config() - API to get CDS configuration parameters
2544 *
2545 * Return: cds config structure
2546 */
2547struct cds_config_info *cds_get_ini_config(void)
2548{
2549 cds_context_type *cds_ctx;
2550
2551 cds_ctx = cds_get_context(QDF_MODULE_ID_QDF);
2552 if (!cds_ctx) {
2553 cds_err("Invalid CDS Context");
2554 return NULL;
2555 }
2556
2557 return cds_ctx->cds_cfg;
2558}
Naveen Rawat64e477e2016-05-20 10:34:56 -07002559
2560/**
2561 * cds_is_5_mhz_enabled() - API to get 5MHZ enabled
2562 *
2563 * Return: true if 5 mhz is enabled, false otherwise
2564 */
2565bool cds_is_5_mhz_enabled(void)
2566{
2567 p_cds_contextType p_cds_context;
2568
2569 p_cds_context = cds_get_context(QDF_MODULE_ID_QDF);
2570 if (!p_cds_context) {
2571 cds_err("%s: cds context is invalid", __func__);
2572 return false;
2573 }
2574
2575 if (p_cds_context->cds_cfg)
2576 return (p_cds_context->cds_cfg->sub_20_channel_width ==
2577 WLAN_SUB_20_CH_WIDTH_5);
2578
2579 return false;
2580}
2581
2582/**
2583 * cds_is_10_mhz_enabled() - API to get 10-MHZ enabled
2584 *
2585 * Return: true if 10 mhz is enabled, false otherwise
2586 */
2587bool cds_is_10_mhz_enabled(void)
2588{
2589 p_cds_contextType p_cds_context;
2590
2591 p_cds_context = cds_get_context(QDF_MODULE_ID_QDF);
2592 if (!p_cds_context) {
2593 cds_err("%s: cds context is invalid", __func__);
2594 return false;
2595 }
2596
2597 if (p_cds_context->cds_cfg)
2598 return (p_cds_context->cds_cfg->sub_20_channel_width ==
2599 WLAN_SUB_20_CH_WIDTH_10);
2600
2601 return false;
2602}
2603
2604/**
2605 * cds_is_sub_20_mhz_enabled() - API to get sub 20-MHZ enabled
2606 *
2607 * Return: true if 5 or 10 mhz is enabled, false otherwise
2608 */
2609bool cds_is_sub_20_mhz_enabled(void)
2610{
2611 p_cds_contextType p_cds_context;
2612
2613 p_cds_context = cds_get_context(QDF_MODULE_ID_QDF);
2614 if (!p_cds_context) {
2615 cds_err("%s: cds context is invalid", __func__);
2616 return false;
2617 }
2618
2619 if (p_cds_context->cds_cfg)
2620 return p_cds_context->cds_cfg->sub_20_channel_width;
2621
2622 return false;
2623}
2624
Komal Seelam78ff65a2016-08-18 15:25:24 +05302625/**
Naveen Rawat91df30a2016-10-12 21:26:18 -07002626 * cds_is_self_recovery_enabled() - API to get self recovery enabled
2627 *
2628 * Return: true if self recovery enabled, false otherwise
2629 */
2630bool cds_is_self_recovery_enabled(void)
2631{
2632 p_cds_contextType p_cds_context;
2633
2634 p_cds_context = cds_get_context(QDF_MODULE_ID_QDF);
2635 if (!p_cds_context) {
2636 cds_err("%s: cds context is invalid", __func__);
2637 return false;
2638 }
2639
2640 if (p_cds_context->cds_cfg)
2641 return p_cds_context->cds_cfg->self_recovery_enabled;
2642
2643 return false;
2644}
2645
2646/**
Komal Seelam78ff65a2016-08-18 15:25:24 +05302647 * cds_svc_fw_shutdown_ind() - API to send userspace about FW crash
2648 *
2649 * @dev: Device Pointer
2650 *
2651 * Return: None
2652 */
2653void cds_svc_fw_shutdown_ind(struct device *dev)
2654{
2655 hdd_svc_fw_shutdown_ind(dev);
2656}
Himanshu Agarwal46956a52016-07-26 19:46:25 +05302657
2658/*
2659 * cds_pkt_stats_to_logger_thread() - send pktstats to user
2660 * @pl_hdr: Pointer to pl_hdr
2661 * @pkt_dump: Pointer to pkt_dump data structure.
2662 * @data: Pointer to data
2663 *
2664 * This function is used to send the pkt stats to SVC module.
2665 *
2666 * Return: None
2667 */
2668inline void cds_pkt_stats_to_logger_thread(void *pl_hdr, void *pkt_dump,
2669 void *data)
2670{
2671 if (cds_get_ring_log_level(RING_ID_PER_PACKET_STATS) !=
2672 WLAN_LOG_LEVEL_ACTIVE)
2673 return;
2674
2675 wlan_pkt_stats_to_logger_thread(pl_hdr, pkt_dump, data);
2676}
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -08002677
2678/**
2679 * cds_get_conparam() - Get the connection mode parameters
2680 *
2681 * Return the connection mode parameter set by insmod or set during statically
2682 * linked driver
2683 *
2684 * Return: enum tQDF_GLOBAL_CON_MODE
2685 */
2686enum tQDF_GLOBAL_CON_MODE cds_get_conparam(void)
2687{
2688 enum tQDF_GLOBAL_CON_MODE con_mode;
2689
2690 con_mode = hdd_get_conparam();
2691
2692 return con_mode;
2693}
Dustin Brown8d2d0f52017-04-03 17:02:08 -07002694
2695#ifdef WMI_INTERFACE_EVENT_LOGGING
2696inline void
2697cds_print_htc_credit_history(uint32_t count, qdf_abstract_print *print,
2698 void *print_priv)
2699{
2700 htc_print_credit_history(gp_cds_context->htc_ctx, count,
2701 print, print_priv);
2702}
2703#endif