blob: 3c809841ce46c2e8e94c84ac6683e2eac5f72e4d [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
2 * Copyright (c) 2012, Code Aurora Forum. 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
22/*===========================================================================
23
24 W L A N _ Q C T _ T L _ HOSUPPORT. C
25
26 OVERVIEW:
27
28 DEPENDENCIES:
29
30 Are listed for each API below.
31
32
33 Copyright (c) 2008 QUALCOMM Incorporated.
34 All Rights Reserved.
35 Qualcomm Confidential and Proprietary
36===========================================================================*/
37
38/*===========================================================================
39
40 EDIT HISTORY FOR FILE
41
42
43 This section contains comments describing changes made to the module.
44 Notice that changes are listed in reverse chronological order.
45
46
47 $Header$$DateTime$$Author$
48
49
50 when who what, where, why
51---------- --- --------------------------------------------------------
5202/19/09 lti Vos trace fix
5302/06/09 sch Dereg Bug fix
5412/11/08 sch Initial creation
55
56===========================================================================*/
57#include "wlan_qct_tl.h"
58#include "wlan_qct_wda.h"
59#if defined WLAN_FEATURE_NEIGHBOR_ROAMING
60/*----------------------------------------------------------------------------
61 * Include Files
62 * -------------------------------------------------------------------------*/
63#include "wlan_qct_tl_hosupport.h"
64#include "wlan_qct_tli.h"
65#include "tlDebug.h"
66/*----------------------------------------------------------------------------
67 * Preprocessor Definitions and Constants
68 * -------------------------------------------------------------------------*/
69//#define WLANTL_HO_DEBUG_MSG
70//#define WLANTL_HO_UTEST
71
72#define WLANTL_HO_DEFAULT_RSSI 0xFF
73#define WLANTL_HO_DEFAULT_ALPHA 5
74#define WLANTL_HO_INVALID_RSSI -100
75/* RSSI sampling period, usec based
76 * To reduce performance overhead
77 * Current default 500msec */
78#define WLANTL_HO_SAMPLING_PERIOD 500000
79
80
81
82/* Get and release lock */
83#define THSGETLOCK(a, b) \
84 do \
85 { \
86 if(!VOS_IS_STATUS_SUCCESS(vos_lock_acquire(b))) \
87 { \
88 TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"%s Get Lock Fail", a)); \
89 return VOS_STATUS_E_FAILURE; \
90 } \
91 }while(0)
92
93#define THSRELEASELOCK(a, b) \
94 do \
95 { \
96 if(!VOS_IS_STATUS_SUCCESS(vos_lock_release(b))) \
97 { \
98 TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"%s Release Lock Fail", a)); \
99 return VOS_STATUS_E_FAILURE; \
100 } \
101 }while(0)
102
103const v_U8_t WLANTL_HO_TID_2_AC[WLAN_MAX_TID] = {WLANTL_AC_BE,
104 WLANTL_AC_BK,
105 WLANTL_AC_BK,
106 WLANTL_AC_BE,
107 WLANTL_AC_VI,
108 WLANTL_AC_VI,
109 WLANTL_AC_VO,
110 WLANTL_AC_VO};
111/*----------------------------------------------------------------------------
112 * Type Declarations
113 * -------------------------------------------------------------------------*/
114/* Temporary threshold store place for BMPS */
115typedef struct
116{
117 v_S7_t rssi;
118 v_U8_t event;
119} WLANTL_HSTempPSIndType;
120
121#ifdef RSSI_HACK
122/* This is a dummy averaged RSSI value that can be controlled using dump commands
123 * to trigger TL to issue handoff related events. We will be using dump 362 <average RSSI>
124 * value to change its value */
125int dumpCmdRSSI = -48;
126#endif
127
128#ifdef WLANTL_HO_UTEST
129/*==========================================================================
130
131 FUNCTION
132
133 DESCRIPTION
134
135 PARAMETERS
136
137 RETURN VALUE
138
139============================================================================*/
140static v_S7_t rssi;
141static v_S7_t direction;
142void TLHS_UtestHandleNewRSSI(v_S7_t *newRSSI, v_PVOID_t pAdapter)
143{
144 if(0 == rssi)
145 {
146 direction = -1;
147 }
148 else if(-90 == rssi)
149 {
150 direction = 1;
151 }
152
153 *newRSSI = rssi;
154 rssi += direction;
155
156 return;
157}
158#endif /* WLANTL_HO_UTEST */
159
160#ifdef WLANTL_HO_DEBUG_MSG
161/*==========================================================================
162
163 FUNCTION
164
165 DESCRIPTION
166
167 PARAMETERS
168
169 RETURN VALUE
170
171============================================================================*/
172void WLANTL_StatDebugDisplay
173(
174 v_U8_t STAid,
175 WLANTL_TRANSFER_STA_TYPE *statistics
176)
177{
178 TLLOG1(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO,"================================================="));
179 TLLOG1(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO,"Statistics for STA %d", STAid));
180 TLLOG1(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO,"RX UC Fcnt %5d, MC Fcnt %5d, BC Fcnt %5d",
181 statistics->rxUCFcnt, statistics->rxMCFcnt, statistics->rxBCFcnt));
182 TLLOG1(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO,"RX UC Bcnt %5d, MC Bcnt %5d, BC Bcnt %5d",
183 statistics->rxUCBcnt, statistics->rxMCBcnt, statistics->rxBCBcnt));
184 TLLOG1(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO,"TX UC Fcnt %5d, MC Fcnt %5d, BC Fcnt %5d",
185 statistics->txUCFcnt, statistics->txMCFcnt, statistics->txBCFcnt));
186 TLLOG1(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO,"TX UC Bcnt %5d, MC Bcnt %5d, BC Bcnt %5d",
187 statistics->txUCBcnt, statistics->txMCBcnt, statistics->txBCBcnt));
188 TLLOG1(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO,"TRX Bcnt %5d, CRCOK Bcnt %5d, RXRate %5d",
189 statistics->rxBcnt, statistics->rxBcntCRCok, statistics->rxRate));
190 TLLOG1(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO,"================================================="));
191 return;
192}
193#endif /* WLANTL_HO_DEBUG_MSG */
194
195/*==========================================================================
196
197 FUNCTION
198
199 DESCRIPTION
200
201 PARAMETERS
202
203 RETURN VALUE
204
205============================================================================*/
206void WLANTL_HSDebugDisplay
207(
208 v_PVOID_t pAdapter
209)
210{
211 WLANTL_CbType *tlCtxt = VOS_GET_TL_CB(pAdapter);
212 v_U8_t idx, sIdx;
213 v_BOOL_t regionFound = VOS_FALSE;
214 WLANTL_CURRENT_HO_STATE_TYPE *currentHO;
215 WLANTL_HO_SUPPORT_TYPE *hoSupport;
216
217 if (NULL == tlCtxt)
218 {
219 TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,
220 "%s: Invalid TL Context",
221 __FUNCTION__));
222 return;
223 }
224
225 currentHO = &(tlCtxt->hoSupport.currentHOState);
226 hoSupport = &(tlCtxt->hoSupport);
227
228
229 for(idx = 0; idx < currentHO->numThreshold; idx++)
230 {
231 if(idx == currentHO->regionNumber)
232 {
233 regionFound = VOS_TRUE;
234 if(VOS_TRUE == tlCtxt->isBMPS)
235 {
236 TLLOG1(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO," ----> CRegion %d, hRSSI:NA, BMPS, Alpha %d",
237 currentHO->regionNumber, currentHO->alpha));
238 }
239 else
240 {
241 TLLOG1(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO," ----> CRegion %d, hRSSI %d, Alpha %d",
242 currentHO->regionNumber,
243 currentHO->historyRSSI,
244 currentHO->alpha));
245 }
246 }
247 for(sIdx = 0; sIdx < WLANTL_HS_NUM_CLIENT; sIdx++)
248 {
249 if(NULL != hoSupport->registeredInd[idx].crossCBFunction[sIdx])
250 {
251 if(VOS_MODULE_ID_HDD == hoSupport->registeredInd[idx].whoIsClient[sIdx])
252 {
253 TLLOG1(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO,"Client HDD pCB %p, triggerEvt %d, RSSI %d",
254 hoSupport->registeredInd[idx].crossCBFunction[sIdx],
255 hoSupport->registeredInd[idx].triggerEvent[sIdx],
256 hoSupport->registeredInd[idx].rssiValue));
257 }
258 else
259 {
260 TLLOG1(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO,"Client SME pCB %p, triggerEvt %d, RSSI %d",
261 hoSupport->registeredInd[idx].crossCBFunction[sIdx],
262 hoSupport->registeredInd[idx].triggerEvent[sIdx],
263 hoSupport->registeredInd[idx].rssiValue));
264 }
265 }
266 }
267 }
268
269 if(VOS_FALSE == regionFound)
270 {
271 if(VOS_TRUE == tlCtxt->isBMPS)
272 {
273 TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR," ----> CRegion %d, hRSSI:NA, BMPS, Alpha %d",
274 currentHO->regionNumber, currentHO->alpha));
275 }
276 else
277 {
278 TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR," ----> CRegion %d, hRSSI %d, Alpha %d",
279 currentHO->regionNumber,
280 currentHO->historyRSSI,
281 currentHO->alpha));
282 }
283 }
284
285 return;
286}
287
288/*==========================================================================
289
290 FUNCTION
291
292 DESCRIPTION
293
294 PARAMETERS
295
296 RETURN VALUE
297
298============================================================================*/
299VOS_STATUS WLANTL_SetFWRSSIThresholds
300(
301 v_PVOID_t pAdapter
302)
303{
304 WLANTL_CbType *tlCtxt = VOS_GET_TL_CB(pAdapter);
305 VOS_STATUS status = VOS_STATUS_SUCCESS;
306 WLANTL_HO_SUPPORT_TYPE *hoSupport;
307 WLANTL_CURRENT_HO_STATE_TYPE *currentHO;
308 tSirRSSIThresholds bmpsThresholds;
309 WLANTL_HSTempPSIndType tempIndSet[WLANTL_SINGLE_CLNT_THRESHOLD];
310 v_U8_t bmpsLoop;
311 v_U8_t bmpsInd;
312 v_U8_t clientLoop;
313
314 if(NULL == tlCtxt)
315 {
316 TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"Invalid TL handle"));
317 return VOS_STATUS_E_INVAL;
318 }
319
320 WLANTL_HSDebugDisplay(pAdapter);
321 currentHO = &(tlCtxt->hoSupport.currentHOState);
322 hoSupport = &(tlCtxt->hoSupport);
323
324 memset((v_U8_t *)&tempIndSet[0], 0, WLANTL_SINGLE_CLNT_THRESHOLD * sizeof(WLANTL_HSTempPSIndType));
325 memset(&bmpsThresholds, 0, sizeof(tSirRSSIThresholds));
326
327 bmpsInd = 0;
328 for(bmpsLoop = 0; bmpsLoop < WLANTL_MAX_AVAIL_THRESHOLD; bmpsLoop++)
329 {
330 for(clientLoop = 0; clientLoop < WLANTL_HS_NUM_CLIENT; clientLoop++)
331 {
332 if(0 != hoSupport->registeredInd[bmpsLoop].triggerEvent[clientLoop])
333 {
334 if(bmpsInd == WLANTL_SINGLE_CLNT_THRESHOLD)
335 {
336 TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"Single Client Threshold should be less than %d", WLANTL_SINGLE_CLNT_THRESHOLD));
337 break;
338 }
339 tempIndSet[bmpsInd].rssi = hoSupport->registeredInd[bmpsLoop].rssiValue;
340 tempIndSet[bmpsInd].event = hoSupport->registeredInd[bmpsLoop].triggerEvent[clientLoop];
341 bmpsInd++;
342 break;
343 }
344 }
345 }
346
347 bmpsThresholds.ucRssiThreshold1 = tempIndSet[0].rssi;
348 if((WLANTL_HO_THRESHOLD_DOWN == tempIndSet[0].event) ||
349 (WLANTL_HO_THRESHOLD_CROSS == tempIndSet[0].event))
350 {
351 bmpsThresholds.bRssiThres1NegNotify = 1;
352 }
353 if((WLANTL_HO_THRESHOLD_UP == tempIndSet[0].event) ||
354 (WLANTL_HO_THRESHOLD_CROSS == tempIndSet[0].event))
355 {
356 bmpsThresholds.bRssiThres1PosNotify = 1;
357 }
358
359 bmpsThresholds.ucRssiThreshold2 = tempIndSet[1].rssi;
360 if((WLANTL_HO_THRESHOLD_DOWN == tempIndSet[1].event) ||
361 (WLANTL_HO_THRESHOLD_CROSS == tempIndSet[1].event))
362 {
363 bmpsThresholds.bRssiThres2NegNotify = 1;
364 }
365 if((WLANTL_HO_THRESHOLD_UP == tempIndSet[1].event) ||
366 (WLANTL_HO_THRESHOLD_CROSS == tempIndSet[1].event))
367 {
368 bmpsThresholds.bRssiThres2PosNotify = 1;
369 }
370
371 bmpsThresholds.ucRssiThreshold3 = tempIndSet[2].rssi;
372 if((WLANTL_HO_THRESHOLD_DOWN == tempIndSet[2].event) ||
373 (WLANTL_HO_THRESHOLD_CROSS == tempIndSet[2].event))
374 {
375 bmpsThresholds.bRssiThres3NegNotify = 1;
376 }
377 if((WLANTL_HO_THRESHOLD_UP == tempIndSet[2].event) ||
378 (WLANTL_HO_THRESHOLD_CROSS == tempIndSet[2].event))
379 {
380 bmpsThresholds.bRssiThres3PosNotify = 1;
381 }
382
383 WDA_SetRSSIThresholds(hoSupport->macCtxt, &bmpsThresholds);
384 return status;
385}
386
387/*==========================================================================
388
389 FUNCTION
390
391 DESCRIPTION
392
393 PARAMETERS
394
395 RETURN VALUE
396
397============================================================================*/
398VOS_STATUS WLANTL_StatHandleRXFrame
399(
400 v_PVOID_t pAdapter,
401 v_PVOID_t pBDHeader,
402 v_U8_t STAid,
403 v_BOOL_t isBroadcast,
404 vos_pkt_t *dataBuffer
405)
406{
407 WLANTL_CbType *tlCtxt = VOS_GET_TL_CB(pAdapter);
408 VOS_STATUS status = VOS_STATUS_SUCCESS;
409 WLANTL_TRANSFER_STA_TYPE *statistics;
410 v_U16_t packetSize;
411
412 if(NULL == tlCtxt)
413 {
414 TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"Invalid TL handle"));
415 return VOS_STATUS_E_INVAL;
416 }
417
418 if(NULL == dataBuffer)
419 {
420 TLLOG1(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO,"Management Frame, not need to handle with Stat"));
421 return status;
422 }
423
424 if(0 == tlCtxt->atlSTAClients[STAid].ucExists)
425 {
426 TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"WLAN TL: %d STA ID is not exist", STAid));
427 return VOS_STATUS_E_INVAL;
428 }
429
430 /* TODO : BC/MC/UC have to be determined by MAC address */
431 statistics = &tlCtxt->atlSTAClients[STAid].trafficStatistics;
432 vos_pkt_get_packet_length(dataBuffer, &packetSize);
433 if(WDA_IS_RX_BCAST(pBDHeader))
434 {
435 TLLOG1(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO,"This is RX BC/MC frame"));
436 if(VOS_FALSE == isBroadcast)
437 {
438 TLLOG1(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO,"This is RX BC frame"));
439 statistics->rxBCFcnt++;
440 statistics->rxBCBcnt += (packetSize - WLANHAL_RX_BD_HEADER_SIZE);
441 }
442 else
443 {
444 TLLOG1(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO,"This is RX MC frame"));
445 statistics->rxMCFcnt++;
446 statistics->rxMCBcnt += (packetSize - WLANHAL_RX_BD_HEADER_SIZE);
447 }
448 }
449 else
450 {
451 TLLOG1(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO,"This is RX UC frame"));
452 statistics->rxUCFcnt++;
453 statistics->rxUCBcnt += (packetSize - WLANHAL_RX_BD_HEADER_SIZE);
454 }
455
456 /* TODO caculation is needed, dimension of 500kbps */
457 statistics->rxRate = WDA_GET_RX_MAC_RATE_IDX(pBDHeader);
458 statistics->rxBcnt += (packetSize - WLANHAL_RX_BD_HEADER_SIZE);
459
460#ifdef WLANTL_HO_DEBUG_MSG
461 WLANTL_StatDebugDisplay(STAid, statistics);
462#endif /* WLANTL_HO_DEBUG_MSG */
463
464 return status;
465}
466
467/*==========================================================================
468
469 FUNCTION
470
471 DESCRIPTION
472
473 PARAMETERS
474
475 RETURN VALUE
476
477============================================================================*/
478VOS_STATUS WLANTL_StatHandleTXFrame
479(
480 v_PVOID_t pAdapter,
481 v_U8_t STAid,
482 vos_pkt_t *dataBuffer,
483 v_PVOID_t pBDHeader
484)
485{
486 WLANTL_CbType *tlCtxt = VOS_GET_TL_CB(pAdapter);
487 VOS_STATUS status = VOS_STATUS_SUCCESS;
488 WLANTL_TRANSFER_STA_TYPE *statistics;
489 v_U16_t packetSize;
490
491 if((NULL == tlCtxt) || (NULL == dataBuffer))
492 {
493 TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"Invalid TL handle"));
494 return VOS_STATUS_E_INVAL;
495 }
496
497 if(0 == tlCtxt->atlSTAClients[STAid].ucExists)
498 {
499 TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"WLAN TL: %d STA ID is not exist", STAid));
500 return VOS_STATUS_E_INVAL;
501 }
502
503 /* TODO : BC/MC/UC have to be determined by MAC address */
504 statistics = &tlCtxt->atlSTAClients[STAid].trafficStatistics;
505 vos_pkt_get_packet_length(dataBuffer, &packetSize);
506 if(WLANTL_STA_ID_BCAST == STAid)
507 {
508 TLLOG1(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO,"This TX is BC frame"));
509 statistics->txBCFcnt++;
510 statistics->txBCBcnt += (packetSize - WLANHAL_TX_BD_HEADER_SIZE);
511 }
512/*
513 if(WLANHAL_TX_BD_GET_UB(pBDHeader))
514 {
515 TLLOG1(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO,"This TX is BC/MC frame"));
516 if(WLANTL_STA_ID_BCAST == STAid)
517 {
518 TLLOG1(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO,"This TX is BC frame"));
519 statistics->txBCFcnt++;
520 statistics->txBCBcnt += (packetSize - WLANHAL_TX_BD_HEADER_SIZE);
521 }
522 else
523 {
524 TLLOG1(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO,"This TX is MC frame"));
525 statistics->txMCFcnt++;
526 statistics->txMCBcnt += (packetSize - WLANHAL_RX_BD_HEADER_SIZE);
527 }
528 }
529*/
530 else
531 {
532 TLLOG1(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO,"This is TX UC frame"));
533 statistics->txUCFcnt++;
534 statistics->txUCBcnt += (packetSize - WLANHAL_RX_BD_HEADER_SIZE);
535 }
536
537#ifdef WLANTL_HO_DEBUG_MSG
538 WLANTL_StatDebugDisplay(STAid, statistics);
539#endif /* WLANTL_HO_DEBUG_MSG */
540
541 return status;
542}
543
544/*==========================================================================
545
546 FUNCTION WLANTL_HSTrafficStatusTimerExpired
547
548 DESCRIPTION If traffic status monitoring timer is expiered,
549 Count how may frames have sent and received during
550 measure period and if traffic status is changed
551 send notification to Client(SME)
552
553 PARAMETERS pAdapter
554 Global handle
555
556 RETURN VALUE
557
558============================================================================*/
559v_VOID_t WLANTL_HSTrafficStatusTimerExpired
560(
561 v_PVOID_t pAdapter
562)
563{
564 WLANTL_CbType *tlCtxt = VOS_GET_TL_CB(pAdapter);
565 WLANTL_HO_TRAFFIC_STATUS_HANDLE_TYPE *trafficHandle = NULL;
566 WLANTL_HO_TRAFFIC_STATUS_TYPE newTraffic;
567 v_U32_t rtFrameCount;
568 v_U32_t nrtFrameCount;
569 v_BOOL_t trafficStatusChanged = VOS_FALSE;
570
571 if(NULL == tlCtxt)
572 {
573 TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"Invalid TL handle"));
574 return;
575 }
576
577 /* Get rt and nrt frame count sum */
578 trafficHandle = &tlCtxt->hoSupport.currentTraffic;
579 rtFrameCount = trafficHandle->rtRXFrameCount + trafficHandle->rtTXFrameCount;
580 nrtFrameCount = trafficHandle->nrtRXFrameCount + trafficHandle->nrtTXFrameCount;
581
582 TLLOG1(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO,"Traffic status timer expired RT FC %d, NRT FC %d", rtFrameCount, nrtFrameCount));
583
584 /* Get current traffic status */
585 if(rtFrameCount > trafficHandle->idleThreshold)
586 {
587 newTraffic.rtTrafficStatus = WLANTL_HO_RT_TRAFFIC_STATUS_ON;
588 }
589 else
590 {
591 newTraffic.rtTrafficStatus = WLANTL_HO_RT_TRAFFIC_STATUS_OFF;
592 }
593
594 if(nrtFrameCount > trafficHandle->idleThreshold)
595 {
596 newTraffic.nrtTrafficStatus = WLANTL_HO_NRT_TRAFFIC_STATUS_ON;
597 }
598 else
599 {
600 newTraffic.nrtTrafficStatus = WLANTL_HO_NRT_TRAFFIC_STATUS_OFF;
601 }
602
603 /* Differentiate with old traffic status */
604 if(trafficHandle->trafficStatus.rtTrafficStatus != newTraffic.rtTrafficStatus)
605 {
606 TLLOGW(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_WARN,"RT Traffic status changed from %d to %d",
607 trafficHandle->trafficStatus.rtTrafficStatus,
608 newTraffic.rtTrafficStatus));
609 trafficStatusChanged = VOS_TRUE;
610 }
611 if(trafficHandle->trafficStatus.nrtTrafficStatus != newTraffic.nrtTrafficStatus)
612 {
613 TLLOGW(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_WARN,"NRT Traffic status changed from %d to %d",
614 trafficHandle->trafficStatus.nrtTrafficStatus,
615 newTraffic.nrtTrafficStatus));
616 trafficStatusChanged = VOS_TRUE;
617 }
618
619 /* If traffic status is changed send notification to client */
620 if((VOS_TRUE == trafficStatusChanged) && (NULL != trafficHandle->trafficCB))
621 {
622 trafficHandle->trafficCB(pAdapter, newTraffic, trafficHandle->usrCtxt);
623 trafficHandle->trafficStatus.rtTrafficStatus = newTraffic.rtTrafficStatus;
624 trafficHandle->trafficStatus.nrtTrafficStatus = newTraffic.nrtTrafficStatus;
625 }
626 else if((VOS_TRUE == trafficStatusChanged) && (NULL == trafficHandle->trafficCB))
627 {
628 TLLOGW(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_WARN,"Traffic status is changed but not need to report"));
629 }
630
631 /* Reset frame counters */
632 trafficHandle->rtRXFrameCount = 0;
633 trafficHandle->rtTXFrameCount = 0;
634 trafficHandle->nrtRXFrameCount = 0;
635 trafficHandle->nrtTXFrameCount = 0;
636
637 if(NULL != trafficHandle->trafficCB)
638 {
639 /* restart timer only when the callback is not NULL */
640 vos_timer_start(&trafficHandle->trafficTimer, trafficHandle->measurePeriod);
641 }
642
643 return;
644}
645
646
647/*==========================================================================
648
649 FUNCTION
650
651 DESCRIPTION
652
653 PARAMETERS
654
655 RETURN VALUE
656
657============================================================================*/
658VOS_STATUS WLANTL_HSGetRSSI
659(
660 v_PVOID_t pAdapter,
661 v_PVOID_t pBDHeader,
662 v_U8_t STAid,
663 v_S7_t *currentAvgRSSI
664)
665{
666 WLANTL_CbType *tlCtxt = VOS_GET_TL_CB(pAdapter);
667 VOS_STATUS status = VOS_STATUS_SUCCESS;
668 v_S7_t currentRSSI, currentRSSI0, currentRSSI1;
669 WLANTL_CURRENT_HO_STATE_TYPE *currentHO = NULL;
670
671
672 if(NULL == tlCtxt)
673 {
674 TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"Invalid TL handle"));
675 return VOS_STATUS_E_INVAL;
676 }
677
678 /*
679 Compute RSSI only for the last MPDU of an AMPDU.
680 Only last MPDU carries the Phy Stats Values
681 */
682 if (WDA_IS_RX_AN_AMPDU (pBDHeader)) {
683 if (!WDA_IS_RX_LAST_MPDU(pBDHeader)) {
684 return VOS_STATUS_E_FAILURE;
685 }
686 }
687
688 currentHO = &tlCtxt->hoSupport.currentHOState;
689
690 currentRSSI0 = WLANTL_GETRSSI0(pBDHeader);
691 currentRSSI1 = WLANTL_GETRSSI0(pBDHeader);
692 currentRSSI = (currentRSSI0 > currentRSSI1) ? currentRSSI0 : currentRSSI1;
693
694 if (0 == currentRSSI)
695 return VOS_STATUS_E_INVAL;
696
697#ifdef WLANTL_HO_UTEST
698 TLHS_UtestHandleNewRSSI(&currentRSSI, pAdapter);
699#endif /* WLANTL_HO_UTEST */
700
701/* Commenting this part of the code as this may not be necessarity true in all cases */
702#if 0
703 if(WLANTL_HO_INVALID_RSSI == currentRSSI)
704 {
705 return status;
706 }
707#endif
708
709 if(0 == currentHO->historyRSSI)
710 {
711 *currentAvgRSSI = currentRSSI;
712 }
713 else
714 {
715 *currentAvgRSSI = ((currentHO->historyRSSI * currentHO->alpha) +
716 (currentRSSI * (10 - currentHO->alpha))) / 10;
717 }
718#ifdef RSSI_HACK
719 *currentAvgRSSI = (v_S7_t)dumpCmdRSSI;
720#endif
721
722
723 tlCtxt->atlSTAClients[STAid].rssiAvg = *currentAvgRSSI;
724
725 TLLOG1(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO,"Current new RSSI is %d, averaged RSSI is %d", currentRSSI, *currentAvgRSSI));
726 return status;
727}
728
729/*==========================================================================
730
731 FUNCTION
732
733 DESCRIPTION
734
735 PARAMETERS
736
737 RETURN VALUE
738
739============================================================================*/
740VOS_STATUS WLANTL_HSBMPSRSSIRegionChangedNotification
741(
742 v_PVOID_t pAdapter,
743 tpSirRSSINotification pRSSINotification
744)
745{
746 WLANTL_CbType *tlCtxt = VOS_GET_TL_CB(pAdapter);
747 VOS_STATUS status = VOS_STATUS_SUCCESS;
748 WLANTL_CURRENT_HO_STATE_TYPE *currentHO;
749 WLANTL_HO_SUPPORT_TYPE *hoSupport;
750 WLANTL_RSSICrossThresholdCBType cbFunction = NULL;
751 v_PVOID_t usrCtxt = NULL;
752 v_U8_t evtType = WLANTL_HO_THRESHOLD_NA;
753 v_U32_t preFWNotification = 0;
754 v_U32_t curFWNotification = 0;
755 v_U8_t newRegionNumber = 0;
756 v_U8_t pRegionNumber = 0, nRegionNumber = 0;
757 v_U32_t isSet;
758 v_U8_t idx, sIdx;
759
760 if(NULL == tlCtxt)
761 {
762 TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"Invalid TL handle"));
763 return VOS_STATUS_E_INVAL;
764 }
765
766 if(NULL == pRSSINotification)
767 {
768 TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"Invalid FW RSSI Notification"));
769 VOS_ASSERT(0);
770 return VOS_STATUS_E_INVAL;
771 }
772
773 currentHO = &(tlCtxt->hoSupport.currentHOState);
774 hoSupport = &(tlCtxt->hoSupport);
775 preFWNotification = currentHO->fwNotification;
776
777 isSet = pRSSINotification->bRssiThres1PosCross;
778 curFWNotification |= isSet << 5;
779 isSet = pRSSINotification->bRssiThres2PosCross;
780 curFWNotification |= isSet << 4;
781 isSet = pRSSINotification->bRssiThres3PosCross;
782 curFWNotification |= isSet << 3;
783 isSet = pRSSINotification->bRssiThres1NegCross;
784 curFWNotification |= isSet << 2;
785 isSet = pRSSINotification->bRssiThres2NegCross;
786 curFWNotification |= isSet << 1;
787 isSet = pRSSINotification->bRssiThres3NegCross;
788 curFWNotification |= isSet;
789 TLLOG1(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO,"Current FW Notification is 0x%x", (v_U32_t)curFWNotification ));
790
791 currentHO->fwNotification = curFWNotification;
792
793 if(0 == preFWNotification)
794 {
795 TLLOG1(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO,"This is the first time notification from FW Value is 0x%x", curFWNotification));
796 preFWNotification = curFWNotification;
797 }
798 else if(preFWNotification == curFWNotification)
799 {
800 return status;
801 }
802
803 if(1 == pRSSINotification->bRssiThres1PosCross)
804 {
805 TLLOG1(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO,"POS Cross to Region 0"));
806 pRegionNumber = 0;
807 }
808 else if(1 == pRSSINotification->bRssiThres2PosCross)
809 {
810 TLLOG1(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO,"POS Cross to Region 1"));
811 pRegionNumber = 1;
812 }
813 else if(1 == pRSSINotification->bRssiThres3PosCross)
814 {
815 TLLOG1(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO,"POS Cross to Region 2"));
816 pRegionNumber = 2;
817 }
818
819 if(1 == pRSSINotification->bRssiThres3NegCross)
820 {
821 TLLOG1(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO,"NEG Cross to Region 3"));
822 nRegionNumber = 3;
823 }
824 else if(1 == pRSSINotification->bRssiThres2NegCross)
825 {
826 TLLOG1(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO,"NEG Cross to Region 2"));
827 nRegionNumber = 2;
828 }
829 else if(1 == pRSSINotification->bRssiThres1NegCross)
830 {
831 TLLOG1(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO,"NEG Cross to Region 1"));
832 nRegionNumber = 1;
833 }
834
835
836 newRegionNumber = (nRegionNumber > pRegionNumber) ? nRegionNumber : pRegionNumber;
837 if((currentHO->regionNumber) && (newRegionNumber == currentHO->regionNumber))
838 {
839 TLLOG1(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO,"No Region Change with BMPS mode"));
840 preFWNotification = curFWNotification;
841 return status;
842 }
843 else if(newRegionNumber > currentHO->regionNumber)
844 {
845 TLLOG1(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO,"Region Increase Worse RSSI"));
846 for(idx = currentHO->regionNumber; idx < newRegionNumber; idx++)
847 {
848 for(sIdx = 0; sIdx < WLANTL_HS_NUM_CLIENT; sIdx++)
849 {
850 if((WLANTL_HO_THRESHOLD_DOWN == hoSupport->registeredInd[idx].triggerEvent[sIdx]) ||
851 (WLANTL_HO_THRESHOLD_CROSS == hoSupport->registeredInd[idx].triggerEvent[sIdx]))
852 {
853 if(NULL != hoSupport->registeredInd[idx].crossCBFunction[sIdx])
854 {
855 cbFunction = hoSupport->registeredInd[idx].crossCBFunction[sIdx];
856 usrCtxt = hoSupport->registeredInd[idx].usrCtxt[sIdx];
857 evtType = WLANTL_HO_THRESHOLD_DOWN;
858 TLLOG1(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO,"Trigger Event %d, region index %d", hoSupport->registeredInd[idx].triggerEvent[sIdx], idx));
859 currentHO->regionNumber = newRegionNumber;
860 status = cbFunction(pAdapter, evtType, usrCtxt);
861 }
862 }
863 }
864 }
865 }
866 else
867 {
868 TLLOG1(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO,"Region Decrease Better RSSI"));
869 idx = (currentHO->regionNumber)?(currentHO->regionNumber-1):0;
870 while (idx >= newRegionNumber)
871 {
872 for(sIdx = 0; sIdx < WLANTL_HS_NUM_CLIENT; sIdx++)
873 {
874 if((WLANTL_HO_THRESHOLD_UP & hoSupport->registeredInd[idx].triggerEvent[sIdx]) ||
875 (WLANTL_HO_THRESHOLD_CROSS & hoSupport->registeredInd[idx].triggerEvent[sIdx]))
876 {
877 if(NULL != hoSupport->registeredInd[idx].crossCBFunction[sIdx])
878 {
879 cbFunction = hoSupport->registeredInd[idx].crossCBFunction[sIdx];
880 usrCtxt = hoSupport->registeredInd[idx].usrCtxt[sIdx];
881 evtType = WLANTL_HO_THRESHOLD_UP;
882 TLLOG1(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO,"Trigger Event %d, region index %d", hoSupport->registeredInd[idx].triggerEvent[sIdx], idx));
883 currentHO->regionNumber = newRegionNumber;
884 status = cbFunction(pAdapter, evtType, usrCtxt);
885 }
886 }
887 }
888 if (!idx--)
889 break;
890 }
891 }
892
893 TLLOG1(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO,"BMPS State, MSG from FW, Trigger Event %d, region index %d",
894 evtType, currentHO->regionNumber));
895
896 return VOS_STATUS_SUCCESS;
897}
898
899/*==========================================================================
900
901 FUNCTION
902
903 DESCRIPTION
904
905 PARAMETERS
906
907 RETURN VALUE
908
909============================================================================*/
910VOS_STATUS WLANTL_HSHandleRSSIChange
911(
912 v_PVOID_t pAdapter,
913 v_S7_t currentRSSI
914)
915{
916 WLANTL_CbType *tlCtxt = VOS_GET_TL_CB(pAdapter);
917 VOS_STATUS status = VOS_STATUS_SUCCESS;
918 v_U8_t currentRegion = 0;
919 v_U8_t idx, sIdx;
920 WLANTL_CURRENT_HO_STATE_TYPE *currentHO;
921 WLANTL_HO_SUPPORT_TYPE *hoSupport;
922 WLANTL_RSSICrossThresholdCBType cbFunction = NULL;
923 v_PVOID_t usrCtxt = NULL;
924 v_U8_t evtType = WLANTL_HO_THRESHOLD_NA;
925
926 if(NULL == tlCtxt)
927 {
928 TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"Invalid TL handle"));
929 return VOS_STATUS_E_INVAL;
930 }
931
932 currentHO = &(tlCtxt->hoSupport.currentHOState);
933 hoSupport = &(tlCtxt->hoSupport);
934 TLLOG1(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO,"CRegion %d, NThreshold %d, HRSSI %d",
935 currentHO->regionNumber,
936 currentHO->numThreshold,
937 currentHO->historyRSSI));
938
939 /* Find where is current region */
940 for(idx = 0; idx < currentHO->numThreshold; idx++)
941 {
942 if(hoSupport->registeredInd[idx].rssiValue < currentRSSI)
943 {
944 currentRegion = idx;
945 TLLOG1(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO,"Found region %d, not bottom", currentRegion));
946 break;
947 }
948 }
949
950 /* If could not find then new RSSI is belong to bottom region */
951 if(idx == currentHO->numThreshold)
952 {
953 currentRegion = idx;
954 TLLOG1(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO,"Current region is bottom %d", idx));
955 }
956
957 /* This is a hack. Actual assignment was happening after the below checks. This hack is needed till TL
958 posts message and nothing else in the callback indicating UP/DOWN event to the registered module */
959 currentHO->historyRSSI = currentRSSI;
960
961 if(currentRegion == currentHO->regionNumber)
962 {
963 currentHO->historyRSSI = currentRSSI;
964 return status;
965 }
966 else if(currentRegion > currentHO->regionNumber)
967 {
968 TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"Region Increase Worse RSSI"));
969 for(idx = currentHO->regionNumber; idx < currentRegion; idx++)
970 {
971 for(sIdx = 0; sIdx < WLANTL_HS_NUM_CLIENT; sIdx++)
972 {
973 if((WLANTL_HO_THRESHOLD_DOWN == hoSupport->registeredInd[idx].triggerEvent[sIdx]) ||
974 (WLANTL_HO_THRESHOLD_CROSS == hoSupport->registeredInd[idx].triggerEvent[sIdx]))
975 {
976 if(NULL != hoSupport->registeredInd[idx].crossCBFunction[sIdx])
977 {
978 cbFunction = hoSupport->registeredInd[idx].crossCBFunction[sIdx];
979 usrCtxt = hoSupport->registeredInd[idx].usrCtxt[sIdx];
980 evtType = WLANTL_HO_THRESHOLD_DOWN;
981 TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"Trigger Event %d, region index %d", hoSupport->registeredInd[idx].triggerEvent[sIdx], idx));
982 status = cbFunction(pAdapter, evtType, usrCtxt);
983 }
984 }
985 }
986 }
987 }
988 else
989 {
990 TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"Region Decrease Better RSSI"));
991 for(idx = currentHO->regionNumber; idx > currentRegion; idx--)
992 {
993 for(sIdx = 0; sIdx < WLANTL_HS_NUM_CLIENT; sIdx++)
994 {
995 if((WLANTL_HO_THRESHOLD_UP & hoSupport->registeredInd[idx - 1].triggerEvent[sIdx]) ||
996 (WLANTL_HO_THRESHOLD_CROSS & hoSupport->registeredInd[idx - 1].triggerEvent[sIdx]))
997 {
998 if(NULL != hoSupport->registeredInd[idx - 1].crossCBFunction[sIdx])
999 {
1000 cbFunction = hoSupport->registeredInd[idx - 1].crossCBFunction[sIdx];
1001 usrCtxt = hoSupport->registeredInd[idx - 1].usrCtxt[sIdx];
1002 evtType = WLANTL_HO_THRESHOLD_UP;
1003 TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"Trigger Event %d, region index %d", hoSupport->registeredInd[idx - 1].triggerEvent[sIdx], idx - 1));
1004 status = cbFunction(pAdapter, evtType, usrCtxt);
1005 }
1006 }
1007 }
1008 }
1009 }
1010
1011 currentHO->historyRSSI = currentRSSI;
1012 currentHO->regionNumber = currentRegion;
1013 WLANTL_HSDebugDisplay(pAdapter);
1014
1015 if(!VOS_IS_STATUS_SUCCESS(status))
1016 {
1017 TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"Client fail to handle region change in normal mode %d", status));
1018 }
1019 return VOS_STATUS_SUCCESS;
1020}
1021
1022/*==========================================================================
1023
1024 FUNCTION
1025
1026 DESCRIPTION
1027
1028 PARAMETERS
1029
1030 RETURN VALUE
1031
1032============================================================================*/
1033VOS_STATUS WLANTL_HSHandleRXFrame
1034(
1035 v_PVOID_t pAdapter,
1036 v_U8_t frameType,
1037 v_PVOID_t pBDHeader,
1038 v_U8_t STAid,
1039 v_BOOL_t isBroadcast,
1040 vos_pkt_t *dataBuffer
1041)
1042{
1043 WLANTL_CURRENT_HO_STATE_TYPE *currentHO = NULL;
1044 WLANTL_CbType *tlCtxt = VOS_GET_TL_CB(pAdapter);
1045 VOS_STATUS status = VOS_STATUS_SUCCESS;
1046 v_S7_t currentAvgRSSI = 0;
1047 v_U8_t ac;
1048 v_U32_t currentTimestamp;
1049 v_U8_t tid;
1050
1051 if(NULL == tlCtxt)
1052 {
1053 TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"Invalid TL handle"));
1054 return VOS_STATUS_E_INVAL;
1055 }
1056
1057 WLANTL_StatHandleRXFrame(pAdapter, pBDHeader, STAid, isBroadcast, dataBuffer);
1058
1059 /* If this frame is not management frame increase frame count */
1060 if((0 != tlCtxt->hoSupport.currentTraffic.idleThreshold) &&
1061 (WLANTL_MGMT_FRAME_TYPE != frameType))
1062 {
1063 tid = WDA_GET_RX_TID( pBDHeader );
1064 ac = WLANTL_HO_TID_2_AC[(v_U8_t)tid];
1065
1066 /* Only Voice traffic is handled as real time traffic */
1067 if(WLANTL_AC_VO == ac)
1068 {
1069 tlCtxt->hoSupport.currentTraffic.rtRXFrameCount++;
1070 }
1071 else
1072 {
1073 tlCtxt->hoSupport.currentTraffic.nrtRXFrameCount++;
1074 }
1075 TLLOG1(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO,"RX frame AC %d, RT Frame Count %d, NRT Frame Count %d",
1076 ac,
1077 tlCtxt->hoSupport.currentTraffic.rtRXFrameCount,
1078 tlCtxt->hoSupport.currentTraffic.nrtRXFrameCount));
1079 }
1080
1081 currentHO = &tlCtxt->hoSupport.currentHOState;
1082 if(VOS_TRUE == tlCtxt->isBMPS)
1083 {
1084 WLANTL_HSGetRSSI(pAdapter, pBDHeader, STAid, &currentAvgRSSI);
1085 return status;
1086 }
1087
1088 currentTimestamp = WDA_GET_RX_TIMESTAMP(pBDHeader);
1089 if((currentTimestamp - currentHO->sampleTime) < WLANTL_HO_SAMPLING_PERIOD)
1090 {
1091 return status;
1092 }
1093 currentHO->sampleTime = currentTimestamp;
1094
1095 /* If any threshold is not registerd, DO NOTHING! */
1096 if(0 == tlCtxt->hoSupport.currentHOState.numThreshold)
1097 {
1098 TLLOG1(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO,"There is no thresholds pass"));
1099 }
1100 else
1101 {
1102 /* Get Current RSSI from BD Heaser */
1103 status = WLANTL_HSGetRSSI(pAdapter, pBDHeader, STAid, &currentAvgRSSI);
1104 if(!VOS_IS_STATUS_SUCCESS(status))
1105 {
1106 TLLOG1(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO,"Get RSSI Fail"));
1107 return status;
1108 }
1109 /* Handle current RSSI value, region, notification, etc */
1110 status = WLANTL_HSHandleRSSIChange(pAdapter, currentAvgRSSI);
1111 if(!VOS_IS_STATUS_SUCCESS(status))
1112 {
1113 TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"Handle new RSSI fail"));
1114 return status;
1115 }
1116 }
1117
1118 return status;
1119}
1120
1121/*==========================================================================
1122
1123 FUNCTION
1124
1125 DESCRIPTION
1126
1127 PARAMETERS
1128
1129 RETURN VALUE
1130
1131============================================================================*/
1132VOS_STATUS WLANTL_HSHandleTXFrame
1133(
1134 v_PVOID_t pAdapter,
1135 v_U8_t ac,
1136 v_U8_t STAid,
1137 vos_pkt_t *dataBuffer,
1138 v_PVOID_t bdHeader
1139)
1140{
1141 WLANTL_CbType *tlCtxt = VOS_GET_TL_CB(pAdapter);
1142 VOS_STATUS status = VOS_STATUS_SUCCESS;
1143
1144 if(NULL == tlCtxt)
1145 {
1146 TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"Invalid TL handle"));
1147 return VOS_STATUS_E_INVAL;
1148 }
1149
1150 /* Traffic status report is not registered, JUST DO NOTHING */
1151 if(0 == tlCtxt->hoSupport.currentTraffic.idleThreshold)
1152 {
1153 return VOS_STATUS_SUCCESS;
1154 }
1155
1156 WLANTL_StatHandleTXFrame(pAdapter, STAid, dataBuffer, bdHeader);
1157
1158 /* Only Voice traffic is handled as real time traffic */
1159 if(WLANTL_AC_VO == ac)
1160 {
1161 tlCtxt->hoSupport.currentTraffic.rtTXFrameCount++;
1162 }
1163 else
1164 {
1165 tlCtxt->hoSupport.currentTraffic.nrtTXFrameCount++;
1166 }
1167 TLLOG1(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO,"TX frame AC %d, RT Frame Count %d, NRT Frame Count %d",
1168 ac,
1169 tlCtxt->hoSupport.currentTraffic.rtTXFrameCount,
1170 tlCtxt->hoSupport.currentTraffic.nrtTXFrameCount));
1171
1172 return status;
1173}
1174
1175/*==========================================================================
1176
1177 FUNCTION
1178
1179 DESCRIPTION
1180
1181 PARAMETERS
1182
1183 RETURN VALUE
1184
1185============================================================================*/
1186VOS_STATUS WLANTL_HSRegRSSIIndicationCB
1187(
1188 v_PVOID_t pAdapter,
1189 v_S7_t rssiValue,
1190 v_U8_t triggerEvent,
1191 WLANTL_RSSICrossThresholdCBType crossCBFunction,
1192 VOS_MODULE_ID moduleID,
1193 v_PVOID_t usrCtxt
1194)
1195{
1196 WLANTL_CbType *tlCtxt = VOS_GET_TL_CB(pAdapter);
1197 VOS_STATUS status = VOS_STATUS_SUCCESS;
1198 v_U8_t idx, sIdx;
1199 WLANTL_HO_SUPPORT_TYPE *hoSupport;
1200 WLANTL_CURRENT_HO_STATE_TYPE *currentHO;
1201 v_U8_t clientOrder = 0;
1202
1203 if(NULL == tlCtxt)
1204 {
1205 TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"Invalid TL handle"));
1206 return VOS_STATUS_E_INVAL;
1207 }
1208
1209 if((-1 < rssiValue) || (NULL == crossCBFunction))
1210 {
1211 TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"Reg Invalid Argument"));
1212 return VOS_STATUS_E_INVAL;
1213 }
1214
1215 THSGETLOCK("WLANTL_HSRegRSSIIndicationCB", &tlCtxt->hoSupport.hosLock);
1216
1217 currentHO = &(tlCtxt->hoSupport.currentHOState);
1218 hoSupport = &(tlCtxt->hoSupport);
1219 TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"Make Registration Module %d, Event %d, RSSI %d", moduleID, triggerEvent, rssiValue));
1220
1221 if((WLANTL_MAX_AVAIL_THRESHOLD < currentHO->numThreshold) ||
1222 (WLANTL_MAX_AVAIL_THRESHOLD == currentHO->numThreshold))
1223 {
1224 TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"No more available slot, please DEL first %d",
1225 currentHO->numThreshold));
1226 THSRELEASELOCK("WLANTL_HSRegRSSIIndicationCB", &tlCtxt->hoSupport.hosLock);
1227 return VOS_STATUS_E_RESOURCES;
1228 }
1229
1230 if(0 == currentHO->numThreshold)
1231 {
1232 TLLOG1(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO,"First Registration"));
1233 hoSupport->registeredInd[0].rssiValue = rssiValue;
1234 hoSupport->registeredInd[0].triggerEvent[0] = triggerEvent;
1235 hoSupport->registeredInd[0].crossCBFunction[0] = crossCBFunction;
1236 hoSupport->registeredInd[0].usrCtxt[0] = usrCtxt;
1237 hoSupport->registeredInd[0].whoIsClient[0] = moduleID;
1238 hoSupport->registeredInd[0].numClient++;
1239 }
1240 else
1241 {
1242 for(idx = 0; idx < currentHO->numThreshold; idx++)
1243 {
1244 if(rssiValue == hoSupport->registeredInd[idx].rssiValue)
1245 {
1246 for(sIdx = 0; sIdx < WLANTL_HS_NUM_CLIENT; sIdx++)
1247 {
1248 TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"Reg CB P 0x%x, registered CB P 0x%x",
1249 crossCBFunction,
1250 hoSupport->registeredInd[idx].crossCBFunction[sIdx]));
1251 if(crossCBFunction == hoSupport->registeredInd[idx].crossCBFunction[sIdx])
1252 {
1253 TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"Same RSSI %d, Same CB 0x%x already registered",
1254 rssiValue, crossCBFunction));
1255 WLANTL_HSDebugDisplay(pAdapter);
1256 THSRELEASELOCK("WLANTL_HSRegRSSIIndicationCB", &tlCtxt->hoSupport.hosLock);
1257 return status;
1258 }
1259 }
1260
1261 for(sIdx = 0; sIdx < WLANTL_HS_NUM_CLIENT; sIdx++)
1262 {
1263 if(NULL == hoSupport->registeredInd[idx].crossCBFunction[sIdx])
1264 {
1265 clientOrder = sIdx;
1266 break;
1267 }
1268 }
1269 hoSupport->registeredInd[idx].triggerEvent[clientOrder] = triggerEvent;
1270 hoSupport->registeredInd[idx].crossCBFunction[clientOrder] = crossCBFunction;
1271 hoSupport->registeredInd[idx].usrCtxt[clientOrder] = usrCtxt;
1272 hoSupport->registeredInd[idx].whoIsClient[clientOrder] = moduleID;
1273 hoSupport->registeredInd[idx].numClient++;
1274 WLANTL_HSDebugDisplay(pAdapter);
1275 THSRELEASELOCK("WLANTL_HSRegRSSIIndicationCB", &tlCtxt->hoSupport.hosLock);
1276 return status;
1277 }
1278 }
1279 for(idx = 0; idx < currentHO->numThreshold; idx++)
1280 {
1281 if(rssiValue > hoSupport->registeredInd[idx].rssiValue)
1282 {
1283 for(sIdx = (currentHO->numThreshold - 1); (sIdx > idx) || (sIdx == idx); sIdx--)
1284 {
1285 TLLOG1(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO, "Shift %d array to %d", sIdx, sIdx + 1));
1286 memcpy(&hoSupport->registeredInd[sIdx + 1], &hoSupport->registeredInd[sIdx], sizeof(WLANTL_HO_RSSI_INDICATION_TYPE));
1287 memset(&hoSupport->registeredInd[sIdx], 0, sizeof(WLANTL_HO_RSSI_INDICATION_TYPE));
1288 if(0 == sIdx)
1289 {
1290 break;
1291 }
1292 }
1293 TLLOG1(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO,"Put in Here %d", idx));
1294 hoSupport->registeredInd[idx].rssiValue = rssiValue;
1295 hoSupport->registeredInd[idx].triggerEvent[0] = triggerEvent;
1296 hoSupport->registeredInd[idx].crossCBFunction[0] = crossCBFunction;
1297 hoSupport->registeredInd[idx].usrCtxt[0] = usrCtxt;
1298 hoSupport->registeredInd[idx].whoIsClient[0] = moduleID;
1299 hoSupport->registeredInd[idx].numClient++;
1300 break;
1301 }
1302 }
1303 if(currentHO->numThreshold == idx)
1304 {
1305 TLLOG1(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO, "New threshold put in bottom"));
1306
1307 hoSupport->registeredInd[currentHO->numThreshold].rssiValue = rssiValue;
1308 hoSupport->registeredInd[currentHO->numThreshold].triggerEvent[0] = triggerEvent;
1309 hoSupport->registeredInd[currentHO->numThreshold].crossCBFunction[0] = crossCBFunction;
1310 hoSupport->registeredInd[currentHO->numThreshold].usrCtxt[0] = usrCtxt;
1311 hoSupport->registeredInd[currentHO->numThreshold].whoIsClient[0] = moduleID;
1312 hoSupport->registeredInd[currentHO->numThreshold].numClient++;
1313 }
1314 }
1315
1316 currentHO->numThreshold++;
1317 if((VOS_FALSE == tlCtxt->isBMPS) && (rssiValue > currentHO->historyRSSI))
1318 {
1319 TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"Added Threshold above current RSSI level, old RN %d", currentHO->regionNumber));
1320 if(4 > currentHO->regionNumber)
1321 {
1322 currentHO->regionNumber++;
1323 }
1324 else
1325 {
1326 TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"Current region number is max %d, cannot increase anymore", currentHO->regionNumber));
1327 }
1328 TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"increase region number without notification %d", currentHO->regionNumber));
1329 }
1330 else if(VOS_TRUE == tlCtxt->isBMPS)
1331 {
1332 if(0 != currentHO->regionNumber)
1333 {
1334 if(hoSupport->registeredInd[currentHO->regionNumber].rssiValue < rssiValue)
1335 {
1336 currentHO->regionNumber++;
1337 if((WLANTL_HO_THRESHOLD_DOWN == triggerEvent) || (WLANTL_HO_THRESHOLD_CROSS == triggerEvent))
1338 {
1339 TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"Registered RSSI value larger than Current RSSI, and DOWN event, Send Notification"));
1340 crossCBFunction(pAdapter, WLANTL_HO_THRESHOLD_DOWN, usrCtxt);
1341 }
1342 }
1343 else if((currentHO->regionNumber < (currentHO->numThreshold - 1)) &&
1344 (hoSupport->registeredInd[currentHO->regionNumber + 1].rssiValue > rssiValue))
1345 {
1346 if((WLANTL_HO_THRESHOLD_UP == triggerEvent) || (WLANTL_HO_THRESHOLD_CROSS == triggerEvent))
1347 {
1348 TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"Registered RSSI value smaller than Current RSSI"));
1349 }
1350 }
1351 }
1352 else
1353 {
1354 if(hoSupport->registeredInd[currentHO->regionNumber].rssiValue > rssiValue)
1355 {
1356 if((WLANTL_HO_THRESHOLD_UP == triggerEvent) || (WLANTL_HO_THRESHOLD_CROSS == triggerEvent))
1357 {
1358 TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"Registered RSSI value smaller than Current RSSI"));
1359 }
1360 }
1361 }
1362 }
1363
1364 if((VOS_FALSE == tlCtxt->isBMPS) &&
1365 (rssiValue >= currentHO->historyRSSI) && (0 != currentHO->historyRSSI) &&
1366 ((WLANTL_HO_THRESHOLD_DOWN == triggerEvent) || (WLANTL_HO_THRESHOLD_CROSS == triggerEvent)))
1367 {
1368 TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"Registered RSSI value larger than Current RSSI, and DOWN event, Send Notification"));
1369 crossCBFunction(pAdapter, WLANTL_HO_THRESHOLD_DOWN, usrCtxt);
1370 }
1371 else if((VOS_FALSE == tlCtxt->isBMPS) &&
1372 (rssiValue < currentHO->historyRSSI) && (0 != currentHO->historyRSSI) &&
1373 ((WLANTL_HO_THRESHOLD_UP == triggerEvent) || (WLANTL_HO_THRESHOLD_CROSS == triggerEvent)))
1374 {
1375 TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"Registered RSSI value smaller than Current RSSI, and UP event, Send Notification"));
1376 crossCBFunction(pAdapter, WLANTL_HO_THRESHOLD_UP, usrCtxt);
1377 }
1378
1379 if(VOS_TRUE == tlCtxt->isBMPS)
1380 {
1381 TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"Register into FW, now BMPS"));
1382 /* this function holds the lock across a downstream WDA function call, this is violates some lock
1383 ordering checks done on some HLOS see CR323221*/
1384 THSRELEASELOCK("WLANTL_HSRegRSSIIndicationCB", &tlCtxt->hoSupport.hosLock);
1385 WLANTL_SetFWRSSIThresholds(pAdapter);
1386 THSGETLOCK("WLANTL_HSRegRSSIIndicationCB", &tlCtxt->hoSupport.hosLock);
1387 }
1388
1389 WLANTL_HSDebugDisplay(pAdapter);
1390 THSRELEASELOCK("WLANTL_HSRegRSSIIndicationCB", &tlCtxt->hoSupport.hosLock);
1391 return status;
1392}
1393
1394/*==========================================================================
1395
1396 FUNCTION
1397
1398 DESCRIPTION
1399
1400 PARAMETERS
1401
1402 RETURN VALUE
1403
1404============================================================================*/
1405VOS_STATUS WLANTL_HSDeregRSSIIndicationCB
1406(
1407 v_PVOID_t pAdapter,
1408 v_S7_t rssiValue,
1409 v_U8_t triggerEvent,
1410 WLANTL_RSSICrossThresholdCBType crossCBFunction,
1411 VOS_MODULE_ID moduleID
1412)
1413{
1414 WLANTL_CbType *tlCtxt = VOS_GET_TL_CB(pAdapter);
1415 VOS_STATUS status = VOS_STATUS_SUCCESS;
1416 v_U8_t idx, sIdx;
1417 WLANTL_HO_SUPPORT_TYPE *hoSupport;
1418 WLANTL_CURRENT_HO_STATE_TYPE *currentHO;
1419 v_BOOL_t bmpsAbove = VOS_FALSE;
1420
1421 if(NULL == tlCtxt)
1422 {
1423 TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"Invalid TL handle"));
1424 return VOS_STATUS_E_INVAL;
1425 }
1426
1427 if(0 == tlCtxt->hoSupport.currentHOState.numThreshold)
1428 {
1429 TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"Empty list, can not remove"));
1430 return VOS_STATUS_E_EMPTY;
1431 }
1432
1433 THSGETLOCK("WLANTL_HSDeregRSSIIndicationCB", &tlCtxt->hoSupport.hosLock);
1434 currentHO = &(tlCtxt->hoSupport.currentHOState);
1435 hoSupport = &(tlCtxt->hoSupport);
1436
1437 TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"DEL target RSSI %d, event %d", rssiValue, triggerEvent));
1438
1439 if((VOS_TRUE == tlCtxt->isBMPS) && (0 < currentHO->regionNumber))
1440 {
1441 if(rssiValue >= hoSupport->registeredInd[currentHO->regionNumber - 1].rssiValue)
1442 {
1443 bmpsAbove = VOS_TRUE;
1444 TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"Remove Threshold larger than current region"));
1445 }
1446 }
1447
1448 for(idx = 0; idx < currentHO->numThreshold; idx++)
1449 {
1450 if(rssiValue == hoSupport->registeredInd[idx].rssiValue)
1451 {
1452 for(sIdx = 0; sIdx < WLANTL_HS_NUM_CLIENT; sIdx++)
1453 {
1454 if(crossCBFunction == tlCtxt->hoSupport.registeredInd[idx].crossCBFunction[sIdx])
1455 {
1456 tlCtxt->hoSupport.registeredInd[idx].triggerEvent[sIdx] = 0;
1457 tlCtxt->hoSupport.registeredInd[idx].crossCBFunction[sIdx] = NULL;
1458 tlCtxt->hoSupport.registeredInd[idx].usrCtxt[sIdx] = NULL;
1459 tlCtxt->hoSupport.registeredInd[idx].whoIsClient[sIdx] = 0;
1460 tlCtxt->hoSupport.registeredInd[idx].numClient--;
1461 }
1462 }
1463 if(0 != tlCtxt->hoSupport.registeredInd[idx].numClient)
1464 {
1465 TLLOG1(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO,"Found Multiple idx is %d", idx));
1466 WLANTL_HSDebugDisplay(pAdapter);
1467 THSRELEASELOCK("WLANTL_HSDeregRSSIIndicationCB", &tlCtxt->hoSupport.hosLock);
1468 return status;
1469 }
1470 else
1471 {
1472 TLLOG1(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO,"Found Single idx is %d", idx));
1473 break;
1474 }
1475 }
1476 }
1477 if(idx == currentHO->numThreshold)
1478 {
1479 TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"Could not find entry, maybe invalid arg"));
1480 THSRELEASELOCK("WLANTL_HSDeregRSSIIndicationCB", &tlCtxt->hoSupport.hosLock);
1481 return VOS_STATUS_E_INVAL;
1482 }
1483
1484 for(idx = 0; idx < currentHO->numThreshold; idx++)
1485 {
1486 if(rssiValue == hoSupport->registeredInd[idx].rssiValue)
1487 {
1488 if((currentHO->numThreshold - 1) == idx)
1489 {
1490 TLLOG1(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO,"Remove target is last one"));
1491 /* Does not need move any element, just remove last array entry */
1492 }
1493 else
1494 {
1495 for(sIdx = idx; sIdx < (currentHO->numThreshold - 1); sIdx++)
1496 {
1497 TLLOG1(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO,"Shift up from %d to %d", sIdx + 1, sIdx));
1498 memcpy(&hoSupport->registeredInd[sIdx], &hoSupport->registeredInd[sIdx + 1], sizeof(WLANTL_HO_RSSI_INDICATION_TYPE));
1499 }
1500 }
1501 break;
1502 }
1503 }
1504 /* Common remove last array entry */
1505 tlCtxt->hoSupport.registeredInd[currentHO->numThreshold - 1].rssiValue = WLANTL_HO_DEFAULT_RSSI;
1506 for(idx = 0; idx < WLANTL_HS_NUM_CLIENT; idx++)
1507 {
1508 tlCtxt->hoSupport.registeredInd[currentHO->numThreshold - 1].triggerEvent[idx] = WLANTL_HO_THRESHOLD_NA;
1509 tlCtxt->hoSupport.registeredInd[currentHO->numThreshold - 1].crossCBFunction[idx] = NULL;
1510 tlCtxt->hoSupport.registeredInd[currentHO->numThreshold - 1].usrCtxt[idx] = NULL;
1511 tlCtxt->hoSupport.registeredInd[currentHO->numThreshold - 1].whoIsClient[idx] = 0;
1512 tlCtxt->hoSupport.registeredInd[currentHO->numThreshold - 1].numClient = 0;
1513 }
1514
1515 if((VOS_FALSE == tlCtxt->isBMPS) && (rssiValue >= currentHO->historyRSSI))
1516 {
1517 TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"Removed Threshold above current RSSI level, old RN %d", currentHO->regionNumber));
1518 if(0 < currentHO->regionNumber)
1519 {
1520 currentHO->regionNumber--;
1521 }
1522 else
1523 {
1524 TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"Current Region number is 0, cannot decrease anymore"));
1525 }
1526 TLLOG1(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO,"Decrease region number without notification %d", currentHO->regionNumber));
1527 }
1528 else if((VOS_TRUE == tlCtxt->isBMPS) && (VOS_TRUE == bmpsAbove))
1529 {
1530 currentHO->regionNumber--;
1531 }
1532 /* Decrease number of thresholds */
1533 tlCtxt->hoSupport.currentHOState.numThreshold--;
1534 /*Reset the FW notification*/
1535 tlCtxt->hoSupport.currentHOState.fwNotification=0;
1536
1537 if(VOS_TRUE == tlCtxt->isBMPS)
1538 {
1539 TLLOG1(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO,"Register into FW, now BMPS"));
1540 /* this function holds the lock across a downstream WDA function call, this is violates some lock
1541 ordering checks done on some HLOS see CR323221*/
1542 THSRELEASELOCK("WLANTL_HSDeregRSSIIndicationCB", &tlCtxt->hoSupport.hosLock);
1543 WLANTL_SetFWRSSIThresholds(pAdapter);
1544 THSGETLOCK("WLANTL_HSDeregRSSIIndicationCB", &tlCtxt->hoSupport.hosLock);
1545 }
1546
1547 /* Based on new threshold set recalculated current RSSI status */
1548 if(0 < tlCtxt->hoSupport.currentHOState.numThreshold)
1549 {
1550 }
1551 else if(0 == tlCtxt->hoSupport.currentHOState.numThreshold)
1552 {
1553 currentHO->regionNumber = 0;
1554 TLLOGW(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_WARN,"No registered Threshold"));
1555 /* What should do? */
1556 }
1557
1558 WLANTL_HSDebugDisplay(pAdapter);
1559 THSRELEASELOCK("WLANTL_HSDeregRSSIIndicationCB", &tlCtxt->hoSupport.hosLock);
1560 return status;
1561}
1562
1563/*==========================================================================
1564
1565 FUNCTION
1566
1567 DESCRIPTION
1568
1569 PARAMETERS
1570
1571 RETURN VALUE
1572
1573============================================================================*/
1574VOS_STATUS WLANTL_HSSetAlpha
1575(
1576 v_PVOID_t pAdapter,
1577 int valueAlpha
1578)
1579{
1580 WLANTL_CbType *tlCtxt = VOS_GET_TL_CB(pAdapter);
1581 VOS_STATUS status = VOS_STATUS_SUCCESS;
1582
1583 if(NULL == tlCtxt)
1584 {
1585 TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"Invalid TL handle"));
1586 return VOS_STATUS_E_INVAL;
1587 }
1588
1589 THSGETLOCK("WLANTL_HSSetAlpha", &tlCtxt->hoSupport.hosLock);
1590 tlCtxt->hoSupport.currentHOState.alpha = (v_U8_t)valueAlpha;
1591 THSRELEASELOCK("WLANTL_HSSetAlpha", &tlCtxt->hoSupport.hosLock);
1592 return status;
1593}
1594
1595/*==========================================================================
1596
1597 FUNCTION
1598
1599 DESCRIPTION
1600
1601 PARAMETERS
1602
1603 RETURN VALUE
1604
1605============================================================================*/
1606VOS_STATUS WLANTL_HSRegGetTrafficStatus
1607(
1608 v_PVOID_t pAdapter,
1609 v_U32_t idleThreshold,
1610 v_U32_t period,
1611 WLANTL_TrafficStatusChangedCBType trfficStatusCB,
1612 v_PVOID_t usrCtxt
1613)
1614{
1615 WLANTL_CbType *tlCtxt = VOS_GET_TL_CB(pAdapter);
1616 VOS_STATUS status = VOS_STATUS_SUCCESS;
1617
1618 if(NULL == tlCtxt)
1619 {
1620 TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"Invalid TL handle"));
1621 return VOS_STATUS_E_INVAL;
1622 }
1623
1624 if((0 == idleThreshold) || (0 == period) || (NULL == trfficStatusCB))
1625 {
1626 TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"Invalid Argument Passed from SME"));
1627 return VOS_STATUS_E_INVAL;
1628 }
1629
1630 tlCtxt->hoSupport.currentTraffic.idleThreshold = idleThreshold;
1631 tlCtxt->hoSupport.currentTraffic.measurePeriod = period;
1632 tlCtxt->hoSupport.currentTraffic.trafficCB = trfficStatusCB;
1633 tlCtxt->hoSupport.currentTraffic.usrCtxt = usrCtxt;
1634
1635 vos_timer_start(&tlCtxt->hoSupport.currentTraffic.trafficTimer,
1636 tlCtxt->hoSupport.currentTraffic.measurePeriod);
1637
1638 return status;
1639}
1640
1641/*==========================================================================
1642
1643 FUNCTION
1644
1645 DESCRIPTION
1646
1647 PARAMETERS
1648
1649 RETURN VALUE
1650
1651============================================================================*/
1652VOS_STATUS WLANTL_HSInit
1653(
1654 v_PVOID_t pAdapter
1655)
1656{
1657 WLANTL_CbType *tlCtxt = VOS_GET_TL_CB(pAdapter);
1658 VOS_STATUS status = VOS_STATUS_SUCCESS;
1659 v_U8_t idx, sIdx;
1660
1661 if(NULL == tlCtxt)
1662 {
1663 TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"Invalid TL handle"));
1664 return VOS_STATUS_E_INVAL;
1665 }
1666#ifdef WLANTL_HO_UTEST
1667 rssi = 0;
1668 direction = -1;
1669#endif /* WLANTL_HO_UTEST */
1670
1671 /* set default current HO status */
1672 tlCtxt->hoSupport.currentHOState.alpha = WLANTL_HO_DEFAULT_ALPHA;
1673 tlCtxt->hoSupport.currentHOState.historyRSSI = 0;
1674 tlCtxt->hoSupport.currentHOState.numThreshold = 0;
1675 tlCtxt->hoSupport.currentHOState.regionNumber = 0;
1676 tlCtxt->hoSupport.currentHOState.sampleTime = 0;
1677
1678 /* set default current traffic status */
1679 tlCtxt->hoSupport.currentTraffic.trafficStatus.rtTrafficStatus
1680 = WLANTL_HO_RT_TRAFFIC_STATUS_OFF;
1681 tlCtxt->hoSupport.currentTraffic.trafficStatus.nrtTrafficStatus
1682 = WLANTL_HO_NRT_TRAFFIC_STATUS_OFF;
1683 tlCtxt->hoSupport.currentTraffic.idleThreshold = 0;
1684 tlCtxt->hoSupport.currentTraffic.measurePeriod = 0;
1685 tlCtxt->hoSupport.currentTraffic.rtRXFrameCount = 0;
1686 tlCtxt->hoSupport.currentTraffic.rtTXFrameCount = 0;
1687 tlCtxt->hoSupport.currentTraffic.nrtRXFrameCount = 0;
1688 tlCtxt->hoSupport.currentTraffic.nrtTXFrameCount = 0;
1689 tlCtxt->hoSupport.currentTraffic.trafficCB = NULL;
1690
1691 /* Initialize indication array */
1692 for(idx = 0; idx < WLANTL_MAX_AVAIL_THRESHOLD; idx++)
1693 {
1694 for(sIdx = 0; sIdx < WLANTL_HS_NUM_CLIENT; sIdx++)
1695 {
1696 tlCtxt->hoSupport.registeredInd[idx].triggerEvent[sIdx] = WLANTL_HO_THRESHOLD_NA;
1697 tlCtxt->hoSupport.registeredInd[idx].crossCBFunction[sIdx] = NULL;
1698 tlCtxt->hoSupport.registeredInd[idx].usrCtxt[sIdx] = NULL;
1699 tlCtxt->hoSupport.registeredInd[idx].whoIsClient[sIdx] = 0;
1700 }
1701 tlCtxt->hoSupport.registeredInd[idx].rssiValue = WLANTL_HO_DEFAULT_RSSI;
1702 tlCtxt->hoSupport.registeredInd[idx].numClient = 0;
1703 }
1704
1705 vos_timer_init(&tlCtxt->hoSupport.currentTraffic.trafficTimer,
1706 VOS_TIMER_TYPE_SW,
1707 WLANTL_HSTrafficStatusTimerExpired,
1708 pAdapter);
1709
1710
1711 vos_lock_init(&tlCtxt->hoSupport.hosLock);
1712 tlCtxt->hoSupport.macCtxt = vos_get_context(VOS_MODULE_ID_SME, pAdapter);
1713
1714 return status;
1715}
1716
1717
1718/*==========================================================================
1719
1720 FUNCTION WLANTL_HSDeInit
1721
1722 DESCRIPTION
1723
1724 PARAMETERS
1725
1726 RETURN VALUE
1727
1728============================================================================*/
1729
1730VOS_STATUS WLANTL_HSDeInit
1731(
1732 v_PVOID_t pAdapter
1733)
1734{
1735 WLANTL_CbType *tlCtxt = VOS_GET_TL_CB(pAdapter);
1736 VOS_STATUS status = VOS_STATUS_SUCCESS;
1737
1738 if(NULL == tlCtxt)
1739 {
1740 TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"Invalid TL handle"));
1741 return VOS_STATUS_E_INVAL;
1742 }
1743
1744 // Destroy the timer...
1745 status = vos_timer_destroy( &tlCtxt->hoSupport.currentTraffic.trafficTimer );
1746 if ( !VOS_IS_STATUS_SUCCESS( status ) )
1747 {
1748 TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"WLANTL_HSStop: Timer Destroy Fail Status %d", status));
1749 }
1750 return status;
1751}
1752
1753
1754/*==========================================================================
1755
1756 FUNCTION
1757
1758 DESCRIPTION
1759
1760 PARAMETERS
1761
1762 RETURN VALUE
1763
1764============================================================================*/
1765VOS_STATUS WLANTL_HSStop
1766(
1767 v_PVOID_t pAdapter
1768)
1769{
1770 WLANTL_CbType *tlCtxt = VOS_GET_TL_CB(pAdapter);
1771 VOS_STATUS status = VOS_STATUS_SUCCESS;
1772 VOS_TIMER_STATE timerState;
1773
1774 if(NULL == tlCtxt)
1775 {
1776 TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"Invalid TL handle"));
1777 return VOS_STATUS_E_INVAL;
1778 }
1779
1780 timerState = vos_timer_getCurrentState(&tlCtxt->hoSupport.currentTraffic.trafficTimer);
1781 if(VOS_TIMER_STATE_RUNNING == timerState)
1782 {
1783 TLLOG1(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO,"Stop Traffic status monitoring timer"));
1784 status = vos_timer_stop(&tlCtxt->hoSupport.currentTraffic.trafficTimer);
1785 }
1786 if(VOS_STATUS_SUCCESS != status)
1787 {
1788 TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"Timer Stop Failed, Status %d", status));
1789 }
1790
1791 //Deregister the traffic Status
1792 tlCtxt->hoSupport.currentTraffic.idleThreshold = 0;
1793 tlCtxt->hoSupport.currentTraffic.measurePeriod = 0;
1794 tlCtxt->hoSupport.currentTraffic.trafficCB = NULL;
1795 tlCtxt->hoSupport.currentTraffic.usrCtxt = NULL;
1796
1797 return status;
1798}
1799#endif //FEATURE_WLAN_GEN6_ROAMING