예제 #1
0
ssize_t BT_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos)
{
	static int chip_reset_count;
	INT32 retval = 0;

	down(&rd_mtx);

	BT_DBG_FUNC("%s: count %zd pos %lld\n", __func__, count, *f_pos);
	if (rstflag) {
		if (rstflag == 1) {	/* Reset start */
			retval = -88;
			if ((chip_reset_count%500) == 0)
				BT_INFO_FUNC("%s: detect whole chip reset start, %d\n", __func__, chip_reset_count);
			chip_reset_count++;
		} else if (rstflag == 2) {	/* Reset end */
			retval = -99;
			BT_INFO_FUNC("%s: detect whole chip reset end\n", __func__);
			chip_reset_count = 0;
		}
		goto OUT;
	}

	if (count > BT_BUFFER_SIZE) {
		count = BT_BUFFER_SIZE;
		BT_ERR_FUNC("%s: count > BT_BUFFER_SIZE\n", __func__);
	}

	retval = mtk_wcn_stp_receive_data(i_buf, count, BT_TASK_INDX);

	while (retval == 0) {	/* Got nothing, wait for STP's signal */
		/*
		* If nonblocking mode, return directly.
		* O_NONBLOCK is specified during open()
		*/
		if (filp->f_flags & O_NONBLOCK) {
			BT_DBG_FUNC("Non-blocking BT_read\n");
			retval = -EAGAIN;
			goto OUT;
		}

		BT_DBG_FUNC("%s: wait_event 1\n", __func__);
		wait_event(BT_wq, flag != 0);
		BT_DBG_FUNC("%s: wait_event 2\n", __func__);
		flag = 0;
		retval = mtk_wcn_stp_receive_data(i_buf, count, BT_TASK_INDX);
		BT_DBG_FUNC("%s: mtk_wcn_stp_receive_data returns %d\n", __func__, retval);
	}

	/* Got something from STP driver */
	if (copy_to_user(buf, i_buf, retval)) {
		retval = -EFAULT;
		goto OUT;
	}

OUT:
	up(&rd_mtx);
	BT_DBG_FUNC("%s: retval = %d\n", __func__, retval);
	return retval;
}
ssize_t BT_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos)
{
    int retval = 0;

    down(&rd_mtx);

    BT_DBG_FUNC("BT_read(): count %d pos %lld\n", count, *f_pos);
    if(retflag)
    {
        if (retflag == 1) //reset start
        {
            retval = -88;
            BT_INFO_FUNC("MT662x reset Read: start\n");
        }
        else if (retflag == 2) // reset end
        {
            retval = -99;
            BT_INFO_FUNC("MT662x reset Read: end\n");
        }
    goto OUT;
    }

    if(count > MTKSTP_BUFFER_SIZE)
    {
        count = MTKSTP_BUFFER_SIZE;
    }
    retval = mtk_wcn_stp_receive_data(i_buf, count, BT_TASK_INDX);

    while(retval == 0) // got nothing, wait for STP's signal
    {
        /*If nonblocking mode, return directly O_NONBLOCK is specified during open() */
        if (filp->f_flags & O_NONBLOCK){
            BT_DBG_FUNC("Non-blocking BT_read() \n");
            retval = -EAGAIN;
            goto OUT;
        }

        BT_DBG_FUNC("BT_read(): wait_event 1\n");
        wait_event(BT_wq, flag != 0);
        BT_DBG_FUNC("BT_read(): wait_event 2\n");
        flag = 0;
        retval = mtk_wcn_stp_receive_data(i_buf, count, BT_TASK_INDX);
        BT_DBG_FUNC("BT_read(): mtk_wcn_stp_receive_data() = %d\n", retval);
    }

    // we got something from STP driver
    if (copy_to_user(buf, i_buf, retval))
    {
        retval = -EFAULT;
        goto OUT;
    }

OUT:
    up(&rd_mtx);
    BT_DBG_FUNC("BT_read(): retval = %d\n", retval);
    return (retval);
}
예제 #3
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;
}
예제 #4
0
INT32 wmt_ctrl_rx(P_WMT_CTRL_DATA pWmtCtrlData/*UINT8 *pBuff, UINT32 buffLen, UINT32 *readSize*/)
{
    P_DEV_WMT pDev = &gDevWmt; /* single instance */
    INT32 readLen;
    LONG waitRet = -1;
    UINT8 *pBuff = (UINT8 *)pWmtCtrlData->au4CtrlData[0];
    UINT32 buffLen = pWmtCtrlData->au4CtrlData[1];
    UINT32 *readSize = (UINT32 *)pWmtCtrlData->au4CtrlData[2];

    if (readSize) {
        *readSize = 0;
    }

    /* sanity check */
    if (!buffLen ) {
        WMT_WARN_FUNC("buffLen = 0\n");
        osal_assert(buffLen);
        return 0;
    }

#if 0
    if (!pDev) {
        WMT_WARN_FUNC("gpDevWmt = NULL\n");
        osal_assert(pDev);
        return -1;
    }
#endif


    if (!osal_test_bit(WMT_STAT_STP_OPEN, &pDev->state)) {
        WMT_WARN_FUNC("state(0x%lx) \n", pDev->state);
        osal_assert(osal_test_bit(WMT_STAT_STP_OPEN, &pDev->state));
        return -2;
    }

    /* sanity ok, proceeding rx operation */
    /* read_len = mtk_wcn_stp_receive_data(data, size, WMT_TASK_INDX); */
    readLen = mtk_wcn_stp_receive_data(pBuff, buffLen, WMT_TASK_INDX);

    while (readLen == 0) { // got nothing, wait for STP's signal
        WMT_LOUD_FUNC("before wmt_dev_rx_timeout\n");
        //iRet = wait_event_interruptible(pdev->rWmtRxWq, osal_test_bit(WMT_STAT_RX, &pdev->state));
        //waitRet = wait_event_interruptible_timeout(pDev->rWmtRxWq, osal_test_bit(WMT_STAT_RX, &pdev->state), msecs_to_jiffies(WMT_LIB_RX_TIMEOUT));
        pDev->rWmtRxWq.timeoutValue = WMT_LIB_RX_TIMEOUT;
        //waitRet = osal_wait_for_event_bit_timeout(&pDev->rWmtRxWq, &pDev->state, WMT_STAT_RX);
        waitRet = wmt_dev_rx_timeout(&pDev->rWmtRxWq);

        WMT_LOUD_FUNC("wmt_dev_rx_timeout returned\n");

        if (0 == waitRet) {
            WMT_ERR_FUNC("wmt_dev_rx_timeout: timeout,jiffies(%lu),timeoutvalue(%d) \n",
				jiffies,pDev->rWmtRxWq.timeoutValue);
            return -1;
        }
        else if (waitRet < 0) {
            WMT_WARN_FUNC("wmt_dev_rx_timeout: interrupted by signal (%ld)\n", waitRet);
            return waitRet;
        }
        WMT_DBG_FUNC("wmt_dev_rx_timeout, iRet(%ld)\n", waitRet);
        /* read_len = mtk_wcn_stp_receive_data(data, size, WMT_TASK_INDX); */
        readLen = mtk_wcn_stp_receive_data(pBuff, buffLen, WMT_TASK_INDX);

        if (0 == readLen) {
            WMT_WARN_FUNC("wmt_ctrl_rx be signaled, but no rx data(%ld)\n", waitRet);
        }
        WMT_DBG_FUNC("readLen(%d) \n", readLen);
    }

    if (readSize) {
        *readSize = readLen ;
    }

    return 0;

}
ssize_t GPS_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos)
{
    long val = 0;
    int retval;

    down(&rd_mtx);

/*    printk("GPS_read(): count %d pos %lld\n", count, *f_pos);*/

    if(count > MTKSTP_BUFFER_SIZE)
    {
        count = MTKSTP_BUFFER_SIZE;
    }
    
#if GPS_DEBUG_TRACE_GPIO    
    mtk_wcn_stp_debug_gpio_assert(IDX_GPS_RX, DBG_TIE_LOW);
#endif
    retval = mtk_wcn_stp_receive_data(i_buf, count, GPS_TASK_INDX);
#if GPS_DEBUG_TRACE_GPIO
    mtk_wcn_stp_debug_gpio_assert(IDX_GPS_RX, DBG_TIE_HIGH);
#endif

    while(retval == 0) // got nothing, wait for STP's signal
    {
        /*wait_event(GPS_wq, flag != 0);*/ /* George: let signal wake up */
        val = wait_event_interruptible(GPS_wq, flag != 0);
        flag = 0;
            
#if GPS_DEBUG_TRACE_GPIO
        mtk_wcn_stp_debug_gpio_assert(IDX_GPS_RX, DBG_TIE_LOW);
#endif

        retval = mtk_wcn_stp_receive_data(i_buf, count, GPS_TASK_INDX);

#if GPS_DEBUG_TRACE_GPIO
        mtk_wcn_stp_debug_gpio_assert(IDX_GPS_RX, DBG_TIE_HIGH);
#endif
        /* if we are signaled */
        if (val) {
            if (-ERESTARTSYS == val) {
                GPS_INFO_FUNC("signaled by -ERESTARTSYS(%ld) \n ", val);
            }
            else {
                GPS_INFO_FUNC("signaled by %ld \n ", val);
            }
            break;
        }
    }

#if GPS_DEBUG_DUMP    
{   
    unsigned char *buf_ptr = &i_buf[0];        
    int k=0;        
    printk("--[GPS-READ]--");       
    for(k=0; k < 10 ; k++){       
    if(k%16 == 0)  printk("\n");            
    printk("0x%02x ", i_buf[k]);        
    }        
    printk("--\n");    
}
#endif

    if (retval) {
    // we got something from STP driver
        if (copy_to_user(buf, i_buf, retval)) {
        retval = -EFAULT;
        goto OUT;
        }
        else {
            /* success */
        }
    }
    else {
        // we got nothing from STP driver, being signaled
        retval = val;
    }

OUT:
    up(&rd_mtx);
/*    printk("GPS_read(): retval = %d\n", retval);*/
    return (retval);
}
예제 #6
0
fm_s32 fm_event_parser(fm_s32(*rds_parser) (struct rds_rx_t *, fm_s32))
{
	fm_s32 len;
	fm_s32 i = 0;
	fm_u8 opcode = 0;
	fm_u16 length = 0;
	fm_u8 ch;
	fm_u8 rx_buf[RX_BUF_SIZE + 10] = { 0 };	/* the 10 bytes are protect gaps */
	static volatile fm_task_parser_state state = FM_TASK_RX_PARSER_PKT_TYPE;
	struct fm_trace_t trace;
	struct task_struct *task = current;

	len = mtk_wcn_stp_receive_data(rx_buf, RX_BUF_SIZE, FM_TASK_INDX);
	WCN_DBG(FM_DBG | LINK, "[len=%d],[CMD=0x%02x 0x%02x 0x%02x 0x%02x]\n", len, rx_buf[0],
		rx_buf[1], rx_buf[2], rx_buf[3]);

	while (i < len) {
		ch = rx_buf[i];

		switch (state) {
		case FM_TASK_RX_PARSER_PKT_TYPE:

			if (ch == FM_TASK_EVENT_PKT_TYPE) {
				if ((i + 5) < RX_BUF_SIZE) {
					WCN_DBG(FM_DBG | LINK,
						"0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x\n",
						rx_buf[i], rx_buf[i + 1], rx_buf[i + 2],
						rx_buf[i + 3], rx_buf[i + 4], rx_buf[i + 5]);
				} else {
					WCN_DBG(FM_DBG | LINK, "0x%02x 0x%02x\n", rx_buf[i],
						rx_buf[i + 1]);
				}

				state = FM_TASK_RX_PARSER_OPCODE;
			} else {
				WCN_DBG(FM_ALT | LINK,
					"event pkt type error (rx_buf[%d] = 0x%02x)\n", i, ch);
			}

			i++;
			break;

		case FM_TASK_RX_PARSER_OPCODE:
			i++;
			opcode = ch;
			state = FM_TASK_RX_PARSER_PKT_LEN_1;
			break;

		case FM_TASK_RX_PARSER_PKT_LEN_1:
			i++;
			length = ch;
			state = FM_TASK_RX_PARSER_PKT_LEN_2;
			break;

		case FM_TASK_RX_PARSER_PKT_LEN_2:
			i++;
			length |= (fm_u16) (ch << 0x8);

#ifdef FM_TRACE_ENABLE
			trace.type = FM_TASK_EVENT_PKT_TYPE;
			trace.opcode = opcode;
			trace.len = length;
			trace.tid = (fm_s32) task->pid;
			fm_memset(trace.pkt, 0, FM_TRACE_PKT_SIZE);
			fm_memcpy(trace.pkt, &rx_buf[i],
				  (length > FM_TRACE_PKT_SIZE) ? FM_TRACE_PKT_SIZE : length);

			if (fm_true == FM_TRACE_FULL(cmd_fifo)) {
				FM_TRACE_OUT(cmd_fifo, NULL);
			}
			FM_TRACE_IN(cmd_fifo, &trace);
#endif
			if (length > 0) {
				state = FM_TASK_RX_PARSER_PKT_PAYLOAD;
			} else if (opcode == CSPI_WRITE_OPCODE) {
				state = FM_TASK_RX_PARSER_PKT_TYPE;
				FM_EVENT_SEND(link_event->ln_event, FLAG_CSPI_WRITE);
			} else {
				state = FM_TASK_RX_PARSER_PKT_TYPE;
				FM_EVENT_SEND(link_event->ln_event, (1 << opcode));
			}

			break;

		case FM_TASK_RX_PARSER_PKT_PAYLOAD:

			switch (opcode) {
			case FM_TUNE_OPCODE:

				if ((length == 1) && (rx_buf[i] == 1)) {
					FM_EVENT_SEND(link_event->ln_event, FLAG_TUNE_DONE);
				}

				break;

			case FM_SOFT_MUTE_TUNE_OPCODE:

				if (length >= 2) {
					fm_memcpy(link_event->result.cqi, &rx_buf[i],
						  (length >
						   FM_CQI_BUF_SIZE) ? FM_CQI_BUF_SIZE : length);
					FM_EVENT_SEND(link_event->ln_event, FLAG_SM_TUNE);
				}
				break;

			case FM_SEEK_OPCODE:

				if ((i + 1) < RX_BUF_SIZE) {
					link_event->result.seek_result = rx_buf[i] + (rx_buf[i + 1] << 8);	/* 8760 means 87.60Mhz */
				}

				FM_EVENT_SEND(link_event->ln_event, FLAG_SEEK_DONE);
				break;

			case FM_SCAN_OPCODE:

				/* check if the result data is long enough */
				if ((RX_BUF_SIZE - i) < (sizeof(fm_u16) * FM_SCANTBL_SIZE)) {
					WCN_DBG(FM_ALT | LINK,
						"FM_SCAN_OPCODE err, [tblsize=%d],[bufsize=%d]\n",
						(unsigned int)(sizeof(fm_u16) * FM_SCANTBL_SIZE),
						(unsigned int)(RX_BUF_SIZE - i));
					FM_EVENT_SEND(link_event->ln_event, FLAG_SCAN_DONE);
					return 0;
				} else if ((length >= FM_CQI_BUF_SIZE)
					   && ((RX_BUF_SIZE - i) >= FM_CQI_BUF_SIZE)) {
					fm_memcpy(link_event->result.cqi, &rx_buf[i],
						  FM_CQI_BUF_SIZE);
					FM_EVENT_SEND(link_event->ln_event, FLAG_CQI_DONE);
				} else {
					fm_memcpy(link_event->result.scan_result, &rx_buf[i],
						  sizeof(fm_u16) * FM_SCANTBL_SIZE);
					FM_EVENT_SEND(link_event->ln_event, FLAG_SCAN_DONE);
				}

				break;

			case FSPI_READ_OPCODE:

				if ((i + 1) < RX_BUF_SIZE) {
					link_event->result.fspi_rd =
					    (rx_buf[i] + (rx_buf[i + 1] << 8));
				}

				FM_EVENT_SEND(link_event->ln_event, (1 << opcode));
				break;
			case CSPI_READ_OPCODE:
				{
					if ((i + 1) < RX_BUF_SIZE) {
						link_event->result.cspi_rd =
						    (rx_buf[i] + (rx_buf[i + 1] << 8) +
						     (rx_buf[i + 2] << 16) + (rx_buf[i + 3] << 24));
					}

					FM_EVENT_SEND(link_event->ln_event, FLAG_CSPI_READ);
					break;
				}
			case FM_HOST_READ_OPCODE:
				{
					if ((i + 1) < RX_BUF_SIZE) {
						link_event->result.cspi_rd =
						    (rx_buf[i] + (rx_buf[i + 1] << 8) +
						     (rx_buf[i + 2] << 16) + (rx_buf[i + 3] << 24));
					}

					FM_EVENT_SEND(link_event->ln_event, (1 << opcode));
					break;
				}

			case RDS_RX_DATA_OPCODE:

				/* check if the rds data is long enough */
				if ((RX_BUF_SIZE - i) < length) {
					WCN_DBG(FM_ALT | LINK,
						"RDS RX err, [rxlen=%d],[bufsize=%d]\n",
						(fm_s32) length, (RX_BUF_SIZE - i));
					FM_EVENT_SEND(link_event->ln_event, (1 << opcode));
					break;
				}
				/* copy rds data to rds buf */
				fm_memcpy(&link_event->result.rds_rx_result, &rx_buf[i], length);

				/*Handle the RDS data that we get */
				if (rds_parser) {
					rds_parser(&link_event->result.rds_rx_result, length);
				} else {
					WCN_DBG(FM_WAR | LINK, "no method to parse RDS data\n");
				}

				FM_EVENT_SEND(link_event->ln_event, (1 << opcode));
				break;

			default:
				FM_EVENT_SEND(link_event->ln_event, (1 << opcode));
				break;
			}

			state = FM_TASK_RX_PARSER_PKT_TYPE;
			i += length;
			break;

		default:
			break;
		}
	}

	return 0;
}