blob: 2c3bcde1b79a2fdad2a52b207f9b6053ff78ede2 [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
Jeff Johnson32d95a32012-09-10 13:15:23 -07002 * Copyright (c) 2012, The Linux Foundation. All rights reserved.
Jeff Johnson295189b2012-06-20 16:38:30 -07003 *
4 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
5 *
6 *
7 * Permission to use, copy, modify, and/or distribute this software for
8 * any purpose with or without fee is hereby granted, provided that the
9 * above copyright notice and this permission notice appear in all
10 * copies.
11 *
12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
13 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
14 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
15 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
16 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
17 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
18 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
19 * PERFORMANCE OF THIS SOFTWARE.
20 */
21
22/*===========================================================================
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"));
Jeff Johnsone7245742012-09-05 17:12:55 -0700436 if(isBroadcast)
Jeff Johnson295189b2012-06-20 16:38:30 -0700437 {
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);
Jeff Johnsone7245742012-09-05 17:12:55 -0700458
459 TLLOG1(VOS_TRACE (VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_MED,
460 "****Received rate Index = %ld type=%d subtype=%d****\n",
461 statistics->rxRate,WDA_GET_RX_TYPE(pBDHeader),WDA_GET_RX_SUBTYPE(pBDHeader)));
462
Jeff Johnson295189b2012-06-20 16:38:30 -0700463 statistics->rxBcnt += (packetSize - WLANHAL_RX_BD_HEADER_SIZE);
464
465#ifdef WLANTL_HO_DEBUG_MSG
466 WLANTL_StatDebugDisplay(STAid, statistics);
467#endif /* WLANTL_HO_DEBUG_MSG */
468
469 return status;
470}
471
472/*==========================================================================
473
474 FUNCTION
475
476 DESCRIPTION
477
478 PARAMETERS
479
480 RETURN VALUE
481
482============================================================================*/
483VOS_STATUS WLANTL_StatHandleTXFrame
484(
485 v_PVOID_t pAdapter,
486 v_U8_t STAid,
487 vos_pkt_t *dataBuffer,
488 v_PVOID_t pBDHeader
Jeff Johnsone7245742012-09-05 17:12:55 -0700489#ifdef FEATURE_WLAN_INTEGRATED_SOC
490 ,WLANTL_MetaInfoType *txMetaInfo
491#endif /* FEATURE_WLAN_INTEGRATED_SOC */
Jeff Johnson295189b2012-06-20 16:38:30 -0700492)
493{
494 WLANTL_CbType *tlCtxt = VOS_GET_TL_CB(pAdapter);
495 VOS_STATUS status = VOS_STATUS_SUCCESS;
496 WLANTL_TRANSFER_STA_TYPE *statistics;
497 v_U16_t packetSize;
498
499 if((NULL == tlCtxt) || (NULL == dataBuffer))
500 {
501 TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"Invalid TL handle"));
502 return VOS_STATUS_E_INVAL;
503 }
504
505 if(0 == tlCtxt->atlSTAClients[STAid].ucExists)
506 {
507 TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"WLAN TL: %d STA ID is not exist", STAid));
508 return VOS_STATUS_E_INVAL;
509 }
510
511 /* TODO : BC/MC/UC have to be determined by MAC address */
512 statistics = &tlCtxt->atlSTAClients[STAid].trafficStatistics;
513 vos_pkt_get_packet_length(dataBuffer, &packetSize);
Jeff Johnsone7245742012-09-05 17:12:55 -0700514#ifdef FEATURE_WLAN_INTEGRATED_SOC
515 if(txMetaInfo->ucBcast)
516#else
Jeff Johnson295189b2012-06-20 16:38:30 -0700517 if(WLANTL_STA_ID_BCAST == STAid)
Jeff Johnsone7245742012-09-05 17:12:55 -0700518#endif /* FEATURE_WLAN_INTEGRATED_SOC */
Jeff Johnson295189b2012-06-20 16:38:30 -0700519 {
520 TLLOG1(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO,"This TX is BC frame"));
521 statistics->txBCFcnt++;
Jeff Johnsone7245742012-09-05 17:12:55 -0700522#ifdef FEATURE_WLAN_INTEGRATED_SOC
523 statistics->txBCBcnt += packetSize;
524#else
Jeff Johnson295189b2012-06-20 16:38:30 -0700525 statistics->txBCBcnt += (packetSize - WLANHAL_TX_BD_HEADER_SIZE);
Jeff Johnsone7245742012-09-05 17:12:55 -0700526#endif /* FEATURE_WLAN_INTEGRATED_SOC */
Jeff Johnson295189b2012-06-20 16:38:30 -0700527 }
Jeff Johnsone7245742012-09-05 17:12:55 -0700528 else if(txMetaInfo->ucMcast)
Jeff Johnson295189b2012-06-20 16:38:30 -0700529 {
Jeff Johnsone7245742012-09-05 17:12:55 -0700530 TLLOG1(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO,"This TX is MC frame"));
531 statistics->txMCFcnt++;
532#ifdef FEATURE_WLAN_INTEGRATED_SOC
533 statistics->txMCBcnt += packetSize;
534#else
535 statistics->txMCBcnt += (packetSize - WLANHAL_RX_BD_HEADER_SIZE);
536#endif /* FEATURE_WLAN_INTEGRATED_SOC */
Jeff Johnson295189b2012-06-20 16:38:30 -0700537 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700538 else
539 {
540 TLLOG1(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO,"This is TX UC frame"));
541 statistics->txUCFcnt++;
Jeff Johnsone7245742012-09-05 17:12:55 -0700542#ifdef FEATURE_WLAN_INTEGRATED_SOC
543 statistics->txUCBcnt += packetSize;
544#else
Jeff Johnson295189b2012-06-20 16:38:30 -0700545 statistics->txUCBcnt += (packetSize - WLANHAL_RX_BD_HEADER_SIZE);
Jeff Johnsone7245742012-09-05 17:12:55 -0700546#endif /* FEATURE_WLAN_INTEGRATED_SOC */
Jeff Johnson295189b2012-06-20 16:38:30 -0700547 }
548
549#ifdef WLANTL_HO_DEBUG_MSG
550 WLANTL_StatDebugDisplay(STAid, statistics);
551#endif /* WLANTL_HO_DEBUG_MSG */
552
553 return status;
554}
555
556/*==========================================================================
557
558 FUNCTION WLANTL_HSTrafficStatusTimerExpired
559
560 DESCRIPTION If traffic status monitoring timer is expiered,
561 Count how may frames have sent and received during
562 measure period and if traffic status is changed
563 send notification to Client(SME)
564
565 PARAMETERS pAdapter
566 Global handle
567
568 RETURN VALUE
569
570============================================================================*/
571v_VOID_t WLANTL_HSTrafficStatusTimerExpired
572(
573 v_PVOID_t pAdapter
574)
575{
576 WLANTL_CbType *tlCtxt = VOS_GET_TL_CB(pAdapter);
577 WLANTL_HO_TRAFFIC_STATUS_HANDLE_TYPE *trafficHandle = NULL;
578 WLANTL_HO_TRAFFIC_STATUS_TYPE newTraffic;
579 v_U32_t rtFrameCount;
580 v_U32_t nrtFrameCount;
581 v_BOOL_t trafficStatusChanged = VOS_FALSE;
582
583 if(NULL == tlCtxt)
584 {
585 TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"Invalid TL handle"));
586 return;
587 }
588
589 /* Get rt and nrt frame count sum */
590 trafficHandle = &tlCtxt->hoSupport.currentTraffic;
591 rtFrameCount = trafficHandle->rtRXFrameCount + trafficHandle->rtTXFrameCount;
592 nrtFrameCount = trafficHandle->nrtRXFrameCount + trafficHandle->nrtTXFrameCount;
593
594 TLLOG1(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO,"Traffic status timer expired RT FC %d, NRT FC %d", rtFrameCount, nrtFrameCount));
595
596 /* Get current traffic status */
597 if(rtFrameCount > trafficHandle->idleThreshold)
598 {
599 newTraffic.rtTrafficStatus = WLANTL_HO_RT_TRAFFIC_STATUS_ON;
600 }
601 else
602 {
603 newTraffic.rtTrafficStatus = WLANTL_HO_RT_TRAFFIC_STATUS_OFF;
604 }
605
606 if(nrtFrameCount > trafficHandle->idleThreshold)
607 {
608 newTraffic.nrtTrafficStatus = WLANTL_HO_NRT_TRAFFIC_STATUS_ON;
609 }
610 else
611 {
612 newTraffic.nrtTrafficStatus = WLANTL_HO_NRT_TRAFFIC_STATUS_OFF;
613 }
614
615 /* Differentiate with old traffic status */
616 if(trafficHandle->trafficStatus.rtTrafficStatus != newTraffic.rtTrafficStatus)
617 {
618 TLLOGW(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_WARN,"RT Traffic status changed from %d to %d",
619 trafficHandle->trafficStatus.rtTrafficStatus,
620 newTraffic.rtTrafficStatus));
621 trafficStatusChanged = VOS_TRUE;
622 }
623 if(trafficHandle->trafficStatus.nrtTrafficStatus != newTraffic.nrtTrafficStatus)
624 {
625 TLLOGW(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_WARN,"NRT Traffic status changed from %d to %d",
626 trafficHandle->trafficStatus.nrtTrafficStatus,
627 newTraffic.nrtTrafficStatus));
628 trafficStatusChanged = VOS_TRUE;
629 }
630
631 /* If traffic status is changed send notification to client */
632 if((VOS_TRUE == trafficStatusChanged) && (NULL != trafficHandle->trafficCB))
633 {
634 trafficHandle->trafficCB(pAdapter, newTraffic, trafficHandle->usrCtxt);
635 trafficHandle->trafficStatus.rtTrafficStatus = newTraffic.rtTrafficStatus;
636 trafficHandle->trafficStatus.nrtTrafficStatus = newTraffic.nrtTrafficStatus;
637 }
638 else if((VOS_TRUE == trafficStatusChanged) && (NULL == trafficHandle->trafficCB))
639 {
640 TLLOGW(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_WARN,"Traffic status is changed but not need to report"));
641 }
642
643 /* Reset frame counters */
644 trafficHandle->rtRXFrameCount = 0;
645 trafficHandle->rtTXFrameCount = 0;
646 trafficHandle->nrtRXFrameCount = 0;
647 trafficHandle->nrtTXFrameCount = 0;
648
649 if(NULL != trafficHandle->trafficCB)
650 {
651 /* restart timer only when the callback is not NULL */
652 vos_timer_start(&trafficHandle->trafficTimer, trafficHandle->measurePeriod);
653 }
654
655 return;
656}
657
658
659/*==========================================================================
660
661 FUNCTION
662
663 DESCRIPTION
664
665 PARAMETERS
666
667 RETURN VALUE
668
669============================================================================*/
670VOS_STATUS WLANTL_HSGetRSSI
671(
672 v_PVOID_t pAdapter,
673 v_PVOID_t pBDHeader,
674 v_U8_t STAid,
675 v_S7_t *currentAvgRSSI
676)
677{
678 WLANTL_CbType *tlCtxt = VOS_GET_TL_CB(pAdapter);
679 VOS_STATUS status = VOS_STATUS_SUCCESS;
680 v_S7_t currentRSSI, currentRSSI0, currentRSSI1;
681 WLANTL_CURRENT_HO_STATE_TYPE *currentHO = NULL;
682
683
684 if(NULL == tlCtxt)
685 {
686 TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"Invalid TL handle"));
687 return VOS_STATUS_E_INVAL;
688 }
689
690 /*
691 Compute RSSI only for the last MPDU of an AMPDU.
692 Only last MPDU carries the Phy Stats Values
693 */
694 if (WDA_IS_RX_AN_AMPDU (pBDHeader)) {
695 if (!WDA_IS_RX_LAST_MPDU(pBDHeader)) {
696 return VOS_STATUS_E_FAILURE;
697 }
698 }
699
700 currentHO = &tlCtxt->hoSupport.currentHOState;
701
702 currentRSSI0 = WLANTL_GETRSSI0(pBDHeader);
703 currentRSSI1 = WLANTL_GETRSSI0(pBDHeader);
704 currentRSSI = (currentRSSI0 > currentRSSI1) ? currentRSSI0 : currentRSSI1;
705
706 if (0 == currentRSSI)
707 return VOS_STATUS_E_INVAL;
708
709#ifdef WLANTL_HO_UTEST
710 TLHS_UtestHandleNewRSSI(&currentRSSI, pAdapter);
711#endif /* WLANTL_HO_UTEST */
712
713/* Commenting this part of the code as this may not be necessarity true in all cases */
714#if 0
715 if(WLANTL_HO_INVALID_RSSI == currentRSSI)
716 {
717 return status;
718 }
719#endif
720
721 if(0 == currentHO->historyRSSI)
722 {
723 *currentAvgRSSI = currentRSSI;
724 }
725 else
726 {
727 *currentAvgRSSI = ((currentHO->historyRSSI * currentHO->alpha) +
728 (currentRSSI * (10 - currentHO->alpha))) / 10;
729 }
730#ifdef RSSI_HACK
731 *currentAvgRSSI = (v_S7_t)dumpCmdRSSI;
732#endif
733
734
735 tlCtxt->atlSTAClients[STAid].rssiAvg = *currentAvgRSSI;
736
737 TLLOG1(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO,"Current new RSSI is %d, averaged RSSI is %d", currentRSSI, *currentAvgRSSI));
738 return status;
739}
740
741/*==========================================================================
742
743 FUNCTION
744
745 DESCRIPTION
746
747 PARAMETERS
748
749 RETURN VALUE
750
751============================================================================*/
752VOS_STATUS WLANTL_HSBMPSRSSIRegionChangedNotification
753(
754 v_PVOID_t pAdapter,
755 tpSirRSSINotification pRSSINotification
756)
757{
758 WLANTL_CbType *tlCtxt = VOS_GET_TL_CB(pAdapter);
759 VOS_STATUS status = VOS_STATUS_SUCCESS;
760 WLANTL_CURRENT_HO_STATE_TYPE *currentHO;
761 WLANTL_HO_SUPPORT_TYPE *hoSupport;
762 WLANTL_RSSICrossThresholdCBType cbFunction = NULL;
763 v_PVOID_t usrCtxt = NULL;
764 v_U8_t evtType = WLANTL_HO_THRESHOLD_NA;
765 v_U32_t preFWNotification = 0;
766 v_U32_t curFWNotification = 0;
767 v_U8_t newRegionNumber = 0;
768 v_U8_t pRegionNumber = 0, nRegionNumber = 0;
769 v_U32_t isSet;
770 v_U8_t idx, sIdx;
771
772 if(NULL == tlCtxt)
773 {
774 TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"Invalid TL handle"));
775 return VOS_STATUS_E_INVAL;
776 }
777
778 if(NULL == pRSSINotification)
779 {
780 TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"Invalid FW RSSI Notification"));
781 VOS_ASSERT(0);
782 return VOS_STATUS_E_INVAL;
783 }
784
785 currentHO = &(tlCtxt->hoSupport.currentHOState);
786 hoSupport = &(tlCtxt->hoSupport);
787 preFWNotification = currentHO->fwNotification;
788
789 isSet = pRSSINotification->bRssiThres1PosCross;
790 curFWNotification |= isSet << 5;
791 isSet = pRSSINotification->bRssiThres2PosCross;
792 curFWNotification |= isSet << 4;
793 isSet = pRSSINotification->bRssiThres3PosCross;
794 curFWNotification |= isSet << 3;
795 isSet = pRSSINotification->bRssiThres1NegCross;
796 curFWNotification |= isSet << 2;
797 isSet = pRSSINotification->bRssiThres2NegCross;
798 curFWNotification |= isSet << 1;
799 isSet = pRSSINotification->bRssiThres3NegCross;
800 curFWNotification |= isSet;
801 TLLOG1(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO,"Current FW Notification is 0x%x", (v_U32_t)curFWNotification ));
802
803 currentHO->fwNotification = curFWNotification;
804
805 if(0 == preFWNotification)
806 {
807 TLLOG1(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO,"This is the first time notification from FW Value is 0x%x", curFWNotification));
808 preFWNotification = curFWNotification;
809 }
810 else if(preFWNotification == curFWNotification)
811 {
812 return status;
813 }
814
815 if(1 == pRSSINotification->bRssiThres1PosCross)
816 {
817 TLLOG1(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO,"POS Cross to Region 0"));
818 pRegionNumber = 0;
819 }
820 else if(1 == pRSSINotification->bRssiThres2PosCross)
821 {
822 TLLOG1(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO,"POS Cross to Region 1"));
823 pRegionNumber = 1;
824 }
825 else if(1 == pRSSINotification->bRssiThres3PosCross)
826 {
827 TLLOG1(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO,"POS Cross to Region 2"));
828 pRegionNumber = 2;
829 }
830
831 if(1 == pRSSINotification->bRssiThres3NegCross)
832 {
833 TLLOG1(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO,"NEG Cross to Region 3"));
834 nRegionNumber = 3;
835 }
836 else if(1 == pRSSINotification->bRssiThres2NegCross)
837 {
838 TLLOG1(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO,"NEG Cross to Region 2"));
839 nRegionNumber = 2;
840 }
841 else if(1 == pRSSINotification->bRssiThres1NegCross)
842 {
843 TLLOG1(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO,"NEG Cross to Region 1"));
844 nRegionNumber = 1;
845 }
846
847
848 newRegionNumber = (nRegionNumber > pRegionNumber) ? nRegionNumber : pRegionNumber;
849 if((currentHO->regionNumber) && (newRegionNumber == currentHO->regionNumber))
850 {
851 TLLOG1(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO,"No Region Change with BMPS mode"));
852 preFWNotification = curFWNotification;
853 return status;
854 }
855 else if(newRegionNumber > currentHO->regionNumber)
856 {
857 TLLOG1(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO,"Region Increase Worse RSSI"));
858 for(idx = currentHO->regionNumber; idx < newRegionNumber; idx++)
859 {
860 for(sIdx = 0; sIdx < WLANTL_HS_NUM_CLIENT; sIdx++)
861 {
862 if((WLANTL_HO_THRESHOLD_DOWN == hoSupport->registeredInd[idx].triggerEvent[sIdx]) ||
863 (WLANTL_HO_THRESHOLD_CROSS == hoSupport->registeredInd[idx].triggerEvent[sIdx]))
864 {
865 if(NULL != hoSupport->registeredInd[idx].crossCBFunction[sIdx])
866 {
867 cbFunction = hoSupport->registeredInd[idx].crossCBFunction[sIdx];
868 usrCtxt = hoSupport->registeredInd[idx].usrCtxt[sIdx];
869 evtType = WLANTL_HO_THRESHOLD_DOWN;
870 TLLOG1(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO,"Trigger Event %d, region index %d", hoSupport->registeredInd[idx].triggerEvent[sIdx], idx));
871 currentHO->regionNumber = newRegionNumber;
872 status = cbFunction(pAdapter, evtType, usrCtxt);
873 }
874 }
875 }
876 }
877 }
878 else
879 {
880 TLLOG1(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO,"Region Decrease Better RSSI"));
881 idx = (currentHO->regionNumber)?(currentHO->regionNumber-1):0;
882 while (idx >= newRegionNumber)
883 {
884 for(sIdx = 0; sIdx < WLANTL_HS_NUM_CLIENT; sIdx++)
885 {
886 if((WLANTL_HO_THRESHOLD_UP & hoSupport->registeredInd[idx].triggerEvent[sIdx]) ||
887 (WLANTL_HO_THRESHOLD_CROSS & hoSupport->registeredInd[idx].triggerEvent[sIdx]))
888 {
889 if(NULL != hoSupport->registeredInd[idx].crossCBFunction[sIdx])
890 {
891 cbFunction = hoSupport->registeredInd[idx].crossCBFunction[sIdx];
892 usrCtxt = hoSupport->registeredInd[idx].usrCtxt[sIdx];
893 evtType = WLANTL_HO_THRESHOLD_UP;
894 TLLOG1(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO,"Trigger Event %d, region index %d", hoSupport->registeredInd[idx].triggerEvent[sIdx], idx));
895 currentHO->regionNumber = newRegionNumber;
896 status = cbFunction(pAdapter, evtType, usrCtxt);
897 }
898 }
899 }
900 if (!idx--)
901 break;
902 }
903 }
904
905 TLLOG1(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO,"BMPS State, MSG from FW, Trigger Event %d, region index %d",
906 evtType, currentHO->regionNumber));
907
908 return VOS_STATUS_SUCCESS;
909}
910
911/*==========================================================================
912
913 FUNCTION
914
915 DESCRIPTION
916
917 PARAMETERS
918
919 RETURN VALUE
920
921============================================================================*/
922VOS_STATUS WLANTL_HSHandleRSSIChange
923(
924 v_PVOID_t pAdapter,
925 v_S7_t currentRSSI
926)
927{
928 WLANTL_CbType *tlCtxt = VOS_GET_TL_CB(pAdapter);
929 VOS_STATUS status = VOS_STATUS_SUCCESS;
930 v_U8_t currentRegion = 0;
931 v_U8_t idx, sIdx;
932 WLANTL_CURRENT_HO_STATE_TYPE *currentHO;
933 WLANTL_HO_SUPPORT_TYPE *hoSupport;
934 WLANTL_RSSICrossThresholdCBType cbFunction = NULL;
935 v_PVOID_t usrCtxt = NULL;
936 v_U8_t evtType = WLANTL_HO_THRESHOLD_NA;
937
938 if(NULL == tlCtxt)
939 {
940 TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"Invalid TL handle"));
941 return VOS_STATUS_E_INVAL;
942 }
943
944 currentHO = &(tlCtxt->hoSupport.currentHOState);
945 hoSupport = &(tlCtxt->hoSupport);
946 TLLOG1(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO,"CRegion %d, NThreshold %d, HRSSI %d",
947 currentHO->regionNumber,
948 currentHO->numThreshold,
949 currentHO->historyRSSI));
950
951 /* Find where is current region */
952 for(idx = 0; idx < currentHO->numThreshold; idx++)
953 {
954 if(hoSupport->registeredInd[idx].rssiValue < currentRSSI)
955 {
956 currentRegion = idx;
957 TLLOG1(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO,"Found region %d, not bottom", currentRegion));
958 break;
959 }
960 }
961
962 /* If could not find then new RSSI is belong to bottom region */
963 if(idx == currentHO->numThreshold)
964 {
965 currentRegion = idx;
966 TLLOG1(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO,"Current region is bottom %d", idx));
967 }
968
969 /* This is a hack. Actual assignment was happening after the below checks. This hack is needed till TL
970 posts message and nothing else in the callback indicating UP/DOWN event to the registered module */
971 currentHO->historyRSSI = currentRSSI;
972
973 if(currentRegion == currentHO->regionNumber)
974 {
975 currentHO->historyRSSI = currentRSSI;
976 return status;
977 }
978 else if(currentRegion > currentHO->regionNumber)
979 {
980 TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"Region Increase Worse RSSI"));
981 for(idx = currentHO->regionNumber; idx < currentRegion; idx++)
982 {
983 for(sIdx = 0; sIdx < WLANTL_HS_NUM_CLIENT; sIdx++)
984 {
985 if((WLANTL_HO_THRESHOLD_DOWN == hoSupport->registeredInd[idx].triggerEvent[sIdx]) ||
986 (WLANTL_HO_THRESHOLD_CROSS == hoSupport->registeredInd[idx].triggerEvent[sIdx]))
987 {
988 if(NULL != hoSupport->registeredInd[idx].crossCBFunction[sIdx])
989 {
990 cbFunction = hoSupport->registeredInd[idx].crossCBFunction[sIdx];
991 usrCtxt = hoSupport->registeredInd[idx].usrCtxt[sIdx];
992 evtType = WLANTL_HO_THRESHOLD_DOWN;
993 TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"Trigger Event %d, region index %d", hoSupport->registeredInd[idx].triggerEvent[sIdx], idx));
Jeff Johnsone7245742012-09-05 17:12:55 -0700994 status = WLANTL_HSSerializeTlIndication(pAdapter, evtType, usrCtxt, cbFunction);
Jeff Johnson295189b2012-06-20 16:38:30 -0700995 }
996 }
997 }
998 }
999 }
1000 else
1001 {
1002 TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"Region Decrease Better RSSI"));
1003 for(idx = currentHO->regionNumber; idx > currentRegion; idx--)
1004 {
1005 for(sIdx = 0; sIdx < WLANTL_HS_NUM_CLIENT; sIdx++)
1006 {
1007 if((WLANTL_HO_THRESHOLD_UP & hoSupport->registeredInd[idx - 1].triggerEvent[sIdx]) ||
1008 (WLANTL_HO_THRESHOLD_CROSS & hoSupport->registeredInd[idx - 1].triggerEvent[sIdx]))
1009 {
1010 if(NULL != hoSupport->registeredInd[idx - 1].crossCBFunction[sIdx])
1011 {
1012 cbFunction = hoSupport->registeredInd[idx - 1].crossCBFunction[sIdx];
1013 usrCtxt = hoSupport->registeredInd[idx - 1].usrCtxt[sIdx];
1014 evtType = WLANTL_HO_THRESHOLD_UP;
1015 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));
Jeff Johnsone7245742012-09-05 17:12:55 -07001016 status = WLANTL_HSSerializeTlIndication(pAdapter, evtType, usrCtxt, cbFunction);
Jeff Johnson295189b2012-06-20 16:38:30 -07001017 }
1018 }
1019 }
1020 }
1021 }
1022
1023 currentHO->historyRSSI = currentRSSI;
1024 currentHO->regionNumber = currentRegion;
1025 WLANTL_HSDebugDisplay(pAdapter);
1026
1027 if(!VOS_IS_STATUS_SUCCESS(status))
1028 {
1029 TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"Client fail to handle region change in normal mode %d", status));
1030 }
1031 return VOS_STATUS_SUCCESS;
1032}
1033
1034/*==========================================================================
1035
1036 FUNCTION
1037
1038 DESCRIPTION
1039
1040 PARAMETERS
1041
1042 RETURN VALUE
1043
1044============================================================================*/
1045VOS_STATUS WLANTL_HSHandleRXFrame
1046(
1047 v_PVOID_t pAdapter,
1048 v_U8_t frameType,
1049 v_PVOID_t pBDHeader,
1050 v_U8_t STAid,
1051 v_BOOL_t isBroadcast,
1052 vos_pkt_t *dataBuffer
1053)
1054{
1055 WLANTL_CURRENT_HO_STATE_TYPE *currentHO = NULL;
1056 WLANTL_CbType *tlCtxt = VOS_GET_TL_CB(pAdapter);
1057 VOS_STATUS status = VOS_STATUS_SUCCESS;
1058 v_S7_t currentAvgRSSI = 0;
1059 v_U8_t ac;
1060 v_U32_t currentTimestamp;
1061 v_U8_t tid;
1062
1063 if(NULL == tlCtxt)
1064 {
1065 TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"Invalid TL handle"));
1066 return VOS_STATUS_E_INVAL;
1067 }
1068
1069 WLANTL_StatHandleRXFrame(pAdapter, pBDHeader, STAid, isBroadcast, dataBuffer);
1070
1071 /* If this frame is not management frame increase frame count */
1072 if((0 != tlCtxt->hoSupport.currentTraffic.idleThreshold) &&
1073 (WLANTL_MGMT_FRAME_TYPE != frameType))
1074 {
1075 tid = WDA_GET_RX_TID( pBDHeader );
1076 ac = WLANTL_HO_TID_2_AC[(v_U8_t)tid];
1077
1078 /* Only Voice traffic is handled as real time traffic */
1079 if(WLANTL_AC_VO == ac)
1080 {
1081 tlCtxt->hoSupport.currentTraffic.rtRXFrameCount++;
1082 }
1083 else
1084 {
1085 tlCtxt->hoSupport.currentTraffic.nrtRXFrameCount++;
1086 }
1087 TLLOG1(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO,"RX frame AC %d, RT Frame Count %d, NRT Frame Count %d",
1088 ac,
1089 tlCtxt->hoSupport.currentTraffic.rtRXFrameCount,
1090 tlCtxt->hoSupport.currentTraffic.nrtRXFrameCount));
1091 }
1092
1093 currentHO = &tlCtxt->hoSupport.currentHOState;
1094 if(VOS_TRUE == tlCtxt->isBMPS)
1095 {
1096 WLANTL_HSGetRSSI(pAdapter, pBDHeader, STAid, &currentAvgRSSI);
1097 return status;
1098 }
1099
1100 currentTimestamp = WDA_GET_RX_TIMESTAMP(pBDHeader);
1101 if((currentTimestamp - currentHO->sampleTime) < WLANTL_HO_SAMPLING_PERIOD)
1102 {
1103 return status;
1104 }
1105 currentHO->sampleTime = currentTimestamp;
1106
Jeff Johnsone7245742012-09-05 17:12:55 -07001107 /* Get Current RSSI from BD Heaser */
1108 status = WLANTL_HSGetRSSI(pAdapter, pBDHeader, STAid, &currentAvgRSSI);
1109 if(!VOS_IS_STATUS_SUCCESS(status))
1110 {
1111 TLLOG1(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO,"Get RSSI Fail"));
1112 return status;
1113 }
1114
Jeff Johnson295189b2012-06-20 16:38:30 -07001115 /* If any threshold is not registerd, DO NOTHING! */
1116 if(0 == tlCtxt->hoSupport.currentHOState.numThreshold)
1117 {
1118 TLLOG1(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO,"There is no thresholds pass"));
1119 }
1120 else
1121 {
Jeff Johnson295189b2012-06-20 16:38:30 -07001122 /* Handle current RSSI value, region, notification, etc */
1123 status = WLANTL_HSHandleRSSIChange(pAdapter, currentAvgRSSI);
1124 if(!VOS_IS_STATUS_SUCCESS(status))
1125 {
1126 TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"Handle new RSSI fail"));
1127 return status;
1128 }
1129 }
1130
1131 return status;
1132}
1133
1134/*==========================================================================
1135
1136 FUNCTION
1137
1138 DESCRIPTION
1139
1140 PARAMETERS
1141
1142 RETURN VALUE
1143
1144============================================================================*/
1145VOS_STATUS WLANTL_HSHandleTXFrame
1146(
1147 v_PVOID_t pAdapter,
1148 v_U8_t ac,
1149 v_U8_t STAid,
1150 vos_pkt_t *dataBuffer,
1151 v_PVOID_t bdHeader
1152)
1153{
1154 WLANTL_CbType *tlCtxt = VOS_GET_TL_CB(pAdapter);
1155 VOS_STATUS status = VOS_STATUS_SUCCESS;
1156
1157 if(NULL == tlCtxt)
1158 {
1159 TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"Invalid TL handle"));
1160 return VOS_STATUS_E_INVAL;
1161 }
1162
1163 /* Traffic status report is not registered, JUST DO NOTHING */
1164 if(0 == tlCtxt->hoSupport.currentTraffic.idleThreshold)
1165 {
1166 return VOS_STATUS_SUCCESS;
1167 }
1168
Jeff Johnsone7245742012-09-05 17:12:55 -07001169#ifndef FEATURE_WLAN_INTEGRATED_SOC
Jeff Johnson295189b2012-06-20 16:38:30 -07001170 WLANTL_StatHandleTXFrame(pAdapter, STAid, dataBuffer, bdHeader);
Jeff Johnsone7245742012-09-05 17:12:55 -07001171#endif /* FEATURE_WLAN_INTEGRATED_SOC */
Jeff Johnson295189b2012-06-20 16:38:30 -07001172
1173 /* Only Voice traffic is handled as real time traffic */
1174 if(WLANTL_AC_VO == ac)
1175 {
1176 tlCtxt->hoSupport.currentTraffic.rtTXFrameCount++;
1177 }
1178 else
1179 {
1180 tlCtxt->hoSupport.currentTraffic.nrtTXFrameCount++;
1181 }
1182 TLLOG1(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO,"TX frame AC %d, RT Frame Count %d, NRT Frame Count %d",
1183 ac,
1184 tlCtxt->hoSupport.currentTraffic.rtTXFrameCount,
1185 tlCtxt->hoSupport.currentTraffic.nrtTXFrameCount));
1186
1187 return status;
1188}
1189
1190/*==========================================================================
1191
1192 FUNCTION
1193
1194 DESCRIPTION
1195
1196 PARAMETERS
1197
1198 RETURN VALUE
1199
1200============================================================================*/
1201VOS_STATUS WLANTL_HSRegRSSIIndicationCB
1202(
1203 v_PVOID_t pAdapter,
1204 v_S7_t rssiValue,
1205 v_U8_t triggerEvent,
1206 WLANTL_RSSICrossThresholdCBType crossCBFunction,
1207 VOS_MODULE_ID moduleID,
1208 v_PVOID_t usrCtxt
1209)
1210{
1211 WLANTL_CbType *tlCtxt = VOS_GET_TL_CB(pAdapter);
1212 VOS_STATUS status = VOS_STATUS_SUCCESS;
1213 v_U8_t idx, sIdx;
1214 WLANTL_HO_SUPPORT_TYPE *hoSupport;
1215 WLANTL_CURRENT_HO_STATE_TYPE *currentHO;
1216 v_U8_t clientOrder = 0;
1217
1218 if(NULL == tlCtxt)
1219 {
1220 TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"Invalid TL handle"));
1221 return VOS_STATUS_E_INVAL;
1222 }
1223
1224 if((-1 < rssiValue) || (NULL == crossCBFunction))
1225 {
1226 TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"Reg Invalid Argument"));
1227 return VOS_STATUS_E_INVAL;
1228 }
1229
1230 THSGETLOCK("WLANTL_HSRegRSSIIndicationCB", &tlCtxt->hoSupport.hosLock);
1231
1232 currentHO = &(tlCtxt->hoSupport.currentHOState);
1233 hoSupport = &(tlCtxt->hoSupport);
1234 TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"Make Registration Module %d, Event %d, RSSI %d", moduleID, triggerEvent, rssiValue));
1235
1236 if((WLANTL_MAX_AVAIL_THRESHOLD < currentHO->numThreshold) ||
1237 (WLANTL_MAX_AVAIL_THRESHOLD == currentHO->numThreshold))
1238 {
1239 TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"No more available slot, please DEL first %d",
1240 currentHO->numThreshold));
1241 THSRELEASELOCK("WLANTL_HSRegRSSIIndicationCB", &tlCtxt->hoSupport.hosLock);
1242 return VOS_STATUS_E_RESOURCES;
1243 }
1244
1245 if(0 == currentHO->numThreshold)
1246 {
1247 TLLOG1(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO,"First Registration"));
1248 hoSupport->registeredInd[0].rssiValue = rssiValue;
1249 hoSupport->registeredInd[0].triggerEvent[0] = triggerEvent;
1250 hoSupport->registeredInd[0].crossCBFunction[0] = crossCBFunction;
1251 hoSupport->registeredInd[0].usrCtxt[0] = usrCtxt;
1252 hoSupport->registeredInd[0].whoIsClient[0] = moduleID;
1253 hoSupport->registeredInd[0].numClient++;
1254 }
1255 else
1256 {
1257 for(idx = 0; idx < currentHO->numThreshold; idx++)
1258 {
1259 if(rssiValue == hoSupport->registeredInd[idx].rssiValue)
1260 {
1261 for(sIdx = 0; sIdx < WLANTL_HS_NUM_CLIENT; sIdx++)
1262 {
1263 TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"Reg CB P 0x%x, registered CB P 0x%x",
1264 crossCBFunction,
1265 hoSupport->registeredInd[idx].crossCBFunction[sIdx]));
1266 if(crossCBFunction == hoSupport->registeredInd[idx].crossCBFunction[sIdx])
1267 {
1268 TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"Same RSSI %d, Same CB 0x%x already registered",
1269 rssiValue, crossCBFunction));
1270 WLANTL_HSDebugDisplay(pAdapter);
1271 THSRELEASELOCK("WLANTL_HSRegRSSIIndicationCB", &tlCtxt->hoSupport.hosLock);
1272 return status;
1273 }
1274 }
1275
1276 for(sIdx = 0; sIdx < WLANTL_HS_NUM_CLIENT; sIdx++)
1277 {
1278 if(NULL == hoSupport->registeredInd[idx].crossCBFunction[sIdx])
1279 {
1280 clientOrder = sIdx;
1281 break;
1282 }
1283 }
1284 hoSupport->registeredInd[idx].triggerEvent[clientOrder] = triggerEvent;
1285 hoSupport->registeredInd[idx].crossCBFunction[clientOrder] = crossCBFunction;
1286 hoSupport->registeredInd[idx].usrCtxt[clientOrder] = usrCtxt;
1287 hoSupport->registeredInd[idx].whoIsClient[clientOrder] = moduleID;
1288 hoSupport->registeredInd[idx].numClient++;
1289 WLANTL_HSDebugDisplay(pAdapter);
1290 THSRELEASELOCK("WLANTL_HSRegRSSIIndicationCB", &tlCtxt->hoSupport.hosLock);
1291 return status;
1292 }
1293 }
1294 for(idx = 0; idx < currentHO->numThreshold; idx++)
1295 {
1296 if(rssiValue > hoSupport->registeredInd[idx].rssiValue)
1297 {
1298 for(sIdx = (currentHO->numThreshold - 1); (sIdx > idx) || (sIdx == idx); sIdx--)
1299 {
1300 TLLOG1(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO, "Shift %d array to %d", sIdx, sIdx + 1));
1301 memcpy(&hoSupport->registeredInd[sIdx + 1], &hoSupport->registeredInd[sIdx], sizeof(WLANTL_HO_RSSI_INDICATION_TYPE));
1302 memset(&hoSupport->registeredInd[sIdx], 0, sizeof(WLANTL_HO_RSSI_INDICATION_TYPE));
1303 if(0 == sIdx)
1304 {
1305 break;
1306 }
1307 }
1308 TLLOG1(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO,"Put in Here %d", idx));
1309 hoSupport->registeredInd[idx].rssiValue = rssiValue;
1310 hoSupport->registeredInd[idx].triggerEvent[0] = triggerEvent;
1311 hoSupport->registeredInd[idx].crossCBFunction[0] = crossCBFunction;
1312 hoSupport->registeredInd[idx].usrCtxt[0] = usrCtxt;
1313 hoSupport->registeredInd[idx].whoIsClient[0] = moduleID;
1314 hoSupport->registeredInd[idx].numClient++;
1315 break;
1316 }
1317 }
1318 if(currentHO->numThreshold == idx)
1319 {
1320 TLLOG1(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO, "New threshold put in bottom"));
1321
1322 hoSupport->registeredInd[currentHO->numThreshold].rssiValue = rssiValue;
1323 hoSupport->registeredInd[currentHO->numThreshold].triggerEvent[0] = triggerEvent;
1324 hoSupport->registeredInd[currentHO->numThreshold].crossCBFunction[0] = crossCBFunction;
1325 hoSupport->registeredInd[currentHO->numThreshold].usrCtxt[0] = usrCtxt;
1326 hoSupport->registeredInd[currentHO->numThreshold].whoIsClient[0] = moduleID;
1327 hoSupport->registeredInd[currentHO->numThreshold].numClient++;
1328 }
1329 }
1330
1331 currentHO->numThreshold++;
1332 if((VOS_FALSE == tlCtxt->isBMPS) && (rssiValue > currentHO->historyRSSI))
1333 {
1334 TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"Added Threshold above current RSSI level, old RN %d", currentHO->regionNumber));
1335 if(4 > currentHO->regionNumber)
1336 {
1337 currentHO->regionNumber++;
1338 }
1339 else
1340 {
1341 TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"Current region number is max %d, cannot increase anymore", currentHO->regionNumber));
1342 }
1343 TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"increase region number without notification %d", currentHO->regionNumber));
1344 }
1345 else if(VOS_TRUE == tlCtxt->isBMPS)
1346 {
1347 if(0 != currentHO->regionNumber)
1348 {
1349 if(hoSupport->registeredInd[currentHO->regionNumber].rssiValue < rssiValue)
1350 {
1351 currentHO->regionNumber++;
1352 if((WLANTL_HO_THRESHOLD_DOWN == triggerEvent) || (WLANTL_HO_THRESHOLD_CROSS == triggerEvent))
1353 {
1354 TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"Registered RSSI value larger than Current RSSI, and DOWN event, Send Notification"));
Jeff Johnsone7245742012-09-05 17:12:55 -07001355 WLANTL_HSSerializeTlIndication(pAdapter, WLANTL_HO_THRESHOLD_DOWN, usrCtxt, crossCBFunction);
Jeff Johnson295189b2012-06-20 16:38:30 -07001356 }
1357 }
1358 else if((currentHO->regionNumber < (currentHO->numThreshold - 1)) &&
1359 (hoSupport->registeredInd[currentHO->regionNumber + 1].rssiValue > rssiValue))
1360 {
1361 if((WLANTL_HO_THRESHOLD_UP == triggerEvent) || (WLANTL_HO_THRESHOLD_CROSS == triggerEvent))
1362 {
1363 TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"Registered RSSI value smaller than Current RSSI"));
1364 }
1365 }
1366 }
1367 else
1368 {
1369 if(hoSupport->registeredInd[currentHO->regionNumber].rssiValue > rssiValue)
1370 {
1371 if((WLANTL_HO_THRESHOLD_UP == triggerEvent) || (WLANTL_HO_THRESHOLD_CROSS == triggerEvent))
1372 {
1373 TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"Registered RSSI value smaller than Current RSSI"));
1374 }
1375 }
1376 }
1377 }
1378
1379 if((VOS_FALSE == tlCtxt->isBMPS) &&
1380 (rssiValue >= currentHO->historyRSSI) && (0 != currentHO->historyRSSI) &&
1381 ((WLANTL_HO_THRESHOLD_DOWN == triggerEvent) || (WLANTL_HO_THRESHOLD_CROSS == triggerEvent)))
1382 {
1383 TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"Registered RSSI value larger than Current RSSI, and DOWN event, Send Notification"));
Jeff Johnsone7245742012-09-05 17:12:55 -07001384 WLANTL_HSSerializeTlIndication(pAdapter, WLANTL_HO_THRESHOLD_DOWN, usrCtxt, crossCBFunction);
Jeff Johnson295189b2012-06-20 16:38:30 -07001385 }
1386 else if((VOS_FALSE == tlCtxt->isBMPS) &&
1387 (rssiValue < currentHO->historyRSSI) && (0 != currentHO->historyRSSI) &&
1388 ((WLANTL_HO_THRESHOLD_UP == triggerEvent) || (WLANTL_HO_THRESHOLD_CROSS == triggerEvent)))
1389 {
1390 TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"Registered RSSI value smaller than Current RSSI, and UP event, Send Notification"));
Jeff Johnsone7245742012-09-05 17:12:55 -07001391 WLANTL_HSSerializeTlIndication(pAdapter, WLANTL_HO_THRESHOLD_UP, usrCtxt, crossCBFunction);
Jeff Johnson295189b2012-06-20 16:38:30 -07001392 }
1393
1394 if(VOS_TRUE == tlCtxt->isBMPS)
1395 {
1396 TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"Register into FW, now BMPS"));
1397 /* this function holds the lock across a downstream WDA function call, this is violates some lock
1398 ordering checks done on some HLOS see CR323221*/
1399 THSRELEASELOCK("WLANTL_HSRegRSSIIndicationCB", &tlCtxt->hoSupport.hosLock);
1400 WLANTL_SetFWRSSIThresholds(pAdapter);
1401 THSGETLOCK("WLANTL_HSRegRSSIIndicationCB", &tlCtxt->hoSupport.hosLock);
1402 }
1403
1404 WLANTL_HSDebugDisplay(pAdapter);
1405 THSRELEASELOCK("WLANTL_HSRegRSSIIndicationCB", &tlCtxt->hoSupport.hosLock);
1406 return status;
1407}
1408
1409/*==========================================================================
1410
1411 FUNCTION
1412
1413 DESCRIPTION
1414
1415 PARAMETERS
1416
1417 RETURN VALUE
1418
1419============================================================================*/
1420VOS_STATUS WLANTL_HSDeregRSSIIndicationCB
1421(
1422 v_PVOID_t pAdapter,
1423 v_S7_t rssiValue,
1424 v_U8_t triggerEvent,
1425 WLANTL_RSSICrossThresholdCBType crossCBFunction,
1426 VOS_MODULE_ID moduleID
1427)
1428{
1429 WLANTL_CbType *tlCtxt = VOS_GET_TL_CB(pAdapter);
1430 VOS_STATUS status = VOS_STATUS_SUCCESS;
1431 v_U8_t idx, sIdx;
1432 WLANTL_HO_SUPPORT_TYPE *hoSupport;
1433 WLANTL_CURRENT_HO_STATE_TYPE *currentHO;
1434 v_BOOL_t bmpsAbove = VOS_FALSE;
1435
1436 if(NULL == tlCtxt)
1437 {
1438 TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"Invalid TL handle"));
1439 return VOS_STATUS_E_INVAL;
1440 }
1441
1442 if(0 == tlCtxt->hoSupport.currentHOState.numThreshold)
1443 {
1444 TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"Empty list, can not remove"));
1445 return VOS_STATUS_E_EMPTY;
1446 }
1447
1448 THSGETLOCK("WLANTL_HSDeregRSSIIndicationCB", &tlCtxt->hoSupport.hosLock);
1449 currentHO = &(tlCtxt->hoSupport.currentHOState);
1450 hoSupport = &(tlCtxt->hoSupport);
1451
1452 TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"DEL target RSSI %d, event %d", rssiValue, triggerEvent));
1453
1454 if((VOS_TRUE == tlCtxt->isBMPS) && (0 < currentHO->regionNumber))
1455 {
1456 if(rssiValue >= hoSupport->registeredInd[currentHO->regionNumber - 1].rssiValue)
1457 {
1458 bmpsAbove = VOS_TRUE;
1459 TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"Remove Threshold larger than current region"));
1460 }
1461 }
1462
1463 for(idx = 0; idx < currentHO->numThreshold; idx++)
1464 {
1465 if(rssiValue == hoSupport->registeredInd[idx].rssiValue)
1466 {
1467 for(sIdx = 0; sIdx < WLANTL_HS_NUM_CLIENT; sIdx++)
1468 {
1469 if(crossCBFunction == tlCtxt->hoSupport.registeredInd[idx].crossCBFunction[sIdx])
1470 {
1471 tlCtxt->hoSupport.registeredInd[idx].triggerEvent[sIdx] = 0;
1472 tlCtxt->hoSupport.registeredInd[idx].crossCBFunction[sIdx] = NULL;
1473 tlCtxt->hoSupport.registeredInd[idx].usrCtxt[sIdx] = NULL;
1474 tlCtxt->hoSupport.registeredInd[idx].whoIsClient[sIdx] = 0;
1475 tlCtxt->hoSupport.registeredInd[idx].numClient--;
1476 }
1477 }
1478 if(0 != tlCtxt->hoSupport.registeredInd[idx].numClient)
1479 {
1480 TLLOG1(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO,"Found Multiple idx is %d", idx));
1481 WLANTL_HSDebugDisplay(pAdapter);
1482 THSRELEASELOCK("WLANTL_HSDeregRSSIIndicationCB", &tlCtxt->hoSupport.hosLock);
1483 return status;
1484 }
1485 else
1486 {
1487 TLLOG1(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO,"Found Single idx is %d", idx));
1488 break;
1489 }
1490 }
1491 }
1492 if(idx == currentHO->numThreshold)
1493 {
1494 TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"Could not find entry, maybe invalid arg"));
1495 THSRELEASELOCK("WLANTL_HSDeregRSSIIndicationCB", &tlCtxt->hoSupport.hosLock);
1496 return VOS_STATUS_E_INVAL;
1497 }
1498
1499 for(idx = 0; idx < currentHO->numThreshold; idx++)
1500 {
1501 if(rssiValue == hoSupport->registeredInd[idx].rssiValue)
1502 {
1503 if((currentHO->numThreshold - 1) == idx)
1504 {
1505 TLLOG1(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO,"Remove target is last one"));
1506 /* Does not need move any element, just remove last array entry */
1507 }
1508 else
1509 {
1510 for(sIdx = idx; sIdx < (currentHO->numThreshold - 1); sIdx++)
1511 {
1512 TLLOG1(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO,"Shift up from %d to %d", sIdx + 1, sIdx));
1513 memcpy(&hoSupport->registeredInd[sIdx], &hoSupport->registeredInd[sIdx + 1], sizeof(WLANTL_HO_RSSI_INDICATION_TYPE));
1514 }
1515 }
1516 break;
1517 }
1518 }
1519 /* Common remove last array entry */
1520 tlCtxt->hoSupport.registeredInd[currentHO->numThreshold - 1].rssiValue = WLANTL_HO_DEFAULT_RSSI;
1521 for(idx = 0; idx < WLANTL_HS_NUM_CLIENT; idx++)
1522 {
1523 tlCtxt->hoSupport.registeredInd[currentHO->numThreshold - 1].triggerEvent[idx] = WLANTL_HO_THRESHOLD_NA;
1524 tlCtxt->hoSupport.registeredInd[currentHO->numThreshold - 1].crossCBFunction[idx] = NULL;
1525 tlCtxt->hoSupport.registeredInd[currentHO->numThreshold - 1].usrCtxt[idx] = NULL;
1526 tlCtxt->hoSupport.registeredInd[currentHO->numThreshold - 1].whoIsClient[idx] = 0;
1527 tlCtxt->hoSupport.registeredInd[currentHO->numThreshold - 1].numClient = 0;
1528 }
1529
1530 if((VOS_FALSE == tlCtxt->isBMPS) && (rssiValue >= currentHO->historyRSSI))
1531 {
1532 TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"Removed Threshold above current RSSI level, old RN %d", currentHO->regionNumber));
1533 if(0 < currentHO->regionNumber)
1534 {
1535 currentHO->regionNumber--;
1536 }
1537 else
1538 {
1539 TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"Current Region number is 0, cannot decrease anymore"));
1540 }
1541 TLLOG1(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO,"Decrease region number without notification %d", currentHO->regionNumber));
1542 }
1543 else if((VOS_TRUE == tlCtxt->isBMPS) && (VOS_TRUE == bmpsAbove))
1544 {
1545 currentHO->regionNumber--;
1546 }
1547 /* Decrease number of thresholds */
1548 tlCtxt->hoSupport.currentHOState.numThreshold--;
1549 /*Reset the FW notification*/
1550 tlCtxt->hoSupport.currentHOState.fwNotification=0;
1551
1552 if(VOS_TRUE == tlCtxt->isBMPS)
1553 {
1554 TLLOG1(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO,"Register into FW, now BMPS"));
1555 /* this function holds the lock across a downstream WDA function call, this is violates some lock
1556 ordering checks done on some HLOS see CR323221*/
1557 THSRELEASELOCK("WLANTL_HSDeregRSSIIndicationCB", &tlCtxt->hoSupport.hosLock);
1558 WLANTL_SetFWRSSIThresholds(pAdapter);
1559 THSGETLOCK("WLANTL_HSDeregRSSIIndicationCB", &tlCtxt->hoSupport.hosLock);
1560 }
1561
1562 /* Based on new threshold set recalculated current RSSI status */
1563 if(0 < tlCtxt->hoSupport.currentHOState.numThreshold)
1564 {
1565 }
1566 else if(0 == tlCtxt->hoSupport.currentHOState.numThreshold)
1567 {
1568 currentHO->regionNumber = 0;
1569 TLLOGW(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_WARN,"No registered Threshold"));
1570 /* What should do? */
1571 }
1572
1573 WLANTL_HSDebugDisplay(pAdapter);
1574 THSRELEASELOCK("WLANTL_HSDeregRSSIIndicationCB", &tlCtxt->hoSupport.hosLock);
1575 return status;
1576}
1577
1578/*==========================================================================
1579
1580 FUNCTION
1581
1582 DESCRIPTION
1583
1584 PARAMETERS
1585
1586 RETURN VALUE
1587
1588============================================================================*/
1589VOS_STATUS WLANTL_HSSetAlpha
1590(
1591 v_PVOID_t pAdapter,
1592 int valueAlpha
1593)
1594{
1595 WLANTL_CbType *tlCtxt = VOS_GET_TL_CB(pAdapter);
1596 VOS_STATUS status = VOS_STATUS_SUCCESS;
1597
1598 if(NULL == tlCtxt)
1599 {
1600 TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"Invalid TL handle"));
1601 return VOS_STATUS_E_INVAL;
1602 }
1603
1604 THSGETLOCK("WLANTL_HSSetAlpha", &tlCtxt->hoSupport.hosLock);
1605 tlCtxt->hoSupport.currentHOState.alpha = (v_U8_t)valueAlpha;
1606 THSRELEASELOCK("WLANTL_HSSetAlpha", &tlCtxt->hoSupport.hosLock);
1607 return status;
1608}
1609
1610/*==========================================================================
1611
1612 FUNCTION
1613
1614 DESCRIPTION
1615
1616 PARAMETERS
1617
1618 RETURN VALUE
1619
1620============================================================================*/
1621VOS_STATUS WLANTL_HSRegGetTrafficStatus
1622(
1623 v_PVOID_t pAdapter,
1624 v_U32_t idleThreshold,
1625 v_U32_t period,
1626 WLANTL_TrafficStatusChangedCBType trfficStatusCB,
1627 v_PVOID_t usrCtxt
1628)
1629{
1630 WLANTL_CbType *tlCtxt = VOS_GET_TL_CB(pAdapter);
1631 VOS_STATUS status = VOS_STATUS_SUCCESS;
1632
1633 if(NULL == tlCtxt)
1634 {
1635 TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"Invalid TL handle"));
1636 return VOS_STATUS_E_INVAL;
1637 }
1638
1639 if((0 == idleThreshold) || (0 == period) || (NULL == trfficStatusCB))
1640 {
1641 TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"Invalid Argument Passed from SME"));
1642 return VOS_STATUS_E_INVAL;
1643 }
1644
1645 tlCtxt->hoSupport.currentTraffic.idleThreshold = idleThreshold;
1646 tlCtxt->hoSupport.currentTraffic.measurePeriod = period;
1647 tlCtxt->hoSupport.currentTraffic.trafficCB = trfficStatusCB;
1648 tlCtxt->hoSupport.currentTraffic.usrCtxt = usrCtxt;
1649
1650 vos_timer_start(&tlCtxt->hoSupport.currentTraffic.trafficTimer,
1651 tlCtxt->hoSupport.currentTraffic.measurePeriod);
1652
1653 return status;
1654}
1655
1656/*==========================================================================
1657
1658 FUNCTION
1659
1660 DESCRIPTION
1661
1662 PARAMETERS
1663
1664 RETURN VALUE
1665
1666============================================================================*/
1667VOS_STATUS WLANTL_HSInit
1668(
1669 v_PVOID_t pAdapter
1670)
1671{
1672 WLANTL_CbType *tlCtxt = VOS_GET_TL_CB(pAdapter);
1673 VOS_STATUS status = VOS_STATUS_SUCCESS;
1674 v_U8_t idx, sIdx;
1675
1676 if(NULL == tlCtxt)
1677 {
1678 TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"Invalid TL handle"));
1679 return VOS_STATUS_E_INVAL;
1680 }
1681#ifdef WLANTL_HO_UTEST
1682 rssi = 0;
1683 direction = -1;
1684#endif /* WLANTL_HO_UTEST */
1685
1686 /* set default current HO status */
1687 tlCtxt->hoSupport.currentHOState.alpha = WLANTL_HO_DEFAULT_ALPHA;
1688 tlCtxt->hoSupport.currentHOState.historyRSSI = 0;
1689 tlCtxt->hoSupport.currentHOState.numThreshold = 0;
1690 tlCtxt->hoSupport.currentHOState.regionNumber = 0;
1691 tlCtxt->hoSupport.currentHOState.sampleTime = 0;
1692
1693 /* set default current traffic status */
1694 tlCtxt->hoSupport.currentTraffic.trafficStatus.rtTrafficStatus
1695 = WLANTL_HO_RT_TRAFFIC_STATUS_OFF;
1696 tlCtxt->hoSupport.currentTraffic.trafficStatus.nrtTrafficStatus
1697 = WLANTL_HO_NRT_TRAFFIC_STATUS_OFF;
1698 tlCtxt->hoSupport.currentTraffic.idleThreshold = 0;
1699 tlCtxt->hoSupport.currentTraffic.measurePeriod = 0;
1700 tlCtxt->hoSupport.currentTraffic.rtRXFrameCount = 0;
1701 tlCtxt->hoSupport.currentTraffic.rtTXFrameCount = 0;
1702 tlCtxt->hoSupport.currentTraffic.nrtRXFrameCount = 0;
1703 tlCtxt->hoSupport.currentTraffic.nrtTXFrameCount = 0;
1704 tlCtxt->hoSupport.currentTraffic.trafficCB = NULL;
1705
1706 /* Initialize indication array */
1707 for(idx = 0; idx < WLANTL_MAX_AVAIL_THRESHOLD; idx++)
1708 {
1709 for(sIdx = 0; sIdx < WLANTL_HS_NUM_CLIENT; sIdx++)
1710 {
1711 tlCtxt->hoSupport.registeredInd[idx].triggerEvent[sIdx] = WLANTL_HO_THRESHOLD_NA;
1712 tlCtxt->hoSupport.registeredInd[idx].crossCBFunction[sIdx] = NULL;
1713 tlCtxt->hoSupport.registeredInd[idx].usrCtxt[sIdx] = NULL;
1714 tlCtxt->hoSupport.registeredInd[idx].whoIsClient[sIdx] = 0;
1715 }
1716 tlCtxt->hoSupport.registeredInd[idx].rssiValue = WLANTL_HO_DEFAULT_RSSI;
1717 tlCtxt->hoSupport.registeredInd[idx].numClient = 0;
1718 }
1719
1720 vos_timer_init(&tlCtxt->hoSupport.currentTraffic.trafficTimer,
1721 VOS_TIMER_TYPE_SW,
1722 WLANTL_HSTrafficStatusTimerExpired,
1723 pAdapter);
1724
1725
1726 vos_lock_init(&tlCtxt->hoSupport.hosLock);
1727 tlCtxt->hoSupport.macCtxt = vos_get_context(VOS_MODULE_ID_SME, pAdapter);
1728
1729 return status;
1730}
1731
1732
1733/*==========================================================================
1734
1735 FUNCTION WLANTL_HSDeInit
1736
1737 DESCRIPTION
1738
1739 PARAMETERS
1740
1741 RETURN VALUE
1742
1743============================================================================*/
1744
1745VOS_STATUS WLANTL_HSDeInit
1746(
1747 v_PVOID_t pAdapter
1748)
1749{
1750 WLANTL_CbType *tlCtxt = VOS_GET_TL_CB(pAdapter);
1751 VOS_STATUS status = VOS_STATUS_SUCCESS;
1752
1753 if(NULL == tlCtxt)
1754 {
1755 TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"Invalid TL handle"));
1756 return VOS_STATUS_E_INVAL;
1757 }
1758
1759 // Destroy the timer...
1760 status = vos_timer_destroy( &tlCtxt->hoSupport.currentTraffic.trafficTimer );
1761 if ( !VOS_IS_STATUS_SUCCESS( status ) )
1762 {
1763 TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"WLANTL_HSStop: Timer Destroy Fail Status %d", status));
1764 }
1765 return status;
1766}
1767
1768
1769/*==========================================================================
1770
1771 FUNCTION
1772
1773 DESCRIPTION
1774
1775 PARAMETERS
1776
1777 RETURN VALUE
1778
1779============================================================================*/
1780VOS_STATUS WLANTL_HSStop
1781(
1782 v_PVOID_t pAdapter
1783)
1784{
1785 WLANTL_CbType *tlCtxt = VOS_GET_TL_CB(pAdapter);
1786 VOS_STATUS status = VOS_STATUS_SUCCESS;
1787 VOS_TIMER_STATE timerState;
1788
1789 if(NULL == tlCtxt)
1790 {
1791 TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"Invalid TL handle"));
1792 return VOS_STATUS_E_INVAL;
1793 }
1794
1795 timerState = vos_timer_getCurrentState(&tlCtxt->hoSupport.currentTraffic.trafficTimer);
1796 if(VOS_TIMER_STATE_RUNNING == timerState)
1797 {
1798 TLLOG1(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO,"Stop Traffic status monitoring timer"));
1799 status = vos_timer_stop(&tlCtxt->hoSupport.currentTraffic.trafficTimer);
1800 }
1801 if(VOS_STATUS_SUCCESS != status)
1802 {
1803 TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"Timer Stop Failed, Status %d", status));
1804 }
1805
1806 //Deregister the traffic Status
1807 tlCtxt->hoSupport.currentTraffic.idleThreshold = 0;
1808 tlCtxt->hoSupport.currentTraffic.measurePeriod = 0;
1809 tlCtxt->hoSupport.currentTraffic.trafficCB = NULL;
1810 tlCtxt->hoSupport.currentTraffic.usrCtxt = NULL;
1811
1812 return status;
1813}
Jeff Johnsone7245742012-09-05 17:12:55 -07001814
1815/*==========================================================================
1816
1817 FUNCTION
1818
1819 DESCRIPTION
1820
1821 PARAMETERS
1822
1823 RETURN VALUE
1824
1825============================================================================*/
1826VOS_STATUS WLANTL_HSSerializeTlIndication
1827(
1828 v_PVOID_t pAdapter,
1829 v_U8_t rssiNotification,
1830 v_PVOID_t pUserCtxt,
1831 WLANTL_RSSICrossThresholdCBType cbFunction
1832)
1833{
1834 VOS_STATUS status = VOS_STATUS_SUCCESS;
1835 vos_msg_t msg;
1836 WLANTL_TlIndicationReq *pMsg;
1837
1838 pMsg = vos_mem_malloc(sizeof(WLANTL_TlIndicationReq));
1839 if ( NULL == pMsg )
1840 {
1841 VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, "In %s, failed to allocate mem for req", __FUNCTION__);
1842 return VOS_STATUS_E_NOMEM;
1843 }
1844
1845 pMsg->msgType = pal_cpu_to_be16((tANI_U16)eWNI_SME_RSSI_IND);
1846 pMsg->msgLen = (tANI_U16)sizeof(WLANTL_TlIndicationReq);
1847 pMsg->sessionId = 0;//for now just pass 0
1848 pMsg->pAdapter = pAdapter;
1849 pMsg->pUserCtxt = pUserCtxt;
1850 pMsg->rssiNotification = rssiNotification;
1851 pMsg->tlCallback = cbFunction;
1852
1853
1854 msg.type = eWNI_SME_RSSI_IND;
1855 msg.bodyptr = pMsg;
1856 msg.reserved = 0;
1857
1858 if(VOS_STATUS_SUCCESS != vos_mq_post_message(VOS_MQ_ID_SME, &msg))
1859 {
1860 VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, "In %s, failed to post msg to self", __FUNCTION__);
1861 vos_mem_free(pMsg);
1862 status = VOS_STATUS_E_FAILURE;
1863 }
1864
1865 return status;
1866}
1867
1868#endif //FEATURE_WLAN_GEN6_ROAMING || WLAN_FEATURE_NEIGHBOR_ROAMING