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