blob: e7758c44d62d8f86679f03c2120e5cfdc39233f8 [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -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 Johnson295189b2012-06-20 16:38:30 -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/******************************************************************************
43*
44* Name: btcApi.c
45*
46* Description: Routines that make up the BTC API.
47*
48* Copyright 2008 (c) Qualcomm, Incorporated. All Rights Reserved.
49* Qualcomm Confidential and Proprietary.
50*
51******************************************************************************/
52#include "wlan_qct_wda.h"
53#ifndef WLAN_MDM_CODE_REDUCTION_OPT
54#include "aniGlobal.h"
55#include "smsDebug.h"
56#include "btcApi.h"
57#include "cfgApi.h"
58#include "pmc.h"
59#include "smeQosInternal.h"
60#ifdef FEATURE_WLAN_DIAG_SUPPORT
61#include "vos_diag_core_event.h"
62#include "vos_diag_core_log.h"
63#endif /* FEATURE_WLAN_DIAG_SUPPORT */
64static void btcLogEvent (tHalHandle hHal, tpSmeBtEvent pBtEvent);
65static void btcRestoreHeartBeatMonitoringHandle(void* hHal);
66static void btcUapsdCheck( tpAniSirGlobal pMac, tpSmeBtEvent pBtEvent );
67VOS_STATUS btcCheckHeartBeatMonitoring(tHalHandle hHal, tpSmeBtEvent pBtEvent);
68static void btcPowerStateCB( v_PVOID_t pContext, tPmcState pmcState );
69static VOS_STATUS btcDeferEvent( tpAniSirGlobal pMac, tpSmeBtEvent pEvent );
70static VOS_STATUS btcDeferDisconnEvent( tpAniSirGlobal pMac, tpSmeBtEvent pEvent );
71#ifdef FEATURE_WLAN_DIAG_SUPPORT
72static void btcDiagEventLog (tHalHandle hHal, tpSmeBtEvent pBtEvent);
73#endif /* FEATURE_WLAN_DIAG_SUPPORT */
74/* ---------------------------------------------------------------------------
75 \fn btcOpen
76 \brief API to init the BTC Events Layer
77 \param hHal - The handle returned by macOpen.
78 \return VOS_STATUS
79 VOS_STATUS_E_FAILURE success
80 VOS_STATUS_SUCCESS failure
81 ---------------------------------------------------------------------------*/
82VOS_STATUS btcOpen (tHalHandle hHal)
83{
84 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
85 VOS_STATUS vosStatus;
86 /* Initialize BTC configuartion. */
87 pMac->btc.btcConfig.btcExecutionMode = BTC_SMART_COEXISTENCE;
88 pMac->btc.btcConfig.btcConsBtSlotsToBlockDuringDhcp = 0;
89 pMac->btc.btcConfig.btcA2DPBtSubIntervalsDuringDhcp = BTC_MAX_NUM_ACL_BT_SUB_INTS;
90 pMac->btc.btcConfig.btcBtIntervalMode1 = BTC_BT_INTERVAL_MODE1_DEFAULT;
91 pMac->btc.btcConfig.btcWlanIntervalMode1 = BTC_WLAN_INTERVAL_MODE1_DEFAULT;
92 pMac->btc.btcConfig.btcActionOnPmFail = BTC_START_NEXT;
Jeff Johnson32d95a32012-09-10 13:15:23 -070093
94 pMac->btc.btcConfig.btcStaticLenInqBt = BTC_STATIC_BT_LEN_INQ_DEF;
95 pMac->btc.btcConfig.btcStaticLenPageBt = BTC_STATIC_BT_LEN_PAGE_DEF;
96 pMac->btc.btcConfig.btcStaticLenConnBt = BTC_STATIC_BT_LEN_CONN_DEF;
97 pMac->btc.btcConfig.btcStaticLenLeBt = BTC_STATIC_BT_LEN_LE_DEF;
98 pMac->btc.btcConfig.btcStaticLenInqWlan = BTC_STATIC_WLAN_LEN_INQ_DEF;
99 pMac->btc.btcConfig.btcStaticLenPageWlan = BTC_STATIC_WLAN_LEN_PAGE_DEF;
100 pMac->btc.btcConfig.btcStaticLenConnWlan = BTC_STATIC_WLAN_LEN_CONN_DEF;
101 pMac->btc.btcConfig.btcStaticLenLeWlan = BTC_STATIC_WLAN_LEN_LE_DEF;
102 pMac->btc.btcConfig.btcDynMaxLenBt = BTC_DYNAMIC_BT_LEN_MAX_DEF;
103 pMac->btc.btcConfig.btcDynMaxLenWlan = BTC_DYNAMIC_WLAN_LEN_MAX_DEF;
104 pMac->btc.btcConfig.btcMaxScoBlockPerc = BTC_SCO_BLOCK_PERC_DEF;
105 pMac->btc.btcConfig.btcDhcpProtOnA2dp = BTC_DHCP_ON_A2DP_DEF;
106 pMac->btc.btcConfig.btcDhcpProtOnSco = BTC_DHCP_ON_SCO_DEF;
107
Jeff Johnson295189b2012-06-20 16:38:30 -0700108 pMac->btc.btcReady = VOS_FALSE;
109 pMac->btc.btcEventState = 0;
110 pMac->btc.btcHBActive = VOS_TRUE;
Kiran Kumar Lokere3527f0c2013-02-24 22:21:28 -0800111 pMac->btc.btcScanCompromise = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -0700112
113 vosStatus = vos_timer_init( &pMac->btc.restoreHBTimer,
114 VOS_TIMER_TYPE_SW,
115 btcRestoreHeartBeatMonitoringHandle,
116 (void*) hHal);
117 if (!VOS_IS_STATUS_SUCCESS(vosStatus)) {
118 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "btcOpen: Fail to init timer");
119 return VOS_STATUS_E_FAILURE;
120 }
121 if( !HAL_STATUS_SUCCESS(pmcRegisterDeviceStateUpdateInd( pMac, btcPowerStateCB, pMac )) )
122 {
Kiran Kumar Lokere691dde12013-03-06 17:00:31 -0800123 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "btcOpen: Fail to register PMC callback");
Jeff Johnson295189b2012-06-20 16:38:30 -0700124 return VOS_STATUS_E_FAILURE;
125 }
126 return VOS_STATUS_SUCCESS;
127}
128/* ---------------------------------------------------------------------------
129 \fn btcClose
130 \brief API to exit the BTC Events Layer
131 \param hHal - The handle returned by macOpen.
132 \return VOS_STATUS
133 VOS_STATUS_E_FAILURE success
134 VOS_STATUS_SUCCESS failure
135 ---------------------------------------------------------------------------*/
136VOS_STATUS btcClose (tHalHandle hHal)
137{
138 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
139 VOS_STATUS vosStatus;
140 pMac->btc.btcReady = VOS_FALSE;
141 pMac->btc.btcUapsdOk = VOS_FALSE;
142 vos_timer_stop(&pMac->btc.restoreHBTimer);
143 vosStatus = vos_timer_destroy(&pMac->btc.restoreHBTimer);
144 if (!VOS_IS_STATUS_SUCCESS(vosStatus)) {
145 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "btcClose: Fail to destroy timer");
146 return VOS_STATUS_E_FAILURE;
147 }
148 if(!HAL_STATUS_SUCCESS(
149 pmcDeregisterDeviceStateUpdateInd(pMac, btcPowerStateCB)))
150 {
151 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_FATAL,
152 "%s: %d: cannot deregister with pmcDeregisterDeviceStateUpdateInd()",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700153 __func__, __LINE__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700154 }
155
156 return VOS_STATUS_SUCCESS;
157}
158
159/* ---------------------------------------------------------------------------
160 \fn btcReady
161 \brief fn to inform BTC that eWNI_SME_SYS_READY_IND has been sent to PE.
162 This acts as a trigger to send a message to HAL to update the BTC
163 related conig to FW. Note that if HDD configures any power BTC
164 related stuff before this API is invoked, BTC will buffer all the
165 configutaion.
166 \param hHal - The handle returned by macOpen.
167 \return VOS_STATUS
168 ---------------------------------------------------------------------------*/
169VOS_STATUS btcReady (tHalHandle hHal)
170{
171 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
172 v_U32_t cfgVal = 0;
173 v_U8_t i;
174 pMac->btc.btcReady = VOS_TRUE;
175 pMac->btc.btcUapsdOk = VOS_TRUE;
176 for(i=0; i < BT_MAX_SCO_SUPPORT; i++)
177 {
178 pMac->btc.btcScoHandles[i] = BT_INVALID_CONN_HANDLE;
179 }
180
181 // Read heartbeat threshold CFG and save it.
182 ccmCfgGetInt(pMac, WNI_CFG_HEART_BEAT_THRESHOLD, &cfgVal);
183 pMac->btc.btcHBCount = (v_U8_t)cfgVal;
184 if (btcSendCfgMsg(hHal, &(pMac->btc.btcConfig)) != VOS_STATUS_SUCCESS)
185 {
186 return VOS_STATUS_E_FAILURE;
187 }
188 return VOS_STATUS_SUCCESS;
189}
190
191static VOS_STATUS btcSendBTEvent(tpAniSirGlobal pMac, tpSmeBtEvent pBtEvent)
192{
193 vos_msg_t msg;
194 tpSmeBtEvent ptrSmeBtEvent = NULL;
195 switch(pBtEvent->btEventType)
196 {
197 case BT_EVENT_CREATE_SYNC_CONNECTION:
198 case BT_EVENT_SYNC_CONNECTION_UPDATED:
199 if(pBtEvent->uEventParam.btSyncConnection.linkType != BT_SCO &&
200 pBtEvent->uEventParam.btSyncConnection.linkType != BT_eSCO)
201 {
202 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "%s: "
203 "Invalid link type %d for Sync Connection. BT event will be dropped ",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700204 __func__, pBtEvent->uEventParam.btSyncConnection.linkType);
Jeff Johnson295189b2012-06-20 16:38:30 -0700205 return VOS_STATUS_E_FAILURE;
206 }
207 break;
208 case BT_EVENT_SYNC_CONNECTION_COMPLETE:
209 if((pBtEvent->uEventParam.btSyncConnection.status == BT_CONN_STATUS_SUCCESS) &&
210 ((pBtEvent->uEventParam.btSyncConnection.linkType != BT_SCO && pBtEvent->uEventParam.btSyncConnection.linkType != BT_eSCO) ||
211 (pBtEvent->uEventParam.btSyncConnection.connectionHandle == BT_INVALID_CONN_HANDLE)))
212 {
213 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "%s: "
214 "Invalid connection handle %d or link type %d for Sync Connection. BT event will be dropped ",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700215 __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -0700216 pBtEvent->uEventParam.btSyncConnection.connectionHandle,
217 pBtEvent->uEventParam.btSyncConnection.linkType);
218 return VOS_STATUS_E_FAILURE;
219 }
220 break;
221 case BT_EVENT_MODE_CHANGED:
222 if(pBtEvent->uEventParam.btAclModeChange.mode >= BT_ACL_MODE_MAX)
223 {
224 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "%s: "
225 "Invalid mode %d for ACL Connection. BT event will be dropped ",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700226 __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -0700227 pBtEvent->uEventParam.btAclModeChange.mode);
228 return VOS_STATUS_E_FAILURE;
229 }
230 break;
231 case BT_EVENT_DEVICE_SWITCHED_OFF:
232 pMac->btc.btcEventState = 0;
233 break;
234 default:
235 break;
236 }
237 ptrSmeBtEvent = vos_mem_malloc(sizeof(tSmeBtEvent));
238 if (NULL == ptrSmeBtEvent)
239 {
240 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "%s: "
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700241 "Not able to allocate memory for BT event", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700242 return VOS_STATUS_E_FAILURE;
243 }
244 btcLogEvent(pMac, pBtEvent);
245#ifdef FEATURE_WLAN_DIAG_SUPPORT
246 btcDiagEventLog(pMac, pBtEvent);
247#endif
248 vos_mem_copy(ptrSmeBtEvent, pBtEvent, sizeof(tSmeBtEvent));
249 msg.type = WDA_SIGNAL_BT_EVENT;
250 msg.reserved = 0;
251 msg.bodyptr = ptrSmeBtEvent;
252 if(VOS_STATUS_SUCCESS != vos_mq_post_message(VOS_MODULE_ID_WDA, &msg))
253 {
254 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "%s: "
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700255 "Not able to post WDA_SIGNAL_BT_EVENT message to WDA", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700256 vos_mem_free( ptrSmeBtEvent );
257 return VOS_STATUS_E_FAILURE;
258 }
259 // After successfully posting the message, check if heart beat
260 // monitoring needs to be turned off
261 (void)btcCheckHeartBeatMonitoring(pMac, pBtEvent);
262 //Check whether BTC and UAPSD can co-exist
263 btcUapsdCheck( pMac, pBtEvent );
264 return VOS_STATUS_SUCCESS;
265 }
266
267#ifndef WLAN_MDM_CODE_REDUCTION_OPT
268/* ---------------------------------------------------------------------------
269 \fn btcSignalBTEvent
270 \brief API to signal Bluetooth (BT) event to the WLAN driver. Based on the
271 BT event type and the current operating mode of Libra (full power,
272 BMPS, UAPSD etc), appropriate Bluetooth Coexistence (BTC) strategy
273 would be employed.
274 \param hHal - The handle returned by macOpen.
275 \param pBtEvent - Pointer to a caller allocated object of type tSmeBtEvent.
276 Caller owns the memory and is responsible for freeing it.
277 \return VOS_STATUS
278 VOS_STATUS_E_FAILURE – BT Event not passed to HAL. This can happen
279 if driver has not yet been initialized or if BTC
280 Events Layer has been disabled.
281 VOS_STATUS_SUCCESS – BT Event passed to HAL
282 ---------------------------------------------------------------------------*/
283VOS_STATUS btcSignalBTEvent (tHalHandle hHal, tpSmeBtEvent pBtEvent)
284{
285 tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
286 VOS_STATUS vosStatus;
287 if( NULL == pBtEvent )
288 {
289 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "%s: "
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700290 "Null pointer for SME BT Event", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700291 return VOS_STATUS_E_FAILURE;
292 }
293 if(( BTC_WLAN_ONLY == pMac->btc.btcConfig.btcExecutionMode ) ||
294 ( BTC_PTA_ONLY == pMac->btc.btcConfig.btcExecutionMode ))
295 {
296 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "%s: "
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700297 "BTC execution mode not set to BTC_SMART_COEXISTENCE. BT event will be dropped", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700298 return VOS_STATUS_E_FAILURE;
299 }
300 if( pBtEvent->btEventType < 0 || pBtEvent->btEventType >= BT_EVENT_TYPE_MAX )
301 {
302 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "%s: "
303 "Invalid BT event %d being passed. BT event will be dropped",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700304 __func__, pBtEvent->btEventType);
Jeff Johnson295189b2012-06-20 16:38:30 -0700305 return VOS_STATUS_E_FAILURE;
306 }
307 //Check PMC state to make sure whether we need to defer
308 //If we already have deferred events, defer the new one as well, in case PMC is in transition state
309 if( pMac->btc.fReplayBTEvents || !PMC_IS_CHIP_ACCESSIBLE(pmcGetPmcState( pMac )) )
310 {
311 //We need to defer the event
312 vosStatus = btcDeferEvent(pMac, pBtEvent);
313 if( VOS_IS_STATUS_SUCCESS(vosStatus) )
314 {
315 pMac->btc.fReplayBTEvents = VOS_TRUE;
316 return VOS_STATUS_SUCCESS;
317 }
318 else
319 {
320 return vosStatus;
321 }
322 }
323 btcSendBTEvent(pMac, pBtEvent);
324 return VOS_STATUS_SUCCESS;
325}
326#endif
327/* ---------------------------------------------------------------------------
328 \fn btcCheckHeartBeatMonitoring
329 \brief API to check whether heartbeat monitoring is required to be disabled
330 for specific BT start events which takes significant time to complete
331 during which WLAN misses beacons. To avoid WLAN-MAC from disconnecting
332 for the not enough beacons received we stop the heartbeat timer during
333 this start BT event till the stop of that BT event.
334 \param hHal - The handle returned by macOpen.
335 \param pBtEvent - Pointer to a caller allocated object of type tSmeBtEvent.
336 Caller owns the memory and is responsible for freeing it.
337 \return VOS_STATUS
338 VOS_STATUS_E_FAILURE Config not passed to HAL.
339 VOS_STATUS_SUCCESS Config passed to HAL
340 ---------------------------------------------------------------------------*/
341VOS_STATUS btcCheckHeartBeatMonitoring(tHalHandle hHal, tpSmeBtEvent pBtEvent)
342{
343 tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
344 VOS_STATUS vosStatus;
345 switch(pBtEvent->btEventType)
346 {
347 // Start events which requires heartbeat monitoring be disabled.
348 case BT_EVENT_INQUIRY_STARTED:
349 pMac->btc.btcEventState |= BT_INQUIRY_STARTED;
350 break;
351 case BT_EVENT_PAGE_STARTED:
352 pMac->btc.btcEventState |= BT_PAGE_STARTED;
353 break;
354 case BT_EVENT_CREATE_ACL_CONNECTION:
355 pMac->btc.btcEventState |= BT_CREATE_ACL_CONNECTION_STARTED;
356 break;
357 case BT_EVENT_CREATE_SYNC_CONNECTION:
358 pMac->btc.btcEventState |= BT_CREATE_SYNC_CONNECTION_STARTED;
359 break;
360 // Stop/done events which indicates heartbeat monitoring can be enabled
361 case BT_EVENT_INQUIRY_STOPPED:
362 pMac->btc.btcEventState &= ~(BT_INQUIRY_STARTED);
363 break;
364 case BT_EVENT_PAGE_STOPPED:
365 pMac->btc.btcEventState &= ~(BT_PAGE_STARTED);
366 break;
367 case BT_EVENT_ACL_CONNECTION_COMPLETE:
368 pMac->btc.btcEventState &= ~(BT_CREATE_ACL_CONNECTION_STARTED);
369 break;
370 case BT_EVENT_SYNC_CONNECTION_COMPLETE:
371 pMac->btc.btcEventState &= ~(BT_CREATE_SYNC_CONNECTION_STARTED);
372 break;
373 default:
374 // Ignore other events
375 return VOS_STATUS_SUCCESS;
376 }
377 // Check if any of the BT start events are active
378 if (pMac->btc.btcEventState) {
379 if (pMac->btc.btcHBActive) {
380 // set heartbeat threshold CFG to zero
381 ccmCfgSetInt(pMac, WNI_CFG_HEART_BEAT_THRESHOLD, 0, NULL, eANI_BOOLEAN_FALSE);
382 pMac->btc.btcHBActive = VOS_FALSE;
383 }
384 // Deactivate and active the restore HB timer
385 vos_timer_stop( &pMac->btc.restoreHBTimer);
386 vosStatus= vos_timer_start( &pMac->btc.restoreHBTimer, BT_MAX_EVENT_DONE_TIMEOUT );
387 if (!VOS_IS_STATUS_SUCCESS(vosStatus)) {
388 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "btcCheckHeartBeatMonitoring: Fail to start timer");
389 return VOS_STATUS_E_FAILURE;
390 }
391 } else {
392 // Restore CFG back to the original value only if it was disabled
393 if (!pMac->btc.btcHBActive) {
394 ccmCfgSetInt(pMac, WNI_CFG_HEART_BEAT_THRESHOLD, pMac->btc.btcHBCount, NULL, eANI_BOOLEAN_FALSE);
395 pMac->btc.btcHBActive = VOS_TRUE;
396 }
397 // Deactivate the timer
398 vosStatus = vos_timer_stop( &pMac->btc.restoreHBTimer);
399 if (!VOS_IS_STATUS_SUCCESS(vosStatus)) {
400 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "btcCheckHeartBeatMonitoring: Fail to stop timer");
401 return VOS_STATUS_E_FAILURE;
402 }
403 }
404 return VOS_STATUS_SUCCESS;
405}
406/* ---------------------------------------------------------------------------
407 \fn btcRestoreHeartBeatMonitoringHandle
408 \brief Timer handler to handlet the timeout condition when a specific BT
409 stop event does not come back, in which case to restore back the
410 heartbeat timer.
411 \param hHal - The handle returned by macOpen.
412 \return VOID
413 ---------------------------------------------------------------------------*/
414void btcRestoreHeartBeatMonitoringHandle(tHalHandle hHal)
415{
416 tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
417 if( !pMac->btc.btcHBActive )
418 {
419 tPmcState pmcState;
420 //Check PMC state to make sure whether we need to defer
421 pmcState = pmcGetPmcState( pMac );
422 if( PMC_IS_CHIP_ACCESSIBLE(pmcState) )
423 {
424 // Restore CFG back to the original value
425 ccmCfgSetInt(pMac, WNI_CFG_HEART_BEAT_THRESHOLD, pMac->btc.btcHBCount, NULL, eANI_BOOLEAN_FALSE);
426 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "BT event timeout, restoring back HeartBeat timer");
427 }
428 else
429 {
430 //defer it
431 pMac->btc.btcEventReplay.fRestoreHBMonitor = VOS_TRUE;
432 }
433 }
434}
435
436
437/* ---------------------------------------------------------------------------
438 \fn btcSetConfig
439 \brief API to change the current Bluetooth Coexistence (BTC) configuration
440 This function should be invoked only after CFG download has completed.
441 \param hHal - The handle returned by macOpen.
442 \param pSmeBtcConfig - Pointer to a caller allocated object of type
443 tSmeBtcConfig. Caller owns the memory and is responsible
444 for freeing it.
445 \return VOS_STATUS
446 VOS_STATUS_E_FAILURE Config not passed to HAL.
447 VOS_STATUS_SUCCESS Config passed to HAL
448 ---------------------------------------------------------------------------*/
449VOS_STATUS btcSetConfig (tHalHandle hHal, tpSmeBtcConfig pSmeBtcConfig)
450{
451 tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
452 //Save a copy in the global BTC config
453 vos_mem_copy(&(pMac->btc.btcConfig), pSmeBtcConfig, sizeof(tSmeBtcConfig));
454 //Send the config down only if SME_HddReady has been invoked. If not ready,
455 //BTC config will plumbed down when btcReady is eventually invoked.
456 if(pMac->btc.btcReady)
457 {
458 if(VOS_STATUS_SUCCESS != btcSendCfgMsg(hHal, pSmeBtcConfig))
459 {
460 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_FATAL,
461 "Failure to send BTC config down");
462 return VOS_STATUS_E_FAILURE;
463 }
464 }
465 return VOS_STATUS_SUCCESS;
466}
467/* ---------------------------------------------------------------------------
468 \fn btcPostBtcCfgMsg
469 \brief Private API to post BTC config message to HAL
470 \param hHal - The handle returned by macOpen.
471 \param pSmeBtcConfig - Pointer to a caller allocated object of type
472 tSmeBtcConfig. Caller owns the memory and is responsible
473 for freeing it.
474 \return VOS_STATUS
475 VOS_STATUS_E_FAILURE Config not passed to HAL.
476 VOS_STATUS_SUCCESS Config passed to HAL
477 ---------------------------------------------------------------------------*/
478VOS_STATUS btcSendCfgMsg(tHalHandle hHal, tpSmeBtcConfig pSmeBtcConfig)
479{
480 tpSmeBtcConfig ptrSmeBtcConfig = NULL;
481 vos_msg_t msg;
482 if( NULL == pSmeBtcConfig )
483 {
484 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "btcSendCfgMsg: "
485 "Null pointer for BTC Config");
486 return VOS_STATUS_E_FAILURE;
487 }
488 if( pSmeBtcConfig->btcExecutionMode >= BT_EXEC_MODE_MAX )
489 {
490 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "btcSendCfgMsg: "
491 "Invalid BT execution mode %d being set",
492 pSmeBtcConfig->btcExecutionMode);
493 return VOS_STATUS_E_FAILURE;
494 }
495 ptrSmeBtcConfig = vos_mem_malloc(sizeof(tSmeBtcConfig));
496 if (NULL == ptrSmeBtcConfig)
497 {
498 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "btcSendCfgMsg: "
499 "Not able to allocate memory for SME BTC Config");
500 return VOS_STATUS_E_FAILURE;
501 }
502 vos_mem_copy(ptrSmeBtcConfig, pSmeBtcConfig, sizeof(tSmeBtcConfig));
503 msg.type = WDA_BTC_SET_CFG;
504 msg.reserved = 0;
505 msg.bodyptr = ptrSmeBtcConfig;
506 if(VOS_STATUS_SUCCESS != vos_mq_post_message(VOS_MODULE_ID_WDA, &msg))
507 {
508 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "btcSendCfgMsg: "
509 "Not able to post WDA_BTC_SET_CFG message to WDA");
510 vos_mem_free( ptrSmeBtcConfig );
511 return VOS_STATUS_E_FAILURE;
512 }
513 return VOS_STATUS_SUCCESS;
514}
515/* ---------------------------------------------------------------------------
516 \fn btcGetConfig
517 \brief API to retrieve the current Bluetooth Coexistence (BTC) configuration
518 \param hHal - The handle returned by macOpen.
519 \param pSmeBtcConfig - Pointer to a caller allocated object of type
520 tSmeBtcConfig. Caller owns the memory and is responsible
521 for freeing it.
522 \return VOS_STATUS
523 VOS_STATUS_E_FAILURE - failure
524 VOS_STATUS_SUCCESS success
525 ---------------------------------------------------------------------------*/
526VOS_STATUS btcGetConfig (tHalHandle hHal, tpSmeBtcConfig pSmeBtcConfig)
527{
528 tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
529 if( NULL == pSmeBtcConfig )
530 {
531 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "btcGetConfig: "
532 "Null pointer for BTC Config");
533 return VOS_STATUS_E_FAILURE;
534 }
535 vos_mem_copy(pSmeBtcConfig, &(pMac->btc.btcConfig), sizeof(tSmeBtcConfig));
536 return VOS_STATUS_SUCCESS;
537}
538/*
539 btcFindAclEventHist find a suited ACL event buffer
540 Param: bdAddr - NULL meaning not care.
541 pointer to caller alocated buffer containing the BD address to find a match
542 handle - BT_INVALID_CONN_HANDLE == not care
543 otherwise, a handle to match
544 NOPTE: Either bdAddr or handle can be valid, if both of them are valid, use bdAddr only. If neither
545 bdAddr nor handle is valid, return the next free slot.
546*/
547static tpSmeBtAclEventHist btcFindAclEventHist( tpAniSirGlobal pMac, v_U8_t *bdAddr, v_U16_t handle )
548{
549 int i, j;
550 tpSmeBtAclEventHist pRet = NULL;
551 tSmeBtcEventReplay *pReplay = &pMac->btc.btcEventReplay;
552 for( i = 0; (i < BT_MAX_ACL_SUPPORT) && (NULL == pRet); i++ )
553 {
554 if( NULL != bdAddr )
555 {
556 //try to match addr
557 if( pReplay->btcEventHist.btAclConnectionEvent[i].bNextEventIdx )
558 {
559 for(j = 0; j < pReplay->btcEventHist.btAclConnectionEvent[i].bNextEventIdx; j++)
560 {
561 if( vos_mem_compare(pReplay->btcEventHist.btAclConnectionEvent[i].btAclConnection[j].bdAddr,
562 bdAddr, 6) )
563 {
564 //found it
565 pRet = &pReplay->btcEventHist.btAclConnectionEvent[i];
566 break;
567 }
568 }
569 }
570 }
571 else if( BT_INVALID_CONN_HANDLE != handle )
572 {
573 //try to match handle
574 if( pReplay->btcEventHist.btAclConnectionEvent[i].bNextEventIdx )
575 {
576 for(j = 0; j < pReplay->btcEventHist.btAclConnectionEvent[i].bNextEventIdx; j++)
577 {
578 if( pReplay->btcEventHist.btAclConnectionEvent[i].btAclConnection[j].connectionHandle ==
579 handle )
580 {
581 //found it
582 pRet = &pReplay->btcEventHist.btAclConnectionEvent[i];
583 break;
584 }
585 }
586 }
587 }
588 else if( 0 == pReplay->btcEventHist.btAclConnectionEvent[i].bNextEventIdx )
589 {
590 pRet = &pReplay->btcEventHist.btAclConnectionEvent[i];
591 break;
592 }
593 }
594 return (pRet);
595}
596
597/*
598 btcFindSyncEventHist find a suited SYNC event buffer
599 Param: bdAddr - NULL meaning not care.
600 pointer to caller alocated buffer containing the BD address to find a match
601 handle - BT_INVALID_CONN_HANDLE == not care
602 otherwise, a handle to match
603 NOPTE: Either bdAddr or handle can be valid, if both of them are valid, use bdAddr only. If neither
604 bdAddr nor handle is valid, return the next free slot.
605*/
606static tpSmeBtSyncEventHist btcFindSyncEventHist( tpAniSirGlobal pMac, v_U8_t *bdAddr, v_U16_t handle )
607{
608 int i, j;
609 tpSmeBtSyncEventHist pRet = NULL;
610 tSmeBtcEventReplay *pReplay = &pMac->btc.btcEventReplay;
611 for( i = 0; (i < BT_MAX_SCO_SUPPORT) && (NULL == pRet); i++ )
612 {
613 if( NULL != bdAddr )
614 {
615 //try to match addr
616 if( pReplay->btcEventHist.btSyncConnectionEvent[i].bNextEventIdx )
617 {
618 for(j = 0; j < pReplay->btcEventHist.btAclConnectionEvent[i].bNextEventIdx; j++)
619 {
620 if( vos_mem_compare(pReplay->btcEventHist.btSyncConnectionEvent[i].btSyncConnection[j].bdAddr,
621 bdAddr, 6) )
622 {
623 //found it
624 pRet = &pReplay->btcEventHist.btSyncConnectionEvent[i];
625 break;
626 }
627 }
628 }
629 }
630 else if( BT_INVALID_CONN_HANDLE != handle )
631 {
632 //try to match handle
633 if( pReplay->btcEventHist.btSyncConnectionEvent[i].bNextEventIdx )
634 {
635 for(j = 0; j < pReplay->btcEventHist.btAclConnectionEvent[i].bNextEventIdx; j++)
636 {
637 if( pReplay->btcEventHist.btSyncConnectionEvent[i].btSyncConnection[j].connectionHandle ==
638 handle )
639 {
640 //found it
641 pRet = &pReplay->btcEventHist.btSyncConnectionEvent[i];
642 break;
643 }
644 }
645 }
646 }
647 else if( !pReplay->btcEventHist.btSyncConnectionEvent[i].bNextEventIdx )
648 {
649 pRet = &pReplay->btcEventHist.btSyncConnectionEvent[i];
650 break;
651 }
652 }
653 return (pRet);
654}
655
656/*
657 btcFindDisconnEventHist find a slot for the deferred disconnect event
658 If handle is invlid, it returns a free slot, if any.
659 If handle is valid, it tries to find a match first in case same disconnect event comes down again.
660*/
661static tpSmeBtDisconnectEventHist btcFindDisconnEventHist( tpAniSirGlobal pMac, v_U16_t handle )
662{
663 tpSmeBtDisconnectEventHist pRet = NULL;
664 tSmeBtcEventReplay *pReplay = &pMac->btc.btcEventReplay;
665 int i;
666 if( BT_INVALID_CONN_HANDLE != handle )
667 {
668 for(i = 0; i < BT_MAX_DISCONN_SUPPORT; i++)
669 {
670 if( pReplay->btcEventHist.btDisconnectEvent[i].fValid &&
671 (handle == pReplay->btcEventHist.btDisconnectEvent[i].btDisconnect.connectionHandle) )
672 {
673 pRet = &pReplay->btcEventHist.btDisconnectEvent[i];
674 break;
675 }
676 }
677 }
678 if( NULL == pRet )
679 {
680 //Find a free slot
681 for(i = 0; i < BT_MAX_DISCONN_SUPPORT; i++)
682 {
683 if( !pReplay->btcEventHist.btDisconnectEvent[i].fValid )
684 {
685 pRet = &pReplay->btcEventHist.btDisconnectEvent[i];
686 break;
687 }
688 }
689 }
690 return (pRet);
691}
692
693/*
694 btcFindModeChangeEventHist find a slot for the deferred mopde change event
695 If handle is invalid, it returns a free slot, if any.
696 If handle is valid, it tries to find a match first in case same disconnect event comes down again.
697*/
698tpSmeBtAclModeChangeEventHist btcFindModeChangeEventHist( tpAniSirGlobal pMac, v_U16_t handle )
699{
700 tpSmeBtAclModeChangeEventHist pRet = NULL;
701 tSmeBtcEventReplay *pReplay = &pMac->btc.btcEventReplay;
702 int i;
703 if( BT_INVALID_CONN_HANDLE != handle )
704 {
705 for(i = 0; i < BT_MAX_ACL_SUPPORT; i++)
706 {
707 if( pReplay->btcEventHist.btAclModeChangeEvent[i].fValid &&
708 (handle == pReplay->btcEventHist.btAclModeChangeEvent[i].btAclModeChange.connectionHandle) )
709 {
710 pRet = &pReplay->btcEventHist.btAclModeChangeEvent[i];
711 break;
712 }
713 }
714 }
715 if( NULL == pRet )
716 {
717 //Find a free slot
718 for(i = 0; i < BT_MAX_ACL_SUPPORT; i++)
719 {
720 if( !pReplay->btcEventHist.btAclModeChangeEvent[i].fValid )
721 {
722 pRet = &pReplay->btcEventHist.btAclModeChangeEvent[i];
723 break;
724 }
725 }
726 }
727 return (pRet);
728}
729
730/*
731 btcFindSyncUpdateEventHist find a slot for the deferred SYNC_UPDATE event
732 If handle is invalid, it returns a free slot, if any.
733 If handle is valid, it tries to find a match first in case same disconnect event comes down again.
734*/
735tpSmeBtSyncUpdateHist btcFindSyncUpdateEventHist( tpAniSirGlobal pMac, v_U16_t handle )
736{
737 tpSmeBtSyncUpdateHist pRet = NULL;
738 tSmeBtcEventReplay *pReplay = &pMac->btc.btcEventReplay;
739 int i;
740 if( BT_INVALID_CONN_HANDLE != handle )
741 {
742 for(i = 0; i < BT_MAX_SCO_SUPPORT; i++)
743 {
744 if( pReplay->btcEventHist.btSyncUpdateEvent[i].fValid &&
745 (handle == pReplay->btcEventHist.btSyncUpdateEvent[i].btSyncConnection.connectionHandle) )
746 {
747 pRet = &pReplay->btcEventHist.btSyncUpdateEvent[i];
748 break;
749 }
750 }
751 }
752 if( NULL == pRet )
753 {
754 //Find a free slot
755 for(i = 0; i < BT_MAX_SCO_SUPPORT; i++)
756 {
757 if( !pReplay->btcEventHist.btSyncUpdateEvent[i].fValid )
758 {
759 pRet = &pReplay->btcEventHist.btSyncUpdateEvent[i];
760 break;
761 }
762 }
763 }
764 return (pRet);
765}
766
767/*
768 Call must validate pAclEventHist
769*/
770static void btcReleaseAclEventHist( tpAniSirGlobal pMac, tpSmeBtAclEventHist pAclEventHist )
771{
772 vos_mem_zero( pAclEventHist, sizeof(tSmeBtAclEventHist) );
773}
774
775/*
776 Call must validate pSyncEventHist
777*/
778static void btcReleaseSyncEventHist( tpAniSirGlobal pMac, tpSmeBtSyncEventHist pSyncEventHist )
779{
780 vos_mem_zero( pSyncEventHist, sizeof(tSmeBtSyncEventHist) );
781}
782
783/*To defer a ACL creation event
784 We only support one ACL per BD address.
785 If the last cached event another ACL create event, replace that event with the new event
786 If a completion event with success status code, and the new ACL creation
787 on same address, defer a new disconnect event(fake one), then cache this ACL creation event.
788 Otherwise, save this create event.
789*/
790static VOS_STATUS btcDeferAclCreate( tpAniSirGlobal pMac, tpSmeBtEvent pEvent )
791{
792 VOS_STATUS status = VOS_STATUS_SUCCESS;
793 tpSmeBtAclEventHist pAclEventHist;
Gopichand Nakkalad5a904e2013-03-29 01:07:54 +0530794 tSmeBtAclConnectionParam *pAclEvent = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -0700795 do
796 {
797 //Find a match
798 pAclEventHist = btcFindAclEventHist( pMac, pEvent->uEventParam.btAclConnection.bdAddr,
799 BT_INVALID_CONN_HANDLE );
800 if( NULL == pAclEventHist )
801 {
802 //No cached ACL event on this address
803 //Find a free slot and save it
804 pAclEventHist = btcFindAclEventHist( pMac, NULL, BT_INVALID_CONN_HANDLE );
805 if( NULL != pAclEventHist )
806 {
807 vos_mem_copy(&pAclEventHist->btAclConnection[0], &pEvent->uEventParam.btAclConnection,
808 sizeof(tSmeBtAclConnectionParam));
809 pAclEventHist->btEventType[0] = BT_EVENT_CREATE_ACL_CONNECTION;
810 pAclEventHist->bNextEventIdx = 1;
811 }
812 else
813 {
Kiran Kumar Lokere691dde12013-03-06 17:00:31 -0800814 smsLog(pMac, LOGE, FL(" failed to find ACL event slot"));
Jeff Johnson295189b2012-06-20 16:38:30 -0700815 status = VOS_STATUS_E_RESOURCES;
816 }
817 //done
818 break;
819 }
820 else
821 {
822 //There is history on this BD address
Krunal Sonia75019a2013-05-01 01:08:22 -0700823 if ((pAclEventHist->bNextEventIdx <= 0) ||
824 (pAclEventHist->bNextEventIdx > BT_MAX_NUM_EVENT_ACL_DEFERRED))
825 {
826 VOS_ASSERT(0);
827 status = VOS_STATUS_E_FAILURE;
828 break;
829 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700830 pAclEvent = &pAclEventHist->btAclConnection[pAclEventHist->bNextEventIdx - 1];
831 if(BT_EVENT_CREATE_ACL_CONNECTION == pAclEventHist->btEventType[pAclEventHist->bNextEventIdx - 1])
832 {
833 //The last cached event is creation, replace it with the new one
Gopichand Nakkalacc8cf8e2013-04-25 06:03:10 -0700834 if (pAclEvent)
835 {
836 vos_mem_copy(pAclEvent,
837 &pEvent->uEventParam.btAclConnection,
838 sizeof(tSmeBtAclConnectionParam));
839 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700840 //done
841 break;
842 }
843 else if(BT_EVENT_ACL_CONNECTION_COMPLETE ==
844 pAclEventHist->btEventType[pAclEventHist->bNextEventIdx - 1])
845 {
846 //The last cached event is completion, check the status.
847 if(BT_CONN_STATUS_SUCCESS == pAclEvent->status)
848 {
849 tSmeBtEvent btEvent;
850 //The last event we have is success completion event.
851 //Should not get a creation event before creation.
Kiran Kumar Lokere691dde12013-03-06 17:00:31 -0800852 smsLog(pMac, LOGE, FL(" Missing disconnect event on handle %d"), pAclEvent->connectionHandle);
Jeff Johnson295189b2012-06-20 16:38:30 -0700853 //Fake a disconnect event
854 btEvent.btEventType = BT_EVENT_DISCONNECTION_COMPLETE;
855 btEvent.uEventParam.btDisconnect.connectionHandle = pAclEvent->connectionHandle;
856 btcDeferDisconnEvent(pMac, &btEvent);
857 }
858 }
859 //Need to save the new event
860 if(pAclEventHist->bNextEventIdx < BT_MAX_NUM_EVENT_ACL_DEFERRED)
861 {
862 pAclEventHist->btEventType[pAclEventHist->bNextEventIdx] = BT_EVENT_CREATE_ACL_CONNECTION;
863 vos_mem_copy(&pAclEventHist->btAclConnection[pAclEventHist->bNextEventIdx],
864 &pEvent->uEventParam.btAclConnection,
865 sizeof(tSmeBtAclConnectionParam));
866 pAclEventHist->bNextEventIdx++;
867 }
868 else
869 {
Kiran Kumar Lokere691dde12013-03-06 17:00:31 -0800870 smsLog(pMac, LOGE, FL(" ACL event overflow"));
Jeff Johnson295189b2012-06-20 16:38:30 -0700871 VOS_ASSERT(0);
872 }
873 }
874 }while(0);
875 return status;
876}
877
878/*Defer a ACL completion event
879 If there is cached event on this BD address, check completion status.
880 If status is fail and last cached event is creation, remove the creation event and drop
881 this completion event. Otherwise, cache this completion event as the latest one.
882*/
883static VOS_STATUS btcDeferAclComplete( tpAniSirGlobal pMac, tpSmeBtEvent pEvent )
884{
885 VOS_STATUS status = VOS_STATUS_SUCCESS;
886 tpSmeBtAclEventHist pAclEventHist;
887 do
888 {
889 //Find a match
890 pAclEventHist = btcFindAclEventHist( pMac, pEvent->uEventParam.btAclConnection.bdAddr,
891 BT_INVALID_CONN_HANDLE );
892 if(pAclEventHist)
893 {
894 VOS_ASSERT(pAclEventHist->bNextEventIdx >0);
895 //Found one
896 if(BT_CONN_STATUS_SUCCESS != pEvent->uEventParam.btAclConnection.status)
897 {
898 //If completion fails, and the last one is creation, remove the creation event
899 if(BT_EVENT_CREATE_ACL_CONNECTION == pAclEventHist->btEventType[pAclEventHist->bNextEventIdx-1])
900 {
901 vos_mem_zero(&pAclEventHist->btAclConnection[pAclEventHist->bNextEventIdx-1],
902 sizeof(tSmeBtAclConnectionParam));
903 pAclEventHist->bNextEventIdx--;
904 //Done with this event
905 break;
906 }
907 else
908 {
Kiran Kumar Lokere691dde12013-03-06 17:00:31 -0800909 smsLog(pMac, LOGE, FL(" ACL completion fail but last event(%d) not creation"),
Jeff Johnson295189b2012-06-20 16:38:30 -0700910 pAclEventHist->btEventType[pAclEventHist->bNextEventIdx-1]);
911 }
912 }
913 }
914 if( NULL == pAclEventHist )
915 {
916 pAclEventHist = btcFindAclEventHist( pMac, NULL, BT_INVALID_CONN_HANDLE );
917 }
918 if(pAclEventHist)
919 {
920 if(pAclEventHist->bNextEventIdx < BT_MAX_NUM_EVENT_ACL_DEFERRED)
921 {
922 //Save this event
923 pAclEventHist->btEventType[pAclEventHist->bNextEventIdx] = BT_EVENT_ACL_CONNECTION_COMPLETE;
924 vos_mem_copy(&pAclEventHist->btAclConnection[pAclEventHist->bNextEventIdx],
925 &pEvent->uEventParam.btAclConnection,
926 sizeof(tSmeBtAclConnectionParam));
927 pAclEventHist->bNextEventIdx++;
928 }
929 else
930 {
Kiran Kumar Lokere691dde12013-03-06 17:00:31 -0800931 smsLog(pMac, LOGE, FL(" ACL event overflow"));
Jeff Johnson295189b2012-06-20 16:38:30 -0700932 VOS_ASSERT(0);
933 }
934 }
935 else
936 {
Kiran Kumar Lokere691dde12013-03-06 17:00:31 -0800937 smsLog( pMac, LOGE, FL(" cannot find match for failed BT_EVENT_ACL_CONNECTION_COMPLETE of bdAddr (%02X-%02X-%02X-%02X-%02X-%02X)"),
Jeff Johnson295189b2012-06-20 16:38:30 -0700938 pEvent->uEventParam.btAclConnection.bdAddr[0],
939 pEvent->uEventParam.btAclConnection.bdAddr[1],
940 pEvent->uEventParam.btAclConnection.bdAddr[2],
941 pEvent->uEventParam.btAclConnection.bdAddr[3],
942 pEvent->uEventParam.btAclConnection.bdAddr[4],
943 pEvent->uEventParam.btAclConnection.bdAddr[5]);
944 status = VOS_STATUS_E_EMPTY;
945 }
946 }while(0);
947 return (status);
948}
949
950/*To defer a SYNC creation event
951 If the last cached event is another SYNC create event, replace
952 that event with the new event.
953 If there is a completion event with success status code, cache a new
954 disconnect event(fake) first, then cache this SYNC creation event.
955 Otherwise, cache this create event.
956*/
957static VOS_STATUS btcDeferSyncCreate( tpAniSirGlobal pMac, tpSmeBtEvent pEvent )
958{
959 VOS_STATUS status = VOS_STATUS_SUCCESS;
960 tpSmeBtSyncEventHist pSyncEventHist;
Gopichand Nakkalad5a904e2013-03-29 01:07:54 +0530961 tSmeBtSyncConnectionParam *pSyncEvent = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -0700962 do
963 {
964 //Find a match
965 pSyncEventHist = btcFindSyncEventHist( pMac, pEvent->uEventParam.btSyncConnection.bdAddr,
966 BT_INVALID_CONN_HANDLE );
967 if( NULL == pSyncEventHist )
968 {
969 //No cached ACL event on this address
970 //Find a free slot and save it
971 pSyncEventHist = btcFindSyncEventHist( pMac, NULL, BT_INVALID_CONN_HANDLE );
972 if( NULL != pSyncEventHist )
973 {
974 vos_mem_copy(&pSyncEventHist->btSyncConnection[0], &pEvent->uEventParam.btSyncConnection,
975 sizeof(tSmeBtSyncConnectionParam));
976 pSyncEventHist->btEventType[0] = BT_EVENT_CREATE_SYNC_CONNECTION;
977 pSyncEventHist->bNextEventIdx = 1;
978 }
979 else
980 {
Kiran Kumar Lokere691dde12013-03-06 17:00:31 -0800981 smsLog(pMac, LOGE, FL(" failed to find SYNC event slot"));
Jeff Johnson295189b2012-06-20 16:38:30 -0700982 status = VOS_STATUS_E_RESOURCES;
983 }
984 //done
985 break;
986 }
987 else
988 {
989 //There is history on this BD address
Krunal Sonia75019a2013-05-01 01:08:22 -0700990 if ((pSyncEventHist->bNextEventIdx <= 0) ||
991 (pSyncEventHist->bNextEventIdx > BT_MAX_NUM_EVENT_SCO_DEFERRED))
992 {
993 VOS_ASSERT(0);
994 status = VOS_STATUS_E_FAILURE;
995 return status;
996 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700997 pSyncEvent = &pSyncEventHist->btSyncConnection[pSyncEventHist->bNextEventIdx - 1];
998 if(BT_EVENT_CREATE_SYNC_CONNECTION ==
999 pSyncEventHist->btEventType[pSyncEventHist->bNextEventIdx - 1])
1000 {
1001 //The last cached event is creation, replace it with the new one
Gopichand Nakkalacc8cf8e2013-04-25 06:03:10 -07001002 if(pSyncEvent)
1003 {
1004 vos_mem_copy(pSyncEvent,
1005 &pEvent->uEventParam.btSyncConnection,
1006 sizeof(tSmeBtSyncConnectionParam));
1007 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001008 //done
1009 break;
1010 }
1011 else if(BT_EVENT_SYNC_CONNECTION_COMPLETE ==
1012 pSyncEventHist->btEventType[pSyncEventHist->bNextEventIdx - 1])
1013 {
1014 //The last cached event is completion, check the status.
1015 if(BT_CONN_STATUS_SUCCESS == pSyncEvent->status)
1016 {
1017 tSmeBtEvent btEvent;
1018 //The last event we have is success completion event.
1019 //Should not get a creation event before creation.
Kiran Kumar Lokere691dde12013-03-06 17:00:31 -08001020 smsLog(pMac, LOGE, FL(" Missing disconnect event on handle %d"), pSyncEvent->connectionHandle);
Jeff Johnson295189b2012-06-20 16:38:30 -07001021 //Fake a disconnect event
1022 btEvent.btEventType = BT_EVENT_DISCONNECTION_COMPLETE;
1023 btEvent.uEventParam.btDisconnect.connectionHandle = pSyncEvent->connectionHandle;
1024 btcDeferDisconnEvent(pMac, &btEvent);
1025 }
1026 }
1027 //Need to save the new event
1028 if(pSyncEventHist->bNextEventIdx < BT_MAX_NUM_EVENT_SCO_DEFERRED)
1029 {
1030 pSyncEventHist->btEventType[pSyncEventHist->bNextEventIdx] = BT_EVENT_CREATE_SYNC_CONNECTION;
1031 vos_mem_copy(&pSyncEventHist->btSyncConnection[pSyncEventHist->bNextEventIdx],
1032 &pEvent->uEventParam.btSyncConnection,
1033 sizeof(tSmeBtSyncConnectionParam));
1034 pSyncEventHist->bNextEventIdx++;
1035 }
1036 else
1037 {
Kiran Kumar Lokere691dde12013-03-06 17:00:31 -08001038 smsLog(pMac, LOGE, FL(" SYNC event overflow"));
Jeff Johnson295189b2012-06-20 16:38:30 -07001039 }
1040 }
1041 }while(0);
1042 return status;
1043}
1044
1045/*Defer a SYNC completion event
1046 If there is cached event on this BD address, check completion status.
1047 If status is fail and last cached event is creation, remove te creation event and drop
1048 this completion event.
1049 Otherwise, cache this completion event as the latest one.
1050*/
1051static VOS_STATUS btcDeferSyncComplete( tpAniSirGlobal pMac, tpSmeBtEvent pEvent )
1052{
1053 VOS_STATUS status = VOS_STATUS_SUCCESS;
1054 tpSmeBtSyncEventHist pSyncEventHist;
1055 do
1056 {
1057 //Find a match
1058 pSyncEventHist = btcFindSyncEventHist( pMac, pEvent->uEventParam.btSyncConnection.bdAddr,
1059 BT_INVALID_CONN_HANDLE );
1060 if(pSyncEventHist)
1061 {
1062 VOS_ASSERT(pSyncEventHist->bNextEventIdx >0);
1063 //Found one
1064 if(BT_CONN_STATUS_SUCCESS != pEvent->uEventParam.btSyncConnection.status)
1065 {
1066 //If completion fails, and the last one is creation, remove the creation event
1067 if(BT_EVENT_CREATE_SYNC_CONNECTION == pSyncEventHist->btEventType[pSyncEventHist->bNextEventIdx-1])
1068 {
1069 vos_mem_zero(&pSyncEventHist->btSyncConnection[pSyncEventHist->bNextEventIdx-1],
1070 sizeof(tSmeBtSyncConnectionParam));
1071 pSyncEventHist->bNextEventIdx--;
1072 //Done with this event
1073 break;
1074 }
1075 else
1076 {
Kiran Kumar Lokere691dde12013-03-06 17:00:31 -08001077 smsLog(pMac, LOGE, FL(" SYNC completion fail but last event(%d) not creation"),
Jeff Johnson295189b2012-06-20 16:38:30 -07001078 pSyncEventHist->btEventType[pSyncEventHist->bNextEventIdx-1]);
1079 }
1080 }
1081 }
1082 if(NULL == pSyncEventHist)
1083 {
1084 //In case we don't defer the creation event
1085 pSyncEventHist = btcFindSyncEventHist( pMac, NULL, BT_INVALID_CONN_HANDLE );
1086 }
1087 if(pSyncEventHist)
1088 {
1089 if(pSyncEventHist->bNextEventIdx < BT_MAX_NUM_EVENT_ACL_DEFERRED)
1090 {
1091 //Save this event
1092 pSyncEventHist->btEventType[pSyncEventHist->bNextEventIdx] = BT_EVENT_SYNC_CONNECTION_COMPLETE;
1093 vos_mem_copy(&pSyncEventHist->btSyncConnection[pSyncEventHist->bNextEventIdx],
1094 &pEvent->uEventParam.btSyncConnection,
1095 sizeof(tSmeBtSyncConnectionParam));
1096 pSyncEventHist->bNextEventIdx++;
1097 }
1098 else
1099 {
Kiran Kumar Lokere691dde12013-03-06 17:00:31 -08001100 smsLog(pMac, LOGE, FL(" SYNC event overflow"));
Jeff Johnson295189b2012-06-20 16:38:30 -07001101 }
1102 }
1103 else
1104 {
Kiran Kumar Lokere691dde12013-03-06 17:00:31 -08001105 smsLog( pMac, LOGE, FL(" cannot find match for BT_EVENT_SYNC_CONNECTION_COMPLETE of bdAddr (%02X-%02X-%02X-%02X-%02X-%02X)"),
Jeff Johnson295189b2012-06-20 16:38:30 -07001106 pEvent->uEventParam.btSyncConnection.bdAddr[0],
1107 pEvent->uEventParam.btSyncConnection.bdAddr[1],
1108 pEvent->uEventParam.btSyncConnection.bdAddr[2],
1109 pEvent->uEventParam.btSyncConnection.bdAddr[3],
1110 pEvent->uEventParam.btSyncConnection.bdAddr[4],
1111 pEvent->uEventParam.btSyncConnection.bdAddr[5]);
1112 status = VOS_STATUS_E_EMPTY;
1113 }
1114 }while(0);
1115 return (status);
1116}
1117
1118//return VOS_STATUS_E_EXISTS if the event handle cannot be found
1119//VOS_STATUS_SUCCESS if the event is processed
1120//Other error status meaning it cannot continue due to other errors
1121/*
1122 Defer a disconnect event for ACL
1123 Check if any history on this event handle.
1124 If both ACL_CREATION and ACL_COMPLETION is cached, remove both those events and drop
1125 this disconnect event.
1126 Otherwise save disconnect event in this ACL's bin.
1127 If not ACL match on this handle, not to do anything.
1128 Either way, remove any cached MODE_CHANGE event matches this disconnect event's handle.
1129*/
1130static VOS_STATUS btcDeferDisconnectEventForACL( tpAniSirGlobal pMac, tpSmeBtEvent pEvent )
1131{
1132 VOS_STATUS status = VOS_STATUS_SUCCESS;
1133 tpSmeBtAclEventHist pAclEventHist;
1134 tpSmeBtAclModeChangeEventHist pModeChangeEventHist;
1135 v_BOOL_t fDone = VOS_FALSE;
1136 int i;
1137 pAclEventHist = btcFindAclEventHist( pMac, NULL,
1138 pEvent->uEventParam.btDisconnect.connectionHandle );
1139 if(pAclEventHist)
1140 {
1141 if( pAclEventHist->bNextEventIdx > BT_MAX_NUM_EVENT_ACL_DEFERRED)
1142 {
Kiran Kumar Lokere691dde12013-03-06 17:00:31 -08001143 smsLog(pMac, LOGE, FL(" ACL event history index:%d overflow, resetting to BT_MAX_NUM_EVENT_ACL_DEFERRED"), pAclEventHist->bNextEventIdx);
Jeff Johnson295189b2012-06-20 16:38:30 -07001144 pAclEventHist->bNextEventIdx = BT_MAX_NUM_EVENT_ACL_DEFERRED;
1145 }
1146 //Looking backwords
1147 for(i = pAclEventHist->bNextEventIdx - 1; i >= 0; i--)
1148 {
1149 if( BT_EVENT_ACL_CONNECTION_COMPLETE == pAclEventHist->btEventType[i] )
1150 {
1151 //make sure we can cancel the link
1152 if( (i > 0) && (BT_EVENT_CREATE_ACL_CONNECTION == pAclEventHist->btEventType[i - 1]) )
1153 {
1154 fDone = VOS_TRUE;
1155 if(i == 1)
1156 {
1157 //All events can be wiped off
1158 btcReleaseAclEventHist(pMac, pAclEventHist);
1159 break;
1160 }
1161 //we have both ACL creation and completion, wipe out all of them
1162 pAclEventHist->bNextEventIdx = (tANI_U8)(i - 1);
1163 vos_mem_zero(&pAclEventHist->btAclConnection[i-1], sizeof(tSmeBtAclConnectionParam));
1164 vos_mem_zero(&pAclEventHist->btAclConnection[i], sizeof(tSmeBtAclConnectionParam));
1165 break;
1166 }
1167 }
1168 }//for loop
1169 if(!fDone)
1170 {
1171 //Save this disconnect event
1172 if(pAclEventHist->bNextEventIdx < BT_MAX_NUM_EVENT_ACL_DEFERRED)
1173 {
1174 pAclEventHist->btEventType[pAclEventHist->bNextEventIdx] =
1175 BT_EVENT_DISCONNECTION_COMPLETE;
1176 pAclEventHist->btAclConnection[pAclEventHist->bNextEventIdx].connectionHandle =
1177 pEvent->uEventParam.btDisconnect.connectionHandle;
1178 pAclEventHist->bNextEventIdx++;
1179 }
1180 else
1181 {
Kiran Kumar Lokere691dde12013-03-06 17:00:31 -08001182 smsLog(pMac, LOGE, FL(" ACL event overflow"));
Jeff Johnson295189b2012-06-20 16:38:30 -07001183 status = VOS_STATUS_E_FAILURE;
1184 }
1185 }
1186 }
1187 else
1188 {
1189 status = VOS_STATUS_E_EXISTS;
1190 }
1191 //Wipe out the related mode change event if it is there
1192 pModeChangeEventHist = btcFindModeChangeEventHist( pMac,
1193 pEvent->uEventParam.btDisconnect.connectionHandle );
1194 if( pModeChangeEventHist && pModeChangeEventHist->fValid )
1195 {
1196 pModeChangeEventHist->fValid = VOS_FALSE;
1197 }
1198 return status;
1199}
1200
1201//This function works the same as btcDeferDisconnectEventForACL except it hanldes SYNC events
1202//return VOS_STATUS_E_EXISTS if the event handle cannot be found
1203//VOS_STATUS_SUCCESS if the event is processed
1204//Other error status meaning it cannot continue due to other errors
1205/*
1206 Defer a disconnect event for SYNC
1207 Check if any SYNC history on this event handle.
1208 If yes and if both SYNC_CREATION and SYNC_COMPLETION is cached, remove both those events and drop
1209 this disconnect event.
1210 Otherwise save disconnect event in this SYNC's bin.
1211 If no match found, not to save this event here.
1212 Either way, remove any cached SYNC_UPDATE event matches this disconnect event's handle.
1213*/
1214static VOS_STATUS btcDeferDisconnectEventForSync( tpAniSirGlobal pMac, tpSmeBtEvent pEvent )
1215{
1216 VOS_STATUS status = VOS_STATUS_SUCCESS;
1217 tpSmeBtSyncEventHist pSyncEventHist;
1218 tpSmeBtSyncUpdateHist pSyncUpdateHist;
1219 v_BOOL_t fDone = VOS_FALSE;
1220 int i;
1221 pSyncEventHist = btcFindSyncEventHist( pMac, NULL,
1222 pEvent->uEventParam.btDisconnect.connectionHandle );
1223 if(pSyncEventHist)
1224 {
1225 if( pSyncEventHist->bNextEventIdx > BT_MAX_NUM_EVENT_SCO_DEFERRED)
1226 {
Kiran Kumar Lokere691dde12013-03-06 17:00:31 -08001227 smsLog(pMac, LOGE, FL(" SYNC event history index:%d overflow, resetting to BT_MAX_NUM_EVENT_SCO_DEFERRED"), pSyncEventHist->bNextEventIdx);
Jeff Johnson295189b2012-06-20 16:38:30 -07001228 pSyncEventHist->bNextEventIdx = BT_MAX_NUM_EVENT_SCO_DEFERRED;
1229 }
1230 //Looking backwords
1231 for(i = pSyncEventHist->bNextEventIdx - 1; i >= 0; i--)
1232 {
1233 //if a mode change event exists, drop it
1234 if( BT_EVENT_SYNC_CONNECTION_COMPLETE == pSyncEventHist->btEventType[i] )
1235 {
1236 //make sure we can cancel the link
1237 if( (i > 0) && (BT_EVENT_CREATE_SYNC_CONNECTION == pSyncEventHist->btEventType[i - 1]) )
1238 {
1239 fDone = VOS_TRUE;
1240 if(i == 1)
1241 {
1242 //All events can be wiped off
1243 btcReleaseSyncEventHist(pMac, pSyncEventHist);
1244 break;
1245 }
1246 //we have both ACL creation and completion, wipe out all of them
1247 pSyncEventHist->bNextEventIdx = (tANI_U8)(i - 1);
1248 vos_mem_zero(&pSyncEventHist->btSyncConnection[i-1], sizeof(tSmeBtSyncConnectionParam));
1249 vos_mem_zero(&pSyncEventHist->btSyncConnection[i], sizeof(tSmeBtSyncConnectionParam));
1250 break;
1251 }
1252 }
1253 }//for loop
1254 if(!fDone)
1255 {
1256 //Save this disconnect event
1257 if(pSyncEventHist->bNextEventIdx < BT_MAX_NUM_EVENT_SCO_DEFERRED)
1258 {
1259 pSyncEventHist->btEventType[pSyncEventHist->bNextEventIdx] =
1260 BT_EVENT_DISCONNECTION_COMPLETE;
1261 pSyncEventHist->btSyncConnection[pSyncEventHist->bNextEventIdx].connectionHandle =
1262 pEvent->uEventParam.btDisconnect.connectionHandle;
1263 pSyncEventHist->bNextEventIdx++;
1264 }
1265 else
1266 {
Kiran Kumar Lokere691dde12013-03-06 17:00:31 -08001267 smsLog(pMac, LOGE, FL(" SYNC event overflow"));
Jeff Johnson295189b2012-06-20 16:38:30 -07001268 status = VOS_STATUS_E_FAILURE;
1269 }
1270 }
1271 }
1272 else
1273 {
1274 status = VOS_STATUS_E_EXISTS;
1275 }
1276 //Wipe out the related mode change event if it is there
1277 pSyncUpdateHist = btcFindSyncUpdateEventHist( pMac,
1278 pEvent->uEventParam.btDisconnect.connectionHandle );
1279 if( pSyncUpdateHist && pSyncUpdateHist->fValid )
1280 {
1281 pSyncUpdateHist->fValid = VOS_FALSE;
1282 }
1283 return status;
1284}
1285
1286/*
1287 Defer a disconnect event.
1288 Try to defer it as part of the ACL event first.
1289 If no match is found, try SYNC.
1290 If still no match found, defer it at DISCONNECT event bin.
1291*/
1292static VOS_STATUS btcDeferDisconnEvent( tpAniSirGlobal pMac, tpSmeBtEvent pEvent )
1293{
1294 VOS_STATUS status = VOS_STATUS_SUCCESS;
1295 tpSmeBtDisconnectEventHist pDisconnEventHist;
1296 if( BT_INVALID_CONN_HANDLE == pEvent->uEventParam.btDisconnect.connectionHandle )
1297 {
Kiran Kumar Lokere691dde12013-03-06 17:00:31 -08001298 smsLog( pMac, LOGE, FL(" invalid handle") );
Jeff Johnson295189b2012-06-20 16:38:30 -07001299 return (VOS_STATUS_E_INVAL);
1300 }
1301 //Check ACL first
1302 status = btcDeferDisconnectEventForACL(pMac, pEvent);
1303 if(!VOS_IS_STATUS_SUCCESS(status))
1304 {
1305 status = btcDeferDisconnectEventForSync(pMac, pEvent);
1306 }
1307 if( !VOS_IS_STATUS_SUCCESS(status) )
1308 {
1309 //Save the disconnect event
1310 pDisconnEventHist = btcFindDisconnEventHist( pMac,
1311 pEvent->uEventParam.btDisconnect.connectionHandle );
1312 if( pDisconnEventHist )
1313 {
1314 pDisconnEventHist->fValid = VOS_TRUE;
1315 vos_mem_copy( &pDisconnEventHist->btDisconnect, &pEvent->uEventParam.btDisconnect,
1316 sizeof(tSmeBtDisconnectParam) );
1317 status = VOS_STATUS_SUCCESS;
1318 }
1319 else
1320 {
Kiran Kumar Lokere691dde12013-03-06 17:00:31 -08001321 smsLog( pMac, LOGE, FL(" cannot find match for BT_EVENT_DISCONNECTION_COMPLETE of handle (%d)"),
Jeff Johnson295189b2012-06-20 16:38:30 -07001322 pEvent->uEventParam.btDisconnect.connectionHandle);
1323 status = VOS_STATUS_E_EMPTY;
1324 }
1325 }
1326 return (status);
1327}
1328
1329/*
1330 btcDeferEvent save the event for possible replay when chip can be accessed
1331 This function is called only when in IMPS/Standby state
1332*/
1333static VOS_STATUS btcDeferEvent( tpAniSirGlobal pMac, tpSmeBtEvent pEvent )
1334{
1335 VOS_STATUS status = VOS_STATUS_SUCCESS;
1336 tpSmeBtSyncUpdateHist pSyncUpdateHist;
1337 tpSmeBtAclModeChangeEventHist pModeChangeEventHist;
1338 tSmeBtcEventReplay *pReplay = &pMac->btc.btcEventReplay;
1339 switch(pEvent->btEventType)
1340 {
1341 case BT_EVENT_DEVICE_SWITCHED_ON:
1342 //Clear all events first
1343 vos_mem_zero( &pReplay->btcEventHist, sizeof(tSmeBtcEventHist) );
1344 pReplay->fBTSwitchOn = VOS_TRUE;
1345 pReplay->fBTSwitchOff = VOS_FALSE;
1346 break;
1347 case BT_EVENT_DEVICE_SWITCHED_OFF:
1348 //Clear all events first
1349 vos_mem_zero( &pReplay->btcEventHist, sizeof(tSmeBtcEventHist) );
1350 pReplay->fBTSwitchOff = VOS_TRUE;
1351 pReplay->fBTSwitchOn = VOS_FALSE;
1352 break;
1353 case BT_EVENT_INQUIRY_STARTED:
1354 pReplay->btcEventHist.nInquiryEvent++;
1355 break;
1356 case BT_EVENT_INQUIRY_STOPPED:
1357 pReplay->btcEventHist.nInquiryEvent--;
1358 break;
1359 case BT_EVENT_PAGE_STARTED:
1360 pReplay->btcEventHist.nPageEvent++;
1361 break;
1362 case BT_EVENT_PAGE_STOPPED:
1363 pReplay->btcEventHist.nPageEvent--;
1364 break;
1365 case BT_EVENT_CREATE_ACL_CONNECTION:
1366 status = btcDeferAclCreate(pMac, pEvent);
1367 break;
1368 case BT_EVENT_ACL_CONNECTION_COMPLETE:
1369 status = btcDeferAclComplete( pMac, pEvent );
1370 break;
1371 case BT_EVENT_CREATE_SYNC_CONNECTION:
1372 status = btcDeferSyncCreate(pMac, pEvent);
1373 break;
1374 case BT_EVENT_SYNC_CONNECTION_COMPLETE:
1375 status = btcDeferSyncComplete( pMac, pEvent );
1376 break;
1377 case BT_EVENT_SYNC_CONNECTION_UPDATED:
1378 if( BT_INVALID_CONN_HANDLE == pEvent->uEventParam.btDisconnect.connectionHandle )
1379 {
Kiran Kumar Lokere691dde12013-03-06 17:00:31 -08001380 smsLog( pMac, LOGE, FL(" invalid handle") );
Jeff Johnson295189b2012-06-20 16:38:30 -07001381 status = VOS_STATUS_E_INVAL;
1382 break;
1383 }
1384 //Find a match on handle. If not found, get a free slot.
1385 pSyncUpdateHist = btcFindSyncUpdateEventHist( pMac,
1386 pEvent->uEventParam.btSyncConnection.connectionHandle );
1387 if(pSyncUpdateHist)
1388 {
1389 pSyncUpdateHist->fValid = VOS_TRUE;
1390 vos_mem_copy(&pSyncUpdateHist->btSyncConnection, &pEvent->uEventParam.btSyncConnection,
1391 sizeof(tSmeBtSyncConnectionParam));
1392 }
1393 else
1394 {
Kiran Kumar Lokere691dde12013-03-06 17:00:31 -08001395 smsLog( pMac, LOGE, FL(" cannot find match for BT_EVENT_SYNC_CONNECTION_UPDATED of handle (%d)"),
Jeff Johnson295189b2012-06-20 16:38:30 -07001396 pEvent->uEventParam.btSyncConnection.connectionHandle );
1397 status = VOS_STATUS_E_EMPTY;
1398 }
1399 break;
1400 case BT_EVENT_DISCONNECTION_COMPLETE:
1401 status = btcDeferDisconnEvent( pMac, pEvent );
1402 break;
1403 case BT_EVENT_MODE_CHANGED:
1404 if( BT_INVALID_CONN_HANDLE == pEvent->uEventParam.btDisconnect.connectionHandle )
1405 {
Kiran Kumar Lokere691dde12013-03-06 17:00:31 -08001406 smsLog( pMac, LOGE, FL(" invalid handle") );
Jeff Johnson295189b2012-06-20 16:38:30 -07001407 status = VOS_STATUS_E_INVAL;
1408 break;
1409 }
1410 //Find a match on handle, If not found, return a free slot
1411 pModeChangeEventHist = btcFindModeChangeEventHist( pMac,
1412 pEvent->uEventParam.btAclModeChange.connectionHandle );
1413 if(pModeChangeEventHist)
1414 {
1415 pModeChangeEventHist->fValid = VOS_TRUE;
1416 vos_mem_copy( &pModeChangeEventHist->btAclModeChange,
1417 &pEvent->uEventParam.btAclModeChange, sizeof(tSmeBtAclModeChangeParam) );
1418 }
1419 else
1420 {
Kiran Kumar Lokere691dde12013-03-06 17:00:31 -08001421 smsLog( pMac, LOGE, FL(" cannot find match for BT_EVENT_MODE_CHANGED of handle (%d)"),
Jeff Johnson295189b2012-06-20 16:38:30 -07001422 pEvent->uEventParam.btAclModeChange.connectionHandle);
1423 status = VOS_STATUS_E_EMPTY;
1424 }
1425 break;
1426 case BT_EVENT_A2DP_STREAM_START:
1427 pReplay->btcEventHist.fA2DPStarted = VOS_TRUE;
1428 pReplay->btcEventHist.fA2DPStopped = VOS_FALSE;
1429 break;
1430 case BT_EVENT_A2DP_STREAM_STOP:
1431 pReplay->btcEventHist.fA2DPStopped = VOS_TRUE;
1432 pReplay->btcEventHist.fA2DPStarted = VOS_FALSE;
1433 break;
1434 default:
Kiran Kumar Lokere691dde12013-03-06 17:00:31 -08001435 smsLog( pMac, LOGE, FL(" event (%d) is not deferred"), pEvent->btEventType );
Jeff Johnson295189b2012-06-20 16:38:30 -07001436 status = VOS_STATUS_E_NOSUPPORT;
1437 break;
1438 }
1439 return (status);
1440}
1441
1442/*
1443 Replay all cached events in the following order
1444 1. If BT_SWITCH_OFF event, send it.
1445 2. Send INQUIRY event (START or STOP),if available
1446 3. Send PAGE event (START or STOP), if available
1447 4. Send DISCONNECT events, these DISCONNECT events are not tied to
1448 any ACL/SYNC event that we have cached
1449 5. Send ACL events (possible events, CREATION, COMPLETION, DISCONNECT)
1450 6. Send MODE_CHANGE events, if available
1451 7. Send A2DP event(START or STOP), if available
1452 8. Send SYNC events (possible events, CREATION, COMPLETION, DISCONNECT)
1453 9. Send SYNC_UPDATE events, if available
1454*/
1455static void btcReplayEvents( tpAniSirGlobal pMac )
1456{
1457 int i, j;
1458 tSmeBtEvent btEvent;
1459 tpSmeBtAclEventHist pAclHist;
1460 tpSmeBtSyncEventHist pSyncHist;
1461 tSmeBtcEventReplay *pReplay = &pMac->btc.btcEventReplay;
1462 //Always turn on HB monitor first.
1463 //It is independent of BT events even though BT event causes this
1464 if( pReplay->fRestoreHBMonitor )
1465 {
1466 pReplay->fRestoreHBMonitor = VOS_FALSE;
1467 //Only do it when needed
1468 if( !pMac->btc.btcHBActive )
1469 {
1470 ccmCfgSetInt(pMac, WNI_CFG_HEART_BEAT_THRESHOLD, pMac->btc.btcHBCount, NULL, eANI_BOOLEAN_FALSE);
1471 pMac->btc.btcHBActive = VOS_TRUE;
1472 }
1473 }
1474 if( pMac->btc.fReplayBTEvents )
1475 {
1476 /*Set the flag to false here so btcSignalBTEvent won't defer any further.
1477 This works because SME has it global lock*/
1478 pMac->btc.fReplayBTEvents = VOS_FALSE;
1479 if( pReplay->fBTSwitchOff )
1480 {
1481 vos_mem_zero( &btEvent, sizeof(tSmeBtEvent) );
1482 btEvent.btEventType = BT_EVENT_DEVICE_SWITCHED_OFF;
1483 btcSendBTEvent( pMac, &btEvent );
1484 pReplay->fBTSwitchOff = VOS_FALSE;
1485 }
1486 else if( pReplay->fBTSwitchOn )
1487 {
1488 vos_mem_zero( &btEvent, sizeof(tSmeBtEvent) );
1489 btEvent.btEventType = BT_EVENT_DEVICE_SWITCHED_ON;
1490 btcSendBTEvent( pMac, &btEvent );
1491 pReplay->fBTSwitchOn = VOS_FALSE;
1492 }
1493 //Do inquire first
1494 if( pReplay->btcEventHist.nInquiryEvent > 0 )
1495 {
1496 vos_mem_zero( &btEvent, sizeof(tSmeBtEvent) );
1497 btEvent.btEventType = BT_EVENT_INQUIRY_STARTED;
1498 i = pReplay->btcEventHist.nInquiryEvent;
1499 while(i--)
1500 {
1501 btcSendBTEvent( pMac, &btEvent );
1502 }
1503 }
1504 else if( pReplay->btcEventHist.nInquiryEvent < 0 )
1505 {
1506 vos_mem_zero( &btEvent, sizeof(tSmeBtEvent) );
1507 btEvent.btEventType = BT_EVENT_INQUIRY_STOPPED;
1508 i = pReplay->btcEventHist.nInquiryEvent;
1509 while(i++)
1510 {
1511 btcSendBTEvent( pMac, &btEvent );
1512 }
1513 }
1514 //Page
1515 if( pReplay->btcEventHist.nPageEvent > 0 )
1516 {
1517 vos_mem_zero( &btEvent, sizeof(tSmeBtEvent) );
1518 btEvent.btEventType = BT_EVENT_PAGE_STARTED;
1519 i = pReplay->btcEventHist.nPageEvent;
1520 while(i--)
1521 {
1522 btcSendBTEvent( pMac, &btEvent );
1523 }
1524 }
1525 else if( pReplay->btcEventHist.nPageEvent < 0 )
1526 {
1527 vos_mem_zero( &btEvent, sizeof(tSmeBtEvent) );
1528 btEvent.btEventType = BT_EVENT_PAGE_STOPPED;
1529 i = pReplay->btcEventHist.nPageEvent;
1530 while(i++)
1531 {
1532 btcSendBTEvent( pMac, &btEvent );
1533 }
1534 }
1535 //Replay non-completion disconnect events first
1536 //Disconnect
1537 for( i = 0; i < BT_MAX_DISCONN_SUPPORT; i++ )
1538 {
1539 if( pReplay->btcEventHist.btDisconnectEvent[i].fValid )
1540 {
1541 vos_mem_zero( &btEvent, sizeof(tSmeBtEvent) );
1542 btEvent.btEventType = BT_EVENT_DISCONNECTION_COMPLETE;
1543 vos_mem_copy( &btEvent.uEventParam.btDisconnect,
1544 &pReplay->btcEventHist.btDisconnectEvent[i].btDisconnect, sizeof(tSmeBtDisconnectParam) );
1545 btcSendBTEvent( pMac, &btEvent );
1546 }
1547 }
1548 //ACL
1549 for( i = 0; i < BT_MAX_ACL_SUPPORT; i++ )
1550 {
1551 if( pReplay->btcEventHist.btAclConnectionEvent[i].bNextEventIdx )
1552 {
1553 pAclHist = &pReplay->btcEventHist.btAclConnectionEvent[i];
1554 //Replay all ACL events for this BD address/handle
1555 for(j = 0; j < pAclHist->bNextEventIdx; j++)
1556 {
1557 vos_mem_zero( &btEvent, sizeof(tSmeBtEvent) );
1558 vos_mem_zero( &btEvent, sizeof(tSmeBtEvent) );
1559 btEvent.btEventType = pAclHist->btEventType[j];
1560 if(BT_EVENT_DISCONNECTION_COMPLETE != btEvent.btEventType)
1561 {
1562 //It must be CREATE or CONNECTION_COMPLETE
1563 vos_mem_copy( &btEvent.uEventParam.btAclConnection,
1564 &pAclHist->btAclConnection[j], sizeof(tSmeBtAclConnectionParam) );
1565 }
1566 else
1567 {
1568 btEvent.uEventParam.btDisconnect.connectionHandle = pAclHist->btAclConnection[j].connectionHandle;
1569 }
1570 btcSendBTEvent( pMac, &btEvent );
1571 }
1572 }
1573 }
1574 //Mode change
1575 for( i = 0; i < BT_MAX_ACL_SUPPORT; i++ )
1576 {
1577 if( pReplay->btcEventHist.btAclModeChangeEvent[i].fValid )
1578 {
1579 vos_mem_zero( &btEvent, sizeof(tSmeBtEvent) );
1580 btEvent.btEventType = BT_EVENT_MODE_CHANGED;
1581 vos_mem_copy( &btEvent.uEventParam.btAclModeChange,
1582 &pReplay->btcEventHist.btAclModeChangeEvent[i].btAclModeChange, sizeof(tSmeBtAclModeChangeParam) );
1583 btcSendBTEvent( pMac, &btEvent );
1584 }
1585 }
1586 //A2DP
1587 if( pReplay->btcEventHist.fA2DPStarted )
1588 {
1589 vos_mem_zero( &btEvent, sizeof(tSmeBtEvent) );
1590 btEvent.btEventType = BT_EVENT_A2DP_STREAM_START;
1591 btcSendBTEvent( pMac, &btEvent );
1592 }
1593 else if( pReplay->btcEventHist.fA2DPStopped )
1594 {
1595 vos_mem_zero( &btEvent, sizeof(tSmeBtEvent) );
1596 btEvent.btEventType = BT_EVENT_A2DP_STREAM_STOP;
1597 btcSendBTEvent( pMac, &btEvent );
1598 }
1599 //SCO
1600 for( i = 0; i < BT_MAX_SCO_SUPPORT; i++ )
1601 {
1602 if( pReplay->btcEventHist.btSyncConnectionEvent[i].bNextEventIdx )
1603 {
1604 pSyncHist = &pReplay->btcEventHist.btSyncConnectionEvent[i];
1605 //Replay all SYNC events for this BD address/handle
1606 for(j = 0; j < pSyncHist->bNextEventIdx; j++)
1607 {
1608 vos_mem_zero( &btEvent, sizeof(tSmeBtEvent) );
1609 vos_mem_zero( &btEvent, sizeof(tSmeBtEvent) );
1610 btEvent.btEventType = pSyncHist->btEventType[j];
1611 if(BT_EVENT_DISCONNECTION_COMPLETE != btEvent.btEventType)
1612 {
1613 //Must be CREATION or CONNECTION_COMPLETE
1614 vos_mem_copy( &btEvent.uEventParam.btSyncConnection,
1615 &pSyncHist->btSyncConnection[j], sizeof(tSmeBtSyncConnectionParam) );
1616 }
1617 else
1618 {
1619 btEvent.uEventParam.btDisconnect.connectionHandle = pSyncHist->btSyncConnection[j].connectionHandle;
1620 }
1621 btcSendBTEvent( pMac, &btEvent );
1622 }
1623 }
1624 }
1625 //SYNC update
1626 for( i = 0; i < BT_MAX_SCO_SUPPORT; i++ )
1627 {
1628 if( pReplay->btcEventHist.btSyncUpdateEvent[i].fValid )
1629 {
1630 vos_mem_zero( &btEvent, sizeof(tSmeBtEvent) );
1631 btEvent.btEventType = BT_EVENT_SYNC_CONNECTION_UPDATED;
1632 vos_mem_copy( &btEvent.uEventParam.btSyncConnection,
1633 &pReplay->btcEventHist.btSyncUpdateEvent[i].btSyncConnection,
1634 sizeof(tSmeBtSyncConnectionParam) );
1635 btcSendBTEvent( pMac, &btEvent );
1636 }
1637 }
1638 //Clear all events
1639 vos_mem_zero( &pReplay->btcEventHist, sizeof(tSmeBtcEventHist) );
1640 }
1641}
1642
1643static void btcPowerStateCB( v_PVOID_t pContext, tPmcState pmcState )
1644{
1645 tpAniSirGlobal pMac = PMAC_STRUCT(pContext);
1646 if( FULL_POWER == pmcState )
1647 {
1648 btcReplayEvents( pMac );
1649 }
1650}
1651
1652/* ---------------------------------------------------------------------------
1653 \fn btcLogEvent
1654 \brief API to log the the current Bluetooth event
1655 \param hHal - The handle returned by macOpen.
1656 \param pSmeBtcConfig - Pointer to a caller allocated object of type
1657 tSmeBtEvent. Caller owns the memory and is responsible
1658 for freeing it.
1659 \return None
1660 ---------------------------------------------------------------------------*/
1661static void btcLogEvent (tHalHandle hHal, tpSmeBtEvent pBtEvent)
1662{
1663 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "%s: "
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001664 "Bluetooth Event %d received", __func__, pBtEvent->btEventType);
Jeff Johnson295189b2012-06-20 16:38:30 -07001665 switch(pBtEvent->btEventType)
1666 {
1667 case BT_EVENT_CREATE_SYNC_CONNECTION:
1668 case BT_EVENT_SYNC_CONNECTION_COMPLETE:
1669 case BT_EVENT_SYNC_CONNECTION_UPDATED:
1670 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "SCO Connection: "
1671 "connectionHandle = %d status = %d linkType %d "
1672 "scoInterval %d scoWindow %d retransmisisonWindow = %d ",
1673 pBtEvent->uEventParam.btSyncConnection.connectionHandle,
1674 pBtEvent->uEventParam.btSyncConnection.status,
1675 pBtEvent->uEventParam.btSyncConnection.linkType,
1676 pBtEvent->uEventParam.btSyncConnection.scoInterval,
1677 pBtEvent->uEventParam.btSyncConnection.scoWindow,
1678 pBtEvent->uEventParam.btSyncConnection.retransmisisonWindow);
1679 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "BD ADDR = "
1680 "0x%x 0x%x 0x%x 0x%x 0x%x 0x%x",
1681 pBtEvent->uEventParam.btSyncConnection.bdAddr[5],
1682 pBtEvent->uEventParam.btSyncConnection.bdAddr[4],
1683 pBtEvent->uEventParam.btSyncConnection.bdAddr[3],
1684 pBtEvent->uEventParam.btSyncConnection.bdAddr[2],
1685 pBtEvent->uEventParam.btSyncConnection.bdAddr[1],
1686 pBtEvent->uEventParam.btSyncConnection.bdAddr[0]);
1687 break;
1688 case BT_EVENT_CREATE_ACL_CONNECTION:
1689 case BT_EVENT_ACL_CONNECTION_COMPLETE:
1690 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "ACL Connection: "
1691 "connectionHandle = %d status = %d ",
1692 pBtEvent->uEventParam.btAclConnection.connectionHandle,
1693 pBtEvent->uEventParam.btAclConnection.status);
1694 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "BD ADDR = "
1695 "0x%x 0x%x 0x%x 0x%x 0x%x 0x%x",
1696 pBtEvent->uEventParam.btAclConnection.bdAddr[5],
1697 pBtEvent->uEventParam.btAclConnection.bdAddr[4],
1698 pBtEvent->uEventParam.btAclConnection.bdAddr[3],
1699 pBtEvent->uEventParam.btAclConnection.bdAddr[2],
1700 pBtEvent->uEventParam.btAclConnection.bdAddr[1],
1701 pBtEvent->uEventParam.btAclConnection.bdAddr[0]);
1702 break;
1703 case BT_EVENT_MODE_CHANGED:
1704 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "ACL Mode change : "
1705 "connectionHandle %d mode %d ",
1706 pBtEvent->uEventParam.btAclModeChange.connectionHandle,
1707 pBtEvent->uEventParam.btAclModeChange.mode);
1708 break;
1709 case BT_EVENT_DISCONNECTION_COMPLETE:
1710 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "Disconnect Event : "
1711 "connectionHandle %d ", pBtEvent->uEventParam.btAclModeChange.connectionHandle);
1712 break;
1713 default:
1714 break;
1715 }
1716 }
1717
1718/*
1719 Caller can check whether BTC's current event allows UAPSD. This doesn't affect
1720 BMPS.
1721 return: VOS_TRUE -- BTC is ready for UAPSD
1722 VOS_FALSE -- certain BT event is active, cannot enter UAPSD
1723*/
1724v_BOOL_t btcIsReadyForUapsd( tHalHandle hHal )
1725{
1726 tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
1727 return( pMac->btc.btcUapsdOk );
1728}
1729
1730/*
1731 Base on the BT event, this function sets the flag on whether to allow UAPSD
1732 At this time, we are only interested in SCO and A2DP.
1733 A2DP tracking is through BT_EVENT_A2DP_STREAM_START and BT_EVENT_A2DP_STREAM_STOP
1734 SCO is through BT_EVENT_SYNC_CONNECTION_COMPLETE and BT_EVENT_DISCONNECTION_COMPLETE
1735 BT_EVENT_DEVICE_SWITCHED_OFF overwrites them all
1736*/
1737void btcUapsdCheck( tpAniSirGlobal pMac, tpSmeBtEvent pBtEvent )
1738{
1739 v_U8_t i;
1740 v_BOOL_t fLastUapsdState = pMac->btc.btcUapsdOk, fMoreSCO = VOS_FALSE;
1741 switch( pBtEvent->btEventType )
1742 {
1743 case BT_EVENT_DISCONNECTION_COMPLETE:
1744 if( (VOS_FALSE == pMac->btc.btcUapsdOk) &&
1745 BT_INVALID_CONN_HANDLE != pBtEvent->uEventParam.btDisconnect.connectionHandle )
1746 {
1747 //Check whether all SCO connections are gone
1748 for(i=0; i < BT_MAX_SCO_SUPPORT; i++)
1749 {
1750 if( (BT_INVALID_CONN_HANDLE != pMac->btc.btcScoHandles[i]) &&
1751 (pMac->btc.btcScoHandles[i] != pBtEvent->uEventParam.btDisconnect.connectionHandle) )
1752 {
1753 //We still have outstanding SCO connection
1754 fMoreSCO = VOS_TRUE;
1755 }
1756 else if( pMac->btc.btcScoHandles[i] == pBtEvent->uEventParam.btDisconnect.connectionHandle )
1757 {
1758 pMac->btc.btcScoHandles[i] = BT_INVALID_CONN_HANDLE;
1759 }
1760 }
1761 if( !fMoreSCO && !pMac->btc.fA2DPUp )
1762 {
1763 //All SCO is disconnected
1764 pMac->btc.btcUapsdOk = VOS_TRUE;
Kiran Kumar Lokere691dde12013-03-06 17:00:31 -08001765 smsLog( pMac, LOGE, "BT event (DISCONNECTION) happens, UAPSD-allowed flag (%d) change to TRUE",
Jeff Johnson295189b2012-06-20 16:38:30 -07001766 pBtEvent->btEventType, pMac->btc.btcUapsdOk );
1767 }
1768 }
1769 break;
1770 case BT_EVENT_DEVICE_SWITCHED_OFF:
Kiran Kumar Lokere691dde12013-03-06 17:00:31 -08001771 smsLog( pMac, LOGE, "BT event (DEVICE_OFF) happens, UAPSD-allowed flag (%d) change to TRUE",
Jeff Johnson295189b2012-06-20 16:38:30 -07001772 pBtEvent->btEventType, pMac->btc.btcUapsdOk );
1773 //Clean up SCO
1774 for(i=0; i < BT_MAX_SCO_SUPPORT; i++)
1775 {
1776 pMac->btc.btcScoHandles[i] = BT_INVALID_CONN_HANDLE;
1777 }
1778 pMac->btc.fA2DPUp = VOS_FALSE;
1779 pMac->btc.btcUapsdOk = VOS_TRUE;
1780 break;
1781 case BT_EVENT_A2DP_STREAM_STOP:
Kiran Kumar Lokere691dde12013-03-06 17:00:31 -08001782 smsLog( pMac, LOGE, "BT event (A2DP_STREAM_STOP) happens, UAPSD-allowed flag (%d)",
Jeff Johnson295189b2012-06-20 16:38:30 -07001783 pMac->btc.btcUapsdOk );
1784 pMac->btc.fA2DPUp = VOS_FALSE;
1785 //Check whether SCO is on
1786 for(i=0; i < BT_MAX_SCO_SUPPORT; i++)
1787 {
1788 if(pMac->btc.btcScoHandles[i] != BT_INVALID_CONN_HANDLE)
1789 {
1790 break;
1791 }
1792 }
1793 if( BT_MAX_SCO_SUPPORT == i )
1794 {
1795 pMac->btc.fA2DPTrafStop = VOS_TRUE;
Kiran Kumar Lokere691dde12013-03-06 17:00:31 -08001796 smsLog( pMac, LOGE, "BT_EVENT_A2DP_STREAM_STOP: UAPSD-allowed flag is now %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07001797 pMac->btc.btcUapsdOk );
1798 }
1799 break;
1800
1801 case BT_EVENT_MODE_CHANGED:
Kiran Kumar Lokere691dde12013-03-06 17:00:31 -08001802 smsLog( pMac, LOGE, "BT event (BT_EVENT_MODE_CHANGED) happens, Mode (%d) UAPSD-allowed flag (%d)",
Jeff Johnson295189b2012-06-20 16:38:30 -07001803 pBtEvent->uEventParam.btAclModeChange.mode, pMac->btc.btcUapsdOk );
1804 if(pBtEvent->uEventParam.btAclModeChange.mode == BT_ACL_SNIFF)
1805 {
1806 //Check whether SCO is on
1807 for(i=0; i < BT_MAX_SCO_SUPPORT; i++)
1808 {
1809 if(pMac->btc.btcScoHandles[i] != BT_INVALID_CONN_HANDLE)
1810 {
1811 break;
1812 }
1813 }
1814 if( BT_MAX_SCO_SUPPORT == i )
1815 {
1816 if(VOS_TRUE == pMac->btc.fA2DPTrafStop)
1817 {
1818 pMac->btc.btcUapsdOk = VOS_TRUE;
1819 pMac->btc.fA2DPTrafStop = VOS_FALSE;
1820 }
Kiran Kumar Lokere691dde12013-03-06 17:00:31 -08001821 smsLog( pMac, LOGE, "BT_EVENT_MODE_CHANGED with Mode:%d UAPSD-allowed flag is now %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07001822 pBtEvent->uEventParam.btAclModeChange.mode,pMac->btc.btcUapsdOk );
1823 }
1824 }
1825 break;
1826 case BT_EVENT_CREATE_SYNC_CONNECTION:
1827 {
1828 pMac->btc.btcUapsdOk = VOS_FALSE;
Kiran Kumar Lokere691dde12013-03-06 17:00:31 -08001829 smsLog( pMac, LOGE, "BT_EVENT_CREATE_SYNC_CONNECTION (%d) happens, UAPSD-allowed flag (%d) change to FALSE",
Jeff Johnson295189b2012-06-20 16:38:30 -07001830 pBtEvent->btEventType, pMac->btc.btcUapsdOk );
1831 }
1832 break;
1833 case BT_EVENT_SYNC_CONNECTION_COMPLETE:
1834 //Make sure it is a success
1835 if( BT_CONN_STATUS_FAIL != pBtEvent->uEventParam.btSyncConnection.status )
1836 {
1837 //Save te handle for later use
1838 for( i = 0; i < BT_MAX_SCO_SUPPORT; i++)
1839 {
1840 VOS_ASSERT(BT_INVALID_CONN_HANDLE != pBtEvent->uEventParam.btSyncConnection.connectionHandle);
1841 if( (BT_INVALID_CONN_HANDLE == pMac->btc.btcScoHandles[i]) &&
1842 (BT_INVALID_CONN_HANDLE != pBtEvent->uEventParam.btSyncConnection.connectionHandle))
1843 {
1844 pMac->btc.btcScoHandles[i] = pBtEvent->uEventParam.btSyncConnection.connectionHandle;
1845 break;
1846 }
1847 }
1848
1849 if( i >= BT_MAX_SCO_SUPPORT )
1850 {
Kiran Kumar Lokere691dde12013-03-06 17:00:31 -08001851 smsLog(pMac, LOGE, FL("Too many SCO, ignore this one"));
Jeff Johnson295189b2012-06-20 16:38:30 -07001852 }
1853 }
1854 else
1855 {
1856 //Check whether SCO is on
1857 for(i=0; i < BT_MAX_SCO_SUPPORT; i++)
1858 {
1859 if(pMac->btc.btcScoHandles[i] != BT_INVALID_CONN_HANDLE)
1860 {
1861 break;
1862 }
1863 }
1864 /*If No Other Sco/A2DP is ON reenable UAPSD*/
1865 if( (BT_MAX_SCO_SUPPORT == i) && !pMac->btc.fA2DPUp)
1866 {
1867 pMac->btc.btcUapsdOk = VOS_TRUE;
1868 }
Kiran Kumar Lokere691dde12013-03-06 17:00:31 -08001869 smsLog(pMac, LOGE, FL("TSYNC complete failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -07001870 }
1871 break;
1872 case BT_EVENT_A2DP_STREAM_START:
Kiran Kumar Lokere691dde12013-03-06 17:00:31 -08001873 smsLog( pMac, LOGE, "BT_EVENT_A2DP_STREAM_START (%d) happens, UAPSD-allowed flag (%d) change to FALSE",
Jeff Johnson295189b2012-06-20 16:38:30 -07001874 pBtEvent->btEventType, pMac->btc.btcUapsdOk );
1875 pMac->btc.fA2DPTrafStop = VOS_FALSE;
1876 pMac->btc.btcUapsdOk = VOS_FALSE;
1877 pMac->btc.fA2DPUp = VOS_TRUE;
1878 break;
1879 default:
1880 //No change for these events
Kiran Kumar Lokere691dde12013-03-06 17:00:31 -08001881 smsLog( pMac, LOGE, "BT event (%d) happens, UAPSD-allowed flag (%d) no change",
Jeff Johnson295189b2012-06-20 16:38:30 -07001882 pBtEvent->btEventType, pMac->btc.btcUapsdOk );
1883 break;
1884 }
1885 if(fLastUapsdState != pMac->btc.btcUapsdOk)
1886 {
1887 sme_QosTriggerUapsdChange( pMac );
1888 }
1889}
1890
1891/* ---------------------------------------------------------------------------
1892 \fn btcHandleCoexInd
1893 \brief API to handle Coex indication from WDI
1894 \param pMac - The handle returned by macOpen.
1895 \return eHalStatus
1896 eHAL_STATUS_FAILURE success
1897 eHAL_STATUS_SUCCESS failure
1898 ---------------------------------------------------------------------------*/
1899eHalStatus btcHandleCoexInd(tHalHandle hHal, void* pMsg)
1900{
1901 tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
1902 eHalStatus status = eHAL_STATUS_SUCCESS;
1903 tSirSmeCoexInd *pSmeCoexInd = (tSirSmeCoexInd *)pMsg;
1904
1905 if (NULL == pMsg)
1906 {
Kiran Kumar Lokere691dde12013-03-06 17:00:31 -08001907 smsLog(pMac, LOGE, "in %s msg ptr is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001908 status = eHAL_STATUS_FAILURE;
1909 }
1910 else
1911 {
1912 // DEBUG
1913 smsLog(pMac, LOG1, "Coex indication in %s(), type %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001914 __func__, pSmeCoexInd->coexIndType);
Jeff Johnson295189b2012-06-20 16:38:30 -07001915
1916 // suspend heartbeat monitoring
1917 if (pSmeCoexInd->coexIndType == SIR_COEX_IND_TYPE_DISABLE_HB_MONITOR)
1918 {
1919 // set heartbeat threshold CFG to zero
1920 ccmCfgSetInt(pMac, WNI_CFG_HEART_BEAT_THRESHOLD, 0, NULL, eANI_BOOLEAN_FALSE);
1921 pMac->btc.btcHBActive = VOS_FALSE;
1922 }
1923
1924 // resume heartbeat monitoring
1925 else if (pSmeCoexInd->coexIndType == SIR_COEX_IND_TYPE_ENABLE_HB_MONITOR)
1926 {
1927 if (!pMac->btc.btcHBActive)
1928 {
1929 ccmCfgSetInt(pMac, WNI_CFG_HEART_BEAT_THRESHOLD, pMac->btc.btcHBCount, NULL, eANI_BOOLEAN_FALSE);
1930 pMac->btc.btcHBActive = VOS_TRUE;
1931 }
1932 }
Kiran Kumar Lokere3527f0c2013-02-24 22:21:28 -08001933 else if (pSmeCoexInd->coexIndType == SIR_COEX_IND_TYPE_SCAN_COMPROMISED)
1934 {
1935 pMac->btc.btcScanCompromise = VOS_TRUE;
Kiran Kumar Lokere691dde12013-03-06 17:00:31 -08001936 smsLog(pMac, LOGW, "Coex indication in %s(), type - SIR_COEX_IND_TYPE_SCAN_COMPROMISED",
Kiran Kumar Lokere3527f0c2013-02-24 22:21:28 -08001937 __func__);
1938 }
1939 else if (pSmeCoexInd->coexIndType == SIR_COEX_IND_TYPE_SCAN_NOT_COMPROMISED)
1940 {
1941 pMac->btc.btcScanCompromise = VOS_FALSE;
Kiran Kumar Lokere691dde12013-03-06 17:00:31 -08001942 smsLog(pMac, LOGW, "Coex indication in %s(), type - SIR_COEX_IND_TYPE_SCAN_NOT_COMPROMISED",
Kiran Kumar Lokere3527f0c2013-02-24 22:21:28 -08001943 __func__);
1944 }
Kiran Kumar Lokere458d7322013-05-29 14:29:43 -07001945 else if (pSmeCoexInd->coexIndType == SIR_COEX_IND_TYPE_DISABLE_AGGREGATION_IN_2p4)
1946 {
1947 if (pMac->roam.configParam.disableAggWithBtc)
1948 {
1949 ccmCfgSetInt(pMac, WNI_CFG_DEL_ALL_RX_BA_SESSIONS_2_4_G_BTC, 1,
1950 NULL, eANI_BOOLEAN_FALSE);
1951 smsLog(pMac, LOGW,
1952 "Coex indication in %s(), type - SIR_COEX_IND_TYPE_DISABLE_AGGREGATION_IN_2p4",
1953 __func__);
1954 }
1955 }
1956 else if (pSmeCoexInd->coexIndType == SIR_COEX_IND_TYPE_ENABLE_AGGREGATION_IN_2p4)
1957 {
1958 if (pMac->roam.configParam.disableAggWithBtc)
1959 {
1960 ccmCfgSetInt(pMac, WNI_CFG_DEL_ALL_RX_BA_SESSIONS_2_4_G_BTC, 0,
1961 NULL, eANI_BOOLEAN_FALSE);
1962 smsLog(pMac, LOGW,
1963 "Coex indication in %s(), type - SIR_COEX_IND_TYPE_ENABLE_AGGREGATION_IN_2p4",
1964 __func__);
1965 }
1966 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001967 // unknown indication type
1968 else
1969 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001970 smsLog(pMac, LOGE, "unknown Coex indication type in %s()", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001971 }
1972 }
1973
1974 return(status);
1975}
1976
1977#ifdef FEATURE_WLAN_DIAG_SUPPORT
1978/* ---------------------------------------------------------------------------
1979 \fn btcDiagEventLog
1980 \brief API to log the the current Bluetooth event
1981 \param hHal - The handle returned by macOpen.
1982 \param pSmeBtcConfig - Pointer to a caller allocated object of type
1983 tSmeBtEvent. Caller owns the memory and is responsible
1984 for freeing it.
1985 \return None
1986 ---------------------------------------------------------------------------*/
1987static void btcDiagEventLog (tHalHandle hHal, tpSmeBtEvent pBtEvent)
1988{
1989 //vos_event_wlan_btc_type *log_ptr = NULL;
1990 WLAN_VOS_DIAG_EVENT_DEF(btDiagEvent, vos_event_wlan_btc_type);
1991 {
1992 btDiagEvent.eventId = pBtEvent->btEventType;
1993 switch(pBtEvent->btEventType)
1994 {
1995 case BT_EVENT_CREATE_SYNC_CONNECTION:
1996 case BT_EVENT_SYNC_CONNECTION_COMPLETE:
1997 case BT_EVENT_SYNC_CONNECTION_UPDATED:
1998 btDiagEvent.connHandle = pBtEvent->uEventParam.btSyncConnection.connectionHandle;
1999 btDiagEvent.connStatus = pBtEvent->uEventParam.btSyncConnection.status;
2000 btDiagEvent.linkType = pBtEvent->uEventParam.btSyncConnection.linkType;
2001 btDiagEvent.scoInterval = pBtEvent->uEventParam.btSyncConnection.scoInterval;
2002 btDiagEvent.scoWindow = pBtEvent->uEventParam.btSyncConnection.scoWindow;
2003 btDiagEvent.retransWindow = pBtEvent->uEventParam.btSyncConnection.retransmisisonWindow;
2004 vos_mem_copy(btDiagEvent.btAddr, pBtEvent->uEventParam.btSyncConnection.bdAddr,
2005 sizeof(btDiagEvent.btAddr));
2006 break;
2007 case BT_EVENT_CREATE_ACL_CONNECTION:
2008 case BT_EVENT_ACL_CONNECTION_COMPLETE:
2009 btDiagEvent.connHandle = pBtEvent->uEventParam.btAclConnection.connectionHandle;
2010 btDiagEvent.connStatus = pBtEvent->uEventParam.btAclConnection.status;
2011 vos_mem_copy(btDiagEvent.btAddr, pBtEvent->uEventParam.btAclConnection.bdAddr,
2012 sizeof(btDiagEvent.btAddr));
2013 break;
2014 case BT_EVENT_MODE_CHANGED:
2015 btDiagEvent.connHandle = pBtEvent->uEventParam.btAclModeChange.connectionHandle;
2016 btDiagEvent.mode = pBtEvent->uEventParam.btAclModeChange.mode;
2017 break;
2018 case BT_EVENT_DISCONNECTION_COMPLETE:
2019 btDiagEvent.connHandle = pBtEvent->uEventParam.btAclModeChange.connectionHandle;
2020 break;
2021 default:
2022 break;
2023 }
2024 }
2025 WLAN_VOS_DIAG_EVENT_REPORT(&btDiagEvent, EVENT_WLAN_BTC);
2026}
2027#endif /* FEATURE_WLAN_DIAG_SUPPORT */
2028#endif /* WLAN_MDM_CODE_REDUCTION_OPT*/