3 #include "osal_typedef.h"
9 #define PFX_BTM "[STP-BTM] "
10 #define STP_BTM_LOG_LOUD 4
11 #define STP_BTM_LOG_DBG 3
12 #define STP_BTM_LOG_INFO 2
13 #define STP_BTM_LOG_WARN 1
14 #define STP_BTM_LOG_ERR 0
16 INT32 gBtmDbgLevel = STP_BTM_LOG_INFO;
18 #define STP_BTM_LOUD_FUNC(fmt, arg...) if(gBtmDbgLevel >= STP_BTM_LOG_LOUD){ osal_dbg_print(PFX_BTM "%s: " fmt, __FUNCTION__ ,##arg);}
19 #define STP_BTM_DBG_FUNC(fmt, arg...) if(gBtmDbgLevel >= STP_BTM_LOG_DBG){ osal_dbg_print(PFX_BTM "%s: " fmt, __FUNCTION__ ,##arg);}
20 #define STP_BTM_INFO_FUNC(fmt, arg...) if(gBtmDbgLevel >= STP_BTM_LOG_INFO){ osal_dbg_print(PFX_BTM "[I]%s: " fmt, __FUNCTION__ ,##arg);}
21 #define STP_BTM_WARN_FUNC(fmt, arg...) if(gBtmDbgLevel >= STP_BTM_LOG_WARN){ osal_dbg_print(PFX_BTM "[W]%s: " fmt, __FUNCTION__ ,##arg);}
22 #define STP_BTM_ERR_FUNC(fmt, arg...) if(gBtmDbgLevel >= STP_BTM_LOG_ERR){ osal_dbg_print(PFX_BTM "[E]%s(%d):ERROR! " fmt, __FUNCTION__ , __LINE__, ##arg);}
23 #define STP_BTM_TRC_FUNC(f) if(gBtmDbgLevel >= STP_BTM_LOG_DBG){ osal_dbg_print(PFX_BTM "<%s> <%d>\n", __FUNCTION__, __LINE__);}
25 INT32 gDumplogflag = 0;
27 extern void dump_uart_history(void);
33 MTKSTP_BTM_T stp_btm_i;
34 MTKSTP_BTM_T *stp_btm = &stp_btm_i;
36 const PCHAR g_btm_op_name[]={
39 "STP_OPID_BTM_DBG_DUMP",
44 static PCHAR _stp_pkt_type(INT32 type){
50 osal_memcpy(s, "WMT", strlen("WMT")+1);
53 osal_memcpy(s, "BT", strlen("BT")+1);
56 osal_memcpy(s, "GPS", strlen("GPS")+1);
59 osal_memcpy(s, "FM", strlen("FM")+1);
62 osal_memcpy(s, "UNKOWN", strlen("UNKOWN")+1);
70 static INT32 _stp_btm_put_dump_to_nl(void)
72 #define NUM_FETCH_ENTRY 8
74 static UINT8 buf[2048];
75 static UINT8 tmp[2048];
80 INT32 remain=0, index =0;
81 INT32 retry = 0, rc = 0, nl_retry = 0;
82 STP_BTM_INFO_FUNC("Enter..\n");
92 remain = stp_dbg_dmp_out_ex(&buf[0], &buf_len);
95 pkt = (STP_PACKET_T *)buf;
97 if (hdr->dbg_type == STP_DBG_FW_DMP){
98 osal_memcpy(&tmp[index], pkt->raw, pkt->hdr.len);
100 if(pkt->hdr.len <= 1500)
102 tmp[index + pkt->hdr.len] = '\n';
103 tmp[index + pkt->hdr.len + 1] = '\0';
105 //printk("\n%s\n+++\n", tmp);
106 rc = stp_dbg_nl_send((PCHAR)&tmp, 2);
113 STP_BTM_WARN_FUNC("**dump send fails, and retry again.**\n");
115 rc = stp_dbg_nl_send((PCHAR)&tmp, 2);
117 STP_BTM_WARN_FUNC("****retry again ok!**\n");
122 STP_BTM_INFO_FUNC("dump entry length is over long\n");
132 }while((remain > 0) || (retry < 2));
134 STP_BTM_INFO_FUNC("Exit..\n");
139 static INT32 _stp_btm_put_dump_to_aee(void)
141 static UINT8 buf[2048];
142 static UINT8 tmp[2048];
150 STP_BTM_INFO_FUNC("Enter..\n");
153 remain = stp_dbg_dmp_out_ex(&buf[0], &buf_len);
155 pkt = (STP_PACKET_T*)buf;
157 if (hdr->dbg_type == STP_DBG_FW_DMP) {
158 osal_memcpy(&tmp[0], pkt->raw, pkt->hdr.len);
160 if (pkt->hdr.len <= 1500) {
161 tmp[pkt->hdr.len] = '\n';
162 tmp[pkt->hdr.len + 1] = '\0';
164 ret = stp_dbg_aee_send(tmp, pkt->hdr.len, 0);
166 STP_BTM_INFO_FUNC("dump entry length is over long\n");
175 }while ((remain > 0) || (retry < 2));
177 STP_BTM_INFO_FUNC("Exit..\n");
181 #define COMBO_DUMP2AEE
183 static INT32 _stp_btm_handler(MTKSTP_BTM_T *stp_btm, P_STP_BTM_OP pStpOp)
186 INT32 dump_sink = 1; //core dump target, 0: aee; 1: netlink
195 case STP_OPID_BTM_EXIT:
196 // TODO: clean all up?
201 case STP_OPID_BTM_RETRY:
208 case STP_OPID_BTM_RST:
209 STP_BTM_INFO_FUNC("whole chip reset start!\n");
210 STP_BTM_INFO_FUNC("....+\n");
211 if(stp_btm->wmt_notify)
213 stp_btm->wmt_notify(BTM_RST_OP);
218 STP_BTM_ERR_FUNC("stp_btm->wmt_notify is NULL.");
222 STP_BTM_INFO_FUNC("whole chip reset end!\n");
226 case STP_OPID_BTM_DBG_DUMP:
227 /*Notify the wmt to get dump data*/
228 STP_BTM_DBG_FUNC("wmt dmp notification\n");
229 dump_sink = ((stp_btm->wmt_notify(BTM_GET_AEE_SUPPORT_FLAG) == MTK_WCN_BOOL_TRUE) ? 0 : 1);
231 if (dump_sink == 0) {
232 _stp_btm_put_dump_to_aee();
233 } else if (dump_sink == 1) {
234 _stp_btm_put_dump_to_nl();
236 STP_BTM_ERR_FUNC("unknown sink %d\n", dump_sink);
242 case STP_OPID_BTM_DUMP_TIMEOUT:
243 // Flush dump data, and reset compressor
244 STP_BTM_INFO_FUNC("Flush dump data\n");
245 wcn_core_dump_flush(0);
256 static P_OSAL_OP _stp_btm_get_op (
257 MTKSTP_BTM_T *stp_btm,
266 STP_BTM_WARN_FUNC("!pOpQ \n");
270 osal_lock_unsleepable_lock(&(stp_btm->wq_spinlock));
271 /* acquire lock success */
273 osal_unlock_unsleepable_lock(&(stp_btm->wq_spinlock));
277 //STP_BTM_WARN_FUNC("RB_GET fail\n");
283 static INT32 _stp_btm_put_op (
284 MTKSTP_BTM_T *stp_btm,
293 STP_BTM_WARN_FUNC("invalid input param: 0x%p, 0x%p \n", pOpQ, pOp);
294 return 0;//;MTK_WCN_BOOL_FALSE;
299 osal_lock_unsleepable_lock(&(stp_btm->wq_spinlock));
300 /* acquire lock success */
309 osal_unlock_unsleepable_lock(&(stp_btm->wq_spinlock));
313 STP_BTM_WARN_FUNC("RB_FULL(0x%p) %d ,rFreeOpQ = %p, rActiveOpQ = %p\n", pOpQ, RB_COUNT(pOpQ),
314 &stp_btm->rFreeOpQ, &stp_btm->rActiveOpQ);
319 //STP_BTM_WARN_FUNC("RB_COUNT = %d\n",RB_COUNT(pOpQ));
324 P_OSAL_OP _stp_btm_get_free_op (
325 MTKSTP_BTM_T *stp_btm
332 pOp = _stp_btm_get_op(stp_btm, &stp_btm->rFreeOpQ);
335 osal_memset(&pOp->op, 0, sizeof(pOp->op));
344 INT32 _stp_btm_put_act_op (
345 MTKSTP_BTM_T *stp_btm,
353 P_OSAL_SIGNAL pSignal = NULL;
356 if (!stp_btm || !pOp)
361 pSignal = &pOp->signal;
363 if (pSignal->timeoutValue)
366 osal_signal_init(&pOp->signal);
369 /* put to active Q */
370 bRet = _stp_btm_put_op(stp_btm, &stp_btm->rActiveOpQ, pOp);
373 STP_BTM_WARN_FUNC("put active queue fail\n");
374 bCleanup = 1;//MTK_WCN_BOOL_TRUE;
379 osal_trigger_event(&stp_btm->STPd_event);
381 if (pSignal->timeoutValue == 0)
383 bRet = 1;//MTK_WCN_BOOL_TRUE;
384 /* clean it in wmtd */
388 /* wait result, clean it here */
389 bCleanup = 1;//MTK_WCN_BOOL_TRUE;
392 wait_ret = osal_wait_for_signal_timeout(&pOp->signal);
394 STP_BTM_DBG_FUNC("wait completion:%ld\n", wait_ret);
397 STP_BTM_ERR_FUNC("wait completion timeout \n");
398 // TODO: how to handle it? retry?
404 STP_BTM_WARN_FUNC("op(%d) result:%d\n", pOp->op.opId, pOp->result);
407 bRet = (pOp->result) ? 0 : 1;
412 /* put Op back to freeQ */
413 _stp_btm_put_op(stp_btm, &stp_btm->rFreeOpQ, pOp);
419 static INT32 _stp_btm_wait_for_msg(void *pvData)
421 MTKSTP_BTM_T *stp_btm = (MTKSTP_BTM_T *)pvData;
422 return ((!RB_EMPTY(&stp_btm->rActiveOpQ)) || osal_thread_should_stop(&stp_btm->BTMd));
425 static INT32 _stp_btm_proc (void *pvData)
427 MTKSTP_BTM_T *stp_btm = (MTKSTP_BTM_T *)pvData;
434 STP_BTM_WARN_FUNC("!stp_btm \n");
442 osal_wait_for_event(&stp_btm->STPd_event,
443 _stp_btm_wait_for_msg,
447 if (osal_thread_should_stop(&stp_btm->BTMd))
449 STP_BTM_INFO_FUNC("should stop now... \n");
450 // TODO: clean up active opQ
457 //printk("enter place1\n");
466 /* get Op from activeQ */
467 pOp = _stp_btm_get_op(stp_btm, &stp_btm->rActiveOpQ);
471 STP_BTM_WARN_FUNC("get_lxop activeQ fail\n");
475 id = osal_op_get_id(pOp);
477 STP_BTM_DBG_FUNC("======> lxop_get_opid = %d, %s, remaining count = *%d*\n",
478 id, (id >= 4)?("???"):(g_btm_op_name[id]), RB_COUNT(&stp_btm->rActiveOpQ));
480 if (id >= STP_OPID_BTM_NUM)
482 STP_BTM_WARN_FUNC("abnormal opid id: 0x%x \n", id);
487 result = _stp_btm_handler(stp_btm, &pOp->op);
493 STP_BTM_WARN_FUNC("opid id(0x%x)(%s) error(%d)\n", id, (id >= 4)?("???"):(g_btm_op_name[id]), result);
496 if (osal_op_is_wait_for_signal(pOp))
498 osal_op_raise_signal(pOp, result);
502 /* put Op back to freeQ */
503 _stp_btm_put_op(stp_btm, &stp_btm->rFreeOpQ, pOp);
506 if (STP_OPID_BTM_EXIT == id)
509 } else if (STP_OPID_BTM_RST == id) {
510 /* prevent multi reset case */
511 stp_btm_reset_btm_wq(stp_btm);
515 STP_BTM_INFO_FUNC("exits \n");
520 static inline INT32 _stp_btm_notify_wmt_rst_wq(MTKSTP_BTM_T *stp_btm)
529 return STP_BTM_OPERATION_FAIL;
533 pOp = _stp_btm_get_free_op(stp_btm);
536 STP_BTM_WARN_FUNC("get_free_lxop fail \n");
539 pOp->op.opId = STP_OPID_BTM_RST;
540 pOp->signal.timeoutValue= 0;
541 bRet = _stp_btm_put_act_op(stp_btm, pOp);
542 STP_BTM_DBG_FUNC("OPID(%d) type(%d) bRet(%d) \n\n",
544 pOp->op.au4OpData[0],
546 retval = (0 == bRet) ? STP_BTM_OPERATION_FAIL : STP_BTM_OPERATION_SUCCESS;
551 static inline INT32 _stp_btm_notify_stp_retry_wq(MTKSTP_BTM_T *stp_btm){
559 return STP_BTM_OPERATION_FAIL;
563 pOp = _stp_btm_get_free_op(stp_btm);
566 STP_BTM_WARN_FUNC("get_free_lxop fail \n");
569 pOp->op.opId = STP_OPID_BTM_RETRY;
570 pOp->signal.timeoutValue= 0;
571 bRet = _stp_btm_put_act_op(stp_btm, pOp);
572 STP_BTM_DBG_FUNC("OPID(%d) type(%d) bRet(%d) \n\n",
574 pOp->op.au4OpData[0],
576 retval = (0 == bRet) ? STP_BTM_OPERATION_FAIL : STP_BTM_OPERATION_SUCCESS;
582 static inline INT32 _stp_btm_notify_coredump_timeout_wq(MTKSTP_BTM_T *stp_btm){
589 return STP_BTM_OPERATION_FAIL;
591 pOp = _stp_btm_get_free_op(stp_btm);
593 STP_BTM_WARN_FUNC("get_free_lxop fail \n");
596 pOp->op.opId = STP_OPID_BTM_DUMP_TIMEOUT;
597 pOp->signal.timeoutValue= 0;
598 bRet = _stp_btm_put_act_op(stp_btm, pOp);
599 STP_BTM_DBG_FUNC("OPID(%d) type(%d) bRet(%d) \n\n",
601 pOp->op.au4OpData[0],
603 retval = (0 == bRet) ? STP_BTM_OPERATION_FAIL : STP_BTM_OPERATION_SUCCESS;
609 static inline INT32 _stp_btm_notify_wmt_dmp_wq(MTKSTP_BTM_T *stp_btm){
617 return STP_BTM_OPERATION_FAIL;
621 pOp = _stp_btm_get_free_op(stp_btm);
624 //STP_BTM_WARN_FUNC("get_free_lxop fail \n");
627 pOp->op.opId = STP_OPID_BTM_DBG_DUMP;
628 pOp->signal.timeoutValue= 0;
629 bRet = _stp_btm_put_act_op(stp_btm, pOp);
630 STP_BTM_DBG_FUNC("OPID(%d) type(%d) bRet(%d) \n\n",
632 pOp->op.au4OpData[0],
634 retval = (0 == bRet) ? STP_BTM_OPERATION_FAIL : STP_BTM_OPERATION_SUCCESS;
639 INT32 stp_btm_notify_wmt_rst_wq(MTKSTP_BTM_T *stp_btm)
641 return _stp_btm_notify_wmt_rst_wq(stp_btm);
644 INT32 stp_btm_notify_stp_retry_wq(MTKSTP_BTM_T *stp_btm)
646 return _stp_btm_notify_stp_retry_wq(stp_btm);
649 INT32 stp_btm_notify_coredump_timeout_wq(MTKSTP_BTM_T *stp_btm)
651 return _stp_btm_notify_coredump_timeout_wq(stp_btm);
654 INT32 stp_btm_notify_wmt_dmp_wq(MTKSTP_BTM_T *stp_btm)
656 return _stp_btm_notify_wmt_dmp_wq(stp_btm);
659 MTKSTP_BTM_T *stp_btm_init(void)
664 osal_unsleepable_lock_init(&stp_btm->wq_spinlock);
665 osal_event_init(&stp_btm->STPd_event);
666 stp_btm->wmt_notify = wmt_lib_btm_cb;
668 RB_INIT(&stp_btm->rFreeOpQ, STP_BTM_OP_BUF_SIZE);
669 RB_INIT(&stp_btm->rActiveOpQ, STP_BTM_OP_BUF_SIZE);
671 /* Put all to free Q */
672 for (i = 0; i < STP_BTM_OP_BUF_SIZE; i++)
674 osal_signal_init(&(stp_btm->arQue[i].signal));
675 _stp_btm_put_op(stp_btm, &stp_btm->rFreeOpQ, &(stp_btm->arQue[i]));
678 /*Generate PSM thread, to servie STP-CORE for packet retrying and core dump receiving*/
679 stp_btm->BTMd.pThreadData = (VOID *)stp_btm;
680 stp_btm->BTMd.pThreadFunc = (VOID *)_stp_btm_proc;
681 osal_memcpy(stp_btm->BTMd.threadName, BTM_THREAD_NAME , osal_strlen(BTM_THREAD_NAME));
683 ret = osal_thread_create(&stp_btm->BTMd);
686 STP_BTM_ERR_FUNC("osal_thread_create fail...\n");
690 /* Start STPd thread*/
691 ret = osal_thread_run(&stp_btm->BTMd);
694 STP_BTM_ERR_FUNC("osal_thread_run FAILS\n");
706 INT32 stp_btm_deinit(MTKSTP_BTM_T *stp_btm){
710 STP_BTM_INFO_FUNC("btm deinit\n");
714 return STP_BTM_OPERATION_FAIL;
717 ret = osal_thread_destroy(&stp_btm->BTMd);
720 STP_BTM_ERR_FUNC("osal_thread_destroy FAILS\n");
721 return STP_BTM_OPERATION_FAIL;
724 return STP_BTM_OPERATION_SUCCESS;
728 INT32 stp_btm_reset_btm_wq(MTKSTP_BTM_T *stp_btm)
731 osal_lock_unsleepable_lock(&(stp_btm->wq_spinlock));
732 RB_INIT(&stp_btm->rFreeOpQ, STP_BTM_OP_BUF_SIZE);
733 RB_INIT(&stp_btm->rActiveOpQ, STP_BTM_OP_BUF_SIZE);
734 osal_unlock_unsleepable_lock(&(stp_btm->wq_spinlock));
735 /* Put all to free Q */
736 for (i = 0; i < STP_BTM_OP_BUF_SIZE; i++)
738 osal_signal_init(&(stp_btm->arQue[i].signal));
739 _stp_btm_put_op(stp_btm, &stp_btm->rFreeOpQ, &(stp_btm->arQue[i]));
746 INT32 stp_notify_btm_dump(MTKSTP_BTM_T *stp_btm)
748 //printk("%s:enter++\n",__func__);
751 osal_dbg_print("%s: NULL POINTER\n",__func__);
757 osal_trigger_event(&stp_btm->STPd_event);