]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - processor-sdk/pdk.git/blob - packages/ti/drv/pa/fw/v0/classify2.p
pa-lld: add to PDK
[processor-sdk/pdk.git] / packages / ti / drv / pa / fw / v0 / classify2.p
1 // *********************************************************************************************************\r
2 // * FILE PURPOSE: Perform packet classification on PDSPS with a LUT2\r
3 // *********************************************************************************************************\r
4 // * FILE NAME: classify2.p\r
5 // *\r
6 // * DESCRIPTION: The PDSP code for L4 classification using a LUT2\r
7 // *\r
8 // *********************************************************************************************************/\r
9 //\r
10 //\r
11 //  TEXAS INSTRUMENTS TEXT FILE LICENSE\r
12 // \r
13 //   Copyright (c) 2016 Texas Instruments Incorporated\r
14 // \r
15 //  All rights reserved not granted herein.\r
16 //  \r
17 //  Limited License.  \r
18 // \r
19 //  Texas Instruments Incorporated grants a world-wide, royalty-free, non-exclusive \r
20 //  license under copyrights and patents it now or hereafter owns or controls to \r
21 //  make, have made, use, import, offer to sell and sell ("Utilize") this software \r
22 //  subject to the terms herein.  With respect to the foregoing patent license, \r
23 //  such license is granted  solely to the extent that any such patent is necessary \r
24 //  to Utilize the software alone.  The patent license shall not apply to any \r
25 //  combinations which include this software, other than combinations with devices \r
26 //  manufactured by or for TI (\93TI Devices\94).  No hardware patent is licensed hereunder.\r
27 // \r
28 //  Redistributions must preserve existing copyright notices and reproduce this license \r
29 //  (including the above copyright notice and the disclaimer and (if applicable) source \r
30 //  code license limitations below) in the documentation and/or other materials provided \r
31 //  with the distribution.\r
32 //  \r
33 //  Redistribution and use in binary form, without modification, are permitted provided \r
34 //  that the following conditions are met:\r
35 //      No reverse engineering, decompilation, or disassembly of this software is \r
36 //   permitted with respect to any software provided in binary form.\r
37 //      Any redistribution and use are licensed by TI for use only with TI Devices.\r
38 //      Nothing shall obligate TI to provide you with source code for the software \r
39 //   licensed and provided to you in object code.\r
40 //  \r
41 //  If software source code is provided to you, modification and redistribution of the \r
42 //  source code are permitted provided that the following conditions are met:\r
43 //      Any redistribution and use of the source code, including any resulting derivative \r
44 //   works, are licensed by TI for use only with TI Devices.\r
45 //      Any redistribution and use of any object code compiled from the source code\r
46 //   and any resulting derivative works, are licensed by TI for use only with TI Devices.\r
47 // \r
48 //  Neither the name of Texas Instruments Incorporated nor the names of its suppliers \r
49 //  may be used to endorse or promote products derived from this software without \r
50 //  specific prior written permission.\r
51 // \r
52 //  DISCLAIMER.\r
53 // \r
54 //  THIS SOFTWARE IS PROVIDED BY TI AND TI\92S LICENSORS "AS IS" AND ANY EXPRESS OR IMPLIED \r
55 //  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY \r
56 //  AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL TI AND TI\92\r
57 //  LICENSORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR \r
58 //  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE \r
59 //  GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER \r
60 //  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT \r
61 //  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, \r
62 //  EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
63 // \r
64 // \r
65 //\r
66 \r
67 #define PDSP_CLASSIFY2  1\r
68 #include "pdsp_pa.h"\r
69 #include "pdsp_mem.h"\r
70 #include "pdsp_subs.h"\r
71 #include "pm_config.h"\r
72 #include "pdsp_ver.h"\r
73 #include "pm_constants.h"\r
74 #include "parsescope.h"\r
75 \r
76 #define PASS_PROC_LUT2\r
77 #define PASS_PROC_PKT_FORWARD\r
78 \r
79 #define HEADER_MAGIC   0xBABE0002                    // PASS classify2\r
80 #define PASS_C2_VER    PASS_VERSION                  // 0x01.0x00.0x00.0x03\r
81 \r
82     .origin      0\r
83     .entrypoint  f_c2Init\r
84 \r
85 f_c2Init:\r
86     jmp f_c2Start\r
87     \r
88 header:\r
89     .codeword  HEADER_MAGIC\r
90     .codeword  PASS_C2_VER\r
91 \r
92     .using  globalScopeC2\r
93 \r
94 #ifdef PASS_GLOBAL_INIT\r
95 \r
96 #include "meminit.p"\r
97 \r
98 #endif\r
99 \r
100 \r
101 f_c2Start:\r
102 \r
103     call  f_c2LocalInit\r
104 \r
105     // Clear the mailbox \r
106     zero &r2, 12\r
107     sbco r2, FIRMWARE_MBOX, 4, 12 \r
108 \r
109     // Write a non-zero value to mailbox slot 0. \r
110     mov   r2, 1\r
111     sbco  r2, FIRMWARE_MBOX, 0, 4\r
112 \r
113         // Wait for the set command to take hold\r
114     wbs  s_flags.info.tStatus_Command0\r
115 \r
116     // The host will clear mailbox slot 0 when it is ready for this PDSP to run\r
117     wbc  s_flags.info.tStatus_Command0\r
118 \r
119 #ifdef PASS_GLOBAL_INIT\r
120 \r
121     // Do common initialization if the host has requested it\r
122     // The host requests a global init by writing a non-zero value into mailbox slot 1\r
123     // (Before clearing mailbox slot 0)\r
124     qbbc  l_c2Start0,  s_flags.info.tStatus_Command1\r
125 \r
126       call f_commonInit\r
127       mov  r2, 0\r
128       sbco r2, FIRMWARE_MBOX, 4, 4      // Clear the mailbox\r
129 #endif\r
130 \r
131 l_c2Start0:\r
132 \r
133     zero  &s_runCxt,       SIZE(s_runCxt)\r
134     zero  &s_statsFlags,   SIZE(s_statsFlags)\r
135 \r
136     // Store the PDSP ID\r
137     lbco  s_runCxt.pdspId,  PAMEM_CONST_PDSP_INFO,  OFFSET_ID, 1\r
138     \r
139     // Store the version number\r
140     mov   r2.w0,   PASS_C2_VER & 0xFFFF\r
141     mov   r2.w2,   PASS_C2_VER >> 16 \r
142     sbco  r2,   PAMEM_CONST_PDSP_INFO,  OFFSET_VER,     4    \r
143 \r
144 \r
145 // *****************************************************************************************\r
146 // * FUNCTION PURPOSE: The main processing loop\r
147 // *****************************************************************************************\r
148 // * DESCRIPTION: The packet processing state machine\r
149 // *\r
150 // *        Register usage:\r
151 // *\r
152 // *   R0:\r
153 // *   R1:\r
154 // *   R2:\r
155 // *   R3:\r
156 // *   R4:\r
157 // *   R5:\r
158 // *   R6:\r
159 // *   R7:\r
160 // *   R8:\r
161 // *   R9:\r
162 // *   R10:\r
163 // *   R11:\r
164 // *   R12:\r
165 // *   R13:\r
166 // *   R14:\r
167 // *   R15:\r
168 // *   R16:\r
169 // *   R17:\r
170 // *   R18:\r
171 // *   R19:\r
172 // *   R20:\r
173 // *   R21:\r
174 // *   R22:\r
175 // *   R23:\r
176 // *   R24:\r
177 // *   R25:\r
178 // *   R26:  \r
179 // *   R27:\r
180 // *   R28:  statistics  (s_statsFlags)                             -\r
181 // *   R29:  c2RunContext (s_runCxt)                              -  Global Scope\r
182 // *   R30:  w2-unused     w0-function return address               -\r
183 // *   R31:  System Flags (s_flags)                                 -\r
184 // *\r
185 // ***********************************************************************************\r
186 \r
187 \r
188 f_mainLoop:\r
189 fci_mainLoop7:  // For compatibility with classify1.p\r
190 \r
191   qbeq  f_mainLoop0, s_statsFlags.event,  0\r
192       sbco   s_statsFlags.event, cStatistics,       OFFSET_STATS_FLAGS, 4\r
193       zero  &s_statsFlags,       SIZE(s_statsFlags)\r
194 \r
195 f_mainLoop0:\r
196 \r
197   qbbc  f_mainLoop,  s_flags.info.tStatus_CDENewPacket\r
198 \r
199 //      Fall through to f_c2Parse\r
200   \r
201 // **************************************************************************************\r
202 // * FUNCTION PURPOSE: Begin parsing a packet\r
203 // **************************************************************************************\r
204 // * DESCRIPTION: A new packet ID is assigned and a packet parse is begun\r
205 // *\r
206 // *   Register Usage:  \r
207 // * \r
208 // *   R0:    \r
209 // *   R1:    \r
210 // *   R2:      \r
211 // *   R3:  \r
212 // *   R4:    |  CDE commands     -  cdeScope\r
213 // *   R5:    |                   -\r
214 // *   R6:        |\r
215 // *   R7:        |\r
216 // *   R8:        |\r
217 // *   R9:        |  \r
218 // *   R10:       |\r
219 // *   R11:       |\r
220 // *   R12:       |\r
221 // *   R13:       |\r
222 // *   R14:          |                                            \r
223 // *   R15:          |                                            \r
224 // *   R16:          |                                            \r
225 // *   R17:          |  \r
226 // *   R18:          |\r
227 // *   R19:          |\r
228 // *   R20:          |\r
229 // *   R21:          |\r
230 // *   R22:     |     \r
231 // *   R23:     |  Packet context - pktScope   \r
232 // *   R24:     |\r
233 // *   R25:     |\r
234 // *   R26:     |  w0(scratch) - Packet ID\r
235 // *   R27:\r
236 // *   R28:  statistics  (s_statsFlags)                             -\r
237 // *   R29:  c2RunContext (s_runCxt)                                -  Global Scope\r
238 // *   R30:  w2 - param.action w0-function return address              -\r
239 // *   R31:  System Flags (s_flags)                                 -\r
240 // *\r
241 // ****************************************************************************************\r
242 \r
243     .using  pktScope\r
244     .using  cdeScope\r
245     .using  currentFwdScope\r
246 \r
247 f_c2Parse:\r
248 \r
249     set  s_statsFlags.event.t_nPacketsC2\r
250 \r
251     // packet counter\r
252         lbco  r1, FIRMWARE_MBOX, 0, 4\r
253         add   r1, r1, 1\r
254         sbco  r1, FIRMWARE_MBOX, 0, 4\r
255 \r
256     xin  XID_CDEDATA,  s_pktDescr,  SIZE(s_pktDescr)\r
257 \r
258     // Only configuration packets should arrive without a packet ID,\r
259     // but go ahead and do the assignement in any case\r
260     qbbs  l_c2Parse3,  s_pktDescr.pktId.t_pktIdAllocated\r
261 \r
262 l_c2Parse2:\r
263 \r
264     // Have a new packet ID. Set the alloc bit\r
265     set  s_pktDescr.pktId,   r1.t_pktIdAllocated\r
266     xout XID_CDEDATA,        s_pktDescr,           SIZE(s_pktDescr)\r
267 \r
268 \r
269 l_c2Parse3:\r
270 \r
271     // There must be a command in the control section for packets\r
272     qbne  l_c1Parse3b,  s_pktDescr.ctrlDataSize, 0\r
273 \r
274 l_c1Parse3a:\r
275       //    Load the error routing info for this error type\r
276       //    There was invalid data in the packet context. Record a system error\r
277       //    and route the packet as a system error packet.\r
278       and   s_pktCxt2.eP1C2Id,  s_pktCxt2.eP1C2Id,  NOT_PKT2_EIDX_MASK\r
279       or    s_pktCxt2.eP1C2Id,  s_pktCxt2.eP1C2Id,  EROUTE_SYSTEM_FAIL << PKT2_EIDX_SHIFT\r
280       \r
281       set    s_statsFlags.event.t_nInvalidControlC2\r
282       \r
283       jmp    f_c2ForwardErr\r
284 \r
285 l_c1Parse3b:\r
286 \r
287     // Advance to the control section to read the packet context\r
288     mov  s_cdeCmdWd.operation,   CDE_CMD_ADVANCE_TO_CONTROL\r
289     xout XID_CDECTRL,            s_cdeCmdWd,            4\r
290 \r
291     // Insert 32 bytes of PS info\r
292     // This is legal even though the window has advanced to control\r
293     //mov s_cdeInsert.operation,  CDE_CMD_INSERT_PSDATA\r
294     //mov s_cdeInsert.byteCount,  32\r
295     ldi r4,     CDE_CMD_INSERT_PSDATA | (32 << 8)\r
296     xout XID_CDECTRL,           s_cdeCmdWd,             4\r
297 \r
298 \r
299 l_c2Parse4:\r
300 \r
301     // Read in the whole packet context.\r
302     // There is no cost if this is not a data packet\r
303     xin  XID_CDEDATA,      s_pktCxt,           SIZE(s_pktCxt)\r
304 \r
305     // extract the command ID\r
306     lsr  r1.b0,  s_pktCxt.paCmdId_Length, SUBS_CMD_WORD_ID_SHIFT\r
307 \r
308     qbeq l_c2Parse6,        r1.b0,  PSH_CMD_PA_RX_PARSE\r
309     qbeq f_paConfigure,     r1.b0,  PSH_CMD_CONFIG\r
310 \r
311 l_c2Parse5:\r
312     set  s_statsFlags.event.t_nSilentDiscardC2\r
313     mov  s_cdeCmdPkt.operation,  CDE_CMD_PACKET_FLUSH\r
314     xout XID_CDECTRL,            s_cdeCmdPkt,           SIZE(s_cdeCmdPkt)\r
315     jmp f_mainLoop\r
316 \r
317 \r
318 l_c2Parse6:\r
319 \r
320     // The next header type is stored in 8 bit format during the parse\r
321     and  s_next.Hdr,  s_pktCxt2.hdrBitmask2_nextHdr,  0x1f\r
322 \r
323     // Clear any values in the error index if not custom\r
324     qbeq l_c2Parse7,    s_next.Hdr,   PA_HDR_CUSTOM_C2  \r
325     and  s_pktCxt2.eP1C2Id,  s_pktCxt2.eP1C2Id,  NOT_PKT2_EIDX_MASK\r
326 \r
327 l_c2Parse7:\r
328 \r
329     // Delete the control info. It will be replaced with new data\r
330     // in protocol specific when the packet is forwarded\r
331     //mov  s_cdeCmdWd.operation,  CDE_CMD_FLUSH_TO_PACKET\r
332     //xout XID_CDECTRL,           s_cdeCmdWd,              SIZE(s_cdeCmdWd)\r
333     // Delete only the pktCxt from the control info\r
334     mov  s_cdeCmdWd.operation,  CDE_CMD_FLUSH\r
335     mov  s_cdeCmdWd.byteCount,  (SIZE(s_pktCxt) + 7) & 0xf8     // Round up to multiple of 8 bytes\r
336     xout XID_CDECTRL,           s_cdeCmdWd,                 4\r
337      \r
338     mov   s_cdeCmdWd.operation,  CDE_CMD_ADVANCE_TO_PACKET \r
339     xout  XID_CDECTRL,           s_cdeCmdWd,                4\r
340 \r
341     // Advance the CDE to the first byte to examine in the packet\r
342     mov  s_cdeCmdWd.operation,  CDE_CMD_WINDOW_ADVANCE\r
343     mov  s_cdeCmdWd.byteCount,  s_pktCxt.startOffset\r
344     xout XID_CDECTRL,           s_cdeCmdWd,              SIZE(s_cdeCmdWd)\r
345 \r
346     mov  s_param.action,   SUBS_ACTION_PARSE\r
347 \r
348     qbne  l_c2Parse8,  s_next.hdr,  PA_HDR_ESP_DECODED\r
349         // Extract nextHdr from ESP Trailer\r
350         //mov s_next.hdr,  PA_HDR_ESP_DECODED_C2\r
351         call f_c2ParseEspDec\r
352         \r
353         // pass through\r
354 \r
355 l_c2Parse8:\r
356     qbge  l_c2Parse9,    s_next.hdr,  PA_HDR_UNKNOWN\r
357     qbge  l_c2Parse10,   s_next.hdr,  PA_HDR_CUSTOM_C2\r
358 \r
359 l_c2Parse9:\r
360 \r
361         // The header type was not valid for classify2\r
362         // The header type can not be processed by classify2, use next fail route\r
363         // Note: It is not a parsing error exception\r
364         // Need a return address\r
365         mov r30.w0, f_mainLoop\r
366         // store innerIP offset\r
367         mov  s_pktCxt6.l3offset2,  s_pktCxt6.l3l5Offset\r
368         \r
369         // Put the next header type back into the context\r
370         and  s_pktCxt2.hdrBitmask2_nextHdr, s_pktCxt2.hdrBitmask2_nextHdr, 0xe0\r
371         or   s_pktCxt2.hdrBitmask2_nextHdr, s_pktCxt2.hdrBitmask2_nextHdr, s_next.Hdr\r
372         \r
373         // Patch the context back to the packet\r
374         wbs   s_flags.info.tStatus_CDEOutPacket\r
375         sbco  s_pktCxt, cCdeOutPkt,  SIZE(s_pktDescr),  SIZE(s_pktCxt)\r
376         jmp  f_c2ForwardNoMatch\r
377         \r
378     // The main loop\r
379     // Multiple parses are only possible because a UDP parse can\r
380     // trigger a change into other type\r
381 \r
382 l_c2Parse10:\r
383 \r
384     //\r
385     //  General Error check to avoid infinite loop\r
386     //\r
387     qblt l_c2Parse10_1,  s_pktCxt.endOffset, s_pktCxt.startOffset\r
388         mov s_pktCxt2.eP1C2Id,  EROUTE_PARSE_FAIL << PKT2_EIDX_SHIFT \r
389         mov s_param.action,          SUBS_ACTION_EXIT\r
390         jmp l_c2Parse11_1\r
391      \r
392 l_c2Parse10_1:\r
393     lsl   r0.b0,       s_next.Hdr,         1\r
394     lbco  r0.w2,       PAMEM_CONST_PARSE,  r0.b0,             2\r
395     call  r0.w2\r
396     qbeq  l_c2Parse10,  s_param.action,     SUBS_ACTION_PARSE\r
397 \r
398 l_c2Parse11:\r
399 \r
400   // Put the next header type back into the context\r
401   and  s_pktCxt2.hdrBitmask2_nextHdr, s_pktCxt2.hdrBitmask2_nextHdr, 0xe0\r
402   or   s_pktCxt2.hdrBitmask2_nextHdr, s_pktCxt2.hdrBitmask2_nextHdr, s_next.Hdr\r
403   \r
404 l_c2Parse11_1:\r
405   // Patch the context back to the packet\r
406   wbs   s_flags.info.tStatus_CDEOutPacket\r
407   sbco  s_pktCxt, cCdeOutPkt,  SIZE(s_pktDescr),  SIZE(s_pktCxt)\r
408 \r
409   qbne  l_c2Parse12,  s_param.action,  SUBS_ACTION_LOOKUP\r
410 \r
411       // The lookup was initiated in the parse. Wait for the lookup to complete\r
412       // Should there be a timeout here?\r
413       wbc  s_flags.info.tStatus_Lut2LookupBusy\r
414 \r
415       // Forward the results\r
416       // Need a return address\r
417       mov r30.w0, f_mainLoop\r
418       qbbs f_c2ForwardMatch,  s_flags.info.tStatus_Lut2MatchData\r
419       jmp  f_c2ForwardNoMatch\r
420 \r
421   \r
422   l_c2Parse12:\r
423     // Exception handling \r
424     // No Lookup required. Forward the packet based on the exception index, which must be\r
425     // loaded into r30.w2\r
426     // Load the error routing information\r
427     lsr   r30.w2,  s_pktCxt2.eP1C2Id,  PKT2_EIDX_SHIFT\r
428     lsl   r30.w2,         r30.w2,              4\r
429     lbco  s_curFmPlace,   PAMEM_CONST_EROUTE,  r30.w2,   SIZE(s_curFmPlace)\r
430 \r
431     // f_curPktForward needs which discard stat to set (classify1 or classify2)\r
432     zero &r3,  4\r
433     set   r3.t_nSilentDiscardC2\r
434 \r
435     // Need a return address\r
436     mov r30.w0, f_mainLoop\r
437     jmp f_curPktForward\r
438     \r
439   \r
440     .leave currentFwdScope\r
441     .leave pktScope\r
442     .leave cdeScope\r
443 \r
444 // ***************************************************************************************\r
445 // * FUNCTION PURPOSE: Forward a packet that matched LUT2 lookup\r
446 // ***************************************************************************************\r
447 // * DESCRIPTION: The forwarding information from the table is used to forward \r
448 // *              the packet\r
449 // *\r
450 // *   Register Usage:  \r
451 // * \r
452 // *   R0:\r
453 // *   R1:    \r
454 // *   R2:    \r
455 // *   R3:       |  bit mask for stat to update on silent discard\r
456 // *   R4:    |  CDE commands     -  cdeScope\r
457 // *   R5:    |                   -\r
458 // *   R6:          |\r
459 // *   R7:          |  Current Packet Forwarding info\r
460 // *   R8:          |\r
461 // *   R9:          |\r
462 // *   R10:     \r
463 // *   R11:     \r
464 // *   R12:     \r
465 // *   R13:                                                                    -\r
466 // *   R14:\r
467 // *   R15:\r
468 // *   R16:\r
469 // *   R17:\r
470 // *   R18:\r
471 // *   R19:\r
472 // *   R20:\r
473 // *   R21:\r
474 // *   R22:     |     \r
475 // *   R23:     |  Packet context - pktScope   \r
476 // *   R24:     |\r
477 // *   R25:     |\r
478 // *   R26:  Packet ID\r
479 // *   R27:\r
480 // *   R28:  statistics  (s_statsFlags)                             -\r
481 // *   R29:  c2RunContext (s_runCxt)                                -  Global Scope\r
482 // *   R30:  w2-Error Index w0-function return address              -\r
483 // *   R31:  System Flags (s_flags)                                 -\r
484 // *\r
485 // **************************************************************************************\r
486 \r
487     .using  cdeScope\r
488     .using  currentFwdScope\r
489     .using  pktScope\r
490 \r
491 f_c2ForwardMatch:\r
492 \r
493     // Get the match info\r
494     xin  XID_LUT2DATA,   s_curFmPlace,  SIZE(s_curFmPlace)\r
495 \r
496     // Set the bitmask for silent discard (credit to classify2)\r
497     zero &r3,  4\r
498     set   r3.t_nSilentDiscardC2\r
499 \r
500     mov r30.w0,  f_mainLoop  // return address\r
501     jmp f_curPktForward\r
502 \r
503     \r
504     .leave cdeScope\r
505     .leave currentFwdScope\r
506     .leave pktScope\r
507 \r
508 \r
509 // **************************************************************************************\r
510 // * FUNCTION PURPOSE: Forward a packet that did not match\r
511 // **************************************************************************************\r
512 // * DESCRIPTION: On match fail the packet is forwarded if previous match information\r
513 // *              is available, otherwise it is discarded.\r
514 // *\r
515 // *   Register Usage:  \r
516 // * \r
517 // *   R0:\r
518 // *   R1:    \r
519 // *   R2:    \r
520 // *   R3:       |  bit mask for stat to update on silent discard\r
521 // *   R4:\r
522 // *   R5:\r
523 // *   R6:          |\r
524 // *   R7:          |  Current Packet Forwarding info\r
525 // *   R8:          |\r
526 // *   R9:          |\r
527 // *   R10:     \r
528 // *   R11:     \r
529 // *   R12:     \r
530 // *   R13:\r
531 // *   R14:\r
532 // *   R15:\r
533 // *   R16:\r
534 // *   R17:\r
535 // *   R18:\r
536 // *   R19:\r
537 // *   R20:\r
538 // *   R21:\r
539 // *   R22:     |     \r
540 // *   R23:     |  Packet context - pktScope   \r
541 // *   R24:     |\r
542 // *   R25:     |\r
543 // *   R26:  Packet ID\r
544 // *   R27:\r
545 // *   R28:  statistics  (s_statsFlags)                             -\r
546 // *   R29:  c2RunContext (s_runCxt)                                -  Global Scope\r
547 // *   R30:  w2-Error Index w0-function return address              -\r
548 // *   R31:  System Flags (s_flags)                                 -\r
549 // *\r
550 // **************************************************************************************\r
551 \r
552     .using pktScope\r
553     .using currentFwdScope\r
554     .using  lut1MatchScope\r
555 \r
556 f_c2ForwardNoMatch:\r
557 \r
558     // Must read the match data even if there was no match - to re-enable the LUT2 search\r
559     xin  XID_LUT2DATA,   s_curFmPlace,  SIZE(s_curFmPlace)\r
560     qbbc l_c2ForwardNoMatch_NotGTPU, s_pktCxt.hdrBitmask_nextHdr.SUBS_PA_BIT_HEADER_GTPU\r
561     and  s_pktCxt2.eP1C2Id,       s_pktCxt2.eP1C2Id,   NOT_PKT2_EIDX_MASK\r
562     or   s_pktCxt2.eP1C2Id,       s_pktCxt2.eP1C2Id,   EROUTE_GTPU_MATCH_FAIL << PKT2_EIDX_SHIFT\r
563     sbco s_pktCxt2.eP1C2Id,       cCdeOutPkt,    SIZE(s_pktDescr) + OFFSET(s_pktCxt2.eP1C2Id), SIZE(s_pktCxt2.eP1C2Id)\r
564     \r
565     mov r1.w0,  EROUTE_GTPU_MATCH_FAIL * 16\r
566 \r
567     lbco  s_curFmPlace,  PAMEM_CONST_EROUTE,  r1.w0,  SIZE(s_curFmPlace)\r
568     // prepare r1.w0, load the exception route\r
569     // check to see if discard\r
570     // true then jump to notgtpu\r
571     // false then \r
572 \r
573     qbeq l_c2ForwardNoMatch_NotGTPU, s_curFwd.forwardType, PA_FORWARD_TYPE_DISCARD\r
574     \r
575     jmp  l_c2ForwardErr_2\r
576 \r
577 l_c2ForwardNoMatch_NotGTPU:\r
578     qbbs  l_c2ForwardNoMatch0,  s_pktCxt.eP1C2IdIdx.t_pl1Match\r
579 \r
580         // No previous match indicated. Set the error field and route based on the error\r
581         and s_pktCxt2.eP1C2Id,  s_pktCxt2.eP1C2Id,  NOT_PKT2_EIDX_MASK\r
582         or  s_pktCxt2.eP1C2Id,  s_pktCxt2.eP1C2Id,  EROUTE_LUT2_FAIL << PKT2_EIDX_SHIFT\r
583 \r
584         jmp f_c2ForwardErr\r
585 \r
586 \r
587 l_c2ForwardNoMatch0:\r
588 \r
589         // Use the previous lut1 match info to forward the packet\r
590         // Extract the LUT1 index number, multiply by 32 to get memory offset\r
591         and  r1.w0,  s_pktCxt2.IdIdx,      L1IDX_MASK   \r
592         lsl  r1.w0,  r1.w0,                6\r
593         set  r1.w0,  12                                                 // add offset 0x1000\r
594         add  r1.w0,  r1.w0,                SIZE(s_fmPlace)+SIZE(s_l1f)  // Offset to next fail info\r
595 \r
596         // Extract the PDSP number\r
597         lsr  r1.w2,  s_pktCxt.eP1C2IdIdx,  SUBS_PKT_CXT_L1ID_BIT_OFFSET\r
598         and  r1.w2,  r1.w2,                SUBS_PKT_CXT_L1ID_SHIFTED_MASK\r
599 \r
600         // Store the stat for silent discard\r
601         zero  &r3,  4\r
602         set    r3.t_nSilentDiscardC2\r
603 \r
604         // Load the routing info\r
605         qbne  l_c2ForwardNoMatch1,  r1.w2,  0\r
606             lbco  s_curFmPlace,  PAMEM_CONST_PDSP0_LUT1_BASE,  r1.w0,  SIZE(s_curFmPlace)\r
607             jmp   f_curPktForward\r
608 \r
609 l_c2ForwardNoMatch1:\r
610 \r
611         qbne  l_c2ForwardNoMatch2,  r1.w2,  1\r
612             lbco  s_curFmPlace,  PAMEM_CONST_PDSP1_LUT1_BASE,  r1.w0,  SIZE(s_curFmPlace)\r
613             jmp   f_curPktForward\r
614 \r
615 l_c2ForwardNoMatch2:\r
616 \r
617         qbne  l_c2ForwardNoMatch3,  r1.w2,  2\r
618             lbco  s_curFmPlace,  PAMEM_CONST_PDSP2_LUT1_BASE,  r1.w0,  SIZE(s_curFmPlace)\r
619             jmp   f_curPktForward\r
620 \r
621 \r
622 l_c2ForwardNoMatch3:\r
623 \r
624         // There was invalid data in the packet context. Record a system error\r
625         // and route the packet as a system error packet.\r
626         and  s_pktCxt2.eP1C2Id,  s_pktCxt2.eP1C2Id,  NOT_PKT2_EIDX_MASK\r
627         or   s_pktCxt2.eP1C2Id,  s_pktCxt2.eP1C2Id,  EROUTE_SYSTEM_FAIL << PKT2_EIDX_SHIFT\r
628 \r
629             jmp f_c2ForwardErr\r
630 \r
631 \r
632     .leave lut1MatchScope\r
633     .leave pktScope\r
634     .leave currentFwdScope\r
635 \r
636 \r
637 // ********************************************************************************************\r
638 // * FUNCTION PURPOSE: Forward a packet based on the error index information\r
639 // ********************************************************************************************\r
640 // * DESCRIPTION: The error index is used to extract the routing information and forward\r
641 // *              the packet\r
642 // *\r
643 // *   Register Usage:  \r
644 // * \r
645 // *   R0:\r
646 // *   R1:    \r
647 // *   R2:    \r
648 // *   R3:       |  bit mask for stat to update on silent discard\r
649 // *   R4:    \r
650 // *   R5:    \r
651 // *   R6:          |\r
652 // *   R7:          |  Current Packet Forwarding info\r
653 // *   R8:          |\r
654 // *   R9:          |\r
655 // *   R10:     \r
656 // *   R11:     \r
657 // *   R12:     \r
658 // *   R13:\r
659 // *   R14:\r
660 // *   R15:\r
661 // *   R16:\r
662 // *   R17:\r
663 // *   R18:\r
664 // *   R19:\r
665 // *   R20:\r
666 // *   R21:\r
667 // *   R22:     |     \r
668 // *   R23:     |  Packet context - pktScope   \r
669 // *   R24:     |\r
670 // *   R25:     |\r
671 // *   R26:  Packet ID\r
672 // *   R27:\r
673 // *   R28:  statistics  (s_statsFlags)                             -\r
674 // *   R29:  c2RunContext (s_runCxt)                                -  Global Scope\r
675 // *   R30:  w2-Error Index w0-function return address              -\r
676 // *   R31:  System Flags (s_flags)                                 -\r
677 // *\r
678 // ****************************************************************************************************\r
679 \r
680     .using pktScope\r
681     .using currentFwdScope\r
682           \r
683 f_c2ForwardErr:\r
684 \r
685     // Get the error index, multiply by 16 to get the memory offset\r
686     lsr r1.w0,  s_pktCxt2.eP1C2Id,  PKT2_EIDX_SHIFT\r
687     lsl r1.w0,  r1.w0,              4\r
688 \r
689     lbco  s_curFmPlace,  PAMEM_CONST_EROUTE,  r1.w0,  SIZE(s_curFmPlace)\r
690 \r
691     l_c2ForwardErr_2:\r
692         // save the potential updated exception Id\r
693         sbco  s_pktCxt2.eP1C2Id,      cCdeOutPkt,  SIZE(s_pktDescr)+OFFSET(s_pktCxt2.eP1C2Id), 1\r
694         \r
695         // Get the bitfield mask for silent discard for classify2\r
696         zero  &r3,  4\r
697         set    r3.t_nSilentDiscardC2\r
698 \r
699         // Need a return address\r
700         mov    r30.w0, f_mainLoop\r
701         jmp    f_curPktForward\r
702 \r
703 \r
704     .leave pktScope\r
705     .leave currentFwdScope\r
706 \r
707 \r
708 // *****************************************************************************************************\r
709 // * FUNCTION PURPOSE: Process an add/modify or delete LUT1 command\r
710 // *****************************************************************************************************\r
711 // * DESCRIPTION: These commands are invalid for PDSPs with a classify2\r
712 // *\r
713 // *   Register Usage:  \r
714 // * \r
715 // *   R0:   w0 - the packet length\r
716 // *   R1:    \r
717 // *   R2:    \r
718 // *   R3:\r
719 // *   R4:   |  CDE commands\r
720 // *   R5:   |\r
721 // *   R6:          \r
722 // *   R7:\r
723 // *   R8:\r
724 // *   R9:\r
725 // *   R10:     \r
726 // *   R11:     \r
727 // *   R12:     \r
728 // *   R13:\r
729 // *   R14:\r
730 // *   R15:\r
731 // *   R16:\r
732 // *   R17:\r
733 // *   R18:\r
734 // *   R19:\r
735 // *   R20:\r
736 // *   R21:\r
737 // *   R22: \r
738 // *   R23:\r
739 // *   R24:\r
740 // *   R25:\r
741 // *   R26:  Packet ID\r
742 // *   R27:\r
743 // *   R28:  statistics  (s_statsFlags)                             -\r
744 // *   R29:  c2RunContext (s_runCxt)                                -  Global Scope\r
745 // *   R30:  w2-Error Index w0-function return address              -\r
746 // *   R31:  System Flags (s_flags)                                 -\r
747 // *\r
748 // ************************************************************************************************\r
749 \r
750     .using configScope\r
751     .using cdeScope\r
752 \r
753 \r
754 f_paComAddRepLut1:\r
755 f_paComDelLut1:\r
756 \r
757     mov  s_paCmd1.commandResult,  PA_COMMAND_RESULT_INVALID_DESTINATION\r
758     xout XID_CDEDATA,             s_paCmd1.commandResult,                SIZE(s_paCmd1.commandResult)\r
759     jmp  f_cfgReply\r
760     \r
761     .leave configScope\r
762     .leave cdeScope\r
763 \r
764 \r
765 // ************************************************************************************************\r
766 // * FUNCTION PURPOSE: Add or modify an entry in LUT2\r
767 // ************************************************************************************************\r
768 // * DESCRIPTION: A new entry is added to the lut\r
769 // *\r
770 // *   Register Usage:  \r
771 // * \r
772 // *   R0:   w0 - the packet length\r
773 // *   R1:    \r
774 // *   R2:    \r
775 // *   R3:   queueDivert Info\r
776 // *   R4:   |  CDE commands\r
777 // *   R5:   |                  \r
778 // *   R6:          |  Command header (entry)\r
779 // *   R7:          |\r
780 // *   R8:          |\r
781 // *   R9:          |\r
782 // *   R10:             |  Add LUT2 command\r
783 // *   R11:             |\r
784 // *   R12:     \r
785 // *   R13:   \r
786 // *   R14:     | LUT2  routing data0\r
787 // *   R15:     | LUT2          data1\r
788 // *   R16:     | LUT2          data2\r
789 // *   R17:     | LUT2          data3\r
790 // *   R18:     | LUT2 key\r
791 // *   R19:     | LUT2 control\r
792 // *   R20:\r
793 // *   R21:\r
794 // *   R22: \r
795 // *   R23:\r
796 // *   R24:\r
797 // *   R25:\r
798 // *   R26:  Packet ID\r
799 // *   R27:\r
800 // *   R28:  statistics  (s_statsFlags)                             -\r
801 // *   R29:  c2RunContext (s_runCxt)                                -  Global Scope\r
802 // *   R30:  w2-Error Index w0-function return address              -\r
803 // *   R31:  System Flags (s_flags)                                 -\r
804 // *\r
805 // *******************************************************************************************\r
806 \r
807     .using cdeScope\r
808     .using configScope\r
809     .using lut2Scope\r
810     .using pktScope\r
811 \r
812 f_paComAddRepLut2:\r
813 \r
814     // If there is an active add or delete the command must be rejected\r
815     qbbc  l_paComAddRepLut2_check_full,  s_flags.info.tStatus_Lut2AddDelBusy\r
816 \r
817         mov  s_paCmd1.commandResult,  PA_COMMAND_RESULT_LUT2_ADD_BUSY\r
818         xout XID_CDEDATA,             s_paCmd1.commandResult,                SIZE(s_paCmd1.commandResult)\r
819         jmp  f_cfgReply\r
820 \r
821 l_paComAddRepLut2_check_full:\r
822         // check if LUT2 is full\r
823         qbbc  l_paComAddRepLut2_a,  s_flags.info.tStatus_Lut2Full\r
824 \r
825           mov  s_paCmd1.commandResult,  PA_COMMAND_RESULT_LUT2_FULL\r
826           xout XID_CDEDATA,             s_paCmd1.commandResult,                SIZE(s_paCmd1.commandResult)\r
827           jmp  f_cfgReply\r
828         \r
829 l_paComAddRepLut2_a:\r
830 \r
831     // Verify that the packet has all the data\r
832     qble l_paComAddRepLut2_0,  r0.w0,  SIZE(s_paCmd1)+SIZE(s_paAddL2Std)\r
833         mov  s_paCmd1.commandResult, PA_COMMAND_RESULT_INVALID_PKT_SIZE\r
834         xout XID_CDEDATA,            s_paCmd1.commandResult,              SIZE(s_paCmd1.commandResult)\r
835         jmp  f_cfgReply\r
836 \r
837 \r
838 l_paComAddRepLut2_0:\r
839 \r
840     // Read in the command info. The command could be either a custom or standard,\r
841     // but it really makes no difference to the add function since the sizes are the same\r
842     xin  XID_CDEDATA,  s_paAddL2Std,  SIZE(s_paAddL2Std)\r
843 \r
844     // It is not required to update the number of entries for entry replacement\r
845     qbbs  l_paComAddRepLut2_1,  s_paAddL2Std.ctrlBitMap.t_pa_lut2_ctrl_replace  \r
846     \r
847     // Keep a count of the number of entries. Return a warning if\r
848     // it exceeds the max\r
849     add   s_runCxt.c2NumInL2Table,  s_runCxt.c2NumInL2Table,  1\r
850     mov   r1.w0,                    SUBS_MAX_LUT2_ENTRIES\r
851     qbge  l_paComAddRepLut2_1,      s_runCxt.c2NumInL2Table,  r1.w0\r
852     \r
853     mov   s_paCmd1.commandResult,   PA_COMMAND_RESULT_WARN_OVER_MAX_ENTRIES\r
854     jmp   l_paComAddRepLut2_1_0\r
855 \r
856 l_paComAddRepLut2_1:\r
857 \r
858     // Return success\r
859     mov  s_paCmd1.commandResult,  PA_COMMAND_RESULT_SUCCESS\r
860     \r
861 l_paComAddRepLut2_1_0:\r
862     xout XID_CDEDATA,             s_paCmd1.commandResult,    SIZE(s_paCmd1.commandResult)\r
863     \r
864     // Advance the CDE then read in the forwarding info \r
865     // The advance must include the common command header as well as the add lut2 command\r
866     mov  s_cdeCmdWd.operation,  CDE_CMD_WINDOW_ADVANCE\r
867     mov  s_cdeCmdWd.byteCount,  SIZE(s_paCmd1)+SIZE(s_paAddL2Std)\r
868     xout XID_CDECTRL,           s_cdeCmdWd,              SIZE(s_cdeCmdWd)\r
869 \r
870     xin  XID_CDEDATA,           s_l2Entry.data0,         SIZE(s_paFwdMatchPlace) + SIZE(s_l2QueueDivert)\r
871     // record the potential Queue diversion parameters \r
872     mvid  r3,                   *&s_l2QueueDivert   \r
873 \r
874     // Put the previously read key into the correct location\r
875     // Switched to the custom version of the structure since it moves all 32 bits at once\r
876     mov  s_l2Entry.key,       s_paAddL2Custom.match\r
877     \r
878     // We may need to update b3 if custom \r
879     qbeq l_paComAddRepLut2_3,  s_paAddL2Std.type,  PA_COM_ADD_LUT2_STANDARD \r
880     qbgt l_paComAddRepLut2_2,  s_paAddL2Std.index, PA_MAX_C2_CUSTOM_TYPES\r
881        mov  s_paCmd1.commandResult, PA_COMMAND_RESULT_INVALID_C2_CUSTOM_IDX\r
882        set  s_pktCxt3.ctrlFlag.t_cmdResultPatch\r
883        jmp  f_cfgReply\r
884     \r
885 l_paComAddRepLut2_2:    \r
886        // Calcualte the offset: 16-byte entries \r
887        lsl  r1.w0,    s_paAddL2Std.index,  4\r
888        add  r1.w0,    r1.w0,  OFFSET_CUSTOM_C2 + OFFSET(struct_paC2Custom.bitSet) \r
889        lbco r1.b3,    PAMEM_CONST_CUSTOM2,  r1.w0,  SIZE(struct_paC2Custom.bitSet)\r
890        //  Update the MS byte\r
891        or   s_l2Entry.key.b3,  s_l2Entry.key.b3, r1.b3 \r
892 \r
893 \r
894 l_paComAddRepLut2_3:\r
895 \r
896     // Disable GTPU parsing only if GTPU flag is set\r
897     qbbc  l_paComAddRepLut2_4,  s_paAddL2Std.ctrlBitMap.t_pa_lut2_ctrl_gtpu  \r
898     set   s_runCxt.ctrlFlag.t_c2_disable_GTPU\r
899 \r
900 l_paComAddRepLut2_4:\r
901     // Put the command word in place\r
902     zero  &s_l2Entry.ctrl,   SIZE(s_l2Entry.ctrl)\r
903     mov   s_l2Entry.ctrl.b3, SUBS_L2_ENTRY_CTRL_ADD\r
904 \r
905     sbco  s_l2Entry,  cLut2Regs,  LUT2_REG_DATA0,  SIZE(s_l2Entry)\r
906     \r
907     // Should we perform queue diversion assistance\r
908     qbbc  l_paComAddRepLut2_5,  s_paAddL2Std.ctrlBitMap.t_pa_lut2_ctrl_queue_divert \r
909     \r
910         // forward the response packet to the Queue-diverion processing queue\r
911         lbco    s_paAddLut2QueueDivert, PAMEM_CONST_CUSTOM, OFFSET_QUEUE_DIVERT_CFG, SIZE(s_paAddLut2QueueDivert)\r
912         \r
913         // Patch timestamp field with queue diversion information \r
914         sbco  r3,  cCdeOutPkt,  OFFSET(s_pktDescr.timestamp), SIZE(s_pktDescr.timestamp)\r
915         \r
916         // Add PA Config command\r
917         mov   r1.b0,   PSH_CMD_CONFIG << 5\r
918         sbco  r1.b0,   cCdeOutPkt,  SIZE(s_pktDescr),  1 \r
919         \r
920         mov  s_cdeCmdPkt.psInfoSize,  4\r
921         mov  s_cdeCmdPkt.threadId,    THREADID_CDMA\r
922         mov  s_cdeCmdPkt.destQueue,   s_paAddLut2QueueDivert.destQueue\r
923         mov  s_cdeCmdPkt.flowId,      s_paAddLut2QueueDivert.destFlowId\r
924         mov  s_cdeCmdPkt.operation,   CDE_CMD_PACKET_ADVANCE\r
925         mov  s_cdeCmdPkt.optionsFlag, CDE_FLG_SET_THREADID | CDE_FLG_SET_FLOWID | CDE_FLG_SET_PSINFO | CDE_FLG_SET_DESTQUEUE\r
926         xout XID_CDECTRL,             s_cdeCmdPkt,            SIZE(s_cdeCmdPkt)\r
927    \r
928         // command response counter\r
929             lbco  r1, FIRMWARE_MBOX, 8, 4\r
930             add   r1, r1, 1\r
931             sbco  r1, FIRMWARE_MBOX, 8, 4\r
932         \r
933         // set queue divert flag (command1)\r
934         mov   r1, 1\r
935             sbco  r1, FIRMWARE_MBOX, 4, 4\r
936 \r
937         // wait for command to be set hold\r
938         wbs     s_flags.info.tStatus_Command1\r
939         \r
940         // wait for entry update\r
941         wbc     s_flags.info.tStatus_Lut2AddDelBusy\r
942         \r
943         // wait for qeue diversion to be completed\r
944         wbc     s_flags.info.tStatus_Command1\r
945 \r
946         jmp   f_mainLoop\r
947 \r
948 \r
949 l_paComAddRepLut2_5:\r
950     jmp  f_cfgReply\r
951 \r
952 \r
953     .leave cdeScope\r
954     .leave configScope\r
955     .leave lut2Scope\r
956     .leave pktScope\r
957     \r
958 \r
959 // ********************************************************************************************\r
960 // * FUNCTION PURPOSE: Delete an entry from LUT2\r
961 // ********************************************************************************************\r
962 // * DESCRIPTION: An existing entry is deleted\r
963 // *\r
964 // *   Register Usage:  \r
965 // * \r
966 // *   R0:   w0 - the packet length\r
967 // *   R1:    \r
968 // *   R2:    \r
969 // *   R3:\r
970 // *   R4:   |  CDE commands\r
971 // *   R5:   |                  \r
972 // *   R6:          |  Command header (entry)\r
973 // *   R7:          |\r
974 // *   R8:          |\r
975 // *   R9:          |\r
976 // *   R10:             |  del LUT2 command\r
977 // *   R11:             |\r
978 // *   R12:     \r
979 // *   R13:   \r
980 // *   R14:     \r
981 // *   R15:     \r
982 // *   R16:     \r
983 // *   R17:     \r
984 // *   R18:   | LUT2 key\r
985 // *   R19:       | LUT2 control\r
986 // *   R20:\r
987 // *   R21:\r
988 // *   R22: \r
989 // *   R23:\r
990 // *   R24:\r
991 // *   R25:\r
992 // *   R26:  Packet ID\r
993 // *   R27:\r
994 // *   R28:  statistics  (s_statsFlags)                             -\r
995 // *   R29:  c2RunContext (s_runCxt)                                -  Global Scope\r
996 // *   R30:  w2-Error Index w0-function return address              -\r
997 // *   R31:  System Flags (s_flags)                                 -\r
998 // *\r
999 // ******************************************************************************************\r
1000 \r
1001     .using cdeScope\r
1002     .using configScope\r
1003     .using lut2Scope\r
1004     .using pktScope\r
1005 \r
1006 f_paComDelLut2:\r
1007 \r
1008 \r
1009     // If there is an active add or delete the command must be rejected\r
1010     qbbc  l_paComDelLut2_0,  s_flags.info.tStatus_Lut2AddDelBusy\r
1011 \r
1012         mov  s_paCmd1.commandResult,  PA_COMMAND_RESULT_LUT2_ADD_BUSY\r
1013         xout XID_CDEDATA,             s_paCmd1.commandResult,                SIZE(s_paCmd1.commandResult)\r
1014         jmp  f_cfgReply\r
1015 \r
1016 l_paComDelLut2_0:\r
1017 \r
1018     // Keep a count of the number of entries. Return a warning if\r
1019     // it seems to drop below zero\r
1020     qbne  l_paComDelLut2_1,   s_runCxt.c2NumInL2Table,   0\r
1021         mov s_paCmd1.commandResult,  PA_COMMAND_RESULT_WARN_NEGATIVE_ENTRY_COUNT\r
1022         xout XID_CDEDATA,             s_paCmd1.commandResult,                SIZE(s_paCmd1.commandResult)\r
1023         jmp l_paComDelLut2_2\r
1024 \r
1025 l_paComDelLut2_1:\r
1026     // Return success\r
1027     mov  s_paCmd1.commandResult,  PA_COMMAND_RESULT_SUCCESS\r
1028     xout XID_CDEDATA,             s_paCmd1.commandResult,    SIZE(s_paCmd1.commandResult)\r
1029 \r
1030     sub  s_runCxt.c2NumInL2Table,  s_runCxt.c2NumInL2table,  1\r
1031 \r
1032 l_paComDelLut2_2:\r
1033 \r
1034     // read in delete command parameters\r
1035     XIN  XID_CDEDATA,  s_paDelL2Custom,  SIZE(s_paDelL2Custom)\r
1036 \r
1037     mov   s_l2Entry.key,      s_paDelL2Custom.match\r
1038     zero &s_l2Entry.ctrl,     SIZE(s_l2Entry.ctrl)\r
1039     mov   s_l2Entry.ctrl.b3,  SUBS_L2_ENTRY_CTRL_DEL\r
1040     \r
1041     // We may need to update b3 if custom \r
1042     qbeq l_paComDelLut2_4,  s_paDelL2Custom.type,  PA_COM_ADD_LUT2_STANDARD \r
1043     qbge l_paComDelLut2_3,  s_paDelL2Custom.index, PA_MAX_C2_CUSTOM_TYPES\r
1044        mov  s_paCmd1.commandResult, PA_COMMAND_RESULT_INVALID_C2_CUSTOM_IDX\r
1045        xout XID_CDEDATA,            s_paCmd1.commandResult,                SIZE(s_paCmd1.commandResult)\r
1046        jmp  f_cfgReply\r
1047     \r
1048 l_paComDelLut2_3:    \r
1049        // Calcualte the offset: 16-byte entries \r
1050        lsl  r1.w0,    s_paDelL2Custom.index,  4\r
1051        add  r1.w0,    r1.w0,  OFFSET_CUSTOM_C2 + OFFSET(struct_paC2Custom.bitSet) \r
1052        lbco r1.b3,    PAMEM_CONST_CUSTOM2,  r1.w0,  SIZE(struct_paC2Custom.bitSet)\r
1053        //  Update the MS byte\r
1054        or   s_l2Entry.key.b3,  s_l2Entry.key.b3, r1.b3 \r
1055        jmp  l_paComDelLut2_5\r
1056 \r
1057 l_paComDelLut2_4:\r
1058     \r
1059     // Re-enable GTPU parsing if GTPU flag is set\r
1060     qbbc  l_paComDelLut2_5,  s_paDelL2Std.ctrlBitMap.t_pa_lut2_ctrl_gtpu  \r
1061     clr   s_runCxt.ctrlFlag.t_c2_disable_GTPU\r
1062 \r
1063 l_paComDelLut2_5:\r
1064     sbco  s_l2Entry.key,  cLut2Regs, LUT2_REG_ADDDEL_KEY, SIZE(s_l2Entry.ctrl)+SIZE(s_l2Entry.key)\r
1065 \r
1066     jmp  f_cfgReply\r
1067 \r
1068     .leave cdeScope\r
1069     .leave configScope\r
1070     .leave lut2Scope\r
1071     .leave pktScope\r
1072 \r
1073 // *********************************************************************************************\r
1074 // * FUNCTION PURPOSE: Initialize the classify2 PDSP\r
1075 // *********************************************************************************************\r
1076 // * DESCRIPTION: One time setup for the PDSP\r
1077 // *\r
1078 // *********************************************************************************************\r
1079 \r
1080     .using initScope\r
1081 \r
1082 f_c2LocalInit:\r
1083 \r
1084         // Reset the LUT2 table to clear all entries. It will take 8192 cycles to\r
1085         // clear the table. Any value written will cause the reset, but just\r
1086         // to be safe a non-zero value will be written\r
1087         mov r3, 1\r
1088         sbco r3, cLut2Regs, LUT2_REG_SOFTRESET, 4\r
1089 \r
1090     // The run context\r
1091     zero  &s_runCxt,  SIZE(s_runCxt)\r
1092     lbco   s_runCxt.pdspId,  PAMEM_CONST_PDSP_INFO, OFFSET_ID,  1   // PDSP ID\r
1093 \r
1094     // The call table\r
1095     mov s_headerParse.c2ParseUdp,     f_c2ParseUdp\r
1096     mov s_headerParse.c2ParseUdpLite, f_c2ParseUdpLite\r
1097     mov s_headerParse.c2ParseTcp,     f_c2ParseTcp\r
1098     mov s_headerParse.c2ParseGtpu,    f_c2ParseGtpu\r
1099     mov s_headerParse.c2ParseEspDec,  f_c2ParseEspDec\r
1100     mov s_headerParse.c2ParseCustom,  f_c2ParseCustom\r
1101 \r
1102     // Assembler limitation on param length. Use some cycles since this is just init code\r
1103     mov  r0.b0,  OFFSET(s_headerParse.c2ParseCustom)\r
1104     add  r0.b0,  r0.b0,                              SIZE(s_headerParse.c2ParseCustom)\r
1105     sub  r0.b0,  r0.b0,                              OFFSET(s_headerParse.c2ParseUdp)\r
1106 \r
1107     sbco s_headerParse.c2ParseUdp, PAMEM_CONST_PARSE, OFFSET(s_headerParse.c2ParseUdp), b0\r
1108     \r
1109     ret\r
1110 \r
1111 \r
1112     .leave initScope\r
1113 \r
1114 // **********************************************************************************************\r
1115 // * FUNCTION PURPOSE: Parse a UDP header\r
1116 // **********************************************************************************************\r
1117 // * DESCRIPTION: The UDP dest port is added to the LUT and the search is initiated\r
1118 // *\r
1119 // *    On entry:\r
1120 // *            - the CDE is at the start of the UDP header\r
1121 // *            - r30.w0 has the function return address\r
1122 // *            - param.action has SUBS_ACTION_PARSE\r
1123 // *            - cdeCmdWd.operation has CDE_CMD_WINDOW_ADVNACE\r
1124 // *\r
1125 // *    On exit:\r
1126 // *            - param.action has SUBS_ACTION_LOOKUP or SUBS_ACTION_PARSE (GTPU only)\r
1127 // *            - cdeCmdWd.operation has CDE_CMD_WINDOW_ADVANCE\r
1128 // *            - the CDE is at the first byte after the UDP header\r
1129 // *            - startOffset is adjusted by the UDP header size \r
1130 // *            - s_next.Hdr is set as PA_HDR_UNKNOWN if non-GTPU, otherwise, it is set to PA_HDR_GTPU\r
1131 // *            \r
1132 // *   Register Usage:  \r
1133 // * \r
1134 // *   R0:   \r
1135 // *   R1:    \r
1136 // *   R2:    \r
1137 // *   R3:\r
1138 // *   R4:   |  CDE commands\r
1139 // *   R5:   |                   | LUT2 search key\r
1140 // *   R6:          |  UDP header\r
1141 // *   R7:          |\r
1142 // *   R8:          \r
1143 // *   R9:          \r
1144 // *   R10:             \r
1145 // *   R11:             \r
1146 // *   R12:     \r
1147 // *   R13:   \r
1148 // *   R14:     \r
1149 // *   R15:     \r
1150 // *   R16:     \r
1151 // *   R17:     \r
1152 // *   R18:   \r
1153 // *   R19:       \r
1154 // *   R20:\r
1155 // *   R21:\r
1156 // *   R22: \r
1157 // *   R23:\r
1158 // *   R24:\r
1159 // *   R25:\r
1160 // *   R26:  Packet ID\r
1161 // *   R27:\r
1162 // *   R28:  statistics  (s_statsFlags)                             -\r
1163 // *   R29:  c2RunContext (s_runCxt)                                -  Global Scope\r
1164 // *   R30:  w2-Error Index w0-function return address              -\r
1165 // *   R31:  System Flags (s_flags)                                 -\r
1166 // *\r
1167 // ***********************************************************************************************\r
1168 \r
1169     .using cdeScope\r
1170     .using pktScope\r
1171     .using udpScope\r
1172     .using lut2Scope\r
1173     .using custC2Scope\r
1174 \r
1175 f_c2ParseUdp:\r
1176 \r
1177     // Record parsing UDP\r
1178     set s_pktCxt.hdrBitmask_nextHdr.SUBS_PA_BIT_HEADER_UDP\r
1179     mov s_pktCxt.l4Offset,      s_pktCxt.startOffset\r
1180 \r
1181     // Read in the UDP header. Do not advance since there could be a switch to\r
1182     // custom mode\r
1183     xin  XID_CDEDATA, s_udp,  SIZE(s_udp) + SIZE(s_ipsecNatT)\r
1184 \r
1185     // If the checksum value is non-zero, configure the CDE to compute the checksum\r
1186     qbeq  l_c2ParseUdp0,  s_udp.chksum,  0\r
1187 \r
1188         add s_pktCxt.pseudo,       s_pktCxt.pseudo, s_udp.len\r
1189         adc s_pktCxt.pseudo,       s_pktCxt.pseudo, IP_PROTO_NEXT_UDP\r
1190         adc s_cdeCmdChk.initSum,   s_pktCxt.pseudo, 0\r
1191         mov s_cdeCmdChk.byteLen,   s_udp.len\r
1192         mov s_cdeCmdChk.options,   0\r
1193         mov s_cdeCmdChk.operation, CDE_CMD_CHECKSUM2_VALIDATE\r
1194 \r
1195         xout XID_CDECTRL, s_cdeCmdChk,  SIZE(s_cdeCmdChk)\r
1196 \r
1197 l_c2ParseUdp0:\r
1198 \r
1199     // UDP length includes the udp header, to the end length is computed \r
1200     // before updating the start offset.\r
1201     add  r0.w0,    s_pktCxt.startOffset,  s_udp.len\r
1202     qbge l_c2ParseUdp0_1, r0.w0,    s_pktCxt.endOffset   \r
1203         // The end of UDP payload goes beyond the end of packet, it must be an illegal packet \r
1204        mov s_param.action, SUBS_ACTION_EXIT\r
1205        mov s_pktCxt2.eP1C2Id, EROUTE_PARSE_FAIL << PKT2_EIDX_SHIFT\r
1206        ret\r
1207     \r
1208 l_c2ParseUdp0_1:    \r
1209     mov  s_pktCxt.endOffset,    r0.w0 \r
1210     add  s_pktCxt.startOffset,  s_pktCxt.startOffset,  UDP_HEADER_LEN_BYTES\r
1211     mov  s_pktCxt6.l3offset2,   s_pktCxt6.l3l5Offset\r
1212     mov  s_pktCxt.l5Offset,     s_pktCxt.startOffset\r
1213 \r
1214     set  s_statsFlags.event.t_nUdp\r
1215     \r
1216     // Verify whether GTPU parsing is enabled\r
1217     qbbs  l_c2ParseUdp1, s_runCxt.ctrlFlag.t_c2_disable_GTPU\r
1218 \r
1219     // A switch to GTPU mode is made based on destination UDP port\r
1220     mov   r0.w0,       UDP_TCP_DEST_PORT_GTP\r
1221     qbne  l_c2ParseUdp1,  s_udp.dst,  r0.w0 \r
1222 \r
1223  \r
1224        // On match change the next parse type to GTPU and return\r
1225        set s_pktCxt.hdrBitmask_nextHdr.SUBS_PA_BIT_HEADER_GTPU\r
1226        mov s_next.Hdr,  PA_HDR_GTPU\r
1227 \r
1228        // Advance past the end of the header \r
1229        mov  s_cdeCmdWd.operation,  CDE_CMD_WINDOW_ADVANCE\r
1230        mov s_cdeCmdWd.byteCount,   SIZE(s_udp)\r
1231        xout XID_CDECTRL,           s_cdeCmdWd,             SIZE(s_cdeCmdWd)\r
1232 \r
1233        ret\r
1234 \r
1235 l_c2ParseUdp1:\r
1236 \r
1237     // Verify whether IPSEC NAT-T  parsing is enabled\r
1238     qbbc  l_c2ParseUdp2, s_runCxt.ctrlFlag.t_c2_enable_IPSEC_NAT_T\r
1239 \r
1240     // A switch to IPSEC_NAT_T mode is made based on destination or source UDP port\r
1241     lbco  r0.w0,  PAMEM_CONST_CUSTOM, OFFSET_IPSEC_NAT_T_CFG + OFFSET(struct_ipsec_nat_t_cfg.udpPort),  SIZE(struct_ipsec_nat_t_cfg.udpPort)\r
1242     qbeq  l_c2ParseUdpNatT_1,  s_udp.dst,  r0.w0 \r
1243     qbne  l_c2ParseUdp2,       s_udp.src,  r0.w0\r
1244 \r
1245 l_c2ParseUdpNatT_1:\r
1246        // IPSEC NAT_T parsing\r
1247        // Keepalive packet: UDP length == 9, payload = 0xFF\r
1248        // Control packet: UDP length > 12 SPI = 0\r
1249        // IPSEC Data Packet: UDP length > 12 SPI != 0\r
1250        // Error Packet UDP length <= 12\r
1251        \r
1252        // Common Operations for all NAT_T packet\r
1253        set  s_pktCxt.hdrBitmask3_frag_portNum.SUBS_PA_BIT_HEADER_IPSEC_NAT_T\r
1254        mov s_next.Hdr,  PA_HDR_UNKNOWN\r
1255        and  s_pktCxt2.eP1C2Id,  s_pktCxt2.eP1C2Id,   NOT_PKT2_EIDX_MASK\r
1256        mov s_param.action, SUBS_ACTION_EXIT\r
1257 \r
1258        qbge l_c2ParseUdpNatT_3, s_udp.len, SIZE(s_udp) + SIZE(s_ipsecNatT) \r
1259             qbeq l_c2ParseUdpNatT_2, s_ipsecNatT.spi, 0    \r
1260                 // IPSEC Data packet\r
1261                 or  s_pktCxt2.eP1C2Id,  s_pktCxt2.eP1C2Id,  EROUTE_NAT_T_DATA << PKT2_EIDX_SHIFT\r
1262                 mov s_next.Hdr,  PA_HDR_ESP\r
1263                 ret   \r
1264        \r
1265 l_c2ParseUdpNatT_2: \r
1266                 // NAT_T Control packet      \r
1267                 or  s_pktCxt2.eP1C2Id,  s_pktCxt2.eP1C2Id,  EROUTE_NAT_T_CTRL << PKT2_EIDX_SHIFT\r
1268                 ret\r
1269                 \r
1270 l_c2ParseUdpNatT_3:\r
1271             qbne l_c2ParseUdpNatT_4,    s_udp.len,          SIZE(s_udp) + SIZE(s_ipsecNatT2)\r
1272             qbne l_c2ParseUdpNatT_4,    s_ipsecNatT2.data,  0xFF\r
1273                 // NAT-T Keepalive Packet\r
1274                 or  s_pktCxt2.eP1C2Id,  s_pktCxt2.eP1C2Id,  EROUTE_NAT_T_KEEPALIVE << PKT2_EIDX_SHIFT\r
1275                 ret\r
1276        \r
1277 l_c2ParseUdpNatT_4:       \r
1278                 // NAT-T Error Packet\r
1279                 or  s_pktCxt2.eP1C2Id,  s_pktCxt2.eP1C2Id,  EROUTE_NAT_T_FAIL << PKT2_EIDX_SHIFT\r
1280                 ret\r
1281 \r
1282 l_c2ParseUdp2:\r
1283 \r
1284     // Do the lookup\r
1285     zero &s_l2Search,   SIZE(s_l2Search)\r
1286     qbbs l_c2ParseUdp2_vlink, s_pktCxt.eP1C2IdIdx.t_vlinkEn\r
1287         mov  s_l2Search.IdIdx,    s_pktCxt2.IdIdx\r
1288         jmp l_c2ParseUdp2_issue_lookup\r
1289 l_c2ParseUdp2_vlink: \r
1290     // Populate lookup using virtual link\r
1291     mov s_l2Search.IdIdx, s_pktCxt.vLinkNum\r
1292     or  s_l2Search.IdIdx, s_l2Search.IdIdx, 0xC0\r
1293 l_c2ParseUdp2_issue_lookup:\r
1294     mov  s_l2Search.dstPort,  s_udp.dst\r
1295 \r
1296     xout XID_LUT2CMD,  s_l2Search,  SIZE(s_l2Search)\r
1297 \r
1298     mov s_param.action, SUBS_ACTION_LOOKUP\r
1299 \r
1300     ret\r
1301 \r
1302     .leave cdeScope\r
1303     .leave pktScope\r
1304     .leave udpScope\r
1305     .leave lut2Scope\r
1306     .leave custC2Scope\r
1307 \r
1308 \r
1309 // **********************************************************************************************\r
1310 // * FUNCTION PURPOSE: Parse a UDP-Lite header\r
1311 // **********************************************************************************************\r
1312 // * DESCRIPTION: The UDP-Lite header is parsed\r
1313 // *\r
1314 // *    On entry:\r
1315 // *            - the CDE is at the start of the UDP header\r
1316 // *            - r30.w0 has the function return address\r
1317 // *            - param.action has SUBS_ACTION_PARSE\r
1318 // *            - cdeCmdWd.operation has CDE_CMD_WINDOW_ADVNACE\r
1319 // *\r
1320 // *    On exit:\r
1321 // *            - param.action has SUBS_ACTION_LOOKUP or SUBS_ACTION_PARSE (GTPU only)\r
1322 // *            - cdeCmdWd.operation has CDE_CMD_WINDOW_ADVANCE\r
1323 // *            - the CDE is at the first byte after the UDP-lite header\r
1324 // *            - startOffset is adjusted by the UDP header size \r
1325 // *            - s_next.Hdr is set as PA_HDR_UNKNOWN if non-GTPU, otherwise, it is set to PA_HDR_GTPU\r
1326 // *   Register Usage:  \r
1327 // * \r
1328 // *   R0:   \r
1329 // *   R1:    \r
1330 // *   R2:    \r
1331 // *   R3:\r
1332 // *   R4:   |  CDE commands\r
1333 // *   R5:   |                   | LUT2 search key\r
1334 // *   R6:          |  UDP lite header\r
1335 // *   R7:          |\r
1336 // *   R8:          \r
1337 // *   R9:          \r
1338 // *   R10:             \r
1339 // *   R11:             \r
1340 // *   R12:     \r
1341 // *   R13:   \r
1342 // *   R14:     \r
1343 // *   R15:     \r
1344 // *   R16:     \r
1345 // *   R17:     \r
1346 // *   R18:   \r
1347 // *   R19:       \r
1348 // *   R20:\r
1349 // *   R21:\r
1350 // *   R22: \r
1351 // *   R23:\r
1352 // *   R24:\r
1353 // *   R25:\r
1354 // *   R26:  Packet ID\r
1355 // *   R27:\r
1356 // *   R28:  statistics  (s_statsFlags)                             -\r
1357 // *   R29:  c2RunContext (s_runCxt)                                -  Global Scope\r
1358 // *   R30:  w2-Error Index w0-function return address              -\r
1359 // *   R31:  System Flags (s_flags)                                 -\r
1360 // *\r
1361 // ************************************************************************************************\r
1362 \r
1363 \r
1364     .using cdeScope\r
1365     .using pktScope\r
1366     .using udpScope\r
1367     .using lut2Scope\r
1368     .using custC2Scope  \r
1369 \r
1370 f_c2ParseUdpLite:\r
1371         \r
1372     // Record parsing UDP\r
1373     set s_pktCxt.hdrBitmask_nextHdr.SUBS_PA_BIT_HEADER_UDP\r
1374     mov s_pktCxt.l4Offset,      s_pktCxt.startOffset\r
1375 \r
1376     // Read in the UDP lite header. Do not advance since there could be a switch to\r
1377     // custom mode\r
1378     xin  XID_CDEDATA, s_udpLite,  SIZE(s_udpLite)\r
1379 \r
1380     // Setup for the UDP checksum\r
1381     // Get the IP length\r
1382     sub  r2.w0,  s_pktCxt.startOffset, s_pktCxt.endOffset\r
1383 \r
1384     mov  s_cdeCmdChk.bytelen,  s_udpLite.chkCov\r
1385 \r
1386     qbne  l_c2ParseUdpLite0,  s_udpLite.chkCov,  0\r
1387         mov  s_cdeCmdChk.bytelen,   r2.w0          // 0 means the whole packet\r
1388 \r
1389 l_c2ParseUdpLite0:\r
1390 \r
1391     qblt l_c2ParseUdpLite2,  s_cdeCmdChk.bytelen,  r2.w0\r
1392     qbgt l_c2ParseUdpLite2,  s_cdeCmdChk.bytelen,  UDP_LITE_HEADER_LEN_BYTES\r
1393 \r
1394     add s_pktCxt.pseudo,       s_pktCxt.pseudo, r2.w0\r
1395     adc s_pktCxt.pseudo,       s_pktCxt.pseudo, IP_PROTO_NEXT_UDP_LITE\r
1396     adc s_cdeCmdChk.initSum,   s_pktCxt.pseudo, 0\r
1397     mov s_cdeCmdChk.options,   0\r
1398     mov s_cdeCmdChk.operation, CDE_CMD_CHECKSUM2_VALIDATE\r
1399 \r
1400     xout XID_CDECTRL, s_cdeCmdChk,  SIZE(s_cdeCmdChk)\r
1401 \r
1402     // UDP-lite length includes the udp header\r
1403     add  s_pktCxt.startOffset,  s_pktCxt.startOffset,  UDP_LITE_HEADER_LEN_BYTES\r
1404     mov  s_pktCxt6.l3offset2,   s_pktCxt6.l3l5Offset\r
1405     mov  s_pktCxt.l5Offset,     s_pktCxt.startOffset\r
1406 \r
1407     set  s_statsFlags.event.t_nUdp\r
1408     \r
1409     // Verify whether GTPU parsing is enabled\r
1410     qbbs  l_c2ParseUdpLite1, s_runCxt.ctrlFlag.t_c2_disable_GTPU\r
1411     \r
1412     // A switch to GTPU mode is made based on destination UDP port\r
1413     mov   r0.w0,       UDP_TCP_DEST_PORT_GTP\r
1414     qbne  l_c2ParseUdpLite1,  s_udpLite.dst,  r0.w0 \r
1415  \r
1416        // On match change the next parse type to custom and return\r
1417        mov s_next.Hdr,  PA_HDR_GTPU\r
1418 \r
1419        // Advance past the end of the header \r
1420        mov  s_cdeCmdWd.operation,  CDE_CMD_WINDOW_ADVANCE\r
1421        mov s_cdeCmdWd.byteCount,   SIZE(s_udpLite)\r
1422        xout XID_CDECTRL,           s_cdeCmdWd,             SIZE(s_cdeCmdWd)\r
1423 \r
1424        ret\r
1425 \r
1426 l_c2ParseUdpLite1:\r
1427 \r
1428     // Do the lookup\r
1429     zero &s_l2Search,   SIZE(s_l2Search)\r
1430     qbbs l_c2ParseUdpLite1_vlink, s_pktCxt.eP1C2IdIdx.t_vlinkEn\r
1431         mov  s_l2Search.IdIdx,    s_pktCxt2.IdIdx\r
1432         jmp l_c2ParseUdpLite1_issue_lookup\r
1433 l_c2ParseUdpLite1_vlink: \r
1434     // Populate lookup using virtual link\r
1435     mov s_l2Search.IdIdx, s_pktCxt.vLinkNum\r
1436     or  s_l2Search.IdIdx, s_l2Search.IdIdx, 0xC0\r
1437 l_c2ParseUdpLite1_issue_lookup:\r
1438     mov  s_l2Search.dstPort,  s_udpLite.dst\r
1439     \r
1440     xout XID_LUT2CMD,  s_l2Search,  SIZE(s_l2Search)\r
1441 \r
1442     mov s_param.action, SUBS_ACTION_LOOKUP\r
1443     ret\r
1444 \r
1445 \r
1446 l_c2ParseUdpLite2:\r
1447 \r
1448     // UDP lite checksum coverage failed\r
1449     and s_pktCxt2.eP1C2Id,  s_pktCxt2.eP1C2Id,  NOT_PKT2_EIDX_MASK\r
1450     or  s_pktCxt2.eP1C2Id,  s_pktCxt2.eP1C2Id,  EROUTE_UDP_LITE_FAIL << PKT2_EIDX_SHIFT\r
1451 \r
1452     mov s_param.action, SUBS_ACTION_EXIT\r
1453     ret\r
1454 \r
1455     .leave cdeScope\r
1456     .leave pktScope\r
1457     .leave udpScope\r
1458     .leave lut2Scope\r
1459     .leave custC2Scope\r
1460 \r
1461 \r
1462 // ***********************************************************************************\r
1463 // * FUNCTION PURPOSE: Process a TCP header\r
1464 // ***********************************************************************************\r
1465 // * DESCRIPTION: The TCP header is parsed and a LUT2 initiated\r
1466 // *\r
1467 // *   Register Usage:  \r
1468 // * \r
1469 // *   R0:   \r
1470 // *   R1:   | scratch\r
1471 // *   R2:    \r
1472 // *   R3:\r
1473 // *   R4:   |  CDE commands\r
1474 // *   R5:   |                   | LUT2 search key\r
1475 // *   R6:          |  TCP header\r
1476 // *   R7:          |\r
1477 // *   R8:          |\r
1478 // *   R9:          |\r
1479 // *   R10:         |\r
1480 // *   R11:             \r
1481 // *   R12:     \r
1482 // *   R13:   \r
1483 // *   R14:     \r
1484 // *   R15:     \r
1485 // *   R16:     \r
1486 // *   R17:     \r
1487 // *   R18:   \r
1488 // *   R19:       \r
1489 // *   R20:\r
1490 // *   R21:\r
1491 // *   R22: \r
1492 // *   R23:\r
1493 // *   R24:\r
1494 // *   R25:\r
1495 // *   R26:  Packet ID\r
1496 // *   R27:\r
1497 // *   R28:  statistics  (s_statsFlags)                             -\r
1498 // *   R29:  c2RunContext (s_runCxt)                                -  Global Scope\r
1499 // *   R30:  w2-Error Index w0-function return address              -\r
1500 // *   R31:  System Flags (s_flags)                                 -\r
1501 // *\r
1502 // *************************************************************************************\r
1503 \r
1504     .using cdeScope\r
1505     .using pktScope\r
1506     .using tcpScope\r
1507     .using lut2Scope\r
1508 \r
1509 f_c2ParseTcp:\r
1510 \r
1511     // Record parsing TCP\r
1512     set s_pktCxt.hdrBitmask_nextHdr.SUBS_PA_BIT_HEADER_TCP\r
1513     mov s_pktCxt.l4Offset,      s_pktCxt.startOffset\r
1514 \r
1515     // Read in the TCP header\r
1516     xin  XID_CDEDATA,  s_tcp,  SIZE(s_tcp)\r
1517 \r
1518     // Configure and initiate the lookup\r
1519     zero &s_l2Search,   SIZE(s_l2Search)\r
1520     qbbs l_c2ParseTcp_vlink, s_pktCxt.eP1C2IdIdx.t_vlinkEn\r
1521         mov  s_l2Search.IdIdx,    s_pktCxt2.IdIdx\r
1522         jmp l_c2ParseTcp_issue_lookup\r
1523 l_c2ParseTcp_vlink: \r
1524     // Populate lookup using virtual link\r
1525     mov s_l2Search.IdIdx, s_pktCxt.vLinkNum\r
1526     or  s_l2Search.IdIdx, s_l2Search.IdIdx, 0xC0\r
1527 l_c2ParseTcp_issue_lookup:\r
1528     mov  s_l2Search.dstPort,  s_tcp.dst\r
1529     \r
1530     xout XID_LUT2CMD,  s_l2Search,  SIZE(s_l2Search)\r
1531 \r
1532 \r
1533     // Setup the CDE to do the L4 checkusm\r
1534     sub s_cdeCmdChk.byteLen,   s_pktCxt.endOffset,  s_pktCxt.startOffset\r
1535     add s_pktCxt.pseudo,       s_pktCxt.pseudo,     s_cdeCmdChk.byteLen\r
1536     adc s_pktCxt.pseudo,       s_pktCxt.pseudo,     IP_PROTO_NEXT_TCP\r
1537     adc s_cdeCmdChk.initSum,   s_pktCxt.pseudo,     0\r
1538     mov s_cdeCmdChk.options,   0\r
1539     mov s_cdeCmdChk.operation, CDE_CMD_CHECKSUM2_VALIDATE\r
1540 \r
1541     xout XID_CDECTRL, s_cdeCmdChk,  SIZE(s_cdeCmdChk)\r
1542 \r
1543     // Adjust the start offset past the tcp header\r
1544     lsr  r1.w0,                s_tcp.offset_ecn_ctrl,  12     // extract the length (32 bit length)\r
1545     lsl  r1.w0,                r1.w0,                  2      // convert to byte length\r
1546     add  s_pktCxt.startOffset, s_pktCxt.startOffset,   r1.w0\r
1547     mov  s_pktCxt6.l3offset2,  s_pktCxt6.l3l5Offset\r
1548     mov  s_pktCxt.l5Offset,    s_pktCxt.startOffset\r
1549 \r
1550     mov  s_param.action,  SUBS_ACTION_LOOKUP\r
1551     set  s_statsFlags.event.t_nTcp\r
1552     ret\r
1553 \r
1554     .leave cdeScope\r
1555     .leave pktScope\r
1556     .leave tcpScope\r
1557     .leave lut2Scope\r
1558     \r
1559 // ******************************************************************************************\r
1560 // * FUNCTION PURPOSE: Parse a GTPU header\r
1561 // ******************************************************************************************\r
1562 // * DESCRIPTION: The custom header fields are extracted, masked, and entered into the LUT\r
1563 // *\r
1564 // *    GTPU processing algorithm:\r
1565 // *        - Version <> 1 or PT <> ==> Error Queue\r
1566 // *        - Message Type 1,2, 26, 31 254 ==> User specified exception routes\r
1567 // *        - Message Type 255: TEID lookup\r
1568 // *           - If ext header present and it is not 0, or 0xc0 ==> Error Queue\r
1569 // *           - If ext header = 0xc0, but the next one is not 0 ==> Error Queue\r
1570 // *           - If ext header = 0xc0, Extract the PDU number to the pktCtx and set the corresponding flag\r
1571 // *           - TEID lookup\r
1572 // *\r
1573 // *    On entry:\r
1574 // *            - the CDE is at the start of the GTPU header\r
1575 // *            - r30.w0 has the function return address\r
1576 // *            - param.action has SUBS_ACTION_PARSE\r
1577 // *\r
1578 // *    On exit:\r
1579 // *            - param.action has SUBS_ACTION_LOOKUP  or SUBS_ACTION_EXIT\r
1580 // *            - the CDE is at the first byte after the GTP header and extention header only if loopkup is required\r
1581 // *            - startOffset is adjusted to the GTPU payload only if lookup is required\r
1582 // *            - s_next.Hdr is set as PA_HDR_UNKNOWN\r
1583 // *\r
1584 // *   Register Usage:  \r
1585 // * \r
1586 // *   R0:   \r
1587 // *   R1:   | scratch r1.b1 GTPU header size\r
1588 // *   R2:    \r
1589 // *   R3:\r
1590 // *   R4:   |  CDE commands\r
1591 // *   R5:   |                   | LUT2 search key\r
1592 // *   R6:     | GTPU header\r
1593 // *   R7:     |     \r
1594 // *   R8:     |     \r
1595 // *   R9:     |     \r
1596 // *   R10:         \r
1597 // *   R11:             \r
1598 // *   R12:     \r
1599 // *   R13:   \r
1600 // *   R14:     \r
1601 // *   R15:     \r
1602 // *   R16:     \r
1603 // *   R17:     \r
1604 // *   R18:   \r
1605 // *   R19:       \r
1606 // *   R20:\r
1607 // *   R21:\r
1608 // *   R22: \r
1609 // *   R23:\r
1610 // *   R24:\r
1611 // *   R25:\r
1612 // *   R26:  Packet ID\r
1613 // *   R27:\r
1614 // *   R28:  statistics  (s_statsFlags)                             -\r
1615 // *   R29:  c2RunContext (s_runCxt)                                -  Global Scope\r
1616 // *   R30:  w2-Error Index w0-function return address              -\r
1617 // *   R31:  System Flags (s_flags)                                 -\r
1618 // *\r
1619 // *****************************************************************************************\r
1620 \r
1621     .using cdeScope\r
1622     .using pktScope\r
1623     .using gtpScope\r
1624     .using lut2Scope\r
1625 \r
1626 f_c2ParseGtpu:\r
1627 \r
1628     // Record parsing GTP\r
1629     // TBD: no protocol bit available\r
1630     // set s_pktCxt.hdrBitmask_nextHdr.SUBS_PA_BIT_HEADER_TCP\r
1631     // TBD: It is set by the UDP or UDP-lite operation\r
1632     // mov s_pktCxt.l5Offset,    s_pktCxt.startOffset\r
1633     \r
1634     // Assume Error case\r
1635     and s_pktCxt2.eP1C2Id,   s_pktCxt2.eP1C2Id,  NOT_PKT2_EIDX_MASK\r
1636     mov s_param.action,      SUBS_ACTION_EXIT\r
1637     mov s_next.Hdr,          PA_HDR_UNKNOWN\r
1638     \r
1639     // Read in the GTPU header\r
1640     xin  XID_CDEDATA,  s_gtp,  SIZE(s_gtp)\r
1641     \r
1642     // Extract version number\r
1643     and  r1.b0, s_gtp.ctrl,  GTP_VER_MASK\r
1644     \r
1645     // Only version 1 should be handled\r
1646     qbeq    l_c2ParseGtpu1, r1.b0,  GTP_VER_GTP_V1 \r
1647         or  s_pktCxt2.eP1C2Id,  s_pktCxt2.eP1C2Id,  EROUTE_GTPU_FAIL << PKT2_EIDX_SHIFT\r
1648         ret  \r
1649       \r
1650 l_c2ParseGtpu1:  \r
1651     // Protocol Type must be 1\r
1652     qbbs    l_c2ParseGtpu2, s_gtp.ctrl.t_gtp_ctrl_pt_1  \r
1653         or  s_pktCxt2.eP1C2Id,  s_pktCxt2.eP1C2Id,  EROUTE_GTPU_FAIL << PKT2_EIDX_SHIFT\r
1654         ret  \r
1655         \r
1656 l_c2ParseGtpu2:\r
1657     qbne    l_c2ParseGtpu3, s_gtp.msgType,  255\r
1658 \r
1659 l_c2ParseGtpu2_0:    \r
1660         mov r1.b1, GTPV1_HEADER_LEN_BYTES \r
1661         and r1.b0, s_gtp.ctrl, GTP_CTRL_MASK \r
1662         \r
1663         qbeq l_c2ParseGtpu2_1,  r1.b0, 0\r
1664             // basic extension header exists \r
1665             add r1.b1, r1.b1, GTPV1_EXT_HDR_LEN_BYTES\r
1666             \r
1667             qbbc l_c2ParseGtpu2_1, s_gtp.ctrl.t_gtp_ctrl_extHdr\r
1668             // extension header exist\r
1669                 qbeq    l_c2ParseGtpu2_1, s_gtp.nextHdr, GTP_NEXTHDR_NONE \r
1670                 \r
1671                     qbne  l_c2ParseGtpu_Err, s_gtp.nextHdr, GTP_NEXTHDR_PDU_NUM  \r
1672                         // PDU header exists\r
1673                         qbne  l_c2ParseGtpu_Err, s_gtp.nextHdr2, GTP_NEXTHDR_NONE\r
1674                             // Process the PDU number\r
1675                             add r1.b1, r1.b1, GTPV1_EXT_HDR_LEN_BYTES\r
1676                             set s_pktCxt.flag.t_flag_gtpu_seqnum_present\r
1677                             sbco    s_gtp.pduNum,  cCdeOutPkt,  SIZE(s_pktDescr) + SIZE(s_pktCxt),  SIZE(s_gtp.pduNum)   \r
1678                             \r
1679                             // Pass Through for TEID lookup\r
1680                 \r
1681 l_c2ParseGtpu2_1:\r
1682         // Adjust the start offset to the GTPU paylaod    \r
1683         add  s_pktCxt.startOffset,  s_pktCxt.startOffset,  r1.b1\r
1684         \r
1685         // Advance past the end of the header \r
1686         mov  s_cdeCmdWd.operation,  CDE_CMD_WINDOW_ADVANCE\r
1687         mov  s_cdeCmdWd.byteCount,  r1.b1\r
1688         xout XID_CDECTRL,           s_cdeCmdWd,             SIZE(s_cdeCmdWd)\r
1689         \r
1690         // TEID lookup\r
1691         zero &s_l2Search2,   SIZE(s_l2Search2)\r
1692         mov  s_l2Search2.data,  s_gtp.teid\r
1693         qbbc l_c2ParseGtpu2_3,  s_runCxt.ctrlFlag.t_c2_GTPU_use_link\r
1694             lsl s_l2Search2.data,  s_gtp.teid, 8     \r
1695             qbbs l_c2ParseGtpu2_2, s_pktCxt.eP1C2IdIdx.t_vlinkEn\r
1696                 mov s_l2Search2.data.b0,    s_pktCxt2.IdIdx\r
1697                 jmp l_c2ParseGtpu2_3\r
1698 l_c2ParseGtpu2_2: \r
1699                 // Populate lookup using virtual link\r
1700                 mov s_l2Search2.data.b0, s_pktCxt.vLinkNum\r
1701                 or  s_l2Search2.data.b0, s_l2Search2.data.b0, 0xC0\r
1702 l_c2ParseGtpu2_3:        \r
1703         xout XID_LUT2CMD,  s_l2Search2,  SIZE(s_l2Search2)\r
1704         mov  s_param.action,    SUBS_ACTION_LOOKUP\r
1705         ret\r
1706     \r
1707         \r
1708 l_c2ParseGtpu3:\r
1709     qbne    l_c2ParseGtpu4, s_gtp.msgType,  1\r
1710         or  s_pktCxt2.eP1C2Id,  s_pktCxt2.eP1C2Id,  EROUTE_GTPU_MESSAGE_TYPE_1 << PKT2_EIDX_SHIFT\r
1711         ret  \r
1712          \r
1713 l_c2ParseGtpu4:\r
1714     qbne    l_c2ParseGtpu5, s_gtp.msgType,  2\r
1715         or  s_pktCxt2.eP1C2Id,  s_pktCxt2.eP1C2Id,  EROUTE_GTPU_MESSAGE_TYPE_2 << PKT2_EIDX_SHIFT\r
1716         ret  \r
1717 \r
1718 l_c2ParseGtpu5:\r
1719     qbne    l_c2ParseGtpu6, s_gtp.msgType,  26\r
1720         or  s_pktCxt2.eP1C2Id,  s_pktCxt2.eP1C2Id,  EROUTE_GTPU_MESSAGE_TYPE_26 << PKT2_EIDX_SHIFT\r
1721         ret  \r
1722 \r
1723 l_c2ParseGtpu6:\r
1724     qbne    l_c2ParseGtpu7, s_gtp.msgType, 31 \r
1725         or  s_pktCxt2.eP1C2Id,  s_pktCxt2.eP1C2Id,  EROUTE_GTPU_MESSAGE_TYPE_31 << PKT2_EIDX_SHIFT\r
1726         ret  \r
1727          \r
1728 l_c2ParseGtpu7:\r
1729     qbne    l_c2ParseGtpu_Err, s_gtp.msgType, 254\r
1730       // Check if the routing feature of treating End marker same as G-PDU is enabled\r
1731       qbbc  l_c2ParseGtpu7_0, s_runCxt.ctrlFlag.t_c2_GTPU_route_msg254_as_msg255\r
1732         // Route same as message 255 if the message type is 254\r
1733         jmp l_c2ParseGtpu2_0\r
1734 \r
1735 l_c2ParseGtpu7_0:\r
1736         or  s_pktCxt2.eP1C2Id,  s_pktCxt2.eP1C2Id,  EROUTE_GTPU_MESSAGE_TYPE_254 << PKT2_EIDX_SHIFT\r
1737         ret  \r
1738     \r
1739 l_c2ParseGtpu_Err:\r
1740         or  s_pktCxt2.eP1C2Id,  s_pktCxt2.eP1C2Id,  EROUTE_GTPU_FAIL << PKT2_EIDX_SHIFT\r
1741         ret  \r
1742 \r
1743     .leave cdeScope\r
1744     .leave pktScope\r
1745     .leave gtpScope\r
1746     .leave lut2Scope\r
1747 \r
1748 // ******************************************************************************************\r
1749 // * FUNCTION PURPOSE: Parse a custom header\r
1750 // ******************************************************************************************\r
1751 // * DESCRIPTION: The custom header fields are extracted, masked, and entered into the LUT\r
1752 // *\r
1753 // *   Register Usage:  \r
1754 // * \r
1755 // *   R0:   \r
1756 // *   R1:   | scratch\r
1757 // *   R2:    \r
1758 // *   R3:\r
1759 // *   R4:   |  CDE commands\r
1760 // *   R5:   |                   | LUT2 search key\r
1761 // *   R6:   | packet data ==> one byte at a time       \r
1762 // *   R7:          \r
1763 // *   R8:          \r
1764 // *   R9:          \r
1765 // *   R10:         \r
1766 // *   R11:             \r
1767 // *   R12:     \r
1768 // *   R13:   \r
1769 // *   R14:  | custom2 Control data   \r
1770 // *   R15:  |   \r
1771 // *   R16:  |   \r
1772 // *   R17:  |   \r
1773 // *   R18:   \r
1774 // *   R19:       \r
1775 // *   R20:\r
1776 // *   R21:\r
1777 // *   R22: \r
1778 // *   R23:\r
1779 // *   R24:\r
1780 // *   R25:\r
1781 // *   R26:  Packet ID\r
1782 // *   R27:\r
1783 // *   R28:  statistics  (s_statsFlags)                             -\r
1784 // *   R29:  c2RunContext (s_runCxt)                                -  Global Scope\r
1785 // *   R30:  w2-Error Index w0-function return address              -\r
1786 // *   R31:  System Flags (s_flags)                                 -\r
1787 // *\r
1788 // *****************************************************************************************\r
1789 \r
1790     .using cdeScope\r
1791     .using pktScope\r
1792     .using custC2Scope\r
1793     .using lut2Scope\r
1794 \r
1795 f_c2ParseCustom:\r
1796 \r
1797     set s_pktCxt.hdrBitmask_nextHdr.SUBS_PA_BIT_HEADER_CUSTOM\r
1798     \r
1799     // eIndex should stote the custom Index\r
1800     // offset = index * 16 + OFFSET_CUSTOM_C2\r
1801     // TBD: Should we do error check here?\r
1802     and   r1.b0,  s_pktCxt2.eP1C2Id,  PKT2_EIDX_MASK\r
1803     lsr   r1.b0,  r1.b0,  PKT2_EIDX_SHIFT \r
1804     lsl   r1.w0,  r1.b0,  4\r
1805     add   r1.w0,  r1.w0,  OFFSET_CUSTOM_C2 \r
1806     \r
1807 \r
1808     // Read the custom parse information from scratch\r
1809     lbco  s_c2Cust,  PAMEM_CONST_CUSTOM2,  r1.w0,  SIZE(s_c2Cust)\r
1810     \r
1811     add  s_pktCxt.startOffset,  s_pktCxt.startOffset,  s_c2Cust.hdrSize\r
1812     mov  s_pktCxt6.l3offset2,   s_pktCxt6.l3l5Offset\r
1813 \r
1814     // store the current offset, update while scrolling\r
1815     mov  r1.w0,                 0\r
1816     mov  s_cdeCmdWd.operation,  CDE_CMD_WINDOW_ADVANCE\r
1817 \r
1818     // Scroll to the first byte\r
1819     sub  s_cdeCmdWd.byteCount,  s_c2Cust.offset3,  r1.w0\r
1820     add  r1.w0,                 r1.w0,             s_cdeCmdWd.byteCount\r
1821     xout XID_CDECTRL,           s_cdeCmdWd,        SIZE(s_cdeCmdWd)\r
1822 \r
1823     // Get the byte, mask it and put it in place\r
1824     xin  XID_CDEDATA,   r6.b3,   1\r
1825     and  s_l2SCust.cb0, r6.b3,   s_c2Cust.bitMask3\r
1826     or   s_l2SCust.cb0, s_l2SCust.cb0,  s_c2Cust.bitSet \r
1827 \r
1828     // Next byte\r
1829     sub  s_cdeCmdWd.byteCount,  s_c2Cust.offset2,  r1.w0\r
1830     add  r1.w0,                 r1.w0,             s_cdeCmdWd.byteCount\r
1831     xout XID_CDECTRL,           s_cdeCmdWd,        SIZE(s_cdeCmdWd)\r
1832 \r
1833     // Get the byte, mask it and put it in place\r
1834     xin  XID_CDEDATA,   r6.b3,   1\r
1835     and  s_l2SCust.cb1, r6.b3,   s_c2Cust.bitMask2\r
1836 \r
1837     // Next byte\r
1838     sub  s_cdeCmdWd.byteCount,  s_c2Cust.offset1,  r1.w0\r
1839     add  r1.w0,                 r1.w0,             s_cdeCmdWd.byteCount\r
1840     xout XID_CDECTRL,           s_cdeCmdWd,        SIZE(s_cdeCmdWd)\r
1841 \r
1842     // Get the byte, mask it and put it in place\r
1843     xin  XID_CDEDATA,   r6.b3,   1\r
1844     and  s_l2SCust.cb2, r6.b3,   s_c2Cust.bitMask1\r
1845 \r
1846 \r
1847     // The last byte can be from the packet or it can be the PDSP ID and index\r
1848     // of the previous lookup. Assume it will use the idx and then \r
1849     // overwrite if the packet values are used\r
1850     mov s_l2SCust.cb3, s_pktCxt2.IdIdx\r
1851 \r
1852     qbbs l_c2ParseCustom1,   s_c2Cust.ctrlBitMap.t_lut2_custom_ctrl_use_link\r
1853 \r
1854         // Last byte\r
1855         sub  s_cdeCmdWd.byteCount,  s_c2Cust.offset0,  r1.w0\r
1856         add  r1.w0,                 r1.w0,             s_cdeCmdWd.byteCount\r
1857         xout XID_CDECTRL,           s_cdeCmdWd,        SIZE(s_cdeCmdWd)\r
1858 \r
1859         // Get the byte, mask it and put it in place\r
1860         xin  XID_CDEDATA,   r6.b3,   1\r
1861         and  s_l2SCust.cb3, r6.b3,   s_c2Cust.bitMask0\r
1862 \r
1863 l_c2ParseCustom1:\r
1864 \r
1865     xout XID_LUT2CMD,                  s_l2SCust,             SIZE(s_l2SCust)\r
1866     mov  s_param.action,               SUBS_ACTION_LOOKUP\r
1867     set  s_statsFlags.event.t_nCustom\r
1868     ret\r
1869 \r
1870 \r
1871     .leave cdeScope\r
1872     .leave pktScope\r
1873     .leave custC2Scope\r
1874     .leave lut2Scope\r
1875 \r
1876 \r
1877 // ***************************************************************************************\r
1878 // * FUNCTION PURPOSE: Parse a decoded ESP header\r
1879 // ***************************************************************************************\r
1880 // * DESCRIPTION: After (optional) authentication and decryption, the ESP header is\r
1881 // *              reparsed. the end offset must now point to the end of the ESP \r
1882 // *              trailer.\r
1883 // *\r
1884 // *   Register Usage:  \r
1885 // * \r
1886 // *   R0:    scratch\r
1887 // *   R1:    \r
1888 // *   R2:    \r
1889 // *   R3:\r
1890 // *   R4:   |  CDE commands\r
1891 // *   R5:   |                   | LUT2 search key\r
1892 // *   R6:          |  UDP header\r
1893 // *   R7:          |\r
1894 // *   R8:          \r
1895 // *   R9:          \r
1896 // *   R10:             \r
1897 // *   R11:             \r
1898 // *   R12:     \r
1899 // *   R13:   \r
1900 // *   R14:     \r
1901 // *   R15:     \r
1902 // *   R16:     \r
1903 // *   R17:     \r
1904 // *   R18:   \r
1905 // *   R19:       \r
1906 // *   R20:\r
1907 // *   R21:\r
1908 // *   R22: \r
1909 // *   R23:\r
1910 // *   R24:\r
1911 // *   R25:\r
1912 // *   R26:  Packet ID\r
1913 // *   R27:\r
1914 // *   R28:  statistics  (s_statsFlags)                             -\r
1915 // *   R29:  c2RunContext (s_runCxt)                                -  Global Scope\r
1916 // *   R30:  w2-Error Index w0-function return address              -\r
1917 // *   R31:  System Flags (s_flags)                                 -\r
1918 // *\r
1919 // *\r
1920 // **************************************************************************************/\r
1921 \r
1922     .using cdeScope\r
1923     .using pktScope\r
1924 \r
1925 f_c2ParseEspDec:\r
1926 \r
1927    // Read in the padlen (r0.b1) and protocol (r0.b0) fields at the end of the packet\r
1928    // Note: It should be the absolute offset including Packet descriptor, PS Info.\r
1929    // sub    r0.w2,   s_pktCxt.endOffset,  s_pktCxt.startOffset\r
1930    // Note: Both the size of packet descriptor and PS Info are constants \r
1931    //       We may need to enhance it for more general cases\r
1932    //add    r0.w2,   s_pktCxt.endOffset,  (32+24)  \r
1933    //sub    r0.w2,   r0.w2,               2\r
1934    add    r0.w2,   s_pktCxt.endOffset,  (32+32)-2\r
1935    lbco   r0.w0,   cCdeInPkt,           r0.w2,                  2\r
1936 \r
1937    // Note: the s_pktCtx.startOffset should already point to the next header \r
1938    //add  s_pktCxt.startOffset,  s_pktCxt.startOffset, ESP_HEADER_LEN_BYTES\r
1939    sub  s_pktCxt.endOffset,    s_pktCxt.endOffset,   r0.b1\r
1940    sub  s_pktCxt.endOffset,    s_pktCxt.endOffset,   2\r
1941 \r
1942    // Get the next header type and action from the protocol field\r
1943    lbco   r1.b0,             PAMEM_CONST_IP_PROTO,  r0.b0,   1\r
1944    and    s_next.Hdr,        r1.b0,                 0x3f\r
1945    // We just need to find the next header, action will be set according at the \r
1946    // next stage \r
1947    // lsr    s_param.action,    r1.b0,               6\r
1948    // mov    s_param.action,    SUBS_ACTION_PARSE \r
1949 \r
1950    ret\r
1951 \r
1952     .leave cdeScope\r
1953     .leave pktScope\r
1954 \r
1955 // *****************************************************************************************\r
1956 // * FUNCTION PURPOSE: Hold the command reply\r
1957 // *****************************************************************************************\r
1958 // * DESCRIPTION: Forwards the reply only if the destination is the host\r
1959 // *\r
1960 // *   Register Usage:  \r
1961 // * \r
1962 // *   R0:    w0 - the packet length (input)\r
1963 // *   R1:    \r
1964 // *   R2:    \r
1965 // *   R3:              \r
1966 // *   R4:    |  CDE commands     -  cdeScope\r
1967 // *   R5:    |                   -\r
1968 // *   R6:        |                                      \r
1969 // *   R7:        |                                      \r
1970 // *   R8:        |                                      \r
1971 // *   R9:        |  LUT1 View1   - lut1Scope\r
1972 // *   R10:       |\r
1973 // *   R11:       |\r
1974 // *   R12:       |\r
1975 // *   R13:       |\r
1976 // *   R14:          |                                          \r
1977 // *   R15:          |                                          \r
1978 // *   R16:          |                                          \r
1979 // *   R17:          |  LUT1 View2  - lut1Scope                 \r
1980 // *   R18:          |\r
1981 // *   R19:          |\r
1982 // *   R20:          |\r
1983 // *   R21:          |\r
1984 // *   R22:     |     \r
1985 // *   R23:     |  Packet context - pktScope   \r
1986 // *   R24:     |\r
1987 // *   R25:     |\r
1988 // *   R26:     |  b3: ctrlFlag, b2:command result offset < 256: w0: pktId\r
1989 // *   R27:\r
1990 // *   R28:  statistics  (s_statsFlags)                             -\r
1991 // *   R29:  c1RunContext (s_runCxt)                                -  Global Scope\r
1992 // *   R30:  w2-param.action  w0-function return address            -\r
1993 // *   R31:  System Flags (s_flags)                                 -\r
1994 // *\r
1995 // *****************************************************************************************/\r
1996 // dumy function\r
1997 f_cfgReplyHoldPkt:\r
1998         ret\r
1999         \r
2000 \r
2001 #include "pacfgcmn.p"\r