blob: 31764cc5626c57684406edc7208c504cb55fbc3b [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
Gopichand Nakkala92f07d82013-01-08 21:16:34 -08002 * Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
3 *
4 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
5 *
6 *
7 * Permission to use, copy, modify, and/or distribute this software for
8 * any purpose with or without fee is hereby granted, provided that the
9 * above copyright notice and this permission notice appear in all
10 * copies.
11 *
12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
13 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
14 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
15 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
16 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
17 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
18 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
19 * PERFORMANCE OF THIS SOFTWARE.
20 */
21/*
Jeff Johnson32d95a32012-09-10 13:15:23 -070022 * Copyright (c) 2012, The Linux Foundation. All rights reserved.
Jeff Johnson295189b2012-06-20 16:38:30 -070023 *
24 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
25 *
26 *
27 * Permission to use, copy, modify, and/or distribute this software for
28 * any purpose with or without fee is hereby granted, provided that the
29 * above copyright notice and this permission notice appear in all
30 * copies.
31 *
32 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
33 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
34 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
35 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
36 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
37 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
38 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
39 * PERFORMANCE OF THIS SOFTWARE.
40 */
41
42/*
43 *
44 * Airgo Networks, Inc proprietary. All rights reserved.
45 * This file limPropExtsUtils.cc contains the utility functions
46 * to populate, parse proprietary extensions required to
47 * support ANI feature set.
48 *
49 * Author: Chandra Modumudi
50 * Date: 11/27/02
51 * History:-
52 * Date Modified by Modification Information
53 * --------------------------------------------------------------------
54 *
55 */
Jeff Johnson295189b2012-06-20 16:38:30 -070056#include "aniGlobal.h"
57#ifdef ANI_PRODUCT_TYPE_AP
58#include "wniCfgAp.h"
59#else
60#include "wniCfgSta.h"
61#endif
62#include "sirCommon.h"
63#include "sirDebug.h"
64#include "utilsApi.h"
65#include "cfgApi.h"
Jeff Johnson295189b2012-06-20 16:38:30 -070066#include "limApi.h"
67#include "limTypes.h"
68#include "limUtils.h"
69#include "limAssocUtils.h"
70#include "limPropExtsUtils.h"
71#include "limSerDesUtils.h"
72#include "limTrace.h"
73#include "limSession.h"
Jeff Johnson295189b2012-06-20 16:38:30 -070074#define LIM_GET_NOISE_MAX_TRY 5
75#if (defined(ANI_PRODUCT_TYPE_AP) || defined(ANI_PRODUCT_TYPE_AP_SDK))
76/**
77 * limGetCurrentLearnChannel()
78 *
79 *FUNCTION:
80 * This function is called in various places to get current channel
81 * number being 'learned'.
82 *
83 *PARAMS:
84 *
85 *LOGIC:
86 *
87 *ASSUMPTIONS:
88 * NA
89 *
90 *NOTE:
91 * NA
92 *
93 * @param pMac Pointer to Global MAC structure
94 * @return Channel number
95 */
96tANI_U8
97limGetCurrentLearnChannel(tpAniSirGlobal pMac)
98{
99 tANI_U8 *pChanNum = pMac->lim.gpLimMeasReq->channelList.channelNumber;
Jeff Johnson295189b2012-06-20 16:38:30 -0700100 return (*(pChanNum + pMac->lim.gLimMeasParams.nextLearnChannelId));
101} /*** end limGetCurrentLearnChannel() ***/
102#endif //#if (defined(ANI_PRODUCT_TYPE_AP) || defined(ANI_PRODUCT_TYPE_AP_SDK))
Jeff Johnson295189b2012-06-20 16:38:30 -0700103/**
104 * limExtractApCapability()
105 *
106 *FUNCTION:
107 * This function is called to extract AP's HCF/WME/WSM capability
108 * from the IEs received from it in Beacon/Probe Response frames
109 *
110 *LOGIC:
111 *
112 *ASSUMPTIONS:
113 * NA
114 *
115 *NOTE:
116 *
117 * @param pMac Pointer to Global MAC structure
118 * @param pIE Pointer to starting IE in Beacon/Probe Response
119 * @param ieLen Length of all IEs combined
120 * @param qosCap Bits are set according to capabilities
121 * @return 0 - If AP does not assert HCF capability & 1 - otherwise
122 */
Jeff Johnson295189b2012-06-20 16:38:30 -0700123void
124limExtractApCapability(tpAniSirGlobal pMac, tANI_U8 *pIE, tANI_U16 ieLen,
125 tANI_U8 *qosCap, tANI_U16 *propCap, tANI_U8 *uapsd,
Madan Mohan Koyyalamudic6226de2012-09-18 16:33:31 -0700126 tPowerdBm *localConstraint,
127 tpPESession psessionEntry
Jeff Johnson295189b2012-06-20 16:38:30 -0700128 )
129{
Madan Mohan Koyyalamudi19032762012-10-21 12:42:11 -0700130 tSirProbeRespBeacon *pBeaconStruct;
Jeff Johnson295189b2012-06-20 16:38:30 -0700131#if !defined WLAN_FEATURE_VOWIFI
132 tANI_U32 localPowerConstraints = 0;
133#endif
Madan Mohan Koyyalamudi19032762012-10-21 12:42:11 -0700134 if(eHAL_STATUS_SUCCESS != palAllocateMemory(pMac->hHdd,
135 (void **)&pBeaconStruct, sizeof(tSirProbeRespBeacon)))
136 {
137 limLog(pMac, LOGE, FL("Unable to PAL allocate memory in limExtractApCapability\n") );
138 return;
139 }
140
141 palZeroMemory( pMac->hHdd, (tANI_U8 *) pBeaconStruct, sizeof(tSirProbeRespBeacon));
Jeff Johnson295189b2012-06-20 16:38:30 -0700142 *qosCap = 0;
143 *propCap = 0;
144 *uapsd = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -0700145 PELOG3(limLog( pMac, LOG3,
146 FL("In limExtractApCapability: The IE's being received are:\n"));
147 sirDumpBuf( pMac, SIR_LIM_MODULE_ID, LOG3, pIE, ieLen );)
Madan Mohan Koyyalamudi19032762012-10-21 12:42:11 -0700148 if (sirParseBeaconIE(pMac, pBeaconStruct, pIE, (tANI_U32)ieLen) == eSIR_SUCCESS)
Jeff Johnson295189b2012-06-20 16:38:30 -0700149 {
150#if (WNI_POLARIS_FW_PACKAGE == ADVANCED)
Madan Mohan Koyyalamudi19032762012-10-21 12:42:11 -0700151 if (pBeaconStruct->propIEinfo.hcfEnabled)
Jeff Johnson295189b2012-06-20 16:38:30 -0700152 LIM_BSS_CAPS_SET(HCF, *qosCap);
153#endif
Madan Mohan Koyyalamudi19032762012-10-21 12:42:11 -0700154 if (pBeaconStruct->wmeInfoPresent || pBeaconStruct->wmeEdcaPresent)
Jeff Johnson295189b2012-06-20 16:38:30 -0700155 LIM_BSS_CAPS_SET(WME, *qosCap);
Madan Mohan Koyyalamudi19032762012-10-21 12:42:11 -0700156 if (LIM_BSS_CAPS_GET(WME, *qosCap) && pBeaconStruct->wsmCapablePresent)
Jeff Johnson295189b2012-06-20 16:38:30 -0700157 LIM_BSS_CAPS_SET(WSM, *qosCap);
Madan Mohan Koyyalamudi19032762012-10-21 12:42:11 -0700158 if (pBeaconStruct->propIEinfo.aniIndicator &&
159 pBeaconStruct->propIEinfo.capabilityPresent)
160 *propCap = pBeaconStruct->propIEinfo.capability;
161 if (pBeaconStruct->HTCaps.present)
Jeff Johnson295189b2012-06-20 16:38:30 -0700162 pMac->lim.htCapabilityPresentInBeacon = 1;
163 else
164 pMac->lim.htCapabilityPresentInBeacon = 0;
165
Jeff Johnsone7245742012-09-05 17:12:55 -0700166#ifdef WLAN_FEATURE_11AC
Jeff Johnson32d95a32012-09-10 13:15:23 -0700167 VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO_MED,
Madan Mohan Koyyalamudi19032762012-10-21 12:42:11 -0700168 "***beacon.VHTCaps.present*****=%d\n",pBeaconStruct->VHTCaps.present);
Shailender Karmuchi08f87c22013-01-17 12:51:24 -0800169 VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO_MED,
170 "***beacon.SU Beamformer Capable*****=%d\n",pBeaconStruct->VHTCaps.suBeamFormerCap);
Jeff Johnsone7245742012-09-05 17:12:55 -0700171
Madan Mohan Koyyalamudi19032762012-10-21 12:42:11 -0700172 if ( pBeaconStruct->VHTCaps.present && pBeaconStruct->VHTOperation.present)
Jeff Johnsone7245742012-09-05 17:12:55 -0700173 {
Madan Mohan Koyyalamudic6226de2012-09-18 16:33:31 -0700174 psessionEntry->vhtCapabilityPresentInBeacon = 1;
Madan Mohan Koyyalamudi19032762012-10-21 12:42:11 -0700175 psessionEntry->apCenterChan = pBeaconStruct->VHTOperation.chanCenterFreqSeg1;
176 psessionEntry->apChanWidth = pBeaconStruct->VHTOperation.chanWidth;
Jeff Johnsone7245742012-09-05 17:12:55 -0700177 }
178 else
179 {
Madan Mohan Koyyalamudic6226de2012-09-18 16:33:31 -0700180 psessionEntry->vhtCapabilityPresentInBeacon = 0;
Jeff Johnsone7245742012-09-05 17:12:55 -0700181 }
182#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700183 // Extract the UAPSD flag from WMM Parameter element
Madan Mohan Koyyalamudi19032762012-10-21 12:42:11 -0700184 if (pBeaconStruct->wmeEdcaPresent)
185 *uapsd = pBeaconStruct->edcaParams.qosInfo.uapsd;
Jeff Johnson295189b2012-06-20 16:38:30 -0700186#if defined FEATURE_WLAN_CCX
187 /* If there is Power Constraint Element specifically,
188 * adapt to it. Hence there is else condition check
189 * for this if statement.
190 */
Madan Mohan Koyyalamudi19032762012-10-21 12:42:11 -0700191 if ( pBeaconStruct->ccxTxPwr.present)
Jeff Johnson295189b2012-06-20 16:38:30 -0700192 {
Madan Mohan Koyyalamudi19032762012-10-21 12:42:11 -0700193 *localConstraint = pBeaconStruct->ccxTxPwr.power_limit;
Jeff Johnson295189b2012-06-20 16:38:30 -0700194 }
195#endif
Madan Mohan Koyyalamudi19032762012-10-21 12:42:11 -0700196 if (pBeaconStruct->powerConstraintPresent)
Jeff Johnsone7245742012-09-05 17:12:55 -0700197#if 0
198 //Remove this check. This function is expected to return localPowerConsraints
199 //and it should just do that. Check for 11h enabled or not can be done at the caller
Jeff Johnson295189b2012-06-20 16:38:30 -0700200#if defined WLAN_FEATURE_VOWIFI
Jeff Johnsone7245742012-09-05 17:12:55 -0700201 && ( pMac->lim.gLim11hEnable
202 || pMac->rrm.rrmPEContext.rrmEnable
Jeff Johnson295189b2012-06-20 16:38:30 -0700203#endif
Jeff Johnsone7245742012-09-05 17:12:55 -0700204#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700205 {
206#if defined WLAN_FEATURE_VOWIFI
Madan Mohan Koyyalamudi19032762012-10-21 12:42:11 -0700207 *localConstraint -= pBeaconStruct->localPowerConstraint.localPowerConstraints;
Jeff Johnson295189b2012-06-20 16:38:30 -0700208#else
Madan Mohan Koyyalamudi19032762012-10-21 12:42:11 -0700209 localPowerConstraints = (tANI_U32)pBeaconStruct->localPowerConstraint.localPowerConstraints;
Jeff Johnson295189b2012-06-20 16:38:30 -0700210#endif
211 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700212#if !defined WLAN_FEATURE_VOWIFI
213 if (cfgSetInt(pMac, WNI_CFG_LOCAL_POWER_CONSTRAINT, localPowerConstraints) != eSIR_SUCCESS)
214 {
215 limLog(pMac, LOGP, FL("Could not update local power constraint to cfg.\n"));
216 }
217#endif
218 }
Madan Mohan Koyyalamudi19032762012-10-21 12:42:11 -0700219 palFreeMemory(pMac->hHdd, pBeaconStruct);
Jeff Johnson295189b2012-06-20 16:38:30 -0700220 return;
221} /****** end limExtractApCapability() ******/
222
Jeff Johnson295189b2012-06-20 16:38:30 -0700223#if (defined(ANI_PRODUCT_TYPE_AP) || defined(ANI_PRODUCT_TYPE_AP_SDK))
224/**
225 * limQuietBss()
226 *
227 *FUNCTION:
228 * This function is called to quiet the BSS
229 * while entering into Learn mode
230 *
231 *LOGIC:
232 * Data frame to self with duration value passed is
233 * transmitted
234 *
235 *ASSUMPTIONS:
236 * NA
237 *
238 *NOTE:
239 * If all associated STAs are 11h compliant, Quiet IE
240 * need to be sent in Beacon/Probe Response frames.
241 *
242 * @param pMac Pointer to Global MAC structure
243 * @param duration Specifies quiet duration in millisec
244 * @return None
245 */
Jeff Johnson295189b2012-06-20 16:38:30 -0700246void
247limQuietBss(tpAniSirGlobal pMac, tANI_U32 duration)
248{
Jeff Johnson295189b2012-06-20 16:38:30 -0700249 // Temporarily not quieting BSS
250 (void) pMac; (void) duration;
251 return;
252} /****** end limQuietBss() ******/
253
Jeff Johnson295189b2012-06-20 16:38:30 -0700254/**
255 * limIsMatrixNodePresent()
256 *
257 *FUNCTION:
258 * This function is called to determine if measurements are
259 * already made on the current learn channel
260 *
261 *LOGIC:
262 *
263 *ASSUMPTIONS:
264 * NA
265 *
266 *NOTE:
267 * NA
268 *
269 * @param pMac - Pointer to Global MAC structure
270 * @return pNode - Pointer to Matrix node if found. Else NULL
271 */
Jeff Johnson295189b2012-06-20 16:38:30 -0700272static tpLimMeasMatrixNode
273limIsMatrixNodePresent(tpAniSirGlobal pMac)
274{
275 tANI_U8 i, chanNum = limGetCurrentLearnChannel(pMac);
276 tpLimMeasMatrixNode pNode = pMac->lim.gpLimMeasData->pMeasMatrixInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -0700277 if (!pNode)
278 return NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -0700279 for (i = 0; i < pMac->lim.gpLimMeasReq->channelList.numChannels; i++)
280 {
281 if (pNode->matrix.channelNumber == chanNum)
282 {
283 return pNode;
284 }
285 else
286 {
287 if (pNode->next)
288 pNode = pNode->next;
289 else
290 break;
291 }
292 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700293 return NULL;
294} /****** end limIsMatrixNodePresent() ******/
295
Jeff Johnson295189b2012-06-20 16:38:30 -0700296/**
297 * limGetMatrixNode()
298 *
299 *FUNCTION:
300 * This function is called to get a metrics node associated
301 * with the current measurement channel. If no node is found
302 * for this channel, one is added at the beginning of the list.
303 *
304 *LOGIC:
305 *
306 *ASSUMPTIONS:
307 * NA
308 *
309 *NOTE:
310 * NA
311 *
312 * @param pMac Pointer to Global MAC structure
313 * @return None
314 */
Jeff Johnson295189b2012-06-20 16:38:30 -0700315static tpLimMeasMatrixNode
316limGetMatrixNode(tpAniSirGlobal pMac)
317{
318 tpLimMeasMatrixNode pNewMatrix;
319 eHalStatus status;
Jeff Johnson295189b2012-06-20 16:38:30 -0700320 pNewMatrix = limIsMatrixNodePresent(pMac);
321 if (!pNewMatrix)
322 {
323 // Making first time measurements on this channel.
324 // Add matrix node for this at the front.
325 status = palAllocateMemory( pMac->hHdd, (void **)&pNewMatrix, sizeof(*pNewMatrix));
326 if (status != eHAL_STATUS_SUCCESS)
327 {
328 /// Could not allocate buffer for new measMatrix Node
329 // Log error
330 limLog(pMac, LOGP,
331 FL("palAllocateMemory failed for new measMatrix Node\n"));
332 return NULL;
333 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700334 status = palZeroMemory( pMac->hHdd, (void *)pNewMatrix, sizeof(*pNewMatrix));
335 if (status != eHAL_STATUS_SUCCESS)
336 {
337 /// Could not allocate buffer for new measMatrix Node
338 // Log error
339 limLog(pMac, LOGP,
340 FL("palZeroMemory failed for new measMatrix Node\n"));
341 return NULL;
342 }
343
344 pNewMatrix->matrix.channelNumber =
345 limGetCurrentLearnChannel(pMac);
346 pNewMatrix->avgRssi = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -0700347 PELOG3(limLog(pMac, LOG3, FL("Adding new Matrix info:channel#=%d\n"),
348 pNewMatrix->matrix.channelNumber);)
Jeff Johnson295189b2012-06-20 16:38:30 -0700349 pNewMatrix->next = pMac->lim.gpLimMeasData->pMeasMatrixInfo;
350 pMac->lim.gpLimMeasData->pMeasMatrixInfo = pNewMatrix;
351 pMac->lim.gpLimMeasData->numMatrixNodes++;
352 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700353 return pNewMatrix;
354} /****** end limGetMatrixNode() ******/
355
Jeff Johnson295189b2012-06-20 16:38:30 -0700356/**
357 * limComputeAvg()
358 *
359 *FUNCTION:
360 * This function is called to compute exponential average
361 * of RSSI, channel utilization etc.
362 *
363 *LOGIC:
364 *
365 *ASSUMPTIONS:
366 * NA
367 *
368 *NOTE:
369 * NA
370 *
371 * @param pMac Pointer to Global MAC structure
372 * @param oldVal Previous averaged value
373 * @param newVal New averaged value
374 * @return None
375 */
Jeff Johnson295189b2012-06-20 16:38:30 -0700376tANI_U32
377limComputeAvg(tpAniSirGlobal pMac, tANI_U32 oldVal, tANI_U32 newVal)
378{
379 return (halExpAvg(newVal,
380 oldVal,
381 pMac->lim.gLimMeasParams.rssiAlpha));
382} /****** end limComputeAvg() ******/
383
Jeff Johnson295189b2012-06-20 16:38:30 -0700384/**
385 * limCollectRSSI()
386 *
387 *FUNCTION:
388 * This function is called to collect RSSI measurements on
389 * the current learn channel
390 *
391 *LOGIC:
392 *
393 *ASSUMPTIONS:
394 * NA
395 *
396 *NOTE:
397 * NA
398 *
399 * @param pMac Pointer to Global MAC structure
400 * @return None
401 */
Jeff Johnson295189b2012-06-20 16:38:30 -0700402void
403limCollectRSSI(tpAniSirGlobal pMac)
404{
405 tpLimMeasMatrixNode pNewMatrix = limGetMatrixNode(pMac);
406 tANI_U32 i, noise;
Jeff Johnson295189b2012-06-20 16:38:30 -0700407 for (i = 0; i < LIM_GET_NOISE_MAX_TRY; i++)
408 if ((noise = halGetNoise(pMac)) != HAL_NOISE_INVALID)
409 {
410 pNewMatrix->avgRssi = limComputeAvg(pMac,
411 pNewMatrix->avgRssi,
412 noise);
413 break;
414 }
415} /****** end limCollectRSSI() ******/
416
Jeff Johnson295189b2012-06-20 16:38:30 -0700417/**----------------------------------------------------------------------------
418\fn limGetNeighbourBssNode
Jeff Johnson295189b2012-06-20 16:38:30 -0700419\brief returns neighbour bss node if it is already present in the list.
420\param pMac
421\param bssid - Bssid of new beacon or data packet.
422\param pSsId - Pointer to SSID of new packet.
423\param nwType - 11b/g/a
424\param chanId - Channel in which we received the packet.
Jeff Johnson295189b2012-06-20 16:38:30 -0700425\return tpLimNeighborBssWdsNode or NULL
426-------------------------------------------------------------------------------*/
427static tpLimNeighborBssWdsNode
428limGetNeighbourBssNode(tpAniSirGlobal pMac, tANI_U8 *bssId, tANI_U8 chanId,
429 tSirNwType nwType, tpAniSSID pSsId, tANI_U8 type)
430{
431 tpLimNeighborBssWdsNode pNode = pMac->lim.gpLimMeasData->pNeighborWdsInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -0700432 while (pNode)
433 {
434 //Do we need to check for ssId also ?
435 if (palEqualMemory(pMac->hHdd, pNode->info.neighborBssInfo.bssId,
436 bssId, sizeof(tSirMacAddr)) &&
437 (pNode->info.neighborBssInfo.channelId == chanId))
438 {
439#if 0
440/** Commented out assuming that comparing bssId and ChanId would be enough to
441uniquely identify a particular BSS, Uncomment if strict checking is needed,
442eventhough not possible if packet type is DATA. */
443 if (type == eSIR_MAC_MGMT_FRAME)
444 {
445 /** Beacon Frame */
446 if (palEqualMemory(pMac->hHdd, &pNode->info.neighborBssInfo.ssId,
447 pSsId, pSsId->length+1) &&
448 (pNode->info.neighborBssInfo.nwType == nwType))
449 {
450 return pNode;
451 }
452 }
453 else
454#endif
455 return pNode;
456 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700457 if (!pNode->next)
458 break;
459 else
460 pNode = pNode->next;
461 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700462 return NULL;
463}
464
Jeff Johnson295189b2012-06-20 16:38:30 -0700465/**
466 * limCollectMeasurementData()
467 *
468 *FUNCTION:
469 * This function is called upon receiving Beacon/Probe Response
470 * or Data frames to collect measurement related data.
471 *
472 *LOGIC:
473 *
474 *ASSUMPTIONS:
475 * NA
476 *
477 *NOTE:
478 * NA
479 *
480 * @param pMac - Pointer to Global MAC structure
481 * @param pRxPacketInfo - Pointer to received BD+payload
482 * @param pBeacon - Pointer to parsed BSS info
483 * @return None
484 */
Jeff Johnson295189b2012-06-20 16:38:30 -0700485void
486limCollectMeasurementData(tpAniSirGlobal pMac,
487 tANI_U32 *pRxPacketInfo, tpSchBeaconStruct pBeacon)
488{
489 tANI_U16 allocLen=0, len=0, realLen=0, ieLen=0;
490 tANI_U32 i;
491 tANI_U8 found = eANI_BOOLEAN_TRUE;
492 tSirMacFrameCtl fc ;
493 tSirMacAddr bssIdRcv;
494 tSirNwType nwType;
495 tAniSSID ssId;
496 tANI_U8 chanId = 0;
497 tpLimNeighborBssWdsNode pNode = NULL;
498 tpLimMeasMatrixNode pNewMatrix;
499 eHalStatus status;
500 tpSirMacMgmtHdr pHdr;
Jeff Johnson295189b2012-06-20 16:38:30 -0700501 PELOG3(limLog(pMac, LOG3, FL("Collecting measurement data for RadioId %d\n"),
502 pMac->sys.gSirRadioId);)
Jeff Johnson295189b2012-06-20 16:38:30 -0700503 tANI_U32 ignore = 0;
504 limGetBssidFromBD(pMac, (tpHalBufDesc) pRxPacketInfo, bssIdRcv, &ignore);
505 if (palEqualMemory( pMac->hHdd, bssIdRcv, pMac->lim.gLimBssid, sizeof(tSirMacAddr)))
506 {
507 // Packet received from our own BSS, dont take measurement.
508 return;
509 }
510 pHdr = WDA_GET_RX_MAC_HEADER(pRxPacketInfo);
511 fc = pHdr->fc;
Jeff Johnson295189b2012-06-20 16:38:30 -0700512 if (fc.type == SIR_MAC_DATA_FRAME)
513 {
514 PELOG2(limLog(pMac, LOG2, FL("Received DATA packet\n"));)
515 ssId.length = 0;
516 ieLen = 0;
517 }
518 else
519 {
520 /** Probe response or beaccon packet */
521 palCopyMemory(pMac->hHdd, (void *)&ssId, (void *) &pBeacon->ssId,
522 sizeof(ssId));
523 chanId = limGetChannelFromBeacon(pMac, pBeacon);
524 ieLen = pBeacon->wpa.length + pBeacon->propIEinfo.wdsLength;
525 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700526 if (chanId == 0)
527 {
528 /* If the channel Id is not retrieved from Beacon, extract the channel from BD */
529 /* Unmapped the channel.This We have to do since we have done mapping in the hal to
530 overcome the limitation of RXBD of not able to accomodate the bigger channel number.*/
531 chanId = WDA_GET_RX_CH(pRxPacketInfo);
532 if(!( chanId = limUnmapChannel(chanId)))
533 {
534 chanId = pMac->lim.gLimCurrentScanChannelId;
535 }
536 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700537 /*
538 * Now always returns nwType as 11G for data packets - FIXIT
539 */
540 nwType = limGetNwType(pMac, chanId, fc.type, pBeacon);
Jeff Johnson295189b2012-06-20 16:38:30 -0700541 pNewMatrix = limGetMatrixNode(pMac);
542 /** LOGP would result in freeing all dynamicall allocated memories. So
543 * return from here if limGetMatrixNode returns NULL
544 */
545 if (!pNewMatrix)
546 return;
Jeff Johnson295189b2012-06-20 16:38:30 -0700547 pNewMatrix->matrix.aggrRssi += WDA_GET_RX_RSSI_DB(pRxPacketInfo);
548 pNewMatrix->matrix.totalPackets++;
Jeff Johnson295189b2012-06-20 16:38:30 -0700549 // Find if this neighbor is already 'learned'
550 // If found, update its information.
551 pNode = limGetNeighbourBssNode(pMac, bssIdRcv, chanId, nwType, &ssId, fc.type);
Jeff Johnson295189b2012-06-20 16:38:30 -0700552 if (!pNode)
553 {
554 realLen = sizeof(tSirNeighborBssWdsInfo);
Jeff Johnson295189b2012-06-20 16:38:30 -0700555 /** Newly discovered neighbor. Inform WSM of this
556 * and add this BSS info at the beginning
557 * Need to limit the number newly discovered BSS added
558 * to the list.
559 */
560 len = LIM_MAX_BUF_SIZE - (sizeof(tSirSmeMeasurementInd) +
561 (pMac->lim.gpLimMeasReq->channelList.numChannels *
562 sizeof(tSirMeasMatrixInfo)));
563 PELOG2(limLog(pMac, LOG2, FL("Current BSS length %d, Real length %d\n"),
564 pMac->lim.gpLimMeasData->totalBssSize, realLen);)
Jeff Johnson295189b2012-06-20 16:38:30 -0700565 /** Check if we have enough room for adding a new node.
566 */
567 if (pMac->lim.gpLimMeasData->totalBssSize + realLen < len)
568 {
569 pMac->lim.gpLimMeasData->numBssWds++;
570 pMac->lim.gpLimMeasData->totalBssSize += realLen;
Jeff Johnson295189b2012-06-20 16:38:30 -0700571 PELOG2(limPrintMacAddr(pMac, bssIdRcv, LOG2);)
572 }
573 else
574 {
575 PELOG2(limLog(pMac, LOG2, FL("Dropping the measurement packets: No memory!\n"));)
576 return;
577 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700578 /** Allocate max memory required even if the packet is of type DATA,
579 * So that next time we receive a beacon, won't run out of memory to
580 * update the information.
581 */
582 allocLen = sizeof(tLimNeighborBssWdsNode) + 4 + ieLen;
583 status = palAllocateMemory( pMac->hHdd, (void **)&pNode, allocLen);
Jeff Johnson295189b2012-06-20 16:38:30 -0700584 if (status != eHAL_STATUS_SUCCESS)
585 {
586 limLog(pMac, LOGP, FL("palAllocateMemory failed for new NeighborBssWds Node\n"));
587 return;
588 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700589 status = palZeroMemory(pMac->hHdd, pNode, allocLen);
590 if (status != eHAL_STATUS_SUCCESS)
591 {
592 limLog(pMac, LOGP, FL("palAllocateMemory failed for new NeighborBssWds Node\n"));
593 return;
594 }
595 pNode->next = pMac->lim.gpLimMeasData->pNeighborWdsInfo;
596 pMac->lim.gpLimMeasData->pNeighborWdsInfo = pNode;
597 found = eANI_BOOLEAN_FALSE;
598 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700599 pNode->info.neighborBssInfo.rssi = WDA_GET_RX_RSSI_DB(pRxPacketInfo);
600 pNode->info.neighborBssInfo.aggrRssi += pNode->info.neighborBssInfo.rssi;
601 if (fc.type == SIR_MAC_DATA_FRAME)
602 pNode->info.neighborBssInfo.dataCount++;
603 pNode->info.neighborBssInfo.totalPackets++;
Jeff Johnson295189b2012-06-20 16:38:30 -0700604 /** If node not found or previous learn was not from a beacon/probe rsp
605 * then learn again.
606 */
607 if (!found || ((pNode->info.neighborBssInfo.ssId.length == 0) &&
608 (fc.type == SIR_MAC_MGMT_FRAME)))
609 {
610 palCopyMemory(pMac->hHdd, pNode->info.neighborBssInfo.bssId, bssIdRcv,
611 sizeof(tSirMacAddr));
612 pNode->info.neighborBssInfo.channelId = chanId;
613 if (fc.type == SIR_MAC_DATA_FRAME)
614 {
615 // Data frame received from other BSS.
616 // Collect as much information as possible
617 pNode->info.neighborBssInfo.wniIndicator = (tAniBool) 0;
Jeff Johnson295189b2012-06-20 16:38:30 -0700618 if (fc.toDS || fc.fromDS)
619 pNode->info.neighborBssInfo.bssType = eSIR_INFRASTRUCTURE_MODE;
620 else
621 pNode->info.neighborBssInfo.bssType = eSIR_IBSS_MODE;
Jeff Johnson295189b2012-06-20 16:38:30 -0700622 pNode->info.neighborBssInfo.load.numStas = 0;
623 pNode->info.neighborBssInfo.load.channelUtilization = 0;
624 pNode->info.neighborBssInfo.ssId.length = 0;
625 pNode->info.neighborBssInfo.apName.length = 0;
626 pNode->info.neighborBssInfo.rsnIE.length = 0;
627 pNode->info.wdsInfo.wdsLength = 0;
628 }
629 else
630 {
Jeff Johnson295189b2012-06-20 16:38:30 -0700631 // This must be either Beacon frame or
632 // Probe Response. Copy all relevant information.
633 pNode->info.neighborBssInfo.wniIndicator = (tAniBool) pBeacon->propIEinfo.aniIndicator;
634 pNode->info.neighborBssInfo.bssType = (tSirBssType) pBeacon->capabilityInfo.ibss;
635 pNode->info.neighborBssInfo.load.numStas = pBeacon->propIEinfo.load.numStas;
636 pNode->info.neighborBssInfo.load.channelUtilization = pBeacon->propIEinfo.load.channelUtilization;
637
638 palCopyMemory( pMac->hHdd, (tANI_U8 *) &pNode->info.neighborBssInfo.ssId,
639 &pBeacon->ssId, pBeacon->ssId.length+1);
640 pNode->info.neighborBssInfo.apName.length = pBeacon->propIEinfo.apName.length;
641 palCopyMemory( pMac->hHdd, (tANI_U8 *) pNode->info.neighborBssInfo.apName.name,
642 pBeacon->propIEinfo.apName.name, pBeacon->propIEinfo.apName.length);
Jeff Johnson295189b2012-06-20 16:38:30 -0700643 pNode->info.neighborBssInfo.rsnIE.length = 0;
644 // Add WPA2 information. Before that make sure that memory is available
645 if (pBeacon->rsnPresent && (pBeacon->rsn.length < SIR_MAC_MAX_IE_LENGTH))
646 {
647 pNode->info.neighborBssInfo.rsnIE.length = 2 + pBeacon->rsn.length;
648 pNode->info.neighborBssInfo.rsnIE.rsnIEdata[0] = SIR_MAC_RSN_EID;
649 pNode->info.neighborBssInfo.rsnIE.rsnIEdata[1] = pBeacon->rsn.length;
650 palCopyMemory( pMac->hHdd, (tANI_U8 *) &pNode->info.neighborBssInfo.rsnIE.rsnIEdata[2],
651 pBeacon->rsn.info, pBeacon->rsn.length);
Jeff Johnson295189b2012-06-20 16:38:30 -0700652 PELOG2(limLog(pMac, LOG2, FL("NeighborBss RSN IE, type=%x, length=%x\n"),
653 pNode->info.neighborBssInfo.rsnIE.rsnIEdata[0],
654 pNode->info.neighborBssInfo.rsnIE.rsnIEdata[1]);)
655 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700656 // Add WPA information. Before that make sure that memory is available
657 if (pBeacon->wpaPresent && ((pBeacon->rsn.length + pBeacon->wpa.length) < (SIR_MAC_MAX_IE_LENGTH-2)))
658 {
659 pNode->info.neighborBssInfo.rsnIE.rsnIEdata[pNode->info.neighborBssInfo.rsnIE.length] =
660 SIR_MAC_WPA_EID;
661 pNode->info.neighborBssInfo.rsnIE.rsnIEdata[pNode->info.neighborBssInfo.rsnIE.length + 1] =
662 pBeacon->wpa.length;
Jeff Johnson295189b2012-06-20 16:38:30 -0700663 palCopyMemory( pMac->hHdd,
664 (tANI_U8 *) &pNode->info.neighborBssInfo.rsnIE.rsnIEdata[pNode->info.neighborBssInfo.rsnIE.length + 2],
665 pBeacon->wpa.info, pBeacon->wpa.length);
Jeff Johnson295189b2012-06-20 16:38:30 -0700666 PELOG2(limLog(pMac, LOG2, FL("NeighborBss WPA IE, type=%x, length=%x\n"),
667 pNode->info.neighborBssInfo.rsnIE.rsnIEdata[pNode->info.neighborBssInfo.rsnIE.length],
668 pNode->info.neighborBssInfo.rsnIE.rsnIEdata[pNode->info.neighborBssInfo.rsnIE.length + 1]);)
669 pNode->info.neighborBssInfo.rsnIE.length += 2 + pBeacon->wpa.length;
670 }
671 pNode->info.wdsInfo.wdsLength = (tANI_U16) pBeacon->propIEinfo.wdsLength;
672 palCopyMemory( pMac->hHdd, (tANI_U8 *) pNode->info.wdsInfo.wdsBytes,
673 pBeacon->propIEinfo.wdsData,
674 pBeacon->propIEinfo.wdsLength);
Jeff Johnson295189b2012-06-20 16:38:30 -0700675 pNode->info.neighborBssInfo.capabilityInfo = *((tANI_U16*)&pBeacon->capabilityInfo);
Jeff Johnson295189b2012-06-20 16:38:30 -0700676#if 0
677 if (pBeacon->HTCaps.present)
678 palCopyMemory( pMac->hHdd, (tANI_U8 *)&pNode->info.neighborBssInfo.HTCaps,
679 (tANI_U8 *)&pBeacon->HTCaps, HT_CAPABILITY_IE_SIZE);
680 else
681 pNode->info.neighborBssInfo.HTCaps.present = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -0700682 if (pBeacon->HTInfo.present)
683 palCopyMemory( pMac->hHdd, (tANI_U8 *)&pNode->info.neighborBssInfo.HTInfo,
684 (tANI_U8 *)&pBeacon->HTInfo, HT_INFO_IE_SIZE);
685 else
686 pNode->info.neighborBssInfo.HTInfo.present = 0;
687#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700688 if (pBeacon->suppRatesPresent && (pBeacon->supportedRates.numRates <=
689 SIR_MAC_RATESET_EID_MAX))
690 {
691 pNode->info.neighborBssInfo.operationalRateSet.numRates = pBeacon->supportedRates.numRates;
Jeff Johnson295189b2012-06-20 16:38:30 -0700692 PELOG4(limLog(pMac, LOG4, FL("Supported Rates (%d) : "),
693 pNode->info.neighborBssInfo.operationalRateSet.numRates);)
694 for (i=0; i<pBeacon->supportedRates.numRates; i++)
695 {
696 pNode->info.neighborBssInfo.operationalRateSet.rate[i] = pBeacon->supportedRates.rate[i];
697 PELOG4(limLog(pMac, LOG4, FL("%d "), pBeacon->supportedRates.rate[i]);)
698 }
699 PELOG4(limLog(pMac, LOG4, FL("\n"));)
700 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700701 if (pBeacon->extendedRatesPresent && (pBeacon->extendedRates.numRates <=
702 SIR_MAC_RATESET_EID_MAX))
703 {
704 pNode->info.neighborBssInfo.extendedRateSet.numRates = pBeacon->extendedRates.numRates;
Jeff Johnson295189b2012-06-20 16:38:30 -0700705 PELOG4(limLog(pMac, LOG4, FL("Extended Rates (%d) : "),
706 pNode->info.neighborBssInfo.extendedRateSet.numRates);)
707 for (i=0; i<pBeacon->extendedRates.numRates; i++)
708 {
709 pNode->info.neighborBssInfo.extendedRateSet.rate[i] = pBeacon->extendedRates.rate[i];
710 PELOG4(limLog(pMac, LOG4, FL("%d "), pBeacon->extendedRates.rate[i]);)
711 }
712 }
713 else
714 {
715 pNode->info.neighborBssInfo.extendedRateSet.numRates = 0;
716 }
717 pNode->info.neighborBssInfo.nwType = nwType;
718 pNode->info.neighborBssInfo.hcfEnabled = pBeacon->propIEinfo.hcfEnabled;
719 pNode->info.neighborBssInfo.beaconInterval = pBeacon->beaconInterval;
720 pNode->info.neighborBssInfo.wmeInfoPresent = pBeacon->wmeInfoPresent;
721 pNode->info.neighborBssInfo.wmeEdcaPresent = pBeacon->wmeEdcaPresent;
722 pNode->info.neighborBssInfo.wsmCapablePresent = pBeacon->wsmCapablePresent;
723 pNode->info.neighborBssInfo.propIECapability = pBeacon->propIEinfo.capability;
724 pNode->info.neighborBssInfo.localPowerConstraints = pBeacon->localPowerConstraint.localPowerConstraints;
725 pNode->info.neighborBssInfo.dtimPeriod = pBeacon->tim.dtimPeriod;
726 pNode->info.neighborBssInfo.HTCapsPresent = pBeacon->HTCaps.present;
727 pNode->info.neighborBssInfo.HTInfoPresent = pBeacon->HTInfo.present;
728 }
729 }
730} /****** end limCollectMeasurementData() ******/
Jeff Johnson295189b2012-06-20 16:38:30 -0700731/**
732 * limCleanupMatrixNodes()
733 *
734 *FUNCTION:
735 * This function is called from various places within LIM code
736 * to cleanup channel info matrix collected by learn mode measurements.
737 *
738 *LOGIC:
739 *
740 *ASSUMPTIONS:
741 * NA
742 *
743 *NOTE:
744 * NA
745 *
746 * @param pMac Pointer to Global MAC structure
747 * @return None
748 */
Jeff Johnson295189b2012-06-20 16:38:30 -0700749static void
750limCleanupMatrixNodes(tpAniSirGlobal pMac)
751{
752 if (pMac->lim.gpLimMeasData->pMeasMatrixInfo)
753 {
754 tpLimMeasMatrixNode pNode = pMac->lim.gpLimMeasData->pMeasMatrixInfo;
755 tpLimMeasMatrixNode pNext;
Jeff Johnson295189b2012-06-20 16:38:30 -0700756 while (pNode)
757 {
758 pNext = pNode->next;
759 palFreeMemory( pMac->hHdd, pNode);
Jeff Johnson295189b2012-06-20 16:38:30 -0700760 if (pNext)
761 pNode = pNext;
762 else
763 break;
764 }
765 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700766 pMac->lim.gpLimMeasData->numMatrixNodes = 0;
767 PELOG2(limLog(pMac, LOG2,
768 FL("Cleaned up channel matrix nodes\n"));)
Jeff Johnson295189b2012-06-20 16:38:30 -0700769 pMac->lim.gpLimMeasData->pMeasMatrixInfo = NULL;
770} /****** end limCleanupMatrixNodes() ******/
Jeff Johnson295189b2012-06-20 16:38:30 -0700771/**
772 * limCleanupNeighborBssNodes()
773 *
774 *FUNCTION:
775 * This function is called from various places within LIM code
776 * to cleanup neighbor info collected by learn mode measurements.
777 *
778 *LOGIC:
779 *
780 *ASSUMPTIONS:
781 * NA
782 *
783 *NOTE:
784 * NA
785 *
786 * @param pMac Pointer to Global MAC structure
787 * @return None
788 */
Jeff Johnson295189b2012-06-20 16:38:30 -0700789static void
790limCleanupNeighborBssNodes(tpAniSirGlobal pMac)
791{
792 if (pMac->lim.gpLimMeasData->pNeighborWdsInfo)
793 {
794 tpLimNeighborBssWdsNode pNode =
795 pMac->lim.gpLimMeasData->pNeighborWdsInfo;
796 tpLimNeighborBssWdsNode pNext;
797 while (pNode)
798 {
799 pNext = pNode->next;
800 pMac->lim.gpLimMeasData->numBssWds--;
801 palFreeMemory( pMac->hHdd, pNode);
Jeff Johnson295189b2012-06-20 16:38:30 -0700802 if (pNext)
803 pNode = pNext;
804 else
805 break;
806 }
807 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700808 PELOG2(limLog(pMac, LOG2,
809 FL("Cleaned up neighbor nodes\n"));)
Jeff Johnson295189b2012-06-20 16:38:30 -0700810 pMac->lim.gpLimMeasData->numBssWds = 0;
811 pMac->lim.gpLimMeasData->totalBssSize = 0;
812 pMac->lim.gpLimMeasData->pNeighborWdsInfo = NULL;
813} /****** end limCleanupNeighborBssNodes() ******/
814
Jeff Johnson295189b2012-06-20 16:38:30 -0700815/**
816 * limSendSmeMeasurementInd()
817 *
818 *FUNCTION:
819 * This function is called by limProcessLmmMessages() to
820 * send SME_MEASUREMENT_IND message to WSM.
821 *
822 *LOGIC:
823 *
824 *ASSUMPTIONS:
825 *
826 *NOTE:
827 *
828 * @param pMac - Pointer to Global MAC structure
829 * @return None
830 */
Jeff Johnson295189b2012-06-20 16:38:30 -0700831void
832limSendSmeMeasurementInd(tpAniSirGlobal pMac)
833{
834 tANI_U8 *pMeasInd;
835 tANI_U16 len = 0;
836 tSirMsgQ mmhMsg;
Jeff Johnson295189b2012-06-20 16:38:30 -0700837#ifdef GEN6_TODO
838 //fetch the sessionEntry based on the sessionId
839 //priority - MEDIUM
840 tpPESession sessionEntry;
Jeff Johnson295189b2012-06-20 16:38:30 -0700841 if((sessionEntry = peFindSessionBySessionId(pMac, pMac->lim.gLimMeasParams.measurementIndTimer.sessionId))== NULL)
842 {
843 limLog(pMac, LOGP,FL("Session Does not exist for given sessionID\n"));
844 return;
845 }
846#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700847 if (!pMac->sys.gSysEnableLearnMode ||
848 (pMac->lim.gpLimMeasReq == NULL))
849 {
850 return;
851 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700852 len = sizeof(tSirSmeMeasurementInd) +
853 (pMac->lim.gpLimMeasReq->channelList.numChannels *
854 sizeof(tSirMeasMatrixInfo)) +
855 pMac->lim.gpLimMeasData->totalBssSize;
856 if (len > LIM_MAX_BUF_SIZE)
857 {
858 limLog(pMac, LOGP,
859 FL("len %d numChannels %d numBssWds %d totalBssSize %d\n"),
860 len,
861 pMac->lim.gpLimMeasReq->channelList.numChannels,
862 pMac->lim.gpLimMeasData->numBssWds,
863 pMac->lim.gpLimMeasData->totalBssSize);
864 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700865 PELOG2(limLog(pMac, LOG2, FL("***** Measurement IND size %d\n"), len);)
Jeff Johnson295189b2012-06-20 16:38:30 -0700866 if( eHAL_STATUS_SUCCESS != palAllocateMemory( pMac->hHdd, (void **)&pMeasInd, len))
867 {
868 /// Buffer not available. Log error
869 limLog(pMac, LOGP,
870 FL("call to palAllocateMemory failed for eWNI_SME_MEAS_IND\n"));
Jeff Johnson295189b2012-06-20 16:38:30 -0700871 return;
872 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700873 PELOG3(limLog(pMac, LOG3,
874 FL("Sending eWNI_SME_MEAS_IND on Radio %d, requested len=%d\n"),
875 pMac->sys.gSirRadioId, len);)
Jeff Johnson295189b2012-06-20 16:38:30 -0700876 limMeasurementIndSerDes(pMac, pMeasInd);
Jeff Johnson295189b2012-06-20 16:38:30 -0700877 mmhMsg.type = eWNI_SME_MEASUREMENT_IND;
878 mmhMsg.bodyptr = pMeasInd;
879 mmhMsg.bodyval = 0;
Jeff Johnsone7245742012-09-05 17:12:55 -0700880 MTRACE(macTraceMsgTx(pMac, NO_SESSION, mmhMsg.type));
Jeff Johnson295189b2012-06-20 16:38:30 -0700881 limSysProcessMmhMsgApi(pMac, &mmhMsg, ePROT);
Jeff Johnson295189b2012-06-20 16:38:30 -0700882 // Cleanup neighbor information
883 limCleanupNeighborBssNodes(pMac);
884 limCleanupMatrixNodes(pMac);
885} /*** end limSendSmeMeasurementInd() ***/
886
Jeff Johnson295189b2012-06-20 16:38:30 -0700887/**
888 * limCleanupMeasData()
889 *
890 *FUNCTION:
891 * This function is called from various places within LIM code
892 * to cleanup measurement related data.
893 *
894 *LOGIC:
895 * Buffers and associated timer resources will be deleted when
896 * this function is called
897 *
898 *ASSUMPTIONS:
899 * NA
900 *
901 *NOTE:
902 * NA
903 *
904 * @param pMac Pointer to Global MAC structure
905 * @return None
906 */
Jeff Johnson295189b2012-06-20 16:38:30 -0700907void
908limCleanupMeasData(tpAniSirGlobal pMac)
909{
910 if (pMac->lim.gpLimMeasReq)
911 palFreeMemory( pMac->hHdd, pMac->lim.gpLimMeasReq);
Jeff Johnson295189b2012-06-20 16:38:30 -0700912 pMac->lim.gpLimMeasReq = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -0700913 if (!pMac->lim.gpLimMeasData)
914 return;
Jeff Johnson295189b2012-06-20 16:38:30 -0700915 if (pMac->lim.gpLimMeasData->pMeasMatrixInfo)
916 {
917 // Retain current channel's data and flush remaining
918 tpLimMeasMatrixNode pMatrix =
919 (pMac->lim.gpLimMeasData->pMeasMatrixInfo)->next;
920 tpLimMeasMatrixNode pNext;
Jeff Johnson295189b2012-06-20 16:38:30 -0700921 while (pMatrix)
922 {
923 pNext = pMatrix->next;
924 palFreeMemory( pMac->hHdd, pMatrix);
Jeff Johnson295189b2012-06-20 16:38:30 -0700925 if (pNext)
926 pMatrix = pNext;
927 else
928 break;
929 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700930 pMac->lim.gpLimMeasData->pMeasMatrixInfo->next = NULL;
931 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700932 pMac->lim.gpLimMeasData->numMatrixNodes = 0;
933 PELOG2(limLog(pMac, LOG2,
934 FL("Cleaned up measurement metrics nodes\n"));)
Jeff Johnson295189b2012-06-20 16:38:30 -0700935 // Cleanup neighbor information
936 limCleanupNeighborBssNodes(pMac);
937} /****** end limCleanupMeasData() ******/
Jeff Johnson295189b2012-06-20 16:38:30 -0700938/**---------------------------------------------------------
939\fn limStopMeasTimers
940\brief Stops all measurement related timers.
Jeff Johnson295189b2012-06-20 16:38:30 -0700941\param pMac
942\return None
943 ----------------------------------------------------------*/
944void
945limStopMeasTimers(tpAniSirGlobal pMac)
946{
947 if (pMac->lim.gpLimMeasReq == NULL)
948 return;
Jeff Johnson295189b2012-06-20 16:38:30 -0700949 if (pMac->lim.gpLimMeasReq->measControl.periodicMeasEnabled)
950 {
951 if (tx_timer_deactivate(&pMac->lim.gLimMeasParams.measurementIndTimer) != TX_SUCCESS)
952 {
953 PELOGE(limLog(pMac, LOGE, FL("Cannot stop measurement Ind timer\n"));)
954 }
955 }
956 pMac->lim.gLimMeasParams.isMeasIndTimerActive = 0;
Jeff Johnsone7245742012-09-05 17:12:55 -0700957 MTRACE(macTrace(pMac, TRACE_CODE_TIMER_DEACTIVATE, NO_SESSION, eLIM_LEARN_INTERVAL_TIMER));
Jeff Johnson295189b2012-06-20 16:38:30 -0700958 if (tx_timer_deactivate(&pMac->lim.gLimMeasParams.learnIntervalTimer) != TX_SUCCESS)
959 {
960 PELOGE(limLog(pMac, LOGE, FL("Cannot stop learn interval timer\n"));)
961 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700962 if (pMac->lim.gLimSpecMgmt.fQuietEnabled)
963 {
Jeff Johnsone7245742012-09-05 17:12:55 -0700964 MTRACE(macTrace(pMac, TRACE_CODE_TIMER_DEACTIVATE, NO_SESSION, eLIM_LEARN_DURATION_TIMER));
Jeff Johnson295189b2012-06-20 16:38:30 -0700965 if (tx_timer_deactivate(&pMac->lim.gLimMeasParams.learnDurationTimer) != TX_SUCCESS)
966 {
967 PELOGE(limLog(pMac, LOGE, FL("Cannot stop learn duration timer\n"));)
968 }
969 }
Jeff Johnsone7245742012-09-05 17:12:55 -0700970 MTRACE(macTrace(pMac, TRACE_CODE_TIMER_DEACTIVATE, NO_SESSION, eLIM_LEARN_DURATION_TIMER));
Jeff Johnson295189b2012-06-20 16:38:30 -0700971 if (tx_timer_deactivate(&pMac->lim.gLimMeasParams.learnDurationTimer) != TX_SUCCESS)
972 {
973 PELOGE(limLog(pMac, LOGE, FL("Cannot stop learn duration timer\n"));)
974 }
975}
Jeff Johnson295189b2012-06-20 16:38:30 -0700976/**
977 * limDeleteMeasTimers()
978 *
979 *FUNCTION:
980 * This function is called by limProcessLmmMessages() upon
981 * receiving SME_MEASUREMENT_REQ. This function deletes
982 * timers associated with Measurements.
983 *
984 *LOGIC:
985 *
986 *ASSUMPTIONS:
987 *
988 *NOTE:
989 *
990 * @param pMac Pointer to Global MAC structure
991 * @return None
992 */
Jeff Johnson295189b2012-06-20 16:38:30 -0700993void
994limDeleteMeasTimers(tpAniSirGlobal pMac)
995{
996 if (pMac->lim.gpLimMeasReq->measControl.periodicMeasEnabled)
997 tx_timer_delete(&pMac->lim.gLimMeasParams.measurementIndTimer);
998 tx_timer_delete(&pMac->lim.gLimMeasParams.learnIntervalTimer);
999 tx_timer_delete(&pMac->lim.gLimMeasParams.learnDurationTimer);
1000} /*** end limDeleteMeasTimers() ***/
1001
Jeff Johnson295189b2012-06-20 16:38:30 -07001002/**
1003 * limCleanupMeasResources()
1004 *
1005 *FUNCTION:
1006 * This function is called from various places within LIM code
1007 * to cleanup measurement related data and resources.
1008 *
1009 *LOGIC:
1010 * Buffers and associated timer resources will be deleted when
1011 * this function is called
1012 *
1013 *ASSUMPTIONS:
1014 * NA
1015 *
1016 *NOTE:
1017 * NA
1018 *
1019 * @param pMac Pointer to Global MAC structure
1020 * @return None
1021 */
Jeff Johnson295189b2012-06-20 16:38:30 -07001022void
1023limCleanupMeasResources(tpAniSirGlobal pMac)
1024{
1025 PELOG1( limLog(pMac, LOG1,
1026 FL("Cleaning up Learn mode Measurement resources\n"));)
Jeff Johnson295189b2012-06-20 16:38:30 -07001027 if (pMac->lim.gpLimMeasReq == NULL)
1028 return;
Jeff Johnson295189b2012-06-20 16:38:30 -07001029 limDeleteMeasTimers(pMac);
Jeff Johnson295189b2012-06-20 16:38:30 -07001030 if (pMac->lim.gpLimMeasData)
1031 {
1032 limCleanupMeasData(pMac);
1033 if (pMac->lim.gpLimMeasData->pMeasMatrixInfo)
1034 palFreeMemory( pMac->hHdd, pMac->lim.gpLimMeasData->pMeasMatrixInfo);
Jeff Johnson295189b2012-06-20 16:38:30 -07001035 palFreeMemory( pMac->hHdd, pMac->lim.gpLimMeasData);
1036 pMac->lim.gpLimMeasData = NULL;
1037 }
1038} /****** end limCleanupMeasResources() ******/
1039
Jeff Johnson295189b2012-06-20 16:38:30 -07001040/**
1041 * limDeleteCurrentBssWdsNode()
1042 *
1043 *FUNCTION:
1044 * This function is called when Loss of link
1045 * is detected with AP and its BssWds info node
1046 * to be deleted
1047 *
1048 *LOGIC:
1049 *
1050 *ASSUMPTIONS:
1051 * NA
1052 *
1053 *NOTE:
1054 * NA
1055 *
1056 * @param None
1057 * @return None
1058 */
1059void limDeleteCurrentBssWdsNode(tpAniSirGlobal pMac)
1060{
1061 tANI_U32 cfg = sizeof(tSirMacAddr);
1062 tSirMacAddr currentBssId;
Jeff Johnson295189b2012-06-20 16:38:30 -07001063#if 0
1064 if (wlan_cfgGetStr(pMac, WNI_CFG_BSSID, currentBssId, &cfg) !=
1065 eSIR_SUCCESS)
1066 {
1067 /// Could not get BSSID from CFG. Log error.
1068 limLog(pMac, LOGP, FL("could not retrieve BSSID\n"));
1069 }
1070#endif //TO SUPPORT BT-AMP
1071 sirCopyMacAddr(currentBssId,sessionEntry->bssId);
Jeff Johnson295189b2012-06-20 16:38:30 -07001072 if (!pMac->lim.gpLimMeasData)
1073 return;
Jeff Johnson295189b2012-06-20 16:38:30 -07001074 if (pMac->lim.gpLimMeasData->pNeighborWdsInfo)
1075 {
1076 tpLimNeighborBssWdsNode pNode =
1077 pMac->lim.gpLimMeasData->pNeighborWdsInfo;
1078 tpLimNeighborBssWdsNode pPrev = pNode;
1079 while (pNode)
1080 {
1081 if (palEqualMemory( pMac->hHdd,pNode->info.neighborBssInfo.bssId,
1082 currentBssId,
1083 sizeof(tSirMacAddr)))
1084 {
1085 pMac->lim.gpLimMeasData->numBssWds--;
1086 pPrev->next = pNode->next;
1087 palFreeMemory( pMac->hHdd, pNode);
1088 break;
1089 }
1090 pPrev = pNode;
Jeff Johnson295189b2012-06-20 16:38:30 -07001091 if (pNode->next)
1092 pNode = pNode->next;
1093 else
1094 break;
1095 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001096 if (!pMac->lim.gpLimMeasData->numBssWds)
1097 pMac->lim.gpLimMeasData->pNeighborWdsInfo = NULL;
1098 }
1099} /****** end limDeleteCurrentBssWdsNode() ******/
1100
Jeff Johnson295189b2012-06-20 16:38:30 -07001101/**
1102 * limRestorePreLearnState()
1103 *
1104 *FUNCTION:
1105 * This function is called when Learn duration timer expires
1106 * to restore pre-Learn mode state
1107 *
1108 *LOGIC:
1109 *
1110 *ASSUMPTIONS:
1111 * NA
1112 *
1113 *NOTE:
1114 * NA
1115 *
1116 * @param pMac Pointer to Global MAC structure
1117 * @return None
1118 */
Jeff Johnson295189b2012-06-20 16:38:30 -07001119void
1120limRestorePreLearnState(tpAniSirGlobal pMac)
1121{
1122 PELOG4(limLog(pMac, LOG4,
1123 FL("Restoring from Learn mode on RadioId %d\n"),
1124 pMac->sys.gSirRadioId);)
Jeff Johnson295189b2012-06-20 16:38:30 -07001125 pMac->lim.gLimSystemInScanLearnMode = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07001126 // Go back to previous state.
1127 pMac->lim.gLimSmeState = pMac->lim.gLimPrevSmeState;
1128 pMac->lim.gLimMlmState = pMac->lim.gLimPrevMlmState;
Jeff Johnsone7245742012-09-05 17:12:55 -07001129 MTRACE(macTrace(pMac, TRACE_CODE_SME_STATE, NO_SESSION, pMac->lim.gLimSmeState));
1130 MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, NO_SESSION, pMac->lim.gLimMlmState));
Jeff Johnson295189b2012-06-20 16:38:30 -07001131 PELOG4(limLog(pMac, LOG4,
1132 FL("Restored from Learn mode on RadioId %d\n"),
1133 pMac->sys.gSirRadioId);)
1134} /****** end limRestorePreLearnState() ******/
Jeff Johnson295189b2012-06-20 16:38:30 -07001135#endif //#if (defined(ANI_PRODUCT_TYPE_AP) || (ANI_PRODUCT_TYPE_AP_SDK))
Jeff Johnson295189b2012-06-20 16:38:30 -07001136/**
1137 * limGetHTCBState
1138 *
1139 *FUNCTION:
1140 * This routing provides the translation of Airgo Enum to HT enum for determining
1141 * secondary channel offset.
1142 * Airgo Enum is required for backward compatibility purposes.
1143 *
1144 *
1145 *NOTE:
1146 *
1147 * @param pMac - Pointer to Global MAC structure
1148 * @return The corresponding HT enumeration
1149 */
Jeff Johnsone7245742012-09-05 17:12:55 -07001150ePhyChanBondState limGetHTCBState(ePhyChanBondState aniCBMode)
Jeff Johnson295189b2012-06-20 16:38:30 -07001151{
Jeff Johnsone7245742012-09-05 17:12:55 -07001152 switch ( aniCBMode )
1153 {
1154#ifdef WLAN_FEATURE_11AC
1155 case PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_LOW:
1156 case PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_CENTERED:
1157 case PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_HIGH:
1158#endif
1159 case PHY_DOUBLE_CHANNEL_HIGH_PRIMARY:
1160 return PHY_DOUBLE_CHANNEL_HIGH_PRIMARY;
1161#ifdef WLAN_FEATURE_11AC
1162 case PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_LOW:
1163 case PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_CENTERED:
1164 case PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_HIGH:
1165#endif
1166 case PHY_DOUBLE_CHANNEL_LOW_PRIMARY:
1167 return PHY_DOUBLE_CHANNEL_LOW_PRIMARY;
1168#ifdef WLAN_FEATURE_11AC
1169 case PHY_QUADRUPLE_CHANNEL_20MHZ_CENTERED_40MHZ_CENTERED:
1170 return PHY_SINGLE_CHANNEL_CENTERED;
1171#endif
1172 default :
1173 return PHY_SINGLE_CHANNEL_CENTERED;
1174 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001175}
1176
Jeff Johnsone7245742012-09-05 17:12:55 -07001177 /*
Jeff Johnson295189b2012-06-20 16:38:30 -07001178 * limGetStaPeerType
1179 *
1180 *FUNCTION:
1181 * Based on a combination of the following -
1182 * 1) tDphHashNode.aniPeer
1183 * 2) tDphHashNode.propCapability
1184 * this API determines if a given STA is an ANI peer or not
1185 *
1186 *LOGIC:
1187 *
1188 *ASSUMPTIONS:
1189 *
1190 *NOTE:
1191 *
1192 * @param pMac - Pointer to Global MAC structure
1193 * @param pStaDs - Pointer to the tpDphHashNode of the STA
1194 * under consideration
1195 * @return tStaRateMode
1196 */
1197tStaRateMode limGetStaPeerType( tpAniSirGlobal pMac,
1198 tpDphHashNode pStaDs,
1199 tpPESession psessionEntry)
1200{
1201tStaRateMode staPeerType = eSTA_11b;
Jeff Johnson295189b2012-06-20 16:38:30 -07001202 // Determine the peer-STA type
1203 if( pStaDs->aniPeer )
1204 {
1205 if(PROP_CAPABILITY_GET( TAURUS, pStaDs->propCapability ))
1206 staPeerType = eSTA_TAURUS;
1207 else if( PROP_CAPABILITY_GET( TITAN, pStaDs->propCapability ))
1208 staPeerType = eSTA_TITAN;
1209 else
1210 staPeerType = eSTA_POLARIS;
1211 }
Jeff Johnsone7245742012-09-05 17:12:55 -07001212#ifdef WLAN_FEATURE_11AC
1213 else if(pStaDs->mlmStaContext.vhtCapability)
1214 staPeerType = eSTA_11ac;
1215#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07001216 else if(pStaDs->mlmStaContext.htCapability)
1217 staPeerType = eSTA_11n;
1218 else if(pStaDs->erpEnabled)
1219 staPeerType = eSTA_11bg;
1220 else if(psessionEntry->limRFBand == SIR_BAND_5_GHZ)
1221 staPeerType = eSTA_11a;
Jeff Johnson295189b2012-06-20 16:38:30 -07001222 return staPeerType;
1223}
1224