blob: ce01b19defcfd9cb9e9c6f689ef36a5f30e7f2cd [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
Bernala0eafe12013-04-26 09:08:08 -070043/** ------------------------------------------------------------------------- *
44 ------------------------------------------------------------------------- *
Jeff Johnsone7245742012-09-05 17:12:55 -070045
Bernala0eafe12013-04-26 09:08:08 -070046
Jeff Johnsone7245742012-09-05 17:12:55 -070047 \file oemDataApi.c
Bernala0eafe12013-04-26 09:08:08 -070048
Jeff Johnsone7245742012-09-05 17:12:55 -070049 Implementation for the OEM DATA REQ/RSP interfaces.
Jeff Johnsone7245742012-09-05 17:12:55 -070050 ========================================================================== */
51#include "aniGlobal.h"
52#include "oemDataApi.h"
53#include "palApi.h"
54#include "smeInside.h"
55#include "smsDebug.h"
56
57#include "csrSupport.h"
58#include "wlan_qct_tl.h"
59
60#include "vos_diag_core_log.h"
61#include "vos_diag_core_event.h"
62
63/* ---------------------------------------------------------------------------
64 \fn oemData_OemDataReqOpen
65 \brief This function must be called before any API call to (OEM DATA REQ/RSP module)
Bernala0eafe12013-04-26 09:08:08 -070066 \return eHalStatus
Jeff Johnsone7245742012-09-05 17:12:55 -070067 -------------------------------------------------------------------------------*/
68
69eHalStatus oemData_OemDataReqOpen(tHalHandle hHal)
70{
71 eHalStatus status = eHAL_STATUS_SUCCESS;
72 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
73
74 do
75 {
76 //initialize all the variables to null
77 vos_mem_set(&(pMac->oemData), sizeof(tOemDataStruct), 0);
78 if(!HAL_STATUS_SUCCESS(status))
79 {
Kiran Kumar Lokere691dde12013-03-06 17:00:31 -080080 smsLog(pMac, LOGE, "oemData_OemDataReqOpen: Cannot allocate memory for the timer function");
Jeff Johnsone7245742012-09-05 17:12:55 -070081 break;
82 }
83 } while(0);
84
85 return status;
86}
87
88/* ---------------------------------------------------------------------------
89 \fn oemData_OemDataReqClose
90 \brief This function must be called before closing the csr module
Bernala0eafe12013-04-26 09:08:08 -070091 \return eHalStatus
Jeff Johnsone7245742012-09-05 17:12:55 -070092 -------------------------------------------------------------------------------*/
93
94eHalStatus oemData_OemDataReqClose(tHalHandle hHal)
95{
96 eHalStatus status = eHAL_STATUS_SUCCESS;
97 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
98
99 do
100 {
101 if(!HAL_STATUS_SUCCESS(status))
102 {
Kiran Kumar Lokere691dde12013-03-06 17:00:31 -0800103 smsLog(pMac, LOGE, "oemData_OemDataReqClose: Failed in oemData_OemDataReqClose at StopTimers");
Jeff Johnsone7245742012-09-05 17:12:55 -0700104 break;
105 }
106
107 if(pMac->oemData.pOemDataRsp != NULL)
108 {
109 vos_mem_free(pMac->oemData.pOemDataRsp);
110 }
Bernala0eafe12013-04-26 09:08:08 -0700111
Jeff Johnsone7245742012-09-05 17:12:55 -0700112 //initialize all the variables to null
113 vos_mem_set(&(pMac->oemData), sizeof(tOemDataStruct), 0);
114 } while(0);
115
116 return eHAL_STATUS_SUCCESS;
117}
118
119/* ---------------------------------------------------------------------------
120 \fn oemData_ReleaseOemDataReqCommand
Bernala0eafe12013-04-26 09:08:08 -0700121 \brief This function removes the oemDataCommand from the active list and
Jeff Johnsone7245742012-09-05 17:12:55 -0700122 and frees up any memory occupied by this
Bernala0eafe12013-04-26 09:08:08 -0700123 \return eHalStatus
Jeff Johnsone7245742012-09-05 17:12:55 -0700124 -------------------------------------------------------------------------------*/
125void oemData_ReleaseOemDataReqCommand(tpAniSirGlobal pMac, tSmeCmd *pOemDataCmd, eOemDataReqStatus oemDataReqStatus)
126{
127 //Do the callback
128 pOemDataCmd->u.oemDataCmd.callback(pMac, pOemDataCmd->u.oemDataCmd.pContext, pOemDataCmd->u.oemDataCmd.oemDataReqID, oemDataReqStatus);
129
130 //First take this command out of the active list
131 if(csrLLRemoveEntry(&pMac->sme.smeCmdActiveList, &pOemDataCmd->Link, LL_ACCESS_LOCK))
132 {
133 vos_mem_set(&(pOemDataCmd->u.oemDataCmd), sizeof(tOemDataCmd), 0);
134
135 //Now put this command back on the avilable command list
136 smeReleaseCommand(pMac, pOemDataCmd);
137 }
138 else
139 {
Kiran Kumar Lokere691dde12013-03-06 17:00:31 -0800140 smsLog(pMac, LOGE, "OEM_DATA: **************** oemData_ReleaseOemDataReqCommand cannot release the command");
Jeff Johnsone7245742012-09-05 17:12:55 -0700141 }
142}
143
144/* ---------------------------------------------------------------------------
145 \fn oemData_OemDataReq
146 \brief Request an OEM DATA RSP
147 \param sessionId - Id of session to be used
148 \param pOemDataReqID - pointer to an object to get back the request ID
149 \param callback - a callback function that is called upon finish
150 \param pContext - a pointer passed in for the callback
Bernala0eafe12013-04-26 09:08:08 -0700151 \return eHalStatus
Jeff Johnsone7245742012-09-05 17:12:55 -0700152 -------------------------------------------------------------------------------*/
Bernala0eafe12013-04-26 09:08:08 -0700153eHalStatus oemData_OemDataReq(tHalHandle hHal,
Jeff Johnsone7245742012-09-05 17:12:55 -0700154 tANI_U8 sessionId,
Bernala0eafe12013-04-26 09:08:08 -0700155 tOemDataReqConfig *oemDataReqConfig,
156 tANI_U32 *pOemDataReqID,
157 oemData_OemDataReqCompleteCallback callback,
Jeff Johnsone7245742012-09-05 17:12:55 -0700158 void *pContext)
159{
160 eHalStatus status = eHAL_STATUS_SUCCESS;
161 tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
162 tSmeCmd *pOemDataCmd = NULL;
163
Bernala0eafe12013-04-26 09:08:08 -0700164 do
Jeff Johnsone7245742012-09-05 17:12:55 -0700165 {
166 if( !CSR_IS_SESSION_VALID( pMac, sessionId ) )
167 {
168 status = eHAL_STATUS_FAILURE;
169 break;
170 }
171
172 pMac->oemData.oemDataReqConfig.sessionId = sessionId;
173 pMac->oemData.callback = callback;
174 pMac->oemData.pContext = pContext;
175 pMac->oemData.oemDataReqID = *(pOemDataReqID);
Bernala0eafe12013-04-26 09:08:08 -0700176
Jeff Johnsone7245742012-09-05 17:12:55 -0700177 vos_mem_copy((v_VOID_t*)(pMac->oemData.oemDataReqConfig.oemDataReq), (v_VOID_t*)(oemDataReqConfig->oemDataReq), OEM_DATA_REQ_SIZE);
Bernala0eafe12013-04-26 09:08:08 -0700178
Jeff Johnsone7245742012-09-05 17:12:55 -0700179 pMac->oemData.oemDataReqActive = eANI_BOOLEAN_FALSE;
Bernala0eafe12013-04-26 09:08:08 -0700180
Jeff Johnsone7245742012-09-05 17:12:55 -0700181 pOemDataCmd = smeGetCommandBuffer(pMac);
Bernala0eafe12013-04-26 09:08:08 -0700182
Jeff Johnsone7245742012-09-05 17:12:55 -0700183 //fill up the command before posting it.
184 if(pOemDataCmd)
185 {
186 pOemDataCmd->command = eSmeCommandOemDataReq;
187 pOemDataCmd->u.oemDataCmd.callback = callback;
188 pOemDataCmd->u.oemDataCmd.pContext = pContext;
189 pOemDataCmd->u.oemDataCmd.oemDataReqID = pMac->oemData.oemDataReqID;
Bernala0eafe12013-04-26 09:08:08 -0700190
Jeff Johnsone7245742012-09-05 17:12:55 -0700191 //set the oem data request
192 pOemDataCmd->u.oemDataCmd.oemDataReq.sessionId = pMac->oemData.oemDataReqConfig.sessionId;
Bernala0eafe12013-04-26 09:08:08 -0700193 vos_mem_copy((v_VOID_t*)(pOemDataCmd->u.oemDataCmd.oemDataReq.oemDataReq),
Jeff Johnsone7245742012-09-05 17:12:55 -0700194 (v_VOID_t*)(pMac->oemData.oemDataReqConfig.oemDataReq), OEM_DATA_REQ_SIZE);
195 }
196 else
197 {
198 status = eHAL_STATUS_FAILURE;
199 break;
200 }
Bernala0eafe12013-04-26 09:08:08 -0700201
Jeff Johnsone7245742012-09-05 17:12:55 -0700202 //now queue this command in the sme command queue
203 //Here since this is not interacting with the csr just push the command
204 //into the sme queue. Also push this command with the normal priority
205 smePushCommand(pMac, pOemDataCmd, eANI_BOOLEAN_FALSE);
206
207 } while(0);
208
209 if(!HAL_STATUS_SUCCESS(status) && pOemDataCmd)
210 {
211 oemData_ReleaseOemDataReqCommand(pMac, pOemDataCmd, eOEM_DATA_REQ_FAILURE);
212 pMac->oemData.oemDataReqActive = eANI_BOOLEAN_FALSE;
213 }
214
215 return status;
216}
217
218/* ---------------------------------------------------------------------------
219 \fn oemData_SendMBOemDataReq
220 \brief Request an OEM DATA REQ to be passed down to PE
221 \param pMac:
222 \param pOemDataReq: Pointer to the oem data request
Bernala0eafe12013-04-26 09:08:08 -0700223 \return eHalStatus
Jeff Johnsone7245742012-09-05 17:12:55 -0700224 -------------------------------------------------------------------------------*/
225eHalStatus oemData_SendMBOemDataReq(tpAniSirGlobal pMac, tOemDataReq *pOemDataReq)
226{
227 eHalStatus status = eHAL_STATUS_SUCCESS;
228 tSirOemDataReq* pMsg;
229 tANI_U16 msgLen;
230 tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, pOemDataReq->sessionId );
231
Kiran Kumar Lokere691dde12013-03-06 17:00:31 -0800232 smsLog(pMac, LOGW, "OEM_DATA: entering Function %s", __func__);
Bernala0eafe12013-04-26 09:08:08 -0700233
Jeff Johnsone7245742012-09-05 17:12:55 -0700234 msgLen = (tANI_U16)(sizeof(tSirOemDataReq));
235
236 status = palAllocateMemory(pMac->hHdd, (void**)&pMsg, msgLen);
237 if(HAL_STATUS_SUCCESS(status))
238 {
239 palZeroMemory(pMac->hHdd, pMsg, msgLen);
240 pMsg->messageType = pal_cpu_to_be16((tANI_U16)eWNI_SME_OEM_DATA_REQ);
241 palCopyMemory(pMac->hHdd, pMsg->selfMacAddr, pSession->selfMacAddr, sizeof(tSirMacAddr) );
242 status = palCopyMemory(pMac->hHdd, pMsg->oemDataReq, pOemDataReq->oemDataReq, OEM_DATA_REQ_SIZE);
243 if(HAL_STATUS_SUCCESS(status))
244 {
Kiran Kumar Lokere691dde12013-03-06 17:00:31 -0800245 smsLog(pMac, LOGW, "OEM_DATA: sending message to pe%s", __func__);
Jeff Johnsone7245742012-09-05 17:12:55 -0700246 status = palSendMBMessage(pMac->hHdd, pMsg);
247 }
248 else
249 {
250 palFreeMemory(pMac->hHdd, pMsg);
251 }
252 }
253
Kiran Kumar Lokere691dde12013-03-06 17:00:31 -0800254 smsLog(pMac, LOGW, "OEM_DATA: exiting Function %s", __func__);
Jeff Johnsone7245742012-09-05 17:12:55 -0700255
256 return status;
257}
258
259/* ---------------------------------------------------------------------------
260 \fn oemData_ProcessOemDataReqCommand
261 \brief This function is called by the smeProcessCommand when the case hits
262 eSmeCommandOemDataReq
Bernala0eafe12013-04-26 09:08:08 -0700263 \return eHalStatus
Jeff Johnsone7245742012-09-05 17:12:55 -0700264 -------------------------------------------------------------------------------*/
265eHalStatus oemData_ProcessOemDataReqCommand(tpAniSirGlobal pMac, tSmeCmd *pOemDataReqCmd)
266{
267 eHalStatus status = eHAL_STATUS_SUCCESS;
268
Bernala0eafe12013-04-26 09:08:08 -0700269 //check if the system is in proper mode of operation for
Jeff Johnsone7245742012-09-05 17:12:55 -0700270 //oem data req/rsp to be functional. Currently, concurrency is not
Bernala0eafe12013-04-26 09:08:08 -0700271 //supported and the driver must be operational only as
272 //STA for oem data req/rsp to be functional. We return an invalid
Jeff Johnsone7245742012-09-05 17:12:55 -0700273 //mode flag if it is operational as any one of the following
274 //in any of the active sessions
275 //1. AP Mode
276 //2. IBSS Mode
277 //3. BTAMP Mode ...
278
279 if(eHAL_STATUS_SUCCESS == oemData_IsOemDataReqAllowed(pMac))
280 {
Kiran Kumar Lokere691dde12013-03-06 17:00:31 -0800281 smsLog(pMac, LOG1, "%s: OEM_DATA REQ allowed in the current mode", __func__);
Jeff Johnsone7245742012-09-05 17:12:55 -0700282 pMac->oemData.oemDataReqActive = eANI_BOOLEAN_TRUE;
283 status = oemData_SendMBOemDataReq(pMac, &(pOemDataReqCmd->u.oemDataCmd.oemDataReq));
284 }
285 else
286 {
Kiran Kumar Lokere691dde12013-03-06 17:00:31 -0800287 smsLog(pMac, LOG1, "%s: OEM_DATA REQ not allowed in the current mode", __func__);
Jeff Johnsone7245742012-09-05 17:12:55 -0700288 oemData_ReleaseOemDataReqCommand(pMac, pOemDataReqCmd, eOEM_DATA_REQ_INVALID_MODE);
289 pMac->oemData.oemDataReqActive = eANI_BOOLEAN_FALSE;
290 }
291
292 return status;
293}
294
295/* ---------------------------------------------------------------------------
296 \fn sme_HandleOemDataRsp
297 \brief This function processes the oem data response obtained from the PE
298 \param pMsg - Pointer to the pSirOemDataRsp
Bernala0eafe12013-04-26 09:08:08 -0700299 \return eHalStatus
Jeff Johnsone7245742012-09-05 17:12:55 -0700300 -------------------------------------------------------------------------------*/
301eHalStatus sme_HandleOemDataRsp(tHalHandle hHal, tANI_U8* pMsg)
302{
303 eHalStatus status = eHAL_STATUS_SUCCESS;
304 tpAniSirGlobal pMac;
305 tListElem *pEntry = NULL;
306 tSmeCmd *pCommand = NULL;
307 tSirOemDataRsp* pOemDataRsp = NULL;
308 pMac = PMAC_STRUCT(hHal);
309
Kiran Kumar Lokere691dde12013-03-06 17:00:31 -0800310 smsLog(pMac, LOG1, "%s: OEM_DATA Entering", __func__);
Jeff Johnsone7245742012-09-05 17:12:55 -0700311
312 do
313 {
314 if(pMsg == NULL)
315 {
Kiran Kumar Lokere691dde12013-03-06 17:00:31 -0800316 smsLog(pMac, LOGE, "in %s msg ptr is NULL", __func__);
Jeff Johnsone7245742012-09-05 17:12:55 -0700317 status = eHAL_STATUS_FAILURE;
318 break;
319 }
Bernala0eafe12013-04-26 09:08:08 -0700320
Jeff Johnsone7245742012-09-05 17:12:55 -0700321 pEntry = csrLLPeekHead( &pMac->sme.smeCmdActiveList, LL_ACCESS_LOCK );
322 if(pEntry)
323 {
324 pCommand = GET_BASE_ADDR( pEntry, tSmeCmd, Link );
325 if(eSmeCommandOemDataReq == pCommand->command)
326 {
327 pOemDataRsp = (tSirOemDataRsp*)pMsg;
328
329 //make sure to acquire the lock before modifying the data
330 status = sme_AcquireGlobalLock(&pMac->sme);
331 if(!HAL_STATUS_SUCCESS(status))
332 {
333 break;
334 }
335
336 if(pMac->oemData.pOemDataRsp != NULL)
337 {
338 vos_mem_free(pMac->oemData.pOemDataRsp);
339 }
340 pMac->oemData.pOemDataRsp = (tOemDataRsp*)vos_mem_malloc(sizeof(tOemDataRsp));
341
342 if(pMac->oemData.pOemDataRsp == NULL)
343 {
344 sme_ReleaseGlobalLock(&pMac->sme);
Kiran Kumar Lokere691dde12013-03-06 17:00:31 -0800345 smsLog(pMac, LOGE, "in %s vos_mem_malloc failed for pMac->oemData.pOemDataRsp", __func__);
Jeff Johnsone7245742012-09-05 17:12:55 -0700346 status = eHAL_STATUS_FAILURE;
347 break;
348 }
349
Kiran Kumar Lokere691dde12013-03-06 17:00:31 -0800350 smsLog(pMac, LOGE, "Before memory copy");
Jeff Johnsone7245742012-09-05 17:12:55 -0700351 vos_mem_copy((v_VOID_t*)(pMac->oemData.pOemDataRsp), (v_VOID_t*)(&pOemDataRsp->oemDataRsp), sizeof(tOemDataRsp));
Kiran Kumar Lokere691dde12013-03-06 17:00:31 -0800352 smsLog(pMac, LOGE, "after memory copy");
Jeff Johnsone7245742012-09-05 17:12:55 -0700353 sme_ReleaseGlobalLock(&pMac->sme);
354 }
355 else
356 {
Kiran Kumar Lokere691dde12013-03-06 17:00:31 -0800357 smsLog(pMac, LOGE, "in %s eWNI_SME_OEM_DATA_RSP Received but NO REQs are ACTIVE ...",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700358 __func__);
Jeff Johnsone7245742012-09-05 17:12:55 -0700359 status = eHAL_STATUS_FAILURE;
360 break;
361 }
362 }
363 else
364 {
Kiran Kumar Lokere691dde12013-03-06 17:00:31 -0800365 smsLog(pMac, LOGE, "in %s eWNI_SME_OEM_DATA_RSP Received but NO commands are ACTIVE ...", __func__);
Jeff Johnsone7245742012-09-05 17:12:55 -0700366 status = eHAL_STATUS_FAILURE;
367 break;
368 }
369
370 oemData_ReleaseOemDataReqCommand(pMac, pCommand, eHAL_STATUS_SUCCESS);
371 pMac->oemData.oemDataReqActive = eANI_BOOLEAN_FALSE;
372
373 } while(0);
374
375 return status;
376}
377
378/* ---------------------------------------------------------------------------
379 \fn oemData_IsOemDataReqAllowed
Bernala0eafe12013-04-26 09:08:08 -0700380 \brief This function checks if OEM DATA REQs can be performed in the
Jeff Johnsone7245742012-09-05 17:12:55 -0700381 current driver state
Bernala0eafe12013-04-26 09:08:08 -0700382 \return eHalStatus
Jeff Johnsone7245742012-09-05 17:12:55 -0700383 -------------------------------------------------------------------------------*/
384eHalStatus oemData_IsOemDataReqAllowed(tHalHandle hHal)
385{
386 eHalStatus status = eHAL_STATUS_SUCCESS;
387 tANI_U32 sessionId;
388
389 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
390
391 for(sessionId = 0; sessionId < CSR_ROAM_SESSION_MAX; sessionId++)
392 {
393 if(CSR_IS_SESSION_VALID(pMac, sessionId))
394 {
Bernala0eafe12013-04-26 09:08:08 -0700395 //co-exist with IBSS or BT-AMP mode is not supported
396 if(csrIsConnStateIbss(pMac, sessionId) || csrIsBTAMP(pMac, sessionId) )
Jeff Johnsone7245742012-09-05 17:12:55 -0700397 {
Bernala0eafe12013-04-26 09:08:08 -0700398 //co-exist with IBSS or BT-AMP mode is not supported
399 smsLog(pMac, LOGW, "OEM DATA REQ is not allowed due to IBSS|BTAMP exist in session %d", sessionId);
Jeff Johnsone7245742012-09-05 17:12:55 -0700400 status = eHAL_STATUS_CSR_WRONG_STATE;
401 break;
402 }
403 }
404 }
405
Kiran Kumar Lokere691dde12013-03-06 17:00:31 -0800406 smsLog(pMac, LOG1, "Exiting oemData_IsOemDataReqAllowed with status %d", status);
Jeff Johnsone7245742012-09-05 17:12:55 -0700407
408 return (status);
409}
410
411#endif /*FEATURE_OEM_DATA_SUPPORT*/