Exemple #1
0
static int GPS_close(struct inode *inode, struct file *file)
{
    printk("%s: major %d minor %d (pid %d)\n", __func__,
        imajor(inode),
        iminor(inode),
        current->pid
        );
	if(retflag == 1)
	{
		GPS_WARN_FUNC("whole chip resetting...\n");
		return -EPERM;
	}
    /*Flush Rx Queue*/
    mtk_wcn_stp_register_event_cb(GPS_TASK_INDX, 0x0);  // unregister event callback function
    mtk_wcn_wmt_msgcb_unreg(WMTDRV_TYPE_GPS);
    
    if (MTK_WCN_BOOL_FALSE == mtk_wcn_wmt_func_off(WMTDRV_TYPE_GPS)) {
        GPS_WARN_FUNC("WMT turn off GPS fail!\n");
        return -EIO;    //mostly, native programer does not care this return vlaue, but we still return error code.
    }
    else {       
        GPS_INFO_FUNC("WMT turn off GPS OK!\n");
    }

    return 0;
}
Exemple #2
0
static VOID wmt_plat_func_ctrl (UINT32 type, UINT32 on)
{
    if (on) {
        mtk_wcn_wmt_func_on((ENUM_WMTDRV_TYPE_T)type);
    }
    else {
        mtk_wcn_wmt_func_off((ENUM_WMTDRV_TYPE_T)type);
    }
    return;
}
static INT32 mtk_wmt_func_off_background(void)
{
	if (MTK_WCN_BOOL_FALSE == mtk_wcn_wmt_func_off(WMTDRV_TYPE_LPBK)) {
		WMT_WARN_FUNC("WMT turn off LPBK fail\n");
	}
	else
	{
		WMT_INFO_FUNC("WMT turn off LPBK suceed");
	}
	return 0;
}
static void wmt_dev_early_suspend(struct early_suspend *h)
{
    osal_lock_sleepable_lock(&g_es_lr_lock);
    g_early_suspend_flag = 1;
    osal_unlock_sleepable_lock(&g_es_lr_lock);
    WMT_INFO_FUNC("@@@@@@@@@@wmt enter early suspend@@@@@@@@@@@@@@\n");
    if (MTK_WCN_BOOL_FALSE == mtk_wcn_wmt_func_off(WMTDRV_TYPE_LPBK)) {
        WMT_WARN_FUNC("WMT turn off LPBK fail\n");
    } else {
	WMT_INFO_FUNC("WMT turn off LPBK suceed");
    }
}
Exemple #5
0
ssize_t WIFI_write(struct file * filp,
		   const char __user * buf, size_t count, loff_t * f_pos)
{
	int retval = -EIO;
	char local[4] = { 0 };
	static int opened = 0;

	down(&wr_mtx);

	if (count > 0) {
		if (0 == copy_from_user(local, buf, (count > 4) ? 4 : count)) {
			WIFI_INFO_FUNC("WIFI_write %c\n", local[0]);
			if (local[0] == '0' && opened == 1) {
/* TODO */
/* Configure the EINT pin to GPIO mode. */

				if (MTK_WCN_BOOL_FALSE ==
				    mtk_wcn_wmt_func_off(WMTDRV_TYPE_WIFI)) {
					WIFI_INFO_FUNC
					    ("WMT turn off WIFI fail!\n");
				} else {
					WIFI_INFO_FUNC
					    ("WMT turn off WIFI OK!\n");
					opened = 0;
					retval = count;
				}
			} else if (local[0] == '1') {
/* TODO */
/* Disable EINT(external interrupt), and set the GPIO to EINT mode. */

				if (MTK_WCN_BOOL_FALSE ==
				    mtk_wcn_wmt_func_on(WMTDRV_TYPE_WIFI)) {
					WIFI_WARN_FUNC
					    ("WMT turn on WIFI fail!\n");
				} else {
					opened = 1;
					retval = count;
					WIFI_INFO_FUNC
					    ("WMT turn on WIFI success!\n");
				}
			}
		}
	}

	up(&wr_mtx);
	return retval;
}
Exemple #6
0
static int BT_close(struct inode *inode, struct file *file)
{
	BT_INFO_FUNC("%s: major %d minor %d (pid %d)\n", __func__, imajor(inode), iminor(inode), current->pid);
	if (current->pid == 1)
		return 0;
	retflag = 0;
	mtk_wcn_wmt_msgcb_unreg(WMTDRV_TYPE_BT);
	mtk_wcn_stp_register_event_cb(BT_TASK_INDX, NULL);

	if (MTK_WCN_BOOL_FALSE == mtk_wcn_wmt_func_off(WMTDRV_TYPE_BT)) {
		BT_INFO_FUNC("WMT turn off BT fail!\n");
		return -EIO;	/* mostly, native programmer will not check this return value. */
	} else {
		BT_INFO_FUNC("WMT turn off BT OK!\n");
	}

	return 0;
}
static int BT_open(struct inode *inode, struct file *file)
{
	BT_INFO_FUNC("%s: major %d minor %d pid %d\n", __func__, imajor(inode), iminor(inode), current->pid);
	if (current->pid == 1)
		return 0;

	/* Turn on BT */
	if (MTK_WCN_BOOL_FALSE == mtk_wcn_wmt_func_on(WMTDRV_TYPE_BT)) {
		BT_WARN_FUNC("WMT turn on BT fail!\n");
		return -ENODEV;
	}

	BT_INFO_FUNC("WMT turn on BT OK!\n");
	rstflag = 0;

	if (mtk_wcn_stp_is_ready()) {

		mtk_wcn_stp_set_bluez(0);

		BT_INFO_FUNC("Now it's in MTK Bluetooth Mode\n");
		BT_INFO_FUNC("STP is ready!\n");

		BT_DBG_FUNC("Register BT event callback!\n");
		mtk_wcn_stp_register_event_cb(BT_TASK_INDX, BT_event_cb);
	} else {
		BT_ERR_FUNC("STP is not ready\n");
		mtk_wcn_wmt_func_off(WMTDRV_TYPE_BT);
		return -ENODEV;
	}

	BT_DBG_FUNC("Register BT reset callback!\n");
	mtk_wcn_wmt_msgcb_reg(WMTDRV_TYPE_BT, bt_cdev_rst_cb);

/* init_MUTEX(&wr_mtx); */
	sema_init(&wr_mtx, 1);
/* init_MUTEX(&rd_mtx); */
	sema_init(&rd_mtx, 1);
	BT_INFO_FUNC("%s: finish\n", __func__);

	return 0;
}
Exemple #8
0
INT32 wmt_dbg_func_ctrl(INT32 par1, INT32 par2, INT32 par3)
{
    if (WMTDRV_TYPE_WMT > par2 || WMTDRV_TYPE_LPBK == par2)
    {
        if (0 == par3)
        {
            WMT_INFO_FUNC("function off test, type(%d)\n", par2);
            mtk_wcn_wmt_func_off(par2);
        }
        else
        {
            WMT_INFO_FUNC("function on test, type(%d)\n", par2);
            mtk_wcn_wmt_func_on(par2);
        }
    }
    else
    {
        WMT_INFO_FUNC("function ctrl test, invalid type(%d)\n", par2);
    }
    return 0;    
}
static int WIFI_close(struct inode *inode, struct file *file)
{
    WIFI_INFO_FUNC("%s: major %d minor %d (pid %d)\n", __func__,
        imajor(inode),
        iminor(inode),
        current->pid
        );
    retflag = 0; 
    
    //TODO
    //Configure the EINT pin to GPIO mode.    

    if (MTK_WCN_BOOL_FALSE == mtk_wcn_wmt_func_off(WMTDRV_TYPE_WIFI)) {
        WIFI_INFO_FUNC("WMT turn off WIFI fail!\n");
        return -EIO;    //mostly, native programmer will not check this return value.
    }
    else {
        WIFI_INFO_FUNC("WMT turn off WIFI OK!\n");
    }

    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;
}
Exemple #11
0
INT32 wmt_dbg_ut_test(INT32 par1, INT32 par2, INT32 par3)
{

    INT32 i = 0;
    INT32 j = 0;
    INT32 iRet = 0;
   
    i = 20;          
    while((i--) > 0){
        WMT_INFO_FUNC("#### UT WMT and STP Function On/Off .... %d\n", i);
        j = 10;
        while((j--) > 0){
            WMT_INFO_FUNC("#### BT  On .... (%d, %d) \n", i, j);
            iRet = mtk_wcn_wmt_func_on(WMTDRV_TYPE_BT); 
            if(iRet == MTK_WCN_BOOL_FALSE){
                break;
            }
            WMT_INFO_FUNC("#### GPS On .... (%d, %d) \n", i, j);
            iRet = mtk_wcn_wmt_func_on(WMTDRV_TYPE_GPS); 
            if(iRet == MTK_WCN_BOOL_FALSE){
                break;
            }
            WMT_INFO_FUNC("#### FM  On .... (%d, %d) \n", i, j);
            iRet = mtk_wcn_wmt_func_on(WMTDRV_TYPE_FM);
            if(iRet == MTK_WCN_BOOL_FALSE){
                break;
            }
            WMT_INFO_FUNC("#### WIFI On .... (%d, %d) \n", i, j);
            iRet = mtk_wcn_wmt_func_on(WMTDRV_TYPE_WIFI); 
            if(iRet == MTK_WCN_BOOL_FALSE){
                break;
            }
            WMT_INFO_FUNC("#### BT  Off .... (%d, %d) \n", i, j);
            iRet = mtk_wcn_wmt_func_off(WMTDRV_TYPE_BT); 
            if(iRet == MTK_WCN_BOOL_FALSE){
                break;
            }
            WMT_INFO_FUNC("#### GPS  Off ....(%d, %d) \n", i, j);
            iRet = mtk_wcn_wmt_func_off(WMTDRV_TYPE_GPS); 
            if(iRet == MTK_WCN_BOOL_FALSE){
                break;
            }
            WMT_INFO_FUNC("#### FM  Off .... (%d, %d) \n", i, j);
            iRet = mtk_wcn_wmt_func_off(WMTDRV_TYPE_FM); 
            if(iRet == MTK_WCN_BOOL_FALSE){
                break;
            }
            WMT_INFO_FUNC("#### WIFI  Off ....(%d, %d) \n", i, j);
            iRet = mtk_wcn_wmt_func_off(WMTDRV_TYPE_WIFI);           
            if(iRet == MTK_WCN_BOOL_FALSE){
                break;
            }
        }
        if(iRet == MTK_WCN_BOOL_FALSE){
                break;
        }          
    }
    if(iRet == MTK_WCN_BOOL_FALSE){
        WMT_INFO_FUNC("#### UT FAIL!!\n");
    } else {
        WMT_INFO_FUNC("#### UT PASS!!\n");
    }
    return iRet;        
}
Exemple #12
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
    )
{
    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 0
        WMT_DBG_FUNC("old patch file: %s \n", pWmtDevCtx->cPatchName);
        if (copy_from_user(pWmtDevCtx->cPatchName, (void *)arg, NAME_MAX)) {
            iRet = -EFAULT;
            break;
        }
        pWmtDevCtx->cPatchName[NAME_MAX] = '\0';
        WMT_DBG_FUNC("new patch file name: %s \n", pWmtDevCtx->cPatchName);
#endif
            UCHAR cPatchName[NAME_MAX + 1];
            if (copy_from_user(cPatchName, (void *)arg, NAME_MAX)) {
                iRet = -EFAULT;
                break;
            }
            cPatchName[NAME_MAX] = '\0';
            wmt_lib_set_patch_name(cPatchName);
        }
        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]);
            DISABLE_PSM_MONITOR();
            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();
			#if 0
            P_OSAL_OP pOp;
            MTK_WCN_BOOL bRet;
            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_FUNC_ON;
            pOp->op.au4OpData[0] = WMTDRV_TYPE_COREDUMP;
            pSignal->timeoutValue= 0;
            WMT_INFO_FUNC("OPID(%d) type(%d) start\n",
                   pOp->op.opId,
                   pOp->op.au4OpData[0]);
            /*do not check return value, we will do this either way*/
            
            /*wake up chip first*/
            DISABLE_PSM_MONITOR();
            bRet = wmt_lib_put_act_op(pOp);
            ENABLE_PSM_MONITOR();
            //wmt_lib_host_awake_put();
            
            if (MTK_WCN_BOOL_FALSE == bRet) {
                WMT_WARN_FUNC("OPID(%d) type(%d) fail\n",
                    pOp->op.opId,
                    pOp->op.au4OpData[0]);
            }
            else {
                    WMT_INFO_FUNC("OPID(%d) type(%d) ok\n",
                    pOp->op.opId,
                    pOp->op.au4OpData[0]);
            }
			#endif
			osal_strcpy(pBuffer, "MT662x f/w coredump start-");
            if (copy_from_user(pBuffer + osal_strlen(pBuffer), (void *)arg, NAME_MAX)) {
                //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;
#ifdef MTK_MULTI_PATCH_SUPPORT
		case 14:
		{

				pAtchNum = arg;
				WMT_DBG_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;
#endif
    default:
        iRet = -EINVAL;
        WMT_WARN_FUNC("unknown cmd (%d)\n", cmd);
        break;
    }


    return iRet;
}
Exemple #13
0
ssize_t WIFI_write(struct file *filp, const char __user *buf, size_t count, loff_t *f_pos)
{
    INT32 retval = -EIO;
    INT8 local[12] = {0};
    struct net_device *netdev = NULL;
    PARAM_CUSTOM_P2P_SET_STRUC_T p2pmode;
    INT32 wait_cnt = 0;

    down(&wr_mtx);
    if (count <= 0) {
        WIFI_ERR_FUNC("WIFI_write invalid param\n");
        goto done;
    }

    if (0 == copy_from_user(local, buf, (count > sizeof(local)) ? sizeof(local) : count)) {
        local[11] = 0;
        WIFI_INFO_FUNC("WIFI_write %s\n", local);

        if (local[0] == '0') {
            if (powered == 0) {
                WIFI_INFO_FUNC("WIFI is already power off!\n");
                retval = count;
                wlan_mode = WLAN_MODE_HALT;
                goto done;
            }

            netdev = dev_get_by_name(&init_net, ifname);
            if (netdev == NULL) {
                WIFI_ERR_FUNC("Fail to get %s net device\n", ifname);
            }
            else {
                p2pmode.u4Enable = 0;
                p2pmode.u4Mode = 0;

                if (pf_set_p2p_mode) {
                    if (pf_set_p2p_mode(netdev, p2pmode) != 0){
                        WIFI_ERR_FUNC("Turn off p2p/ap mode fail");
                    } else {
                        WIFI_INFO_FUNC("Turn off p2p/ap mode");
                        wlan_mode = WLAN_MODE_HALT;
                    }
               }
               dev_put(netdev);
               netdev = NULL;
            }

            if (MTK_WCN_BOOL_FALSE == mtk_wcn_wmt_func_off(WMTDRV_TYPE_WIFI)) {
                WIFI_ERR_FUNC("WMT turn off WIFI fail!\n");
                powered = 2;
            }
            else {
                WIFI_INFO_FUNC("WMT turn off WIFI OK!\n");
                powered = 0;
                retval = count;
                wlan_mode = WLAN_MODE_HALT;
            #if CFG_TC1_FEATURE
                ifname = WLAN_IFACE_NAME;
                wlan_if_changed = 0;
            #endif
            }
        }
        else if (local[0] == '1') {
            if (powered == 1) {
                WIFI_INFO_FUNC("WIFI is already power on!\n");
                retval = count;
                goto done;
            } 

            if (MTK_WCN_BOOL_FALSE == mtk_wcn_wmt_func_on(WMTDRV_TYPE_WIFI)) {
                WIFI_ERR_FUNC("WMT turn on WIFI fail!\n");
            }
            else {
                powered = 1;
                retval = count;
                WIFI_INFO_FUNC("WMT turn on WIFI success!\n");
                wlan_mode = WLAN_MODE_HALT;
            }
        }
        else if (local[0] == 'D') {
            INT32 k = 0;
            /* 
             * 0: no debug
             * 1: common debug output
             * 2: more detials
             * 3: verbose
             */
            switch (local[1]) {
            case '0':
                for (k = 0; k < DBG_MODULE_NUM; k++) {
                    wlan_dbg_level[k] = 0;
                }
                if (pf_set_dbg_level) {
                    pf_set_dbg_level(wlan_dbg_level);
                }
                break;
            case '1':
                for (k = 0; k < DBG_MODULE_NUM; k++) {
                    wlan_dbg_level[k] = DBG_CLASS_ERROR | \
                        DBG_CLASS_WARN | \
                        DBG_CLASS_STATE | \
                        DBG_CLASS_EVENT | \
                        DBG_CLASS_TRACE | \
                        DBG_CLASS_INFO;
                }
                wlan_dbg_level[DBG_TX_IDX] &= ~(DBG_CLASS_EVENT | \
                    DBG_CLASS_TRACE | \
                    DBG_CLASS_INFO);
                wlan_dbg_level[DBG_RX_IDX] &= ~(DBG_CLASS_EVENT | \
                    DBG_CLASS_TRACE | \
                    DBG_CLASS_INFO);
                wlan_dbg_level[DBG_REQ_IDX] &= ~(DBG_CLASS_EVENT | \
                    DBG_CLASS_TRACE | \
                    DBG_CLASS_INFO);
                wlan_dbg_level[DBG_INTR_IDX] = 0;
                wlan_dbg_level[DBG_MEM_IDX] = 0;
                if (pf_set_dbg_level) {
                    pf_set_dbg_level(wlan_dbg_level);
                }
                break;
            case '2':
                for (k = 0; k < DBG_MODULE_NUM; k++) {
                    wlan_dbg_level[k] = DBG_CLASS_ERROR | \
                        DBG_CLASS_WARN | \
                        DBG_CLASS_STATE | \
                        DBG_CLASS_EVENT | \
                        DBG_CLASS_TRACE | \
                        DBG_CLASS_INFO;
                }	
                wlan_dbg_level[DBG_INTR_IDX] = 0;
                wlan_dbg_level[DBG_MEM_IDX] = 0;
                if (pf_set_dbg_level) {
                    pf_set_dbg_level(wlan_dbg_level);
                }
                break;
            case '3':
                for (k = 0; k < DBG_MODULE_NUM; k++) {
                    wlan_dbg_level[k] = DBG_CLASS_ERROR | \
                        DBG_CLASS_WARN | \
                        DBG_CLASS_STATE | \
                        DBG_CLASS_EVENT | \
                        DBG_CLASS_TRACE | \
                        DBG_CLASS_INFO | \
                        DBG_CLASS_LOUD;
                }	
                if (pf_set_dbg_level) {
                    pf_set_dbg_level(wlan_dbg_level);
                }
                break;
            default:
                break;
            }
        }
        else if (local[0] == 'S' || local[0] == 'P' || local[0] == 'A') {
            if (powered == 0) {
                /* If WIFI is off, turn on WIFI first */
                if (MTK_WCN_BOOL_FALSE == mtk_wcn_wmt_func_on(WMTDRV_TYPE_WIFI)) {
                    WIFI_ERR_FUNC("WMT turn on WIFI fail!\n");
                    goto done;
                }
                else {
                    powered = 1;
                    WIFI_INFO_FUNC("WMT turn on WIFI success!\n");
                    wlan_mode = WLAN_MODE_HALT;
                }
            }

            if (pf_set_p2p_mode == NULL) {
                WIFI_ERR_FUNC("Set p2p mode handler is NULL\n");
                goto done;
            }

            netdev = dev_get_by_name(&init_net, ifname);
            while (netdev == NULL && wait_cnt < 10) {
                WIFI_ERR_FUNC("Fail to get %s net device, sleep 300ms\n", ifname);
                msleep(300);
                wait_cnt ++;
                netdev = dev_get_by_name(&init_net, ifname);
            }
            if (wait_cnt >= 10) {
                WIFI_ERR_FUNC("Get %s net device timeout\n", ifname);
                goto done;
            }

            if ((wlan_mode == WLAN_MODE_STA_P2P && (local[0] == 'S' || local[0] == 'P')) ||
                (wlan_mode == WLAN_MODE_AP && (local[0] == 'A'))){
                WIFI_INFO_FUNC("WIFI is already in mode %d!\n", wlan_mode);
                retval = count;
                goto done;
            }

            if ((wlan_mode == WLAN_MODE_AP && (local[0] == 'S' || local[0] == 'P')) ||
                (wlan_mode == WLAN_MODE_STA_P2P && (local[0] == 'A'))){
                p2pmode.u4Enable = 0;
                p2pmode.u4Mode = 0;
                if (pf_set_p2p_mode(netdev, p2pmode) != 0){
                    WIFI_ERR_FUNC("Turn off p2p/ap mode fail");
                    goto done;
                }
            }

            if (local[0] == 'S' || local[0] == 'P'){
            #if CFG_TC1_FEATURE
                /* Restore NIC name to wlan0 */
                rtnl_lock();
                if (strcmp(ifname, WLAN_IFACE_NAME) != 0){
                    if (dev_change_name(netdev, WLAN_IFACE_NAME) != 0){
                        WIFI_ERR_FUNC("netdev name change to %s fail\n", WLAN_IFACE_NAME);
                        rtnl_unlock();
                        goto done;
                    }
                    else{
                        WIFI_INFO_FUNC("netdev name changed %s --> %s\n", ifname, WLAN_IFACE_NAME);
                        ifname = WLAN_IFACE_NAME;
                        wlan_if_changed = 0;
                    }
                }
                rtnl_unlock();
            #endif
                p2pmode.u4Enable = 1;
                p2pmode.u4Mode = 0;
                if (pf_set_p2p_mode(netdev, p2pmode) != 0){
                    WIFI_ERR_FUNC("Set wlan mode fail\n");
                }
                else{
                    WIFI_INFO_FUNC("Set wlan mode %d --> %d\n", wlan_mode, WLAN_MODE_STA_P2P);
                    wlan_mode = WLAN_MODE_STA_P2P;
                    retval = count;
                }
            } else if (local[0] == 'A'){
            #if CFG_TC1_FEATURE
                /* Change NIC name to legacy0, since wlan0 is used for AP */
                rtnl_lock();
                if (strcmp(ifname, LEGACY_IFACE_NAME) != 0){
                    if (dev_change_name(netdev, LEGACY_IFACE_NAME) != 0){
                        WIFI_ERR_FUNC("netdev name change to %s fail\n", LEGACY_IFACE_NAME);
                        rtnl_unlock();
                        goto done;
                    }
                    else{
                        WIFI_INFO_FUNC("netdev name changed %s --> %s\n", ifname, LEGACY_IFACE_NAME);
                        ifname = LEGACY_IFACE_NAME;
                        wlan_if_changed = 1;
                    }
                }
                rtnl_unlock();
            #endif
                p2pmode.u4Enable = 1;
                p2pmode.u4Mode = 1;
                if (pf_set_p2p_mode(netdev, p2pmode) != 0){
                    WIFI_ERR_FUNC("Set wlan mode fail\n");
                }
                else{
                    WIFI_INFO_FUNC("Set wlan mode %d --> %d\n", wlan_mode, WLAN_MODE_AP);
                    wlan_mode = WLAN_MODE_AP;
                    retval = count;
                }
            }
            dev_put(netdev);
            netdev = NULL;
        }
    }
done:
    if (netdev != NULL){
        dev_put(netdev);
    }
    up(&wr_mtx);
    return (retval);
}
ssize_t WIFI_write(struct file *filp, const char __user *buf, size_t count, loff_t *f_pos)
{
    int retval = -EIO;
    char local[12] = {0};
    static int opened = 0;
	int ret = -1;
	struct net_device *netdev = NULL;
	PARAM_CUSTOM_P2P_SET_STRUC_T p2pmode;
	int wait_cnt = 0;

    down(&wr_mtx);
	if (count <= 0) {
		WIFI_INFO_FUNC("WIFI_write invalid param \n");
		goto done;
	}
	if (0 == copy_from_user(local, buf, (count > sizeof(local)) ? sizeof(local) : count)) {
		/*mtk80707 rollback aosp hal*/
		local[11] = 0;
	    WIFI_INFO_FUNC("WIFI_write %s\n", local);

            if (local[0] == '0' && opened == 1) {
                //TODO
                //Configure the EINT pin to GPIO mode.
			p2pmode.u4Enable = 0;
			p2pmode.u4Mode = 0;

			/*IF power off already*/
			if (power_state == 0) {
				WIFI_INFO_FUNC("WMT turn off WIFI OK!\n");
	            opened = 0;
	            retval = count;
				wlan_mode = WLAN_MODE_HALT;
				goto done;
			}
			if (flagIsIFchanged==1)
				{
			     netdev = dev_get_by_name(&init_net, WLAN_LEG_IFACE_NAME);}
		    else
		    	{netdev = dev_get_by_name(&init_net, WLAN_IFACE_NAME);}
			while (netdev == NULL && wait_cnt < 10) {
				WIFI_WARN_FUNC("WMT fail to get wlan0 net device, sleep 300ms\n");
				msleep(300);
				wait_cnt ++;
				if (flagIsIFchanged==1)
				{ netdev = dev_get_by_name(&init_net, WLAN_LEG_IFACE_NAME);}
		        else
		    	{ netdev = dev_get_by_name(&init_net, WLAN_IFACE_NAME);}
			}
			if (wait_cnt >= 10) {
				WIFI_WARN_FUNC("WMT get wlan0 net device time out\n");
				goto done;
			}
			if (pf_set_p2p_mode) {
				ret = pf_set_p2p_mode(netdev, p2pmode);
				if (ret != 0) {
					WIFI_WARN_FUNC("WMT trun off p2p & ap mode ret = %d", ret);
					goto done;
				}
				//msleep(300);
			}
			dev_put(netdev);
			netdev = NULL;

                if (MTK_WCN_BOOL_FALSE == mtk_wcn_wmt_func_off(WMTDRV_TYPE_WIFI)) {
                    WIFI_INFO_FUNC("WMT turn off WIFI fail!\n");
                }
                else {
                    WIFI_INFO_FUNC("WMT turn off WIFI OK!\n");
                    opened = 0;
                    retval = count;
				wlan_mode = WLAN_MODE_HALT;
				power_state = 0;
				flagIsIFchanged=0;
				PowerOnIFname = 0;
                }
            }
            else if (local[0] == '1') {
                //TODO
                //Disable EINT(external interrupt), and set the GPIO to EINT mode.
                if (power_state == 1){
					WIFI_INFO_FUNC("WIFI is already on!\n");
                    retval = count;
                	}
				else {
			    pf_set_p2p_mode = NULL;
                if (MTK_WCN_BOOL_FALSE == mtk_wcn_wmt_func_on(WMTDRV_TYPE_WIFI)) {
                    WIFI_WARN_FUNC("WMT turn on WIFI fail!\n");
                }
                else {
                    opened = 1;
                    retval = count;
                    WIFI_INFO_FUNC("WMT turn on WIFI success!\n");
				    wlan_mode = WLAN_MODE_HALT;
				    power_state = 1;
					//msleep(300);
                }
				    }
            }
		else if (local[0] == 'S' || local[0] == 'P' || local[0] == 'A') {	
			p2pmode.u4Enable = 1;
			p2pmode.u4Mode = 0;
			ret = -1;

            if (power_state ==0) {
				WIFI_INFO_FUNC("Turn on WIFI first if WIFI is off\n");
				if(local[0] == 'A')
					{
					 PowerOnIFname = 1; //legacy_wlan0
					 printk("change PoweronIFname\n");
					}
				pf_set_p2p_mode = NULL;
                if (MTK_WCN_BOOL_FALSE == mtk_wcn_wmt_func_on(WMTDRV_TYPE_WIFI)) {
                    WIFI_WARN_FUNC("WMT turn on WIFI fail!\n");
                }
                else {
                    opened = 1;
                    retval = count;
                    WIFI_INFO_FUNC("WMT turn on WIFI success!\n");
				    wlan_mode = WLAN_MODE_HALT;
				    power_state = 1;
					if (local[0] == 'A'){
					flagIsIFchanged=1;}
                }
				
			}
			if (flagIsIFchanged==1)
				{netdev = dev_get_by_name(&init_net, WLAN_LEG_IFACE_NAME);
			    }
			else {
			    netdev = dev_get_by_name(&init_net, WLAN_IFACE_NAME);
				if (local[0] == 'A'&&netdev!=NULL)
					{
					 rtnl_lock();
		             ret = dev_change_name(netdev,WLAN_LEG_IFACE_NAME);
		             rtnl_unlock();
					 flagIsIFchanged=1;
					 printk("change_leagcy_name, ret = %d",ret);
					}
			     }
			while (netdev == NULL && wait_cnt < 10) {
				WIFI_WARN_FUNC("WMT fail to get wlan0 net device, sleep 300ms\n");
				msleep(300);
				wait_cnt ++;
				if (flagIsIFchanged==1)
				{netdev = dev_get_by_name(&init_net, WLAN_LEG_IFACE_NAME);}
			    else {
			     netdev = dev_get_by_name(&init_net, WLAN_IFACE_NAME);
                 if (local[0] == 'A'&&netdev!=NULL)
					{
					 rtnl_lock();
		             ret = dev_change_name(netdev,WLAN_LEG_IFACE_NAME);
		             rtnl_unlock();
					 flagIsIFchanged=1;
					 printk("change_leagcy_name, ret = %d",ret);
					}
				}
			    }
			if (wait_cnt >= 10) {
				WIFI_WARN_FUNC("WMT get wlan0 net device time out\n");
				goto done;
                }
			if (pf_set_p2p_mode == NULL) {
				WIFI_INFO_FUNC("set p2p handler is NULL\n");
				goto done;
			    }
			if (wlan_mode == WLAN_MODE_AP&&(local[0] == 'S' || local[0] == 'P') )
				{
			     p2pmode.u4Enable = 0;
			     p2pmode.u4Mode = 0;
				 ret = pf_set_p2p_mode(netdev, p2pmode);
				// msleep(300);
				 WIFI_INFO_FUNC("success to turn off p2p/AP mode\n");
				}
			p2pmode.u4Enable = 1;
			p2pmode.u4Mode = 0;
			ret = -1;
			if (local[0] == 'A') {
				p2pmode.u4Mode = 1;
            }
			ret = pf_set_p2p_mode(netdev, p2pmode);
			//msleep(300);
			dev_put(netdev);
			netdev = NULL;
			WIFI_INFO_FUNC("WMT WIFI set p2p mode ret=%d\n", ret);

			if (ret == 0 && (local[0] == 'S' || local[0] == 'P')) {
				WIFI_INFO_FUNC("wlan mode %d --> %d\n", wlan_mode, WLAN_MODE_STA_P2P);
				wlan_mode = WLAN_MODE_STA_P2P;
				retval = count;
			} else if (ret == 0 && local[0] == 'A') {
				WIFI_INFO_FUNC("wlan mode %d --> %d\n", wlan_mode, WLAN_MODE_AP);
				wlan_mode = WLAN_MODE_AP;
				retval = count;
			} else {
				WIFI_INFO_FUNC("fail to set wlan mode\n");
			}
		}
	}
done:
    up(&wr_mtx);
	if (netdev != NULL) {
		dev_put(netdev);
	}
    return (retval);
}
/* 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_SET_PATCH_NAME		_IOW(WMT_IOC_MAGIC, 4, char*)
#define WMT_IOCTL_SET_STP_MODE			_IOW(WMT_IOC_MAGIC, 5, int)
#define WMT_IOCTL_FUNC_ONOFF_CTRL		_IOW(WMT_IOC_MAGIC, 6, int)
#define WMT_IOCTL_LPBK_POWER_CTRL		_IOW(WMT_IOC_MAGIC, 7, int)
#define WMT_IOCTL_LPBK_TEST				_IOWR(WMT_IOC_MAGIC, 8, char*)
#define WMT_IOCTL_GET_CHIP_INFO			_IOR(WMT_IOC_MAGIC, 12, int)
#define WMT_IOCTL_SET_LAUNCHER_KILL		_IOW(WMT_IOC_MAGIC, 13, int)
#define WMT_IOCTL_SET_PATCH_NUM			_IOW(WMT_IOC_MAGIC, 14, int)
#define WMT_IOCTL_SET_PATCH_INFO		_IOW(WMT_IOC_MAGIC, 15, char*)
#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)
#define WMT_IOCTL_WMT_STP_ASSERT_CTRL   _IOW(WMT_IOC_MAGIC, 27, int)



	INT32 iRet = 0;
	UINT8 pBuffer[NAME_MAX + 1];
	WMT_DBG_FUNC("cmd (%u), arg (0x%lx)\n", cmd, arg);
	switch (cmd) {
	case WMT_IOCTL_SET_PATCH_NAME:	/* 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 WMT_IOCTL_SET_STP_MODE:	/* 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 (%lu)\n", arg);
				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 WMT_IOCTL_FUNC_ONOFF_CTRL:	/* 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 WMT_IOCTL_LPBK_POWER_CTRL:
		/*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 WMT_IOCTL_LPBK_TEST:
		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] = (size_t) &gLpbkBuf[0];
			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(unsigned long) + sizeof(UINT8[2048]), gLpbkBuf,
				     iRet)) {
					iRet = -EFAULT;
					break;
				}
			}
		} while (0);

		break;
#if 0
	case 9:
		{
#define LOG_BUF_SZ 300
			UINT8 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, (PUINT8)&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 WMT_IOCTL_GET_CHIP_INFO:
		{
			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 WMT_IOCTL_SET_LAUNCHER_KILL:{
			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 WMT_IOCTL_SET_PATCH_NUM:{
			pAtchNum = arg;
			WMT_INFO_FUNC(" get patch num from launcher = %d\n", pAtchNum);
			wmt_lib_set_patch_num(pAtchNum);
			if (pAtchNum > 0)
				pPatchInfo = kzalloc(sizeof(WMT_PATCH_INFO) *pAtchNum, GFP_ATOMIC);
			else
				WMT_ERR_FUNC("patch num == 0!\n");
			if (!pPatchInfo) {
				WMT_ERR_FUNC("allocate memory fail!\n");
				break;
			}
		}
		break;

	case WMT_IOCTL_SET_PATCH_INFO:{
			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:{
			INT8 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:
		{
			INT8 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:
		{
#if !(DELETE_HIF_SDIO_CHRDEV)
			iRet = mtk_wcn_hif_sdio_query_chipid(1);
#else
			iRet = mtk_wcn_wmt_chipid_query();
#endif
		}
		break;
	case WMT_IOCTL_WMT_TELL_CHIPID:
		{
#if !(DELETE_HIF_SDIO_CHRDEV)
			iRet = mtk_wcn_hif_sdio_tell_chipid(arg);
#endif

			if (0x6628 == arg || 0x6630 == 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;
		case WMT_IOCTL_WMT_STP_ASSERT_CTRL:
			if (MTK_WCN_BOOL_TRUE == wmt_lib_btm_cb(BTM_TRIGGER_STP_ASSERT_OP))
			{
				WMT_INFO_FUNC("trigger stp assert succeed\n");
				iRet = 0;
			}
			else
			{
				WMT_INFO_FUNC("trigger stp assert failed\n");
				iRet = -1;
			}
		break;
	default:
		iRet = -EINVAL;
		WMT_WARN_FUNC("unknown cmd (%d)\n", cmd);
		break;
	}


	return iRet;
}
ssize_t WIFI_write(struct file *filp, const char __user *buf, size_t count, loff_t *f_pos)
{
	int retval = -EIO;
	char local[12] = { 0 };
	struct net_device *netdev = NULL;
	PARAM_CUSTOM_P2P_SET_STRUC_T p2pmode;
	int wait_cnt = 0;

	down(&wr_mtx);
	if (count <= 0) {
		WIFI_ERR_FUNC("WIFI_write invalid param\n");
		goto done;
	}

	if (0 == copy_from_user(local, buf, (count > sizeof(local)) ? sizeof(local) : count)) {
		local[11] = 0;
		WIFI_INFO_FUNC("WIFI_write %s\n", local);

		if (local[0] == '0') {
			/* TODO */
			/* Configure the EINT pin to GPIO mode. */
			if (powered == 0) {
				WIFI_INFO_FUNC("WIFI is already power off!\n");
				retval = count;
				wlan_mode = WLAN_MODE_HALT;
				goto done;
			}

			netdev = dev_get_by_name(&init_net, WLAN_IFACE_NAME);
			if (netdev == NULL) {
				WIFI_ERR_FUNC("Fail to get wlan0 net device\n");
			} else {
				p2pmode.u4Enable = 0;
				p2pmode.u4Mode = 0;

				if (pf_set_p2p_mode) {
					if (pf_set_p2p_mode(netdev, p2pmode) != 0) {
						WIFI_ERR_FUNC("Turn off p2p/ap mode fail");
					} else {
						WIFI_INFO_FUNC("Turn off p2p/ap mode");
						wlan_mode = WLAN_MODE_HALT;
					}
				}
				dev_put(netdev);
				netdev = NULL;
			}

			if (MTK_WCN_BOOL_FALSE == mtk_wcn_wmt_func_off(WMTDRV_TYPE_WIFI)) {
				WIFI_ERR_FUNC("WMT turn off WIFI fail!\n");
			} else {
				WIFI_INFO_FUNC("WMT turn off WIFI OK!\n");
				powered = 0;
				retval = count;
				wlan_mode = WLAN_MODE_HALT;
			}
		} else if (local[0] == '1') {
			/* TODO */
			/* Disable EINT(external interrupt), and set the GPIO to EINT mode. */
			if (powered == 1) {
				WIFI_INFO_FUNC("WIFI is already power on!\n");
				retval = count;
				goto done;
			}

			if (MTK_WCN_BOOL_FALSE == mtk_wcn_wmt_func_on(WMTDRV_TYPE_WIFI)) {
				WIFI_ERR_FUNC("WMT turn on WIFI fail!\n");
			} else {
				powered = 1;
				retval = count;
				WIFI_INFO_FUNC("WMT turn on WIFI success!\n");
				wlan_mode = WLAN_MODE_HALT;
			}
		} else if (local[0] == 'D') {
			int k = 0;
			/*
			 * 0: no debug
			 * 1: common debug output
			 * 2: more detials
			 * 3: verbose
			 */
			switch (local[1]) {
			case '0':
				for (k = 0; k < DBG_MODULE_NUM; k++) {
					wlan_dbg_level[k] = 0;
				}
				if (pf_set_dbg_level) {
					pf_set_dbg_level(wlan_dbg_level);
				}
				break;
			case '1':
				for (k = 0; k < DBG_MODULE_NUM; k++) {
					wlan_dbg_level[k] = DBG_CLASS_ERROR |
					    DBG_CLASS_WARN |
					    DBG_CLASS_STATE |
					    DBG_CLASS_EVENT | DBG_CLASS_TRACE | DBG_CLASS_INFO;
				}
				wlan_dbg_level[DBG_TX_IDX] &= ~(DBG_CLASS_EVENT |
								DBG_CLASS_TRACE | DBG_CLASS_INFO);
				wlan_dbg_level[DBG_RX_IDX] &= ~(DBG_CLASS_EVENT |
								DBG_CLASS_TRACE | DBG_CLASS_INFO);
				wlan_dbg_level[DBG_REQ_IDX] &= ~(DBG_CLASS_EVENT |
								 DBG_CLASS_TRACE | DBG_CLASS_INFO);
				wlan_dbg_level[DBG_INTR_IDX] = 0;
				wlan_dbg_level[DBG_MEM_IDX] = 0;
				if (pf_set_dbg_level) {
					pf_set_dbg_level(wlan_dbg_level);
				}
				break;
			case '2':
				for (k = 0; k < DBG_MODULE_NUM; k++) {
					wlan_dbg_level[k] = DBG_CLASS_ERROR |
					    DBG_CLASS_WARN |
					    DBG_CLASS_STATE |
					    DBG_CLASS_EVENT | DBG_CLASS_TRACE | DBG_CLASS_INFO;
				}
				wlan_dbg_level[DBG_INTR_IDX] = 0;
				wlan_dbg_level[DBG_MEM_IDX] = 0;
				if (pf_set_dbg_level) {
					pf_set_dbg_level(wlan_dbg_level);
				}
				break;
			case '3':
				for (k = 0; k < DBG_MODULE_NUM; k++) {
					wlan_dbg_level[k] = DBG_CLASS_ERROR |
					    DBG_CLASS_WARN |
					    DBG_CLASS_STATE |
					    DBG_CLASS_EVENT |
					    DBG_CLASS_TRACE | DBG_CLASS_INFO | DBG_CLASS_LOUD;
				}
				if (pf_set_dbg_level) {
					pf_set_dbg_level(wlan_dbg_level);
				}
				break;
			default:
				break;
			}
		} else if (local[0] == 'S' || local[0] == 'P' || local[0] == 'A') {
			if (powered == 0) {
				/* If WIFI is off, turn on WIFI first */
				if (MTK_WCN_BOOL_FALSE == mtk_wcn_wmt_func_on(WMTDRV_TYPE_WIFI)) {
					WIFI_ERR_FUNC("WMT turn on WIFI fail!\n");
					goto done;
				} else {
					powered = 1;
					WIFI_INFO_FUNC("WMT turn on WIFI success!\n");
					wlan_mode = WLAN_MODE_HALT;
				}
			}

			if (pf_set_p2p_mode == NULL) {
				WIFI_ERR_FUNC("Set p2p mode handler is NULL\n");
				goto done;
			}

			netdev = dev_get_by_name(&init_net, WLAN_IFACE_NAME);
			while (netdev == NULL && wait_cnt < 10) {
				WIFI_ERR_FUNC("Fail to get wlan0 net device, sleep 300ms\n");
				msleep(300);
				wait_cnt++;
				netdev = dev_get_by_name(&init_net, WLAN_IFACE_NAME);
			}
			if (wait_cnt >= 10) {
				WIFI_ERR_FUNC("Get wlan0 net device timeout\n");
				goto done;
			}

			if ((wlan_mode == WLAN_MODE_AP && (local[0] == 'S' || local[0] == 'P')) ||
			    (wlan_mode == WLAN_MODE_STA_P2P && (local[0] == 'A'))) {
				p2pmode.u4Enable = 0;
				p2pmode.u4Mode = 0;
				if (pf_set_p2p_mode(netdev, p2pmode) != 0) {
					WIFI_ERR_FUNC("Turn off p2p/ap mode fail");
					goto done;
				}
			}

			if (local[0] == 'S' || local[0] == 'P') {
				p2pmode.u4Enable = 1;
				p2pmode.u4Mode = 0;
				if (pf_set_p2p_mode(netdev, p2pmode) != 0) {
					WIFI_ERR_FUNC("Set wlan mode fail\n");
				} else {
					WIFI_INFO_FUNC("Set wlan mode %d --> %d\n", wlan_mode,
						       WLAN_MODE_STA_P2P);
					wlan_mode = WLAN_MODE_STA_P2P;
					retval = count;
				}
			} else if (local[0] == 'A') {
				p2pmode.u4Enable = 1;
				p2pmode.u4Mode = 1;
				if (pf_set_p2p_mode(netdev, p2pmode) != 0) {
					WIFI_ERR_FUNC("Set wlan mode fail\n");
				} else {
					WIFI_INFO_FUNC("Set wlan mode %d --> %d\n", wlan_mode,
						       WLAN_MODE_AP);
					wlan_mode = WLAN_MODE_AP;
					retval = count;
				}
			}
			dev_put(netdev);
			netdev = NULL;
		}
	}
 done:
	if (netdev != NULL) {
		dev_put(netdev);
	}
	up(&wr_mtx);
	return (retval);
}