VOS_VOID ADS_UL_ClearIpfUlSrcMem(VOS_VOID)
{
    IMM_ZC_HEAD_STRU                 *pstUlFreeQue = VOS_NULL_PTR;
    VOS_UINT32                        ulQueCnt;
    VOS_UINT32                        ulCnt;
    IMM_ZC_STRU                      *pstFreeNode = VOS_NULL_PTR;
    VOS_UINT8                         i;
    VOS_UINT32                        ulIpfUlBdNum;

    pstUlFreeQue = ADS_UL_IPF_SRCMEM_FREE_QUE();

    ulQueCnt = IMM_ZcQueueLen(pstUlFreeQue);
    if (0 == ulQueCnt)
    {
        return;
    }

    /* 所有的PDP都去激活后,并且BD已经全部空闲,即上行数据全部搬完,才清空上行源内存队列 */
    for (i = 0; i < ADS_INSTANCE_MAX_NUM; i++)
    {
        if (VOS_FALSE == ADS_UL_CheckAllQueueEmpty(i))
        {
            return;
        }
    }

#if(FEATURE_OFF == FEATURE_SKB_EXP)
    ulIpfUlBdNum = BSP_IPF_GetUlDescNum();
#else
    ulIpfUlBdNum = BSP_IPF_GetUlBDNum();
#endif

    /* 空闲BD最多63个 */
    if (IPF_ULBD_DESC_SIZE != ulIpfUlBdNum)
    {
        return;
    }

    /*free src mem*/
    for (ulCnt = 0; ulCnt < ulQueCnt; ulCnt++)
    {
        pstFreeNode = IMM_ZcDequeueHead(pstUlFreeQue);

        IMM_ZcFree(pstFreeNode);

        ADS_DBG_UL_IPF_FREE_SRCMEM_NUM(1);
    }

    return;
}
VOS_VOID ADS_UL_FreeIpfUlConfigSuccSrcMem(VOS_VOID)
{
    IMM_ZC_HEAD_STRU                 *pstUlFreeQue = VOS_NULL_PTR;
    VOS_UINT32                        ulIdleBD;
    VOS_UINT32                        ulBusyBD;
    VOS_UINT32                        ulCanFree;
    VOS_UINT32                        ulQueCnt;
    VOS_UINT32                        ulCnt;
    IMM_ZC_STRU                      *pFreeNode = VOS_NULL_PTR;

    pstUlFreeQue = ADS_UL_IPF_SRCMEM_FREE_QUE();

    ulQueCnt = IMM_ZcQueueLen(pstUlFreeQue);
    if (0 == ulQueCnt)
    {
        return;
    }

    /* get busy bd num */
#if(FEATURE_OFF == FEATURE_SKB_EXP)
    ulIdleBD = BSP_IPF_GetUlDescNum();
#else
    ulIdleBD = BSP_IPF_GetUlBDNum();
#endif
    ulBusyBD = IPF_ULBD_DESC_SIZE - ulIdleBD;
    if (ulQueCnt >= ulBusyBD)
    {
        ulCanFree = ulQueCnt - ulBusyBD;
    }
    else
    {
        ADS_ERROR_LOG2(ACPU_PID_ADS_UL, "ADS_UL_FreeIpfUlSrcMem: Buff Num Less IPF Busy BD Num.",ulQueCnt,ulBusyBD);
        ADS_DBG_UL_IPF_FREE_SRCMEM_ERROR(1);
        return;
    }

    /*free src mem*/
    for (ulCnt = 0; ulCnt < ulCanFree; ulCnt++)
    {
        pFreeNode = IMM_ZcDequeueHead(pstUlFreeQue);

        IMM_ZcFree(pFreeNode);

        ADS_DBG_UL_IPF_FREE_SRCMEM_NUM(1);
    }

    return;
}
/*****************************************************************************
* 函 数 名  : BSP_IPF_GetUlDescNum
*
* 功能描述  : 该接口用于读取上行可发送包数
*
* 输入参数  : 无
*
* 输出参数  : 无
*
* 返 回 值  : 上行可发送包数
*
* 修改记录  :2013年12月17日   z00212992  创建
*****************************************************************************/
unsigned int BSP_IPF_GetUlDescNum(void)
{
    unsigned int u32UlAd0Num = 0;
    unsigned int u32UlAd1Num = 0;
    unsigned int u32UlBdNum = 0;
    unsigned int u32UlAdwptr = 0;
    unsigned int u32UlAdrptr = 0;
    unsigned int u32UlBdDepth = 0;
    SOC_IPF_CH0_DQ_DEPTH_UNION unDQDepth;

    /* 计算BD深度 */
    unDQDepth.value = 0;
    IPF_REG_READ(SOC_IPF_CH0_DQ_DEPTH_ADDR(IPF_REGBASE_ADR), unDQDepth.value);
    u32UlBdDepth = unDQDepth.reg.ul_bdq_depth;

    /* 计算空闲AD0数量 */
    IPF_REG_READ(SOC_IPF_CH0_ADQ0_WPTR_ADDR(IPF_REGBASE_ADR), u32UlAdwptr);
    IPF_REG_READ(SOC_IPF_CH0_ADQ0_RPTR_ADDR(IPF_REGBASE_ADR), u32UlAdrptr);

    /*写指针在前,正常顺序*/
    if (u32UlAdwptr >= u32UlAdrptr)
    {
        u32UlAd0Num = u32UlAdwptr - u32UlAdrptr;
    }
    else
    {
        u32UlAd0Num = IPF_ULAD0_DESC_SIZE - (u32UlAdrptr -u32UlAdwptr);
    }
    if(u32UlAd0Num > u32UlBdDepth)
    {
        u32UlAd0Num -= u32UlBdDepth;
    }
    else
    {
        u32UlAd0Num = 0;
        g_stIPFDebugInfo->u32UlAd0NotEnough++;
    }

    /* 计算空闲AD1数量 */
    IPF_REG_READ(SOC_IPF_CH0_ADQ1_WPTR_ADDR(IPF_REGBASE_ADR), u32UlAdwptr);
    IPF_REG_READ(SOC_IPF_CH0_ADQ1_RPTR_ADDR(IPF_REGBASE_ADR), u32UlAdrptr);

    if (u32UlAdwptr >= u32UlAdrptr)/*写指针在前,正常顺序*/
    {
        u32UlAd1Num = u32UlAdwptr - u32UlAdrptr;
    }
    else
    {
        u32UlAd1Num =  IPF_ULAD1_DESC_SIZE - (u32UlAdrptr -u32UlAdwptr);
    }

    if(u32UlAd1Num > u32UlBdDepth)
    {
        u32UlAd1Num -= u32UlBdDepth;
    }
    else
    {
        u32UlAd1Num = 0;
        g_stIPFDebugInfo->u32UlAd1NotEnough++;
    }

    u32UlBdNum = BSP_IPF_GetUlBDNum();
    if(0 == u32UlBdNum)
    {
        g_stIPFDebugInfo->u32UlBdNotEnough++;
    }

    if(u32UlBdNum > u32UlAd0Num)
    {
        u32UlBdNum = u32UlAd0Num;
    }

    if(u32UlBdNum > u32UlAd1Num)
    {
        u32UlBdNum = u32UlAd1Num;
    }

    return u32UlBdNum;
}
VOS_VOID ADS_UL_ProcLinkData(VOS_VOID)
{
    VOS_UINT32                          ulAllUlQueueDataNum;
    VOS_UINT32                          ulIpfUlBdNum;
    VOS_UINT32                          ulSndBdNum;

    /* 判断当前是否允许发送,如果不允许发送,直接退出 */
    if ((VOS_FALSE == ADS_UL_GET_MODEM_SND_PERMIT_FLAG(ADS_INSTANCE_INDEX_0))
     && (VOS_FALSE == ADS_UL_GET_MODEM_SND_PERMIT_FLAG((ADS_INSTANCE_INDEX_0 + 1) % ADS_INSTANCE_MAX_NUM)))
    {
        ADS_NORMAL_LOG(ACPU_PID_ADS_UL, "ADS_UL_ProcLinkData: not permit send!");
        return;
    }

    /* 处理队列时中的数据 */
    for (;;)
    {

        /* 获取上行可以发送的BD数。 */
#if(FEATURE_OFF == FEATURE_SKB_EXP)
        ulIpfUlBdNum = BSP_IPF_GetUlDescNum();
#else
        ulIpfUlBdNum = BSP_IPF_GetUlBDNum();
#endif
        if (0 == ulIpfUlBdNum)
        {
            ADS_DBG_UL_CFG_IPF_HAVE_NO_BDCD(1);

            /* 设置发送结束标志 */
            ADS_UL_SET_SENDING_FLAG(VOS_FALSE);

            /* 启动定时器退出 */
            ADS_StartTimer(ACPU_PID_ADS_UL, TI_ADS_UL_SEND, ADS_UL_GET_PROTECT_TIMER_LEN());
            break;
        }


        /* 设置正在发送标志 */
        ADS_UL_SET_SENDING_FLAG(VOS_TRUE);

        /* 获取当前所有队列中的数据包个数 */
        ulAllUlQueueDataNum = ADS_UL_GetAllQueueDataNum();

        /* 计算当前可发送的BD数目 */
        ulSndBdNum = PS_MIN(ulIpfUlBdNum, ulAllUlQueueDataNum);

#if(FEATURE_OFF == FEATURE_SKB_EXP)
        ADS_UL_FreeIpfUlConfigSuccSrcMem();
#endif

        /* 配置BD,写入IPF */
        ADS_UL_ConfigBD(ulSndBdNum);

        /* 获取当前所有队列中的数据包个数 */
        ulAllUlQueueDataNum = ADS_UL_GetAllQueueDataNum();

        /* 当前队列中没有数据,退出,等待下次队列由空变为非空处理 */
        if (0 == ulAllUlQueueDataNum)
        {
            /* 设置发送结束标志 */
            ADS_UL_SET_SENDING_FLAG(VOS_FALSE);

            break;
        }
        /* 当前队列中有数据,但是需要继续攒包 */
        else if (ulAllUlQueueDataNum <= ADS_UL_SEND_DATA_NUM_THREDHOLD)
        {
            ADS_StartTimer(ACPU_PID_ADS_UL, TI_ADS_UL_SEND, ADS_UL_GET_PROTECT_TIMER_LEN());

            /* 设置发送结束标志 */
            ADS_UL_SET_SENDING_FLAG(VOS_FALSE);

            break;
        }
        else
        {
            continue;
        }
    }

    return;
}