Exemple #1
0
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;
}