blob: ad9ace313f705550032f7a5f0564c17af508eca1 [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>
48#ifdef CONFIG_CNSS
49#include <net/cnss.h>
50#endif
51
52#include "sap_api.h"
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +053053#include "qdf_trace.h"
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080054#include "bmi.h"
55#include "ol_fw.h"
56#include "ol_if_athvar.h"
57#include "hif.h"
Yue Ma1e11d792016-02-26 18:58:44 -080058#include "cds_concurrency.h"
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080059#include "cds_utils.h"
60#include "wlan_logging_sock_svc.h"
61#include "wma.h"
62
63#include "wlan_hdd_ipa.h"
64/* Preprocessor Definitions and Constants */
65
66/* Maximum number of cds message queue get wrapper failures to cause panic */
67#define CDS_WRAPPER_MAX_FAIL_COUNT (CDS_CORE_MAX_MESSAGES * 3)
68
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080069/* Data definitions */
70static cds_context_type g_cds_context;
71static p_cds_contextType gp_cds_context;
Anurag Chouhandf2b2682016-02-29 14:15:27 +053072static struct __qdf_device g_qdf_ctx;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080073
74/* Debug variable to detect MC thread stuck */
75static atomic_t cds_wrapper_empty_count;
76
77static uint8_t cds_multicast_logging;
78
79void cds_sys_probe_thread_cback(void *pUserData);
80
81/**
Prashanth Bhatta5da711e2015-11-30 14:28:52 -080082 * cds_init() - Initialize CDS
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080083 *
Prashanth Bhatta5da711e2015-11-30 14:28:52 -080084 * This function allocates the resource required for CDS, but does not
85 * initialize all the members. This overall initialization will happen at
86 * cds_open().
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080087 *
Prashanth Bhatta5da711e2015-11-30 14:28:52 -080088 * Return: Global context on success and NULL on failure.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080089 */
Prashanth Bhatta5da711e2015-11-30 14:28:52 -080090v_CONTEXT_t cds_init(void)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080091{
Anurag Chouhan210db072016-02-22 18:42:15 +053092 qdf_mc_timer_manager_init();
Anurag Chouhan600c3a02016-03-01 10:33:54 +053093 qdf_mem_init();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080094
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080095 gp_cds_context = &g_cds_context;
96
Anurag Chouhandf2b2682016-02-29 14:15:27 +053097 gp_cds_context->qdf_ctx = &g_qdf_ctx;
Anurag Chouhan600c3a02016-03-01 10:33:54 +053098 qdf_mem_zero(&g_qdf_ctx, sizeof(g_qdf_ctx));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080099
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530100 qdf_trace_spin_lock_init();
Prashanth Bhatta5da711e2015-11-30 14:28:52 -0800101
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800102#if defined(TRACE_RECORD)
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530103 qdf_trace_init();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800104#endif
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530105 qdf_dp_trace_init();
Prashanth Bhatta5da711e2015-11-30 14:28:52 -0800106
107 cds_ssr_protect_init();
108
109 return gp_cds_context;
110}
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800111
112/**
Prashanth Bhatta5da711e2015-11-30 14:28:52 -0800113 * cds_deinit() - Deinitialize CDS
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800114 *
Prashanth Bhatta5da711e2015-11-30 14:28:52 -0800115 * This function frees the CDS resources
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800116 */
Prashanth Bhatta5da711e2015-11-30 14:28:52 -0800117void cds_deinit(void)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800118{
Prashanth Bhatta5da711e2015-11-30 14:28:52 -0800119 if (gp_cds_context == NULL)
120 return;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800121
Anurag Chouhan6d760662016-02-20 16:05:43 +0530122 gp_cds_context->qdf_ctx = NULL;
Prashanth Bhatta5da711e2015-11-30 14:28:52 -0800123 gp_cds_context = NULL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800124
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530125 qdf_mem_zero(&g_cds_context, sizeof(g_cds_context));
Prashanth Bhatta9e143052015-12-04 11:56:47 -0800126
Anurag Chouhan210db072016-02-22 18:42:15 +0530127 qdf_mc_timer_manager_exit();
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530128 qdf_mem_exit();
Yuanyuan Liufd9bfc52015-12-14 15:44:20 -0800129
Prashanth Bhatta5da711e2015-11-30 14:28:52 -0800130 return;
131}
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800132
133#ifdef WLAN_FEATURE_NAN
134/**
135 * cds_set_nan_enable() - set nan enable flag in mac open param
136 * @wma_handle: Pointer to mac open param
137 * @hdd_ctx: Pointer to hdd context
138 *
139 * Return: none
140 */
141static void cds_set_nan_enable(tMacOpenParameters *param,
142 hdd_context_t *hdd_ctx)
143{
144 param->is_nan_enabled = hdd_ctx->config->enable_nan_support;
145}
146#else
147static void cds_set_nan_enable(tMacOpenParameters *param,
148 hdd_context_t *pHddCtx)
149{
150}
151#endif
152
153/**
154 * cds_open() - open the CDS Module
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800155 *
156 * cds_open() function opens the CDS Scheduler
157 * Upon successful initialization:
158 * - All CDS submodules should have been initialized
159 *
160 * - The CDS scheduler should have opened
161 *
162 * - All the WLAN SW components should have been opened. This includes
163 * SYS, MAC, SME, WMA and TL.
164 *
Anurag Chouhanf04e84f2016-03-03 10:12:12 +0530165 * Return: QDF status
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800166 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530167QDF_STATUS cds_open(void)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800168{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530169 QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800170 int iter = 0;
171 tSirRetStatus sirStatus = eSIR_SUCCESS;
172 tMacOpenParameters mac_openParms;
Anurag Chouhan6d760662016-02-20 16:05:43 +0530173 qdf_device_t qdf_ctx;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800174 HTC_INIT_INFO htcInfo;
Komal Seelamd9106492016-02-15 10:31:44 +0530175 struct ol_context *ol_ctx;
Komal Seelam3d202862016-02-24 18:43:24 +0530176 struct hif_opaque_softc *scn;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800177 void *HTCHandle;
178 hdd_context_t *pHddCtx;
179
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530180 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_INFO_HIGH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800181 "%s: Opening CDS", __func__);
182
183 if (NULL == gp_cds_context) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530184 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_FATAL,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800185 "%s: Trying to open CDS without a PreOpen", __func__);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530186 QDF_ASSERT(0);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530187 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800188 }
189
190 /* Initialize the timer module */
Anurag Chouhan210db072016-02-22 18:42:15 +0530191 qdf_timer_module_init();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800192
193 /* Initialize bug reporting structure */
194 cds_init_log_completion();
195
196 /* Initialize the probe event */
Anurag Chouhance0dc992016-02-16 18:18:03 +0530197 if (qdf_event_create(&gp_cds_context->ProbeEvent) != QDF_STATUS_SUCCESS) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530198 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_FATAL,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800199 "%s: Unable to init probeEvent", __func__);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530200 QDF_ASSERT(0);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530201 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800202 }
Anurag Chouhance0dc992016-02-16 18:18:03 +0530203 if (qdf_event_create(&(gp_cds_context->wmaCompleteEvent)) !=
204 QDF_STATUS_SUCCESS) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530205 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_FATAL,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800206 "%s: Unable to init wmaCompleteEvent", __func__);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530207 QDF_ASSERT(0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800208 goto err_probe_event;
209 }
210
211 /* Initialize the free message queue */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530212 qdf_status = cds_mq_init(&gp_cds_context->freeVosMq);
213 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800214 /* Critical Error ... Cannot proceed further */
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530215 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_FATAL,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800216 "%s: Failed to initialize CDS free message queue",
217 __func__);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530218 QDF_ASSERT(0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800219 goto err_wma_complete_event;
220 }
221
222 for (iter = 0; iter < CDS_CORE_MAX_MESSAGES; iter++) {
223 (gp_cds_context->aMsgWrappers[iter]).pVosMsg =
224 &(gp_cds_context->aMsgBuffers[iter]);
225 INIT_LIST_HEAD(&gp_cds_context->aMsgWrappers[iter].msgNode);
226 cds_mq_put(&gp_cds_context->freeVosMq,
227 &(gp_cds_context->aMsgWrappers[iter]));
228 }
229
230 /* Now Open the CDS Scheduler */
Anurag Chouhanf04e84f2016-03-03 10:12:12 +0530231 qdf_status = cds_sched_open(gp_cds_context, &gp_cds_context->qdf_sched,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800232 sizeof(cds_sched_context));
233
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530234 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800235 /* Critical Error ... Cannot proceed further */
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: Failed to open CDS Scheduler", __func__);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530238 QDF_ASSERT(0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800239 goto err_msg_queue;
240 }
241
242 pHddCtx = (hdd_context_t *) (gp_cds_context->pHDDContext);
243 if ((NULL == pHddCtx) || (NULL == pHddCtx->config)) {
244 /* Critical Error ... Cannot proceed further */
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530245 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_FATAL,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800246 "%s: Hdd Context is Null", __func__);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530247 QDF_ASSERT(0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800248 goto err_sched_close;
249 }
250
Anurag Chouhan6d760662016-02-20 16:05:43 +0530251 scn = cds_get_context(QDF_MODULE_ID_HIF);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800252 if (!scn) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530253 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_FATAL,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800254 "%s: scn is null!", __func__);
255 goto err_sched_close;
256 }
Komal Seelamc11bb222016-01-27 18:57:10 +0530257
Komal Seelamec702b02016-02-24 18:42:16 +0530258 hdd_update_config(pHddCtx);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800259
Anurag Chouhan6d760662016-02-20 16:05:43 +0530260 ol_ctx = cds_get_context(QDF_MODULE_ID_BMI);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800261 /* Initialize BMI and Download firmware */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530262 qdf_status = bmi_download_firmware(ol_ctx);
263 if (qdf_status != QDF_STATUS_SUCCESS) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530264 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_FATAL,
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530265 "BMI FIALED status:%d", qdf_status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800266 goto err_bmi_close;
267 }
268
Komal Seelam08633492016-02-24 18:05:07 +0530269 htcInfo.pContext = ol_ctx;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800270 htcInfo.TargetFailure = ol_target_failure;
271 htcInfo.TargetSendSuspendComplete = wma_target_suspend_acknowledge;
Anurag Chouhan6d760662016-02-20 16:05:43 +0530272 qdf_ctx = cds_get_context(QDF_MODULE_ID_QDF_DEVICE);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800273
274 /* Create HTC */
275 gp_cds_context->htc_ctx =
Yue Ma1e11d792016-02-26 18:58:44 -0800276 htc_create(scn, &htcInfo, qdf_ctx, cds_get_conparam());
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800277 if (!gp_cds_context->htc_ctx) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530278 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_FATAL,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800279 "%s: Failed to Create HTC", __func__);
280 goto err_bmi_close;
281 }
282
Komal Seelamd9106492016-02-15 10:31:44 +0530283 if (bmi_done(ol_ctx)) {
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: Failed to complete BMI phase", __func__);
286 goto err_htc_close;
287 }
288
289 /*
290 ** Need to open WMA first because it calls WDI_Init, which calls wpalOpen
291 ** The reason that is needed becasue cds_packet_open need to use PAL APIs
292 */
293
294 /*Open the WMA module */
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530295 qdf_mem_set(&mac_openParms, sizeof(mac_openParms), 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800296 /* UMA is supported in hardware for performing the
297 ** frame translation 802.11 <-> 802.3
298 */
299 mac_openParms.frameTransRequired = 1;
300 mac_openParms.driverType = eDRIVER_TYPE_PRODUCTION;
301 mac_openParms.powersaveOffloadEnabled =
302 pHddCtx->config->enablePowersaveOffload;
303 mac_openParms.staDynamicDtim = pHddCtx->config->enableDynamicDTIM;
304 mac_openParms.staModDtim = pHddCtx->config->enableModulatedDTIM;
305 mac_openParms.staMaxLIModDtim = pHddCtx->config->fMaxLIModulatedDTIM;
306 mac_openParms.wowEnable = pHddCtx->config->wowEnable;
307 mac_openParms.maxWoWFilters = pHddCtx->config->maxWoWFilters;
308 /* Here olIniInfo is used to store ini status of arp offload
309 * ns offload and others. Currently 1st bit is used for arp
310 * off load and 2nd bit for ns offload currently, rest bits are unused
311 */
312 if (pHddCtx->config->fhostArpOffload)
313 mac_openParms.olIniInfo = mac_openParms.olIniInfo | 0x1;
314 if (pHddCtx->config->fhostNSOffload)
315 mac_openParms.olIniInfo = mac_openParms.olIniInfo | 0x2;
316 /*
317 * Copy the DFS Phyerr Filtering Offload status.
318 * This parameter reflects the value of the
319 * dfsPhyerrFilterOffload flag as set in the ini.
320 */
321 mac_openParms.dfsPhyerrFilterOffload =
322 pHddCtx->config->fDfsPhyerrFilterOffload;
323 if (pHddCtx->config->ssdp)
324 mac_openParms.ssdp = pHddCtx->config->ssdp;
325#ifdef FEATURE_WLAN_RA_FILTERING
326 mac_openParms.RArateLimitInterval =
327 pHddCtx->config->RArateLimitInterval;
328 mac_openParms.IsRArateLimitEnabled =
329 pHddCtx->config->IsRArateLimitEnabled;
330#endif
331
332 mac_openParms.apMaxOffloadPeers = pHddCtx->config->apMaxOffloadPeers;
333
334 mac_openParms.apMaxOffloadReorderBuffs =
335 pHddCtx->config->apMaxOffloadReorderBuffs;
336
337 mac_openParms.apDisableIntraBssFwd =
338 pHddCtx->config->apDisableIntraBssFwd;
339
340 mac_openParms.dfsRadarPriMultiplier =
341 pHddCtx->config->dfsRadarPriMultiplier;
342 mac_openParms.reorderOffload = pHddCtx->config->reorderOffloadSupport;
343
344 /* IPA micro controller data path offload resource config item */
345 mac_openParms.ucOffloadEnabled = hdd_ipa_uc_is_enabled(pHddCtx);
346 mac_openParms.ucTxBufCount = pHddCtx->config->IpaUcTxBufCount;
347 mac_openParms.ucTxBufSize = pHddCtx->config->IpaUcTxBufSize;
348 mac_openParms.ucRxIndRingCount = pHddCtx->config->IpaUcRxIndRingCount;
349 mac_openParms.ucTxPartitionBase = pHddCtx->config->IpaUcTxPartitionBase;
350 mac_openParms.max_scan = pHddCtx->config->max_scan_count;
351
352 mac_openParms.ip_tcp_udp_checksum_offload =
353 pHddCtx->config->enable_ip_tcp_udp_checksum_offload;
354 mac_openParms.enable_rxthread = pHddCtx->config->enableRxThread;
355 mac_openParms.ce_classify_enabled =
356 pHddCtx->config->ce_classify_enabled;
357
358#ifdef QCA_LL_TX_FLOW_CONTROL_V2
359 mac_openParms.tx_flow_stop_queue_th =
360 pHddCtx->config->TxFlowStopQueueThreshold;
361 mac_openParms.tx_flow_start_queue_offset =
362 pHddCtx->config->TxFlowStartQueueOffset;
363#endif
364 cds_set_nan_enable(&mac_openParms, pHddCtx);
365
366 mac_openParms.tx_chain_mask_cck = pHddCtx->config->tx_chain_mask_cck;
367 mac_openParms.self_gen_frm_pwr = pHddCtx->config->self_gen_frm_pwr;
Komal Seelam02d09342016-02-23 18:03:19 +0530368 mac_openParms.maxStation = pHddCtx->config->maxNumberOfPeers;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800369
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530370 qdf_status = wma_open(gp_cds_context,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800371 hdd_update_tgt_cfg,
372 hdd_dfs_indicate_radar, &mac_openParms);
373
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530374 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800375 /* Critical Error ... Cannot proceed further */
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530376 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_FATAL,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800377 "%s: Failed to open WMA module", __func__);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530378 QDF_ASSERT(0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800379 goto err_htc_close;
380 }
381
382 /* Number of peers limit differs in each chip version. If peer max
383 * limit configured in ini exceeds more than supported, WMA adjusts
384 * and keeps correct limit in mac_openParms.maxStation. So, make sure
385 * config entry pHddCtx->config->maxNumberOfPeers has adjusted value
386 */
387 pHddCtx->config->maxNumberOfPeers = mac_openParms.maxStation;
Anurag Chouhan6d760662016-02-20 16:05:43 +0530388 HTCHandle = cds_get_context(QDF_MODULE_ID_HTC);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800389 if (!HTCHandle) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530390 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_FATAL,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800391 "%s: HTCHandle is null!", __func__);
392 goto err_wma_close;
393 }
394 if (htc_wait_target(HTCHandle)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530395 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_FATAL,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800396 "%s: Failed to complete BMI phase", __func__);
397 goto err_wma_close;
398 }
399
400 /* Now proceed to open the MAC */
401
402 /* UMA is supported in hardware for performing the
403 * frame translation 802.11 <-> 802.3
404 */
405 mac_openParms.frameTransRequired = 1;
406
407 sirStatus =
408 mac_open(&(gp_cds_context->pMACContext), gp_cds_context->pHDDContext,
409 &mac_openParms);
410
411 if (eSIR_SUCCESS != sirStatus) {
412 /* Critical Error ... Cannot proceed further */
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530413 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_FATAL,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800414 "%s: Failed to open MAC", __func__);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530415 QDF_ASSERT(0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800416 goto err_wma_close;
417 }
418
419 /* Now proceed to open the SME */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530420 qdf_status = sme_open(gp_cds_context->pMACContext);
421 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800422 /* Critical Error ... Cannot proceed further */
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530423 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_FATAL,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800424 "%s: Failed to open SME", __func__);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530425 QDF_ASSERT(0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800426 goto err_mac_close;
427 }
428
429 gp_cds_context->pdev_txrx_ctx =
Dhanashri Atre12a08392016-02-17 13:10:34 -0800430 ol_txrx_pdev_attach(gp_cds_context->cfg_ctx,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800431 gp_cds_context->htc_ctx,
Anurag Chouhan6d760662016-02-20 16:05:43 +0530432 gp_cds_context->qdf_ctx);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800433 if (!gp_cds_context->pdev_txrx_ctx) {
434 /* Critical Error ... Cannot proceed further */
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530435 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_FATAL,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800436 "%s: Failed to open TXRX", __func__);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530437 QDF_ASSERT(0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800438 goto err_sme_close;
439 }
440
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530441 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_INFO_HIGH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800442 "%s: CDS successfully Opened", __func__);
443
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530444 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800445
446err_sme_close:
447 sme_close(gp_cds_context->pMACContext);
448
449err_mac_close:
450 mac_close(gp_cds_context->pMACContext);
451
452err_wma_close:
453 wma_close(gp_cds_context);
454
455 wma_wmi_service_close(gp_cds_context);
456
457err_htc_close:
458 if (gp_cds_context->htc_ctx) {
459 htc_destroy(gp_cds_context->htc_ctx);
460 gp_cds_context->htc_ctx = NULL;
461 }
462
463err_bmi_close:
Komal Seelam5a6e5082016-02-24 17:59:09 +0530464 bmi_cleanup(ol_ctx);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800465
466err_sched_close:
467 cds_sched_close(gp_cds_context);
468
469err_msg_queue:
470 cds_mq_deinit(&gp_cds_context->freeVosMq);
471
472err_wma_complete_event:
Anurag Chouhance0dc992016-02-16 18:18:03 +0530473 qdf_event_destroy(&gp_cds_context->wmaCompleteEvent);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800474
475err_probe_event:
Anurag Chouhance0dc992016-02-16 18:18:03 +0530476 qdf_event_destroy(&gp_cds_context->ProbeEvent);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800477
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530478 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800479} /* cds_open() */
480
481/**
482 * cds_pre_enable() - pre enable cds
483 * @cds_context: CDS context
484 *
Anurag Chouhanf04e84f2016-03-03 10:12:12 +0530485 * Return: QDF status
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800486 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530487QDF_STATUS cds_pre_enable(v_CONTEXT_t cds_context)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800488{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530489 QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800490 p_cds_contextType p_cds_context = (p_cds_contextType) cds_context;
491 void *scn;
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530492 QDF_TRACE(QDF_MODULE_ID_SYS, QDF_TRACE_LEVEL_INFO, "cds prestart");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800493
494 if (gp_cds_context != p_cds_context) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530495 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800496 "%s: Context mismatch", __func__);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530497 QDF_ASSERT(0);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530498 return QDF_STATUS_E_INVAL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800499 }
500
501 if (p_cds_context->pMACContext == NULL) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530502 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800503 "%s: MAC NULL context", __func__);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530504 QDF_ASSERT(0);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530505 return QDF_STATUS_E_INVAL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800506 }
507
508 if (p_cds_context->pWMAContext == NULL) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530509 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800510 "%s: WMA NULL context", __func__);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530511 QDF_ASSERT(0);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530512 return QDF_STATUS_E_INVAL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800513 }
514
Anurag Chouhan6d760662016-02-20 16:05:43 +0530515 scn = cds_get_context(QDF_MODULE_ID_HIF);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800516 if (!scn) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530517 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_FATAL,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800518 "%s: scn is null!", __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530519 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800520 }
521
522 /* Reset wma wait event */
Anurag Chouhance0dc992016-02-16 18:18:03 +0530523 qdf_event_reset(&gp_cds_context->wmaCompleteEvent);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800524
525 /*call WMA pre start */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530526 qdf_status = wma_pre_start(gp_cds_context);
527 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530528 QDF_TRACE(QDF_MODULE_ID_SYS, QDF_TRACE_LEVEL_FATAL,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800529 "Failed to WMA prestart");
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530530 QDF_ASSERT(0);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530531 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800532 }
533
534 /* Need to update time out of complete */
Anurag Chouhance0dc992016-02-16 18:18:03 +0530535 qdf_status = qdf_wait_single_event(&gp_cds_context->wmaCompleteEvent,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800536 CDS_WMA_TIMEOUT);
Anurag Chouhance0dc992016-02-16 18:18:03 +0530537 if (qdf_status != QDF_STATUS_SUCCESS) {
538 if (qdf_status == QDF_STATUS_E_TIMEOUT) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530539 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800540 "%s: Timeout occurred before WMA complete",
541 __func__);
542 } else {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530543 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800544 "%s: wma_pre_start reporting other error",
545 __func__);
546 }
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530547 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800548 "%s: Test MC thread by posting a probe message to SYS",
549 __func__);
550 wlan_sys_probe();
551
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530552 QDF_ASSERT(0);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530553 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800554 }
555
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530556 qdf_status = htc_start(gp_cds_context->htc_ctx);
557 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530558 QDF_TRACE(QDF_MODULE_ID_SYS, QDF_TRACE_LEVEL_FATAL,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800559 "Failed to Start HTC");
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530560 QDF_ASSERT(0);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530561 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800562 }
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530563 qdf_status = wma_wait_for_ready_event(gp_cds_context->pWMAContext);
564 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530565 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_FATAL,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800566 "Failed to get ready event from target firmware");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800567 htc_stop(gp_cds_context->htc_ctx);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530568 QDF_ASSERT(0);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530569 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800570 }
571
Dhanashri Atre12a08392016-02-17 13:10:34 -0800572 if (ol_txrx_pdev_post_attach(gp_cds_context->pdev_txrx_ctx)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530573 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_FATAL,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800574 "Failed to attach pdev");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800575 htc_stop(gp_cds_context->htc_ctx);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530576 QDF_ASSERT(0);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530577 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800578 }
579
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530580 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800581}
582
583/**
584 * cds_enable() - start/enable cds module
585 * @cds_context: CDS context
586 *
Anurag Chouhanf04e84f2016-03-03 10:12:12 +0530587 * Return: QDF status
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800588 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530589QDF_STATUS cds_enable(v_CONTEXT_t cds_context)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800590{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530591 QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800592 tSirRetStatus sirStatus = eSIR_SUCCESS;
593 p_cds_contextType p_cds_context = (p_cds_contextType) cds_context;
594 tHalMacStartParameters halStartParams;
595
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530596 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_INFO,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800597 "%s: Starting Libra SW", __func__);
598
599 /* We support only one instance for now ... */
600 if (gp_cds_context != p_cds_context) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530601 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800602 "%s: mismatch in context", __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530603 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800604 }
605
606 if ((p_cds_context->pWMAContext == NULL) ||
607 (p_cds_context->pMACContext == NULL)) {
608 if (p_cds_context->pWMAContext == NULL)
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530609 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800610 "%s: WMA NULL context", __func__);
611 else
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530612 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800613 "%s: MAC NULL context", __func__);
614
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530615 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800616 }
617
618 /* Start the wma */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530619 qdf_status = wma_start(p_cds_context);
620 if (qdf_status != QDF_STATUS_SUCCESS) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530621 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800622 "%s: Failed to start wma", __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530623 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800624 }
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530625 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_INFO,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800626 "%s: wma correctly started", __func__);
627
628 /* Start the MAC */
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530629 qdf_mem_zero(&halStartParams,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800630 sizeof(tHalMacStartParameters));
631
632 /* Start the MAC */
633 sirStatus =
634 mac_start(p_cds_context->pMACContext, &halStartParams);
635
636 if (eSIR_SUCCESS != sirStatus) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530637 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_FATAL,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800638 "%s: Failed to start MAC", __func__);
639 goto err_wma_stop;
640 }
641
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530642 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_INFO,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800643 "%s: MAC correctly started", __func__);
644
645 /* START SME */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530646 qdf_status = sme_start(p_cds_context->pMACContext);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800647
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530648 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530649 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_FATAL,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800650 "%s: Failed to start SME", __func__);
651 goto err_mac_stop;
652 }
653
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530654 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_INFO,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800655 "%s: SME correctly started", __func__);
656
657 if (ol_txrx_pdev_attach_target
Dhanashri Atre12a08392016-02-17 13:10:34 -0800658 (p_cds_context->pdev_txrx_ctx)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530659 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_FATAL,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800660 "%s: Failed attach target", __func__);
661 goto err_sme_stop;
662 }
663
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530664 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_INFO,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800665 "TL correctly started");
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530666 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_INFO,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800667 "%s: CDS Start is successful!!", __func__);
668
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530669 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800670
671err_sme_stop:
672 sme_stop(p_cds_context->pMACContext, HAL_STOP_TYPE_SYS_RESET);
673
674err_mac_stop:
675 mac_stop(p_cds_context->pMACContext, HAL_STOP_TYPE_SYS_RESET);
676
677err_wma_stop:
Anurag Chouhance0dc992016-02-16 18:18:03 +0530678 qdf_event_reset(&(gp_cds_context->wmaCompleteEvent));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530679 qdf_status = wma_stop(p_cds_context, HAL_STOP_TYPE_RF_KILL);
680 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530681 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800682 "%s: Failed to stop wma", __func__);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530683 QDF_ASSERT(QDF_IS_STATUS_SUCCESS(qdf_status));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800684 wma_setneedshutdown(cds_context);
685 } else {
Anurag Chouhance0dc992016-02-16 18:18:03 +0530686 qdf_status =
687 qdf_wait_single_event(&(gp_cds_context->wmaCompleteEvent),
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800688 CDS_WMA_TIMEOUT);
Anurag Chouhance0dc992016-02-16 18:18:03 +0530689 if (qdf_status != QDF_STATUS_SUCCESS) {
690 if (qdf_status == QDF_STATUS_E_TIMEOUT) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530691 QDF_TRACE(QDF_MODULE_ID_QDF,
692 QDF_TRACE_LEVEL_FATAL,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800693 "%s: Timeout occurred before WMA_stop complete",
694 __func__);
695 } else {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530696 QDF_TRACE(QDF_MODULE_ID_QDF,
697 QDF_TRACE_LEVEL_FATAL,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800698 "%s: WMA_stop reporting other error",
699 __func__);
700 }
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530701 QDF_ASSERT(0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800702 wma_setneedshutdown(cds_context);
703 }
704 }
705
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530706 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800707} /* cds_enable() */
708
709/**
710 * cds_disable() - stop/disable cds module
711 * @cds_context: CDS context
712 *
Anurag Chouhanf04e84f2016-03-03 10:12:12 +0530713 * Return: QDF status
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800714 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530715QDF_STATUS cds_disable(v_CONTEXT_t cds_context)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800716{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530717 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800718
719 /* wma_stop is called before the SYS so that the processing of target
720 * pending responses will not be handled during uninitialization of
721 * WLAN driver
722 */
Anurag Chouhance0dc992016-02-16 18:18:03 +0530723 qdf_event_reset(&(gp_cds_context->wmaCompleteEvent));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800724
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530725 qdf_status = wma_stop(cds_context, HAL_STOP_TYPE_RF_KILL);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800726
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530727 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530728 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800729 "%s: Failed to stop wma", __func__);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530730 QDF_ASSERT(QDF_IS_STATUS_SUCCESS(qdf_status));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800731 wma_setneedshutdown(cds_context);
732 }
733
734 hif_disable_isr(((cds_context_type *) cds_context)->pHIFContext);
735 hif_reset_soc(((cds_context_type *) cds_context)->pHIFContext);
736
737 /* SYS STOP will stop SME and MAC */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530738 qdf_status = sys_stop(cds_context);
739 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530740 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800741 "%s: Failed to stop SYS", __func__);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530742 QDF_ASSERT(QDF_IS_STATUS_SUCCESS(qdf_status));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800743 }
744
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530745 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800746}
747
748/**
749 * cds_close() - close cds module
750 * @cds_context: CDS context
751 *
Anurag Chouhanf04e84f2016-03-03 10:12:12 +0530752 * Return: QDF status
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800753 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530754QDF_STATUS cds_close(v_CONTEXT_t cds_context)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800755{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530756 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800757
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530758 qdf_status = wma_wmi_work_close(cds_context);
759 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530760 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Xun Luoa858a472015-11-10 08:24:45 -0800761 "%s: Failed to close wma_wmi_work", __func__);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530762 QDF_ASSERT(0);
Xun Luoa858a472015-11-10 08:24:45 -0800763 }
764
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800765 if (gp_cds_context->htc_ctx) {
766 htc_stop(gp_cds_context->htc_ctx);
767 htc_destroy(gp_cds_context->htc_ctx);
768 gp_cds_context->htc_ctx = NULL;
769 }
770
771 ol_txrx_pdev_detach(gp_cds_context->pdev_txrx_ctx, 1);
Anurag Chouhan6d760662016-02-20 16:05:43 +0530772 cds_free_context(cds_context, QDF_MODULE_ID_TXRX,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800773 gp_cds_context->pdev_txrx_ctx);
774
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530775 qdf_status = sme_close(((p_cds_contextType) cds_context)->pMACContext);
776 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530777 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800778 "%s: Failed to close SME", __func__);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530779 QDF_ASSERT(QDF_IS_STATUS_SUCCESS(qdf_status));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800780 }
781
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530782 qdf_status = mac_close(((p_cds_contextType) cds_context)->pMACContext);
783 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530784 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800785 "%s: Failed to close MAC", __func__);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530786 QDF_ASSERT(QDF_IS_STATUS_SUCCESS(qdf_status));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800787 }
788
789 ((p_cds_contextType) cds_context)->pMACContext = NULL;
790
791 if (true == wma_needshutdown(cds_context)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530792 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800793 "%s: Failed to shutdown wma", __func__);
794 } else {
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530795 qdf_status = wma_close(cds_context);
796 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530797 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800798 "%s: Failed to close wma", __func__);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530799 QDF_ASSERT(QDF_IS_STATUS_SUCCESS(qdf_status));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800800 }
801 }
802
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530803 qdf_status = wma_wmi_service_close(cds_context);
804 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530805 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800806 "%s: Failed to close wma_wmi_service", __func__);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530807 QDF_ASSERT(QDF_IS_STATUS_SUCCESS(qdf_status));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800808 }
809
810 cds_mq_deinit(&((p_cds_contextType) cds_context)->freeVosMq);
811
Anurag Chouhance0dc992016-02-16 18:18:03 +0530812 qdf_status = qdf_event_destroy(&gp_cds_context->wmaCompleteEvent);
813 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530814 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800815 "%s: failed to destroy wmaCompleteEvent", __func__);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530816 QDF_ASSERT(QDF_IS_STATUS_SUCCESS(qdf_status));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800817 }
818
Anurag Chouhance0dc992016-02-16 18:18:03 +0530819 qdf_status = qdf_event_destroy(&gp_cds_context->ProbeEvent);
820 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530821 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800822 "%s: failed to destroy ProbeEvent", __func__);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530823 QDF_ASSERT(QDF_IS_STATUS_SUCCESS(qdf_status));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800824 }
825
826 cds_deinit_log_completion();
Prashanth Bhattac2a16f62015-12-03 15:06:15 -0800827
828 gp_cds_context->pHDDContext = NULL;
829
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530830 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800831}
832
833/**
834 * cds_get_context() - get context data area
835 *
836 * @moduleId: ID of the module who's context data is being retrived.
837 *
838 * Each module in the system has a context / data area that is allocated
839 * and managed by CDS. This API allows any user to get a pointer to its
840 * allocated context data area from the CDS global context.
841 *
842 * Return: pointer to the context data area of the module ID
843 * specified, or NULL if the context data is not allocated for
844 * the module ID specified
845 */
Anurag Chouhan6d760662016-02-20 16:05:43 +0530846void *cds_get_context(QDF_MODULE_ID moduleId)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800847{
848 void *pModContext = NULL;
849
850 if (gp_cds_context == NULL) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530851 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800852 "%s: cds context pointer is null", __func__);
853 return NULL;
854 }
855
856 switch (moduleId) {
Anurag Chouhan6d760662016-02-20 16:05:43 +0530857 case QDF_MODULE_ID_HDD:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800858 {
859 pModContext = gp_cds_context->pHDDContext;
860 break;
861 }
862
Anurag Chouhan6d760662016-02-20 16:05:43 +0530863 case QDF_MODULE_ID_SME:
864 case QDF_MODULE_ID_PE:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800865 {
866 /* In all these cases, we just return the MAC Context */
867 pModContext = gp_cds_context->pMACContext;
868 break;
869 }
870
Anurag Chouhan6d760662016-02-20 16:05:43 +0530871 case QDF_MODULE_ID_WMA:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800872 {
873 /* For wma module */
874 pModContext = gp_cds_context->pWMAContext;
875 break;
876 }
877
Anurag Chouhan6d760662016-02-20 16:05:43 +0530878 case QDF_MODULE_ID_QDF:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800879 {
880 /* For SYS this is CDS itself */
881 pModContext = gp_cds_context;
882 break;
883 }
884
Anurag Chouhan6d760662016-02-20 16:05:43 +0530885 case QDF_MODULE_ID_HIF:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800886 {
887 pModContext = gp_cds_context->pHIFContext;
888 break;
889 }
890
Anurag Chouhan6d760662016-02-20 16:05:43 +0530891 case QDF_MODULE_ID_HTC:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800892 {
893 pModContext = gp_cds_context->htc_ctx;
894 break;
895 }
896
Anurag Chouhan6d760662016-02-20 16:05:43 +0530897 case QDF_MODULE_ID_QDF_DEVICE:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800898 {
Anurag Chouhan6d760662016-02-20 16:05:43 +0530899 pModContext = gp_cds_context->qdf_ctx;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800900 break;
901 }
902
Anurag Chouhan6d760662016-02-20 16:05:43 +0530903 case QDF_MODULE_ID_BMI:
Komal Seelamd9106492016-02-15 10:31:44 +0530904 {
905 pModContext = gp_cds_context->g_ol_context;
906 break;
907 }
908
Anurag Chouhan6d760662016-02-20 16:05:43 +0530909 case QDF_MODULE_ID_TXRX:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800910 {
911 pModContext = gp_cds_context->pdev_txrx_ctx;
912 break;
913 }
914
Anurag Chouhan6d760662016-02-20 16:05:43 +0530915 case QDF_MODULE_ID_CFG:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800916 {
917 pModContext = gp_cds_context->cfg_ctx;
918 break;
919 }
920
921 default:
922 {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530923 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800924 "%s: Module ID %i does not have its context maintained by CDS",
925 __func__, moduleId);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530926 QDF_ASSERT(0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800927 return NULL;
928 }
929 }
930
931 if (pModContext == NULL) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530932 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800933 "%s: Module ID %i context is Null", __func__,
934 moduleId);
935 }
936
937 return pModContext;
938} /* cds_get_context() */
939
940/**
941 * cds_get_global_context() - get CDS global Context
942 *
943 * This API allows any user to get the CDS Global Context pointer from a
944 * module context data area.
945 *
946 * Return: pointer to the CDS global context, NULL if the function is
947 * unable to retreive the CDS context.
948 */
949v_CONTEXT_t cds_get_global_context(void)
950{
951 if (gp_cds_context == NULL) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530952 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800953 "%s: global cds context is NULL", __func__);
954 }
955
956 return gp_cds_context;
957} /* cds_get_global_context() */
958
959/**
Prashanth Bhatta9e143052015-12-04 11:56:47 -0800960 * cds_get_driver_state() - Get current driver state
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800961 *
Prashanth Bhatta9e143052015-12-04 11:56:47 -0800962 * This API returns current driver state stored in global context.
963 *
964 * Return: Driver state enum
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800965 */
Prashanth Bhatta9e143052015-12-04 11:56:47 -0800966enum cds_driver_state cds_get_driver_state(void)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800967{
968 if (gp_cds_context == NULL) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530969 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800970 "%s: global cds context is NULL", __func__);
Prashanth Bhatta9e143052015-12-04 11:56:47 -0800971
972 return CDS_DRIVER_STATE_UNINITIALIZED;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800973 }
974
Prashanth Bhatta9e143052015-12-04 11:56:47 -0800975 return gp_cds_context->driver_state;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800976}
977
978/**
Prashanth Bhatta9e143052015-12-04 11:56:47 -0800979 * cds_set_driver_state() - Set current driver state
980 * @state: Driver state to be set to.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800981 *
Prashanth Bhatta9e143052015-12-04 11:56:47 -0800982 * This API sets driver state to state. This API only sets the state and doesn't
983 * clear states, please make sure to use cds_clear_driver_state to clear any
984 * state if required.
985 *
986 * Return: None
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800987 */
Prashanth Bhatta9e143052015-12-04 11:56:47 -0800988void cds_set_driver_state(enum cds_driver_state state)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800989{
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800990 if (gp_cds_context == NULL) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530991 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prashanth Bhatta9e143052015-12-04 11:56:47 -0800992 "%s: global cds context is NULL: %x", __func__,
993 state);
994
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800995 return;
996 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800997
Prashanth Bhatta9e143052015-12-04 11:56:47 -0800998 gp_cds_context->driver_state |= state;
999}
1000
1001/**
1002 * cds_clear_driver_state() - Clear current driver state
1003 * @state: Driver state to be cleared.
1004 *
1005 * This API clears driver state. This API only clears the state, please make
1006 * sure to use cds_set_driver_state to set any new states.
1007 *
1008 * Return: None
1009 */
1010void cds_clear_driver_state(enum cds_driver_state state)
1011{
1012 if (gp_cds_context == NULL) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301013 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prashanth Bhatta9e143052015-12-04 11:56:47 -08001014 "%s: global cds context is NULL: %x", __func__,
1015 state);
1016
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001017 return;
1018 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001019
Prashanth Bhatta9e143052015-12-04 11:56:47 -08001020 gp_cds_context->driver_state &= ~state;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001021}
1022
1023/**
1024 * cds_alloc_context() - allocate a context within the CDS global Context
1025 * @p_cds_context: pointer to the global Vos context
1026 * @moduleId: module ID who's context area is being allocated.
1027 * @ppModuleContext: pointer to location where the pointer to the
1028 * allocated context is returned. Note this output pointer
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301029 * is valid only if the API returns QDF_STATUS_SUCCESS
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001030 * @param size: size of the context area to be allocated.
1031 *
1032 * This API allows any user to allocate a user context area within the
1033 * CDS Global Context.
1034 *
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05301035 * Return: QDF status
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001036 */
Anurag Chouhan6d760662016-02-20 16:05:43 +05301037QDF_STATUS cds_alloc_context(void *p_cds_context, QDF_MODULE_ID moduleID,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001038 void **ppModuleContext, uint32_t size)
1039{
1040 void **pGpModContext = NULL;
1041
1042 if (p_cds_context == NULL) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301043 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001044 "%s: cds context is null", __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301045 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001046 }
1047
1048 if ((gp_cds_context != p_cds_context) || (ppModuleContext == NULL)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301049 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001050 "%s: context mismatch or null param passed",
1051 __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301052 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001053 }
1054
1055 switch (moduleID) {
Anurag Chouhan6d760662016-02-20 16:05:43 +05301056 case QDF_MODULE_ID_WMA:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001057 {
1058 pGpModContext = &(gp_cds_context->pWMAContext);
1059 break;
1060 }
1061
Anurag Chouhan6d760662016-02-20 16:05:43 +05301062 case QDF_MODULE_ID_HIF:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001063 {
1064 pGpModContext = &(gp_cds_context->pHIFContext);
1065 break;
1066 }
1067
Anurag Chouhan6d760662016-02-20 16:05:43 +05301068 case QDF_MODULE_ID_BMI:
Komal Seelamd9106492016-02-15 10:31:44 +05301069 {
1070 pGpModContext = &(gp_cds_context->g_ol_context);
1071 break;
1072 }
1073
Anurag Chouhan6d760662016-02-20 16:05:43 +05301074 case QDF_MODULE_ID_EPPING:
1075 case QDF_MODULE_ID_SME:
1076 case QDF_MODULE_ID_PE:
1077 case QDF_MODULE_ID_HDD:
1078 case QDF_MODULE_ID_HDD_SOFTAP:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001079 default:
1080 {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301081 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001082 "%s: Module ID %i "
1083 "does not have its context allocated by CDS",
1084 __func__, moduleID);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301085 QDF_ASSERT(0);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301086 return QDF_STATUS_E_INVAL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001087 }
1088 }
1089
1090 if (NULL != *pGpModContext) {
1091 /* Context has already been allocated!
1092 * Prevent double allocation
1093 */
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301094 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001095 "%s: Module ID %i context has already been allocated",
1096 __func__, moduleID);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301097 return QDF_STATUS_E_EXISTS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001098 }
1099
1100 /* Dynamically allocate the context for module */
1101
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301102 *ppModuleContext = qdf_mem_malloc(size);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001103
1104 if (*ppModuleContext == NULL) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301105 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001106 "%s: Failed to " "allocate Context for module ID %i",
1107 __func__, moduleID);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301108 QDF_ASSERT(0);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301109 return QDF_STATUS_E_NOMEM;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001110 }
1111
Anurag Chouhan6d760662016-02-20 16:05:43 +05301112 if (moduleID == QDF_MODULE_ID_TLSHIM)
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301113 qdf_mem_zero(*ppModuleContext, size);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001114
1115 *pGpModContext = *ppModuleContext;
1116
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301117 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001118} /* cds_alloc_context() */
1119
1120/**
Komal Seelamad5a90d2016-02-16 13:50:03 +05301121 * cds_set_context() - API to set context in global CDS Context
Komal Seelam1aac1982016-03-02 15:57:26 +05301122 * @module_id: Module ID
Komal Seelamad5a90d2016-02-16 13:50:03 +05301123 * @context: Pointer to the Module Context
1124 *
Komal Seelam1aac1982016-03-02 15:57:26 +05301125 * API to set a MODULE Context in global CDS Context
Komal Seelamad5a90d2016-02-16 13:50:03 +05301126 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301127 * Return: QDF_STATUS
Komal Seelamad5a90d2016-02-16 13:50:03 +05301128 */
Anurag Chouhan6d760662016-02-20 16:05:43 +05301129QDF_STATUS cds_set_context(QDF_MODULE_ID module_id, void *context)
Komal Seelamad5a90d2016-02-16 13:50:03 +05301130{
1131 p_cds_contextType p_cds_context = cds_get_global_context();
1132
1133 if (!p_cds_context) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301134 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Komal Seelam1aac1982016-03-02 15:57:26 +05301135 "cds context is Invalid");
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301136 return QDF_STATUS_NOT_INITIALIZED;
Komal Seelamad5a90d2016-02-16 13:50:03 +05301137 }
1138
1139 switch (module_id) {
Anurag Chouhan6d760662016-02-20 16:05:43 +05301140 case QDF_MODULE_ID_HIF:
Komal Seelamad5a90d2016-02-16 13:50:03 +05301141 p_cds_context->pHIFContext = context;
1142 break;
1143 default:
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301144 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Komal Seelam1aac1982016-03-02 15:57:26 +05301145 "%s: Module ID %i does not have its context managed by CDS",
1146 __func__, module_id);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301147 QDF_ASSERT(0);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301148 return QDF_STATUS_E_INVAL;
Komal Seelamad5a90d2016-02-16 13:50:03 +05301149 }
1150
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301151 return QDF_STATUS_SUCCESS;
Komal Seelamad5a90d2016-02-16 13:50:03 +05301152}
1153
1154/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001155 * cds_free_context() - free an allocated context within the
1156 * CDS global Context
1157 * @p_cds_context: pointer to the global Vos context
1158 * @moduleId: module ID who's context area is being free
1159 * @pModuleContext: pointer to module context area to be free'd.
1160 *
1161 * This API allows a user to free the user context area within the
1162 * CDS Global Context.
1163 *
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05301164 * Return: QDF status
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001165 */
Anurag Chouhan6d760662016-02-20 16:05:43 +05301166QDF_STATUS cds_free_context(void *p_cds_context, QDF_MODULE_ID moduleID,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001167 void *pModuleContext)
1168{
1169 void **pGpModContext = NULL;
1170
1171 if ((p_cds_context == NULL) || (gp_cds_context != p_cds_context) ||
1172 (pModuleContext == NULL)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301173 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001174 "%s: Null params or context mismatch", __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301175 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001176 }
1177
1178 switch (moduleID) {
Anurag Chouhan6d760662016-02-20 16:05:43 +05301179 case QDF_MODULE_ID_WMA:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001180 {
1181 pGpModContext = &(gp_cds_context->pWMAContext);
1182 break;
1183 }
1184
Anurag Chouhan6d760662016-02-20 16:05:43 +05301185 case QDF_MODULE_ID_HIF:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001186 {
1187 pGpModContext = &(gp_cds_context->pHIFContext);
1188 break;
1189 }
1190
Anurag Chouhan6d760662016-02-20 16:05:43 +05301191 case QDF_MODULE_ID_TXRX:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001192 {
1193 pGpModContext = &(gp_cds_context->pdev_txrx_ctx);
1194 break;
1195 }
1196
Anurag Chouhan6d760662016-02-20 16:05:43 +05301197 case QDF_MODULE_ID_BMI:
Komal Seelamd9106492016-02-15 10:31:44 +05301198 {
1199 pGpModContext = &(gp_cds_context->g_ol_context);
1200 break;
1201 }
1202
Anurag Chouhan6d760662016-02-20 16:05:43 +05301203 case QDF_MODULE_ID_EPPING:
1204 case QDF_MODULE_ID_HDD:
1205 case QDF_MODULE_ID_SME:
1206 case QDF_MODULE_ID_PE:
1207 case QDF_MODULE_ID_HDD_SOFTAP:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001208 default:
1209 {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301210 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001211 "%s: Module ID %i "
1212 "does not have its context allocated by CDS",
1213 __func__, moduleID);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301214 QDF_ASSERT(0);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301215 return QDF_STATUS_E_INVAL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001216 }
1217 }
1218
1219 if (NULL == *pGpModContext) {
1220 /* Context has not been allocated or freed already! */
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301221 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001222 "%s: Module ID %i "
1223 "context has not been allocated or freed already",
1224 __func__, moduleID);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301225 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001226 }
1227
1228 if (*pGpModContext != pModuleContext) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301229 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001230 "%s: pGpModContext != pModuleContext", __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301231 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001232 }
1233
1234 if (pModuleContext != NULL)
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301235 qdf_mem_free(pModuleContext);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001236
1237 *pGpModContext = NULL;
1238
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301239 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001240} /* cds_free_context() */
1241
1242/**
1243 * cds_mq_post_message() - post a message to a message queue
1244 * @msgQueueId: identifies the message queue upon which the message
1245 * will be posted.
1246 * @message: a pointer to a message buffer. Memory for this message
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05301247 * buffer is allocated by the caller and free'd by the QDF after the
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001248 * message is posted to the message queue. If the consumer of the
1249 * message needs anything in this message, it needs to copy the contents
1250 * before returning from the message queue handler.
1251 *
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05301252 * Return: QDF status
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001253 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301254QDF_STATUS cds_mq_post_message(CDS_MQ_ID msgQueueId, cds_msg_t *pMsg)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001255{
1256 p_cds_mq_type pTargetMq = NULL;
1257 p_cds_msg_wrapper pMsgWrapper = NULL;
1258 uint32_t debug_count = 0;
1259
1260 if ((gp_cds_context == NULL) || (pMsg == NULL)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301261 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001262 "%s: Null params or global cds context is null",
1263 __func__);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301264 QDF_ASSERT(0);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301265 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001266 }
1267
1268 switch (msgQueueId) {
1269 /* Message Queue ID for messages bound for SME */
1270 case CDS_MQ_ID_SME:
1271 {
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05301272 pTargetMq = &(gp_cds_context->qdf_sched.smeMcMq);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001273 break;
1274 }
1275
1276 /* Message Queue ID for messages bound for PE */
1277 case CDS_MQ_ID_PE:
1278 {
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05301279 pTargetMq = &(gp_cds_context->qdf_sched.peMcMq);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001280 break;
1281 }
1282
1283 /* Message Queue ID for messages bound for wma */
1284 case CDS_MQ_ID_WMA:
1285 {
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05301286 pTargetMq = &(gp_cds_context->qdf_sched.wmaMcMq);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001287 break;
1288 }
1289
1290 /* Message Queue ID for messages bound for the SYS module */
1291 case CDS_MQ_ID_SYS:
1292 {
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05301293 pTargetMq = &(gp_cds_context->qdf_sched.sysMcMq);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001294 break;
1295 }
1296
1297 default:
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301298 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001299 ("%s: Trying to queue msg into unknown MC Msg queue ID %d"),
1300 __func__, msgQueueId);
1301
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301302 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001303 }
1304
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301305 QDF_ASSERT(NULL != pTargetMq);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001306 if (pTargetMq == NULL) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301307 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001308 "%s: pTargetMq == NULL", __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301309 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001310 }
1311
1312 /* Try and get a free Msg wrapper */
1313 pMsgWrapper = cds_mq_get(&gp_cds_context->freeVosMq);
1314
1315 if (NULL == pMsgWrapper) {
1316 debug_count = atomic_inc_return(&cds_wrapper_empty_count);
1317 if (1 == debug_count)
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301318 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001319 "%s: CDS Core run out of message wrapper %d",
1320 __func__, debug_count);
1321
1322 if (CDS_WRAPPER_MAX_FAIL_COUNT == debug_count)
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301323 QDF_BUG(0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001324
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301325 return QDF_STATUS_E_RESOURCES;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001326 }
1327
1328 atomic_set(&cds_wrapper_empty_count, 0);
1329
1330 /* Copy the message now */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301331 qdf_mem_copy((void *)pMsgWrapper->pVosMsg,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001332 (void *)pMsg, sizeof(cds_msg_t));
1333
1334 cds_mq_put(pTargetMq, pMsgWrapper);
1335
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05301336 set_bit(MC_POST_EVENT_MASK, &gp_cds_context->qdf_sched.mcEventFlag);
1337 wake_up_interruptible(&gp_cds_context->qdf_sched.mcWaitQueue);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001338
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301339 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001340} /* cds_mq_post_message() */
1341
1342/**
1343 * cds_sys_probe_thread_cback() - probe mc thread callback
1344 * @pUserData: pointer to user data
1345 *
1346 * Return: none
1347 */
1348void cds_sys_probe_thread_cback(void *pUserData)
1349{
1350 if (gp_cds_context != pUserData) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301351 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001352 "%s: gp_cds_context != pUserData", __func__);
1353 return;
1354 }
1355
Anurag Chouhance0dc992016-02-16 18:18:03 +05301356 if (qdf_event_set(&gp_cds_context->ProbeEvent) != QDF_STATUS_SUCCESS) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301357 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Anurag Chouhance0dc992016-02-16 18:18:03 +05301358 "%s: qdf_event_set failed", __func__);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001359 return;
1360 }
1361} /* cds_sys_probe_thread_cback() */
1362
1363/**
1364 * cds_wma_complete_cback() - wma complete callback
1365 * @pUserData: pointer to user data
1366 *
1367 * Return: none
1368 */
1369void cds_wma_complete_cback(void *pUserData)
1370{
1371 if (gp_cds_context != pUserData) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301372 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001373 "%s: gp_cds_context != pUserData", __func__);
1374 return;
1375 }
1376
Anurag Chouhance0dc992016-02-16 18:18:03 +05301377 if (qdf_event_set(&gp_cds_context->wmaCompleteEvent) !=
1378 QDF_STATUS_SUCCESS) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301379 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Anurag Chouhance0dc992016-02-16 18:18:03 +05301380 "%s: qdf_event_set failed", __func__);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001381 return;
1382 }
1383} /* cds_wma_complete_cback() */
1384
1385/**
1386 * cds_core_return_msg() - return core message
1387 * @pVContext: pointer to cds context
1388 * @pMsgWrapper: pointer to message wrapper
1389 *
1390 * Return: none
1391 */
1392void cds_core_return_msg(void *pVContext, p_cds_msg_wrapper pMsgWrapper)
1393{
1394 p_cds_contextType p_cds_context = (p_cds_contextType) pVContext;
1395
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301396 QDF_ASSERT(gp_cds_context == p_cds_context);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001397
1398 if (gp_cds_context != p_cds_context) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301399 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001400 "%s: gp_cds_context != p_cds_context", __func__);
1401 return;
1402 }
1403
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301404 QDF_ASSERT(NULL != pMsgWrapper);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001405
1406 if (pMsgWrapper == NULL) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301407 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001408 "%s: pMsgWrapper == NULL in function", __func__);
1409 return;
1410 }
1411
1412 /*
1413 ** Return the message on the free message queue
1414 */
1415 INIT_LIST_HEAD(&pMsgWrapper->msgNode);
1416 cds_mq_put(&p_cds_context->freeVosMq, pMsgWrapper);
1417} /* cds_core_return_msg() */
1418
1419
1420/**
1421 * cds_shutdown() - shutdown CDS
1422 * @cds_context: global cds context
1423 *
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05301424 * Return: QDF status
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001425 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301426QDF_STATUS cds_shutdown(v_CONTEXT_t cds_context)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001427{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301428 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001429 tpAniSirGlobal pmac = (((p_cds_contextType)cds_context)->pMACContext);
1430
1431 ol_txrx_pdev_detach(gp_cds_context->pdev_txrx_ctx, 1);
Anurag Chouhan6d760662016-02-20 16:05:43 +05301432 cds_free_context(cds_context, QDF_MODULE_ID_TXRX,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001433 gp_cds_context->pdev_txrx_ctx);
1434
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301435 qdf_status = sme_close(((p_cds_contextType) cds_context)->pMACContext);
1436 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
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: Failed to close SME", __func__);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301439 QDF_ASSERT(QDF_IS_STATUS_SUCCESS(qdf_status));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001440 }
1441 /*
1442 * CAC timer will be initiated and started only when SAP starts on
1443 * DFS channel and it will be stopped and destroyed immediately once the
1444 * radar detected or timedout. So as per design CAC timer should be
1445 * destroyed after stop
1446 */
1447 if (pmac->sap.SapDfsInfo.is_dfs_cac_timer_running) {
Anurag Chouhan210db072016-02-22 18:42:15 +05301448 qdf_mc_timer_stop(&pmac->sap.SapDfsInfo.sap_dfs_cac_timer);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001449 pmac->sap.SapDfsInfo.is_dfs_cac_timer_running = 0;
Anurag Chouhan210db072016-02-22 18:42:15 +05301450 qdf_mc_timer_destroy(&pmac->sap.SapDfsInfo.sap_dfs_cac_timer);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001451 }
1452
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301453 qdf_status = mac_close(((p_cds_contextType) cds_context)->pMACContext);
1454 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301455 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001456 "%s: Failed to close MAC", __func__);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301457 QDF_ASSERT(QDF_IS_STATUS_SUCCESS(qdf_status));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001458 }
1459
1460 ((p_cds_contextType) cds_context)->pMACContext = NULL;
1461
1462 if (false == wma_needshutdown(cds_context)) {
1463
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301464 qdf_status = wma_close(cds_context);
1465 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301466 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001467 "%s: Failed to close wma!", __func__);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301468 QDF_ASSERT(QDF_IS_STATUS_SUCCESS(qdf_status));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001469 }
1470 }
1471
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301472 qdf_status = wma_wmi_work_close(cds_context);
1473 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301474 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Xun Luoa858a472015-11-10 08:24:45 -08001475 "%s: Failed to close wma_wmi_work!", __func__);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301476 QDF_ASSERT(0);
Xun Luoa858a472015-11-10 08:24:45 -08001477 }
1478
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001479 if (gp_cds_context->htc_ctx) {
1480 htc_stop(gp_cds_context->htc_ctx);
1481 htc_destroy(gp_cds_context->htc_ctx);
1482 gp_cds_context->htc_ctx = NULL;
1483 }
1484
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301485 qdf_status = wma_wmi_service_close(cds_context);
1486 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301487 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001488 "%s: Failed to close wma_wmi_service!", __func__);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301489 QDF_ASSERT(QDF_IS_STATUS_SUCCESS(qdf_status));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001490 }
1491
1492 cds_mq_deinit(&((p_cds_contextType) cds_context)->freeVosMq);
1493
Anurag Chouhance0dc992016-02-16 18:18:03 +05301494 qdf_status = qdf_event_destroy(&gp_cds_context->wmaCompleteEvent);
1495 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301496 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001497 "%s: failed to destroy wmaCompleteEvent", __func__);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301498 QDF_ASSERT(QDF_IS_STATUS_SUCCESS(qdf_status));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001499 }
1500
Anurag Chouhance0dc992016-02-16 18:18:03 +05301501 qdf_status = qdf_event_destroy(&gp_cds_context->ProbeEvent);
1502 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301503 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001504 "%s: failed to destroy ProbeEvent", __func__);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301505 QDF_ASSERT(QDF_IS_STATUS_SUCCESS(qdf_status));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001506 }
1507
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301508 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001509}
1510
1511/**
1512 * cds_get_vdev_types() - get vdev type
1513 * @mode: mode
1514 * @type: type
1515 * @sub_type: sub_type
1516 *
1517 * Return: WMI vdev type
1518 */
Anurag Chouhan6d760662016-02-20 16:05:43 +05301519QDF_STATUS cds_get_vdev_types(enum tQDF_ADAPTER_MODE mode, uint32_t *type,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001520 uint32_t *sub_type)
1521{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301522 QDF_STATUS status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001523 *type = 0;
1524 *sub_type = 0;
1525
1526 switch (mode) {
Anurag Chouhan6d760662016-02-20 16:05:43 +05301527 case QDF_STA_MODE:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001528 *type = WMI_VDEV_TYPE_STA;
1529 break;
Anurag Chouhan6d760662016-02-20 16:05:43 +05301530 case QDF_SAP_MODE:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001531 *type = WMI_VDEV_TYPE_AP;
1532 break;
Anurag Chouhan6d760662016-02-20 16:05:43 +05301533 case QDF_P2P_DEVICE_MODE:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001534 *type = WMI_VDEV_TYPE_AP;
1535 *sub_type = WMI_UNIFIED_VDEV_SUBTYPE_P2P_DEVICE;
1536 break;
Anurag Chouhan6d760662016-02-20 16:05:43 +05301537 case QDF_P2P_CLIENT_MODE:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001538 *type = WMI_VDEV_TYPE_STA;
1539 *sub_type = WMI_UNIFIED_VDEV_SUBTYPE_P2P_CLIENT;
1540 break;
Anurag Chouhan6d760662016-02-20 16:05:43 +05301541 case QDF_P2P_GO_MODE:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001542 *type = WMI_VDEV_TYPE_AP;
1543 *sub_type = WMI_UNIFIED_VDEV_SUBTYPE_P2P_GO;
1544 break;
Anurag Chouhan6d760662016-02-20 16:05:43 +05301545 case QDF_OCB_MODE:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001546 *type = WMI_VDEV_TYPE_OCB;
1547 break;
1548 default:
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301549 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Ryan Hsud7e6fc72015-12-07 17:26:14 -08001550 "Invalid device mode %d", mode);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301551 status = QDF_STATUS_E_INVAL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001552 break;
1553 }
1554 return status;
1555}
1556
1557/**
1558 * cds_flush_work() - flush pending works
1559 * @work: pointer to work
1560 *
1561 * Return: none
1562 */
1563void cds_flush_work(void *work)
1564{
1565#if defined (CONFIG_CNSS)
1566 cnss_flush_work(work);
1567#elif defined (WLAN_OPEN_SOURCE)
1568 cancel_work_sync(work);
1569#endif
1570}
1571
1572/**
1573 * cds_flush_delayed_work() - flush delayed works
1574 * @dwork: pointer to delayed work
1575 *
1576 * Return: none
1577 */
1578void cds_flush_delayed_work(void *dwork)
1579{
1580#if defined (CONFIG_CNSS)
1581 cnss_flush_delayed_work(dwork);
1582#elif defined (WLAN_OPEN_SOURCE)
1583 cancel_delayed_work_sync(dwork);
1584#endif
1585}
1586
1587/**
1588 * cds_is_packet_log_enabled() - check if packet log is enabled
1589 *
1590 * Return: true if packet log is enabled else false
1591 */
1592bool cds_is_packet_log_enabled(void)
1593{
1594 hdd_context_t *pHddCtx;
1595
1596 pHddCtx = (hdd_context_t *) (gp_cds_context->pHDDContext);
1597 if ((NULL == pHddCtx) || (NULL == pHddCtx->config)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301598 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_FATAL,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001599 "%s: Hdd Context is Null", __func__);
1600 return false;
1601 }
1602
1603 return pHddCtx->config->enablePacketLog;
1604}
1605
1606/**
1607 * cds_trigger_recovery() - trigger self recovery
1608 *
1609 * Return: none
1610 */
1611void cds_trigger_recovery(void)
1612{
Anurag Chouhan6d760662016-02-20 16:05:43 +05301613 tp_wma_handle wma_handle = cds_get_context(QDF_MODULE_ID_WMA);
Anurag Chouhance0dc992016-02-16 18:18:03 +05301614 QDF_STATUS status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001615
1616 if (!wma_handle) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301617 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Komal Seelam1aac1982016-03-02 15:57:26 +05301618 "WMA context is invalid!");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001619 return;
1620 }
1621
1622 wma_crash_inject(wma_handle, RECOVERY_SIM_SELF_RECOVERY, 0);
1623
Anurag Chouhance0dc992016-02-16 18:18:03 +05301624 status = qdf_wait_single_event(&wma_handle->recovery_event,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001625 WMA_CRASH_INJECT_TIMEOUT);
1626
Anurag Chouhance0dc992016-02-16 18:18:03 +05301627 if (QDF_STATUS_SUCCESS != status) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301628 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001629 "CRASH_INJECT command is timed out!");
1630 #ifdef CONFIG_CNSS
Prashanth Bhatta9e143052015-12-04 11:56:47 -08001631 if (cds_is_driver_recovering()) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301632 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prashanth Bhatta9e143052015-12-04 11:56:47 -08001633 "Recovery is in progress, ignore!");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001634 return;
1635 }
Prashanth Bhatta9e143052015-12-04 11:56:47 -08001636 cds_set_recovery_in_progress(true);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001637 cnss_schedule_recovery_work();
1638 #endif
1639
1640 return;
1641 }
1642}
1643
1644/**
1645 * cds_get_monotonic_boottime() - Get kernel boot time.
1646 *
1647 * Return: Time in microseconds
1648 */
1649
1650uint64_t cds_get_monotonic_boottime(void)
1651{
1652#ifdef CONFIG_CNSS
1653 struct timespec ts;
1654
1655 cnss_get_monotonic_boottime(&ts);
1656 return ((uint64_t) ts.tv_sec * 1000000) + (ts.tv_nsec / 1000);
1657#else
Anurag Chouhan50220ce2016-02-18 20:11:33 +05301658 return ((uint64_t)qdf_system_ticks_to_msecs(qdf_system_ticks()) *
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001659 1000);
1660#endif
1661}
1662
1663/**
1664 * cds_set_wakelock_logging() - Logging of wakelock enabled/disabled
1665 * @value: Boolean value
1666 *
1667 * This function is used to set the flag which will indicate whether
1668 * logging of wakelock is enabled or not
1669 *
1670 * Return: None
1671 */
1672void cds_set_wakelock_logging(bool value)
1673{
1674 p_cds_contextType p_cds_context;
1675
1676 p_cds_context = cds_get_global_context();
1677 if (!p_cds_context) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301678 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001679 "cds context is Invald");
1680 return;
1681 }
1682 p_cds_context->is_wakelock_log_enabled = value;
1683}
1684
1685/**
1686 * cds_is_wakelock_enabled() - Check if logging of wakelock is enabled/disabled
1687 * @value: Boolean value
1688 *
1689 * This function is used to check whether logging of wakelock is enabled or not
1690 *
1691 * Return: true if logging of wakelock is enabled
1692 */
1693bool cds_is_wakelock_enabled(void)
1694{
1695 p_cds_contextType p_cds_context;
1696
1697 p_cds_context = cds_get_global_context();
1698 if (!p_cds_context) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301699 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001700 "cds context is Invald");
1701 return false;
1702 }
1703 return p_cds_context->is_wakelock_log_enabled;
1704}
1705
1706/**
1707 * cds_set_ring_log_level() - Sets the log level of a particular ring
1708 * @ring_id: ring_id
1709 * @log_levelvalue: Log level specificed
1710 *
1711 * This function converts HLOS values to driver log levels and sets the log
1712 * level of a particular ring accordingly.
1713 *
1714 * Return: None
1715 */
1716void cds_set_ring_log_level(uint32_t ring_id, uint32_t log_level)
1717{
1718 p_cds_contextType p_cds_context;
1719 uint32_t log_val;
1720
1721 p_cds_context = cds_get_global_context();
1722 if (!p_cds_context) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301723 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001724 "%s: cds context is Invald", __func__);
1725 return;
1726 }
1727
1728 switch (log_level) {
1729 case LOG_LEVEL_NO_COLLECTION:
1730 log_val = WLAN_LOG_LEVEL_OFF;
1731 break;
1732 case LOG_LEVEL_NORMAL_COLLECT:
1733 log_val = WLAN_LOG_LEVEL_NORMAL;
1734 break;
1735 case LOG_LEVEL_ISSUE_REPRO:
1736 log_val = WLAN_LOG_LEVEL_REPRO;
1737 break;
1738 case LOG_LEVEL_ACTIVE:
1739 default:
1740 log_val = WLAN_LOG_LEVEL_ACTIVE;
1741 break;
1742 }
1743
1744 if (ring_id == RING_ID_WAKELOCK) {
1745 p_cds_context->wakelock_log_level = log_val;
1746 return;
1747 } else if (ring_id == RING_ID_CONNECTIVITY) {
1748 p_cds_context->connectivity_log_level = log_val;
1749 return;
1750 } else if (ring_id == RING_ID_PER_PACKET_STATS) {
1751 p_cds_context->packet_stats_log_level = log_val;
1752 return;
Chandrasekaran, Manishekar907c2af2015-11-13 12:50:04 +05301753 } else if (ring_id == RING_ID_DRIVER_DEBUG) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001754 p_cds_context->driver_debug_log_level = log_val;
1755 return;
1756 } else if (ring_id == RING_ID_FIRMWARE_DEBUG) {
1757 p_cds_context->fw_debug_log_level = log_val;
1758 return;
1759 }
1760}
1761
1762/**
1763 * cds_get_ring_log_level() - Get the a ring id's log level
1764 * @ring_id: Ring id
1765 *
1766 * Fetch and return the log level corresponding to a ring id
1767 *
1768 * Return: Log level corresponding to the ring ID
1769 */
1770enum wifi_driver_log_level cds_get_ring_log_level(uint32_t ring_id)
1771{
1772 p_cds_contextType p_cds_context;
1773
1774 p_cds_context = cds_get_global_context();
1775 if (!p_cds_context) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301776 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001777 "%s: cds context is Invald", __func__);
1778 return WLAN_LOG_LEVEL_OFF;
1779 }
1780
1781 if (ring_id == RING_ID_WAKELOCK)
1782 return p_cds_context->wakelock_log_level;
1783 else if (ring_id == RING_ID_CONNECTIVITY)
1784 return p_cds_context->connectivity_log_level;
1785 else if (ring_id == RING_ID_PER_PACKET_STATS)
1786 return p_cds_context->packet_stats_log_level;
Chandrasekaran, Manishekar907c2af2015-11-13 12:50:04 +05301787 else if (ring_id == RING_ID_DRIVER_DEBUG)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001788 return p_cds_context->driver_debug_log_level;
1789 else if (ring_id == RING_ID_FIRMWARE_DEBUG)
1790 return p_cds_context->fw_debug_log_level;
1791
1792 return WLAN_LOG_LEVEL_OFF;
1793}
1794
1795/**
1796 * cds_set_multicast_logging() - Set mutlicast logging value
1797 * @value: Value of multicast logging
1798 *
1799 * Set the multicast logging value which will indicate
1800 * whether to multicast host and fw messages even
1801 * without any registration by userspace entity
1802 *
1803 * Return: None
1804 */
1805void cds_set_multicast_logging(uint8_t value)
1806{
1807 cds_multicast_logging = value;
1808}
1809
1810/**
1811 * cds_is_multicast_logging() - Get multicast logging value
1812 *
1813 * Get the multicast logging value which will indicate
1814 * whether to multicast host and fw messages even
1815 * without any registration by userspace entity
1816 *
1817 * Return: 0 - Multicast logging disabled, 1 - Multicast logging enabled
1818 */
1819uint8_t cds_is_multicast_logging(void)
1820{
1821 return cds_multicast_logging;
1822}
1823
1824/*
1825 * cds_init_log_completion() - Initialize log param structure
1826 *
1827 * This function is used to initialize the logging related
1828 * parameters
1829 *
1830 * Return: None
1831 */
1832void cds_init_log_completion(void)
1833{
1834 p_cds_contextType p_cds_context;
1835
1836 p_cds_context = cds_get_global_context();
1837 if (!p_cds_context) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301838 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001839 "%s: cds context is Invalid", __func__);
1840 return;
1841 }
1842
1843 p_cds_context->log_complete.is_fatal = WLAN_LOG_TYPE_NON_FATAL;
1844 p_cds_context->log_complete.indicator = WLAN_LOG_INDICATOR_UNUSED;
1845 p_cds_context->log_complete.reason_code = WLAN_LOG_REASON_CODE_UNUSED;
1846 p_cds_context->log_complete.is_report_in_progress = false;
1847 /* Attempting to initialize an already initialized lock
1848 * results in a failure. This must be ok here.
1849 */
Anurag Chouhana37b5b72016-02-21 14:53:42 +05301850 qdf_spinlock_create(&p_cds_context->bug_report_lock);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001851}
1852
1853/**
1854 * cds_deinit_log_completion() - Deinitialize log param structure
1855 *
1856 * This function is used to deinitialize the logging related
1857 * parameters
1858 *
1859 * Return: None
1860 */
1861void cds_deinit_log_completion(void)
1862{
1863 p_cds_contextType p_cds_context;
1864
1865 p_cds_context = cds_get_global_context();
1866 if (!p_cds_context) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301867 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001868 "%s: cds context is Invalid", __func__);
1869 return;
1870 }
1871
Anurag Chouhana37b5b72016-02-21 14:53:42 +05301872 qdf_spinlock_destroy(&p_cds_context->bug_report_lock);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001873}
1874
1875/**
1876 * cds_set_log_completion() - Store the logging params
1877 * @is_fatal: Indicates if the event triggering bug report is fatal or not
1878 * @indicator: Source which trigerred the bug report
1879 * @reason_code: Reason for triggering bug report
1880 *
1881 * This function is used to set the logging parameters based on the
1882 * caller
1883 *
1884 * Return: 0 if setting of params is successful
1885 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301886QDF_STATUS cds_set_log_completion(uint32_t is_fatal,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001887 uint32_t indicator,
1888 uint32_t reason_code)
1889{
1890 p_cds_contextType p_cds_context;
1891
1892 p_cds_context = cds_get_global_context();
1893 if (!p_cds_context) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301894 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001895 "%s: cds context is Invalid", __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301896 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001897 }
1898
Anurag Chouhana37b5b72016-02-21 14:53:42 +05301899 qdf_spinlock_acquire(&p_cds_context->bug_report_lock);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001900 p_cds_context->log_complete.is_fatal = is_fatal;
1901 p_cds_context->log_complete.indicator = indicator;
1902 p_cds_context->log_complete.reason_code = reason_code;
1903 p_cds_context->log_complete.is_report_in_progress = true;
Anurag Chouhana37b5b72016-02-21 14:53:42 +05301904 qdf_spinlock_release(&p_cds_context->bug_report_lock);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301905 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001906}
1907
1908/**
1909 * cds_get_log_completion() - Get the logging related params
1910 * @is_fatal: Indicates if the event triggering bug report is fatal or not
1911 * @indicator: Source which trigerred the bug report
1912 * @reason_code: Reason for triggering bug report
1913 *
1914 * This function is used to get the logging related parameters
1915 *
1916 * Return: None
1917 */
1918void cds_get_log_completion(uint32_t *is_fatal,
1919 uint32_t *indicator,
1920 uint32_t *reason_code)
1921{
1922 p_cds_contextType p_cds_context;
1923
1924 p_cds_context = cds_get_global_context();
1925 if (!p_cds_context) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301926 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001927 "%s: cds context is Invalid", __func__);
1928 return;
1929 }
1930
Anurag Chouhana37b5b72016-02-21 14:53:42 +05301931 qdf_spinlock_acquire(&p_cds_context->bug_report_lock);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001932 *is_fatal = p_cds_context->log_complete.is_fatal;
1933 *indicator = p_cds_context->log_complete.indicator;
1934 *reason_code = p_cds_context->log_complete.reason_code;
1935 p_cds_context->log_complete.is_report_in_progress = false;
Anurag Chouhana37b5b72016-02-21 14:53:42 +05301936 qdf_spinlock_release(&p_cds_context->bug_report_lock);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001937}
1938
1939/**
1940 * cds_is_log_report_in_progress() - Check if bug reporting is in progress
1941 *
1942 * This function is used to check if the bug reporting is already in progress
1943 *
1944 * Return: true if the bug reporting is in progress
1945 */
1946bool cds_is_log_report_in_progress(void)
1947{
1948 p_cds_contextType p_cds_context;
1949
1950 p_cds_context = cds_get_global_context();
1951 if (!p_cds_context) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301952 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001953 "%s: cds context is Invalid", __func__);
1954 return true;
1955 }
1956 return p_cds_context->log_complete.is_report_in_progress;
1957}
1958
1959/**
1960 * cds_flush_logs() - Report fatal event to userspace
1961 * @is_fatal: Indicates if the event triggering bug report is fatal or not
1962 * @indicator: Source which trigerred the bug report
1963 * @reason_code: Reason for triggering bug report
1964 *
1965 * This function sets the log related params and send the WMI command to the
1966 * FW to flush its logs. On receiving the flush completion event from the FW
1967 * the same will be conveyed to userspace
1968 *
1969 * Return: 0 on success
1970 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301971QDF_STATUS cds_flush_logs(uint32_t is_fatal,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001972 uint32_t indicator,
1973 uint32_t reason_code)
1974{
1975 uint32_t ret;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301976 QDF_STATUS status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001977
1978 p_cds_contextType p_cds_context;
1979
1980 p_cds_context = cds_get_global_context();
1981 if (!p_cds_context) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301982 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001983 "%s: cds context is Invalid", __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301984 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001985 }
1986
1987 if (cds_is_log_report_in_progress() == true) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301988 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001989 "%s: Bug report already in progress - dropping! type:%d, indicator=%d reason_code=%d",
1990 __func__, is_fatal, indicator, reason_code);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301991 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001992 }
1993
1994 status = cds_set_log_completion(is_fatal, indicator, reason_code);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301995 if (QDF_STATUS_SUCCESS != status) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301996 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001997 "%s: Failed to set log trigger params", __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301998 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001999 }
2000
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302001 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_INFO,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002002 "%s: Triggering bug report: type:%d, indicator=%d reason_code=%d",
2003 __func__, is_fatal, indicator, reason_code);
2004
2005 ret = sme_send_flush_logs_cmd_to_fw(p_cds_context->pMACContext);
2006 if (0 != ret) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302007 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002008 "%s: Failed to send flush FW log", __func__);
2009 cds_init_log_completion();
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302010 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002011 }
2012
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302013 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002014}
2015
2016/**
2017 * cds_logging_set_fw_flush_complete() - Wrapper for FW log flush completion
2018 *
2019 * This function is used to send signal to the logger thread to indicate
2020 * that the flushing of FW logs is complete by the FW
2021 *
2022 * Return: None
2023 *
2024 */
2025void cds_logging_set_fw_flush_complete(void)
2026{
2027 wlan_logging_set_fw_flush_complete();
2028}