blob: 610a8466d6ba775d13068891f7f935f3be460620 [file] [log] [blame]
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001/*
Ryan Hsu4252a2f2016-01-05 11:18:24 -08002 * Copyright (c) 2012-2016 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
34#include <cds_mq.h>
35#include "cds_sched.h"
36#include <cds_api.h>
37#include "sir_types.h"
38#include "sir_api.h"
39#include "sir_mac_prot_def.h"
40#include "sme_api.h"
41#include "mac_init_api.h"
42#include "wlan_qct_sys.h"
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080043#include "i_cds_packet.h"
44#include "cds_reg_service.h"
45#include "wma_types.h"
46#include "wlan_hdd_main.h"
47#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"
Yue Ma1e11d792016-02-26 18:58:44 -080056#include "cds_concurrency.h"
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080057#include "cds_utils.h"
58#include "wlan_logging_sock_svc.h"
59#include "wma.h"
60
61#include "wlan_hdd_ipa.h"
62/* Preprocessor Definitions and Constants */
63
64/* Maximum number of cds message queue get wrapper failures to cause panic */
65#define CDS_WRAPPER_MAX_FAIL_COUNT (CDS_CORE_MAX_MESSAGES * 3)
66
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080067/* Data definitions */
68static cds_context_type g_cds_context;
69static p_cds_contextType gp_cds_context;
Anurag Chouhandf2b2682016-02-29 14:15:27 +053070static struct __qdf_device g_qdf_ctx;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080071
72/* Debug variable to detect MC thread stuck */
73static atomic_t cds_wrapper_empty_count;
74
75static uint8_t cds_multicast_logging;
76
77void cds_sys_probe_thread_cback(void *pUserData);
78
79/**
Prashanth Bhatta5da711e2015-11-30 14:28:52 -080080 * cds_init() - Initialize CDS
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080081 *
Prashanth Bhatta5da711e2015-11-30 14:28:52 -080082 * This function allocates the resource required for CDS, but does not
83 * initialize all the members. This overall initialization will happen at
84 * cds_open().
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080085 *
Prashanth Bhatta5da711e2015-11-30 14:28:52 -080086 * Return: Global context on success and NULL on failure.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080087 */
Prashanth Bhatta5da711e2015-11-30 14:28:52 -080088v_CONTEXT_t cds_init(void)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080089{
Anurag Chouhan210db072016-02-22 18:42:15 +053090 qdf_mc_timer_manager_init();
Anurag Chouhan600c3a02016-03-01 10:33:54 +053091 qdf_mem_init();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080092
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080093 gp_cds_context = &g_cds_context;
94
Anurag Chouhandf2b2682016-02-29 14:15:27 +053095 gp_cds_context->qdf_ctx = &g_qdf_ctx;
Anurag Chouhan600c3a02016-03-01 10:33:54 +053096 qdf_mem_zero(&g_qdf_ctx, sizeof(g_qdf_ctx));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080097
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +053098 qdf_trace_spin_lock_init();
Prashanth Bhatta5da711e2015-11-30 14:28:52 -080099
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800100#if defined(TRACE_RECORD)
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530101 qdf_trace_init();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800102#endif
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530103 qdf_dp_trace_init();
Prashanth Bhatta5da711e2015-11-30 14:28:52 -0800104
105 cds_ssr_protect_init();
106
107 return gp_cds_context;
108}
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800109
110/**
Prashanth Bhatta5da711e2015-11-30 14:28:52 -0800111 * cds_deinit() - Deinitialize CDS
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800112 *
Prashanth Bhatta5da711e2015-11-30 14:28:52 -0800113 * This function frees the CDS resources
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800114 */
Prashanth Bhatta5da711e2015-11-30 14:28:52 -0800115void cds_deinit(void)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800116{
Prashanth Bhatta5da711e2015-11-30 14:28:52 -0800117 if (gp_cds_context == NULL)
118 return;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800119
Anurag Chouhan6d760662016-02-20 16:05:43 +0530120 gp_cds_context->qdf_ctx = NULL;
Prashanth Bhatta5da711e2015-11-30 14:28:52 -0800121 gp_cds_context = NULL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800122
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530123 qdf_mem_zero(&g_cds_context, sizeof(g_cds_context));
Prashanth Bhatta9e143052015-12-04 11:56:47 -0800124
Anurag Chouhan210db072016-02-22 18:42:15 +0530125 qdf_mc_timer_manager_exit();
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530126 qdf_mem_exit();
Yuanyuan Liufd9bfc52015-12-14 15:44:20 -0800127
Prashanth Bhatta5da711e2015-11-30 14:28:52 -0800128 return;
129}
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800130
Abhishek Singh437606a2016-04-27 13:51:49 +0530131#ifdef FEATURE_WLAN_DIAG_SUPPORT
132/**
133 * cds_tdls_tx_rx_mgmt_event()- send tdls mgmt rx tx event
134 * @event_id: event id
135 * @tx_rx: tx or rx
136 * @type: type of frame
137 * @action_sub_type: action frame type
138 * @peer_mac: peer mac
139 *
140 * This Function sends tdls mgmt rx tx diag event
141 *
142 * Return: void.
143 */
144void cds_tdls_tx_rx_mgmt_event(uint8_t event_id, uint8_t tx_rx,
145 uint8_t type, uint8_t action_sub_type, uint8_t *peer_mac)
146{
147 WLAN_HOST_DIAG_EVENT_DEF(tdls_tx_rx_mgmt,
148 struct host_event_tdls_tx_rx_mgmt);
149
150 tdls_tx_rx_mgmt.event_id = event_id;
151 tdls_tx_rx_mgmt.tx_rx = tx_rx;
152 tdls_tx_rx_mgmt.type = type;
153 tdls_tx_rx_mgmt.action_sub_type = action_sub_type;
154 qdf_mem_copy(tdls_tx_rx_mgmt.peer_mac,
155 peer_mac, CDS_MAC_ADDRESS_LEN);
156 WLAN_HOST_DIAG_EVENT_REPORT(&tdls_tx_rx_mgmt,
157 EVENT_WLAN_TDLS_TX_RX_MGMT);
158}
159#endif
160
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800161#ifdef WLAN_FEATURE_NAN
162/**
163 * cds_set_nan_enable() - set nan enable flag in mac open param
164 * @wma_handle: Pointer to mac open param
165 * @hdd_ctx: Pointer to hdd context
166 *
167 * Return: none
168 */
169static void cds_set_nan_enable(tMacOpenParameters *param,
170 hdd_context_t *hdd_ctx)
171{
172 param->is_nan_enabled = hdd_ctx->config->enable_nan_support;
173}
174#else
175static void cds_set_nan_enable(tMacOpenParameters *param,
176 hdd_context_t *pHddCtx)
177{
178}
179#endif
180
181/**
182 * cds_open() - open the CDS Module
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800183 *
184 * cds_open() function opens the CDS Scheduler
185 * Upon successful initialization:
186 * - All CDS submodules should have been initialized
187 *
188 * - The CDS scheduler should have opened
189 *
190 * - All the WLAN SW components should have been opened. This includes
191 * SYS, MAC, SME, WMA and TL.
192 *
Anurag Chouhanf04e84f2016-03-03 10:12:12 +0530193 * Return: QDF status
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800194 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530195QDF_STATUS cds_open(void)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800196{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530197 QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800198 int iter = 0;
199 tSirRetStatus sirStatus = eSIR_SUCCESS;
200 tMacOpenParameters mac_openParms;
Anurag Chouhan6d760662016-02-20 16:05:43 +0530201 qdf_device_t qdf_ctx;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800202 HTC_INIT_INFO htcInfo;
Komal Seelamd9106492016-02-15 10:31:44 +0530203 struct ol_context *ol_ctx;
Komal Seelam3d202862016-02-24 18:43:24 +0530204 struct hif_opaque_softc *scn;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800205 void *HTCHandle;
206 hdd_context_t *pHddCtx;
207
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530208 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_INFO_HIGH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800209 "%s: Opening CDS", __func__);
210
211 if (NULL == gp_cds_context) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530212 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_FATAL,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800213 "%s: Trying to open CDS without a PreOpen", __func__);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530214 QDF_ASSERT(0);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530215 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800216 }
217
218 /* Initialize the timer module */
Anurag Chouhan210db072016-02-22 18:42:15 +0530219 qdf_timer_module_init();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800220
221 /* Initialize bug reporting structure */
222 cds_init_log_completion();
223
Mohit Khannaebf8a862016-04-28 17:53:59 -0700224 /* Initialize protocol trace functionality */
225 cds_pkt_proto_trace_init();
226
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800227 /* Initialize the probe event */
Anurag Chouhance0dc992016-02-16 18:18:03 +0530228 if (qdf_event_create(&gp_cds_context->ProbeEvent) != QDF_STATUS_SUCCESS) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530229 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_FATAL,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800230 "%s: Unable to init probeEvent", __func__);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530231 QDF_ASSERT(0);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530232 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800233 }
Anurag Chouhance0dc992016-02-16 18:18:03 +0530234 if (qdf_event_create(&(gp_cds_context->wmaCompleteEvent)) !=
235 QDF_STATUS_SUCCESS) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530236 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_FATAL,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800237 "%s: Unable to init wmaCompleteEvent", __func__);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530238 QDF_ASSERT(0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800239 goto err_probe_event;
240 }
241
242 /* Initialize the free message queue */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530243 qdf_status = cds_mq_init(&gp_cds_context->freeVosMq);
244 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800245 /* Critical Error ... Cannot proceed further */
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530246 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_FATAL,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800247 "%s: Failed to initialize CDS free message queue",
248 __func__);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530249 QDF_ASSERT(0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800250 goto err_wma_complete_event;
251 }
252
253 for (iter = 0; iter < CDS_CORE_MAX_MESSAGES; iter++) {
254 (gp_cds_context->aMsgWrappers[iter]).pVosMsg =
255 &(gp_cds_context->aMsgBuffers[iter]);
256 INIT_LIST_HEAD(&gp_cds_context->aMsgWrappers[iter].msgNode);
257 cds_mq_put(&gp_cds_context->freeVosMq,
258 &(gp_cds_context->aMsgWrappers[iter]));
259 }
260
261 /* Now Open the CDS Scheduler */
Anurag Chouhanf04e84f2016-03-03 10:12:12 +0530262 qdf_status = cds_sched_open(gp_cds_context, &gp_cds_context->qdf_sched,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800263 sizeof(cds_sched_context));
264
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530265 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800266 /* Critical Error ... Cannot proceed further */
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530267 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_FATAL,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800268 "%s: Failed to open CDS Scheduler", __func__);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530269 QDF_ASSERT(0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800270 goto err_msg_queue;
271 }
272
273 pHddCtx = (hdd_context_t *) (gp_cds_context->pHDDContext);
274 if ((NULL == pHddCtx) || (NULL == pHddCtx->config)) {
275 /* Critical Error ... Cannot proceed further */
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530276 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_FATAL,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800277 "%s: Hdd Context is Null", __func__);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530278 QDF_ASSERT(0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800279 goto err_sched_close;
280 }
281
Anurag Chouhan6d760662016-02-20 16:05:43 +0530282 scn = cds_get_context(QDF_MODULE_ID_HIF);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800283 if (!scn) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530284 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_FATAL,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800285 "%s: scn is null!", __func__);
286 goto err_sched_close;
287 }
Komal Seelamc11bb222016-01-27 18:57:10 +0530288
Komal Seelamec702b02016-02-24 18:42:16 +0530289 hdd_update_config(pHddCtx);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800290
Anurag Chouhan6d760662016-02-20 16:05:43 +0530291 ol_ctx = cds_get_context(QDF_MODULE_ID_BMI);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800292 /* Initialize BMI and Download firmware */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530293 qdf_status = bmi_download_firmware(ol_ctx);
294 if (qdf_status != QDF_STATUS_SUCCESS) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530295 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_FATAL,
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530296 "BMI FIALED status:%d", qdf_status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800297 goto err_bmi_close;
298 }
299
Komal Seelam08633492016-02-24 18:05:07 +0530300 htcInfo.pContext = ol_ctx;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800301 htcInfo.TargetFailure = ol_target_failure;
302 htcInfo.TargetSendSuspendComplete = wma_target_suspend_acknowledge;
Anurag Chouhan6d760662016-02-20 16:05:43 +0530303 qdf_ctx = cds_get_context(QDF_MODULE_ID_QDF_DEVICE);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800304
305 /* Create HTC */
306 gp_cds_context->htc_ctx =
Yue Ma1e11d792016-02-26 18:58:44 -0800307 htc_create(scn, &htcInfo, qdf_ctx, cds_get_conparam());
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800308 if (!gp_cds_context->htc_ctx) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530309 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_FATAL,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800310 "%s: Failed to Create HTC", __func__);
311 goto err_bmi_close;
312 }
313
Komal Seelamd9106492016-02-15 10:31:44 +0530314 if (bmi_done(ol_ctx)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530315 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_FATAL,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800316 "%s: Failed to complete BMI phase", __func__);
317 goto err_htc_close;
318 }
319
320 /*
321 ** Need to open WMA first because it calls WDI_Init, which calls wpalOpen
322 ** The reason that is needed becasue cds_packet_open need to use PAL APIs
323 */
324
325 /*Open the WMA module */
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530326 qdf_mem_set(&mac_openParms, sizeof(mac_openParms), 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800327 /* UMA is supported in hardware for performing the
328 ** frame translation 802.11 <-> 802.3
329 */
330 mac_openParms.frameTransRequired = 1;
331 mac_openParms.driverType = eDRIVER_TYPE_PRODUCTION;
332 mac_openParms.powersaveOffloadEnabled =
333 pHddCtx->config->enablePowersaveOffload;
334 mac_openParms.staDynamicDtim = pHddCtx->config->enableDynamicDTIM;
335 mac_openParms.staModDtim = pHddCtx->config->enableModulatedDTIM;
336 mac_openParms.staMaxLIModDtim = pHddCtx->config->fMaxLIModulatedDTIM;
337 mac_openParms.wowEnable = pHddCtx->config->wowEnable;
338 mac_openParms.maxWoWFilters = pHddCtx->config->maxWoWFilters;
339 /* Here olIniInfo is used to store ini status of arp offload
340 * ns offload and others. Currently 1st bit is used for arp
341 * off load and 2nd bit for ns offload currently, rest bits are unused
342 */
343 if (pHddCtx->config->fhostArpOffload)
344 mac_openParms.olIniInfo = mac_openParms.olIniInfo | 0x1;
345 if (pHddCtx->config->fhostNSOffload)
346 mac_openParms.olIniInfo = mac_openParms.olIniInfo | 0x2;
347 /*
348 * Copy the DFS Phyerr Filtering Offload status.
349 * This parameter reflects the value of the
350 * dfsPhyerrFilterOffload flag as set in the ini.
351 */
352 mac_openParms.dfsPhyerrFilterOffload =
353 pHddCtx->config->fDfsPhyerrFilterOffload;
354 if (pHddCtx->config->ssdp)
355 mac_openParms.ssdp = pHddCtx->config->ssdp;
356#ifdef FEATURE_WLAN_RA_FILTERING
357 mac_openParms.RArateLimitInterval =
358 pHddCtx->config->RArateLimitInterval;
359 mac_openParms.IsRArateLimitEnabled =
360 pHddCtx->config->IsRArateLimitEnabled;
361#endif
362
363 mac_openParms.apMaxOffloadPeers = pHddCtx->config->apMaxOffloadPeers;
364
365 mac_openParms.apMaxOffloadReorderBuffs =
366 pHddCtx->config->apMaxOffloadReorderBuffs;
367
368 mac_openParms.apDisableIntraBssFwd =
369 pHddCtx->config->apDisableIntraBssFwd;
370
371 mac_openParms.dfsRadarPriMultiplier =
372 pHddCtx->config->dfsRadarPriMultiplier;
373 mac_openParms.reorderOffload = pHddCtx->config->reorderOffloadSupport;
374
375 /* IPA micro controller data path offload resource config item */
376 mac_openParms.ucOffloadEnabled = hdd_ipa_uc_is_enabled(pHddCtx);
377 mac_openParms.ucTxBufCount = pHddCtx->config->IpaUcTxBufCount;
378 mac_openParms.ucTxBufSize = pHddCtx->config->IpaUcTxBufSize;
379 mac_openParms.ucRxIndRingCount = pHddCtx->config->IpaUcRxIndRingCount;
380 mac_openParms.ucTxPartitionBase = pHddCtx->config->IpaUcTxPartitionBase;
381 mac_openParms.max_scan = pHddCtx->config->max_scan_count;
382
383 mac_openParms.ip_tcp_udp_checksum_offload =
384 pHddCtx->config->enable_ip_tcp_udp_checksum_offload;
385 mac_openParms.enable_rxthread = pHddCtx->config->enableRxThread;
386 mac_openParms.ce_classify_enabled =
387 pHddCtx->config->ce_classify_enabled;
388
389#ifdef QCA_LL_TX_FLOW_CONTROL_V2
390 mac_openParms.tx_flow_stop_queue_th =
391 pHddCtx->config->TxFlowStopQueueThreshold;
392 mac_openParms.tx_flow_start_queue_offset =
393 pHddCtx->config->TxFlowStartQueueOffset;
394#endif
395 cds_set_nan_enable(&mac_openParms, pHddCtx);
396
397 mac_openParms.tx_chain_mask_cck = pHddCtx->config->tx_chain_mask_cck;
398 mac_openParms.self_gen_frm_pwr = pHddCtx->config->self_gen_frm_pwr;
Komal Seelam02d09342016-02-23 18:03:19 +0530399 mac_openParms.maxStation = pHddCtx->config->maxNumberOfPeers;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800400
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530401 qdf_status = wma_open(gp_cds_context,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800402 hdd_update_tgt_cfg,
403 hdd_dfs_indicate_radar, &mac_openParms);
404
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530405 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800406 /* Critical Error ... Cannot proceed further */
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530407 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_FATAL,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800408 "%s: Failed to open WMA module", __func__);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530409 QDF_ASSERT(0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800410 goto err_htc_close;
411 }
412
413 /* Number of peers limit differs in each chip version. If peer max
414 * limit configured in ini exceeds more than supported, WMA adjusts
415 * and keeps correct limit in mac_openParms.maxStation. So, make sure
416 * config entry pHddCtx->config->maxNumberOfPeers has adjusted value
417 */
418 pHddCtx->config->maxNumberOfPeers = mac_openParms.maxStation;
Anurag Chouhan6d760662016-02-20 16:05:43 +0530419 HTCHandle = cds_get_context(QDF_MODULE_ID_HTC);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800420 if (!HTCHandle) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530421 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_FATAL,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800422 "%s: HTCHandle is null!", __func__);
423 goto err_wma_close;
424 }
425 if (htc_wait_target(HTCHandle)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530426 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_FATAL,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800427 "%s: Failed to complete BMI phase", __func__);
428 goto err_wma_close;
429 }
430
431 /* Now proceed to open the MAC */
432
433 /* UMA is supported in hardware for performing the
434 * frame translation 802.11 <-> 802.3
435 */
436 mac_openParms.frameTransRequired = 1;
437
438 sirStatus =
439 mac_open(&(gp_cds_context->pMACContext), gp_cds_context->pHDDContext,
440 &mac_openParms);
441
442 if (eSIR_SUCCESS != sirStatus) {
443 /* Critical Error ... Cannot proceed further */
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530444 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_FATAL,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800445 "%s: Failed to open MAC", __func__);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530446 QDF_ASSERT(0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800447 goto err_wma_close;
448 }
449
450 /* Now proceed to open the SME */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530451 qdf_status = sme_open(gp_cds_context->pMACContext);
452 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800453 /* Critical Error ... Cannot proceed further */
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530454 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_FATAL,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800455 "%s: Failed to open SME", __func__);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530456 QDF_ASSERT(0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800457 goto err_mac_close;
458 }
459
460 gp_cds_context->pdev_txrx_ctx =
Dhanashri Atre12a08392016-02-17 13:10:34 -0800461 ol_txrx_pdev_attach(gp_cds_context->cfg_ctx,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800462 gp_cds_context->htc_ctx,
Anurag Chouhan6d760662016-02-20 16:05:43 +0530463 gp_cds_context->qdf_ctx);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800464 if (!gp_cds_context->pdev_txrx_ctx) {
465 /* Critical Error ... Cannot proceed further */
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530466 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_FATAL,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800467 "%s: Failed to open TXRX", __func__);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530468 QDF_ASSERT(0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800469 goto err_sme_close;
470 }
471
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530472 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_INFO_HIGH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800473 "%s: CDS successfully Opened", __func__);
474
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530475 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800476
477err_sme_close:
478 sme_close(gp_cds_context->pMACContext);
479
480err_mac_close:
481 mac_close(gp_cds_context->pMACContext);
482
483err_wma_close:
484 wma_close(gp_cds_context);
485
486 wma_wmi_service_close(gp_cds_context);
487
488err_htc_close:
489 if (gp_cds_context->htc_ctx) {
490 htc_destroy(gp_cds_context->htc_ctx);
491 gp_cds_context->htc_ctx = NULL;
492 }
493
494err_bmi_close:
Komal Seelam5a6e5082016-02-24 17:59:09 +0530495 bmi_cleanup(ol_ctx);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800496
497err_sched_close:
498 cds_sched_close(gp_cds_context);
499
500err_msg_queue:
501 cds_mq_deinit(&gp_cds_context->freeVosMq);
502
503err_wma_complete_event:
Anurag Chouhance0dc992016-02-16 18:18:03 +0530504 qdf_event_destroy(&gp_cds_context->wmaCompleteEvent);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800505
506err_probe_event:
Anurag Chouhance0dc992016-02-16 18:18:03 +0530507 qdf_event_destroy(&gp_cds_context->ProbeEvent);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800508
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530509 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800510} /* cds_open() */
511
512/**
513 * cds_pre_enable() - pre enable cds
514 * @cds_context: CDS context
515 *
Anurag Chouhanf04e84f2016-03-03 10:12:12 +0530516 * Return: QDF status
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800517 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530518QDF_STATUS cds_pre_enable(v_CONTEXT_t cds_context)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800519{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530520 QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800521 p_cds_contextType p_cds_context = (p_cds_contextType) cds_context;
522 void *scn;
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530523 QDF_TRACE(QDF_MODULE_ID_SYS, QDF_TRACE_LEVEL_INFO, "cds prestart");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800524
525 if (gp_cds_context != p_cds_context) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530526 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800527 "%s: Context mismatch", __func__);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530528 QDF_ASSERT(0);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530529 return QDF_STATUS_E_INVAL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800530 }
531
532 if (p_cds_context->pMACContext == NULL) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530533 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800534 "%s: MAC NULL context", __func__);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530535 QDF_ASSERT(0);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530536 return QDF_STATUS_E_INVAL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800537 }
538
539 if (p_cds_context->pWMAContext == NULL) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530540 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800541 "%s: WMA NULL context", __func__);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530542 QDF_ASSERT(0);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530543 return QDF_STATUS_E_INVAL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800544 }
545
Anurag Chouhan6d760662016-02-20 16:05:43 +0530546 scn = cds_get_context(QDF_MODULE_ID_HIF);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800547 if (!scn) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530548 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_FATAL,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800549 "%s: scn is null!", __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530550 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800551 }
552
553 /* Reset wma wait event */
Anurag Chouhance0dc992016-02-16 18:18:03 +0530554 qdf_event_reset(&gp_cds_context->wmaCompleteEvent);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800555
556 /*call WMA pre start */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530557 qdf_status = wma_pre_start(gp_cds_context);
558 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530559 QDF_TRACE(QDF_MODULE_ID_SYS, QDF_TRACE_LEVEL_FATAL,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800560 "Failed to WMA prestart");
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530561 QDF_ASSERT(0);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530562 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800563 }
564
565 /* Need to update time out of complete */
Anurag Chouhance0dc992016-02-16 18:18:03 +0530566 qdf_status = qdf_wait_single_event(&gp_cds_context->wmaCompleteEvent,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800567 CDS_WMA_TIMEOUT);
Anurag Chouhance0dc992016-02-16 18:18:03 +0530568 if (qdf_status != QDF_STATUS_SUCCESS) {
569 if (qdf_status == QDF_STATUS_E_TIMEOUT) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530570 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800571 "%s: Timeout occurred before WMA complete",
572 __func__);
573 } else {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530574 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800575 "%s: wma_pre_start reporting other error",
576 __func__);
577 }
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530578 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800579 "%s: Test MC thread by posting a probe message to SYS",
580 __func__);
581 wlan_sys_probe();
582
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530583 QDF_ASSERT(0);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530584 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800585 }
586
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530587 qdf_status = htc_start(gp_cds_context->htc_ctx);
588 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530589 QDF_TRACE(QDF_MODULE_ID_SYS, QDF_TRACE_LEVEL_FATAL,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800590 "Failed to Start HTC");
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530591 QDF_ASSERT(0);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530592 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800593 }
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530594 qdf_status = wma_wait_for_ready_event(gp_cds_context->pWMAContext);
595 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530596 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_FATAL,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800597 "Failed to get ready event from target firmware");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800598 htc_stop(gp_cds_context->htc_ctx);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530599 QDF_ASSERT(0);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530600 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800601 }
602
Dhanashri Atre12a08392016-02-17 13:10:34 -0800603 if (ol_txrx_pdev_post_attach(gp_cds_context->pdev_txrx_ctx)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530604 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_FATAL,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800605 "Failed to attach pdev");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800606 htc_stop(gp_cds_context->htc_ctx);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530607 QDF_ASSERT(0);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530608 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800609 }
610
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530611 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800612}
613
614/**
615 * cds_enable() - start/enable cds module
616 * @cds_context: CDS context
617 *
Anurag Chouhanf04e84f2016-03-03 10:12:12 +0530618 * Return: QDF status
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800619 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530620QDF_STATUS cds_enable(v_CONTEXT_t cds_context)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800621{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530622 QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800623 tSirRetStatus sirStatus = eSIR_SUCCESS;
624 p_cds_contextType p_cds_context = (p_cds_contextType) cds_context;
625 tHalMacStartParameters halStartParams;
626
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530627 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_INFO,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800628 "%s: Starting Libra SW", __func__);
629
630 /* We support only one instance for now ... */
631 if (gp_cds_context != p_cds_context) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530632 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800633 "%s: mismatch in context", __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530634 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800635 }
636
637 if ((p_cds_context->pWMAContext == NULL) ||
638 (p_cds_context->pMACContext == NULL)) {
639 if (p_cds_context->pWMAContext == NULL)
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530640 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800641 "%s: WMA NULL context", __func__);
642 else
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530643 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800644 "%s: MAC NULL context", __func__);
645
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530646 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800647 }
648
649 /* Start the wma */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530650 qdf_status = wma_start(p_cds_context);
651 if (qdf_status != QDF_STATUS_SUCCESS) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530652 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800653 "%s: Failed to start wma", __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530654 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800655 }
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530656 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_INFO,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800657 "%s: wma correctly started", __func__);
658
659 /* Start the MAC */
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530660 qdf_mem_zero(&halStartParams,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800661 sizeof(tHalMacStartParameters));
662
663 /* Start the MAC */
664 sirStatus =
665 mac_start(p_cds_context->pMACContext, &halStartParams);
666
667 if (eSIR_SUCCESS != sirStatus) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530668 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_FATAL,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800669 "%s: Failed to start MAC", __func__);
670 goto err_wma_stop;
671 }
672
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530673 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_INFO,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800674 "%s: MAC correctly started", __func__);
675
676 /* START SME */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530677 qdf_status = sme_start(p_cds_context->pMACContext);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800678
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530679 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530680 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_FATAL,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800681 "%s: Failed to start SME", __func__);
682 goto err_mac_stop;
683 }
684
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530685 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_INFO,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800686 "%s: SME correctly started", __func__);
687
688 if (ol_txrx_pdev_attach_target
Dhanashri Atre12a08392016-02-17 13:10:34 -0800689 (p_cds_context->pdev_txrx_ctx)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530690 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_FATAL,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800691 "%s: Failed attach target", __func__);
692 goto err_sme_stop;
693 }
694
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530695 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_INFO,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800696 "TL correctly started");
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530697 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_INFO,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800698 "%s: CDS Start is successful!!", __func__);
699
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530700 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800701
702err_sme_stop:
703 sme_stop(p_cds_context->pMACContext, HAL_STOP_TYPE_SYS_RESET);
704
705err_mac_stop:
706 mac_stop(p_cds_context->pMACContext, HAL_STOP_TYPE_SYS_RESET);
707
708err_wma_stop:
Anurag Chouhance0dc992016-02-16 18:18:03 +0530709 qdf_event_reset(&(gp_cds_context->wmaCompleteEvent));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530710 qdf_status = wma_stop(p_cds_context, HAL_STOP_TYPE_RF_KILL);
711 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530712 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800713 "%s: Failed to stop wma", __func__);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530714 QDF_ASSERT(QDF_IS_STATUS_SUCCESS(qdf_status));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800715 wma_setneedshutdown(cds_context);
716 } else {
Anurag Chouhance0dc992016-02-16 18:18:03 +0530717 qdf_status =
718 qdf_wait_single_event(&(gp_cds_context->wmaCompleteEvent),
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800719 CDS_WMA_TIMEOUT);
Anurag Chouhance0dc992016-02-16 18:18:03 +0530720 if (qdf_status != QDF_STATUS_SUCCESS) {
721 if (qdf_status == QDF_STATUS_E_TIMEOUT) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530722 QDF_TRACE(QDF_MODULE_ID_QDF,
723 QDF_TRACE_LEVEL_FATAL,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800724 "%s: Timeout occurred before WMA_stop complete",
725 __func__);
726 } else {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530727 QDF_TRACE(QDF_MODULE_ID_QDF,
728 QDF_TRACE_LEVEL_FATAL,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800729 "%s: WMA_stop reporting other error",
730 __func__);
731 }
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530732 QDF_ASSERT(0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800733 wma_setneedshutdown(cds_context);
734 }
735 }
736
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530737 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800738} /* cds_enable() */
739
740/**
741 * cds_disable() - stop/disable cds module
742 * @cds_context: CDS context
743 *
Anurag Chouhanf04e84f2016-03-03 10:12:12 +0530744 * Return: QDF status
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800745 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530746QDF_STATUS cds_disable(v_CONTEXT_t cds_context)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800747{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530748 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800749
750 /* wma_stop is called before the SYS so that the processing of target
751 * pending responses will not be handled during uninitialization of
752 * WLAN driver
753 */
Anurag Chouhance0dc992016-02-16 18:18:03 +0530754 qdf_event_reset(&(gp_cds_context->wmaCompleteEvent));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800755
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530756 qdf_status = wma_stop(cds_context, HAL_STOP_TYPE_RF_KILL);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800757
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530758 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530759 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800760 "%s: Failed to stop wma", __func__);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530761 QDF_ASSERT(QDF_IS_STATUS_SUCCESS(qdf_status));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800762 wma_setneedshutdown(cds_context);
763 }
764
765 hif_disable_isr(((cds_context_type *) cds_context)->pHIFContext);
766 hif_reset_soc(((cds_context_type *) cds_context)->pHIFContext);
767
768 /* SYS STOP will stop SME and MAC */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530769 qdf_status = sys_stop(cds_context);
770 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530771 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800772 "%s: Failed to stop SYS", __func__);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530773 QDF_ASSERT(QDF_IS_STATUS_SUCCESS(qdf_status));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800774 }
775
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530776 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800777}
778
779/**
780 * cds_close() - close cds module
781 * @cds_context: CDS context
782 *
Anurag Chouhanf04e84f2016-03-03 10:12:12 +0530783 * Return: QDF status
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800784 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530785QDF_STATUS cds_close(v_CONTEXT_t cds_context)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800786{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530787 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800788
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530789 qdf_status = wma_wmi_work_close(cds_context);
790 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530791 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Xun Luoa858a472015-11-10 08:24:45 -0800792 "%s: Failed to close wma_wmi_work", __func__);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530793 QDF_ASSERT(0);
Xun Luoa858a472015-11-10 08:24:45 -0800794 }
795
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800796 if (gp_cds_context->htc_ctx) {
797 htc_stop(gp_cds_context->htc_ctx);
798 htc_destroy(gp_cds_context->htc_ctx);
799 gp_cds_context->htc_ctx = NULL;
800 }
801
802 ol_txrx_pdev_detach(gp_cds_context->pdev_txrx_ctx, 1);
Anurag Chouhan6d760662016-02-20 16:05:43 +0530803 cds_free_context(cds_context, QDF_MODULE_ID_TXRX,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800804 gp_cds_context->pdev_txrx_ctx);
805
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530806 qdf_status = sme_close(((p_cds_contextType) cds_context)->pMACContext);
807 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530808 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800809 "%s: Failed to close SME", __func__);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530810 QDF_ASSERT(QDF_IS_STATUS_SUCCESS(qdf_status));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800811 }
812
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530813 qdf_status = mac_close(((p_cds_contextType) cds_context)->pMACContext);
814 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530815 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800816 "%s: Failed to close MAC", __func__);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530817 QDF_ASSERT(QDF_IS_STATUS_SUCCESS(qdf_status));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800818 }
819
820 ((p_cds_contextType) cds_context)->pMACContext = NULL;
821
822 if (true == wma_needshutdown(cds_context)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530823 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800824 "%s: Failed to shutdown wma", __func__);
825 } else {
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530826 qdf_status = wma_close(cds_context);
827 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530828 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800829 "%s: Failed to close wma", __func__);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530830 QDF_ASSERT(QDF_IS_STATUS_SUCCESS(qdf_status));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800831 }
832 }
833
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530834 qdf_status = wma_wmi_service_close(cds_context);
835 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530836 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800837 "%s: Failed to close wma_wmi_service", __func__);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530838 QDF_ASSERT(QDF_IS_STATUS_SUCCESS(qdf_status));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800839 }
840
841 cds_mq_deinit(&((p_cds_contextType) cds_context)->freeVosMq);
842
Anurag Chouhance0dc992016-02-16 18:18:03 +0530843 qdf_status = qdf_event_destroy(&gp_cds_context->wmaCompleteEvent);
844 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530845 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800846 "%s: failed to destroy wmaCompleteEvent", __func__);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530847 QDF_ASSERT(QDF_IS_STATUS_SUCCESS(qdf_status));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800848 }
849
Anurag Chouhance0dc992016-02-16 18:18:03 +0530850 qdf_status = qdf_event_destroy(&gp_cds_context->ProbeEvent);
851 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530852 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800853 "%s: failed to destroy ProbeEvent", __func__);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530854 QDF_ASSERT(QDF_IS_STATUS_SUCCESS(qdf_status));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800855 }
856
Mohit Khannaebf8a862016-04-28 17:53:59 -0700857 /* De-Initialize protocol trace functionality */
858 cds_pkt_proto_trace_deinit();
859
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800860 cds_deinit_log_completion();
Prashanth Bhattac2a16f62015-12-03 15:06:15 -0800861
862 gp_cds_context->pHDDContext = NULL;
863
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530864 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800865}
866
867/**
868 * cds_get_context() - get context data area
869 *
870 * @moduleId: ID of the module who's context data is being retrived.
871 *
872 * Each module in the system has a context / data area that is allocated
873 * and managed by CDS. This API allows any user to get a pointer to its
874 * allocated context data area from the CDS global context.
875 *
876 * Return: pointer to the context data area of the module ID
877 * specified, or NULL if the context data is not allocated for
878 * the module ID specified
879 */
Anurag Chouhan6d760662016-02-20 16:05:43 +0530880void *cds_get_context(QDF_MODULE_ID moduleId)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800881{
882 void *pModContext = NULL;
883
884 if (gp_cds_context == NULL) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530885 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800886 "%s: cds context pointer is null", __func__);
887 return NULL;
888 }
889
890 switch (moduleId) {
Anurag Chouhan6d760662016-02-20 16:05:43 +0530891 case QDF_MODULE_ID_HDD:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800892 {
893 pModContext = gp_cds_context->pHDDContext;
894 break;
895 }
896
Anurag Chouhan6d760662016-02-20 16:05:43 +0530897 case QDF_MODULE_ID_SME:
898 case QDF_MODULE_ID_PE:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800899 {
900 /* In all these cases, we just return the MAC Context */
901 pModContext = gp_cds_context->pMACContext;
902 break;
903 }
904
Anurag Chouhan6d760662016-02-20 16:05:43 +0530905 case QDF_MODULE_ID_WMA:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800906 {
907 /* For wma module */
908 pModContext = gp_cds_context->pWMAContext;
909 break;
910 }
911
Anurag Chouhan6d760662016-02-20 16:05:43 +0530912 case QDF_MODULE_ID_QDF:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800913 {
914 /* For SYS this is CDS itself */
915 pModContext = gp_cds_context;
916 break;
917 }
918
Anurag Chouhan6d760662016-02-20 16:05:43 +0530919 case QDF_MODULE_ID_HIF:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800920 {
921 pModContext = gp_cds_context->pHIFContext;
922 break;
923 }
924
Anurag Chouhan6d760662016-02-20 16:05:43 +0530925 case QDF_MODULE_ID_HTC:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800926 {
927 pModContext = gp_cds_context->htc_ctx;
928 break;
929 }
930
Anurag Chouhan6d760662016-02-20 16:05:43 +0530931 case QDF_MODULE_ID_QDF_DEVICE:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800932 {
Anurag Chouhan6d760662016-02-20 16:05:43 +0530933 pModContext = gp_cds_context->qdf_ctx;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800934 break;
935 }
936
Anurag Chouhan6d760662016-02-20 16:05:43 +0530937 case QDF_MODULE_ID_BMI:
Komal Seelamd9106492016-02-15 10:31:44 +0530938 {
939 pModContext = gp_cds_context->g_ol_context;
940 break;
941 }
942
Anurag Chouhan6d760662016-02-20 16:05:43 +0530943 case QDF_MODULE_ID_TXRX:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800944 {
945 pModContext = gp_cds_context->pdev_txrx_ctx;
946 break;
947 }
948
Anurag Chouhan6d760662016-02-20 16:05:43 +0530949 case QDF_MODULE_ID_CFG:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800950 {
951 pModContext = gp_cds_context->cfg_ctx;
952 break;
953 }
954
955 default:
956 {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530957 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800958 "%s: Module ID %i does not have its context maintained by CDS",
959 __func__, moduleId);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530960 QDF_ASSERT(0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800961 return NULL;
962 }
963 }
964
965 if (pModContext == NULL) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530966 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800967 "%s: Module ID %i context is Null", __func__,
968 moduleId);
969 }
970
971 return pModContext;
972} /* cds_get_context() */
973
974/**
975 * cds_get_global_context() - get CDS global Context
976 *
977 * This API allows any user to get the CDS Global Context pointer from a
978 * module context data area.
979 *
980 * Return: pointer to the CDS global context, NULL if the function is
981 * unable to retreive the CDS context.
982 */
983v_CONTEXT_t cds_get_global_context(void)
984{
985 if (gp_cds_context == NULL) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530986 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800987 "%s: global cds context is NULL", __func__);
988 }
989
990 return gp_cds_context;
991} /* cds_get_global_context() */
992
993/**
Prashanth Bhatta9e143052015-12-04 11:56:47 -0800994 * cds_get_driver_state() - Get current driver state
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800995 *
Prashanth Bhatta9e143052015-12-04 11:56:47 -0800996 * This API returns current driver state stored in global context.
997 *
998 * Return: Driver state enum
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800999 */
Prashanth Bhatta9e143052015-12-04 11:56:47 -08001000enum cds_driver_state cds_get_driver_state(void)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001001{
1002 if (gp_cds_context == NULL) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301003 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001004 "%s: global cds context is NULL", __func__);
Prashanth Bhatta9e143052015-12-04 11:56:47 -08001005
1006 return CDS_DRIVER_STATE_UNINITIALIZED;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001007 }
1008
Prashanth Bhatta9e143052015-12-04 11:56:47 -08001009 return gp_cds_context->driver_state;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001010}
1011
1012/**
Prashanth Bhatta9e143052015-12-04 11:56:47 -08001013 * cds_set_driver_state() - Set current driver state
1014 * @state: Driver state to be set to.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001015 *
Prashanth Bhatta9e143052015-12-04 11:56:47 -08001016 * This API sets driver state to state. This API only sets the state and doesn't
1017 * clear states, please make sure to use cds_clear_driver_state to clear any
1018 * state if required.
1019 *
1020 * Return: None
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001021 */
Prashanth Bhatta9e143052015-12-04 11:56:47 -08001022void cds_set_driver_state(enum cds_driver_state state)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001023{
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001024 if (gp_cds_context == NULL) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301025 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prashanth Bhatta9e143052015-12-04 11:56:47 -08001026 "%s: global cds context is NULL: %x", __func__,
1027 state);
1028
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001029 return;
1030 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001031
Prashanth Bhatta9e143052015-12-04 11:56:47 -08001032 gp_cds_context->driver_state |= state;
1033}
1034
1035/**
1036 * cds_clear_driver_state() - Clear current driver state
1037 * @state: Driver state to be cleared.
1038 *
1039 * This API clears driver state. This API only clears the state, please make
1040 * sure to use cds_set_driver_state to set any new states.
1041 *
1042 * Return: None
1043 */
1044void cds_clear_driver_state(enum cds_driver_state state)
1045{
1046 if (gp_cds_context == NULL) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301047 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prashanth Bhatta9e143052015-12-04 11:56:47 -08001048 "%s: global cds context is NULL: %x", __func__,
1049 state);
1050
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001051 return;
1052 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001053
Prashanth Bhatta9e143052015-12-04 11:56:47 -08001054 gp_cds_context->driver_state &= ~state;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001055}
1056
1057/**
1058 * cds_alloc_context() - allocate a context within the CDS global Context
1059 * @p_cds_context: pointer to the global Vos context
1060 * @moduleId: module ID who's context area is being allocated.
1061 * @ppModuleContext: pointer to location where the pointer to the
1062 * allocated context is returned. Note this output pointer
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301063 * is valid only if the API returns QDF_STATUS_SUCCESS
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001064 * @param size: size of the context area to be allocated.
1065 *
1066 * This API allows any user to allocate a user context area within the
1067 * CDS Global Context.
1068 *
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05301069 * Return: QDF status
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001070 */
Anurag Chouhan6d760662016-02-20 16:05:43 +05301071QDF_STATUS cds_alloc_context(void *p_cds_context, QDF_MODULE_ID moduleID,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001072 void **ppModuleContext, uint32_t size)
1073{
1074 void **pGpModContext = NULL;
1075
1076 if (p_cds_context == NULL) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301077 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001078 "%s: cds context is null", __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301079 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001080 }
1081
1082 if ((gp_cds_context != p_cds_context) || (ppModuleContext == NULL)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301083 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001084 "%s: context mismatch or null param passed",
1085 __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301086 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001087 }
1088
1089 switch (moduleID) {
Anurag Chouhan6d760662016-02-20 16:05:43 +05301090 case QDF_MODULE_ID_WMA:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001091 {
1092 pGpModContext = &(gp_cds_context->pWMAContext);
1093 break;
1094 }
1095
Anurag Chouhan6d760662016-02-20 16:05:43 +05301096 case QDF_MODULE_ID_HIF:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001097 {
1098 pGpModContext = &(gp_cds_context->pHIFContext);
1099 break;
1100 }
1101
Anurag Chouhan6d760662016-02-20 16:05:43 +05301102 case QDF_MODULE_ID_BMI:
Komal Seelamd9106492016-02-15 10:31:44 +05301103 {
1104 pGpModContext = &(gp_cds_context->g_ol_context);
1105 break;
1106 }
1107
Anurag Chouhan6d760662016-02-20 16:05:43 +05301108 case QDF_MODULE_ID_EPPING:
1109 case QDF_MODULE_ID_SME:
1110 case QDF_MODULE_ID_PE:
1111 case QDF_MODULE_ID_HDD:
1112 case QDF_MODULE_ID_HDD_SOFTAP:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001113 default:
1114 {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301115 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001116 "%s: Module ID %i "
1117 "does not have its context allocated by CDS",
1118 __func__, moduleID);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301119 QDF_ASSERT(0);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301120 return QDF_STATUS_E_INVAL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001121 }
1122 }
1123
1124 if (NULL != *pGpModContext) {
1125 /* Context has already been allocated!
1126 * Prevent double allocation
1127 */
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301128 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001129 "%s: Module ID %i context has already been allocated",
1130 __func__, moduleID);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301131 return QDF_STATUS_E_EXISTS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001132 }
1133
1134 /* Dynamically allocate the context for module */
1135
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301136 *ppModuleContext = qdf_mem_malloc(size);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001137
1138 if (*ppModuleContext == NULL) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301139 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001140 "%s: Failed to " "allocate Context for module ID %i",
1141 __func__, moduleID);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301142 QDF_ASSERT(0);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301143 return QDF_STATUS_E_NOMEM;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001144 }
1145
Anurag Chouhan6d760662016-02-20 16:05:43 +05301146 if (moduleID == QDF_MODULE_ID_TLSHIM)
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301147 qdf_mem_zero(*ppModuleContext, size);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001148
1149 *pGpModContext = *ppModuleContext;
1150
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301151 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001152} /* cds_alloc_context() */
1153
1154/**
Komal Seelamad5a90d2016-02-16 13:50:03 +05301155 * cds_set_context() - API to set context in global CDS Context
Komal Seelam1aac1982016-03-02 15:57:26 +05301156 * @module_id: Module ID
Komal Seelamad5a90d2016-02-16 13:50:03 +05301157 * @context: Pointer to the Module Context
1158 *
Komal Seelam1aac1982016-03-02 15:57:26 +05301159 * API to set a MODULE Context in global CDS Context
Komal Seelamad5a90d2016-02-16 13:50:03 +05301160 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301161 * Return: QDF_STATUS
Komal Seelamad5a90d2016-02-16 13:50:03 +05301162 */
Anurag Chouhan6d760662016-02-20 16:05:43 +05301163QDF_STATUS cds_set_context(QDF_MODULE_ID module_id, void *context)
Komal Seelamad5a90d2016-02-16 13:50:03 +05301164{
1165 p_cds_contextType p_cds_context = cds_get_global_context();
1166
1167 if (!p_cds_context) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301168 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Komal Seelam1aac1982016-03-02 15:57:26 +05301169 "cds context is Invalid");
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301170 return QDF_STATUS_NOT_INITIALIZED;
Komal Seelamad5a90d2016-02-16 13:50:03 +05301171 }
1172
1173 switch (module_id) {
Anurag Chouhan6d760662016-02-20 16:05:43 +05301174 case QDF_MODULE_ID_HIF:
Komal Seelamad5a90d2016-02-16 13:50:03 +05301175 p_cds_context->pHIFContext = context;
1176 break;
1177 default:
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301178 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Komal Seelam1aac1982016-03-02 15:57:26 +05301179 "%s: Module ID %i does not have its context managed by CDS",
1180 __func__, module_id);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301181 QDF_ASSERT(0);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301182 return QDF_STATUS_E_INVAL;
Komal Seelamad5a90d2016-02-16 13:50:03 +05301183 }
1184
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301185 return QDF_STATUS_SUCCESS;
Komal Seelamad5a90d2016-02-16 13:50:03 +05301186}
1187
1188/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001189 * cds_free_context() - free an allocated context within the
1190 * CDS global Context
1191 * @p_cds_context: pointer to the global Vos context
1192 * @moduleId: module ID who's context area is being free
1193 * @pModuleContext: pointer to module context area to be free'd.
1194 *
1195 * This API allows a user to free the user context area within the
1196 * CDS Global Context.
1197 *
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05301198 * Return: QDF status
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001199 */
Anurag Chouhan6d760662016-02-20 16:05:43 +05301200QDF_STATUS cds_free_context(void *p_cds_context, QDF_MODULE_ID moduleID,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001201 void *pModuleContext)
1202{
1203 void **pGpModContext = NULL;
1204
1205 if ((p_cds_context == NULL) || (gp_cds_context != p_cds_context) ||
1206 (pModuleContext == NULL)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301207 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001208 "%s: Null params or context mismatch", __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301209 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001210 }
1211
1212 switch (moduleID) {
Anurag Chouhan6d760662016-02-20 16:05:43 +05301213 case QDF_MODULE_ID_WMA:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001214 {
1215 pGpModContext = &(gp_cds_context->pWMAContext);
1216 break;
1217 }
1218
Anurag Chouhan6d760662016-02-20 16:05:43 +05301219 case QDF_MODULE_ID_HIF:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001220 {
1221 pGpModContext = &(gp_cds_context->pHIFContext);
1222 break;
1223 }
1224
Anurag Chouhan6d760662016-02-20 16:05:43 +05301225 case QDF_MODULE_ID_TXRX:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001226 {
1227 pGpModContext = &(gp_cds_context->pdev_txrx_ctx);
1228 break;
1229 }
1230
Anurag Chouhan6d760662016-02-20 16:05:43 +05301231 case QDF_MODULE_ID_BMI:
Komal Seelamd9106492016-02-15 10:31:44 +05301232 {
1233 pGpModContext = &(gp_cds_context->g_ol_context);
1234 break;
1235 }
1236
Anurag Chouhan6d760662016-02-20 16:05:43 +05301237 case QDF_MODULE_ID_EPPING:
1238 case QDF_MODULE_ID_HDD:
1239 case QDF_MODULE_ID_SME:
1240 case QDF_MODULE_ID_PE:
1241 case QDF_MODULE_ID_HDD_SOFTAP:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001242 default:
1243 {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301244 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001245 "%s: Module ID %i "
1246 "does not have its context allocated by CDS",
1247 __func__, moduleID);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301248 QDF_ASSERT(0);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301249 return QDF_STATUS_E_INVAL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001250 }
1251 }
1252
1253 if (NULL == *pGpModContext) {
1254 /* Context has not been allocated or freed already! */
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301255 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001256 "%s: Module ID %i "
1257 "context has not been allocated or freed already",
1258 __func__, moduleID);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301259 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001260 }
1261
1262 if (*pGpModContext != pModuleContext) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301263 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001264 "%s: pGpModContext != pModuleContext", __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301265 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001266 }
1267
1268 if (pModuleContext != NULL)
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301269 qdf_mem_free(pModuleContext);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001270
1271 *pGpModContext = NULL;
1272
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301273 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001274} /* cds_free_context() */
1275
1276/**
1277 * cds_mq_post_message() - post a message to a message queue
1278 * @msgQueueId: identifies the message queue upon which the message
1279 * will be posted.
1280 * @message: a pointer to a message buffer. Memory for this message
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05301281 * buffer is allocated by the caller and free'd by the QDF after the
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001282 * message is posted to the message queue. If the consumer of the
1283 * message needs anything in this message, it needs to copy the contents
1284 * before returning from the message queue handler.
1285 *
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05301286 * Return: QDF status
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001287 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301288QDF_STATUS cds_mq_post_message(CDS_MQ_ID msgQueueId, cds_msg_t *pMsg)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001289{
1290 p_cds_mq_type pTargetMq = NULL;
1291 p_cds_msg_wrapper pMsgWrapper = NULL;
1292 uint32_t debug_count = 0;
1293
1294 if ((gp_cds_context == NULL) || (pMsg == NULL)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301295 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001296 "%s: Null params or global cds context is null",
1297 __func__);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301298 QDF_ASSERT(0);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301299 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001300 }
1301
1302 switch (msgQueueId) {
1303 /* Message Queue ID for messages bound for SME */
1304 case CDS_MQ_ID_SME:
1305 {
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05301306 pTargetMq = &(gp_cds_context->qdf_sched.smeMcMq);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001307 break;
1308 }
1309
1310 /* Message Queue ID for messages bound for PE */
1311 case CDS_MQ_ID_PE:
1312 {
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05301313 pTargetMq = &(gp_cds_context->qdf_sched.peMcMq);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001314 break;
1315 }
1316
1317 /* Message Queue ID for messages bound for wma */
1318 case CDS_MQ_ID_WMA:
1319 {
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05301320 pTargetMq = &(gp_cds_context->qdf_sched.wmaMcMq);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001321 break;
1322 }
1323
1324 /* Message Queue ID for messages bound for the SYS module */
1325 case CDS_MQ_ID_SYS:
1326 {
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05301327 pTargetMq = &(gp_cds_context->qdf_sched.sysMcMq);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001328 break;
1329 }
1330
1331 default:
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301332 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001333 ("%s: Trying to queue msg into unknown MC Msg queue ID %d"),
1334 __func__, msgQueueId);
1335
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301336 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001337 }
1338
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301339 QDF_ASSERT(NULL != pTargetMq);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001340 if (pTargetMq == NULL) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301341 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001342 "%s: pTargetMq == NULL", __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301343 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001344 }
1345
1346 /* Try and get a free Msg wrapper */
1347 pMsgWrapper = cds_mq_get(&gp_cds_context->freeVosMq);
1348
1349 if (NULL == pMsgWrapper) {
1350 debug_count = atomic_inc_return(&cds_wrapper_empty_count);
Abhishek Singh5ea86532016-04-27 14:10:53 +05301351 if (1 == debug_count) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301352 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001353 "%s: CDS Core run out of message wrapper %d",
1354 __func__, debug_count);
Abhishek Singh5ea86532016-04-27 14:10:53 +05301355 cds_flush_logs(WLAN_LOG_TYPE_FATAL,
1356 WLAN_LOG_INDICATOR_HOST_ONLY,
1357 WLAN_LOG_REASON_VOS_MSG_UNDER_RUN,
1358 true, false);
1359 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001360 if (CDS_WRAPPER_MAX_FAIL_COUNT == debug_count)
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301361 QDF_BUG(0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001362
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301363 return QDF_STATUS_E_RESOURCES;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001364 }
1365
1366 atomic_set(&cds_wrapper_empty_count, 0);
1367
1368 /* Copy the message now */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301369 qdf_mem_copy((void *)pMsgWrapper->pVosMsg,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001370 (void *)pMsg, sizeof(cds_msg_t));
1371
1372 cds_mq_put(pTargetMq, pMsgWrapper);
1373
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05301374 set_bit(MC_POST_EVENT_MASK, &gp_cds_context->qdf_sched.mcEventFlag);
1375 wake_up_interruptible(&gp_cds_context->qdf_sched.mcWaitQueue);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001376
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301377 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001378} /* cds_mq_post_message() */
1379
1380/**
1381 * cds_sys_probe_thread_cback() - probe mc thread callback
1382 * @pUserData: pointer to user data
1383 *
1384 * Return: none
1385 */
1386void cds_sys_probe_thread_cback(void *pUserData)
1387{
1388 if (gp_cds_context != pUserData) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301389 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001390 "%s: gp_cds_context != pUserData", __func__);
1391 return;
1392 }
1393
Anurag Chouhance0dc992016-02-16 18:18:03 +05301394 if (qdf_event_set(&gp_cds_context->ProbeEvent) != QDF_STATUS_SUCCESS) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301395 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Anurag Chouhance0dc992016-02-16 18:18:03 +05301396 "%s: qdf_event_set failed", __func__);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001397 return;
1398 }
1399} /* cds_sys_probe_thread_cback() */
1400
1401/**
1402 * cds_wma_complete_cback() - wma complete callback
1403 * @pUserData: pointer to user data
1404 *
1405 * Return: none
1406 */
1407void cds_wma_complete_cback(void *pUserData)
1408{
1409 if (gp_cds_context != pUserData) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301410 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001411 "%s: gp_cds_context != pUserData", __func__);
1412 return;
1413 }
1414
Anurag Chouhance0dc992016-02-16 18:18:03 +05301415 if (qdf_event_set(&gp_cds_context->wmaCompleteEvent) !=
1416 QDF_STATUS_SUCCESS) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301417 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Anurag Chouhance0dc992016-02-16 18:18:03 +05301418 "%s: qdf_event_set failed", __func__);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001419 return;
1420 }
1421} /* cds_wma_complete_cback() */
1422
1423/**
1424 * cds_core_return_msg() - return core message
1425 * @pVContext: pointer to cds context
1426 * @pMsgWrapper: pointer to message wrapper
1427 *
1428 * Return: none
1429 */
1430void cds_core_return_msg(void *pVContext, p_cds_msg_wrapper pMsgWrapper)
1431{
1432 p_cds_contextType p_cds_context = (p_cds_contextType) pVContext;
1433
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301434 QDF_ASSERT(gp_cds_context == p_cds_context);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001435
1436 if (gp_cds_context != p_cds_context) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301437 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001438 "%s: gp_cds_context != p_cds_context", __func__);
1439 return;
1440 }
1441
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301442 QDF_ASSERT(NULL != pMsgWrapper);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001443
1444 if (pMsgWrapper == NULL) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301445 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001446 "%s: pMsgWrapper == NULL in function", __func__);
1447 return;
1448 }
1449
1450 /*
1451 ** Return the message on the free message queue
1452 */
1453 INIT_LIST_HEAD(&pMsgWrapper->msgNode);
1454 cds_mq_put(&p_cds_context->freeVosMq, pMsgWrapper);
1455} /* cds_core_return_msg() */
1456
1457
1458/**
1459 * cds_shutdown() - shutdown CDS
1460 * @cds_context: global cds context
1461 *
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05301462 * Return: QDF status
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001463 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301464QDF_STATUS cds_shutdown(v_CONTEXT_t cds_context)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001465{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301466 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001467 tpAniSirGlobal pmac = (((p_cds_contextType)cds_context)->pMACContext);
1468
1469 ol_txrx_pdev_detach(gp_cds_context->pdev_txrx_ctx, 1);
Anurag Chouhan6d760662016-02-20 16:05:43 +05301470 cds_free_context(cds_context, QDF_MODULE_ID_TXRX,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001471 gp_cds_context->pdev_txrx_ctx);
1472
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301473 qdf_status = sme_close(((p_cds_contextType) cds_context)->pMACContext);
1474 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
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: Failed to close SME", __func__);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301477 QDF_ASSERT(QDF_IS_STATUS_SUCCESS(qdf_status));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001478 }
1479 /*
1480 * CAC timer will be initiated and started only when SAP starts on
1481 * DFS channel and it will be stopped and destroyed immediately once the
1482 * radar detected or timedout. So as per design CAC timer should be
1483 * destroyed after stop
1484 */
1485 if (pmac->sap.SapDfsInfo.is_dfs_cac_timer_running) {
Anurag Chouhan210db072016-02-22 18:42:15 +05301486 qdf_mc_timer_stop(&pmac->sap.SapDfsInfo.sap_dfs_cac_timer);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001487 pmac->sap.SapDfsInfo.is_dfs_cac_timer_running = 0;
Anurag Chouhan210db072016-02-22 18:42:15 +05301488 qdf_mc_timer_destroy(&pmac->sap.SapDfsInfo.sap_dfs_cac_timer);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001489 }
1490
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301491 qdf_status = mac_close(((p_cds_contextType) cds_context)->pMACContext);
1492 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301493 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001494 "%s: Failed to close MAC", __func__);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301495 QDF_ASSERT(QDF_IS_STATUS_SUCCESS(qdf_status));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001496 }
1497
1498 ((p_cds_contextType) cds_context)->pMACContext = NULL;
1499
1500 if (false == wma_needshutdown(cds_context)) {
1501
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301502 qdf_status = wma_close(cds_context);
1503 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301504 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001505 "%s: Failed to close wma!", __func__);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301506 QDF_ASSERT(QDF_IS_STATUS_SUCCESS(qdf_status));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001507 }
1508 }
1509
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301510 qdf_status = wma_wmi_work_close(cds_context);
1511 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301512 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Xun Luoa858a472015-11-10 08:24:45 -08001513 "%s: Failed to close wma_wmi_work!", __func__);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301514 QDF_ASSERT(0);
Xun Luoa858a472015-11-10 08:24:45 -08001515 }
1516
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001517 if (gp_cds_context->htc_ctx) {
1518 htc_stop(gp_cds_context->htc_ctx);
1519 htc_destroy(gp_cds_context->htc_ctx);
1520 gp_cds_context->htc_ctx = NULL;
1521 }
1522
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301523 qdf_status = wma_wmi_service_close(cds_context);
1524 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301525 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001526 "%s: Failed to close wma_wmi_service!", __func__);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301527 QDF_ASSERT(QDF_IS_STATUS_SUCCESS(qdf_status));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001528 }
1529
1530 cds_mq_deinit(&((p_cds_contextType) cds_context)->freeVosMq);
1531
Anurag Chouhance0dc992016-02-16 18:18:03 +05301532 qdf_status = qdf_event_destroy(&gp_cds_context->wmaCompleteEvent);
1533 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301534 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001535 "%s: failed to destroy wmaCompleteEvent", __func__);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301536 QDF_ASSERT(QDF_IS_STATUS_SUCCESS(qdf_status));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001537 }
1538
Anurag Chouhance0dc992016-02-16 18:18:03 +05301539 qdf_status = qdf_event_destroy(&gp_cds_context->ProbeEvent);
1540 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301541 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001542 "%s: failed to destroy ProbeEvent", __func__);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301543 QDF_ASSERT(QDF_IS_STATUS_SUCCESS(qdf_status));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001544 }
1545
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301546 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001547}
1548
1549/**
1550 * cds_get_vdev_types() - get vdev type
1551 * @mode: mode
1552 * @type: type
1553 * @sub_type: sub_type
1554 *
1555 * Return: WMI vdev type
1556 */
Anurag Chouhan6d760662016-02-20 16:05:43 +05301557QDF_STATUS cds_get_vdev_types(enum tQDF_ADAPTER_MODE mode, uint32_t *type,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001558 uint32_t *sub_type)
1559{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301560 QDF_STATUS status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001561 *type = 0;
1562 *sub_type = 0;
1563
1564 switch (mode) {
Anurag Chouhan6d760662016-02-20 16:05:43 +05301565 case QDF_STA_MODE:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001566 *type = WMI_VDEV_TYPE_STA;
1567 break;
Anurag Chouhan6d760662016-02-20 16:05:43 +05301568 case QDF_SAP_MODE:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001569 *type = WMI_VDEV_TYPE_AP;
1570 break;
Anurag Chouhan6d760662016-02-20 16:05:43 +05301571 case QDF_P2P_DEVICE_MODE:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001572 *type = WMI_VDEV_TYPE_AP;
1573 *sub_type = WMI_UNIFIED_VDEV_SUBTYPE_P2P_DEVICE;
1574 break;
Anurag Chouhan6d760662016-02-20 16:05:43 +05301575 case QDF_P2P_CLIENT_MODE:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001576 *type = WMI_VDEV_TYPE_STA;
1577 *sub_type = WMI_UNIFIED_VDEV_SUBTYPE_P2P_CLIENT;
1578 break;
Anurag Chouhan6d760662016-02-20 16:05:43 +05301579 case QDF_P2P_GO_MODE:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001580 *type = WMI_VDEV_TYPE_AP;
1581 *sub_type = WMI_UNIFIED_VDEV_SUBTYPE_P2P_GO;
1582 break;
Anurag Chouhan6d760662016-02-20 16:05:43 +05301583 case QDF_OCB_MODE:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001584 *type = WMI_VDEV_TYPE_OCB;
1585 break;
Krunal Soni8c37e322016-02-03 16:08:37 -08001586 case QDF_IBSS_MODE:
1587 *type = WMI_VDEV_TYPE_IBSS;
1588 break;
Manjunathappa Prakashb7573722016-04-21 11:24:07 -07001589 case QDF_MONITOR_MODE:
1590 *type = WMI_VDEV_TYPE_MONITOR;
1591 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001592 default:
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301593 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Ryan Hsud7e6fc72015-12-07 17:26:14 -08001594 "Invalid device mode %d", mode);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301595 status = QDF_STATUS_E_INVAL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001596 break;
1597 }
1598 return status;
1599}
1600
1601/**
1602 * cds_flush_work() - flush pending works
1603 * @work: pointer to work
1604 *
1605 * Return: none
1606 */
1607void cds_flush_work(void *work)
1608{
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001609 cancel_work_sync(work);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001610}
1611
1612/**
1613 * cds_flush_delayed_work() - flush delayed works
1614 * @dwork: pointer to delayed work
1615 *
1616 * Return: none
1617 */
1618void cds_flush_delayed_work(void *dwork)
1619{
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001620 cancel_delayed_work_sync(dwork);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001621}
1622
1623/**
1624 * cds_is_packet_log_enabled() - check if packet log is enabled
1625 *
1626 * Return: true if packet log is enabled else false
1627 */
1628bool cds_is_packet_log_enabled(void)
1629{
1630 hdd_context_t *pHddCtx;
1631
1632 pHddCtx = (hdd_context_t *) (gp_cds_context->pHDDContext);
1633 if ((NULL == pHddCtx) || (NULL == pHddCtx->config)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301634 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_FATAL,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001635 "%s: Hdd Context is Null", __func__);
1636 return false;
1637 }
1638
1639 return pHddCtx->config->enablePacketLog;
1640}
1641
1642/**
1643 * cds_trigger_recovery() - trigger self recovery
1644 *
1645 * Return: none
1646 */
1647void cds_trigger_recovery(void)
1648{
Anurag Chouhan6d760662016-02-20 16:05:43 +05301649 tp_wma_handle wma_handle = cds_get_context(QDF_MODULE_ID_WMA);
Anurag Chouhance0dc992016-02-16 18:18:03 +05301650 QDF_STATUS status = QDF_STATUS_SUCCESS;
Houston Hoffmanc7c72a82015-12-07 15:30:48 -08001651 qdf_runtime_lock_t recovery_lock;
Yuanyuan Liu0e0aa932016-05-12 10:17:58 -07001652 qdf_device_t qdf_ctx = cds_get_context(QDF_MODULE_ID_QDF_DEVICE);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001653
1654 if (!wma_handle) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301655 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Komal Seelam1aac1982016-03-02 15:57:26 +05301656 "WMA context is invalid!");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001657 return;
1658 }
1659
Houston Hoffmanc7c72a82015-12-07 15:30:48 -08001660 recovery_lock = qdf_runtime_lock_init("cds_recovery");
1661 if (!recovery_lock) {
1662 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
1663 "Could not acquire runtime pm lock!");
1664 return;
1665 }
1666
1667 qdf_runtime_pm_prevent_suspend(recovery_lock);
1668
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001669 wma_crash_inject(wma_handle, RECOVERY_SIM_SELF_RECOVERY, 0);
1670
Anurag Chouhance0dc992016-02-16 18:18:03 +05301671 status = qdf_wait_single_event(&wma_handle->recovery_event,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001672 WMA_CRASH_INJECT_TIMEOUT);
1673
Anurag Chouhance0dc992016-02-16 18:18:03 +05301674 if (QDF_STATUS_SUCCESS != status) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301675 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001676 "CRASH_INJECT command is timed out!");
Prashanth Bhatta9e143052015-12-04 11:56:47 -08001677 if (cds_is_driver_recovering()) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301678 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prashanth Bhatta9e143052015-12-04 11:56:47 -08001679 "Recovery is in progress, ignore!");
Houston Hoffmanc7c72a82015-12-07 15:30:48 -08001680 } else {
1681 cds_set_recovery_in_progress(true);
Yuanyuan Liu0e0aa932016-05-12 10:17:58 -07001682 pld_schedule_recovery_work(qdf_ctx->dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001683 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001684 }
Houston Hoffmanc7c72a82015-12-07 15:30:48 -08001685
1686 qdf_runtime_pm_allow_suspend(recovery_lock);
1687 qdf_runtime_lock_deinit(recovery_lock);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001688}
1689
1690/**
1691 * cds_get_monotonic_boottime() - Get kernel boot time.
1692 *
1693 * Return: Time in microseconds
1694 */
1695
1696uint64_t cds_get_monotonic_boottime(void)
1697{
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001698 struct timespec ts;
1699
Yuanyuan Liu2e03b412016-04-06 14:36:15 -07001700 get_monotonic_boottime(&ts);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001701 return ((uint64_t) ts.tv_sec * 1000000) + (ts.tv_nsec / 1000);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001702}
1703
1704/**
1705 * cds_set_wakelock_logging() - Logging of wakelock enabled/disabled
1706 * @value: Boolean value
1707 *
1708 * This function is used to set the flag which will indicate whether
1709 * logging of wakelock is enabled or not
1710 *
1711 * Return: None
1712 */
1713void cds_set_wakelock_logging(bool value)
1714{
1715 p_cds_contextType p_cds_context;
1716
1717 p_cds_context = cds_get_global_context();
1718 if (!p_cds_context) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301719 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001720 "cds context is Invald");
1721 return;
1722 }
1723 p_cds_context->is_wakelock_log_enabled = value;
1724}
1725
1726/**
1727 * cds_is_wakelock_enabled() - Check if logging of wakelock is enabled/disabled
1728 * @value: Boolean value
1729 *
1730 * This function is used to check whether logging of wakelock is enabled or not
1731 *
1732 * Return: true if logging of wakelock is enabled
1733 */
1734bool cds_is_wakelock_enabled(void)
1735{
1736 p_cds_contextType p_cds_context;
1737
1738 p_cds_context = cds_get_global_context();
1739 if (!p_cds_context) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301740 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001741 "cds context is Invald");
1742 return false;
1743 }
1744 return p_cds_context->is_wakelock_log_enabled;
1745}
1746
1747/**
1748 * cds_set_ring_log_level() - Sets the log level of a particular ring
1749 * @ring_id: ring_id
1750 * @log_levelvalue: Log level specificed
1751 *
1752 * This function converts HLOS values to driver log levels and sets the log
1753 * level of a particular ring accordingly.
1754 *
1755 * Return: None
1756 */
1757void cds_set_ring_log_level(uint32_t ring_id, uint32_t log_level)
1758{
1759 p_cds_contextType p_cds_context;
1760 uint32_t log_val;
1761
1762 p_cds_context = cds_get_global_context();
1763 if (!p_cds_context) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301764 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001765 "%s: cds context is Invald", __func__);
1766 return;
1767 }
1768
1769 switch (log_level) {
1770 case LOG_LEVEL_NO_COLLECTION:
1771 log_val = WLAN_LOG_LEVEL_OFF;
1772 break;
1773 case LOG_LEVEL_NORMAL_COLLECT:
1774 log_val = WLAN_LOG_LEVEL_NORMAL;
1775 break;
1776 case LOG_LEVEL_ISSUE_REPRO:
1777 log_val = WLAN_LOG_LEVEL_REPRO;
1778 break;
1779 case LOG_LEVEL_ACTIVE:
1780 default:
1781 log_val = WLAN_LOG_LEVEL_ACTIVE;
1782 break;
1783 }
1784
1785 if (ring_id == RING_ID_WAKELOCK) {
1786 p_cds_context->wakelock_log_level = log_val;
1787 return;
1788 } else if (ring_id == RING_ID_CONNECTIVITY) {
1789 p_cds_context->connectivity_log_level = log_val;
1790 return;
1791 } else if (ring_id == RING_ID_PER_PACKET_STATS) {
1792 p_cds_context->packet_stats_log_level = log_val;
1793 return;
Chandrasekaran, Manishekar907c2af2015-11-13 12:50:04 +05301794 } else if (ring_id == RING_ID_DRIVER_DEBUG) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001795 p_cds_context->driver_debug_log_level = log_val;
1796 return;
1797 } else if (ring_id == RING_ID_FIRMWARE_DEBUG) {
1798 p_cds_context->fw_debug_log_level = log_val;
1799 return;
1800 }
1801}
1802
1803/**
1804 * cds_get_ring_log_level() - Get the a ring id's log level
1805 * @ring_id: Ring id
1806 *
1807 * Fetch and return the log level corresponding to a ring id
1808 *
1809 * Return: Log level corresponding to the ring ID
1810 */
1811enum wifi_driver_log_level cds_get_ring_log_level(uint32_t ring_id)
1812{
1813 p_cds_contextType p_cds_context;
1814
1815 p_cds_context = cds_get_global_context();
1816 if (!p_cds_context) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301817 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001818 "%s: cds context is Invald", __func__);
1819 return WLAN_LOG_LEVEL_OFF;
1820 }
1821
1822 if (ring_id == RING_ID_WAKELOCK)
1823 return p_cds_context->wakelock_log_level;
1824 else if (ring_id == RING_ID_CONNECTIVITY)
1825 return p_cds_context->connectivity_log_level;
1826 else if (ring_id == RING_ID_PER_PACKET_STATS)
1827 return p_cds_context->packet_stats_log_level;
Chandrasekaran, Manishekar907c2af2015-11-13 12:50:04 +05301828 else if (ring_id == RING_ID_DRIVER_DEBUG)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001829 return p_cds_context->driver_debug_log_level;
1830 else if (ring_id == RING_ID_FIRMWARE_DEBUG)
1831 return p_cds_context->fw_debug_log_level;
1832
1833 return WLAN_LOG_LEVEL_OFF;
1834}
1835
1836/**
1837 * cds_set_multicast_logging() - Set mutlicast logging value
1838 * @value: Value of multicast logging
1839 *
1840 * Set the multicast logging value which will indicate
1841 * whether to multicast host and fw messages even
1842 * without any registration by userspace entity
1843 *
1844 * Return: None
1845 */
1846void cds_set_multicast_logging(uint8_t value)
1847{
1848 cds_multicast_logging = value;
1849}
1850
1851/**
1852 * cds_is_multicast_logging() - Get multicast logging value
1853 *
1854 * Get the multicast logging value which will indicate
1855 * whether to multicast host and fw messages even
1856 * without any registration by userspace entity
1857 *
1858 * Return: 0 - Multicast logging disabled, 1 - Multicast logging enabled
1859 */
1860uint8_t cds_is_multicast_logging(void)
1861{
1862 return cds_multicast_logging;
1863}
1864
1865/*
1866 * cds_init_log_completion() - Initialize log param structure
1867 *
1868 * This function is used to initialize the logging related
1869 * parameters
1870 *
1871 * Return: None
1872 */
1873void cds_init_log_completion(void)
1874{
1875 p_cds_contextType p_cds_context;
1876
1877 p_cds_context = cds_get_global_context();
1878 if (!p_cds_context) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301879 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001880 "%s: cds context is Invalid", __func__);
1881 return;
1882 }
1883
1884 p_cds_context->log_complete.is_fatal = WLAN_LOG_TYPE_NON_FATAL;
1885 p_cds_context->log_complete.indicator = WLAN_LOG_INDICATOR_UNUSED;
1886 p_cds_context->log_complete.reason_code = WLAN_LOG_REASON_CODE_UNUSED;
1887 p_cds_context->log_complete.is_report_in_progress = false;
1888 /* Attempting to initialize an already initialized lock
1889 * results in a failure. This must be ok here.
1890 */
Anurag Chouhana37b5b72016-02-21 14:53:42 +05301891 qdf_spinlock_create(&p_cds_context->bug_report_lock);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001892}
1893
1894/**
1895 * cds_deinit_log_completion() - Deinitialize log param structure
1896 *
1897 * This function is used to deinitialize the logging related
1898 * parameters
1899 *
1900 * Return: None
1901 */
1902void cds_deinit_log_completion(void)
1903{
1904 p_cds_contextType p_cds_context;
1905
1906 p_cds_context = cds_get_global_context();
1907 if (!p_cds_context) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301908 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001909 "%s: cds context is Invalid", __func__);
1910 return;
1911 }
1912
Anurag Chouhana37b5b72016-02-21 14:53:42 +05301913 qdf_spinlock_destroy(&p_cds_context->bug_report_lock);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001914}
1915
1916/**
1917 * cds_set_log_completion() - Store the logging params
1918 * @is_fatal: Indicates if the event triggering bug report is fatal or not
1919 * @indicator: Source which trigerred the bug report
1920 * @reason_code: Reason for triggering bug report
Abhishek Singh5ea86532016-04-27 14:10:53 +05301921 * @recovery_needed: If recovery is needed after bug report
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001922 *
1923 * This function is used to set the logging parameters based on the
1924 * caller
1925 *
1926 * Return: 0 if setting of params is successful
1927 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301928QDF_STATUS cds_set_log_completion(uint32_t is_fatal,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001929 uint32_t indicator,
Abhishek Singh5ea86532016-04-27 14:10:53 +05301930 uint32_t reason_code,
1931 bool recovery_needed)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001932{
1933 p_cds_contextType p_cds_context;
1934
1935 p_cds_context = cds_get_global_context();
1936 if (!p_cds_context) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301937 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001938 "%s: cds context is Invalid", __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301939 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001940 }
1941
Anurag Chouhana37b5b72016-02-21 14:53:42 +05301942 qdf_spinlock_acquire(&p_cds_context->bug_report_lock);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001943 p_cds_context->log_complete.is_fatal = is_fatal;
1944 p_cds_context->log_complete.indicator = indicator;
1945 p_cds_context->log_complete.reason_code = reason_code;
Abhishek Singh5ea86532016-04-27 14:10:53 +05301946 p_cds_context->log_complete.recovery_needed = recovery_needed;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001947 p_cds_context->log_complete.is_report_in_progress = true;
Anurag Chouhana37b5b72016-02-21 14:53:42 +05301948 qdf_spinlock_release(&p_cds_context->bug_report_lock);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301949 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001950}
1951
1952/**
Abhishek Singh5ea86532016-04-27 14:10:53 +05301953 * cds_get_and_reset_log_completion() - Get and reset logging related params
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001954 * @is_fatal: Indicates if the event triggering bug report is fatal or not
1955 * @indicator: Source which trigerred the bug report
1956 * @reason_code: Reason for triggering bug report
Abhishek Singh5ea86532016-04-27 14:10:53 +05301957 * @recovery_needed: If recovery is needed after bug report
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001958 *
1959 * This function is used to get the logging related parameters
1960 *
1961 * Return: None
1962 */
Abhishek Singh5ea86532016-04-27 14:10:53 +05301963void cds_get_and_reset_log_completion(uint32_t *is_fatal,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001964 uint32_t *indicator,
Abhishek Singh5ea86532016-04-27 14:10:53 +05301965 uint32_t *reason_code,
1966 bool *recovery_needed)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001967{
1968 p_cds_contextType p_cds_context;
1969
1970 p_cds_context = cds_get_global_context();
1971 if (!p_cds_context) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301972 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001973 "%s: cds context is Invalid", __func__);
1974 return;
1975 }
1976
Anurag Chouhana37b5b72016-02-21 14:53:42 +05301977 qdf_spinlock_acquire(&p_cds_context->bug_report_lock);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001978 *is_fatal = p_cds_context->log_complete.is_fatal;
1979 *indicator = p_cds_context->log_complete.indicator;
1980 *reason_code = p_cds_context->log_complete.reason_code;
Abhishek Singh5ea86532016-04-27 14:10:53 +05301981 *recovery_needed = p_cds_context->log_complete.recovery_needed;
1982
1983 /* reset */
1984 p_cds_context->log_complete.indicator = WLAN_LOG_INDICATOR_UNUSED;
1985 p_cds_context->log_complete.is_fatal = WLAN_LOG_TYPE_NON_FATAL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001986 p_cds_context->log_complete.is_report_in_progress = false;
Abhishek Singh5ea86532016-04-27 14:10:53 +05301987 p_cds_context->log_complete.reason_code = WLAN_LOG_REASON_CODE_UNUSED;
1988 p_cds_context->log_complete.recovery_needed = false;
Anurag Chouhana37b5b72016-02-21 14:53:42 +05301989 qdf_spinlock_release(&p_cds_context->bug_report_lock);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001990}
1991
1992/**
1993 * cds_is_log_report_in_progress() - Check if bug reporting is in progress
1994 *
1995 * This function is used to check if the bug reporting is already in progress
1996 *
1997 * Return: true if the bug reporting is in progress
1998 */
1999bool cds_is_log_report_in_progress(void)
2000{
2001 p_cds_contextType p_cds_context;
2002
2003 p_cds_context = cds_get_global_context();
2004 if (!p_cds_context) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302005 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002006 "%s: cds context is Invalid", __func__);
2007 return true;
2008 }
2009 return p_cds_context->log_complete.is_report_in_progress;
2010}
2011
2012/**
Abhishek Singh5ea86532016-04-27 14:10:53 +05302013 * cds_is_fatal_event_enabled() - Return if fatal event is enabled
2014 *
2015 * Return true if fatal event is enabled.
2016 */
2017bool cds_is_fatal_event_enabled(void)
2018{
2019 p_cds_contextType p_cds_context;
2020
2021 p_cds_context = cds_get_global_context();
2022 if (!p_cds_context) {
2023 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
2024 "%s: cds context is Invalid", __func__);
2025 return false;
2026 }
2027
2028
2029 return p_cds_context->enable_fatal_event;
2030}
2031
2032/**
2033 * cds_get_log_indicator() - Get the log flush indicator
2034 *
2035 * This function is used to get the log flush indicator
2036 *
2037 * Return: log indicator
2038 */
2039uint32_t cds_get_log_indicator(void)
2040{
2041 p_cds_contextType p_cds_context;
2042 uint32_t indicator;
2043
2044 p_cds_context = cds_get_global_context();
2045 if (!p_cds_context) {
2046 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
2047 "%s: cds context is Invalid", __func__);
2048 return WLAN_LOG_INDICATOR_UNUSED;
2049 }
2050
2051 if (cds_is_load_or_unload_in_progress() ||
2052 cds_is_driver_recovering()) {
2053 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
2054 "%s: vos context initialization is in progress"
2055 , __func__);
2056 return WLAN_LOG_INDICATOR_UNUSED;
2057 }
2058
2059 qdf_spinlock_acquire(&p_cds_context->bug_report_lock);
2060 indicator = p_cds_context->log_complete.indicator;
2061 qdf_spinlock_release(&p_cds_context->bug_report_lock);
2062 return indicator;
2063}
2064
2065/**
2066 * cds_wlan_flush_host_logs_for_fatal() - Wrapper to flush host logs
2067 *
2068 * This function is used to send signal to the logger thread to
2069 * flush the host logs.
2070 *
2071 * Return: None
2072 *
2073 */
2074void cds_wlan_flush_host_logs_for_fatal(void)
2075{
2076 wlan_flush_host_logs_for_fatal();
2077}
2078
2079/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002080 * cds_flush_logs() - Report fatal event to userspace
2081 * @is_fatal: Indicates if the event triggering bug report is fatal or not
2082 * @indicator: Source which trigerred the bug report
2083 * @reason_code: Reason for triggering bug report
Abhishek Singh5ea86532016-04-27 14:10:53 +05302084 * @dump_mac_trace: If mac trace are needed in logs.
2085 * @recovery_needed: If recovery is needed after bug report
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002086 *
2087 * This function sets the log related params and send the WMI command to the
2088 * FW to flush its logs. On receiving the flush completion event from the FW
2089 * the same will be conveyed to userspace
2090 *
2091 * Return: 0 on success
2092 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302093QDF_STATUS cds_flush_logs(uint32_t is_fatal,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002094 uint32_t indicator,
Abhishek Singh5ea86532016-04-27 14:10:53 +05302095 uint32_t reason_code,
2096 bool dump_mac_trace,
2097 bool recovery_needed)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002098{
2099 uint32_t ret;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302100 QDF_STATUS status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002101
2102 p_cds_contextType p_cds_context;
2103
2104 p_cds_context = cds_get_global_context();
2105 if (!p_cds_context) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302106 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002107 "%s: cds context is Invalid", __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302108 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002109 }
Abhishek Singh5ea86532016-04-27 14:10:53 +05302110 if (!p_cds_context->enable_fatal_event) {
2111 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
2112 "%s: Fatal event not enabled", __func__);
2113 return QDF_STATUS_E_FAILURE;
2114 }
2115 if (cds_is_load_or_unload_in_progress() ||
2116 cds_is_driver_recovering()) {
2117 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
2118 "%s: un/Load/SSR in progress", __func__);
2119 return QDF_STATUS_E_FAILURE;
2120 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002121
2122 if (cds_is_log_report_in_progress() == true) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302123 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002124 "%s: Bug report already in progress - dropping! type:%d, indicator=%d reason_code=%d",
2125 __func__, is_fatal, indicator, reason_code);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302126 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002127 }
2128
Abhishek Singh5ea86532016-04-27 14:10:53 +05302129 status = cds_set_log_completion(is_fatal, indicator,
2130 reason_code, recovery_needed);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302131 if (QDF_STATUS_SUCCESS != status) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302132 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002133 "%s: Failed to set log trigger params", __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302134 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002135 }
2136
Abhishek Singh5ea86532016-04-27 14:10:53 +05302137 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002138 "%s: Triggering bug report: type:%d, indicator=%d reason_code=%d",
2139 __func__, is_fatal, indicator, reason_code);
2140
Abhishek Singh5ea86532016-04-27 14:10:53 +05302141 if (dump_mac_trace)
2142 qdf_trace_dump_all(p_cds_context->pMACContext, 0, 0, 500, 0);
2143
2144 if (WLAN_LOG_INDICATOR_HOST_ONLY == indicator) {
2145 cds_wlan_flush_host_logs_for_fatal();
2146 return QDF_STATUS_SUCCESS;
2147 }
2148
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002149 ret = sme_send_flush_logs_cmd_to_fw(p_cds_context->pMACContext);
2150 if (0 != ret) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302151 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002152 "%s: Failed to send flush FW log", __func__);
2153 cds_init_log_completion();
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302154 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002155 }
2156
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302157 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002158}
2159
2160/**
2161 * cds_logging_set_fw_flush_complete() - Wrapper for FW log flush completion
2162 *
2163 * This function is used to send signal to the logger thread to indicate
2164 * that the flushing of FW logs is complete by the FW
2165 *
2166 * Return: None
2167 *
2168 */
2169void cds_logging_set_fw_flush_complete(void)
2170{
2171 wlan_logging_set_fw_flush_complete();
2172}
Abhishek Singh5ea86532016-04-27 14:10:53 +05302173
2174/**
2175 * cds_set_fatal_event() - set fatal event status
2176 * @value: pending statue to set
2177 *
2178 * Return: None
2179 */
2180void cds_set_fatal_event(bool value)
2181{
2182 p_cds_contextType p_cds_context;
2183
2184 p_cds_context = cds_get_global_context();
2185 if (!p_cds_context) {
2186 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
2187 "%s: cds context is Invalid", __func__);
2188 return;
2189 }
2190 p_cds_context->enable_fatal_event = value;
2191}
2192