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); mtk_wcn_stp_coredump_timeout_handle(); 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; }