Hi TI folks,
Attn: Eric or any other designer in the PA or multicore navigator queue etc
I am trying to get ethernet packets sent out through the switch on the c6678. So I am using the 9th port (which is the switch transmit port) when I push a descriptor with the ethernet packet location specified in the buffer location in the descriptor this works and I am able to capture the packets sent by the EVM. However, I have the IP and UDP checksums set to zero which is obviously incorrect. I now want the PDSP4 to compute the checksums and then have the packet routed to the transmit queue of the switch so I instead push the packets onto the 5th port (which is PDSP4). I am making use of the Pa_formatTxRoute command where I can specify the IPv4 header checksum as NULL, UDP as null and then set up the route and the command buffer and size and this too works as the size of the command is only 12 bytes long. Please note my TX descriptors are 64 bytes long, 32bytes of regular data plus 16 bytes of software info etc plus 16 bytes of PS data. So as the PS data is less than 16 bytes, this case works and I am able to capture the outgoing packets. However when I add the pktIpChksum command, the Pa_formatTxRoute returns a command that is larger than 16 bytes (24 bytes to be precise) it obviously cannot fit in the PS section overwriting the next descriptor. Now I could make this TX descriptors much larger like 96 or 128 bytes long but I am hoping I could make use of a suggestion in the multicore navigator user guide under programming consideration TIp2 which I have pasted below.
TIP2:
You must program a descriptor region with a fixed size, but you do not have to use every descriptor. As long as each descriptor is a multiple of the
programmed size (which itself is a multiple of 16 bytes), you can use contiguousdescriptors to create a single larger descriptor. The host must manage how it tracks the different sized descriptors.
I am also including my SendPacket function which is based on the SendPacket that is part of the multicore PA example project that comes with PDK. How can I go about making use of two descriptors as one. Some programming suggested steps would be useful i.e. Do I have to pop 2 descriptors etc. Alternatively can I have the PS information stored in the buffers pointed to by the descriptors i.e PD Word 4 in the descriptor as specified in the navigator user guide and does this ensure that the PS info is actually not transmitted as part of the packet but rather used by the PDSP4 to perform the checksum computation before routing to the switch for transmission.
Thanks, Aamir
--------------------------------------------------------------------------------------------
Int32 SendPacket (unsigned char* pucOutData, UInt32 dataBufferSize)
{
Cppi_HostDesc* pCppiDesc;
uint32_t key;
char psFlags = 0x1;
uint32_t cmdStack[(sizeof(pasahoNextRoute_t) + (2 * sizeof(pasahoComChkCrc_t))) / sizeof (uint32_t)];
UInt16 cmdSize = CMD_BUF_SIZE;
paRouteInfo_t route = { pa_DEST_EMAC, /* Route - host */
0, /* flow Id */
0, /* Queue */
-1, /* Multi route disabled */
0, /* SWInfo 0 */
0, /* SWInfo 1 */
0, /* customType : not used */
0, /* customIndex: not used */
0, /* pkyType: for SRIO only */
NULL}; /* No commands */
paReturn_t retVal;
//
retVal = Pa_formatTxRoute (
&pktIpChksum, /* IPv4 header checksum */
NULL, /* No second checksum */
&route, /* Internal routing */
(Ptr)(pasahoNextRoute_t *)cmdStack, /* Command buffer */
&cmdSize); /* Command size */
if (retVal != pa_OK) {
System_printf ("Pa_formatTxRoute returned error code %d\n", retVal);
return -1;
}
/* Get a free descriptor from the global free queue we setup
* during initialization.
*/
if ((pCppiDesc = Qmss_queuePop (gTxFreeQHnd)) == NULL)
{
System_printf ("No Tx free descriptor. Cant run send/rcv test \n");
return -1;
}
/* The descriptor address returned from the hardware has the
* descriptor size appended to the address in the last 4 bits.
*
* To get the true descriptor size, always mask off the last
* 4 bits of the address.
*/
pCppiDesc = (Ptr) ((UInt32) pCppiDesc & 0xFFFFFFF0);
/* Disable Interrupts */
key = Hwi_disable();
/* Cleanup the prefetch buffer also. */
CSL_XMC_invalidatePrefetchBuffer();
SYS_CACHE_INV (pCppiDesc, SIZE_HOST_DESC, CACHE_FENCE_WAIT);
Cppi_setData ( Cppi_DescType_HOST,
(Cppi_Desc *) pCppiDesc,
//(UInt8 *) Convert_CoreLocal2GlobalAddr((UInt32)pktMatch),
(UInt8 *) Convert_CoreLocal2GlobalAddr((UInt32)pucOutData),
dataBufferSize
);
Cppi_setPacketLen (Cppi_DescType_HOST, (Cppi_Desc *)pCppiDesc, dataBufferSize);
if (cpswLpbkMode != CPSW_LOOPBACK_NONE)
{
/* Force the packet to EMAC port 0 if loopback is enabled */
Cppi_setPSFlags(Cppi_DescType_HOST, (Cppi_Desc *)pCppiDesc, psFlags);
}
/* Clear PS Data */
Cppi_setPSLen (Cppi_DescType_HOST, (Cppi_Desc *)pCppiDesc, 0);
/* Attach the command in PS data */
Cppi_setPSData (Cppi_DescType_HOST, (Cppi_Desc *)pCppiDesc, (uint8_t *)cmdStack, cmdSize);
SYS_CACHE_WB (pCppiDesc, SIZE_HOST_DESC, CACHE_FENCE_WAIT);
/* Reenable Interrupts. */
Hwi_restore(key);
/* Send the packet out the mac. It will loop back to PA if the mac/switch
* have been configured properly
*/
//Qmss_queuePushDescSize (gPaTxQHnd[8], pCppiDesc, SIZE_HOST_DESC);
Qmss_queuePushDescSize (gPaTxQHnd[4], pCppiDesc, SIZE_HOST_DESC);
/* Increment the application transmit counter */
gTxCounter ++;
/* Give some time for the PA to process the packet */
CycleDelay (10000);
return 0;
}