char stp_dbg_nl_send( char * aucMsg, unsigned char cmd ) { struct sk_buff *skb = NULL; void *msg_head = NULL; int rc = -1; int i; if(num_bind_process == 0) { /* no listening process */ STP_DBG_ERR_FUNC("%s(): the process is not invoked\n", __func__); return 0; } for(i = 0 ; i < num_bind_process ; i++) { skb = genlmsg_new(2048, GFP_KERNEL); if(skb) { msg_head = genlmsg_put(skb, 0, stp_dbg_seqnum++, &stp_dbg_gnl_family, 0, cmd); if(msg_head == NULL) { nlmsg_free(skb); STP_DBG_ERR_FUNC("%s(): genlmsg_put fail...\n", __func__); return -1; } rc = nla_put_string(skb, STP_DBG_ATTR_MSG, aucMsg); if(rc != 0) { nlmsg_free(skb); STP_DBG_ERR_FUNC("%s(): nla_put_string fail...\n", __func__); return -1; } /* finalize the message */ genlmsg_end(skb, msg_head); /* sending message */ rc = genlmsg_unicast(&init_net, skb, bind_pid[i]); if(rc != 0) { STP_DBG_ERR_FUNC("%s(): genlmsg_unicast fail...\n", __func__); return -1; } } else { STP_DBG_ERR_FUNC("%s(): genlmsg_new fail...\n", __func__); return -1; } } return 0; }
/* wcn_core_dump_flush - Fulsh dump data and reset core dump sys * * Retunr 0 if success, else error code */ INT32 wcn_core_dump_flush(INT32 rst) { PUINT8 pbuf = NULL; INT32 len = 0; INT32 ret = 0; if (!g_core_dump) { STP_DBG_ERR_FUNC("invalid pointer!\n"); return -1; } wcn_core_dump_out(g_core_dump, &pbuf, &len); STP_DBG_INFO_FUNC("buf 0x%08x, len %d\n", (unsigned int)pbuf, len); // show coredump end info on UI //osal_dbg_assert_aee("MT662x f/w coredump end", "MT662x firmware coredump ends"); #if WMT_PLAT_ALPS aee_kernel_dal_show("MT662x coredump end\n"); ret = stp_dbg_set_fw_info(pbuf, 512, STP_FW_ASSERT_ISSUE); if (ret) { STP_DBG_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); } // call AEE driver API aed_combo_exception(NULL, 0, (const int*)pbuf, len, (const char*)g_core_dump->info); #endif // reset wcn_core_dump_reset(g_core_dump, STP_CORE_DUMP_TIMEOUT); return 0; }
static INT32 wcn_gzip_compressor(void *worker, UINT8 *in_buf, INT32 in_sz, UINT8 *out_buf, INT32 *out_sz, INT32 finish) { INT32 ret = 0; z_stream *stream = NULL; INT32 tmp = *out_sz; STP_DBG_INFO_FUNC("in buf 0x%08x, in sz %d\n", (unsigned int)in_buf, in_sz); STP_DBG_INFO_FUNC("out buf 0x%08x, out sz %d\n", (unsigned int)out_buf, tmp); stream = (z_stream*)worker; if (!stream) { STP_DBG_ERR_FUNC("invalid workspace!\n"); return -1; } if (in_sz > 0) { #if 0 ret = zlib_deflateReset(stream); if (ret != Z_OK) { STP_DBG_ERR_FUNC("reset failed!\n"); return -2; } #endif stream->next_in = in_buf; stream->avail_in = in_sz; stream->next_out = out_buf; stream->avail_out = tmp; zlib_deflate(stream, Z_FULL_FLUSH); if (finish) { while (1) { int val = zlib_deflate(stream, Z_FINISH); if (val == Z_OK) { continue; } else if (val == Z_STREAM_END) { break; } else { STP_DBG_ERR_FUNC("finish operation failed %d\n", val); return -3; } } } *out_sz = tmp - stream->avail_out; } STP_DBG_INFO_FUNC("out buf 0x%08x, out sz %d\n", (unsigned int)out_buf, *out_sz); return ret; }
/* wcn_core_dump_init - create core dump sys * @ timeout - core dump time out value * * Return object pointer if success, else NULL */ P_WCN_CORE_DUMP_T wcn_core_dump_init(UINT32 timeout) { #define KBYTES (1024*sizeof(char)) #define L1_BUF_SIZE (32*KBYTES) #define L2_BUF_SIZE (512*KBYTES) P_WCN_CORE_DUMP_T core_dmp = NULL; core_dmp = (P_WCN_CORE_DUMP_T)osal_malloc(sizeof(WCN_CORE_DUMP_T)); if (!core_dmp) { STP_DBG_ERR_FUNC("alloc mem failed!\n"); goto fail; } osal_memset(core_dmp, 0, sizeof(WCN_CORE_DUMP_T)); core_dmp->compressor = wcn_compressor_init("core_dump_compressor", L1_BUF_SIZE, L2_BUF_SIZE); if (!core_dmp->compressor) { STP_DBG_ERR_FUNC("create compressor failed!\n"); goto fail; } wcn_compressor_reset(core_dmp->compressor, 1, GZIP); core_dmp->dmp_timer.timeoutHandler = core_dump_timeout_handler; core_dmp->dmp_timer.timeroutHandlerData = (ULONG)core_dmp; osal_timer_create(&core_dmp->dmp_timer); core_dmp->timeout = timeout; osal_sleepable_lock_init(&core_dmp->dmp_lock); core_dmp->sm = CORE_DUMP_INIT; STP_DBG_INFO_FUNC("create coredump object OK!\n"); return core_dmp; fail: if (core_dmp && core_dmp->compressor) { wcn_compressor_deinit(core_dmp->compressor); core_dmp->compressor = NULL; } if (core_dmp) { osal_free(core_dmp); } osal_sleepable_lock_deinit(&core_dmp->dmp_lock); return NULL; }
/* wcn_core_dump_flush - Fulsh dump data and reset core dump sys * * Retunr 0 if success, else error code */ INT32 wcn_core_dump_flush(INT32 rst) { PUINT8 pbuf = NULL; INT32 len = 0; if (!g_core_dump) { STP_DBG_ERR_FUNC("invalid pointer!\n"); return -1; } wcn_core_dump_out(g_core_dump, &pbuf, &len); STP_DBG_INFO_FUNC("buf 0x%08x, len %d\n", (unsigned int)pbuf, len); // show coredump end info on UI //osal_dbg_assert_aee("MT662x f/w coredump end", "MT662x firmware coredump ends"); aee_kernel_dal_show("MT662x coredump end\n"); // call AEE driver API aed_combo_exception(NULL, 0, (const int*)pbuf, len, (const char*)g_core_dump->info); // reset wcn_core_dump_reset(g_core_dump, STP_CORE_DUMP_TIMEOUT); return 0; }
INT32 stp_dbg_set_version_info(UINT32 chipid, UINT8 *pRomVer, UINT8 *wifiVer, UINT8 *pPatchVer, UINT8 *pPatchBrh) { if (g_stp_dbg_cpupcr) { osal_lock_sleepable_lock(&g_stp_dbg_cpupcr->lock); g_stp_dbg_cpupcr->chipId = chipid; if (wifiVer) { osal_memcpy(g_stp_dbg_cpupcr->wifiVer, wifiVer, 4); } if (pRomVer) { osal_memcpy(g_stp_dbg_cpupcr->romVer, pRomVer, 2); } if (pPatchVer) { osal_memcpy(g_stp_dbg_cpupcr->patchVer, pPatchVer, 8); } if (pPatchBrh) { osal_memcpy(g_stp_dbg_cpupcr->branchVer, pPatchBrh, 4); } osal_unlock_sleepable_lock(&g_stp_dbg_cpupcr->lock); } else { STP_DBG_ERR_FUNC("NULL pointer\n"); return -1; } STP_DBG_INFO_FUNC("chipid(0x%x),wifiver(%s),romver(%s),patchver(%s),branchver(%s)\n", g_stp_dbg_cpupcr->chipId, g_stp_dbg_cpupcr->wifiVer, &g_stp_dbg_cpupcr->romVer[0], &g_stp_dbg_cpupcr->patchVer[0], &g_stp_dbg_cpupcr->branchVer[0]); return 0; }
MTKSTP_DBG_T *stp_dbg_init(void *btm_half) { MTKSTP_DBG_T *stp_dbg= NULL; STP_DBG_INFO_FUNC("stp-dbg init\n"); stp_dbg = kzalloc(sizeof(MTKSTP_DBG_T), GFP_KERNEL); if(IS_ERR(stp_dbg)){ STP_DBG_ERR_FUNC("-ENOMEM\n"); goto ERR_EXIT1; } stp_dbg->logsys = vmalloc(sizeof(MTKSTP_LOG_SYS_T)); if(IS_ERR(stp_dbg->logsys)){ STP_DBG_ERR_FUNC("-ENOMEM stp_gdb->logsys\n"); goto ERR_EXIT2; } memset(stp_dbg->logsys, 0, sizeof(MTKSTP_LOG_SYS_T)); spin_lock_init(&(stp_dbg->logsys->lock)); stp_dbg->pkt_trace_no=0; stp_dbg->is_enable=0; g_stp_dbg = stp_dbg; if(btm_half != NULL){ stp_dbg->btm = btm_half; } else { stp_dbg->btm = NULL; } //bind to netlink stp_dbg_nl_init(); g_core_dump = wcn_core_dump_init(STP_CORE_DUMP_TIMEOUT); g_stp_dbg_cpupcr = stp_dbg_cpupcr_init(); return stp_dbg; ERR_EXIT2: kfree(stp_dbg); return NULL; ERR_EXIT1: return NULL; }
static int stp_dbg_nl_reset( struct sk_buff *skb, struct genl_info *info ) { STP_DBG_ERR_FUNC("%s(): should not be invoked\n", __func__); return 0; }
static void stp_dbg_nl_init(void) { if(genl_register_family(&stp_dbg_gnl_family) != 0) { STP_DBG_ERR_FUNC("%s(): GE_NELINK family registration fail\n", __func__); } else { if(genl_register_ops(&stp_dbg_gnl_family, &stp_dbg_gnl_ops_bind) != 0) { STP_DBG_ERR_FUNC("%s(): BIND operation registration fail\n", __func__); } if(genl_register_ops(&stp_dbg_gnl_family, &stp_dbg_gnl_ops_reset) != 0) { STP_DBG_ERR_FUNC("%s(): RESET operation registration fail\n", __func__); } } return; }
/* wcn_core_dump_out - get compressed data from compressor buffer * @ dmp - pointer of object * @ pbuf - target buffer's pointer * @ len - data length * * Retunr 0 if success; else error code */ INT32 wcn_core_dump_out(P_WCN_CORE_DUMP_T dmp, PUINT8 *pbuf, PINT32 plen) { INT32 ret = 0; if ((!dmp) || (!pbuf) || (!plen)) { STP_DBG_ERR_FUNC("invalid pointer!\n"); return -1; } ret = osal_lock_sleepable_lock(&dmp->dmp_lock); if (ret) { STP_DBG_ERR_FUNC("--->lock dmp->dmp_lock failed, ret=%d\n", ret); return ret; } ret = wcn_compressor_out(dmp->compressor, pbuf, plen); osal_unlock_sleepable_lock(&dmp->dmp_lock); return ret; }
MTKSTP_DBG_T *stp_dbg_init(VOID *btm_half) { MTKSTP_DBG_T *stp_dbg= NULL; STP_DBG_INFO_FUNC("stp-dbg init\n"); stp_dbg = osal_kzalloc_sleep(osal_sizeof(MTKSTP_DBG_T)); if (!stp_dbg){ STP_DBG_ERR_FUNC("-ENOMEM\n"); goto ERR_EXIT1; } stp_dbg->logsys = osal_malloc(osal_sizeof(MTKSTP_LOG_SYS_T)); if (!stp_dbg->logsys){ STP_DBG_ERR_FUNC("-ENOMEM stp_gdb->logsys\n"); goto ERR_EXIT2; } osal_memset(stp_dbg->logsys, 0, osal_sizeof(MTKSTP_LOG_SYS_T)); osal_unsleepable_lock_init(&(stp_dbg->logsys->lock)); stp_dbg->pkt_trace_no = 0; stp_dbg->is_enable = 0; if (btm_half != NULL){ stp_dbg->btm = btm_half; } else { stp_dbg->btm = NULL; } return stp_dbg; ERR_EXIT2: osal_kfree(stp_dbg); return NULL; ERR_EXIT1: return NULL; }
/* wcn_core_dump_reset - reset core dump sys * @ dmp - pointer of object * @ timeout - core dump time out value * * Retunr 0 if success, else error code */ INT32 wcn_core_dump_reset(P_WCN_CORE_DUMP_T dmp, UINT32 timeout) { if (!dmp) { STP_DBG_ERR_FUNC("invalid pointer!\n"); return -1; } dmp->sm = CORE_DUMP_INIT; dmp->timeout = timeout; osal_timer_stop(&dmp->dmp_timer); wcn_compressor_reset(dmp->compressor, 1, GZIP); osal_memset(dmp->info, 0, STP_CORE_DUMP_INFO_SZ + 1); return 0; }
P_STP_DBG_CPUPCR_T stp_dbg_cpupcr_init(VOID) { P_STP_DBG_CPUPCR_T pSdCpupcr = NULL; pSdCpupcr = (P_STP_DBG_CPUPCR_T) osal_malloc(osal_sizeof(STP_DBG_CPUPCR_T)); if (!pSdCpupcr) { STP_DBG_ERR_FUNC("stp dbg cpupcr allocate memory fail!\n"); return NULL; } osal_memset(pSdCpupcr, 0, osal_sizeof(STP_DBG_CPUPCR_T)); osal_sleepable_lock_init(&pSdCpupcr->lock); return pSdCpupcr; }
/* wcn_compressor_reset - reset compressor * @ cprs - compressor's pointer * @ enable - enable/disable compress * @ type - compress algorithm * * Retunr 0 if success, else NULL */ INT32 wcn_compressor_reset(P_WCN_COMPRESSOR_T cprs, UINT8 enable, WCN_COMPRESS_ALG_T type) { if (!cprs) { STP_DBG_ERR_FUNC("invalid para!\n"); return -1; } cprs->f_compress_en = enable; //cprs->f_compress_en = 0; // disable compress for test cprs->compress_type = type; cprs->L1_pos = 0; cprs->L2_pos = 0; cprs->uncomp_size = 0; cprs->crc32 = 0xffffffffUL; STP_DBG_INFO_FUNC("OK! compress algorithm %d\n", type); return 0; }
static int stp_dbg_nl_bind( struct sk_buff *skb, struct genl_info *info ) { struct nlattr *na; char * mydata; if (info == NULL) { goto out; } STP_DBG_INFO_FUNC("%s():->\n", __func__); na = info->attrs[STP_DBG_ATTR_MSG]; if (na) { mydata = (char *)nla_data(na); } if(num_bind_process < MAX_BIND_PROCESS) { #if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0)) bind_pid[num_bind_process] = info->snd_pid; num_bind_process++; STP_DBG_INFO_FUNC("%s():-> pid = %d\n", __func__, info->snd_pid); #else bind_pid[num_bind_process] = info->snd_portid; num_bind_process++; STP_DBG_INFO_FUNC("%s():-> pid = %d\n", __func__, info->snd_portid); #endif } else { STP_DBG_ERR_FUNC("%s(): exceeding binding limit %d\n", __func__, MAX_BIND_PROCESS); } out: return 0; }
static int stp_dbg_fill_hdr(struct stp_dbg_pkt_hdr *hdr, int type, int ack, int seq, int crc, int dir, int len, int dbg_type) { struct timeval now; if(!hdr) { STP_DBG_ERR_FUNC("function invalid\n"); return -EINVAL; } else { do_gettimeofday(&now); hdr->dbg_type = dbg_type; hdr->ack = ack; hdr->seq = seq; hdr->sec = now.tv_sec; hdr->usec = now.tv_usec; hdr->crc = crc; hdr->dir = dir;//rx hdr->dmy = 0xffffffff; hdr->len = len; hdr->type = type; return 0; } }
static INT32 stp_dbg_fill_hdr (struct stp_dbg_pkt_hdr *hdr, INT32 type, INT32 ack, INT32 seq, INT32 crc, INT32 dir, INT32 len, INT32 dbg_type) { INT32 sec = 0; INT32 usec = 0; if (!hdr){ STP_DBG_ERR_FUNC("function invalid\n"); return -22; } else { osal_gettimeofday(&sec,&usec); hdr->dbg_type = dbg_type; hdr->ack = ack; hdr->seq = seq; hdr->sec = sec; hdr->usec = usec; hdr->crc = crc; hdr->dir = dir;//rx hdr->dmy = 0xffffffff; hdr->len = len; hdr->type = type; return 0; } }
/* wcn_compressor_out - get the result data from L2 buffer * @ cprs - compressor's pointer * @ pbuf - point to L2 buffer * @ plen - out len * * Retunr 0 if success, else NULL */ INT32 wcn_compressor_out(P_WCN_COMPRESSOR_T cprs, PUINT8 *pbuf, PINT32 plen) { INT32 ret = 0; INT32 tmp_len = 0; if ((!cprs) || (!pbuf) || (!plen)) { STP_DBG_ERR_FUNC("invalid para!\n"); return -1; } // check if there's L1 data need flush to L2 buffer if (cprs->L1_pos > 0) { tmp_len = cprs->L2_buf_sz - cprs->L2_pos; if (cprs->f_compress_en && cprs->handler) { // need compress ret = cprs->handler(cprs->worker, cprs->L1_buf, cprs->L1_pos, &cprs->L2_buf[cprs->L2_pos], &tmp_len, 1); if (!ret) { cprs->crc32 = (crc32(cprs->crc32, cprs->L1_buf, cprs->L1_pos)); cprs->L2_pos += tmp_len; /* Add 8 byte suffix === 32 bits UNCOMPRESS SIZE 32 bits CRC */ *(uint32_t *)(&cprs->L2_buf[cprs->L2_pos]) = (cprs->crc32 ^ 0xffffffffUL); *(uint32_t *)(&cprs->L2_buf[cprs->L2_pos + 4]) = cprs->uncomp_size; cprs->L2_pos += 8; STP_DBG_INFO_FUNC("compress OK!\n"); } else { STP_DBG_ERR_FUNC("compress error!\n"); } } else { // no need compress tmp_len = (cprs->L1_pos > tmp_len) ? tmp_len : cprs->L1_pos; osal_memcpy(&cprs->L2_buf[cprs->L2_pos], cprs->L1_buf, tmp_len); cprs->L2_pos += tmp_len; } cprs->L1_pos = 0; } *pbuf = cprs->L2_buf; *plen = cprs->L2_pos; STP_DBG_INFO_FUNC("0x%08x, len %d\n", (unsigned int)*pbuf, *plen); #if 1 ret = zlib_deflateReset((z_stream*)cprs->worker); if (ret != Z_OK) { STP_DBG_ERR_FUNC("reset failed!\n"); return -2; } #endif return 0; }
INT32 _stp_dbg_parser_assert_str(CHAR *str, ENUM_ASSERT_INFO_PARSER_TYPE type) { char *pStr = NULL; char *pDtr = NULL; char *pTemp = NULL; char *pTemp2 = NULL; char tempBuf[64] = {0}; UINT32 len = 0; char *parser_sub_string[] = { "<ASSERT> ", "id=", "isr=", "irq=", "rc=" }; if (!str) { STP_DBG_ERR_FUNC("NULL string source\n"); return -1; } if (!g_stp_dbg_cpupcr) { STP_DBG_ERR_FUNC("NULL pointer\n"); return -2; } pStr = str; STP_DBG_DBG_FUNC("source infor:%s\n", pStr); switch (type) { case STP_DBG_ASSERT_INFO: pDtr = osal_strstr(pStr, parser_sub_string[type]); if (NULL != pDtr) { pDtr += osal_strlen(parser_sub_string[type]); pTemp = osal_strchr(pDtr, ' '); } else { STP_DBG_ERR_FUNC("parser str is NULL,substring(%s)\n", parser_sub_string[type]); return -3; } len = pTemp - pDtr; osal_memcpy(&g_stp_dbg_cpupcr->assert_info[0], "assert@", osal_strlen("assert@")); osal_memcpy(&g_stp_dbg_cpupcr->assert_info[osal_strlen("assert@")], pDtr, len); g_stp_dbg_cpupcr->assert_info[osal_strlen("assert@") + len] = '_'; pTemp = osal_strchr(pDtr, '#'); pTemp += 1; pTemp2 = osal_strchr(pTemp, ' '); osal_memcpy(&g_stp_dbg_cpupcr->assert_info[osal_strlen("assert@") + len + 1], pTemp, pTemp2 - pTemp); g_stp_dbg_cpupcr->assert_info[osal_strlen("assert@") + len + 1 + pTemp2 - pTemp] = '\0'; STP_DBG_INFO_FUNC("assert info:%s\n", &g_stp_dbg_cpupcr->assert_info[0]); break; case STP_DBG_FW_TASK_ID: pDtr = osal_strstr(pStr, parser_sub_string[type]); if (NULL != pDtr) { pDtr += osal_strlen(parser_sub_string[type]); pTemp = osal_strchr(pDtr, ' '); } else { STP_DBG_ERR_FUNC("parser str is NULL,substring(%s)\n", parser_sub_string[type]); return -3; } len = pTemp - pDtr; osal_memcpy(&tempBuf[0], pDtr, len); tempBuf[len] = '\0'; g_stp_dbg_cpupcr->fwTaskId = osal_strtol(tempBuf, NULL, 16); STP_DBG_INFO_FUNC("fw task id :%x\n", (UINT32)osal_strtol(tempBuf, NULL, 16)); break; case STP_DBG_FW_ISR: pDtr = osal_strstr(pStr, parser_sub_string[type]); if (NULL != pDtr) { pDtr += osal_strlen(parser_sub_string[type]); pTemp = osal_strchr(pDtr, ','); } else { STP_DBG_ERR_FUNC("parser str is NULL,substring(%s)\n", parser_sub_string[type]); return -3; } len = pTemp - pDtr; osal_memcpy(&tempBuf[0], pDtr, len); tempBuf[len] = '\0'; g_stp_dbg_cpupcr->fwIsr = osal_strtol(tempBuf, NULL, 16); STP_DBG_INFO_FUNC("fw isr str:%x\n", (UINT32)osal_strtol(tempBuf, NULL, 16)); break; case STP_DBG_FW_IRQ: pDtr = osal_strstr(pStr, parser_sub_string[type]); if (NULL != pDtr) { pDtr += osal_strlen(parser_sub_string[type]); pTemp = osal_strchr(pDtr, ','); } else { STP_DBG_ERR_FUNC("parser str is NULL,substring(%s)\n", parser_sub_string[type]); return -3; } len = pTemp - pDtr; osal_memcpy(&tempBuf[0], pDtr, len); tempBuf[len] = '\0'; g_stp_dbg_cpupcr->fwRrq = osal_strtol(tempBuf, NULL, 16); STP_DBG_INFO_FUNC("fw irq value:%x\n", (UINT32)osal_strtol(tempBuf, NULL, 16)); break; case STP_DBG_ASSERT_TYPE: pDtr = osal_strstr(pStr, parser_sub_string[type]); if (NULL != pDtr) { pDtr += osal_strlen(parser_sub_string[type]); pTemp = osal_strchr(pDtr, ','); } else { STP_DBG_ERR_FUNC("parser str is NULL,substring(%s)\n", parser_sub_string[type]); return -3; } len = pTemp - pDtr; osal_memcpy(&tempBuf[0], pDtr, len); tempBuf[len] = '\0'; if (0 == osal_memcmp(tempBuf, "*", len)) { osal_memcpy(&g_stp_dbg_cpupcr->assert_type[0], "general assert", osal_strlen("general assert")); } if (0 == osal_memcmp(tempBuf, "Watch Dog Timeout", len)) { osal_memcpy(&g_stp_dbg_cpupcr->assert_type[0], "wdt", osal_strlen("wdt")); } if (0 == osal_memcmp(tempBuf, "RB_FULL", osal_strlen("RB_FULL"))) { osal_memcpy(&g_stp_dbg_cpupcr->assert_type[0], tempBuf, len); pDtr = osal_strstr(&g_stp_dbg_cpupcr->assert_type[0], "RB_FULL("); if (NULL != pDtr) { pDtr += osal_strlen("RB_FULL("); pTemp = osal_strchr(pDtr, ')'); } else { STP_DBG_ERR_FUNC("parser str is NULL,substring(RB_FULL()\n"); return -4; } len = pTemp - pDtr; osal_memcpy(&tempBuf[0], pDtr, len); tempBuf[len] = '\0'; g_stp_dbg_cpupcr->fwTaskId = osal_strtol(tempBuf, NULL, 16); STP_DBG_INFO_FUNC("update fw task id :%x\n", (UINT32)osal_strtol(tempBuf, NULL, 16)); } STP_DBG_INFO_FUNC("fw asert type:%s\n", g_stp_dbg_cpupcr->assert_type); break; default: STP_DBG_ERR_FUNC("unknow parser type\n"); break; } return 0; }
/* wcn_compressor_in - put in a raw data, and compress L1 buffer if need * @ cprs - compressor's pointer * @ buf - raw data buffer * @ len - raw data length * @ finish - core dump finish or not, 1: finished; 0: not finish * * Retunr 0 if success, else NULL */ INT32 wcn_compressor_in(P_WCN_COMPRESSOR_T cprs, PUINT8 buf, INT32 len, INT32 finish) { INT32 tmp_len = 0; INT32 ret = 0; if (!cprs) { STP_DBG_ERR_FUNC("invalid para!\n"); return -1; } cprs->uncomp_size += len; // check L1 buf valid space if (len > (cprs->L1_buf_sz - cprs->L1_pos)) { STP_DBG_INFO_FUNC("L1 buffer full\n"); if (cprs->f_compress_en && cprs->handler) { // need compress // compress L1 buffer, and put result to L2 buffer tmp_len = cprs->L2_buf_sz - cprs->L2_pos; ret = cprs->handler(cprs->worker, cprs->L1_buf, cprs->L1_pos, &cprs->L2_buf[cprs->L2_pos], &tmp_len, finish); if (!ret) { cprs->crc32 = (crc32(cprs->crc32, cprs->L1_buf, cprs->L1_pos)); cprs->L2_pos += tmp_len; if (finish) { /* Add 8 byte suffix === 32 bits UNCOMPRESS SIZE 32 bits CRC */ *(uint32_t *)(&cprs->L2_buf[cprs->L2_pos]) = (cprs->crc32 ^ 0xffffffffUL); *(uint32_t *)(&cprs->L2_buf[cprs->L2_pos + 4]) = cprs->uncomp_size; cprs->L2_pos += 8; } STP_DBG_INFO_FUNC("compress OK!\n"); } else { STP_DBG_ERR_FUNC("compress error!\n"); } } else { // no need compress // Flush L1 buffer to L2 buffer STP_DBG_INFO_FUNC("No need do compress, Put to L2 buf\n"); tmp_len = cprs->L2_buf_sz - cprs->L2_pos; tmp_len = (cprs->L1_pos > tmp_len) ? tmp_len : cprs->L1_pos; osal_memcpy(&cprs->L2_buf[cprs->L2_pos], cprs->L1_buf, tmp_len); cprs->L2_pos += tmp_len; } // reset L1 buf pos cprs->L1_pos = 0; // put curren data to L1 buf if (len > cprs->L1_buf_sz) { STP_DBG_ERR_FUNC("len=%d, too long err!\n", len); } else { STP_DBG_INFO_FUNC("L1 Flushed, and Put %d bytes to L1 buf\n", len); osal_memcpy(&cprs->L1_buf[cprs->L1_pos], buf, len); cprs->L1_pos += len; } } else { // put to L1 buffer STP_DBG_INFO_FUNC("Put %d bytes to L1 buf\n", len); osal_memcpy(&cprs->L1_buf[cprs->L1_pos], buf, len); cprs->L1_pos += len; } return ret; }
/* wcn_compressor_init - create a compressor and do init * @ name - compressor's name * @ L1_buf_sz - L1 buffer size * @ L2_buf_sz - L2 buffer size * * Retunr object's pointer if success, else NULL */ P_WCN_COMPRESSOR_T wcn_compressor_init(PUINT8 name, INT32 L1_buf_sz, INT32 L2_buf_sz) { z_stream *pstream = NULL; P_WCN_COMPRESSOR_T compress = NULL; compress = (P_WCN_COMPRESSOR_T)osal_malloc(sizeof(WCN_COMPRESSOR_T)); if (!compress) { STP_DBG_ERR_FUNC("alloc compressor failed!\n"); goto fail; } osal_memset(compress, 0, sizeof(WCN_COMPRESSOR_T)); osal_memcpy(compress->name, name, STP_OJB_NAME_SZ); compress->f_compress_en = 0; compress->compress_type = GZIP; if (compress->compress_type == GZIP) { compress->worker = osal_malloc(sizeof(z_stream)); if (!compress->worker) { STP_DBG_ERR_FUNC("alloc stream failed!\n"); goto fail; } pstream = (z_stream*)compress->worker; pstream->workspace = osal_malloc(zlib_deflate_workspacesize(MAX_WBITS, MAX_MEM_LEVEL)); if (!pstream->workspace) { STP_DBG_ERR_FUNC("alloc workspace failed!\n"); goto fail; } zlib_deflateInit2(pstream, Z_DEFAULT_COMPRESSION, Z_DEFLATED, -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY); } compress->handler = wcn_gzip_compressor; compress->L1_buf_sz = L1_buf_sz; compress->L2_buf_sz = L2_buf_sz; compress->L1_pos = 0; compress->L2_pos = 0; compress->uncomp_size = 0; compress->crc32 = 0xffffffffUL; compress->L1_buf = osal_malloc(compress->L1_buf_sz); if (!compress->L1_buf) { STP_DBG_ERR_FUNC("alloc %d bytes for L1 buf failed!\n", compress->L1_buf_sz); goto fail; } compress->L2_buf = osal_malloc(compress->L2_buf_sz); if (!compress->L2_buf) { STP_DBG_ERR_FUNC("alloc %d bytes for L2 buf failed!\n", compress->L2_buf_sz); goto fail; } STP_DBG_INFO_FUNC("create compressor OK! L1 %d bytes, L2 %d bytes\n", L1_buf_sz, L2_buf_sz); return compress; fail: if (compress) { if (compress->L2_buf) { osal_free(compress->L2_buf); compress->L2_buf = NULL; } if (compress->L1_buf) { osal_free(compress->L1_buf); compress->L1_buf = NULL; } if (compress->worker) { pstream = (z_stream*)compress->worker; if ((compress->compress_type == GZIP) && pstream->workspace) { zlib_deflateEnd(pstream); osal_free(pstream->workspace); } osal_free(compress->worker); compress->worker = NULL; } if (compress->worker) { osal_free(compress->worker); compress->worker = NULL; } osal_free(compress); compress = NULL; } STP_DBG_ERR_FUNC("init failed!\n"); return NULL; }
INT32 stp_dbg_set_fw_info(UINT8 *issue_info, UINT32 len, ENUM_STP_FW_ISSUE_TYPE issue_type) { ENUM_ASSERT_INFO_PARSER_TYPE type_index; UINT8 *tempbuf = NULL; UINT32 i = 0; INT32 iRet = 0; if (NULL == issue_info) { STP_DBG_ERR_FUNC("null issue infor\n"); return -1; } STP_DBG_INFO_FUNC("issue type(%d)\n", issue_type); g_stp_dbg_cpupcr->issue_type = issue_type; osal_memset(&g_stp_dbg_cpupcr->assert_info[0], 0, STP_ASSERT_INFO_SIZE); if (STP_FW_ASSERT_ISSUE == issue_type) { tempbuf = osal_malloc(len); if (!tempbuf) { return -2; } osal_memcpy(&tempbuf[0], issue_info, len); for (i = 0; i < len; i++) { if (tempbuf[i] == '\0') { tempbuf[i] = '?'; } } tempbuf[len] = '\0'; #if 0 STP_DBG_INFO_FUNC("FW assert infor len(%d)\n", len); for (i = 0; i < len; i++) { if (0 == len % 64) { printk("\n"); } printk("%c", tempbuf[i]); } printk("\n"); #endif for (type_index = STP_DBG_ASSERT_INFO; type_index < STP_DBG_PARSER_TYPE_MAX; type_index ++) { iRet += _stp_dbg_parser_assert_str(&tempbuf[0], type_index); } if (iRet) { STP_DBG_ERR_FUNC("passert assert infor fail(%d)\n", iRet); } osal_free(tempbuf); } else if (STP_FW_NOACK_ISSUE == issue_type) { osal_lock_sleepable_lock(&g_stp_dbg_cpupcr->lock); osal_memcpy(&g_stp_dbg_cpupcr->assert_info[0], issue_info, len); g_stp_dbg_cpupcr->fwTaskId = 6; g_stp_dbg_cpupcr->fwRrq = 0; g_stp_dbg_cpupcr->fwIsr = 0; osal_unlock_sleepable_lock(&g_stp_dbg_cpupcr->lock); } else if (STP_DBG_PROC_TEST == issue_type) { osal_lock_sleepable_lock(&g_stp_dbg_cpupcr->lock); osal_memcpy(&g_stp_dbg_cpupcr->assert_info[0], issue_info, len); g_stp_dbg_cpupcr->fwTaskId = 0; g_stp_dbg_cpupcr->fwRrq = 0; g_stp_dbg_cpupcr->fwIsr = 0; osal_unlock_sleepable_lock(&g_stp_dbg_cpupcr->lock); } else if (STP_FW_WARM_RST_ISSUE == issue_type) { osal_lock_sleepable_lock(&g_stp_dbg_cpupcr->lock); osal_memcpy(&g_stp_dbg_cpupcr->assert_info[0], issue_info, len); g_stp_dbg_cpupcr->fwTaskId = 0; g_stp_dbg_cpupcr->fwRrq = 0; g_stp_dbg_cpupcr->fwIsr = 0; osal_unlock_sleepable_lock(&g_stp_dbg_cpupcr->lock); } else { STP_DBG_ERR_FUNC("invalid issue type(%d)\n", issue_type); return -3; } return iRet; }
INT32 stp_dbg_cpupcr_infor_format(UINT8 **buf, UINT32 *str_len) { UINT32 len = 0; UINT32 i = 0; if (!g_stp_dbg_cpupcr) { STP_DBG_ERR_FUNC("NULL pointer\n"); return -1; } /*format common information about issue*/ len = osal_sprintf(*buf, "<main>\n\t"); len += osal_sprintf(*buf + len, "<chipid>\n\t\tMT%x\n\t</chipid>\n\t", g_stp_dbg_cpupcr->chipId); len += osal_sprintf(*buf + len, "<version>\n\t\t"); len += osal_sprintf(*buf + len, "<rom>%s</rom>\n\t\t", g_stp_dbg_cpupcr->romVer); if (!(osal_memcmp(g_stp_dbg_cpupcr->branchVer, "ALPS", STP_PATCH_BRANCH_SZIE))) { len += osal_sprintf(*buf + len, "<branch>Internal Dev</branch>\n\t\t", g_stp_dbg_cpupcr->branchVer); } else { len += osal_sprintf(*buf + len, "<branch>W%sMP</branch>\n\t\t", g_stp_dbg_cpupcr->branchVer); } len += osal_sprintf(*buf + len, "<patch>%s</patch>\n\t\t", g_stp_dbg_cpupcr->patchVer); if (!g_stp_dbg_cpupcr->wifiVer[0]) { len += osal_sprintf(*buf + len, "<wifi>NULL</wifi>\n\t"); } else { len += osal_sprintf(*buf + len, "<wifi>%s</wifi>\n\t", g_stp_dbg_cpupcr->wifiVer); } len += osal_sprintf(*buf + len, "</version>\n\t"); /*format issue information: no ack, assert*/ len += osal_sprintf(*buf + len, "<issue>\n\t\t<classification>\n\t\t\t"); if ((STP_FW_NOACK_ISSUE == g_stp_dbg_cpupcr->issue_type) || (STP_DBG_PROC_TEST == g_stp_dbg_cpupcr->issue_type) || (STP_FW_WARM_RST_ISSUE == g_stp_dbg_cpupcr->issue_type)) { len += osal_sprintf(*buf + len, "%s\n\t\t</classification>\n\t\t<rc>\n\t\t\t", g_stp_dbg_cpupcr->assert_info); len += osal_sprintf(*buf + len, "NULL\n\t\t</rc>\n\t</issue>\n\t"); len += osal_sprintf(*buf + len, "<hint>\n\t\t<time_align>NULL</time_align>\n\t\t"); len += osal_sprintf(*buf + len, "<host>NULL</host>\n\t\t"); len += osal_sprintf(*buf + len, "<client>\n\t\t\t<task>%s</task>\n\t\t\t", _stp_dbg_id_to_task(g_stp_dbg_cpupcr->fwTaskId)); len += osal_sprintf(*buf + len, "<irqx>IRQ_0x%x</irqx>\n\t\t\t", g_stp_dbg_cpupcr->fwRrq); len += osal_sprintf(*buf + len, "<isr>0x%x</isr>\n\t\t\t", g_stp_dbg_cpupcr->fwIsr); } else if ((STP_FW_ASSERT_ISSUE == g_stp_dbg_cpupcr->issue_type)) { len += osal_sprintf(*buf + len, "%s\n\t\t</classification>\n\t\t<rc>\n\t\t\t", g_stp_dbg_cpupcr->assert_info); len += osal_sprintf(*buf + len, "%s\n\t\t</rc>\n\t</issue>\n\t", g_stp_dbg_cpupcr->assert_type); len += osal_sprintf(*buf + len, "<hint>\n\t\t<time_align>NULL</time_align>\n\t\t"); len += osal_sprintf(*buf + len, "<host>NULL</host>\n\t\t"); len += osal_sprintf(*buf + len, "<client>\n\t\t\t<task>%s</task>\n\t\t\t", _stp_dbg_id_to_task(g_stp_dbg_cpupcr->fwTaskId)); len += osal_sprintf(*buf + len, "<irqx>IRQ_0x%x</irqx>\n\t\t\t", g_stp_dbg_cpupcr->fwRrq); len += osal_sprintf(*buf + len, "<isr>0x%x</isr>\n\t\t\t", g_stp_dbg_cpupcr->fwIsr); } else { len += osal_sprintf(*buf + len, "NULL\n\t\t</classification>\n\t\t<rc>\n\t\t\t"); len += osal_sprintf(*buf + len, "NULL\n\t\t</rc>\n\t</issue>\n\t"); len += osal_sprintf(*buf + len, "<hint>\n\t\t<time_align>NULL</time_align>\n\t\t"); len += osal_sprintf(*buf + len, "<host>NULL</host>\n\t\t"); len += osal_sprintf(*buf + len, "<client>\n\t\t\t<task>NULL</task>\n\t\t\t"); len += osal_sprintf(*buf + len, "<irqx>NULL</irqx>\n\t\t\t"); len += osal_sprintf(*buf + len, "<isr>NULL</isr>\n\t\t\t"); } len += osal_sprintf(*buf + len, "<pctrace>"); STP_DBG_INFO_FUNC("stp-dbg:sub len1 for debug(%d)\n", len); if (!g_stp_dbg_cpupcr->count) { len += osal_sprintf(*buf + len, "NULL"); } else { for (i = 0; i < g_stp_dbg_cpupcr->count; i++) { len += osal_sprintf(*buf + len, "%08x,", g_stp_dbg_cpupcr->buffer[i]); } } STP_DBG_INFO_FUNC("stp-dbg:sub len2 for debug(%d)\n", len); len += osal_sprintf(*buf + len, "</pctrace>\n\t\t\t"); len += osal_sprintf(*buf + len, "<extension>NULL</extension>\n\t\t</client>\n\t</hint>\n</main>\n"); STP_DBG_INFO_FUNC("buffer len[%d]\n", len); //STP_DBG_INFO_FUNC("Format infor:\n%s\n",*buf); *str_len = len; osal_memset(&g_stp_dbg_cpupcr->buffer[0], 0, STP_DBG_CPUPCR_NUM); g_stp_dbg_cpupcr->count = 0; return 0; }
/* wcn_core_dump_in - add a packet to compressor buffer * @ dmp - pointer of object * @ buf - input buffer * @ len - data length * * Retunr 0 if success; return 1 if find end string; else error code */ INT32 wcn_core_dump_in(P_WCN_CORE_DUMP_T dmp, PUINT8 buf, INT32 len) { INT32 ret = 0; INT32 tmp; #define INFO_HEAD "MT6628 FW CORE, " if ((!dmp) || (!buf)) { STP_DBG_ERR_FUNC("invalid pointer!\n"); return -1; } ret = osal_lock_sleepable_lock(&dmp->dmp_lock); if (ret) { STP_DBG_ERR_FUNC("--->lock dmp->dmp_lock failed, ret=%d\n", ret); return ret; } switch (dmp->sm) { case CORE_DUMP_INIT: wcn_compressor_reset(dmp->compressor, 1, GZIP); osal_timer_start(&dmp->dmp_timer, STP_CORE_DUMP_TIMEOUT); // first package, copy to info buffer osal_strcpy(&dmp->info[0], INFO_HEAD); tmp = STP_CORE_DUMP_INFO_SZ - osal_strlen(INFO_HEAD); tmp = (len > tmp) ? tmp : len; osal_memcpy(&dmp->info[osal_strlen(INFO_HEAD)], buf, tmp); dmp->info[STP_CORE_DUMP_INFO_SZ] = '\0'; // show coredump start info on UI //osal_dbg_assert_aee("MT662x f/w coredump start", "MT662x firmware coredump start"); aee_kernel_dal_show("MT662x coredump start, please wait up to 5 minutes.\n"); // parsing data, and check end srting ret = wcn_core_dump_check_end(buf, len); if (ret == 1) { STP_DBG_INFO_FUNC("core dump end!\n"); dmp->sm = CORE_DUMP_DONE; wcn_compressor_in(dmp->compressor, buf, len, 1); } else { dmp->sm = CORE_DUMP_DOING; wcn_compressor_in(dmp->compressor, buf, len, 0); } break; case CORE_DUMP_DOING: // parsing data, and check end srting ret = wcn_core_dump_check_end(buf, len); if (ret == 1) { STP_DBG_INFO_FUNC("core dump end!\n"); dmp->sm = CORE_DUMP_DONE; wcn_compressor_in(dmp->compressor, buf, len, 1); } else { dmp->sm = CORE_DUMP_DOING; wcn_compressor_in(dmp->compressor, buf, len, 0); } break; case CORE_DUMP_DONE: wcn_compressor_reset(dmp->compressor, 1, GZIP); osal_timer_start(&dmp->dmp_timer, STP_CORE_DUMP_TIMEOUT); wcn_compressor_in(dmp->compressor, buf, len, 0); dmp->sm = CORE_DUMP_DOING; break; case CORE_DUMP_TIMEOUT: break; default: break; } osal_unlock_sleepable_lock(&dmp->dmp_lock); return ret; }