blob: d36f8b6292107ee3c54a5bbcdf03a86fb89fd6a0 [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"
66#ifdef FEATURE_WLAN_NON_INTEGRATED_SOC
67#include "halCommonApi.h"
68#endif
69#include "limApi.h"
70#include "limTypes.h"
71#include "limUtils.h"
72#include "limAssocUtils.h"
73#include "limPropExtsUtils.h"
74#include "limSerDesUtils.h"
75#include "limTrace.h"
76#include "limSession.h"
Jeff Johnson295189b2012-06-20 16:38:30 -070077#define LIM_GET_NOISE_MAX_TRY 5
78#if (defined(ANI_PRODUCT_TYPE_AP) || defined(ANI_PRODUCT_TYPE_AP_SDK))
79/**
80 * limGetCurrentLearnChannel()
81 *
82 *FUNCTION:
83 * This function is called in various places to get current channel
84 * number being 'learned'.
85 *
86 *PARAMS:
87 *
88 *LOGIC:
89 *
90 *ASSUMPTIONS:
91 * NA
92 *
93 *NOTE:
94 * NA
95 *
96 * @param pMac Pointer to Global MAC structure
97 * @return Channel number
98 */
99tANI_U8
100limGetCurrentLearnChannel(tpAniSirGlobal pMac)
101{
102 tANI_U8 *pChanNum = pMac->lim.gpLimMeasReq->channelList.channelNumber;
Jeff Johnson295189b2012-06-20 16:38:30 -0700103 return (*(pChanNum + pMac->lim.gLimMeasParams.nextLearnChannelId));
104} /*** end limGetCurrentLearnChannel() ***/
105#endif //#if (defined(ANI_PRODUCT_TYPE_AP) || defined(ANI_PRODUCT_TYPE_AP_SDK))
Jeff Johnson295189b2012-06-20 16:38:30 -0700106/**
107 * limExtractApCapability()
108 *
109 *FUNCTION:
110 * This function is called to extract AP's HCF/WME/WSM capability
111 * from the IEs received from it in Beacon/Probe Response frames
112 *
113 *LOGIC:
114 *
115 *ASSUMPTIONS:
116 * NA
117 *
118 *NOTE:
119 *
120 * @param pMac Pointer to Global MAC structure
121 * @param pIE Pointer to starting IE in Beacon/Probe Response
122 * @param ieLen Length of all IEs combined
123 * @param qosCap Bits are set according to capabilities
124 * @return 0 - If AP does not assert HCF capability & 1 - otherwise
125 */
Jeff Johnson295189b2012-06-20 16:38:30 -0700126void
127limExtractApCapability(tpAniSirGlobal pMac, tANI_U8 *pIE, tANI_U16 ieLen,
128 tANI_U8 *qosCap, tANI_U16 *propCap, tANI_U8 *uapsd,
Madan Mohan Koyyalamudic6226de2012-09-18 16:33:31 -0700129 tPowerdBm *localConstraint,
130 tpPESession psessionEntry
Jeff Johnson295189b2012-06-20 16:38:30 -0700131 )
132{
Madan Mohan Koyyalamudi19032762012-10-21 12:42:11 -0700133 tSirProbeRespBeacon *pBeaconStruct;
Jeff Johnson295189b2012-06-20 16:38:30 -0700134#if !defined WLAN_FEATURE_VOWIFI
135 tANI_U32 localPowerConstraints = 0;
136#endif
Madan Mohan Koyyalamudi19032762012-10-21 12:42:11 -0700137 if(eHAL_STATUS_SUCCESS != palAllocateMemory(pMac->hHdd,
138 (void **)&pBeaconStruct, sizeof(tSirProbeRespBeacon)))
139 {
140 limLog(pMac, LOGE, FL("Unable to PAL allocate memory in limExtractApCapability\n") );
141 return;
142 }
143
144 palZeroMemory( pMac->hHdd, (tANI_U8 *) pBeaconStruct, sizeof(tSirProbeRespBeacon));
Jeff Johnson295189b2012-06-20 16:38:30 -0700145 *qosCap = 0;
146 *propCap = 0;
147 *uapsd = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -0700148 PELOG3(limLog( pMac, LOG3,
149 FL("In limExtractApCapability: The IE's being received are:\n"));
150 sirDumpBuf( pMac, SIR_LIM_MODULE_ID, LOG3, pIE, ieLen );)
Madan Mohan Koyyalamudi19032762012-10-21 12:42:11 -0700151 if (sirParseBeaconIE(pMac, pBeaconStruct, pIE, (tANI_U32)ieLen) == eSIR_SUCCESS)
Jeff Johnson295189b2012-06-20 16:38:30 -0700152 {
153#if (WNI_POLARIS_FW_PACKAGE == ADVANCED)
Madan Mohan Koyyalamudi19032762012-10-21 12:42:11 -0700154 if (pBeaconStruct->propIEinfo.hcfEnabled)
Jeff Johnson295189b2012-06-20 16:38:30 -0700155 LIM_BSS_CAPS_SET(HCF, *qosCap);
156#endif
Madan Mohan Koyyalamudi19032762012-10-21 12:42:11 -0700157 if (pBeaconStruct->wmeInfoPresent || pBeaconStruct->wmeEdcaPresent)
Jeff Johnson295189b2012-06-20 16:38:30 -0700158 LIM_BSS_CAPS_SET(WME, *qosCap);
Madan Mohan Koyyalamudi19032762012-10-21 12:42:11 -0700159 if (LIM_BSS_CAPS_GET(WME, *qosCap) && pBeaconStruct->wsmCapablePresent)
Jeff Johnson295189b2012-06-20 16:38:30 -0700160 LIM_BSS_CAPS_SET(WSM, *qosCap);
Madan Mohan Koyyalamudi19032762012-10-21 12:42:11 -0700161 if (pBeaconStruct->propIEinfo.aniIndicator &&
162 pBeaconStruct->propIEinfo.capabilityPresent)
163 *propCap = pBeaconStruct->propIEinfo.capability;
164 if (pBeaconStruct->HTCaps.present)
Jeff Johnson295189b2012-06-20 16:38:30 -0700165 pMac->lim.htCapabilityPresentInBeacon = 1;
166 else
167 pMac->lim.htCapabilityPresentInBeacon = 0;
168
Jeff Johnsone7245742012-09-05 17:12:55 -0700169#ifdef WLAN_FEATURE_11AC
Jeff Johnson32d95a32012-09-10 13:15:23 -0700170 VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO_MED,
Madan Mohan Koyyalamudi19032762012-10-21 12:42:11 -0700171 "***beacon.VHTCaps.present*****=%d\n",pBeaconStruct->VHTCaps.present);
Jeff Johnsone7245742012-09-05 17:12:55 -0700172
Madan Mohan Koyyalamudi19032762012-10-21 12:42:11 -0700173 if ( pBeaconStruct->VHTCaps.present && pBeaconStruct->VHTOperation.present)
Jeff Johnsone7245742012-09-05 17:12:55 -0700174 {
Madan Mohan Koyyalamudic6226de2012-09-18 16:33:31 -0700175 psessionEntry->vhtCapabilityPresentInBeacon = 1;
Madan Mohan Koyyalamudi19032762012-10-21 12:42:11 -0700176 psessionEntry->apCenterChan = pBeaconStruct->VHTOperation.chanCenterFreqSeg1;
177 psessionEntry->apChanWidth = pBeaconStruct->VHTOperation.chanWidth;
Jeff Johnsone7245742012-09-05 17:12:55 -0700178 }
179 else
180 {
Madan Mohan Koyyalamudic6226de2012-09-18 16:33:31 -0700181 psessionEntry->vhtCapabilityPresentInBeacon = 0;
Jeff Johnsone7245742012-09-05 17:12:55 -0700182 }
183#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700184 // Extract the UAPSD flag from WMM Parameter element
Madan Mohan Koyyalamudi19032762012-10-21 12:42:11 -0700185 if (pBeaconStruct->wmeEdcaPresent)
186 *uapsd = pBeaconStruct->edcaParams.qosInfo.uapsd;
Jeff Johnson295189b2012-06-20 16:38:30 -0700187#if defined FEATURE_WLAN_CCX
188 /* If there is Power Constraint Element specifically,
189 * adapt to it. Hence there is else condition check
190 * for this if statement.
191 */
Madan Mohan Koyyalamudi19032762012-10-21 12:42:11 -0700192 if ( pBeaconStruct->ccxTxPwr.present)
Jeff Johnson295189b2012-06-20 16:38:30 -0700193 {
Madan Mohan Koyyalamudi19032762012-10-21 12:42:11 -0700194 *localConstraint = pBeaconStruct->ccxTxPwr.power_limit;
Jeff Johnson295189b2012-06-20 16:38:30 -0700195 }
196#endif
Madan Mohan Koyyalamudi19032762012-10-21 12:42:11 -0700197 if (pBeaconStruct->powerConstraintPresent)
Jeff Johnsone7245742012-09-05 17:12:55 -0700198#if 0
199 //Remove this check. This function is expected to return localPowerConsraints
200 //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 -0700201#if defined WLAN_FEATURE_VOWIFI
Jeff Johnsone7245742012-09-05 17:12:55 -0700202 && ( pMac->lim.gLim11hEnable
203 || pMac->rrm.rrmPEContext.rrmEnable
Jeff Johnson295189b2012-06-20 16:38:30 -0700204#endif
Jeff Johnsone7245742012-09-05 17:12:55 -0700205#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700206 {
207#if defined WLAN_FEATURE_VOWIFI
Madan Mohan Koyyalamudi19032762012-10-21 12:42:11 -0700208 *localConstraint -= pBeaconStruct->localPowerConstraint.localPowerConstraints;
Jeff Johnson295189b2012-06-20 16:38:30 -0700209#else
Madan Mohan Koyyalamudi19032762012-10-21 12:42:11 -0700210 localPowerConstraints = (tANI_U32)pBeaconStruct->localPowerConstraint.localPowerConstraints;
Jeff Johnson295189b2012-06-20 16:38:30 -0700211#endif
212 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700213#if !defined WLAN_FEATURE_VOWIFI
214 if (cfgSetInt(pMac, WNI_CFG_LOCAL_POWER_CONSTRAINT, localPowerConstraints) != eSIR_SUCCESS)
215 {
216 limLog(pMac, LOGP, FL("Could not update local power constraint to cfg.\n"));
217 }
218#endif
219 }
Madan Mohan Koyyalamudi19032762012-10-21 12:42:11 -0700220 palFreeMemory(pMac->hHdd, pBeaconStruct);
Jeff Johnson295189b2012-06-20 16:38:30 -0700221 return;
222} /****** end limExtractApCapability() ******/
223
Jeff Johnson295189b2012-06-20 16:38:30 -0700224#if (defined(ANI_PRODUCT_TYPE_AP) || defined(ANI_PRODUCT_TYPE_AP_SDK))
225/**
226 * limQuietBss()
227 *
228 *FUNCTION:
229 * This function is called to quiet the BSS
230 * while entering into Learn mode
231 *
232 *LOGIC:
233 * Data frame to self with duration value passed is
234 * transmitted
235 *
236 *ASSUMPTIONS:
237 * NA
238 *
239 *NOTE:
240 * If all associated STAs are 11h compliant, Quiet IE
241 * need to be sent in Beacon/Probe Response frames.
242 *
243 * @param pMac Pointer to Global MAC structure
244 * @param duration Specifies quiet duration in millisec
245 * @return None
246 */
Jeff Johnson295189b2012-06-20 16:38:30 -0700247void
248limQuietBss(tpAniSirGlobal pMac, tANI_U32 duration)
249{
Jeff Johnson295189b2012-06-20 16:38:30 -0700250 // Temporarily not quieting BSS
251 (void) pMac; (void) duration;
252 return;
253} /****** end limQuietBss() ******/
254
Jeff Johnson295189b2012-06-20 16:38:30 -0700255/**
256 * limIsMatrixNodePresent()
257 *
258 *FUNCTION:
259 * This function is called to determine if measurements are
260 * already made on the current learn channel
261 *
262 *LOGIC:
263 *
264 *ASSUMPTIONS:
265 * NA
266 *
267 *NOTE:
268 * NA
269 *
270 * @param pMac - Pointer to Global MAC structure
271 * @return pNode - Pointer to Matrix node if found. Else NULL
272 */
Jeff Johnson295189b2012-06-20 16:38:30 -0700273static tpLimMeasMatrixNode
274limIsMatrixNodePresent(tpAniSirGlobal pMac)
275{
276 tANI_U8 i, chanNum = limGetCurrentLearnChannel(pMac);
277 tpLimMeasMatrixNode pNode = pMac->lim.gpLimMeasData->pMeasMatrixInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -0700278 if (!pNode)
279 return NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -0700280 for (i = 0; i < pMac->lim.gpLimMeasReq->channelList.numChannels; i++)
281 {
282 if (pNode->matrix.channelNumber == chanNum)
283 {
284 return pNode;
285 }
286 else
287 {
288 if (pNode->next)
289 pNode = pNode->next;
290 else
291 break;
292 }
293 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700294 return NULL;
295} /****** end limIsMatrixNodePresent() ******/
296
Jeff Johnson295189b2012-06-20 16:38:30 -0700297/**
298 * limGetMatrixNode()
299 *
300 *FUNCTION:
301 * This function is called to get a metrics node associated
302 * with the current measurement channel. If no node is found
303 * for this channel, one is added at the beginning of the list.
304 *
305 *LOGIC:
306 *
307 *ASSUMPTIONS:
308 * NA
309 *
310 *NOTE:
311 * NA
312 *
313 * @param pMac Pointer to Global MAC structure
314 * @return None
315 */
Jeff Johnson295189b2012-06-20 16:38:30 -0700316static tpLimMeasMatrixNode
317limGetMatrixNode(tpAniSirGlobal pMac)
318{
319 tpLimMeasMatrixNode pNewMatrix;
320 eHalStatus status;
Jeff Johnson295189b2012-06-20 16:38:30 -0700321 pNewMatrix = limIsMatrixNodePresent(pMac);
322 if (!pNewMatrix)
323 {
324 // Making first time measurements on this channel.
325 // Add matrix node for this at the front.
326 status = palAllocateMemory( pMac->hHdd, (void **)&pNewMatrix, sizeof(*pNewMatrix));
327 if (status != eHAL_STATUS_SUCCESS)
328 {
329 /// Could not allocate buffer for new measMatrix Node
330 // Log error
331 limLog(pMac, LOGP,
332 FL("palAllocateMemory failed for new measMatrix Node\n"));
333 return NULL;
334 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700335 status = palZeroMemory( pMac->hHdd, (void *)pNewMatrix, sizeof(*pNewMatrix));
336 if (status != eHAL_STATUS_SUCCESS)
337 {
338 /// Could not allocate buffer for new measMatrix Node
339 // Log error
340 limLog(pMac, LOGP,
341 FL("palZeroMemory failed for new measMatrix Node\n"));
342 return NULL;
343 }
344
345 pNewMatrix->matrix.channelNumber =
346 limGetCurrentLearnChannel(pMac);
347 pNewMatrix->avgRssi = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -0700348 PELOG3(limLog(pMac, LOG3, FL("Adding new Matrix info:channel#=%d\n"),
349 pNewMatrix->matrix.channelNumber);)
Jeff Johnson295189b2012-06-20 16:38:30 -0700350 pNewMatrix->next = pMac->lim.gpLimMeasData->pMeasMatrixInfo;
351 pMac->lim.gpLimMeasData->pMeasMatrixInfo = pNewMatrix;
352 pMac->lim.gpLimMeasData->numMatrixNodes++;
353 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700354 return pNewMatrix;
355} /****** end limGetMatrixNode() ******/
356
Jeff Johnson295189b2012-06-20 16:38:30 -0700357/**
358 * limComputeAvg()
359 *
360 *FUNCTION:
361 * This function is called to compute exponential average
362 * of RSSI, channel utilization etc.
363 *
364 *LOGIC:
365 *
366 *ASSUMPTIONS:
367 * NA
368 *
369 *NOTE:
370 * NA
371 *
372 * @param pMac Pointer to Global MAC structure
373 * @param oldVal Previous averaged value
374 * @param newVal New averaged value
375 * @return None
376 */
Jeff Johnson295189b2012-06-20 16:38:30 -0700377tANI_U32
378limComputeAvg(tpAniSirGlobal pMac, tANI_U32 oldVal, tANI_U32 newVal)
379{
380 return (halExpAvg(newVal,
381 oldVal,
382 pMac->lim.gLimMeasParams.rssiAlpha));
383} /****** end limComputeAvg() ******/
384
Jeff Johnson295189b2012-06-20 16:38:30 -0700385/**
386 * limCollectRSSI()
387 *
388 *FUNCTION:
389 * This function is called to collect RSSI measurements on
390 * the current learn channel
391 *
392 *LOGIC:
393 *
394 *ASSUMPTIONS:
395 * NA
396 *
397 *NOTE:
398 * NA
399 *
400 * @param pMac Pointer to Global MAC structure
401 * @return None
402 */
Jeff Johnson295189b2012-06-20 16:38:30 -0700403void
404limCollectRSSI(tpAniSirGlobal pMac)
405{
406 tpLimMeasMatrixNode pNewMatrix = limGetMatrixNode(pMac);
407 tANI_U32 i, noise;
Jeff Johnson295189b2012-06-20 16:38:30 -0700408 for (i = 0; i < LIM_GET_NOISE_MAX_TRY; i++)
409 if ((noise = halGetNoise(pMac)) != HAL_NOISE_INVALID)
410 {
411 pNewMatrix->avgRssi = limComputeAvg(pMac,
412 pNewMatrix->avgRssi,
413 noise);
414 break;
415 }
416} /****** end limCollectRSSI() ******/
417
Jeff Johnson295189b2012-06-20 16:38:30 -0700418/**----------------------------------------------------------------------------
419\fn limGetNeighbourBssNode
Jeff Johnson295189b2012-06-20 16:38:30 -0700420\brief returns neighbour bss node if it is already present in the list.
421\param pMac
422\param bssid - Bssid of new beacon or data packet.
423\param pSsId - Pointer to SSID of new packet.
424\param nwType - 11b/g/a
425\param chanId - Channel in which we received the packet.
Jeff Johnson295189b2012-06-20 16:38:30 -0700426\return tpLimNeighborBssWdsNode or NULL
427-------------------------------------------------------------------------------*/
428static tpLimNeighborBssWdsNode
429limGetNeighbourBssNode(tpAniSirGlobal pMac, tANI_U8 *bssId, tANI_U8 chanId,
430 tSirNwType nwType, tpAniSSID pSsId, tANI_U8 type)
431{
432 tpLimNeighborBssWdsNode pNode = pMac->lim.gpLimMeasData->pNeighborWdsInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -0700433 while (pNode)
434 {
435 //Do we need to check for ssId also ?
436 if (palEqualMemory(pMac->hHdd, pNode->info.neighborBssInfo.bssId,
437 bssId, sizeof(tSirMacAddr)) &&
438 (pNode->info.neighborBssInfo.channelId == chanId))
439 {
440#if 0
441/** Commented out assuming that comparing bssId and ChanId would be enough to
442uniquely identify a particular BSS, Uncomment if strict checking is needed,
443eventhough not possible if packet type is DATA. */
444 if (type == eSIR_MAC_MGMT_FRAME)
445 {
446 /** Beacon Frame */
447 if (palEqualMemory(pMac->hHdd, &pNode->info.neighborBssInfo.ssId,
448 pSsId, pSsId->length+1) &&
449 (pNode->info.neighborBssInfo.nwType == nwType))
450 {
451 return pNode;
452 }
453 }
454 else
455#endif
456 return pNode;
457 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700458 if (!pNode->next)
459 break;
460 else
461 pNode = pNode->next;
462 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700463 return NULL;
464}
465
Jeff Johnson295189b2012-06-20 16:38:30 -0700466/**
467 * limCollectMeasurementData()
468 *
469 *FUNCTION:
470 * This function is called upon receiving Beacon/Probe Response
471 * or Data frames to collect measurement related data.
472 *
473 *LOGIC:
474 *
475 *ASSUMPTIONS:
476 * NA
477 *
478 *NOTE:
479 * NA
480 *
481 * @param pMac - Pointer to Global MAC structure
482 * @param pRxPacketInfo - Pointer to received BD+payload
483 * @param pBeacon - Pointer to parsed BSS info
484 * @return None
485 */
Jeff Johnson295189b2012-06-20 16:38:30 -0700486void
487limCollectMeasurementData(tpAniSirGlobal pMac,
488 tANI_U32 *pRxPacketInfo, tpSchBeaconStruct pBeacon)
489{
490 tANI_U16 allocLen=0, len=0, realLen=0, ieLen=0;
491 tANI_U32 i;
492 tANI_U8 found = eANI_BOOLEAN_TRUE;
493 tSirMacFrameCtl fc ;
494 tSirMacAddr bssIdRcv;
495 tSirNwType nwType;
496 tAniSSID ssId;
497 tANI_U8 chanId = 0;
498 tpLimNeighborBssWdsNode pNode = NULL;
499 tpLimMeasMatrixNode pNewMatrix;
500 eHalStatus status;
501 tpSirMacMgmtHdr pHdr;
Jeff Johnson295189b2012-06-20 16:38:30 -0700502 PELOG3(limLog(pMac, LOG3, FL("Collecting measurement data for RadioId %d\n"),
503 pMac->sys.gSirRadioId);)
Jeff Johnson295189b2012-06-20 16:38:30 -0700504 tANI_U32 ignore = 0;
505 limGetBssidFromBD(pMac, (tpHalBufDesc) pRxPacketInfo, bssIdRcv, &ignore);
506 if (palEqualMemory( pMac->hHdd, bssIdRcv, pMac->lim.gLimBssid, sizeof(tSirMacAddr)))
507 {
508 // Packet received from our own BSS, dont take measurement.
509 return;
510 }
511 pHdr = WDA_GET_RX_MAC_HEADER(pRxPacketInfo);
512 fc = pHdr->fc;
Jeff Johnson295189b2012-06-20 16:38:30 -0700513 if (fc.type == SIR_MAC_DATA_FRAME)
514 {
515 PELOG2(limLog(pMac, LOG2, FL("Received DATA packet\n"));)
516 ssId.length = 0;
517 ieLen = 0;
518 }
519 else
520 {
521 /** Probe response or beaccon packet */
522 palCopyMemory(pMac->hHdd, (void *)&ssId, (void *) &pBeacon->ssId,
523 sizeof(ssId));
524 chanId = limGetChannelFromBeacon(pMac, pBeacon);
525 ieLen = pBeacon->wpa.length + pBeacon->propIEinfo.wdsLength;
526 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700527 if (chanId == 0)
528 {
529 /* If the channel Id is not retrieved from Beacon, extract the channel from BD */
530 /* Unmapped the channel.This We have to do since we have done mapping in the hal to
531 overcome the limitation of RXBD of not able to accomodate the bigger channel number.*/
532 chanId = WDA_GET_RX_CH(pRxPacketInfo);
533 if(!( chanId = limUnmapChannel(chanId)))
534 {
535 chanId = pMac->lim.gLimCurrentScanChannelId;
536 }
537 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700538 /*
539 * Now always returns nwType as 11G for data packets - FIXIT
540 */
541 nwType = limGetNwType(pMac, chanId, fc.type, pBeacon);
Jeff Johnson295189b2012-06-20 16:38:30 -0700542 pNewMatrix = limGetMatrixNode(pMac);
543 /** LOGP would result in freeing all dynamicall allocated memories. So
544 * return from here if limGetMatrixNode returns NULL
545 */
546 if (!pNewMatrix)
547 return;
Jeff Johnson295189b2012-06-20 16:38:30 -0700548 pNewMatrix->matrix.aggrRssi += WDA_GET_RX_RSSI_DB(pRxPacketInfo);
549 pNewMatrix->matrix.totalPackets++;
Jeff Johnson295189b2012-06-20 16:38:30 -0700550 // Find if this neighbor is already 'learned'
551 // If found, update its information.
552 pNode = limGetNeighbourBssNode(pMac, bssIdRcv, chanId, nwType, &ssId, fc.type);
Jeff Johnson295189b2012-06-20 16:38:30 -0700553 if (!pNode)
554 {
555 realLen = sizeof(tSirNeighborBssWdsInfo);
Jeff Johnson295189b2012-06-20 16:38:30 -0700556 /** Newly discovered neighbor. Inform WSM of this
557 * and add this BSS info at the beginning
558 * Need to limit the number newly discovered BSS added
559 * to the list.
560 */
561 len = LIM_MAX_BUF_SIZE - (sizeof(tSirSmeMeasurementInd) +
562 (pMac->lim.gpLimMeasReq->channelList.numChannels *
563 sizeof(tSirMeasMatrixInfo)));
564 PELOG2(limLog(pMac, LOG2, FL("Current BSS length %d, Real length %d\n"),
565 pMac->lim.gpLimMeasData->totalBssSize, realLen);)
Jeff Johnson295189b2012-06-20 16:38:30 -0700566 /** Check if we have enough room for adding a new node.
567 */
568 if (pMac->lim.gpLimMeasData->totalBssSize + realLen < len)
569 {
570 pMac->lim.gpLimMeasData->numBssWds++;
571 pMac->lim.gpLimMeasData->totalBssSize += realLen;
Jeff Johnson295189b2012-06-20 16:38:30 -0700572 PELOG2(limPrintMacAddr(pMac, bssIdRcv, LOG2);)
573 }
574 else
575 {
576 PELOG2(limLog(pMac, LOG2, FL("Dropping the measurement packets: No memory!\n"));)
577 return;
578 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700579 /** Allocate max memory required even if the packet is of type DATA,
580 * So that next time we receive a beacon, won't run out of memory to
581 * update the information.
582 */
583 allocLen = sizeof(tLimNeighborBssWdsNode) + 4 + ieLen;
584 status = palAllocateMemory( pMac->hHdd, (void **)&pNode, allocLen);
Jeff Johnson295189b2012-06-20 16:38:30 -0700585 if (status != eHAL_STATUS_SUCCESS)
586 {
587 limLog(pMac, LOGP, FL("palAllocateMemory failed for new NeighborBssWds Node\n"));
588 return;
589 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700590 status = palZeroMemory(pMac->hHdd, pNode, allocLen);
591 if (status != eHAL_STATUS_SUCCESS)
592 {
593 limLog(pMac, LOGP, FL("palAllocateMemory failed for new NeighborBssWds Node\n"));
594 return;
595 }
596 pNode->next = pMac->lim.gpLimMeasData->pNeighborWdsInfo;
597 pMac->lim.gpLimMeasData->pNeighborWdsInfo = pNode;
598 found = eANI_BOOLEAN_FALSE;
599 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700600 pNode->info.neighborBssInfo.rssi = WDA_GET_RX_RSSI_DB(pRxPacketInfo);
601 pNode->info.neighborBssInfo.aggrRssi += pNode->info.neighborBssInfo.rssi;
602 if (fc.type == SIR_MAC_DATA_FRAME)
603 pNode->info.neighborBssInfo.dataCount++;
604 pNode->info.neighborBssInfo.totalPackets++;
Jeff Johnson295189b2012-06-20 16:38:30 -0700605 /** If node not found or previous learn was not from a beacon/probe rsp
606 * then learn again.
607 */
608 if (!found || ((pNode->info.neighborBssInfo.ssId.length == 0) &&
609 (fc.type == SIR_MAC_MGMT_FRAME)))
610 {
611 palCopyMemory(pMac->hHdd, pNode->info.neighborBssInfo.bssId, bssIdRcv,
612 sizeof(tSirMacAddr));
613 pNode->info.neighborBssInfo.channelId = chanId;
614 if (fc.type == SIR_MAC_DATA_FRAME)
615 {
616 // Data frame received from other BSS.
617 // Collect as much information as possible
618 pNode->info.neighborBssInfo.wniIndicator = (tAniBool) 0;
Jeff Johnson295189b2012-06-20 16:38:30 -0700619 if (fc.toDS || fc.fromDS)
620 pNode->info.neighborBssInfo.bssType = eSIR_INFRASTRUCTURE_MODE;
621 else
622 pNode->info.neighborBssInfo.bssType = eSIR_IBSS_MODE;
Jeff Johnson295189b2012-06-20 16:38:30 -0700623 pNode->info.neighborBssInfo.load.numStas = 0;
624 pNode->info.neighborBssInfo.load.channelUtilization = 0;
625 pNode->info.neighborBssInfo.ssId.length = 0;
626 pNode->info.neighborBssInfo.apName.length = 0;
627 pNode->info.neighborBssInfo.rsnIE.length = 0;
628 pNode->info.wdsInfo.wdsLength = 0;
629 }
630 else
631 {
Jeff Johnson295189b2012-06-20 16:38:30 -0700632 // This must be either Beacon frame or
633 // Probe Response. Copy all relevant information.
634 pNode->info.neighborBssInfo.wniIndicator = (tAniBool) pBeacon->propIEinfo.aniIndicator;
635 pNode->info.neighborBssInfo.bssType = (tSirBssType) pBeacon->capabilityInfo.ibss;
636 pNode->info.neighborBssInfo.load.numStas = pBeacon->propIEinfo.load.numStas;
637 pNode->info.neighborBssInfo.load.channelUtilization = pBeacon->propIEinfo.load.channelUtilization;
638
639 palCopyMemory( pMac->hHdd, (tANI_U8 *) &pNode->info.neighborBssInfo.ssId,
640 &pBeacon->ssId, pBeacon->ssId.length+1);
641 pNode->info.neighborBssInfo.apName.length = pBeacon->propIEinfo.apName.length;
642 palCopyMemory( pMac->hHdd, (tANI_U8 *) pNode->info.neighborBssInfo.apName.name,
643 pBeacon->propIEinfo.apName.name, pBeacon->propIEinfo.apName.length);
Jeff Johnson295189b2012-06-20 16:38:30 -0700644 pNode->info.neighborBssInfo.rsnIE.length = 0;
645 // Add WPA2 information. Before that make sure that memory is available
646 if (pBeacon->rsnPresent && (pBeacon->rsn.length < SIR_MAC_MAX_IE_LENGTH))
647 {
648 pNode->info.neighborBssInfo.rsnIE.length = 2 + pBeacon->rsn.length;
649 pNode->info.neighborBssInfo.rsnIE.rsnIEdata[0] = SIR_MAC_RSN_EID;
650 pNode->info.neighborBssInfo.rsnIE.rsnIEdata[1] = pBeacon->rsn.length;
651 palCopyMemory( pMac->hHdd, (tANI_U8 *) &pNode->info.neighborBssInfo.rsnIE.rsnIEdata[2],
652 pBeacon->rsn.info, pBeacon->rsn.length);
Jeff Johnson295189b2012-06-20 16:38:30 -0700653 PELOG2(limLog(pMac, LOG2, FL("NeighborBss RSN IE, type=%x, length=%x\n"),
654 pNode->info.neighborBssInfo.rsnIE.rsnIEdata[0],
655 pNode->info.neighborBssInfo.rsnIE.rsnIEdata[1]);)
656 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700657 // Add WPA information. Before that make sure that memory is available
658 if (pBeacon->wpaPresent && ((pBeacon->rsn.length + pBeacon->wpa.length) < (SIR_MAC_MAX_IE_LENGTH-2)))
659 {
660 pNode->info.neighborBssInfo.rsnIE.rsnIEdata[pNode->info.neighborBssInfo.rsnIE.length] =
661 SIR_MAC_WPA_EID;
662 pNode->info.neighborBssInfo.rsnIE.rsnIEdata[pNode->info.neighborBssInfo.rsnIE.length + 1] =
663 pBeacon->wpa.length;
Jeff Johnson295189b2012-06-20 16:38:30 -0700664 palCopyMemory( pMac->hHdd,
665 (tANI_U8 *) &pNode->info.neighborBssInfo.rsnIE.rsnIEdata[pNode->info.neighborBssInfo.rsnIE.length + 2],
666 pBeacon->wpa.info, pBeacon->wpa.length);
Jeff Johnson295189b2012-06-20 16:38:30 -0700667 PELOG2(limLog(pMac, LOG2, FL("NeighborBss WPA IE, type=%x, length=%x\n"),
668 pNode->info.neighborBssInfo.rsnIE.rsnIEdata[pNode->info.neighborBssInfo.rsnIE.length],
669 pNode->info.neighborBssInfo.rsnIE.rsnIEdata[pNode->info.neighborBssInfo.rsnIE.length + 1]);)
670 pNode->info.neighborBssInfo.rsnIE.length += 2 + pBeacon->wpa.length;
671 }
672 pNode->info.wdsInfo.wdsLength = (tANI_U16) pBeacon->propIEinfo.wdsLength;
673 palCopyMemory( pMac->hHdd, (tANI_U8 *) pNode->info.wdsInfo.wdsBytes,
674 pBeacon->propIEinfo.wdsData,
675 pBeacon->propIEinfo.wdsLength);
Jeff Johnson295189b2012-06-20 16:38:30 -0700676 pNode->info.neighborBssInfo.capabilityInfo = *((tANI_U16*)&pBeacon->capabilityInfo);
Jeff Johnson295189b2012-06-20 16:38:30 -0700677#if 0
678 if (pBeacon->HTCaps.present)
679 palCopyMemory( pMac->hHdd, (tANI_U8 *)&pNode->info.neighborBssInfo.HTCaps,
680 (tANI_U8 *)&pBeacon->HTCaps, HT_CAPABILITY_IE_SIZE);
681 else
682 pNode->info.neighborBssInfo.HTCaps.present = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -0700683 if (pBeacon->HTInfo.present)
684 palCopyMemory( pMac->hHdd, (tANI_U8 *)&pNode->info.neighborBssInfo.HTInfo,
685 (tANI_U8 *)&pBeacon->HTInfo, HT_INFO_IE_SIZE);
686 else
687 pNode->info.neighborBssInfo.HTInfo.present = 0;
688#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700689 if (pBeacon->suppRatesPresent && (pBeacon->supportedRates.numRates <=
690 SIR_MAC_RATESET_EID_MAX))
691 {
692 pNode->info.neighborBssInfo.operationalRateSet.numRates = pBeacon->supportedRates.numRates;
Jeff Johnson295189b2012-06-20 16:38:30 -0700693 PELOG4(limLog(pMac, LOG4, FL("Supported Rates (%d) : "),
694 pNode->info.neighborBssInfo.operationalRateSet.numRates);)
695 for (i=0; i<pBeacon->supportedRates.numRates; i++)
696 {
697 pNode->info.neighborBssInfo.operationalRateSet.rate[i] = pBeacon->supportedRates.rate[i];
698 PELOG4(limLog(pMac, LOG4, FL("%d "), pBeacon->supportedRates.rate[i]);)
699 }
700 PELOG4(limLog(pMac, LOG4, FL("\n"));)
701 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700702 if (pBeacon->extendedRatesPresent && (pBeacon->extendedRates.numRates <=
703 SIR_MAC_RATESET_EID_MAX))
704 {
705 pNode->info.neighborBssInfo.extendedRateSet.numRates = pBeacon->extendedRates.numRates;
Jeff Johnson295189b2012-06-20 16:38:30 -0700706 PELOG4(limLog(pMac, LOG4, FL("Extended Rates (%d) : "),
707 pNode->info.neighborBssInfo.extendedRateSet.numRates);)
708 for (i=0; i<pBeacon->extendedRates.numRates; i++)
709 {
710 pNode->info.neighborBssInfo.extendedRateSet.rate[i] = pBeacon->extendedRates.rate[i];
711 PELOG4(limLog(pMac, LOG4, FL("%d "), pBeacon->extendedRates.rate[i]);)
712 }
713 }
714 else
715 {
716 pNode->info.neighborBssInfo.extendedRateSet.numRates = 0;
717 }
718 pNode->info.neighborBssInfo.nwType = nwType;
719 pNode->info.neighborBssInfo.hcfEnabled = pBeacon->propIEinfo.hcfEnabled;
720 pNode->info.neighborBssInfo.beaconInterval = pBeacon->beaconInterval;
721 pNode->info.neighborBssInfo.wmeInfoPresent = pBeacon->wmeInfoPresent;
722 pNode->info.neighborBssInfo.wmeEdcaPresent = pBeacon->wmeEdcaPresent;
723 pNode->info.neighborBssInfo.wsmCapablePresent = pBeacon->wsmCapablePresent;
724 pNode->info.neighborBssInfo.propIECapability = pBeacon->propIEinfo.capability;
725 pNode->info.neighborBssInfo.localPowerConstraints = pBeacon->localPowerConstraint.localPowerConstraints;
726 pNode->info.neighborBssInfo.dtimPeriod = pBeacon->tim.dtimPeriod;
727 pNode->info.neighborBssInfo.HTCapsPresent = pBeacon->HTCaps.present;
728 pNode->info.neighborBssInfo.HTInfoPresent = pBeacon->HTInfo.present;
729 }
730 }
731} /****** end limCollectMeasurementData() ******/
Jeff Johnson295189b2012-06-20 16:38:30 -0700732/**
733 * limCleanupMatrixNodes()
734 *
735 *FUNCTION:
736 * This function is called from various places within LIM code
737 * to cleanup channel info matrix collected by learn mode measurements.
738 *
739 *LOGIC:
740 *
741 *ASSUMPTIONS:
742 * NA
743 *
744 *NOTE:
745 * NA
746 *
747 * @param pMac Pointer to Global MAC structure
748 * @return None
749 */
Jeff Johnson295189b2012-06-20 16:38:30 -0700750static void
751limCleanupMatrixNodes(tpAniSirGlobal pMac)
752{
753 if (pMac->lim.gpLimMeasData->pMeasMatrixInfo)
754 {
755 tpLimMeasMatrixNode pNode = pMac->lim.gpLimMeasData->pMeasMatrixInfo;
756 tpLimMeasMatrixNode pNext;
Jeff Johnson295189b2012-06-20 16:38:30 -0700757 while (pNode)
758 {
759 pNext = pNode->next;
760 palFreeMemory( pMac->hHdd, pNode);
Jeff Johnson295189b2012-06-20 16:38:30 -0700761 if (pNext)
762 pNode = pNext;
763 else
764 break;
765 }
766 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700767 pMac->lim.gpLimMeasData->numMatrixNodes = 0;
768 PELOG2(limLog(pMac, LOG2,
769 FL("Cleaned up channel matrix nodes\n"));)
Jeff Johnson295189b2012-06-20 16:38:30 -0700770 pMac->lim.gpLimMeasData->pMeasMatrixInfo = NULL;
771} /****** end limCleanupMatrixNodes() ******/
Jeff Johnson295189b2012-06-20 16:38:30 -0700772/**
773 * limCleanupNeighborBssNodes()
774 *
775 *FUNCTION:
776 * This function is called from various places within LIM code
777 * to cleanup neighbor info collected by learn mode measurements.
778 *
779 *LOGIC:
780 *
781 *ASSUMPTIONS:
782 * NA
783 *
784 *NOTE:
785 * NA
786 *
787 * @param pMac Pointer to Global MAC structure
788 * @return None
789 */
Jeff Johnson295189b2012-06-20 16:38:30 -0700790static void
791limCleanupNeighborBssNodes(tpAniSirGlobal pMac)
792{
793 if (pMac->lim.gpLimMeasData->pNeighborWdsInfo)
794 {
795 tpLimNeighborBssWdsNode pNode =
796 pMac->lim.gpLimMeasData->pNeighborWdsInfo;
797 tpLimNeighborBssWdsNode pNext;
798 while (pNode)
799 {
800 pNext = pNode->next;
801 pMac->lim.gpLimMeasData->numBssWds--;
802 palFreeMemory( pMac->hHdd, pNode);
Jeff Johnson295189b2012-06-20 16:38:30 -0700803 if (pNext)
804 pNode = pNext;
805 else
806 break;
807 }
808 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700809 PELOG2(limLog(pMac, LOG2,
810 FL("Cleaned up neighbor nodes\n"));)
Jeff Johnson295189b2012-06-20 16:38:30 -0700811 pMac->lim.gpLimMeasData->numBssWds = 0;
812 pMac->lim.gpLimMeasData->totalBssSize = 0;
813 pMac->lim.gpLimMeasData->pNeighborWdsInfo = NULL;
814} /****** end limCleanupNeighborBssNodes() ******/
815
Jeff Johnson295189b2012-06-20 16:38:30 -0700816/**
817 * limSendSmeMeasurementInd()
818 *
819 *FUNCTION:
820 * This function is called by limProcessLmmMessages() to
821 * send SME_MEASUREMENT_IND message to WSM.
822 *
823 *LOGIC:
824 *
825 *ASSUMPTIONS:
826 *
827 *NOTE:
828 *
829 * @param pMac - Pointer to Global MAC structure
830 * @return None
831 */
Jeff Johnson295189b2012-06-20 16:38:30 -0700832void
833limSendSmeMeasurementInd(tpAniSirGlobal pMac)
834{
835 tANI_U8 *pMeasInd;
836 tANI_U16 len = 0;
837 tSirMsgQ mmhMsg;
Jeff Johnson295189b2012-06-20 16:38:30 -0700838#ifdef GEN6_TODO
839 //fetch the sessionEntry based on the sessionId
840 //priority - MEDIUM
841 tpPESession sessionEntry;
Jeff Johnson295189b2012-06-20 16:38:30 -0700842 if((sessionEntry = peFindSessionBySessionId(pMac, pMac->lim.gLimMeasParams.measurementIndTimer.sessionId))== NULL)
843 {
844 limLog(pMac, LOGP,FL("Session Does not exist for given sessionID\n"));
845 return;
846 }
847#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700848 if (!pMac->sys.gSysEnableLearnMode ||
849 (pMac->lim.gpLimMeasReq == NULL))
850 {
851 return;
852 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700853 len = sizeof(tSirSmeMeasurementInd) +
854 (pMac->lim.gpLimMeasReq->channelList.numChannels *
855 sizeof(tSirMeasMatrixInfo)) +
856 pMac->lim.gpLimMeasData->totalBssSize;
857 if (len > LIM_MAX_BUF_SIZE)
858 {
859 limLog(pMac, LOGP,
860 FL("len %d numChannels %d numBssWds %d totalBssSize %d\n"),
861 len,
862 pMac->lim.gpLimMeasReq->channelList.numChannels,
863 pMac->lim.gpLimMeasData->numBssWds,
864 pMac->lim.gpLimMeasData->totalBssSize);
865 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700866 PELOG2(limLog(pMac, LOG2, FL("***** Measurement IND size %d\n"), len);)
Jeff Johnson295189b2012-06-20 16:38:30 -0700867 if( eHAL_STATUS_SUCCESS != palAllocateMemory( pMac->hHdd, (void **)&pMeasInd, len))
868 {
869 /// Buffer not available. Log error
870 limLog(pMac, LOGP,
871 FL("call to palAllocateMemory failed for eWNI_SME_MEAS_IND\n"));
Jeff Johnson295189b2012-06-20 16:38:30 -0700872 return;
873 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700874 PELOG3(limLog(pMac, LOG3,
875 FL("Sending eWNI_SME_MEAS_IND on Radio %d, requested len=%d\n"),
876 pMac->sys.gSirRadioId, len);)
Jeff Johnson295189b2012-06-20 16:38:30 -0700877 limMeasurementIndSerDes(pMac, pMeasInd);
Jeff Johnson295189b2012-06-20 16:38:30 -0700878 mmhMsg.type = eWNI_SME_MEASUREMENT_IND;
879 mmhMsg.bodyptr = pMeasInd;
880 mmhMsg.bodyval = 0;
Jeff Johnsone7245742012-09-05 17:12:55 -0700881 MTRACE(macTraceMsgTx(pMac, NO_SESSION, mmhMsg.type));
Jeff Johnson295189b2012-06-20 16:38:30 -0700882 limSysProcessMmhMsgApi(pMac, &mmhMsg, ePROT);
Jeff Johnson295189b2012-06-20 16:38:30 -0700883 // Cleanup neighbor information
884 limCleanupNeighborBssNodes(pMac);
885 limCleanupMatrixNodes(pMac);
886} /*** end limSendSmeMeasurementInd() ***/
887
Jeff Johnson295189b2012-06-20 16:38:30 -0700888/**
889 * limCleanupMeasData()
890 *
891 *FUNCTION:
892 * This function is called from various places within LIM code
893 * to cleanup measurement related data.
894 *
895 *LOGIC:
896 * Buffers and associated timer resources will be deleted when
897 * this function is called
898 *
899 *ASSUMPTIONS:
900 * NA
901 *
902 *NOTE:
903 * NA
904 *
905 * @param pMac Pointer to Global MAC structure
906 * @return None
907 */
Jeff Johnson295189b2012-06-20 16:38:30 -0700908void
909limCleanupMeasData(tpAniSirGlobal pMac)
910{
911 if (pMac->lim.gpLimMeasReq)
912 palFreeMemory( pMac->hHdd, pMac->lim.gpLimMeasReq);
Jeff Johnson295189b2012-06-20 16:38:30 -0700913 pMac->lim.gpLimMeasReq = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -0700914 if (!pMac->lim.gpLimMeasData)
915 return;
Jeff Johnson295189b2012-06-20 16:38:30 -0700916 if (pMac->lim.gpLimMeasData->pMeasMatrixInfo)
917 {
918 // Retain current channel's data and flush remaining
919 tpLimMeasMatrixNode pMatrix =
920 (pMac->lim.gpLimMeasData->pMeasMatrixInfo)->next;
921 tpLimMeasMatrixNode pNext;
Jeff Johnson295189b2012-06-20 16:38:30 -0700922 while (pMatrix)
923 {
924 pNext = pMatrix->next;
925 palFreeMemory( pMac->hHdd, pMatrix);
Jeff Johnson295189b2012-06-20 16:38:30 -0700926 if (pNext)
927 pMatrix = pNext;
928 else
929 break;
930 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700931 pMac->lim.gpLimMeasData->pMeasMatrixInfo->next = NULL;
932 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700933 pMac->lim.gpLimMeasData->numMatrixNodes = 0;
934 PELOG2(limLog(pMac, LOG2,
935 FL("Cleaned up measurement metrics nodes\n"));)
Jeff Johnson295189b2012-06-20 16:38:30 -0700936 // Cleanup neighbor information
937 limCleanupNeighborBssNodes(pMac);
938} /****** end limCleanupMeasData() ******/
Jeff Johnson295189b2012-06-20 16:38:30 -0700939/**---------------------------------------------------------
940\fn limStopMeasTimers
941\brief Stops all measurement related timers.
Jeff Johnson295189b2012-06-20 16:38:30 -0700942\param pMac
943\return None
944 ----------------------------------------------------------*/
945void
946limStopMeasTimers(tpAniSirGlobal pMac)
947{
948 if (pMac->lim.gpLimMeasReq == NULL)
949 return;
Jeff Johnson295189b2012-06-20 16:38:30 -0700950 if (pMac->lim.gpLimMeasReq->measControl.periodicMeasEnabled)
951 {
952 if (tx_timer_deactivate(&pMac->lim.gLimMeasParams.measurementIndTimer) != TX_SUCCESS)
953 {
954 PELOGE(limLog(pMac, LOGE, FL("Cannot stop measurement Ind timer\n"));)
955 }
956 }
957 pMac->lim.gLimMeasParams.isMeasIndTimerActive = 0;
Jeff Johnsone7245742012-09-05 17:12:55 -0700958 MTRACE(macTrace(pMac, TRACE_CODE_TIMER_DEACTIVATE, NO_SESSION, eLIM_LEARN_INTERVAL_TIMER));
Jeff Johnson295189b2012-06-20 16:38:30 -0700959 if (tx_timer_deactivate(&pMac->lim.gLimMeasParams.learnIntervalTimer) != TX_SUCCESS)
960 {
961 PELOGE(limLog(pMac, LOGE, FL("Cannot stop learn interval timer\n"));)
962 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700963 if (pMac->lim.gLimSpecMgmt.fQuietEnabled)
964 {
Jeff Johnsone7245742012-09-05 17:12:55 -0700965 MTRACE(macTrace(pMac, TRACE_CODE_TIMER_DEACTIVATE, NO_SESSION, eLIM_LEARN_DURATION_TIMER));
Jeff Johnson295189b2012-06-20 16:38:30 -0700966 if (tx_timer_deactivate(&pMac->lim.gLimMeasParams.learnDurationTimer) != TX_SUCCESS)
967 {
968 PELOGE(limLog(pMac, LOGE, FL("Cannot stop learn duration timer\n"));)
969 }
970 }
Jeff Johnsone7245742012-09-05 17:12:55 -0700971 MTRACE(macTrace(pMac, TRACE_CODE_TIMER_DEACTIVATE, NO_SESSION, eLIM_LEARN_DURATION_TIMER));
Jeff Johnson295189b2012-06-20 16:38:30 -0700972 if (tx_timer_deactivate(&pMac->lim.gLimMeasParams.learnDurationTimer) != TX_SUCCESS)
973 {
974 PELOGE(limLog(pMac, LOGE, FL("Cannot stop learn duration timer\n"));)
975 }
976}
Jeff Johnson295189b2012-06-20 16:38:30 -0700977/**
978 * limDeleteMeasTimers()
979 *
980 *FUNCTION:
981 * This function is called by limProcessLmmMessages() upon
982 * receiving SME_MEASUREMENT_REQ. This function deletes
983 * timers associated with Measurements.
984 *
985 *LOGIC:
986 *
987 *ASSUMPTIONS:
988 *
989 *NOTE:
990 *
991 * @param pMac Pointer to Global MAC structure
992 * @return None
993 */
Jeff Johnson295189b2012-06-20 16:38:30 -0700994void
995limDeleteMeasTimers(tpAniSirGlobal pMac)
996{
997 if (pMac->lim.gpLimMeasReq->measControl.periodicMeasEnabled)
998 tx_timer_delete(&pMac->lim.gLimMeasParams.measurementIndTimer);
999 tx_timer_delete(&pMac->lim.gLimMeasParams.learnIntervalTimer);
1000 tx_timer_delete(&pMac->lim.gLimMeasParams.learnDurationTimer);
1001} /*** end limDeleteMeasTimers() ***/
1002
Jeff Johnson295189b2012-06-20 16:38:30 -07001003/**
1004 * limCleanupMeasResources()
1005 *
1006 *FUNCTION:
1007 * This function is called from various places within LIM code
1008 * to cleanup measurement related data and resources.
1009 *
1010 *LOGIC:
1011 * Buffers and associated timer resources will be deleted when
1012 * this function is called
1013 *
1014 *ASSUMPTIONS:
1015 * NA
1016 *
1017 *NOTE:
1018 * NA
1019 *
1020 * @param pMac Pointer to Global MAC structure
1021 * @return None
1022 */
Jeff Johnson295189b2012-06-20 16:38:30 -07001023void
1024limCleanupMeasResources(tpAniSirGlobal pMac)
1025{
1026 PELOG1( limLog(pMac, LOG1,
1027 FL("Cleaning up Learn mode Measurement resources\n"));)
Jeff Johnson295189b2012-06-20 16:38:30 -07001028 if (pMac->lim.gpLimMeasReq == NULL)
1029 return;
Jeff Johnson295189b2012-06-20 16:38:30 -07001030 limDeleteMeasTimers(pMac);
Jeff Johnson295189b2012-06-20 16:38:30 -07001031 if (pMac->lim.gpLimMeasData)
1032 {
1033 limCleanupMeasData(pMac);
1034 if (pMac->lim.gpLimMeasData->pMeasMatrixInfo)
1035 palFreeMemory( pMac->hHdd, pMac->lim.gpLimMeasData->pMeasMatrixInfo);
Jeff Johnson295189b2012-06-20 16:38:30 -07001036 palFreeMemory( pMac->hHdd, pMac->lim.gpLimMeasData);
1037 pMac->lim.gpLimMeasData = NULL;
1038 }
1039} /****** end limCleanupMeasResources() ******/
1040
Jeff Johnson295189b2012-06-20 16:38:30 -07001041/**
1042 * limDeleteCurrentBssWdsNode()
1043 *
1044 *FUNCTION:
1045 * This function is called when Loss of link
1046 * is detected with AP and its BssWds info node
1047 * to be deleted
1048 *
1049 *LOGIC:
1050 *
1051 *ASSUMPTIONS:
1052 * NA
1053 *
1054 *NOTE:
1055 * NA
1056 *
1057 * @param None
1058 * @return None
1059 */
1060void limDeleteCurrentBssWdsNode(tpAniSirGlobal pMac)
1061{
1062 tANI_U32 cfg = sizeof(tSirMacAddr);
1063 tSirMacAddr currentBssId;
Jeff Johnson295189b2012-06-20 16:38:30 -07001064#if 0
1065 if (wlan_cfgGetStr(pMac, WNI_CFG_BSSID, currentBssId, &cfg) !=
1066 eSIR_SUCCESS)
1067 {
1068 /// Could not get BSSID from CFG. Log error.
1069 limLog(pMac, LOGP, FL("could not retrieve BSSID\n"));
1070 }
1071#endif //TO SUPPORT BT-AMP
1072 sirCopyMacAddr(currentBssId,sessionEntry->bssId);
Jeff Johnson295189b2012-06-20 16:38:30 -07001073 if (!pMac->lim.gpLimMeasData)
1074 return;
Jeff Johnson295189b2012-06-20 16:38:30 -07001075 if (pMac->lim.gpLimMeasData->pNeighborWdsInfo)
1076 {
1077 tpLimNeighborBssWdsNode pNode =
1078 pMac->lim.gpLimMeasData->pNeighborWdsInfo;
1079 tpLimNeighborBssWdsNode pPrev = pNode;
1080 while (pNode)
1081 {
1082 if (palEqualMemory( pMac->hHdd,pNode->info.neighborBssInfo.bssId,
1083 currentBssId,
1084 sizeof(tSirMacAddr)))
1085 {
1086 pMac->lim.gpLimMeasData->numBssWds--;
1087 pPrev->next = pNode->next;
1088 palFreeMemory( pMac->hHdd, pNode);
1089 break;
1090 }
1091 pPrev = pNode;
Jeff Johnson295189b2012-06-20 16:38:30 -07001092 if (pNode->next)
1093 pNode = pNode->next;
1094 else
1095 break;
1096 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001097 if (!pMac->lim.gpLimMeasData->numBssWds)
1098 pMac->lim.gpLimMeasData->pNeighborWdsInfo = NULL;
1099 }
1100} /****** end limDeleteCurrentBssWdsNode() ******/
1101
Jeff Johnson295189b2012-06-20 16:38:30 -07001102/**
1103 * limRestorePreLearnState()
1104 *
1105 *FUNCTION:
1106 * This function is called when Learn duration timer expires
1107 * to restore pre-Learn mode state
1108 *
1109 *LOGIC:
1110 *
1111 *ASSUMPTIONS:
1112 * NA
1113 *
1114 *NOTE:
1115 * NA
1116 *
1117 * @param pMac Pointer to Global MAC structure
1118 * @return None
1119 */
Jeff Johnson295189b2012-06-20 16:38:30 -07001120void
1121limRestorePreLearnState(tpAniSirGlobal pMac)
1122{
1123 PELOG4(limLog(pMac, LOG4,
1124 FL("Restoring from Learn mode on RadioId %d\n"),
1125 pMac->sys.gSirRadioId);)
Jeff Johnson295189b2012-06-20 16:38:30 -07001126 pMac->lim.gLimSystemInScanLearnMode = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07001127 // Go back to previous state.
1128 pMac->lim.gLimSmeState = pMac->lim.gLimPrevSmeState;
1129 pMac->lim.gLimMlmState = pMac->lim.gLimPrevMlmState;
Jeff Johnsone7245742012-09-05 17:12:55 -07001130 MTRACE(macTrace(pMac, TRACE_CODE_SME_STATE, NO_SESSION, pMac->lim.gLimSmeState));
1131 MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, NO_SESSION, pMac->lim.gLimMlmState));
Jeff Johnson295189b2012-06-20 16:38:30 -07001132 PELOG4(limLog(pMac, LOG4,
1133 FL("Restored from Learn mode on RadioId %d\n"),
1134 pMac->sys.gSirRadioId);)
1135} /****** end limRestorePreLearnState() ******/
Jeff Johnson295189b2012-06-20 16:38:30 -07001136#endif //#if (defined(ANI_PRODUCT_TYPE_AP) || (ANI_PRODUCT_TYPE_AP_SDK))
Jeff Johnson295189b2012-06-20 16:38:30 -07001137/**
1138 * limGetHTCBState
1139 *
1140 *FUNCTION:
1141 * This routing provides the translation of Airgo Enum to HT enum for determining
1142 * secondary channel offset.
1143 * Airgo Enum is required for backward compatibility purposes.
1144 *
1145 *
1146 *NOTE:
1147 *
1148 * @param pMac - Pointer to Global MAC structure
1149 * @return The corresponding HT enumeration
1150 */
Jeff Johnsone7245742012-09-05 17:12:55 -07001151ePhyChanBondState limGetHTCBState(ePhyChanBondState aniCBMode)
Jeff Johnson295189b2012-06-20 16:38:30 -07001152{
Jeff Johnsone7245742012-09-05 17:12:55 -07001153 switch ( aniCBMode )
1154 {
1155#ifdef WLAN_FEATURE_11AC
1156 case PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_LOW:
1157 case PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_CENTERED:
1158 case PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_HIGH:
1159#endif
1160 case PHY_DOUBLE_CHANNEL_HIGH_PRIMARY:
1161 return PHY_DOUBLE_CHANNEL_HIGH_PRIMARY;
1162#ifdef WLAN_FEATURE_11AC
1163 case PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_LOW:
1164 case PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_CENTERED:
1165 case PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_HIGH:
1166#endif
1167 case PHY_DOUBLE_CHANNEL_LOW_PRIMARY:
1168 return PHY_DOUBLE_CHANNEL_LOW_PRIMARY;
1169#ifdef WLAN_FEATURE_11AC
1170 case PHY_QUADRUPLE_CHANNEL_20MHZ_CENTERED_40MHZ_CENTERED:
1171 return PHY_SINGLE_CHANNEL_CENTERED;
1172#endif
1173 default :
1174 return PHY_SINGLE_CHANNEL_CENTERED;
1175 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001176}
1177
Jeff Johnsone7245742012-09-05 17:12:55 -07001178 /*
Jeff Johnson295189b2012-06-20 16:38:30 -07001179 * limGetStaPeerType
1180 *
1181 *FUNCTION:
1182 * Based on a combination of the following -
1183 * 1) tDphHashNode.aniPeer
1184 * 2) tDphHashNode.propCapability
1185 * this API determines if a given STA is an ANI peer or not
1186 *
1187 *LOGIC:
1188 *
1189 *ASSUMPTIONS:
1190 *
1191 *NOTE:
1192 *
1193 * @param pMac - Pointer to Global MAC structure
1194 * @param pStaDs - Pointer to the tpDphHashNode of the STA
1195 * under consideration
1196 * @return tStaRateMode
1197 */
1198tStaRateMode limGetStaPeerType( tpAniSirGlobal pMac,
1199 tpDphHashNode pStaDs,
1200 tpPESession psessionEntry)
1201{
1202tStaRateMode staPeerType = eSTA_11b;
Jeff Johnson295189b2012-06-20 16:38:30 -07001203 // Determine the peer-STA type
1204 if( pStaDs->aniPeer )
1205 {
1206 if(PROP_CAPABILITY_GET( TAURUS, pStaDs->propCapability ))
1207 staPeerType = eSTA_TAURUS;
1208 else if( PROP_CAPABILITY_GET( TITAN, pStaDs->propCapability ))
1209 staPeerType = eSTA_TITAN;
1210 else
1211 staPeerType = eSTA_POLARIS;
1212 }
Jeff Johnsone7245742012-09-05 17:12:55 -07001213#ifdef WLAN_FEATURE_11AC
1214 else if(pStaDs->mlmStaContext.vhtCapability)
1215 staPeerType = eSTA_11ac;
1216#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07001217 else if(pStaDs->mlmStaContext.htCapability)
1218 staPeerType = eSTA_11n;
1219 else if(pStaDs->erpEnabled)
1220 staPeerType = eSTA_11bg;
1221 else if(psessionEntry->limRFBand == SIR_BAND_5_GHZ)
1222 staPeerType = eSTA_11a;
Jeff Johnson295189b2012-06-20 16:38:30 -07001223 return staPeerType;
1224}
1225