1 /*
2 *
3 * Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com/
4 *
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *
10 * Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 *
13 * Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the
16 * distribution.
17 *
18 * Neither the name of Texas Instruments Incorporated nor the names of
19 * its contributors may be used to endorse or promote products derived
20 * from this software without specific prior written permission.
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
25 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
26 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
27 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
28 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
29 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
30 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
32 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 *
34 */
35 #include <stdio.h>
36 #include <stdint.h>
38 #include <xdc/runtime/System.h>
40 #include "pa1.h"
42 #include <ti/drv/pa/pa.h>
43 #include <ti/drv/cppi/cppi_drv.h>
44 #include <ti/drv/cppi/cppi_desc.h>
45 #include <ti/drv/qmss/qmss_drv.h>
47 /* Example test Packet*/
49 #pragma DATA_ALIGN(pktMatch, 16)
50 unsigned char pktMatch[] = {
51 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, /* Dest MAC */
52 0x00, 0xe0, 0xa6, 0x66, 0x57, 0x04, /* Src MAC */
53 0x08, 0x00, /* Ethertype = IPv4 */
54 0x45, 0x00, 0x00, 0x6c, /* IP version, services, total length */
55 0x00, 0x00, 0x00, 0x00, /* IP ID, flags, fragment offset */
56 0x05, 0x11, 0xa5, 0x97, /* IP ttl, protocol (UDP), header checksum */
57 0x9e, 0xda, 0x6d, 0x0a, /* Source IP address */
58 0x01, 0x02, 0x03, 0x04, /* Destination IP address */
59 0x12, 0x34, 0x05, 0x55, /* UDP source port, dest port */
60 0x00, 0x58, 0xe1, 0x98, /* UDP len, UDP checksum */
61 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, /* 80 bytes of payload data */
62 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 0x40, 0x41,
63 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49,
64 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51,
65 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59,
66 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, 0x60, 0x61,
67 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69,
68 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71,
69 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79,
70 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x80, 0x81 };
73 /* Send the Test Packet - Push to Q 640 or 648 */
74 Int sendPacket (void)
75 {
76 Cppi_HostDesc *hd;
77 Qmss_Queue q;
78 Int len4;
80 /* Pop a descriptor without a linked buffer */
81 hd = (Cppi_HostDesc *)(((Uint32)Qmss_queuePop (gvDescQ)) & ~0xf);
82 /* Setup the return for the descriptor */
83 q.qMgr = 0;
84 q.qNum = gvDescQ;
85 Cppi_setReturnQueue (Cppi_DescType_HOST, (Cppi_Desc *)hd, q);
87 len4 = sizeof(pktMatch);
88 Cppi_setData (Cppi_DescType_HOST, (Cppi_Desc *)hd, (Uint8 *)gAddr((Uint32)pktMatch), len4);
89 Cppi_setPacketLen (Cppi_DescType_HOST, (Cppi_Desc *)hd, len4);
91 /* Send the packet out the mac. It will loop back to PA if the mac/switch have been
92 * configured properly */
93 if(cpswLpbkMode == CPSW_LOOPBACK_PA)
94 Qmss_queuePush (gvTxQ[0], hd, len4, CONFIG_SIZE_DESC, Qmss_Location_TAIL);
95 else
96 Qmss_queuePush (gvTxQ[8], hd, len4, CONFIG_SIZE_DESC, Qmss_Location_TAIL);
98 /* Give some time for the PA to process the packet */
99 CycleDelay (10000);
101 return (0);
102 }
105 /* Check if the packet goes through MAC, OuterIP and UDP classification and reaches the intended Receive Q- destination Q*/
107 Int findPacket (void)
108 {
109 Cppi_HostDesc *hd;
110 Uint8 *uc;
111 Int i;
112 Int j;
114 /* Wait for a data packet from PA */
115 for (j = 0; j < 100; j++) {
116 CycleDelay (1000);
118 if (Qmss_getQueueEntryCount (gvRxPktQ[0]) > 0) {
119 hd = (Cppi_HostDesc *)(((Uint32)Qmss_queuePop (gvRxPktQ[0])) & ~0xf);
121 if (hd->softwareInfo0 != CONFIG_RCV_PKT_ID) {
122 //printf ("function findPacket: Found an entry in receive queue with swinfo0 = 0x%08x, expected 0x%08x\n",
123 // hd->softwareInfo0, CONFIG_RCV_PKT_ID);
124 System_printf("\r\nFound an entry in receive queue with swinfo0 wrong");
125 hd->buffLen = hd->origBufferLen;
126 Qmss_queuePush (gvRxBufQ, (Ptr)hd, hd->buffLen, CONFIG_SIZE_DESC, Qmss_Location_TAIL);
128 return (-1);
129 }
131 /* See if the packet matches */
132 uc = (Uint8 *)hd->buffPtr;
133 for (i = 0; i < sizeof (pktMatch); i++) {
134 if (pktMatch[i] != uc[i]) {
135 //printf ("function findPacket: Byte %d expected 0x%02x, found 0x%02x\n", i, pktMatch[i], uc[i]);
136 //System_flush();
137 hd->buffLen = hd->origBufferLen;
138 Qmss_queuePush (gvRxBufQ, (Ptr)hd, hd->buffLen, CONFIG_SIZE_DESC, Qmss_Location_TAIL);
139 return (-1);
140 }
141 }
143 // System_printf ("function findPacket: Correct packet found\n");
144 // System_printf("\r\n\ function findPacket: Correct packet found");
146 /* Reset the buffer lenght and put the descriptor back on the free queue */
147 hd->buffLen = hd->origBufferLen;
148 Qmss_queuePush (gvRxBufQ, (Ptr)hd, hd->buffLen, CONFIG_SIZE_DESC, Qmss_Location_TAIL);
150 break;
151 }
152 }
154 if (j == 100) {
155 // printf ("function findPacket: Timeout waiting for data packet\n");
156 return (-1);
157 }
159 return (0);
160 }
163 Int getPaStats (void)
164 {
165 Cppi_HostDesc *hd;
166 Qmss_Queue q;
168 Uint16 csize;
169 paReturn_t paret;
170 paCmdReply_t reply = CONFIG_PACOM_REPLY;
171 Int cmdDest;
173 paSysStats_t *stats;
175 Int j;
176 Uint32 myswinfo[] = { 0x11112222, 0x33334444 };
177 Uint32 psCmd = ((Uint32)(4 << 5) << 24); /* Command word - will be moved to common pa/sa file */
179 hd = (Cppi_HostDesc *)(((Uint32)Qmss_queuePop (gvRxBufQ)) & ~0xf);
180 q.qMgr = 0;
181 q.qNum = gvPaTxRecycleQ;
182 Cppi_setReturnQueue (Cppi_DescType_HOST, (Cppi_Desc *)hd, q);
184 csize = hd->buffLen;
185 reply.replyId = CONFIG_PA_CMD_REPLY_ID;
187 paret = Pa_requestStats (paInst,
188 TRUE,
189 (paCmd_t) hd->buffPtr,
190 &csize,
191 &reply,
192 &cmdDest);
194 if (paret != pa_OK) {
195 printf ("function getPaStats: call to Pa_requestStats returned error code %d\n", paret);
196 return (-1);
197 }
199 /* This sets the extended info for descriptors, and this is required so PS info
200 * goes to the right spot */
201 Cppi_setSoftwareInfo (Cppi_DescType_HOST, (Cppi_Desc *)hd, (Uint8 *)myswinfo);
203 /* Set the buffer length to the size used. It will be restored when the descriptor
204 * is returned */
205 Cppi_setPacketLen (Cppi_DescType_HOST, (Cppi_Desc *)hd, csize);
206 hd->buffLen = csize;
208 /* Mark the packet as a configuration packet */
209 Cppi_setPSData (Cppi_DescType_HOST, (Cppi_Desc *)hd, (Uint8 *)&psCmd, 4);
211 /* Send the request to the PA */
212 Qmss_queuePush (gvTxQ[cmdDest - pa_CMD_TX_DEST_0], (Uint32 *)gAddr((Uint32)hd), csize, CONFIG_SIZE_DESC, Qmss_Location_TAIL);
214 CycleDelay (100000);
216 /* wait for return buffer */
217 for (j = 0; j < 100; j++) {
218 CycleDelay (1000);
220 if (Qmss_getQueueEntryCount (gvPaTxRecycleQ) > 0) {
221 hd = (Cppi_HostDesc *)(((Uint32)Qmss_queuePop (gvPaTxRecycleQ)) & ~0xf);
222 /* Reset the buffer lenght and put the descriptor back on the free queue */
223 hd->buffLen = hd->origBufferLen;
224 Qmss_queuePush (gvRxBufQ, hd, hd->buffLen, CONFIG_SIZE_DESC, Qmss_Location_TAIL);
225 break;
226 }
227 }
229 if (j == 100) {
230 // printf ("function getPaStats: Timeout waiting for return buffer from complete queue to Pa_addIp command\n");
231 return (-1);
232 }
234 /* Wait for the PA to return a response */
235 for (j = 0; j < 100; j++) {
236 CycleDelay (1000);
238 if (Qmss_getQueueEntryCount (gvPaRespQ) > 0) {
239 hd = (Cppi_HostDesc *)(((Uint32)Qmss_queuePop (gvPaRespQ)) & ~0xf);
241 if (hd->softwareInfo0 != reply.replyId) {
242 // printf ("function getPaStats: Found an entry in PA reply queue with swinfo0 = 0x%08x, expected 0x%08x\n",
243 //hd->softwareInfo0, reply.replyId);
244 hd->buffLen = hd->origBufferLen;
245 Qmss_queuePush (gvRxBufQ, hd, hd->buffLen, CONFIG_SIZE_DESC, Qmss_Location_TAIL);
247 return (-1);
248 }
251 stats = (paSysStats_t *)Pa_formatStatsReply (paInst, (paCmd_t)hd->buffPtr);
252 if (stats == NULL) {
253 //printf ("function getPaStats: Pa_formatStats returned invalid stats\n");
254 hd->buffLen = hd->origBufferLen;
255 Qmss_queuePush (gvRxBufQ, hd, hd->buffLen, CONFIG_SIZE_DESC, Qmss_Location_TAIL);
256 return (-1);
257 }
259 hd->buffLen = hd->origBufferLen;
260 Qmss_queuePush (gvRxBufQ, hd, hd->buffLen, CONFIG_SIZE_DESC, Qmss_Location_TAIL);
262 break;
263 }
264 }
266 return (0);
267 }