1 #include "osal_typedef.h"
5 #include <mach/mtk_wcn_cmb_stub.h>
7 INT32 gPsmDbgLevel = STP_PSM_LOG_INFO;
8 MTKSTP_PSM_T stp_psm_i;
9 MTKSTP_PSM_T *stp_psm = &stp_psm_i;
11 #define STP_PSM_LOUD_FUNC(fmt, arg...) if(gPsmDbgLevel >= STP_PSM_LOG_LOUD){ osal_dbg_print(PFX_PSM "%s: " fmt, __FUNCTION__ ,##arg);}
12 #define STP_PSM_DBG_FUNC(fmt, arg...) if(gPsmDbgLevel >= STP_PSM_LOG_DBG){ osal_dbg_print(PFX_PSM "%s: " fmt, __FUNCTION__ ,##arg);}
13 #define STP_PSM_INFO_FUNC(fmt, arg...) if(gPsmDbgLevel >= STP_PSM_LOG_INFO){ osal_dbg_print(PFX_PSM "[I]%s: " fmt, __FUNCTION__ ,##arg);}
14 #define STP_PSM_WARN_FUNC(fmt, arg...) if(gPsmDbgLevel >= STP_PSM_LOG_WARN){ osal_dbg_print(PFX_PSM "[W]%s: " fmt, __FUNCTION__ ,##arg);}
15 #define STP_PSM_ERR_FUNC(fmt, arg...) if(gPsmDbgLevel >= STP_PSM_LOG_ERR){ osal_dbg_print(PFX_PSM "[E]%s(%d):ERROR! " fmt, __FUNCTION__ , __LINE__, ##arg);}
16 #define STP_PSM_TRC_FUNC(f) if(gPsmDbgLevel >= STP_PSM_LOG_DBG){ osal_dbg_print(PFX_PSM "<%s> <%d>\n", __FUNCTION__, __LINE__);}
18 static inline INT32 _stp_psm_notify_wmt(MTKSTP_PSM_T *stp_psm, const MTKSTP_PSM_ACTION_T action);
19 static INT32 _stp_psm_thread_lock_aquire(MTKSTP_PSM_T *stp_psm);
20 static INT32 _stp_psm_thread_lock_release(MTKSTP_PSM_T *stp_psm);
22 static const PCHAR g_psm_state[STP_PSM_MAX_STATE] = {
29 static const PCHAR g_psm_action[STP_PSM_MAX_ACTION] = {
37 static const PCHAR g_psm_op_name[STP_OPID_PSM_NUM] = {
39 "STP_OPID_PSM_WAKEUP",
40 "STP_OPID_PSM_HOST_AWAKE",
44 INT32 _stp_psm_release_data(MTKSTP_PSM_T *stp_psm);
46 static inline INT32 _stp_psm_get_state(MTKSTP_PSM_T *stp_psm);
48 static INT32 _stp_psm_is_redundant_active_op(
53 static INT32 _stp_psm_clean_up_redundant_active_op(
56 static MTK_WCN_BOOL _stp_psm_is_quick_ps_support (VOID);
57 extern void mt_combo_plt_enter_deep_idle (
61 extern void mt_combo_plt_exit_deep_idle (
64 MTK_WCN_BOOL mtk_wcn_stp_psm_dbg_level(UINT32 dbglevel)
66 if (0 <= dbglevel && dbglevel <= 4)
68 gPsmDbgLevel = dbglevel;
69 STP_PSM_INFO_FUNC("gPsmDbgLevel = %d\n", gPsmDbgLevel);
74 STP_PSM_INFO_FUNC("invalid psm debug level. gPsmDbgLevel = %d\n", gPsmDbgLevel);
79 /* change from macro to static function to enforce type checking on parameters. */
80 static INT32 psm_fifo_lock_init (MTKSTP_PSM_T *psm)
84 #if CFG_PSM_CORE_FIFO_SPIN_LOCK
85 #if defined(CONFIG_PROVE_LOCKING)
86 osal_unsleepable_lock_init(&(psm->hold_fifo_lock));
89 return osal_unsleepable_lock_init(&(psm->hold_fifo_lock));
92 #if defined(CONFIG_PROVE_LOCKING)
93 osal_sleepable_lock_init(&(psm->hold_fifo_lock));
96 return osal_sleepable_lock_init(&(psm->hold_fifo_lock));
101 static INT32 psm_fifo_lock_deinit (MTKSTP_PSM_T *psm)
103 #if CFG_PSM_CORE_FIFO_SPIN_LOCK
104 return osal_unsleepable_lock_deinit(&(psm->hold_fifo_lock));
106 return osal_sleepable_lock_deinit(&(psm->hold_fifo_lock));
110 static INT32 psm_fifo_lock (MTKSTP_PSM_T *psm)
114 #if CFG_PSM_CORE_FIFO_SPIN_LOCK
115 return osal_lock_unsleepable_lock(&(psm->hold_fifo_lock));
117 return osal_lock_sleepable_lock(&(psm->hold_fifo_lock));
121 static INT32 psm_fifo_unlock (MTKSTP_PSM_T *psm)
125 #if CFG_PSM_CORE_FIFO_SPIN_LOCK
126 return osal_unlock_unsleepable_lock(&(psm->hold_fifo_lock));
128 return osal_unlock_sleepable_lock(&(psm->hold_fifo_lock));
132 static INT32 _stp_psm_handler(MTKSTP_PSM_T *stp_psm, P_STP_OP pStpOp)
136 //if (NULL == pStpOp)
140 ret = _stp_psm_thread_lock_aquire(stp_psm);
142 STP_PSM_ERR_FUNC("--->lock psm_thread_lock failed ret=%d\n", ret);
148 case STP_OPID_PSM_EXIT:
149 // TODO: clean all up?
153 case STP_OPID_PSM_SLEEP:
154 if (stp_psm_check_sleep_enable(stp_psm) > 0) {
155 ret =_stp_psm_notify_wmt(stp_psm, SLEEP);
157 STP_PSM_INFO_FUNC("cancel sleep request\n");
161 case STP_OPID_PSM_WAKEUP:
162 ret = _stp_psm_notify_wmt(stp_psm, WAKEUP);
165 case STP_OPID_PSM_HOST_AWAKE:
166 ret = _stp_psm_notify_wmt(stp_psm, HOST_AWAKE);
170 STP_PSM_ERR_FUNC("invalid operation id (%d)\n", pStpOp->opId);
174 _stp_psm_thread_lock_release(stp_psm);
178 static P_OSAL_OP _stp_psm_get_op (
179 MTKSTP_PSM_T *stp_psm,
187 STP_PSM_WARN_FUNC("pOpQ == NULL\n");
191 osal_lock_unsleepable_lock(&(stp_psm->wq_spinlock));
192 /* acquire lock success */
195 if((pOpQ == &stp_psm->rActiveOpQ) && (NULL != pOp))
197 //stp_psm->current_active_op = pOp;//*(pOp);
198 stp_psm->last_active_opId = pOp->op.opId;
200 osal_unlock_unsleepable_lock(&(stp_psm->wq_spinlock));
202 if((pOpQ == &stp_psm->rActiveOpQ) && (NULL != pOp))
204 STP_PSM_DBG_FUNC("last_active_opId(%d)\n", stp_psm->last_active_opId);
209 STP_PSM_WARN_FUNC("RB_GET fail\n");
215 static INT32 _stp_psm_dump_active_q(
223 if(pOpQ == &stp_psm->rActiveOpQ)
225 read_idx = stp_psm->rActiveOpQ.read;
226 write_idx = stp_psm->rActiveOpQ.write;
228 STP_PSM_DBG_FUNC("Active op list:++\n");
229 while ((read_idx & RB_MASK(pOpQ)) != (write_idx & RB_MASK(pOpQ)))
231 opId = pOpQ->queue[read_idx & RB_MASK(pOpQ)]->op.opId;
232 if(opId < STP_OPID_PSM_NUM)
234 STP_PSM_DBG_FUNC("%s\n", g_psm_op_name[opId] );
238 STP_PSM_WARN_FUNC("Unkown OP Id\n");
242 STP_PSM_DBG_FUNC("Active op list:--\n");
246 STP_PSM_DBG_FUNC("%s: not active queue, dont dump\n", __func__);
252 static INT32 _stp_psm_is_redundant_active_op(
258 UINT32 prev_opId = 0;
260 //if((pOpQ == &stp_psm->rActiveOpQ) && (NULL != stp_psm->current_active_op))
261 if((pOpQ == &stp_psm->rActiveOpQ) && (STP_OPID_PSM_INALID != stp_psm->last_active_opId))
266 if(opId == STP_OPID_PSM_SLEEP)
270 //prev_opId = stp_psm->current_active_op->op.opId;
271 prev_opId = stp_psm->last_active_opId;
275 prev_opId = pOpQ->queue[(pOpQ->write - 1) & RB_MASK(pOpQ)]->op.opId;
278 if(prev_opId == STP_OPID_PSM_SLEEP)
280 STP_PSM_DBG_FUNC("redundant sleep opId found\n");
292 //prev_opId = stp_psm->current_active_op->op.opId;
293 prev_opId = stp_psm->last_active_opId;
297 prev_opId = pOpQ->queue[(pOpQ->write - 1) & RB_MASK(pOpQ)]->op.opId;
300 if(((opId== STP_OPID_PSM_WAKEUP) && ( prev_opId == STP_OPID_PSM_WAKEUP)) ||
301 ((opId == STP_OPID_PSM_HOST_AWAKE) && ( prev_opId == STP_OPID_PSM_WAKEUP)) ||
302 ((opId == STP_OPID_PSM_HOST_AWAKE) && ( prev_opId == STP_OPID_PSM_HOST_AWAKE)) ||
303 ((opId == STP_OPID_PSM_WAKEUP) && ( prev_opId == STP_OPID_PSM_HOST_AWAKE))
306 STP_PSM_DBG_FUNC("redundant opId found, opId(%d), preOpid(%d)\n", opId, prev_opId);
322 static INT32 _stp_psm_clean_up_redundant_active_op(
326 UINT32 prev_opId = 0;
327 UINT32 prev_prev_opId = 0;
330 P_OSAL_OP_Q pFreeOpQ= &stp_psm->rFreeOpQ;
332 if(pOpQ == &stp_psm->rActiveOpQ)
334 // sleep , wakeup | sleep, --> null | sleep (x)
335 // wakeup , sleep , wakeup | sleep --> wakeup | sleep (v)
336 // sleep , wakeup , sleep | wakeup --> sleep | wakeup (v)
337 // xxx, sleep | sleep --> xxx, sleep (v)
338 // xxx, wakeup | wakeup --> xxx, wakeup (v)
339 // xxx, awake | awake --> xxx, awake (v) --> should never happen
340 while(RB_COUNT(pOpQ) > 2)
342 prev_opId = pOpQ->queue[(pOpQ->write - 1) & RB_MASK(pOpQ)]->op.opId;
343 prev_prev_opId = pOpQ->queue[(pOpQ->write - 2) & RB_MASK(pOpQ)]->op.opId;
345 if((prev_opId == STP_OPID_PSM_SLEEP && prev_prev_opId == STP_OPID_PSM_WAKEUP)||
346 (prev_opId == STP_OPID_PSM_SLEEP && prev_prev_opId == STP_OPID_PSM_HOST_AWAKE) ||
347 (prev_opId == STP_OPID_PSM_WAKEUP&& prev_prev_opId == STP_OPID_PSM_SLEEP) ||
348 (prev_opId == STP_OPID_PSM_HOST_AWAKE&& prev_prev_opId == STP_OPID_PSM_SLEEP)
352 RB_PUT(pFreeOpQ, pOp);
354 RB_PUT(pFreeOpQ, pOp);
356 else if (prev_opId == prev_prev_opId)
359 STP_PSM_DBG_FUNC("redundant opId(%d) found, remove it\n", pOp->op.opId);
360 RB_PUT(pFreeOpQ, pOp);
368 static INT32 _stp_psm_put_op (
369 MTKSTP_PSM_T *stp_psm,
376 // if (!pOpQ || !pOp)
378 // STP_PSM_WARN_FUNC("pOpQ = 0x%p, pLxOp = 0x%p \n", pOpQ, pOp);
383 osal_lock_unsleepable_lock(&(stp_psm->wq_spinlock));
384 /* acquire lock success */
385 if(pOpQ == &stp_psm->rActiveOpQ)
387 if(!_stp_psm_is_redundant_active_op(pOp, pOpQ))
389 /* acquire lock success */
393 STP_PSM_DBG_FUNC("opId(%d) enqueue\n", pOp->op.opId);
397 STP_PSM_INFO_FUNC("************ Active Queue Full ************\n");
401 _stp_psm_clean_up_redundant_active_op(pOpQ);
405 /*redundant opId, mark ret as success*/
406 P_OSAL_OP_Q pFreeOpQ = &stp_psm->rFreeOpQ;
407 if (!RB_FULL(pFreeOpQ))
409 RB_PUT(pFreeOpQ, pOp);
413 osal_assert(!RB_FULL(pFreeOpQ));
430 if(pOpQ == &stp_psm->rActiveOpQ)
432 _stp_psm_dump_active_q(&stp_psm->rActiveOpQ);
435 osal_unlock_unsleepable_lock(&(stp_psm->wq_spinlock));
439 STP_PSM_WARN_FUNC("RB_FULL, RB_COUNT=%d , RB_SIZE=%d\n",RB_COUNT(pOpQ), RB_SIZE(pOpQ));
448 P_OSAL_OP _stp_psm_get_free_op (
449 MTKSTP_PSM_T *stp_psm
456 pOp = _stp_psm_get_op(stp_psm, &stp_psm->rFreeOpQ);
459 osal_memset(&pOp->op, 0, sizeof(pOp->op));
469 INT32 _stp_psm_put_act_op (
470 MTKSTP_PSM_T *stp_psm,
474 INT32 bRet = 0;//MTK_WCN_BOOL_FALSE;
475 INT32 bCleanup = 0;//MTK_WCN_BOOL_FALSE;
477 P_OSAL_SIGNAL pSignal = NULL;
481 if (!stp_psm || !pOp)
483 STP_PSM_ERR_FUNC("stp_psm = %p, pOp = %p\n", stp_psm, pOp);
487 pSignal = &pOp->signal;
489 if (pSignal->timeoutValue)
492 osal_signal_init(&pOp->signal);
495 /* put to active Q */
496 bRet = _stp_psm_put_op(stp_psm, &stp_psm->rActiveOpQ, pOp);
500 STP_PSM_WARN_FUNC("+++++++++++ Put op Active queue Fail\n");
501 bCleanup = 1;//MTK_WCN_BOOL_TRUE;
506 osal_trigger_event(&stp_psm->STPd_event);
508 if (pSignal->timeoutValue == 0)
510 bRet = 1;//MTK_WCN_BOOL_TRUE;
511 /* clean it in wmtd */
515 /* wait result, clean it here */
516 bCleanup = 1;//MTK_WCN_BOOL_TRUE;
519 wait_ret = osal_wait_for_signal_timeout(&pOp->signal);
520 STP_PSM_DBG_FUNC("wait completion:%d\n", wait_ret);
523 STP_PSM_ERR_FUNC("wait completion timeout \n");
524 // TODO: how to handle it? retry?
530 STP_PSM_WARN_FUNC("op(%d) result:%d\n", pOp->op.opId, pOp->result);
532 /* op completes, check result */
533 bRet = (pOp->result) ? 0 : 1;
538 /* put Op back to freeQ */
539 bRet = _stp_psm_put_op(stp_psm, &stp_psm->rFreeOpQ, pOp);
542 STP_PSM_WARN_FUNC("+++++++++++ Put op active free fail, maybe disable/enable psm\n");
549 static INT32 _stp_psm_wait_for_msg(void *pvData)
551 MTKSTP_PSM_T *stp_psm = (MTKSTP_PSM_T *)pvData;
552 STP_PSM_DBG_FUNC("%s: stp_psm->rActiveOpQ = %d\n", __func__, RB_COUNT(&stp_psm->rActiveOpQ));
554 return ((!RB_EMPTY(&stp_psm->rActiveOpQ)) || osal_thread_should_stop(&stp_psm->PSMd));
557 static INT32 _stp_psm_proc (void *pvData)
559 MTKSTP_PSM_T *stp_psm = (MTKSTP_PSM_T *)pvData;
565 STP_PSM_WARN_FUNC("!stp_psm \n");
569 // STP_PSM_INFO_FUNC("wmtd starts running: pWmtDev(0x%p) [pol, rt_pri, n_pri, pri]=[%d, %d, %d, %d] \n",
570 // stp_psm, current->policy, current->rt_priority, current->normal_prio, current->prio);
576 osal_wait_for_event(&stp_psm->STPd_event,
577 _stp_psm_wait_for_msg,
580 //we set reset flag when calling stp_reset after cleanup all op.
581 if(stp_psm->flag & STP_PSM_RESET_EN)
583 stp_psm->flag &= ~STP_PSM_RESET_EN;
586 if (osal_thread_should_stop(&stp_psm->PSMd))
588 STP_PSM_INFO_FUNC("should stop now... \n");
589 // TODO: clean up active opQ
593 /* get Op from activeQ */
594 pOp = _stp_psm_get_op(stp_psm, &stp_psm->rActiveOpQ);
597 STP_PSM_WARN_FUNC("+++++++++++ Get op from activeQ fail, maybe disable/enable psm\n");
601 id = osal_op_get_id(pOp);
603 if (id >= STP_OPID_PSM_NUM)
605 STP_PSM_WARN_FUNC("abnormal opid id: 0x%x \n", id);
610 result = _stp_psm_handler(stp_psm, &pOp->op);
616 STP_PSM_WARN_FUNC("opid id(0x%x)(%s) error(%d)\n", id, (id >= 4)?("???"):(g_psm_op_name[id]), result);
619 if (osal_op_is_wait_for_signal(pOp))
621 osal_op_raise_signal(pOp, result);
625 /* put Op back to freeQ */
626 if(_stp_psm_put_op(stp_psm, &stp_psm->rFreeOpQ, pOp) == 0)
628 STP_PSM_WARN_FUNC("+++++++++++ Put op to FreeOpQ fail, maybe disable/enable psm\n");
632 if (STP_OPID_PSM_EXIT == id)
637 STP_PSM_INFO_FUNC("exits \n");
642 static inline INT32 _stp_psm_get_time(void)
644 if(gPsmDbgLevel >= STP_PSM_LOG_LOUD)
646 osal_printtimeofday("<psm time>>>>");
652 static inline INT32 _stp_psm_get_state(MTKSTP_PSM_T *stp_psm)
657 return STP_PSM_OPERATION_FAIL;
661 if(stp_psm->work_state < STP_PSM_MAX_STATE)
663 return stp_psm->work_state;
667 STP_PSM_ERR_FUNC("work_state = %d, invalid\n", stp_psm->work_state);
669 return -STP_PSM_OPERATION_FAIL;
674 static inline INT32 _stp_psm_set_state(MTKSTP_PSM_T *stp_psm,const MTKSTP_PSM_STATE_T state)
678 return STP_PSM_OPERATION_FAIL;
682 if(stp_psm->work_state < STP_PSM_MAX_STATE)
685 //STP_PSM_INFO_FUNC("work_state = %s --> %s\n", g_psm_state[stp_psm->work_state], g_psm_state[state]);
687 stp_psm->work_state = state;
688 if(stp_psm->work_state != ACT)
690 // osal_lock_unsleepable_lock(&stp_psm->flagSpinlock);
691 stp_psm->flag |= STP_PSM_BLOCK_DATA_EN;
692 // osal_unlock_unsleepable_lock(&stp_psm->flagSpinlock);
697 STP_PSM_ERR_FUNC("work_state = %d, invalid\n", stp_psm->work_state);
701 return STP_PSM_OPERATION_SUCCESS;
704 static inline INT32 _stp_psm_start_monitor(MTKSTP_PSM_T *stp_psm)
709 return STP_PSM_OPERATION_FAIL;
712 if((stp_psm->flag & STP_PSM_WMT_EVENT_DISABLE_MONITOR)!= 0)
714 STP_PSM_DBG_FUNC("STP-PSM DISABLE, DONT restart monitor!\n\r");
715 return STP_PSM_OPERATION_SUCCESS;
719 STP_PSM_LOUD_FUNC("start monitor\n");
720 osal_timer_modify(&stp_psm->psm_timer, stp_psm->idle_time_to_sleep);
722 return STP_PSM_OPERATION_SUCCESS;
725 static inline INT32 _stp_psm_stop_monitor(MTKSTP_PSM_T *stp_psm)
730 return STP_PSM_OPERATION_FAIL;
734 STP_PSM_DBG_FUNC("stop monitor\n");
735 osal_timer_stop_sync(&stp_psm->psm_timer);
738 return STP_PSM_OPERATION_SUCCESS;
743 MTKSTP_PSM_T *stp_psm,
749 INT32 available_space = 0;
750 INT32 needed_space = 0;
751 UINT8 delimiter [] = {0xbb, 0xbb};
755 return STP_PSM_OPERATION_FAIL;
759 psm_fifo_lock(stp_psm);
761 available_space = STP_PSM_FIFO_SIZE- osal_fifo_len(&stp_psm->hold_fifo);
762 needed_space = len + sizeof(UINT8) + sizeof(UINT32) + 2;
764 //STP_PSM_INFO_FUNC("*******FIFO Available(%d), Need(%d)\n", available_space, needed_space);
766 if( available_space < needed_space )
768 STP_PSM_ERR_FUNC("FIFO Available!! Reset FIFO\n");
769 osal_fifo_reset(&stp_psm->hold_fifo);
772 osal_fifo_in(&stp_psm->hold_fifo,(UINT8 *) &type , sizeof(UINT8));
774 osal_fifo_in(&stp_psm->hold_fifo,(UINT8 *) &len , sizeof(UINT32));
776 osal_fifo_in(&stp_psm->hold_fifo,(UINT8 *) buffer, len);
778 osal_fifo_in(&stp_psm->hold_fifo,(UINT8 *) delimiter, 2);
780 psm_fifo_unlock(stp_psm);
786 INT32 _stp_psm_has_pending_data(MTKSTP_PSM_T *stp_psm)
788 return osal_fifo_len(&stp_psm->hold_fifo);
791 INT32 _stp_psm_release_data(MTKSTP_PSM_T *stp_psm)
794 INT32 i = 20; /*Max buffered packet number*/
800 //STP_PSM_ERR_FUNC("++++++++++release data++len=%d\n", osal_fifo_len(&stp_psm->hold_fifo));
801 while(osal_fifo_len(&stp_psm->hold_fifo) && i > 0)
804 psm_fifo_lock(stp_psm);
806 ret = osal_fifo_out(&stp_psm->hold_fifo, (UINT8 *)&type, sizeof(UINT8));
807 ret = osal_fifo_out(&stp_psm->hold_fifo, (UINT8 *)&len, sizeof(UINT32));
809 if(len > STP_PSM_PACKET_SIZE_MAX)
811 STP_PSM_ERR_FUNC("***psm packet's length too Long!****\n");
812 STP_PSM_INFO_FUNC("***reset psm's fifo***\n");
816 osal_memset(stp_psm->out_buf, 0, STP_PSM_TX_SIZE);
817 ret = osal_fifo_out(&stp_psm->hold_fifo, (UINT8 *)stp_psm->out_buf, len);
820 ret = osal_fifo_out(&stp_psm->hold_fifo, (UINT8 *)delimiter, 2);
822 if(delimiter[0]==0xbb && delimiter[1]==0xbb)
824 //osal_buffer_dump(stp_psm->out_buf, "psm->out_buf", len, 32);
825 stp_send_data_no_ps(stp_psm->out_buf, len, type);
829 STP_PSM_ERR_FUNC("***psm packet fifo parsing fail****\n");
830 STP_PSM_INFO_FUNC("***reset psm's fifo***\n");
832 osal_fifo_reset(&stp_psm->hold_fifo);
835 psm_fifo_unlock(stp_psm);
837 return STP_PSM_OPERATION_SUCCESS;
840 static inline INT32 _stp_psm_notify_wmt_host_awake_wq(MTKSTP_PSM_T *stp_psm)
849 return STP_PSM_OPERATION_FAIL;
853 pOp = _stp_psm_get_free_op(stp_psm);
856 STP_PSM_WARN_FUNC("get_free_lxop fail \n");
860 pOp->op.opId = STP_OPID_PSM_HOST_AWAKE;
861 pOp->signal.timeoutValue = 0;
862 bRet = _stp_psm_put_act_op(stp_psm, pOp);
864 STP_PSM_DBG_FUNC("OPID(%d) type(%d) bRet(%d) \n\n",
866 pOp->op.au4OpData[0],
869 retval = (0 == bRet) ? (STP_PSM_OPERATION_FAIL) : 0;
874 static inline INT32 _stp_psm_notify_wmt_wakeup_wq(MTKSTP_PSM_T *stp_psm)
882 return (STP_PSM_OPERATION_FAIL);
886 pOp = _stp_psm_get_free_op(stp_psm);
889 STP_PSM_WARN_FUNC("get_free_lxop fail \n");
893 pOp->op.opId = STP_OPID_PSM_WAKEUP;
894 pOp->signal.timeoutValue = 0;
895 bRet = _stp_psm_put_act_op(stp_psm, pOp);
898 STP_PSM_WARN_FUNC("OPID(%d) type(%d) bRet(%s)\n\n",
900 pOp->op.au4OpData[0],
903 retval = (0 == bRet) ? (STP_PSM_OPERATION_FAIL) : (STP_PSM_OPERATION_SUCCESS);
908 static inline INT32 _stp_psm_notify_wmt_sleep_wq(MTKSTP_PSM_T *stp_psm)
916 return STP_PSM_OPERATION_FAIL;
920 if((stp_psm->flag & STP_PSM_WMT_EVENT_DISABLE_MONITOR_TX_HIGH_DENSITY) != 0)
925 if((stp_psm->flag & STP_PSM_WMT_EVENT_DISABLE_MONITOR_RX_HIGH_DENSITY) != 0)
930 if((stp_psm->flag & STP_PSM_WMT_EVENT_DISABLE_MONITOR) != 0)
935 pOp = _stp_psm_get_free_op(stp_psm);
937 STP_PSM_WARN_FUNC("get_free_lxop fail \n");
941 pOp->op.opId = STP_OPID_PSM_SLEEP;
942 pOp->signal.timeoutValue = 0;
943 bRet = _stp_psm_put_act_op(stp_psm, pOp);
945 STP_PSM_DBG_FUNC("OPID(%d) type(%d) bRet(%d) \n\n",
947 pOp->op.au4OpData[0],
950 retval = (0 == bRet) ? (STP_PSM_OPERATION_FAIL) : 0;
955 /*internal function*/
957 static inline INT32 _stp_psm_reset(MTKSTP_PSM_T *stp_psm)
964 STP_PSM_DBG_FUNC("PSM MODE RESET=============================>\n\r");
966 STP_PSM_INFO_FUNC("_stp_psm_reset\n");
967 STP_PSM_INFO_FUNC("reset-wake_lock(%d)\n", osal_wake_lock_count(&stp_psm->wake_lock));
968 osal_wake_unlock(&stp_psm->wake_lock);
969 STP_PSM_INFO_FUNC("reset-wake_lock(%d)\n", osal_wake_lock_count(&stp_psm->wake_lock));
971 //--> serialized the request from wmt <--//
972 ret = osal_lock_sleepable_lock(&stp_psm->user_lock);
974 STP_PSM_ERR_FUNC("--->lock stp_psm->user_lock failed, ret=%d\n", ret);
978 //--> disable psm <--//
979 stp_psm->flag = STP_PSM_WMT_EVENT_DISABLE_MONITOR;
980 _stp_psm_stop_monitor(stp_psm);
982 //--> prepare the op list <--//
983 osal_lock_unsleepable_lock(&(stp_psm->wq_spinlock));
984 RB_INIT(&stp_psm->rFreeOpQ, STP_OP_BUF_SIZE);
985 RB_INIT(&stp_psm->rActiveOpQ, STP_OP_BUF_SIZE);
987 //stp_psm->current_active_op = NULL;
988 stp_psm->last_active_opId = STP_OPID_PSM_INALID;
990 pOpQ = &stp_psm->rFreeOpQ;
991 for (i = 0; i < STP_OP_BUF_SIZE; i++)
995 pOp = &stp_psm->arQue[i];
999 osal_unlock_unsleepable_lock(&(stp_psm->wq_spinlock));
1001 //--> clean up interal data structure<--//
1002 _stp_psm_set_state(stp_psm, ACT);
1004 psm_fifo_lock(stp_psm);
1005 osal_fifo_reset(&stp_psm->hold_fifo);
1006 psm_fifo_unlock(stp_psm);
1008 //--> stop psm thread wait <--//
1009 stp_psm->flag |= STP_PSM_RESET_EN;
1010 osal_trigger_event(&stp_psm->wait_wmt_q);
1012 osal_unlock_sleepable_lock(&stp_psm->user_lock);
1014 STP_PSM_DBG_FUNC("PSM MODE RESET<============================\n\r");
1016 return STP_PSM_OPERATION_SUCCESS;
1019 static INT32 _stp_psm_wait_wmt_event(void *pvData)
1021 MTKSTP_PSM_T *stp_psm = (MTKSTP_PSM_T *)pvData;
1023 STP_PSM_DBG_FUNC("%s, stp_psm->flag=0x%08x\n", __func__, stp_psm->flag);
1025 return ((stp_psm->flag & STP_PSM_WMT_EVENT_SLEEP_EN) ||
1026 (stp_psm->flag & STP_PSM_WMT_EVENT_WAKEUP_EN) ||
1027 (stp_psm->flag & STP_PSM_WMT_EVENT_ROLL_BACK_EN) ||
1028 (stp_psm->flag & STP_PSM_RESET_EN));
1032 static inline INT32 _stp_psm_wait_wmt_event_wq(MTKSTP_PSM_T *stp_psm){
1038 return STP_PSM_OPERATION_FAIL;
1042 osal_wait_for_event_timeout(&stp_psm->wait_wmt_q,
1043 _stp_psm_wait_wmt_event,
1046 if(stp_psm->flag & STP_PSM_WMT_EVENT_WAKEUP_EN)
1048 stp_psm->flag &= ~STP_PSM_WMT_EVENT_WAKEUP_EN;
1049 // osal_lock_unsleepable_lock(&stp_psm->flagSpinlock);
1050 //STP send data here: STP enqueue data to psm buffer.
1051 _stp_psm_release_data(stp_psm);
1052 //STP send data here: STP enqueue data to psm buffer. We release packet by the next one.
1053 stp_psm->flag &= ~STP_PSM_BLOCK_DATA_EN;
1054 //STP send data here: STP sends data directly without PSM.
1055 _stp_psm_set_state(stp_psm, ACT);
1056 // osal_unlock_unsleepable_lock(&stp_psm->flagSpinlock);
1058 if (stp_psm_is_quick_ps_support())
1059 stp_psm_notify_wmt_sleep(stp_psm);
1061 _stp_psm_start_monitor(stp_psm);
1063 else if ( stp_psm->flag & STP_PSM_WMT_EVENT_SLEEP_EN)
1065 stp_psm->flag &= ~STP_PSM_WMT_EVENT_SLEEP_EN;
1066 _stp_psm_set_state(stp_psm, INACT);
1068 STP_PSM_DBG_FUNC("mt_combo_plt_enter_deep_idle++\n");
1069 mt_combo_plt_enter_deep_idle(COMBO_IF_UART);
1070 STP_PSM_DBG_FUNC("mt_combo_plt_enter_deep_idle--\n");
1072 STP_PSM_DBG_FUNC("sleep-wake_lock(%d)\n", osal_wake_lock_count(&stp_psm->wake_lock));
1073 osal_wake_unlock(&stp_psm->wake_lock);
1074 STP_PSM_DBG_FUNC("sleep-wake_lock#(%d)\n", osal_wake_lock_count(&stp_psm->wake_lock));
1076 else if ( stp_psm->flag & STP_PSM_WMT_EVENT_ROLL_BACK_EN)
1078 stp_psm->flag &= ~STP_PSM_WMT_EVENT_ROLL_BACK_EN;
1079 if(_stp_psm_get_state(stp_psm) == ACT_INACT){
1080 // osal_lock_unsleepable_lock(&stp_psm->flagSpinlock);
1081 _stp_psm_release_data(stp_psm);
1082 stp_psm->flag &= ~STP_PSM_BLOCK_DATA_EN;
1083 _stp_psm_set_state(stp_psm, ACT);
1084 // osal_unlock_unsleepable_lock(&stp_psm->flagSpinlock);
1085 } else if(_stp_psm_get_state(stp_psm) == INACT_ACT) {
1086 _stp_psm_set_state(stp_psm, INACT);
1087 STP_PSM_INFO_FUNC("[WARNING]PSM state rollback due too wakeup fail\n");
1090 else if (stp_psm->flag & STP_PSM_RESET_EN)
1092 stp_psm->flag &= ~STP_PSM_WMT_EVENT_ROLL_BACK_EN;
1096 STP_PSM_ERR_FUNC("flag = %x<== Abnormal flag be set!!\n\r", stp_psm->flag);
1097 STP_PSM_ERR_FUNC("state = %d, flag = %d\n", stp_psm->work_state, stp_psm->flag);
1099 retval = STP_PSM_OPERATION_SUCCESS;
1104 static inline INT32 _stp_psm_notify_stp(MTKSTP_PSM_T *stp_psm, const MTKSTP_PSM_ACTION_T action){
1110 STP_PSM_DBG_FUNC("Call _stp_psm_notify_wmt_host_awake_wq\n\r");
1112 _stp_psm_notify_wmt_host_awake_wq(stp_psm);
1114 return STP_PSM_OPERATION_FAIL;
1117 if((_stp_psm_get_state(stp_psm) < STP_PSM_MAX_STATE) && (_stp_psm_get_state(stp_psm) >= 0))
1119 STP_PSM_DBG_FUNC("state = %s, action=%s \n\r", g_psm_state[_stp_psm_get_state(stp_psm)], g_psm_action[action]);
1122 // If STP trigger WAKEUP and SLEEP, to do the job below
1123 switch(_stp_psm_get_state(stp_psm))
1130 STP_PSM_LOUD_FUNC("Action = %s, ACT_INACT state, ready to INACT\n\r", g_psm_action[action]);
1131 stp_psm->flag &= ~STP_PSM_WMT_EVENT_WAKEUP_EN;
1132 stp_psm->flag |= STP_PSM_WMT_EVENT_SLEEP_EN;
1134 //wake_up(&stp_psm->wait_wmt_q);
1135 osal_trigger_event(&stp_psm->wait_wmt_q);
1137 else if(action == ROLL_BACK)
1139 STP_PSM_LOUD_FUNC("Action = %s, ACT_INACT state, back to ACT\n\r", g_psm_action[action]);
1140 //stp_psm->flag &= ~STP_PSM_WMT_EVENT_ROLL_BACK_EN;
1141 stp_psm->flag |= STP_PSM_WMT_EVENT_ROLL_BACK_EN;
1142 //wake_up(&stp_psm->wait_wmt_q);
1143 osal_trigger_event(&stp_psm->wait_wmt_q);
1147 if(action < STP_PSM_MAX_ACTION)
1149 STP_PSM_ERR_FUNC("Action = %s, ACT_INACT state, the case should not happens\n\r", g_psm_action[action]);
1150 STP_PSM_ERR_FUNC("state = %d, flag = %d\n", stp_psm->work_state, stp_psm->flag);
1154 STP_PSM_ERR_FUNC("Invalid Action!!\n\r");
1156 retval = STP_PSM_OPERATION_FAIL;
1163 if(action == WAKEUP)
1165 STP_PSM_LOUD_FUNC("Action = %s, INACT_ACT state, ready to ACT\n\r", g_psm_action[action]);
1166 stp_psm->flag &= ~STP_PSM_WMT_EVENT_SLEEP_EN;
1167 stp_psm->flag |= STP_PSM_WMT_EVENT_WAKEUP_EN;
1168 //wake_up(&stp_psm->wait_wmt_q);
1169 osal_trigger_event(&stp_psm->wait_wmt_q);
1171 else if(action == HOST_AWAKE)
1173 STP_PSM_LOUD_FUNC("Action = %s, INACT_ACT state, ready to ACT\n\r", g_psm_action[action]);
1174 stp_psm->flag &= ~STP_PSM_WMT_EVENT_SLEEP_EN;
1175 stp_psm->flag |= STP_PSM_WMT_EVENT_WAKEUP_EN;
1176 //wake_up(&stp_psm->wait_wmt_q);
1177 osal_trigger_event(&stp_psm->wait_wmt_q);
1179 else if(action == ROLL_BACK)
1181 STP_PSM_LOUD_FUNC("Action = %s, INACT_ACT state, back to INACT\n\r", g_psm_action[action]);
1182 // stp_psm->flag &= ~STP_PSM_WMT_EVENT_ROLL_BACK_EN;
1183 stp_psm->flag |= STP_PSM_WMT_EVENT_ROLL_BACK_EN;
1184 //wake_up(&stp_psm->wait_wmt_q);
1185 osal_trigger_event(&stp_psm->wait_wmt_q);
1189 if(action < STP_PSM_MAX_ACTION)
1191 STP_PSM_ERR_FUNC("Action = %s, INACT_ACT state, the case should not happens\n\r", g_psm_action[action]);
1192 STP_PSM_ERR_FUNC("state = %d, flag = %d\n", stp_psm->work_state, stp_psm->flag);
1196 STP_PSM_ERR_FUNC("Invalid Action!!\n\r");
1198 retval = STP_PSM_OPERATION_FAIL;
1204 if(action < STP_PSM_MAX_ACTION)
1206 STP_PSM_ERR_FUNC("Action = %s, INACT state, the case should not happens\n\r", g_psm_action[action]);
1207 STP_PSM_ERR_FUNC("state = %d, flag = %d\n", stp_psm->work_state, stp_psm->flag);
1211 STP_PSM_ERR_FUNC("Invalid Action!!\n\r");
1220 if(action < STP_PSM_MAX_ACTION)
1222 STP_PSM_ERR_FUNC("Action = %s, ACT state, the case should not happens\n\r", g_psm_action[action]);
1223 STP_PSM_ERR_FUNC("state = %d, flag = %d\n", stp_psm->work_state, stp_psm->flag);
1227 STP_PSM_ERR_FUNC("Invalid Action!!\n\r");
1230 retval = STP_PSM_OPERATION_FAIL;
1237 if(action < STP_PSM_MAX_ACTION)
1239 STP_PSM_ERR_FUNC("Action = %s, Invalid state, the case should not happens\n\r", g_psm_action[action]);
1240 STP_PSM_ERR_FUNC("state = %d, flag = %d\n", stp_psm->work_state, stp_psm->flag);
1244 STP_PSM_ERR_FUNC("Invalid Action!!\n\r");
1247 retval = STP_PSM_OPERATION_FAIL;
1256 static inline INT32 _stp_psm_notify_wmt(MTKSTP_PSM_T *stp_psm, const MTKSTP_PSM_ACTION_T action)
1260 if (stp_psm == NULL)
1262 return STP_PSM_OPERATION_FAIL;
1265 switch(_stp_psm_get_state(stp_psm))
1271 if (stp_psm->flag & STP_PSM_WMT_EVENT_DISABLE_MONITOR) {
1272 STP_PSM_ERR_FUNC("psm monitor disabled, can't do sleep op\n");
1273 return STP_PSM_OPERATION_FAIL;
1276 _stp_psm_set_state(stp_psm, ACT_INACT);
1278 _stp_psm_release_data(stp_psm);
1280 if(stp_psm->wmt_notify)
1282 stp_psm->wmt_notify(SLEEP);
1283 _stp_psm_wait_wmt_event_wq(stp_psm);
1287 STP_PSM_ERR_FUNC("stp_psm->wmt_notify = NULL\n");
1288 ret = STP_PSM_OPERATION_FAIL;
1291 else if(action == WAKEUP || action == HOST_AWAKE)
1293 STP_PSM_INFO_FUNC("In ACT state, dont do WAKEUP/HOST_AWAKE again\n");
1294 _stp_psm_release_data(stp_psm);
1298 STP_PSM_ERR_FUNC("invalid operation, the case should not happen\n");
1299 STP_PSM_ERR_FUNC("state = %d, flag = %d\n", stp_psm->work_state, stp_psm->flag);
1301 ret = STP_PSM_OPERATION_FAIL;
1309 if(action == WAKEUP)
1311 _stp_psm_set_state(stp_psm, INACT_ACT);
1313 if(stp_psm->wmt_notify)
1315 STP_PSM_DBG_FUNC("wakeup +wake_lock(%d)\n", osal_wake_lock_count(&stp_psm->wake_lock));
1316 osal_wake_lock(&stp_psm->wake_lock);
1317 STP_PSM_DBG_FUNC("wakeup +wake_lock(%d)#\n", osal_wake_lock_count(&stp_psm->wake_lock));
1319 STP_PSM_DBG_FUNC("mt_combo_plt_exit_deep_idle++\n");
1320 mt_combo_plt_exit_deep_idle(COMBO_IF_UART);
1321 STP_PSM_DBG_FUNC("mt_combo_plt_exit_deep_idle--\n");
1323 stp_psm->wmt_notify(WAKEUP);
1324 _stp_psm_wait_wmt_event_wq(stp_psm);
1328 STP_PSM_ERR_FUNC("stp_psm->wmt_notify = NULL\n");
1329 ret = STP_PSM_OPERATION_FAIL;
1332 else if(action == HOST_AWAKE)
1334 _stp_psm_set_state(stp_psm, INACT_ACT);
1336 if(stp_psm->wmt_notify)
1338 STP_PSM_DBG_FUNC("host awake +wake_lock(%d)\n", osal_wake_lock_count(&stp_psm->wake_lock));
1339 osal_wake_lock(&stp_psm->wake_lock);
1340 STP_PSM_DBG_FUNC("host awake +wake_lock(%d)#\n", osal_wake_lock_count(&stp_psm->wake_lock));
1342 STP_PSM_DBG_FUNC("mt_combo_plt_exit_deep_idle++\n");
1343 mt_combo_plt_exit_deep_idle(COMBO_IF_UART);
1344 STP_PSM_DBG_FUNC("mt_combo_plt_exit_deep_idle--\n");
1346 stp_psm->wmt_notify(HOST_AWAKE);
1347 _stp_psm_wait_wmt_event_wq(stp_psm);
1351 STP_PSM_ERR_FUNC("stp_psm->wmt_notify = NULL\n");
1352 ret = STP_PSM_OPERATION_FAIL;
1355 else if(action == SLEEP)
1357 STP_PSM_INFO_FUNC("In INACT state, dont do SLEEP again\n");
1361 STP_PSM_ERR_FUNC("invalid operation, the case should not happen\n");
1362 STP_PSM_ERR_FUNC("state = %d, flag = %d\n", stp_psm->work_state, stp_psm->flag);
1363 ret = STP_PSM_OPERATION_FAIL;
1371 STP_PSM_ERR_FUNC("invalid state, the case should not happen\n");
1372 STP_PSM_ERR_FUNC("state = %d, flag = %d\n", stp_psm->work_state, stp_psm->flag);
1373 ret = STP_PSM_OPERATION_FAIL;
1380 static inline void _stp_psm_stp_is_idle(ULONG data)
1382 MTKSTP_PSM_T *stp_psm = (MTKSTP_PSM_T *)data;
1384 stp_psm->flag &= ~STP_PSM_WMT_EVENT_DISABLE_MONITOR_RX_HIGH_DENSITY;
1385 stp_psm->flag &= ~STP_PSM_WMT_EVENT_DISABLE_MONITOR_TX_HIGH_DENSITY;
1387 if((stp_psm->flag & STP_PSM_WMT_EVENT_DISABLE_MONITOR)!= 0)
1389 STP_PSM_DBG_FUNC("STP-PSM DISABLE!\n");
1393 STP_PSM_INFO_FUNC("**IDLE is over %d msec, go to sleep!!!**\n", stp_psm->idle_time_to_sleep);
1394 _stp_psm_notify_wmt_sleep_wq(stp_psm);
1397 static inline INT32 _stp_psm_init_monitor(MTKSTP_PSM_T *stp_psm)
1401 return STP_PSM_OPERATION_FAIL;
1404 STP_PSM_INFO_FUNC("init monitor\n");
1406 stp_psm->psm_timer.timeoutHandler = _stp_psm_stp_is_idle;
1407 stp_psm->psm_timer.timeroutHandlerData = (UINT32)stp_psm;
1408 osal_timer_create(&stp_psm->psm_timer);
1410 return STP_PSM_OPERATION_SUCCESS;
1413 static inline INT32 _stp_psm_deinit_monitor(MTKSTP_PSM_T *stp_psm)
1418 return STP_PSM_OPERATION_FAIL;
1422 STP_PSM_INFO_FUNC("deinit monitor\n");
1424 osal_timer_stop_sync(&stp_psm->psm_timer);
1430 static inline INT32 _stp_psm_is_to_block_traffic(MTKSTP_PSM_T *stp_psm)
1434 // osal_lock_unsleepable_lock(&stp_psm->flagSpinlock);
1436 if(stp_psm->flag & STP_PSM_BLOCK_DATA_EN)
1444 // osal_unlock_unsleepable_lock(&stp_psm->flagSpinlock);
1448 static inline INT32 _stp_psm_is_disable(MTKSTP_PSM_T *stp_psm)
1450 if(stp_psm->flag & STP_PSM_WMT_EVENT_DISABLE_MONITOR)
1460 static inline INT32 _stp_psm_do_wait(MTKSTP_PSM_T *stp_psm, MTKSTP_PSM_STATE_T state){
1462 #define POLL_WAIT 20//200
1463 #define POLL_WAIT_TIME 2000
1466 INT32 limit = POLL_WAIT_TIME/POLL_WAIT;
1468 while(_stp_psm_get_state(stp_psm)!=state && i < limit)
1470 osal_msleep(POLL_WAIT);
1472 STP_PSM_INFO_FUNC("STP is waiting state for %s, i=%d, state = %d\n", g_psm_state[state],i , _stp_psm_get_state(stp_psm));
1477 STP_PSM_WARN_FUNC("-Wait for %s takes %d msec\n", g_psm_state[state], i*POLL_WAIT);
1478 return STP_PSM_OPERATION_FAIL;
1482 STP_PSM_DBG_FUNC("+Total waits for %s takes %d msec\n", g_psm_state[state], i*POLL_WAIT);
1483 return STP_PSM_OPERATION_SUCCESS;
1487 static inline INT32 _stp_psm_do_wakeup(MTKSTP_PSM_T *stp_psm)
1495 STP_PSM_LOUD_FUNC("*** Do Force Wakeup!***\n\r");
1497 //<1>If timer is active, we will stop it.
1498 _stp_psm_stop_monitor(stp_psm);
1500 osal_lock_unsleepable_lock(&(stp_psm->wq_spinlock));
1502 pOpQ = &stp_psm->rFreeOpQ;
1504 while (!RB_EMPTY(&stp_psm->rActiveOpQ))
1506 RB_GET(&stp_psm->rActiveOpQ, pOp);
1507 if (NULL != pOp && !RB_FULL(pOpQ))
1509 STP_PSM_DBG_FUNC("opid = %d\n", pOp->op.opId);
1514 STP_PSM_ERR_FUNC("clear up active queue fail, freeQ full\n");
1517 osal_unlock_unsleepable_lock(&(stp_psm->wq_spinlock));
1518 //<5>We issue wakeup request into op queue. and wait for active.
1520 ret = _stp_psm_notify_wmt_wakeup_wq(stp_psm);
1522 if(ret == STP_PSM_OPERATION_SUCCESS)
1524 ret = _stp_psm_do_wait(stp_psm, ACT);
1526 //STP_PSM_INFO_FUNC("<< wait ret = %d, num of activeQ = %d\n", ret, RB_COUNT(&stp_psm->rActiveOpQ));
1527 if(ret == STP_PSM_OPERATION_SUCCESS)
1534 STP_PSM_ERR_FUNC("_stp_psm_notify_wmt_wakeup_wq fail!!\n");
1537 //STP_PSM_INFO_FUNC("retry = %d\n", retry);
1549 return STP_PSM_OPERATION_FAIL;
1553 return STP_PSM_OPERATION_SUCCESS;
1557 static inline INT32 _stp_psm_disable(MTKSTP_PSM_T *stp_psm)
1559 INT32 ret = STP_PSM_OPERATION_FAIL;
1561 STP_PSM_DBG_FUNC("PSM Disable start\n\r");
1563 ret = osal_lock_sleepable_lock(&stp_psm->user_lock);
1565 STP_PSM_ERR_FUNC("--->lock stp_psm->user_lock failed, ret=%d\n", ret);
1569 stp_psm->flag |= STP_PSM_WMT_EVENT_DISABLE_MONITOR;
1570 ret = _stp_psm_do_wakeup(stp_psm);
1571 osal_unlock_sleepable_lock(&stp_psm->user_lock);
1572 if (ret == STP_PSM_OPERATION_SUCCESS)
1574 STP_PSM_DBG_FUNC("PSM Disable Success\n");
1578 STP_PSM_ERR_FUNC("***PSM Disable Fail***\n");
1584 static inline INT32 _stp_psm_enable(MTKSTP_PSM_T *stp_psm, INT32 idle_time_to_sleep)
1586 INT32 ret = STP_PSM_OPERATION_FAIL;
1587 STP_PSM_LOUD_FUNC("PSM Enable start\n\r");
1589 ret = osal_lock_sleepable_lock(&stp_psm->user_lock);
1591 STP_PSM_ERR_FUNC("--->lock stp_psm->user_lock failed, ret=%d\n", ret);
1595 stp_psm->flag |= STP_PSM_WMT_EVENT_DISABLE_MONITOR;
1597 ret = _stp_psm_do_wakeup(stp_psm);
1598 if(ret == STP_PSM_OPERATION_SUCCESS)
1600 stp_psm->flag &= ~STP_PSM_WMT_EVENT_DISABLE_MONITOR;
1601 stp_psm->idle_time_to_sleep = idle_time_to_sleep;
1603 if(osal_wake_lock_count(&stp_psm->wake_lock) == 0)
1605 STP_PSM_DBG_FUNC("psm_en+wake_lock(%d)\n", osal_wake_lock_count(&stp_psm->wake_lock));
1606 osal_wake_lock(&stp_psm->wake_lock);
1607 STP_PSM_DBG_FUNC("psm_en+wake_lock(%d)#\n", osal_wake_lock_count(&stp_psm->wake_lock));
1610 _stp_psm_start_monitor(stp_psm);
1612 STP_PSM_DBG_FUNC("PSM Enable succeed\n\r");
1616 STP_PSM_ERR_FUNC("***PSM Enable Fail***\n");
1618 osal_unlock_sleepable_lock(&stp_psm->user_lock);
1623 INT32 _stp_psm_thread_lock_aquire(MTKSTP_PSM_T *stp_psm)
1625 return osal_lock_sleepable_lock(&stp_psm->stp_psm_lock);
1628 INT32 _stp_psm_thread_lock_release(MTKSTP_PSM_T *stp_psm)
1630 osal_unlock_sleepable_lock(&stp_psm->stp_psm_lock);
1634 MTK_WCN_BOOL _stp_psm_is_quick_ps_support (VOID)
1636 if (stp_psm->is_wmt_quick_ps_support)
1638 return (*(stp_psm->is_wmt_quick_ps_support))();
1640 STP_PSM_DBG_FUNC("stp_psm->is_wmt_quick_ps_support is NULL, return false\n\r");
1641 return MTK_WCN_BOOL_FALSE;
1645 MTK_WCN_BOOL stp_psm_is_quick_ps_support (VOID)
1647 return _stp_psm_is_quick_ps_support();
1650 INT32 stp_psm_disable_by_tx_rx_density(MTKSTP_PSM_T *stp_psm, INT32 dir){
1652 //easy the variable maintain beween stp tx, rx thread.
1653 //so we create variable for tx, rx respectively.
1655 static INT32 tx_cnt = 0;
1656 static INT32 rx_cnt = 0;
1657 static INT32 is_tx_first = 1;
1658 static INT32 is_rx_first = 1;
1659 static ULONG tx_end_time = 0;
1660 static ULONG rx_end_time = 0;
1663 //BT A2DP TX CNT = 220, RX CNT = 843
1664 //BT FTP Transferring TX CNT = 574, RX CNT = 2233 (1228~1588)
1665 //BT FTP Receiving TX CNT = 204, RX CNT = 3301 (2072~2515)
1666 //BT OPP Tx TX_CNT= 330, RX CNT = 1300~1800
1667 //BT OPP Rx TX_CNT= (109~157), RX CNT = 1681~2436
1672 if(((LONG)jiffies - (LONG)tx_end_time >= 0) || (is_tx_first))
1674 tx_end_time = jiffies + (3*HZ);
1675 STP_PSM_INFO_FUNC("tx cnt = %d in the previous 3 sec\n", tx_cnt);
1676 //if(tx_cnt > 400)//for high traffic , not to do sleep.
1679 stp_psm->flag |= STP_PSM_WMT_EVENT_DISABLE_MONITOR_TX_HIGH_DENSITY;
1680 stp_psm_start_monitor(stp_psm);
1684 stp_psm->flag &= ~STP_PSM_WMT_EVENT_DISABLE_MONITOR_TX_HIGH_DENSITY;
1695 if(((LONG)jiffies - (LONG)rx_end_time >= 0) || (is_rx_first))
1697 rx_end_time = jiffies + (3*HZ);
1698 STP_PSM_INFO_FUNC("rx cnt = %d in the previous 3 sec\n", rx_cnt);
1700 //if(rx_cnt > 2000)//for high traffic , not to do sleep.
1701 if(rx_cnt > 1200)//for high traffic , not to do sleep.
1703 stp_psm->flag |= STP_PSM_WMT_EVENT_DISABLE_MONITOR_RX_HIGH_DENSITY;
1704 stp_psm_start_monitor(stp_psm);
1708 stp_psm->flag &= ~STP_PSM_WMT_EVENT_DISABLE_MONITOR_RX_HIGH_DENSITY;
1719 /*external function for WMT module to do sleep/wakeup*/
1720 INT32 stp_psm_set_state(MTKSTP_PSM_T *stp_psm, MTKSTP_PSM_STATE_T state)
1722 return _stp_psm_set_state(stp_psm, state);
1726 INT32 stp_psm_thread_lock_aquire(MTKSTP_PSM_T *stp_psm)
1728 return _stp_psm_thread_lock_aquire(stp_psm);
1732 INT32 stp_psm_thread_lock_release(MTKSTP_PSM_T *stp_psm)
1734 return _stp_psm_thread_lock_release(stp_psm);
1739 INT32 stp_psm_do_wakeup(MTKSTP_PSM_T *stp_psm)
1741 return _stp_psm_do_wakeup(stp_psm);
1744 INT32 stp_psm_notify_stp(MTKSTP_PSM_T *stp_psm, const MTKSTP_PSM_ACTION_T action)
1747 return _stp_psm_notify_stp(stp_psm, action);
1750 INT32 stp_psm_notify_wmt_wakeup(MTKSTP_PSM_T *stp_psm)
1752 return _stp_psm_notify_wmt_wakeup_wq(stp_psm);
1755 INT32 stp_psm_notify_wmt_sleep(MTKSTP_PSM_T *stp_psm){
1757 return _stp_psm_notify_wmt_sleep_wq(stp_psm);
1760 INT32 stp_psm_start_monitor(MTKSTP_PSM_T *stp_psm)
1762 return _stp_psm_start_monitor(stp_psm);
1765 INT32 stp_psm_is_to_block_traffic(MTKSTP_PSM_T *stp_psm)
1767 return _stp_psm_is_to_block_traffic(stp_psm);
1770 INT32 stp_psm_is_disable(MTKSTP_PSM_T *stp_psm)
1772 return _stp_psm_is_disable(stp_psm);
1775 INT32 stp_psm_has_pending_data(MTKSTP_PSM_T *stp_psm)
1777 return _stp_psm_has_pending_data(stp_psm);
1780 INT32 stp_psm_release_data(MTKSTP_PSM_T *stp_psm)
1782 return _stp_psm_release_data(stp_psm);
1787 MTKSTP_PSM_T *stp_psm,
1788 const UINT8 *buffer,
1793 return _stp_psm_hold_data(stp_psm, buffer, len, type);
1796 INT32 stp_psm_disable(MTKSTP_PSM_T *stp_psm)
1798 return _stp_psm_disable(stp_psm);
1801 INT32 stp_psm_enable(MTKSTP_PSM_T *stp_psm, INT32 idle_time_to_sleep)
1803 return _stp_psm_enable(stp_psm, idle_time_to_sleep);
1806 INT32 stp_psm_reset(MTKSTP_PSM_T *stp_psm)
1808 stp_psm_set_sleep_enable(stp_psm);
1810 return _stp_psm_reset(stp_psm);
1813 INT32 stp_psm_sleep_for_thermal(MTKSTP_PSM_T *stp_psm)
1815 return _stp_psm_notify_wmt_sleep_wq(stp_psm);
1819 INT32 stp_psm_set_sleep_enable(MTKSTP_PSM_T *stp_psm)
1824 stp_psm->sleep_en = 1;
1825 STP_PSM_DBG_FUNC("\n");
1828 STP_PSM_INFO_FUNC("Null pointer\n");
1836 INT32 stp_psm_set_sleep_disable(MTKSTP_PSM_T *stp_psm)
1841 stp_psm->sleep_en = 0;
1842 STP_PSM_DBG_FUNC("\n");
1845 STP_PSM_INFO_FUNC("Null pointer\n");
1853 /* stp_psm_check_sleep_enable - to check if sleep cmd is enabled or not
1854 * @ stp_psm - pointer of psm
1856 * return 1 if sleep is enabled; else return 0 if disabled; else error code
1858 INT32 stp_psm_check_sleep_enable(MTKSTP_PSM_T *stp_psm)
1863 ret = stp_psm->sleep_en;
1864 STP_PSM_DBG_FUNC("%s \n", ret? "enabled" : "disabled");
1866 STP_PSM_INFO_FUNC("Null pointer\n");
1874 MTKSTP_PSM_T *stp_psm_init(void)
1880 STP_PSM_INFO_FUNC("psm init\n");
1882 stp_psm->work_state = ACT;
1883 stp_psm->wmt_notify = wmt_lib_ps_stp_cb;
1884 stp_psm->is_wmt_quick_ps_support = wmt_lib_is_quick_ps_support;
1885 stp_psm->idle_time_to_sleep = STP_PSM_IDLE_TIME_SLEEP;
1887 stp_psm->stp_tx_cb = NULL;
1888 stp_psm_set_sleep_enable(stp_psm);
1890 ret = osal_fifo_init(&stp_psm->hold_fifo, NULL, STP_PSM_FIFO_SIZE);
1893 STP_PSM_ERR_FUNC("FIFO INIT FAILS\n");
1897 osal_fifo_reset(&stp_psm->hold_fifo);
1898 osal_sleepable_lock_init(&stp_psm->user_lock);
1899 psm_fifo_lock_init(stp_psm);
1900 osal_unsleepable_lock_init(&stp_psm->wq_spinlock);
1901 osal_sleepable_lock_init(&stp_psm->stp_psm_lock);
1903 // osal_unsleepable_lock_init(&stp_psm->flagSpinlock);
1905 osal_memcpy(stp_psm->wake_lock.name, "MT662x", 6);
1906 osal_wake_lock_init(&stp_psm->wake_lock);
1908 osal_event_init(&stp_psm->STPd_event);
1909 RB_INIT(&stp_psm->rFreeOpQ, STP_OP_BUF_SIZE);
1910 RB_INIT(&stp_psm->rActiveOpQ, STP_OP_BUF_SIZE);
1911 /* Put all to free Q */
1912 for (i = 0; i < STP_OP_BUF_SIZE; i++)
1914 osal_signal_init(&(stp_psm->arQue[i].signal));
1915 _stp_psm_put_op(stp_psm, &stp_psm->rFreeOpQ, &(stp_psm->arQue[i]));
1917 //stp_psm->current_active_op = NULL;
1918 stp_psm->last_active_opId = STP_OPID_PSM_INALID;
1919 /*Generate BTM thread, to servie STP-CORE and WMT-CORE for sleeping, waking up and host awake*/
1920 stp_psm->PSMd.pThreadData = (VOID *)stp_psm;
1921 stp_psm->PSMd.pThreadFunc = (VOID *)_stp_psm_proc;
1922 osal_memcpy(stp_psm->PSMd.threadName, PSM_THREAD_NAME, osal_strlen(PSM_THREAD_NAME));
1924 ret = osal_thread_create(&stp_psm->PSMd);
1927 STP_PSM_ERR_FUNC("osal_thread_create fail...\n");
1931 //init_waitqueue_head(&stp_psm->wait_wmt_q);
1932 stp_psm->wait_wmt_q.timeoutValue = STP_PSM_WAIT_EVENT_TIMEOUT;
1933 osal_event_init(&stp_psm->wait_wmt_q);
1935 err = _stp_psm_init_monitor(stp_psm);
1938 STP_PSM_ERR_FUNC("__stp_psm_init ERROR\n");
1943 ret = osal_thread_run(&stp_psm->PSMd);
1946 STP_PSM_ERR_FUNC("osal_thread_run FAILS\n");
1950 //psm disable in default
1951 _stp_psm_disable(stp_psm);
1958 ret = osal_thread_destroy(&stp_psm->PSMd);
1961 STP_PSM_ERR_FUNC("osal_thread_destroy FAILS\n");
1965 osal_fifo_deinit(&stp_psm->hold_fifo);
1971 INT32 stp_psm_deinit(MTKSTP_PSM_T *stp_psm)
1975 STP_PSM_INFO_FUNC("psm deinit\n");
1979 return STP_PSM_OPERATION_FAIL;
1982 ret = osal_thread_destroy(&stp_psm->PSMd);
1985 STP_PSM_ERR_FUNC("osal_thread_destroy FAILS\n");
1988 ret = _stp_psm_deinit_monitor(stp_psm);
1991 STP_PSM_ERR_FUNC("_stp_psm_deinit_monitor ERROR\n");
1994 osal_fifo_deinit(&stp_psm->hold_fifo);
1995 osal_sleepable_lock_deinit(&stp_psm->user_lock);
1996 psm_fifo_lock_deinit(stp_psm);
1997 osal_unsleepable_lock_deinit(&stp_psm->wq_spinlock);
1998 osal_sleepable_lock_deinit(&stp_psm->stp_psm_lock);
1999 // osal_unsleepable_lock_deinit(&stp_psm->flagSpinlock);
2001 return STP_PSM_OPERATION_SUCCESS;
2004 EXPORT_SYMBOL(mtk_wcn_stp_psm_dbg_level);