This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

66AK2E05: Flow control for Ethernet

Part Number: 66AK2E05

okay so simple problem. i m not able to fully understand how the flow control is happening in the PA_emac example (Receive setup) i.e. what is the usage of rx_fdq(1-3)_qnum/qmgr

i was under the impression that if for some reason the free descriptors are not enough to handle large number of incoming packets then i can make multiple ques of free descriptors that would run side by side and act as a redundancy for when the descriptors cannot be as fast as the number of incoming packets.

so therefore i created multiple "rxFreeQInfo" as seen in the code below to be used to achieve the idea described above

    rxFlowCfg.flowIdNum             =   CPPI_PARAM_NOT_SPECIFIED;

    rxFlowCfg.rx_dest_qmgr          =   rxQInfo.qMgr;
    rxFlowCfg.rx_dest_qnum          =   rxQInfo.qNum;
    rxFlowCfg.rx_desc_type          =   Cppi_DescType_HOST;

    rxFlowCfg.rx_ps_location        =   Cppi_PSLoc_PS_IN_DESC;
    rxFlowCfg.rx_psinfo_present     =   1;    /* Enable PS info */

    rxFlowCfg.rx_error_handling     =   1;    /*  retry on starvation by default */
    rxFlowCfg.rx_einfo_present      =   1;    /* EPIB info present */

    rxFlowCfg.rx_dest_tag_lo_sel    =   0;    /* Disable tagging */
    rxFlowCfg.rx_dest_tag_hi_sel    =   0;
    rxFlowCfg.rx_src_tag_lo_sel     =   0;
    rxFlowCfg.rx_src_tag_hi_sel     =   0;

    rxFlowCfg.rx_size_thresh0_en    =   0;    /* By default, we disable Rx Thresholds */
    rxFlowCfg.rx_size_thresh1_en    =   0;    /* By default, we disable Rx Thresholds */
    rxFlowCfg.rx_size_thresh2_en    =   0;    /* By default, we disable Rx Thresholds */
    rxFlowCfg.rx_size_thresh0       =   0x0;
    rxFlowCfg.rx_size_thresh1       =   0x0;
    rxFlowCfg.rx_size_thresh2       =   0x0;

    rxFlowCfg.rx_fdq0_sz0_qmgr      =   rxFreeQInfo.qMgr; /* Setup the Receive free queue for the flow */
    rxFlowCfg.rx_fdq0_sz0_qnum      =   rxFreeQInfo.qNum;
    rxFlowCfg.rx_fdq0_sz1_qnum      =   0x0;
    rxFlowCfg.rx_fdq0_sz1_qmgr      =   0x0;
    rxFlowCfg.rx_fdq0_sz2_qnum      =   0x0;
    rxFlowCfg.rx_fdq0_sz2_qmgr      =   0x0;
    rxFlowCfg.rx_fdq0_sz3_qnum      =   0x0;
    rxFlowCfg.rx_fdq0_sz3_qmgr      =   0x0;

    rxFlowCfg.rx_fdq1_qnum          =   rxFreeQInfo1.qNum;  /* Use the Rx Queue to pick descriptors */
    rxFlowCfg.rx_fdq1_qmgr          =   rxFreeQInfo1.qMgr;
    rxFlowCfg.rx_fdq2_qnum          =   rxFreeQInfo2.qNum;  /* Use the Rx Queue to pick descriptors */
    rxFlowCfg.rx_fdq2_qmgr          =   rxFreeQInfo2.qMgr;
    rxFlowCfg.rx_fdq3_qnum          =   rxFreeQInfo3.qNum;  /* Use the Rx Queue to pick descriptors */
    rxFlowCfg.rx_fdq3_qmgr          =   rxFreeQInfo3.qMgr;

    /* Configure the Rx flow */
    if ((gRxFlowHnd = Cppi_configureRxFlow (gCpdmaHnd, &rxFlowCfg, &isAllocated)) == NULL)
    {
        UART_printf ("Error configuring Rx flow \n");
        return -1;
    }

is my hypothesis & implementation correct and if so why am i unable to receive data correct had how would and where would i push the used descriptors 

  • Hi Hannan,

    I've forwarded this to the ethernet experts. Their feedback should be posted here.

    BR
    Tsvetolin Shulev
  • Hi,

    This is the Rx flow management by CPPI, you can refer to cppi_drv.h for Cppi_RxFlowCfg structure. It is used to put receive frame with different size in different queue. See setupFlows() in pa\test\PAUnitTest\src\c66x\bios\framework.c.

    Regards, Eric
  • Hi Eric !!

    i was under the impression that the

    /** This field specifies which Queue should be used for the 1st Rx buffer in a packet whose size is 
         * less than or equal to the rx_size0 value */
        uint16_t          rx_fdq0_sz1_qnum;
        /** This field specifies which Queue Manager should be used for the 1st Rx buffer in a packet whose size 
         * is less than or equal to the rx_size0 value */
        uint16_t          rx_fdq0_sz1_qmgr;

    etc etc were responsible to allocate buffer with variable sizes

    and the

        /** This field specifies which Free Descriptor Queue should be used for the 2nd Rx buffer in a host type packet */
        uint16_t          rx_fdq1_qnum;
        /** This field specifies which Queue Manager should be used for the 2nd Rx buffer in a host type packet */
        uint16_t          rx_fdq1_qmgr;

    specifies something else.

    but are you saying that both the rx_fdq1_sz1_qnum & rx_fdq_qnum are same?

  • Hi,

    Please see this thread for explanation e2e.ti.com/.../1462274

    Regards, Eric
  • Hi,
    Thanks for your quick response !

    now just to clarify the
    rxFlowCfg.rx_fdq1_qmgr = rxFreeQInfo1.qMgr;
    rxFlowCfg.rx_fdq2_qnum = rxFreeQInfo2.qNum;
    rxFlowCfg.rx_fdq2_qmgr = rxFreeQInfo2.qMgr;
    rxFlowCfg.rx_fdq3_qnum = rxFreeQInfo3.qNum;
    rxFlowCfg.rx_fdq3_qmgr = rxFreeQInfo3.qMgr;

    would not be used if the buffer i use (at the setData()) is bigger then the packet bytes?

    Also just one more thing i wanted to ask was that the "rxFreeQInfo.q.." if is not able to free itself fast enough can i somehow use rxFreeQInfo1/2/3 to facilitate the packets until my primary FDQ is free?
  • any update on this regard?
  • Hi,

    If you use:

    rxFlowCfg.rx_size_thresh0_en = 0; /* By default, we disable Rx Thresholds */

    rxFlowCfg.rx_size_thresh1_en = 0; /* By default, we disable Rx Thresholds */

    rxFlowCfg.rx_size_thresh2_en = 0; /* By default, we disable Rx Thresholds */

    Then all the packets go into rx_fdq0_sz0_qmgr/qnum, no packets go into rx_fdq1/2/3_qmgr/qnum.

    if is not able to free itself fast enough can i somehow use rxFreeQInfo1/2/3 to facilitate the packets until my primary FDQ is free====>Yes, "Nobody says that the size of the buffers linked to the descriptors in RX_FDQ0_SZ#_QNUM/QMGR is >= the corresponding RX_SIZE_THRESH(#-1). Thus if the free descriptor queue has "small" buffers, more than one descriptor will still be needed to finish the packet. Regardless of the size, the DMA will always get second, third, fourth and subsequent descriptors from RX_FDQ1_QMGR/QNUM, RX_FDQ2_QMGR/QNUM, and RX_FDQ3_QMGR/QNUM. The first descriptor will use the size of the packet and the size thresholds to pick the first (SOP) descriptor. The DMA will take as many descriptors as needed to fit the packet (its not limited to 4)."

    Regards, Eric