static inline INT32 _stp_btm_notify_wmt_dmp_wq(MTKSTP_BTM_T *stp_btm) { P_OSAL_OP pOp; INT32 bRet; INT32 retval; if (stp_btm == NULL) { return STP_BTM_OPERATION_FAIL; } else { pOp = _stp_btm_get_free_op(stp_btm); if (!pOp) { STP_BTM_DBG_FUNC("get_free_lxop fail\n"); return -1; /* break; */ } pOp->op.opId = STP_OPID_BTM_DBG_DUMP; pOp->signal.timeoutValue = 0; bRet = _stp_btm_put_act_op(stp_btm, pOp); STP_BTM_DBG_FUNC("OPID(%d) type(%d) bRet(%d)\n\n", pOp->op.opId, pOp->op.au4OpData[0], bRet); retval = (0 == bRet) ? STP_BTM_OPERATION_FAIL : STP_BTM_OPERATION_SUCCESS; if (!retval) mtk_wcn_stp_coredump_start_ctrl(1); } return retval; }
static INT32 _stp_btm_proc (void *pvData) { MTKSTP_BTM_T *stp_btm = (MTKSTP_BTM_T *)pvData; P_OSAL_OP pOp; INT32 id; INT32 result; if (!stp_btm) { STP_BTM_WARN_FUNC("!stp_btm \n"); return -1; } for (;;) { pOp = NULL; osal_wait_for_event(&stp_btm->STPd_event, _stp_btm_wait_for_msg, (void *)stp_btm ); if (osal_thread_should_stop(&stp_btm->BTMd)) { STP_BTM_INFO_FUNC("should stop now... \n"); // TODO: clean up active opQ break; } /* get Op from activeQ */ pOp = _stp_btm_get_op(stp_btm, &stp_btm->rActiveOpQ); if (!pOp) { STP_BTM_WARN_FUNC("get_lxop activeQ fail\n"); continue; } id = osal_op_get_id(pOp); STP_BTM_DBG_FUNC("======> lxop_get_opid = %d, %s, remaining count = *%d*\n", id, (id >= osal_array_size(g_btm_op_name))?("???"):(g_btm_op_name[id]), RB_COUNT(&stp_btm->rActiveOpQ)); if (id >= STP_OPID_BTM_NUM) { STP_BTM_WARN_FUNC("abnormal opid id: 0x%x \n", id); result = -1; goto handler_done; } result = _stp_btm_handler(stp_btm, &pOp->op); handler_done: if (result) { STP_BTM_WARN_FUNC("opid id(0x%x)(%s) error(%d)\n", id, (id >= osal_array_size(g_btm_op_name))?("???"):(g_btm_op_name[id]), result); } if (osal_op_is_wait_for_signal(pOp)) { osal_op_raise_signal(pOp, result); } else { /* put Op back to freeQ */ _stp_btm_put_op(stp_btm, &stp_btm->rFreeOpQ, pOp); } if (STP_OPID_BTM_EXIT == id) { break; } else if (STP_OPID_BTM_RST == id) { /* prevent multi reset case */ stp_btm_reset_btm_wq(stp_btm); mtk_wcn_stp_coredump_start_ctrl(0); } } STP_BTM_INFO_FUNC("exits \n"); return 0; };
//INT32 WMT_ioctl(struct inode *inode, struct file *filp, UINT32 cmd, unsigned long arg) long WMT_unlocked_ioctl ( struct file *filp, unsigned int cmd, unsigned long arg ) { #define WMT_IOC_MAGIC 0xa0 #define WMT_IOCTL_PORT_NAME _IOWR(WMT_IOC_MAGIC, 20, char*) #define WMT_IOCTL_WMT_CFG_NAME _IOWR(WMT_IOC_MAGIC, 21, char*) #define WMT_IOCTL_WMT_QUERY_CHIPID _IOR(WMT_IOC_MAGIC, 22, int) #define WMT_IOCTL_WMT_TELL_CHIPID _IOW(WMT_IOC_MAGIC, 23, int) #define WMT_IOCTL_WMT_COREDUMP_CTRL _IOW(WMT_IOC_MAGIC, 24, int) INT32 iRet = 0; UCHAR pBuffer[NAME_MAX + 1]; WMT_DBG_FUNC("cmd (%u), arg (0x%lx)\n", cmd, arg); switch(cmd) { case 4: /* patch location */ { if (copy_from_user(pBuffer, (void *)arg, NAME_MAX)) { iRet = -EFAULT; break; } pBuffer[NAME_MAX] = '\0'; wmt_lib_set_patch_name(pBuffer); } break; case 5: /* stp/hif/fm mode */ /* set hif conf */ do { P_OSAL_OP pOp; MTK_WCN_BOOL bRet; P_OSAL_SIGNAL pSignal = NULL; P_WMT_HIF_CONF pHif = NULL; iRet = wmt_lib_set_hif(arg); if (0 != iRet) { WMT_INFO_FUNC("wmt_lib_set_hif fail\n"); break; } pOp = wmt_lib_get_free_op(); if (!pOp) { WMT_INFO_FUNC("get_free_lxop fail\n"); break; } pSignal = &pOp->signal; pOp->op.opId = WMT_OPID_HIF_CONF; pHif = wmt_lib_get_hif(); osal_memcpy(&pOp->op.au4OpData[0], pHif, sizeof(WMT_HIF_CONF)); pOp->op.u4InfoBit = WMT_OP_HIF_BIT; pSignal->timeoutValue = 0; bRet = wmt_lib_put_act_op(pOp); WMT_DBG_FUNC("WMT_OPID_HIF_CONF result(%d) \n", bRet); iRet = (MTK_WCN_BOOL_FALSE == bRet) ? -EFAULT : 0; } while (0); break; case 6: /* test turn on/off func */ do { MTK_WCN_BOOL bRet = MTK_WCN_BOOL_FALSE; if (arg & 0x80000000) { bRet = mtk_wcn_wmt_func_on(arg & 0xF); } else { bRet = mtk_wcn_wmt_func_off(arg & 0xF); } iRet = (MTK_WCN_BOOL_FALSE == bRet) ? -EFAULT : 0; } while (0); break; case 7: /*switch Loopback function on/off arg: bit0 = 1:turn loopback function on bit0 = 0:turn loopback function off */ do{ MTK_WCN_BOOL bRet = MTK_WCN_BOOL_FALSE; if (arg & 0x01) { bRet = mtk_wcn_wmt_func_on(WMTDRV_TYPE_LPBK); } else { bRet = mtk_wcn_wmt_func_off(WMTDRV_TYPE_LPBK); } iRet = (MTK_WCN_BOOL_FALSE == bRet) ? -EFAULT : 0; }while(0); break; case 8: do { P_OSAL_OP pOp; MTK_WCN_BOOL bRet; UINT32 u4Wait; //UINT8 lpbk_buf[1024] = {0}; UINT32 effectiveLen = 0; P_OSAL_SIGNAL pSignal = NULL; if (copy_from_user(&effectiveLen, (void *)arg, sizeof(effectiveLen))) { iRet = -EFAULT; WMT_ERR_FUNC("copy_from_user failed at %d\n", __LINE__); break; } if(effectiveLen > sizeof(gLpbkBuf)) { iRet = -EFAULT; WMT_ERR_FUNC("length is too long\n"); break; } WMT_DBG_FUNC("len = %d\n", effectiveLen); pOp = wmt_lib_get_free_op(); if (!pOp) { WMT_WARN_FUNC("get_free_lxop fail \n"); iRet = -EFAULT; break; } u4Wait = 2000; if (copy_from_user(&gLpbkBuf[0], (void *)arg + sizeof(unsigned long), effectiveLen)) { WMT_ERR_FUNC("copy_from_user failed at %d\n", __LINE__); iRet = -EFAULT; break; } pSignal = &pOp->signal; pOp->op.opId = WMT_OPID_LPBK; pOp->op.au4OpData[0] = effectiveLen; //packet length pOp->op.au4OpData[1] = (UINT32)&gLpbkBuf[0]; //packet buffer pointer memcpy(&gLpbkBufLog, &gLpbkBuf[((effectiveLen >=4) ? effectiveLen-4:0)], 4); pSignal->timeoutValue = MAX_EACH_WMT_CMD; WMT_INFO_FUNC("OPID(%d) type(%d) start\n", pOp->op.opId, pOp->op.au4OpData[0]); if (DISABLE_PSM_MONITOR()) { WMT_ERR_FUNC("wake up failed\n"); wmt_lib_put_op_to_free_queue(pOp); return -1; } bRet = wmt_lib_put_act_op(pOp); ENABLE_PSM_MONITOR(); if (MTK_WCN_BOOL_FALSE == bRet) { WMT_WARN_FUNC("OPID(%d) type(%d) buf tail(0x%08x) fail\n", pOp->op.opId, pOp->op.au4OpData[0], gLpbkBufLog); iRet = -1; break; } else { WMT_INFO_FUNC("OPID(%d) length(%d) ok\n", pOp->op.opId, pOp->op.au4OpData[0]); iRet = pOp->op.au4OpData[0] ; if (copy_to_user((void *)arg + sizeof(ULONG) + sizeof(UCHAR[2048]), gLpbkBuf, iRet)) { iRet = -EFAULT; break; } } }while(0); break; #if 0 case 9: { #define LOG_BUF_SZ 300 UCHAR buf[LOG_BUF_SZ]; INT32 len = 0; INT32 remaining = 0; remaining = mtk_wcn_stp_btm_get_dmp(buf, &len); if(remaining == 0){ WMT_DBG_FUNC("waiting dmp \n"); wait_event_interruptible(dmp_wq, dmp_flag != 0); dmp_flag = 0; remaining = mtk_wcn_stp_btm_get_dmp(buf, &len); //WMT_INFO_FUNC("len = %d ###%s#\n", len, buf); } else { WMT_LOUD_FUNC("no waiting dmp \n"); } if(unlikely((len+sizeof(INT32)) >= LOG_BUF_SZ)){ WMT_ERR_FUNC("len is larger buffer\n"); iRet = -EFAULT; goto fail_exit; } buf[sizeof(INT32)+len]='\0'; if (copy_to_user((void *)arg, (UCHAR *)&len, sizeof(INT32))){ iRet = -EFAULT; goto fail_exit; } if (copy_to_user((void *)arg + sizeof(INT32), buf, len)){ iRet = -EFAULT; goto fail_exit; } } break; case 10: { WMT_INFO_FUNC("Enable combo trace32 dump\n"); wmt_cdev_t32dmp_enable(); WMT_INFO_FUNC("Enable STP debugging mode\n"); mtk_wcn_stp_dbg_enable(); } break; case 11: { WMT_INFO_FUNC("Disable combo trace32 dump\n"); wmt_cdev_t32dmp_disable(); WMT_INFO_FUNC("Disable STP debugging mode\n"); mtk_wcn_stp_dbg_disable(); } break; #endif case 10: { wmt_lib_host_awake_get(); mtk_wcn_stp_coredump_start_ctrl(1); osal_strcpy(pBuffer, "MT662x f/w coredump start-"); if (copy_from_user(pBuffer + osal_strlen(pBuffer), (void *)arg, NAME_MAX - osal_strlen(pBuffer))) { //osal_strcpy(pBuffer, "MT662x f/w assert core dump start"); WMT_ERR_FUNC("copy assert string failed\n"); } pBuffer[NAME_MAX] = '\0'; osal_dbg_assert_aee(pBuffer, pBuffer); } break; case 11: { osal_dbg_assert_aee("MT662x f/w coredump end", "MT662x firmware coredump ends"); wmt_lib_host_awake_put(); } break; case 12: { if (0 == arg) { return wmt_lib_get_icinfo(WMTCHIN_CHIPID); } else if (1 == arg) { return wmt_lib_get_icinfo(WMTCHIN_HWVER); } else if (2 == arg) { return wmt_lib_get_icinfo(WMTCHIN_FWVER); } } break; case 13: { if (1 == arg) { WMT_INFO_FUNC("launcher may be killed,block abnormal stp tx. \n"); wmt_lib_set_stp_wmt_last_close(1); } else { wmt_lib_set_stp_wmt_last_close(0); } } break; case 14: { pAtchNum = arg; WMT_INFO_FUNC(" get patch num from launcher = %d\n",pAtchNum); wmt_lib_set_patch_num(pAtchNum); pPatchInfo = kzalloc(sizeof(WMT_PATCH_INFO)*pAtchNum,GFP_ATOMIC); if (!pPatchInfo) { WMT_ERR_FUNC("allocate memory fail!\n"); break; } } break; case 15: { WMT_PATCH_INFO wMtPatchInfo; P_WMT_PATCH_INFO pTemp = NULL; UINT32 dWloadSeq; static UINT32 counter = 0; if (!pPatchInfo) { WMT_ERR_FUNC("NULL patch info pointer\n"); break; } if (copy_from_user(&wMtPatchInfo, (void *)arg, sizeof(WMT_PATCH_INFO))) { WMT_ERR_FUNC("copy_from_user failed at %d\n", __LINE__); iRet = -EFAULT; break; } dWloadSeq = wMtPatchInfo.dowloadSeq; WMT_DBG_FUNC("current download seq no is %d,patch name is %s,addres info is 0x%02x,0x%02x,0x%02x,0x%02x\n",dWloadSeq,wMtPatchInfo.patchName,wMtPatchInfo.addRess[0],wMtPatchInfo.addRess[1],wMtPatchInfo.addRess[2],wMtPatchInfo.addRess[3]); osal_memcpy(pPatchInfo + dWloadSeq - 1,&wMtPatchInfo,sizeof(WMT_PATCH_INFO)); pTemp = pPatchInfo + dWloadSeq - 1; if (++counter == pAtchNum) { wmt_lib_set_patch_info(pPatchInfo); counter = 0; } } break; case WMT_IOCTL_PORT_NAME: { CHAR cUartName[NAME_MAX + 1]; if (copy_from_user(cUartName, (void *)arg, NAME_MAX)) { iRet = -EFAULT; break; } cUartName[NAME_MAX] = '\0'; wmt_lib_set_uart_name(cUartName); } break; case WMT_IOCTL_WMT_CFG_NAME: { CHAR cWmtCfgName[NAME_MAX + 1]; if (copy_from_user(cWmtCfgName, (void *)arg, NAME_MAX)) { iRet = -EFAULT; break; } cWmtCfgName[NAME_MAX] = '\0'; wmt_conf_set_cfg_file(cWmtCfgName); } break; case WMT_IOCTL_WMT_QUERY_CHIPID: { iRet = mtk_wcn_hif_sdio_query_chipid(1); } break; case WMT_IOCTL_WMT_TELL_CHIPID: { iRet = mtk_wcn_hif_sdio_tell_chipid(arg); if (0x6628 == arg) { wmt_lib_merge_if_flag_ctrl(1); } else { wmt_lib_merge_if_flag_ctrl(0); } } break; case WMT_IOCTL_WMT_COREDUMP_CTRL: { if (0 == arg) { mtk_wcn_stp_coredump_flag_ctrl(0); } else { mtk_wcn_stp_coredump_flag_ctrl(1); } } break; default: iRet = -EINVAL; WMT_WARN_FUNC("unknown cmd (%d)\n", cmd); break; } return iRet; }