Example #1
0
static inline INT32 _stp_btm_do_fw_assert(MTKSTP_BTM_T *stp_btm){

	INT32 status = -1;
	INT32 j = 0;
	MTK_WCN_BOOL bRet = MTK_WCN_BOOL_FALSE;
	//send assert command
	STP_BTM_INFO_FUNC("trigger stp assert process\n");
	bRet = stp_btm->wmt_notify(BTM_TRIGGER_STP_ASSERT_OP);
	if (MTK_WCN_BOOL_TRUE == bRet)
	{
	do {  
        if(0 != mtk_wcn_stp_coredump_start_get()){
            status = 0;
            break;
        }
		j++;
		STP_BTM_INFO_FUNC("Wait for assert message (%d)\n", j);
		
        if(j > 150) 
            break;   
		osal_sleep_ms(20); 

    } while(1);
	}
	else
	{
		status = -1;
		STP_BTM_INFO_FUNC("trigger stp assert failed\n");
	}
    if (0 == status)
		STP_BTM_INFO_FUNC("trigger stp assert succeed\n");
    return status;
	
}
INT32 _stp_trigger_firmware_assert_via_emi(VOID)
{
    INT32 status = -1;
	INT32 j = 0;
	
	CONSYS_REG_WRITE(CONSYS_AP2CONN_OSC_EN_REG,CONSYS_REG_READ(CONSYS_AP2CONN_OSC_EN_REG) & ~CONSYS_AP2CONN_WAKEUP_BIT);
	STP_BTM_INFO_FUNC("enable:dump CONSYS_AP2CONN_OSC_EN_REG(0x%x)\n",CONSYS_REG_READ(CONSYS_AP2CONN_OSC_EN_REG));
	usleep_range(64, 96);
	CONSYS_REG_WRITE(CONSYS_AP2CONN_OSC_EN_REG,CONSYS_REG_READ(CONSYS_AP2CONN_OSC_EN_REG) | CONSYS_AP2CONN_WAKEUP_BIT);
	STP_BTM_INFO_FUNC("disable:dump CONSYS_AP2CONN_OSC_EN_REG(0x%x)\n",CONSYS_REG_READ(CONSYS_AP2CONN_OSC_EN_REG));

	do {  
        if(0 != mtk_wcn_stp_coredump_start_get()){
            status = 0;
            break;
        }
		
		stp_dbg_poll_cpupcr(5 , 1 , 1);
		j++;
		STP_BTM_INFO_FUNC("Wait for assert message (%d)\n", j);
		osal_msleep(20); 
        if(j > 8) 
            break;   

    } while(1);
    
    return status;
}
static inline INT32 _stp_btm_notify_wmt_dmp_wq(MTKSTP_BTM_T *stp_btm){

    INT32 retval;
#if 0
	UINT32 dump_type;
	UINT8 *virtual_addr = NULL;
#endif	
    if(stp_btm == NULL)
    {
        return STP_BTM_OPERATION_FAIL;
    }
    else 
    {

#if 1 /* Paged dump */
        STP_BTM_INFO_FUNC("paged dump start++\n");
        retval = _stp_btm_dump_type(stp_btm,STP_OPID_BTM_PAGED_DUMP);
		if(retval)
		{
			STP_BTM_ERR_FUNC("paged dump fail\n");
		}

#else    
    	virtual_addr = wmt_plat_get_emi_virt_add(EXP_APMEM_CTRL_CHIP_SYNC_ADDR);
		if(!virtual_addr){
			STP_BTM_ERR_FUNC("get dump type virtual addr fail\n");
			return -1;
		}
		else
		{
    		dump_type = CONSYS_REG_READ(virtual_addr);
			STP_BTM_INFO_FUNC("dump type:%08x\n",dump_type);
		}

		if((dump_type & 0xfffff) == (CONSYS_PAGED_DUMP_START_ADDR & 0xfffff))
		{
			STP_BTM_INFO_FUNC("do paged dump\n");
        	retval = _stp_btm_dump_type(stp_btm,STP_OPID_BTM_PAGED_DUMP);
			if(retval)
			{
				STP_BTM_ERR_FUNC("paged dump fail,do full dump\n");
				_stp_btm_dump_type(stp_btm,STP_OPID_BTM_FULL_DUMP);
			}
		}
		else if((dump_type & 0xfffff) == (CONSYS_FULL_DUMP_START_ADDR & 0xfffff))
		{
			STP_BTM_INFO_FUNC("do full dump\n");
			retval = _stp_btm_dump_type(stp_btm,STP_OPID_BTM_FULL_DUMP);
		}
		else
		{
			STP_BTM_INFO_FUNC("do normal dump\n");
			retval = _stp_btm_dump_type(stp_btm,STP_OPID_BTM_DBG_DUMP);
		}
#endif        

    }
    return retval;
}
Example #4
0
static INT32 _stp_btm_put_dump_to_nl(VOID)
{
#define NUM_FETCH_ENTRY 8

	static UINT8 buf[2048];
	static UINT8 tmp[2048];

	UINT32 buf_len;
	STP_PACKET_T *pkt;
	STP_DBG_HDR_T *hdr;
	INT32 remain = 0, index = 0;
	INT32 retry = 0, rc = 0;
	INT32 len;

	STP_BTM_INFO_FUNC("Enter..\n");

	index = 0;
	tmp[index++] = '[';
	tmp[index++] = 'M';
	tmp[index++] = ']';

	do {
		index = 3;
		remain = stp_dbg_dmp_out_ex(&buf[0], &buf_len);
		if (buf_len > 0) {
			pkt = (STP_PACKET_T *) buf;
			hdr = &pkt->hdr;
			len = pkt->hdr.len;
			osal_memcpy(&tmp[index], &len, 2);
			index += 2;
			if (hdr->dbg_type == STP_DBG_FW_DMP) {
				osal_memcpy(&tmp[index], pkt->raw, pkt->hdr.len);

				if (pkt->hdr.len <= 1500) {
					tmp[index + pkt->hdr.len] = '\n';
					tmp[index + pkt->hdr.len + 1] = '\0';

					/* pr_warn("\n%s\n+++\n", tmp); */
					rc = stp_btm_dump_send_retry_handler((PINT8)&tmp, len);
					if (rc)
						goto exit;

					/* schedule(); */
				} else {
					STP_BTM_INFO_FUNC("dump entry length is over long\n");
					osal_bug_on(0);
				}
				retry = 0;
			}
		} else {
			retry++;
			osal_sleep_ms(100);
		}
	} while ((remain > 0) || (retry < 2));

exit:
	STP_BTM_INFO_FUNC("Exit..\n");
	return 0;
}
static INT32 _stp_btm_handler(MTKSTP_BTM_T *stp_btm, P_STP_BTM_OP pStpOp)
{
    INT32 ret = -1;

    if (NULL == pStpOp) 
    {
        return -1;
    }

    switch(pStpOp->opId) 
    {
        case STP_OPID_BTM_EXIT:
            // TODO: clean all up?
            ret = 0;
        break;

        /*tx timeout retry*/
        case STP_OPID_BTM_RETRY:
            stp_do_tx_timeout();
            ret = 0;
            
        break;

        /*whole chip reset*/
        case STP_OPID_BTM_RST:
            STP_BTM_INFO_FUNC("whole chip reset start!\n");
            STP_BTM_INFO_FUNC("....+\n");
            if(stp_btm->wmt_notify)
            {
                stp_btm->wmt_notify(BTM_RST_OP);
                ret = 0;
            }
            else
            {
                STP_BTM_ERR_FUNC("stp_btm->wmt_notify is NULL.");
                ret = -1;
            }

            STP_BTM_INFO_FUNC("whole chip reset end!\n");
            
        break;

        case STP_OPID_BTM_DBG_DUMP:
            /*Notify the wmt to get dump data*/
            STP_BTM_DBG_FUNC("wmt dmp notification\n");
            
            _stp_btm_put_dump_to_nl();
                           
        break;

        default:
            ret = -1;
        break;
    }
    
    return ret;
}
INT32 _stp_trigger_firmware_assert_via_emi(VOID)
{
	PUINT8 p_virtual_addr = NULL;
    INT32 status = -1;
   	INT32 i = 0, j = 0;
	
    do {        
        STP_BTM_INFO_FUNC("[Force Assert] stp_trigger_firmware_assert_via_emi -->\n");
    	p_virtual_addr = wmt_plat_get_emi_virt_add(EXP_APMEM_CTRL_HOST_OUTBAND_ASSERT_W1);
    	if(!p_virtual_addr)
    	{
    		STP_BTM_ERR_FUNC("get virtual address fail\n");
    		return -1;
    	}

    	CONSYS_REG_WRITE(p_virtual_addr, EXP_APMEM_HOST_OUTBAND_ASSERT_MAGIC_W1);
        STP_BTM_INFO_FUNC("[Force Assert] stp_trigger_firmware_assert_via_emi <--\n");
#if 1
        //wait for firmware assert 
        osal_sleep_ms(50); 
        //if firmware is not assert self, host driver helps it.
        do
        {
            if(0 != mtk_wcn_stp_coredump_start_get()){
                status = 0;
                break;
            }  
			
            mtk_wcn_stp_wakeup_consys();
            STP_BTM_INFO_FUNC("[Force Assert] wakeup consys (%d)\n", i);
            stp_dbg_poll_cpupcr(5 , 1 , 1);
            osal_sleep_ms(5);

			i++;
            if(i > 20){
				i = 0;
                break;
            }          
        } while(1);
#endif

        if(0 != mtk_wcn_stp_coredump_start_get()){
            status = 0;
            break;
        }

		j++;
        if(j > 8) {
			j = 0;
            break;        
        }
    } while(1);
    
    return status;
}
INT32 _stp_trigger_firmware_assert_via_emi(VOID)
{
    INT32 status = -1;
	INT32 j = 0;

	wmt_plat_force_trigger_assert(STP_FORCE_TRG_ASSERT_DEBUG_PIN);

	do {  
        if(0 != mtk_wcn_stp_coredump_start_get()){
            status = 0;
            break;
        }
		
		stp_dbg_poll_cpupcr(5 , 1 , 1);
		stp_dbg_poll_dmaregs(5 , 1);
		j++;
		STP_BTM_INFO_FUNC("Wait for assert message (%d)\n", j);
		osal_sleep_ms(20); 
        if(j > 49) { /* wait for 1 second*/
			stp_dbg_set_fw_info("host trigger fw assert timeout",
				osal_strlen("host trigger fw assert timeout"),STP_HOST_TRIGGER_ASSERT_TIMEOUT);
			wcn_core_dump_timeout();/* trigger collect SYS_FTRACE*/
            break;   
        }
    } while(1);
    
    return status;
}
static inline INT32 _stp_btm_do_fw_assert_via_emi(MTKSTP_BTM_T *stp_btm){

#if 0
    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_WARN_FUNC("get_free_lxop fail \n");
            return -1;//break;
        }
        pOp->op.opId = STP_OPID_BTM_FORCE_FW_ASSERT;
        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;
    }
    return retval;
#endif
	INT32 ret  = -1;

	ret = _stp_trigger_firmware_assert_via_emi();
#if 0
	if(0 != _stp_get_dump_info(EXP_APMEM_CTRL_HOST_OUTBAND_ASSERT_W1))
	{
		STP_BTM_INFO_FUNC("EXP_APMEM_CTRL_HOST_OUTBAND_ASSERT_W1 has not clear,reset it\n");
		_stp_set_dump_info(EXP_APMEM_CTRL_HOST_OUTBAND_ASSERT_W1, 0x0);
	}
	else
	{
		STP_BTM_INFO_FUNC("EXP_APMEM_CTRL_HOST_OUTBAND_ASSERT_W1 reset by fw side\n");
	}
#endif
	return ret;
	
}
Example #9
0
static INT32 _stp_btm_put_dump_to_aee(void)
{
    static UINT8  buf[2048];
    static UINT8  tmp[2048];

    UINT32  buf_len;       
    STP_PACKET_T  *pkt;
    STP_DBG_HDR_T *hdr;
    INT32 remain = 0;
    INT32 retry = 0;
    INT32 ret = 0;
    STP_BTM_INFO_FUNC("Enter..\n");

    do {
        remain = stp_dbg_dmp_out_ex(&buf[0], &buf_len);
        if (buf_len > 0) {
            pkt = (STP_PACKET_T*)buf;
            hdr = &pkt->hdr;
            if (hdr->dbg_type == STP_DBG_FW_DMP) {
                osal_memcpy(&tmp[0], pkt->raw, pkt->hdr.len);

                if (pkt->hdr.len <= 1500) {
                    tmp[pkt->hdr.len] = '\n';
                    tmp[pkt->hdr.len + 1] = '\0';

                    ret = stp_dbg_aee_send(tmp, pkt->hdr.len, 0);                 
                } else {
                    STP_BTM_INFO_FUNC("dump entry length is over long\n");
                    osal_bug_on(0);
                }
                retry = 0;
            }
			retry = 0;
        } else {  
            retry ++;
            osal_sleep_ms(20);
        }
    }while ((remain > 0) || (retry < 10));

    STP_BTM_INFO_FUNC("Exit..\n");
    return ret;
}
Example #10
0
INT32 stp_btm_deinit(MTKSTP_BTM_T *stp_btm)
{

	UINT32 ret = -1;

	STP_BTM_INFO_FUNC("btm deinit\n");

	if (!stp_btm)
		return STP_BTM_OPERATION_FAIL;

	ret = osal_thread_destroy(&stp_btm->BTMd);
	if (ret < 0) {
		STP_BTM_ERR_FUNC("osal_thread_destroy FAILS\n");
		return STP_BTM_OPERATION_FAIL;
	}

	return STP_BTM_OPERATION_SUCCESS;
}
INT32 _stp_trigger_firmware_assert_via_emi(VOID)
{
    INT32 status = -1;
	INT32 j = 0;

	wmt_plat_force_trigger_assert(STP_FORCE_TRG_ASSERT_DEBUG_PIN);

	do {  
        if(0 != mtk_wcn_stp_coredump_start_get()){
            status = 0;
            break;
        }
		
		stp_dbg_poll_cpupcr(5 , 1 , 1);
		j++;
		STP_BTM_INFO_FUNC("Wait for assert message (%d)\n", j);
		osal_msleep(20); 
        if(j > 24) 
            break;   

    } while(1);
    
    return status;
}
static INT32 _stp_btm_put_dump_to_nl(void)
{
    #define NUM_FETCH_ENTRY 8   

    static UINT8  buf[2048];
    static UINT8  tmp[2048];

    UINT32  buf_len;       
    STP_PACKET_T  *pkt;
    STP_DBG_HDR_T *hdr;
    INT32  remain=0, index =0;
    INT32 retry = 0, rc = 0, nl_retry = 0;
    STP_BTM_INFO_FUNC("Enter..\n");
  
    index = 0;
    tmp[index++]='[';
    tmp[index++]='M';
    tmp[index++]=']'; 

    do
    {
        index = 3;
        remain = stp_dbg_dmp_out_ex(&buf[0], &buf_len);
        if (buf_len > 0)
        {
            pkt = (STP_PACKET_T  *)buf;
            hdr = &pkt->hdr;
            if (hdr->dbg_type == STP_DBG_FW_DMP){
                memcpy(&tmp[index], pkt->raw, pkt->hdr.len);

                if(pkt->hdr.len <= 1500)
                {
                    tmp[index + pkt->hdr.len] = '\n';
                    tmp[index + pkt->hdr.len + 1] = '\0';

                    //printk("\n%s\n+++\n", tmp);
                    rc = stp_dbg_nl_send((char *)&tmp, 2);

                    while(rc){
                       nl_retry++;                       
                       if(nl_retry > 1000){
                            break;
                       }                       
                       STP_BTM_WARN_FUNC("**dump send fails, and retry again.**\n");
                       msleep(3);
                       rc = stp_dbg_nl_send((char *)&tmp, 2);
                       if(!rc){
                          STP_BTM_WARN_FUNC("****retry again ok!**\n");
                       }
                    }                    
                    //schedule();
                } else {
                    STP_BTM_INFO_FUNC("dump entry length is over long\n");
                    BUG_ON(0);
                }
                retry = 0;
            }
        }else
        {
            retry ++;
            msleep(100);
        }
    }while((remain > 0) || (retry < 2));

    STP_BTM_INFO_FUNC("Exit..\n");
    return 0;
}
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 >= 4)?("???"):(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 >= 4)?("???"):(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;
        }
    }
    
    STP_BTM_INFO_FUNC("exits \n");

    return 0;
};
Example #14
0
static INT32 _stp_btm_handler(MTKSTP_BTM_T *stp_btm, P_STP_BTM_OP pStpOp)
{
    INT32 ret = -1;
    INT32 dump_sink = 1; //core dump target, 0: aee; 1: netlink
    static UINT32 counter = 0;
	UINT32 full_dump_left = STP_FULL_DUMP_TIME;
	UINT32 page_counter = 0;
	ENUM_STP_FW_ISSUE_TYPE issue_type;
	
    if (NULL == pStpOp) 
    {
        return -1;
    }

    switch(pStpOp->opId) 
    {
        case STP_OPID_BTM_EXIT:
            // TODO: clean all up?
            ret = 0;
        break;

        /*tx timeout retry*/
        case STP_OPID_BTM_RETRY:
            stp_do_tx_timeout();
            ret = 0;
            
        break;

        /*whole chip reset*/
        case STP_OPID_BTM_RST:
            STP_BTM_INFO_FUNC("whole chip reset start!\n");
            STP_BTM_INFO_FUNC("....+\n");
            if(stp_btm->wmt_notify)
            {
                stp_btm->wmt_notify(BTM_RST_OP);
                ret = 0;
            }
            else
            {
                STP_BTM_ERR_FUNC("stp_btm->wmt_notify is NULL.");
                ret = -1;
            }

            STP_BTM_INFO_FUNC("whole chip reset end!\n");
            
        break;

        case STP_OPID_BTM_DBG_DUMP:
            /*Notify the wmt to get dump data*/
            STP_BTM_DBG_FUNC("wmt dmp notification\n");
            dump_sink = ((stp_btm->wmt_notify(BTM_GET_AEE_SUPPORT_FLAG) == MTK_WCN_BOOL_TRUE) ? 0 : 1);
            
            if (dump_sink == 0) {
                _stp_btm_put_dump_to_aee();
            } else if (dump_sink == 1) {
                _stp_btm_put_dump_to_nl();
            } else {
                STP_BTM_ERR_FUNC("unknown sink %d\n", dump_sink);
            }            
                           
        break;


        case STP_OPID_BTM_DUMP_TIMEOUT:
            // Flush dump data, and reset compressor
            STP_BTM_INFO_FUNC("Flush dump data\n");
            wcn_core_dump_flush(0,MTK_WCN_BOOL_TRUE);
        break;

		case STP_OPID_BTM_POLL_CPUPCR:
			do{
				UINT32 times;
				UINT32 sleep;

				times = pStpOp->au4OpData[0];
				sleep = pStpOp->au4OpData[1];

				ret = stp_dbg_poll_cpupcr(times, sleep,0);
				ret += stp_dbg_poll_dmaregs(times, sleep);
			}while(0);
		break;
		
		case STP_OPID_BTM_PAGED_DUMP:
		g_paged_dump_len = 0;
		issue_type = STP_FW_ASSERT_ISSUE;
		
		wmt_plat_set_host_dump_state(STP_HOST_DUMP_NOT_START);
		page_counter = 0;
		do{
			UINT32 loop_cnt1 = 0;
			UINT32 loop_cnt2 = 0;
			ENUM_HOST_DUMP_STATE host_state;
			ENUM_CHIP_DUMP_STATE chip_state;
			UINT32 dump_phy_addr = 0;
			UINT8 *dump_vir_addr = NULL;
			UINT32 dump_len = 0;
			UINT32 isEnd = 0;
			P_CONSYS_EMI_ADDR_INFO p_emi_ctrl_state_info;

			p_emi_ctrl_state_info = wmt_plat_get_emi_phy_add();
			osal_assert(p_emi_ctrl_state_info);

			host_state = (ENUM_HOST_DUMP_STATE)wmt_plat_get_dump_info(p_emi_ctrl_state_info->p_emi_ctrl_state_offset->emi_apmem_ctrl_host_sync_state);
			if(STP_HOST_DUMP_NOT_START == host_state)
			{
				counter++;
				STP_BTM_INFO_FUNC("counter(%d)\n",counter);
				osal_sleep_ms(100);
			}
			else
			{
				counter = 0;
			}
			while(1)
			{
				chip_state = (ENUM_CHIP_DUMP_STATE)wmt_plat_get_dump_info(p_emi_ctrl_state_info->p_emi_ctrl_state_offset->emi_apmem_ctrl_chip_sync_state);
				if(STP_CHIP_DUMP_PUT_DONE == chip_state){
                    STP_BTM_INFO_FUNC("chip put done\n");
                    break;
                }    
				else
				{
				    STP_BTM_INFO_FUNC("waiting chip put done\n");
				    STP_BTM_INFO_FUNC("chip_state: %d\n", chip_state);
					loop_cnt1 ++;
					osal_sleep_ms(5);
				}
				if(loop_cnt1 > 10)
					goto paged_dump_end;
				
			}

			wmt_plat_set_host_dump_state(STP_HOST_DUMP_GET);

			dump_phy_addr = wmt_plat_get_dump_info(p_emi_ctrl_state_info->p_emi_ctrl_state_offset->emi_apmem_ctrl_chip_sync_addr);
			
			if(!dump_phy_addr)
			{
				STP_BTM_ERR_FUNC("get paged dump phy address fail\n");
				ret = -1;
				break;
			}

			dump_vir_addr = wmt_plat_get_emi_virt_add(dump_phy_addr - p_emi_ctrl_state_info->emi_phy_addr);
			if(!dump_vir_addr)
			{
				STP_BTM_ERR_FUNC("get paged dump phy address fail\n");
				ret = -2;
				break;
			}
			dump_len = wmt_plat_get_dump_info(p_emi_ctrl_state_info->p_emi_ctrl_state_offset->emi_apmem_ctrl_chip_sync_len);
			STP_BTM_INFO_FUNC("dump_phy_ddr(%08x),dump_vir_add(0x%p),dump_len(%d)\n",dump_phy_addr,dump_vir_addr,dump_len);

			/*move dump info according to dump_addr & dump_len*/
#if 1
			osal_memcpy(&g_paged_dump_buffer[0],dump_vir_addr,dump_len);
			_stp_dump_emi_dump_buffer(&g_paged_dump_buffer[0],dump_len);

			if(0 == page_counter)//do fw assert infor paser in first paged dump
			{
				if(1 == stp_dbg_get_host_trigger_assert())
				{
					issue_type = STP_HOST_TRIGGER_FW_ASSERT;
				}
				ret = stp_dbg_set_fw_info(&g_paged_dump_buffer[0],512,issue_type);
				if(ret)
				{
					STP_BTM_ERR_FUNC("set fw issue infor fail(%d),maybe fw warm reset...\n",ret);
					stp_dbg_set_fw_info("Fw Warm reset",osal_strlen("Fw Warm reset"),STP_FW_WARM_RST_ISSUE);
				}
			}
			
            if(dump_len <= 32*1024){
                ret = stp_dbg_aee_send(&g_paged_dump_buffer[0],dump_len, 0);
                if(ret == 0){
                     STP_BTM_INFO_FUNC("aee send ok!\n");
                } else if (ret == 1) {
                     STP_BTM_INFO_FUNC("aee send fisish!\n");
                } else {
                     STP_BTM_ERR_FUNC("aee send error!\n");
                }
            } else {
                STP_BTM_ERR_FUNC("dump len is over than 32K(%d)\n",dump_len);
            }
            
            g_paged_dump_len += dump_len;
			STP_BTM_INFO_FUNC("dump len update(%d)\n",g_paged_dump_len);
#endif
			wmt_plat_update_host_sync_num();
			wmt_plat_set_host_dump_state(STP_HOST_DUMP_GET_DONE);

			STP_BTM_INFO_FUNC("host sync num(%d),chip sync num(%d)\n",
				wmt_plat_get_dump_info(p_emi_ctrl_state_info->p_emi_ctrl_state_offset->emi_apmem_ctrl_host_sync_num),
				wmt_plat_get_dump_info(p_emi_ctrl_state_info->p_emi_ctrl_state_offset->emi_apmem_ctrl_chip_sync_num));

            page_counter++;
            STP_BTM_INFO_FUNC("\n\n++ paged dump counter(%d) ++\n\n\n",page_counter);
            
			while(1)
			{
				chip_state = (ENUM_CHIP_DUMP_STATE)wmt_plat_get_dump_info(p_emi_ctrl_state_info->p_emi_ctrl_state_offset->emi_apmem_ctrl_chip_sync_state);
				if(STP_CHIP_DUMP_END == chip_state)
				{
				    STP_BTM_INFO_FUNC("chip put end\n");
					wmt_plat_set_host_dump_state(STP_HOST_DUMP_END);
					break;
				}
				else
				{
                    STP_BTM_INFO_FUNC("waiting chip put end\n");
                
					loop_cnt2++;
					osal_sleep_ms(10);
				}
				if(loop_cnt2 > 10)
					goto paged_dump_end;
			}
			
paged_dump_end:
			wmt_plat_set_host_dump_state(STP_HOST_DUMP_NOT_START);
			
            if(counter * 100 > STP_PAGED_DUMP_TIME_LIMIT)
            {
    			isEnd = wmt_plat_get_dump_info(p_emi_ctrl_state_info->p_emi_ctrl_state_offset->emi_apmem_ctrl_chip_paded_dump_end);

                if(isEnd)
    			{
    				STP_BTM_INFO_FUNC("paged dump end\n");

                    STP_BTM_INFO_FUNC("\n\n paged dump print  ++ \n\n");
                    _stp_dump_emi_dump_buffer(&g_paged_dump_buffer[0],g_paged_dump_len);
                    STP_BTM_INFO_FUNC("\n\n paged dump print  -- \n\n");
                    STP_BTM_INFO_FUNC("\n\n paged dump size = %d, paged dump page number = %d \n\n", g_paged_dump_len, page_counter);
                    counter = 0;
    				ret = 0;
    				break;
     			} 
                else
                {    			
                    STP_BTM_ERR_FUNC("paged dump fail\n");
                    wmt_plat_set_host_dump_state(STP_HOST_DUMP_NOT_START);
					stp_dbg_poll_cpupcr(5,5,0);
					stp_dbg_poll_dmaregs(5, 1);
					counter = 0;
                    ret = -1;
                    break;
                }
            }

		}while(1);
        
        break;

		case STP_OPID_BTM_FULL_DUMP:

		wmt_plat_set_host_dump_state(STP_HOST_DUMP_NOT_START);
		do{
			UINT32 loop_cnt1 = 0;
			UINT32 loop_cnt2 = 0;
			ENUM_CHIP_DUMP_STATE chip_state;
			UINT32 dump_phy_addr = 0;
			UINT8 *dump_vir_addr = NULL;
			UINT32 dump_len = 0;
			UINT32 isFail = 0;
			P_CONSYS_EMI_ADDR_INFO p_emi_ctrl_state_info;

			p_emi_ctrl_state_info = wmt_plat_get_emi_phy_add();
			osal_assert(p_emi_ctrl_state_info);
			
			while(1)
			{
				chip_state = (ENUM_CHIP_DUMP_STATE)wmt_plat_get_dump_info(p_emi_ctrl_state_info->p_emi_ctrl_state_offset->emi_apmem_ctrl_chip_sync_state);
				if(STP_CHIP_DUMP_PUT_DONE == chip_state)
					break;
				else
				{
					loop_cnt1 ++;
					osal_sleep_ms(10);
				}
				if(loop_cnt1 > 10)
				{
					isFail = 1;
					goto full_dump_end;
				}
			}

			wmt_plat_set_host_dump_state(STP_HOST_DUMP_GET);

			dump_phy_addr = wmt_plat_get_dump_info(p_emi_ctrl_state_info->p_emi_ctrl_state_offset->emi_apmem_ctrl_chip_sync_addr);
			if(!dump_phy_addr)
			{
				STP_BTM_ERR_FUNC("get phy dump address fail\n");
				ret = -1;
				break;
			}
			
			dump_vir_addr = wmt_plat_get_emi_virt_add(dump_phy_addr - p_emi_ctrl_state_info->emi_phy_addr);
			if(!dump_vir_addr)
			{
				STP_BTM_ERR_FUNC("get vir dump address fail\n");
				ret = -2;
				break;
			}
			dump_len = wmt_plat_get_dump_info(p_emi_ctrl_state_info->p_emi_ctrl_state_offset->emi_apmem_ctrl_chip_sync_len);
			/*move dump info according to dump_addr & dump_len*/
			wmt_plat_update_host_sync_num();
			wmt_plat_set_host_dump_state(STP_HOST_DUMP_GET_DONE);

			STP_BTM_INFO_FUNC("host sync num(%d),chip sync num(%d)\n",
				wmt_plat_get_dump_info(p_emi_ctrl_state_info->p_emi_ctrl_state_offset->emi_apmem_ctrl_host_sync_num),
				wmt_plat_get_dump_info(p_emi_ctrl_state_info->p_emi_ctrl_state_offset->emi_apmem_ctrl_chip_sync_num));
			
			while(1)
			{
				chip_state = (ENUM_CHIP_DUMP_STATE)wmt_plat_get_dump_info(p_emi_ctrl_state_info->p_emi_ctrl_state_offset->emi_apmem_ctrl_chip_sync_state);
				if(STP_CHIP_DUMP_END == chip_state)
				{
					wmt_plat_set_host_dump_state(STP_HOST_DUMP_END);
					break;
				}
				else
				{
					loop_cnt2++;
					osal_sleep_ms(10);
				}
				if(loop_cnt2 > 10)
				{
					isFail = 1;
					goto full_dump_end;
				}
			}
			wmt_plat_set_host_dump_state(STP_HOST_DUMP_NOT_START);
full_dump_end:
			if(isFail)
			{
				STP_BTM_ERR_FUNC("full dump fail\n");
				wmt_plat_set_host_dump_state(STP_HOST_DUMP_NOT_START);
				ret = -1;
				break;
			}
		}while(--full_dump_left > 0);
		if(0 == full_dump_left)
		{
			STP_BTM_INFO_FUNC("full dump end\n");
			ret = 0;
		}
		break;
		case STP_OPID_BTM_PAGED_TRACE:
		g_paged_trace_len = 0;
		do{
			UINT32 ctrl_val = 0;
			UINT32 loop_cnt1 = 0;
			UINT32 buffer_start = 0;
			UINT32 buffer_idx = 0;
			UINT8 *dump_vir_addr = NULL; 
			P_CONSYS_EMI_ADDR_INFO p_emi_ctrl_state_info;

			p_emi_ctrl_state_info = wmt_plat_get_emi_phy_add();
			osal_assert(p_emi_ctrl_state_info);
			
			while(loop_cnt1 < 10)
			{
				ctrl_val = wmt_plat_get_dump_info(p_emi_ctrl_state_info->p_emi_ctrl_state_offset->emi_apmem_ctrl_state);
				if(0x8 == ctrl_val)
					break;
				else
				{
					osal_sleep_ms(10);
					loop_cnt1++;
				}
			}

			if(loop_cnt1 >= 10)
			{
				STP_BTM_ERR_FUNC("polling CTRL STATE fail\n");
				ret = -1;
				break;
			}

			buffer_start = wmt_plat_get_dump_info(p_emi_ctrl_state_info->p_emi_ctrl_state_offset->emi_apmem_ctrl_chip_print_buff_start);
			buffer_idx = wmt_plat_get_dump_info(p_emi_ctrl_state_info->p_emi_ctrl_state_offset->emi_apmem_ctrl_chip_print_buff_idx);
			//buffer_len = buffer_idx - buffer_start;
			g_paged_trace_len = buffer_idx;
			STP_BTM_INFO_FUNC("paged trace buffer addr(%08x),buffer_len(%d)\n",buffer_start,buffer_idx);
			dump_vir_addr = wmt_plat_get_emi_virt_add(buffer_start - p_emi_ctrl_state_info->emi_phy_addr);
			if(!dump_vir_addr)
			{
				STP_BTM_ERR_FUNC("get vir dump address fail\n");
				ret = -2;
				break;
			}
			osal_memcpy(&g_paged_trace_buffer[0],dump_vir_addr,buffer_idx < STP_DBG_PAGED_TRACE_SIZE ? buffer_idx : STP_DBG_PAGED_TRACE_SIZE);
			/*moving paged trace according to buffer_start & buffer_len*/
            do {
                int i = 0;
				int dump_len = 0;
				dump_len = buffer_idx < STP_DBG_PAGED_TRACE_SIZE ? buffer_idx : STP_DBG_PAGED_TRACE_SIZE;
                printk("\n\n -- paged trace hex output --\n\n");
                for(i = 0;i < dump_len; i++)
                {
                    if(i%16 == 0){
                    printk("\n");
                    }
                    printk("%02x ",g_paged_trace_buffer[i]);
                }
                printk("\n\n -- paged trace ascii output --\n\n");	
                for(i = 0;i < dump_len; i++)
                {
                    if(i%64 == 0)
                    printk("\n");
                    printk("%c",g_paged_trace_buffer[i]);
                }
            }while(0);
			/*move parser fw assert infor to paged dump in the one paged dump*/
			//ret = stp_dbg_set_fw_info(&g_paged_trace_buffer[0],g_paged_trace_len,issue_type);
			ret = 0;

		}while(0);
		mtk_wcn_stp_ctx_restore();
		break;

#if CFG_WMT_LTE_COEX_HANDLING
		case STP_OPID_BTM_WMT_LTE_COEX:
			ret = wmt_idc_msg_to_lte_handing();
		break;
#endif
        default:
            ret = -1;
        break;
    }
    
    return ret;
}
Example #15
0
static INT32 _stp_btm_handler(MTKSTP_BTM_T *stp_btm, P_STP_BTM_OP pStpOp)
{
    INT32 ret = -1;
    INT32 dump_sink = 1; //core dump target, 0: aee; 1: netlink

    if (NULL == pStpOp) 
    {
        return -1;
    }

    switch(pStpOp->opId) 
    {
        case STP_OPID_BTM_EXIT:
            // TODO: clean all up?
            ret = 0;
        break;

        /*tx timeout retry*/
        case STP_OPID_BTM_RETRY:
            stp_do_tx_timeout();
            ret = 0;
            
        break;

        /*whole chip reset*/
        case STP_OPID_BTM_RST:
            STP_BTM_INFO_FUNC("whole chip reset start!\n");
            STP_BTM_INFO_FUNC("....+\n");
            if(stp_btm->wmt_notify)
            {
                stp_btm->wmt_notify(BTM_RST_OP);
                ret = 0;
            }
            else
            {
                STP_BTM_ERR_FUNC("stp_btm->wmt_notify is NULL.");
                ret = -1;
            }

            STP_BTM_INFO_FUNC("whole chip reset end!\n");
            
        break;

        case STP_OPID_BTM_DBG_DUMP:
            /*Notify the wmt to get dump data*/
            STP_BTM_DBG_FUNC("wmt dmp notification\n");
            dump_sink = ((stp_btm->wmt_notify(BTM_GET_AEE_SUPPORT_FLAG) == MTK_WCN_BOOL_TRUE) ? 0 : 1);
            
            if (dump_sink == 0) {
                _stp_btm_put_dump_to_aee();
            } else if (dump_sink == 1) {
                _stp_btm_put_dump_to_nl();
            } else {
                STP_BTM_ERR_FUNC("unknown sink %d\n", dump_sink);
            }            
                           
        break;


        case STP_OPID_BTM_DUMP_TIMEOUT:
            // Flush dump data, and reset compressor
            STP_BTM_INFO_FUNC("Flush dump data\n");
            wcn_core_dump_flush(0);
        break;
        
        default:
            ret = -1;
        break;
    }
    
    return ret;
}
Example #16
0
static INT32 _stp_btm_proc(PVOID 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, (PVOID)stp_btm);

		if (osal_thread_should_stop(&stp_btm->BTMd)) {
			STP_BTM_INFO_FUNC("should stop now...\n");
			/* TODO: clean up active opQ */
			break;
		}
#if 1
		if (gDumplogflag) {
			/* pr_warn("enter place1\n"); */
			if (mtk_wcn_stp_is_uart_mand_mode() || mtk_wcn_stp_is_uart_fullset_mode())
				dump_uart_history();
			gDumplogflag = 0;
			continue;
		}
#endif

		/* 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 >= 4) ? ("???") : (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;
		}

		osal_lock_unsleepable_lock(&(stp_btm->wq_spinlock));
		stp_btm_set_current_op(stp_btm, pOp);
		osal_unlock_unsleepable_lock(&(stp_btm->wq_spinlock));
		result = _stp_btm_handler(stp_btm, &pOp->op);
		osal_lock_unsleepable_lock(&(stp_btm->wq_spinlock));
		stp_btm_set_current_op(stp_btm, NULL);
		osal_unlock_unsleepable_lock(&(stp_btm->wq_spinlock));

 handler_done:

		if (result) {
			STP_BTM_WARN_FUNC("opid id(0x%x)(%s) error(%d)\n",
				id, (id >= 4) ? ("???") : (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);
		}
	}

	STP_BTM_INFO_FUNC("exits\n");

	return 0;
};