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