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.

TMS570LS3137: Problem appending to TX descriptor list

Part Number: TMS570LS3137


It has been six weeks since my last post and no response.  I came back to ask about this issue as my workaround has limitations.  Why was this post locked without providing a response?

  • Hi Tom,

    I am sorry for missing your previous post.
  • Umm... am I expected to copy the previous post's information here, or could you simply respond to it here?

  • Hi Tom,

    Can you please try the code used in lwip demo? The file is attached2526.emac.c

     /* For the first time, write the HDP with the filled bd */

     if(txch->active_tail == NULL) {

       /*SAFETYMCUSW 439 S MR:11.3 <APPROVED> "Address stored in pointer is passed as as an int parameter. - Advisory as per MISRA" */

       /*SAFETYMCUSW 45 D MR:21.1 <APPROVED> "Valid non NULL input parameters are assigned in this driver" */      

       EMACTxHdrDescPtrWrite(hdkif->emac_base, (uint32)(active_head), (uint32)EMAC_CHANNELNUMBER);

     }

     /*

      * Chain the bd's. If the DMA engine, already reached the end of the chain,

      * the EOQ will be set. In that case, the HDP shall be written again.

      */

     else {

       /*SAFETYMCUSW 45 D MR:21.1 <APPROVED> "Valid non NULL input parameters are assigned in this driver" */  

       curr_bd = txch->active_tail;

       /* Wait for the EOQ bit is set */

       /*SAFETYMCUSW 28 D MR:NA <APPROVED> "Hardware status bit read check" */

       /*SAFETYMCUSW 134 S MR:12.2 <APPROVED> "LDRA Tool issue" */

       /*SAFETYMCUSW 45 D MR:21.1 <APPROVED> "Valid non NULL input parameters are assigned in this driver" */  

       while (EMAC_BUF_DESC_EOQ != (EMACSwizzleData(curr_bd->flags_pktlen) & EMAC_BUF_DESC_EOQ))

       {

       }

       /* Don't write to TXHDP0 until it turns to zero */

       /*SAFETYMCUSW 28 D MR:NA <APPROVED> "Hardware status bit read check" */

       /*SAFETYMCUSW 134 S MR:12.2 <APPROVED> "LDRA Tool issue" */

       while (((uint32)0U != *((uint32 *)0xFCF78600U)))

       {

       }

       /*SAFETYMCUSW 45 D MR:21.1 <APPROVED> "Valid non NULL input parameters are assigned in this driver" */  

       curr_bd->next = (emac_tx_bd_t *)EMACSwizzleData((uint32)active_head);

       /*SAFETYMCUSW 134 S MR:12.2 <APPROVED> "LDRA Tool issue" */

       /*SAFETYMCUSW 45 D MR:21.1 <APPROVED> "Valid non NULL input parameters are assigned in this driver" */      

       if (EMAC_BUF_DESC_EOQ == (EMACSwizzleData(curr_bd->flags_pktlen) & EMAC_BUF_DESC_EOQ)) {

         /* Write the Header Descriptor Pointer and start DMA */

         /*SAFETYMCUSW 439 S MR:11.3 <APPROVED> "Address stored in pointer is passed as as an int parameter. - Advisory as per MISRA" */

         /*SAFETYMCUSW 45 D MR:21.1 <APPROVED> "Valid non NULL input parameters are assigned in this driver" */          

         EMACTxHdrDescPtrWrite(hdkif->emac_base, (uint32)(active_head), (uint32)EMAC_CHANNELNUMBER);

       }

     }

  • The demo code is tested and used by a lot of users, we don't see the race issue.
  • Hi QJ Wang,

    I do not want to try this demo code as it does not do what the TRM says the hardware can do.
    The TRM says a descriptor list can be appended to. It goes on to say this can create a race condition whereby you should write to the HDP if EOQ is set.
    The demo code you provided does not do this. It does check for an EOQ and writes the HDP if set. But prior to this check it waited for the EOQ condition.

    This seems to be a clear patch as there is no reason to have a check for EOQ if you previously waited for the EOQ.
    If you wait for the previous list to complete, then you are starting a new list, not appending to an existing list.
    It is interesting to see the HDP being compared to 0 as well. Please explain this as there is no mention in the TRM of the need to do this.

    I would appreciate a straight answer on this as I feel like you are playing a word game around a hardware issue.
    Can I really append to a list?
    Or do I have to wait for the current list to complete?

    Thanks,

    Tom
  • Tom,

    I am sorry I haven't got time to do this kind of test.
  • Hi QJ Wang,

    I am confused by your response since I am not asking you to do any kind of test.

    I have the following questions which are still unanswered:

    Why is the sample code you provided waiting for TX0HDP to be 0? The TRM does not mention the need to do this so I would like to understand this.

    Can I append to a tx descriptor list? And if so, how? The TRM says it is possible but I have been unable to reliably do this. The provided sample code waits for any previous transmission(s) to complete, so it is not appending to a list.

    Thanks,

    Tom

  • Hi Tom,

    Yes, you can append a new TX descriptor to the existing list. This new descriptor must be NULL terminated. 

    If the next descriptor pointer is zero, the current buffer is the last buffer in the queue. The SW application must set this value prior to adding the descriptor to the active transmit list.

    The value of pNext should never be altered once the descriptor is in an active transmit queue, unless its current value is NULL. If the pNext pointer is initially NULL, and more packets need to be queued for transmit, the software application may alter this pointer to point to a newly appended descriptor.

    The EMAC will use the new pointer value and proceed to the next descriptor unless the pNext value has already been read. The software can detect this case by checking for an end of queue (EOQ) condition flag. When EOQ is detected, the application may submit a new list (TX0HDP=0).

    To be honest, I didn't test the feature of appending a new descriptor to the linked list.

  • Received automated messages asking if this resolved my issue. Simply responding to this email that it did not resolve my issue. Sample code has been provided and issue has been reproduced by TI. Awaiting findings by TI team.
  • Hi Tom,

    I did a test with EMAC loopback. A packet is appended to an existing packet, and the appended packet is transferred successfully. Attached is my test project (CCS).

    The received packet is located 0x08001500 (existing packet), and 0x08001AEA (appended).

    The existing packet: total length is 470, each buffer is 94 bytes.

    The appended packet: total length is 470, each buffer is 94 bytes. But the payload is different.

    https://e2e.ti.com/cfs-file/__key/communityserver-discussions-components-files/312/5657.TMS570LS3137_5F00_EMAC_5F00_LPBK_5F00_PacketAppend.7z

  • Hi QJ,

    The idea of appending to a list is to allow software to add messages to the EMAC without stalling the software.  Therefore, appending to a list consists of two parts.  The first part is adding the new packet to the buffer descriptor list.  You have pointed me to that part.  The second part is updating the Header Descriptor pointer IF NECESSARY.  The IF NECESSARY is important to the idea of not stalling the software.  If software is required to wait/stall for the current list to complete, then the added packet is simply a new packet, not an appended packet.

    If you look just a few lines down at line 1517, you can see that line is stalling software until the current list completes.  Per the TRM this is not required so why is this line there?  Looking just a few more lines down at line 1530, the code checks to see if the hardware is still processing a list.  This is per the TRM to ensure the hardware is still running after the added packet data has been added to the list.  The idea here is if the hardware has completed the existing list, then the hardware needs to be restarted to process the new data.  If the hardware is still running, then the added data should be processed when the hardware gets to that point in the list.

    I have copied the lines of code in question below.  The lines in question have been highlighted in green, while my questions and comments are in red.

    /*
    * Chain the bd's. If the DMA engine, already reached the end of the chain,
    * the EOQ will be set. In that case, the HDP shall be written again.
    */
    else {
    /*SAFETYMCUSW 45 D MR:21.1 <APPROVED> "Valid non NULL input parameters are assigned in this driver" */
    curr_bd = txch->active_tail;
    /* Wait for the EOQ bit is set */
    /*SAFETYMCUSW 28 D MR:NA <APPROVED> "Hardware status bit read check" */
    /*SAFETYMCUSW 134 S MR:12.2 <APPROVED> "LDRA Tool issue" */
    /*SAFETYMCUSW 45 D MR:21.1 <APPROVED> "Valid non NULL input parameters are assigned in this driver" */

    why is this here?  This is not mentioned by the TRM.

    while (EMAC_BUF_DESC_EOQ != (curr_bd->flags_pktlen & EMAC_BUF_DESC_EOQ))

    {
    }
    /* Don't write to TXHDP0 until it turns to zero */
    /*SAFETYMCUSW 28 D MR:NA <APPROVED> "Hardware status bit read check" */
    /*SAFETYMCUSW 134 S MR:12.2 <APPROVED> "LDRA Tool issue" */

    why is this here? This is not mentioned in the TRM.

    while (((uint32)0U != *((uint32 *)0xFCF78600U)))
    {
    }
    /*SAFETYMCUSW 45 D MR:21.1 <APPROVED> "Valid non NULL input parameters are assigned in this driver" */
    curr_bd->next = active_head;
    /*SAFETYMCUSW 134 S MR:12.2 <APPROVED> "LDRA Tool issue" */
    /*SAFETYMCUSW 45 D MR:21.1 <APPROVED> "Valid non NULL input parameters are assigned in this driver" */

    This check is mentioned in the TRM, but it will always be true because of the code above which I am asking about.

    if (EMAC_BUF_DESC_EOQ == (curr_bd->flags_pktlen & EMAC_BUF_DESC_EOQ)) {
    /* Write the Header Descriptor Pointer and start DMA */
    /*SAFETYMCUSW 439 S MR:11.3 <APPROVED> "Address stored in pointer is passed as as an int parameter. - Advisory as per MISRA" */
    /*SAFETYMCUSW 45 D MR:21.1 <APPROVED> "Valid non NULL input parameters are assigned in this driver" */
    EMACTxHdrDescPtrWrite(hdkif->emac_base, (uint32)(active_head), (uint32)EMAC_CHANNELNUMBER);

    Regards,

    Tom

  • Hi QJ,

    The intent of appending to a list is to be able to add new packet information without stalling the software. Your example adds the additional information but is stalling the software. My questions center around code just a little further down from where you show the packet data being added. This code is added below with line number for reference.

    Line 1507 comment says 'If the DMA engine' which agrees with TRM.
    Line 1517 contradicts the line 1507 'If' comment by explicitly waiting. This wait is not specified in the TRM so why is it being done?
    Line 1523 is not specified in the TRM so why is it being done?
    Line 1530 is specified by the TRM and matches with the comment at 1507. But why have the check if you wait at 1517?

    The primary thing to appending a list is to have the system work when line 1530 is not true. But line 1517 STALLS the software until 1530 is true.


    00001506 /*
    00001507 * Chain the bd's. If the DMA engine, already reached the end of the chain,
    00001508 * the EOQ will be set. In that case, the HDP shall be written again.
    00001509 */
    00001510 else {
    00001511 /*SAFETYMCUSW 45 D MR:21.1 <APPROVED> "Valid non NULL input parameters are assigned in this driver" */
    00001512 curr_bd = txch->active_tail;
    00001513 /* Wait for the EOQ bit is set */
    00001514 /*SAFETYMCUSW 28 D MR:NA <APPROVED> "Hardware status bit read check" */
    00001515 /*SAFETYMCUSW 134 S MR:12.2 <APPROVED> "LDRA Tool issue" */
    00001516 /*SAFETYMCUSW 45 D MR:21.1 <APPROVED> "Valid non NULL input parameters are assigned in this driver" */
    00001517 while (EMAC_BUF_DESC_EOQ != (curr_bd->flags_pktlen & EMAC_BUF_DESC_EOQ))
    00001518 {
    00001519 }
    00001520 /* Don't write to TXHDP0 until it turns to zero */
    00001521 /*SAFETYMCUSW 28 D MR:NA <APPROVED> "Hardware status bit read check" */
    00001522 /*SAFETYMCUSW 134 S MR:12.2 <APPROVED> "LDRA Tool issue" */
    00001523 while (((uint32)0U != *((uint32 *)0xFCF78600U)))
    00001524 {
    00001525 }
    00001526 /*SAFETYMCUSW 45 D MR:21.1 <APPROVED> "Valid non NULL input parameters are assigned in this driver" */
    00001527 curr_bd->next = active_head;
    00001528 /*SAFETYMCUSW 134 S MR:12.2 <APPROVED> "LDRA Tool issue" */
    00001529 /*SAFETYMCUSW 45 D MR:21.1 <APPROVED> "Valid non NULL input parameters are assigned in this driver" */
    00001530 if (EMAC_BUF_DESC_EOQ == (curr_bd->flags_pktlen & EMAC_BUF_DESC_EOQ)) {
    00001531 /* Write the Header Descriptor Pointer and start DMA */
    00001532 /*SAFETYMCUSW 439 S MR:11.3 <APPROVED> "Address stored in pointer is passed as as an int parameter. - Advisory as per MISRA" */
    00001533 /*SAFETYMCUSW 45 D MR:21.1 <APPROVED> "Valid non NULL input parameters are assigned in this driver" */
    00001534 EMACTxHdrDescPtrWrite(hdkif->emac_base, (uint32)(active_head), (uint32)EMAC_CHANNELNUMBER);
    00001535 }
    00001536 }


    Regards,

    Tom
  • Sorry for what are basically duplicate posts. I did not notice the first reply went to another page so thought it had gotten dropped.
  • Hi Tom,

    The example code appends the new descriptor to a descriptor list, then submits the appended portion to the HDP for transmission. I commented those lines:
    // while (EMAC_BUF_DESC_EOQ != (curr_bd->flags_pktlen & EMAC_BUF_DESC_EOQ))
    // while (((uint32)0U != *((uint32 *)0xFCF78600U)))

    The code works fine. To be honest, I am clear why those 2 lines are added here to force the new HDP process.
  • Hi QJ,

    The first packet is too small to create my problem.  Please increase the size of the first packet to max packet size.  I have not had time to understand your entire test case, but I was able to verify it is not hitting my condition.

    Thanks,

    Tom

  • Sorry for my typo:

    I am not clear why those 2 lines are added here to force the new HDP process.
  • Hi Tom,

    I did another test:
    1. First existing packet: packet length is 1500 byes, 5 fragments and each buffer length is 300 byes
    2. the appended packet is: packet length is 1500 byes, 5 fragments and each buffer length is 300 byes

    The RXed data (first packet + appended packet) is equal to the TXed data. HDP is written once only: the pointer of the 1st descriptor.
  • QJ,

    I cannot reconcile what you are telling me.


    I have taken the project you provided. I commented out emac.h line 76 to remove the loopback mode. I used wireshark to capture the data on the wire and got the following.
    No. Time Source Destination Protocol Length Info
    1 0.000000 LogicPro_03:a6:6c Broadcast LLC 470
    2 0.000001 LogicPro_03:a6:6c Broadcast LLC 470
    3 0.000002 LogicPro_03:a6:6c Broadcast LLC 600
    4 0.000003 LogicPro_03:a6:6c Broadcast LLC 470
    These packet sizes correlate to what was set in sys_main, but I don't know why the 470 byte packet occurs three times.


    Then I changed the code to comment out emac.c 1517 and 1523 and got the following.
    No. Time Source Destination Protocol Length Info
    1 0.000000 LogicPro_03:a6:6c Broadcast LLC 470
    2 0.000016 LogicPro_03:a6:6c Broadcast LLC 470
    3 0.000029 LogicPro_03:a6:6c Broadcast LLC 600
    4 0.000041 LogicPro_03:a6:6c Broadcast LLC 470
    Again, I don't know why the 470 byte packet occurs three times, but both packets are here.


    Then I doubled the size of the first packet and got the following.
    No. Time Source Destination Protocol Length Info
    1 0.000000 LogicPro_03:a6:6c Broadcast LLC 940
    No second packet.


    Using wireshark does not rely on interpretation so I am pretty sure there is an issue here. Perhaps the issue is the same problem I am having with my driver, perhaps it is something with this particular test case.


    Please recheck your tests and verification.


    Regards,

    Tom
  • Hi QJ,

    Playing with your code, I noticed the code ends up in a module called EMACTxIntHandler. FYI, my code does not use interrupts to service the Ethernet.

    I also found where the extra 470 byte packets were coming from. They are the appended packets added in the EMACTransmit function. I thought the second packet in sys_main was the appended packet. I did not realize the appended packets were added in EMACTransmit. So looks like the test should send a total of 4 packets where the appended packets are 470 bytes and the other two packets sizes are defined in sys_main. It was just a coincidence that one of the packets in sys_main was also 470 bytes long.

    So the extra packets are now explained, but still does not explain why there was only one packet after the 940 byte packet in my previous reply.

    It would be easier to check for this issue with interrupt disabled and would also align with how we are using the device. Can you please disable the interrupts for your test case.



    Thanks,

    Tom
  • Hi Tom,

    Yes, I added code in EMACTransmit() for appending another packet. The length of both packets is 1500 bytes. I created a loopback plug by crossing pin 1 (TX+) and pin 3 (RX+) together, and crossing pin 2 (TX-) and pin 6 (RX-) together. Using loopback, I can verify if the received data is equal to the transmitted data. I didn't use wireshark.
  • Hi QJ,

    Since we are not getting consistent results and I do not want the EMAC to be interrupt driven, I prefer not spending more time looking at this code.

    I am interested in the results of the code I sent you that is not interrupt driven.  I had heard from your digital FAE that you had duplicated the issue I am seeing using this code.  Since we seem to have consistent results with this code and it is what I am trying to use, I would prefer to determine why there is an issue with this code. BTW, this code works fine if I simply add the same type of stalling while loop your code has.  Can you please review the code file and comment?

    Thanks,

    Tom

  • Tom,

    I did not test your code. Since I forgot to write the data length to the appended packet, so I did not receive the appended packet. After modifying my loopback code, I received the appended packet without any problem.
  • QJ,

    My apologies. I went back to the email and it did say you saw the problem on your code, not mine.

    It bothers me we are seeing different results. are you sure you have all the updates (larger packets and commented out while loops) in your latest test? Perhaps one got inadvertently left out. Different size packets would be nice as well to make sure there is no misinterpretation.

    Regardless, since we are not having consistent results, your example is interrupt driven and my case is not, and I have provided my code at TI's request... Can you please run my code and comment.

    Thanks,

    Tom
  • Tom,

    I am doing test for another customer, and will run your test case. To run your test, I need connect HDK to a ethernet router, is that right?
  •  Hi QJ,

    I connect the HDK Enet to my PC so I can use wireshark to look at what is sent.  The following is pasted from a previous email to the FAE but there is an image that is not coming through.  I will attempt to attach it.

    To generate and see the problem, do the following. 

    1. Put a breakpoint at sys_main.c line 88.
    2. Put a breakpoint at urdc_enet.c line 312.
    3. Load and run/resume the program.  We are using the tms570ls3137 hdk.
    4. When it breaks at sys_main(88), modify variable i to 900 decimal. 
    5. Run/resume the program
    6. When it breaks at urdc_enet(312), you can see the following:
      1. Variable tx_status is 0x40000000 which indicates there is no EOQ.
      2. Use memory browser to look at descriptors at 0xFC520200.  Address 0xFC52022C has value 0x50000000.  This is the same address read to obtain 0x40000000 value at step 6.a.
      3. Wireshark trace only shows the first of the two packets has been sent.

     Some notes/observations/interpretations:

    • FYI, The code initializes the flag_pktlen words of the descriptor list to 0x50000000.  Only addresses 0xfc520210 – 0xfc52024f are used when the test case fails.
    • The values at 6.a and 6.b are different.  This is a temporal thing.  The descriptors shown in the memory browser are grabbed after the breakpoint.  By this time, the EMAC has indicated an EOQ.
    • The second packet appended from 0xfc520230 – 0xfc52024C should have been transmitted since tx_status did not show an EOQ.
    • The descriptors at 0xfc52022c and 0xfc52024c and a wireshark trace indicate the second packet did not get sent.
    • If you do not set the first breakpoint at main(88), two packets will repeatedly get sent.  In this case, the first packet is short enough the EOQ is set before the second packets information has completely been added to the descriptor list. This is evident since the breakpoint at urdc_enet.c(312) is never hit.  Since the two packets are repeatedly sent, it would also indicate the logic setting the descriptors is good.

     

     Thanks,

    Tom

  • QJ,

    I did a little more testing with your code. It was bugging me that we were not seeing the same thing.

    What I found was the code requires size1 to be 5 times size2. I was keeping them as multiples of each other, but I did not keep to the expectation of 5. So that explains some of the difference. So I set all packets to 1500/300 like you did.

    What I see now is only two packets being sent, both 1500 The first should be the one created at emac.c line 125. The second is the one created by create_append_packet with the first call to EMACTransmit. I noticed the appended packet is added prior to the initial write to the HDP, so it is not appending to an active list.

    Packets 3 and 4 never got sent as the code gets stuck at emac.c line 1585 which is in the EMACTxIntHandler function.

    Did you verify you received 4 messages or just two?
    Do you see the program getting stuck at 1585 as well?
    Or does it end in the while loop in main?


    Thanks,

    Tom
  • Hi QJ,

    Just curious what the status on this is.

    Thanks,

    Tom

  • Hi QJ,

    Please provide status on this issue.

    Thanks,

    Tom

  • It has now been six months since my initial post on this issue and a month since your last response on this post.  Can I get some status on this?

  • Now six weeks since (8/10) I was told by TI a test case would be run. Another week with total silence. Amazing. Not even a reply to repeated attempts for status both in the forum and in emails.

  • Hello Tom,

    I had vocation starting from Aug 13th, then business travel until last week. I am catching up the E2E threads now. Sorry for that.
  • Received automated message from TI asking if issue was resolved and stating thread would be locked after 30 days of inactivity. So just adding activity. Still hoping for response.
  • I was assigned for the new thread this morning you opened yesterday, I will close this thread. I apologize for the delayed action on this issue.