예제 #1
0
INT32 wmt_ctrl_get_patch_info(P_WMT_CTRL_DATA pWmtCtrlData)
{
	P_DEV_WMT pDev = &gDevWmt; /* single instance */
	UINT32 downLoadSeq = 0;
	P_WMT_PATCH_INFO pPatchinfo = NULL;
	PUCHAR pNbuf = NULL;
	PUCHAR pAbuf =NULL;
	
	downLoadSeq = pWmtCtrlData->au4CtrlData[0];
	WMT_DBG_FUNC("download seq is %d\n",downLoadSeq);

	pPatchinfo = pDev->pWmtPatchInfo + downLoadSeq - 1;
	pNbuf = (PUCHAR)pWmtCtrlData->au4CtrlData[1];
	pAbuf = (PUCHAR)pWmtCtrlData->au4CtrlData[2];
	if(pPatchinfo)
	{
		osal_memcpy(pNbuf,pPatchinfo->patchName,osal_sizeof(pPatchinfo->patchName));
		osal_memcpy(pAbuf,pPatchinfo->addRess,osal_sizeof(pPatchinfo->addRess));
		WMT_DBG_FUNC("get 4 address bytes is 0x%2x,0x%2x,0x%2x,0x%2x",pAbuf[0],pAbuf[1],pAbuf[2],pAbuf[3]);
	}
	else
	{
		WMT_ERR_FUNC("NULL patchinfo pointer\n");
	}

	return 0;
}
예제 #2
0
INT32 wmt_conf_read_file(VOID)
{
	INT32 ret = -1;

	osal_memset(&gDevWmt.rWmtGenConf, 0, osal_sizeof(gDevWmt.rWmtGenConf));
	osal_memset(&gDevWmt.pWmtCfg, 0, osal_sizeof(gDevWmt.pWmtCfg));

#if 1
	osal_memset(&gDevWmt.cWmtcfgName[0], 0, osal_sizeof(gDevWmt.cWmtcfgName));

	osal_strncat(&(gDevWmt.cWmtcfgName[0]), CUST_CFG_WMT_PREFIX, osal_sizeof(CUST_CFG_WMT_PREFIX));
	osal_strncat(&(gDevWmt.cWmtcfgName[0]), CUST_CFG_WMT, osal_sizeof(CUST_CFG_WMT));
#endif

	if (!osal_strlen(&(gDevWmt.cWmtcfgName[0]))) {
		WMT_ERR_FUNC("empty Wmtcfg name\n");
		osal_assert(0);
		return ret;
	}
	WMT_INFO_FUNC("WMT config file:%s\n", &(gDevWmt.cWmtcfgName[0]));
	if (0 == wmt_dev_patch_get(&gDevWmt.cWmtcfgName[0], (osal_firmware **) &gDevWmt.pWmtCfg, 0)) {
		/*get full name patch success */
		WMT_INFO_FUNC("get full file name(%s) buf(0x%p) size(%d)\n",
			      &gDevWmt.cWmtcfgName[0], gDevWmt.pWmtCfg->data, gDevWmt.pWmtCfg->size);

		if (0 == wmt_conf_parse(&gDevWmt, (const PINT8)gDevWmt.pWmtCfg->data, gDevWmt.pWmtCfg->size)) {
			/*config file exists */
			gDevWmt.rWmtGenConf.cfgExist = 1;

			WMT_INFO_FUNC("&gDevWmt.rWmtGenConf=%p\n", &gDevWmt.rWmtGenConf);
			ret = 0;
		} else {
			WMT_ERR_FUNC("wmt conf parsing fail\n");
			osal_assert(0);
			ret = -1;
		}
		wmt_dev_patch_put((osal_firmware **) &gDevWmt.pWmtCfg);
/*
	if (gDevWmt.pWmtCfg)
	{
	    if (gDevWmt.pWmtCfg->data)
	    {
		osal_free(gDevWmt.pWmtCfg->data);
	    }
	    osal_free(gDevWmt.pWmtCfg);
	    gDevWmt.pWmtCfg = 0;
	}
*/
		return ret;
	} else {
		WMT_ERR_FUNC("read %s file fails\n", &(gDevWmt.cWmtcfgName[0]));
		osal_assert(0);

		gDevWmt.rWmtGenConf.cfgExist = 0;
		return ret;
	}
}
예제 #3
0
INT32
mtk_wcn_cmb_hw_init (
    P_PWR_SEQ_TIME pPwrSeqTime
    )
{
    if (NULL != pPwrSeqTime            && 
        pPwrSeqTime->ldoStableTime > 0 &&
        pPwrSeqTime->rtcStableTime > 0 &&
        pPwrSeqTime->offStableTime > DFT_OFF_STABLE_TIME &&
        pPwrSeqTime->onStableTime  > DFT_ON_STABLE_TIME  &&
        pPwrSeqTime->rstStableTime > DFT_RST_STABLE_TIME
    ) {
        /*memcpy may be more performance*/
        WMT_DBG_FUNC("setting hw init sequence parameters\n");
        osal_memcpy(&gPwrSeqTime, pPwrSeqTime, osal_sizeof(gPwrSeqTime));
    }
    else {    
        WMT_WARN_FUNC("invalid pPwrSeqTime parameter, use default hw init sequence parameters\n");
        gPwrSeqTime.ldoStableTime = DFT_LDO_STABLE_TIME;
        gPwrSeqTime.offStableTime = DFT_OFF_STABLE_TIME;
        gPwrSeqTime.onStableTime = DFT_ON_STABLE_TIME;
        gPwrSeqTime.rstStableTime = DFT_RST_STABLE_TIME;
        gPwrSeqTime.rtcStableTime = DFT_RTC_STABLE_TIME;
    }
    mtk_wcn_cmb_hw_dmp_seq();
    return 0;
}
예제 #4
0
INT32 wmt_conf_set_cfg_file(const char *name)
{
	if (NULL == name) {
		WMT_ERR_FUNC("name is NULL\n");
		return -1;
	}
	if (osal_strlen(name) >= osal_sizeof(gDevWmt.cWmtcfgName)) {
		WMT_ERR_FUNC("name is too long, length=%d, expect to < %d\n", osal_strlen(name),
			     osal_sizeof(gDevWmt.cWmtcfgName));
		return -2;
	}
	osal_memset(&gDevWmt.cWmtcfgName[0], 0, osal_sizeof(gDevWmt.cWmtcfgName));
	osal_strcpy(&(gDevWmt.cWmtcfgName[0]), name);
	WMT_ERR_FUNC("WMT config file is set to (%s)\n", &(gDevWmt.cWmtcfgName[0]));

	return 0;
}
예제 #5
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;
}
예제 #6
0
INT32 wmt_idc_deinit(VOID)
{
	INT32 iRet;

	iRet = mtk_conn_md_bridge_unreg(gWmtIdcInfo.iit.src_mod_id);
	if (iRet)
		WMT_ERR_FUNC("mtk_conn_md_bridge_unreg fail(%d)\n", iRet);

	osal_memset(&gWmtIdcInfo, 0, osal_sizeof(gWmtIdcInfo));

	return 0;
}
예제 #7
0
static INT32 wmt_dev_dbg_write(struct file *file, const CHAR *buffer, ULONG count, VOID *data){

    CHAR buf[256];
    CHAR *pBuf;
    ULONG len = count;

    WMT_INFO_FUNC("write parameter len = %d\n\r", (int)len);
    if (len >= osal_sizeof(buf)){
        WMT_ERR_FUNC("input handling fail!\n");
        len = osal_sizeof(buf) - 1;
        return -1;
    }

    if (copy_from_user(buf,buffer,len)/*copy_from_user(buf, buffer, len)*/){
        return -EFAULT;
    }
    buf[len] = '\0';
    WMT_INFO_FUNC("write parameter data = %s\n\r", buf);
    pBuf = buf;
    wmt_dbg_proc_write(pBuf);
    return len;
}
예제 #8
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 = 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;
}
예제 #9
0
INT32 wmt_idc_init(VOID)
{
	INT32 iRet;

	osal_memset(&gWmtIdcInfo, 0, osal_sizeof(gWmtIdcInfo));
	gWmtIdcInfo.iit.src_mod_id = AP_MOD_WMT;
	gWmtIdcInfo.iit.dest_mod_id = MD_MOD_EL1;
	gWmtIdcInfo.iit.sap_id = 0;
	gWmtIdcInfo.ops.rx_cb = wmt_idc_msg_from_lte_handing;

	iRet = mtk_conn_md_bridge_reg(gWmtIdcInfo.iit.src_mod_id, &gWmtIdcInfo.ops);
	if (iRet) {
		WMT_ERR_FUNC("mtk_conn_md_bridge_reg fail(%d)\n", iRet);
		return -1;
	}
	/* mtk_wcn_stp_flush_rx_queue(COEX_TASK_INDX); */
	return 0;

}
예제 #10
0
static INT32 _stp_dbg_disable (MTKSTP_DBG_T *stp_dbg)
{
    osal_lock_unsleepable_lock(&(stp_dbg->logsys->lock));
    stp_dbg->pkt_trace_no = 0;

    /* [FIXME][George] DANGEROUS CODING to MEMSET A STRUCTURE in a NON-INIT
     * or a NON-DEINIT CONTEXT!!!
     */
#if 0
    osal_memset(stp_dbg->logsys,0,osal_sizeof(MTKSTP_LOG_SYS_T));
#else
    osal_memset(&stp_dbg->logsys->queue[0], 0x0, sizeof(stp_dbg->logsys->queue));
    stp_dbg->logsys->size = 0;
    stp_dbg->logsys->in = 0;
    stp_dbg->logsys->out = 0;
#endif
    stp_dbg->is_enable = 0;
    osal_unlock_unsleepable_lock(&(stp_dbg->logsys->lock));

    return 0;
}
예제 #11
0
UINT32 wmt_idc_msg_to_lte_handing_for_test(UINT8 *p_buf, UINT32 len)
{
	UINT32 readlen = len;
	local_para_struct *p_lps = NULL;
	UINT8 *p_data = NULL;
	UINT8 opcode = 0;
	UINT16 msg_len = 0;
	UINT32 handle_len = 0;
	MTK_WCN_BOOL unknow_msgid = MTK_WCN_BOOL_FALSE;

	osal_memcpy(&gWmtIdcInfo.buffer[0], p_buf, len);

	if (readlen > 0) {
		WMT_DBG_FUNC("read data len from fw(%d)\n", 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;

				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_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);
				}
				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 handle_len;
}
예제 #12
0
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;
}
예제 #13
0
INT32  wmt_ctrl_get_patch_name(P_WMT_CTRL_DATA pWmtCtrlData)
{
    PUCHAR pBuf = (PUCHAR)pWmtCtrlData->au4CtrlData[0];
    osal_memcpy(pBuf, gDevWmt.cPatchName, osal_sizeof(gDevWmt.cPatchName));
    return 0;
}
예제 #14
0
static int wmt_dev_dbg_write(struct file *file, const char *buffer, unsigned long count, void *data){
    
    CHAR buf[256];
    CHAR *pBuf;
    ULONG len = count;
    INT32 x = 0,y = 0, z=0;
    CHAR *pToken = NULL;
    CHAR *pDelimiter = " \t";

    WMT_INFO_FUNC("write parameter len = %d\n\r", (int)len);
    if(len >= osal_sizeof(buf)){
        WMT_ERR_FUNC("input handling fail!\n");
        len = osal_sizeof(buf) - 1;
        return -1;
    }    
    
    if(copy_from_user(buf, buffer, len)){
        return -EFAULT;
    }
    buf[len] = '\0';
    WMT_INFO_FUNC("write parameter data = %s\n\r", buf);

    pBuf = buf;
    pToken = osal_strsep(&pBuf, pDelimiter);
    x = NULL != pToken ? osal_strtol(pToken, NULL, 16) : 0; 

    pToken = osal_strsep(&pBuf, "\t\n ");
    if(pToken != NULL){
        y = osal_strtol(pToken, NULL, 16);
        WMT_INFO_FUNC("y = 0x%08x \n\r", y);
    } else {
        y = 3000;
         /*efuse, register read write default value*/
        if(0x11 == x || 0x12 == x || 0x13 == x) {
            y = 0x80000000;
        }
    }

    pToken = osal_strsep(&pBuf, "\t\n ");
    if(pToken != NULL){
        z = osal_strtol(pToken, NULL, 16);
    } else {
        z = 10;
        /*efuse, register read write default value*/
        if(0x11 == x || 0x12 == x || 0x13 == x) {
            z = 0xffffffff;
        }
    }
    
    WMT_INFO_FUNC("x(0x%08x), y(0x%08x), z(0x%08x)\n\r", x, y, z);

    if (osal_array_size(wmt_dev_dbg_func) > x && NULL != wmt_dev_dbg_func[x])
    {
        (*wmt_dev_dbg_func[x])(x, y, z);
    }
    else
    {
        WMT_WARN_FUNC("no handler defined for command id(0x%08x)\n\r", x);
    }
    return len;
}
예제 #15
0
INT32 wmt_dbg_cmd_test_api(ENUM_WMTDRV_CMD_T cmd)
{
    
    P_OSAL_OP pOp = NULL;
    MTK_WCN_BOOL bRet = MTK_WCN_BOOL_FALSE;
    P_OSAL_SIGNAL pSignal;
    
    pOp  = wmt_lib_get_free_op();
    if (!pOp ) {
        WMT_WARN_FUNC("get_free_lxop fail\n");
        return MTK_WCN_BOOL_FALSE;
    }

    pSignal = &pOp ->signal;

    pOp ->op.opId = WMT_OPID_CMD_TEST;
    
    pSignal->timeoutValue= MAX_EACH_WMT_CMD;
    /*this test command should be run with usb cable connected, so no host awake is needed*/
    //wmt_lib_host_awake_get();
    switch (cmd)
    {
        case WMTDRV_CMD_ASSERT:
            pOp->op.au4OpData[0] = 0;
        break;
        case WMTDRV_CMD_EXCEPTION:
            pOp->op.au4OpData[0] = 1;
        break;
        default:
            if (WMTDRV_CMD_COEXDBG_00 <= cmd && WMTDRV_CMD_COEXDBG_15 >= cmd)
            {
                pOp->op.au4OpData[0] = 2;
                pOp->op.au4OpData[1] = cmd - 2;
            }
            else
            {
                pOp->op.au4OpData[0] = 0xff;
                pOp->op.au4OpData[1] = 0xff;
            }
            pOp->op.au4OpData[2] = (ULONG)gCoexBuf.buffer;
            pOp->op.au4OpData[3] = osal_sizeof(gCoexBuf.buffer);
        break;
    }
    WMT_INFO_FUNC("CMD_TEST, opid(%d), par(%d, %d)\n", pOp->op.opId, pOp->op.au4OpData[0], pOp->op.au4OpData[1]);
    /*wake up chip first*/
    DISABLE_PSM_MONITOR();
    bRet = wmt_lib_put_act_op(pOp);
    ENABLE_PSM_MONITOR();
    if ((cmd != WMTDRV_CMD_ASSERT) && (cmd != WMTDRV_CMD_EXCEPTION))
    {
        if (MTK_WCN_BOOL_FALSE == bRet)
        {
            gCoexBuf.availSize = 0;
        }
        else
        {
            gCoexBuf.availSize = pOp->op.au4OpData[3];
            WMT_INFO_FUNC("gCoexBuf.availSize = %d\n", gCoexBuf.availSize);
        }
    }
    //wmt_lib_host_awake_put();
    WMT_INFO_FUNC("CMD_TEST, opid (%d), par(%d, %d), ret(%d), result(%s)\n", \
    pOp->op.opId, \
    pOp->op.au4OpData[0], \
    pOp->op.au4OpData[1], \
    bRet, \
    MTK_WCN_BOOL_FALSE == bRet ? "failed" : "succeed"\
    );
    
    return 0;
}
ssize_t wmt_dbg_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos)
{

	INT32 retval = 0;
	INT32 i_ret = 0;
	CHAR *warn_msg = "no data available, please run echo 15 xx > /proc/driver/wmt_psm first\n";
	
    if(*f_pos > 0){
        retval = 0;
    } else {
        /*len = sprintf(page, "%d\n", g_psm_enable);*/
        if ( gCoexBuf.availSize <= 0)
        {
            WMT_INFO_FUNC("no data available, please run echo 15 xx > /proc/driver/wmt_psm first\n");
			retval = osal_strlen(warn_msg) + 1;
			if (count < retval)
			{
				retval = count;
			}
			i_ret = copy_to_user(buf, warn_msg, retval);
	        if (i_ret)
	        {
	        	WMT_ERR_FUNC("copy to buffer failed, ret:%d\n", retval);
	        	retval = -EFAULT;
	        	goto err_exit;
	        }
			*f_pos += retval;
        }
        else
        {
            INT32 i = 0;
			INT32 len = 0;
			CHAR msg_info[128];
			INT32 max_num = 0;
            /*we do not check page buffer, because there are only 100 bytes in g_coex_buf, no reason page buffer is not enough, a bomb is placed here on unexpected condition*/
			
			WMT_INFO_FUNC("%d bytes avaliable\n", gCoexBuf.availSize);
			max_num = ((osal_sizeof(msg_info) > count ? osal_sizeof(msg_info) : count) -1) / 5;
			
			if (max_num > gCoexBuf.availSize)
			{
				max_num = gCoexBuf.availSize;
			}
			else
			{
				WMT_INFO_FUNC("round to %d bytes due to local buffer size limitation\n", max_num);
			}
			
			
			for (i = 0; i < max_num; i++)
            {
                len += osal_sprintf(msg_info + len, "0x%02x ", gCoexBuf.buffer[i]);
            }
			
			len += osal_sprintf(msg_info + len, "\n");
			retval = len;
			
			i_ret = copy_to_user(buf, msg_info, retval);
	        if (i_ret)
	        {
	        	WMT_ERR_FUNC("copy to buffer failed, ret:%d\n", retval);
	        	retval = -EFAULT;
	        	goto err_exit;
	        }
			*f_pos += retval;
            
        }
    }
    gCoexBuf.availSize = 0;
err_exit:

    return retval;
}