blob: f7fac1cf57d626bd092620a35a950061239c0ed3 [file] [log] [blame]
Jeff Johnsone7245742012-09-05 17:12:55 -07001/*
Jeff Johnson32d95a32012-09-10 13:15:23 -07002 * Copyright (c) 2012, The Linux Foundation. All rights reserved.
Jeff Johnsone7245742012-09-05 17:12:55 -07003 *
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#ifdef FEATURE_OEM_DATA_SUPPORT
23/** ------------------------------------------------------------------------- *
24 ------------------------------------------------------------------------- *
25
26
27 \file oemDataApi.c
28
29 Implementation for the OEM DATA REQ/RSP interfaces.
30
31 Copyright (C) 2010 Qualcomm Incorporated.
32
33
34 ========================================================================== */
35#include "aniGlobal.h"
36#include "oemDataApi.h"
37#include "palApi.h"
38#include "smeInside.h"
39#include "smsDebug.h"
40
41#include "csrSupport.h"
42#include "wlan_qct_tl.h"
43
44#include "vos_diag_core_log.h"
45#include "vos_diag_core_event.h"
46
47/* ---------------------------------------------------------------------------
48 \fn oemData_OemDataReqOpen
49 \brief This function must be called before any API call to (OEM DATA REQ/RSP module)
50 \return eHalStatus
51 -------------------------------------------------------------------------------*/
52
53eHalStatus oemData_OemDataReqOpen(tHalHandle hHal)
54{
55 eHalStatus status = eHAL_STATUS_SUCCESS;
56 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
57
58 do
59 {
60 //initialize all the variables to null
61 vos_mem_set(&(pMac->oemData), sizeof(tOemDataStruct), 0);
62 if(!HAL_STATUS_SUCCESS(status))
63 {
64 smsLog(pMac, LOGE, "oemData_OemDataReqOpen: Cannot allocate memory for the timer function\n");
65 break;
66 }
67 } while(0);
68
69 return status;
70}
71
72/* ---------------------------------------------------------------------------
73 \fn oemData_OemDataReqClose
74 \brief This function must be called before closing the csr module
75 \return eHalStatus
76 -------------------------------------------------------------------------------*/
77
78eHalStatus oemData_OemDataReqClose(tHalHandle hHal)
79{
80 eHalStatus status = eHAL_STATUS_SUCCESS;
81 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
82
83 do
84 {
85 if(!HAL_STATUS_SUCCESS(status))
86 {
87 smsLog(pMac, LOGE, "oemData_OemDataReqClose: Failed in oemData_OemDataReqClose at StopTimers\n");
88 break;
89 }
90
91 if(pMac->oemData.pOemDataRsp != NULL)
92 {
93 vos_mem_free(pMac->oemData.pOemDataRsp);
94 }
95
96 //initialize all the variables to null
97 vos_mem_set(&(pMac->oemData), sizeof(tOemDataStruct), 0);
98 } while(0);
99
100 return eHAL_STATUS_SUCCESS;
101}
102
103/* ---------------------------------------------------------------------------
104 \fn oemData_ReleaseOemDataReqCommand
105 \brief This function removes the oemDataCommand from the active list and
106 and frees up any memory occupied by this
107 \return eHalStatus
108 -------------------------------------------------------------------------------*/
109void oemData_ReleaseOemDataReqCommand(tpAniSirGlobal pMac, tSmeCmd *pOemDataCmd, eOemDataReqStatus oemDataReqStatus)
110{
111 //Do the callback
112 pOemDataCmd->u.oemDataCmd.callback(pMac, pOemDataCmd->u.oemDataCmd.pContext, pOemDataCmd->u.oemDataCmd.oemDataReqID, oemDataReqStatus);
113
114 //First take this command out of the active list
115 if(csrLLRemoveEntry(&pMac->sme.smeCmdActiveList, &pOemDataCmd->Link, LL_ACCESS_LOCK))
116 {
117 vos_mem_set(&(pOemDataCmd->u.oemDataCmd), sizeof(tOemDataCmd), 0);
118
119 //Now put this command back on the avilable command list
120 smeReleaseCommand(pMac, pOemDataCmd);
121 }
122 else
123 {
124 smsLog(pMac, LOGE, "OEM_DATA: **************** oemData_ReleaseOemDataReqCommand cannot release the command\n");
125 }
126}
127
128/* ---------------------------------------------------------------------------
129 \fn oemData_OemDataReq
130 \brief Request an OEM DATA RSP
131 \param sessionId - Id of session to be used
132 \param pOemDataReqID - pointer to an object to get back the request ID
133 \param callback - a callback function that is called upon finish
134 \param pContext - a pointer passed in for the callback
135 \return eHalStatus
136 -------------------------------------------------------------------------------*/
137eHalStatus oemData_OemDataReq(tHalHandle hHal,
138 tANI_U8 sessionId,
139 tOemDataReqConfig *oemDataReqConfig,
140 tANI_U32 *pOemDataReqID,
141 oemData_OemDataReqCompleteCallback callback,
142 void *pContext)
143{
144 eHalStatus status = eHAL_STATUS_SUCCESS;
145 tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
146 tSmeCmd *pOemDataCmd = NULL;
147
148 do
149 {
150 if( !CSR_IS_SESSION_VALID( pMac, sessionId ) )
151 {
152 status = eHAL_STATUS_FAILURE;
153 break;
154 }
155
156 pMac->oemData.oemDataReqConfig.sessionId = sessionId;
157 pMac->oemData.callback = callback;
158 pMac->oemData.pContext = pContext;
159 pMac->oemData.oemDataReqID = *(pOemDataReqID);
160
161 vos_mem_copy((v_VOID_t*)(pMac->oemData.oemDataReqConfig.oemDataReq), (v_VOID_t*)(oemDataReqConfig->oemDataReq), OEM_DATA_REQ_SIZE);
162
163 pMac->oemData.oemDataReqActive = eANI_BOOLEAN_FALSE;
164
165 pOemDataCmd = smeGetCommandBuffer(pMac);
166
167 //fill up the command before posting it.
168 if(pOemDataCmd)
169 {
170 pOemDataCmd->command = eSmeCommandOemDataReq;
171 pOemDataCmd->u.oemDataCmd.callback = callback;
172 pOemDataCmd->u.oemDataCmd.pContext = pContext;
173 pOemDataCmd->u.oemDataCmd.oemDataReqID = pMac->oemData.oemDataReqID;
174
175 //set the oem data request
176 pOemDataCmd->u.oemDataCmd.oemDataReq.sessionId = pMac->oemData.oemDataReqConfig.sessionId;
177 vos_mem_copy((v_VOID_t*)(pOemDataCmd->u.oemDataCmd.oemDataReq.oemDataReq),
178 (v_VOID_t*)(pMac->oemData.oemDataReqConfig.oemDataReq), OEM_DATA_REQ_SIZE);
179 }
180 else
181 {
182 status = eHAL_STATUS_FAILURE;
183 break;
184 }
185
186 //now queue this command in the sme command queue
187 //Here since this is not interacting with the csr just push the command
188 //into the sme queue. Also push this command with the normal priority
189 smePushCommand(pMac, pOemDataCmd, eANI_BOOLEAN_FALSE);
190
191 } while(0);
192
193 if(!HAL_STATUS_SUCCESS(status) && pOemDataCmd)
194 {
195 oemData_ReleaseOemDataReqCommand(pMac, pOemDataCmd, eOEM_DATA_REQ_FAILURE);
196 pMac->oemData.oemDataReqActive = eANI_BOOLEAN_FALSE;
197 }
198
199 return status;
200}
201
202/* ---------------------------------------------------------------------------
203 \fn oemData_SendMBOemDataReq
204 \brief Request an OEM DATA REQ to be passed down to PE
205 \param pMac:
206 \param pOemDataReq: Pointer to the oem data request
207 \return eHalStatus
208 -------------------------------------------------------------------------------*/
209eHalStatus oemData_SendMBOemDataReq(tpAniSirGlobal pMac, tOemDataReq *pOemDataReq)
210{
211 eHalStatus status = eHAL_STATUS_SUCCESS;
212 tSirOemDataReq* pMsg;
213 tANI_U16 msgLen;
214 tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, pOemDataReq->sessionId );
215
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700216 smsLog(pMac, LOGW, "OEM_DATA: entering Function %s\n", __func__);
Jeff Johnsone7245742012-09-05 17:12:55 -0700217
218 msgLen = (tANI_U16)(sizeof(tSirOemDataReq));
219
220 status = palAllocateMemory(pMac->hHdd, (void**)&pMsg, msgLen);
221 if(HAL_STATUS_SUCCESS(status))
222 {
223 palZeroMemory(pMac->hHdd, pMsg, msgLen);
224 pMsg->messageType = pal_cpu_to_be16((tANI_U16)eWNI_SME_OEM_DATA_REQ);
225 palCopyMemory(pMac->hHdd, pMsg->selfMacAddr, pSession->selfMacAddr, sizeof(tSirMacAddr) );
226 status = palCopyMemory(pMac->hHdd, pMsg->oemDataReq, pOemDataReq->oemDataReq, OEM_DATA_REQ_SIZE);
227 if(HAL_STATUS_SUCCESS(status))
228 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700229 smsLog(pMac, LOGW, "OEM_DATA: sending message to pe%s\n", __func__);
Jeff Johnsone7245742012-09-05 17:12:55 -0700230 status = palSendMBMessage(pMac->hHdd, pMsg);
231 }
232 else
233 {
234 palFreeMemory(pMac->hHdd, pMsg);
235 }
236 }
237
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700238 smsLog(pMac, LOGW, "OEM_DATA: exiting Function %s\n", __func__);
Jeff Johnsone7245742012-09-05 17:12:55 -0700239
240 return status;
241}
242
243/* ---------------------------------------------------------------------------
244 \fn oemData_ProcessOemDataReqCommand
245 \brief This function is called by the smeProcessCommand when the case hits
246 eSmeCommandOemDataReq
247 \return eHalStatus
248 -------------------------------------------------------------------------------*/
249eHalStatus oemData_ProcessOemDataReqCommand(tpAniSirGlobal pMac, tSmeCmd *pOemDataReqCmd)
250{
251 eHalStatus status = eHAL_STATUS_SUCCESS;
252
253 //check if the system is in proper mode of operation for
254 //oem data req/rsp to be functional. Currently, concurrency is not
255 //supported and the driver must be operational only as
256 //STA for oem data req/rsp to be functional. We return an invalid
257 //mode flag if it is operational as any one of the following
258 //in any of the active sessions
259 //1. AP Mode
260 //2. IBSS Mode
261 //3. BTAMP Mode ...
262
263 if(eHAL_STATUS_SUCCESS == oemData_IsOemDataReqAllowed(pMac))
264 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700265 smsLog(pMac, LOG1, "%s: OEM_DATA REQ allowed in the current mode\n", __func__);
Jeff Johnsone7245742012-09-05 17:12:55 -0700266 pMac->oemData.oemDataReqActive = eANI_BOOLEAN_TRUE;
267 status = oemData_SendMBOemDataReq(pMac, &(pOemDataReqCmd->u.oemDataCmd.oemDataReq));
268 }
269 else
270 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700271 smsLog(pMac, LOG1, "%s: OEM_DATA REQ not allowed in the current mode\n", __func__);
Jeff Johnsone7245742012-09-05 17:12:55 -0700272 oemData_ReleaseOemDataReqCommand(pMac, pOemDataReqCmd, eOEM_DATA_REQ_INVALID_MODE);
273 pMac->oemData.oemDataReqActive = eANI_BOOLEAN_FALSE;
274 }
275
276 return status;
277}
278
279/* ---------------------------------------------------------------------------
280 \fn sme_HandleOemDataRsp
281 \brief This function processes the oem data response obtained from the PE
282 \param pMsg - Pointer to the pSirOemDataRsp
283 \return eHalStatus
284 -------------------------------------------------------------------------------*/
285eHalStatus sme_HandleOemDataRsp(tHalHandle hHal, tANI_U8* pMsg)
286{
287 eHalStatus status = eHAL_STATUS_SUCCESS;
288 tpAniSirGlobal pMac;
289 tListElem *pEntry = NULL;
290 tSmeCmd *pCommand = NULL;
291 tSirOemDataRsp* pOemDataRsp = NULL;
292 pMac = PMAC_STRUCT(hHal);
293
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700294 smsLog(pMac, LOG1, "%s: OEM_DATA Entering\n", __func__);
Jeff Johnsone7245742012-09-05 17:12:55 -0700295
296 do
297 {
298 if(pMsg == NULL)
299 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700300 smsLog(pMac, LOGE, "in %s msg ptr is NULL\n", __func__);
Jeff Johnsone7245742012-09-05 17:12:55 -0700301 status = eHAL_STATUS_FAILURE;
302 break;
303 }
304
305 pEntry = csrLLPeekHead( &pMac->sme.smeCmdActiveList, LL_ACCESS_LOCK );
306 if(pEntry)
307 {
308 pCommand = GET_BASE_ADDR( pEntry, tSmeCmd, Link );
309 if(eSmeCommandOemDataReq == pCommand->command)
310 {
311 pOemDataRsp = (tSirOemDataRsp*)pMsg;
312
313 //make sure to acquire the lock before modifying the data
314 status = sme_AcquireGlobalLock(&pMac->sme);
315 if(!HAL_STATUS_SUCCESS(status))
316 {
317 break;
318 }
319
320 if(pMac->oemData.pOemDataRsp != NULL)
321 {
322 vos_mem_free(pMac->oemData.pOemDataRsp);
323 }
324 pMac->oemData.pOemDataRsp = (tOemDataRsp*)vos_mem_malloc(sizeof(tOemDataRsp));
325
326 if(pMac->oemData.pOemDataRsp == NULL)
327 {
328 sme_ReleaseGlobalLock(&pMac->sme);
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700329 smsLog(pMac, LOGE, "in %s vos_mem_malloc failed for pMac->oemData.pOemDataRsp\n", __func__);
Jeff Johnsone7245742012-09-05 17:12:55 -0700330 status = eHAL_STATUS_FAILURE;
331 break;
332 }
333
334 smsLog(pMac, LOGE, "Before memory copy\n");
335 vos_mem_copy((v_VOID_t*)(pMac->oemData.pOemDataRsp), (v_VOID_t*)(&pOemDataRsp->oemDataRsp), sizeof(tOemDataRsp));
336 smsLog(pMac, LOGE, "after memory copy\n");
337 sme_ReleaseGlobalLock(&pMac->sme);
338 }
339 else
340 {
341 smsLog(pMac, LOGE, "in %s eWNI_SME_OEM_DATA_RSP Received but NO REQs are ACTIVE ...\n",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700342 __func__);
Jeff Johnsone7245742012-09-05 17:12:55 -0700343 status = eHAL_STATUS_FAILURE;
344 break;
345 }
346 }
347 else
348 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700349 smsLog(pMac, LOGE, "in %s eWNI_SME_OEM_DATA_RSP Received but NO commands are ACTIVE ...\n", __func__);
Jeff Johnsone7245742012-09-05 17:12:55 -0700350 status = eHAL_STATUS_FAILURE;
351 break;
352 }
353
354 oemData_ReleaseOemDataReqCommand(pMac, pCommand, eHAL_STATUS_SUCCESS);
355 pMac->oemData.oemDataReqActive = eANI_BOOLEAN_FALSE;
356
357 } while(0);
358
359 return status;
360}
361
362/* ---------------------------------------------------------------------------
363 \fn oemData_IsOemDataReqAllowed
364 \brief This function checks if OEM DATA REQs can be performed in the
365 current driver state
366 \return eHalStatus
367 -------------------------------------------------------------------------------*/
368eHalStatus oemData_IsOemDataReqAllowed(tHalHandle hHal)
369{
370 eHalStatus status = eHAL_STATUS_SUCCESS;
371 tANI_U32 sessionId;
372
373 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
374
375 for(sessionId = 0; sessionId < CSR_ROAM_SESSION_MAX; sessionId++)
376 {
377 if(CSR_IS_SESSION_VALID(pMac, sessionId))
378 {
379 if(csrIsConnStateIbss(pMac, sessionId) || csrIsBTAMP(pMac, sessionId)
380#ifdef WLAN_SOFTAP_FEATURE
381 || csrIsConnStateConnectedInfraAp(pMac, sessionId)
382#endif
383 )
384 {
385 //co-exist with IBSS or BT-AMP or Soft-AP mode is not supported
386 smsLog(pMac, LOGW, "OEM DATA REQ is not allowed due to IBSS|BTAMP|SAP exist in session %d\n", sessionId);
387 status = eHAL_STATUS_CSR_WRONG_STATE;
388 break;
389 }
390 }
391 }
392
393 smsLog(pMac, LOG1, "Exiting oemData_IsOemDataReqAllowed with status %d\n", status);
394
395 return (status);
396}
397
398#endif /*FEATURE_OEM_DATA_SUPPORT*/