blob: 87ffbf3e2586245e9f09ebce8dd126032cc53acb [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 limProcessLmmMessages.cc contains the code
46 * for processing SME/LMM messages related to ANI feature set.
47 * Author: Chandra Modumudi
48 * Date: 10/20/02
49 * History:-
50 * Date Modified by Modification Information
51 * --------------------------------------------------------------------
52 *
53 */
54
55#include "aniGlobal.h"
56#include "wniApi.h"
57#if (WNI_POLARIS_FW_PRODUCT == AP)
58#include "wniCfgAp.h"
59#else
60#include "wniCfgSta.h"
61#endif
62#include "cfgApi.h"
63#include "sirApi.h"
64#include "schApi.h"
65#include "utilsApi.h"
66#include "limTypes.h"
67#include "limUtils.h"
68#include "limAssocUtils.h"
69#include "limSerDesUtils.h"
70#include "limPropExtsUtils.h"
71#include "limSession.h"
72
73
74#if (WNI_POLARIS_FW_PACKAGE == ADVANCED) && (WNI_POLARIS_FW_PRODUCT == AP)
75/**
76 * limIsSmeMeasurementReqValid()
77 *
78 *FUNCTION:
79 * This function is called by limProcessLmmMessages() upon
80 * receiving SME_MEASUREMENT_REQ.
81 *
82 *LOGIC:
83 * Message validity checks are performed in this function
84 *
85 *ASSUMPTIONS:
86 *
87 *NOTE:
88 *
89 * @param pMeasReq Pointer to Received MEASUREMENT_REQ message
90 * @return true When received SME_MEASUREMENT_REQ is formatted
91 * correctly
92 * false otherwise
93 */
94
95inline static tANI_BOOLEAN
96limIsSmeMeasurementReqValid(tpAniSirGlobal pMac, tpSirSmeMeasurementReq pMeasReq)
97{
98#ifdef ANI_AP_SDK
99 if (!pMeasReq->channelList.numChannels ||
100 ((pMeasReq->measControl.periodicMeasEnabled) &&
101 (!pMeasReq->measIndPeriod)) ||
102 (pMeasReq->measIndPeriod &&
103 ((pMeasReq->measIndPeriod < 1))) ||
104 !pMeasReq->measDuration.shortTermPeriod ||
105 ((pMeasReq->measDuration.shortTermPeriod < 1)) ||
106 !pMeasReq->measDuration.averagingPeriod ||
107 (pMeasReq->measDuration.averagingPeriod <
108 pMeasReq->measDuration.shortTermPeriod) ||
109 !pMeasReq->measDuration.shortChannelScanDuration ||
110 ((pMeasReq->measDuration.shortChannelScanDuration <
111 1)) ||
112 !pMeasReq->measDuration.longChannelScanDuration ||
113 (pMeasReq->measDuration.longChannelScanDuration <
114 pMeasReq->measDuration.shortChannelScanDuration) ||
115 ((pMeasReq->measDuration.longChannelScanDuration <
116 1)))
117#else
118 if (!pMeasReq->channelList.numChannels ||
119 ((pMeasReq->measControl.periodicMeasEnabled) &&
120 (!pMeasReq->measIndPeriod)) ||
121 (pMeasReq->measIndPeriod &&
122 ((pMeasReq->measIndPeriod < SYS_TICK_DUR_MS))) ||
123 !pMeasReq->measDuration.shortTermPeriod ||
124 ((pMeasReq->measDuration.shortTermPeriod < SYS_TICK_DUR_MS)) ||
125 !pMeasReq->measDuration.averagingPeriod ||
126 (pMeasReq->measDuration.averagingPeriod <
127 pMeasReq->measDuration.shortTermPeriod) ||
128 !pMeasReq->measDuration.shortChannelScanDuration ||
129 ((pMeasReq->measDuration.shortChannelScanDuration <
130 SYS_TICK_DUR_MS)) ||
131 !pMeasReq->measDuration.longChannelScanDuration ||
132 (pMeasReq->measDuration.longChannelScanDuration <
133 pMeasReq->measDuration.shortChannelScanDuration) ||
134 ((pMeasReq->measDuration.longChannelScanDuration <
135 SYS_TICK_DUR_MS)))
136
137
138#endif
139 {
140 limLog(pMac, LOGW,
141 FL("Received MEASUREMENT_REQ with invalid data\n"));
142
143 return eANI_BOOLEAN_FALSE;
144 }
145 else
146 return eANI_BOOLEAN_TRUE;
147
148} /*** end limIsSmeMeasurementReqValid() ***/
149
150
151/**
152 * limInitMeasResources()
153 *
154 *FUNCTION:
155 * This function is called by limProcessLmmMessages() upon
156 * receiving SME_MEASUREMENT_REQ. This function initializes
157 * resources required for making measurements like creating
158 * timers related to Measurement Request etc.
159 *
160 *LOGIC:
161 *
162 *ASSUMPTIONS:
163 *
164 *NOTE:
165 *
166 * @param pMac - Pointer to Global MAC structure
167 * @param None
168 * @return None
169 */
170
171inline static tSirRetStatus
172limInitMeasResources(tpAniSirGlobal pMac)
173{
174 tANI_U32 val;
175 tANI_U32 beaconInterval;
176
177
178 // Create Meas related timers only when
179 // periodic measurements are enabled
180 if (pMac->lim.gpLimMeasReq->measControl.periodicMeasEnabled)
181 {
182 val = SYS_MS_TO_TICKS(pMac->lim.gpLimMeasReq->measIndPeriod);
183 if (tx_timer_create(
184 &pMac->lim.gLimMeasParams.measurementIndTimer,
185 "Meas Ind TIMEOUT",
186 limTimerHandler,
187 SIR_LIM_MEASUREMENT_IND_TIMEOUT,
188 val,
189 val,
190 TX_NO_ACTIVATE) != TX_SUCCESS)
191 {
192 /// Could not create MeasInd timer.
193 // Log error
194 limLog(pMac, LOGP, FL("call to create MeasInd timer failed\n"));
195
196 return eSIR_SYS_TX_TIMER_CREATE_FAILED;
197 }
198 pMac->lim.gLimMeasParams.isMeasIndTimerActive = 0;
199 PELOG3(limLog(pMac, LOG3, FL("MeasurementIndication timer initialized, period = %d\n"),
200 pMac->lim.gpLimMeasReq->measIndPeriod);)
201
202#if defined(ANI_OS_TYPE_RTAI_LINUX)
203 tx_timer_set_expiry_list(
204 &pMac->lim.gLimMeasParams.measurementIndTimer,
205 LIM_TIMER_EXPIRY_LIST);
206#endif
207 }
208
209 tANI_U32 learnInterval =
210 pMac->lim.gpLimMeasReq->measDuration.shortTermPeriod /
211 pMac->lim.gpLimMeasReq->channelList.numChannels;
212 if (tx_timer_create(&pMac->lim.gLimMeasParams.learnIntervalTimer,
213 "Learn interval TIMEOUT",
214 limTimerHandler,
215 SIR_LIM_LEARN_INTERVAL_TIMEOUT,
216 SYS_MS_TO_TICKS(learnInterval),
217 0,
218 TX_NO_ACTIVATE) != TX_SUCCESS)
219 {
220 /// Could not create learnInterval timer.
221 // Log error
222 limLog(pMac, LOGP, FL("call to create learnInterval timer failed\n"));
223
224 return eSIR_SYS_TX_TIMER_CREATE_FAILED;
225 }
226
227#if defined(ANI_OS_TYPE_RTAI_LINUX)
228 tx_timer_set_expiry_list(
229 &pMac->lim.gLimMeasParams.learnIntervalTimer,
230 LIM_TIMER_EXPIRY_LIST);
231#endif
232
233 val = SYS_MS_TO_TICKS(pMac->lim.gpLimMeasReq->measDuration.shortChannelScanDuration);
234 if (tx_timer_create(
235 &pMac->lim.gLimMeasParams.learnDurationTimer,
236 "Learn duration TIMEOUT",
237 limTimerHandler,
238 SIR_LIM_LEARN_DURATION_TIMEOUT,
239 val,
240 0,
241 TX_NO_ACTIVATE) != TX_SUCCESS)
242 {
243 /// Could not create LearnDuration timer.
244 // Log error
245 limLog(pMac, LOGP,
246 FL("call to create LearnDuration timer failed\n"));
247
248 return eSIR_SYS_TX_TIMER_CREATE_FAILED;
249 }
250
251#if defined(ANI_OS_TYPE_RTAI_LINUX)
252 tx_timer_set_expiry_list(
253 &pMac->lim.gLimMeasParams.learnDurationTimer,
254 LIM_TIMER_EXPIRY_LIST);
255#endif
256
257 #if 0
258 if (wlan_cfgGetInt(pMac, WNI_CFG_BEACON_INTERVAL, &beaconInterval) != eSIR_SUCCESS)
259 {
260 limLog(pMac, LOGP, FL("Can't read beacon interval\n"));
261 return eSIR_FAILURE;
262 }
263 #endif // TO SUPPORT BT-AMP
264
265 /* Copy the beacon interval from the sessio Id */
266 beaconInterval = psessionEntry->beaconParams.beaconInterval;
267
268 if ((learnInterval > ( 2 * beaconInterval)) &&
269 (pMac->lim.gLimSystemRole == eLIM_AP_ROLE))
270 {
271 //learinterval should be > 2 * beaconinterval
272 val = SYS_MS_TO_TICKS(learnInterval - (2 * beaconInterval));
273 // Create Quiet BSS Timer
274 if( TX_SUCCESS !=
275 tx_timer_create( &pMac->lim.limTimers.gLimQuietBssTimer,
276 "QUIET BSS TIMER",
277 limQuietBssTimerHandler,
278 SIR_LIM_QUIET_BSS_TIMEOUT,
279 val, // initial_ticks
280 0, // reschedule_ticks
281 TX_NO_ACTIVATE ))
282 {
283 limLog( pMac, LOGP,
284 FL( "Failed to create gLimQuietBssTimer!\n" ));
285 return eSIR_SYS_TX_TIMER_CREATE_FAILED;
286 }
287
288#if defined(ANI_OS_TYPE_RTAI_LINUX)
289 tx_timer_set_expiry_list(
290 &pMac->lim.limTimers.gLimQuietBssTimer,
291 LIM_TIMER_EXPIRY_LIST );
292#endif
293 pMac->lim.gLimSpecMgmt.fQuietEnabled = eANI_BOOLEAN_TRUE;
294 }
295
296 pMac->lim.gLimMeasParams.shortDurationCount = 0;
297 pMac->lim.gLimMeasParams.nextLearnChannelId = 0;
298
299 pMac->lim.gLimMeasParams.rssiAlpha =
300 (100 * pMac->lim.gpLimMeasReq->measDuration.shortTermPeriod) /
301 pMac->lim.gpLimMeasReq->measDuration.averagingPeriod;
302
303 if (!pMac->lim.gLimMeasParams.rssiAlpha)
304 pMac->lim.gLimMeasParams.rssiAlpha = 1;
305
306 pMac->lim.gLimMeasParams.chanUtilAlpha =
307 (100 * learnInterval) / pMac->lim.gpLimMeasReq->measIndPeriod;
308
309 if (!pMac->lim.gLimMeasParams.chanUtilAlpha)
310 pMac->lim.gLimMeasParams.chanUtilAlpha = 1;
311
312 return eSIR_SUCCESS;
313} /*** end limInitMeasResources() ***/
314
315
316/**-----------------------------------------------
317\fn __limFreeMeasAndSendRsp
318\brief Free the meas related resources and send
319 response to SME.
320\param pMac
321\param resultCode
322\return None
323 ------------------------------------------------*/
324static void
325__limFreeMeasAndSendRsp(tpAniSirGlobal pMac, tSirResultCodes resultCode)
326{
327 if (pMac->lim.gpLimMeasReq != NULL)
328 {
329 palFreeMemory( pMac->hHdd, pMac->lim.gpLimMeasReq);
330 pMac->lim.gpLimMeasReq = NULL;
331 }
332
333 if (pMac->lim.gpLimMeasData != NULL)
334 {
335 palFreeMemory( pMac->hHdd, pMac->lim.gpLimMeasData);
336 pMac->lim.gpLimMeasData = NULL;
337 }
338
339 /// Send failure response to WSM
340 limSendSmeRsp(pMac, eWNI_SME_MEASUREMENT_RSP, resultCode);
341}
342
343/**
344 * limProcessSmeMeasurementReq()
345 *
346 *FUNCTION:
347 * This function is called by limProcessLmmMessages() upon
348 * receiving SME_MEASUREMENT_REQ from WSM.
349 *
350 *LOGIC:
351 *
352 *ASSUMPTIONS:
353 *
354 *NOTE:
355 *
356 * @param pMac Pointer to Global MAC structure
357 * @param *pMsgBuf A pointer to the SME message buffer
358 *
359 * @return None
360 */
361
362static void
363limProcessSmeMeasurementReq(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf)
364{
365 PELOG1(limLog(pMac, LOG1, FL("SME State = %d\n"), pMac->lim.gLimSmeState);)
366 switch (pMac->lim.gLimSmeState)
367 {
368 case eLIM_SME_OFFLINE_STATE:
369 case eLIM_SME_IDLE_STATE:
370 case eLIM_SME_JOIN_FAILURE_STATE:
371 case eLIM_SME_NORMAL_STATE:
372 case eLIM_SME_LINK_EST_STATE:
373 case eLIM_SME_CHANNEL_SCAN_STATE:
374 case eLIM_SME_NORMAL_CHANNEL_SCAN_STATE:
375 break;
376
377 default:
378 limLog(pMac, LOGE,
379 FL("Received unexpected MeasReq message in state %X\n"),
380 pMac->lim.gLimSmeState);
381
382 /// Send failure response to host
383 limSendSmeRsp(
384 pMac,
385 eWNI_SME_MEASUREMENT_RSP,
386 eSIR_SME_UNEXPECTED_REQ_RESULT_CODE);
387 return;
388 } // end switch (pMac->lim.gLimSmeState)
389
390 if (pMac->lim.gpLimMeasReq)
391 {
392 // There was a previous measurement req issued.
393 // Cleanup resources allocated for that request.
394 limDeleteMeasTimers(pMac);
395 limCleanupMeasData(pMac);
396 }
397 else
398 {
399 // There was no previous measurement req issued.
400 // Allocate memory required to hold measurements.
401 if (eHAL_STATUS_SUCCESS !=
402 palAllocateMemory(pMac->hHdd,
403 (void **)&pMac->lim.gpLimMeasData,
404 sizeof(tLimMeasData)))
405 {
406 // Log error
407 limLog(pMac, LOGE,
408 FL("memory allocate failed for MeasData\n"));
409
410 /// Send failure response to host
411 limSendSmeRsp(pMac, eWNI_SME_MEASUREMENT_RSP,
412 eSIR_SME_RESOURCES_UNAVAILABLE);
413 return;
414 }
415
416 palZeroMemory(pMac->hHdd, (void *)pMac->lim.gpLimMeasData,
417 sizeof(tLimMeasData));
418 pMac->lim.gpLimMeasData->duration = 120;
419 }
420
421 if (eHAL_STATUS_SUCCESS !=
422 palAllocateMemory(pMac->hHdd,
423 (void **)&pMac->lim.gpLimMeasReq,
424 (sizeof(tSirSmeMeasurementReq) +
425 SIR_MAX_NUM_CHANNELS)))
426 {
427 // Log error
428 PELOGE(limLog(pMac, LOGE, FL("memory allocate failed for MeasReq\n"));)
429
430 __limFreeMeasAndSendRsp(pMac, eSIR_SME_RESOURCES_UNAVAILABLE);
431 return;
432 }
433
434 if ((limMeasurementReqSerDes(
435 pMac,
436 pMac->lim.gpLimMeasReq,
437 (tANI_U8 *) pMsgBuf) == eSIR_FAILURE) ||
438 !limIsSmeMeasurementReqValid(pMac,pMac->lim.gpLimMeasReq))
439 {
440 limLog(pMac, LOGE,
441 FL("Rx'ed MeasReq message with invalid parameters\n"));
442
443 __limFreeMeasAndSendRsp(pMac, eSIR_SME_INVALID_PARAMETERS);
444 return;
445 }
446#ifdef ANI_AP_SDK
447 /* convert from mS to TU and TICKS */
448 limConvertScanDuration(pMac);
449#endif /* ANI_AP_SDK */
450
451 // Initialize Measurement related resources
452 if (limInitMeasResources(pMac) != eSIR_SUCCESS)
453 {
454 __limFreeMeasAndSendRsp(pMac, eSIR_SME_RESOURCES_UNAVAILABLE);
455 return;
456 }
457
458 PELOG3(limLog(pMac, LOG3,
459 FL("NumChannels=%d, shortDuration=%d, shortInterval=%d, longInterval=%d\n"),
460 pMac->lim.gpLimMeasReq->channelList.numChannels,
461 pMac->lim.gpLimMeasReq->measDuration.shortTermPeriod,
462 pMac->lim.gpLimMeasReq->measDuration.shortChannelScanDuration,
463 pMac->lim.gpLimMeasReq->measDuration.longChannelScanDuration);)
464
465 limRadarInit(pMac);
466
467 /**
468 * Start Learn interval timer so that
469 * measurements are made from that
470 * timeout onwards.
471 */
472 limReEnableLearnMode(pMac);
473
474 /// All is well with MeasReq. Send response to WSM
475 limSendSmeRsp(pMac, eWNI_SME_MEASUREMENT_RSP,
476 eSIR_SME_SUCCESS);
477 PELOG2(limLog(pMac, LOG2, FL("Sending succes response to SME\n"));)
478
479 if (pMac->lim.gpLimMeasReq->channelList.numChannels == 1)
480 limLog(pMac, LOGE, FL("Starting Channel Availability Check on Channel %d... Wait\n"),
481 *pMac->lim.gpLimMeasReq->channelList.channelNumber);
482} /*** end limProcessSmeMeasurementReq() ***/
483
484
485/**
486 * limProcessSmeSetWdsInfoReq()
487 *
488 *FUNCTION:
489 * This function is called by limProcessLmmMessages() upon
490 * receiving SME_SET_WDS_INFO_REQ from WSM.
491 *
492 *LOGIC:
493 *
494 *ASSUMPTIONS:
495 *
496 *NOTE:
497 *
498 * @param pMac Pointer to Global MAC structure
499 * @param *pMsgBuf A pointer to the SME message buffer
500 *
501 * @return None
502 */
503
504static void
505limProcessSmeSetWdsInfoReq(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf)
506{
507 tANI_U16 i;
508 tSirSmeSetWdsInfoReq wdsInfoReq;
509
510 pMac->lim.gLimNumWdsInfoSet++;
511
512 switch (pMac->lim.gLimSmeState)
513 {
514 case eLIM_SME_NORMAL_STATE:
515 break;
516
517 default:
518 limLog(pMac, LOGE,
519 FL("Rx'ed unexp SetWdsInfoReq message in state %X\n"),
520 pMac->lim.gLimSmeState);
521
522 /// Send failure response to host
523 limSendSmeRsp(
524 pMac,
525 eWNI_SME_SET_WDS_INFO_RSP,
526 eSIR_SME_UNEXPECTED_REQ_RESULT_CODE);
527 return;
528 } // end switch (pMac->lim.gLimSmeState)
529
530 if ((limWdsReqSerDes( pMac,
531 &wdsInfoReq,
532 (tANI_U8 *) pMsgBuf) == eSIR_FAILURE))
533 {
534 limLog(pMac, LOGW,
535 FL("Rx'ed SetWdsInfoReq message with invalid parameters\n"));
536
537 /// Send failure response to WSM
538 limSendSmeRsp(pMac, eWNI_SME_SET_WDS_INFO_RSP,
539 eSIR_SME_INVALID_PARAMETERS);
540
541 return;
542 }
543
544 // check whether the WDS info is the same as current
545 if ((wdsInfoReq.wdsInfo.wdsLength ==
546 psessionEntry->pLimStartBssReq->wdsInfo.wdsLength) &&
547 (palEqualMemory( pMac->hHdd,wdsInfoReq.wdsInfo.wdsBytes,
548 psessionEntry->pLimStartBssReq->wdsInfo.wdsBytes,
549 psessionEntry->pLimStartBssReq->wdsInfo.wdsLength) ) )
550 {
551 /// Send success response to WSM
552 limSendSmeRsp(pMac,
553 eWNI_SME_SET_WDS_INFO_RSP,
554 eSIR_SME_SUCCESS);
555
556 return;
557 }
558
559 // copy WDS info
560 psessionEntry->pLimStartBssReq->wdsInfo.wdsLength =
561 wdsInfoReq.wdsInfo.wdsLength;
562 for (i=0; i<wdsInfoReq.wdsInfo.wdsLength; i++)
563 psessionEntry->pLimStartBssReq->wdsInfo.wdsBytes[i] =
564 wdsInfoReq.wdsInfo.wdsBytes[i];
565
566 schSetFixedBeaconFields(pMac,psessionEntry);
567
568 /// Send success response to WSM
569 limSendSmeRsp(pMac, eWNI_SME_SET_WDS_INFO_RSP,
570 eSIR_SME_SUCCESS);
571
572} /*** end limProcessSmeMeasurementReq() ***/
573
574
575/**
576 * limProcessLearnDurationTimeout()
577 *
578 *FUNCTION:
579 * This function is called by limProcessLmmMessages() upon
580 * receiving LEARN_DURATION_TIMEOUT.
581 *
582 *LOGIC:
583 *
584 *ASSUMPTIONS:
585 *
586 *NOTE:
587 *
588 * @param pMac Pointer to Global MAC structure
589 * @param *pMsgBuf A pointer to the SME message buffer
590 *
591 * @return None
592 */
593
594static void
595limProcessLearnDurationTimeout(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf)
596{
597 if ( pMac->lim.gLimHalScanState == eLIM_HAL_IDLE_SCAN_STATE)
598 {
599 limSendHalInitScanReq(pMac, eLIM_HAL_INIT_LEARN_WAIT_STATE, eSIR_DONT_CHECK_LINK_TRAFFIC_BEFORE_SCAN );
600 return;
601 }
602
603 // Current learn duration expired.
604 if (pMac->lim.gLimMeasParams.nextLearnChannelId ==
605 pMac->lim.gpLimMeasReq->channelList.numChannels - 1)
606 {
607 //Set the resume channel to Any valid channel (invalid).
608 //This will instruct HAL to set it to any previous valid channel.
609 peSetResumeChannel(pMac, 0, 0);
610 // Send WDA_END_SCAN_REQ to HAL first
611 limSendHalFinishScanReq(pMac, eLIM_HAL_FINISH_LEARN_WAIT_STATE);
612 }
613 else
614 {
615 pMac->lim.gLimMeasParams.nextLearnChannelId++;
616
617 if (pMac->lim.gLimSystemRole == eLIM_UNKNOWN_ROLE)
618 {
619 // LIM did not take AP/BP role yet.
620 // So continue Learn process on remaining channels
621 // Send WDA_END_SCAN_REQ to HAL first
622 limSendHalEndScanReq(pMac, (tANI_U8)pMac->lim.gLimMeasParams.nextLearnChannelId,
623 eLIM_HAL_END_LEARN_WAIT_STATE);
624 }
625 else
626 {
627 //Set the resume channel to Any valid channel (invalid).
628 //This will instruct HAL to set it to any previous valid channel.
629 peSetResumeChannel(pMac, 0, 0);
630 // Send WDA_FINISH_SCAN_REQ to HAL first
631 limSendHalFinishScanReq(pMac, eLIM_HAL_FINISH_LEARN_WAIT_STATE);
632 }
633 }
634} /*** end limProcessLearnDurationTimeout() ***/
635
636/**
637 * limProcessLearnIntervalTimeout()
638 *
639 *FUNCTION:
640 * This function is called whenever
641 * SIR_LIM_LEARN_INTERVAL_TIMEOUT message is receive.
642 *
643 *LOGIC:
644 *
645 *ASSUMPTIONS:
646 *
647 *NOTE:
648 *
649 * @param pMac Pointer to Global MAC structure
650 *
651 * @return None
652 */
653
654void
655limProcessLearnIntervalTimeout(tpAniSirGlobal pMac)
656{
657
658#ifdef GEN6_TODO
659 //fetch the sessionEntry based on the sessionId
660 //priority - MEDIUM
661 tpPESession sessionEntry;
662
663 if((sessionEntry = peFindSessionBySessionId(pMac, pMac->lim.gLimMeasParams.learnIntervalTimer.sessionId))== NULL)
664 {
665 limLog(pMac, LOGP,FL("Session Does not exist for given sessionID\n"));
666 return;
667 }
668#endif
669
670 PELOG2(limLog(pMac, LOG2, FL("SME state = %d\n"), pMac->lim.gLimSmeState);)
671 if (!pMac->sys.gSysEnableLearnMode)
672 {
673 PELOG3(limLog(pMac, LOG3,
674 FL("Ignoring LEARN_INTERVAL_TIMEOUT because gSysEnableLearnMode is disabled...\n"));)
675 limReEnableLearnMode(pMac);
676 return;
677 }
678
679 if (pMac->lim.gLimSystemInScanLearnMode)
680 {
681 limLog(pMac, LOGE,
682 FL("Sending START_SCAN from LIM while one req is pending\n"));
683 return;
684 }
685
686 pMac->lim.gLimPrevSmeState = pMac->lim.gLimSmeState;
687 if ((pMac->lim.gLimSmeState == eLIM_SME_OFFLINE_STATE) ||
688 (pMac->lim.gLimSmeState == eLIM_SME_IDLE_STATE) ||
689 (pMac->lim.gLimSmeState == eLIM_SME_JOIN_FAILURE_STATE))
690 pMac->lim.gLimSmeState = eLIM_SME_CHANNEL_SCAN_STATE;
691 else if (pMac->lim.gLimSmeState == eLIM_SME_NORMAL_STATE)
692 pMac->lim.gLimSmeState = eLIM_SME_NORMAL_CHANNEL_SCAN_STATE;
693 else if (pMac->lim.gLimSmeState == eLIM_SME_LINK_EST_STATE)
694 pMac->lim.gLimSmeState = eLIM_SME_LINK_EST_WT_SCAN_STATE;
695 else
696 return;
Jeff Johnsone7245742012-09-05 17:12:55 -0700697 MTRACE(macTrace(pMac, TRACE_CODE_SME_STATE, NO_SESSION, pMac->lim.gLimSmeState));
Jeff Johnson295189b2012-06-20 16:38:30 -0700698
699 /* The commented piece of code here is to handle the Measurement Request from WSM as Scan
700 * request in the LIM in Linux Station. Currently, the station uses Measurement request to
701 * get the scan list. If measurement request itself is used for station also while scanning, this
702 * code can be removed. If we need to handle the measurement request as scan request, we need to
703 * implement the below commented code in a more cleaner way(handling the SCAN_CNF, memory freeing, etc)
704 */
705// if (pMac->lim.gLimSystemRole != eLIM_STA_ROLE)
706 {
707 pMac->lim.gLimPrevMlmState = pMac->lim.gLimMlmState;
708 pMac->lim.gLimMlmState = eLIM_MLM_LEARN_STATE;
Jeff Johnsone7245742012-09-05 17:12:55 -0700709 MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, NO_SESSION, pMac->lim.gLimMlmState));
Jeff Johnson295189b2012-06-20 16:38:30 -0700710 pMac->lim.gLimSystemInScanLearnMode = eANI_BOOLEAN_TRUE;
711 }
712#if 0
713 /**
714 * start the timer to enter into Learn mode
715 */
716 if (pMac->lim.gLimSystemRole == eLIM_STA_ROLE)
717 {
718 tLimMlmScanReq *pMlmScanReq;
719 tANI_U32 len;
720
721 if( eHAL_STATUS_SUCCESS != palAllocateMemory( pMac->hHdd, (void **)&pMlmScanReq,
722 (sizeof(tLimMlmScanReq) + WNI_CFG_VALID_CHANNEL_LIST_LEN)))
723 {
724 limLog(pMac, LOGP,
725 FL("call to palAllocateMemory failed for mlmScanReq\n"));
726 return;
727 }
728 palZeroMemory( pMac->hHdd, (tANI_U8 *) pMlmScanReq,
729 (tANI_U32)(sizeof(tLimMlmScanReq) + WNI_CFG_VALID_CHANNEL_LIST_LEN ));
730
731 len = WNI_CFG_VALID_CHANNEL_LIST_LEN;
732 if (wlan_cfgGetStr(pMac, WNI_CFG_VALID_CHANNEL_LIST,
733 pMlmScanReq->channelList.channelNumber,
734 &len) != eSIR_SUCCESS)
735 {
736 limLog(pMac, LOGP,
737 FL("could not retrieve Valid channel list\n"));
738 }
739 pMlmScanReq->channelList.numChannels = (tANI_U8) len;
740
741 palFillMemory(pMac->hHdd, &pMlmScanReq->bssId, sizeof(tSirMacAddr), 0xff);
742 pMlmScanReq->bssType = eSIR_AUTO_MODE;
743 pMlmScanReq->scanType = eSIR_ACTIVE_SCAN;
744 pMlmScanReq->backgroundScanMode = 0;
745 pMlmScanReq->maxChannelTime = 40;
746 pMlmScanReq->minChannelTime = 20;
747 limPostMlmMessage(pMac, LIM_MLM_SCAN_REQ, (tANI_U32 *) pMlmScanReq);
748 }
749 else
750#endif
751 limSetLearnMode(pMac);
752}
753
754
755/**
756 * limProcessLmmMessages()
757 *
758 *FUNCTION:
759 * This function is called by limProcessMessageQueue(). This
760 * function processes SME messages from WSM and MLM cnf/ind
761 * messages from MLM module.
762 *
763 *LOGIC:
764 * Depending on the message type, corresponding function will be
765 * called.
766 *
767 *ASSUMPTIONS:
768 *
769 *NOTE:
770 *
771 * @param pMac Pointer to Global MAC structure
772 * @param msgType Indicates the SME message type
773 * @param *pMsgBuf A pointer to the SME message buffer
774 *
775 * @return None
776 */
777
778void
779limProcessLmmMessages(tpAniSirGlobal pMac, tANI_U32 msgType, tANI_U32 *pMsgBuf)
780{
781 switch (msgType)
782 {
783 case eWNI_SME_MEASUREMENT_REQ:
784 PELOG1(limLog(pMac, LOG1, FL("Received MEASUREMENT_REQ message\n"));)
785 limProcessSmeMeasurementReq(pMac, pMsgBuf);
786
787 break;
788
789 case eWNI_SME_SET_WDS_INFO_REQ:
790
791 limProcessSmeSetWdsInfoReq(pMac, pMsgBuf);
792
793 break;
794
795 case SIR_LIM_MEASUREMENT_IND_TIMEOUT:
796 // Time to send Measurement Indication to WSM
797 limSendSmeMeasurementInd(pMac);
798
799 break;
800
801 case SIR_LIM_LEARN_INTERVAL_TIMEOUT:
802 limProcessLearnIntervalTimeout(pMac);
803 break;
804
805 case SIR_LIM_LEARN_DURATION_TIMEOUT:
806 limProcessLearnDurationTimeout(pMac, pMsgBuf);
807
808 break;
809
810 default:
811
812 break;
813 } // switch (msgType)
814
815 return;
816} /*** end limProcessLmmMessages() ***/
817
818#endif