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.

pa SimpleExample questions

 

I have been looking through the simpleExample that comes with the PA in the pdk subdirectory and I had a few questions that need clarification.

The example talks of two tables of layer 2/3 configuration information. When setting up the MAC address with the pa_addMac it make changes to the memL2Ram by writing the mac address amongst other things into the memory. Similarly it does this for the IP address into the memL3Ram when doing pa_addIP. However where does the port info get stored or is that because it is just a port number so it does not need to be saved like the IP and Mac addresses? I gather these are just duplicates of the actual tables stored in the PA for the purpose of preparing the actual command to send to the PA to setup the tables and the PA hardware actually contains the LUT table and the configuration is just supposed to write to those tables? If doing custom LUT2 would I need a layer 4 Ram section?

The setupFlow0 function sets up the default return queue as 902 which is what is used for PA cmd reply. However in the case of pkts received by the PA on loopback, the CONFIG_ADDPORT0_ROUTE is used in config.h to set up the queue CONFIG_FIRST_RX_PKT_Q i.e. 904 for routing packets to the host overriding this default setup. The CONFIG_PACOM_REPLY is also setup to use flow 0 and it uses the dest queue as 902 also. I guess my question really is why the need to setup the default return queue number as it is always setup by the PA for all packets being received such as command reply and others packets being received from the loopback. Is it just for completeness sake?

The length of the buffers are setup to be 304 bytes. Now for configuration of PAs what is the maximum size of Tx packets required for configuration only? Is it okay to use 256 byte buffers and use multiple of these when TX during PA config setup just like for regular Tx by PA of Ethernet packets. In other words can the configuration by broken into multiple packets and pushed onto the queue as a multi-packet configuration, the response of which to a command like say Pa_addMac is then forwarded back to the LLD through the Pa_forwardResult.

If I want to allocate 256 byte buffers for all incoming packets to the DSP through the PA in external memory. How do I go about ensuring that the first 12 bytes off every packet are not written to? I need to put some proprietary stuff in those bytes when stored in external memory. Would that be through the rx_sop_offset in the flow to be configured? So for example an Ethernet packet greater than 256 bytes would use multiple buffers with the first 12 bytes of each buffer skipped.

Thanks, Aamir

  •  Hi, Aamir:

    It is my pleasure to talk to you again.
    Please note that the PA simple example is a simple example, but it may not be the best example for CPPI flow configuration and etc.
    Let me try to answer your questions below:

    I have been looking through the simpleExample that comes with the PA in the pdk subdirectory and I had a few questions that need clarification.

    The example talks of two tables of layer 2/3 configuration information. When setting up the MAC address with the pa_addMac it make changes to the memL2Ram by writing the mac address amongst other things into the memory. Similarly it does this for the IP address into the memL3Ram when doing pa_addIP. However where does the port info get stored or is that because it is just a port number so it does not need to be saved like the IP and Mac addresses? I gather these are just duplicates of the actual tables stored in the PA for the purpose of preparing the actual command to send to the PA to setup the tables and the PA hardware actually contains the LUT table and the configuration is just supposed to write to those tables? If doing custom LUT2 would I need a layer 4 Ram section?

    [Eric] PA LLD maintains  local L2/L3 tables so that LLD is able to link L3/L4 entry to the previos L2/L3 entry. We can also verify the new entry against the entries in the corresponding table to detect duplicate entry and ordering violation which means the module user tries to add an entry after a more specific entry is already at the table.
    The L4 related information is stored at the L4 handle returned by API Pa_addPort() and Pa_addCoustomLut2().

    The setupFlow0 function sets up the default return queue as 902 which is what is used for PA cmd reply. However in the case of pkts received by the PA on loopback, the CONFIG_ADDPORT0_ROUTE is used in config.h to set up the queue CONFIG_FIRST_RX_PKT_Q i.e. 904 for routing packets to the host overriding this default setup. The CONFIG_PACOM_REPLY is also setup to use flow 0 and it uses the dest queue as 902 also. I guess my question really is why the need to setup the default return queue number as it is always setup by the PA for all packets being received such as command reply and others packets being received from the loopback. Is it just for completeness sake?

    [Eric] Excellent observation. You are right, the CPPI flow default destination queue is not used by PASS. The PASS stream interface will always overwrite this queue with the destination queue specified by PASS.

    The length of the buffers are setup to be 304 bytes. Now for configuration of PAs what is the maximum size of Tx packets required for configuration only? Is it okay to use 256 byte buffers and use multiple of these when TX during PA config setup just like for regular Tx by PA of Ethernet packets. In other words can the configuration by broken into multiple packets and pushed onto the queue as a multi-packet configuration, the response of which to a command like say Pa_addMac is then forwarded back to the LLD through the Pa_forwardResult.
    [Eric] The current LLD implementation requires a single linear buffer. You can call API with a large linear buffer and then copy the output into multiple small buffers, setup CPPI buffer link. However, must of command packets are pretty small and can be fit into a 256-byte buffer. Please refer to the command size definitions at the "Command buffer minimum size requirements" section.

    If I want to allocate 256 byte buffers for all incoming packets to the DSP through the PA in external memory. How do I go about ensuring that the first 12 bytes off every packet are not written to? I need to put some proprietary stuff in those bytes when stored in external memory. Would that be through the rx_sop_offset in the flow to be configured? So for example an Ethernet packet greater than 256 bytes would use multiple buffers with the first 12 bytes of each buffer skipped.
    [Eric]  No, rx_sop_offset is only applicable to the first packet segment. However, you can set the buffer pointer to be 12-byte off from the original buffer pointer and the buffer size to be 12 off from the original buffer length so that the first 12 bytes will not be written by PASS.

    If my answer is good enough, could you please click the "verify answer" botton.

    Best regards,

    Eric

    Thanks, Aamir

  • Eric Ruei wrote the following post at 02-21-2012 3:20 PM:

     Hi, Aamir:

    It is my pleasure to talk to you again.
    Please note that the PA simple example is a simple example, but it may not be the best example for CPPI flow configuration and etc.
    Let me try to answer your questions below:

    Good to hear from you Eric

    I have been looking through the simpleExample that comes with the PA in the pdk subdirectory and I had a few questions that need clarification.

    The example talks of two tables of layer 2/3 configuration information. When setting up the MAC address with the pa_addMac it make changes to the memL2Ram by writing the mac address amongst other things into the memory. Similarly it does this for the IP address into the memL3Ram when doing pa_addIP. However where does the port info get stored or is that because it is just a port number so it does not need to be saved like the IP and Mac addresses? I gather these are just duplicates of the actual tables stored in the PA for the purpose of preparing the actual command to send to the PA to setup the tables and the PA hardware actually contains the LUT table and the configuration is just supposed to write to those tables? If doing custom LUT2 would I need a layer 4 Ram section?

    [Eric] PA LLD maintains  local L2/L3 tables so that LLD is able to link L3/L4 entry to the previos L2/L3 entry. We can also verify the new entry against the entries in the corresponding table to detect duplicate entry and ordering violation which means the module user tries to add an entry after a more specific entry is already at the table.
    The L4 related information is stored at the L4 handle returned by API Pa_addPort() and Pa_addCoustomLut2().

    Okay so it has a two-fold usage of linking entries and detecting duplicates. I also take it from your statement above that for port info, just the handles are needed to store the details unlike in the L2 and L3 case which need the RAM tables for linking etc? How though does one deal with duplicate entries and ordering violations if I try to add a duplcaite custom LUT2 entry?

    The setupFlow0 function sets up the default return queue as 902 which is what is used for PA cmd reply. However in the case of pkts received by the PA on loopback, the CONFIG_ADDPORT0_ROUTE is used in config.h to set up the queue CONFIG_FIRST_RX_PKT_Q i.e. 904 for routing packets to the host overriding this default setup. The CONFIG_PACOM_REPLY is also setup to use flow 0 and it uses the dest queue as 902 also. I guess my question really is why the need to setup the default return queue number as it is always setup by the PA for all packets being received such as command reply and others packets being received from the loopback. Is it just for completeness sake?

    [Eric] Excellent observation. You are right, the CPPI flow default destination queue is not used by PASS. The PASS stream interface will always overwrite this queue with the destination queue specified by PASS.

    The length of the buffers are setup to be 304 bytes. Now for configuration of PAs what is the maximum size of Tx packets required for configuration only? Is it okay to use 256 byte buffers and use multiple of these when TX during PA config setup just like for regular Tx by PA of Ethernet packets. In other words can the configuration by broken into multiple packets and pushed onto the queue as a multi-packet configuration, the response of which to a command like say Pa_addMac is then forwarded back to the LLD through the Pa_forwardResult.
    [Eric] The current LLD implementation requires a single linear buffer. You can call API with a large linear buffer and then copy the output into multiple small buffers, setup CPPI buffer link. However, must of command packets are pretty small and can be fit into a 256-byte buffer. Please refer to the command size definitions at the "Command buffer minimum size requirements" section.

    I am not sure what document are you referring to in the section comment above - Can you please elaborate. Okay so it is actually the LLD that has a one buffer requirement and the PA itself can accept multiple buffer command packets. I can use your workaround that you suggested if the maximum size exceeds 256 bytes as I want to use 256 byte buffers for messages to the PA.

    If I want to allocate 256 byte buffers for all incoming packets to the DSP through the PA in external memory. How do I go about ensuring that the first 12 bytes off every packet are not written to? I need to put some proprietary stuff in those bytes when stored in external memory. Would that be through the rx_sop_offset in the flow to be configured? So for example an Ethernet packet greater than 256 bytes would use multiple buffers with the first 12 bytes of each buffer skipped.
    [Eric]  No, rx_sop_offset is only applicable to the first packet segment. However, you can set the buffer pointer to be 12-byte off from the original buffer pointer and the buffer size to be 12 off from the original buffer length so that the first 12 bytes will not be written by PASS.

    Okay so I do not need to use rx_sop_offset and can just adjust by 12 bytes each buffer pointer for every buffer I use and the length adjustment that you mention too. Thanks!

    Also Eric can you please answer my question on the ALE that I posted seperately today. Thanks.

    Aamir

  • Hi,  Aamir:

    I also take it from your statement above that for port info, just the handles are needed to store the details unlike in the L2 and L3 case which need the RAM tables for linking etc?
    [Eric] Yes.
    How though does one deal with duplicate entries and ordering violations if I try to add a duplcaite custom LUT2 entry?
    [Eric] There is no ordering violation for LUT2 where all entries are in ascending order for binary search.
              The routing information of the new entry will replace the old one. You should set the parameter "replace" to TRUE if you want to replace the existing entry.

    I am not sure what document are you referring to in the section comment above - Can you please elaborate.
    [Eric] ti/drv/pa/pa.h or ti/drv/pa/docs/paDocs.chm or ti/drv/pa/docs/doxygen/html/index.html

    Best regards,

    Eric

     

     


             

     

  • Thanks for the doc link. It would appear that only the exception route command could be >256 and I think I will not need it so I am okay.

  • Hi,Eric

    I got some problems with PA ,too.I am changing the example code of PA_emac example and trying to let both emac0 and emac1 do interal_loopback at the same time. The two SGMII and different mac,so I need to add another mac address to the L2 table using function Pa_addMac. The help document says that the pa would search from lowest entry location to highest entry location until the first matching entry is found, but when I add a new  Pa_addMac by make a copy of Add_MACAddress fuction and change the corresponding parameter in Pa_addMac(i am not sure if this is the right way ,or you simply has to add a new Pa_addMac function in the old Add_MACAddress), the pass simple discard the packet intead of continue searching for a match. I tried to change nextRtFail   parameter in the added Pa_addMac from discard to pa_DEST_CONTINUE_PARSE_LUT1,and the pa_addMac returned config error. How should I do and a new entry to pa l2? And do you always have to push a descriptor to the command queue in order to send the command to the PA , or just add a new  Pa_addMac  function can config the pa ?

  • Hi, Long:

    You do not need to worry about the ordering unless you are adding two entries where the matching criteria of one is the subset of the other. For example, the first entry requires both source address and destination address matching and the second entry only requires the destination address matching and the destination address is the same. In this case, you need to add the second entry  which is more general than the other one at first.

    The Pa_addMAC() function only formats the command packet and specifies the desired command destination. It is up to the application to forward the command packet to PASS. You need to follow the example of Add_MACAddress() at PA_emac_example for each MAC entry.

    Best regards,

    Eric

     

     

     

  • Hi,Eric:

    You answer is helpful, but i still got stuck. The  PA_emac_example use Emac0 and its mac address as default destination settings. Now  I add a " Add_MACAddress1()" following  Add_MACAddress(), adding Emac1's mac address as a new mac entry. Both entry use only destination mac and input Emac port. Both entry are unique. The debug went well, and When I sent the pack with Emac1's destination address, it succeeded. But then I change the packet back to Emac0's mac address ,I always got "received 0 packets so far" feed back. It seemed that when PA failed to match the packet's mac address(Emac0's) with the new adding entry(with Emac1's address), it simply tossed the packet instead of continue searching for a hit(which is the old entry). I changed  Add_MACAddress1() and Add_MACAddress()'s position and sent packet with Emac0, now I could receive the packet well. How shall I configure Pa to let it search all the mac entry before toss the packet? I tried to change the  nFailInfo  for a fail match from "pa_DEST_DISCARD" to "pa_DEST_CONTINUE_PARSE_LUT1", still didn't work. Looking forwarding to you suggestions.

    Best regards

    Long Cui

  • Dear Long:

    We are glad to learn that you start to use TI product as a college student and will try our test to help you succeed. It is a little tricky to setup the CPSW for loopback operation. The best way is to disable ALE learning at all ports and enable ALE bypass for ingress traffics and enable SGMII internal loopback at both EMAC ports. When you send packets to CPSW CPPI port through queue 648, use psFlags to specify the desired EMAC ports. The loopbacked packets will be delivered to PASS.

    Please note that the EMAC port 0 is not connected to the RJ45 so that it can be used in internal loopback mode only.
    Besides, the nextFail route will be invoked when the input packet matches this rule (MAC rule) and is forworded to the next stage (IP rule) and no match is found.

    To help you debug, please provide the following information:
    - CPSW and EMAC port settings
    - Two MAC rules (ethInfo, routeInfo and etc.)
    -  test packets
    - use CCS to dump the following memory region (16 32-bit words) before and after the packet is delivered to queue 648
      - 0x2090b00
      - 0x2090c00
      - 0x2000000

    Best regards,

    Eric

     

     

     

     

     

     

     

     

  • Dear Eric:

    Thanks for your help again! Your TI guys are so cool and helpful! I am using pdk_C6670_1_0_0_17, PA_emac exmaple. The CPSW, ALE table SGMII mode(both internal),Q648, psFlags are all setted just as described above. You answer proved my wondering about the nextFail setting was wrong, and I finally found the problem. For each new mac entry, there is a handle  specified for L2 to reference L2 arouting information . Instead of using a new one for a new entry I added, I simply copied the function Pa_addmac and used the old handle. Now I have both Emac0&1 initiated and working on internal loopback mode on EVM board in a single program successfully. I wouldn't have done it without your guys help these days, so thank you again!

    Although I reached my goal, there a few points left still confused me. First is about adding new ALE entries in function Init_Cpsw.  It seems in loopback mode, the program sets both port0&1 with port1's mac address, why? I quote as following:

    if(cpswLpbkMode == CPSW_LOOPBACK_NONE)
    Switch_update_addr(0, macAddress0, 0);
    else
    Switch_update_addr(0, macAddress1, 0);

    Switch_update_addr(1, macAddress1, 0);
    Switch_update_addr(2, macAddress2, 0);

    Now i send a packet with destination mac address 0x 10,11,12,13,14,15(for Emac0),with the settings above , the console window reads:

    "Following is the ALE table before transmits.

    Port =0, Mac address 10:11:12:13:14:15 ,unicast_type =0

    Port =1, Mac address 10:11:12:13:14:15 ,unicast_type =0

    Port =2, Mac address 20:21:22:23:24:25 ,unicast_type =0

    Packet Transmission Start ...

    Following is the ALE table after transmits.

    Port =0, Mac address 10:11:12:13:14:15 ,unicast_type =0

    Port =1, Mac address 10:11:12:13:14:15 ,unicast_type =0

    Port =2, Mac address 20:21:22:23:24:25 ,unicast_type =0"

    The program runs successfully. So there are 2 entries with same MaCaddress(is that OK?),and the Mac address for 3 ports remain unchange.

    Then I set  the macaddress for port0 to  0x 00:01:02:03:04:05, set psFlags to 1 and send the same packet with 10:11:12:13:14:15(Emac0's,or port1's) as detination address,the console goes:

    "Following is the ALE table before transmits.

    Port =0, Mac address 00:01:02:03:04:05 ,unicast_type =0

    Port =1, Mac address 10:11:12:13:14:15 ,unicast_type =0

    Port =2, Mac address 20:21:22:23:24:25 ,unicast_type =0

    Packet Transmission Start ...

    Following is the ALE table after transmits.

    Port =1, Mac address 00:01:02:03:04:05 ,unicast_type =0

    Port =1, Mac address 10:11:12:13:14:15 ,unicast_type =0

    Port =2, Mac address 20:21:22:23:24:25 ,unicast_type =0"

    The program runs successfully.There are no ports with same address before transmit, but afterwards, the ALE table changed. I already set the nolearning mode (to 1)for each and every port, how is that possible?

    I change the packet's destination macaddress to Emac1's(or port2's),and set psFlags=2,the console before transmit remain the same,an afterwards goes :

    Port =2, Mac address 00:01:02:03:04:05 ,unicast_type =0

    Port =1, Mac address 10:11:12:13:14:15 ,unicast_type =0

    Port =2, Mac address 20:21:22:23:24:25 ,unicast_type =0

    and still I can't explain why. I suppose ALE table would be always the same. Can you throw some light on that?

  • Second, with the hardware interrupt in Setup_Rx. The program I quote as following:

    "

    /* System event 48 - Accumulator Channel 0 */
    eventId = 48;

    /* Pick a interrupt vector id to use */
    vectId = 7;

    /* Register our ISR handle for this event */
    EventCombiner_dispatchPlug (eventId, (EventCombiner_FuncPtr)Cpsw_RxISR, (UArg)NULL, TRUE);

    /* Map the combiner's output event id (evevtId/32) to hardware interrupt 8. */
    /* The HW int 8 is slected via CM.eventGroupHwiNum[] specified at cpsw_example.cfg */
    Hwi_eventMap(vectId, 1);

    /* Enable interrupt 8. */
    Hwi_enableInterrupt(vectId);"

    The comment says it uses HW int8 for event48(that's group event1), but how can Vectid=7? In the help contents of CCS5, the first parameter of Hwi_eventMap and Hwi_enableInterrupt is interrupt number, shouldn't it be 8?

    and in the .cfg file of the program,there are:

    "ECM.eventGroupHwiNum[0] = 7;
    ECM.eventGroupHwiNum[1] = 8;
    ECM.eventGroupHwiNum[2] = 9;
    ECM.eventGroupHwiNum[3] = 10;"

    the HW int num for group event 1 is set to 8(or at least to my understanding). Is this setting conflict with the one in the Setup_Rx? And if there is one settings for the relationship between group event Num and the HW Int num in the cfg file , is the one in Setup_Rx necessary?

    Again looking forward to your answers.

    Best regards,

    Long 

  • Hi, Long:

    There is a typo in the comment which is misleading as well. What you understand is correct. The ECM.eventGroupHwiNum[] specifies a number of interrupt id which can be used for event-to-interrupt group mapping. In this example, vectId can be set to 7, 8, 9 or 10.

    Best regards,

    Eric

     

  • Hi, Long:

    I believe that you understand how switch works in general. The switch will add the source MAC address into its ALE table with the ingress port number when it receives a packet. Then the switch routes the packet based on its destination MAC address, if the destination address is at ALE table with a port number. the packet will be delivered to that port only. Otherwise, it will be broadcasted to all switch ports.  In general, ALE table will not conatin two entries of the same MAC address with different port number, the later entry will overwrite the previous one.

    The CPSW is not a general switch. It is a combination of a general switch and the CPPI port. Therere, its behavior may not be the same as normal switch regarding the CPPI port. For example, the unicast packet will not be delivered to CPPI port unless its destination MAC address is at the ALE table with CPPI port number (0).

    It is not a good idea to loopback the same packet through a switch since the switch will be confused due to packet with same source address entering from two different ports. To achieve the mission impossible, we disable ALE learning and use psFlag to direct egress traffic and the ingress traffic will be delivered to CPPI port from both EMAC port by enabling ALE bypass mode. As you may image, there is no need to add ALE entries.  Therefore, we have removed the portion of code for EVM opeartion:

        /*
         * The following code is required for device simulator only.
         * It is also served as an example of adding MAC address to the ALE table manually
         */

        if (cpswSimTest)
        {
            /* Program the ALE with the MAC address.
            *
            * The ALE entries determine the switch port to which any
            * matching received packet must be forwarded to.
            */
            /* Get the next free ALE entry to program */
            for (i = 0; i < CSL_CPSW_3GF_NUMALE_ENTRIES; i++)
            {
                if (CSL_CPSW_3GF_getALEEntryType (i) == ALE_ENTRYTYPE_FREE)
                {
                    /* Found a free entry */
                    break;                   
                }
            }
            if (i == CSL_CPSW_3GF_NUMALE_ENTRIES)
            {
                /* No free ALE entry found. return error. */           
                return -1;           
            }
            else
            {
                /* Found a free ALE entry to program our MAC address */           
                memcpy (ucastAddrCfg.macAddress, macAddress, 6);    // Set the MAC address
                ucastAddrCfg.ucastType      =      ALE_UCASTTYPE_UCAST_NOAGE;   // Add a permanent unicast address entryALE_UCASTTYPE_UCAST_NOAGE.
                ucastAddrCfg.secureEnable   =      FALSE;  
                ucastAddrCfg.blockEnable    =      FALSE;  
                ucastAddrCfg.portNumber     =      portNum;   // Add the ALE entry for this port

                /* Setup the ALE entry for this port's MAC address */
                CSL_CPSW_3GF_setAleUnicastAddrEntry (i, &ucastAddrCfg);           
            }
        }

    There is no need to add ALE entry for normal operation, either. Unless, you expect to receive unicast traffic without sending any egress traffic.

    Could you please click "Verify Answer" button if I answer your question? And please start a new thread for other questions taht byou may have.

     

    Best regards,

    Eric

     

     

  • Hi, Eric

    Thank you! That explain a lot.

    Best regards,

    Long

  • Hi, Eric:

    Your answer is very helpful, thanks. I cant find "verify answer" button, maybe it's because I didn't start the original posts. I will start a new thread for other questions in the future. Sorry for any trouble that I might have caused for this :).

    Best regards,

    Long

  • Hi, Long:

    No prollem! I am glad that I can help alittle bit.

    Best regards,

    Eric

     

     

  • Hi Eric,

    Can you please provide some guidance on my post below. Somehow it got moved to BIOS forum by a moderator or something though it would seem it should be in the multicore c66 forum.

    Thanks, Amir

    http://e2e.ti.com/support/embedded/bios/f/355/t/224059.aspx