5 /*! \file "roaming_fsm.c"
6 \brief This file defines the FSM for Roaming MODULE.
8 This file defines the FSM for Roaming MODULE.
14 ** $Log: roaming_fsm.c $
17 * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG
18 * Adjust code for DBG and CONFIG_XLOG.
21 * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG
22 * modify the xlog related code.
25 * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG
26 * adding the code for XLOG.
28 * 08 31 2011 tsaiyuan.hsu
29 * [WCXRP00000931] [MT5931 Wi-Fi][DRV/FW] add swcr to disable roaming from driver
30 * remove obsolete code.
32 * 08 15 2011 tsaiyuan.hsu
33 * [WCXRP00000931] [MT5931 Wi-Fi][DRV/FW] add swcr to disable roaming from driver
34 * add swcr in driver reg, 0x9fxx0000, to disable roaming .
36 * 03 16 2011 tsaiyuan.hsu
37 * [WCXRP00000517] [MT6620 Wi-Fi][Driver][FW] Fine Tune Performance of Roaming
38 * remove obsolete definition and unused variables.
40 * 02 26 2011 tsaiyuan.hsu
41 * [WCXRP00000391] [MT6620 Wi-Fi][FW] Add Roaming Support
42 * not send disassoc or deauth to leaving AP so as to improve performace of roaming.
44 * 01 27 2011 tsaiyuan.hsu
45 * [WCXRP00000392] [MT6620 Wi-Fi][Driver] Add Roaming Support
47 * 1. not support 11r, only use strength of signal to determine roaming.
48 * 2. not enable CFG_SUPPORT_ROAMING until completion of full test.
49 * 3. in 6620, adopt work-around to avoid sign extension problem of cck of hw
50 * 4. assume that change of link quality in smooth way.
52 * 01 27 2011 tsaiyuan.hsu
53 * [WCXRP00000392] [MT6620 Wi-Fi][Driver] Add Roaming Support
55 * 1. not support 11r, only use strength of signal to determine roaming.
56 * 2. not enable CFG_SUPPORT_ROAMING until completion of full test.
57 * 3. in 6620, adopt work-around to avoid sign extension problem of cck of hw
58 * 4. assume that change of link quality in smooth way.
62 /*******************************************************************************
63 * C O M P I L E R F L A G S
64 ********************************************************************************
67 /*******************************************************************************
68 * E X T E R N A L R E F E R E N C E S
69 ********************************************************************************
73 #if CFG_SUPPORT_ROAMING
74 /*******************************************************************************
76 ********************************************************************************
79 /*******************************************************************************
81 ********************************************************************************
84 /*******************************************************************************
86 ********************************************************************************
89 /*******************************************************************************
90 * P R I V A T E D A T A
91 ********************************************************************************
95 /*lint -save -e64 Type mismatch */
96 static PUINT_8 apucDebugRoamingState[ROAMING_STATE_NUM] = {
97 (PUINT_8)DISP_STRING("ROAMING_STATE_IDLE"),
98 (PUINT_8)DISP_STRING("ROAMING_STATE_DECISION"),
99 (PUINT_8)DISP_STRING("ROAMING_STATE_DISCOVERY"),
100 (PUINT_8)DISP_STRING("ROAMING_STATE_ROAM")
105 /*******************************************************************************
107 ********************************************************************************
110 #define ROAMING_ENABLE_CHECK(_roam) \
112 if (!(_roam->fgIsEnableRoaming)) {return;} \
115 /*******************************************************************************
116 * F U N C T I O N D E C L A R A T I O N S
117 ********************************************************************************
120 /*******************************************************************************
122 ********************************************************************************
125 /*----------------------------------------------------------------------------*/
127 * @brief Initialize the value in ROAMING_FSM_INFO_T for ROAMING FSM operation
129 * @param [IN P_ADAPTER_T] prAdapter
133 /*----------------------------------------------------------------------------*/
136 IN P_ADAPTER_T prAdapter
139 P_ROAMING_INFO_T prRoamingFsmInfo;
140 P_CONNECTION_SETTINGS_T prConnSettings;
142 DBGLOG(ROAMING, LOUD, ("->roamingFsmInit(): Current Time = %ld\n", kalGetTimeTick()));
144 prRoamingFsmInfo = (P_ROAMING_INFO_T)&(prAdapter->rWifiVar.rRoamingInfo);
145 prConnSettings = &(prAdapter->rWifiVar.rConnSettings);
148 prRoamingFsmInfo->fgIsEnableRoaming = prConnSettings->fgIsEnableRoaming;
149 prRoamingFsmInfo->eCurrentState = ROAMING_STATE_IDLE;
150 prRoamingFsmInfo->rRoamingDiscoveryUpdateTime = 0;
153 } /* end of roamingFsmInit() */
155 /*----------------------------------------------------------------------------*/
157 * @brief Uninitialize the value in AIS_FSM_INFO_T for AIS FSM operation
159 * @param [IN P_ADAPTER_T] prAdapter
163 /*----------------------------------------------------------------------------*/
166 IN P_ADAPTER_T prAdapter
169 P_ROAMING_INFO_T prRoamingFsmInfo;
171 DBGLOG(ROAMING, LOUD, ("->roamingFsmUninit(): Current Time = %ld\n", kalGetTimeTick()));
173 prRoamingFsmInfo = (P_ROAMING_INFO_T)&(prAdapter->rWifiVar.rRoamingInfo);
175 prRoamingFsmInfo->eCurrentState = ROAMING_STATE_IDLE;
178 } /* end of roamingFsmUninit() */
180 /*----------------------------------------------------------------------------*/
182 * @brief Send commands to firmware
184 * @param [IN P_ADAPTER_T] prAdapter
185 * [IN P_ROAMING_PARAM_T] prParam
189 /*----------------------------------------------------------------------------*/
192 IN P_ADAPTER_T prAdapter,
193 IN P_ROAMING_PARAM_T prParam
196 P_ROAMING_INFO_T prRoamingFsmInfo;
199 DBGLOG(ROAMING, LOUD, ("->roamingFsmSendCmd(): Current Time = %ld\n", kalGetTimeTick()));
201 prRoamingFsmInfo = (P_ROAMING_INFO_T)&(prAdapter->rWifiVar.rRoamingInfo);
203 rStatus = wlanSendSetQueryCmd (
204 prAdapter, /* prAdapter */
205 CMD_ID_ROAMING_TRANSIT, /* ucCID */
206 TRUE, /* fgSetQuery */
207 FALSE, /* fgNeedResp */
209 NULL, /* pfCmdDoneHandler */
210 NULL, /* pfCmdTimeoutHandler */
211 sizeof(ROAMING_PARAM_T), /* u4SetQueryInfoLen */
212 (PUINT_8) prParam, /* pucInfoBuffer */
213 NULL, /* pvSetQueryBuffer */
214 0 /* u4SetQueryBufferLen */
217 ASSERT(rStatus == WLAN_STATUS_PENDING);
220 } /* end of roamingFsmSendCmd() */
222 /*----------------------------------------------------------------------------*/
224 * @brief Update the recent time when ScanDone occurred
226 * @param [IN P_ADAPTER_T] prAdapter
230 /*----------------------------------------------------------------------------*/
232 roamingFsmScanResultsUpdate (
233 IN P_ADAPTER_T prAdapter
236 P_ROAMING_INFO_T prRoamingFsmInfo;
238 prRoamingFsmInfo = (P_ROAMING_INFO_T)&(prAdapter->rWifiVar.rRoamingInfo);
240 /* Check Roaming Conditions */
241 ROAMING_ENABLE_CHECK(prRoamingFsmInfo);
243 DBGLOG(ROAMING, LOUD, ("->roamingFsmScanResultsUpdate(): Current Time = %ld\n", kalGetTimeTick()));
245 GET_CURRENT_SYSTIME(&prRoamingFsmInfo->rRoamingDiscoveryUpdateTime);
248 } /* end of roamingFsmScanResultsUpdate() */
250 /*----------------------------------------------------------------------------*/
252 * @brief The Core FSM engine of ROAMING for AIS Infra.
254 * @param [IN P_ADAPTER_T] prAdapter
255 * [IN ENUM_ROAMING_STATE_T] eNextState Enum value of next AIS STATE
259 /*----------------------------------------------------------------------------*/
262 IN P_ADAPTER_T prAdapter,
263 IN ENUM_ROAMING_STATE_T eNextState
266 P_ROAMING_INFO_T prRoamingFsmInfo;
267 ENUM_ROAMING_STATE_T ePreviousState;
268 BOOLEAN fgIsTransition = (BOOLEAN)FALSE;
270 prRoamingFsmInfo = (P_ROAMING_INFO_T)&(prAdapter->rWifiVar.rRoamingInfo);
274 /* Do entering Next State */
276 DBGLOG(ROAMING, STATE, ("TRANSITION: [%s] -> [%s]\n",
277 apucDebugRoamingState[prRoamingFsmInfo->eCurrentState],
278 apucDebugRoamingState[eNextState]));
280 DBGLOG(ROAMING, STATE, ("[%d] TRANSITION: [%d] -> [%d]\n",
282 prRoamingFsmInfo->eCurrentState,
285 /* NOTE(Kevin): This is the only place to change the eCurrentState(except initial) */
286 ePreviousState = prRoamingFsmInfo->eCurrentState;
287 prRoamingFsmInfo->eCurrentState = eNextState;
289 fgIsTransition = (BOOLEAN)FALSE;
291 /* Do tasks of the State that we just entered */
292 switch (prRoamingFsmInfo->eCurrentState) {
293 /* NOTE(Kevin): we don't have to rearrange the sequence of following
294 * switch case. Instead I would like to use a common lookup table of array
295 * of function pointer to speed up state search.
297 case ROAMING_STATE_IDLE:
298 case ROAMING_STATE_DECISION:
301 case ROAMING_STATE_DISCOVERY:
303 OS_SYSTIME rCurrentTime;
305 GET_CURRENT_SYSTIME(&rCurrentTime);
306 if (CHECK_FOR_TIMEOUT(rCurrentTime, prRoamingFsmInfo->rRoamingDiscoveryUpdateTime,
307 SEC_TO_SYSTIME(ROAMING_DISCOVERY_TIMEOUT_SEC))) {
308 DBGLOG(ROAMING, LOUD, ("roamingFsmSteps: DiscoveryUpdateTime Timeout"));
309 aisFsmRunEventRoamingDiscovery(prAdapter, TRUE);
312 DBGLOG(ROAMING, LOUD, ("roamingFsmSteps: DiscoveryUpdateTime Updated"));
313 aisFsmRunEventRoamingDiscovery(prAdapter, FALSE);
318 case ROAMING_STATE_ROAM:
322 ASSERT(0); /* Make sure we have handle all STATEs */
325 while (fgIsTransition);
329 } /* end of roamingFsmSteps() */
331 /*----------------------------------------------------------------------------*/
333 * @brief Transit to Decision state after join completion
335 * @param [IN P_ADAPTER_T] prAdapter
339 /*----------------------------------------------------------------------------*/
341 roamingFsmRunEventStart (
342 IN P_ADAPTER_T prAdapter
345 P_ROAMING_INFO_T prRoamingFsmInfo;
346 ENUM_ROAMING_STATE_T eNextState;
347 P_BSS_INFO_T prAisBssInfo;
348 ROAMING_PARAM_T rParam;
350 prRoamingFsmInfo = (P_ROAMING_INFO_T)&(prAdapter->rWifiVar.rRoamingInfo);
352 /* Check Roaming Conditions */
353 ROAMING_ENABLE_CHECK(prRoamingFsmInfo);
355 prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]);
356 if (prAisBssInfo->eCurrentOPMode != OP_MODE_INFRASTRUCTURE) {
360 DBGLOG(ROAMING, EVENT, ("EVENT-ROAMING START: Current Time = %ld\n", kalGetTimeTick()));
362 /* IDLE, ROAM -> DECISION */
363 /* Errors as DECISION, DISCOVERY -> DECISION */
364 if (!(prRoamingFsmInfo->eCurrentState == ROAMING_STATE_IDLE
365 || prRoamingFsmInfo->eCurrentState == ROAMING_STATE_ROAM)) {
369 eNextState = ROAMING_STATE_DECISION;
370 if (eNextState != prRoamingFsmInfo->eCurrentState) {
371 rParam.u2Event = ROAMING_EVENT_START;
372 roamingFsmSendCmd(prAdapter, (P_ROAMING_PARAM_T) &rParam);
374 /* Step to next state */
375 roamingFsmSteps(prAdapter, eNextState);
379 } /* end of roamingFsmRunEventStart() */
381 /*----------------------------------------------------------------------------*/
383 * @brief Transit to Discovery state when deciding to find a candidate
385 * @param [IN P_ADAPTER_T] prAdapter
389 /*----------------------------------------------------------------------------*/
391 roamingFsmRunEventDiscovery (
392 IN P_ADAPTER_T prAdapter,
396 P_ROAMING_INFO_T prRoamingFsmInfo;
397 ENUM_ROAMING_STATE_T eNextState;
399 prRoamingFsmInfo = (P_ROAMING_INFO_T)&(prAdapter->rWifiVar.rRoamingInfo);
401 /* Check Roaming Conditions */
402 ROAMING_ENABLE_CHECK(prRoamingFsmInfo);
404 DBGLOG(ROAMING, EVENT, ("EVENT-ROAMING DISCOVERY: Current Time = %ld\n", kalGetTimeTick()));
406 /* DECISION -> DISCOVERY */
407 /* Errors as IDLE, DISCOVERY, ROAM -> DISCOVERY */
408 if (prRoamingFsmInfo->eCurrentState != ROAMING_STATE_DECISION) {
412 eNextState = ROAMING_STATE_DISCOVERY;
413 /* DECISION -> DISCOVERY */
414 if (eNextState != prRoamingFsmInfo->eCurrentState) {
415 P_BSS_INFO_T prAisBssInfo;
416 P_BSS_DESC_T prBssDesc;
418 // sync. rcpi with firmware
419 prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]);
420 prBssDesc = scanSearchBssDescByBssid(prAdapter, prAisBssInfo->aucBSSID);
422 prBssDesc->ucRCPI = (UINT_8)(u4Param&0xff);
425 roamingFsmSteps(prAdapter, eNextState);
429 } /* end of roamingFsmRunEventDiscovery() */
431 /*----------------------------------------------------------------------------*/
433 * @brief Transit to Roam state after Scan Done
435 * @param [IN P_ADAPTER_T] prAdapter
439 /*----------------------------------------------------------------------------*/
441 roamingFsmRunEventRoam (
442 IN P_ADAPTER_T prAdapter
445 P_ROAMING_INFO_T prRoamingFsmInfo;
446 ENUM_ROAMING_STATE_T eNextState;
447 ROAMING_PARAM_T rParam;
449 prRoamingFsmInfo = (P_ROAMING_INFO_T)&(prAdapter->rWifiVar.rRoamingInfo);
451 /* Check Roaming Conditions */
452 ROAMING_ENABLE_CHECK(prRoamingFsmInfo);
454 DBGLOG(ROAMING, EVENT, ("EVENT-ROAMING ROAM: Current Time = %ld\n", kalGetTimeTick()));
456 /* IDLE, ROAM -> DECISION */
457 /* Errors as IDLE, DECISION, ROAM -> ROAM */
458 if (prRoamingFsmInfo->eCurrentState != ROAMING_STATE_DISCOVERY) {
462 eNextState = ROAMING_STATE_ROAM;
463 /* DISCOVERY -> ROAM */
464 if (eNextState != prRoamingFsmInfo->eCurrentState) {
465 rParam.u2Event = ROAMING_EVENT_ROAM;
466 roamingFsmSendCmd(prAdapter, (P_ROAMING_PARAM_T) &rParam);
468 /* Step to next state */
469 roamingFsmSteps(prAdapter, eNextState);
473 } /* end of roamingFsmRunEventRoam() */
475 /*----------------------------------------------------------------------------*/
477 * @brief Transit to Decision state as being failed to find out any candidate
479 * @param [IN P_ADAPTER_T] prAdapter
483 /*----------------------------------------------------------------------------*/
485 roamingFsmRunEventFail (
486 IN P_ADAPTER_T prAdapter,
490 P_ROAMING_INFO_T prRoamingFsmInfo;
491 ENUM_ROAMING_STATE_T eNextState;
492 ROAMING_PARAM_T rParam;
494 prRoamingFsmInfo = (P_ROAMING_INFO_T)&(prAdapter->rWifiVar.rRoamingInfo);
496 /* Check Roaming Conditions */
497 ROAMING_ENABLE_CHECK(prRoamingFsmInfo);
499 DBGLOG(ROAMING, EVENT, ("EVENT-ROAMING FAIL: reason %x Current Time = %ld\n", u4Param, kalGetTimeTick()));
501 /* IDLE, ROAM -> DECISION */
502 /* Errors as IDLE, DECISION, DISCOVERY -> DECISION */
503 if (prRoamingFsmInfo->eCurrentState != ROAMING_STATE_ROAM) {
507 eNextState = ROAMING_STATE_DECISION;
508 /* ROAM -> DECISION */
509 if (eNextState != prRoamingFsmInfo->eCurrentState) {
510 rParam.u2Event = ROAMING_EVENT_FAIL;
511 rParam.u2Data = (UINT_16)(u4Param&0xffff);
512 roamingFsmSendCmd(prAdapter, (P_ROAMING_PARAM_T) &rParam);
514 /* Step to next state */
515 roamingFsmSteps(prAdapter, eNextState);
519 } /* end of roamingFsmRunEventFail() */
521 /*----------------------------------------------------------------------------*/
523 * @brief Transit to Idle state as beging aborted by other moduels, AIS
525 * @param [IN P_ADAPTER_T] prAdapter
529 /*----------------------------------------------------------------------------*/
531 roamingFsmRunEventAbort (
532 IN P_ADAPTER_T prAdapter
535 P_ROAMING_INFO_T prRoamingFsmInfo;
536 ENUM_ROAMING_STATE_T eNextState;
537 ROAMING_PARAM_T rParam;
539 prRoamingFsmInfo = (P_ROAMING_INFO_T)&(prAdapter->rWifiVar.rRoamingInfo);
541 ROAMING_ENABLE_CHECK(prRoamingFsmInfo);
543 DBGLOG(ROAMING, EVENT, ("EVENT-ROAMING ABORT: Current Time = %ld\n", kalGetTimeTick()));
545 eNextState = ROAMING_STATE_IDLE;
546 /* IDLE, DECISION, DISCOVERY, ROAM -> IDLE */
547 if (eNextState != prRoamingFsmInfo->eCurrentState) {
548 rParam.u2Event = ROAMING_EVENT_ABORT;
549 roamingFsmSendCmd(prAdapter, (P_ROAMING_PARAM_T) &rParam);
551 /* Step to next state */
552 roamingFsmSteps(prAdapter, eNextState);
556 } /* end of roamingFsmRunEventAbort() */
558 /*----------------------------------------------------------------------------*/
560 * @brief Process events from firmware
562 * @param [IN P_ADAPTER_T] prAdapter
563 * [IN P_ROAMING_PARAM_T] prParam
567 /*----------------------------------------------------------------------------*/
569 roamingFsmProcessEvent (
570 IN P_ADAPTER_T prAdapter,
571 IN P_ROAMING_PARAM_T prParam
574 DBGLOG(ROAMING, LOUD, ("ROAMING Process Events: Current Time = %ld\n", kalGetTimeTick()));
576 if (ROAMING_EVENT_DISCOVERY == prParam->u2Event) {
577 roamingFsmRunEventDiscovery(prAdapter, prParam->u2Data);
580 return WLAN_STATUS_SUCCESS;