static inline INT32 _stp_btm_notify_wmt_dmp_wq(MTKSTP_BTM_T *stp_btm){ INT32 retval; #if 0 UINT32 dump_type; UINT8 *virtual_addr = NULL; #endif if(stp_btm == NULL) { return STP_BTM_OPERATION_FAIL; } else { #if 1 /* Paged dump */ STP_BTM_INFO_FUNC("paged dump start++\n"); retval = _stp_btm_dump_type(stp_btm,STP_OPID_BTM_PAGED_DUMP); if(retval) { STP_BTM_ERR_FUNC("paged dump fail\n"); } #else virtual_addr = wmt_plat_get_emi_ctrl_state_base_add(EXP_APMEM_CTRL_CHIP_SYNC_ADDR); if(!virtual_addr){ STP_BTM_ERR_FUNC("get dump type virtual addr fail\n"); return -1; } else { dump_type = CONSYS_REG_READ(virtual_addr); STP_BTM_INFO_FUNC("dump type:%08x\n",dump_type); } if((dump_type & 0xfffff) == (CONSYS_PAGED_DUMP_START_ADDR & 0xfffff)) { STP_BTM_INFO_FUNC("do paged dump\n"); retval = _stp_btm_dump_type(stp_btm,STP_OPID_BTM_PAGED_DUMP); if(retval) { STP_BTM_ERR_FUNC("paged dump fail,do full dump\n"); _stp_btm_dump_type(stp_btm,STP_OPID_BTM_FULL_DUMP); } } else if((dump_type & 0xfffff) == (CONSYS_FULL_DUMP_START_ADDR & 0xfffff)) { STP_BTM_INFO_FUNC("do full dump\n"); retval = _stp_btm_dump_type(stp_btm,STP_OPID_BTM_FULL_DUMP); } else { STP_BTM_INFO_FUNC("do normal dump\n"); retval = _stp_btm_dump_type(stp_btm,STP_OPID_BTM_DBG_DUMP); } #endif } return retval; }
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_handler(MTKSTP_BTM_T *stp_btm, P_STP_BTM_OP pStpOp) { INT32 ret = -1; if (NULL == pStpOp) { return -1; } switch(pStpOp->opId) { case STP_OPID_BTM_EXIT: // TODO: clean all up? ret = 0; break; /*tx timeout retry*/ case STP_OPID_BTM_RETRY: stp_do_tx_timeout(); ret = 0; break; /*whole chip reset*/ case STP_OPID_BTM_RST: STP_BTM_INFO_FUNC("whole chip reset start!\n"); STP_BTM_INFO_FUNC("....+\n"); if(stp_btm->wmt_notify) { stp_btm->wmt_notify(BTM_RST_OP); ret = 0; } else { STP_BTM_ERR_FUNC("stp_btm->wmt_notify is NULL."); ret = -1; } STP_BTM_INFO_FUNC("whole chip reset end!\n"); break; case STP_OPID_BTM_DBG_DUMP: /*Notify the wmt to get dump data*/ STP_BTM_DBG_FUNC("wmt dmp notification\n"); _stp_btm_put_dump_to_nl(); break; default: ret = -1; break; } return ret; }
P_OSAL_OP stp_btm_get_current_op(MTKSTP_BTM_T *stp_btm) { if (stp_btm) { return stp_btm->pCurOP; } else { STP_BTM_ERR_FUNC("Invalid pointer\n"); return NULL; } }
INT32 _stp_trigger_firmware_assert_via_emi(VOID) { PUINT8 p_virtual_addr = NULL; INT32 status = -1; INT32 i = 0, j = 0; do { STP_BTM_INFO_FUNC("[Force Assert] stp_trigger_firmware_assert_via_emi -->\n"); p_virtual_addr = wmt_plat_get_emi_virt_add(EXP_APMEM_CTRL_HOST_OUTBAND_ASSERT_W1); if(!p_virtual_addr) { STP_BTM_ERR_FUNC("get virtual address fail\n"); return -1; } CONSYS_REG_WRITE(p_virtual_addr, EXP_APMEM_HOST_OUTBAND_ASSERT_MAGIC_W1); STP_BTM_INFO_FUNC("[Force Assert] stp_trigger_firmware_assert_via_emi <--\n"); #if 1 //wait for firmware assert osal_sleep_ms(50); //if firmware is not assert self, host driver helps it. do { if(0 != mtk_wcn_stp_coredump_start_get()){ status = 0; break; } mtk_wcn_stp_wakeup_consys(); STP_BTM_INFO_FUNC("[Force Assert] wakeup consys (%d)\n", i); stp_dbg_poll_cpupcr(5 , 1 , 1); osal_sleep_ms(5); i++; if(i > 20){ i = 0; break; } } while(1); #endif if(0 != mtk_wcn_stp_coredump_start_get()){ status = 0; break; } j++; if(j > 8) { j = 0; break; } } while(1); return status; }
INT32 stp_btm_set_current_op(MTKSTP_BTM_T *stp_btm, P_OSAL_OP pOp) { if (stp_btm) { stp_btm->pCurOP = pOp; STP_BTM_DBG_FUNC("pOp=0x%p\n", pOp); return 0; } else { STP_BTM_ERR_FUNC("Invalid pointer\n"); return -1; } }
static INT32 _stp_set_dump_info(ENUM_EMI_CTRL_STATE_OFFSET offset,UINT32 value) { UINT8 * p_virtual_addr = NULL; p_virtual_addr = wmt_plat_get_emi_ctrl_state_base_add(offset); if(!p_virtual_addr) { STP_BTM_ERR_FUNC("get virtual address fail\n"); return -1; } CONSYS_REG_WRITE(p_virtual_addr,value); return 0; }
static INT32 _stp_set_host_dump_state(ENUM_HOST_DUMP_STATE state) { UINT8 * p_virtual_addr = NULL; p_virtual_addr = wmt_plat_get_emi_ctrl_state_base_add(EXP_APMEM_CTRL_HOST_SYNC_STATE); if(!p_virtual_addr) { STP_BTM_ERR_FUNC("get virtual address fail\n"); return -1; } CONSYS_REG_WRITE(p_virtual_addr, state); return 0; }
static INT32 stp_btm_dump_send_retry_handler(PINT8 tmp, INT32 len) { if (NULL == tmp) return -1; INT32 rc = 0, nl_retry = 0; rc = stp_dbg_nl_send(tmp, 2, len+5); while (rc) { nl_retry++; if (rc == 32) { STP_BTM_ERR_FUNC("**dump send timeout : %d**\n", rc); return 1; } if (nl_retry > 1000) { STP_BTM_ERR_FUNC("**dump send fails, and retry more than 1000: %d.**\n", rc); return 2; } STP_BTM_WARN_FUNC("**dump send fails, and retry again.**\n"); osal_sleep_ms(3); rc = stp_dbg_nl_send(tmp, 2, len+5); if (!rc) STP_BTM_DBG_FUNC("****retry again ok!**\n"); } return rc; }
static INT32 _stp_update_host_sync_num(VOID) { UINT8 * p_virtual_addr = NULL; UINT32 sync_num = 0; p_virtual_addr = wmt_plat_get_emi_ctrl_state_base_add(EXP_APMEM_CTRL_HOST_SYNC_NUM); if(!p_virtual_addr) { STP_BTM_ERR_FUNC("get virtual address fail\n"); return -1; } sync_num = CONSYS_REG_READ(p_virtual_addr); CONSYS_REG_WRITE(p_virtual_addr, sync_num + 1); return 0; }
INT32 stp_btm_deinit(MTKSTP_BTM_T *stp_btm) { UINT32 ret = -1; STP_BTM_INFO_FUNC("btm deinit\n"); if (!stp_btm) return STP_BTM_OPERATION_FAIL; ret = osal_thread_destroy(&stp_btm->BTMd); if (ret < 0) { STP_BTM_ERR_FUNC("osal_thread_destroy FAILS\n"); return STP_BTM_OPERATION_FAIL; } return STP_BTM_OPERATION_SUCCESS; }
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_handler(MTKSTP_BTM_T *stp_btm, P_STP_BTM_OP pStpOp) { INT32 ret = -1; INT32 dump_sink = 1; //core dump target, 0: aee; 1: netlink static UINT32 counter = 0; UINT32 full_dump_left = STP_FULL_DUMP_TIME; UINT32 page_counter = 0; ENUM_STP_FW_ISSUE_TYPE issue_type; if (NULL == pStpOp) { return -1; } switch(pStpOp->opId) { case STP_OPID_BTM_EXIT: // TODO: clean all up? ret = 0; break; /*tx timeout retry*/ case STP_OPID_BTM_RETRY: stp_do_tx_timeout(); ret = 0; break; /*whole chip reset*/ case STP_OPID_BTM_RST: STP_BTM_INFO_FUNC("whole chip reset start!\n"); STP_BTM_INFO_FUNC("....+\n"); if(stp_btm->wmt_notify) { stp_btm->wmt_notify(BTM_RST_OP); ret = 0; } else { STP_BTM_ERR_FUNC("stp_btm->wmt_notify is NULL."); ret = -1; } STP_BTM_INFO_FUNC("whole chip reset end!\n"); break; case STP_OPID_BTM_DBG_DUMP: /*Notify the wmt to get dump data*/ STP_BTM_DBG_FUNC("wmt dmp notification\n"); dump_sink = ((stp_btm->wmt_notify(BTM_GET_AEE_SUPPORT_FLAG) == MTK_WCN_BOOL_TRUE) ? 0 : 1); if (dump_sink == 0) { _stp_btm_put_dump_to_aee(); } else if (dump_sink == 1) { _stp_btm_put_dump_to_nl(); } else { STP_BTM_ERR_FUNC("unknown sink %d\n", dump_sink); } break; case STP_OPID_BTM_DUMP_TIMEOUT: // Flush dump data, and reset compressor STP_BTM_INFO_FUNC("Flush dump data\n"); wcn_core_dump_flush(0,MTK_WCN_BOOL_TRUE); break; case STP_OPID_BTM_POLL_CPUPCR: do{ UINT32 times; UINT32 sleep; times = pStpOp->au4OpData[0]; sleep = pStpOp->au4OpData[1]; ret = stp_dbg_poll_cpupcr(times, sleep,0); ret += stp_dbg_poll_dmaregs(times, sleep); }while(0); break; case STP_OPID_BTM_PAGED_DUMP: g_paged_dump_len = 0; issue_type = STP_FW_ASSERT_ISSUE; wmt_plat_set_host_dump_state(STP_HOST_DUMP_NOT_START); page_counter = 0; do{ UINT32 loop_cnt1 = 0; UINT32 loop_cnt2 = 0; ENUM_HOST_DUMP_STATE host_state; ENUM_CHIP_DUMP_STATE chip_state; UINT32 dump_phy_addr = 0; UINT8 *dump_vir_addr = NULL; UINT32 dump_len = 0; UINT32 isEnd = 0; P_CONSYS_EMI_ADDR_INFO p_emi_ctrl_state_info; p_emi_ctrl_state_info = wmt_plat_get_emi_phy_add(); osal_assert(p_emi_ctrl_state_info); host_state = (ENUM_HOST_DUMP_STATE)wmt_plat_get_dump_info(p_emi_ctrl_state_info->p_emi_ctrl_state_offset->emi_apmem_ctrl_host_sync_state); if(STP_HOST_DUMP_NOT_START == host_state) { counter++; STP_BTM_INFO_FUNC("counter(%d)\n",counter); osal_sleep_ms(100); } else { counter = 0; } while(1) { chip_state = (ENUM_CHIP_DUMP_STATE)wmt_plat_get_dump_info(p_emi_ctrl_state_info->p_emi_ctrl_state_offset->emi_apmem_ctrl_chip_sync_state); if(STP_CHIP_DUMP_PUT_DONE == chip_state){ STP_BTM_INFO_FUNC("chip put done\n"); break; } else { STP_BTM_INFO_FUNC("waiting chip put done\n"); STP_BTM_INFO_FUNC("chip_state: %d\n", chip_state); loop_cnt1 ++; osal_sleep_ms(5); } if(loop_cnt1 > 10) goto paged_dump_end; } wmt_plat_set_host_dump_state(STP_HOST_DUMP_GET); dump_phy_addr = wmt_plat_get_dump_info(p_emi_ctrl_state_info->p_emi_ctrl_state_offset->emi_apmem_ctrl_chip_sync_addr); if(!dump_phy_addr) { STP_BTM_ERR_FUNC("get paged dump phy address fail\n"); ret = -1; break; } dump_vir_addr = wmt_plat_get_emi_virt_add(dump_phy_addr - p_emi_ctrl_state_info->emi_phy_addr); if(!dump_vir_addr) { STP_BTM_ERR_FUNC("get paged dump phy address fail\n"); ret = -2; break; } dump_len = wmt_plat_get_dump_info(p_emi_ctrl_state_info->p_emi_ctrl_state_offset->emi_apmem_ctrl_chip_sync_len); STP_BTM_INFO_FUNC("dump_phy_ddr(%08x),dump_vir_add(0x%p),dump_len(%d)\n",dump_phy_addr,dump_vir_addr,dump_len); /*move dump info according to dump_addr & dump_len*/ #if 1 osal_memcpy(&g_paged_dump_buffer[0],dump_vir_addr,dump_len); _stp_dump_emi_dump_buffer(&g_paged_dump_buffer[0],dump_len); if(0 == page_counter)//do fw assert infor paser in first paged dump { if(1 == stp_dbg_get_host_trigger_assert()) { issue_type = STP_HOST_TRIGGER_FW_ASSERT; } ret = stp_dbg_set_fw_info(&g_paged_dump_buffer[0],512,issue_type); if(ret) { STP_BTM_ERR_FUNC("set fw issue infor fail(%d),maybe fw warm reset...\n",ret); stp_dbg_set_fw_info("Fw Warm reset",osal_strlen("Fw Warm reset"),STP_FW_WARM_RST_ISSUE); } } if(dump_len <= 32*1024){ ret = stp_dbg_aee_send(&g_paged_dump_buffer[0],dump_len, 0); if(ret == 0){ STP_BTM_INFO_FUNC("aee send ok!\n"); } else if (ret == 1) { STP_BTM_INFO_FUNC("aee send fisish!\n"); } else { STP_BTM_ERR_FUNC("aee send error!\n"); } } else { STP_BTM_ERR_FUNC("dump len is over than 32K(%d)\n",dump_len); } g_paged_dump_len += dump_len; STP_BTM_INFO_FUNC("dump len update(%d)\n",g_paged_dump_len); #endif wmt_plat_update_host_sync_num(); wmt_plat_set_host_dump_state(STP_HOST_DUMP_GET_DONE); STP_BTM_INFO_FUNC("host sync num(%d),chip sync num(%d)\n", wmt_plat_get_dump_info(p_emi_ctrl_state_info->p_emi_ctrl_state_offset->emi_apmem_ctrl_host_sync_num), wmt_plat_get_dump_info(p_emi_ctrl_state_info->p_emi_ctrl_state_offset->emi_apmem_ctrl_chip_sync_num)); page_counter++; STP_BTM_INFO_FUNC("\n\n++ paged dump counter(%d) ++\n\n\n",page_counter); while(1) { chip_state = (ENUM_CHIP_DUMP_STATE)wmt_plat_get_dump_info(p_emi_ctrl_state_info->p_emi_ctrl_state_offset->emi_apmem_ctrl_chip_sync_state); if(STP_CHIP_DUMP_END == chip_state) { STP_BTM_INFO_FUNC("chip put end\n"); wmt_plat_set_host_dump_state(STP_HOST_DUMP_END); break; } else { STP_BTM_INFO_FUNC("waiting chip put end\n"); loop_cnt2++; osal_sleep_ms(10); } if(loop_cnt2 > 10) goto paged_dump_end; } paged_dump_end: wmt_plat_set_host_dump_state(STP_HOST_DUMP_NOT_START); if(counter * 100 > STP_PAGED_DUMP_TIME_LIMIT) { isEnd = wmt_plat_get_dump_info(p_emi_ctrl_state_info->p_emi_ctrl_state_offset->emi_apmem_ctrl_chip_paded_dump_end); if(isEnd) { STP_BTM_INFO_FUNC("paged dump end\n"); STP_BTM_INFO_FUNC("\n\n paged dump print ++ \n\n"); _stp_dump_emi_dump_buffer(&g_paged_dump_buffer[0],g_paged_dump_len); STP_BTM_INFO_FUNC("\n\n paged dump print -- \n\n"); STP_BTM_INFO_FUNC("\n\n paged dump size = %d, paged dump page number = %d \n\n", g_paged_dump_len, page_counter); counter = 0; ret = 0; break; } else { STP_BTM_ERR_FUNC("paged dump fail\n"); wmt_plat_set_host_dump_state(STP_HOST_DUMP_NOT_START); stp_dbg_poll_cpupcr(5,5,0); stp_dbg_poll_dmaregs(5, 1); counter = 0; ret = -1; break; } } }while(1); break; case STP_OPID_BTM_FULL_DUMP: wmt_plat_set_host_dump_state(STP_HOST_DUMP_NOT_START); do{ UINT32 loop_cnt1 = 0; UINT32 loop_cnt2 = 0; ENUM_CHIP_DUMP_STATE chip_state; UINT32 dump_phy_addr = 0; UINT8 *dump_vir_addr = NULL; UINT32 dump_len = 0; UINT32 isFail = 0; P_CONSYS_EMI_ADDR_INFO p_emi_ctrl_state_info; p_emi_ctrl_state_info = wmt_plat_get_emi_phy_add(); osal_assert(p_emi_ctrl_state_info); while(1) { chip_state = (ENUM_CHIP_DUMP_STATE)wmt_plat_get_dump_info(p_emi_ctrl_state_info->p_emi_ctrl_state_offset->emi_apmem_ctrl_chip_sync_state); if(STP_CHIP_DUMP_PUT_DONE == chip_state) break; else { loop_cnt1 ++; osal_sleep_ms(10); } if(loop_cnt1 > 10) { isFail = 1; goto full_dump_end; } } wmt_plat_set_host_dump_state(STP_HOST_DUMP_GET); dump_phy_addr = wmt_plat_get_dump_info(p_emi_ctrl_state_info->p_emi_ctrl_state_offset->emi_apmem_ctrl_chip_sync_addr); if(!dump_phy_addr) { STP_BTM_ERR_FUNC("get phy dump address fail\n"); ret = -1; break; } dump_vir_addr = wmt_plat_get_emi_virt_add(dump_phy_addr - p_emi_ctrl_state_info->emi_phy_addr); if(!dump_vir_addr) { STP_BTM_ERR_FUNC("get vir dump address fail\n"); ret = -2; break; } dump_len = wmt_plat_get_dump_info(p_emi_ctrl_state_info->p_emi_ctrl_state_offset->emi_apmem_ctrl_chip_sync_len); /*move dump info according to dump_addr & dump_len*/ wmt_plat_update_host_sync_num(); wmt_plat_set_host_dump_state(STP_HOST_DUMP_GET_DONE); STP_BTM_INFO_FUNC("host sync num(%d),chip sync num(%d)\n", wmt_plat_get_dump_info(p_emi_ctrl_state_info->p_emi_ctrl_state_offset->emi_apmem_ctrl_host_sync_num), wmt_plat_get_dump_info(p_emi_ctrl_state_info->p_emi_ctrl_state_offset->emi_apmem_ctrl_chip_sync_num)); while(1) { chip_state = (ENUM_CHIP_DUMP_STATE)wmt_plat_get_dump_info(p_emi_ctrl_state_info->p_emi_ctrl_state_offset->emi_apmem_ctrl_chip_sync_state); if(STP_CHIP_DUMP_END == chip_state) { wmt_plat_set_host_dump_state(STP_HOST_DUMP_END); break; } else { loop_cnt2++; osal_sleep_ms(10); } if(loop_cnt2 > 10) { isFail = 1; goto full_dump_end; } } wmt_plat_set_host_dump_state(STP_HOST_DUMP_NOT_START); full_dump_end: if(isFail) { STP_BTM_ERR_FUNC("full dump fail\n"); wmt_plat_set_host_dump_state(STP_HOST_DUMP_NOT_START); ret = -1; break; } }while(--full_dump_left > 0); if(0 == full_dump_left) { STP_BTM_INFO_FUNC("full dump end\n"); ret = 0; } break; case STP_OPID_BTM_PAGED_TRACE: g_paged_trace_len = 0; do{ UINT32 ctrl_val = 0; UINT32 loop_cnt1 = 0; UINT32 buffer_start = 0; UINT32 buffer_idx = 0; UINT8 *dump_vir_addr = NULL; P_CONSYS_EMI_ADDR_INFO p_emi_ctrl_state_info; p_emi_ctrl_state_info = wmt_plat_get_emi_phy_add(); osal_assert(p_emi_ctrl_state_info); while(loop_cnt1 < 10) { ctrl_val = wmt_plat_get_dump_info(p_emi_ctrl_state_info->p_emi_ctrl_state_offset->emi_apmem_ctrl_state); if(0x8 == ctrl_val) break; else { osal_sleep_ms(10); loop_cnt1++; } } if(loop_cnt1 >= 10) { STP_BTM_ERR_FUNC("polling CTRL STATE fail\n"); ret = -1; break; } buffer_start = wmt_plat_get_dump_info(p_emi_ctrl_state_info->p_emi_ctrl_state_offset->emi_apmem_ctrl_chip_print_buff_start); buffer_idx = wmt_plat_get_dump_info(p_emi_ctrl_state_info->p_emi_ctrl_state_offset->emi_apmem_ctrl_chip_print_buff_idx); //buffer_len = buffer_idx - buffer_start; g_paged_trace_len = buffer_idx; STP_BTM_INFO_FUNC("paged trace buffer addr(%08x),buffer_len(%d)\n",buffer_start,buffer_idx); dump_vir_addr = wmt_plat_get_emi_virt_add(buffer_start - p_emi_ctrl_state_info->emi_phy_addr); if(!dump_vir_addr) { STP_BTM_ERR_FUNC("get vir dump address fail\n"); ret = -2; break; } osal_memcpy(&g_paged_trace_buffer[0],dump_vir_addr,buffer_idx < STP_DBG_PAGED_TRACE_SIZE ? buffer_idx : STP_DBG_PAGED_TRACE_SIZE); /*moving paged trace according to buffer_start & buffer_len*/ do { int i = 0; int dump_len = 0; dump_len = buffer_idx < STP_DBG_PAGED_TRACE_SIZE ? buffer_idx : STP_DBG_PAGED_TRACE_SIZE; printk("\n\n -- paged trace hex output --\n\n"); for(i = 0;i < dump_len; i++) { if(i%16 == 0){ printk("\n"); } printk("%02x ",g_paged_trace_buffer[i]); } printk("\n\n -- paged trace ascii output --\n\n"); for(i = 0;i < dump_len; i++) { if(i%64 == 0) printk("\n"); printk("%c",g_paged_trace_buffer[i]); } }while(0); /*move parser fw assert infor to paged dump in the one paged dump*/ //ret = stp_dbg_set_fw_info(&g_paged_trace_buffer[0],g_paged_trace_len,issue_type); ret = 0; }while(0); mtk_wcn_stp_ctx_restore(); break; #if CFG_WMT_LTE_COEX_HANDLING case STP_OPID_BTM_WMT_LTE_COEX: ret = wmt_idc_msg_to_lte_handing(); break; #endif default: ret = -1; break; } return ret; }
static INT32 _stp_btm_handler(MTKSTP_BTM_T *stp_btm, P_STP_BTM_OP pStpOp) { INT32 ret = -1; INT32 dump_sink = 1; //core dump target, 0: aee; 1: netlink if (NULL == pStpOp) { return -1; } switch(pStpOp->opId) { case STP_OPID_BTM_EXIT: // TODO: clean all up? ret = 0; break; /*tx timeout retry*/ case STP_OPID_BTM_RETRY: stp_do_tx_timeout(); ret = 0; break; /*whole chip reset*/ case STP_OPID_BTM_RST: STP_BTM_INFO_FUNC("whole chip reset start!\n"); STP_BTM_INFO_FUNC("....+\n"); if(stp_btm->wmt_notify) { stp_btm->wmt_notify(BTM_RST_OP); ret = 0; } else { STP_BTM_ERR_FUNC("stp_btm->wmt_notify is NULL."); ret = -1; } STP_BTM_INFO_FUNC("whole chip reset end!\n"); break; case STP_OPID_BTM_DBG_DUMP: /*Notify the wmt to get dump data*/ STP_BTM_DBG_FUNC("wmt dmp notification\n"); dump_sink = ((stp_btm->wmt_notify(BTM_GET_AEE_SUPPORT_FLAG) == MTK_WCN_BOOL_TRUE) ? 0 : 1); if (dump_sink == 0) { _stp_btm_put_dump_to_aee(); } else if (dump_sink == 1) { _stp_btm_put_dump_to_nl(); } else { STP_BTM_ERR_FUNC("unknown sink %d\n", dump_sink); } break; case STP_OPID_BTM_DUMP_TIMEOUT: // Flush dump data, and reset compressor STP_BTM_INFO_FUNC("Flush dump data\n"); wcn_core_dump_flush(0); break; default: ret = -1; break; } return ret; }
static INT32 _stp_btm_put_op(MTKSTP_BTM_T *stp_btm, P_OSAL_OP_Q pOpQ, P_OSAL_OP pOp) { INT32 ret; P_OSAL_OP pOp_latest; P_OSAL_OP pOp_current; INT32 flag_latest = 1; INT32 flag_current = 1; if (!pOpQ || !pOp) { STP_BTM_WARN_FUNC("invalid input param: 0x%p, 0x%p\n", pOpQ, pOp); return 0; /* ;MTK_WCN_BOOL_FALSE; */ } ret = 0; osal_lock_unsleepable_lock(&(stp_btm->wq_spinlock)); /* acquire lock success */ if (&stp_btm->rFreeOpQ == pOpQ) { if (!RB_FULL(pOpQ)) RB_PUT(pOpQ, pOp); else ret = -1; } else if (pOp->op.opId == STP_OPID_BTM_RST || pOp->op.opId == STP_OPID_BTM_DUMP_TIMEOUT) { if (!RB_FULL(pOpQ)) { RB_PUT(pOpQ, pOp); STP_BTM_ERR_FUNC("RB_PUT: 0x%d\n", pOp->op.opId); } else ret = -1; } else { pOp_current = stp_btm_get_current_op(stp_btm); if (pOp_current) { if (pOp_current->op.opId == STP_OPID_BTM_RST || pOp_current->op.opId == STP_OPID_BTM_DUMP_TIMEOUT) { STP_BTM_ERR_FUNC("current: 0x%d\n", pOp_current->op.opId); flag_current = 0; } } RB_GET_LATEST(pOpQ, pOp_latest); if (pOp_latest) { if (pOp_latest->op.opId == STP_OPID_BTM_RST || pOp_latest->op.opId == STP_OPID_BTM_DUMP_TIMEOUT) { STP_BTM_ERR_FUNC("latest: 0x%d\n", pOp_latest->op.opId); flag_latest = 0; } if (pOp_latest->op.opId == pOp->op.opId) { flag_latest = 0; STP_BTM_DBG_FUNC("With the latest a command repeat: latest 0x%d,current 0x%d\n", pOp_latest->op.opId, pOp->op.opId); } } if (flag_current && flag_latest) { if (!RB_FULL(pOpQ)) { RB_PUT(pOpQ, pOp); STP_BTM_ERR_FUNC("RB_PUT: 0x%d\n", pOp->op.opId); } else ret = -1; } else ret = -1; } osal_unlock_unsleepable_lock(&(stp_btm->wq_spinlock)); if (ret) { STP_BTM_DBG_FUNC("RB_FULL(0x%p) %d ,rFreeOpQ = %p, rActiveOpQ = %p\n", pOpQ, RB_COUNT(pOpQ), &stp_btm->rFreeOpQ, &stp_btm->rActiveOpQ); return 0; } else { /* STP_BTM_WARN_FUNC("RB_COUNT = %d\n",RB_COUNT(pOpQ)); */ return 1; } }