blob: 6c8ac82a730577c9bd3d6227b13817def4e1c40f [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 \file rrmApi.c
45
46 \brief implementation for PE RRM APIs
47
48 Copyright 2008 (c) Qualcomm, Incorporated. All Rights Reserved.
49
50 Qualcomm Confidential and Proprietary.
51
52 ========================================================================*/
53
54/* $Header$ */
55
56#if defined WLAN_FEATURE_VOWIFI
57
58/*--------------------------------------------------------------------------
59 Include Files
60 ------------------------------------------------------------------------*/
61#include "palTypes.h"
62#include "wniApi.h"
63#include "sirApi.h"
64#include "aniGlobal.h"
Jeff Johnson295189b2012-06-20 16:38:30 -070065#include "wniCfgSta.h"
Jeff Johnson295189b2012-06-20 16:38:30 -070066#include "limTypes.h"
67#include "limUtils.h"
68#include "limSendSmeRspMessages.h"
69#include "parserApi.h"
70#include "limSendMessages.h"
71#include "rrmGlobal.h"
72#include "rrmApi.h"
73
Gopichand Nakkala41b56fd2013-02-28 15:26:52 +053074tANI_U8
75rrmGetMinOfMaxTxPower(tPowerdBm regMax, tPowerdBm apTxPower)
76{
77 tANI_U8 maxTxPower = 0;
78 tANI_U8 txPower = VOS_MIN( regMax , (apTxPower) );
79 if((txPower >= RRM_MIN_TX_PWR_CAP) && (txPower <= RRM_MAX_TX_PWR_CAP))
80 maxTxPower = txPower;
81 else if (txPower < RRM_MIN_TX_PWR_CAP)
82 maxTxPower = RRM_MIN_TX_PWR_CAP;
83 else
84 maxTxPower = RRM_MAX_TX_PWR_CAP;
85
86 return maxTxPower;
87}
Jeff Johnson295189b2012-06-20 16:38:30 -070088
89// --------------------------------------------------------------------
90/**
91 * rrmCacheMgmtTxPower
92 **
93 * FUNCTION: Store Tx power for management frames.
94 *
95 * LOGIC:
96 *
97 * ASSUMPTIONS:
98 *
99 * NOTE:
100 *
101 * @param pSessionEntry session entry.
102 * @return None
103 */
104void
105rrmCacheMgmtTxPower ( tpAniSirGlobal pMac, tPowerdBm txPower, tpPESession pSessionEntry )
106{
107#if defined WLAN_VOWIFI_DEBUG
108 PELOGE(limLog( pMac, LOGE, "Cache Mgmt Tx Power = %d\n", txPower );)
109#endif
110 if( pSessionEntry == NULL )
111 pMac->rrm.rrmPEContext.txMgmtPower = txPower;
112 else
113 pSessionEntry->txMgmtPower = txPower;
114}
115
116// --------------------------------------------------------------------
117/**
118 * rrmGetMgmtTxPower
119 *
120 * FUNCTION: Get the Tx power for management frames.
121 *
122 * LOGIC:
123 *
124 * ASSUMPTIONS:
125 *
126 * NOTE:
127 *
128 * @param pSessionEntry session entry.
129 * @return txPower
130 */
131tPowerdBm
132rrmGetMgmtTxPower ( tpAniSirGlobal pMac, tpPESession pSessionEntry )
133{
134#if defined WLAN_VOWIFI_DEBUG
135 PELOGE(limLog( pMac, LOGE, "RrmGetMgmtTxPower called\n" );)
136#endif
137 if( pSessionEntry == NULL )
138 return pMac->rrm.rrmPEContext.txMgmtPower;
139
140 return pSessionEntry->txMgmtPower;
141}
142
143// --------------------------------------------------------------------
144/**
145 * rrmSendSetMaxTxPowerReq
146 *
147 * FUNCTION: Send WDA_SET_MAX_TX_POWER_REQ message to change the max tx power.
148 *
149 * LOGIC:
150 *
151 * ASSUMPTIONS:
152 *
153 * NOTE:
154 *
155 * @param txPower txPower to be set.
156 * @param pSessionEntry session entry.
157 * @return None
158 */
159tSirRetStatus
160rrmSendSetMaxTxPowerReq ( tpAniSirGlobal pMac, tPowerdBm txPower, tpPESession pSessionEntry )
161{
162 tpMaxTxPowerParams pMaxTxParams;
163 tSirRetStatus retCode = eSIR_SUCCESS;
164 tSirMsgQ msgQ;
165
166 if( pSessionEntry == NULL )
167 {
168 PELOGE(limLog(pMac, LOGE, FL(" Inavalid parameters\n"));)
169 return eSIR_FAILURE;
170 }
171 if( eHAL_STATUS_SUCCESS != palAllocateMemory( pMac->hHdd,
172 (void **) &pMaxTxParams, sizeof(tMaxTxPowerParams) ) )
173 {
174 limLog( pMac, LOGP, FL("Unable to allocate memory for pMaxTxParams \n") );
175 return eSIR_MEM_ALLOC_FAILED;
176
177 }
178#if defined WLAN_VOWIFI_DEBUG
179 PELOGE(limLog( pMac, LOGE, FL(" Allocated memory for pMaxTxParams...will be freed in other module\n") );)
180#endif
181 pMaxTxParams->power = txPower;
182 palCopyMemory( pMac->hHdd, pMaxTxParams->bssId, pSessionEntry->bssId, sizeof(tSirMacAddr) );
183 palCopyMemory( pMac->hHdd, pMaxTxParams->selfStaMacAddr, pSessionEntry->selfMacAddr, sizeof(tSirMacAddr) );
184
185
186 msgQ.type = WDA_SET_MAX_TX_POWER_REQ;
187 msgQ.reserved = 0;
188 msgQ.bodyptr = pMaxTxParams;
189 msgQ.bodyval = 0;
190
191 PELOGW(limLog(pMac, LOGW, FL( "Sending WDA_SET_MAX_TX_POWER_REQ to HAL"));)
192
Jeff Johnsone7245742012-09-05 17:12:55 -0700193 MTRACE(macTraceMsgTx(pMac, pSessionEntry->peSessionId, msgQ.type));
Jeff Johnson295189b2012-06-20 16:38:30 -0700194 if( eSIR_SUCCESS != (retCode = wdaPostCtrlMsg( pMac, &msgQ )))
195 {
196 limLog( pMac, LOGP, FL("Posting WDA_SET_MAX_TX_POWER_REQ to HAL failed, reason=%X"), retCode );
197 if (NULL != pMaxTxParams)
198 {
199 palFreeMemory( pMac->hHdd, (tANI_U8 *) pMaxTxParams );
200 }
201 return retCode;
202 }
203 return retCode;
204}
205
206
207// --------------------------------------------------------------------
208/**
209 * rrmSetMaxTxPowerRsp
210 *
211 * FUNCTION: Process WDA_SET_MAX_TX_POWER_RSP message.
212 *
213 * LOGIC:
214 *
215 * ASSUMPTIONS:
216 *
217 * NOTE:
218 *
219 * @param txPower txPower to be set.
220 * @param pSessionEntry session entry.
221 * @return None
222 */
223tSirRetStatus
224rrmSetMaxTxPowerRsp ( tpAniSirGlobal pMac, tpSirMsgQ limMsgQ )
225{
226 tSirRetStatus retCode = eSIR_SUCCESS;
227 tpMaxTxPowerParams pMaxTxParams = (tpMaxTxPowerParams) limMsgQ->bodyptr;
228 tpPESession pSessionEntry;
229 tANI_U8 sessionId;
230
231 if((pSessionEntry = peFindSessionByBssid(pMac, pMaxTxParams->bssId, &sessionId))==NULL)
232 {
233 PELOGE(limLog(pMac, LOGE, FL("Unable to find session:\n") );)
234 retCode = eSIR_FAILURE;
235 }
236 else
237 {
238 rrmCacheMgmtTxPower ( pMac, pMaxTxParams->power, pSessionEntry );
239 }
240
241 palFreeMemory(pMac->hHdd, (void*)limMsgQ->bodyptr);
242 limMsgQ->bodyptr = NULL;
243 return retCode;
244}
245// --------------------------------------------------------------------
246/**
247 * rrmProcessLinkMeasurementRequest
248 *
249 * FUNCTION: Processes the Link measurement request and send the report.
250 *
251 * LOGIC:
252 *
253 * ASSUMPTIONS:
254 *
255 * NOTE:
256 *
257 * @param pBd pointer to BD to extract RSSI and SNR
258 * @param pLinkReq pointer to the Link request frame structure.
259 * @param pSessionEntry session entry.
260 * @return None
261 */
262tSirRetStatus
263rrmProcessLinkMeasurementRequest( tpAniSirGlobal pMac,
264 tANI_U8 *pRxPacketInfo,
265 tDot11fLinkMeasurementRequest *pLinkReq,
266 tpPESession pSessionEntry )
267{
268 tSirMacLinkReport LinkReport;
269 tpSirMacMgmtHdr pHdr;
270 v_S7_t currentRSSI = 0;
271
272#if defined WLAN_VOWIFI_DEBUG
273 PELOGE(limLog( pMac, LOGE, "Received Link measurement request\n");)
274#endif
275 if( pRxPacketInfo == NULL || pLinkReq == NULL || pSessionEntry == NULL )
276 {
277 PELOGE(limLog( pMac, LOGE, "%s:%d: Invalid parameters - Ignoring the request\n");)
278 return eSIR_FAILURE;
279 }
280 pHdr = WDA_GET_RX_MAC_HEADER( pRxPacketInfo );
281#if defined WLAN_VOWIFI_DEBUG
282 if( pSessionEntry->maxTxPower != (tPowerdBm) pLinkReq->MaxTxPower.maxTxPower )
283 {
284 PELOGE(limLog( pMac, LOGE, FL(" maxTx power in link request is not same as local...Local = %d LinkReq = %d\n"),
285 pSessionEntry->maxTxPower, pLinkReq->MaxTxPower.maxTxPower );)
286 }
287#endif
288
289 LinkReport.dialogToken = pLinkReq->DialogToken.token;
290 LinkReport.txPower = pSessionEntry->txMgmtPower;
291 LinkReport.rxAntenna = 0;
292 LinkReport.txAntenna = 0;
293 currentRSSI = WDA_GET_RX_RSSI_DB(pRxPacketInfo);
294
295#if defined WLAN_VOWIFI_DEBUG
296 PELOGE(limLog( pMac, LOGE, "Received Link report frame with %d\n", currentRSSI);)
297#endif
298
299 // 2008 11k spec reference: 18.4.8.5 RCPI Measurement
300 if ((currentRSSI) <= RCPI_LOW_RSSI_VALUE)
301 LinkReport.rcpi = 0;
302 else if ((currentRSSI > RCPI_LOW_RSSI_VALUE) && (currentRSSI <= 0))
303 LinkReport.rcpi = CALCULATE_RCPI(currentRSSI);
304 else
305 LinkReport.rcpi = RCPI_MAX_VALUE;
306
307 LinkReport.rsni = WDA_GET_RX_SNR(pRxPacketInfo);
308
309#if defined WLAN_VOWIFI_DEBUG
310 PELOGE(limLog( pMac, LOGE, "Sending Link report frame\n");)
311#endif
312 return limSendLinkReportActionFrame( pMac, &LinkReport, pHdr->sa, pSessionEntry );
313
314
315}
316
317// --------------------------------------------------------------------
318/**
319 * rrmProcessNeighborReportResponse
320 *
321 * FUNCTION: Processes the Neighbor Report response from the peer AP.
322 *
323 * LOGIC:
324 *
325 * ASSUMPTIONS:
326 *
327 * NOTE:
328 *
329 * @param pNeighborRep pointer to the Neighbor report frame structure.
330 * @param pSessionEntry session entry.
331 * @return None
332 */
333tSirRetStatus
334rrmProcessNeighborReportResponse( tpAniSirGlobal pMac,
335 tDot11fNeighborReportResponse *pNeighborRep,
336 tpPESession pSessionEntry )
337{
338 tSirRetStatus status = eSIR_FAILURE;
339 tpSirNeighborReportInd pSmeNeighborRpt = NULL;
340 tANI_U16 length;
341 tANI_U8 i;
342 tSirMsgQ mmhMsg;
343
344 if( pNeighborRep == NULL || pSessionEntry == NULL )
345 {
346 PELOGE(limLog( pMac, LOGE, FL(" Invalid parameters\n") );)
347 return status;
348 }
349
350#if defined WLAN_VOWIFI_DEBUG
351 PELOGE(limLog( pMac, LOGE, FL("Neighbor report response received \n") );)
352#endif
353
354 // Dialog token
355 if( pMac->rrm.rrmPEContext.DialogToken != pNeighborRep->DialogToken.token )
356 {
357 PELOGE(limLog( pMac, LOGE, "Dialog token mismatch in the received Neighbor report\n");)
358 return eSIR_FAILURE;
359 }
360 if( pNeighborRep->num_NeighborReport == 0 )
361 {
362 PELOGE(limLog( pMac, LOGE, "No neighbor report in the frame...Dropping it\n");)
363 return eSIR_FAILURE;
364 }
365 length = (sizeof( tSirNeighborReportInd )) +
366 (sizeof( tSirNeighborBssDescription ) * (pNeighborRep->num_NeighborReport - 1) ) ;
367
368 //Prepare the request to send to SME.
369 if( eHAL_STATUS_SUCCESS != palAllocateMemory( pMac->hHdd,
370 (void **) &pSmeNeighborRpt, length ) )
371 {
372 PELOGE(limLog( pMac, LOGP, FL("Unable to allocate memory\n") );)
373 return eSIR_MEM_ALLOC_FAILED;
374
375 }
376 palZeroMemory( pMac->hHdd, pSmeNeighborRpt, length );
377#if defined WLAN_VOWIFI_DEBUG
378 PELOGE(limLog( pMac, LOGE, FL(" Allocated memory for pSmeNeighborRpt...will be freed by other module\n") );)
379#endif
380
381 for( i = 0 ; i < pNeighborRep->num_NeighborReport ; i++ )
382 {
383 pSmeNeighborRpt->sNeighborBssDescription[i].length = sizeof( tSirNeighborBssDescription ); /*+ any optional ies */
384 palCopyMemory( pMac->hHdd, pSmeNeighborRpt->sNeighborBssDescription[i].bssId,
385 pNeighborRep->NeighborReport[i].bssid, sizeof(tSirMacAddr) );
386 pSmeNeighborRpt->sNeighborBssDescription[i].bssidInfo.rrmInfo.fApPreauthReachable = pNeighborRep->NeighborReport[i].APReachability;
387 pSmeNeighborRpt->sNeighborBssDescription[i].bssidInfo.rrmInfo.fSameSecurityMode = pNeighborRep->NeighborReport[i].Security;
388 pSmeNeighborRpt->sNeighborBssDescription[i].bssidInfo.rrmInfo.fSameAuthenticator = pNeighborRep->NeighborReport[i].KeyScope;
389 pSmeNeighborRpt->sNeighborBssDescription[i].bssidInfo.rrmInfo.fCapSpectrumMeasurement = pNeighborRep->NeighborReport[i].SpecMgmtCap;
390 pSmeNeighborRpt->sNeighborBssDescription[i].bssidInfo.rrmInfo.fCapQos = pNeighborRep->NeighborReport[i].QosCap;
391 pSmeNeighborRpt->sNeighborBssDescription[i].bssidInfo.rrmInfo.fCapApsd = pNeighborRep->NeighborReport[i].apsd;
392 pSmeNeighborRpt->sNeighborBssDescription[i].bssidInfo.rrmInfo.fCapRadioMeasurement = pNeighborRep->NeighborReport[i].rrm;
393 pSmeNeighborRpt->sNeighborBssDescription[i].bssidInfo.rrmInfo.fCapDelayedBlockAck = pNeighborRep->NeighborReport[i].DelayedBA;
394 pSmeNeighborRpt->sNeighborBssDescription[i].bssidInfo.rrmInfo.fCapImmediateBlockAck = pNeighborRep->NeighborReport[i].ImmBA;
395 pSmeNeighborRpt->sNeighborBssDescription[i].bssidInfo.rrmInfo.fMobilityDomain = pNeighborRep->NeighborReport[i].MobilityDomain;
396
397 pSmeNeighborRpt->sNeighborBssDescription[i].regClass = pNeighborRep->NeighborReport[i].regulatoryClass;
398 pSmeNeighborRpt->sNeighborBssDescription[i].channel = pNeighborRep->NeighborReport[i].channel;
399 pSmeNeighborRpt->sNeighborBssDescription[i].phyType = pNeighborRep->NeighborReport[i].PhyType;
400 }
401
402 pSmeNeighborRpt->messageType = eWNI_SME_NEIGHBOR_REPORT_IND;
403 pSmeNeighborRpt->length = length;
404 pSmeNeighborRpt->numNeighborReports = pNeighborRep->num_NeighborReport;
405 palCopyMemory( pMac->hHdd, pSmeNeighborRpt->bssId, pSessionEntry->bssId, sizeof(tSirMacAddr) );
406
407 //Send request to SME.
408 mmhMsg.type = pSmeNeighborRpt->messageType;
409 mmhMsg.bodyptr = pSmeNeighborRpt;
Jeff Johnsone7245742012-09-05 17:12:55 -0700410 MTRACE(macTraceMsgTx(pMac, pSessionEntry->peSessionId, mmhMsg.type));
Jeff Johnson295189b2012-06-20 16:38:30 -0700411 status = limSysProcessMmhMsgApi(pMac, &mmhMsg, ePROT);
412
413 return status;
414
415}
416
417// --------------------------------------------------------------------
418/**
419 * rrmProcessNeighborReportReq
420 *
421 * FUNCTION:
422 *
423 * LOGIC: Create a Neighbor report request and send it to peer.
424 *
425 * ASSUMPTIONS:
426 *
427 * NOTE:
428 *
429 * @param pNeighborReq Neighbor report request params .
430 * @return None
431 */
432tSirRetStatus
433rrmProcessNeighborReportReq( tpAniSirGlobal pMac,
434 tpSirNeighborReportReqInd pNeighborReq )
435{
436 tSirRetStatus status = eSIR_SUCCESS;
437 tSirMacNeighborReportReq NeighborReportReq;
438 tpPESession pSessionEntry ;
439 tANI_U8 sessionId;
440
441 if( pNeighborReq == NULL )
442 {
443 PELOGE(limLog( pMac, LOGE, "NeighborReq is NULL\n" );)
444 return eSIR_FAILURE;
445 }
446 if ((pSessionEntry = peFindSessionByBssid(pMac,pNeighborReq->bssId,&sessionId))==NULL)
447 {
448 PELOGE(limLog(pMac, LOGE,FL("session does not exist for given bssId\n"));)
449 return eSIR_FAILURE;
450 }
451
452#if defined WLAN_VOWIFI_DEBUG
453 PELOGE(limLog( pMac, LOGE, FL("Neighbor Request received \n") );)
454 PELOGE(limLog( pMac, LOGE, "SSID present = %d \n", pNeighborReq->noSSID );)
455#endif
456
457 palZeroMemory( pMac->hHdd, &NeighborReportReq, sizeof( tSirMacNeighborReportReq ) );
458
459 NeighborReportReq.dialogToken = ++pMac->rrm.rrmPEContext.DialogToken;
460 NeighborReportReq.ssid_present = !pNeighborReq->noSSID;
461 if( NeighborReportReq.ssid_present )
462 {
463 palCopyMemory( pMac->hHdd, &NeighborReportReq.ssid, &pNeighborReq->ucSSID, sizeof(tSirMacSSid) );
464#if defined WLAN_VOWIFI_DEBUG
465 PELOGE(sirDumpBuf( pMac, SIR_LIM_MODULE_ID, LOGE, (tANI_U8*) NeighborReportReq.ssid.ssId, NeighborReportReq.ssid.length );)
466#endif
467 }
468
469 status = limSendNeighborReportRequestFrame( pMac, &NeighborReportReq, pNeighborReq->bssId, pSessionEntry );
470
471 return status;
472}
473
474#define ABS(x) ((x < 0) ? -x : x)
475// --------------------------------------------------------------------
476/**
477 * rrmProcessBeaconReportReq
478 *
479 * FUNCTION: Processes the Beacon report request from the peer AP.
480 *
481 * LOGIC:
482 *
483 * ASSUMPTIONS:
484 *
485 * NOTE:
486 *
487 * @param pCurrentReq pointer to the current Req comtext.
488 * @param pBeaconReq pointer to the beacon report request IE from the peer.
489 * @param pSessionEntry session entry.
490 * @return None
491 */
492static tRrmRetStatus
493rrmProcessBeaconReportReq( tpAniSirGlobal pMac,
494 tpRRMReq pCurrentReq,
495 tDot11fIEMeasurementRequest *pBeaconReq,
496 tpPESession pSessionEntry )
497{
498 tSirMsgQ mmhMsg;
499 tpSirBeaconReportReqInd pSmeBcnReportReq;
500 tANI_U8 num_channels = 0, num_APChanReport;
501 tANI_U16 measDuration, maxMeasduration;
502 tANI_S8 maxDuration;
503 tANI_U8 sign;
504
505 if( pBeaconReq->measurement_request.Beacon.BeaconReporting.present &&
506 (pBeaconReq->measurement_request.Beacon.BeaconReporting.reportingCondition != 0) )
507 {
508 //Repeated measurement is not supported. This means number of repetitions should be zero.(Already checked)
509 //All test case in VoWifi(as of version 0.36) use zero for number of repetitions.
510 //Beacon reporting should not be included in request if number of repetitons is zero.
511 // IEEE Std 802.11k-2008 Table 7-29g and section 11.10.8.1
512
Jeff Johnson1250df42012-12-10 14:31:52 -0800513 PELOGE(limLog( pMac, LOGE, "Dropping the request: Reporting condition included in beacon report request and it is not zero\n");)
Jeff Johnson295189b2012-06-20 16:38:30 -0700514 return eRRM_INCAPABLE;
515 }
516
517 /* The logic here is to check the measurement duration passed in the beacon request. Following are the cases handled.
518 Case 1: If measurement duration received in the beacon request is greater than the max measurement duration advertised
519 in the RRM capabilities(Assoc Req), and Duration Mandatory bit is set to 1, REFUSE the beacon request
520 Case 2: If measurement duration received in the beacon request is greater than the max measurement duration advertised
521 in the RRM capabilities(Assoc Req), and Duration Mandatory bit is set to 0, perform measurement for
522 the duration advertised in the RRM capabilities
523
524 maxMeasurementDuration = 2^(nonOperatingChanMax - 4) * BeaconInterval
525 */
526 maxDuration = pMac->rrm.rrmPEContext.rrmEnabledCaps.nonOperatingChanMax - 4;
527 sign = (maxDuration < 0) ? 1 : 0;
528 maxDuration = (1L << ABS(maxDuration));
529 if (!sign)
530 maxMeasduration = maxDuration * pSessionEntry->beaconParams.beaconInterval;
531 else
532 maxMeasduration = pSessionEntry->beaconParams.beaconInterval / maxDuration;
533
534 measDuration = pBeaconReq->measurement_request.Beacon.meas_duration;
535
536#if defined WLAN_VOWIFI_DEBUG
537 limLog( pMac, LOGE, "maxDuration = %d sign = %d maxMeasduration = %d measDuration = %d\n",
538 maxDuration, sign, maxMeasduration, measDuration );
539#endif
540
541 if( maxMeasduration < measDuration )
542 {
543 if( pBeaconReq->durationMandatory )
544 {
Jeff Johnson1250df42012-12-10 14:31:52 -0800545 limLog( pMac, LOGE, "Dropping the request: duration mandatory and maxduration > measduration\n");
Jeff Johnson295189b2012-06-20 16:38:30 -0700546 return eRRM_REFUSED;
547 }
548 else
549 measDuration = maxMeasduration;
550 }
551
552 //Cache the data required for sending report.
553 pCurrentReq->request.Beacon.reportingDetail = pBeaconReq->measurement_request.Beacon.BcnReportingDetail.present ?
554 pBeaconReq->measurement_request.Beacon.BcnReportingDetail.reportingDetail :
555 BEACON_REPORTING_DETAIL_ALL_FF_IE ;
556
557 if( pBeaconReq->measurement_request.Beacon.RequestedInfo.present )
558 {
559 if( eHAL_STATUS_SUCCESS != palAllocateMemory( pMac->hHdd, (void**) &pCurrentReq->request.Beacon.reqIes.pElementIds,
560 ( sizeof( tANI_U8) *
561 pBeaconReq->measurement_request.Beacon.RequestedInfo.num_requested_eids ) ) )
562 {
563 limLog( pMac, LOGP,
564 FL( "Unable to PAL allocate memory for request IEs buffer\n" ));
565 return eRRM_FAILURE;
566 }
567#if defined WLAN_VOWIFI_DEBUG
568 PELOGE(limLog( pMac, LOGE, FL(" Allocated memory for pElementIds\n") );)
569#endif
570 pCurrentReq->request.Beacon.reqIes.num = pBeaconReq->measurement_request.Beacon.RequestedInfo.num_requested_eids;
571 palCopyMemory ( pMac->hHdd, pCurrentReq->request.Beacon.reqIes.pElementIds,
572 pBeaconReq->measurement_request.Beacon.RequestedInfo.requested_eids,
573 pCurrentReq->request.Beacon.reqIes.num );
574 }
575
576 if( pBeaconReq->measurement_request.Beacon.num_APChannelReport )
577 {
578 for( num_APChanReport = 0 ; num_APChanReport < pBeaconReq->measurement_request.Beacon.num_APChannelReport ; num_APChanReport++ )
579 num_channels += pBeaconReq->measurement_request.Beacon.APChannelReport[num_APChanReport].num_channelList;
580 }
581
582 //Prepare the request to send to SME.
583 if( eHAL_STATUS_SUCCESS != palAllocateMemory( pMac->hHdd,
584 (void **) &pSmeBcnReportReq,
585 (sizeof( tSirBeaconReportReqInd ) + num_channels) ) )
586 {
587 limLog( pMac, LOGP,
588 FL( "Unable to PAL allocate memory during Beacon Report Req Ind to SME\n" ));
589
590 return eRRM_FAILURE;
591
592 }
593
594 palZeroMemory( pMac->hHdd, pSmeBcnReportReq, sizeof( tSirBeaconReportReqInd ) + num_channels );
595
596#if defined WLAN_VOWIFI_DEBUG
597 PELOGE(limLog( pMac, LOGE, FL(" Allocated memory for pSmeBcnReportReq....will be freed by other module\n") );)
598#endif
599 palCopyMemory( pMac->hHdd, pSmeBcnReportReq->bssId, pSessionEntry->bssId, sizeof(tSirMacAddr) );
600 pSmeBcnReportReq->messageType = eWNI_SME_BEACON_REPORT_REQ_IND;
601 pSmeBcnReportReq->length = sizeof( tSirBeaconReportReqInd ) + num_channels;
602 pSmeBcnReportReq->uDialogToken = pBeaconReq->measurement_token;
603 //pSmeBcnReportReq->measurementDuration = SYS_TU_TO_MS(pBeaconReq->measurement_request.Beacon.meas_duration);
604 pSmeBcnReportReq->measurementDuration = SYS_TU_TO_MS(measDuration /*pBeaconReq->measurement_request.Beacon.meas_duration*/);
605 pSmeBcnReportReq->randomizationInterval = SYS_TU_TO_MS (pBeaconReq->measurement_request.Beacon.randomization);
606 pSmeBcnReportReq->fMeasurementtype = pBeaconReq->measurement_request.Beacon.meas_mode;
607 pSmeBcnReportReq->channelInfo.regulatoryClass = pBeaconReq->measurement_request.Beacon.regClass;
608 pSmeBcnReportReq->channelInfo.channelNum = pBeaconReq->measurement_request.Beacon.channel;
609 palCopyMemory( pMac->hHdd, pSmeBcnReportReq->macaddrBssid, pBeaconReq->measurement_request.Beacon.BSSID, sizeof(tSirMacAddr) );
610
611 if( pBeaconReq->measurement_request.Beacon.SSID.present )
612 {
613 pSmeBcnReportReq->ssId.length = pBeaconReq->measurement_request.Beacon.SSID.num_ssid;
614 palCopyMemory( pMac->hHdd, pSmeBcnReportReq->ssId.ssId, pBeaconReq->measurement_request.Beacon.SSID.ssid,
615 pSmeBcnReportReq->ssId.length );
616 }
617
618 pCurrentReq->token = pBeaconReq->measurement_token;
619
620 pSmeBcnReportReq->channelList.numChannels = num_channels;
621 if( pBeaconReq->measurement_request.Beacon.num_APChannelReport )
622 {
623 tANI_U8 *pChanList = pSmeBcnReportReq->channelList.channelNumber;
624 for( num_APChanReport = 0 ; num_APChanReport < pBeaconReq->measurement_request.Beacon.num_APChannelReport ; num_APChanReport++ )
625 {
626 palCopyMemory( pMac->hHdd, pChanList,
627 pBeaconReq->measurement_request.Beacon.APChannelReport[num_APChanReport].channelList,
628 pBeaconReq->measurement_request.Beacon.APChannelReport[num_APChanReport].num_channelList );
629
630 pChanList += pBeaconReq->measurement_request.Beacon.APChannelReport[num_APChanReport].num_channelList;
631 }
632 }
633
634 //Send request to SME.
635 mmhMsg.type = eWNI_SME_BEACON_REPORT_REQ_IND;
636 mmhMsg.bodyptr = pSmeBcnReportReq;
Jeff Johnsone7245742012-09-05 17:12:55 -0700637 MTRACE(macTraceMsgTx(pMac, pSessionEntry->peSessionId, mmhMsg.type));
Jeff Johnson295189b2012-06-20 16:38:30 -0700638 return limSysProcessMmhMsgApi(pMac, &mmhMsg, ePROT);
639}
640
641// --------------------------------------------------------------------
642/**
643 * rrmFillBeaconIes
644 *
645 * FUNCTION:
646 *
647 * LOGIC: Fills Fixed fields and Ies in bss description to an array of tANI_U8.
648 *
649 * ASSUMPTIONS:
650 *
651 * NOTE:
652 *
653 * @param pIes - pointer to the buffer that should be populated with ies.
654 * @param pNumIes - returns the num of ies filled in this param.
655 * @param pIesMaxSize - Max size of the buffer pIes.
656 * @param eids - pointer to array of eids. If NULL, all ies will be populated.
657 * @param numEids - number of elements in array eids.
658 * @param pBssDesc - pointer to Bss Description.
659 * @return None
660 */
661static void
662rrmFillBeaconIes( tpAniSirGlobal pMac,
663 tANI_U8 *pIes, tANI_U8 *pNumIes, tANI_U8 pIesMaxSize,
664 tANI_U8 *eids, tANI_U8 numEids,
665 tpSirBssDescription pBssDesc )
666{
667 tANI_U8 len, *pBcnIes, BcnNumIes, count = 0, i;
668
669 if( (pIes == NULL) || (pNumIes == NULL) || (pBssDesc == NULL) )
670 {
671 PELOGE(limLog( pMac, LOGE, FL(" Invalid parameters\n") );)
672 return;
673 }
674
675 //Make sure that if eid is null, numEids is set to zero.
676 numEids = (eids == NULL) ? 0 : numEids;
677
678 pBcnIes = (tANI_U8*) &pBssDesc->ieFields[0];
679 BcnNumIes = (tANI_U8)GET_IE_LEN_IN_BSS( pBssDesc->length );
680
681 *pNumIes = 0;
682
683 *((tANI_U32*)pIes) = pBssDesc->timeStamp[0];
684 *pNumIes+=sizeof(tANI_U32); pIes+=sizeof(tANI_U32);
685 *((tANI_U32*)pIes) = pBssDesc->timeStamp[1];
686 *pNumIes+=sizeof(tANI_U32); pIes+=sizeof(tANI_U32);
687 *((tANI_U16*)pIes) = pBssDesc->beaconInterval;
688 *pNumIes+=sizeof(tANI_U16); pIes+=sizeof(tANI_U16);
689 *((tANI_U16*)pIes) = pBssDesc->capabilityInfo;
690 *pNumIes+=sizeof(tANI_U16); pIes+=sizeof(tANI_U16);
691
692 while ( BcnNumIes > 0 )
693 {
694 len = *(pBcnIes + 1) + 2; //element id + length.
695#if defined WLAN_VOWIFI_DEBUG
696 PELOGE(limLog( pMac, LOGE, "EID = %d, len = %d total = %d\n", *pBcnIes, *(pBcnIes+1), len );)
697#endif
698
699 i = 0;
700 do
701 {
702 if( ( (eids == NULL) || ( *pBcnIes == eids[i] ) ) &&
703 ( (*pNumIes) + len) < pIesMaxSize )
704 {
705#if defined WLAN_VOWIFI_DEBUG
706 PELOGE(limLog( pMac, LOGE, "Adding Eid %d, len=%d\n", *pBcnIes, len );)
707#endif
708 palCopyMemory( pMac->hHdd, pIes, pBcnIes, len );
709 pIes += len;
710 *pNumIes += len;
711 count++;
712 break;
713 }
714 i++;
715 }while( i < numEids );
716
717 pBcnIes += len;
718 BcnNumIes -= len;
719 }
720#if defined WLAN_VOWIFI_DEBUG
721 PELOGE(limLog( pMac, LOGE, "Total length of Ies added = %d\n", *pNumIes );)
722#endif
723}
724
725// --------------------------------------------------------------------
726/**
727 * rrmProcessBeaconReportXmit
728 *
729 * FUNCTION:
730 *
731 * LOGIC: Create a Radio measurement report action frame and send it to peer.
732 *
733 * ASSUMPTIONS:
734 *
735 * NOTE:
736 *
737 * @param pBcnReport Data for beacon report IE from SME.
738 * @return None
739 */
740tSirRetStatus
741rrmProcessBeaconReportXmit( tpAniSirGlobal pMac,
742 tpSirBeaconReportXmitInd pBcnReport)
743{
744 tSirRetStatus status = eSIR_SUCCESS;
745 tSirMacRadioMeasureReport report, *pReport;
746 tpRRMReq pCurrentReq = pMac->rrm.rrmPEContext.pCurrentReq;
747 tpPESession pSessionEntry ;
748 tANI_U8 sessionId;
Gopichand Nakkala72717fd2013-02-08 12:23:45 +0530749 v_U8_t flagBSSPresent = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -0700750
751#if defined WLAN_VOWIFI_DEBUG
752 PELOGE(limLog( pMac, LOGE, "Received beacon report xmit indication\n");)
753#endif
754 if(NULL == pBcnReport)
755 return eSIR_FAILURE;
756
757 if ( pCurrentReq == NULL )
758 {
759 PELOGE(limLog( pMac, LOGE, "Received report xmit while there is no request pending in PE\n");)
760 return eSIR_FAILURE;
761 }
762 if ((pSessionEntry = peFindSessionByBssid(pMac,pBcnReport->bssId,&sessionId))==NULL)
763 {
764 PELOGE(limLog(pMac, LOGE,FL("session does not exist for given bssId\n"));)
765 return eSIR_FAILURE;
766 }
767
768 pReport = &report;
769 palZeroMemory( pMac->hHdd, pReport, sizeof(tSirMacRadioMeasureReport) );
770 //Prepare the beacon report and send it to the peer.
771 pReport->token = pBcnReport->uDialogToken;
772 pReport->refused = 0;
773 pReport->incapable = 0;
774 pReport->type = SIR_MAC_RRM_BEACON_TYPE;
775
Gopichand Nakkala72717fd2013-02-08 12:23:45 +0530776 //If the scan result is NULL then send report request with option subelement as NULL..
777 if ( NULL != pBcnReport->pBssDescription[0] )
Jeff Johnson295189b2012-06-20 16:38:30 -0700778 {
Gopichand Nakkala72717fd2013-02-08 12:23:45 +0530779 flagBSSPresent = TRUE;
780 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700781
Gopichand Nakkala72717fd2013-02-08 12:23:45 +0530782 //Valid response is included if the size of beacon xmit is == size of beacon xmit ind + ies
783 if ( pBcnReport->length >= sizeof( tSirBeaconReportXmitInd ) )
784 {
785 pReport->report.beaconReport.regClass = pBcnReport->regClass;
786 if ( flagBSSPresent )
787 {
788 pReport->report.beaconReport.channel = pBcnReport->pBssDescription[0]->channelId;
789 palCopyMemory( pMac->hHdd, pReport->report.beaconReport.measStartTime,
790 pBcnReport->pBssDescription[0]->startTSF,
791 sizeof( pBcnReport->pBssDescription[0]->startTSF) );
792 pReport->report.beaconReport.measDuration = SYS_MS_TO_TU(pBcnReport->duration);
793 pReport->report.beaconReport.phyType = pBcnReport->pBssDescription[0]->nwType;
794 pReport->report.beaconReport.bcnProbeRsp = 1;
795 pReport->report.beaconReport.rsni = pBcnReport->pBssDescription[0]->sinr;
796 pReport->report.beaconReport.rcpi = pBcnReport->pBssDescription[0]->rssi;
797
798 pReport->report.beaconReport.antennaId = 0;
799 pReport->report.beaconReport.parentTSF = pBcnReport->pBssDescription[0]->parentTSF;
800 palCopyMemory(pMac->hHdd, pReport->report.beaconReport.bssid,
801 pBcnReport->pBssDescription[0]->bssId, sizeof(tSirMacAddr));
802 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700803
804 switch ( pCurrentReq->request.Beacon.reportingDetail )
805 {
806 case BEACON_REPORTING_DETAIL_NO_FF_IE: //0 No need to include any elements.
807#if defined WLAN_VOWIFI_DEBUG
808 PELOGE(limLog(pMac, LOGE, "No reporting detail requested\n");)
809#endif
810 break;
811 case BEACON_REPORTING_DETAIL_ALL_FF_REQ_IE: //1: Include all FFs and Requested Ies.
812#if defined WLAN_VOWIFI_DEBUG
813 PELOGE(limLog(pMac, LOGE, "Only requested IEs in reporting detail requested\n");)
814#endif
815
Gopichand Nakkala72717fd2013-02-08 12:23:45 +0530816 if ( flagBSSPresent )
817 {
818 rrmFillBeaconIes( pMac, (tANI_U8*) &pReport->report.beaconReport.Ies[0],
819 (tANI_U8*) &pReport->report.beaconReport.numIes, BEACON_REPORT_MAX_IES,
820 pCurrentReq->request.Beacon.reqIes.pElementIds, pCurrentReq->request.Beacon.reqIes.num,
821 pBcnReport->pBssDescription[0] );
822 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700823
824 break;
825 case BEACON_REPORTING_DETAIL_ALL_FF_IE: //2 / default - Include all FFs and all Ies.
826 default:
827#if defined WLAN_VOWIFI_DEBUG
828 PELOGE(limLog(pMac, LOGE, "Default all IEs and FFs\n");)
829#endif
Gopichand Nakkala72717fd2013-02-08 12:23:45 +0530830 if ( flagBSSPresent )
831 {
832 rrmFillBeaconIes( pMac, (tANI_U8*) &pReport->report.beaconReport.Ies[0],
833 (tANI_U8*) &pReport->report.beaconReport.numIes, BEACON_REPORT_MAX_IES,
834 NULL, 0,
835 pBcnReport->pBssDescription[0] );
836 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700837 break;
838 }
839
840#if defined WLAN_VOWIFI_DEBUG
841 PELOGE(limLog( pMac, LOGE, "Sending Action frame \n");)
842#endif
843 limSendRadioMeasureReportActionFrame( pMac, pCurrentReq->dialog_token, 1,
844 pReport, pBcnReport->bssId, pSessionEntry );
845 }
846
847 if( pBcnReport->fMeasureDone )
848 {
849 PELOGE(limLog( pMac, LOGE, "Measurement done....cleanup the context\n");)
850
851 rrmCleanup(pMac);
852 }
853 return status;
854}
855
856void rrmProcessBeaconRequestFailure(tpAniSirGlobal pMac, tpPESession pSessionEntry,
857 tSirMacAddr peer, tRrmRetStatus status)
858{
859 tpSirMacRadioMeasureReport pReport = NULL;
860 tpRRMReq pCurrentReq = pMac->rrm.rrmPEContext.pCurrentReq;
861
862 if( eHAL_STATUS_SUCCESS != palAllocateMemory( pMac->hHdd,
863 (void **) &pReport,
864 sizeof( tSirMacRadioMeasureReport ) ) )
865 {
866 limLog( pMac, LOGP,
867 FL( "Unable to PAL allocate memory during RRM Req processing\n" ));
868 return;
869 }
870 palZeroMemory( pMac->hHdd, pReport, sizeof(tSirMacRadioMeasureReport) );
871 pReport->token = pCurrentReq->token;
872 pReport->type = SIR_MAC_RRM_BEACON_TYPE;
873
874 switch (status)
875 {
876 case eRRM_REFUSED:
877 pReport->refused = 1;
878 break;
879 case eRRM_INCAPABLE:
880 pReport->incapable = 1;
881 break;
882 default:
883 PELOGE(limLog( pMac, LOGE, FL(" Beacon request processing failed no report sent with status %d \n"), status););
884 palFreeMemory( pMac->hHdd, pReport );
885 return;
886 }
887
888 limSendRadioMeasureReportActionFrame( pMac, pCurrentReq->dialog_token, 1,
889 pReport, peer, pSessionEntry );
890
891 palFreeMemory( pMac->hHdd, pReport );
892#if defined WLAN_VOWIFI_DEBUG
893 PELOGE(limLog( pMac, LOGE, FL(" Free memory for pReport\n") );)
894#endif
895 return;
896}
897
898// --------------------------------------------------------------------
899/**
900 * rrmProcessRadioMeasurementRequest
901 *
902 * FUNCTION: Processes the Radio Resource Measurement request.
903 *
904 * LOGIC:
905
906
907*
908 * ASSUMPTIONS:
909 *
910 * NOTE:
911 *
912 * @param peer Macaddress of the peer requesting the radio measurement.
913 * @param pRRMReq Array of Measurement request IEs
914 * @param pSessionEntry session entry.
915 * @return None
916 */
917tSirRetStatus
Gopichand Nakkala72717fd2013-02-08 12:23:45 +0530918rrmProcessRadioMeasurementRequest( tpAniSirGlobal pMac,
Jeff Johnson295189b2012-06-20 16:38:30 -0700919 tSirMacAddr peer,
920 tDot11fRadioMeasurementRequest *pRRMReq,
921 tpPESession pSessionEntry )
922{
923 tANI_U8 i;
924 tSirRetStatus status = eSIR_SUCCESS;
925 tpSirMacRadioMeasureReport pReport = NULL;
926 tANI_U8 num_report = 0;
927 tpRRMReq pCurrentReq = pMac->rrm.rrmPEContext.pCurrentReq;
928 tRrmRetStatus rrmStatus = eRRM_SUCCESS;
929
930 if( !pRRMReq->num_MeasurementRequest )
931 {
932 //No measurement requests....
933 //
Gopichand Nakkala72717fd2013-02-08 12:23:45 +0530934 if( eHAL_STATUS_SUCCESS != palAllocateMemory( pMac->hHdd,
935 (void **) &pReport,
936 sizeof( tSirMacRadioMeasureReport ) ) )
937 {
938 limLog( pMac, LOGP,
939 FL( "Unable to PAL allocate memory during RRM Req processing\n" ));
940 return eSIR_MEM_ALLOC_FAILED;
941 }
942 palZeroMemory( pMac->hHdd, pReport, sizeof(tSirMacRadioMeasureReport) );
943#if defined WLAN_VOWIFI_DEBUG
944 PELOGE(limLog( pMac, LOGE, FL(" Allocated memory for pReport\n") );)
945#endif
946 pReport->incapable = 1;
947 num_report = 1;
948 limSendRadioMeasureReportActionFrame( pMac, pRRMReq->DialogToken.token, num_report,
949 pReport, peer, pSessionEntry );
950 palFreeMemory( pMac->hHdd, pReport );
Jeff Johnson295189b2012-06-20 16:38:30 -0700951 PELOGE(limLog( pMac, LOGE, "No requestIes in the measurement request\n" );)
952 return eSIR_FAILURE;
953 }
954
955 // PF Fix
956 if( pRRMReq->NumOfRepetitions.repetitions > 0 )
957 {
958 //Send a report with incapable bit set. Not supporting repetitions.
959 if( eHAL_STATUS_SUCCESS != palAllocateMemory( pMac->hHdd,
960 (void **) &pReport,
961 sizeof( tSirMacRadioMeasureReport ) ) )
962 {
963 limLog( pMac, LOGP,
964 FL( "Unable to PAL allocate memory during RRM Req processing\n" ));
965 return eSIR_MEM_ALLOC_FAILED;
966 }
967 palZeroMemory( pMac->hHdd, pReport, sizeof(tSirMacRadioMeasureReport) );
968#if defined WLAN_VOWIFI_DEBUG
969 PELOGE(limLog( pMac, LOGE, FL(" Allocated memory for pReport\n") );)
970#endif
971 pReport->incapable = 1;
972 pReport->type = pRRMReq->MeasurementRequest[0].measurement_type;
973 num_report = 1;
974 goto end;
975
976 }
977
978 for( i= 0; i < pRRMReq->num_MeasurementRequest; i++ )
979 {
980 switch( pRRMReq->MeasurementRequest[i].measurement_type )
981 {
982 case SIR_MAC_RRM_BEACON_TYPE:
983 //Process beacon request.
984 if( pCurrentReq )
985 {
986 if ( pReport == NULL ) //Allocate memory to send reports for any subsequent requests.
987 {
988 if( eHAL_STATUS_SUCCESS != palAllocateMemory( pMac->hHdd,
989 (void **) &pReport,
990 sizeof( tSirMacRadioMeasureReport ) * (pRRMReq->num_MeasurementRequest - i) ) )
991 {
992 limLog( pMac, LOGP,
993 FL( "Unable to PAL allocate memory during RRM Req processing\n" ));
994 return eSIR_MEM_ALLOC_FAILED;
995 }
996 palZeroMemory( pMac->hHdd, pReport, sizeof( tSirMacRadioMeasureReport ) * (pRRMReq->num_MeasurementRequest - i) );
997#if defined WLAN_VOWIFI_DEBUG
998 limLog( pMac, LOGE, FL(" Allocated memory for pReport\n") );
999#endif
1000
1001 }
1002 pReport[num_report].refused = 1;
1003 pReport[num_report].type = SIR_MAC_RRM_BEACON_TYPE;
1004 pReport[num_report].token = pRRMReq->MeasurementRequest[i].measurement_token;
1005 num_report++;
1006 continue;
1007 }
1008 else
1009 {
1010 if( eHAL_STATUS_SUCCESS != palAllocateMemory( pMac->hHdd,
1011 (void **) &pCurrentReq,
1012 sizeof( *pCurrentReq ) ) )
1013 {
1014 limLog( pMac, LOGP,
1015 FL( "Unable to PAL allocate memory during RRM Req processing\n" ));
1016 return eSIR_MEM_ALLOC_FAILED;
1017 }
1018#if defined WLAN_VOWIFI_DEBUG
1019 PELOGE(limLog( pMac, LOGE, FL(" Allocated memory for pCurrentReq\n") );)
1020#endif
1021 palZeroMemory( pMac->hHdd, pCurrentReq, sizeof( *pCurrentReq ) );
1022 pCurrentReq->dialog_token = pRRMReq->DialogToken.token;
1023 pCurrentReq->token = pRRMReq->MeasurementRequest[i].measurement_token;
1024 pMac->rrm.rrmPEContext.pCurrentReq = pCurrentReq;
1025 rrmStatus = rrmProcessBeaconReportReq( pMac, pCurrentReq, &pRRMReq->MeasurementRequest[i], pSessionEntry );
1026 if (eRRM_SUCCESS != rrmStatus)
1027 {
1028 rrmProcessBeaconRequestFailure(pMac, pSessionEntry, peer, rrmStatus);
1029 rrmCleanup(pMac);
1030 }
1031 }
1032 break;
1033 default:
1034 //Send a report with incapabale bit set.
1035 if ( pReport == NULL ) //Allocate memory to send reports for any subsequent requests.
1036 {
1037 if( eHAL_STATUS_SUCCESS != palAllocateMemory( pMac->hHdd,
1038 (void **) &pReport,
1039 sizeof( tSirMacRadioMeasureReport ) * (pRRMReq->num_MeasurementRequest - i) ) )
1040 {
1041 limLog( pMac, LOGP,
1042 FL( "Unable to PAL allocate memory during RRM Req processing\n" ));
1043 return eSIR_MEM_ALLOC_FAILED;
1044 }
1045 palZeroMemory( pMac->hHdd, pReport, sizeof( tSirMacRadioMeasureReport ) * (pRRMReq->num_MeasurementRequest - i) );
1046#if defined WLAN_VOWIFI_DEBUG
1047 PELOGE(limLog( pMac, LOGE, FL(" Allocated memory for pReport\n") );)
1048#endif
1049
1050 }
1051 pReport[num_report].incapable = 1;
1052 pReport[num_report].type = pRRMReq->MeasurementRequest[i].measurement_type;
1053 pReport[num_report].token = pRRMReq->MeasurementRequest[i].measurement_token;
1054 num_report++;
1055 break;
1056 }
1057 }
1058
1059end:
1060 if( pReport )
1061 {
1062 limSendRadioMeasureReportActionFrame( pMac, pRRMReq->DialogToken.token, num_report,
1063 pReport, peer, pSessionEntry );
1064
1065 palFreeMemory( pMac->hHdd, pReport );
1066#if defined WLAN_VOWIFI_DEBUG
1067 PELOGE(limLog( pMac, LOGE, FL(" Free memory for pReport\n") );)
1068#endif
1069 }
1070 return status;
1071
1072}
1073
1074// --------------------------------------------------------------------
1075/**
1076 * rrmUpdateStartTSF
1077 **
1078 * FUNCTION: Store start TSF of measurement.
1079 *
1080 * LOGIC:
1081 *
1082 * ASSUMPTIONS:
1083 *
1084 * NOTE:
1085 *
1086 * @param startTSF - TSF value at the start of measurement.
1087 * @return None
1088 */
1089void
1090rrmUpdateStartTSF ( tpAniSirGlobal pMac, tANI_U32 startTSF[2] )
1091{
1092#if 0 //defined WLAN_VOWIFI_DEBUG
1093 limLog( pMac, LOGE, "Update Start TSF = %d %d\n", startTSF[0], startTSF[1] );
1094#endif
1095 pMac->rrm.rrmPEContext.startTSF[0] = startTSF[0];
1096 pMac->rrm.rrmPEContext.startTSF[1] = startTSF[1];
1097}
1098
1099// --------------------------------------------------------------------
1100/**
1101 * rrmGetStartTSF
1102 *
1103 * FUNCTION: Get the Start TSF.
1104 *
1105 * LOGIC:
1106 *
1107 * ASSUMPTIONS:
1108 *
1109 * NOTE:
1110 *
1111 * @param startTSF - store star TSF in this buffer.
1112 * @return txPower
1113 */
1114void
1115rrmGetStartTSF ( tpAniSirGlobal pMac, tANI_U32 *pStartTSF )
1116{
1117#if 0 //defined WLAN_VOWIFI_DEBUG
1118 limLog( pMac, LOGE, "Get the start TSF, TSF = %d %d \n", pMac->rrm.rrmPEContext.startTSF[0], pMac->rrm.rrmPEContext.startTSF[1] );
1119#endif
1120 pStartTSF[0] = pMac->rrm.rrmPEContext.startTSF[0];
1121 pStartTSF[1] = pMac->rrm.rrmPEContext.startTSF[1];
1122
1123}
1124// --------------------------------------------------------------------
1125/**
1126 * rrmGetCapabilities
1127 *
1128 * FUNCTION:
1129 * Returns a pointer to tpRRMCaps with all the caps enabled in RRM
1130 *
1131 * LOGIC:
1132 *
1133 * ASSUMPTIONS:
1134 *
1135 * NOTE:
1136 *
1137 * @param pSessionEntry
1138 * @return pointer to tRRMCaps
1139 */
1140tpRRMCaps rrmGetCapabilities ( tpAniSirGlobal pMac,
1141 tpPESession pSessionEntry )
1142{
1143 return &pMac->rrm.rrmPEContext.rrmEnabledCaps;
1144}
1145
1146// --------------------------------------------------------------------
1147/**
1148 * rrmUpdateConfig
1149 *
1150 * FUNCTION:
1151 * Update the configuration. This is called from limUpdateConfig.
1152 *
1153 * LOGIC:
1154 *
1155 * ASSUMPTIONS:
1156 *
1157 * NOTE:
1158 *
1159 * @param pSessionEntry
1160 * @return pointer to tRRMCaps
1161 */
1162void rrmUpdateConfig ( tpAniSirGlobal pMac,
1163 tpPESession pSessionEntry )
1164{
1165 tANI_U32 val;
1166 tpRRMCaps pRRMCaps = &pMac->rrm.rrmPEContext.rrmEnabledCaps;
1167
1168 if (wlan_cfgGetInt(pMac, WNI_CFG_RRM_ENABLED, &val) != eSIR_SUCCESS)
1169 {
1170 limLog(pMac, LOGP, FL("cfg get rrm enabled failed\n"));
1171 return;
1172 }
1173 pMac->rrm.rrmPEContext.rrmEnable = (val) ? 1 : 0;
1174
1175 if (wlan_cfgGetInt(pMac, WNI_CFG_RRM_OPERATING_CHAN_MAX, &val) != eSIR_SUCCESS)
1176 {
1177 limLog(pMac, LOGP, FL("cfg get rrm operating channel max measurement duration failed\n"));
1178 return;
1179 }
1180 pRRMCaps->operatingChanMax = (tANI_U8)val;
1181
1182 if (wlan_cfgGetInt(pMac, WNI_CFG_RRM_NON_OPERATING_CHAN_MAX, &val) != eSIR_SUCCESS)
1183 {
1184 limLog(pMac, LOGP, FL("cfg get rrm non-operating channel max measurement duration failed\n"));
1185 return;
1186 }
1187 pRRMCaps->nonOperatingChanMax =(tANI_U8) val;
1188
1189#if defined WLAN_VOWIFI_DEBUG
1190 PELOGE(limLog( pMac, LOGE, "RRM enabled = %d OperatingChanMax = %d NonOperatingMax = %d\n", pMac->rrm.rrmPEContext.rrmEnable,
1191 pRRMCaps->operatingChanMax, pRRMCaps->nonOperatingChanMax );)
1192#endif
1193}
1194// --------------------------------------------------------------------
1195/**
1196 * rrmInitialize
1197 *
1198 * FUNCTION:
1199 * Initialize RRM module
1200 *
1201 * LOGIC:
1202 *
1203 * ASSUMPTIONS:
1204 *
1205 * NOTE:
1206 *
1207 * @return None
1208 */
1209
1210tSirRetStatus
1211rrmInitialize(tpAniSirGlobal pMac)
1212{
1213 tpRRMCaps pRRMCaps = &pMac->rrm.rrmPEContext.rrmEnabledCaps;
1214
1215 pMac->rrm.rrmPEContext.pCurrentReq = NULL;
1216 pMac->rrm.rrmPEContext.txMgmtPower = 0;
1217 pMac->rrm.rrmPEContext.DialogToken = 0;
1218
1219 pMac->rrm.rrmPEContext.rrmEnable = 0;
1220
1221 palZeroMemory( pMac->hHdd, pRRMCaps, sizeof(tRRMCaps) );
1222 pRRMCaps->LinkMeasurement = 1;
1223 pRRMCaps->NeighborRpt = 1;
1224 pRRMCaps->BeaconPassive = 1;
1225 pRRMCaps->BeaconActive = 1;
1226 pRRMCaps->BeaconTable = 1;
1227 pRRMCaps->APChanReport = 1;
1228
1229 //pRRMCaps->TCMCapability = 1;
1230 //pRRMCaps->triggeredTCM = 1;
1231 pRRMCaps->operatingChanMax = 3;
1232 pRRMCaps->nonOperatingChanMax = 3;
1233
1234 return eSIR_SUCCESS;
1235}
1236
1237// --------------------------------------------------------------------
1238/**
1239 * rrmCleanup
1240 *
1241 * FUNCTION:
1242 * cleanup RRM module
1243 *
1244 * LOGIC:
1245 *
1246 * ASSUMPTIONS:
1247 *
1248 * NOTE:
1249 *
1250 * @param mode
1251 * @param rate
1252 * @return None
1253 */
1254
1255tSirRetStatus
1256rrmCleanup(tpAniSirGlobal pMac)
1257{
1258 if( pMac->rrm.rrmPEContext.pCurrentReq )
1259 {
1260 if( pMac->rrm.rrmPEContext.pCurrentReq->request.Beacon.reqIes.pElementIds )
1261 {
1262 palFreeMemory( pMac->hHdd, pMac->rrm.rrmPEContext.pCurrentReq->request.Beacon.reqIes.pElementIds );
1263#if defined WLAN_VOWIFI_DEBUG
1264 PELOGE(limLog( pMac, LOGE, FL(" Free memory for pElementIds\n") );)
1265#endif
1266 }
1267
1268 palFreeMemory( pMac->hHdd, pMac->rrm.rrmPEContext.pCurrentReq );
1269#if defined WLAN_VOWIFI_DEBUG
1270 PELOGE(limLog( pMac, LOGE, FL(" Free memory for pCurrentReq\n") );)
1271#endif
1272 }
1273
1274 pMac->rrm.rrmPEContext.pCurrentReq = NULL;
1275 return eSIR_SUCCESS;
1276}
1277
1278// --------------------------------------------------------------------
1279/**
1280 * rrmProcessMessage
1281 *
1282 * FUNCTION: Processes the next received Radio Resource Management message
1283 *
1284 * LOGIC:
1285 *
1286 * ASSUMPTIONS:
1287 *
1288 * NOTE:
1289 *
1290 * @param None
1291 * @return None
1292 */
1293
1294void rrmProcessMessage(tpAniSirGlobal pMac, tpSirMsgQ pMsg)
1295{
1296 switch (pMsg->type)
1297 {
1298 case eWNI_SME_NEIGHBOR_REPORT_REQ_IND:
1299 rrmProcessNeighborReportReq( pMac, pMsg->bodyptr );
1300 break;
1301 case eWNI_SME_BEACON_REPORT_RESP_XMIT_IND:
1302 rrmProcessBeaconReportXmit( pMac, pMsg->bodyptr );
1303 break;
1304 }
1305
1306}
1307
1308#endif