/*****************************************************************************
* 函 数 名  : BSP_IPF_GetDlAdNum
*
* 功能描述  : 获取下行通道ADQ0和ADQ1队列中空闲AD个数
*
* 输入参数  : 无
*
* 输出参数  : pu32AD0Num    下行ADQ0队列中空闲AD个数
*             pu32AD1Num    下行ADQ1队列中空闲AD个数
* 返 回 值  : IPF_SUCCESS
*             IPF_ERROR
*
* 修改记录  : 2012年11月29日   z00212992  创建
*
*****************************************************************************/
int BSP_IPF_GetDlAdNum(unsigned int* pu32AD0Num, unsigned int* pu32AD1Num)
{
    unsigned int u32DlAd0Depth = 0;
    unsigned int u32DlAd1Depth = 0;
    unsigned int u32DlAd0wptr = 0;
    unsigned int u32DlAd0rptr = 0;
    unsigned int u32DlAd1wptr = 0;
    unsigned int u32DlAd1rptr = 0;
    unsigned int u32AD0Num = 0;
    unsigned int u32AD1Num = 0;
    /*入参检测*/
    if((NULL == pu32AD0Num)||(NULL == pu32AD1Num))
    {
        IPF_PRINT_ERROR("parameter is error\n");
        return BSP_ERR_IPF_INVALID_PARA;
    }

    /* 计算空闲AD0数量 */
    IPF_REG_READ(SOC_IPF_CH1_ADQ0_WPTR_ADDR(IPF_REGBASE_ADR), u32DlAd0wptr);
    IPF_REG_READ(SOC_IPF_CH1_ADQ0_RPTR_ADDR(IPF_REGBASE_ADR), u32DlAd0rptr);
    if (u32DlAd0wptr >= u32DlAd0rptr)/*写指针在前,正常顺序*/
        u32DlAd0Depth = IPF_DLAD0_DESC_SIZE - (u32DlAd0wptr - u32DlAd0rptr+1);
    else
        u32DlAd0Depth = u32DlAd0rptr - u32DlAd0wptr - 1;
    u32AD0Num = (u32DlAd0Depth > IPF_OBLIGATE_AD_NUM) ? (u32DlAd0Depth - IPF_OBLIGATE_AD_NUM) : 0;
    if(u32AD0Num > IPF_DLAD0_DESC_SIZE)
    {
        IPF_PRINT_ERROR("adq0 num is error\n");
        return BSP_ERR_IPF_INVALID_PARA;
    }
    *pu32AD0Num = u32AD0Num;

    /* 计算空闲AD1数量 */
    IPF_REG_READ(SOC_IPF_CH1_ADQ1_WPTR_ADDR(IPF_REGBASE_ADR), u32DlAd1wptr);
    IPF_REG_READ(SOC_IPF_CH1_ADQ1_RPTR_ADDR(IPF_REGBASE_ADR), u32DlAd1rptr);
    if (u32DlAd1wptr >= u32DlAd1rptr)/*写指针在前,正常顺序*/
        u32DlAd1Depth = IPF_DLAD1_DESC_SIZE - (u32DlAd1wptr - u32DlAd1rptr+1);
    else
        u32DlAd1Depth = u32DlAd1rptr - u32DlAd1wptr - 1;

    u32AD1Num = (u32DlAd1Depth > IPF_OBLIGATE_AD_NUM) ? (u32DlAd1Depth - IPF_OBLIGATE_AD_NUM) : 0;
    if(u32AD1Num > IPF_DLAD1_DESC_SIZE)
    {
        IPF_PRINT_ERROR("adq1 num is error\n");
        return BSP_ERR_IPF_INVALID_PARA;
    }
    *pu32AD1Num = u32AD1Num;

    return IPF_SUCCESS;
}
/*****************************************************************************
* 函 数 名  : BSP_IPF_ConfigDlAd
*
* 功能描述  : 配置下行ADQ队列,给空闲的AD分配新的内存缓冲区
*
* 输入参数  : eAdType    配置下行AD的类型
*             u32AdNum    配置下行AD的数目
*             pstAdDesc   下行AD分配的缓存空间对应的数据结构首地址
* 输出参数  : 无
*
* 返 回 值  : IPF_SUCCESS
*             IPF_ERROR
*
* 修改记录  : 2012年11月29日   z00212992  创建
*
*****************************************************************************/
int BSP_IPF_ConfigDlAd(IPF_AD_TYPE_E eAdType, unsigned int u32AdNum, IPF_AD_DESC_S *pstAdDesc  )
{
    unsigned int i;
    unsigned int u32ADQ0wptr;
    unsigned int u32ADQ1wptr;

    /*Modify_for_c_reset, l00212112,20130511, starts*/
    /*如果C核复位,则返回*/
    if (IPF_FORRESET_CONTROL_FORBID == IPF_GetControlFLagForCcoreReset())
    {
        IPF_PRINT_ERROR("ccore is resetting\n");
        return BSP_ERR_IPF_CCORE_RESETTING;
    }
    /*Modify_for_c_reset, l00212112,20130511, ends*/

    /* 入参检查 */
    if((IPF_AD_MAX <= eAdType) || (NULL == pstAdDesc))
    {
        IPF_PRINT_ERROR("parameter is error\n");
        return BSP_ERR_IPF_INVALID_PARA;
    }

    /* 检查模块是否初始化 */
    IPF_INIT_CHECK();

    if(IPF_AD_0 == eAdType)
    {
        g_stIPFDebugInfo->u32DlAdq0Num += u32AdNum;
        /* 读取ADQ0写指针 */
        IPF_REG_READ(SOC_IPF_CH1_ADQ0_WPTR_ADDR(IPF_REGBASE_ADR), u32ADQ0wptr);
        /* 获取目的结构体指针和目的结构体数据指针,插入到ADQ中 */
        for(i=0; i < u32AdNum; i++)
        {
            if((0 == pstAdDesc[i].u32OutPtr0) || (0 == pstAdDesc[i].u32OutPtr1))
            {
                IPF_PRINT_ERROR("point is null\n");
                return BSP_ERR_IPF_INVALID_PARA;
            }
            g_stIpfDl.pstIpfADQ0[u32ADQ0wptr].u32OutPtr0 = pstAdDesc[i].u32OutPtr0;
            g_stIpfDl.pstIpfADQ0[u32ADQ0wptr].u32OutPtr1 = pstAdDesc[i].u32OutPtr1;
            u32ADQ0wptr = ((u32ADQ0wptr + 1) < IPF_DLAD0_DESC_SIZE)? (u32ADQ0wptr + 1) : 0;
        }
        /* 更新ADQ0写指针 */
        IPF_REG_WRITE(SOC_IPF_CH1_ADQ0_WPTR_ADDR(IPF_REGBASE_ADR), u32ADQ0wptr);
    }
    else
    {
        g_stIPFDebugInfo->u32DlAdq1Num += u32AdNum;
        /* 读取ADQ1写指针 */
        IPF_REG_READ(SOC_IPF_CH1_ADQ1_WPTR_ADDR(IPF_REGBASE_ADR), u32ADQ1wptr);
        /* 获取目的结构体指针和目的结构体数据指针,插入到ADQ中 */
        for(i=0; i < u32AdNum; i++)
        {
            if((0 == pstAdDesc[i].u32OutPtr0) || (0 == pstAdDesc[i].u32OutPtr1))
            {
                IPF_PRINT_ERROR("point is null\n");
                return BSP_ERR_IPF_INVALID_PARA;
            }
            g_stIpfDl.pstIpfADQ1[u32ADQ1wptr].u32OutPtr0 = pstAdDesc[i].u32OutPtr0;
            g_stIpfDl.pstIpfADQ1[u32ADQ1wptr].u32OutPtr1 = pstAdDesc[i].u32OutPtr1;
            u32ADQ1wptr = ((u32ADQ1wptr + 1) < IPF_DLAD1_DESC_SIZE)? (u32ADQ1wptr + 1) : 0;
        }
        /* 更新ADQ1写指针 */
        IPF_REG_WRITE(SOC_IPF_CH1_ADQ1_WPTR_ADDR(IPF_REGBASE_ADR), u32ADQ1wptr);
    }
    return IPF_SUCCESS;
}
/*****************************************************************************
* 函 数 名  : BSP_IPF_GetUsedDlAd
*
* 功能描述  : 获取下行ADQ队列中已经被配置使用的AD信息,调用者必须确保调用过程中不会再配置BD
*
* 输入参数  : eAdType       下行AD的类型
* 输出参数  : pu32AdNum     保存该下行AD类型队列中已经被配置使用的AD数目指针
*             pstAdDesc     保存该下行AD类型队列中已经被配置使用的AD结构体指针
                            (需要调用者事先申请好,大小为IPF_DLAD_DESC_SIZE*IPF_AD_DESC_S)
* 返 回 值  : IPF_SUCCESS           成功
*             IPF_ERROR(其他错误码) 失败
*
* 修改记录  : 2013年9月9日   z00212992  创建
*
*****************************************************************************/
int BSP_IPF_GetUsedDlAd(IPF_AD_TYPE_E eAdType, unsigned int *pu32AdNum, IPF_AD_DESC_S *pstAdDesc)
{
    unsigned int i = 0;
    unsigned int u32IpfAdqRpt = 0;
    unsigned int u32IpfAdqWpt = 0;
    unsigned int u32IpfAdqSize = 0;
    IPF_AD_DESC_S *pstIpfADQ = (IPF_AD_DESC_S*)NULL;
    unsigned int u32AdNum = 0;

    /*  入参检查 */
    if((IPF_AD_MAX <= eAdType)|| (NULL == pu32AdNum) || (NULL == pstAdDesc))
    {
        IPF_PRINT_ERROR("parameter is error\n");
        return BSP_ERR_IPF_INVALID_PARA;
    }

    /* 获取真实的读指针 */
    if(IPF_SUCCESS != IPF_ObligateAdqRpt(IPF_CHANNEL_DOWN, eAdType, &u32IpfAdqRpt))
    {
        IPF_PRINT_ERROR("IPF_ObligateAdqRpt error\n");
        return IPF_ERROR;
    }

    /* 根据通道ID和AD类型获取操作寄存器对象(写指针、大小、队列) */
    switch (eAdType) {
        case IPF_AD_0:
                IPF_REG_READ(SOC_IPF_CH1_ADQ0_WPTR_ADDR(IPF_REGBASE_ADR), u32IpfAdqWpt);
                u32IpfAdqSize = IPF_DLAD0_DESC_SIZE;
                pstIpfADQ = g_stIpfDl.pstIpfADQ0;
            break;
        case IPF_AD_1:
                IPF_REG_READ(SOC_IPF_CH1_ADQ1_WPTR_ADDR(IPF_REGBASE_ADR), u32IpfAdqWpt);
                u32IpfAdqSize = IPF_DLAD1_DESC_SIZE;
                pstIpfADQ = g_stIpfDl.pstIpfADQ1;
            break;
        default:
            IPF_PRINT_ERROR("parameter is error\n");
            break;
    }

    if((IPF_AD_DESC_S*)NULL == pstIpfADQ)
    {
        return BSP_ERR_IPF_INVALID_PARA;
    }

    /* 根据获取下行ADQ队列(对应类型)中已经被配置使用的AD信息,并传给pu32AdNum和pstAdDesc */
    for(i = u32IpfAdqRpt; i != u32IpfAdqWpt; i %= u32IpfAdqSize)
    {
        if(NULL == pstAdDesc)
        {
            IPF_PRINT_ERROR("point is null\n");
            return BSP_ERR_IPF_INVALID_PARA;
        }
        pstAdDesc->u32OutPtr0 = pstIpfADQ[i].u32OutPtr0;
        pstAdDesc->u32OutPtr1 = pstIpfADQ[i].u32OutPtr1;
        u32AdNum++;
        pstAdDesc++;
        i++;
    }
    *pu32AdNum = u32AdNum;

    return IPF_SUCCESS;
}
BSP_S32 BSP_IPF_CHInfo(IPF_CHANNEL_TYPE_E eChnType)
{
    BSP_U32 u32ChanCtrlInfo = 0;
    BSP_U32 u32ChanStateInfo = 0;

    BSP_U32 u32BdqBaseAddr = 0;
    BSP_U32 u32BdqDepth = 0;
    BSP_U32 u32BdqWptr = 0;
    BSP_U32 u32BdqRptr = 0;
    BSP_U32 u32BdqWaddr = 0;
    BSP_U32 u32BdqRaddr = 0;
    BSP_U32 u32RdqBaseAddr = 0;
    BSP_U32 u32RdqDepth = 0;
    BSP_U32 u32RdqRptr = 0;
    BSP_U32 u32RdqWptr = 0;
    BSP_U32 u32RdqWaddr = 0;
    BSP_U32 u32RdqRaddr = 0;
    BSP_U32 u32Depth = 0;

    BSP_U32 u32AdqCtrlInfo = 0;
    BSP_U32 u32Adq0BaseAddr = 0;
    BSP_U32 u32Adq0StateInfo = 0;
    BSP_U32 u32Adq0Wptr = 0;
    BSP_U32 u32Adq0Rptr = 0;
    BSP_U32 u32Adq1BaseAddr = 0;
    BSP_U32 u32Adq1StateInfo = 0;
    BSP_U32 u32Adq1Wptr = 0;
    BSP_U32 u32Adq1Rptr = 0;

    switch (eChnType) {

        case IPF_CHANNEL_UP:
            IPF_REG_READ(SOC_IPF_CH0_CTRL_ADDR(IPF_REGBASE_ADR), u32ChanCtrlInfo);
            IPF_REG_READ(SOC_IPF_CH0_STATE_ADDR(IPF_REGBASE_ADR), u32ChanStateInfo);

            IPF_REG_READ(SOC_IPF_CH0_BDQ_BADDR_ADDR(IPF_REGBASE_ADR), u32BdqBaseAddr);
            IPF_REG_READ(SOC_IPF_CH0_BDQ_SIZE_ADDR(IPF_REGBASE_ADR), u32BdqDepth);
            IPF_REG_READ(SOC_IPF_CH0_BDQ_WPTR_ADDR(IPF_REGBASE_ADR), u32BdqWptr);
            IPF_REG_READ(SOC_IPF_CH0_BDQ_RPTR_ADDR(IPF_REGBASE_ADR), u32BdqRptr);
            IPF_REG_READ(SOC_IPF_CH0_BDQ_WADDR_ADDR(IPF_REGBASE_ADR), u32BdqWaddr);
            IPF_REG_READ(SOC_IPF_CH0_BDQ_RADDR_ADDR(IPF_REGBASE_ADR), u32BdqRaddr);
            IPF_REG_READ(SOC_IPF_CH0_RDQ_BADDR_ADDR(IPF_REGBASE_ADR), u32RdqBaseAddr);
            IPF_REG_READ(SOC_IPF_CH0_RDQ_SIZE_ADDR(IPF_REGBASE_ADR), u32RdqDepth);
            IPF_REG_READ(SOC_IPF_CH0_RDQ_RPTR_ADDR(IPF_REGBASE_ADR), u32RdqRptr);
            IPF_REG_READ(SOC_IPF_CH0_RDQ_WPTR_ADDR(IPF_REGBASE_ADR), u32RdqWptr);
            IPF_REG_READ(SOC_IPF_CH0_RDQ_WADDR_ADDR(IPF_REGBASE_ADR), u32RdqWaddr);
            IPF_REG_READ(SOC_IPF_CH0_RDQ_RADDR_ADDR(IPF_REGBASE_ADR), u32RdqRaddr);
            IPF_REG_READ(SOC_IPF_CH0_DQ_DEPTH_ADDR(IPF_REGBASE_ADR), u32Depth);

            IPF_REG_READ(SOC_IPF_CH0_ADQ_CTRL_ADDR(IPF_REGBASE_ADR), u32AdqCtrlInfo);
            IPF_REG_READ(SOC_IPF_CH0_ADQ0_BASE_ADDR(IPF_REGBASE_ADR), u32Adq0BaseAddr);
            IPF_REG_READ(SOC_IPF_CH0_ADQ0_STAT_ADDR(IPF_REGBASE_ADR), u32Adq0StateInfo);
            IPF_REG_READ(SOC_IPF_CH0_ADQ0_WPTR_ADDR(IPF_REGBASE_ADR), u32Adq0Wptr);
            IPF_REG_READ(SOC_IPF_CH0_ADQ0_RPTR_ADDR(IPF_REGBASE_ADR), u32Adq0Rptr);
            IPF_REG_READ(SOC_IPF_CH0_ADQ1_BASE_ADDR(IPF_REGBASE_ADR), u32Adq1BaseAddr);
            IPF_REG_READ(SOC_IPF_CH0_ADQ1_STAT_ADDR(IPF_REGBASE_ADR), u32Adq1StateInfo);
            IPF_REG_READ(SOC_IPF_CH0_ADQ1_WPTR_ADDR(IPF_REGBASE_ADR), u32Adq1Wptr);
            IPF_REG_READ(SOC_IPF_CH0_ADQ1_RPTR_ADDR(IPF_REGBASE_ADR), u32Adq1Rptr);
            break;

        case IPF_CHANNEL_DOWN:
            IPF_REG_READ(SOC_IPF_CH1_CTRL_ADDR(IPF_REGBASE_ADR), u32ChanCtrlInfo);
            IPF_REG_READ(SOC_IPF_CH1_STATE_ADDR(IPF_REGBASE_ADR), u32ChanStateInfo);

            IPF_REG_READ(SOC_IPF_CH1_BDQ_BADDR_ADDR(IPF_REGBASE_ADR), u32BdqBaseAddr);
            IPF_REG_READ(SOC_IPF_CH1_BDQ_SIZE_ADDR(IPF_REGBASE_ADR), u32BdqDepth);
            IPF_REG_READ(SOC_IPF_CH1_BDQ_WPTR_ADDR(IPF_REGBASE_ADR), u32BdqWptr);
            IPF_REG_READ(SOC_IPF_CH1_BDQ_RPTR_ADDR(IPF_REGBASE_ADR), u32BdqRptr);
            IPF_REG_READ(SOC_IPF_CH1_BDQ_WADDR_ADDR(IPF_REGBASE_ADR), u32BdqWaddr);
            IPF_REG_READ(SOC_IPF_CH1_BDQ_RADDR_ADDR(IPF_REGBASE_ADR), u32BdqRaddr);
            IPF_REG_READ(SOC_IPF_CH1_RDQ_BADDR_ADDR(IPF_REGBASE_ADR), u32RdqBaseAddr);
            IPF_REG_READ(SOC_IPF_CH1_RDQ_SIZE_ADDR(IPF_REGBASE_ADR), u32RdqDepth);
            IPF_REG_READ(SOC_IPF_CH1_RDQ_RPTR_ADDR(IPF_REGBASE_ADR), u32RdqRptr);
            IPF_REG_READ(SOC_IPF_CH1_RDQ_WPTR_ADDR(IPF_REGBASE_ADR), u32RdqWptr);
            IPF_REG_READ(SOC_IPF_CH1_RDQ_WADDR_ADDR(IPF_REGBASE_ADR), u32RdqWaddr);
            IPF_REG_READ(SOC_IPF_CH1_RDQ_RADDR_ADDR(IPF_REGBASE_ADR), u32RdqRaddr);
            IPF_REG_READ(SOC_IPF_CH1_DQ_DEPTH_ADDR(IPF_REGBASE_ADR), u32Depth);

            IPF_REG_READ(SOC_IPF_CH1_ADQ_CTRL_ADDR(IPF_REGBASE_ADR), u32AdqCtrlInfo);
            IPF_REG_READ(SOC_IPF_CH1_ADQ0_BASE_ADDR(IPF_REGBASE_ADR), u32Adq0BaseAddr);
            IPF_REG_READ(SOC_IPF_CH1_ADQ0_STAT_ADDR(IPF_REGBASE_ADR), u32Adq0StateInfo);
            IPF_REG_READ(SOC_IPF_CH1_ADQ0_WPTR_ADDR(IPF_REGBASE_ADR), u32Adq0Wptr);
            IPF_REG_READ(SOC_IPF_CH1_ADQ0_RPTR_ADDR(IPF_REGBASE_ADR), u32Adq0Rptr);
            IPF_REG_READ(SOC_IPF_CH1_ADQ1_BASE_ADDR(IPF_REGBASE_ADR), u32Adq1BaseAddr);
            IPF_REG_READ(SOC_IPF_CH1_ADQ1_STAT_ADDR(IPF_REGBASE_ADR), u32Adq1StateInfo);
            IPF_REG_READ(SOC_IPF_CH1_ADQ1_WPTR_ADDR(IPF_REGBASE_ADR), u32Adq1Wptr);
            IPF_REG_READ(SOC_IPF_CH1_ADQ1_RPTR_ADDR(IPF_REGBASE_ADR), u32Adq1Rptr);
            break;

        default:
            IPF_PRINT("invalidable channel type \n");
            break;
    }

    IPF_PRINT("============BEGIN===========\n");
    IPF_PRINT("通道控制寄存器:     0x%x\n", u32ChanCtrlInfo);
    IPF_PRINT("通道状态寄存器:     0x%x\n", u32ChanStateInfo);

    IPF_PRINT("BD 基地址:          0x%x\n", u32BdqBaseAddr);
    IPF_PRINT("BD 深度:            0x%x\n", u32BdqDepth);
    IPF_PRINT("BD 写指针:          0x%x\n", u32BdqWptr);
    IPF_PRINT("BD 读指针:          0x%x\n", u32BdqRptr);
    IPF_PRINT("BD 写地址:          0x%x\n", u32BdqWaddr);
    IPF_PRINT("BD 读地址:          0x%x\n", u32BdqRaddr);
    IPF_PRINT("RD 基地址:          0x%x\n", u32RdqBaseAddr);
    IPF_PRINT("RD 深度:            0x%x\n", u32RdqDepth);
    IPF_PRINT("RD 读指针:          0x%x\n", u32RdqRptr);
    IPF_PRINT("RD 写指针:          0x%x\n", u32RdqWptr);
    IPF_PRINT("RD 读地址:          0x%x\n", u32RdqRaddr);
    IPF_PRINT("RD 写地址:          0x%x\n", u32RdqWaddr);
    IPF_PRINT("通道深度寄存器:     0x%x\n", u32Depth);

    IPF_PRINT("ADQ控制寄存器:      0x%x\n", u32AdqCtrlInfo);
    IPF_PRINT("ADQ0 基地址:          0x%x\n", u32Adq0BaseAddr);
    IPF_PRINT("ADQ0 状态寄存器:          0x%x\n", u32Adq0StateInfo);
    IPF_PRINT("ADQ0 写指针:            0x%x\n", u32Adq0Wptr);
    IPF_PRINT("ADQ0 读指针:          0x%x\n", u32Adq0Rptr);
    IPF_PRINT("ADQ1 基地址:          0x%x\n", u32Adq1BaseAddr);
    IPF_PRINT("ADQ1 状态寄存器:          0x%x\n", u32Adq1StateInfo);
    IPF_PRINT("ADQ1 写指针:            0x%x\n", u32Adq1Wptr);
    IPF_PRINT("ADQ1 读指针:          0x%x\n", u32Adq1Rptr);
    IPF_PRINT("=============END============\n");
    return 0;
}