/*****************************************************************************
* 函 数 名  : BSP_IPF_SetControlFLagForCcoreReset
*
* 功能描述  : ccore复位时,设置IPF标志,用于控制IPF上行
*
* 输入参数  : IPF_FORRESET_CONTROL_E flagvalue,0:允许;1:不允许上行
* 输出参数  : 无
* 返 回 值  : IPF_SUCCESS    初始化成功
*             IPF_ERROR      初始化失败
*
* 修改记录  :2013年4月19日   卢彦胜 创建
*   1.修改日期 :2013年9月12
*     修改作者 :周珊
*     修改记录 :添加入参检查、forbidden之后等待idle
*****************************************************************************/
void BSP_IPF_SetControlFLagForCcoreReset(IPF_FORRESET_CONTROL_E flagvalue)
{
    unsigned int u32UlState = 0;
    unsigned int u32DlState = 0;
    unsigned int u32Cnt = 0;

    /* 入参检查 */
    if(IPF_FORRESET_CONTROL_MAX <= flagvalue)
    {
        IPF_PRINT_ERROR("parameter is error\n");
    }

    /* 设置当前IPF状态 */
    g_forCcore_reset_Up_flag = flagvalue;

    if(IPF_FORRESET_CONTROL_FORBID == flagvalue)
    {
        /* 等待IPF进入idle态(不释放CPU但加入等待超时),如果无法进入idle,则等待时间后确保IPF不再处理数据为止 */
        do{
            IPF_REG_READ(SOC_IPF_CH0_STATE_ADDR(IPF_REGBASE_ADR), u32UlState);
            IPF_REG_READ(SOC_IPF_CH1_STATE_ADDR(IPF_REGBASE_ADR), u32DlState);
            msleep(10);
            u32Cnt++;
        }while(((u32UlState != IPF_CH_IDLE) || (u32DlState != IPF_CH_IDLE)) && (u32Cnt <= IPF_IDLE_TIMEOUT_NUM));
        if(u32UlState != IPF_CH_IDLE)
        {
            IPF_PRINT_ERROR("ul is not idle\n");
        }
        if(u32DlState != IPF_CH_IDLE)
        {
            IPF_PRINT_ERROR("ul is not idle\n");
        }
    }
}
/*****************************************************************************
* 函 数 名  : 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_S32 BSP_IPF_RegDump(BSP_VOID)
{
    BSP_U32 i = 0;
    BSP_U32 u32RegValue = 0;

    IPF_PRINT_ERROR("============BEGIN===========\n");
    for(i = 0; i < IPF_REG_NUM; i++)
    {
        IPF_REG_READ(IPF_REG_OFFSET_TO_ADDR(i), u32RegValue);
        IPF_PRINT_ERROR("[0x%lx]:          0x%x\n", IPF_REG_OFFSET_TO_ADDR(i), u32RegValue); 
    }
    IPF_PRINT_ERROR("=============END============\n");

    return 0;
}
BSP_VOID BSP_IPF_MemInfo(BSP_VOID)
{
    IPF_PRINT_ERROR("============BEGIN===========\n");
    IPF_PRINT_ERROR("   BSP_IPF_MEM          ADDR            SIZE\n");
    IPF_PRINT_ERROR("%s%#lx\t\t%#x\n", "IPF_ULBD_MEM_ADDR    ", IPF_ULBD_MEM_ADDR, (BSP_U32)IPF_ULBD_MEM_SIZE);
    IPF_PRINT_ERROR("%s%#lx\t\t%#x\n", "IPF_ULRD_MEM_ADDR    ", IPF_ULRD_MEM_ADDR, (BSP_U32)IPF_ULRD_MEM_SIZE);
    IPF_PRINT_ERROR("%s%#lx\t\t%#x\n", "IPF_DLBD_MEM_ADDR    ", IPF_DLBD_MEM_ADDR, (BSP_U32)IPF_DLBD_MEM_SIZE);
    IPF_PRINT_ERROR("%s%#lx\t\t%#x\n", "IPF_DLRD_MEM_ADDR    ", IPF_DLRD_MEM_ADDR, (BSP_U32)IPF_DLRD_MEM_SIZE);
    IPF_PRINT_ERROR("%s%#lx\t\t%#x\n", "IPF_DLCD_MEM_ADDR    ", IPF_DLCD_MEM_ADDR, (BSP_U32)IPF_DLCD_MEM_SIZE);
    IPF_PRINT_ERROR("%20s%#lx\t\t%#x\n", "IPF_DEBUG_INFO_ADDR  ", IPF_DEBUG_INFO_ADDR, (BSP_U32)IPF_DEBUG_INFO_SIZE);
    IPF_PRINT_ERROR("=============END============\n");
}
/*****************************************************************************
* 函 数 名  : IPF_Int_Connect
*
* 功能描述  : 挂IPF中断处理函数(两核都提供)
*
* 输入参数  : void
* 输出参数  : 无
* 返 回 值  : 无
*
* 修改记录  :2011年12月2日   鲁婷  创建
*****************************************************************************/
void IPF_Int_Connect(void)
{
    if(request_irq(INT_LVL_IPF, (irq_handler_t)IPF_IntHandler, 0, "IPF_APP_IRQ", NULL) != 0)
    {
        IPF_PRINT_ERROR("irequest_irq error\n");
    }
}
/*****************************************************************************
* 函 数 名  : IPF_ObligateAdqRpt
*
* 功能描述  : 根据adq状态寄存器和当前adq读指针获取adq回退读指针
*
* 输入参数  : eChId     通道ID
*             eType     AD类型
* 输出参数  : pu32Rpt   保存AD读指针
* 返 回 值  : IPF_SUCCESS           成功
*             IPF_ERROR(其他错误码) 失败
*
* 修改记录  : 2013年9月9日   z00212992  创建
*   1.修改日期 : 2014年05月27日
*     修改作者 : z00212992
*     修改记录 : 芯片修改adq buff预读机制,软件不再需要根据adq状态寄存器来获取adq读指针
*****************************************************************************/
static int IPF_ObligateAdqRpt(IPF_CHANNEL_TYPE_E eChId, IPF_AD_TYPE_E eType, unsigned int *pu32Rpt)
{
    unsigned int u32Index = 0;
    unsigned int u32RptValue = 0;
    IPF_ADQ_INFO_S *pIpfAdqReg = NULL;

    /* ADQ读指针和状态寄存器表 */
    IPF_ADQ_INFO_S stIpfAdqReg[4] = {{0}};
    pIpfAdqReg = &stIpfAdqReg[0];
    pIpfAdqReg->pu32RptReg = (unsigned int *)(SOC_IPF_CH0_ADQ0_RPTR_ADDR(IPF_REGBASE_ADR));
    pIpfAdqReg = &stIpfAdqReg[1];
    pIpfAdqReg->pu32RptReg = (unsigned int *)(SOC_IPF_CH0_ADQ1_RPTR_ADDR(IPF_REGBASE_ADR));
    pIpfAdqReg = &stIpfAdqReg[2];
    pIpfAdqReg->pu32RptReg = (unsigned int *)(SOC_IPF_CH1_ADQ0_RPTR_ADDR(IPF_REGBASE_ADR));
    pIpfAdqReg = &stIpfAdqReg[3];
    pIpfAdqReg->pu32RptReg = (unsigned int *)(SOC_IPF_CH1_ADQ1_RPTR_ADDR(IPF_REGBASE_ADR));

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

    /* 根据通道ID和AD类型获取操作寄存器对象index值 */
    switch (eChId) {
        case IPF_CHANNEL_UP:
            u32Index = (IPF_AD_0 == eType) ? 0 : 1;
            break;
        case IPF_CHANNEL_DOWN:
            u32Index = (IPF_AD_0 == eType) ? 2 : 3;
            break;
        default:
            IPF_PRINT_ERROR("parameter is error\n");
            u32Index = 0;
            break;
    }

    /* 读取ADQ读指针寄存器 */
    IPF_REG_READ(stIpfAdqReg[u32Index].pu32RptReg, u32RptValue);

    /* 保存ADQ读指针 */
    *pu32Rpt = u32RptValue;
    return IPF_SUCCESS;
}
/*****************************************************************************
* 函 数 名  : BSP_IPF_RegisterAdqEmptyDlCb
*
* 功能描述  : 该接口用于注册下行ADQ空回调函数
*
* 输入参数  : BSP_IPF_AdqEmptyUlCb pAdqEmptyUl
*
* 输出参数  : 无
* 返 回 值  : IPF_SUCCESS
*             BSP_ERR_IPF_INVALID_PARA
* 修改记录  : 2012年11月29日   z00212992  创建
*****************************************************************************/
int BSP_IPF_RegisterAdqEmptyDlCb(BSP_IPF_AdqEmptyDlCb pAdqEmptyDl)
{
    /* 参数检查 */
    if(NULL == pAdqEmptyDl)
    {
        IPF_PRINT_ERROR("parameter is error\n");
        return BSP_ERR_IPF_INVALID_PARA;
    }
    g_stIpfDl.pAdqEmptyDlCb = pAdqEmptyDl;
    return IPF_SUCCESS;
}
/*****************************************************************************
* 函 数 名  : BSP_IPF_RegisterWakeupDlCb
*
* 功能描述  : 该接口用于注册下行PS任务回调函数
*
* 输入参数  : BSP_IPF_WakeupDlkCb *pFnWakeupDl
*
* 输出参数  : 无
* 返 回 值  : 无
*
* 修改记录  :2011年11月30日   鲁婷  创建
*****************************************************************************/
int BSP_IPF_RegisterWakeupDlCb(BSP_IPF_WakeupDlCb pFnWakeupDl)
{
    /* 参数检查 */
    if(NULL == pFnWakeupDl)
    {
        IPF_PRINT_ERROR("parameter is error\n");
        return BSP_ERR_IPF_INVALID_PARA;
    }
    g_stIpfDl.pFnDlIntCb = pFnWakeupDl;
    return IPF_SUCCESS;
}
/*****************************************************************************
  3 函数实现
*****************************************************************************/
BSP_VOID BSP_IPF_Help(BSP_VOID)
{
    IPF_PRINT_ERROR("===============================================\n");
    IPF_PRINT_ERROR("BSP_IPF_RegDump 参数1:无\n");
    IPF_PRINT_ERROR("BSP_IPF_DbgInfo 参数1:无\n");
    IPF_PRINT_ERROR("BSP_IPF_MemInfo 参数1:无\n");
    IPF_PRINT_ERROR("BSP_IPF_BDInfo  参数1:通道类型(0-上行;1-下行)  参数2:BD指针偏移(0~63)\n");
    IPF_PRINT_ERROR("BSP_IPF_RDInfo  参数1:通道类型(0-上行;1-下行)  参数2:RD指针偏移(0~63)\n");
    IPF_PRINT_ERROR("BSP_IPF_CHInfo  参数1:通道类型(0-上行;1-下行)\n");
}
/*****************************************************************************
* 函 数 名  : BSP_IPF_ConfigTimeout
*
* 功能描述  : 调试使用,配置超时时间接口
*
* 输入参数  : unsigned int u32Timeout 配置的超时时间
* 输出参数  : 无
* 返 回 值  : IPF_SUCCESS                   成功
*             BSP_ERR_IPF_INVALID_PARA      参数无效
*
* 说明      : 1代表256个时钟周期
*
* 修改记录   : 2011年11月30日   鲁婷  创建
*****************************************************************************/
int BSP_IPF_ConfigTimeout(unsigned int u32Timeout)
{
    SOC_IPF_TIME_OUT_UNION unTimeout;

    unTimeout.value = 0;
    if((u32Timeout == 0) || (u32Timeout > 0xFFFF))
    {
        IPF_PRINT_ERROR("parameter is error\n");
        return BSP_ERR_IPF_INVALID_PARA;
    }
    unTimeout.reg.time_out_cfg = u32Timeout;
    unTimeout.reg.time_out_valid = 1;

    IPF_REG_WRITE(SOC_IPF_TIME_OUT_ADDR(IPF_REGBASE_ADR), unTimeout.value);

    return IPF_SUCCESS;
}
/*****************************************************************************
* 函 数 名  : BSP_IPF_PktLen
*
* 功能描述  : 该接口用来配置过滤器的最大和最小包长
*
* 输入参数  : unsigned int MaxLen   最大包长
*             unsigned int MinLen   最小包长
*
* 输出参数  : 无
* 返 回 值  : IPF_SUCCESS                成功
*             BSP_ERR_IPF_INVALID_PARA   参数错误(最大包长比最小包长小)
*
* 修改记录  :2011年2月17日   鲁婷  创建
*****************************************************************************/
int BSP_IPF_SetPktLen(unsigned int u32MaxLen, unsigned int u32MinLen)
{
    SOC_IPF_PKT_LEN_UNION unPktLen;

    unPktLen.value = 0;
    /* 参数检查 */
    if(u32MaxLen < u32MinLen)
    {
        IPF_PRINT_ERROR("parameter is error\n");
        return BSP_ERR_IPF_INVALID_PARA;
    }

    unPktLen.reg.max_pkt_len = u32MaxLen;
    unPktLen.reg.min_pkt_len = u32MinLen;

    IPF_REG_WRITE(SOC_IPF_PKT_LEN_ADDR(IPF_REGBASE_ADR), unPktLen.value);
    return IPF_SUCCESS;
}
/*****************************************************************************
* 函 数 名  : IPF_IntHandler
*
* 功能描述  : IPF中断处理函数
*
* 输入参数  : 无
* 输出参数  : 无
* 返 回 值  : 无
*
* 修改记录  :2011年1月24日   鲁婷  创建
*   1.修改日期 : 2012年11月29日
*     修改作者 : z00212992
*     修改记录 : 增加ADQ队列为空中断处理
*   2.修改日期 : 2012年1月28日
*     修改作者 : z00212992
*     修改记录 : DTS2013012800111
*****************************************************************************/
irqreturn_t  IPF_IntHandler (int irq, void* dev)
{
    unsigned int u32IpfAdqInt = 0;
    SOC_IPF_INT1_UNION unIpfInt;

    unIpfInt.value = 0;
    /* 读取中断状态 */
    IPF_REG_READ(SOC_IPF_INT1_ADDR(IPF_REGBASE_ADR), unIpfInt.value);
    /* 下行结果上报和结果超时上报 */
    if((unIpfInt.reg.dl_rpt_int1) || (unIpfInt.reg.dl_timeout_int1))
    {
        /* 写1清除下行结果和结果超时中断 */
        IPF_REG_WRITE(SOC_IPF_INT_STATE_ADDR(IPF_REGBASE_ADR), (IPF_DL_RPT_INT | IPF_DL_TIMEOUT_INT));
    #ifdef __BSP_IPF_DEBUG__
        if(unIpfInt.reg.dl_rpt_int1)
        {
            g_stIPFDebugInfo->u32DlResultCnt++;
        }
        if(unIpfInt.reg.dl_timeout_int1)
        {
            g_stIPFDebugInfo->u32DlResultTimeoutCnt++;
        }
    #endif
        /* 唤醒ps下行任务 */
        if(g_stIpfDl.pFnDlIntCb != NULL)
        {
            (void)g_stIpfDl.pFnDlIntCb();
        }
        else
        {
            IPF_PRINT_ERROR("dl int callback is null\n");
        }
    }

    /* 下行ADQ0、ADQ1空指示 */
    if((unIpfInt.reg.dl_adq0_epty_int1) || (unIpfInt.reg.dl_adq1_epty_int1))
    {
        /* 写1清除下行ADQ、ADQ1空中断 */
        IPF_REG_WRITE(SOC_IPF_INT_STATE_ADDR(IPF_REGBASE_ADR), (IPF_DL_ADQ0_EMPTY_INT | IPF_DL_ADQ1_EMPTY_INT));
        if(unIpfInt.reg.dl_adq0_epty_int1)
        {
        #ifdef __BSP_IPF_DEBUG__
            g_stIPFDebugInfo->u32DlAdq0Empty++;
        #endif
            u32IpfAdqInt += IPF_EMPTY_ADQ0;
        }
        if(unIpfInt.reg.dl_adq1_epty_int1)
        {
        #ifdef __BSP_IPF_DEBUG__
            g_stIPFDebugInfo->u32DlAdq1Empty++;
        #endif
            u32IpfAdqInt += IPF_EMPTY_ADQ1;
        }
        if(g_stIpfDl.pAdqEmptyDlCb != NULL)
        {
            (void)g_stIpfDl.pAdqEmptyDlCb(u32IpfAdqInt);
        }
        else
        {
            IPF_PRINT_ERROR("dl adq callback is null\n");
        }
    }
    return IRQ_HANDLED;
}
/*****************************************************************************
* 函 数 名  : BSP_IPF_ConfigUpFilter
*
* 功能描述  : IPF上行IP过滤函数
*
* 输入参数  : unsigned int u32Num, IPF_CONFIG_ULPARAM_S* pstUlPara, BSP_BOOL bintFlag
* 输出参数  : 无
* 返 回 值  : IPF_SUCCESS    配置成功
*             IPF_ERROR      配置失败
*             BSP_ERR_IPF_NOT_INIT         模块未初始化
*             BSP_ERR_IPF_INVALID_PARA     参数错误
*
* 修改记录  :2011年11月30日   鲁婷  创建
*   1.修改日期 : 2012年11月29日
*     修改作者 : z00212992
*     修改记录 : 增加IPF备份恢复机制修改
*****************************************************************************/
int BSP_IPF_ConfigUpFilter(unsigned int u32Num, IPF_CONFIG_ULPARAM_S* pstUlPara)
{
    unsigned int i = 0;
    unsigned int u32BdqWptr = 0;
    IPF_CONFIG_ULPARAM_S* pstUlParam = pstUlPara;
#ifdef __BSP_IPF_DEBUG__
    SOC_IPF_CH0_ADQ_CTRL_UNION unCh0AdqCtrl;
#endif
    /*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((NULL == pstUlPara))
    {
        IPF_PRINT_ERROR("point is null\n");
        return BSP_ERR_IPF_INVALID_PARA;
    }

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

    if(u32Num > *(g_stIpfUl.pu32IdleBd))
    {
    #ifdef __BSP_IPF_DEBUG__
        g_stIPFDebugInfo->u32UlBdNotEnough++;
    #endif
        return IPF_ERROR;
    }

#ifdef __BSP_IPF_DEBUG__
    IPF_REG_READ(SOC_IPF_CH0_ADQ_CTRL_ADDR(IPF_REGBASE_ADR), unCh0AdqCtrl.value);
    if(unCh0AdqCtrl.reg.ul_adq_en != IPF_BOTH_ADQ_EN)
    {
        IPF_PRINT_ERROR("adq is not supported\n");
        return IPF_ERROR;
    }

    g_stIPFDebugInfo->u32UlBdNum += u32Num;
#endif

    /* 确保IPF已恢复 */
    if(IPF_ERROR == IPF_WaitResume())
    {
        IPF_PRINT_ERROR("wait for resume timeout\n");
        g_stIPFDebugInfo->u32UlResumeTimeoutCnt++;
        return  BSP_ERR_IPF_RESUME_TIMEOUT;
    }

    /* 读出BD写指针,将u32BdqWptr作为临时写指针使用 */
    IPF_REG_READ(SOC_IPF_CH0_BDQ_WPTR_ADDR(IPF_REGBASE_ADR), u32BdqWptr);

    for(i = 0; i < u32Num; i++)
    {
        if(0 == pstUlParam[i].u32Data)
        {
            IPF_PRINT_ERROR("ulbd inptr is null\n");
            return BSP_ERR_IPF_INVALID_PARA;
        }
        if(0 == pstUlParam[i].u16Len)
        {
            IPF_PRINT_ERROR("ulbd len is zero\n");
            g_stIPFDebugInfo->u32UlBdSizeErr = 1;
            return BSP_ERR_IPF_INVALID_PARA;
        }

        g_stIpfUl.pstIpfBDQ[u32BdqWptr].u16Attribute = pstUlParam[i].u16Attribute;
        g_stIpfUl.pstIpfBDQ[u32BdqWptr].u32InPtr = pstUlParam[i].u32Data;
        g_stIpfUl.pstIpfBDQ[u32BdqWptr].u16PktLen = pstUlParam[i].u16Len;
        g_stIpfUl.pstIpfBDQ[u32BdqWptr].u16UsrField1 = pstUlParam[i].u16UsrField1;
        g_stIpfUl.pstIpfBDQ[u32BdqWptr].u32UsrField2= pstUlParam[i].u32UsrField2;
        g_stIpfUl.pstIpfBDQ[u32BdqWptr].u32UsrField3 = pstUlParam[i].u32UsrField3;
        u32BdqWptr = ((u32BdqWptr + 1) < IPF_ULBD_DESC_SIZE)? (u32BdqWptr + 1) : 0;
    }

    /* 更新BD写指针*/
    IPF_REG_WRITE(SOC_IPF_CH0_BDQ_WPTR_ADDR(IPF_REGBASE_ADR), u32BdqWptr);

    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_ERROR("invalidable channel type \n");
            break;
    }

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

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

    IPF_PRINT_ERROR("ADQ控制寄存器:      0x%x\n", u32AdqCtrlInfo);
    IPF_PRINT_ERROR("ADQ0 基地址:          0x%x\n", u32Adq0BaseAddr);
    IPF_PRINT_ERROR("ADQ0 状态寄存器:          0x%x\n", u32Adq0StateInfo);
    IPF_PRINT_ERROR("ADQ0 写指针:            0x%x\n", u32Adq0Wptr);
    IPF_PRINT_ERROR("ADQ0 读指针:          0x%x\n", u32Adq0Rptr);
    IPF_PRINT_ERROR("ADQ1 基地址:          0x%x\n", u32Adq1BaseAddr);
    IPF_PRINT_ERROR("ADQ1 状态寄存器:          0x%x\n", u32Adq1StateInfo);
    IPF_PRINT_ERROR("ADQ1 写指针:            0x%x\n", u32Adq1Wptr);
    IPF_PRINT_ERROR("ADQ1 读指针:          0x%x\n", u32Adq1Rptr);
    IPF_PRINT_ERROR("=============END============\n");
    return 0;
}
BSP_S32 BSP_IPF_DbgInfo(BSP_VOID)
{
    IPF_PRINT_ERROR("============BEGIN===========\n");
    IPF_PRINT_ERROR("上行处理结果中断上报次数:           %d\n",g_stIPFDebugInfo->u32UlResultCnt);
    IPF_PRINT_ERROR("上行处理结果超时中断上报次数:       %d\n",g_stIPFDebugInfo->u32UlResultTimeoutCnt);
    IPF_PRINT_ERROR("下行处理结果中断上报次数:           %d\n",g_stIPFDebugInfo->u32DlResultCnt);
    IPF_PRINT_ERROR("下行处理结果超时中断上报次数:       %d\n",g_stIPFDebugInfo->u32DlResultTimeoutCnt);
    IPF_PRINT_ERROR("上行ADQ0空中断次数:                 %d\n",g_stIPFDebugInfo->u32UlAdq0Empty);
    IPF_PRINT_ERROR("上行ADQ1空中断次数:                 %d\n",g_stIPFDebugInfo->u32UlAdq1Empty);
    IPF_PRINT_ERROR("下行ADQ0空中断次数:                 %d\n",g_stIPFDebugInfo->u32DlAdq0Empty);
    IPF_PRINT_ERROR("下行ADQ1空中断次数:                 %d\n",g_stIPFDebugInfo->u32DlAdq1Empty);
    IPF_PRINT_ERROR("上行配置BD,BD不够用次数:            %d\n",g_stIPFDebugInfo->u32UlBdNotEnough);
    IPF_PRINT_ERROR("下行配置BD,BD不够用次数:            %d\n",g_stIPFDebugInfo->u32DlBdNotEnough);
    IPF_PRINT_ERROR("下行配置CD,CD不够用次数:            %d\n",g_stIPFDebugInfo->u32DlCdNotEnough);

    IPF_PRINT_ERROR("上行过滤规则恢复超时次数:           %d\n",g_stIPFDebugInfo->u32UlResumeTimeoutCnt);
    IPF_PRINT_ERROR("下行过滤规则恢复超时次数:           %d\n",g_stIPFDebugInfo->u32DlResumeTimeoutCnt);
    IPF_PRINT_ERROR("上行发送BD计数:                     %d\n",g_stIPFDebugInfo->u32UlBdNum);
    IPF_PRINT_ERROR("上行配置AD0计数:                    %d\n",g_stIPFDebugInfo->u32UlAdq0Num);
    IPF_PRINT_ERROR("上行配置AD1计数:                    %d\n",g_stIPFDebugInfo->u32UlAdq1Num);
    IPF_PRINT_ERROR("上行接收RD计数:                     %d\n",g_stIPFDebugInfo->u32UlRdNum);
    IPF_PRINT_ERROR("下行发送BD计数:                     %d\n",g_stIPFDebugInfo->u32DlBdNum);
    IPF_PRINT_ERROR("下行配置AD0计数:                    %d\n",g_stIPFDebugInfo->u32DlAdq0Num);
    IPF_PRINT_ERROR("下行配置AD1计数:                    %d\n",g_stIPFDebugInfo->u32DlAdq1Num);
    IPF_PRINT_ERROR("下行接收RD计数:                     %d\n",g_stIPFDebugInfo->u32DlRdNum);

    IPF_PRINT_ERROR("上行BD对齐错误:                     %d\n",g_stIPFDebugInfo->u32UlBdAlignErr);
    IPF_PRINT_ERROR("下行BD对齐错误:                     %d\n",g_stIPFDebugInfo->u32DlBdAlignErr);
    IPF_PRINT_ERROR("上行BD大小错误:                     %d\n",g_stIPFDebugInfo->u32UlBdSizeErr);
    IPF_PRINT_ERROR("下行BD大小错误:                     %d\n",g_stIPFDebugInfo->u32DlBdSizeErr);

    IPF_PRINT_ERROR("MEMORY_AXI_IPF_ADDR:                0x%x\n",MEMORY_AXI_IPF_ADDR);

    IPF_PRINT_ERROR("=============END============\n");

    return 0;
}
BSP_S32 BSP_IPF_RDInfo(IPF_CHANNEL_TYPE_E eChnType, BSP_U32 u32RdqPtr)
{
    if(u32RdqPtr >= IPF_ULRD_DESC_SIZE)
    {
        return IPF_ERROR;
    }
    switch(eChnType)
    {
        case IPF_CHANNEL_UP:
            IPF_PRINT_ERROR("===========RD Info==========\n");
            IPF_PRINT_ERROR("RD位置:             %d\n",u32RdqPtr);
            IPF_PRINT_ERROR("u16Attribute:       %d\n",g_stIpfUl.pstIpfRDQ[u32RdqPtr].u16Attribute);
            IPF_PRINT_ERROR("u16PktLen:          %d\n",g_stIpfUl.pstIpfRDQ[u32RdqPtr].u16PktLen);
            IPF_PRINT_ERROR("u32InPtr:           0x%x\n",g_stIpfUl.pstIpfRDQ[u32RdqPtr].u32InPtr);
            IPF_PRINT_ERROR("u32OutPtr:          0x%x\n",g_stIpfUl.pstIpfRDQ[u32RdqPtr].u32OutPtr);
            IPF_PRINT_ERROR("u16Result:          0x%x\n",g_stIpfUl.pstIpfRDQ[u32RdqPtr].u16Result);
            IPF_PRINT_ERROR("u16UsrField1:       0x%x\n",g_stIpfUl.pstIpfRDQ[u32RdqPtr].u16UsrField1);
            IPF_PRINT_ERROR("u32UsrField2:       0x%x\n",g_stIpfUl.pstIpfRDQ[u32RdqPtr].u32UsrField2);
            IPF_PRINT_ERROR("u32UsrField3:       0x%x\n",g_stIpfUl.pstIpfRDQ[u32RdqPtr].u32UsrField3);
            break;
       case IPF_CHANNEL_DOWN:
            IPF_PRINT_ERROR("============RD Info===========\n");
            IPF_PRINT_ERROR("RD位置:             %d\n",u32RdqPtr);
            IPF_PRINT_ERROR("u16Attribute:       %d\n",g_stIpfDl.pstIpfRDQ[u32RdqPtr].u16Attribute);
            IPF_PRINT_ERROR("u16PktLen:          %d\n",g_stIpfDl.pstIpfRDQ[u32RdqPtr].u16PktLen);
            IPF_PRINT_ERROR("u32InPtr:           0x%x\n",g_stIpfDl.pstIpfRDQ[u32RdqPtr].u32InPtr);
            IPF_PRINT_ERROR("u32OutPtr:          0x%x\n",g_stIpfDl.pstIpfRDQ[u32RdqPtr].u32OutPtr);
            IPF_PRINT_ERROR("u16Result:          0x%x\n",g_stIpfDl.pstIpfRDQ[u32RdqPtr].u16Result);
            IPF_PRINT_ERROR("u16UsrField1:       0x%x\n",g_stIpfDl.pstIpfRDQ[u32RdqPtr].u16UsrField1);
            IPF_PRINT_ERROR("u32UsrField2:       0x%x\n",g_stIpfDl.pstIpfRDQ[u32RdqPtr].u32UsrField2);
            IPF_PRINT_ERROR("u32UsrField3:       0x%x\n",g_stIpfDl.pstIpfRDQ[u32RdqPtr].u32UsrField3);
            break;
        default:
            break;
    }
    IPF_PRINT_ERROR("************************\n");
    return 0;
}
/*****************************************************************************
* 函 数 名  : BSP_IPF_GetDlRd
*
* 功能描述  : 该接口用于读取下行BD, 支持一次读取多个BD
*
* 输入参数  : unsigned int* pu32Num
*             IPF_RD_DESC_S *pstRd
*
* 输出参数  : unsigned int* pu32Num    实际读取的RD数目
*
* 返 回 值  : IPF_SUCCESS               操作成功
*             IPF_ERROR                   操作失败
*
* 修改记录  :2011年11月30日   鲁婷  创建
*   1.修改日期 : 2012年8月4日
*     修改作者 : z00212992
*     修改记录 : 源地址内存释放上移修改
*****************************************************************************/
void BSP_IPF_GetDlRd(unsigned int* pu32Num, IPF_RD_DESC_S *pstRd)
{
    SOC_IPF_CH1_DQ_DEPTH_UNION unDqDepth;
    unsigned int u32CdqRptr = 0;
    unsigned int u32RdqRptr = 0;
    unsigned int u32RdqDepth = 0;
    unsigned int u32Num = 0;
    unsigned int i = 0;

    if((NULL == pu32Num) || (NULL == pstRd))
    {
        IPF_PRINT_ERROR("parameter is error\n");
        return;
    }

    /* 读取RD深度 */
    unDqDepth.value = 0;
    IPF_REG_READ(SOC_IPF_CH1_DQ_DEPTH_ADDR(IPF_REGBASE_ADR), unDqDepth.value);
    u32RdqDepth = unDqDepth.reg.dl_rdq_depth;

    u32Num = (u32RdqDepth < *pu32Num)?u32RdqDepth:*pu32Num;
    if(u32Num > 0)
    {
        g_stIPFDebugInfo->u32DlRdNum += u32Num;
        for(i = 0; i < u32Num; i++)
        {
            /* 读取RD读指针 */
            IPF_REG_READ(SOC_IPF_CH1_RDQ_RPTR_ADDR(IPF_REGBASE_ADR), u32RdqRptr);
            if(u32RdqRptr >= IPF_DLRD_DESC_SIZE)
            {
                IPF_PRINT_ERROR("u32RdqRptr = %d\n", u32RdqRptr);
            }

            /* 获取RD */
            pstRd[i].u16Attribute = g_stIpfDl.pstIpfRDQ[u32RdqRptr].u16Attribute;
            pstRd[i].u16PktLen = g_stIpfDl.pstIpfRDQ[u32RdqRptr].u16PktLen;
            pstRd[i].u16Result = g_stIpfDl.pstIpfRDQ[u32RdqRptr].u16Result;
            pstRd[i].u32InPtr = g_stIpfDl.pstIpfRDQ[u32RdqRptr].u32InPtr;
            pstRd[i].u32OutPtr = g_stIpfDl.pstIpfRDQ[u32RdqRptr].u32OutPtr;
            if((0 == pstRd[i].u32OutPtr)/* || (0x55555555 == pstRd[i].u32OutPtr) || (0xAAAAAAAA == pstRd[i].u32OutPtr)*/)
            {
                IPF_PRINT_ERROR("invalid rd of dl\n");
                IPF_Assert(BSP_ERR_IPF_INVALID_DLRD);
            }
            pstRd[i].u16UsrField1 = g_stIpfDl.pstIpfRDQ[u32RdqRptr].u16UsrField1;
            pstRd[i].u32UsrField2 = g_stIpfDl.pstIpfRDQ[u32RdqRptr].u32UsrField2;
            pstRd[i].u32UsrField3 = g_stIpfDl.pstIpfRDQ[u32RdqRptr].u32UsrField3;

            u32RdqRptr = ((u32RdqRptr+1) < IPF_DLRD_DESC_SIZE)?(u32RdqRptr+1):0;

            /* 更新RD读指针 */
            IPF_REG_WRITE(SOC_IPF_CH1_RDQ_RPTR_ADDR(IPF_REGBASE_ADR), u32RdqRptr);
            /* 更新CD读指针 */
            u32CdqRptr = (unsigned int)((char *)(HISI_VA_ADDRESS(pstRd[i].u32InPtr)) - (char *)g_stIpfDl.pstIpfCDQ)/sizeof(IPF_CD_DESC_S);
            while(g_stIpfDl.pstIpfCDQ[u32CdqRptr].u16Attribute != 1)
            {
                /* 将释放的CD清0 */
                g_stIpfDl.pstIpfCDQ[u32CdqRptr].u16Attribute = 0;
                g_stIpfDl.pstIpfCDQ[u32CdqRptr].u16PktLen = 0;
                g_stIpfDl.pstIpfCDQ[u32CdqRptr].u32Ptr = 0;
                u32CdqRptr = ((u32CdqRptr+1) < IPF_DLCD_DESC_SIZE)?(u32CdqRptr+1):0;
            }
            u32CdqRptr = ((u32CdqRptr+1) < IPF_DLCD_DESC_SIZE)?(u32CdqRptr+1):0;
            *(g_stIpfDl.u32IpfCdRptr) = u32CdqRptr;
        }
    }
    *pu32Num = u32Num;
}
/*****************************************************************************
* 函 数 名  : 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_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;
}
/*****************************************************************************
* 函 数 名  : IPF_Init
*
* 功能描述  : IPF初始化     内部使用,不作为接口函数
*
* 输入参数  : void
* 输出参数  : 无
* 返 回 值  : IPF_SUCCESS    初始化成功
*             IPF_ERROR      初始化失败
*
* 修改记录  :2011年1月21日   鲁婷  创建
*   1.修改日期 : 2012年11月29日
*     修改作者 : z00212992
*     修改记录 : 增加ADQ初始化
*****************************************************************************/
int IPF_Init(void)
{
    int s32Ret = 0;

    /* IPF内存配置越界检查 */
    if(IPF_MEM_USED_SIZE > IPF_AXI_MEM_SIZE)
    {
        IPF_PRINT_ERROR("memory overstep the boundary\n");
        return IPF_ERROR;
    }


    hisi_io_memset((BSP_VOID*)&g_stIpfCtx, 0x0, sizeof(IPF_CONTEXT_S));

    IPF_ULBD_MEM_ADDR = HISI_VA_ADDRESS(IPF_AXI_MEM_ADDR);

    if (0 == (IPF_REGBASE_ADR = (unsigned long)ioremap(REG_BASE_IPF,REG_IPF_IOSIZE))){
        BUG_ON(1);
        return IPF_ERROR;
    }

    /* 为上行BD、RD描述符分配一段连续的物理地址 */
    g_stIpfUl.pstIpfBDQ = (IPF_BD_DESC_S*)IPF_ULBD_MEM_ADDR;
    g_stIpfUl.pstIpfRDQ = (IPF_RD_DESC_S*)IPF_ULRD_MEM_ADDR;

    /* 为上行AD描述符分配一段连续内存(首地址8字节对齐)*/
    g_stIpfUl.pstIpfADQ0 = (IPF_AD_DESC_S*)IPF_ULAD0_MEM_ADDR;
    g_stIpfUl.pstIpfADQ1 = (IPF_AD_DESC_S*)IPF_ULAD1_MEM_ADDR;

    /* 为下行BD、RD描述符分配一段连续的物理地址 */
    g_stIpfDl.pstIpfBDQ = (IPF_BD_DESC_S*)IPF_DLBD_MEM_ADDR;
    g_stIpfDl.pstIpfRDQ = (IPF_RD_DESC_S*)IPF_DLRD_MEM_ADDR;

    /* 为下行AD描述符分配一段连续内存(首地址8字节对齐)*/
    g_stIpfDl.pstIpfADQ0 = (IPF_AD_DESC_S*)IPF_DLAD0_MEM_ADDR;
    g_stIpfDl.pstIpfADQ1 = (IPF_AD_DESC_S*)IPF_DLAD1_MEM_ADDR;

    /* 为下行CD描述符分配一段连续的物理地址 */
    g_stIpfDl.pstIpfCDQ = (IPF_CD_DESC_S*)IPF_DLCD_MEM_ADDR;

    /* 记录IPF上行空闲BD个数 */
    g_stIpfUl.pu32IdleBd = (unsigned int*)IPF_ULBD_IDLENUM_ADDR;

#ifdef __BSP_IPF_DEBUG__
    /* 记录IPF debug信息 */
    g_stIPFDebugInfo = (IPF_DEBUG_INFO_S*)IPF_DEBUG_INFO_ADDR;

    /* 记录IPF 下行CDdebug信息 */
    g_stIpfDl.pstIpfDebugCDQ = (IPF_CD_DESC_S*)IPF_DEBUG_DLCD_ADDR;
#endif

    /* 记录IPF 下行CD读写指针 */
    g_stIpfDl.u32IpfCdRptr = (unsigned int*)IPF_DLCD_PTR_ADDR;
    g_stIpfDl.u32IpfCdWptr = (unsigned int*)(IPF_DLCD_PTR_ADDR+4);

    /* 挂接IPF中断 */
    IPF_Int_Connect();

    /* 注册IPF设备 */
    s32Ret = platform_device_register(&ipf_pfdev);
    if(s32Ret)
    {
        IPF_PRINT_ERROR("ipf device register fail\n");
        return s32Ret;
    }

    /* 注册IPF驱动 */
    s32Ret = platform_driver_register(&ipf_pfdrv);
    if(s32Ret)
    {
        platform_device_unregister(&ipf_pfdev);
        IPF_PRINT_ERROR("ipf driver register fail\n");
        return s32Ret;
    }

    ipf_peri_ctrl_base = (unsigned long)HISI_VA_ADDRESS(SOC_PERI_SCTRL_BASE_ADDR);
	if (!ipf_peri_ctrl_base)
	{
        IPF_PRINT_ERROR("unable to ioremap ipf peri ctrl\n");
	}

    /* 打开IPF hclk时钟、axi总线时钟 */
    IPF_REG_WRITE(SOC_PERI_SCTRL_SC_PERIPH_CLKEN2_ADDR(ipf_peri_ctrl_base), \
                (0x1 << SOC_PERI_SCTRL_SC_PERIPH_CLKEN2_periph_clken2_ipf_acpu_START));

    /* 等待另外一个core ipf初始化同步完成 */
    s32Ret = BSP_SYNC_Wait(SYNC_MODULE_IPF, 5000);
    if(s32Ret != BSP_OK)
    {
        IPF_PRINT_ERROR("BSP_SYNC_Wait timeout\n");
        return IPF_ERROR;
    }

    /* IPF初始化完成 */
    g_stIpfCtx.isInit = BSP_TRUE;


    IPF_PRINT_ERROR("success\n");
    return IPF_SUCCESS;
}
BSP_S32 BSP_IPF_BDInfo(IPF_CHANNEL_TYPE_E eChnType, BSP_U32 u32BdqPtr)
{
    BSP_U32 u32CdPtr;
    if(u32BdqPtr >= IPF_ULBD_DESC_SIZE)
    {
        return IPF_ERROR;
    }
    switch(eChnType)
    {
        case IPF_CHANNEL_UP:

                IPF_PRINT_ERROR("==========BD Info=========\n");
                IPF_PRINT_ERROR("BD位置:         %d\n",u32BdqPtr);
                IPF_PRINT_ERROR("u16Attribute:   %d\n",g_stIpfUl.pstIpfBDQ[u32BdqPtr].u16Attribute);
                IPF_PRINT_ERROR("u16PktLen:      %d\n",g_stIpfUl.pstIpfBDQ[u32BdqPtr].u16PktLen);
                IPF_PRINT_ERROR("u32InPtr:       0x%x\n",g_stIpfUl.pstIpfBDQ[u32BdqPtr].u32InPtr);
                IPF_PRINT_ERROR("u32OutPtr:      0x%x\n",g_stIpfUl.pstIpfBDQ[u32BdqPtr].u32OutPtr);
                IPF_PRINT_ERROR("u16Resv:        %d\n",g_stIpfUl.pstIpfBDQ[u32BdqPtr].u16Result);
                IPF_PRINT_ERROR("u16UsrField1:   %d\n",g_stIpfUl.pstIpfBDQ[u32BdqPtr].u16UsrField1);
                IPF_PRINT_ERROR("u32UsrField2:   0x%x\n",g_stIpfUl.pstIpfBDQ[u32BdqPtr].u32UsrField2);
                IPF_PRINT_ERROR("u32UsrField3:   0x%x\n",g_stIpfUl.pstIpfBDQ[u32BdqPtr].u32UsrField3);
            break;
       case IPF_CHANNEL_DOWN:
                IPF_PRINT_ERROR("==========BD Info=========\n");
                IPF_PRINT_ERROR("BD位置:         %d\n",u32BdqPtr);
                IPF_PRINT_ERROR("u16Attribute:   %d\n",g_stIpfDl.pstIpfBDQ[u32BdqPtr].u16Attribute);
                IPF_PRINT_ERROR("u16PktLen:      %d\n",g_stIpfDl.pstIpfBDQ[u32BdqPtr].u16PktLen);
                IPF_PRINT_ERROR("u32InPtr:       0x%x\n",g_stIpfDl.pstIpfBDQ[u32BdqPtr].u32InPtr);
                IPF_PRINT_ERROR("u32OutPtr:      0x%x\n",g_stIpfDl.pstIpfBDQ[u32BdqPtr].u32OutPtr);
                IPF_PRINT_ERROR("u16Resv:        %d\n",g_stIpfDl.pstIpfBDQ[u32BdqPtr].u16Result);
                IPF_PRINT_ERROR("u16UsrField1:   %d\n",g_stIpfDl.pstIpfBDQ[u32BdqPtr].u16UsrField1);
                IPF_PRINT_ERROR("u32UsrField2:   0x%x\n",g_stIpfDl.pstIpfBDQ[u32BdqPtr].u32UsrField2);
                IPF_PRINT_ERROR("u32UsrField3:   0x%x\n",g_stIpfDl.pstIpfBDQ[u32BdqPtr].u32UsrField3);
                u32CdPtr = (BSP_U32)((char*)HISI_VA_ADDRESS(g_stIpfDl.pstIpfBDQ[u32BdqPtr].u32InPtr)-(char*)g_stIpfDl.pstIpfCDQ);
                u32CdPtr = u32CdPtr/sizeof(IPF_CD_DESC_S);
                while(g_stIpfDl.pstIpfDebugCDQ[u32CdPtr].u16Attribute != 1)
                {
                    IPF_PRINT_ERROR("==========CD Info=========\n");
                    IPF_PRINT_ERROR("CD位置:             %d\n",u32CdPtr);
                    IPF_PRINT_ERROR("u16Attribute:       %d\n",g_stIpfDl.pstIpfDebugCDQ[u32CdPtr].u16Attribute);
                    IPF_PRINT_ERROR("u16PktLen:          %d\n",g_stIpfDl.pstIpfDebugCDQ[u32CdPtr].u16PktLen);
                    IPF_PRINT_ERROR("u32Ptr:             0x%x\n",g_stIpfDl.pstIpfDebugCDQ[u32CdPtr].u32Ptr);
                    u32CdPtr = ((u32CdPtr+1) < IPF_DLCD_DESC_SIZE)?(u32CdPtr+1):0;
                };
                IPF_PRINT_ERROR("==========CD Info=========\n");
                IPF_PRINT_ERROR("CD位置:             %d\n",u32CdPtr);
                IPF_PRINT_ERROR("u16Attribute:       %d\n",g_stIpfDl.pstIpfDebugCDQ[u32CdPtr].u16Attribute);
                IPF_PRINT_ERROR("u16PktLen:          %d\n",g_stIpfDl.pstIpfDebugCDQ[u32CdPtr].u16PktLen);
                IPF_PRINT_ERROR("u32Ptr:             0x%x\n",g_stIpfDl.pstIpfDebugCDQ[u32CdPtr].u32Ptr);
            break;
        default:
            break;
    }
    IPF_PRINT_ERROR("************************\n");
    return 0;
}