1 // *********************************************************************************************************
2 // * FILE PURPOSE: Perform packet classification on PDSPS with a LUT2
3 // *********************************************************************************************************
4 // * FILE NAME: classify2.p
5 // *
6 // * DESCRIPTION: The PDSP code for L4 classification using a LUT2
7 // *
8 // *********************************************************************************************************/
9 //
10 // TEXAS INSTRUMENTS TEXT FILE LICENSE
11 //
12 // Copyright (c) 2016 Texas Instruments Incorporated
13 //
14 // All rights reserved not granted herein.
15 //
16 // Limited License.
17 //
18 // Texas Instruments Incorporated grants a world-wide, royalty-free, non-exclusive
19 // license under copyrights and patents it now or hereafter owns or controls to
20 // make, have made, use, import, offer to sell and sell ("Utilize") this software
21 // subject to the terms herein. With respect to the foregoing patent license,
22 // such license is granted solely to the extent that any such patent is necessary
23 // to Utilize the software alone. The patent license shall not apply to any
24 // combinations which include this software, other than combinations with devices
26 //
27 // Redistributions must preserve existing copyright notices and reproduce this license
28 // (including the above copyright notice and the disclaimer and (if applicable) source
29 // code license limitations below) in the documentation and/or other materials provided
30 // with the distribution.
31 //
32 // Redistribution and use in binary form, without modification, are permitted provided
33 // that the following conditions are met:
34 // No reverse engineering, decompilation, or disassembly of this software is
35 // permitted with respect to any software provided in binary form.
36 // Any redistribution and use are licensed by TI for use only with TI Devices.
37 // Nothing shall obligate TI to provide you with source code for the software
38 // licensed and provided to you in object code.
39 //
40 // If software source code is provided to you, modification and redistribution of the
41 // source code are permitted provided that the following conditions are met:
42 // Any redistribution and use of the source code, including any resulting derivative
43 // works, are licensed by TI for use only with TI Devices.
44 // Any redistribution and use of any object code compiled from the source code
45 // and any resulting derivative works, are licensed by TI for use only with TI Devices.
46 //
47 // Neither the name of Texas Instruments Incorporated nor the names of its suppliers
48 // may be used to endorse or promote products derived from this software without
49 // specific prior written permission.
50 //
51 // DISCLAIMER.
52 //
53 // THIS SOFTWARE IS PROVIDED BY TI AND TI\92S LICENSORS "AS IS" AND ANY EXPRESS OR IMPLIED
54 // WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
55 // AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL TI AND TI\92S
56 // LICENSORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
57 // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
58 // GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
59 // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
60 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
61 // EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
62 //
63 //
64 //
65 #define PASS_CLASSIFY2 1
66 #include "pdsp_pa.h"
67 #include "pdsp_mem.h"
68 #include "pdsp_subs.h"
69 #include "pm_config.h"
70 #include "pdsp_ver.h"
71 #include "pm_constants.h"
72 #include "parsescope.h"
74 #define PASS_C2_VER PASS_VERSION // 0x01.0x00.0x00.0x03
76 .origin 0
77 .entrypoint f_c2Init
79 f_c2Init:
80 jmp f_c2Start
82 header:
83 .codeword HEADER_MAGIC
84 .codeword PASS_C2_VER
86 .using globalScopeC2
88 #include "meminit.p"
90 f_c2Start:
92 call f_c2LocalInit
94 // Clear the mailbox
95 zero &r2, 12
96 sbco r2, cMailbox, 4, 12
98 // Write a non-zero value to mailbox slot 0.
99 mov r2, 1
100 sbco r2, cMailbox, 0, 4
102 // Wait for the set command to take hold
103 wbs s_flags.info.tStatus_Command0
105 // The host will clear mailbox slot 0 when it is ready for this PDSP to run
106 wbc s_flags.info.tStatus_Command0
108 // Do common initialization if the host has requested it
109 // The host requests a global init by writing a non-zero value into mailbox slot 1
110 // (Before clearing mailbox slot 0)
111 // qbbc l_c2Start0, s_flags.info.tStatus_Command1
113 // Note: The first PDSP at each stage should perform global init
114 #ifdef PASS_GLOBAL_INIT
115 call f_commonInit
116 #endif
118 //mov r2, 0
119 //sbco r2, cMailbox, 4, 4 // Clear the mailbox
121 l_c2Start0:
123 zero &s_runCxt, SIZE(s_runCxt)
125 // Store the PDSP ID
126 mov r2.b0, PASS_PDSP_ID
127 sbco r2.b0, PAMEM_CONST_PDSP_INFO, OFFSET_ID, 1
130 // Store the version number
131 mov r2.w0, PASS_C2_VER & 0xFFFF
132 mov r2.w2, PASS_C2_VER >> 16
133 sbco r2, PAMEM_CONST_PDSP_INFO, OFFSET_VER, 4
135 // *****************************************************************************************
136 // * FUNCTION PURPOSE: The main processing loop
137 // *****************************************************************************************
138 // * DESCRIPTION: The packet processing state machine
139 // *
140 // * Register usage:
141 // *
142 // * R0:
143 // * R1:
144 // * R2:
145 // * R3:
146 // * R4:
147 // * R5:
148 // * R6:
149 // * R7:
150 // * R8:
151 // * R9:
152 // * R10:
153 // * R11:
154 // * R12:
155 // * R13:
156 // * R14: | (packet extended descriptor)
157 // * R15: |
158 // * R16: |
159 // * R17: |
160 // * R18: |
161 // * R19:
162 // * R20:
163 // * R21:
164 // * R22: |
165 // * R23: | Packet context - pktScope
166 // * R24: |
167 // * R25: |
168 // * R26: |
169 // * R27: |
170 // * R28:
171 // * R29: c2RunContext (s_runCxt) - Global Scope
172 // * R30: w2-unused w0-function return address -
173 // * R31: System Flags (s_flags) -
174 // *
175 // ***********************************************************************************
178 f_mainLoop:
179 fci_mainLoop7: // For compatibility with classify1.p
181 #ifdef PASS_PROC_CMD1
182 // Look for command
183 qbbc l_mainLoop0_1, s_flags.info.tStatus_Command1
184 #ifdef PASS_PROC_EOAM_CMD
185 // Process EOAM config command
186 lbco r1, cMailbox, FIRMWARE_CMD_EOAM_CFG_OFFSET, 4
187 qbne l_mainLoop_not_eoamcfg, r1.b3, FIRMWARE_CMD_EOAM_CFG
188 // Clear the valid bit fields
189 not r1.b2, r1.b1
190 // force clear valid bits to zero and retain valid bits positions
191 and s_runCxt.flags, s_runCxt.flags, r1.b2
193 // set the run time flags
194 or s_runCxt.flags, s_runCxt.flags, r1.b0
196 // clear the command flag
197 mov r1, 0
198 sbco r1, cMailbox, FIRMWARE_CMD_EOAM_CFG_OFFSET, 4
199 l_mainLoop_not_eoamcfg:
200 #endif
201 l_mainLoop0_1:
202 #endif
203 f_mainLoop0:
204 qbbc f_mainLoop, s_flags.info.tStatus_CDENewPacket
206 // Fall through to f_c2Parse
208 // **************************************************************************************
209 // * FUNCTION PURPOSE: Begin parsing a packet
210 // **************************************************************************************
211 // * DESCRIPTION: A new packet ID is assigned and a packet parse is begun
212 // *
213 // * Register Usage:
214 // *
215 // * R0:
216 // * R1:
217 // * R2:
218 // * R3:
219 // * R4: | CDE commands - cdeScope
220 // * R5: | -
221 // * R6: |
222 // * R7: |
223 // * R8: |
224 // * R9: |
225 // * R10: |
226 // * R11: |
227 // * R12: |
228 // * R13: |
229 // * R14: | (packet extended descriptor)
230 // * R15: |
231 // * R16: |
232 // * R17: |
233 // * R18: |
234 // * R19:
235 // * R20:
236 // * R21:
237 // * R22: |
238 // * R23: | Packet context - pktScope
239 // * R24: |
240 // * R25: |
241 // * R26: |
242 // * R27: |
243 // * R28:
244 // * R29: c2RunContext (s_runCxt) - Global Scope
245 // * R30: w2 - param.action w0-function return address -
246 // * R31: System Flags (s_flags) -
247 // *
248 // ****************************************************************************************
250 .using pktScope
251 .using cdeScope
252 .using currentFwdScope
254 f_c2Parse:
256 // packet counter
257 lbco r1, cMailbox, 0, 4
258 add r1, r1, 1
259 sbco r1, cMailbox, 0, 4
261 // Read the descriptor
262 xin XID_CDEDATA, s_pktDescr, SIZE(s_pktDescr)
264 // Read packet extended info
265 xin XID_PINFO_SRC, s_pktExtDescr, SIZE(s_pktExtDescr)
267 // TBD: check drop/bypass flag
268 // jmp to skip operation
269 qbbc l_c2Parse1, s_pktDescr.pktFlags.t_pktBypass
270 // Advance to the control section to read the packet context
271 mov s_cdeCmdWd.operation, CDE_CMD_ADVANCE_TO_END
272 xout XID_CDECTRL, s_cdeCmdWd, SIZE(s_cdeCmdWd)
273 jmp f_c2ForwardPkt
275 l_c2Parse1:
276 l_c2Parse2:
277 l_c2Parse3:
279 mov s_stats.value, PA_STATS_UPDATE_REQ | PA_STATS_C2_N_PKTS
282 // Advance to the control section to read the packet context
283 mov s_cdeCmdWd.operation, CDE_CMD_ADVANCE_TO_CONTROL
284 xout XID_CDECTRL, s_cdeCmdWd, 4
286 // Insert 32 bytes of PS info
287 // This is legal even though the window has advanced to control
288 //mov s_cdeInsert.operation, CDE_CMD_INSERT_PSDATA
289 //mov s_cdeInsert.byteCount, 32
290 ldi r4, CDE_CMD_INSERT_PSDATA | (32 << 8)
291 xout XID_CDECTRL, s_cdeCmdWd, 4
293 // Read in the whole packet context.
294 // There is no cost if this is not a data packet
295 xin XID_CDEDATA, s_pktCxt, SIZE(s_pktCxt)
297 // There must be a command in the control section for packets
298 qbne l_c2Parse4, s_pktDescr.ctrlDataSize, 0
299 // Load the error routing info for this error type
300 // There was invalid data in the packet context. Record a system error
301 // and route the packet as a system error packet.
302 and s_pktCxt.eId_portNum_nextHdr.b1, s_pktCxt.eId_portNum_nextHdr.b1, NOT_PKT_EIDX_MASK
303 or s_pktCxt.eId_portNum_nextHdr.b1, s_pktCxt.eId_portNum_nextHdr.b1, EROUTE_SYSTEM_FAIL << PKT_EIDX_SHIFT
304 mov s_stats.value, PA_STATS_UPDATE_REQ | PA_STATS_C2_INVALID_CONTROL
306 jmp f_c2ForwardErr
308 l_c2Parse4:
310 #ifdef PASS_VERIFY_SCTP_CRC
312 qbbc l_c2Parse4_1, s_pktCxt.flags.t_flag_crc_verify
313 // SCTP CRC Verification
314 jmp f_paSctpVerifyCRC // No return
316 l_c2Parse4_1:
318 #endif
320 // extract the command ID
321 lsr r1.b0, s_pktCxt.paCmdId_Length, SUBS_CMD_WORD_ID_SHIFT
323 qbeq l_c2Parse6, r1.b0, PSH_CMD_PA_RX_PARSE
324 qbeq f_paConfigure, r1.b0, PSH_CMD_CONFIG
326 l_c2Parse5:
327 // This pdsp requires that the packet have a command word. No valid
328 // command was found, the packet must be discarded.
329 mov s_stats.value, PA_STATS_UPDATE_REQ | PA_STATS_C2_DISCARD
330 // TBD: drop bad packet (bypass)
331 set s_pktExtDescr.flags.fDroppedInd
332 //mov s_cdeCmdPkt.operation, CDE_CMD_PACKET_FLUSH
333 //xout XID_CDECTRL, s_cdeCmdPkt, SIZE(s_cdeCmdPkt)
334 jmp f_c2ForwardPkt
336 l_c2Parse6:
337 // The next header type is stored in 8 bit format during the parse
338 and s_next.Hdr, s_pktCxt.eId_portNum_nextHdr.b0, 0x3f
340 // Clear any values in the error index if not custom
341 qbeq l_c2Parse7, s_next.Hdr, PA_HDR_CUSTOM_C2
342 and s_pktCxt.eId_portNum_nextHdr.b1, s_pktCxt.eId_portNum_nextHdr.b1, NOT_PKT_EIDX_MASK
344 l_c2Parse7:
345 // Delete the control info. It will be replaced with new data
346 // in protocol specific when the packet is forwarded
347 //mov s_cdeCmdWd.operation, CDE_CMD_FLUSH_TO_PACKET
348 //xout XID_CDECTRL, s_cdeCmdWd, SIZE(s_cdeCmdWd)
349 // Delete only the pktCxt from the control info
350 mov s_cdeCmdWd.operation, CDE_CMD_FLUSH
351 mov s_cdeCmdWd.byteCount, (SIZE(s_pktCxt) + 7) & 0xf8 // Round up to multiple of 8 bytes
352 xout XID_CDECTRL, s_cdeCmdWd, 4
354 mov s_cdeCmdWd.operation, CDE_CMD_ADVANCE_TO_PACKET
355 xout XID_CDECTRL, s_cdeCmdWd, 4
357 // Advance the CDE to the first byte to examine in the packet
358 mov s_cdeCmdWd.operation, CDE_CMD_WINDOW_ADVANCE
359 mov s_cdeCmdWd.byteCount, s_pktCxt.startOffset
360 xout XID_CDECTRL, s_cdeCmdWd, SIZE(s_cdeCmdWd)
362 mov s_param.action, SUBS_ACTION_PARSE
364 // save Extended Header to be examined later
365 xout XID_PINFO_A, s_pktExtDescr, SIZE(s_pktExtDescr)
367 // Convert an PA_HDR_ESP_DECODED header type to C2 version
368 qbne l_c2Parse8, s_next.hdr, PA_HDR_ESP_DECODED
369 mov s_next.hdr, PA_HDR_ESP_DECODED_C2
371 l_c2Parse8:
372 qbge l_c2Parse9, s_next.hdr, PA_HDR_UNKNOWN
373 qbge l_c2Parse10_1, s_next.hdr, PA_HDR_CUSTOM_C2
375 l_c2Parse9:
376 // The header type was not valid for classify2
377 // The header type can not be processed by classify2, use next fail route
378 // Note: It is not a parsing error exception
379 // Need a return address
380 mov r30.w0, f_mainLoop
381 // store innerIP offset
382 mov s_pktCxt5.l3offset2, s_pktCxt5.l3l5Offset
383 // Patch the context back to the packet
384 wbs s_flags.info.tStatus_CDEOutPacket
385 sbco s_pktCxt, cCdeOutPkt, SIZE(s_pktDescr), SIZE(s_pktCxt)
386 jmp f_c2ForwardNoMatch
389 // The main loop
390 // Multiple parses are only possible because a ESP_DECODED and UDP parse can
391 // trigger a change into other type
393 l_c2Parse10:
395 //
396 // General Error check to avoid infinite loop
397 // r28.b3: previous startOffset
398 //
399 qbge l_c2Parse10_1, r28.b3, s_pktCxt.startOffset
400 and s_pktCxt.eId_portNum_nextHdr.b1, s_pktCxt.eId_portNum_nextHdr.b1, NOT_PKT_EIDX_MASK
401 or s_pktCxt.eId_portNum_nextHdr.b1, s_pktCxt.eId_portNum_nextHdr.b1, EROUTE_PARSE_FAIL << PKT_EIDX_SHIFT
402 mov s_param.action, SUBS_ACTION_EXIT
403 jmp l_c2Parse11_1
405 l_c2Parse10_1:
406 mov r28.b3, s_pktCxt.startOffset
407 lsl r0.b0, s_next.Hdr, 1
408 lbco r0.w2, PAMEM_CONST_PARSE, r0.b0, 2
409 call r0.w2
410 qbeq l_c2Parse10, s_param.action, SUBS_ACTION_PARSE
412 l_c2Parse11:
413 // Put the next header type back into the context
414 and s_pktCxt.eId_portNum_nextHdr.b0, s_pktCxt.eId_portNum_nextHdr.b0, 0xc0
415 or s_pktCxt.eId_portNum_nextHdr.b0, s_pktCxt.eId_portNum_nextHdr.b0, s_next.Hdr
417 l_c2Parse11_1:
418 // Patch the context back to the packet
419 // Restore the latest extended Packet Info
420 xin XID_PINFO_A, s_pktExtDescr, SIZE(s_pktExtDescr)
421 wbs s_flags.info.tStatus_CDEOutPacket
422 sbco s_pktCxt, cCdeOutPkt, SIZE(s_pktDescr), SIZE(s_pktCxt)
424 qbne l_c2Parse12, s_param.action, SUBS_ACTION_LOOKUP
425 // The lookup was initiated in the parse. Wait for the lookup to complete
426 // Should there be a timeout here?
427 wbc s_flags.info.tStatus_Lut2LookupBusy
429 // Forward the results
430 // Need a return address
431 mov r30.w0, f_mainLoop
432 qbbs f_c2ForwardMatch, s_flags.info.tStatus_Lut2MatchData
433 jmp f_c2ForwardNoMatch
435 l_c2Parse12:
436 // Exception handling
437 // No Lookup required. Forward the packet based on the exception index
438 jmp f_c2ForwardErr
440 .leave currentFwdScope
441 .leave pktScope
442 .leave cdeScope
444 // ***************************************************************************************
445 // * FUNCTION PURPOSE: Forward a packet that matched LUT2 lookup
446 // ***************************************************************************************
447 // * DESCRIPTION: The forwarding information from the table is used to forward
448 // * the packet
449 // *
450 // * Register Usage:
451 // *
452 // * R0:
453 // * R1:
454 // * R2:
455 // * R3: | bit mask for stat to update on silent discard
456 // * R4: | CDE commands - cdeScope
457 // * R5: | -
458 // * R6: |
459 // * R7: | Current Packet Forwarding info
460 // * R8: |
461 // * R9: |
462 // * R10:
463 // * R11:
464 // * R12:
465 // * R13: -
466 // * R14: | (packet extended descriptor)
467 // * R15: |
468 // * R16: |
469 // * R17: |
470 // * R18: |
471 // * R19:
472 // * R20:
473 // * R21:
474 // * R22: |
475 // * R23: | Packet context - pktScope
476 // * R24: |
477 // * R25: |
478 // * R26: |
479 // * R27: |
480 // * R28:
481 // * R29: c2RunContext (s_runCxt) - Global Scope
482 // * R30: w2-Error Index w0-function return address -
483 // * R31: System Flags (s_flags) -
484 // *
485 // **************************************************************************************
487 .using cdeScope
488 .using currentFwdScope
489 .using pktScope
491 f_c2ForwardMatch:
493 // Get the match info
494 xin XID_LUT2DATA, s_curFmPlace, SIZE(s_curFmPlace)
496 // Set the bitmask for silent discard (credit to classify2)
497 mov r3.w0, PA_STATS_UPDATE_REQ | PA_STATS_C2_DISCARD
499 mov r30.w0, f_mainLoop // return address
500 jmp f_curPktForward
502 .leave cdeScope
503 .leave currentFwdScope
504 .leave pktScope
506 // **************************************************************************************
507 // * FUNCTION PURPOSE: Forward a packet that did not match
508 // **************************************************************************************
509 // * DESCRIPTION: On match fail the packet is forwarded if previous match information
510 // * is available, otherwise it is discarded.
511 // *
512 // * Register Usage:
513 // *
514 // * R0:
515 // * R1:
516 // * R2:
517 // * R3: | bit mask for stat to update on silent discard
518 // * R4:
519 // * R5:
520 // * R6: |
521 // * R7: | Current Packet Forwarding info
522 // * R8: |
523 // * R9: |
524 // * R10:
525 // * R11:
526 // * R12:
527 // * R13:
528 // * R14: | (packet extended descriptor)
529 // * R15: |
530 // * R16: |
531 // * R17: |
532 // * R18: |
533 // * R19:
534 // * R20:
535 // * R21:
536 // * R22: |
537 // * R23: | Packet context - pktScope
538 // * R24: |
539 // * R25: |
540 // * R26: |
541 // * R27: |
542 // * R28:
543 // * R29: c2RunContext (s_runCxt) - Global Scope
544 // * R30: w2-Error Index w0-function return address -
545 // * R31: System Flags (s_flags) -
546 // *
547 // **************************************************************************************
549 .using pktScope
550 .using currentFwdScope
551 .using lut1MatchScope
553 f_c2ForwardNoMatch:
554 // Must read the match data even if there was no match - to re-enable the LUT2 search
555 xin XID_LUT2DATA, s_curFmPlace, SIZE(s_curFmPlace)
557 qbbc l_c2ForwardNoMatch_NotGTPU, s_pktCxt.hdrBitmask.SUBS_PA_BIT_HEADER_GTPU
558 and s_pktCxt.eId_portNum_nextHdr.b1, s_pktCxt.eId_portNum_nextHdr.b1, NOT_PKT_EIDX_MASK
559 or s_pktCxt.eId_portNum_nextHdr.b1, s_pktCxt.eId_portNum_nextHdr.b1, EROUTE_GTPU_MATCH_FAIL << PKT_EIDX_SHIFT
561 // prepare r1.w0, load the exception route
562 // check to see if discard
563 // true then jump to notgtpu
564 // false then
566 mov r1.w0, EROUTE_GTPU_MATCH_FAIL * 16
568 lbco s_curFmPlace, PAMEM_CONST_EROUTE, r1.w0, SIZE(s_curFmPlace)
570 qbeq l_c2ForwardNoMatch_NotGTPU, s_curFwd.forwardType, PA_FORWARD_TYPE_DISCARD
572 //store the exception ID only if it is used
573 sbco s_pktCxt.eId_portNum_nextHdr, cCdeOutPkt, SIZE(s_pktDescr)+OFFSET(s_pktCxt.eId_portNum_nextHdr), 2
574 jmp fci_c2ForwardErr_2
576 l_c2ForwardNoMatch_NotGTPU:
578 qbbs l_c2ForwardNoMatch0, s_pktCxt.flags.t_flag_pl1Match
580 // No previous match indicated. Set the error field and route based on the error
581 and s_pktCxt.eId_portNum_nextHdr.b1, s_pktCxt.eId_portNum_nextHdr.b1, NOT_PKT_EIDX_MASK
582 or s_pktCxt.eId_portNum_nextHdr.b1, s_pktCxt.eId_portNum_nextHdr.b1, EROUTE_LUT2_FAIL << PKT_EIDX_SHIFT
583 sbco s_pktCxt.eId_portNum_nextHdr, cCdeOutPkt, SIZE(s_pktDescr)+OFFSET(s_pktCxt.eId_portNum_nextHdr), 2
584 jmp f_c2ForwardErr
586 l_c2ForwardNoMatch0:
588 // Use the previous lut1 match info to forward the packet
589 // Extract the LUT1 index number, multiply by 32 to get memory offset
590 // In the case of a previous match, the previous match routing information
591 // must be loaded into the matchForward context
592 lsr r1.b2, s_pktCxt.phyLink, PKT_PDSP_ID_SHIFT // Get PDSP ID
593 mov r1.w0, s_pktCxt.phyLink
594 and r1.b1, r1.b1, PKT_L1IDX_MASK
595 lsl r1.w0, r1.w0, 6 // get the associated table offset
597 lsl r1.b2, r1.b2, 2 // PDSP ID * 4 = offset to the nextFail table base address
598 lbco r2, PAMEM_CONST_NFAIL_BASE, r1.b2, 4
600 //Load the nextfail routing information
601 lbbo s_curFmPlace, r2, r1.w0, SIZE(s_curFmPlace)
602 // Store the stat for silent discard
603 mov r3.w0, PA_STATS_UPDATE_REQ | PA_STATS_C2_DISCARD
605 jmp f_curPktForward
607 .leave lut1MatchScope
608 .leave pktScope
609 .leave currentFwdScope
612 // ********************************************************************************************
613 // * FUNCTION PURPOSE: Forward a packet based on the error index information
614 // ********************************************************************************************
615 // * DESCRIPTION: The error index is used to extract the routing information and forward
616 // * the packet
617 // *
618 // * Register Usage:
619 // *
620 // * R0:
621 // * R1:
622 // * R2:
623 // * R3: | bit mask for stat to update on silent discard
624 // * R4:
625 // * R5:
626 // * R6: |
627 // * R7: | Current Packet Forwarding info
628 // * R8: |
629 // * R9: |
630 // * R10:
631 // * R11:
632 // * R12:
633 // * R13:
634 // * R14: | (packet extended descriptor)
635 // * R15: |
636 // * R16: |
637 // * R17: |
638 // * R18: |
639 // * R19:
640 // * R20:
641 // * R21:
642 // * R22: |
643 // * R23: | Packet context - pktScope
644 // * R24: |
645 // * R25: |
646 // * R26: |
647 // * R27: |
648 // * R28:
649 // * R29: c2RunContext (s_runCxt) - Global Scope
650 // * R30: w2-Error Index w0-function return address -
651 // * R31: System Flags (s_flags) -
652 // *
653 // ****************************************************************************************************
655 .using pktScope
656 .using currentFwdScope
658 f_c2ForwardErr:
660 // Get the error index, multiply by 16 to get the memory offset
661 // Load the error routing information
662 lsr r30.w2, s_pktCxt.eId_portNum_nextHdr.b1, PKT_EIDX_SHIFT
663 lsl r30.w2, r30.w2, 4
665 lbco s_curFmPlace, PAMEM_CONST_EROUTE, r30.w2, SIZE(s_curFmPlace)
667 fci_c2ForwardErr_2:
669 l_c2ForwardErr_2:
670 // Get the bitfield mask for silent discard for classify2
671 mov r3.w0, PA_STATS_UPDATE_REQ | PA_STATS_C2_DISCARD
673 // Need a return address
674 mov r30.w0, f_mainLoop
675 jmp f_curPktForward
678 .leave pktScope
679 .leave currentFwdScope
682 // ********************************************************************************************
683 // * FUNCTION PURPOSE: Forward a packet without routing information
684 // ********************************************************************************************
685 // * DESCRIPTION: Forward a byapps or dropped packet
686 // *
687 // * Register Usage:
688 // *
689 // * R0:
690 // * R1:
691 // * R2:
692 // * R3: | bit mask for stat to update on silent discard
693 // * R4:
694 // * R5:
695 // * R6: |
696 // * R7: |
697 // * R8: |
698 // * R9: |
699 // * R10:
700 // * R11:
701 // * R12:
702 // * R13:
703 // * R14: | (packet extended descriptor)
704 // * R15: |
705 // * R16: |
706 // * R17: |
707 // * R18: |
708 // * R19:
709 // * R20:
710 // * R21:
711 // * R22: |
712 // * R23: | Packet context - pktScope
713 // * R24: |
714 // * R25: |
715 // * R26: |
716 // * R27: |
717 // * R28:
718 // * R29: c2RunContext (s_runCxt) - Global Scope
719 // * R30: w2-Error Index w0-function return address -
720 // * R31: System Flags (s_flags) -
721 // *
722 // ****************************************************************************************************
724 .using pktScope
725 .using currentFwdScope
726 .using cdeScope
728 f_c2ForwardPkt:
729 // TBD: packet could be too small to trigger the output ready flag.
730 // wbs s_flags.info.tStatus_CDEOutPacket
731 wbc s_flags.info.tStatus_CDEBusy
732 lbco s_pktDescr.pktFlags, cCdeOutPkt, OFFSET(s_pktDescr.pktFlags), SIZE(s_pktDescr.pktFlags)
733 mov s_cdeCmdPkt.operation, CDE_CMD_PACKET_ADVANCE
734 mov s_cdeCmdPkt.optionsFlag, 0
736 #ifdef PASS_LAST_PDSP
737 // Clear Bypass Flag
738 clr s_pktDescr.pktFlags.t_pktBypass
739 qbbc l_c2ForwardPkt_1, s_pktExtDescr.flags.fDroppedInd
740 set s_pktExtDescr.flags.fDropped
741 //clr s_pktExtDescr.flags.fDroppedInd
742 mov s_cdeCmdPkt.operation, CDE_CMD_PACKET_FLUSH
743 #else
744 set s_pktDescr.pktFlags.t_pktBypass
745 #endif
747 l_c2ForwardPkt_1:
748 sbco s_pktDescr.pktFlags, cCdeOutPkt, OFFSET(s_pktDescr.pktFlags), SIZE(s_pktDescr.pktFlags)
749 xout XID_PINFO_DST, s_pktExtDescr, SIZE(s_pktExtDescr)
751 xout XID_CDECTRL, s_cdeCmdPkt, SIZE(s_cdeCmdPkt)
752 jmp f_mainLoop
754 .leave pktScope
755 .leave currentFwdScope
756 .leave cdeScope
758 // *****************************************************************************************************
759 // * FUNCTION PURPOSE: Process an add/modify or delete LUT1 command
760 // *****************************************************************************************************
761 // * DESCRIPTION: These commands are invalid for PDSPs with a classify2
762 // *
763 // * Register Usage:
764 // *
765 // * R0: w0 - the packet length
766 // * R1:
767 // * R2:
768 // * R3:
769 // * R4: | CDE commands
770 // * R5: |
771 // * R6:
772 // * R7:
773 // * R8:
774 // * R9:
775 // * R10:
776 // * R11:
777 // * R12:
778 // * R13:
779 // * R14: | (packet extended descriptor)
780 // * R15: |
781 // * R16: |
782 // * R17: |
783 // * R18: |
784 // * R19:
785 // * R20:
786 // * R21:
787 // * R22: |
788 // * R23: | Packet context - pktScope
789 // * R24: |
790 // * R25: |
791 // * R26: |
792 // * R27: |
793 // * R28:
794 // * R29: c2RunContext (s_runCxt) - Global Scope
795 // * R30: w2-Error Index w0-function return address -
796 // * R31: System Flags (s_flags) -
797 // *
798 // ************************************************************************************************
799 .using configScope
800 .using cdeScope
802 f_paComAddRepLut1:
803 f_paComDelLut1:
805 mov s_paCmd1.commandResult, PA_COMMAND_RESULT_INVALID_DESTINATION
806 xout XID_CDEDATA, s_paCmd1.commandResult, SIZE(s_paCmd1.commandResult)
807 jmp f_cfgReply
809 .leave configScope
810 .leave cdeScope
812 // ************************************************************************************************
813 // * FUNCTION PURPOSE: Add or modify an entry in LUT2
814 // ************************************************************************************************
815 // * DESCRIPTION: A new entry is added to the lut
816 // *
817 // * Register Usage:
818 // *
819 // * R0: w0 - the packet length
820 // * R1:
821 // * R2:
822 // * R3: queueDivert Info
823 // * R4: | CDE commands
824 // * R5: |
825 // * R6: | Command header (entry)
826 // * R7: |
827 // * R8: |
828 // * R9: |
829 // * R10: | Add LUT2 command
830 // * R11: |
831 // * R12: |
832 // * R13:
833 // * R14: | LUT2 routing data0
834 // * R15: | LUT2 data1
835 // * R16: | LUT2 data2
836 // * R17: | LUT2 data3
837 // * R18: | LUT2 queueDivert
838 // * R19: | LUT2 control
839 // * R20:
840 // * R21:
841 // * R22: |
842 // * R23: | Packet context - pktScope
843 // * R24: |
844 // * R25: |
845 // * R26: |
846 // * R27: |
847 // * R28:
848 // * R29: c2RunContext (s_runCxt) - Global Scope
849 // * R30: w2-Error Index w0-function return address -
850 // * R31: System Flags (s_flags) -
851 // *
852 // *******************************************************************************************
853 .using cdeScope
854 .using configScope
855 .using lut2Scope
856 .using pktScope
858 f_paComAddRepLut2:
860 // If there is an active add or delete the command must be rejected
861 qbbc l_paComAddRepLut2_check_full, s_flags.info.tStatus_Lut2AddDelBusy
863 mov s_paCmd1.commandResult, PA_COMMAND_RESULT_LUT2_ADD_BUSY
864 xout XID_CDEDATA, s_paCmd1.commandResult, SIZE(s_paCmd1.commandResult)
865 jmp f_cfgReply
867 l_paComAddRepLut2_check_full:
868 // If there is an active add or delete the command must be rejected
869 qbbc l_paComAddRepLut2_a, s_flags.info.tStatus_Lut2Full
870 mov s_paCmd1.commandResult, PA_COMMAND_RESULT_LUT2_FULL
871 xout XID_CDEDATA, s_paCmd1.commandResult, SIZE(s_paCmd1.commandResult)
872 jmp f_cfgReply
874 l_paComAddRepLut2_a:
876 // Verify that the packet has all the data
877 qble l_paComAddRepLut2_0, r0.w0, SIZE(s_paAddL2Std)
878 mov s_paCmd1.commandResult, PA_COMMAND_RESULT_INVALID_PKT_SIZE
879 xout XID_CDEDATA, s_paCmd1.commandResult, SIZE(s_paCmd1.commandResult)
880 jmp f_cfgReply
882 l_paComAddRepLut2_0:
884 // Read in the command info. The command could be either a custom or standard,
885 // but it really makes no difference to the add function since the sizes are the same
886 xin XID_CDEDATA, s_paAddL2Std, SIZE(s_paAddL2Std)
888 // It is not required to update the number of entries for entry replacement
889 qbbs l_paComAddRepLut2_1, s_paAddL2Std.ctrlBitMap.t_pa_lut2_ctrl_replace
891 // Keep a count of the number of entries. Return a warning if
892 // it exceeds the max
893 add s_runCxt.c2NumInL2Table, s_runCxt.c2NumInL2Table, 1
894 mov r1.w0, SUBS_MAX_LUT2_ENTRIES
895 qbge l_paComAddRepLut2_1, s_runCxt.c2NumInL2Table, r1.w0
897 mov s_paCmd1.commandResult, PA_COMMAND_RESULT_WARN_OVER_MAX_ENTRIES
898 jmp l_paComAddRepLut2_1_0
900 l_paComAddRepLut2_1:
902 // Return success
903 mov s_paCmd1.commandResult, PA_COMMAND_RESULT_SUCCESS
905 l_paComAddRepLut2_1_0:
906 xout XID_CDEDATA, s_paCmd1.commandResult, SIZE(s_paCmd1.commandResult)
908 // Advance the CDE then read in the forwarding info
909 // The advance must include the common command header as well as the add lut2 command
910 mov s_cdeCmdWd.operation, CDE_CMD_WINDOW_ADVANCE
911 mov s_cdeCmdWd.byteCount, SIZE(s_paCmd1)+SIZE(s_paAddL2Std)
912 xout XID_CDECTRL, s_cdeCmdWd, SIZE(s_cdeCmdWd)
914 xin XID_CDEDATA, s_l2Entry.data0, SIZE(s_paFwdMatchPlace) + SIZE(s_l2QueueDivert)
915 // record the potential Queue diversion parameters
916 mvid r3, *&s_l2QueueDivert
918 // Put the previously read key into the correct location
919 // Switched to the custom version of the structure since it moves all 32 bits at once
920 mov s_l2Entry.key1.b0, 0
921 add s_l2Entry.key1.b1, s_paAddL2Custom.l4Type, s_paAddL2Custom.index
922 mvid s_l2Entry.key2, *&s_paAddL2Custom.match0
923 mov s_l2Entry.key1.w2, s_paAddL2Custom.srcVC
925 // We may need to update b3 if custom
926 qbeq l_paComAddRepLut2_3, s_paAddL2Std.type, PA_COM_ADD_LUT2_STANDARD
927 qbgt l_paComAddRepLut2_2, s_paAddL2Std.index, PA_MAX_C2_CUSTOM_TYPES
928 mov s_pktCxt2.commandResult, PA_COMMAND_RESULT_INVALID_C2_CUSTOM_IDX
929 set s_pktCxt2.ctrlFlag.t_cmdResultPatch
930 clr s_pktCxt2.ctrlFlag.t_cmdContinue
931 jmp f_cfgReply
933 l_paComAddRepLut2_2:
934 // Calcualte the offset: 16-byte entries
935 lsl r1.w0, s_paAddL2Std.index, 4
936 add r1.w0, r1.w0, OFFSET_CUSTOM_C2 + OFFSET(struct_paC2Custom.bitSet)
937 lbco r1.b3, PAMEM_CONST_CUSTOM2, r1.w0, SIZE(struct_paC2Custom.bitSet)
938 // Update the MS byte
939 or s_l2Entry.key2.b3, s_l2Entry.key2.b3, r1.b3
941 l_paComAddRepLut2_3:
943 // Disable GTPU parsing only if GTPU flag is set
944 qbbc l_paComAddRepLut2_4, s_paAddL2Std.ctrlBitMap.t_pa_lut2_ctrl_gtpu
945 set s_runCxt.ctrlFlag.t_c2_disable_GTPU
947 l_paComAddRepLut2_4:
948 // Put the command word in place
949 zero &s_l2Entry.ctrl, SIZE(s_l2Entry.ctrl)
950 mov s_l2Entry.ctrl.b3, SUBS_L2_ENTRY_CTRL_ADD
952 sbco s_l2Entry, cLut2Regs, LUT2_REG_DATA0, SIZE(s_l2Entry)
954 // Should we perform queue diversion assistance
955 qbbc l_paComAddRepLut2_5, s_paAddL2Std.ctrlBitMap.t_pa_lut2_ctrl_queue_divert
957 // forward the response packet to the Queue-diverion processing queue
958 lbco s_paAddLut2QueueDivert, PAMEM_CONST_CUSTOM, OFFSET_QUEUE_DIVERT_CFG, SIZE(s_paAddLut2QueueDivert)
960 // Patch timestamp field with queue diversion information
961 sbco r3, cCdeOutPkt, OFFSET(s_pktDescr.timestamp), SIZE(s_pktDescr.timestamp)
964 xin XID_PINFO_A, s_pktExtDescr, SIZE(s_pktExtDescr)
966 lbco s_pktDescr.pktFlags, cCdeOutPkt, OFFSET(s_pktDescr.pktFlags), SIZE(s_pktDescr.pktFlags)
967 #ifdef PASS_LAST_PDSP
968 // Clear Bypass Flag
969 clr s_pktDescr.pktFlags.t_pktBypass
970 #else
971 set s_pktDescr.pktFlags.t_pktBypass
972 #endif
973 sbco s_pktDescr.pktFlags, cCdeOutPkt, OFFSET(s_pktDescr.pktFlags), SIZE(s_pktDescr.pktFlags)
975 // Add PA Config command
976 mov r1.b0, PSH_CMD_CONFIG << 5
977 sbco r1.b0, cCdeOutPkt, SIZE(s_pktDescr), 1
979 // CDE workaround: do not use CDE_FLG_SET_DESTQUEUE
980 mov s_cdeCmdPkt.psInfoSize, 4
981 //mov s_cdeCmdPkt.threadId, THREADID_CDMA
982 //mov s_cdeCmdPkt.destQueue, s_paAddLut2QueueDivert.destQueue
983 mov s_cdeCmdPkt.flowId, s_paAddLut2QueueDivert.destFlowId
984 //mov s_cdeCmdPkt.operation, CDE_CMD_PACKET_ADVANCE
985 //mov s_cdeCmdPkt.optionsFlag, CDE_FLG_SET_FLOWID | CDE_FLG_SET_PSINFO | CDE_FLG_SET_DESTQUEUE
986 mov r4.w0, CDE_CMD_PACKET_ADVANCE | ((CDE_FLG_SET_FLOWID | CDE_FLG_SET_PSINFO) << 8)
987 sbco s_paAddLut2QueueDivert.destQueue, cCdeOutPkt, OFFSET(s_pktDescr.destQ), SIZE(s_pktDescr.destQ)
988 xout XID_CDECTRL, s_cdeCmdPkt, SIZE(s_cdeCmdPkt)
990 // Free the extended header
991 mov s_pktExtDescr.threadId, THREADID_CDMA0
992 xout XID_PINFO_DST, s_pktExtDescr, SIZE(s_pktExtDescr)
994 // command response counter
995 lbco r1, cMailbox, 8, 4
996 add r1, r1, 1
997 sbco r1, cMailbox, 8, 4
999 // set queue divert flag (command1)
1000 mov r1, 1
1001 sbco r1, cMailbox, 4, 4
1003 // Wait for the set command to take hold
1004 wbs s_flags.info.tStatus_Command1
1006 // wait for entry update
1007 wbc s_flags.info.tStatus_Lut2AddDelBusy
1009 // wait for qeue diversion to be completed
1010 wbc s_flags.info.tStatus_Command1
1012 jmp f_mainLoop
1015 l_paComAddRepLut2_5:
1016 jmp f_cfgReply
1018 .leave cdeScope
1019 .leave configScope
1020 .leave lut2Scope
1021 .leave pktScope
1023 // ********************************************************************************************
1024 // * FUNCTION PURPOSE: Delete an entry from LUT2
1025 // ********************************************************************************************
1026 // * DESCRIPTION: An existing entry is deleted
1027 // *
1028 // * Register Usage:
1029 // *
1030 // * R0: w0 - the packet length
1031 // * R1:
1032 // * R2:
1033 // * R3:
1034 // * R4: | CDE commands
1035 // * R5: |
1036 // * R6: | Command header (entry)
1037 // * R7: |
1038 // * R8: |
1039 // * R9: |
1040 // * R10: | del LUT2 command
1041 // * R11: |
1042 // * R12: |
1043 // * R13:
1044 // * R14:
1045 // * R15:
1046 // * R16:
1047 // * R17:
1048 // * R18: | LUT2 key
1049 // * R19: | LUT2 control
1050 // * R20:
1051 // * R21:
1052 // * R22: |
1053 // * R23: | Packet context - pktScope
1054 // * R24: |
1055 // * R25: |
1056 // * R26: |
1057 // * R27: |
1058 // * R28:
1059 // * R29: c2RunContext (s_runCxt) - Global Scope
1060 // * R30: w2-Error Index w0-function return address -
1061 // * R31: System Flags (s_flags) -
1062 // *
1063 // ******************************************************************************************
1065 .using cdeScope
1066 .using configScope
1067 .using lut2Scope
1068 .using pktScope
1070 f_paComDelLut2:
1072 // If there is an active add or delete the command must be rejected
1073 qbbc l_paComDelLut2_0, s_flags.info.tStatus_Lut2AddDelBusy
1075 mov s_paCmd1.commandResult, PA_COMMAND_RESULT_LUT2_ADD_BUSY
1076 xout XID_CDEDATA, s_paCmd1.commandResult, SIZE(s_paCmd1.commandResult)
1077 jmp f_cfgReply
1079 l_paComDelLut2_0:
1081 // Keep a count of the number of entries. Return a warning if
1082 // it seems to drop below zero
1083 qbne l_paComDelLut2_1, s_runCxt.c2NumInL2Table, 0
1084 mov s_paCmd1.commandResult, PA_COMMAND_RESULT_WARN_NEGATIVE_ENTRY_COUNT
1085 xout XID_CDEDATA, s_paCmd1.commandResult, SIZE(s_paCmd1.commandResult)
1086 jmp l_paComDelLut2_2
1088 l_paComDelLut2_1:
1089 // Return success
1090 mov s_paCmd1.commandResult, PA_COMMAND_RESULT_SUCCESS
1091 xout XID_CDEDATA, s_paCmd1.commandResult, SIZE(s_paCmd1.commandResult)
1093 sub s_runCxt.c2NumInL2Table, s_runCxt.c2NumInL2table, 1
1095 l_paComDelLut2_2:
1097 // read in delete command parameters
1098 xin XID_CDEDATA, s_paDelL2Custom, SIZE(s_paDelL2Custom)
1100 mov s_l2Entry.key1.b0, 0
1101 add s_l2Entry.key1.b1, s_paDelL2Custom.l4Type, s_paDelL2Custom.index
1102 mvid s_l2Entry.key2, *&s_paDelL2Custom.match0
1103 mov s_l2Entry.key1.w2, s_paDelL2Custom.srcVC
1105 zero &s_l2Entry.ctrl, SIZE(s_l2Entry.ctrl)
1106 mov s_l2Entry.ctrl.b3, SUBS_L2_ENTRY_CTRL_DEL
1108 // We may need to update b3 if custom
1109 qbeq l_paComDelLut2_4, s_paDelL2Custom.type, PA_COM_ADD_LUT2_STANDARD
1110 qbge l_paComDelLut2_3, s_paDelL2Custom.index, PA_MAX_C2_CUSTOM_TYPES
1111 mov s_paCmd1.commandResult, PA_COMMAND_RESULT_INVALID_C2_CUSTOM_IDX
1112 xout XID_CDEDATA, s_paCmd1.commandResult, SIZE(s_paCmd1.commandResult)
1113 jmp f_cfgReply
1115 l_paComDelLut2_3:
1116 // Calcualte the offset: 16-byte entries
1117 lsl r1.w0, s_paDelL2Custom.index, 4
1118 add r1.w0, r1.w0, OFFSET_CUSTOM_C2 + OFFSET(struct_paC2Custom.bitSet)
1119 lbco r1.b3, PAMEM_CONST_CUSTOM2, r1.w0, SIZE(struct_paC2Custom.bitSet)
1120 // Update the MS byte
1121 or s_l2Entry.key2.b3, s_l2Entry.key2.b3, r1.b3
1122 jmp l_paComDelLut2_5
1124 l_paComDelLut2_4:
1126 // Re-enable GTPU parsing if GTPU flag is set
1127 qbbc l_paComDelLut2_5, s_paDelL2Std.ctrlBitMap.t_pa_lut2_ctrl_gtpu
1128 clr s_runCxt.ctrlFlag.t_c2_disable_GTPU
1130 l_paComDelLut2_5:
1131 sbco s_l2Entry.key1, cLut2Regs, LUT2_REG_ADDDEL_KEY0, SIZE(s_l2Entry.ctrl)+ 2*SIZE(s_l2Entry.key1)
1133 jmp f_cfgReply
1135 .leave cdeScope
1136 .leave configScope
1137 .leave lut2Scope
1138 .leave pktScope
1140 // *********************************************************************************************
1141 // * FUNCTION PURPOSE: Initialize the classify2 PDSP
1142 // *********************************************************************************************
1143 // * DESCRIPTION: One time setup for the PDSP
1144 // *
1145 // *********************************************************************************************
1147 .using initScope
1149 f_c2LocalInit:
1151 // Reset the LUT2 table to clear all entries. It will take 8192 cycles to
1152 // clear the table. Any value written will cause the reset, but just
1153 // to be safe a non-zero value will be written
1154 mov r3, 1
1155 sbco r3, cLut2Regs, LUT2_REG_SOFTRESET, 4
1157 // The run context
1158 // TBD: duplicate code
1159 //zero &s_runCxt, SIZE(s_runCxt)
1160 //lbco s_runCxt.pdspId, PAMEM_CONST_PDSP_INFO, OFFSET_ID, 1 // PDSP ID
1162 // The call table (per PDSP initialization)
1163 // TBD: may need more entries
1164 mov s_headerParse.c2ParseUdp, f_c2ParseUdp
1165 mov s_headerParse.c2ParseUdpLite, f_c2ParseUdpLite
1166 mov s_headerParse.c2ParseTcp, f_c2ParseTcp
1167 mov s_headerParse.c2ParseGtpu, f_c2ParseGtpu
1168 mov s_headerParse.c2ParseEspDec, f_c2ParseEspDec
1169 mov s_headerParse.c2ParseCustom, f_c2ParseCustom
1171 sbco s_headerParse.c1ParseMac, PAMEM_CONST_PARSE, 0, SIZE(s_headerParse)
1173 // Custom Classify 2 (16*16)
1174 zero &r0, 64
1175 sbco &r0, PAMEM_CONST_CUSTOM2, OFFSET_CUSTOM_C2, 4*16
1176 sbco &r0, PAMEM_CONST_CUSTOM2, OFFSET_CUSTOM_C2+64, 4*16
1177 sbco &r0, PAMEM_CONST_CUSTOM2, OFFSET_CUSTOM_C2+64*2, 4*16
1178 sbco &r0, PAMEM_CONST_CUSTOM2, OFFSET_CUSTOM_C2+64*3, 4*16
1181 #ifdef PASS_FIRST_PDSP
1182 // Initialize the next Fail Route base table (4 * 8 = 32 byte)
1183 // Dead code: not used by classify2
1184 mov32 s_nextFailRouteBase.pdsp0, PAMEM_NFAIL_BASE_ADDR_PDSP0
1185 mov32 s_nextFailRouteBase.pdsp1, PAMEM_NFAIL_BASE_ADDR_PDSP1
1186 mov32 s_nextFailRouteBase.pdsp2, PAMEM_NFAIL_BASE_ADDR_PDSP2
1187 mov32 s_nextFailRouteBase.pdsp3, PAMEM_NFAIL_BASE_ADDR_PDSP3
1188 mov32 s_nextFailRouteBase.pdsp4, PAMEM_NFAIL_BASE_ADDR_PDSP4
1189 mov32 s_nextFailRouteBase.pdsp5, PAMEM_NFAIL_BASE_ADDR_PDSP5
1190 mov32 s_nextFailRouteBase.pdsp6, PAMEM_NFAIL_BASE_ADDR_PDSP6
1191 mov32 s_nextFailRouteBase.pdsp7, PAMEM_NFAIL_BASE_ADDR_PDSP7
1193 sbco s_nextFailRouteBase.pdsp0, PAMEM_CONST_NFAIL_BASE, 0, SIZE(s_nextFailRouteBase)
1195 #endif
1197 ret
1199 .leave initScope
1201 // *********************************************************************************
1202 // * FUNCTION PURPOSE: SCTP CRC Verification Processing
1203 // *********************************************************************************
1204 // * DESCRIPTION: Verify the SCTP CRC calculation result with pre-stored data
1205 // *
1206 // * On entry:
1207 // * - CDE points to the Control Info section
1208 // * - r30.w0 has the return address
1209 // * - s_pktCxt has valid packet context
1210 // *
1211 // * On exit:
1212 // * - packet is forwarded
1213 // *
1214 // * Register Usage:
1215 // *
1216 // * R0:
1217 // * R1:
1218 // * R2:
1219 // * R3:
1220 // * R4: | CDE commands - cdeScope
1221 // * R5: | -
1222 // * R6: | SCTP CRC value
1223 // * R7: |
1224 // * R8: | Not used
1225 // * R9: |
1226 // * R10: |
1227 // * R11: |
1228 // * R12: |
1229 // * R13: |
1230 // * R14: |
1231 // * R15: | Extended packet descriptor
1232 // * R16: |
1233 // * R17: |
1234 // * R18: |
1235 // * R19:
1236 // * R20: | CRC context
1237 // * R21: |
1238 // * R22: |
1239 // * R23: |
1240 // * R24: | Packet context
1241 // * R25: |
1242 // * R26: |
1243 // * R27: |
1244 // * R28:
1245 // * R29:
1246 // * R30: w0-function return address -
1247 // * R31: System Flags (s_flags) -
1248 // *
1249 // ************************************************************************
1251 .using cdeScope
1252 .using sctpScope
1253 .using pktScope
1255 #ifdef PASS_VERIFY_SCTP_CRC
1257 f_paSctpVerifyCRC:
1258 // Read in the CRC context
1259 xin XID_CDEDATA, s_sctpCrcCxt, SIZE(s_sctpCrcCxt)
1261 // Scroll past and flush the control info
1262 mov s_cdeCmdWd.operation, CDE_CMD_FLUSH_TO_PACKET
1263 xout XID_CDECTRL, s_cdeCmdWd, SIZE(s_cdeCmdWd)
1265 // Scroll to the CRC location in the packet must be within the CDE range
1266 mov s_cdeCmdWd.operation, CDE_CMD_WINDOW_ADVANCE
1267 sub s_cdeCmdWd.byteCount, s_sctpCrcCxt.offset, s_pktExtDescr.mopLength
1268 xout XID_CDECTRL, s_cdeCmdWd, SIZE(s_cdeCmdWd)
1270 // Write back the original CRC
1271 mov r6, s_sctpCrcCxt.crc
1272 mov r0.b0, s_sctpCrcCxt.crcSize
1273 xout XID_CDEDATA, r6, b0
1275 qbeq l_paSctpVerifyCRC1, s_sctpCrcCxt.crc, s_pktExtDescr.crcValue
1276 // CRC is incorrect
1277 wbs s_flags.info.tStatus_CDEOutPacket
1279 // Set the CRC error flag
1280 lbco r1.b0, cCdeOutPkt, OFFSET(s_pktDescr.psFlags_errorFlags), SIZE(s_pktDescr.psFlags_errorFlags)
1281 set r1.b0.t_pkt_desc_err_flag_chksum2
1282 sbco r1.b0, cCdeOutPkt, OFFSET(s_pktDescr.psFlags_errorFlags), SIZE(s_pktDescr.psFlags_errorFlags)
1284 l_paSctpVerifyCRC1:
1285 // Update and copy the pkt context
1286 clr s_pktCxt.flags.t_flag_crc_verify
1287 mov s_pktCxt5.l3offset2, s_pktCxt5.l3l5Offset
1288 sbco s_pktCxt, cCdeOutPkt, SIZE(s_pktDescr), SIZE(s_pktCxt)
1289 clr s_pktExtDescr.flags.fDoCRC
1291 // Ready to forward the packet
1292 mov s_cdeCmdPkt.optionsFlag, (CDE_FLG_SET_PSINFO)
1293 mov s_cdeCmdPkt.psInfoSize, (SIZE(s_pktCxt) + 7) & 0xf8 // Round up to multiple of 8 bytes
1294 mov s_cdeCmdPkt.operation, CDE_CMD_PACKET_ADVANCE
1296 #ifndef PASS_LAST_PDSP
1297 lbco r1.w0, cCdeOutPkt, OFFSET(s_pktDescr.pktFlags), SIZE(s_pktDescr.pktFlags)
1298 set r1.w0.t_pktBypass
1299 sbco r1.w0, cCdeOutPkt, OFFSET(s_pktDescr.pktFlags), SIZE(s_pktDescr.pktFlags)
1300 #endif
1302 xout XID_PINFO_DST, s_pktExtDescr, SIZE(s_pktExtDescr)
1303 xout XID_CDECTRL, s_cdeCmdPkt, SIZE(s_cdeCmdPkt)
1304 jmp f_mainLoop
1306 #endif
1308 .leave cdeScope
1309 .leave sctpScope
1310 .leave pktScope
1314 // **********************************************************************************************
1315 // * FUNCTION PURPOSE: Parse a UDP header
1316 // **********************************************************************************************
1317 // * DESCRIPTION: The UDP dest port is added to the LUT and the search is initiated
1318 // *
1319 // * On entry:
1320 // * - the CDE is at the start of the UDP header
1321 // * - r30.w0 has the function return address
1322 // * - param.action has SUBS_ACTION_PARSE
1323 // * - cdeCmdWd.operation has CDE_CMD_WINDOW_ADVNACE
1324 // *
1325 // * On exit:
1326 // * - param.action has SUBS_ACTION_LOOKUP or SUBS_ACTION_PARSE (GTPU only)
1327 // * - cdeCmdWd.operation has CDE_CMD_WINDOW_ADVANCE
1328 // * - the CDE is at the first byte after the UDP header
1329 // * - startOffset is adjusted by the UDP header size
1330 // * - s_next.Hdr is set as PA_HDR_UNKNOWN if non-GTPU, otherwise, it is set to PA_HDR_GTPU
1331 // *
1332 // * Register Usage:
1333 // *
1334 // * R0:
1335 // * R1:
1336 // * R2:
1337 // * R3:
1338 // * R4: | CDE commands |
1339 // * R5: | | LUT2 search key
1340 // * R6: | UDP header
1341 // * R7: |
1342 // * R8:
1343 // * R9:
1344 // * R10:
1345 // * R11:
1346 // * R12:
1347 // * R13:
1348 // * R14: | Extender Header
1349 // * R15: |
1350 // * R16: |
1351 // * R17: |
1352 // * R18: |
1353 // * R19:
1354 // * R20:
1355 // * R21:
1356 // * R22: |
1357 // * R23: | Packet context - pktScope
1358 // * R24: |
1359 // * R25: |
1360 // * R26: |
1361 // * R27: |
1362 // * R28:
1363 // * R29: c2RunContext (s_runCxt) - Global Scope
1364 // * R30: w2-Error Index w0-function return address -
1365 // * R31: System Flags (s_flags) -
1366 // *
1367 // ***********************************************************************************************
1369 .using cdeScope
1370 .using pktScope
1371 .using udpScope
1372 .using lut2Scope
1373 .using custC2Scope
1375 f_c2ParseUdp:
1377 // Record parsing UDP
1378 set s_pktCxt.hdrBitmask.SUBS_PA_BIT_HEADER_UDP
1379 mov s_pktCxt.l4Offset, s_pktCxt.startOffset
1381 // Read in the UDP header. Do not advance since there could be a switch to
1382 // custom mode
1383 xin XID_CDEDATA, s_udp, SIZE(s_udp) + SIZE(s_ipsecNatT)
1385 #ifdef PASS_PROC_L4_CHECKSUM
1387 // If the checksum value is non-zero, configure the CDE to compute the checksum
1388 qbeq l_c2ParseUdp0, s_udp.chksum, 0
1390 add s_pktCxt.pseudo, s_pktCxt.pseudo, s_udp.len
1391 adc s_pktCxt.pseudo, s_pktCxt.pseudo, IP_PROTO_NEXT_UDP
1392 adc s_cdeCmdChk.initSum, s_pktCxt.pseudo, s_pktExtDescr.mopCsum
1393 adc s_cdeCmdChk.initSum, s_cdeCmdChk.initSum, 0
1394 sub s_cdeCmdChk.byteLen, s_udp.len, s_pktExtDescr.mopLength
1395 mov s_cdeCmdChk.options, 0
1396 mov s_cdeCmdChk.operation, CDE_CMD_CHECKSUM2_VALIDATE
1398 xout XID_CDECTRL, s_cdeCmdChk, SIZE(s_cdeCmdChk)
1400 #endif
1402 l_c2ParseUdp0:
1403 // UDP length includes the udp header, to the end length is computed
1404 // before updating the start offset.
1405 add r0.w0, s_pktCxt.startOffset, s_udp.len
1406 qbge l_c2ParseUdp0_1, r0.w0, s_pktCxt.endOffset
1407 // The end of UDP payload goes beyond the end of packet, it must be an illegal packet
1408 mov s_param.action, SUBS_ACTION_EXIT
1409 and s_pktCxt.eId_portNum_nextHdr.b1, s_pktCxt.eId_portNum_nextHdr.b1, NOT_PKT_EIDX_MASK
1410 or s_pktCxt.eId_portNum_nextHdr.b1, s_pktCxt.eId_portNum_nextHdr.b1, EROUTE_PARSE_FAIL << PKT_EIDX_SHIFT
1411 ret
1413 l_c2ParseUdp0_1:
1414 mov s_pktCxt.endOffset, r0.w0
1415 add s_pktCxt.startOffset, s_pktCxt.startOffset, UDP_HEADER_LEN_BYTES
1416 mov s_pktCxt5.l3offset2, s_pktCxt5.l3l5Offset
1417 mov s_pktCxt.l5Offset, s_pktCxt.startOffset
1419 mov s_stats.value, PA_STATS_UPDATE_REQ | PA_STATS_UDP_PKTS
1421 // Verify whether GTPU parsing is enabled
1422 qbbs l_c2ParseUdp1, s_runCxt.ctrlFlag.t_c2_disable_GTPU
1424 // A switch to GTPU mode is made based on destination UDP port
1425 mov r0.w0, UDP_TCP_DEST_PORT_GTP
1426 qbne l_c2ParseUdp1, s_udp.dst, r0.w0
1428 // On match change the next parse type to GTPU and return
1429 set s_pktCxt.hdrBitmask.SUBS_PA_BIT_HEADER_GTPU
1430 mov s_next.Hdr, PA_HDR_GTPU
1432 // Advance past the end of the header
1433 mov s_cdeCmdWd.operation, CDE_CMD_WINDOW_ADVANCE
1434 mov s_cdeCmdWd.byteCount, SIZE(s_udp)
1435 xout XID_CDECTRL, s_cdeCmdWd, SIZE(s_cdeCmdWd)
1436 ret
1438 l_c2ParseUdp1:
1440 #ifdef PASS_PROC_IPSEC_NAT_T
1442 // Verify whether IPSEC NAT-T parsing is enabled
1443 qbbc l_c2ParseUdp2, s_runCxt.ctrlFlag.t_c2_enable_IPSEC_NAT_T
1445 // A switch to IPSEC_NAT_T mode is made based on destination or source UDP port
1446 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)
1447 qbeq l_c2ParseUdpNatT_1, s_udp.dst, r0.w0
1448 qbne l_c2ParseUdp2, s_udp.src, r0.w0
1450 l_c2ParseUdpNatT_1:
1451 // IPSEC NAT_T parsing
1452 // Keepalive packet: UDP length == 9, payload = 0xFF
1453 // Control packet: UDP length > 12 SPI = 0
1454 // IPSEC Data Packet: UDP length > 12 SPI != 0
1455 // Error Packet UDP length <= 12
1457 // Common Operations for all NAT_T packet
1458 set s_pktCxt.hdrBitmask.SUBS_PA_BIT_HEADER_IPSEC_NAT_T
1459 mov s_next.Hdr, PA_HDR_UNKNOWN
1460 and s_pktCxt.eId_portNum_nextHdr.b1, s_pktCxt.eId_portNum_nextHdr.b1, NOT_PKT_EIDX_MASK
1461 mov s_param.action, SUBS_ACTION_EXIT
1463 qbge l_c2ParseUdpNatT_3, s_udp.len, SIZE(s_udp) + SIZE(s_ipsecNatT)
1464 qbeq l_c2ParseUdpNatT_2, s_ipsecNatT.spi, 0
1465 // IPSEC Data packet
1466 or s_pktCxt.eId_portNum_nextHdr.b1, s_pktCxt.eId_portNum_nextHdr.b1, EROUTE_NAT_T_DATA << PKT_EIDX_SHIFT
1467 mov s_next.Hdr, PA_HDR_ESP
1468 ret
1470 l_c2ParseUdpNatT_2:
1471 // NAT_T Control packet
1472 or s_pktCxt.eId_portNum_nextHdr.b1, s_pktCxt.eId_portNum_nextHdr.b1, EROUTE_NAT_T_CTRL << PKT_EIDX_SHIFT
1473 ret
1475 l_c2ParseUdpNatT_3:
1476 qbne l_c2ParseUdpNatT_4, s_udp.len, SIZE(s_udp) + SIZE(s_ipsecNatT2)
1477 qbne l_c2ParseUdpNatT_4, s_ipsecNatT2.data, 0xFF
1478 // NAT-T Keepalive Packet
1479 or s_pktCxt.eId_portNum_nextHdr.b1, s_pktCxt.eId_portNum_nextHdr.b1, EROUTE_NAT_T_KEEPALIVE << PKT_EIDX_SHIFT
1480 ret
1482 l_c2ParseUdpNatT_4:
1483 // NAT-T Error Packet
1484 or s_pktCxt.eId_portNum_nextHdr.b1, s_pktCxt.eId_portNum_nextHdr.b1, EROUTE_NAT_T_FAIL << PKT_EIDX_SHIFT
1485 ret
1487 #endif
1489 l_c2ParseUdp2:
1491 // Do the lookup
1492 zero &s_l2Search, SIZE(s_l2Search)
1493 mov s_l2Search.dstPort, s_udp.dst
1494 mov s_l2Search.type, PA_L4_PKT_TYPE_PORT16
1495 // Check to see whether virtual link is used
1496 qbbs l_c2ParseUdp_vLink, s_pktCxt.flags.t_flag_use_vlink
1497 // The previous lookup PDSP ID and LUT1 index is stored in the srcVC field
1498 mov s_l2Search.srcVC, s_pktCxt.phyLink
1499 jmp l_c2ParseUdp_link_end
1500 l_c2ParseUdp_vLink:
1501 mov s_l2Search.srcVC, s_pktCxt.vlanPri_vLink
1502 and s_l2Search.srcVC.b1, s_l2Search.srcVC.b1, NOT_PKT_VLAN_PRI_MASK
1503 // Clear virtual link enable for further look ups
1504 clr s_pktCxt.flags.t_flag_use_vlink
1506 l_c2ParseUdp_link_end:
1508 xout XID_LUT2CMD, s_l2Search, SIZE(s_l2Search)
1510 mov s_param.action, SUBS_ACTION_LOOKUP
1512 ret
1514 .leave cdeScope
1515 .leave pktScope
1516 .leave udpScope
1517 .leave lut2Scope
1518 .leave custC2Scope
1521 // **********************************************************************************************
1522 // * FUNCTION PURPOSE: Parse a UDP-Lite header
1523 // **********************************************************************************************
1524 // * DESCRIPTION: The UDP-Lite header is parsed
1525 // *
1526 // * On entry:
1527 // * - the CDE is at the start of the UDP header
1528 // * - r30.w0 has the function return address
1529 // * - param.action has SUBS_ACTION_PARSE
1530 // * - cdeCmdWd.operation has CDE_CMD_WINDOW_ADVNACE
1531 // *
1532 // * On exit:
1533 // * - param.action has SUBS_ACTION_LOOKUP or SUBS_ACTION_PARSE (GTPU only)
1534 // * - cdeCmdWd.operation has CDE_CMD_WINDOW_ADVANCE
1535 // * - the CDE is at the first byte after the UDP-lite header
1536 // * - startOffset is adjusted by the UDP header size
1537 // * - s_next.Hdr is set as PA_HDR_UNKNOWN if non-GTPU, otherwise, it is set to PA_HDR_GTPU
1538 // * Register Usage:
1539 // *
1540 // * R0:
1541 // * R1:
1542 // * R2:
1543 // * R3:
1544 // * R4: | CDE commands |
1545 // * R5: | | LUT2 search key
1546 // * R6: | UDP header
1547 // * R7: |
1548 // * R8:
1549 // * R9:
1550 // * R10:
1551 // * R11:
1552 // * R12:
1553 // * R13:
1554 // * R14: | Extender Header
1555 // * R15: |
1556 // * R16: |
1557 // * R17: |
1558 // * R18: |
1559 // * R19:
1560 // * R20:
1561 // * R21:
1562 // * R22: |
1563 // * R23: | Packet context - pktScope
1564 // * R24: |
1565 // * R25: |
1566 // * R26: |
1567 // * R27: |
1568 // * R28:
1569 // * R29: c2RunContext (s_runCxt) - Global Scope
1570 // * R30: w2-Error Index w0-function return address -
1571 // * R31: System Flags (s_flags) -
1572 // *
1573 // ************************************************************************************************
1576 .using cdeScope
1577 .using pktScope
1578 .using udpScope
1579 .using lut2Scope
1580 .using custC2Scope
1582 f_c2ParseUdpLite:
1584 // Record parsing UDP
1585 set s_pktCxt.hdrBitmask.SUBS_PA_BIT_HEADER_UDP
1586 mov s_pktCxt.l4Offset, s_pktCxt.startOffset
1588 // Read in the UDP lite header. Do not advance since there could be a switch to
1589 // custom mode
1590 xin XID_CDEDATA, s_udpLite, SIZE(s_udpLite)
1592 #ifdef PASS_PROC_L4_CHECKSUM
1594 // Setup for the UDP checksum
1595 // Get the IP length
1596 sub r2.w0, s_pktCxt.startOffset, s_pktCxt.endOffset
1598 mov s_cdeCmdChk.bytelen, s_udpLite.chkCov
1600 qbne l_c2ParseUdpLite0, s_udpLite.chkCov, 0
1601 mov s_cdeCmdChk.bytelen, r2.w0 // 0 means the whole packet
1603 l_c2ParseUdpLite0:
1605 qblt l_c2ParseUdpLite2, s_cdeCmdChk.bytelen, r2.w0
1606 qbgt l_c2ParseUdpLite2, s_cdeCmdChk.bytelen, UDP_LITE_HEADER_LEN_BYTES
1608 sub s_cdeCmdChk.bytelen, s_cdeCmdChk.bytelen, s_pktExtDescr.mopLength
1609 add s_pktCxt.pseudo, s_pktCxt.pseudo, r2.w0
1610 adc s_pktCxt.pseudo, s_pktCxt.pseudo, IP_PROTO_NEXT_UDP_LITE
1611 adc s_cdeCmdChk.initSum, s_pktCxt.pseudo, s_pktExtDescr.mopCsum
1612 adc s_cdeCmdChk.initSum, s_cdeCmdChk.initSum, 0
1613 mov s_cdeCmdChk.options, 0
1614 mov s_cdeCmdChk.operation, CDE_CMD_CHECKSUM2_VALIDATE
1616 xout XID_CDECTRL, s_cdeCmdChk, SIZE(s_cdeCmdChk)
1618 #endif
1620 // UDP-lite length includes the udp header
1621 add s_pktCxt.startOffset, s_pktCxt.startOffset, UDP_LITE_HEADER_LEN_BYTES
1622 mov s_pktCxt5.l3offset2, s_pktCxt5.l3l5Offset
1623 mov s_pktCxt.l5Offset, s_pktCxt.startOffset
1625 mov s_stats.value, PA_STATS_UPDATE_REQ | PA_STATS_UDP_PKTS
1627 // Verify whether GTPU parsing is enabled
1628 qbbs l_c2ParseUdpLite1, s_runCxt.ctrlFlag.t_c2_disable_GTPU
1630 // A switch to GTPU mode is made based on destination UDP port
1631 mov r0.w0, UDP_TCP_DEST_PORT_GTP
1632 qbne l_c2ParseUdpLite1, s_udpLite.dst, r0.w0
1634 // On match change the next parse type to custom and return
1635 mov s_next.Hdr, PA_HDR_GTPU
1637 // Advance past the end of the header
1638 mov s_cdeCmdWd.operation, CDE_CMD_WINDOW_ADVANCE
1639 mov s_cdeCmdWd.byteCount, SIZE(s_udpLite)
1640 xout XID_CDECTRL, s_cdeCmdWd, SIZE(s_cdeCmdWd)
1642 ret
1644 l_c2ParseUdpLite1:
1646 // Do the lookup
1647 zero &s_l2Search, SIZE(s_l2Search)
1648 mov s_l2Search.dstPort, s_udpLite.dst
1649 mov s_l2Search.type, PA_L4_PKT_TYPE_PORT16
1650 // Check to see whether virtual link is used
1651 qbbs l_c2ParseUdpLite_vLink, s_pktCxt.flags.t_flag_use_vlink
1652 // The previous lookup PDSP ID and LUT1 index is stored in the srcVC field
1653 mov s_l2Search.srcVC, s_pktCxt.phyLink
1654 jmp l_c2ParseUdpLite_link_end
1655 l_c2ParseUdpLite_vLink:
1656 mov s_l2Search.srcVC, s_pktCxt.vlanPri_vLink
1657 and s_l2Search.srcVC.b1, s_l2Search.srcVC.b1, NOT_PKT_VLAN_PRI_MASK
1658 // Clear virtual link enable for further look ups
1659 clr s_pktCxt.flags.t_flag_use_vlink
1661 l_c2ParseUdpLite_link_end:
1664 xout XID_LUT2CMD, s_l2Search, SIZE(s_l2Search)
1666 mov s_param.action, SUBS_ACTION_LOOKUP
1667 ret
1669 #ifdef PASS_PROC_L4_CHECKSUM
1671 l_c2ParseUdpLite2:
1673 // UDP lite checksum coverage failed
1674 and s_pktCxt.eId_portNum_nextHdr.b1, s_pktCxt.eId_portNum_nextHdr.b1, NOT_PKT_EIDX_MASK
1675 or s_pktCxt.eId_portNum_nextHdr.b1, s_pktCxt.eId_portNum_nextHdr.b1, EROUTE_UDP_LITE_FAIL << PKT_EIDX_SHIFT
1677 mov s_param.action, SUBS_ACTION_EXIT
1678 ret
1680 #endif
1682 .leave cdeScope
1683 .leave pktScope
1684 .leave udpScope
1685 .leave lut2Scope
1686 .leave custC2Scope
1689 // ***********************************************************************************
1690 // * FUNCTION PURPOSE: Process a TCP header
1691 // ***********************************************************************************
1692 // * DESCRIPTION: The TCP header is parsed and a LUT2 initiated
1693 // *
1694 // * Register Usage:
1695 // *
1696 // * R0:
1697 // * R1: | scratch
1698 // * R2:
1699 // * R3:
1700 // * R4: | CDE commands |
1701 // * R5: | | LUT2 search key
1702 // * R6: | TCP header
1703 // * R7: |
1704 // * R8: |
1705 // * R9: |
1706 // * R10: |
1707 // * R11:
1708 // * R12:
1709 // * R13:
1710 // * R14: | Extender Header
1711 // * R15: |
1712 // * R16: |
1713 // * R17: |
1714 // * R18: |
1715 // * R19:
1716 // * R20:
1717 // * R21:
1718 // * R22: |
1719 // * R23: | Packet context - pktScope
1720 // * R24: |
1721 // * R25: |
1722 // * R26: |
1723 // * R27: |
1724 // * R28:
1725 // * R29: c2RunContext (s_runCxt) - Global Scope
1726 // * R30: w2-Error Index w0-function return address -
1727 // * R31: System Flags (s_flags) -
1728 // *
1729 // *************************************************************************************
1731 .using cdeScope
1732 .using pktScope
1733 .using tcpScope
1734 .using lut2Scope
1736 f_c2ParseTcp:
1738 // Record parsing TCP
1739 set s_pktCxt.hdrBitmask.SUBS_PA_BIT_HEADER_TCP
1740 mov s_pktCxt.l4Offset, s_pktCxt.startOffset
1742 // Read in the TCP header
1743 xin XID_CDEDATA, s_tcp, SIZE(s_tcp)
1745 // Configure and initiate the lookup
1746 zero &s_l2Search, SIZE(s_l2Search)
1747 mov s_l2Search.dstPort, s_tcp.dst
1748 mov s_l2Search.type, PA_L4_PKT_TYPE_PORT16
1749 // Check to see whether virtual link is used
1750 qbbs l_c2ParseTcp_vLink, s_pktCxt.flags.t_flag_use_vlink
1751 // The previous lookup PDSP ID and LUT1 index is stored in the srcVC field
1752 mov s_l2Search.srcVC, s_pktCxt.phyLink
1753 jmp l_c2ParseTcp_link_end
1754 l_c2ParseTcp_vLink:
1755 mov s_l2Search.srcVC, s_pktCxt.vlanPri_vLink
1756 and s_l2Search.srcVC.b1, s_l2Search.srcVC.b1, NOT_PKT_VLAN_PRI_MASK
1757 // Clear virtual link enable for further look ups
1758 clr s_pktCxt.flags.t_flag_use_vlink
1760 l_c2ParseTcp_link_end:
1762 xout XID_LUT2CMD, s_l2Search, SIZE(s_l2Search)
1764 #ifdef PASS_PROC_L4_CHECKSUM
1766 // Setup the CDE to do the L4 checkusm
1767 sub s_cdeCmdChk.byteLen, s_pktCxt.endOffset, s_pktCxt.startOffset
1768 sub s_cdeCmdChk.byteLen, s_cdeCmdChk.byteLen, s_pktExtDescr.mopLength
1769 add s_pktCxt.pseudo, s_pktCxt.pseudo, s_cdeCmdChk.byteLen
1770 adc s_pktCxt.pseudo, s_pktCxt.pseudo, IP_PROTO_NEXT_TCP
1771 adc s_cdeCmdChk.initSum, s_pktCxt.pseudo, s_pktExtDescr.mopCsum
1772 adc s_cdeCmdChk.initSum, s_cdeCmdChk.initSum, 0
1773 mov s_cdeCmdChk.options, 0
1774 mov s_cdeCmdChk.operation, CDE_CMD_CHECKSUM2_VALIDATE
1776 xout XID_CDECTRL, s_cdeCmdChk, SIZE(s_cdeCmdChk)
1777 #endif
1779 // Adjust the start offset past the tcp header
1780 lsr r1.w0, s_tcp.offset_ecn, 4 // extract the length (32 bit length)
1781 lsl r1.w0, r1.w0, 2 // convert to byte length
1782 add s_pktCxt.startOffset, s_pktCxt.startOffset, r1.w0
1783 mov s_pktCxt5.l3offset2, s_pktCxt5.l3l5Offset
1784 mov s_pktCxt.l5Offset, s_pktCxt.startOffset
1786 mov s_param.action, SUBS_ACTION_LOOKUP
1787 mov s_stats.value, PA_STATS_UPDATE_REQ | PA_STATS_TCP_PKTS
1788 ret
1790 .leave cdeScope
1791 .leave pktScope
1792 .leave tcpScope
1793 .leave lut2Scope
1795 // ******************************************************************************************
1796 // * FUNCTION PURPOSE: Parse a GTPU header
1797 // ******************************************************************************************
1798 // * DESCRIPTION: The custom header fields are extracted, masked, and entered into the LUT
1799 // *
1800 // * GTPU processing algorithm:
1801 // * - Version <> 1 or PT <> ==> Error Queue
1802 // * - Message Type 1,2, 26, 31 254 ==> User specified exception routes
1803 // * - Message Type 255: TEID lookup
1804 // * - If ext header present and it is not 0, or 0xc0 ==> Error Queue
1805 // * - If ext header = 0xc0, but the next one is not 0 ==> Error Queue
1806 // * - If ext header = 0xc0, Extract the PDU number to the pktCtx and set the corresponding flag
1807 // * - TEID lookup
1808 // *
1809 // * On entry:
1810 // * - the CDE is at the start of the GTPU header
1811 // * - r30.w0 has the function return address
1812 // * - param.action has SUBS_ACTION_PARSE
1813 // *
1814 // * On exit:
1815 // * - param.action has SUBS_ACTION_LOOKUP or SUBS_ACTION_EXIT
1816 // * - the CDE is at the first byte after the GTP header and extention header only if loopkup is required
1817 // * - startOffset is adjusted to the GTPU payload only if lookup is required
1818 // * - s_next.Hdr is set as PA_HDR_UNKNOWN
1819 // *
1820 // * Register Usage:
1821 // *
1822 // * R0:
1823 // * R1: | scratch r1.b1 GTPU header size
1824 // * R2:
1825 // * R3:
1826 // * R4: | CDE commands |
1827 // * R5: | | LUT2 search key
1828 // * R6: | GTPU header
1829 // * R7: |
1830 // * R8: |
1831 // * R9: |
1832 // * R10:
1833 // * R11:
1834 // * R12:
1835 // * R13:
1836 // * R14: | Extender Header
1837 // * R15: |
1838 // * R16: |
1839 // * R17: |
1840 // * R18: |
1841 // * R19:
1842 // * R20:
1843 // * R21:
1844 // * R22: |
1845 // * R23: | Packet context - pktScope
1846 // * R24: |
1847 // * R25: |
1848 // * R26: |
1849 // * R27: |
1850 // * R28:
1851 // * R29: c2RunContext (s_runCxt) - Global Scope
1852 // * R30: w2-Error Index w0-function return address -
1853 // * R31: System Flags (s_flags) -
1854 // *
1855 // *****************************************************************************************
1857 .using cdeScope
1858 .using pktScope
1859 .using gtpScope
1860 .using lut2Scope
1862 f_c2ParseGtpu:
1864 // Record parsing GTP
1865 set s_pktCxt.hdrBitmask.SUBS_PA_BIT_HEADER_GTPU
1867 // Assume Error case
1868 and s_pktCxt.eId_portNum_nextHdr.b1, s_pktCxt.eId_portNum_nextHdr.b1, NOT_PKT_EIDX_MASK
1869 mov s_param.action, SUBS_ACTION_EXIT
1870 mov s_next.Hdr, PA_HDR_UNKNOWN
1872 // Read in the GTPU header
1873 xin XID_CDEDATA, s_gtp, SIZE(s_gtp)
1875 // Extract version number
1876 and r1.b0, s_gtp.ctrl, GTP_VER_MASK
1878 // Only version 1 should be handled
1879 qbeq l_c2ParseGtpu1, r1.b0, GTP_VER_GTP_V1
1880 or s_pktCxt.eId_portNum_nextHdr.b1, s_pktCxt.eId_portNum_nextHdr.b1, EROUTE_GTPU_FAIL << PKT_EIDX_SHIFT
1881 ret
1883 l_c2ParseGtpu1:
1884 // Protocol Type must be 1
1885 qbbs l_c2ParseGtpu2, s_gtp.ctrl.t_gtp_ctrl_pt_1
1886 or s_pktCxt.eId_portNum_nextHdr.b1, s_pktCxt.eId_portNum_nextHdr.b1, EROUTE_GTPU_FAIL << PKT_EIDX_SHIFT
1887 ret
1889 l_c2ParseGtpu2:
1890 qbne l_c2ParseGtpu3, s_gtp.msgType, 255
1892 l_c2ParseGtpu2_0:
1893 mov r1.b1, GTPV1_HEADER_LEN_BYTES
1894 and r1.b0, s_gtp.ctrl, GTP_CTRL_MASK
1896 qbeq l_c2ParseGtpu2_1, r1.b0, 0
1897 // basic extension header exists
1898 add r1.b1, r1.b1, GTPV1_EXT_HDR_LEN_BYTES
1900 qbbc l_c2ParseGtpu2_1, s_gtp.ctrl.t_gtp_ctrl_extHdr
1901 // extension header exist
1902 qbeq l_c2ParseGtpu2_1, s_gtp.nextHdr, GTP_NEXTHDR_NONE
1904 qbne l_c2ParseGtpu_Err, s_gtp.nextHdr, GTP_NEXTHDR_PDU_NUM
1905 // PDU header exists
1906 qbne l_c2ParseGtpu_Err, s_gtp.nextHdr2, GTP_NEXTHDR_NONE
1907 // Process the PDU number
1908 add r1.b1, r1.b1, GTPV1_EXT_HDR_LEN_BYTES
1909 set s_pktCxt.flags.t_flag_gtpu_seqnum_present
1910 sbco s_gtp.pduNum, cCdeOutPkt, SIZE(s_pktDescr) + SIZE(s_pktCxt), SIZE(s_gtp.pduNum)
1912 // Pass Through for TEID lookup
1914 l_c2ParseGtpu2_1:
1915 // Adjust the start offset to the GTPU paylaod
1916 add s_pktCxt.startOffset, s_pktCxt.startOffset, r1.b1
1918 // Advance past the end of the header
1919 mov s_cdeCmdWd.operation, CDE_CMD_WINDOW_ADVANCE
1920 mov s_cdeCmdWd.byteCount, r1.b1
1921 xout XID_CDECTRL, s_cdeCmdWd, SIZE(s_cdeCmdWd)
1923 // TEID lookup
1924 zero &s_l2Search2, SIZE(s_l2Search2)
1925 mov s_l2Search2.srcVC, s_pktCxt.phyLink
1926 mov s_l2Search2.data0, s_gtp.teid.w2
1927 mov s_l2Search2.data1, s_gtp.teid.w0
1928 mov s_l2Search2.type, PA_L4_PKT_TYPE_PORT32
1929 // Check to see whether virtual link is used
1930 qbbs l_c2ParseGtpu_vLink, s_pktCxt.flags.t_flag_use_vlink
1931 // The previous lookup PDSP ID and LUT1 index is stored in the srcVC field
1932 mov s_l2Search2.srcVC, s_pktCxt.phyLink
1933 jmp l_c2ParseGtpu_link_end
1934 l_c2ParseGtpu_vLink:
1935 mov s_l2Search2.srcVC, s_pktCxt.vlanPri_vLink
1936 and s_l2Search2.srcVC.b1, s_l2Search2.srcVC.b1, NOT_PKT_VLAN_PRI_MASK
1937 // Clear virtual link enable for further look ups
1938 clr s_pktCxt.flags.t_flag_use_vlink
1940 l_c2ParseGtpu_link_end:
1942 xout XID_LUT2CMD, s_l2Search2, SIZE(s_l2Search2)
1943 mov s_param.action, SUBS_ACTION_LOOKUP
1944 ret
1947 l_c2ParseGtpu3:
1948 qbne l_c2ParseGtpu4, s_gtp.msgType, 1
1949 or s_pktCxt.eId_portNum_nextHdr.b1, s_pktCxt.eId_portNum_nextHdr.b1, EROUTE_GTPU_MESSAGE_TYPE_1 << PKT_EIDX_SHIFT
1950 ret
1952 l_c2ParseGtpu4:
1953 qbne l_c2ParseGtpu5, s_gtp.msgType, 2
1954 or s_pktCxt.eId_portNum_nextHdr.b1, s_pktCxt.eId_portNum_nextHdr.b1, EROUTE_GTPU_MESSAGE_TYPE_2 << PKT_EIDX_SHIFT
1955 ret
1957 l_c2ParseGtpu5:
1958 qbne l_c2ParseGtpu6, s_gtp.msgType, 26
1959 or s_pktCxt.eId_portNum_nextHdr.b1, s_pktCxt.eId_portNum_nextHdr.b1, EROUTE_GTPU_MESSAGE_TYPE_26 << PKT_EIDX_SHIFT
1960 ret
1962 l_c2ParseGtpu6:
1963 qbne l_c2ParseGtpu7, s_gtp.msgType, 31
1964 or s_pktCxt.eId_portNum_nextHdr.b1, s_pktCxt.eId_portNum_nextHdr.b1, EROUTE_GTPU_MESSAGE_TYPE_31 << PKT_EIDX_SHIFT
1965 ret
1967 l_c2ParseGtpu7:
1968 qbne l_c2ParseGtpu_Err, s_gtp.msgType, 254
1969 // Check if the routing feature of treating End marker same as G-PDU is enabled
1970 qbbc l_c2ParseGtpu7_0, s_runCxt.ctrlFlag.t_c2_GTPU_route_msg254_as_msg255
1971 // Route same as message 255 if the message type is 254
1972 jmp l_c2ParseGtpu2_0
1974 l_c2ParseGtpu7_0:
1975 or s_pktCxt.eId_portNum_nextHdr.b1, s_pktCxt.eId_portNum_nextHdr.b1, EROUTE_GTPU_MESSAGE_TYPE_254 << PKT_EIDX_SHIFT
1976 ret
1978 l_c2ParseGtpu_Err:
1979 or s_pktCxt.eId_portNum_nextHdr.b1, s_pktCxt.eId_portNum_nextHdr.b1, EROUTE_GTPU_FAIL << PKT_EIDX_SHIFT
1980 ret
1982 .leave cdeScope
1983 .leave pktScope
1984 .leave gtpScope
1985 .leave lut2Scope
1987 // ******************************************************************************************
1988 // * FUNCTION PURPOSE: Parse a custom header
1989 // ******************************************************************************************
1990 // * DESCRIPTION: The custom header fields are extracted, masked, and entered into the LUT
1991 // *
1992 // * Register Usage:
1993 // *
1994 // * R0:
1995 // * R1: | scratch
1996 // * R2:
1997 // * R3:
1998 // * R4: | CDE commands |
1999 // * R5: | | LUT2 search key
2000 // * R6: | packet data ==> one byte at a time
2001 // * R7:
2002 // * R8:
2003 // * R9:
2004 // * R10:
2005 // * R11:
2006 // * R12:
2007 // * R13:
2008 // * R14: | custom2 Control data
2009 // * R15: |
2010 // * R16: |
2011 // * R17: |
2012 // * R18:
2013 // * R19:
2014 // * R20:
2015 // * R21:
2016 // * R22: |
2017 // * R23: | Packet context - pktScope
2018 // * R24: |
2019 // * R25: |
2020 // * R26: |
2021 // * R27: |
2022 // * R28:
2023 // * R29: c2RunContext (s_runCxt) - Global Scope
2024 // * R30: w2-Error Index w0-function return address -
2025 // * R31: System Flags (s_flags) -
2026 // *
2027 // *****************************************************************************************
2028 .using cdeScope
2029 .using pktScope
2030 .using custC2Scope
2031 .using lut2Scope
2033 f_c2ParseCustom:
2035 set s_pktCxt.hdrBitmask.SUBS_PA_BIT_HEADER_CUSTOM
2037 // eIndex should stote the custom Index
2038 // offset = index * 16 + OFFSET_CUSTOM_C2
2039 // TBD: Should we do error check here?
2040 lsr r1.b0, s_pktCxt.eId_portNum_nextHdr.b1, PKT_EIDX_SHIFT
2041 lsl r1.w0, r1.b0, 4
2042 add r1.w0, r1.w0, OFFSET_CUSTOM_C2
2044 // Read the custom parse information from scratch
2045 lbco s_c2Cust, PAMEM_CONST_CUSTOM2, r1.w0, SIZE(s_c2Cust)
2047 add s_pktCxt.startOffset, s_pktCxt.startOffset, s_c2Cust.hdrSize
2048 mov s_pktCxt5.l3offset2, s_pktCxt5.l3l5Offset
2050 add s_l2SCust.type, s_c2Cust.idx, PA_L4_PKT_TYPE_CUSTOM
2052 // store the current offset, update while scrolling
2053 mov r1.w0, 0
2054 mov s_cdeCmdWd.operation, CDE_CMD_WINDOW_ADVANCE
2056 zero &s_l2SCust, SIZE(s_l2SCust)
2057 // Scroll to the first byte
2058 sub s_cdeCmdWd.byteCount, s_c2Cust.offset3, r1.w0
2059 add r1.w0, r1.w0, s_cdeCmdWd.byteCount
2060 xout XID_CDECTRL, s_cdeCmdWd, SIZE(s_cdeCmdWd)
2062 // Get the byte, mask it and put it in place
2063 xin XID_CDEDATA, r6.b3, 1
2064 and s_l2SCust.cb0, r6.b3, s_c2Cust.bitMask3
2065 or s_l2SCust.cb0, s_l2SCust.cb0, s_c2Cust.bitSet
2067 // Next byte
2068 sub s_cdeCmdWd.byteCount, s_c2Cust.offset2, r1.w0
2069 add r1.w0, r1.w0, s_cdeCmdWd.byteCount
2070 xout XID_CDECTRL, s_cdeCmdWd, SIZE(s_cdeCmdWd)
2072 // Get the byte, mask it and put it in place
2073 xin XID_CDEDATA, r6.b3, 1
2074 and s_l2SCust.cb1, r6.b3, s_c2Cust.bitMask2
2076 // Next byte
2077 sub s_cdeCmdWd.byteCount, s_c2Cust.offset1, r1.w0
2078 add r1.w0, r1.w0, s_cdeCmdWd.byteCount
2079 xout XID_CDECTRL, s_cdeCmdWd, SIZE(s_cdeCmdWd)
2081 // Get the byte, mask it and put it in place
2082 xin XID_CDEDATA, r6.b3, 1
2083 and s_l2SCust.cb2, r6.b3, s_c2Cust.bitMask1
2085 // Last byte
2086 sub s_cdeCmdWd.byteCount, s_c2Cust.offset0, r1.w0
2087 add r1.w0, r1.w0, s_cdeCmdWd.byteCount
2088 xout XID_CDECTRL, s_cdeCmdWd, SIZE(s_cdeCmdWd)
2090 // Get the byte, mask it and put it in place
2091 xin XID_CDEDATA, r6.b3, 1
2092 and s_l2SCust.cb3, r6.b3, s_c2Cust.bitMask0
2094 // The last byte can be from the packet or it can be the PDSP ID and index
2095 // of the previous lookup. Assume it will use the idx and then
2096 // overwrite if the packet values are used
2097 mov s_l2SCust.srcVC, s_pktCxt.phyLink
2098 add s_l2SCust.type, s_c2Cust.idx, PA_L4_PKT_TYPE_CUSTOM
2101 l_c2ParseCustom1:
2103 xout XID_LUT2CMD, s_l2SCust, SIZE(s_l2SCust)
2104 mov s_param.action, SUBS_ACTION_LOOKUP
2105 mov s_stats.value, PA_STATS_UPDATE_REQ | PA_STATS_C2_CUSTOM_PKTS
2106 ret
2108 .leave cdeScope
2109 .leave pktScope
2110 .leave custC2Scope
2111 .leave lut2Scope
2113 // ***************************************************************************************
2114 // * FUNCTION PURPOSE: Parse a decoded ESP header
2115 // ***************************************************************************************
2116 // * DESCRIPTION: After (optional) authentication and decryption, the ESP header is
2117 // * reparsed. the end offset must now point to the end of the ESP
2118 // * trailer.
2119 // *
2120 // * Register Usage:
2121 // *
2122 // * R0: scratch
2123 // * R1:
2124 // * R2:
2125 // * R3:
2126 // * R4: | CDE commands
2127 // * R5: | | LUT2 search key
2128 // * R6: | UDP header
2129 // * R7: |
2130 // * R8:
2131 // * R9:
2132 // * R10:
2133 // * R11:
2134 // * R12:
2135 // * R13:
2136 // * R14: |
2137 // * R15: | extended packet dewscriptor
2138 // * R16: |
2139 // * R17: |
2140 // * R18: |
2141 // * R19:
2142 // * R20:
2143 // * R21:
2144 // * R22: |
2145 // * R23: | Packet context - pktScope
2146 // * R24: |
2147 // * R25: |
2148 // * R26: |
2149 // * R27: |
2150 // * R28:
2151 // * R29: c2RunContext (s_runCxt) - Global Scope
2152 // * R30: w2-Error Index w0-function return address -
2153 // * R31: System Flags (s_flags) -
2154 // *
2155 // *
2156 // **************************************************************************************/
2158 .using cdeScope
2159 .using pktScope
2161 f_c2ParseEspDec:
2163 // Read in the padlen (r0.b1) and protocol (r0.b0) fields at the end of the packet
2164 // Note: It should be the absolute offset including Packet descriptor, PS Info.
2165 // sub r0.w2, s_pktCxt.endOffset, s_pktCxt.startOffset
2166 // Note: Both the size of packet descriptor and PS Info are constants
2167 // We may need to enhance it for more general cases
2168 xin XID_PINFO_A, s_pktExtDescr, SIZE(s_pktExtDescr)
2169 add r0.w2, s_pktCxt.endOffset, (32+32-2)
2170 // Extra 8 bytes are inserted during EOAM enabled case
2171 qbbc l_c2ParseEspDec_1, s_runCxt.flags.t_c2_flags_enable_EOAM
2172 add r0.w2, r0.w2, 8
2173 l_c2ParseEspDec_1:
2175 sub r0.w2, r0.w2, s_pktExtDescr.mopLength
2177 // wait for the sideband data to be ready
2178 wbc s_flags.info.tStatus_CDEBusy
2179 lbco r0.w0, cCdeInPkt, r0.w2, 2
2181 // Note: the s_pktCtx.startOffset should already point to the next header
2182 sub s_pktCxt.endOffset, s_pktCxt.endOffset, r0.b1
2183 sub s_pktCxt.endOffset, s_pktCxt.endOffset, 2
2185 // TBD: Perform the standard pending check
2186 // sub r0.w2, r0.w2, r0.b1
2188 // Get the next header type and action from the protocol field
2189 lbco r1.b0, PAMEM_CONST_IP_PROTO, r0.b0, 1
2190 and s_next.Hdr, r1.b0, 0x3f
2192 // Always contiune to parse the next header
2193 mov s_param.action, SUBS_ACTION_PARSE
2195 ret
2197 .leave cdeScope
2198 .leave pktScope
2200 #include "pacfgcmn.p"