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.

C6748 Emac TX question

 

Hi,

will appreciate your input about the following EMAC TX issue.  (we are using BIOS 5)

The following is being done  in Tx packets via EMAC.  Only channel 0 is used.

1)  prepare BD to be TX 
2) if this is  the first packet that is going to be Tx, then 
                Tx0HDP =   the prepared BD 
                 lastPtrBD = the prepared BD   //   lastPtrBD  points to the last BD in active list.
     otherwise
                lastPtrBD -> next descriptor ptr   =     the  prepared BD
               if the BD pointed to by   lastPtrBD  has its EOQ bit set then
                       Tx0HDP =   the prepared BD 
                       lastPtrBD = the prepared BD
               otherwise
                        lastPtrBD  =  the prepared BD   // at this point  the prepared BD is appended to the active list

 

Question:
with this logic,  we have packets that are  not TXed, and it happens  in cases where packets are appended to the active list.
do you see  issues with the above logic. I am missing something there?

Thank you

    Hezi.

 

 

 

 

 


 

 

 

 

  • Hezi,

    Can you please respond with the exact version numbers of the following components you are using?

    1. NDK version?

    2. NSP version? (Ethernet driver package for the 6748, if you are using it)

    3. BIOS 5.x version you are using?

    Just to understand your situation a little better, are you modifying the original 6748 Ethernet driver?

    Steve

  • Hezi,

    You mentioned that you are using BIOS, but your question seems to be specific to the device.  I have moved this thread over to the C674x forum in hopes that it will get a faster response there.

    Dave

  •  

    Hi

    We are using our own implementation of Emac driver for 6748. I copied here my original question below. In the meanime,  I think that I have resolved the issue by appending new  packets  to an active list only if the last packet in the active list indicates EOQ. i.e:

      if the last packet in the active list does not indicate EOQ, then  new packets are put into a list that is not appended to current active list. once active list indicate EOQ, then make the list  of the new packets to be the new active list by repost of HDP.  This works OK, but please let me know if my understanding is correct .

    Thank you

     Hezi.

    ----------------
     below is my original question, and the  line where the issue of a new packet  appended to an active list is marked in red.

    The following is being done  in Tx packets via EMAC.  Only channel 0 is used.

    1)  prepare BD to be TX 
    2) if this is  the first packet that is going to be Tx, then 
                    Tx0HDP =   the prepared BD 
                     lastPtrBD = the prepared BD   //   lastPtrBD  points to the last BD in active list.
         otherwise
                    lastPtrBD -> next descriptor ptr   =     the  prepared BD          
                   if the BD pointed to by   lastPtrBD  has its EOQ bit set then
                           Tx0HDP =   the prepared BD 
                           lastPtrBD = the prepared BD
                   otherwise
                            lastPtrBD  =  the prepared BD   // at this point  the prepared BD is appended to the active list

     

    Question:
    with this logic,  we have packets that are  not TXed, and it happens  in cases where packets are appended to the active list.

  • I am facing a similar issue.Is there a solution to this problem

  • I resolved it as follows:

    there is some race condition with Emac
    If the Emac is in progress with transmitting the last active packet,  then EMAC may have already read the p_next pointer as NULL before the new list is appended to the active list . i.e before the following assignment occurs:
     lastPtrBD -> next descriptor ptr   =     the  prepared BD

    in this race case, the appended list will not be processed.

    the resolution is to keep 2 lists: active list that is being transmitted, and waiting list that BD will be appended to it.
    when EOQ of last aBD in active list is set, then make the waiting list as the new active list. this EOQ condition can be checked, either when a new BD needs to be tranmitted, or when TX interrupt occurs. Also, note that since these lists will be looked at or manipulated by TX ISR or the code that handles adding new BD, then some mutual exclusion protection should be put in place as apropriate.

    Regards

    Hezi.

     

     

     

     

  • Can you please share the code?

    Regards

    Manoj

  •  

    Hi,

    I put a psuedo code and general description of how it was resolved  ( there could be different approaches such as not using the SWI below.)


    Data structures:
    =================
    there are two lists that points to EDBs:
    active list
    appended list

    the code contain three main code peices:
    ========================================
    1) a routine to add EDB to the appended list, and post a software interrupt
    2) TX HW ISR which is called upon TX completion of packets:
    it ack the interrupt, and post a software   interrupt
    3) software interrupt (posted from items 1 or 2)
    checks if last EDB of active list has its EOQ set, and the appended list is not empty, then:
    set the appended list list as the new active list.

    AddEDB
    ======
    get a free EDB, and update its fields buffer and flags fields
    SWI_disable();
    if append_list is empty then
      start a new appended list with this EDB
    else
      append this EDB to the existing appended list
    SWI_enable();
    SWI_post ...
     

    TX HW Interrupt service routine
    =================================

     volatile UINT32 p_IntBD;

     /* TXCP points to the BD that interrupted */
        p_IntBD = (UINT32)(EMAC->TXCP[0]);

     /* writing the address of the BD that interrupted back to TXCP will ack the interrupt */
     EMAC->TXCP[0] = (UINT32) p_IntBD;

     /* from TI doc: Interrupts must be acknowledged by writing the appropriate value to the EMAC End-Of-Interrupt Vector
     (MACEOIVECTOR). The MACEOIVECTOR behaves as an interrupt pulse interlock -- once the EMAC
     control module has issued an interrupt pulse to the CPU, it will not generate further pulses of the same
     type until the original pulse has been acknowledged. */
     EMAC->MACEOIVECTOR = 0x02;

     SWI_post ...

     

    Softwaere interrupt
    =====================
     
      if appended list is empty then
      {
     
            flags = CHKBIT(lastActiveEDB->flags_pkt_length, EMAC_DSC_FLAG_EOQ);

      if (flags)
      {
       set last EDB of active list =  last EDB of appended list

       EMAC->TXHDP[0] = (uint32_t) first packet of appended list

       appended list = NULL;
            }
     }