add rk3288 pinctrl dts code
[firefly-linux-kernel-4.4.55.git] / drivers / net / wireless / combo_mt66xx / mt6620 / wlan / mgmt / roaming_fsm.c
1 /*
2 ** $Id:
3 */
4
5 /*! \file   "roaming_fsm.c"
6     \brief  This file defines the FSM for Roaming MODULE.
7
8     This file defines the FSM for Roaming MODULE.
9 */
10
11
12
13 /*
14 ** $Log: roaming_fsm.c $
15  *
16  * 11 24 2011 wh.su
17  * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG
18  * Adjust code for DBG and CONFIG_XLOG.
19  *
20  * 11 11 2011 wh.su
21  * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG
22  * modify the xlog related code.
23  *
24  * 11 02 2011 wh.su
25  * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG
26  * adding the code for XLOG.
27  *
28  * 08 31 2011 tsaiyuan.hsu
29  * [WCXRP00000931] [MT5931 Wi-Fi][DRV/FW] add swcr to disable roaming from driver
30  * remove obsolete code.
31  *
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 .
35  *
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.
39  *
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.
43  *
44  * 01 27 2011 tsaiyuan.hsu
45  * [WCXRP00000392] [MT6620 Wi-Fi][Driver] Add Roaming Support
46  * add roaming fsm
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.
51  *
52  * 01 27 2011 tsaiyuan.hsu
53  * [WCXRP00000392] [MT6620 Wi-Fi][Driver] Add Roaming Support
54  * add roaming fsm
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.
59  *
60 */
61
62 /*******************************************************************************
63 *                         C O M P I L E R   F L A G S
64 ********************************************************************************
65 */
66
67 /*******************************************************************************
68 *                    E X T E R N A L   R E F E R E N C E S
69 ********************************************************************************
70 */
71 #include "precomp.h"
72
73 #if CFG_SUPPORT_ROAMING
74 /*******************************************************************************
75 *                              C O N S T A N T S
76 ********************************************************************************
77 */
78
79 /*******************************************************************************
80 *                             D A T A   T Y P E S
81 ********************************************************************************
82 */
83
84 /*******************************************************************************
85 *                            P U B L I C   D A T A
86 ********************************************************************************
87 */
88
89 /*******************************************************************************
90 *                           P R I V A T E   D A T A
91 ********************************************************************************
92 */
93
94 #if DBG
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")
101 };
102 /*lint -restore */
103 #endif /* DBG */
104
105 /*******************************************************************************
106 *                                 M A C R O S
107 ********************************************************************************
108 */
109
110 #define ROAMING_ENABLE_CHECK(_roam) \
111         { \
112             if (!(_roam->fgIsEnableRoaming)) {return;} \
113         }
114
115 /*******************************************************************************
116 *                   F U N C T I O N   D E C L A R A T I O N S
117 ********************************************************************************
118 */
119
120 /*******************************************************************************
121 *                              F U N C T I O N S
122 ********************************************************************************
123 */
124
125 /*----------------------------------------------------------------------------*/
126 /*!
127 * @brief Initialize the value in ROAMING_FSM_INFO_T for ROAMING FSM operation
128 *
129 * @param [IN P_ADAPTER_T] prAdapter
130 *
131 * @return (none)
132 */
133 /*----------------------------------------------------------------------------*/
134 VOID
135 roamingFsmInit (
136     IN P_ADAPTER_T prAdapter
137     )
138 {
139     P_ROAMING_INFO_T prRoamingFsmInfo;
140     P_CONNECTION_SETTINGS_T prConnSettings;
141
142     DBGLOG(ROAMING, LOUD, ("->roamingFsmInit(): Current Time = %ld\n", kalGetTimeTick()));
143
144     prRoamingFsmInfo = (P_ROAMING_INFO_T)&(prAdapter->rWifiVar.rRoamingInfo);
145     prConnSettings = &(prAdapter->rWifiVar.rConnSettings);
146
147     //4 <1> Initiate FSM
148     prRoamingFsmInfo->fgIsEnableRoaming = prConnSettings->fgIsEnableRoaming;
149     prRoamingFsmInfo->eCurrentState = ROAMING_STATE_IDLE;
150     prRoamingFsmInfo->rRoamingDiscoveryUpdateTime = 0;
151
152     return;
153 } /* end of roamingFsmInit() */
154
155 /*----------------------------------------------------------------------------*/
156 /*!
157 * @brief Uninitialize the value in AIS_FSM_INFO_T for AIS FSM operation
158 *
159 * @param [IN P_ADAPTER_T] prAdapter
160 *
161 * @return (none)
162 */
163 /*----------------------------------------------------------------------------*/
164 VOID
165 roamingFsmUninit (
166     IN P_ADAPTER_T prAdapter
167     )
168 {
169     P_ROAMING_INFO_T prRoamingFsmInfo;
170
171     DBGLOG(ROAMING, LOUD, ("->roamingFsmUninit(): Current Time = %ld\n", kalGetTimeTick()));
172
173     prRoamingFsmInfo = (P_ROAMING_INFO_T)&(prAdapter->rWifiVar.rRoamingInfo);
174
175     prRoamingFsmInfo->eCurrentState = ROAMING_STATE_IDLE;
176
177     return;
178 } /* end of roamingFsmUninit() */
179
180 /*----------------------------------------------------------------------------*/
181 /*!
182 * @brief Send commands to firmware
183 *
184 * @param [IN P_ADAPTER_T]       prAdapter
185 *        [IN P_ROAMING_PARAM_T] prParam
186 *
187 * @return (none)
188 */
189 /*----------------------------------------------------------------------------*/
190 VOID
191 roamingFsmSendCmd (
192     IN P_ADAPTER_T prAdapter,
193     IN P_ROAMING_PARAM_T prParam
194     )
195 {
196     P_ROAMING_INFO_T prRoamingFsmInfo;
197     WLAN_STATUS rStatus;
198
199     DBGLOG(ROAMING, LOUD, ("->roamingFsmSendCmd(): Current Time = %ld\n", kalGetTimeTick()));
200
201     prRoamingFsmInfo = (P_ROAMING_INFO_T)&(prAdapter->rWifiVar.rRoamingInfo);
202
203     rStatus = wlanSendSetQueryCmd (
204                 prAdapter,                  /* prAdapter */
205                 CMD_ID_ROAMING_TRANSIT,     /* ucCID */
206                 TRUE,                       /* fgSetQuery */
207                 FALSE,                      /* fgNeedResp */
208                 FALSE,                      /* fgIsOid */
209                 NULL,                       /* pfCmdDoneHandler */
210                 NULL,                       /* pfCmdTimeoutHandler */
211                 sizeof(ROAMING_PARAM_T),    /* u4SetQueryInfoLen */
212                 (PUINT_8) prParam,          /* pucInfoBuffer */
213                 NULL,                       /* pvSetQueryBuffer */
214                 0                           /* u4SetQueryBufferLen */
215                 );
216
217     ASSERT(rStatus == WLAN_STATUS_PENDING);
218
219     return;
220 } /* end of roamingFsmSendCmd() */
221
222 /*----------------------------------------------------------------------------*/
223 /*!
224 * @brief Update the recent time when ScanDone occurred
225 *
226 * @param [IN P_ADAPTER_T] prAdapter
227 *
228 * @return none
229 */
230 /*----------------------------------------------------------------------------*/
231 VOID
232 roamingFsmScanResultsUpdate (
233     IN P_ADAPTER_T prAdapter
234     )
235 {
236     P_ROAMING_INFO_T prRoamingFsmInfo;
237
238     prRoamingFsmInfo = (P_ROAMING_INFO_T)&(prAdapter->rWifiVar.rRoamingInfo);
239
240     /* Check Roaming Conditions */
241     ROAMING_ENABLE_CHECK(prRoamingFsmInfo);
242
243     DBGLOG(ROAMING, LOUD, ("->roamingFsmScanResultsUpdate(): Current Time = %ld\n", kalGetTimeTick()));
244
245     GET_CURRENT_SYSTIME(&prRoamingFsmInfo->rRoamingDiscoveryUpdateTime);
246
247     return;
248 } /* end of roamingFsmScanResultsUpdate() */
249
250 /*----------------------------------------------------------------------------*/
251 /*!
252 * @brief The Core FSM engine of ROAMING for AIS Infra.
253 *
254 * @param [IN P_ADAPTER_T]          prAdapter
255 *        [IN ENUM_ROAMING_STATE_T] eNextState Enum value of next AIS STATE
256 *
257 * @return (none)
258 */
259 /*----------------------------------------------------------------------------*/
260 VOID
261 roamingFsmSteps (
262     IN P_ADAPTER_T prAdapter,
263     IN ENUM_ROAMING_STATE_T eNextState
264     )
265 {
266     P_ROAMING_INFO_T prRoamingFsmInfo;
267     ENUM_ROAMING_STATE_T ePreviousState;
268     BOOLEAN fgIsTransition = (BOOLEAN)FALSE;
269
270     prRoamingFsmInfo = (P_ROAMING_INFO_T)&(prAdapter->rWifiVar.rRoamingInfo);
271
272     do {
273
274         /* Do entering Next State */
275 #if DBG
276         DBGLOG(ROAMING, STATE, ("TRANSITION: [%s] -> [%s]\n",
277                             apucDebugRoamingState[prRoamingFsmInfo->eCurrentState],
278                             apucDebugRoamingState[eNextState]));
279 #else
280         DBGLOG(ROAMING, STATE, ("[%d] TRANSITION: [%d] -> [%d]\n",
281                             DBG_ROAMING_IDX,
282                             prRoamingFsmInfo->eCurrentState,
283                             eNextState));
284 #endif
285         /* NOTE(Kevin): This is the only place to change the eCurrentState(except initial) */
286         ePreviousState = prRoamingFsmInfo->eCurrentState;
287         prRoamingFsmInfo->eCurrentState = eNextState;
288
289         fgIsTransition = (BOOLEAN)FALSE;
290
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.
296          */
297         case ROAMING_STATE_IDLE:
298         case ROAMING_STATE_DECISION:
299                   break;
300
301         case ROAMING_STATE_DISCOVERY:
302                   {
303                       OS_SYSTIME rCurrentTime;
304
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);
310                 }
311                 else {
312                           DBGLOG(ROAMING, LOUD, ("roamingFsmSteps: DiscoveryUpdateTime Updated"));
313                           aisFsmRunEventRoamingDiscovery(prAdapter, FALSE);
314                 }
315             }
316                   break;
317
318         case ROAMING_STATE_ROAM:
319                   break;
320
321         default:
322             ASSERT(0); /* Make sure we have handle all STATEs */
323         }
324     }
325     while (fgIsTransition);
326
327     return;
328
329 } /* end of roamingFsmSteps() */
330
331 /*----------------------------------------------------------------------------*/
332 /*!
333 * @brief Transit to Decision state after join completion
334 *
335 * @param [IN P_ADAPTER_T] prAdapter
336 *
337 * @return none
338 */
339 /*----------------------------------------------------------------------------*/
340 VOID
341 roamingFsmRunEventStart (
342     IN P_ADAPTER_T prAdapter
343     )
344 {
345     P_ROAMING_INFO_T prRoamingFsmInfo;
346     ENUM_ROAMING_STATE_T eNextState;
347     P_BSS_INFO_T prAisBssInfo;
348     ROAMING_PARAM_T rParam;
349
350     prRoamingFsmInfo = (P_ROAMING_INFO_T)&(prAdapter->rWifiVar.rRoamingInfo);
351
352     /* Check Roaming Conditions */
353     ROAMING_ENABLE_CHECK(prRoamingFsmInfo);
354
355     prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]);
356     if (prAisBssInfo->eCurrentOPMode != OP_MODE_INFRASTRUCTURE) {
357         return;
358     }
359
360     DBGLOG(ROAMING, EVENT, ("EVENT-ROAMING START: Current Time = %ld\n", kalGetTimeTick()));
361
362     /* IDLE, ROAM -> DECISION */
363     /* Errors as DECISION, DISCOVERY -> DECISION */
364     if (!(prRoamingFsmInfo->eCurrentState == ROAMING_STATE_IDLE
365           || prRoamingFsmInfo->eCurrentState == ROAMING_STATE_ROAM)) {
366         return;
367     }
368
369     eNextState = ROAMING_STATE_DECISION;
370     if (eNextState != prRoamingFsmInfo->eCurrentState) {
371           rParam.u2Event = ROAMING_EVENT_START;
372           roamingFsmSendCmd(prAdapter, (P_ROAMING_PARAM_T) &rParam);
373
374           /* Step to next state */
375         roamingFsmSteps(prAdapter, eNextState);
376     }
377
378     return;
379 } /* end of roamingFsmRunEventStart() */
380
381 /*----------------------------------------------------------------------------*/
382 /*!
383 * @brief Transit to Discovery state when deciding to find a candidate
384 *
385 * @param [IN P_ADAPTER_T] prAdapter
386 *
387 * @return none
388 */
389 /*----------------------------------------------------------------------------*/
390 VOID
391 roamingFsmRunEventDiscovery (
392     IN P_ADAPTER_T prAdapter,
393     IN UINT_32 u4Param
394     )
395 {
396     P_ROAMING_INFO_T prRoamingFsmInfo;
397     ENUM_ROAMING_STATE_T eNextState;
398
399     prRoamingFsmInfo = (P_ROAMING_INFO_T)&(prAdapter->rWifiVar.rRoamingInfo);
400
401     /* Check Roaming Conditions */
402     ROAMING_ENABLE_CHECK(prRoamingFsmInfo);
403
404     DBGLOG(ROAMING, EVENT, ("EVENT-ROAMING DISCOVERY: Current Time = %ld\n", kalGetTimeTick()));
405
406     /* DECISION -> DISCOVERY */
407     /* Errors as IDLE, DISCOVERY, ROAM -> DISCOVERY */
408     if (prRoamingFsmInfo->eCurrentState != ROAMING_STATE_DECISION) {
409         return;
410     }
411
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;
417
418         // sync. rcpi with firmware
419         prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]);
420         prBssDesc = scanSearchBssDescByBssid(prAdapter, prAisBssInfo->aucBSSID);
421         if (prBssDesc) {
422                   prBssDesc->ucRCPI = (UINT_8)(u4Param&0xff);
423         }
424
425         roamingFsmSteps(prAdapter, eNextState);
426     }
427
428     return;
429 } /* end of roamingFsmRunEventDiscovery() */
430
431 /*----------------------------------------------------------------------------*/
432 /*!
433 * @brief Transit to Roam state after Scan Done
434 *
435 * @param [IN P_ADAPTER_T] prAdapter
436 *
437 * @return none
438 */
439 /*----------------------------------------------------------------------------*/
440 VOID
441 roamingFsmRunEventRoam (
442     IN P_ADAPTER_T prAdapter
443     )
444 {
445     P_ROAMING_INFO_T prRoamingFsmInfo;
446     ENUM_ROAMING_STATE_T eNextState;
447     ROAMING_PARAM_T rParam;
448
449     prRoamingFsmInfo = (P_ROAMING_INFO_T)&(prAdapter->rWifiVar.rRoamingInfo);
450
451     /* Check Roaming Conditions */
452     ROAMING_ENABLE_CHECK(prRoamingFsmInfo);
453
454     DBGLOG(ROAMING, EVENT, ("EVENT-ROAMING ROAM: Current Time = %ld\n", kalGetTimeTick()));
455
456     /* IDLE, ROAM -> DECISION */
457     /* Errors as IDLE, DECISION, ROAM -> ROAM */
458     if (prRoamingFsmInfo->eCurrentState != ROAMING_STATE_DISCOVERY) {
459         return;
460     }
461
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);
467
468           /* Step to next state */
469         roamingFsmSteps(prAdapter, eNextState);
470     }
471
472     return;
473 } /* end of roamingFsmRunEventRoam() */
474
475 /*----------------------------------------------------------------------------*/
476 /*!
477 * @brief Transit to Decision state as being failed to find out any candidate
478 *
479 * @param [IN P_ADAPTER_T] prAdapter
480 *
481 * @return none
482 */
483 /*----------------------------------------------------------------------------*/
484 VOID
485 roamingFsmRunEventFail (
486     IN P_ADAPTER_T prAdapter,
487     IN UINT_32 u4Param
488     )
489 {
490     P_ROAMING_INFO_T prRoamingFsmInfo;
491     ENUM_ROAMING_STATE_T eNextState;
492     ROAMING_PARAM_T rParam;
493
494     prRoamingFsmInfo = (P_ROAMING_INFO_T)&(prAdapter->rWifiVar.rRoamingInfo);
495
496     /* Check Roaming Conditions */
497     ROAMING_ENABLE_CHECK(prRoamingFsmInfo);
498
499     DBGLOG(ROAMING, EVENT, ("EVENT-ROAMING FAIL: reason %x Current Time = %ld\n", u4Param, kalGetTimeTick()));
500
501     /* IDLE, ROAM -> DECISION */
502     /* Errors as IDLE, DECISION, DISCOVERY -> DECISION */
503     if (prRoamingFsmInfo->eCurrentState != ROAMING_STATE_ROAM) {
504         return;
505     }
506
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);
513
514           /* Step to next state */
515         roamingFsmSteps(prAdapter, eNextState);
516     }
517
518     return;
519 } /* end of roamingFsmRunEventFail() */
520
521 /*----------------------------------------------------------------------------*/
522 /*!
523 * @brief Transit to Idle state as beging aborted by other moduels, AIS
524 *
525 * @param [IN P_ADAPTER_T] prAdapter
526 *
527 * @return none
528 */
529 /*----------------------------------------------------------------------------*/
530 VOID
531 roamingFsmRunEventAbort (
532     IN P_ADAPTER_T prAdapter
533     )
534 {
535     P_ROAMING_INFO_T prRoamingFsmInfo;
536     ENUM_ROAMING_STATE_T eNextState;
537     ROAMING_PARAM_T rParam;
538
539     prRoamingFsmInfo = (P_ROAMING_INFO_T)&(prAdapter->rWifiVar.rRoamingInfo);
540
541     ROAMING_ENABLE_CHECK(prRoamingFsmInfo);
542
543     DBGLOG(ROAMING, EVENT, ("EVENT-ROAMING ABORT: Current Time = %ld\n", kalGetTimeTick()));
544
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);
550
551         /* Step to next state */
552         roamingFsmSteps(prAdapter, eNextState);
553     }
554
555     return;
556 } /* end of roamingFsmRunEventAbort() */
557
558 /*----------------------------------------------------------------------------*/
559 /*!
560 * @brief Process events from firmware
561 *
562 * @param [IN P_ADAPTER_T]       prAdapter
563 *        [IN P_ROAMING_PARAM_T] prParam
564 *
565 * @return none
566 */
567 /*----------------------------------------------------------------------------*/
568 WLAN_STATUS
569 roamingFsmProcessEvent (
570     IN P_ADAPTER_T prAdapter,
571     IN P_ROAMING_PARAM_T prParam
572     )
573 {
574     DBGLOG(ROAMING, LOUD, ("ROAMING Process Events: Current Time = %ld\n", kalGetTimeTick()));
575
576     if (ROAMING_EVENT_DISCOVERY == prParam->u2Event) {
577         roamingFsmRunEventDiscovery(prAdapter, prParam->u2Data);
578     }
579
580     return WLAN_STATUS_SUCCESS;
581 }
582
583 #endif