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_trigger_firmware_assert_via_emi(VOID) { INT32 status = -1; INT32 j = 0; wmt_plat_force_trigger_assert(STP_FORCE_TRG_ASSERT_DEBUG_PIN); do { if(0 != mtk_wcn_stp_coredump_start_get()){ status = 0; break; } stp_dbg_poll_cpupcr(5 , 1 , 1); stp_dbg_poll_dmaregs(5 , 1); j++; STP_BTM_INFO_FUNC("Wait for assert message (%d)\n", j); osal_sleep_ms(20); if(j > 49) { /* wait for 1 second*/ stp_dbg_set_fw_info("host trigger fw assert timeout", osal_strlen("host trigger fw assert timeout"),STP_HOST_TRIGGER_ASSERT_TIMEOUT); wcn_core_dump_timeout();/* trigger collect SYS_FTRACE*/ break; } } while(1); return status; }
static inline INT32 _stp_btm_do_fw_assert(MTKSTP_BTM_T *stp_btm){ INT32 status = -1; INT32 j = 0; MTK_WCN_BOOL bRet = MTK_WCN_BOOL_FALSE; //send assert command STP_BTM_INFO_FUNC("trigger stp assert process\n"); bRet = stp_btm->wmt_notify(BTM_TRIGGER_STP_ASSERT_OP); if (MTK_WCN_BOOL_TRUE == bRet) { do { if(0 != mtk_wcn_stp_coredump_start_get()){ status = 0; break; } j++; STP_BTM_INFO_FUNC("Wait for assert message (%d)\n", j); if(j > 150) break; osal_sleep_ms(20); } while(1); } else { status = -1; STP_BTM_INFO_FUNC("trigger stp assert failed\n"); } if (0 == status) STP_BTM_INFO_FUNC("trigger stp assert succeed\n"); return status; }
static INT32 _stp_btm_put_dump_to_nl(VOID) { #define NUM_FETCH_ENTRY 8 static UINT8 buf[2048]; static UINT8 tmp[2048]; UINT32 buf_len; STP_PACKET_T *pkt; STP_DBG_HDR_T *hdr; INT32 remain = 0, index = 0; INT32 retry = 0, rc = 0; INT32 len; STP_BTM_INFO_FUNC("Enter..\n"); index = 0; tmp[index++] = '['; tmp[index++] = 'M'; tmp[index++] = ']'; do { index = 3; remain = stp_dbg_dmp_out_ex(&buf[0], &buf_len); if (buf_len > 0) { pkt = (STP_PACKET_T *) buf; hdr = &pkt->hdr; len = pkt->hdr.len; osal_memcpy(&tmp[index], &len, 2); index += 2; if (hdr->dbg_type == STP_DBG_FW_DMP) { osal_memcpy(&tmp[index], pkt->raw, pkt->hdr.len); if (pkt->hdr.len <= 1500) { tmp[index + pkt->hdr.len] = '\n'; tmp[index + pkt->hdr.len + 1] = '\0'; /* pr_warn("\n%s\n+++\n", tmp); */ rc = stp_btm_dump_send_retry_handler((PINT8)&tmp, len); if (rc) goto exit; /* schedule(); */ } else { STP_BTM_INFO_FUNC("dump entry length is over long\n"); osal_bug_on(0); } retry = 0; } } else { retry++; osal_sleep_ms(100); } } while ((remain > 0) || (retry < 2)); exit: STP_BTM_INFO_FUNC("Exit..\n"); return 0; }
INT32 mtk_wcn_consys_stp_btif_tx(const UINT8 *pBuf, const UINT32 len, UINT32 *written_len) { INT32 retry_left = STP_BTIF_TX_RTY_LMT; INT32 wr_count = 0; INT32 written = 0; if (!stpBtifId) { WMT_WARN_FUNC("NULL BTIF ID reference!\n"); return -1; } if (len == 0) { *written_len = 0; WMT_INFO_FUNC("special case for STP-CORE,pbuf(%p)\n", pBuf); return 0; } *written_len = 0; if (len > STP_MAX_PACKAGE_ALLOWED) { WMT_WARN_FUNC("abnormal pacage length,len(%d),pid[%d/%s]\n", len, current->pid, current->comm); return -2; } wr_count = mtk_wcn_btif_write(stpBtifId, pBuf, len); if (wr_count < 0) { WMT_ERR_FUNC("mtk_wcn_btif_write err(%d)\n", wr_count); *written_len = 0; return -3; } if (wr_count == len) { /*perfect case */ *written_len = wr_count; return wr_count; } while ((retry_left--) && (wr_count < len)) { osal_sleep_ms(STP_BTIF_TX_RTY_DLY); written = mtk_wcn_btif_write(stpBtifId, pBuf + wr_count, len - wr_count); if (written < 0) { WMT_ERR_FUNC("mtk_wcn_btif_write err(%d)when do recovered\n", written); break; } wr_count += written; } if (wr_count == len) { WMT_INFO_FUNC("recovered,len(%d),retry_left(%d)\n", len, retry_left); /*recovered case */ *written_len = wr_count; return wr_count; } WMT_ERR_FUNC("stp btif write fail,len(%d),written(%d),retry_left(%d),pid[%d/%s]\n", len, wr_count, retry_left, current->pid, current->comm); *written_len = 0; return -wr_count; }
static int hif_sdio_proc(void * pvData) { while (!kthread_should_stop()) { //HIF_SDIO_INFO_FUNC("enter sleep.\n"); osal_sleep_ms(10000); //HIF_SDIO_INFO_FUNC("wakeup\n"); } HIF_SDIO_INFO_FUNC("hifsdiod exit.\n"); return 0; }
static INT32 _stp_btm_put_dump_to_aee(void) { static UINT8 buf[2048]; static UINT8 tmp[2048]; UINT32 buf_len; STP_PACKET_T *pkt; STP_DBG_HDR_T *hdr; INT32 remain = 0; INT32 retry = 0; INT32 ret = 0; STP_BTM_INFO_FUNC("Enter..\n"); do { remain = stp_dbg_dmp_out_ex(&buf[0], &buf_len); if (buf_len > 0) { pkt = (STP_PACKET_T*)buf; hdr = &pkt->hdr; if (hdr->dbg_type == STP_DBG_FW_DMP) { osal_memcpy(&tmp[0], pkt->raw, pkt->hdr.len); if (pkt->hdr.len <= 1500) { tmp[pkt->hdr.len] = '\n'; tmp[pkt->hdr.len + 1] = '\0'; ret = stp_dbg_aee_send(tmp, pkt->hdr.len, 0); } else { STP_BTM_INFO_FUNC("dump entry length is over long\n"); osal_bug_on(0); } retry = 0; } retry = 0; } else { retry ++; osal_sleep_ms(20); } }while ((remain > 0) || (retry < 10)); STP_BTM_INFO_FUNC("Exit..\n"); return ret; }
INT32 wmt_dbg_assert_test(INT32 par1, INT32 par2, INT32 par3) { if (0 == par3) { //par2 = 0: send assert command //par2 != 0: send exception command return wmt_dbg_cmd_test_api(0 == par2 ? 0 : 1); } else { INT32 sec = 8; INT32 times = 0; times = par3; do{ WMT_INFO_FUNC("Send Assert Command per 8 secs!!\n"); wmt_dbg_cmd_test_api(0); osal_sleep_ms(sec * 1000); }while(--times); } return 0; }
static INT32 wmt_pwr_on_thread (void *pvData) { INT32 retryCounter = 1; WMT_INFO_FUNC("wmt_pwr_on_thread start to run\n"); #if CONSYS_EARLYSUSPEND_ENABLE osal_lock_sleepable_lock(&g_es_lr_lock); if (1 == g_early_suspend_flag) { WMT_INFO_FUNC("wmt_pwr_on_thread exit, do nothing due to early_suspend flag set\n"); osal_unlock_sleepable_lock(&g_es_lr_lock); return 0; } osal_unlock_sleepable_lock(&g_es_lr_lock); #endif do { if (MTK_WCN_BOOL_FALSE == mtk_wcn_wmt_func_on(WMTDRV_TYPE_LPBK)) { WMT_WARN_FUNC("WMT turn on LPBK fail, retrying, retryCounter left:%d!\n", retryCounter); retryCounter--; osal_sleep_ms(1000); } else { WMT_INFO_FUNC("WMT turn on LPBK suceed"); break; } } while (retryCounter > 0); #if CONSYS_EARLYSUSPEND_ENABLE osal_lock_sleepable_lock(&g_es_lr_lock); if (1 == g_early_suspend_flag) { WMT_INFO_FUNC("turn off lpbk due to early_suspend flag set\n"); mtk_wcn_wmt_func_off(WMTDRV_TYPE_LPBK); } osal_unlock_sleepable_lock(&g_es_lr_lock); #endif WMT_INFO_FUNC("wmt_pwr_on_thread exits\n"); return 0; }
INT32 _stp_trigger_firmware_assert_via_emi(VOID) { INT32 status = -1; INT32 j = 0; wmt_plat_force_trigger_assert(STP_FORCE_TRG_ASSERT_DEBUG_PIN); do { if(0 != mtk_wcn_stp_coredump_start_get()) { status = 0; break; } stp_dbg_poll_cpupcr(5 , 1 , 1); j++; STP_BTM_INFO_FUNC("Wait for assert message (%d)\n", j); osal_sleep_ms(20); if(j > 24) break; } while(1); return status; }
INT32 mtk_wcn_hif_sdio_query_chipid(INT32 waitFlag) { UINT32 timeSlotMs = 200; UINT32 maxTimeSlot = 15; UINT32 counter = 0; //gComboChipId = 0x6628; if (0 == waitFlag) return gComboChipId; if (0 <= hif_sdio_is_chipid_valid(gComboChipId)) return gComboChipId; wmt_plat_pwr_ctrl(FUNC_ON); wmt_plat_sdio_ctrl(WMT_SDIO_SLOT_SDIO1, FUNC_ON); while (counter < maxTimeSlot) { if (0 <= hif_sdio_is_chipid_valid(gComboChipId)) break; osal_sleep_ms(timeSlotMs); counter++; } wmt_plat_sdio_ctrl(WMT_SDIO_SLOT_SDIO1, FUNC_OFF); wmt_plat_pwr_ctrl(FUNC_OFF); return gComboChipId; }
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; }
INT32 wmt_idc_msg_to_lte_handing(VOID) { UINT32 readlen = 0; local_para_struct *p_lps = NULL; UINT8 *p_data = NULL; UINT8 opcode = 0; UINT16 msg_len = 0; UINT32 handle_len = 0; #if CFG_WMT_LTE_ENABLE_MSGID_MAPPING MTK_WCN_BOOL unknow_msgid = MTK_WCN_BOOL_FALSE; #endif readlen = mtk_wcn_stp_receive_data(&gWmtIdcInfo.buffer[0], LTE_IDC_BUFFER_MAX_SIZE, COEX_TASK_INDX); if (readlen == 0) { osal_sleep_ms(5); readlen = mtk_wcn_stp_receive_data(&gWmtIdcInfo.buffer[0], LTE_IDC_BUFFER_MAX_SIZE, COEX_TASK_INDX); } if (readlen > 0) { WMT_DBG_FUNC("read data len from fw(%d)\n", readlen); wmt_idc_dump_debug_msg("WMT->LTE from STP buffer", &gWmtIdcInfo.buffer[0], readlen); p_data = &gWmtIdcInfo.buffer[0]; while (handle_len < readlen) { p_data += 2; /*omit direction & opcode 2 bytes */ osal_memcpy(&msg_len, p_data, 2); msg_len -= 1; /*flag byte */ WMT_DBG_FUNC("current raw data len(%d) from connsys firmware\n", msg_len); p_data += 2; /*length: 2 bytes */ /*how to handle flag(msg type) need to Scott comment */ /************************************************/ if (*p_data == WMT_IDC_RX_OPCODE_DEBUG_MONITOR) /*do not need transfer to LTE */ { p_data += 1; /*flag : 1 byte */ /*need to handle these debug message */ wmt_idc_dump_debug_msg("WIFI DEBUG MONITOR", p_data, msg_len); } else /*need to transfer to LTE */ { p_lps = (local_para_struct *) osal_malloc(osal_sizeof(local_para_struct) + osal_sizeof(UINT8) * msg_len); if (NULL == p_lps) { WMT_ERR_FUNC("allocate local_para_struct memory fail\n"); return -1; } p_lps->msg_len = msg_len + osal_sizeof(local_para_struct); opcode = *p_data; WMT_DBG_FUNC("current opcode(%d) to LTE\n", opcode); p_data += 1; /*flag : 1 byte */ osal_memcpy(p_lps->data, p_data, msg_len); gWmtIdcInfo.iit.local_para_ptr = p_lps; #if CFG_WMT_LTE_ENABLE_MSGID_MAPPING switch (opcode) { case WMT_IDC_RX_OPCODE_BTWF_DEF_PARA: gWmtIdcInfo.iit.msg_id = IPC_MSG_ID_EL1_WIFIBT_OPER_DEFAULT_PARAM_IND; break; case WMT_IDC_RX_OPCODE_BTWF_CHAN_RAN: gWmtIdcInfo.iit.msg_id = IPC_MSG_ID_EL1_WIFIBT_OPER_FREQ_IND; break; case WMT_IDC_RX_OPCODE_LTE_FREQ_IDX_TABLE: gWmtIdcInfo.iit.msg_id = IPC_MSG_ID_EL1_WIFIBT_FREQ_IDX_TABLE_IND; break; case WMT_IDC_RX_OPCODE_BTWF_PROFILE_IND: gWmtIdcInfo.iit.msg_id = IPC_MSG_ID_EL1_WIFIBT_PROFILE_IND; break; case WMT_IDC_RX_OPCODE_UART_PIN_SEL: gWmtIdcInfo.iit.msg_id = IPC_MSG_ID_EL1_PIN_TYPE_IND; break; /* case WMT_IDC_RX_OPCODE_TDM_REQ: */ /* gWmtIdcInfo.iit.msg_id = IPC_MSG_ID_EL1_WIFIBT_OPER_FREQ_IND; */ /* break; */ default: unknow_msgid = MTK_WCN_BOOL_TRUE; WMT_ERR_FUNC("unknow opcode(%d) from connsys firmware\n", opcode); break; } if (MTK_WCN_BOOL_FALSE == unknow_msgid) { /*handling flag value in wmt cmd */ mtk_conn_md_bridge_send_msg(&gWmtIdcInfo.iit); } #else if (opcode >= LTE_MSG_ID_OFFSET) { gWmtIdcInfo.iit.msg_id = opcode + IPC_EL1_MSG_ID_BEGIN - LTE_MSG_ID_OFFSET + 1; /*handling flag value in wmt cmd */ mtk_conn_md_bridge_send_msg(&gWmtIdcInfo.iit); WMT_INFO_FUNC("CONN->LTE: (0x%x->0x%x)\n", opcode, gWmtIdcInfo.iit.msg_id); } else { WMT_ERR_FUNC("opcode(%d)from connsys fw is out of range,drop it!\n", opcode); } #endif osal_free(p_lps); } p_data += msg_len; /*point to next package header */ handle_len += (msg_len + 5); } } else { WMT_ERR_FUNC("there is no coex data in stp buffer\n"); } osal_memset(&gWmtIdcInfo.buffer[0], 0, LTE_IDC_BUFFER_MAX_SIZE); return 0; }
INT32 wmt_ctrl_sdio_func(P_WMT_CTRL_DATA pWmtCtrlData) { INT32 iRet = -1; UINT32 statBit = WMT_STAT_SDIO_WIFI_ON; INT32 retry = 10; P_DEV_WMT pDev = &gDevWmt; /* single instance */ WMT_SDIO_FUNC_TYPE sdioFuncType = pWmtCtrlData->au4CtrlData[0]; UINT32 u4On = pWmtCtrlData->au4CtrlData[1]; if (WMT_SDIO_FUNC_MAX <= sdioFuncType) { WMT_ERR_FUNC("CTRL_SDIO_FUNC, invalid func type (%d) \n", sdioFuncType); return -1; } if (WMT_SDIO_FUNC_STP == sdioFuncType) { statBit = WMT_STAT_SDIO_STP_ON; } if (u4On) { if (osal_test_bit(statBit, &pDev->state)) { WMT_WARN_FUNC("CTRL_SDIO_FUNC(%d) but already ON \n", sdioFuncType); iRet = 0; } else { while (retry-- > 0 && iRet != 0) { if (iRet) { /* sleep 150ms before sdio slot ON ready */ osal_sleep_ms(150); } iRet = mtk_wcn_hif_sdio_wmt_control(sdioFuncType, MTK_WCN_BOOL_TRUE); if (HIF_SDIO_ERR_NOT_PROBED == iRet) { /* not probed case, retry */ continue; } else if (HIF_SDIO_ERR_CLT_NOT_REG == iRet){ /* For WiFi, client not reg yet, no need to retry, WiFi function can work any time when wlan.ko is insert into system*/ iRet = 0; } else { /* other fail cases, stop */ break; } } if (!retry || iRet) { WMT_ERR_FUNC("mtk_wcn_hif_sdio_wmt_control(%d, TRUE) fail(%d) retry(%d)\n", sdioFuncType, iRet, retry); } else { osal_set_bit(statBit, &pDev->state); } } } else { if (osal_test_bit(statBit, &pDev->state)) { iRet = mtk_wcn_hif_sdio_wmt_control(sdioFuncType, MTK_WCN_BOOL_FALSE); if (iRet) { WMT_ERR_FUNC("mtk_wcn_hif_sdio_wmt_control(%d, FALSE) fail(%d)\n", sdioFuncType, iRet); } /*any way, set to OFF state*/ osal_clear_bit(statBit, &pDev->state); } else { WMT_WARN_FUNC("CTRL_SDIO_FUNC(%d) but already OFF \n", sdioFuncType); iRet = 0; } } return iRet; }
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_put_dump_to_nl(void) { #define NUM_FETCH_ENTRY 8 static UINT8 buf[2048]; static UINT8 tmp[2048]; UINT32 buf_len; STP_PACKET_T *pkt; STP_DBG_HDR_T *hdr; INT32 remain=0, index =0; INT32 retry = 0, rc = 0, nl_retry = 0; STP_BTM_INFO_FUNC("Enter..\n"); index = 0; tmp[index++]='['; tmp[index++]='M'; tmp[index++]=']'; do { index = 3; remain = stp_dbg_dmp_out_ex(&buf[0], &buf_len); if (buf_len > 0) { pkt = (STP_PACKET_T *)buf; hdr = &pkt->hdr; if (hdr->dbg_type == STP_DBG_FW_DMP){ osal_memcpy(&tmp[index], pkt->raw, pkt->hdr.len); if(pkt->hdr.len <= 1500) { tmp[index + pkt->hdr.len] = '\n'; tmp[index + pkt->hdr.len + 1] = '\0'; //printk("\n%s\n+++\n", tmp); rc = stp_dbg_nl_send((PCHAR)&tmp, 2); while(rc){ nl_retry++; if(nl_retry > 1000){ break; } STP_BTM_WARN_FUNC("**dump send fails, and retry again.**\n"); osal_sleep_ms(3); rc = stp_dbg_nl_send((PCHAR)&tmp, 2); if(!rc){ STP_BTM_WARN_FUNC("****retry again ok!**\n"); } } //schedule(); } else { STP_BTM_INFO_FUNC("dump entry length is over long\n"); osal_bug_on(0); } retry = 0; } }else { retry ++; osal_sleep_ms(100); } }while((remain > 0) || (retry < 2)); STP_BTM_INFO_FUNC("Exit..\n"); return 0; }