add rk3288 pinctrl dts code
[firefly-linux-kernel-4.4.55.git] / drivers / net / wireless / mt5931_kk / drv_wlan / mgmt / cnm_timer.c
1 /*
2 ** $Id: //Department/DaVinci/BRANCHES/MT662X_593X_WIFI_DRIVER_V2_3/mgmt/cnm_timer.c#1 $
3 */
4
5 /*! \file   "cnm_timer.c"
6     \brief
7
8 */
9
10 /*******************************************************************************
11 * Copyright (c) 2009 MediaTek Inc.
12 *
13 * All rights reserved. Copying, compilation, modification, distribution
14 * or any other use whatsoever of this material is strictly prohibited
15 * except in accordance with a Software License Agreement with
16 * MediaTek Inc.
17 ********************************************************************************
18 */
19
20 /*******************************************************************************
21 * LEGAL DISCLAIMER
22 *
23 * BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND
24 * AGREES THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK
25 * SOFTWARE") RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE
26 * PROVIDED TO BUYER ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY
27 * DISCLAIMS ANY AND ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT
28 * LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
29 * PARTICULAR PURPOSE OR NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE
30 * ANY WARRANTY WHATSOEVER WITH RESPECT TO THE SOFTWARE OF ANY THIRD PARTY
31 * WHICH MAY BE USED BY, INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK
32 * SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY
33 * WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE
34 * FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S SPECIFICATION OR TO
35 * CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
36 *
37 * BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
38 * LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL
39 * BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT
40 * ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY
41 * BUYER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
42 *
43 * THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
44 * WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT
45 * OF LAWS PRINCIPLES.  ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING
46 * THEREOF AND RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN
47 * FRANCISCO, CA, UNDER THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE
48 * (ICC).
49 ********************************************************************************
50 */
51
52 /*
53 ** $Log: cnm_timer.c $
54  *
55  * 12 13 2011 cm.chang
56  * [WCXRP00001136] [All Wi-Fi][Driver] Add wake lock for pending timer
57  * Add wake lock if timer timeout value is smaller than 5 seconds
58  *
59  * 02 24 2011 cp.wu
60  * [WCXRP00000490] [MT6620 Wi-Fi][Driver][Win32] modify kalMsleep() implementation because NdisMSleep() won't sleep long enough for specified interval such as 500ms
61  * modify cnm_timer and hem_mbox APIs to be thread safe to ease invoking restrictions
62  *
63  * 07 08 2010 cp.wu
64  *
65  * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository.
66  *
67  * 06 08 2010 cp.wu
68  * [WPD00003833][MT6620 and MT5931] Driver migration
69  * cnm_timer has been migrated.
70  *
71  * 05 28 2010 cm.chang
72  * [BORA00000018]Integrate WIFI part into BORA for the 1st time
73  * Support sleep notification to host
74  *
75  * 05 19 2010 cm.chang
76  * [BORA00000018]Integrate WIFI part into BORA for the 1st time
77  * Add some checking assertions
78  *
79  * 04 24 2010 cm.chang
80  * [BORA00000018]Integrate WIFI part into BORA for the 1st time
81  * Return timer token back to COS when entering wait off state
82  *
83  * 01 11 2010 cm.chang
84  * [BORA00000018]Integrate WIFI part into BORA for the 1st time
85  * Remove compiling warning
86  *
87  * 01 08 2010 cm.chang
88  * [BORA00000018]Integrate WIFI part into BORA for the 1st time
89  * Support longer timeout interval to 45 days from 65secu1rwduu`wvpghlqg|fh+fmdkb
90  *
91  * 01 06 2010 cm.chang
92  * [BORA00000018]Integrate WIFI part into BORA for the 1st time
93  * Fix system time is 32KHz instead of 1ms
94  *
95  * 01 04 2010 tehuang.liu
96  * [BORA00000018]Integrate WIFI part into BORA for the 1st time
97  * For working out the first connection Chariot-verified version
98  *
99  * Dec 3 2009 mtk01461
100  * [BORA00000018] Integrate WIFI part into BORA for the 1st time
101  * Place rRootTimer.rNextExpiredSysTime = rExpiredSysTime; before set timer
102  *
103  * Oct 30 2009 mtk01104
104  * [BORA00000018] Integrate WIFI part into BORA for the 1st time
105  * In cnmTimerInitialize(), just stop timer if it was already created.
106  *
107  * Oct 30 2009 mtk01461
108  * [BORA00000018] Integrate WIFI part into BORA for the 1st time
109  * Move the external reference for Lint to precomp.h
110  *
111  * Oct 30 2009 mtk01461
112  * [BORA00000018] Integrate WIFI part into BORA for the 1st time
113  * Fix lint warning
114  *
115  * Oct 28 2009 mtk01104
116  * [BORA00000018] Integrate WIFI part into BORA for the 1st time
117  *
118 **
119 */
120
121 /*******************************************************************************
122 *                         C O M P I L E R   F L A G S
123 ********************************************************************************
124 */
125
126 /*******************************************************************************
127 *                    E X T E R N A L   R E F E R E N C E S
128 ********************************************************************************
129 */
130 #include "precomp.h"
131
132 /*******************************************************************************
133 *                              C O N S T A N T S
134 ********************************************************************************
135 */
136
137 /*******************************************************************************
138 *                             D A T A   T Y P E S
139 ********************************************************************************
140 */
141
142 /*******************************************************************************
143 *                            P U B L I C   D A T A
144 ********************************************************************************
145 */
146
147 /*******************************************************************************
148 *                           P R I V A T E   D A T A
149 ********************************************************************************
150 */
151
152 /*******************************************************************************
153 *                                 M A C R O S
154 ********************************************************************************
155 */
156
157 /*******************************************************************************
158 *                   F U N C T I O N   D E C L A R A T I O N S
159 ********************************************************************************
160 */
161
162 /*******************************************************************************
163 *                              F U N C T I O N S
164 ********************************************************************************
165 */
166
167 /*----------------------------------------------------------------------------*/
168 /*!
169 * \brief This routine is called to set the time to do the time out check.
170 *
171 * \param[in] rTimeout Time out interval from current time.
172 *
173 * \retval TRUE Success.
174 *
175 */
176 /*----------------------------------------------------------------------------*/
177 static BOOLEAN
178 cnmTimerSetTimer (
179     IN P_ADAPTER_T prAdapter,
180     IN OS_SYSTIME  rTimeout
181     )
182 {
183     P_ROOT_TIMER        prRootTimer;
184     BOOLEAN             fgNeedWakeLock;
185
186     ASSERT(prAdapter);
187
188     prRootTimer = &prAdapter->rRootTimer;
189
190     kalSetTimer(prAdapter->prGlueInfo, rTimeout);
191
192     if (rTimeout <= SEC_TO_SYSTIME(WAKE_LOCK_MAX_TIME)) {
193         fgNeedWakeLock = TRUE;
194
195         if (!prRootTimer->fgWakeLocked) {
196             KAL_WAKE_LOCK(prAdapter, &prRootTimer->rWakeLock);
197             prRootTimer->fgWakeLocked = TRUE;
198         }
199     }
200     else {
201         fgNeedWakeLock = FALSE;
202     }
203
204     return fgNeedWakeLock;
205 }
206
207 /*----------------------------------------------------------------------------*/
208 /*!
209 * \brief This routines is called to initialize a root timer.
210 *
211 * \param[in] prAdapter
212 *
213 * \return (none)
214 */
215 /*----------------------------------------------------------------------------*/
216 VOID
217 cnmTimerInitialize (
218     IN P_ADAPTER_T prAdapter
219     )
220 {
221     P_ROOT_TIMER    prRootTimer;
222     KAL_SPIN_LOCK_DECLARATION();
223
224     ASSERT(prAdapter);
225
226     prRootTimer = &prAdapter->rRootTimer;
227
228     /* Note: glue layer have configured timer */
229
230     KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TIMER);
231     LINK_INITIALIZE(&prRootTimer->rLinkHead);
232     KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TIMER);
233
234     KAL_WAKE_LOCK_INIT(prAdapter, &prRootTimer->rWakeLock, "WLAN Timer");
235     prRootTimer->fgWakeLocked = FALSE;
236     return;
237 }
238
239 /*----------------------------------------------------------------------------*/
240 /*!
241 * \brief This routines is called to destroy a root timer.
242 *        When WIFI is off, the token shall be returned back to system.
243 *
244 * \param[in]
245 *
246 * \return (none)
247 */
248 /*----------------------------------------------------------------------------*/
249 VOID
250 cnmTimerDestroy (
251     IN P_ADAPTER_T prAdapter
252     )
253 {
254     P_ROOT_TIMER    prRootTimer;
255     KAL_SPIN_LOCK_DECLARATION();
256
257     ASSERT(prAdapter);
258
259     prRootTimer = &prAdapter->rRootTimer;
260
261     if (prRootTimer->fgWakeLocked) {
262         KAL_WAKE_UNLOCK(prAdapter, &prRootTimer->rWakeLock);
263         prRootTimer->fgWakeLocked = FALSE;
264     }
265     KAL_WAKE_LOCK_DESTROY(prAdapter, &prRootTimer->rWakeLock);
266
267     KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TIMER);
268     LINK_INITIALIZE(&prRootTimer->rLinkHead);
269     KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TIMER);
270
271     /* Note: glue layer will be responsible for timer destruction */
272
273     return;
274 }
275
276 /*----------------------------------------------------------------------------*/
277 /*!
278 * \brief This routines is called to initialize a timer.
279 *
280 * \param[in] prTimer Pointer to a timer structure.
281 * \param[in] pfnFunc Pointer to the call back function.
282 * \param[in] u4Data Parameter for call back function.
283 *
284 * \return (none)
285 */
286 /*----------------------------------------------------------------------------*/
287 VOID
288 cnmTimerInitTimer (
289     IN P_ADAPTER_T              prAdapter,
290     IN P_TIMER_T                prTimer,
291     IN PFN_MGMT_TIMEOUT_FUNC    pfFunc,
292     IN UINT_32                  u4Data
293     )
294 {
295     ASSERT(prAdapter);
296
297     ASSERT(prTimer);
298
299 #if DBG
300     /* Note: NULL function pointer is permitted for HEM POWER */
301     if (pfFunc == NULL) {
302         DBGLOG(CNM, WARN, ("Init timer with NULL callback function!\n"));
303     }
304 #endif
305
306 #if DBG
307     ASSERT(prAdapter->rRootTimer.rLinkHead.prNext);
308     {
309         P_LINK_T            prTimerList;
310         P_LINK_ENTRY_T      prLinkEntry;
311         P_TIMER_T           prPendingTimer;
312
313         prTimerList = &(prAdapter->rRootTimer.rLinkHead);
314
315         LINK_FOR_EACH(prLinkEntry, prTimerList) {
316             prPendingTimer = LINK_ENTRY(prLinkEntry, TIMER_T, rLinkEntry);
317             ASSERT(prPendingTimer);
318             ASSERT(prPendingTimer != prTimer);
319         }
320     }
321 #endif
322
323     LINK_ENTRY_INITIALIZE(&prTimer->rLinkEntry);
324
325     prTimer->pfMgmtTimeOutFunc  = pfFunc;
326     prTimer->u4Data             = u4Data;
327
328     return;
329 }
330
331
332 /*----------------------------------------------------------------------------*/
333 /*!
334 * \brief This routines is called to stop a timer.
335 *
336 * \param[in] prTimer Pointer to a timer structure.
337 *
338 * \return (none)
339 */
340 /*----------------------------------------------------------------------------*/
341 static VOID
342 cnmTimerStopTimer_impl (
343     IN P_ADAPTER_T              prAdapter,
344     IN P_TIMER_T                prTimer,
345     IN BOOLEAN                  fgAcquireSpinlock
346     )
347 {
348     P_ROOT_TIMER    prRootTimer;
349     KAL_SPIN_LOCK_DECLARATION();
350
351     ASSERT(prAdapter);
352     ASSERT(prTimer);
353
354     prRootTimer = &prAdapter->rRootTimer;
355
356     if (fgAcquireSpinlock) {
357         KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TIMER);
358     }
359
360     if (timerPendingTimer(prTimer)) {
361         LINK_REMOVE_KNOWN_ENTRY(&prRootTimer->rLinkHead,
362                     &prTimer->rLinkEntry);
363
364         /* Reduce dummy timeout for power saving, especially HIF activity.
365          * If two or more timers exist and being removed timer is smallest,
366          * this dummy timeout will still happen, but it is OK.
367          */
368         if (LINK_IS_EMPTY(&prRootTimer->rLinkHead)) {
369             kalCancelTimer(prAdapter->prGlueInfo);
370
371             if (fgAcquireSpinlock && prRootTimer->fgWakeLocked) {
372                 KAL_WAKE_UNLOCK(prAdapter, &prRootTimer->rWakeLock);
373                 prRootTimer->fgWakeLocked = FALSE;
374             }
375         }
376     }
377
378     if (fgAcquireSpinlock) {
379         KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TIMER);
380     }
381 }
382
383 /*----------------------------------------------------------------------------*/
384 /*!
385 * \brief This routines is called to stop a timer.
386 *
387 * \param[in] prTimer Pointer to a timer structure.
388 *
389 * \return (none)
390 */
391 /*----------------------------------------------------------------------------*/
392 VOID
393 cnmTimerStopTimer (
394     IN P_ADAPTER_T              prAdapter,
395     IN P_TIMER_T                prTimer
396     )
397 {
398     ASSERT(prAdapter);
399     ASSERT(prTimer);
400
401     cnmTimerStopTimer_impl(prAdapter, prTimer, TRUE);
402 }
403
404 /*----------------------------------------------------------------------------*/
405 /*!
406 * \brief This routines is called to start a timer with wake_lock.
407 *
408 * \param[in] prTimer Pointer to a timer structure.
409 * \param[in] u4TimeoutMs Timeout to issue the timer and call back function
410 *                        (unit: ms).
411 *
412 * \return (none)
413 */
414 /*----------------------------------------------------------------------------*/
415 VOID
416 cnmTimerStartTimer (
417     IN P_ADAPTER_T      prAdapter,
418     IN P_TIMER_T        prTimer,
419     IN UINT_32          u4TimeoutMs
420     )
421 {
422     P_ROOT_TIMER    prRootTimer;
423     P_LINK_T        prTimerList;
424     OS_SYSTIME      rExpiredSysTime, rTimeoutSystime;
425     KAL_SPIN_LOCK_DECLARATION();
426
427     ASSERT(prAdapter);
428     ASSERT(prTimer);
429
430     KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TIMER);
431
432     prRootTimer = &prAdapter->rRootTimer;
433     prTimerList= &prRootTimer->rLinkHead;
434
435     /* If timeout interval is larger than 1 minute, the mod value is set
436      * to the timeout value first, then per minutue.
437      */
438     if (u4TimeoutMs > MSEC_PER_MIN) {
439         ASSERT(u4TimeoutMs <= ((UINT_32)0xFFFF * MSEC_PER_MIN));
440
441         prTimer->u2Minutes = (UINT_16)(u4TimeoutMs / MSEC_PER_MIN);
442         u4TimeoutMs -= (prTimer->u2Minutes * MSEC_PER_MIN);
443         if (u4TimeoutMs == 0) {
444             u4TimeoutMs = MSEC_PER_MIN;
445             prTimer->u2Minutes--;
446         }
447     }
448     else {
449         prTimer->u2Minutes = 0;
450     }
451
452     /* The assertion check if MSEC_TO_SYSTIME() may be overflow. */
453     ASSERT(u4TimeoutMs < (((UINT_32)0x80000000 - MSEC_PER_SEC) / KAL_HZ));
454     rTimeoutSystime = MSEC_TO_SYSTIME(u4TimeoutMs);
455     rExpiredSysTime = kalGetTimeTick() + rTimeoutSystime;
456
457     /* If no timer pending or the fast time interval is used. */
458     if (LINK_IS_EMPTY(prTimerList) ||
459         TIME_BEFORE(rExpiredSysTime, prRootTimer->rNextExpiredSysTime)) {
460
461         prRootTimer->rNextExpiredSysTime = rExpiredSysTime;
462         cnmTimerSetTimer(prAdapter, rTimeoutSystime);
463     }
464
465     /* Add this timer to checking list */
466     prTimer->rExpiredSysTime = rExpiredSysTime;
467
468     if (!timerPendingTimer(prTimer)) {
469         LINK_INSERT_TAIL(prTimerList, &prTimer->rLinkEntry);
470     }
471
472     KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TIMER);
473
474     return;
475 }
476
477 /*----------------------------------------------------------------------------*/
478 /*!
479 * \brief This routines is called to check the timer list.
480 *
481 * \param[in]
482 *
483 * \return (none)
484 */
485 /*----------------------------------------------------------------------------*/
486 VOID
487 cnmTimerDoTimeOutCheck (
488     IN P_ADAPTER_T      prAdapter
489     )
490 {
491     P_ROOT_TIMER        prRootTimer;
492     P_LINK_T            prTimerList;
493     P_LINK_ENTRY_T      prLinkEntry;
494     P_TIMER_T           prTimer;
495     OS_SYSTIME          rCurSysTime;
496     PFN_MGMT_TIMEOUT_FUNC   pfMgmtTimeOutFunc;
497     UINT_32             u4TimeoutData;
498     BOOLEAN             fgNeedWakeLock;
499     KAL_SPIN_LOCK_DECLARATION();
500
501     ASSERT(prAdapter);
502
503     /* acquire spin lock */
504     KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TIMER);
505
506     prRootTimer = &prAdapter->rRootTimer;
507     prTimerList= &prRootTimer->rLinkHead;
508
509     rCurSysTime = kalGetTimeTick();
510
511     /* Set the permitted max timeout value for new one */
512     prRootTimer->rNextExpiredSysTime = rCurSysTime + MGMT_MAX_TIMEOUT_INTERVAL;
513
514     LINK_FOR_EACH(prLinkEntry, prTimerList) {
515         prTimer = LINK_ENTRY(prLinkEntry, TIMER_T, rLinkEntry);
516         ASSERT(prTimer);
517
518         /* Check if this entry is timeout. */
519         if (!TIME_BEFORE(rCurSysTime, prTimer->rExpiredSysTime)) {
520             cnmTimerStopTimer_impl(prAdapter, prTimer, FALSE);
521
522             pfMgmtTimeOutFunc = prTimer->pfMgmtTimeOutFunc;
523             u4TimeoutData = prTimer->u4Data;
524
525             if (prTimer->u2Minutes > 0) {
526                 prTimer->u2Minutes--;
527                 prTimer->rExpiredSysTime =
528                     rCurSysTime + MSEC_TO_SYSTIME(MSEC_PER_MIN);
529                 LINK_INSERT_TAIL(prTimerList, &prTimer->rLinkEntry);
530             }
531             else if (pfMgmtTimeOutFunc) {
532                 KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TIMER);
533                 (pfMgmtTimeOutFunc)(prAdapter, u4TimeoutData);
534                 KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TIMER);
535             }
536
537             /* Search entire list again because of nest del and add timers
538              * and current MGMT_TIMER could be volatile after stopped
539              */
540             prLinkEntry = (P_LINK_ENTRY_T)prTimerList;
541
542             prRootTimer->rNextExpiredSysTime =
543                     rCurSysTime + MGMT_MAX_TIMEOUT_INTERVAL;
544         }
545         else if (TIME_BEFORE(prTimer->rExpiredSysTime,
546                              prRootTimer->rNextExpiredSysTime)) {
547             prRootTimer->rNextExpiredSysTime = prTimer->rExpiredSysTime;
548         }
549     } /* end of for loop */
550
551     /* Setup the prNext timeout event. It is possible the timer was already
552      * set in the above timeout callback function.
553      */
554     fgNeedWakeLock = FALSE;
555     if (!LINK_IS_EMPTY(prTimerList)) {
556         ASSERT(TIME_AFTER(prRootTimer->rNextExpiredSysTime, rCurSysTime));
557
558         fgNeedWakeLock = cnmTimerSetTimer(prAdapter, (OS_SYSTIME)
559             ((INT_32)prRootTimer->rNextExpiredSysTime - (INT_32)rCurSysTime));
560     }
561
562     if (prRootTimer->fgWakeLocked && !fgNeedWakeLock) {
563         KAL_WAKE_UNLOCK(prAdapter, &prRootTimer->rWakeLock);
564         prRootTimer->fgWakeLocked = FALSE;
565     }
566
567     /* release spin lock */
568     KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TIMER);
569 }
570
571