blob: c684b4e2309c2d58489af300e1a959e58c5313fd [file] [log] [blame]
Jeff Johnsone7245742012-09-05 17:12:55 -07001/*
Gopichand Nakkala92f07d82013-01-08 21:16:34 -08002 * Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
3 *
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/*
Jeff Johnson32d95a32012-09-10 13:15:23 -070022 * Copyright (c) 2012, The Linux Foundation. All rights reserved.
Jeff Johnsone7245742012-09-05 17:12:55 -070023 *
24 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
25 *
26 *
27 * Permission to use, copy, modify, and/or distribute this software for
28 * any purpose with or without fee is hereby granted, provided that the
29 * above copyright notice and this permission notice appear in all
30 * copies.
31 *
32 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
33 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
34 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
35 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
36 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
37 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
38 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
39 * PERFORMANCE OF THIS SOFTWARE.
40 */
41
42#ifdef FEATURE_OEM_DATA_SUPPORT
43/** ------------------------------------------------------------------------- *
44 ------------------------------------------------------------------------- *
45
46
47 \file oemDataApi.c
48
49 Implementation for the OEM DATA REQ/RSP interfaces.
50
51 Copyright (C) 2010 Qualcomm Incorporated.
52
53
54 ========================================================================== */
55#include "aniGlobal.h"
56#include "oemDataApi.h"
57#include "palApi.h"
58#include "smeInside.h"
59#include "smsDebug.h"
60
61#include "csrSupport.h"
62#include "wlan_qct_tl.h"
63
64#include "vos_diag_core_log.h"
65#include "vos_diag_core_event.h"
66
67/* ---------------------------------------------------------------------------
68 \fn oemData_OemDataReqOpen
69 \brief This function must be called before any API call to (OEM DATA REQ/RSP module)
70 \return eHalStatus
71 -------------------------------------------------------------------------------*/
72
73eHalStatus oemData_OemDataReqOpen(tHalHandle hHal)
74{
75 eHalStatus status = eHAL_STATUS_SUCCESS;
76 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
77
78 do
79 {
80 //initialize all the variables to null
81 vos_mem_set(&(pMac->oemData), sizeof(tOemDataStruct), 0);
82 if(!HAL_STATUS_SUCCESS(status))
83 {
Kiran Kumar Lokere691dde12013-03-06 17:00:31 -080084 smsLog(pMac, LOGE, "oemData_OemDataReqOpen: Cannot allocate memory for the timer function");
Jeff Johnsone7245742012-09-05 17:12:55 -070085 break;
86 }
87 } while(0);
88
89 return status;
90}
91
92/* ---------------------------------------------------------------------------
93 \fn oemData_OemDataReqClose
94 \brief This function must be called before closing the csr module
95 \return eHalStatus
96 -------------------------------------------------------------------------------*/
97
98eHalStatus oemData_OemDataReqClose(tHalHandle hHal)
99{
100 eHalStatus status = eHAL_STATUS_SUCCESS;
101 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
102
103 do
104 {
105 if(!HAL_STATUS_SUCCESS(status))
106 {
Kiran Kumar Lokere691dde12013-03-06 17:00:31 -0800107 smsLog(pMac, LOGE, "oemData_OemDataReqClose: Failed in oemData_OemDataReqClose at StopTimers");
Jeff Johnsone7245742012-09-05 17:12:55 -0700108 break;
109 }
110
111 if(pMac->oemData.pOemDataRsp != NULL)
112 {
113 vos_mem_free(pMac->oemData.pOemDataRsp);
114 }
115
116 //initialize all the variables to null
117 vos_mem_set(&(pMac->oemData), sizeof(tOemDataStruct), 0);
118 } while(0);
119
120 return eHAL_STATUS_SUCCESS;
121}
122
123/* ---------------------------------------------------------------------------
124 \fn oemData_ReleaseOemDataReqCommand
125 \brief This function removes the oemDataCommand from the active list and
126 and frees up any memory occupied by this
127 \return eHalStatus
128 -------------------------------------------------------------------------------*/
129void oemData_ReleaseOemDataReqCommand(tpAniSirGlobal pMac, tSmeCmd *pOemDataCmd, eOemDataReqStatus oemDataReqStatus)
130{
131 //Do the callback
132 pOemDataCmd->u.oemDataCmd.callback(pMac, pOemDataCmd->u.oemDataCmd.pContext, pOemDataCmd->u.oemDataCmd.oemDataReqID, oemDataReqStatus);
133
134 //First take this command out of the active list
135 if(csrLLRemoveEntry(&pMac->sme.smeCmdActiveList, &pOemDataCmd->Link, LL_ACCESS_LOCK))
136 {
137 vos_mem_set(&(pOemDataCmd->u.oemDataCmd), sizeof(tOemDataCmd), 0);
138
139 //Now put this command back on the avilable command list
140 smeReleaseCommand(pMac, pOemDataCmd);
141 }
142 else
143 {
Kiran Kumar Lokere691dde12013-03-06 17:00:31 -0800144 smsLog(pMac, LOGE, "OEM_DATA: **************** oemData_ReleaseOemDataReqCommand cannot release the command");
Jeff Johnsone7245742012-09-05 17:12:55 -0700145 }
146}
147
148/* ---------------------------------------------------------------------------
149 \fn oemData_OemDataReq
150 \brief Request an OEM DATA RSP
151 \param sessionId - Id of session to be used
152 \param pOemDataReqID - pointer to an object to get back the request ID
153 \param callback - a callback function that is called upon finish
154 \param pContext - a pointer passed in for the callback
155 \return eHalStatus
156 -------------------------------------------------------------------------------*/
157eHalStatus oemData_OemDataReq(tHalHandle hHal,
158 tANI_U8 sessionId,
159 tOemDataReqConfig *oemDataReqConfig,
160 tANI_U32 *pOemDataReqID,
161 oemData_OemDataReqCompleteCallback callback,
162 void *pContext)
163{
164 eHalStatus status = eHAL_STATUS_SUCCESS;
165 tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
166 tSmeCmd *pOemDataCmd = NULL;
167
168 do
169 {
170 if( !CSR_IS_SESSION_VALID( pMac, sessionId ) )
171 {
172 status = eHAL_STATUS_FAILURE;
173 break;
174 }
175
176 pMac->oemData.oemDataReqConfig.sessionId = sessionId;
177 pMac->oemData.callback = callback;
178 pMac->oemData.pContext = pContext;
179 pMac->oemData.oemDataReqID = *(pOemDataReqID);
180
181 vos_mem_copy((v_VOID_t*)(pMac->oemData.oemDataReqConfig.oemDataReq), (v_VOID_t*)(oemDataReqConfig->oemDataReq), OEM_DATA_REQ_SIZE);
182
183 pMac->oemData.oemDataReqActive = eANI_BOOLEAN_FALSE;
184
185 pOemDataCmd = smeGetCommandBuffer(pMac);
186
187 //fill up the command before posting it.
188 if(pOemDataCmd)
189 {
190 pOemDataCmd->command = eSmeCommandOemDataReq;
191 pOemDataCmd->u.oemDataCmd.callback = callback;
192 pOemDataCmd->u.oemDataCmd.pContext = pContext;
193 pOemDataCmd->u.oemDataCmd.oemDataReqID = pMac->oemData.oemDataReqID;
194
195 //set the oem data request
196 pOemDataCmd->u.oemDataCmd.oemDataReq.sessionId = pMac->oemData.oemDataReqConfig.sessionId;
197 vos_mem_copy((v_VOID_t*)(pOemDataCmd->u.oemDataCmd.oemDataReq.oemDataReq),
198 (v_VOID_t*)(pMac->oemData.oemDataReqConfig.oemDataReq), OEM_DATA_REQ_SIZE);
199 }
200 else
201 {
202 status = eHAL_STATUS_FAILURE;
203 break;
204 }
205
206 //now queue this command in the sme command queue
207 //Here since this is not interacting with the csr just push the command
208 //into the sme queue. Also push this command with the normal priority
209 smePushCommand(pMac, pOemDataCmd, eANI_BOOLEAN_FALSE);
210
211 } while(0);
212
213 if(!HAL_STATUS_SUCCESS(status) && pOemDataCmd)
214 {
215 oemData_ReleaseOemDataReqCommand(pMac, pOemDataCmd, eOEM_DATA_REQ_FAILURE);
216 pMac->oemData.oemDataReqActive = eANI_BOOLEAN_FALSE;
217 }
218
219 return status;
220}
221
222/* ---------------------------------------------------------------------------
223 \fn oemData_SendMBOemDataReq
224 \brief Request an OEM DATA REQ to be passed down to PE
225 \param pMac:
226 \param pOemDataReq: Pointer to the oem data request
227 \return eHalStatus
228 -------------------------------------------------------------------------------*/
229eHalStatus oemData_SendMBOemDataReq(tpAniSirGlobal pMac, tOemDataReq *pOemDataReq)
230{
231 eHalStatus status = eHAL_STATUS_SUCCESS;
232 tSirOemDataReq* pMsg;
233 tANI_U16 msgLen;
234 tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, pOemDataReq->sessionId );
235
Kiran Kumar Lokere691dde12013-03-06 17:00:31 -0800236 smsLog(pMac, LOGW, "OEM_DATA: entering Function %s", __func__);
Jeff Johnsone7245742012-09-05 17:12:55 -0700237
238 msgLen = (tANI_U16)(sizeof(tSirOemDataReq));
239
240 status = palAllocateMemory(pMac->hHdd, (void**)&pMsg, msgLen);
241 if(HAL_STATUS_SUCCESS(status))
242 {
243 palZeroMemory(pMac->hHdd, pMsg, msgLen);
244 pMsg->messageType = pal_cpu_to_be16((tANI_U16)eWNI_SME_OEM_DATA_REQ);
245 palCopyMemory(pMac->hHdd, pMsg->selfMacAddr, pSession->selfMacAddr, sizeof(tSirMacAddr) );
246 status = palCopyMemory(pMac->hHdd, pMsg->oemDataReq, pOemDataReq->oemDataReq, OEM_DATA_REQ_SIZE);
247 if(HAL_STATUS_SUCCESS(status))
248 {
Kiran Kumar Lokere691dde12013-03-06 17:00:31 -0800249 smsLog(pMac, LOGW, "OEM_DATA: sending message to pe%s", __func__);
Jeff Johnsone7245742012-09-05 17:12:55 -0700250 status = palSendMBMessage(pMac->hHdd, pMsg);
251 }
252 else
253 {
254 palFreeMemory(pMac->hHdd, pMsg);
255 }
256 }
257
Kiran Kumar Lokere691dde12013-03-06 17:00:31 -0800258 smsLog(pMac, LOGW, "OEM_DATA: exiting Function %s", __func__);
Jeff Johnsone7245742012-09-05 17:12:55 -0700259
260 return status;
261}
262
263/* ---------------------------------------------------------------------------
264 \fn oemData_ProcessOemDataReqCommand
265 \brief This function is called by the smeProcessCommand when the case hits
266 eSmeCommandOemDataReq
267 \return eHalStatus
268 -------------------------------------------------------------------------------*/
269eHalStatus oemData_ProcessOemDataReqCommand(tpAniSirGlobal pMac, tSmeCmd *pOemDataReqCmd)
270{
271 eHalStatus status = eHAL_STATUS_SUCCESS;
272
273 //check if the system is in proper mode of operation for
274 //oem data req/rsp to be functional. Currently, concurrency is not
275 //supported and the driver must be operational only as
276 //STA for oem data req/rsp to be functional. We return an invalid
277 //mode flag if it is operational as any one of the following
278 //in any of the active sessions
279 //1. AP Mode
280 //2. IBSS Mode
281 //3. BTAMP Mode ...
282
283 if(eHAL_STATUS_SUCCESS == oemData_IsOemDataReqAllowed(pMac))
284 {
Kiran Kumar Lokere691dde12013-03-06 17:00:31 -0800285 smsLog(pMac, LOG1, "%s: OEM_DATA REQ allowed in the current mode", __func__);
Jeff Johnsone7245742012-09-05 17:12:55 -0700286 pMac->oemData.oemDataReqActive = eANI_BOOLEAN_TRUE;
287 status = oemData_SendMBOemDataReq(pMac, &(pOemDataReqCmd->u.oemDataCmd.oemDataReq));
288 }
289 else
290 {
Kiran Kumar Lokere691dde12013-03-06 17:00:31 -0800291 smsLog(pMac, LOG1, "%s: OEM_DATA REQ not allowed in the current mode", __func__);
Jeff Johnsone7245742012-09-05 17:12:55 -0700292 oemData_ReleaseOemDataReqCommand(pMac, pOemDataReqCmd, eOEM_DATA_REQ_INVALID_MODE);
293 pMac->oemData.oemDataReqActive = eANI_BOOLEAN_FALSE;
294 }
295
296 return status;
297}
298
299/* ---------------------------------------------------------------------------
300 \fn sme_HandleOemDataRsp
301 \brief This function processes the oem data response obtained from the PE
302 \param pMsg - Pointer to the pSirOemDataRsp
303 \return eHalStatus
304 -------------------------------------------------------------------------------*/
305eHalStatus sme_HandleOemDataRsp(tHalHandle hHal, tANI_U8* pMsg)
306{
307 eHalStatus status = eHAL_STATUS_SUCCESS;
308 tpAniSirGlobal pMac;
309 tListElem *pEntry = NULL;
310 tSmeCmd *pCommand = NULL;
311 tSirOemDataRsp* pOemDataRsp = NULL;
312 pMac = PMAC_STRUCT(hHal);
313
Kiran Kumar Lokere691dde12013-03-06 17:00:31 -0800314 smsLog(pMac, LOG1, "%s: OEM_DATA Entering", __func__);
Jeff Johnsone7245742012-09-05 17:12:55 -0700315
316 do
317 {
318 if(pMsg == NULL)
319 {
Kiran Kumar Lokere691dde12013-03-06 17:00:31 -0800320 smsLog(pMac, LOGE, "in %s msg ptr is NULL", __func__);
Jeff Johnsone7245742012-09-05 17:12:55 -0700321 status = eHAL_STATUS_FAILURE;
322 break;
323 }
324
325 pEntry = csrLLPeekHead( &pMac->sme.smeCmdActiveList, LL_ACCESS_LOCK );
326 if(pEntry)
327 {
328 pCommand = GET_BASE_ADDR( pEntry, tSmeCmd, Link );
329 if(eSmeCommandOemDataReq == pCommand->command)
330 {
331 pOemDataRsp = (tSirOemDataRsp*)pMsg;
332
333 //make sure to acquire the lock before modifying the data
334 status = sme_AcquireGlobalLock(&pMac->sme);
335 if(!HAL_STATUS_SUCCESS(status))
336 {
337 break;
338 }
339
340 if(pMac->oemData.pOemDataRsp != NULL)
341 {
342 vos_mem_free(pMac->oemData.pOemDataRsp);
343 }
344 pMac->oemData.pOemDataRsp = (tOemDataRsp*)vos_mem_malloc(sizeof(tOemDataRsp));
345
346 if(pMac->oemData.pOemDataRsp == NULL)
347 {
348 sme_ReleaseGlobalLock(&pMac->sme);
Kiran Kumar Lokere691dde12013-03-06 17:00:31 -0800349 smsLog(pMac, LOGE, "in %s vos_mem_malloc failed for pMac->oemData.pOemDataRsp", __func__);
Jeff Johnsone7245742012-09-05 17:12:55 -0700350 status = eHAL_STATUS_FAILURE;
351 break;
352 }
353
Kiran Kumar Lokere691dde12013-03-06 17:00:31 -0800354 smsLog(pMac, LOGE, "Before memory copy");
Jeff Johnsone7245742012-09-05 17:12:55 -0700355 vos_mem_copy((v_VOID_t*)(pMac->oemData.pOemDataRsp), (v_VOID_t*)(&pOemDataRsp->oemDataRsp), sizeof(tOemDataRsp));
Kiran Kumar Lokere691dde12013-03-06 17:00:31 -0800356 smsLog(pMac, LOGE, "after memory copy");
Jeff Johnsone7245742012-09-05 17:12:55 -0700357 sme_ReleaseGlobalLock(&pMac->sme);
358 }
359 else
360 {
Kiran Kumar Lokere691dde12013-03-06 17:00:31 -0800361 smsLog(pMac, LOGE, "in %s eWNI_SME_OEM_DATA_RSP Received but NO REQs are ACTIVE ...",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700362 __func__);
Jeff Johnsone7245742012-09-05 17:12:55 -0700363 status = eHAL_STATUS_FAILURE;
364 break;
365 }
366 }
367 else
368 {
Kiran Kumar Lokere691dde12013-03-06 17:00:31 -0800369 smsLog(pMac, LOGE, "in %s eWNI_SME_OEM_DATA_RSP Received but NO commands are ACTIVE ...", __func__);
Jeff Johnsone7245742012-09-05 17:12:55 -0700370 status = eHAL_STATUS_FAILURE;
371 break;
372 }
373
374 oemData_ReleaseOemDataReqCommand(pMac, pCommand, eHAL_STATUS_SUCCESS);
375 pMac->oemData.oemDataReqActive = eANI_BOOLEAN_FALSE;
376
377 } while(0);
378
379 return status;
380}
381
382/* ---------------------------------------------------------------------------
383 \fn oemData_IsOemDataReqAllowed
384 \brief This function checks if OEM DATA REQs can be performed in the
385 current driver state
386 \return eHalStatus
387 -------------------------------------------------------------------------------*/
388eHalStatus oemData_IsOemDataReqAllowed(tHalHandle hHal)
389{
390 eHalStatus status = eHAL_STATUS_SUCCESS;
391 tANI_U32 sessionId;
392
393 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
394
395 for(sessionId = 0; sessionId < CSR_ROAM_SESSION_MAX; sessionId++)
396 {
397 if(CSR_IS_SESSION_VALID(pMac, sessionId))
398 {
399 if(csrIsConnStateIbss(pMac, sessionId) || csrIsBTAMP(pMac, sessionId)
Jeff Johnsone7245742012-09-05 17:12:55 -0700400 || csrIsConnStateConnectedInfraAp(pMac, sessionId)
Jeff Johnsone7245742012-09-05 17:12:55 -0700401 )
402 {
403 //co-exist with IBSS or BT-AMP or Soft-AP mode is not supported
Kiran Kumar Lokere691dde12013-03-06 17:00:31 -0800404 smsLog(pMac, LOGW, "OEM DATA REQ is not allowed due to IBSS|BTAMP|SAP exist in session %d", sessionId);
Jeff Johnsone7245742012-09-05 17:12:55 -0700405 status = eHAL_STATUS_CSR_WRONG_STATE;
406 break;
407 }
408 }
409 }
410
Kiran Kumar Lokere691dde12013-03-06 17:00:31 -0800411 smsLog(pMac, LOG1, "Exiting oemData_IsOemDataReqAllowed with status %d", status);
Jeff Johnsone7245742012-09-05 17:12:55 -0700412
413 return (status);
414}
415
416#endif /*FEATURE_OEM_DATA_SUPPORT*/