INT32 stp_btm_reset_btm_wq(MTKSTP_BTM_T *stp_btm) { UINT32 i = 0; osal_lock_unsleepable_lock(&(stp_btm->wq_spinlock)); RB_INIT(&stp_btm->rFreeOpQ, STP_BTM_OP_BUF_SIZE); RB_INIT(&stp_btm->rActiveOpQ, STP_BTM_OP_BUF_SIZE); osal_unlock_unsleepable_lock(&(stp_btm->wq_spinlock)); /* Put all to free Q */ for (i = 0; i < STP_BTM_OP_BUF_SIZE; i++) { osal_signal_init(&(stp_btm->arQue[i].signal)); _stp_btm_put_op(stp_btm, &stp_btm->rFreeOpQ, &(stp_btm->arQue[i])); } return 0; }
MTKSTP_BTM_T *stp_btm_init(void) { INT32 i = 0x0; INT32 ret =-1; osal_unsleepable_lock_init(&stp_btm->wq_spinlock); osal_event_init(&stp_btm->STPd_event); stp_btm->wmt_notify = wmt_lib_btm_cb; RB_INIT(&stp_btm->rFreeOpQ, STP_BTM_OP_BUF_SIZE); RB_INIT(&stp_btm->rActiveOpQ, STP_BTM_OP_BUF_SIZE); /* Put all to free Q */ for (i = 0; i < STP_BTM_OP_BUF_SIZE; i++) { osal_signal_init(&(stp_btm->arQue[i].signal)); _stp_btm_put_op(stp_btm, &stp_btm->rFreeOpQ, &(stp_btm->arQue[i])); } /*Generate PSM thread, to servie STP-CORE for packet retrying and core dump receiving*/ stp_btm->BTMd.pThreadData = (VOID *)stp_btm; stp_btm->BTMd.pThreadFunc = (VOID *)_stp_btm_proc; osal_memcpy(stp_btm->BTMd.threadName, BTM_THREAD_NAME , osal_strlen(BTM_THREAD_NAME)); ret = osal_thread_create(&stp_btm->BTMd); if (ret < 0) { STP_BTM_ERR_FUNC("osal_thread_create fail...\n"); goto ERR_EXIT1; } /* Start STPd thread*/ ret = osal_thread_run(&stp_btm->BTMd); if(ret < 0) { STP_BTM_ERR_FUNC("osal_thread_run FAILS\n"); goto ERR_EXIT1; } return stp_btm; ERR_EXIT1: return NULL; }
static INT32 _stp_btm_proc (void *pvData) { MTKSTP_BTM_T *stp_btm = (MTKSTP_BTM_T *)pvData; P_OSAL_OP pOp; INT32 id; INT32 result; if (!stp_btm) { STP_BTM_WARN_FUNC("!stp_btm \n"); return -1; } for (;;) { pOp = NULL; osal_wait_for_event(&stp_btm->STPd_event, _stp_btm_wait_for_msg, (void *)stp_btm ); if (osal_thread_should_stop(&stp_btm->BTMd)) { STP_BTM_INFO_FUNC("should stop now... \n"); // TODO: clean up active opQ break; } /* get Op from activeQ */ pOp = _stp_btm_get_op(stp_btm, &stp_btm->rActiveOpQ); if (!pOp) { STP_BTM_WARN_FUNC("get_lxop activeQ fail\n"); continue; } id = osal_op_get_id(pOp); STP_BTM_DBG_FUNC("======> lxop_get_opid = %d, %s, remaining count = *%d*\n", id, (id >= 4)?("???"):(g_btm_op_name[id]), RB_COUNT(&stp_btm->rActiveOpQ)); if (id >= STP_OPID_BTM_NUM) { STP_BTM_WARN_FUNC("abnormal opid id: 0x%x \n", id); result = -1; goto handler_done; } result = _stp_btm_handler(stp_btm, &pOp->op); handler_done: if (result) { STP_BTM_WARN_FUNC("opid id(0x%x)(%s) error(%d)\n", id, (id >= 4)?("???"):(g_btm_op_name[id]), result); } if (osal_op_is_wait_for_signal(pOp)) { osal_op_raise_signal(pOp, result); } else { /* put Op back to freeQ */ _stp_btm_put_op(stp_btm, &stp_btm->rFreeOpQ, pOp); } if (STP_OPID_BTM_EXIT == id) { break; } } STP_BTM_INFO_FUNC("exits \n"); return 0; };
INT32 _stp_btm_put_act_op ( MTKSTP_BTM_T *stp_btm, P_OSAL_OP pOp ) { INT32 bRet = 0; INT32 bCleanup = 0; long wait_ret = -1; P_OSAL_SIGNAL pSignal = NULL; do { if (!stp_btm || !pOp) { break; } pSignal = &pOp->signal; if (pSignal->timeoutValue) { pOp->result = -9; osal_signal_init(&pOp->signal); } /* put to active Q */ bRet = _stp_btm_put_op(stp_btm, &stp_btm->rActiveOpQ, pOp); if(0 == bRet) { STP_BTM_WARN_FUNC("put active queue fail\n"); bCleanup = 1;//MTK_WCN_BOOL_TRUE; break; } /* wake up wmtd */ osal_trigger_event(&stp_btm->STPd_event); if (pSignal->timeoutValue == 0) { bRet = 1;//MTK_WCN_BOOL_TRUE; /* clean it in wmtd */ break; } /* wait result, clean it here */ bCleanup = 1;//MTK_WCN_BOOL_TRUE; /* check result */ wait_ret = osal_wait_for_signal_timeout(&pOp->signal); STP_BTM_DBG_FUNC("wait completion:%ld\n", wait_ret); if (!wait_ret) { STP_BTM_ERR_FUNC("wait completion timeout \n"); // TODO: how to handle it? retry? } else { if (pOp->result) { STP_BTM_WARN_FUNC("op(%d) result:%d\n", pOp->op.opId, pOp->result); } bRet = (pOp->result) ? 0 : 1; } } while(0); if (bCleanup) { /* put Op back to freeQ */ _stp_btm_put_op(stp_btm, &stp_btm->rFreeOpQ, pOp); } return bRet; }
static INT32 _stp_btm_proc(PVOID pvData) { MTKSTP_BTM_T *stp_btm = (MTKSTP_BTM_T *) pvData; P_OSAL_OP pOp; INT32 id; INT32 result; if (!stp_btm) { STP_BTM_WARN_FUNC("!stp_btm\n"); return -1; } for (;;) { pOp = NULL; osal_wait_for_event(&stp_btm->STPd_event, _stp_btm_wait_for_msg, (PVOID)stp_btm); if (osal_thread_should_stop(&stp_btm->BTMd)) { STP_BTM_INFO_FUNC("should stop now...\n"); /* TODO: clean up active opQ */ break; } #if 1 if (gDumplogflag) { /* pr_warn("enter place1\n"); */ if (mtk_wcn_stp_is_uart_mand_mode() || mtk_wcn_stp_is_uart_fullset_mode()) dump_uart_history(); gDumplogflag = 0; continue; } #endif /* get Op from activeQ */ pOp = _stp_btm_get_op(stp_btm, &stp_btm->rActiveOpQ); if (!pOp) { STP_BTM_WARN_FUNC("get_lxop activeQ fail\n"); continue; } id = osal_op_get_id(pOp); STP_BTM_DBG_FUNC("======> lxop_get_opid = %d, %s, remaining count = *%d*\n", id, (id >= 4) ? ("???") : (g_btm_op_name[id]), RB_COUNT(&stp_btm->rActiveOpQ)); if (id >= STP_OPID_BTM_NUM) { STP_BTM_WARN_FUNC("abnormal opid id: 0x%x\n", id); result = -1; goto handler_done; } osal_lock_unsleepable_lock(&(stp_btm->wq_spinlock)); stp_btm_set_current_op(stp_btm, pOp); osal_unlock_unsleepable_lock(&(stp_btm->wq_spinlock)); result = _stp_btm_handler(stp_btm, &pOp->op); osal_lock_unsleepable_lock(&(stp_btm->wq_spinlock)); stp_btm_set_current_op(stp_btm, NULL); osal_unlock_unsleepable_lock(&(stp_btm->wq_spinlock)); handler_done: if (result) { STP_BTM_WARN_FUNC("opid id(0x%x)(%s) error(%d)\n", id, (id >= 4) ? ("???") : (g_btm_op_name[id]), result); } if (osal_op_is_wait_for_signal(pOp)) { osal_op_raise_signal(pOp, result); } else { /* put Op back to freeQ */ _stp_btm_put_op(stp_btm, &stp_btm->rFreeOpQ, pOp); } if (STP_OPID_BTM_EXIT == id) { break; } else if (STP_OPID_BTM_RST == id) { /* prevent multi reset case */ stp_btm_reset_btm_wq(stp_btm); } } STP_BTM_INFO_FUNC("exits\n"); return 0; };