]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - processor-sdk/pdk.git/blob - packages/ti/drv/pa/fw/v1/parse1.p
pa-lld: add to PDK
[processor-sdk/pdk.git] / packages / ti / drv / pa / fw / v1 / parse1.p
1 // ********************************************************************************
2 // * FILE PURPOSE: Packet parsing functions
3 // ********************************************************************************
4 // * FILE NAME: parse1.p
5 // *
6 // * DESCRIPTION: Contains the functions that actually parse packets
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 
25 //  manufactured by or for TI (\93TI Devices\94).  No hardware patent is licensed hereunder.
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\92
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 // *********************************************************************************
66 // * FUNCTION PURPOSE: Parse a MAC header
67 // *********************************************************************************
68 // * DESCRIPTION: the MAC destination and source addresses are added to the LUT
69 // *
70 // *   On entry:
71 // *            - CDE points to the MAC address
72 // *            - r30.w0 has the return address
73 // *            - cdeCmdWd.operation has CDE_CMD_WINDOW_ADVANCE
74 // *            - param.action has SUBS_ACTION_PARSE
75 // *            - s_runCxt has valid packet context
76 // *
77 // *   On exit:
78 // *            - CDE points to the first byte after the MAC address
79 // *            - cdeCmdWd.operation has CDE_CMD_WINDOW_ADVANCE
80 // *            - param.action has SUBS_ACTION_PARSE
81 // *
82 // *   Register Usage:  
83 // * 
84 // *   R0:    scratch
85 // *   R1:    scratch
86 // *   R2:    
87 // *   R3:              b0 - next header type  - pktScope
88 // *   R4:    |  CDE commands     -  cdeScope
89 // *   R5:    |                   -
90 // *   R6:        |  (packet desc) before read           |
91 // *   R7:        |                in MAC                |  mac addres (macVlanScope)
92 // *   R8:        |                                      |  Note: Should not be overwritten by other prorocol header
93 // *   R9:        |  LUT1 View   - lut1Scope
94 // *   R10:       |                                     | 
95 // *   R11:       |                                     |  LUT1 View3
96 // *   R12:       |                                     |
97 // *   R13:       |                                     |
98 // *   R14:          |  (packet extended descriptor)                                        
99 // *   R15:          |                                          
100 // *   R16:          |                                          
101 // *   R17:          |  LUT1 View  - lut1Scope                 
102 // *   R18:          |                                  | 
103 // *   R19:          |                                  |  ethertypes table
104 // *   R20:          |                                  |
105 // *   R21:          |                                  |
106 // *   R22:     |     
107 // *   R23:     |  Packet context - pktScope   
108 // *   R24:     |
109 // *   R25:     |
110 // *   R26:     |
111 // *   R27:     |
112 // *   R28:  
113 // *   R29:  c1RunContext (s_runCxt)                                -  Global Scope
114 // *   R30:  w2-param.action  w0-function return address            -
115 // *   R31:  System Flags (s_flags)                                 -
116 // *
117 // **********************************************************************************/
119     .using  lut1Scope
120     .using  pktScope
121     .using  cdeScope
122     .using  macVlanScope
125 f_c1ParseMac:
127 #ifdef PASS_PROC_FIREWALL
128   qbbs  l_c1ParseMacEoam, s_runCxt.flag3.t_eoamEn  
129     jmp fci_c1FirewallException
131 l_c1ParseMacEoam:
132   // May need to rewind to beginning of the packet
133   // clear all the EOAM flags, they would be set per packet after EOAM parse
134   #ifdef PASS_PROC_EOAM
135       //  clr  s_pktCxt6.eoamFlags.t_flag_ip
136       //  clr  s_pktCxt6.eoamFlags.t_flag_cipherPkt    
137       //  clr  s_pktCxt6.eoamFlags.t_flag_fDisableCnt    
138       //  clr  s_pktCxt6.eoamFlags.t_flag_knownOpcodes
139       //  clr  s_pktCxt6.eoamFlags.t_flag_eType8902
141       // The flags are cleared already from previous stage
142       //  mov  s_pktCxt6.eoamFlags, 0
143       //  mov  s_pktCxt6.startOffsetEoam, 0
144       // As the previous stage used the count value, clear it here 
145         mov  s_pktCxt6.count, 0
146    #endif  // PASS_PROC_EOAM
147 #endif  // PASS_PROC_FIREWALL
149 #ifdef PASS_PROC_L2_PARSE
151 #ifndef PASS_PROC_EOAM 
152   set  s_pktCxt.hdrBitmask.SUBS_PA_BIT_HEADER_MAC
153   
154   // Verify and clear psFlags_errorFlags
155   // The CPSW passes CRC and Error Information: To be checked for error handling
156   // This field needs to be cleared since psFlags and errorFlags will be used by PASS
157   // abd SASS differently
158   wbs  s_flags.info.tStatus_CDEOutPacket
159   mov  r1.b0, 0
160   sbco  r1.b0,  cCdeOutPkt, OFFSET(s_pktDescr.psFlags_errorFlags),  SIZE(s_pktDescr.psFlags_errorFlags)
162   // record the input EMA port number (1-4)
163   // Note: It is one-based port number where 0 indicates that the packet is not from CPSW
164   //       We can simply add the EMAC port without mask since this is only place that this field may be updated from initial value (0)
165   and s_pktDescr.srcId, s_pktDescr.srcId, PKT_EMACPORT_MASK 
166   lsl s_pktCxt.eId_portNum_nextHdr,  s_pktDescr.srcId, PKT_EMACPORT_SHIFT
167   
168   //Remove CRC from the endOffset if the packet is from CPSW
169   //qbeq  l_c1ParseMac_1, s_pktDescr.srcId, 0
170   qbbc  l_c1ParseMac_1, s_pktDescr.psFlags_errorFlags.t_psFlags_crcPresent  
171       sub s_pktCxt.endOffset, s_pktCxt.endOffset, 4
172 #endif // PASS_PROC_EOAM
174 l_c1ParseMac_1:  
175   // update inport
176   zero &s_l1View3bMac, SIZE(s_l1View3bMac)
177   mov  s_l1View3bMac.inPort,  s_pktDescr.srcId
178   
179   // Set pktType to indicate MAC operation
180   set  s_l1View3bMac.pktType.fL2PktTypeMac
182   // Load the destination and source mac into the LUT1 search
183   xin  XID_CDEDATA,   s_macAddr,  SIZE(s_macAddr)
184   mov  s_l1View3bMac.dstMac5,  s_macAddr.DstAddr_45.b0 
185   // To be removed
186   // Set the vlan tag to 0x8000 - the four msbs will be zero for a true tag.
187   // This is done in case there is no vlan present. The ethertype will
188   // definitely be placed later
189   //mov  s_l1View1aMac.etherType,  0x8000
191   // Write the entire view to the lut
192   xout XID_LUT1V1,   s_l1View1aMac,    SIZE(s_l1View1aMac)
193   
194 #ifndef PASS_PROC_EOAM 
195   // cdeCmdWd.operation already has CDE_CMD_WINDOW_ADVANCE
196   add  s_pktCxt.startOffset,   s_pktCxt.startOffset,  SIZE(s_macAddr)
197 #else
198   add  s_pktCxt6.startOffsetEoam, s_pktCxt6.startOffsetEoam, SIZE(s_macAddr)
199   mov  s_cdeCmdWd.operation,  CDE_CMD_WINDOW_ADVANCE  
200 #endif // PASS_PROC_EOAM
202   mov  s_cdeCmdWd.byteCount,   SIZE(s_macAddr)
203   xout XID_CDECTRL,            s_cdeCmdWd,            SIZE(s_cdeCmdWd)
204   
205 l_c1ParseMac_BM:  
206   // Detect Broadcast & Multicast
207   qbbc  l_c1ParseMac_BM_end,  s_macAddr.DstAddr_01.t_eth_multicast_ind
208 #ifndef PASS_PROC_EOAM
209        // assume it is muticast 
210        set   s_pktCxt.flags.t_flag_multicast
211 #endif     // PASS_PROC_EOAM  
212        set   s_l1View3bMac.pktFlags.fL2Mcast
213   
214 l_c1ParseMac_BM_0:
215   
216   mov   r0, 0xFFFF
217   qbne  l_c1ParseMac_BM_end,  s_macAddr.DstAddr_01, r0
218   qbne  l_c1ParseMac_BM_end,  s_macAddr.DstAddr_23, r0
219   qbne  l_c1ParseMac_BM_end,  s_macAddr.DstAddr_45, r0 
220 #ifndef PASS_PROC_EOAM  
221         // It is broadcast
222         clr   s_pktCxt.flags.t_flag_multicast
223         set   s_pktCxt.flags.t_flag_broadcast
224 #endif    // PASS_PROC_EOAM    
225         clr   s_l1View3bMac.pktFlags.fL2Mcast         
226         set   s_l1View3bMac.pktFlags.fL2Bcast
228 l_c1ParseMac_BM_end:
230     // Load the ethertype table from memory  (move here to avoid multile load)
231     // Note: The register space will not be overwritten during mac header parsing
232     lbco  s_ethertypes,  PAMEM_CONST_PARSE,  OFFSET_ETYPE_TABLE,  SIZE(s_ethertypes)
235   // Fall through to c1ProcessTagOrLen
237     .leave lut1Scope
238     .leave pktScope
239     .leave cdeScope
240     .leave macVlanScope
243 // ************************************************************************************
244 // * FUNCTION PURPSE: Process an ethertype/802.3 ethertype/length field
245 // ************************************************************************************
246 // * DESCRIPTION: Examine the packet starting at an ethertype or length field
247 // *              and find the ethertype
248 // *
249 // *    On entry:
250 // *                - CDE points at the tag or length field
251 // *                - r30.w0 contains the return address
252 // *                - cdeCmdWd.operation has CDE_CMD_WINDOW_ADVANCE
253 // *                - param.action has SUBS_ACTION_PARSE
254 // *
255 // *    On exit:
256 // *                - CDE points to the 1st byte after the ethertype (and llc/snap if present)
257 // *                - param.action has the next action to take
258 // *                - cdeCmdWd.operation has CDE_CMD_WINDOW_ADVANCE
259 // *
260 // *   Register Usage:  
261 // * 
262 // *   R0:    scratch
263 // *   R1:    scratch
264 // *   R2:      |  checkScope  
265 // *   R3:              b0 - next header type  - pktScope
266 // *   R4:    |  CDE commands     -  cdeScope
267 // *   R5:    |                   -
268 // *   R6:        |  (packet desc) before read           |
269 // *   R7:        |                in MAC                |  mac addres (macVlanScope)
270 // *   R8:        |                                      |  Note: Should not be overwritten by other prorocol header
271 // *   R9:        |  LUT1 View   - lut1Scope
272 // *   R10:       |                                     | 
273 // *   R11:       |                                     |  LUT1 View3
274 // *   R12:       |                                     |
275 // *   R13:       |                                     |
276 // *   R14:          |  (packet extended descriptor)                                        
277 // *   R15:          |                                          
278 // *   R16:          |                                          
279 // *   R17:          |  LUT1 View  - lut1Scope                 
280 // *   R18:          |                                  | 
281 // *   R19:          |                                  |  ethertypes table
282 // *   R20:          |                                  |
283 // *   R21:          |                                  |
284 // *   R22:     |     
285 // *   R23:     |  Packet context - pktScope   
286 // *   R24:     |
287 // *   R25:     |
288 // *   R26:     |
289 // *   R27:     |
290 // *   R28:  
291 // *   R29:  c1RunContext (s_runCxt)                                -  Global Scope
292 // *   R30:  w2-param.action  w0-function return address            -
293 // *   R31:  System Flags (s_flags)                                 -
294 // *
295 // ***********************************************************************************/
297     .using  lut1Scope
298     .using  pktScope
299     .using  cdeScope
300     .using  macVlanScope
302 f_c1ProcessTagOrLen:
304     mov  s_cdeCmdWd.byteCount,   2   // minimum 2 bytes for ethertype
306     // Read in enough data to cover the llc/snap header if present
307     xin  XID_CDEDATA,   s_tagOrLen,  SIZE(s_tagOrLen)
309     mov    r3,    1500
310     qblt   l_c1ProcessTagOrLen0,  s_tagOrLen.len,   r3
312         // tag/len < 1500, so verify DSP, SSAP and ctrl
313         qbne  l_c1ProcessTagOrLen9,  s_tagOrLen.dsap,  0xaa
314         qbne  l_c1ProcessTagOrLen9,  s_tagOrLen.asap,  0xaa
315         qbne  l_c1ProcessTagOrLen9,  s_tagOrLen.ctrl,  0x03
316         
317 #ifndef PASS_PROC_EOAM        
318         //Padding check ?
319         qbbc l_c1ProcessTagOrLen00, s_runCxt.flag2.t_macPaddingChk
320             // Is payload length >= 46?
321             qble l_c1ProcessTagOrLen00, s_tagOrLen.len, 46 
322             // Is packet size == 64?
323             qbeq l_c1ProcessTagOrLen00, s_pktCxt.endOffset, 64
324                 //Padding error, update the counter and drop the packet
325                 // User Statistics operation:
326                 // Record and insert the statistics update into the FIFO
327                 
328                 mov   s_usrStatsReq.pktSize, s_pktCxt.endOffset
329                 lbco  s_usrStatsReq.index,  PAMEM_CONST_CUSTOM,  OFFSET_MAC_PADDING_CFG,  SIZE(s_usrStatsReq.index)
330                 lbco  s_fifoCb, PAMEM_CONST_USR_STATS_FIFO_BASE,  OFFSET_PDSP_USR_STATS_FIFO_CB, SIZE(s_fifoCb)
331                 add   r1.b0,    s_fifoCb.in, 4
332                 and   r1.b0,    r1.b0,       0x1F
333         
334                 qbne  l_c1ProcessTagOrLen000, s_fifoCb.out, r1.b0
335                     // FIFO is full, bump the system error
336                     mov s_stats.value,  PA_STATS_UPDATE_REQ | PA_STATS_C1_SYSTEM_FAIL
338                     jmp l_c1ProcessTagOrLen9_1
340 l_c1ProcessTagOrLen000:
341                 // Insert the request into the FIFO   
342                 add   r1.w2,   s_fifoCb.in, OFFSET_PDSP_USR_STATS_FIFO
343                 sbco  s_usrStatsReq,  PAMEM_CONST_USR_STATS_FIFO_BASE, r1.w2, SIZE(s_usrStatsReq)
344                 sbco  r1.b0,   PAMEM_CONST_USR_STATS_FIFO_BASE,    OFFSET_PDSP_USR_STATS_FIFO_CB + OFFSET(s_fifoCb.in), SIZE(s_fifoCb.in)     
345                  
346                 jmp l_c1ProcessTagOrLen9_1        
347         
348         
349 l_c1ProcessTagOrLen00:  
350         // Mark 802.3
351         set  s_pktCxt.hdrBitmask.SUBS_PA_BIT_HEADER_802_3
352 #endif       // PASS_PROC_EOAM  
353         set   s_l1View3bMac.pktFlags.f802p3
355         //  Copy the new ethertype value to the common location
356         mov   s_tagOrLen.len,    s_tagOrLen.etype2
358         // scroll past the 8 bytes of llc/snap header
359         add   s_cdeCmdWd.byteCount,  s_cdeCmdWd.byteCount,  8
361 l_c1ProcessTagOrLen0:
363     // Copy the ethertype value to LUT1 view 1
364     mov  s_l1View1aMac.etherType,  s_tagOrLen.len
366     xout XID_LUT1V1, s_l1View1aMac.etherType,  SIZE(s_l1View1aMac.etherType)
367     xout XID_LUT1V3, s_l1View3bMac, SIZE(s_l1View3bMac)             
369     // scroll past the ethertype/llc snap
370     // cdeCmdWd.operation already has the value CDE_CMD_WINDOW_ADVANCE
371     xout  XID_CDECTRL,   s_cdeCmdWd,          SIZE(s_cdeCmdWd)
373 #ifndef PASS_PROC_EOAM 
374     // Track the active parse
375     add  s_pktCxt.startOffset,  s_pktCxt.startOffset,  s_cdeCmdWd.byteCount 
376 #else
377     add  s_pktCxt6.startOffsetEoam, s_pktCxt6.startOffsetEoam, s_cdeCmdWd.byteCount 
378 #endif // PASS_PROC_EOAM
380     // Determine the next header type based on the tag value
381     // These are arranged in order of expected appearance to reduce cycles in
382     // the common cases. Assume the action is to do a lookup, and change
383     // as required
385     mov s_param.action,  SUBS_ACTION_LOOKUP
387     qbne  l_c1ProcessTagOrLen1,   s_tagOrLen.len,  s_ethertypes.ip
388         jmp  f_l2Ipv4Proc
390 l_c1ProcessTagOrLen1:
392     qbne l_c1ProcessTagOrLen2,    s_tagOrLen.len,  s_ethertypes.ipv6
393         jmp f_l2Ipv6Proc
396 l_c1ProcessTagOrLen2:
397     qbne l_c1ProcessTagOrLen3,    s_tagOrLen.len,  s_ethertypes.vlan
398         set s_l1View3bMac.pktFlags.fL2Vlan1
399         // mov s_param.action,  SUBS_ACTION_PARSE
400         // mov s_next.Hdr,      PA_HDR_VLAN
401         // ret
402         jmp f_c1ParseVlan
404 l_c1ProcessTagOrLen3:
406     qbne l_c1ProcessTagOrLen4,    s_tagOrLen.len,   s_ethertypes.SpVlan
407         set s_l1View3bMac.pktFlags.fL2Vlan2
408         // mov s_param.action,  SUBS_ACTION_PARSE
409         // mov s_next.Hdr,      PA_HDR_VLAN
410         // ret
411         jmp f_c1ParseVlan
413 l_c1ProcessTagOrLen4:
415     qbne l_c1ProcessTagOrLen5,    s_tagOrLen.len,   s_ethertypes.mpls
416         // mov s_param.action,  SUBS_ACTION_PARSE
417         // mov s_next.Hdr,  PA_HDR_MPLS
418         // ret
419         jmp f_c1ParseMpls        
421 l_c1ProcessTagOrLen5:
423     qbne l_c1ProcessTagOrLen6,    s_tagOrLen.len,   s_ethertypes.mplsMulti
424         // mov s_param.action,  SUBS_ACTION_PARSE
425         // mov s_next.Hdr,      PA_HDR_MPLS
426         // ret
427         jmp f_c1ParseMpls
429 l_c1ProcessTagOrLen6:
431     qbne l_c1ProcessTagOrLen6_1,    s_tagOrLen.len,   s_ethertypes.PPPoE
432         // mov s_param.action,  SUBS_ACTION_PARSE
433         // mov s_next.Hdr,      PA_HDR_PPPoE
434         // ret
435         jmp f_c1ParsePPPoE
436         
437 l_c1ProcessTagOrLen6_1:
438     qbne l_c1ProcessTagOrLen7,      s_tagOrLen.len,   s_ethertypes.PPPoE_discov
439 #ifndef PASS_PROC_EOAM
440     // Mark PPPoE packet and then pass through
441    set  s_pktCxt.hdrBitmask.SUBS_PA_BIT_HEADER_PPPoE
442 #endif    // PASS_PROC_EOAM
443    set  s_l1View3bMac.pktFlags.fPPPoE //no match required
445 l_c1ProcessTagOrLen7:
446 #ifndef PASS_PROC_EOAM
447     // Unknown ethertype  proceed to lookup with next header type unknown.
448     mov s_next.Hdr,         PA_HDR_UNKNOWN
449     // 802.1ag detection
450     qbbc    l_c1ProcessTagOrLen8, s_runCxt.flag2.t_802_1agDet
451 #endif     // PASS_PROC_EOAM
452         // Common rule (draft and standard) 01 80 C2 XX XX XX or 01 80 C2 00 00 3X
453         mov     r0.w0,  ETH_TYPE_802_1AG
454         qbne    l_c1ProcessTagOrLen8,   s_tagOrLen.len, r0.w0   
455 #ifndef PASS_PROC_EOAM        
456         qbne    l_c1ProcessTagOrLen8,   s_macAddr.DstAddr_01.b1,    0x01  
457         qbne    l_c1ProcessTagOrLen8,   s_macAddr.DstAddr_01.b0,    0x80
458         qbne    l_c1ProcessTagOrLen8,   s_macAddr.DstAddr_23.b1,    0xc2
459 //#ifndef PASS_PROC_EOAM
460         // draft or standard
461         qbbc    l_c1ProcessTagOrLen7_1, s_runCxt.flag2.t_802_1agStd 
462 //#endif  // PASS_PROC_EOAM      
463             qbne    l_c1ProcessTagOrLen8,   s_macAddr.DstAddr_23.b0,    0x00
464             qbne    l_c1ProcessTagOrLen8,   s_macAddr.DstAddr_45.b1,    0x00
465             and     r0.b0,  s_macAddr.DstAddr_45.b0,    0xF0
466             qbne    l_c1ProcessTagOrLen8,   r0.b0,   0x30
467         
468 l_c1ProcessTagOrLen7_1:
469 #endif
470         // 802.1ag packet detected      
471 #ifndef PASS_PROC_EOAM 
472         //   Note: save one instruction since pl1Match is not important for exception route
473         or   s_pktCxt.eId_portNum_nextHdr.b1,  s_pktCxt.eId_portNum_nextHdr.b1, EROUTE_802_1ag << PKT_EIDX_SHIFT
474         jmp  l_c1ProcessTagOrLen9_2
475 #else
476         // Record the opcde and meg level in packet context
477         set  s_pktCxt6.eoamFlags.t_flag_eType8902
478 .using eoamScope        
479         // Store MEG Level and Opcode in case we need EOAM routing
480         xin  XID_CDEDATA,  s_Eoam,   SIZE(s_Eoam)
481         and  r1.b0, s_Eoam.megVer,  EOAM_VER_MASK
482         // If version is not zero, it is a invalid EOAM packet and no need
483       // to work on deciding if it is a known type or not
484       qbeq l_c1ProcessTagOrLen7_2_0, r1.b0, 0
485         set  s_pktCxt6.eoamFlags.t_flag_invalidVer
486         jmp  l_c1ProcessTagOrLen7_6
488 l_c1ProcessTagOrLen7_2_0:
489         lsr  s_pktCxt6.megLevel, s_Eoam.megVer, EOAM_MEL_SHIFT
490         mov  s_pktCxt6.opcode,   s_Eoam.opcode
492         qbne l_c1ProcessTagOrLen7_2,  s_Eoam.opcode, PA_EOAM_OPCODE_LMR
493           set s_pktCxt6.eoamFlags.t_flag_knownOpcodes
494           set s_pktCxt6.eoamFlags.t_flag_reportCount
495           jmp l_c1ProcessTagOrLen7_6
496           
497 l_c1ProcessTagOrLen7_2:
498         qbne l_c1ProcessTagOrLen7_3,  s_Eoam.opcode, PA_EOAM_OPCODE_LMM
499           set s_pktCxt6.eoamFlags.t_flag_knownOpcodes
500           set s_pktCxt6.eoamFlags.t_flag_reportCount          
501           jmp l_c1ProcessTagOrLen7_6
503 l_c1ProcessTagOrLen7_3:
504         qbne l_c1ProcessTagOrLen7_4,  s_Eoam.opcode, PA_EOAM_OPCODE_IDM
505           set s_pktCxt6.eoamFlags.t_flag_knownOpcodes
506           jmp l_c1ProcessTagOrLen7_6          
508 l_c1ProcessTagOrLen7_4:
509         qbne l_c1ProcessTagOrLen7_5,  s_Eoam.opcode, PA_EOAM_OPCODE_DMR
510           set s_pktCxt6.eoamFlags.t_flag_knownOpcodes
511           jmp l_c1ProcessTagOrLen7_6  
513 l_c1ProcessTagOrLen7_5:
514         qbne l_c1ProcessTagOrLen7_6,  s_Eoam.opcode, PA_EOAM_OPCODE_DMM
515           set s_pktCxt6.eoamFlags.t_flag_knownOpcodes
516           // jmp l_c1ProcessTagOrLen7_6          
518 l_c1ProcessTagOrLen7_6:        
519 .leave eoamScope        
520 #endif // PASS_PROC_EOAM
522 l_c1ProcessTagOrLen8:
523 #ifndef PASS_PROC_EOAM
524     xout XID_LUT1V3, s_l1View3bMac, SIZE(s_l1View3bMac) 
525     ret
526 #else
527 .using  eoamScope
528     // Parse through the Exception protocols to disable count for match
529     // Load the protocol list from the exception table
530     // Check with each exception tabled protocol to force disable the counts
532     // mov  r1, OFFSET_EOAM_EXCEPTION_TBL
533     // Load first two protocols to check
534     lbco r1,  PAMEM_CONST_EOAM_EXC_TABLE, OFFSET_EOAM_EXCEPTION_TBL, 8
535     qbeq l_c1ProcessEoamExcProcComplete, r1.w2, 0
536       qbne l_c1ProcessEoamCheckProto1, r1.w2, s_tagOrLen.len
537         set s_pktCxt6.eoamFlags.t_flag_fDisableCnt       
538         jmp l_c1ProcessEoamExcProcComplete
540 l_c1ProcessEoamCheckProto1:    
541     qbeq l_c1ProcessEoamExcProcComplete, r1.w0, 0
542       qbne l_c1ProcessEoamCheckProto2, r1.w0, s_tagOrLen.len
543         set s_pktCxt6.eoamFlags.t_flag_fDisableCnt    
544         jmp l_c1ProcessEoamExcProcComplete    
546 l_c1ProcessEoamCheckProto2:
547     // point to next two exception protocols
548     //add  r1,  r1, 4
549     //lbco r3,  PAMEM_CONST_EOAM_EXC_TABLE, r1, 4        
550     qbeq l_c1ProcessEoamExcProcComplete, r2.w2, 0
551       qbne l_c1ProcessEoamCheckProto3, r2.w2, s_tagOrLen.len
552         set s_pktCxt6.eoamFlags.t_flag_fDisableCnt   
553         jmp l_c1ProcessEoamExcProcComplete
555 l_c1ProcessEoamCheckProto3:      
556     qbeq  l_c1ProcessEoamExcProcComplete, r2.w0,0 
557       qbne l_c1ProcessEoamCheckProto4, r2.w0, s_tagOrLen.len
558         set s_pktCxt6.eoamFlags.t_flag_fDisableCnt   
559         jmp l_c1ProcessEoamExcProcComplete    
561 l_c1ProcessEoamCheckProto4:
562     // point to next two exception protocols
563     // add  r1,  r1, 8
564     lbco r1,  PAMEM_CONST_EOAM_EXC_TABLE, OFFSET_EOAM_EXCEPTION_TBL + 8, 8
565     qbeq l_c1ProcessEoamExcProcComplete, r1.w2, 0
566       qbne l_c1ProcessEoamCheckProto5, r1.w2, s_tagOrLen.len
567         set s_pktCxt6.eoamFlags.t_flag_fDisableCnt    
568         jmp l_c1ProcessEoamExcProcComplete
570 l_c1ProcessEoamCheckProto5:      
571     qbeq  l_c1ProcessEoamExcProcComplete, r1.w0, 0 
572       qbne l_c1ProcessEoamCheckProto6, r1.w0, s_tagOrLen.len
573         set s_pktCxt6.eoamFlags.t_flag_fDisableCnt   
574         jmp l_c1ProcessEoamExcProcComplete    
576 l_c1ProcessEoamCheckProto6:
577     // point to next two exception protocols
578     // add  r1,  r1, 4
579     // lbco r3,  PAMEM_CONST_EOAM_EXC_TABLE, r1, 4        
580     qbeq  l_c1ProcessEoamExcProcComplete, r2.w2,0
581       qbne l_c1ProcessEoamCheckProto1, r2.w2, s_tagOrLen.len
582         set s_pktCxt6.eoamFlags.t_flag_fDisableCnt   
583         jmp l_c1ProcessEoamExcProcComplete
585 l_c1ProcessEoamCheckProto7:      
586     qbeq  l_c1ProcessEoamExcProcComplete, r2.w0, 0
587       qbne l_c1ProcessEoamExcProcComplete, r2.w0, s_tagOrLen.len
588         set s_pktCxt6.eoamFlags.t_flag_fDisableCnt    
589         //jmp l_c1ProcessEoamExcProcComplete    
590     
591 l_c1ProcessEoamExcProcComplete:    
592      jmp  fci_c1Parse14
593 .leave eoamScope    
594 #endif // PASS_PROC_EOAM
596 l_c1ProcessTagOrLen9:
597     //  LLC/SNAP failure
598     mov s_stats.value,  PA_STATS_UPDATE_REQ | PA_STATS_LLC_SNAP_FAIL 
600 l_c1ProcessTagOrLen9_1:    
601     //   Note: save one instruction since pl1Match is not important for exception route
602     or   s_pktCxt.eId_portNum_nextHdr.b1,  s_pktCxt.eId_portNum_nextHdr.b1, EROUTE_PARSE_FAIL << PKT_EIDX_SHIFT
604 l_c1ProcessTagOrLen9_2:    
605     mov  s_param.action,     SUBS_ACTION_EXIT
606     ret 
608 #else
609     // Error Handling
610     mov  s_param.action,     SUBS_ACTION_EXIT
611     ret 
613 #endif    // PASS_PROC_L2_PARSE
615     .leave lut1Scope
616     .leave pktScope
617     .leave cdeScope
618     .leave macVlanScope
620 #ifdef PASS_PROC_L2_PARSE
621 // ************************************************************************************
622 // * FUNCTION PURPSE: Process Ipv4 packet in L2 Parsing
623 // ************************************************************************************
624 // * DESCRIPTION: Process the IP packet, (EOAM: Also record the RA specific information)
625 // *
626 // *    On entry:
627 // *                - CDE points at the IPV4 header
628 // *                - cdeCmdWd.operation has CDE_CMD_WINDOW_ADVANCE
629 // *                - param.action has SUBS_ACTION_PARSE
630 // *
631 // *    On exit:
632 // *                - CDE points to the 1st byte after the ethertype (and llc/snap if present)
633 // *                - param.action has the next action to take
634 // *                - cdeCmdWd.operation has CDE_CMD_WINDOW_ADVANCE
635 // *
636 // *   Register Usage:  
637 // * 
638 // *   R0:    scratch
639 // *   R1:    scratch
640 // *   R2:      |  checkScope  
641 // *   R3:              b0 - next header type  - pktScope
642 // *   R4:    |  CDE commands     -  cdeScope
643 // *   R5:    |                   -
644 // *   R6:        |                                     | 
645 // *   R7:        |                                     |
646 // *   R8:        |                                     |  Note: Should not be overwritten by other prorocol header
647 // *   R9:        |  LUT1 View   - lut1Scope
648 // *   R10:       |                                     | 
649 // *   R11:       |                                     |  LUT1 View3
650 // *   R12:       |                                     |
651 // *   R13:       |                                     |
652 // *   R14:          |  (packet extended descriptor)                                        
653 // *   R15:          |                                          
654 // *   R16:          |                                          
655 // *   R17:          |  LUT1 View  - lut1Scope                 
656 // *   R18:          |                                  | 
657 // *   R19:          |                                  |  ethertypes table
658 // *   R20:          |                                  |
659 // *   R21:          |                                  |
660 // *   R22:     |     
661 // *   R23:     |  Packet context - pktScope   
662 // *   R24:     |
663 // *   R25:     |
664 // *   R26:     |
665 // *   R27:     |
666 // *   R28:  
667 // *   R29:  c1RunContext (s_runCxt)                                -  Global Scope
668 // *   R30:  w2-param.action  w0-function return address            -
669 // *   R31:  System Flags (s_flags)                                 -
670 // *
671 // ***********************************************************************************/
673     .using  lut1Scope
674     .using  pktScope
675     .using  cdeScope
676     .using  ipScope
678 f_l2Ipv4Proc: 
680 #ifndef PASS_PROC_EOAM
681         // Store DSCP in case we need DSCP priority routing
682         xin  XID_CDEDATA,  s_Ip,   OFFSET(s_Ip.checksum) 
683         lsr s_pktCxt.priority, s_Ip.tos, 2
684         mov s_next.Hdr,  PA_HDR_IPv4
685         ret
686 #else
687         xin  XID_CDEDATA,  s_Ip,   SIZE(s_Ip) 
688         set  s_runCxt.flags.t_l4Avil  
689         set  s_pktCxt6.eoamFlags.t_flag_ip 
690         // Setup RA Info
691         lbco  s_raInfo,  cCdeOutPkt,  SIZE(s_pktDescr) + 24,  SIZE(s_raInfo)
692         mov  s_raInfo.l3Offset, s_pktCxt6.startOffsetEoam   
694         // Fragmentation check
695         mov   r3.w0,    IPV4_FRAG_MASK
696         and   r3.w0,    s_Ip.fragOff,     r3.w0
697         qbeq  l_l2Ipv4Proc_2,  r3.w0, 0
698           clr  r3.w0.t_ipv4_frag_m
699           qbeq l_l2Ipv4Proc_1, r3.w0, 0
700           clr  s_runCxt.flags.t_l4Avil
701          
702 l_l2Ipv4Proc_1: 
703         set s_raInfo.flags.t_ra_flag_reasm  
704         set s_pktCxt6.eoamFlags.t_flag_fragFound        
705         
706 l_l2Ipv4Proc_2:
707         wbs   s_flags.info.tStatus_CDEOutPacket
708         sbco  s_raInfo,  cCdeOutPkt,  SIZE(s_pktDescr) + 24,  SIZE(s_raInfo)
709         
710         // Check if it is ESP header as next Header, if so set Cipher Pkt Detected
711         qbne l_l2Ipv4Proc_3, s_Ip.protocol, IP_PROTO_NEXT_ESP
712           set s_pktCxt6.eoamFlags.t_flag_cipherPkt
713           
714 l_l2Ipv4Proc_3:
715         qbne l_l2Ipv4Proc_4, s_Ip.protocol, IP_PROTO_NEXT_AUTH
716           set s_pktCxt6.eoamFlags.t_flag_cipherPkt 
717           
718 l_l2Ipv4Proc_4:
720         // Check if NAT-T detection is enabled, if yes treat the Pkt as Cipher if matching port found
721         qbbc  l_l2Ipv4Proc_5,  s_runCxt.flag2.t_IpsecNatTDetEnEoam 
723           add  r0.w0, s_pktCxt6.startOffsetEoam, SIZE(s_Ip)
724          
725           // Read in the UDP header
726           add     r0.w0, r0.w0, 32+32+8
727           lbco    r1,  cCdeInPkt, r0.w0, 4
728         
729           // A switch to IPSEC_NAT_T mode is made based on destination or source UDP port
730           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)
731           qbeq  l_l2Ipv4Proc_5_0, r1.w0,  r0.w0 
732           qbne  l_l2Ipv4Proc_5,   r1.w2,  r0.w0
733 l_l2Ipv4Proc_5_0:          
734             set s_pktCxt6.eoamFlags.t_flag_cipherPkt 
735             
736 l_l2Ipv4Proc_5:        
737         jmp fci_c1Parse14
738 #endif
739     .leave lut1Scope
740     .leave pktScope
741     .leave cdeScope
742     .leave ipScope
744 // ************************************************************************************
745 // * FUNCTION PURPSE: Process Ipv6 packet in L2 Parsing
746 // ************************************************************************************
747 // * DESCRIPTION: Process the IP packet, (EOAM: Also record the RA specific information)
748 // *
749 // *    On entry:
750 // *                - CDE points at the IPV4 header
751 // *                - cdeCmdWd.operation has CDE_CMD_WINDOW_ADVANCE
752 // *                - param.action has SUBS_ACTION_PARSE
753 // *
754 // *    On exit:
755 // *                - CDE points to the 1st byte after the ethertype (and llc/snap if present)
756 // *                - param.action has the next action to take
757 // *                - cdeCmdWd.operation has CDE_CMD_WINDOW_ADVANCE
758 // *
759 // *   Register Usage:  
760 // * 
761 // *   R0:    scratch
762 // *   R1:    scratch
763 // *   R2:      |  checkScope  
764 // *   R3:              b0 - next header type  - pktScope
765 // *   R4:    |  CDE commands     -  cdeScope
766 // *   R5:    |                   -
767 // *   R6:        |                                     | 
768 // *   R7:        |                                     |
769 // *   R8:        |                                     |  Note: Should not be overwritten by other prorocol header
770 // *   R9:        |  LUT1 View   - lut1Scope
771 // *   R10:       |                                     | 
772 // *   R11:       |                                     |  LUT1 View3
773 // *   R12:       |                                     |
774 // *   R13:       |                                     |
775 // *   R14:          |  (packet extended descriptor)                                        
776 // *   R15:          |                                          
777 // *   R16:          |                                          
778 // *   R17:          |  LUT1 View  - lut1Scope                 
779 // *   R18:          |                                  | 
780 // *   R19:          |                                  |  ethertypes table
781 // *   R20:          |                                  |
782 // *   R21:          |                                  |
783 // *   R22:     |     
784 // *   R23:     |  Packet context - pktScope   
785 // *   R24:     |
786 // *   R25:     |
787 // *   R26:     |
788 // *   R27:     |
789 // *   R28:  
790 // *   R29:  c1RunContext (s_runCxt)                                -  Global Scope
791 // *   R30:  w2-param.action  w0-function return address            -
792 // *   R31:  System Flags (s_flags)                                 -
793 // *
794 // ***********************************************************************************/
796     .using  lut1Scope
797     .using  pktScope
798     .using  cdeScope
799     .using  ipScope
801 #ifdef PASS_PROC_EOAM
802 // Local structure defintion and assignment    
803 .struct struct_ipv6Frag_ctrl
804   .u8    nextHdr
805   .u8    hdrLen
806   .u16   offset
807   .u16   maxOffset
808   .u16   rsvd
809 .ends
811 .assign struct_ipv6Frag_ctrl,  r0,     r1,    s_ipv6Frag_ctrl
812 #endif
814 #define PA_EOAM_MAX_HDR_LEN                   256
816 f_l2Ipv6Proc:
817 #ifndef PASS_PROC_EOAM
818         // Store DSCP in case we need DSCP priority routing
819         xin  XID_CDEDATA,  s_Ipv6a,   OFFSET(s_Ipv6a.payloadLen)
820         lsr  s_pktCxt.priority,   s_Ipv6a.ver_tclass_flow.w2,  4
821         lsr  s_pktCxt.priority,   s_pktCxt.priority,           2
822         mov s_next.Hdr,  PA_HDR_IPv6
823         ret
824 #else
825         // Read in the IPv6 header.
826         xin  XID_CDEDATA,  s_Ipv6a,   SIZE(s_Ipv6a)
827         
828         set  s_pktCxt6.eoamFlags.t_flag_ip
829         set  s_runCxt.flags.t_l4Avil 
831         // Setup RA Info
832         lbco s_raInfo,  cCdeOutPkt,  SIZE(s_pktDescr) + 24,  SIZE(s_raInfo)
833         mov  s_raInfo.l3Offset, s_pktCxt6.startOffsetEoam  
835         add  s_raInfo.ipv6NextOffset, s_pktCxt6.startOffsetEoam, OFFSET(s_Ipv6a.next)
836         add  s_pktCxt6.startOffsetEoam,   s_pktCxt6.startOffsetEoam,  IPV6_HEADER_LEN_BYTES
837    
838         qbbs  l_l2Ipv6Proc_1_0, s_pktCxt.flags.t_flag_cascaded_forwarding
839         qbbc  l_l2Ipv6Proc_1_0, s_runCxt.flag2.t_raEn
840           wbs   s_flags.info.tStatus_CDEOutPacket
841           sbco  s_raInfo,  cCdeOutPkt,  SIZE(s_pktDescr) + 24,  SIZE(s_raInfo)
842 //           jmp  l_l2Ipv6Proc_1
843 l_l2Ipv6Proc_1_0: 
844    
845         // Pass 1 operation
846         // Fragmentation detection: Is there fragment header?
847         // Get to nextHdr field in IPv6 header
848         // Load nextHdr and hdrLen field
849         // Check to see if nextHdr is an extension header
850         zero    &s_ipv6Frag_ctrl,     SIZE(s_ipv6Frag_ctrl)
851         mov     s_ipv6Frag_ctrl.nextHdr,  s_Ipv6a.next 
852         add     s_ipv6Frag_ctrl.offset,   s_pktCxt6.startOffsetEoam, (32 + 40) 
853         mov     s_ipv6Frag_ctrl.maxOffset, (32 + PA_EOAM_MAX_HDR_LEN)
854             
855         //mov     s_ipv6Frag_ctrl.hdrLen,   IPV6_HEADER_LEN_BYTES
857         //  Advance past the ipv6 main header
858         //  Advance past the fisr 8 byte (Ipv6a).
859         zero &s_cdeCmdWd,            SIZE(s_cdeCmdWd)
860         mov  s_cdeCmdWd.operation,   CDE_CMD_WINDOW_ADVANCE
861         mov  s_cdeCmdWd.byteCount,   SIZE(s_Ipv6a)                     // Bytes always present in the header
862         xout XID_CDECTRL,    s_cdeCmdWd,   SIZE(s_cdeCmdWd)
864 l_l2Ipv6Proc_exthdrCheck:
865         qble    l_l2Ipv6Proc_exthdrDone,  s_ipv6Frag_ctrl.offset,  s_ipv6Frag_ctrl.maxOffset    
866         qbeq    l_l2Ipv6Proc_fragfound,   s_ipv6Frag_ctrl.nextHdr, IP_PROTO_NEXT_IPV6_FRAG      
867         qbeq    l_l2Ipv6Proc_exthdrNext,  s_ipv6Frag_ctrl.nextHdr, IP_PROTO_NEXT_IPV6_HOP_BY_HOP
868         qbeq    l_l2Ipv6Proc_exthdrNext,  s_ipv6Frag_ctrl.nextHdr, IP_PROTO_NEXT_IPV6_ROUTE
869         qbeq    l_l2Ipv6Proc_exthdrNext,  s_ipv6Frag_ctrl.nextHdr, IP_PROTO_NEXT_IPV6_DEST_OPT
870 //   below would save one cycle since jmp is to header done.
871 //      qbeq    l_l2Ipv6Proc_exthdrDone,  s_ipv6Frag_ctrl.nextHdr, IP_PROTO_NEXT_IPV6_NO_NEXT
872         jmp     l_l2Ipv6Proc_exthdrDone   
874 l_l2Ipv6Proc_exthdrNext:    
875         // load the next header
876         lbco    s_ipv6Frag_ctrl.nextHdr,  cCdeInPkt, s_ipv6Frag_ctrl.offset, 2
878         // Check for hdr size greater than 255
879         qble    l_l2Ipv6Proc_exthdrDone, s_ipv6Frag_ctrl.hdrLen, 63
881         // adjust the offset for next one
882         add     s_ipv6Frag_ctrl.hdrLen,    s_ipv6Frag_ctrl.hdrLen, 1
883         lsl     s_ipv6Frag_ctrl.hdrLen,    s_ipv6Frag_ctrl.hdrLen, 3
884         add     s_ipv6Frag_ctrl.offset,    s_ipv6Frag_ctrl.offset,  s_ipv6Frag_ctrl.hdrLen
885         mov     s_raInfo.ipv6NextOffset,   s_pktCxt6.startOffsetEoam
886         add     s_pktCxt6.startOffsetEoam, s_pktCxt6.startOffsetEoam, s_ipv6Frag_ctrl.hdrLen        
887         jmp     l_l2Ipv6Proc_exthdrCheck
888     
889 l_l2Ipv6Proc_fragfound:
890         qbbs  l_c1L2ParseIpv6ExtFrag00, s_pktCxt.flags.t_flag_cascaded_forwarding
891         qbbc  l_c1L2ParseIpv6ExtFrag00, s_runCxt.flag2.t_raEn
892           mov  s_raInfo.ipv6FragOffset, s_pktCxt6.startOffsetEoam
893           set  s_raInfo.flags.t_ra_flag_reasm
894           set  s_pktCxt6.eoamFlags.t_flag_fragFound            
895           //wbs  s_flags.info.tStatus_CDEOutPacket
896           //sbco s_raInfo,  cCdeOutPkt,  SIZE(s_pktDescr) + 24,  SIZE(s_raInfo)
897 l_c1L2ParseIpv6ExtFrag00: 
898           add  s_pktCxt6.startOffsetEoam, s_pktCxt6.startOffsetEoam,  IPV6_OPT_FRAG_EXTENSION_LEN_BYTES
899         // The fragmentation header is always 8 bytes. The whole 
900         // header is read here, but only the 1st byte is used
901         lbco    s_ipv6Frag_ctrl.nextHdr,  cCdeInPkt, s_ipv6Frag_ctrl.offset, 1
902    
903         lsr   r3.w0,   s_Ipv6Frag.fragnFlag,     IPV6_FRAG_OFF_SHIFT
904         qbeq  l_l2Ipv6Proc_ExtFrag1, r3.w0, 0
905         //    clr  s_l1View3bIpv6.pktFlags.fL3IpContainL4
906             clr  s_runCxt.flags.t_l4Avil
907 l_l2Ipv6Proc_ExtFrag1:
908          // mov   s_raInfo.ipv6FragOffset,   s_ipv6Frag_ctrl.offset          
909          // set   s_raInfo.flags.t_ra_flag_reasm
910          // set   s_pktCxt6.eoamFlags.t_flag_fragFound  
912 l_l2Ipv6Proc_exthdrDone: 
913          qbbc  l_l2Ipv6Proc_1, s_runCxt.flag2.t_raEn
914            wbs   s_flags.info.tStatus_CDEOutPacket
915            sbco  s_raInfo,  cCdeOutPkt,  SIZE(s_pktDescr) + 24,  SIZE(s_raInfo)
916   
917           //pass through
918         
919 l_l2Ipv6Proc_1: 
920         // Check if it is ESP header as next Header, if so set Cipher Pkt Detected
921         qbne l_l2Ipv6Proc_2, s_ipv6Frag_ctrl.nextHdr, IP_PROTO_NEXT_ESP
922           set s_pktCxt6.eoamFlags.t_flag_cipherPkt
923           
924 l_l2Ipv6Proc_2:   
925         // Check if it is AH header as next Header, if so set Cipher Pkt Detected
926         qbne l_l2Ipv6Proc_3, s_ipv6Frag_ctrl.nextHdr, IP_PROTO_NEXT_AUTH
927           set s_pktCxt6.eoamFlags.t_flag_cipherPkt 
928           
929 l_l2Ipv6Proc_3:  
931         // Check if NAT-T detection is enabled, if yes treat the Pkt as Cipher if matching port found
932         qbbc  l_l2Ipv6Proc_4,  s_runCxt.flag2.t_IpsecNatTDetEnEoam        
933         
934           // Read in the UDP PORTs
935           lbco    r1,  cCdeInPkt, s_ipv6Frag_ctrl.offset, 4       
936   
937           // A switch to IPSEC_NAT_T mode is made based on destination or source UDP port
938           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)
939           qbeq  l_l2Ipv6Proc_4_0,  r1.w0,  r0.w0 
940           qbne  l_l2Ipv6Proc_4, r1.w2,  r0.w0
941 l_l2Ipv6Proc_4_0:
942             set s_pktCxt6.eoamFlags.t_flag_cipherPkt 
943             
944 l_l2Ipv6Proc_4:
945         jmp fci_c1Parse14
947 #endif
948         
949     .leave lut1Scope
950     .leave pktScope
951     .leave cdeScope
952     .leave ipScope
954 #endif    
955 // ***********************************************************************************
956 // * FUNCTION PURPOSE: Parse VLAN tags
957 // ***********************************************************************************
958 // * DESCRIPTION: Vlan tags are a special case for maximum depth check. Unlike
959 // *              GRE and IP, a lookup is not performed after a vlan tag is found,
960 // *              so the max depth must be checked each time a tag is found.
961 // *
962 // *    On entry:
963 // *                - CDE points to the VLAN tag
964 // *                - param.action has SUBS_ACTION_PARSE
965 // *                - cdeCmdWd.operation has CDE_CMD_WINDOW_ADVANCE
966 // *                - r30.w0 has the return address
967 // *
968 // *    On exit:
969 // *                - CDE points to the 1st byte after the VLAN tag
970 // *                - param.action has the next action to take  
971 // *                  jmp back to f_c1ProcessTagOrLen until a ethertype is recognized 
972 // *                - cdeCmdWd.operation has CDE_CMD_WINDOW_ADVANCE
973 // *
974 // *   Register Usage:  
975 // * 
976 // *   R0:    scratch
977 // *   R1:    scratch
978 // *   R2:      |  checkScope  
979 // *   R3:              b0 - next header type  - pktScope
980 // *   R4:    |  CDE commands     -  cdeScope
981 // *   R5:    |                   -
982 // *   R6:        |  (packet desc) before read           |
983 // *   R7:        |                in MAC                |  mac addres (macVlanScope)
984 // *   R8:        |                                      |  Note: Should not be overwritten by other prorocol header
985 // *   R9:        |  LUT1 View   - lut1Scope
986 // *   R10:       |                                     | 
987 // *   R11:       |                                     |  LUT1 View3
988 // *   R12:       |                                     |
989 // *   R13:       |                                     |
990 // *   R14:          |  (packet extended descriptor)                                        
991 // *   R15:          |                                          
992 // *   R16:          |                                          
993 // *   R17:          |  LUT1 View  - lut1Scope                 
994 // *   R18:          |                                  | 
995 // *   R19:          |                                  |  ethertypes table
996 // *   R20:          |                                  |
997 // *   R21:          |                                  |
998 // *   R22:     |     
999 // *   R23:     |  Packet context - pktScope   
1000 // *   R24:     |
1001 // *   R25:     |
1002 // *   R26:     |
1003 // *   R27:     |
1004 // *   R28:  
1005 // *   R29:  c1RunContext (s_runCxt)                                -  Global Scope
1006 // *   R30:  w2-param.action  w0-function return address            -
1007 // *   R31:  System Flags (s_flags)                                 -
1008 // *
1009 // *
1010 // *
1011 // ***********************************************************************************
1012     .using pktScope
1013     .using checkScope
1014     .using cdeScope
1015     .using lut1Scope
1016     .using macVlanScope
1018 f_c1ParseVlan:
1019 #ifdef PASS_PROC_L2_PARSE
1020 #ifndef PASS_PROC_EOAM
1021   set  s_pktCxt.hdrBitmask.SUBS_PA_BIT_HEADER_VLAN
1023   // Check agains the max
1024   lsr  r0.w0,   s_pktCxt.protCount, PROT_COUNT_VLAN_SHIFT
1025   lbco  s_paMaxHdrCount.vlanMaxCount,  PAMEM_CONST_CUSTOM,  OFFSET_MAX_HDR + OFFSET(s_paMaxHdrCount.vlanMaxCount), 2
1027   qbgt l_c1ParseVlan1,  r0.w0,  s_paMaxHdrCount.vlanMaxCount
1028       or     s_pktCxt.eId_portNum_nextHdr.b1, s_pktCxt.eId_portNum_nextHdr.b1,   EROUTE_VLAN_MAX_DEPTH << PKT_EIDX_SHIFT
1029       mov s_param.action, SUBS_ACTION_EXIT
1030       ret
1032 l_c1ParseVlan1:
1033   // Inc the vlan count
1034   add  s_pktCxt.protCount,   s_pktCxt.protCount,    PROT_COUNT_VLAN_STEP
1035 #endif
1037   // Read in the pri/cfi/vlanId fields. Mask out pri/cfi
1038   xin  XID_CDEDATA,         s_vtag.tag,           SIZE(s_vtag.tag)
1040 #ifndef PASS_PROC_EOAM  
1041   // record vlan priority 
1042   and  s_pktCxt.vlanPri_vLink.b1,    s_vtag.tag.b1, PKT_VALN_PRI_MASK
1043 #endif
1045   qbbc l_c1ParseVlan2, s_l1View3bMac.pktFlags.fL2Vlan1
1046     // VLAN2 always appear in front of VLAN1
1047     mov  s_l1View3bMac.vlanId1,     s_vtag.tag
1048     and  s_l1View3bMac.vlanId1.b1,  s_l1View3bMac.vlanId1.b1,   0xf
1049     lsr  s_l1View3bMac.vlanPri1,    s_vtag.tag, 13       
1050     //xout XID_LUT1V1,          s_l1View1a.VLAN,      SIZE(s_l1View1a.VLAN)
1051     jmp  l_c1ParseVlan3
1052   
1053 l_c1ParseVlan2: 
1054     // VLAN1 operation
1055     mov  s_l1View3bMac.vlanId2,     s_vtag.tag
1056     and  s_l1View3bMac.vlanId2.b1,  s_l1View3bMac.vlanId2.b1,   0xf
1057     lsr  s_l1View3bMac.vlanPri2,    s_vtag.tag, 13
1058     
1059     // pass through       
1060 l_c1ParseVlan3:
1061 #ifndef PASS_PROC_EOAM
1062   add s_pktCxt.startOffset, s_pktCxt.startOffset, SIZE(s_vtag.tag)
1063 #else
1064   add  s_pktCxt6.startOffsetEoam, s_pktCxt6.startOffsetEoam, SIZE(s_vtag.tag)
1065 #endif
1066   // Scroll the CDE past the tag to point to the next ethertype candidate
1067   mov  s_cdeCmdWd.byteCount,  SIZE(s_vtag.tag)
1068   xout XID_CDECTRL,           s_cdeCmdWd,         SIZE(s_cdeCmdWd)
1070   jmp f_c1ProcessTagOrLen
1072 #endif      
1073     .leave pktScope
1074     .leave checkScope
1075     .leave cdeScope
1076     .leave lut1Scope
1077     .leave macVlanScope
1078     
1079 // ***************************************************************************************
1080 // * FUNCTION PURPOSE: Parse MPLS headers
1081 // ***************************************************************************************
1082 // * DESCRIPTION: An MPLS label stack is processed. If there is more then one label in
1083 // *              the stack then the packet is sent immediately to LUT1 with the top
1084 // *              label in the LUT. If there is only one lable then parsing continues
1085 // *              after checking that the next header protocol COULD be Ipv4 or IPv6
1086 // *
1087 // *        On Entry
1088 // *            -  CDE points to start of MPLS header
1089 // *            -  param.action set to SUBS_ACTION_PARSE
1090 // *            -  next.hdr set to PA_HDR_MPLS
1091 // *        
1092 // *        On Exit
1093 // *            -  CDE points to 1st byte after 1st MPLS tag
1094 // *            -  param.action is (either SUBS_ACTION_PARSE ) or SUBS_ACTION_LOOKUP
1095 // *            -  next.hdr set to either PA_HDR_IPv4, PA_HDR_IPv6 or PA_HDR_UNKNOWN
1096 // *
1097 // *   Register Usage:  
1098 // * 
1099 // *   R0:    scratch
1100 // *   R1:    
1101 // *   R2:    
1102 // *   R3:              b0 - next header type  - pktScope
1103 // *   R4:    |  CDE commands     -  cdeScope
1104 // *   R5:    |                   -
1105 // *   R6:        |  (packet desc) before read           |
1106 // *   R7:        |                in MAC                |  mac addres (macVlanScope)
1107 // *   R8:        |                                      |  Note: Should not be overwritten by other prorocol header
1108 // *   R9:        |  LUT1 View   - lut1Scope
1109 // *   R10:       |                                     | 
1110 // *   R11:       |                                     |  LUT1 View3
1111 // *   R12:       |                                     |
1112 // *   R13:       |                                     |
1113 // *   R14:          |  (packet extended descriptor)                                        
1114 // *   R15:          |                                          
1115 // *   R16:          |                                          
1116 // *   R17:          |  LUT1 View  - lut1Scope                 
1117 // *   R18:          |                                  | 
1118 // *   R19:          |                                  |  ethertypes table
1119 // *   R20:          |                                  |
1120 // *   R21:          |                                  |
1121 // *   R22:     |     
1122 // *   R23:     |  Packet context - pktScope   
1123 // *   R24:     |
1124 // *   R25:     |
1125 // *   R26:     |
1126 // *   R27:     |
1127 // *   R28:  
1128 // *   R29:  c1RunContext (s_runCxt)                                -  Global Scope
1129 // *   R30:  w2-param.action  w0-function return address            -
1130 // *   R31:  System Flags (s_flags)                                 -
1131 // *
1132 // ***************************************************************************************
1134     .using pktScope
1135     .using cdeScope
1136     .using lut1Scope
1137     .using mplsScope
1139 f_c1ParseMpls:
1140 #ifdef PASS_PROC_L2_PARSE
1142 #ifndef PASS_PROC_EOAM
1143    set s_pktCxt.hdrBitmask.SUBS_PA_BIT_HEADER_MPLS
1144    mov s_stats.value,  PA_STATS_UPDATE_REQ | PA_STATS_MPLS_PKTS
1145 #endif
1146    xin  XID_CDEDATA,  s_mpls,  SIZE(s_mpls)   // Read in a single tag
1148    // The tag is the 20 MSBs of the 32 bit word
1149    lsr  s_l1View2cMac.mpls,  s_mpls.tagTtl,  12
1150    xout XID_LUT1V2,          s_l1View2cMac.mpls,  SIZE(s_l1View2cMac.mpls)
1152    set  s_l1View3bMac.pktFlags.fMpls
1153    
1154 #ifndef PASS_PROC_EOAM   
1155    add  s_pktCxt.startOffset,   s_pktCxt.startOffset,  SIZE(s_mpls.tagTtl)
1156 #else
1157    add  s_pktCxt6.startOffsetEoam, s_pktCxt6.startOffsetEoam, SIZE(s_mpls.tagTtl)
1158 #endif
1160    mov   s_cdeCmdWd.byteCount,  SIZE(s_mpls.tagTtl)
1161    xout  XID_CDECTRL,           s_cdeCmdWd,           SIZE(s_cdeCmdWd)
1163    // Always perform a lookup after finding an MPLS headeer
1164    mov  s_param.action,  SUBS_ACTION_LOOKUP
1166    // Extract the S bit. If set then get a potential IP version number
1167    // For possible IPv4 and IPv6 continue parse
1169    qbbc  l_c1ParseMpls1,  s_mpls.tagTtl.t_s
1170        lsr  r0.b0,  s_mpls.ipVer,   4
1171        qbne l_c1ParseMpls0,  r0.b0,   4
1172            //mov   s_next.hdr,          PA_HDR_IPv4
1173            //ret
1174            jmp  f_l2Ipv4Proc
1176 l_c1ParseMpls0:
1177        qbne l_c1ParseMpls1,  r0.b0,   6
1178            // mov   s_next.hdr,          PA_HDR_IPv6
1179            // ret
1180            jmp  f_l2Ipv6Proc
1181     
1182      
1183     // If there is more then one label or there is one label but the
1184     // next header doesnt look like IP, run the current packet through the LUT
1185 l_c1ParseMpls1:
1186 #ifndef PASS_PROC_EOAM
1187     mov  s_next.hdr,      PA_HDR_UNKNOWN
1188     ret
1189 #else
1190     jmp fci_c1Parse14
1191 #endif
1192     
1193 #endif    //PASS_PROC_L2_PARSE
1194       
1195     .leave pktScope
1196     .leave cdeScope
1197     .leave lut1Scope
1198     .leave mplsScope
1200 // ***************************************************************************************
1201 // * FUNCTION PURPOSE: Parse PPPoE headers
1202 // ***************************************************************************************
1203 // * DESCRIPTION: An PPPoE stack is processed. 
1204 // *              Check that the PPP protocol number, Set next hdr to unknown if it is
1205 // *              not IPv4 or IPv6 
1206 // *
1207 // *        On Entry
1208 // *            -  CDE points to start of PPPoE header
1209 // *            -  param.action set to SUBS_ACTION_PARSE
1210 // *            -  next.hdr set to PA_HDR_PPPoE
1211 // *        
1212 // *        On Exit
1213 // *            -  CDE points to start of PPPoE header
1214 // *            -  startOffset is set to the start of IP header if IPv4 or IPv6
1215 // *               Otherwise, it is set to the 1st byte after PPPoE header 
1216 // *            -  param.action is either SUBS_ACTION_EXIT  or SUBS_ACTION_LOOKUP
1217 // *            -  next.hdr set to either PA_HDR_IPv4, PA_HDR_IPv6 or PA_HDR_UNKNOWN
1218 // *
1219 // *   Register Usage:  
1220 // * 
1221 // *   R0:    scratch
1222 // *   R1:    
1223 // *   R2:    
1224 // *   R3:              b0 - next header type  - pktScope
1225 // *   R4:    |  CDE commands     -  cdeScope
1226 // *   R5:    |                   -
1227 // *   R6:        |  (packet desc) before read           |
1228 // *   R7:        |                in MAC                |  mac addres (macVlanScope)
1229 // *   R8:        |                                      |  Note: Should not be overwritten by other prorocol header
1230 // *   R9:        |  LUT1 View   - lut1Scope
1231 // *   R10:       |                                     | 
1232 // *   R11:       |                                     |  LUT1 View3
1233 // *   R12:       |                                     |
1234 // *   R13:       |                                     |
1235 // *   R14:          |  (packet extended descriptor)                                        
1236 // *   R15:          |                                          
1237 // *   R16:          |                                          
1238 // *   R17:          |  LUT1 View  - lut1Scope                 
1239 // *   R18:          |                                  | 
1240 // *   R19:          |                                  |  ethertypes table
1241 // *   R20:          |                                  |
1242 // *   R21:          |                                  |
1243 // *   R22:     |     
1244 // *   R23:     |  Packet context - pktScope   
1245 // *   R24:     |
1246 // *   R25:     |
1247 // *   R26:     |
1248 // *   R27:     |
1249 // *   R28:  
1250 // *   R29:  c1RunContext (s_runCxt)                                -  Global Scope
1251 // *   R30:  w2-param.action  w0-function return address            -
1252 // *   R31:  System Flags (s_flags)                                 -
1253 // *
1254 // ***************************************************************************************
1256     .using pktScope
1257     .using cdeScope
1258     .using lut1Scope
1259     .using pppoeScope
1261 f_c1ParsePPPoE:
1263 #ifdef PASS_PROC_L2_PARSE
1264    xin  XID_CDEDATA,  s_pppoe,  SIZE(s_pppoe)   // Read in the PPPoE header
1265    
1266    // Protocol header error check
1267    qbbc  l_c1ParsePPPoE_0, s_runCxt.flag2.t_PPPoEHdrCheck
1268      qbne  l_c1ParsePPPoE_3, s_pppoe.verType, PPPoE_VER_TYPE
1269      qbne  l_c1ParsePPPoE_3, s_pppoe.code,    PPPoE_CODE_SESSION
1270    
1271 l_c1ParsePPPoE_0:
1272 #ifndef PASS_PROC_EOAM
1273    // Mark PPPoE
1274    set  s_pktCxt.hdrBitmask.SUBS_PA_BIT_HEADER_PPPoE
1275 #endif   
1276    set  s_l1View3bMac.pktFlags.fPPPoE
1277    
1278     mov  s_l1View1aMac.PPPoE_SessionId,  s_pppoe.sessionId
1279     xout XID_LUT1V1, s_l1View1aMac.PPPoE_SessionId,  SIZE(s_l1View1aMac.PPPoE_SessionId)
1280    
1281 #ifndef PASS_PROC_EOAM  
1282    add s_pktCxt.startOffset,    s_pktCxt.startOffset,  OFFSET(s_pppoe.prot)
1283    add s_pktCxt.endOffset,      s_pktCxt.startOffset,  s_pppoe.len
1284 #else
1285    add  s_pktCxt6.startOffsetEoam, s_pktCxt6.startOffsetEoam, OFFSET(s_pppoe.prot)
1286 #endif
1288    // Always perform a lookup after finding an PPPoE headeer
1289    mov  s_param.action,  SUBS_ACTION_LOOKUP
1291    // Find out the next prot
1292    mov   r0.w0, PPPoE_PROT_IPv4           
1294    qbne  l_c1ParsePPPoE_1,  s_pppoe.prot, r0.w0
1295 #ifndef PASS_PROC_EOAM    
1296        add   s_pktCxt.startOffset,    s_pktCxt.startOffset, SIZE(s_pppoe.prot)
1297 #else
1298        add   s_pktCxt6.startOffsetEoam, s_pktCxt6.startOffsetEoam, SIZE(s_pppoe.prot)
1299 #endif       
1300        //mov   s_next.hdr,          PA_HDR_IPv4
1301        //ret
1302        jmp  f_l2Ipv4Proc
1304 l_c1ParsePPPoE_1:
1305    mov   r0.w0, PPPoE_PROT_IPv6
1306    qbne  l_c1ParsePPPoE_2,  s_pppoe.prot, r0.w0
1307 #ifndef PASS_PROC_EOAM    
1308        add   s_pktCxt.startOffset,    s_pktCxt.startOffset, SIZE(s_pppoe.prot)
1309 #else
1310        add  s_pktCxt6.startOffsetEoam, s_pktCxt6.startOffsetEoam, SIZE(s_pppoe.prot)
1311 #endif       
1312        // mov   s_next.hdr,          PA_HDR_IPv6
1313        // ret
1314        jmp  f_l2Ipv6Proc       
1315      
1316     // Unsupported protocol
1317     // next header does not look like IP;  Exception route
1318 l_c1ParsePPPoE_2:
1319 #ifndef PASS_PROC_EOAM
1320     or     s_pktCxt.eId_portNum_nextHdr.b1, s_pktCxt.eId_portNum_nextHdr.b1, EROUTE_PPPoE_CTRL << PKT_EIDX_SHIFT      
1321 #endif    
1322     jmp l_c1ParsePPPoE_4
1323     
1324     // PPPoE header Error: Exception route
1325 l_c1ParsePPPoE_3:
1326 #ifndef PASS_PROC_EOAM
1327     or     s_pktCxt.eId_portNum_nextHdr.b1, s_pktCxt.eId_portNum_nextHdr.b1, EROUTE_PPPoE_FAIL << PKT_EIDX_SHIFT      
1328     // pass through
1329 l_c1ParsePPPoE_4:    
1330     // Common Error handling 
1331     mov s_param.action, SUBS_ACTION_EXIT
1332     mov  s_next.hdr,    PA_HDR_UNKNOWN
1333     ret
1334 #else
1335 l_c1ParsePPPoE_4:  
1336     jmp fci_c1Parse14
1337 #endif
1338 #endif    
1339       
1340     .leave pktScope
1341     .leave cdeScope
1342     .leave lut1Scope
1343     .leave pppoeScope
1344     
1345 // *********************************************************************************
1346 // *********************************************************************************
1347 // * FUNCTION PURPOSE: Parsing of SRIO header information
1348 // *********************************************************************************
1349 // * DESCRIPTION: The 1st two 32 bit words in the control data contain L0-L2 info. 
1350 // *
1351 // *   On entry:
1352 // *            - CDE points to the SRIO header (Control Info section)
1353 // *            - r30.w0 has the return address
1354 // *            - cdeCmdWd.operation has is not set
1355 // *            - param.action is not set
1356 // *            - s_runCxt has valid packet context
1357 // *            - r0.b0 packet Type (SRIO type 9 or 11 only)
1358 // *
1359 // *   On exit:
1360 // *            - CDE points to the first byte of packet
1361 // *            - cdeCmdWd.operation has CDE_CMD_FLUSH_TO_PACKET
1362 // *            - param.action has SUBS_ACTION_LOOKUP
1363 // *
1364 // *   Register Usage:  
1365 // * 
1366 // *   R0:    scratch
1367 // *   R1:    r1.b0: packet type
1368 // *   R2:    scratch
1369 // *   R3:               
1370 // *   R4:    |  CDE commands     -  cdeScope
1371 // *   R5:    |                   -
1372 // *   R6:                                              
1373 // *   R7:                                              
1374 // *   R8:                                              
1375 // *   R9:          
1376 // *   R10:       |
1377 // *   R11:       |  LUT1 View3a   - lut1Scope
1378 // *   R12:       |
1379 // *   R13:       |
1380 // *   R14:          |  SRIO header L0-L2                                        
1381 // *   R15:          |  SRIO header L0-L2                                        
1382 // *   R16:            |                                          
1383 // *   R17:            |  
1384 // *   R18:            |
1385 // *   R19:            |
1386 // *   R20:            |
1387 // *   R21:            |
1388 // *   R22:     |     
1389 // *   R23:     |  Packet context - pktScope   
1390 // *   R24:     |
1391 // *   R25:     |
1392 // *   R26:     |
1393 // *   R27:     |
1394 // *   R28:  
1395 // *   R29:  c1RunContext (s_runCxt)                                -  Global Scope
1396 // *   R30:  w2-param.action  w0-function return address            -
1397 // *   R31:  System Flags (s_flags)                                 -
1398 // *
1399 // **********************************************************************************/
1401     .using  lut1Scope
1402     .using  pktScope
1403     .using  cdeScope
1404     .using  srioScope
1406 f_c1ParseSrio:
1408 #ifdef PASS_PROC_FIREWALL
1409     jmp fci_c1FirewallException
1410 #endif
1412 #ifdef PASS_PROC_L2
1414   mov s_stats.value,  PA_STATS_UPDATE_REQ | PA_STATS_SRIO_PKTS
1416   // Load the SRIO L0-L2 info: assuming type 11 
1417   xin  XID_CDEDATA,   s_srio11,  SIZE(s_srio11)
1418   
1419   // Delete the control information. It will be replace with the packet context during parse
1420   mov   s_cdeCmdWd.operation,  CDE_CMD_FLUSH_TO_PACKET
1421   xout  XID_CDECTRL,           s_cdeCmdWd,       SIZE(s_cdeCmdWd)
1422   
1423   mov  s_param.action, SUBS_ACTION_LOOKUP
1425   // Clear the LUT1 view areas; Only Lut1V3 is used  
1426   zero &s_l1View3bSrio,     SIZE(s_l1View3bSrio)
1427   set   s_l1View3bSrio.pktType.fL2PktTypeSrio
1428   
1429   qbeq  l_c1ParseSrioType9, r1.b0, PA_PKT_TYPE_SRIO_TYPE_9
1431 l_c1ParseSrioType11:
1432     // Type 11 Message Lookup
1433     set  s_l1View3bSrio.pktFlags.fSrioType11
1434     
1435     qbbc    l_c1ParseSrioType11_1,  s_srio11.ctrl.b1.t_srio_type11_t_port16
1436         // 16-bit device 
1437         //clr s_l1View3bSrio.pktFlags.fSrioPort8
1438         mov s_l1View3bSrio.srcId,   s_srio11.srcId
1439         mov s_l1View3bSrio.dstId,   s_srio11.dstId
1440         jmp l_c1ParseSrioType11_2
1441         
1442  l_c1ParseSrioType11_1:        
1443         // 8-bit device 
1444         set s_l1View3bSrio.pktFlags.fSrioPort8
1445         and s_l1View3bSrio.srcId,   s_srio11.srcId,     0xFF
1446         and s_l1View3bSrio.dstId,   s_srio11.dstId,     0xFF
1447         
1448  l_c1ParseSrioType11_2:    
1449    
1450    and  s_l1View3bSrio.typeParam1, s_srio11.ctrl.b0,  SRIO_TYPE11_MBOX_MASK
1451    and  r1.b0,              s_srio11.ctrl.b1,   SRIO_TYPE11_PRI_MASK
1452    lsr  s_l1View3bSrio.pri, r1.b0,              SRIO_TYPE11_PRI_SHIFT   
1453    lsr  s_l1View3bSrio.typeParam2,   s_srio11.ctrl.w0,     SRIO_TYPE11_LTR_SHIFT
1454    and  s_l1View3bSrio.typeParam2,   s_l1View3bSrio.typeParam2, SRIO_TYPE11_LTR_MASK >> SRIO_TYPE11_LTR_SHIFT
1455    lsr  s_l1View3bSrio.cc,   s_srio11.ctrl.w1,  SRIO_TYPE11_CC_SHIFT
1456    and  s_l1View3bSrio.cc,   s_l1View3bSrio.cc, SRIO_TYPE11_CC_MASK >> SRIO_TYPE11_CC_SHIFT              
1457    xout XID_LUT1V3,         s_l1View3bSrio,     SIZE(s_l1View3bSrio)
1458    
1459    ret
1460    
1461 l_c1ParseSrioType9:
1462     // Type 9 Message Lookup
1463     set  s_l1View3bSrio.pktFlags.fSrioType9
1464     
1465     qbbc l_c1ParseSrioType9_1,   s_srio9.ctrl.t_srio_type9_t_port16
1466         // 16-bit device 
1467         //clr s_l1View3bSrio.pktFlags.fSrioPort8
1468         mov s_l1View3bSrio.srcId,   s_srio9.srcId
1469         mov s_l1View3bSrio.dstId,   s_srio9.dstId
1470         jmp l_c1ParseSrioType9_2
1471         
1472  l_c1ParseSrioType9_1:        
1473         // 8-bit device 
1474         set s_l1View3bSrio.pktFlags.fSrioPort8
1475         and s_l1View3bSrio.srcId,   s_srio9.srcId,     0xFF
1476         and s_l1View3bSrio.dstId,   s_srio9.dstId,     0xFF
1477         
1478  l_c1ParseSrioType9_2:    
1479    mov  s_l1View3bSrio.typeParam1, s_srio9.streamId
1480    and  r1.b0,              s_srio9.ctrl,       SRIO_TYPE9_PRI_MASK
1481    lsr  s_l1View3bSrio.pri, r1.b0,              SRIO_TYPE9_PRI_SHIFT   
1482    mov  s_l1View3bSrio.typeParam2,   s_srio9.cos
1483    and  s_l1View3bSrio.cc,  s_srio9.ctrl,       SRIO_TYPE9_CC_MASK              
1484    xout XID_LUT1V3,         s_l1View3bSrio,     SIZE(s_l1View3bSrio)
1485    
1486    ret
1487    
1488 #else
1489     // Error Handling
1490     mov  s_param.action,     SUBS_ACTION_EXIT
1491     ret 
1493 #endif  
1494    
1495     .leave lut1Scope
1496     .leave pktScope
1497     .leave cdeScope
1498     .leave srioScope
1499     
1500 // ************************************************************************************
1501 // * FUNCTION PURPOSE: Parse a custom LUT1 header
1502 // ************************************************************************************
1503 // * DESCRIPTION:
1504 // *
1505 // *    On entry:
1506 // *            - the CDE is at the start of the Custom header
1507 // *            - r30.w0 has the function return address
1508 // *            - param.action has SUBS_ACTION_PARSE
1509 // *            - cdeCmdWd.operation has CDE_CMD_WINDOW_ADVNACE
1510 // *
1511 // *    On exit:
1512 // *            - param.action has SUBS_ACTION_LOOKUP
1513 // *            - cdeCmdWd.operation has CDE_CMD_WINDOW_ADVANCE
1514 // *            - the CDE is at the first byte after Custom offset
1515 // *            - startOffset is adjusted based on nextHdr Offset
1516 // *            - s_next.Hdr is set as custHdr.nextHdr
1517 // *            
1518 // *   Register Usage:  
1519 // * 
1520 // *   R0:    scratch
1521 // *   R1:    
1522 // *   R2:    
1523 // *   R3:              
1524 // *   R4:    |  CDE commands     -  cdeScope
1525 // *   R5:    |                   -
1526 // *   R6:        |                                      
1527 // *   R7:        |                                      
1528 // *   R8:        |                                      
1529 // *   R9:        |  LUT1 View1&2   - lut1Scope
1530 // *   R10:       |
1531 // *   R11:       |
1532 // *   R12:       |
1533 // *   R13:       |
1534 // *   R14:          |  CustomHdr & Custom                                      
1535 // *   R15:          |                                          
1536 // *   R16:          |                                          
1537 // *   R17:          |                   
1538 // *   R18:          |                    |  LUT1 View3
1539 // *   R19:          |                    |
1540 // *   R20:          |                    |
1541 // *   R21:          |                    |
1542 // *   R22:     |     
1543 // *   R23:     |  Packet context - pktScope   
1544 // *   R24:     |
1545 // *   R25:     |
1546 // *   R26:     |
1547 // *   R27:     |
1548 // *   R28:  
1549 // *   R29:  c1RunContext (s_runCxt)                                -  Global Scope
1550 // *   R30:  w2-param.action  w0-function return address            -
1551 // *   R31:  System Flags (s_flags)                                 -
1552 // *
1553 // *
1554 // ************************************************************************************
1556     .using cdeScope
1557     .using pktScope
1558     .using lut1Scope
1559     .using customC1Scope
1561 f_c1ParseCustom:
1563 #ifdef PASS_PROC_LUT1_CUSTOM
1565   set  s_pktCxt.hdrBitmask.SUBS_PA_BIT_HEADER_CUSTOM
1566   mov  s_pktCxt.l3Offset,  s_pktCxt.startOffset
1567   mov s_stats.value,  PA_STATS_UPDATE_REQ | PA_STATS_C1_CUSTOM_PKTS
1569   // The previous lookup PDSP ID and index is stored in the sourceVC (Virtual Link) field
1570   zero &s_l1View3dCustom,     SIZE(s_l1View3dCustom)  
1571   mov  s_l1View3dCustom.srcVC,  s_pktCxt.phyLink
1573   // eIndex should stote the custom Index
1574   // offset = index * 40 + OFFSET_CUSTOM_C1
1575   // TBD: Should we do error check here?
1576   lsr   r1.b0,  s_pktCxt.eId_portNum_nextHdr.b1,  PKT_EIDX_SHIFT 
1577   mov   s_l1View3dCustom.pktType,   r1.b0  // record the custom index as part of matching crierta 
1578   set   s_l1View3dCustom.pktType.fL2PktTypeCustom
1579   lsl   r1.w2,  r1.b0,  5
1580   lsl   r1.w0,  r1.b0,  3
1581   add   r1.w0,  r1.w0,  r1.w2
1582   add   r1.w0,  r1.w0,  OFFSET_CUSTOM_C1 
1583   
1584   xout  XID_LUT1V3,  s_l1View3dCustom,  SIZE(s_l1View3dCustom)
1585   
1586   // find customer offset
1587   lbco  s_c1CustomHdr,  PAMEM_CONST_CUSTOM,  r1.w0,  SIZE(s_c1CustomHdr)
1589   mov  s_cdeCmdWd.byteCount,  s_c1CustomHdr.offset
1590   mov  s_next.Hdr,            s_c1CustomHdr.nextHdr
1591   xout XID_CDECTRL,           s_cdeCmdWd,         SIZE(s_cdeCmdWd)
1592   
1593   add   s_pktCxt.startOffset, s_pktCxt.startOffset, s_c1CustomHdr.nextHdrOffset  
1594   
1595   // read in the customer masks
1596   add   r1.w0,  r1.w0,  SIZE(s_c1CustomHdr) 
1597   lbco  s_c1Custom,  PAMEM_CONST_CUSTOM,  r1.w0,  SIZE(s_c1Custom)
1599   // Read in the 32 bytes of the custom info (s_l1View1aCustom & s_l1View2bCustom)
1600   xin  XID_CDEDATA,   s_l1View1aCustom,   SIZE(s_l1View1aCustom) + SIZE(s_l1View2bCustom)   
1601   
1602   //  Relying on big endian data
1603   and   s_l1View1aCustom.match0,  s_l1View1aCustom.match0,  s_c1Custom.bitmask0
1604   and   s_l1View1aCustom.match1,  s_l1View1aCustom.match1,  s_c1Custom.bitmask1
1605   and   s_l1View1aCustom.match2,  s_l1View1aCustom.match2,  s_c1Custom.bitmask2
1606   and   s_l1View1aCustom.match3,  s_l1View1aCustom.match3,  s_c1Custom.bitmask3
1607   and   s_l1View2bCustom.match4,  s_l1View2bCustom.match4,  s_c1Custom.bitmask4
1608   and   s_l1View2bCustom.match5,  s_l1View2bCustom.match5,  s_c1Custom.bitmask5
1609   and   s_l1View2bCustom.match6,  s_l1View2bCustom.match6,  s_c1Custom.bitmask6
1610   and   s_l1View2bCustom.match7,  s_l1View2bCustom.match7,  s_c1Custom.bitmask7
1612   xout  XID_LUT1V1,  s_l1View1aCustom,  SIZE(s_l1View1aCustom)
1613   xout  XID_LUT1V2,  s_l1View2bCustom,  SIZE(s_l1View2bCustom)
1615   mov  s_param.action, SUBS_ACTION_LOOKUP
1616   ret
1617   
1618 #else 
1620     // Error Handling
1621     mov  s_param.action,     SUBS_ACTION_EXIT
1622     ret 
1623  
1624 #endif
1626     .leave cdeScope
1627     .leave pktScope
1628     .leave lut1Scope
1629     .leave customC1Scope
1631 #ifdef PASS_PROC_LUT1_L4
1632 // *************************************************************************************
1633 // * FUNCTION PURPOSE: Parse an IPv4/IPv6 header when EOAM feature is enabled for the 2nd ACL
1634 // *************************************************************************************
1635 // * DESCRIPTION: The IPv4 source and destination address are placed into the LTU.
1636 // *              The pseudo header checksum is computed, and any options are parsed
1637 // *
1638 // *    On entry:
1639 // *            - the CDE is at the start of the IPv4 header
1640 // *            - r30.w0 has the function return address
1641 // *            - param.action has SUBS_ACTION_PARSE
1642 // *            - cdeCmdWd.operation has CDE_CMD_WINDOW_ADVNACE
1643 // *
1644 // *    On exit:
1645 // *            - the next action to take is in param.action
1646 // *            - the IP addresses, next protocol and TOS are in the lut
1647 // *            - the CDE points to the first byte after the IP header
1648 // *            - cdeCmdWd.operation has CDE_CMD_WINDOW_ADVANCE
1649 // *
1650 // *   Register Usage:  
1651 // * 
1652 // *   R0:    scratch
1653 // *   R1:    scratch
1654 // *   R2:    scratch
1655 // *   R3:    scratch          
1656 // *   R4:    |  CDE commands     -  cdeScope
1657 // *   R5:    |                   -
1658 // *   R6:        |                                      | IPv4 header 
1659 // *   R7:        |                                      |  
1660 // *   R8:        |                                      |  
1661 // *   R9:        |  LUT1 View   - lut1Scope             |
1662 // *   R10:       |                                     || dst address
1663 // *   R11:       |                                     |  LUT1 View1
1664 // *   R12:       |                                     |
1665 // *   R13:       |                                     |
1666 // *   R14:          |  (packet extended descriptor)      
1667 // *   R15:          |                                    
1668 // *   R16:          |                                    | raInfo     
1669 // *   R17:          |  LUT1 View  - lut1Scope            |     
1670 // *   R18:          |                                  |
1671 // *   R19:          |                                  |  LUT1 View3
1672 // *   R20:          |                                  |
1673 // *   R21:          |                                  |
1674 // *   R22:     |     
1675 // *   R23:     |  Packet context - pktScope   
1676 // *   R24:     |
1677 // *   R25:     |
1678 // *   R26:     |
1679 // *   R27:     |
1680 // *   R28:  
1681 // *   R29:  c1RunContext (s_runCxt)                                -  Global Scope
1682 // *   R30:  w2-param.action  w0-function return address            -
1683 // *   R31:  System Flags (s_flags)                                 -
1684 // *
1685 // *
1686 // *************************************************************************************
1688     .using pktScope
1689     .using cdeScope
1690     .using lut1Scope
1691     .using ipScope
1692     
1693 f_c1ParseIpForEoamAcl:
1695   // Read the minimum IP header
1696   add   r0, s_pktCxt.l3Offset, 32+32+8
1697   lbco   s_Ip,   cCdeInPkt, r0, SIZE(s_Ip)
1698   and   r0,               s_Ip.verLen,  0xF0
1699   qbeq  l_c1ParseIpvForEoamAcl_v4, r0,         0x40
1700   qbeq  l_c1ParseIpvForEoamAcl_v6, r0,         0x60
1701   jmp   fci_c1FirewallException      
1703 l_c1ParseIpvForEoamAcl_v4:
1704   // Save src port and destination port information before clearing
1705   mov  r0.w0, s_l1View3dIpv4.srcPort
1706   mov  r0.w2, s_l1View3dIpv4.dstPort
1707   zero  &s_l1View3dIpv4,    SIZE(s_l1View3dIpv4)
1708   // Restore the information
1709   mov  s_l1View3dIpv4.srcPort, r0.w0
1710   mov  s_l1View3dIpv4.dstPort, r0.w2
1711   
1712   mov  s_l1View3dIpv4.srcVC,  s_pktCxt.phyLink  
1713   // Fragmentation check
1714   set  s_l1View3dIpv4.pktFlags.fL3IpContainL4
1715   mov   r3.w0,    IPV4_FRAG_MASK
1716   and   r3.w0,    s_Ip.fragOff,     r3.w0
1717   qbeq  l_c1ParseIpv4ForEoamAcl_1,  r3.w0,            0
1718       set  s_l1View3dIpv4.pktFlags.fL3IpFrag
1719       clr  r3.w0.t_ipv4_frag_m
1720       qbeq l_c1ParseIpv4ForEoamAcl_1, r3.w0, 0
1721         clr  s_l1View3dIpv4.pktFlags.fL3IpContainL4
1722          
1723 l_c1ParseIpv4ForEoamAcl_1:   
1724   // dstIp already in the correct location
1725   mov   s_l1View1bIpv4.srcIp,   s_Ip.srcIp
1726   xout  XID_LUT1V1,             s_l1View1bIpv4,                  OFFSET(s_l1View1bIpv4.res32a)
1727   set  s_l1View3dIpv4.pktType.fL3PktTypeFirewall  
1728   set  s_l1View3dIpv4.pktFlags.fL3Ipv4
1729   mov  s_l1View3dIpv4.protocol,    s_Ip.protocol
1730   mov  s_l1View3dIpv4.pktFlags.b0, s_pktCxt.priority
1731   xout XID_LUT1V3,               s_l1View3dIpv4,  SIZE(s_l1View3dIpv4)     
1732   ret
1733      
1734 l_c1ParseIpvForEoamAcl_v6:
1735    // Save src port and destination port information before clearing
1736    mov  r0.w0, s_l1View3bIpv6.srcPort
1737    mov  r0.w2, s_l1View3bIpv6.dstPort
1738    zero  &s_l1View3bIpv6,    SIZE(s_l1View3bIpv6)   
1739    // Restore the information
1740    mov  s_l1View3bIpv6.srcPort, r0.w0
1741    mov  s_l1View3bIpv6.dstPort, r0.w2
1742    
1743    mov  s_l1View3bIpv6.srcVC,  s_pktCxt.phyLink 
1744    mov  r0.w0, s_pktCxt.l3Offset   
1745    lbco   s_Ipv6a,   cCdeInPkt, r0.w0, SIZE(s_Ipv6a)    
1746    add  r0.w0, r0.w0, SIZE(s_Ipv6a) 
1747    lbco  s_Ipv6b,  cCdeInPkt, r0.w0, SIZE(s_Ipv6b)
1748    
1749    // Source and dest IP go out unchanged
1750    xout XID_LUT1V1,   s_l1View1cIpv6,   SIZE(s_l1View1cIpv6)
1751    xout XID_LUT1V2,   s_l1View2dIpv6,   SIZE(s_l1View2dIpv6)   
1752    // The protocol, tclass, and flow labels are moved as 
1753    // required
1754    mov   s_l1View3bIpv6.flowLabel, s_Ipv6a.ver_tclass_flow
1755    and   s_l1View3bIpv6.flowLabel.w2,  s_l1View3bIpv6.flowLabel.w2,   0x0f   
1756    set   s_l1View3bIpv6.pktType.fL3PktTypeFirewall
1758    mov   s_l1View3bIpv6.protocol,      s_Ipv6a.next
1759    lsr   s_l1View3bIpv6.pktFlags.b0,   s_Ipv6a.ver_tclass_flow.w2,  4
1760    and   s_l1View3bIpv6.pktFlags.b0,   s_l1View3bIpv6.pktFlags.b0, 0x3F
1761    
1762    xout  XID_LUT1V3,               s_l1View3bIpv6,         SIZE(s_l1View3bIpv6)  
1764    // Get the next header and action
1765    set    s_l1View3bIpv6.pktFlags.fL3IpContainL4     
1766    ret
1767      
1768     .leave pktScope
1769     .leave cdeScope
1770     .leave lut1Scope
1771     .leave ipScope    
1772 #endif 
1774 // *************************************************************************************
1775 // * FUNCTION PURPOSE: Parse an IPv4 header
1776 // *************************************************************************************
1777 // * DESCRIPTION: The IPv4 source and destination address are placed into the LTU.
1778 // *              The pseudo header checksum is computed, and any options are parsed
1779 // *
1780 // *    On entry:
1781 // *            - the CDE is at the start of the IPv4 header
1782 // *            - r30.w0 has the function return address
1783 // *            - param.action has SUBS_ACTION_PARSE
1784 // *            - cdeCmdWd.operation has CDE_CMD_WINDOW_ADVNACE
1785 // *
1786 // *    On exit:
1787 // *            - the next action to take is in param.action
1788 // *            - the IP addresses, next protocol and TOS are in the lut
1789 // *            - the CDE points to the first byte after the IP header
1790 // *            - cdeCmdWd.operation has CDE_CMD_WINDOW_ADVANCE
1791 // *
1792 // *   Register Usage:  
1793 // * 
1794 // *   R0:    scratch
1795 // *   R1:    scratch
1796 // *   R2:    scratch
1797 // *   R3:    scratch          
1798 // *   R4:    |  CDE commands     -  cdeScope
1799 // *   R5:    |                   -
1800 // *   R6:        |                                      | IPv4 header 
1801 // *   R7:        |                                      |  
1802 // *   R8:        |                                      |  
1803 // *   R9:        |  LUT1 View   - lut1Scope             |
1804 // *   R10:       |                                     || dst address
1805 // *   R11:       |                                     |  LUT1 View1
1806 // *   R12:       |                                     |
1807 // *   R13:       |                                     |
1808 // *   R14:          |  (packet extended descriptor)      
1809 // *   R15:          |                                    
1810 // *   R16:          |                                    | raInfo     
1811 // *   R17:          |  LUT1 View  - lut1Scope            |     
1812 // *   R18:          |                                  |
1813 // *   R19:          |                                  |  LUT1 View3
1814 // *   R20:          |                                  |
1815 // *   R21:          |                                  |
1816 // *   R22:     |     
1817 // *   R23:     |  Packet context - pktScope   
1818 // *   R24:     |
1819 // *   R25:     |
1820 // *   R26:     |
1821 // *   R27:     |
1822 // *   R28:  
1823 // *   R29:  c1RunContext (s_runCxt)                                -  Global Scope
1824 // *   R30:  w2-param.action  w0-function return address            -
1825 // *   R31:  System Flags (s_flags)                                 -
1826 // *
1827 // *
1828 // *************************************************************************************
1830     .using pktScope
1831     .using cdeScope
1832     .using lut1Scope
1833     .using ipScope
1835 f_c1ParseIpv4:
1837 #ifdef PASS_PROC_L3
1838  
1839 #ifndef PASS_PROC_FIREWALL
1841   // Ipv4 reassembly operation
1842   qbbs fci_c1ParseIpv4_0,    s_pktCxt.flags.t_flag_cascaded_forwarding    
1843   qbbs f_c1IpReassm,         s_runCxt.flags.t_ipReassmEn   
1845 fci_c1ParseIpv4_0:
1847 #ifdef PASS_VERIFY_POST_RA_DROP
1848     wbs  s_flags.info.tStatus_CDEOutPacket
1849     lbco  r1.b0,  cCdeOutPkt, OFFSET(s_pktDescr.psFlags_errorFlags),  SIZE(s_pktDescr.psFlags_errorFlags)
1850     qbbc  l_c1ParseIpv4_ra_drop_end, r1.b0.t_psFlags_pktDropFromRA
1851         // drop the packet
1852         mov s_param.action, SUBS_ACTION_DISCARD
1853         ret
1854 l_c1ParseIpv4_ra_drop_end:    
1855 #endif    
1857   // New IPv4 packet or Reassembled packet: check maximum count
1858   lbco  r0.w2,  PAMEM_CONST_CUSTOM, OFFSET_MAX_HDR + OFFSET(struct_paComMaxCount.ipMaxCount), 2
1860   // IP depth count
1861   and  r0.w0,         s_pktCxt.protCount,  PROT_COUNT_IP_MASK
1862   qblt l_c1ParseIpv4_00,   r0.w2,  r0.w0
1863       // Setup for IP overflow exception route
1864       and  s_pktCxt.eId_portNum_nextHdr.b1,  s_pktCxt.eId_portNum_nextHdr.b1,   NOT_PKT_EIDX_MASK
1865       or   s_pktCxt.eId_portNum_nextHdr.b1,  s_pktCxt.eId_portNum_nextHdr.b1,   EROUTE_IP_MAX_DEPTH << PKT_EIDX_SHIFT  
1867       mov s_stats.value,  PA_STATS_UPDATE_REQ | PA_STATS_IP_DEPTH_OVERFLOW
1868       mov s_param.action,        SUBS_ACTION_EXIT
1869       ret
1871 l_c1ParseIpv4_00:  
1873   add  s_pktCxt.protCount,  s_pktCxt.protCount, PROT_COUNT_IP_STEP
1874   set  s_pktCxt.hdrBitmask.SUBS_PA_BIT_HEADER_IPv4
1875   mov s_stats.value,  PA_STATS_UPDATE_REQ | PA_STATS_IPV4_PKTS
1876   
1877 #ifdef PASS_PROC_INNER_IP
1878   mov s_stats.value,  PA_STATS_UPDATE_REQ | PA_STATS_INNER_IPV4_PKTS
1879   // store the inner IP offset
1880   mov s_pktCxt5.l3l5Offset, s_pktCxt.startOffset
1881 #else
1882   // store the outer IP offset
1883   mov  s_pktCxt.l3Offset, s_pktCxt.startOffset
1884 #endif  
1886 #ifdef TOBE_DELETED
1887   
1888   //
1889   // t_l3toInnerIp = FALSE: Set l3Offset for outer IP 
1890   // t_l3toInnerIp = TRUE:  Set l3Offset for inner IP
1891   //
1892   qbbs l_c1ParseIpv4_01_setInnerIp, s_runCxt.flag2.t_l3toInnerIp
1893     qbne l_c1ParseIpv4_01,    s_pktCxt.l3Offset, 0
1894 l_c1ParseIpv4_01_setInnerIp:      
1895         mov  s_pktCxt.l3Offset, s_pktCxt.startOffset
1896 #endif        
1897         
1898 #else
1900 #ifdef PASS_DETECT_IP_PROC
1901  qbbc l_c1ParseIpv4_in3, s_runCxt.flag3.t_eoamEn
1902   set  s_pktCxt.flags.t_flag_ipProc
1903 l_c1ParseIpv4_in3:
1904 #endif
1906 // Firewall (RA) specific processing
1907 // TBD: priority settings
1908   lbco  s_raInfo,  cCdeOutPkt,  SIZE(s_pktDescr) + 24,  SIZE(s_raInfo)
1909   //zero &s_raInfo,   SIZE(s_raInfo)
1910   mov  s_raInfo.l3Offset, s_pktCxt.startOffset 
1911   //qbbc l_c1ParseIpv4_set_ra_threadId_1, s_runCxt.flag2.t_raToQueue
1912     // RA output is host queue
1913     //mov  s_raInfo.flags, THREADID_CDMA0
1914     //jmp  l_c1ParseIpv4_set_ra_threadId_end
1915 //l_c1ParseIpv4_set_ra_threadId_1:  
1916   //  mov  s_raInfo.flags, PASS_RA_DEST_THREAD_ID 
1917     // pass through  
1918 //l_c1ParseIpv4_set_ra_threadId_end:
1920 #endif    
1922 l_c1ParseIpv4_01:
1923   zero  &s_l1View3dIpv4,    SIZE(s_l1View3dIpv4)
1924    
1925 #ifndef PASS_PROC_FIREWALL
1926   // Check to see whether virtual link is used 
1927   qbbs l_c1ParseIpv4_01_vLink, s_pktCxt.flags.t_flag_use_vlink
1928     // The previous lookup PDSP ID and LUT1 index is stored in the srcVC field
1929     mov  s_l1View3dIpv4.srcVC,  s_pktCxt.phyLink
1930     jmp  l_c1ParseIpv4_01_link_end
1931 l_c1ParseIpv4_01_vLink:    
1932     mov  s_l1View3dIpv4.srcVC,  s_pktCxt.vlanPri_vLink
1933     and  s_l1View3dIpv4.srcVC.b1, s_l1View3dIpv4.srcVC.b1, NOT_PKT_VLAN_PRI_MASK
1934     // Clear virtual link enable for further look ups
1935     clr s_pktCxt.flags.t_flag_use_vlink
1937 l_c1ParseIpv4_01_link_end:
1939 #else
1940     mov  s_l1View3dIpv4.srcVC,  s_pktCxt.phyLink
1941 #endif
1944   // Read the minimum IP header
1945   xin  XID_CDEDATA,  s_Ip,   SIZE(s_Ip) 
1946   
1947   // Basic Error Check
1948   // - version = 4
1949   // - ipHdrLen >= 20 
1950   // - (ipOffset + ipLength) <= pktLen
1951   // version check
1952   and   r0,               s_Ip.verLen,  0xF0
1953   qbne  fci_c1ParseIpv4_10, r0,         0x40
1954   
1955   // Is ipHdrLength vaild?
1956   and  r0.b0,  s_Ip.verLen,   0x0F
1957   qbgt fci_c1ParseIpv4_10,    r0.b0,       IPV4_MIN_HDR_SIZE >> 2  // IP Hdr length check
1958   
1959   // Is ipLength valid?
1960   // TBD: The outer IP length is incorrect at our IP fragmentation test
1961 #ifdef TO_BE_ADDED  
1962   add  r0.w0,  s_Ip.totalLen, s_pktCxt.startOffset
1963   qblt fci_c1ParseIpv4_10,    r0.w0,       s_pktCxt.endOffset      // IP length check
1964 #endif  
1965   
1966 #ifndef PASS_PROC_FIREWALL  
1967   // Strong error check required by some customers: (Disabled by default)
1968   // ipLength <= 20
1969   // src addr == 0xffffffff (broadcast)
1970   // dest addr == 0
1971   // ttl == 0
1972   
1973   qbbc  l_c1ParseIpv4_000,   s_runCxt.flag2.t_ipHdrCheck
1974     qbge fci_c1ParseIpv4_10, s_Ip.totalLen,  IPV4_MIN_HDR_SIZE     // Total length check
1975     qbeq fci_c1ParseIpv4_10,    s_Ip.dstIp,     0                  // Dest IP == 0
1976     qbeq fci_c1ParseIpv4_10,    s_Ip.ttl,       0                  // TTL == 0
1977     // IP Source IP check == 0xFFFFFFFF 
1978     // Method 1: Assignment plus two 16-bit comparison (3 instruction, 3 cycles)
1979     // Method 2: Search for zero and then check result (2 instruction, 2 cycles)
1980     lmbd r0,    s_Ip.srcIp,     0    
1981     qbeq fci_c1ParseIpv4_10,    r0,        32     
1982     
1983 #endif                    
1984         
1985     // IPv4 Hdr check complete: pass through
1986 l_c1ParseIpv4_000:
1987   // Fragmentation check
1988   set  s_l1View3dIpv4.pktFlags.fL3IpContainL4
1989   mov   r3.w0,    IPV4_FRAG_MASK
1990   and   r3.w0,    s_Ip.fragOff,     r3.w0
1991   qbeq  l_c1ParseIpv4_0,  r3.w0,            0
1992       set  s_l1View3dIpv4.pktFlags.fL3IpFrag
1993       clr  r3.w0.t_ipv4_frag_m
1994       qbeq l_c1ParseIpv4_000_1, r3.w0, 0
1995         clr  s_l1View3dIpv4.pktFlags.fL3IpContainL4
1996         clr  s_runCxt.flags.t_l4Avil
1997          
1998 l_c1ParseIpv4_000_1: 
1999 #ifndef PASS_PROC_RA
2000       set  s_pktCxt.flags.t_flag_frag
2001 #else // PASS_PROC_RA
2002       mov s_stats.value,  PA_STATS_UPDATE_REQ | PA_STATS_IP_FRAG 
2003       set s_raInfo.flags.t_ra_flag_reasm   
2004 #ifdef PASS_INNER_RA
2005       //set s_raInfo.flags.t_ra_flag_2nd_inst   
2006 #endif         
2007 #endif  
2008     
2009       // pass through
2011 l_c1ParseIpv4_0:
2012   // dstIp already in the correct location
2013   mov   s_l1View1bIpv4.srcIp,   s_Ip.srcIp
2014   xout  XID_LUT1V1,             s_l1View1bIpv4,                  OFFSET(s_l1View1bIpv4.res32a)
2016 #ifdef PASS_PROC_FIREWALL
2017   // TBD???: Read back in the IP header info (It should not be required anymore)
2018   // xin  XID_CDEDATA,    s_Ip,   SIZE(s_Ip)
2019   
2020   // Setup the CDE for the IP header checksum, set the global pointer
2021   // past the IP header
2022   zero &s_cdeCmdChk,            SIZE(s_cdeCmdChk)
2023   and   r2.w0,                  s_Ip.verLen,                    0x0f
2024   lsl   s_cdeCmdChk.byteLen,    r2.w0,                          2  // 32 bit size to 8 bit size conversion
2025   mov   s_cdeCmdChk.operation,  CDE_CMD_CHECKSUM1_VALIDATE
2026   xout  XID_CDECTRL,            s_cdeCmdChk,                    SIZE(s_cdeCmdChk)
2027   
2028 #else
2029   // Recalculate IP checksum after IP 
2030   // Skip this operation if checksum error flag is set
2031   // wait for the sideband data to be ready 
2032   //wbc    s_flags.info.tStatus_CDEBusy
2033   //lbco   r0.b0,   cCdeInPkt,           OFFSET(struct_pktDscFine.psFlags_errorFlags),     1   
2034   //qbbs   l_c1ParseIpv4_cksum_skip, r0.b0.t_errorFlags_cksumIp          
2035     zero  &s_cdeCmdChk,         SIZE(s_cdeCmdChk)
2036     mov   s_cdeCmdChk.operation,CDE_CMD_CHECKSUM1_COMPUTE
2037     and   r2.w0,                s_Ip.verLen,              0x0f
2038     lsl   s_cdeCmdChk.byteLen,  r2.w0,                    2  // 32 bit size to 8 bit size conversion
2039     mov   s_cdeCmdChk.offset, OFFSET(s_Ip.Checksum)          // Starting sum is 0, offset is 10
2040     xout  XID_CDECTRL, s_cdeCmdChk,  SIZE(s_cdeCmdChk)
2041   
2042     mov   s_Ip.Checksum, 0
2043     xout  XID_CDEDATA, s_Ip.Checksum, 2
2044   
2045 l_c1ParseIpv4_cksum_skip:  
2047 #endif
2049 #ifndef PASS_PROC_FIREWALL  
2051   // Update the start and end offsets while the IP header length is in bytes
2052   add   s_pktCxt.endOffset,     s_pktCxt.startOffset,           s_Ip.totalLen
2053   add   s_pktCxt.startOffset,   s_pktCxt.startOffset,           s_cdeCmdChk.byteLen
2055   // Compute the pseudo header checkusm except protocol and payload length
2056   add    r1,               s_Ip.srcIp,       s_Ip.dstIp
2057   adc    r1,               r1.w0,            r1.w2
2058   add    s_pktCxt.pseudo,  r1.w0,            r1.w2
2059   
2060   // Broadcast and Multicast IP detection
2061 l_c1ParseIpv4_BM:  
2062    // IP Destination IP broadcast == 0xFFFFFFFF 
2063    // Method 1: Assignment plus two 16-bit comparison (3 instruction, 3 cycles)
2064    // Method 2: Search for zero and then check result (2 instruction, 2 cycles)
2065   //mov    r1.w0,               0xffff
2066   //qbne   l_c1ParseIpv4_BM_1,  s_Ip.dstIp.w2,   r1.w0
2067   //qbne   l_c1ParseIpv4_BM_1,  s_Ip.dstIp.w0,   r1.w0
2068     lmbd r1.b0,    s_Ip.DstIp,     0    
2069     qbne l_c1ParseIpv4_BM_1,       r1.b0,        32    // 0 found?                 
2070         set  s_pktCxt.flags.t_flag_broadcast
2071         jmp  l_c1ParseIpv4_BM_end
2072     
2073 l_c1ParseIpv4_BM_1:
2074   qbgt   l_c1ParseIpv4_BM_end, s_Ip.dstIp.b3,   IPV4_MULTICAST_START     
2075   qblt   l_c1ParseIpv4_BM_end, s_Ip.dstIp.b3,   IPV4_MULTICAST_END
2076     set  s_pktCxt.flags.t_flag_multicast  
2077   
2078 l_c1ParseIpv4_BM_end:
2080 #else
2081   // Firewall operation:adjust startOffset only
2082   and   r2.w0,                  s_Ip.verLen,                    0x0f
2083   lsl   s_cdeCmdWd.byteCount,   r2.w0,                          2  // 32 bit size to 8 bit size conversion
2084   add   s_pktCxt.startOffset,   s_pktCxt.startOffset,           s_cdeCmdWd.byteCount
2085   
2086   qbbs  l_c1ParseIpv4_8_0, s_pktCxt.flags.t_flag_cascaded_forwarding
2087   qbbc  l_c1ParseIpv4_8_0, s_runCxt.flag2.t_raEn
2088     //wbs   s_flags.info.tStatus_CDEOutPacket
2089     sbco  s_raInfo,  cCdeOutPkt,  SIZE(s_pktDescr) + 24,  SIZE(s_raInfo)
2090   
2091     //pass through
2092 l_c1ParseIpv4_8_0:  
2093 #endif
2095   // Get the next action and header type from the IP protocol field
2096   lbco   r0.b0,             PAMEM_CONST_IP_PROTO,  s_Ip.protocol,   1
2097   and    s_next.Hdr,        r0.b0,                 0x3f
2098   lsr    s_param.action,    r0.b0,                 6
2099   
2100 #ifdef PASS_PROC_LUT1_L4
2101     // TBD???:To be delted
2102     //qbeq l_c1ParseIpv4_9_0, s_next.Hdr,   PA_HDR_UNKNOWN
2103     //    mov s_param.action, SUBS_ACTION_PARSE 
2104     
2105 l_c1ParseIpv4_9_0:
2106 #endif 
2108 #ifdef PASS_PROC_FIREWALL
2109     qbbs l_c1ParseIpv4_9_1, s_runCxt.flags.t_l4Avil
2110         mov s_param.action, SUBS_ACTION_LOOKUP 
2111     
2112 l_c1ParseIpv4_9_1:
2113 #endif 
2114   
2115   //  Advance past the IP header.
2116   mov   s_cdeCmdWd.operation,   CDE_CMD_WINDOW_ADVANCE
2117   xout   XID_CDECTRL,    s_cdeCmdWd,   SIZE(s_cdeCmdWd)
2118   
2119    // The protocol type and TOS must be added
2120    // to the LUT1 search
2122 #ifdef PASS_PROC_FIREWALL
2123    set  s_l1View3dIpv4.pktType.fL3PktTypeFirewall
2124 #else
2125    set  s_l1View3dIpv4.pktType.fL3PktTypeIp
2126 #endif   
2127    set  s_l1View3dIpv4.pktFlags.fL3Ipv4
2128    mov  s_l1View3dIpv4.protocol,    s_Ip.protocol
2129    // Store DSCP in case we need DSCP priority routing
2130    lsr  s_pktCxt.priority, s_Ip.tos, 2
2131    mov  s_l1View3dIpv4.dscp, s_pktCxt.priority
2132    xout XID_LUT1V3,               s_l1View3dIpv4,  SIZE(s_l1View3dIpv4)
2133    ret
2135 l_c1ParseIpv4_9:
2136    // IPv4 Parse error
2137    and  s_pktCxt.eId_portNum_nextHdr.b1,  s_pktCxt.eId_portNum_nextHdr.b1,   NOT_PKT_EIDX_MASK
2138    or   s_pktCxt.eId_portNum_nextHdr.b1,  s_pktCxt.eId_portNum_nextHdr.b1,   EROUTE_PARSE_FAIL << PKT_EIDX_SHIFT  
2139    jmp  l_c1ParseIpv4_11
2140    
2141 fci_c1ParseIpv4_10:
2142    // IPv4/v6 Hdr Error
2143 #ifdef PASS_PROC_FIREWALL
2144   //add  s_pktCxt.protCount,  s_pktCxt.protCount, PROT_COUNT_IP_STEP
2145   //set  s_pktCxt.hdrBitmask.SUBS_PA_BIT_HEADER_IPv4
2146   //mov s_stats.value,  PA_STATS_UPDATE_REQ | PA_STATS_IPV4_PKTS
2147   
2148   //
2149   // Set l3Offset only for outer IP
2150   //
2151   //qbne l_c1ParseIpv4_10_1,    s_pktCxt.l3Offset, 0    
2152     //mov  s_pktCxt.l3Offset, s_pktCxt.startOffset
2153   //TBD: forward to next stage since it should be dropped there
2154   jmp   fci_c1FirewallException  
2155     
2156 l_c1ParseIpv4_10_1:    
2157 #endif    
2158    
2159    and  s_pktCxt.eId_portNum_nextHdr.b1,  s_pktCxt.eId_portNum_nextHdr.b1,   NOT_PKT_EIDX_MASK
2160    or   s_pktCxt.eId_portNum_nextHdr.b1,  s_pktCxt.eId_portNum_nextHdr.b1,   EROUTE_IP_FAIL << PKT_EIDX_SHIFT  
2161    
2162    // Common Error
2163 l_c1ParseIpv4_11:
2164    mov  s_param.action,     SUBS_ACTION_EXIT
2165    ret
2166        
2167     .leave pktScope
2168     .leave cdeScope
2169     .leave lut1Scope
2170     .leave ipScope
2171     
2172     
2173 // *************************************************************************************
2174 // * FUNCTION PURPOSE: IPv4 Reassembly Assistance
2175 // *************************************************************************************
2176 // * DESCRIPTION: Perform the IP Reassembly Assistance.
2177 // * First Pass: (traffics from network)
2178 // *    Search to find the matching traffic flow (cycle :12 * number of active traffic flows)
2179 // *    If traffic flow is identified, increment its packet counter and forward the packet with its traffic flow id to the host queue
2180 // *    If traffic flow is not identified
2181 // *        -   Non-fragmented: normal lookup operation
2182 // *        -   Fragments: allocate a new traffic flow, set its packet counter to 1 and forward the fragment with its traffic flow id 
2183 // *            to the host queue. If traffic flow is not available, just forward the fragment with "NA" traffic flow id to the host queue
2184 // *
2185 // * Second Pass: (traffics from the host)
2186 // *    Decrement the packet counter by the specific count if the traffic flow id is specified. 
2187 // *    Free the traffic flow if its counter reaches 0
2188 // *    Normal lookup operation
2189 // * 
2190 // *
2191 // *    On entry:
2192 // *            - the CDE is at the start of the IPv4 header
2193 // *            - r30.w0 has the function return address
2194 // *            - param.action has SUBS_ACTION_PARSE
2195 // *            - cdeCmdWd.operation has CDE_CMD_WINDOW_ADVNACE
2196 // *
2197 // *    On exit:
2198 // *            - the next action to take is in param.action
2199 // *            - the IP addresses, next protocol and TOS are in the lut
2200 // *            - the CDE points to the first byte after the IP header
2201 // *            - cdeCmdWd.operation has CDE_CMD_WINDOW_ADVANCE
2202 // *
2203 // *   Note: It is an extension of the f_c1ParseIp. Therefore, it is OK to jump back to f_c1ParseIp 
2204 // *
2205 // *   Register Usage:  
2206 // * 
2207 // *   R0:    scratch
2208 // *   R1:    scratch r1.w0: fragment offset field: (non-zero ==> fragmented)
2209 // *   R2:    scratch
2210 // *   R3:    scratch          
2211 // *   R4:    |  CDE commands     -  cdeScope
2212 // *   R5:    |                   -
2213 // *   R6:        |  IPv4 header                                    
2214 // *   R7:        |                                      
2215 // *   R8:        |                                      
2216 // *   R9:        |  
2217 // *   R10:       |
2218 // *   R11:         | Traffic Flow
2219 // *   R12:         |
2220 // *   R13:         |
2221 // *   R14:           | IP Reassembly Control Block                                         
2222 // *   R15:           |                                          
2223 // *   R16:           |                                          
2224 // *   R17:           |  
2225 // *   R18:           
2226 // *   R19:           
2227 // *   R20:           
2228 // *   R21:           
2229 // *   R22:     |     
2230 // *   R23:     |  Packet context - pktScope   
2231 // *   R24:     |
2232 // *   R25:     |
2233 // *   R26:     |
2234 // *   R27:     |
2235 // *   R28:  
2236 // *   R29:  c1RunContext (s_runCxt)                                -  Global Scope
2237 // *   R30:  w2-param.action  w0-function return address            -
2238 // *   R31:  System Flags (s_flags)                                 -
2239 // *
2240 // *
2241 // *************************************************************************************
2243     .using pktScope
2244     .using cdeScope
2245     .using lut1Scope
2246     .using ipScope
2247     
2248 #ifndef PASS_PROC_FIREWALL    
2250 f_c1IpReassm:
2252   qbbs l_c1IpReassm_pass2,  s_pktCxt.flags.t_flag_2nd_pass  
2254 // First Pass operations
2255 l_c1IpReassm_pass1:
2257   // Read the minimum IP header
2258   xin  XID_CDEDATA,  s_Ip,   SIZE(s_Ip) 
2260   // Verify version
2261   and   r0,   s_Ip.verLen,  0xF0
2262   qbne  fci_c1ParseIpv4_10,  r0,         0x40
2263   
2264   mov   r1.w0,    IPV4_FRAG_MASK
2265   and   r1.w0,    s_Ip.FragOff,          r1.w0
2266   // 
2267   // IP Frag stats has already been incremented at the RA stage
2268   //
2269   //qbeq  l_c1IpReassm_pass1_0,  r1.w0,    0
2270   //    mov s_stats.value,  PA_STATS_UPDATE_REQ | PA_STATS_IP_FRAG
2271   
2272 l_c1IpReassm_pass1_0:
2273   
2274   // 
2275   // Search through the active Traffic flows
2276   //
2277   lbco  s_ipReassmCxt, PAMEM_CONST_IP_REASSEM_CONTEXT, 0, OFFSET(s_ipReassmCxt.tfMapTemp)
2278   mov   s_ipReassmCxt.tfMapTemp, s_ipReassmCxt.tfMap  
2279   
2280 l_c1IpReassm_pass1_1:
2281   
2282   qbeq  l_c1IpReassm_pass1_2, s_ipReassmCxt.tfMapTemp, 0
2283   lmbd  s_pktCxt3.tfIndex, s_ipReassmCxt.tfMapTemp, 1 
2284   clr   s_ipReassmCxt.tfMapTemp, s_pktCxt3.tfIndex  
2285   lsl   s_ipReassmCxt.offset,   s_pktCxt3.tfIndex, 4
2286   lbco  s_ipTf, PAMEM_CONST_TF_TABLE, s_ipReassmCxt.offset,  SIZE(s_ipTf)
2287   qbne  l_c1IpReassm_pass1_1, s_ipTf.srcIp, s_Ip.srcIp
2288   qbne  l_c1IpReassm_pass1_1, s_ipTf.destIp, s_Ip.dstIp
2289   qbne  l_c1IpReassm_pass1_1, s_ipTf.proto, s_Ip.protocol
2290   
2291   //match found: update and store the counter
2292   add   s_ipTf.cnt, s_ipTf.cnt, 1
2293   sbco  s_ipTf, PAMEM_CONST_TF_TABLE, s_ipReassmCxt.offset,  OFFSET(s_ipTf.proto)
2294   
2295   jmp   l_c1IpReassm_pass1_4
2296   
2297 l_c1IpReassm_pass1_2:
2298   //match not found
2299   
2300   // normal operation for non-fragments packet
2301   qbeq  fci_c1ParseIpv4_0,  r1.w0,  0
2302   
2303   // Find available traffic flow
2304   qble  l_c1IpReassm_pass1_3, s_ipReassmCxt.numActiveTF, s_ipReassmCxt.numTF  
2305   lmbd  s_pktCxt3.tfIndex, s_ipReassmCxt.tfMap, 0
2306   qbeq  l_c1IpReassm_pass1_3, s_pktCxt3.tfIndex, 32
2307   
2308   // Traffic Flow found
2309   set   s_ipReassmCxt.tfMap, s_pktCxt3.tfIndex
2310   add   s_ipReassmCxt.numActiveTF, s_ipReassmCxt.numActiveTF,  1
2311   sbco  s_ipReassmCxt, PAMEM_CONST_IP_REASSEM_CONTEXT, 0, OFFSET(s_ipReassmCxt.tfMapTemp)
2312   
2313   // store the traffic flow
2314   mov   s_ipTf.srcIp, s_Ip.srcIp
2315   mov   s_ipTf.destIp, s_Ip.dstIp
2316   mov   s_ipTf.proto, s_Ip.protocol
2317   mov   s_ipTf.cnt, 1
2318   lsl   s_ipReassmCxt.offset,   s_pktCxt3.tfIndex, 4
2319   sbco  s_ipTf, PAMEM_CONST_TF_TABLE, s_ipReassmCxt.offset,  SIZE(s_ipTf)
2320   
2321   jmp    l_c1IpReassm_pass1_4
2322   
2323 l_c1IpReassm_pass1_3:  
2324   //No Traffic flow available
2325   mov  s_pktCxt3.tfIndex, PA_INV_TF_INDEX 
2326   
2327   // pass through 
2328    
2329 l_c1IpReassm_pass1_4:
2330   mov   s_pktCxt3.fragCnt,  1
2331   set   s_pktCxt.flags.t_flag_2nd_pass  
2332   wbs   s_flags.info.tStatus_CDEOutPacket
2333 \r
2334 l_c1IpReassm_pass1_4_queue_bounce:\r
2335         // Check for Queue Bounce operation\r
2336 l_c1IpReassm_pass1_4_queue_bounce_ddr:\r
2337         qbbc l_c1IpReassm_pass1_4_queue_bounce_msmc, s_ipReassmCxt.queue.t_pa_forward_queue_bounce_ddr\r
2338             clr s_ipReassmCxt.queue.t_pa_forward_queue_bounce_ddr\r
2339             sbco s_ipReassmCxt.queue,  cCdeOutPkt, OFFSET(s_pktDescr.swinfo1) + 2,  2\r
2340             lbco s_ipReassmCxt.queue,  PAMEM_CONST_CUSTOM, OFFSET_QUEUE_BOUNCE_CFG, 2\r
2341             jmp  l_c1IpReassm_pass1_4_queue_bounce_end\r
2342 \r
2343 l_c1IpReassm_pass1_4_queue_bounce_msmc:\r
2344         qbbc l_c1IpReassm_pass1_4_queue_bounce_end, s_ipReassmCxt.queue.t_pa_forward_queue_bounce_msmc\r
2345             clr s_ipReassmCxt.queue.t_pa_forward_queue_bounce_msmc\r
2346             sbco s_ipReassmCxt.queue,  cCdeOutPkt, OFFSET(s_pktDescr.swinfo1) + 2,  2\r
2347             lbco s_ipReassmCxt.queue,  PAMEM_CONST_CUSTOM, OFFSET_QUEUE_BOUNCE_CFG+2, 2\r
2348             // pass through\r
2349 l_c1IpReassm_pass1_4_queue_bounce_end:\r
2350 \r
2351   sbco  s_ipReassmCxt.queue,  cCdeOutPkt,  OFFSET(s_pktDescr.destQ),    SIZE(s_pktDescr.destQ)
2352   sbco  s_ipReassmCxt.flowId, cCdeOutPkt,  OFFSET(s_pktDescr.flowIdx),  SIZE(s_pktDescr.flowIdx)
2353   mov   s_param.action,     SUBS_ACTION_FWPKT
2354   mov   s_next.hdr,         PA_HDR_IPv4
2355   ret
2356   
2357   // Second Pass operations
2358 l_c1IpReassm_pass2:
2359   clr   s_pktCxt.flags.t_flag_2nd_pass
2360   // TF index range check
2361   qbeq  l_c1IpReassm_pass2_3, s_pktCxt3.tfIndex, PA_INV_TF_INDEX
2362   qble  l_c1ParseIpv4_9,   s_pktCxt3.tfIndex,   32
2363   
2364   lsl   r1.w0,  s_pktCxt3.tfIndex, 4  //tfIndex * 16
2365   lbco  s_ipTf, PAMEM_CONST_TF_TABLE, r1.w0,  OFFSET(s_ipTf.srcIp)
2366   
2367   qbge  l_c1IpReassm_pass2_1,   s_ipTf.cnt,     s_pktCxt3.fragCnt
2368   
2369     sub  s_ipTf.cnt,    s_ipTf.cnt, s_pktCxt3.fragCnt
2370     sbco s_ipTf, PAMEM_CONST_TF_TABLE, r1.w0,  OFFSET(s_ipTf.srcIp)
2371     jmp  l_c1IpReassm_pass2_3
2372     
2373 l_c1IpReassm_pass2_1:
2374     // Counter has reached zero, clear the corresponding bit
2375     lbco s_ipReassmCxt, PAMEM_CONST_IP_REASSEM_CONTEXT, 0, OFFSET(s_ipReassmCxt.tfMapTemp)
2376     clr  s_ipReassmCxt.tfMap,   s_pktCxt3.tfIndex
2377     qbeq l_c1IpReassm_pass2_2,  s_ipReassmCxt.numActiveTF, 0
2378         sub  s_ipReassmCxt.numActiveTF, s_ipReassmCxt.numActiveTF, 1
2379                        
2380 l_c1IpReassm_pass2_2:
2381     sbco s_ipReassmCxt, PAMEM_CONST_IP_REASSEM_CONTEXT, 0, OFFSET(s_ipReassmCxt.tfMapTemp)
2382     // pass through  
2383     
2384 l_c1IpReassm_pass2_3:
2385     // verify whether it is an null packet  
2386     qbbc fci_c1ParseIpv4_0,  s_pktCxt.flags.t_flag_null_pkt  
2387         // drop the null packet
2388         mov   s_param.action,     SUBS_ACTION_DISCARD
2389         ret
2390 #endif        
2391         
2392 #else
2393         // Ingress1, PDSP1 only
2394         // Forward the packets to Ingess3 for continue L3 processing
2395         mov   s_param.action,     SUBS_ACTION_FWPKT4
2396         ret
2398 #endif        
2399        
2400     .leave pktScope
2401     .leave cdeScope
2402     .leave lut1Scope
2403     .leave ipScope
2404     
2406 // ************************************************************************************
2407 // * FUNCTION PURPOSE: Parse an IPv6 header
2408 // ************************************************************************************
2409 // * DESCRIPTION: Ipv6 entries are added to the LUT
2410 // *
2411 // *        On entry:
2412 // *            -  CDE points to the start of the IPv6 packet
2413 // *            -  param.action is SUBS_ACTION_PARSE
2414 // *            -  next.Hdr is PA_HDR_IPv6
2415 // *            -  cdeCmdWd.operation is CDE_CMD_WINDOW_ADVANCE
2416 // *
2417 // *        On exit
2418 // *            -  CDE points to first byte after the IPv6 header
2419 // *            -  param.action is SUBS_ACTION_LOOKUP
2420 // *            -  next.Hdr is as found in the IP protocol table
2421 // *            -  cdeCmdWd.operationis CDE_CMD_WINDOW_ADVANCE
2422 // *
2423 // *   Register Usage:  
2424 // * 
2425 // *   R0:    scratch   | Local Reassembly control instance
2426 // *   R1:    scratch   |
2427 // *   R2:    
2428 // *   R3:              b0 - next header type  - pktScope
2429 // *   R4:    |  CDE commands     -  cdeScope
2430 // *   R5:    |                   -
2431 // *   R6:        |                                  |  IPv6 header & option headers
2432 // *   R7:        |                                  |  
2433 // *   R8:        |                                    
2434 // *   R9:        |  LUT1 View   - lut1Scope
2435 // *   R10:       |                                     | 
2436 // *   R11:       |                                     |  LUT1 View3
2437 // *   R12:       |                                     |
2438 // *   R13:       |                                     |
2439 // *   R14:          |  (packet extended descriptor)     |                        | IP reassembly control block                     
2440 // *   R15:          |                                   |                        |
2441 // *   R16:          |                                   | LUT1 View1   | raInfo  |
2442 // *   R17:          |  LUT1 View  - lut1Scope           |              |         |
2443 // *   R18:          |  (IP address)                       |                      
2444 // *   R19:          |                                     | LUT1 View2           
2445 // *   R20:          |                                     |                      
2446 // *   R21:          |                                     |                      
2447 // *   R22:     |     
2448 // *   R23:     |  Packet context - pktScope   
2449 // *   R24:     |
2450 // *   R25:     |
2451 // *   R26:     |
2452 // *   R27:     |
2453 // *   R28:  
2454 // *   R29:  c1RunContext (s_runCxt)                                -  Global Scope
2455 // *   R30:  w2-param.action  w0-function return address            -
2456 // *   R31:  System Flags (s_flags)                                 -
2457 // *
2458 // *************************************************************************************
2460     .using lut1Scope
2461     .using cdeScope
2462     .using pktScope
2463     .using ipScope
2464     
2465 // Local structure defintion and assignment    
2466 .struct struct_ipv6Reassm_ctrl
2467   .u8    nextHdr
2468   .u8    hdrLen
2469   .u16   offset
2470   .u8    flag
2471   .u8    rsvd1
2472   .u16   maxOffset
2473   .u16   tHdrLen
2474   .u16   rsvd2
2475 .ends
2477 #define  t_reassm_ctrl_flag_frag         t0
2479 .assign struct_ipv6Reassm_ctrl,  r0,     r2,    s_ipv6Reassm_ctrl
2481 #define PA_MAX_HDR_LEN                   256
2483 f_c1ParseIpv6:
2485 #ifdef PASS_PROC_L3
2486 // IPv6 Reassembly-assisted code does not run at PDSP of Firewall and Reassembly
2487 #ifndef PASS_PROC_FIREWALL
2488   
2489     // Reassembly-assisted operation
2490     qbbs l_c1Ipv6ExtReasm_pass2, s_pktCxt.flags.t_flag_null_pkt
2491     
2492         // Read in the IPv6 header.
2493         xin  XID_CDEDATA,  s_Ipv6a,   SIZE(s_Ipv6a)
2495         // Verify version
2496         and   r0.b0,                s_Ip.VerLen,   0xF0
2497         qbne  fci_c1ParseIpv4_10,   r0.b0,         0x60
2499         //  Advance past the fisr 8 byte (Ipv6a).
2500         mov  s_cdeCmdWd.operation,   CDE_CMD_WINDOW_ADVANCE
2501         mov  s_cdeCmdWd.byteCount,   SIZE(s_Ipv6a)                      // Bytes always present in the header
2502         xout XID_CDECTRL,    s_cdeCmdWd,   SIZE(s_cdeCmdWd)
2504         xin  XID_CDEDATA,  s_Ipv6b,   SIZE(s_Ipv6b)
2506         // Source and dest IP go out unchanged
2507         xout XID_LUT1V1,   s_l1View1cIpv6,   SIZE(s_l1View1cIpv6)
2508         xout XID_LUT1V2,   s_l1View2dIpv6,   SIZE(s_l1View2dIpv6)
2510         // If no reassm check
2511         qbbs l_c1ParseIpv6_main, s_pktCxt.flags.t_flag_cascaded_forwarding    
2512         qbbc l_c1ParseIpv6_main, s_runCxt.flags.t_ipReassmEn
2513         qbbs l_c1Ipv6ExtReasm_pass2, s_pktCxt.flags.t_flag_2nd_pass
2515         // Pass 1 operation
2516         // Fragmentation detection: Is there fragment header?
2517         // Get to nextHdr field in IPv6 header
2518         // add s_ipv6Reassm_ctrl.offset, s_pktCxt.startOffset, (32+32+6)
2519         // Load nextHdr and hdrLen field
2520         // Check to see if nextHdr is an extension header
2521         zero    &s_ipv6Reassm_ctrl,     SIZE(s_ipv6Reassm_ctrl)
2522         mov     s_ipv6Reassm_ctrl.nextHdr,  s_Ipv6a.next 
2523         add     s_ipv6Reassm_ctrl.offset,   s_pktCxt.startOffset, (32+32+40) 
2524         mov     s_ipv6Reassm_ctrl.maxOffset, (32 + 32 + PA_MAX_HDR_LEN)
2525         qbbc    l_c1Ipv6ExtReasm_eoamCheck, s_runCxt.flag2.t_raEn
2526           add  s_ipv6Reassm_ctrl.offset,   s_ipv6Reassm_ctrl.offset, 8 
2527 l_c1Ipv6ExtReasm_eoamCheck:        
2528         qbbc l_c1Ipv6ExtReasm_exthdrCheck, s_runCxt.flag3.t_eoamEn   
2529           add  s_ipv6Reassm_ctrl.offset,   s_ipv6Reassm_ctrl.offset, 8 
2530           add  s_ipv6Reassm_ctrl.maxOffset, s_ipv6Reassm_ctrl.maxOffset, 8          
2531 l_c1Ipv6ExtReasm_exthdrCheck:    
2532     qble    l_c1Ipv6ExtReasm_exthdrDone,  s_ipv6Reassm_ctrl.offset,  s_ipv6Reassm_ctrl.maxOffset
2533     qbeq    l_c1Ipv6ExtReasm_fragfound,   s_ipv6Reassm_ctrl.nextHdr, IP_PROTO_NEXT_IPV6_FRAG      
2534     qbeq    l_c1Ipv6ExtReasm_exthdrNext,  s_ipv6Reassm_ctrl.nextHdr, IP_PROTO_NEXT_IPV6_HOP_BY_HOP
2535     qbeq    l_c1Ipv6ExtReasm_exthdrNext,  s_ipv6Reassm_ctrl.nextHdr, IP_PROTO_NEXT_IPV6_ROUTE
2536     qbeq    l_c1Ipv6ExtReasm_exthdrNext,  s_ipv6Reassm_ctrl.nextHdr, IP_PROTO_NEXT_IPV6_DEST_OPT
2537 //   below would save one cycle since jmp is to header done.
2538 //    qbeq    l_c1Ipv6ExtReasm_exthdrDone,  s_ipv6Reassm_ctrl.nextHdr, IP_PROTO_NEXT_IPV6_NO_NEXT
2539     jmp     l_c1Ipv6ExtReasm_exthdrDone   
2540     
2541 l_c1Ipv6ExtReasm_exthdrNext:        
2542     // load the next header
2543     lbco    s_ipv6Reassm_ctrl.nextHdr,  cCdeInPkt, s_ipv6Reassm_ctrl.offset, 2
2544     
2545     // adjust the offset for next one
2546     add     s_ipv6Reassm_ctrl.thdrLen,  s_ipv6Reassm_ctrl.hdrLen, 1
2547     lsl     s_ipv6Reassm_ctrl.tHdrLen,  s_ipv6Reassm_ctrl.thdrLen, 3
2548     add     s_ipv6Reassm_ctrl.offset,  s_ipv6Reassm_ctrl.offset, s_ipv6Reassm_ctrl.tHdrLen
2549     
2550     jmp     l_c1Ipv6ExtReasm_exthdrCheck
2551     
2552 l_c1Ipv6ExtReasm_fragfound:
2553     lbco    s_ipv6Reassm_ctrl.nextHdr,  cCdeInPkt, s_ipv6Reassm_ctrl.offset, 1
2554     set     s_ipv6Reassm_ctrl.flag.t_reassm_ctrl_flag_frag 
2555     // 
2556     // IP Frag stats has already been incremented at the RA stage
2557     //
2558     //mov     s_stats.value,  PA_STATS_UPDATE_REQ | PA_STATS_IP_FRAG
2560 l_c1Ipv6ExtReasm_exthdrDone:        
2562 l_c1Ipv6ExtReasm_pass1_1:
2564     // s_ipReassmCxt is r14 - r17, which overwrites s_Ipv6b.srcIp_3
2565     mov  r2, s_Ipv6b.srcIp_3
2566     lbco s_ipReassmCxt, PAMEM_CONST_IP_REASSEM_CONTEXT, 0, OFFSET(s_ipReassmCxt.tfMapTemp)
2567     mov s_ipReassmCxt.tfMapTemp, s_ipReassmCxt.tfMap
2569 l_c1Ipv6ExtReasm_pass1_2:
2570     qbeq l_c1Ipv6ExtReasm_pass1_3, s_ipReassmCxt.tfMapTemp, 0
2571         lmbd s_pktCxt3.tfIndex, s_ipReassmCxt.tfMapTemp, 1
2572         clr s_ipReassmCxt.tfMapTemp, s_pktCxt3.tfIndex
2573         lsl s_ipReassmCxt.offset, s_pktCxt3.tfIndex, 4
2574         lbco s_ipTf, PAMEM_CONST_TF_TABLE, s_ipReassmCxt.offset, SIZE(s_ipTf)
2576         // Only compare the last 4 bytes of Ipv6 header
2577         // r1 now contains s_Ipv6b.srcIp_3
2578         qbne  l_c1Ipv6ExtReasm_pass1_2, s_ipTf.srcIp, r2
2579         qbne  l_c1Ipv6ExtReasm_pass1_2, s_ipTf.destIp, s_Ipv6b.dstIp_3
2580         qbne  l_c1Ipv6ExtReasm_pass1_2, s_ipTf.proto,  s_ipv6Reassm_ctrl.nextHdr
2581   
2582         // match found: update and store the counter
2583         add   s_ipTf.cnt, s_ipTf.cnt, 1
2584         sbco  s_ipTf, PAMEM_CONST_TF_TABLE, s_ipReassmCxt.offset,  OFFSET(s_ipTf.proto)
2585   
2586         jmp   l_c1Ipv6ExtReasm_pass1_5
2587   
2588 l_c1Ipv6ExtReasm_pass1_3:
2589         //match not found
2590         // Fragmentation check  
2591         // normal operation for non-fragments packet
2592         qbbc  l_c1ParseIpv6_main,  s_ipv6Reassm_ctrl.flag.t_reassm_ctrl_flag_frag
2593   
2594         // Find available traffic flow
2595         qble  l_c1Ipv6ExtReasm_pass1_4, s_ipReassmCxt.numActiveTF, s_ipReassmCxt.numTF  
2596             lmbd  s_pktCxt3.tfIndex, s_ipReassmCxt.tfMap, 0
2597             qbeq  l_c1Ipv6ExtReasm_pass1_4, s_pktCxt3.tfIndex, 32
2598   
2599         // Traffic Flow found
2600         set   s_ipReassmCxt.tfMap, s_pktCxt3.tfIndex
2601         add   s_ipReassmCxt.numActiveTF, s_ipReassmCxt.numActiveTF,  1
2602         sbco  s_ipReassmCxt, PAMEM_CONST_IP_REASSEM_CONTEXT, 0, OFFSET(s_ipReassmCxt.tfMapTemp)
2603   
2604         // store the traffic flow
2605         // r2 now contains s_Ipv6b.srcIp_3
2606         mov   s_ipTf.srcIp, r2
2607         mov   s_ipTf.destIp, s_Ipv6b.dstIp_3
2608         mov   s_ipTf.proto,  s_ipv6Reassm_ctrl.nextHdr
2609         mov   s_ipTf.cnt, 1
2610         lsl   s_ipReassmCxt.offset,   s_pktCxt3.tfIndex, 4
2611         sbco  s_ipTf, PAMEM_CONST_TF_TABLE, s_ipReassmCxt.offset,  SIZE(s_ipTf)
2612   
2613         jmp    l_c1Ipv6ExtReasm_pass1_5
2614   
2615 l_c1Ipv6ExtReasm_pass1_4:  
2616     // No Traffic flow available
2617     mov  s_pktCxt3.tfIndex, PA_INV_TF_INDEX 
2618   
2619   // pass through 
2620 l_c1Ipv6ExtReasm_pass1_5:
2621     mov   s_pktCxt3.fragCnt,  1
2622     set   s_pktCxt.flags.t_flag_2nd_pass  
2623     wbs   s_flags.info.tStatus_CDEOutPacket
2625 l_c1Ipv6ExtReasm_pass1_5_queue_bounce:\r
2626     // Check for Queue Bounce operation\r
2627 l_c1Ipv6ExtReasm_pass1_5_queue_bounce_ddr:\r
2628     qbbc l_c1Ipv6ExtReasm_pass1_5_queue_bounce_msmc, s_ipReassmCxt.queue.t_pa_forward_queue_bounce_ddr\r
2629         clr s_ipReassmCxt.queue.t_pa_forward_queue_bounce_ddr\r
2630         sbco s_ipReassmCxt.queue,  cCdeOutPkt, OFFSET(s_pktDescr.swinfo1) + 2,  2\r
2631         lbco s_ipReassmCxt.queue,  PAMEM_CONST_CUSTOM, OFFSET_QUEUE_BOUNCE_CFG, 2\r
2632         jmp  l_c1Ipv6ExtReasm_pass1_5_queue_bounce_end\r
2633 \r
2634 l_c1Ipv6ExtReasm_pass1_5_queue_bounce_msmc:\r
2635     qbbc l_c1Ipv6ExtReasm_pass1_5_queue_bounce_end, s_ipReassmCxt.queue.t_pa_forward_queue_bounce_msmc\r
2636         clr s_ipReassmCxt.queue.t_pa_forward_queue_bounce_msmc\r
2637         sbco s_ipReassmCxt.queue,  cCdeOutPkt, OFFSET(s_pktDescr.swinfo1) + 2,  2\r
2638         lbco s_ipReassmCxt.queue,  PAMEM_CONST_CUSTOM, OFFSET_QUEUE_BOUNCE_CFG+2, 2\r
2639          // pass through\r
2640 l_c1Ipv6ExtReasm_pass1_5_queue_bounce_end:\r
2641 \r
2642     sbco  s_ipReassmCxt.queue,  cCdeOutPkt,  OFFSET(s_pktDescr.destQ),    SIZE(s_pktDescr.destQ)
2643     sbco  s_ipReassmCxt.flowId, cCdeOutPkt,  OFFSET(s_pktDescr.flowIdx),  SIZE(s_pktDescr.flowIdx)
2644     mov   s_param.action,     SUBS_ACTION_FWPKT
2645     mov   s_next.hdr,         PA_HDR_IPv6
2646     ret
2647   
2648   // Second Pass operations
2649 l_c1Ipv6ExtReasm_pass2:
2650     clr   s_pktCxt.flags.t_flag_2nd_pass
2651     // TF index range check
2652     qbeq  l_c1Ipv6ExtReasm_pass2_3, s_pktCxt3.tfIndex, PA_INV_TF_INDEX
2653     qble  l_c1ParseIpv4_9,   s_pktCxt3.tfIndex,   32
2654   
2655     lsl   r1.w0,  s_pktCxt3.tfIndex, 4  //tfIndex * 16
2656     lbco  s_ipTf, PAMEM_CONST_TF_TABLE, r1.w0,  OFFSET(s_ipTf.srcIp)
2657   
2658     qbge  l_c1Ipv6ExtReasm_pass2_1,   s_ipTf.cnt,     s_pktCxt3.fragCnt
2659   
2660     sub  s_ipTf.cnt,    s_ipTf.cnt, s_pktCxt3.fragCnt
2661     sbco s_ipTf, PAMEM_CONST_TF_TABLE, r1.w0,  OFFSET(s_ipTf.srcIp)
2662     jmp  l_c1Ipv6ExtReasm_pass2_3
2663     
2664 l_c1Ipv6ExtReasm_pass2_1:
2665     // Counter has reached zero, clear the corresponding bit
2666     lbco s_ipReassmCxt, PAMEM_CONST_IP_REASSEM_CONTEXT, 0, OFFSET(s_ipReassmCxt.tfMapTemp)
2667     clr  s_ipReassmCxt.tfMap,   s_pktCxt3.tfIndex
2668     qbeq l_c1Ipv6ExtReasm_pass2_2,  s_ipReassmCxt.numActiveTF, 0
2669     sub  s_ipReassmCxt.numActiveTF, s_ipReassmCxt.numActiveTF, 1
2670                        
2671 l_c1Ipv6ExtReasm_pass2_2:
2672     sbco s_ipReassmCxt, PAMEM_CONST_IP_REASSEM_CONTEXT, 0, OFFSET(s_ipReassmCxt.tfMapTemp)
2673     // pass through
2674     
2675 l_c1Ipv6ExtReasm_pass2_3:
2676     // verify whether it is an null packet  
2677     qbbc l_c1ParseIpv6_main,  s_pktCxt.flags.t_flag_null_pkt
2678         // drop the null packet
2679         mov   s_param.action,     SUBS_ACTION_DISCARD
2680         ret
2681         
2682 #endif  // PASS_PROC_FIREWALL        
2684 l_c1ParseIpv6_main:
2686 #ifdef PASS_VERIFY_POST_RA_DROP
2687         wbs  s_flags.info.tStatus_CDEOutPacket
2688         lbco  r1.b0,  cCdeOutPkt, OFFSET(s_pktDescr.psFlags_errorFlags),  SIZE(s_pktDescr.psFlags_errorFlags)
2689         qbbc  l_c1ParseIpv6_main_0, r1.b0.t_psFlags_pktDropFromRA
2690             // drop the packet
2691             mov s_param.action, SUBS_ACTION_DISCARD
2692             ret
2693     l_c1ParseIpv6_main_0:    
2694 #endif    
2696 #ifndef PASS_PROC_FIREWALL
2698     // New IPv6 packet: check maximum count
2699     lbco  r0.w2,  PAMEM_CONST_CUSTOM, OFFSET_MAX_HDR + OFFSET(struct_paComMaxCount.ipMaxCount), 2
2701     // IP depth count
2702     and  r0.w0,         s_pktCxt.protCount,  PROT_COUNT_IP_MASK
2703     qblt l_c1ParseIpv6_00,   r0.w2,  r0.w0
2704         and  s_pktCxt.eId_portNum_nextHdr.b1,  s_pktCxt.eId_portNum_nextHdr.b1,   NOT_PKT_EIDX_MASK
2705         or   s_pktCxt.eId_portNum_nextHdr.b1,  s_pktCxt.eId_portNum_nextHdr.b1,   EROUTE_IP_MAX_DEPTH << PKT_EIDX_SHIFT  
2707         mov s_stats.value,  PA_STATS_UPDATE_REQ | PA_STATS_IP_DEPTH_OVERFLOW
2708         mov s_param.action,        SUBS_ACTION_EXIT
2709         ret
2711 l_c1ParseIpv6_00:
2712     add  s_pktCxt.protCount, s_pktCxt.protCount, PROT_COUNT_IP_STEP
2713     mov s_stats.value,  PA_STATS_UPDATE_REQ | PA_STATS_IPV6_PKTS
2714     set  s_pktCxt.hdrBitmask.SUBS_PA_BIT_HEADER_IPv6
2715     
2716 #ifdef PASS_PROC_INNER_IP
2717     mov s_stats.value,  PA_STATS_UPDATE_REQ | PA_STATS_INNER_IPV6_PKTS
2718   // store the inner IP offset
2719   mov s_pktCxt5.l3l5Offset, s_pktCxt.startOffset
2720 #else
2721   // store the outer IP offset
2722   mov  s_pktCxt.l3Offset, s_pktCxt.startOffset
2723 #endif  
2725 #ifdef TOBE_DELETED
2726     
2727   //
2728   // t_l3toInnerIp = FALSE: Set l3Offset for outer IP 
2729   // t_l3toInnerIp = TRUE:  Set l3Offset for inner IP
2730   //
2731   qbbs l_c1ParseIpv6_01_setInnerIp, s_runCxt.flag2.t_l3toInnerIp
2732     qbne l_c1ParseIpv6_0,    s_pktCxt.l3Offset, 0
2733 l_c1ParseIpv6_01_setInnerIp:      
2734         mov  s_pktCxt.l3Offset, s_pktCxt.startOffset
2735     
2736 #endif
2737         
2738 #endif  // End of Firewall condition    
2739    
2740 l_c1ParseIpv6_0:
2741     zero  &s_l1View3bIpv6,    SIZE(s_l1View3bIpv6)
2742    
2743 #ifndef PASS_PROC_FIREWALL
2744   // Check to see whether virtual link is used 
2745   qbbs l_c1ParseIpv6_01_vLink, s_pktCxt.flags.t_flag_use_vlink
2746     // The previous lookup PDSP ID and LUT1 index is stored in the srcVC field
2747     mov  s_l1View3bIpv6.srcVC,  s_pktCxt.phyLink
2748     jmp  l_c1ParseIpv6_01_link_end
2749 l_c1ParseIpv6_01_vLink:    
2750     mov  s_l1View3bIpv6.srcVC,  s_pktCxt.vlanPri_vLink
2751     and  s_l1View3bIpv6.srcVC.b1, s_l1View3bIpv6.srcVC.b1, NOT_PKT_VLAN_PRI_MASK
2752     // Clear virtual link enable for further look ups
2753     clr s_pktCxt.flags.t_flag_use_vlink
2755 l_c1ParseIpv6_01_link_end:
2756 #else
2757     mov  s_l1View3bIpv6.srcVC,  s_pktCxt.phyLink
2758 #endif
2760 #ifdef   PASS_PROC_FIREWALL
2762 #ifdef PASS_DETECT_IP_PROC
2763  qbbc l_c1ParseIpv6_in3, s_runCxt.flag3.t_eoamEn
2764   set  s_pktCxt.flags.t_flag_ipProc
2765 l_c1ParseIpv6_in3:
2766 #endif 
2767    // Read in the IPv6 header.
2768    xin  XID_CDEDATA,  s_Ipv6a,   SIZE(s_Ipv6a)
2769    
2770    // Verify version
2771    and   r0.b0,                s_Ip.verLen,   0xF0
2772    qbne  fci_c1ParseIpv4_10,   r0.b0,         0x60
2773   
2774    //  Advance past the fisr 8 byte (Ipv6a).
2775    zero &s_cdeCmdWd,            SIZE(s_cdeCmdWd)
2776    mov  s_cdeCmdWd.operation,   CDE_CMD_WINDOW_ADVANCE
2777    mov  s_cdeCmdWd.byteCount,   SIZE(s_Ipv6a)                      // Bytes always present in the header
2778    xout XID_CDECTRL,    s_cdeCmdWd,   SIZE(s_cdeCmdWd)
2779    
2780    xin  XID_CDEDATA,  s_Ipv6b,   SIZE(s_Ipv6b)
2782    // Source and dest IP go out unchanged
2783    xout XID_LUT1V1,   s_l1View1cIpv6,   SIZE(s_l1View1cIpv6)
2784    xout XID_LUT1V2,   s_l1View2dIpv6,   SIZE(s_l1View2dIpv6)
2785    
2786 #endif
2787    
2788 #ifndef PASS_PROC_FIREWALL   
2790    // Begin the pseudo header checksum to free up LUT window 1 & 2
2791    // note: the pseudo header checksum does not include protocol and length
2792    // reload the IPv6 addresses
2793    xin   XID_CDEDATA,  s_Ipv6b,   SIZE(s_Ipv6b)
2794    add   r0,   s_Ipv6b.srcIp_0,   s_Ipv6b.srcIp_1
2795    adc   r0,   r0,                s_Ipv6b.srcIp_2
2796    adc   r0,   r0,                s_Ipv6b.srcIp_3
2797    adc   r0,   r0,                s_Ipv6b.dstIp_0
2798    adc   r0,   r0,                s_Ipv6b.dstIp_1
2799    adc   r0,   r0,                s_Ipv6b.dstIp_2
2800    adc   r0,   r0,                s_Ipv6b.dstIp_3
2801    adc   r0,   r0.w0,             r0.w2     // Fold carry once
2802    add   s_pktCxt.pseudo, r0.w0,  r0.w2     // Fold carry twice
2803    
2804    //Multicast detection
2805    qbne l_c1ParseIpv6_1,    s_Ipv6b.dstIp_0.b3, IPV6_MULTICAST_ADDR_BYTE0
2806    qbne l_c1ParseIpv6_1,    s_Ipv6b.dstIp_0.b2, IPV6_MULTICAST_ADDR_BYTE1
2807         set s_pktCxt.flags.t_flag_multicast  
2808         
2809 #else
2810    // Firewall (RA) specific operation 
2811    // TBD: priority settings
2812    lbco  s_raInfo,  cCdeOutPkt,  SIZE(s_pktDescr) + 24,  SIZE(s_raInfo)
2813    //zero &s_raInfo,   SIZE(s_raInfo)
2814    mov  s_raInfo.l3Offset, s_pktCxt.startOffset 
2815   //qbbc l_c1ParseIpv6_set_ra_threadId_1, s_runCxt.flag2.t_raToQueue
2816     // RA output is host queue
2817     //mov  s_raInfo.flags, THREADID_CDMA0
2818     //jmp  l_c1ParseIpv6_set_ra_threadId_end
2819 l_c1ParseIpv6_set_ra_threadId_1:  
2820     //mov  s_raInfo.flags, PASS_RA_DEST_THREAD_ID 
2821     // pass through  
2822 l_c1ParseIpv6_set_ra_threadId_end:
2823 #endif        
2824    
2825 l_c1ParseIpv6_1:
2826    
2827    // The protocol, tclass, and flow labels are moved as 
2828    // required
2829    mov   s_l1View3bIpv6.flowLabel, s_Ipv6a.ver_tclass_flow
2830    and   s_l1View3bIpv6.flowLabel.w2,  s_l1View3bIpv6.flowLabel.w2,   0x0f
2832 #ifdef PASS_PROC_FIREWALL   
2833    set   s_l1View3bIpv6.pktType.fL3PktTypeFirewall
2834 #else
2835    set   s_l1View3bIpv6.pktType.fL3PktTypeIp
2836 #endif   
2837    mov   s_l1View3bIpv6.protocol,      s_Ipv6a.next
2838    lsr   s_l1View3bIpv6.dscp,   s_Ipv6a.ver_tclass_flow.w2,  4
2839    and   s_l1View3bIpv6.dscp,   s_l1View3bIpv6.dscp, 0x3F
2840    // Store the DSCP priority bits in case we need DSCP priority routing 
2841    mov   s_pktCxt.priority,    s_l1View3bIpv6.dscp
2842    
2843    xout  XID_LUT1V3,               s_l1View3bIpv6,         SIZE(s_l1View3bIpv6)
2845    // Update packet offsets
2846 #ifndef PASS_PROC_FIREWALL  
2847    add   s_pktCxt.startOffset,   s_pktCxt.startOffset,  IPV6_HEADER_LEN_BYTES
2848    add   s_pktCxt.endOffset,     s_pktCxt.startOffset,  s_Ipv6a.payloadLen
2849 #else 
2850    add   s_raInfo.ipv6NextOffset, s_pktCxt.startOffset, OFFSET(s_Ipv6a.next)    
2851    add   s_pktCxt.startOffset,   s_pktCxt.startOffset,  IPV6_HEADER_LEN_BYTES
2852    qbbs  l_c1ParseIpv6_1_0, s_pktCxt.flags.t_flag_cascaded_forwarding
2853    qbbc  l_c1ParseIpv6_1_0, s_runCxt.flag2.t_raEn
2854       //wbs   s_flags.info.tStatus_CDEOutPacket
2855       sbco  s_raInfo,  cCdeOutPkt,  SIZE(s_pktDescr) + 24,  SIZE(s_raInfo)
2856   
2857     //pass through
2858 l_c1ParseIpv6_1_0:   
2859 #endif
2861    // Get the next header and action
2862    set    s_l1View3bIpv6.pktFlags.fL3IpContainL4
2863    lbco   r0.b0,             PAMEM_CONST_IP_PROTO,  s_Ipv6a.next,   1
2864    and    s_next.Hdr,        r0.b0,                 0x3f
2865    lsr    s_param.action,    r0.b0,                 6
2866    
2867 #ifdef PASS_PROC_LUT1_L4
2868     //qbeq l_c1ParseIpv6_1_1, s_next.Hdr,   PA_HDR_UNKNOWN
2869     //    mov s_param.action, SUBS_ACTION_PARSE 
2870     
2871 l_c1ParseIpv6_1_1:
2873 #endif  
2874    
2875    
2876    //  Advance past the always present IP header.
2877    //  Note: The other parameters are set previously
2878    mov   s_cdeCmdWd.byteCount,   IPV6_HEADER_LEN_BYTES - SIZE(s_Ipv6a) // Bytes always present in the header
2879    xout   XID_CDECTRL,    s_cdeCmdWd,   SIZE(s_cdeCmdWd)
2880    
2881    ret
2882    
2883 #else
2884    // Ingress1, PDSP1 only
2885    // Forward the packets to Ingess3 for continue L3 processing
2886    mov   s_param.action,     SUBS_ACTION_FWPKT4
2887    ret
2889 #endif
2890     .leave lut1Scope
2891     .leave cdeScope
2892     .leave pktScope
2893     .leave ipScope
2895 // ***********************************************************************************
2896 // * FUNCTION PURPOSE: Parse the IPv6 optional hop by hop header
2897 // ***********************************************************************************
2898 // * DESCRIPTION: The hop by hop option header is processed. The only recognized option
2899 // *              is the jumbo frame option. When detected the entire packet is sent
2900 // *              to the jumbo frame queue. In reality it should have never made it 
2901 // *              to classify1 since the smallest jumbo frame is larger then 64k bytes
2902 // *
2903 // *              Unknown hop by hop options are bypassed, independent of the action bits
2904 // *              in the option type
2905 // *
2906 // *   Register Usage:  
2907 // * 
2908 // *   R0:    scratch
2909 // *   R1:    
2910 // *   R2:    
2911 // *   R3:              b0 - next header type  - pktScope
2912 // *   R4:    |  CDE commands     -  cdeScope
2913 // *   R5:    |                   -
2914 // *   R5:    |                   -
2915 // *   R6:        |                                  |  IPv6 header & option headers
2916 // *   R7:        |                                  |  
2917 // *   R8:        |                                    
2918 // *   R9:        |  LUT1 View   - lut1Scope
2919 // *   R10:       |                                     | 
2920 // *   R11:       |                                     |  LUT1 View3
2921 // *   R12:       |                                     |
2922 // *   R13:       |                                     |
2923 // *   R14:          |  (packet extended descriptor)     |             
2924 // *   R15:          |                                   |                   
2925 // *   R16:          |                                   | LUT1 View1  | raInfo   
2926 // *   R17:          |  LUT1 View  - lut1Scope           |             |
2927 // *   R18:          |  (IP address)                       | 
2928 // *   R19:          |                                     | LUT1 View2 
2929 // *   R20:          |                                     |
2930 // *   R21:          |                                     |
2931 // *   R22:     |     
2932 // *   R23:     |  Packet context - pktScope   
2933 // *   R24:     |
2934 // *   R25:     |
2935 // *   R26:     |
2936 // *   R27:     |
2937 // *   R28:  
2938 // *   R29:  c1RunContext (s_runCxt)                                -  Global Scope
2939 // *   R30:  w2-param.action  w0-function return address            -
2940 // *   R31:  System Flags (s_flags)                                 -
2941 // *
2942 // ************************************************************************************
2944     .using cdeScope
2945     .using pktScope
2946     .using ipScope
2947     .using lut1Scope
2949 f_c1ParseIpv6ExtHop:
2951 #ifdef PASS_PROC_L3
2953 #ifdef PASS_PROC_RA
2954    mov  s_raInfo.ipv6NextOffset, s_pktCxt.startOffset
2955 #endif
2957    // The length of the options field in the header is in 8 byte units, not
2958    // including the 1st 8 bytes.
2959    xin  XID_CDEDATA,  s_Ipv6Opt,         SIZE(s_Ipv6Opt)
2960    lsl  r0.w0,        s_Ipv6Opt.optlen,  3
2961    qblt fci_c1ParseIpv4_10,      r0.w0,       (PA_MAX_HDR_LEN-1)      // Hdr length check     
2962    add  s_cdeCmdWd.byteCount,    r0.w0,             8
2963    add  s_pktCxt.startOffset, s_pktCxt.startOffset, s_cdeCmdWd.byteCount
2964    
2965    // Scroll past this header
2966    xout XID_CDECTRL,           s_cdeCmdWd,        SIZE(s_cdeCmdWd)
2968    // Put the next proto type into the lookup
2969    mov  s_l1View3bIpv6.protocol,  s_Ipv6Opt.proto
2970    xout XID_LUT1V3,           s_l1View3bIpv6.protocol,  SIZE(s_l1View3bIpv6.protocol)
2972    // Get the next header type and action from the protocol field
2973    lbco   r1.b0,             PAMEM_CONST_IP_PROTO,  s_Ipv6Opt.proto,   1
2974    and    s_next.Hdr,        r1.b0,                 0x3f
2975    lsr    s_param.action,    r1.b0,                 6
2976    ret
2977    
2978 #endif   
2980     .leave cdeScope
2981     .leave pktScope
2982     .leave ipScope
2983     .leave lut1Scope
2986 // ************************************************************************************
2987 // * FUNCTION PURPOSE: Parse the IPv6 route extension header
2988 // ************************************************************************************
2989 // * DESCRIPTION: The header is checked to see if any routes remain. If so a flag is set
2990 // *              which will cause the packet to route to the destination specified in the
2991 // *              error routing table for IP routing (assuming LUT1 lookup is successful).
2992 // *              If LUT1 lookup fails then the packet is routed as a LUT1 match fail.
2993 // *
2994 // *   Register Usage:  
2995 // * 
2996 // *   R0:    scratch
2997 // *   R1:    
2998 // *   R2:    
2999 // *   R3:              b0 - next header type  - pktScope
3000 // *   R4:    |  CDE commands     -  cdeScope
3001 // *   R5:    |                   -
3002 // *   R5:    |                   -
3003 // *   R6:        |                                  |  IPv6 header & option headers
3004 // *   R7:        |                                  |  
3005 // *   R8:        |                                    
3006 // *   R9:        |  LUT1 View   - lut1Scope
3007 // *   R10:       |                                     |              
3008 // *   R11:       |                                     |  LUT1 View3  
3009 // *   R12:       |                                     |              | raInfo
3010 // *   R13:       |                                     |              |      
3011 // *   R14:          |  (packet extended descriptor)     |                                    
3012 // *   R15:          |                                   |        
3013 // *   R16:          |                                   | LUT1 View1      
3014 // *   R17:          |  LUT1 View  - lut1Scope           |      
3015 // *   R18:          |  (IP address)                       | 
3016 // *   R19:          |                                     | LUT1 View2 
3017 // *   R20:          |                                     |
3018 // *   R21:          |                                     |
3019 // *   R22:     |     
3020 // *   R23:     |  Packet context - pktScope   
3021 // *   R24:     |
3022 // *   R25:     |
3023 // *   R26:     |
3024 // *   R27:     |
3025 // *   R28:  
3026 // *   R29:  c1RunContext (s_runCxt)                                -  Global Scope
3027 // *   R30:  w2-param.action  w0-function return address            -
3028 // *   R31:  System Flags (s_flags)                                 -
3029 // *
3030 // *************************************************************************************
3032     .using cdeScope
3033     .using pktScope
3034     .using ipScope
3035     .using lut1Scope
3037 f_c1ParseIpv6ExtRoute:
3039 #ifdef PASS_PROC_L3
3041 #ifdef PASS_PROC_RA
3042    mov  s_raInfo.ipv6NextOffset, s_pktCxt.startOffset
3043 #endif
3045    xin  XID_CDEDATA,  s_Ipv6ExtRt,   SIZE(s_Ipv6ExtRt)
3047    // Put the next proto type into the lookup
3048    mov  s_l1View3bIpv6.protocol,  s_Ipv6ExtRt.proto
3049    xout XID_LUT1V3,           s_l1View3bIpv6.protocol,  SIZE(s_l1View3bIpv6.protocol)
3050    
3051    // Get the next header type and action from the protocol field
3052    lbco   r1.b0,             PAMEM_CONST_IP_PROTO,  s_Ipv6ExtRt.proto,   1
3053    and    s_next.Hdr,        r1.b0,                 0x3f
3054    lsr    s_param.action,    r1.b0,                 6
3056 l_c1ParseIpv6ExtRoute0:
3057    // The options header length is in 8 byte units, not including the 1st 8 bytes
3058    lsl  r0.w0,                 s_Ipv6ExtRt.hdrlen,    3
3059    qblt fci_c1ParseIpv4_10,    r0.w0,       (PA_MAX_HDR_LEN-1)      // Hdr length check     
3060    add  s_cdeCmdWd.byteCount,  r0.w0,                 8
3061    xout XID_CDECTRL,           s_cdeCmdWd,            SIZE(s_cdeCmdWd)
3062    add  s_pktCxt.startOffset,  s_pktCxt.startoffset,  s_cdeCmdWd.byteCount
3064    ret
3065    
3066 #endif   
3068     .leave cdeScope
3069     .leave pktScope
3070     .leave ipScope
3071     .leave lut1Scope
3073 // *************************************************************************************
3074 // * FUNCTION PURPOSE: Parse the IPv6 fragment extension header
3075 // *************************************************************************************
3076 // * DESCRIPTION: The packet is marked as fragmented
3077 // *
3078 // *
3079 // *   Register Usage:  
3080 // * 
3081 // *   R0:    scratch
3082 // *   R1:    
3083 // *   R2:    
3084 // *   R3:              b0 - next header type  - pktScope
3085 // *   R4:    |  CDE commands     -  cdeScope
3086 // *   R5:    |                   -
3087 // *   R5:    |                   -
3088 // *   R6:        |                                  |  IPv6 header & option headers
3089 // *   R7:        |                                  |  
3090 // *   R8:        |                                    
3091 // *   R9:        |  LUT1 View   - lut1Scope
3092 // *   R10:       |                                     |              
3093 // *   R11:       |                                     |  LUT1 View3  
3094 // *   R12:       |                                     |              | raInfo
3095 // *   R13:       |                                     |              |      
3096 // *   R14:          |  (packet extended descriptor)     |                                    
3097 // *   R15:          |                                   |        
3098 // *   R16:          |                                   | LUT1 View1      
3099 // *   R17:          |  LUT1 View  - lut1Scope           |      
3100 // *   R18:          |  (IP address)                       | 
3101 // *   R19:          |                                     | LUT1 View2 
3102 // *   R20:          |                                     |
3103 // *   R21:          |                                     |
3104 // *   R22:     |     
3105 // *   R23:     |  Packet context - pktScope   
3106 // *   R24:     |
3107 // *   R25:     |
3108 // *   R26:     |
3109 // *   R27:     |
3110 // *   R28:  
3111 // *   R29:  c1RunContext (s_runCxt)                                -  Global Scope
3112 // *   R30:  w2-param.action  w0-function return address            -
3113 // *   R31:  System Flags (s_flags)                                 -
3114 // *
3115 // *************************************************************************************/
3116     .using cdeScope
3117     .using ipScope
3118     .using pktScope
3119     .using lut1Scope
3121 f_c1ParseIpv6ExtFrag:
3123 #ifdef PASS_PROC_L3
3125 #ifdef PASS_PROC_RA
3126   qbbs  l_c1ParseIpv6ExtFrag00, s_pktCxt.flags.t_flag_cascaded_forwarding
3127   qbbc  l_c1ParseIpv6ExtFrag00, s_runCxt.flag2.t_raEn
3128     mov  s_raInfo.ipv6FragOffset, s_pktCxt.startOffset
3129     set  s_raInfo.flags.t_ra_flag_reasm
3130 #ifdef PASS_INNER_RA
3131       //set s_raInfo.flags.t_ra_flag_2nd_inst   
3132 #endif         
3133     //wbs  s_flags.info.tStatus_CDEOutPacket
3134     sbco s_raInfo,  cCdeOutPkt,  SIZE(s_pktDescr) + 24,  SIZE(s_raInfo)
3135 l_c1ParseIpv6ExtFrag00:   
3136 #endif
3138    // The fragmentation header is always 8 bytes. The whole 
3139    // header is read here, but only the 1st byte is used
3140    xin  XID_CDEDATA,           s_Ipv6Frag,      SIZE(s_Ipv6Frag)      
3141    mov  s_cdeCmdWd.byteCount,  SIZE(s_Ipv6Frag)
3142    xout XID_CDECTRL,           s_cdeCmdWd,      SIZE(s_cdeCmdWd)
3144    // Put the next proto type into the lookup
3145    mov  s_l1View3bIpv6.protocol,  s_Ipv6Frag.proto
3146    xout XID_LUT1V3,           s_l1View3bIpv6.protocol,  SIZE(s_l1View3bIpv6.protocol)
3147    
3148 l_c1ParseIpv6ExtFrag0:
3149    add  s_pktCxt.startOffset,           s_pktCxt.startOffset,  IPV6_OPT_FRAG_EXTENSION_LEN_BYTES
3150    set  s_l1View3bIpv6.pktFlags.fL3IpFrag
3151   // Fragmentation check
3152   lsr   r3.w0,   s_Ipv6Frag.fragnFlag,     IPV6_FRAG_OFF_SHIFT
3153   qbeq  l_c1ParseIpv6ExtFrag1, r3.w0, 0
3154         clr  s_l1View3bIpv6.pktFlags.fL3IpContainL4
3155         clr  s_runCxt.flags.t_l4Avil
3156 l_c1ParseIpv6ExtFrag1:  
3157    xout XID_LUT1V3,           s_l1View3bIpv6.pktFlags,  SIZE(s_l1View3bIpv6.pktFlags)
3158    
3159 #ifndef PASS_PROC_RA    
3160    set  s_pktCxt.flags.t_flag_frag
3161 #else  // PASS_PROC_RA
3162    mov s_stats.value,  PA_STATS_UPDATE_REQ | PA_STATS_IP_FRAG
3163   //qbbs  l_c1ParseIpv6ExtFrag2_1, s_pktCxt.flags.t_flag_cascaded_forwarding
3164   //qbbc  l_c1ParseIpv6ExtFrag2_1, s_runCxt.flag2.t_raEn
3165     
3166 l_c1ParseIpv6ExtFrag2_1:
3167 #endif
3170    // Get the next header type and action from the protocol field
3171    lbco   r1.b0,             PAMEM_CONST_IP_PROTO,  s_Ipv6Frag.proto,   1
3172    and    s_next.Hdr,        r1.b0,                 0x3f
3173    lsr    s_param.action,    r1.b0,                 6
3174    
3175 #ifdef PASS_PROC_FIREWALL
3176     qbbs l_c1ParseIpv6ExtFrag3, s_runCxt.flags.t_l4Avil
3177         mov s_param.action, SUBS_ACTION_LOOKUP 
3178     
3179 l_c1ParseIpv6ExtFrag3:
3180 #endif 
3181    
3182    ret
3184 #endif
3186     .leave cdeScope
3187     .leave ipScope
3188     .leave pktScope
3189     .leave lut1Scope
3191 // ***********************************************************************************
3192 // * FUNCTION PURPOSE: Parse the IPv6 destination options extension header
3193 // ***********************************************************************************
3194 // * DESCRIPTION: The destination options header is ignored
3195 // *
3196 // *   Register Usage:  
3197 // * 
3198 // *   R0:    scratch
3199 // *   R1:    
3200 // *   R2:    
3201 // *   R3:              b0 - next header type  - pktScope
3202 // *   R4:    |  CDE commands     -  cdeScope
3203 // *   R5:    |                   -
3204 // *   R5:    |                   -
3205 // *   R6:        |                                  |  IPv6 header & option headers
3206 // *   R7:        |                                  |  
3207 // *   R8:        |                                    
3208 // *   R9:        |  LUT1 View   - lut1Scope
3209 // *   R10:       |                                     |              
3210 // *   R11:       |                                     |  LUT1 View3  
3211 // *   R12:       |                                     |              | raInfo
3212 // *   R13:       |                                     |              |      
3213 // *   R14:          |  (packet extended descriptor)     |                                    
3214 // *   R15:          |                                   |        
3215 // *   R16:          |                                   | LUT1 View1      
3216 // *   R17:          |  LUT1 View  - lut1Scope           |      
3217 // *   R18:          |  (IP address)                       | 
3218 // *   R19:          |                                     | LUT1 View2 
3219 // *   R20:          |                                     |
3220 // *   R21:          |                                     |
3221 // *   R22:     |     
3222 // *   R23:     |  Packet context - pktScope   
3223 // *   R24:     |
3224 // *   R25:     |
3225 // *   R26:     |
3226 // *   R27:     |
3227 // *   R28:  
3228 // *   R29:  c1RunContext (s_runCxt)                                -  Global Scope
3229 // *   R30:  w2-param.action  w0-function return address            -
3230 // *   R31:  System Flags (s_flags)                                 -
3231 // *
3232 // *
3233 // ***********************************************************************************
3235     .using cdeScope
3236     .using pktScope
3237     .using ipScope
3238     .using lut1Scope
3240 f_c1ParseIpv6ExtDestOpt:
3242 #ifdef PASS_PROC_L3
3244 #ifdef PASS_PROC_RA
3245    mov  s_raInfo.ipv6NextOffset, s_pktCxt.startOffset
3246 #endif
3248    xin  XID_CDEDATA,  s_Ipv6Opt,  SIZE(s_Ipv6Opt)
3250    // Put the next proto type into the lookup
3251    mov  s_l1View3bIpv6.protocol,  s_Ipv6Opt.proto
3252    xout XID_LUT1V3,           s_l1View3bIpv6.protocol,  SIZE(s_l1View3bIpv6.protocol)
3254    // Get the next header type and action from the protocol field
3255    lbco   r1.b0,             PAMEM_CONST_IP_PROTO,  s_Ipv6Opt.proto,   1
3256    and    s_next.Hdr,        r1.b0,                 0x3f
3257    lsr    s_param.action,    r1.b0,                 6
3259    lsl    r0.w0,                s_Ipv6Opt.optlen,     3
3260    qblt   fci_c1ParseIpv4_10,   r0.w0,       (PA_MAX_HDR_LEN-1)      // Hdr length check     
3261    add    s_cdeCmdWd.byteCount, r0.w0,                8
3262    xout   XID_CDECTRL,          s_cdeCmdWd,           SIZE(s_cdeCmdWd)
3263    add    s_pktCxt.startOffset, s_pktCxt.startOffset, s_cdeCmdWd.byteCount
3265    ret
3267 #endif
3268    
3269     .leave cdeScope
3270     .leave pktScope
3271     .leave ipScope
3272     .leave lut1Scope
3274 // **********************************************************************************
3275 // * FUNCTION PURPOSE: Parse a GRE header
3276 // **********************************************************************************
3277 // * DESCRIPTION:
3278 // *
3279 // *   Register Usage:  
3280 // * 
3281 // *   R0:    scratch
3282 // *   R1:    
3283 // *   R2:    
3284 // *   R3:              b0 - next header type  - pktScope
3285 // *   R4:    |  CDE commands     -  cdeScope
3286 // *   R5:    |                   -
3287 // *   R5:    |                   -
3288 // *   R6:        |                                  |  GRE header
3289 // *   R7:        |                                  |  
3290 // *   R8:        |                                    
3291 // *   R9:        |  LUT1 View   - lut1Scope
3292 // *   R10:       |                                     | 
3293 // *   R11:       |                                     |  LUT1 View3
3294 // *   R12:       |                                     |
3295 // *   R13:       |                                     |
3296 // *   R14:          |  (packet extended descriptor)     |                                    
3297 // *   R15:          |                                   |        
3298 // *   R16:          |                                   | LUT1 View1      
3299 // *   R17:          |  LUT1 View  - lut1Scope           |      
3300 // *   R18:          |  (IP address)                       | 
3301 // *   R19:          |                                     | LUT1 View2 
3302 // *   R20:          |                                     |
3303 // *   R21:          |                                     |
3304 // *   R22:     |     
3305 // *   R23:     |  Packet context - pktScope   
3306 // *   R24:     |
3307 // *   R25:     |
3308 // *   R26:     |
3309 // *   R27:     |
3310 // *   R28:  
3311 // *   R29:  c1RunContext (s_runCxt)                                -  Global Scope
3312 // *   R30:  w2-param.action  w0-function return address            -
3313 // *   R31:  System Flags (s_flags)                                 -
3314 // *
3315 // *
3316 // **********************************************************************************
3317     .using cdeScope
3318     .using pktScope
3319     .using greScope
3320     .using lut1Scope
3322 f_c1ParseGre:
3324 #ifdef PASS_PROC_FIREWALL
3325     // Terminate parsing
3326     mov s_param.action,        SUBS_ACTION_LOOKUP
3327     mov s_next.Hdr,     PA_HDR_UNKNOWN
3328     ret
3329 #endif
3331 #ifdef PASS_PROC_L3
3333   // New GRE packet: check maximum count
3334   lbco  r0.w2,  PAMEM_CONST_CUSTOM, OFFSET_MAX_HDR + OFFSET(struct_paComMaxCount.greMaxCount), 2
3336   // IP depth count
3337   lsr  r0.w0,   s_pktCxt.protCount,  PROT_COUNT_GRE_SHIFT
3338   and  r0.w0,   r0.w0,               PROT_COUNT_GRE_MASK
3339   qblt l_c1ParseGre00,   r0.w2,  r0.w0
3340       and  s_pktCxt.eId_portNum_nextHdr.b1,  s_pktCxt.eId_portNum_nextHdr.b1,   NOT_PKT_EIDX_MASK
3341       or   s_pktCxt.eId_portNum_nextHdr.b1,  s_pktCxt.eId_portNum_nextHdr.b1,   EROUTE_GRE_MAX_DEPTH << PKT_EIDX_SHIFT  
3342       mov s_stats.value,  PA_STATS_UPDATE_REQ | PA_STATS_GRE_DEPTH_OVERFLOW
3343       mov s_param.action,        SUBS_ACTION_EXIT
3344       ret
3346 l_c1ParseGre00:
3347   mov  s_param.action, SUBS_ACTION_LOOKUP
3348   add  s_pktCxt.protCount,  s_pktCxt.protCount,  PROT_COUNT_GRE_STEP
3350   xin  XID_CDEDATA,           s_greHdr,      SIZE(s_greHdr)
3351   mov  s_cdeCmdWd.byteCount,  SIZE(s_greHdr)
3352   xout XID_CDECTRL,           s_cdeCmdWd,    SIZE(s_cdeCmdWd)
3353   
3354   add  s_pktCxt.startOffset,  s_pktCxt.startOffset,  SIZE(s_greHdr)
3355   mov  s_cdeCmdWd.byteCount,  0
3357   // GRE checksum calculation
3358   qbbc  l_c1ParseGre0, s_greHdr.flags.t_GreCBit
3359 #ifdef GRE_CHECKSUM_VALIDATE
3360       // Not validated  
3361       // Restore the latest extended Packet Info
3362       xin   XID_PINFO_A, s_pktExtDescr, SIZE(s_pktExtDescr)
3363       zero &s_cdeCmdChk,           SIZE(s_cdeCmdChk)
3364       sub   s_cdeCmdChk.byteLen,   s_pktCxt.endOffset,  s_pktCxt.startOffset
3365       sub   s_cdeCmdChk.byteLen,   s_cdeCmdChk.byteLen, s_pktExtDescr.mopLength
3366       mov   s_cdeCmdChk.initSum,   s_pktExtDescr.mopCsum
3367       mov   s_cdeCmdChk.operation, CDE_CMD_CHECKSUM2_VALIDATE
3368       xout  XID_CDECTRL,           s_cdeCmdChk,                   SIZE(s_cdeCmdChk)
3369 #endif
3370       mov   s_cdeCmdWd.operation,  CDE_CMD_WINDOW_ADVANCE
3371       mov   s_cdeCmdWd.byteCount,  GRE_SIZE_CHKSUM_BYTES
3373 l_c1ParseGre0:
3374    // Load the GRE ethertype value into the View3 dstPort
3375    xin XID_LUT1V3,        s_l1View3bIpv6.pktFlags,   SIZE(s_l1View3bIpv6.pktFlags)
3376    set  s_l1View3bIpv6.pktFlags.fGre
3377    xout XID_LUT1V3,       s_l1View3bIpv6.pktFlags,   SIZE(s_l1View3bIpv6.pktFlags)
3379    mov  s_l1View3bIpv6.dstPort, s_greHdr.proto
3380    xout XID_LUT1V3,       s_l1View3bIpv6.dstPort,   SIZE(s_l1View3bIpv6.dstPort)
3382    //mov  s_cdeCmdWd.byteCount,  0
3383    qbbc  l_c1ParseGre1,  s_greHdr.flags.t_GreKBit
3384        add  s_cdeCmdWd.byteCount,   s_cdeCmdWd.byteCount,  GRE_SIZE_KEY_BYTES
3386 l_c1ParseGre1:
3387    qbbc  l_c1ParseGre2,  s_greHdr.flags.t_GreSBit
3388        add   s_cdeCmdWd.byteCount,  s_cdeCmdWd.byteCount,   GRE_SIZE_SEQNUM_BYTES
3390 l_c1ParseGre2:
3391    //  scroll past the optional key and sequence number fields
3392    //  a scroll of 0 should be ok
3393    xout  XID_CDECTRL,  s_cdeCmdWd,   SIZE(s_cdeCmdWd)
3394    add   s_pktCxt.startOffset,  s_pktCxt.startOffset,  s_cdeCmdWd.byteCount
3396    mov   r0.w0,  ETH_TYPE_IP
3397    qbne  l_c1ParseGre3, s_greHdr.proto, r0.w0 
3398        mov s_next.Hdr,  PA_HDR_IPv4
3399        ret
3401 l_c1ParseGre3:
3402    mov   r0.w0,  ETH_TYPE_IPV6
3403    qbne  l_c1ParseGre4, s_greHdr.proto, r0.w0
3404        mov s_next.Hdr,  PA_HDR_IPv6
3405        ret
3407 l_c1ParseGre4:
3408        mov s_next.Hdr,  PA_HDR_UNKNOWN
3409        ret
3410 #endif
3412     .leave cdeScope
3413     .leave pktScope
3414     .leave greScope
3415     .leave lut1Scope
3416     
3418 // **************************************************************************************
3419 // * FUNCTION PURPOSE: Parse an ESP header
3420 // **************************************************************************************
3421 // * DESCRIPTION: The SPI field is added to the LUT. At this stage there is no information
3422 // *              available about the next header
3423 // *              
3424 // *              The offset is not updated
3425 // *
3426 // *    On entry:
3427 // *            - the CDE is at the start of the ESP header
3428 // *            - r30.w0 has the function return address
3429 // *            - param.action has SUBS_ACTION_PARSE
3430 // *            - cdeCmdWd.operation has CDE_CMD_WINDOW_ADVNACE
3431 // *
3432 // *    On exit:
3433 // *            - param.action has SUBS_ACTION_LOOKUP
3434 // *            - cdeCmdWd.operation has CDE_CMD_WINDOW_ADVANCE
3435 // *            - CDE View window does not move
3436 // *            - startOffset is added by ESP_HEADER_LEN_BYTES
3437 // *
3438 // *   Register Usage:  
3439 // * 
3440 // *   R0:    scratch
3441 // *   R1:    
3442 // *   R2:    
3443 // *   R3:              b0 - next header type  - pktScope
3444 // *   R4:    |  CDE commands     -  cdeScope
3445 // *   R5:    |                   -
3446 // *   R6:        |                                  |  ESP Header
3447 // *   R7:        |                                    
3448 // *   R8:        |                                    
3449 // *   R9:        |  LUT1 View   - lut1Scope
3450 // *   R10:       |                                     | 
3451 // *   R11:       |                                     |  LUT1 View3
3452 // *   R12:       |                                     |
3453 // *   R13:       |                                     |
3454 // *   R14:          |                                          
3455 // *   R15:          |                                          
3456 // *   R16:          |                                          
3457 // *   R17:          |  LUT1 View2  - lut1Scope                 
3458 // *   R18:          |
3459 // *   R19:          |
3460 // *   R20:          |
3461 // *   R21:          |
3462 // *   R22:     |     
3463 // *   R23:     |  Packet context - pktScope   
3464 // *   R24:     |
3465 // *   R25:     |
3466 // *   R26:     |
3467 // *   R27:     |
3468 // *   R28:  
3469 // *   R29:  c1RunContext (s_runCxt)                                -  Global Scope
3470 // *   R30:  w2-param.action  w0-function return address            -
3471 // *   R31:  System Flags (s_flags)                                 -
3472 // *
3473 // *
3474 // **************************************************************************************
3476     .using cdeScope
3477     .using lut1Scope
3478     .using pktScope
3479     .using secScope
3482 f_c1ParseEsp:
3484 #ifdef PASS_PROC_FIREWALL
3485     // Terminate parsing
3486     mov s_param.action,        SUBS_ACTION_LOOKUP
3487     ret
3488 #endif
3490 #ifdef PASS_PROC_IPSEC   
3493 #ifdef PASS_SKIP_IPSEC
3494    qbbs l_c1ParseEsp_fwpkt, s_runCxt.flags.t_firstLookup
3495         xin  XID_LUT1V3,   s_l1View3bIpsec.pktFlags, SIZE(s_l1View3bIpsec.pktFlags)
3496         set  s_l1View3bIpsec.pktFlags.fIpsec
3497         xout XID_LUT1V3,   s_l1View3bIpsec.pktFlags, SIZE(s_l1View3bIpsec.pktFlags)
3498         set  s_pktCxt.hdrBitmask.SUBS_PA_BIT_HEADER_ESP
3499         mov  s_param.action, SUBS_ACTION_LOOKUP
3500         ret
3501 l_c1ParseEsp_fwpkt:
3502    // The IPSEC lookup occurs at the next stage (Ingress1, CED1)
3503    // This is IPSEC ESP NAT-T traffic back from Ingress4
3504         mov  s_param.action, SUBS_ACTION_FWPKT2
3505         ret
3506 #else
3507    // Read in the ESP spi and add it to the LUT
3508    xin  XID_CDEDATA,  s_esp,     SIZE(s_esp)
3509    
3510    // Populate the lookup views
3511    zero &s_l1View3bIpsec,   SIZE(s_l1View3bIpsec)
3512    mov  s_l1View3bIpsec.spi,    s_esp.spi
3513    set  s_l1View3bIpsec.pktFlags.fIpsecEsp
3514    set  s_l1View3bIpsec.pktType.fL3PktTypeIpsec
3515    
3516 #ifndef PASS_PROC_FIREWALL
3517   // Check to see whether virtual link is used 
3518   qbbs l_c1ParseEsp_vLink, s_pktCxt.flags.t_flag_use_vlink
3519     // The previous lookup PDSP ID and LUT1 index is stored in the srcVC field
3520     mov  s_l1View3bIpsec.srcVC,  s_pktCxt.phyLink
3521     jmp  l_c1ParseEsp_link_end
3522 l_c1ParseEsp_vLink:    
3523     mov  s_l1View3bIpsec.srcVC,  s_pktCxt.vlanPri_vLink
3524     and  s_l1View3bIpsec.srcVC.b1, s_l1View3bIpsec.srcVC.b1, NOT_PKT_VLAN_PRI_MASK
3525     // Clear virtual link enable for further look ups
3526     clr s_pktCxt.flags.t_flag_use_vlink
3528 l_c1ParseEsp_link_end:
3529 #else
3530     mov  s_l1View3bIpsec.srcVC,  s_pktCxt.phyLink
3531 #endif   
3532    xout XID_LUT1V3,   s_l1View3bIpsec, SIZE(s_l1View3bIpsec)
3533    
3534    mov  s_next.hdr,     PA_HDR_UNKNOWN
3535    mov  s_param.action, SUBS_ACTION_LOOKUP
3537    set  s_pktCxt.hdrBitmask.SUBS_PA_BIT_HEADER_ESP
3539    mov  s_pktCxt.espAhOffset,  s_pktCxt.startOffset
3540    // Adjust the start offset to end of ESP header
3541    // It is up to the Host or SA to further adjust it for the IV size
3542    add  s_pktCxt.startOffset,  s_pktCxt.startOffset, ESP_HEADER_LEN_BYTES
3543    ret
3544 #endif   
3545 #endif   
3547     .leave cdeScope
3548     .leave lut1Scope
3549     .leave pktScope
3550     .leave secScope
3552 // ***************************************************************************************
3553 // * FUNCTION PURPOSE: Parse a decoded ESP header
3554 // ***************************************************************************************
3555 // * DESCRIPTION: After (optional) authentication and decryption, the ESP header is
3556 // *              reparsed. the end offset must now point to the end of the ESP 
3557 // *              trailer.
3558 // *
3559 // *    On entry:
3560 // *            - the CDE points to the first byte after the ESP header
3561 // *            - r30.w0 has the function return address
3562 // *            - param.action has SUBS_ACTION_PARSE
3563 // *            - cdeCmdWd.operation has CDE_CMD_WINDOW_ADVNACE
3564 // *
3565 // *    On exit:
3566 // *            - the next action to take is in param.action
3567 // *            - the CDE points to the first byte after the ESP header
3568 // *            - cdeCmdWd.operation has CDE_CMD_WINDOW_ADVANCE
3569 // *            - endOffset is adjusted by the size of ESP Trail
3570 // *
3571 // *   Register Usage:  
3572 // * 
3573 // *   R0:    scratch
3574 // *   R1:    
3575 // *   R2:    
3576 // *   R3:              
3577 // *   R4:    |  CDE commands     -  cdeScope
3578 // *   R5:    |                   -
3579 // *   R6:        |                                      
3580 // *   R7:        |                                      
3581 // *   R8:        |                                      
3582 // *   R9:        |  
3583 // *   R10:       |
3584 // *   R11:       |
3585 // *   R12:       |
3586 // *   R13:       |
3587 // *   R14:          |                                          
3588 // *   R15:          |  extended packet dewscriptor                                        
3589 // *   R16:          |                                          
3590 // *   R17:          |  
3591 // *   R18:          |   
3592 // *   R19:             |
3593 // *   R20:             |
3594 // *   R21:             |
3595 // *   R22:     |     
3596 // *   R23:     |  Packet context - pktScope   
3597 // *   R24:     |
3598 // *   R25:     |
3599 // *   R26:     |
3600 // *   R27:     |
3601 // *   R28:  
3602 // *   R29:  c1RunContext (s_runCxt)                                -  Global Scope
3603 // *   R30:  w2-param.action  w0-function return address            -
3604 // *   R31:  System Flags (s_flags)                                 -
3605 // *
3606 // *
3607 // **************************************************************************************/
3609     .using cdeScope
3610     .using pktScope
3612 f_c1ParseEspDec:
3613    
3614 #ifdef PASS_PROC_POST_IPSEC  
3615    
3616    // Read in the padlen (r0.b1) and protocol (r0.b0) fields at the end of the packet
3617    // Note: It should be the absolute offset including Packet descriptor, PS Info.
3618    // sub    r0.w2,   s_pktCxt.endOffset,  s_pktCxt.startOffset
3619    // Note: Both the size of packet descriptor and PS Info are constants 
3620    //       We may need to enhance it for more general cases
3621    xin    XID_PINFO_A,  s_pktExtDescr,  SIZE(s_pktExtDescr)  
3622    add    r0.w2,   s_pktCxt.endOffset,  (32+32-2 )  
3623    qbbc l_c1ParseEspDec_1, s_runCxt.flag3.t_eoamEn   
3624      add  r0.w2,   r0.w2, 8      
3625 l_c1ParseEspDec_1:    
3626    sub    r0.w2,   r0.w2, s_pktExtDescr.mopLength
3627                
3628    // wait for the sideband data to be ready 
3629    wbc    s_flags.info.tStatus_CDEBusy
3630    lbco   r0.w0,   cCdeInPkt,           r0.w2,                  2
3632    // Note: the s_pktCtx.startOffset should already point to the next header 
3633    sub  s_pktCxt.endOffset,    s_pktCxt.endOffset,   r0.b1
3634    sub  s_pktCxt.endOffset,    s_pktCxt.endOffset,   2
3635    
3636    // TBD: Perform the standard pending check
3637    // sub   r0.w2,  r0.w2, r0.b1
3638    
3639    // Get the next header type and action from the protocol field
3640    lbco   r1.b0,             PAMEM_CONST_IP_PROTO,  r0.b0,   1
3641    and    s_next.Hdr,        r1.b0,                 0x3f
3642    
3643    // Always contiune to parse the next header 
3644    mov      s_param.action,    SUBS_ACTION_PARSE 
3645    
3646 #ifdef PASS_PROC_FIREWALL    
3647     // Adjust and  the next header type and startOffset for next stage lookup
3648     and  s_pktCxt.eId_portNum_nextHdr.b0, s_pktCxt.eId_portNum_nextHdr.b0,  0xc0
3649     or   s_pktCxt.eId_portNum_nextHdr.b0, s_pktCxt.eId_portNum_nextHdr.b0,  s_next.Hdr
3650     // The stratOffset does not change
3651     //mov  s_pktCxt5.temp.b1, s_pktCxt.startOffset  
3652 #endif    
3653    
3655    ret
3656    
3657 #endif   
3659     .leave cdeScope
3660     .leave pktScope
3663 // ************************************************************************************
3664 // * FUNCTION PURPOSE: Process an AH header
3665 // ************************************************************************************
3666 // * DESCRIPTION: The authentication header is parsed. The length field could have 0,
3667 // *              which means the authentication length is not known, so the length
3668 // *              field is not updated at all.
3669 // *    On entry:
3670 // *            - the CDE is at the start of the AH header
3671 // *            - r30.w0 has the function return address
3672 // *            - param.action has SUBS_ACTION_PARSE
3673 // *            - cdeCmdWd.operation has CDE_CMD_WINDOW_ADVNACE
3674 // *
3675 // *    On exit:
3676 // *            - param.action has SUBS_ACTION_LOOKUP
3677 // *            - cdeCmdWd.operation has CDE_CMD_WINDOW_ADVANCE
3678 // *            - CDE View window does not move
3679 // *            - startOffset is adjusted by the size of AH Header
3680 // *
3681 // *   Register Usage:  
3682 // * 
3683 // *   R0:    scratch
3684 // *   R1:    
3685 // *   R2:    
3686 // *   R3:              b0 - next header type  - pktScope
3687 // *   R4:    |  CDE commands     -  cdeScope
3688 // *   R5:    |                   -
3689 // *   R6:        |                                  |  AH header
3690 // *   R7:        |                                  |  
3691 // *   R8:        |                                  |  
3692 // *   R9:        |  LUT1 View   - lut1Scope
3693 // *   R10:       |                                     | 
3694 // *   R11:       |                                     |  LUT1 View3
3695 // *   R12:       |                                     |
3696 // *   R13:       |                                     |
3697 // *   R14:          |                                          
3698 // *   R15:          |                                          
3699 // *   R16:          |                                          
3700 // *   R17:          |  LUT1 View2  - lut1Scope                 
3701 // *   R18:          |
3702 // *   R19:          |
3703 // *   R20:          |
3704 // *   R21:          |
3705 // *   R22:     |     
3706 // *   R23:     |  Packet context - pktScope   
3707 // *   R24:     |
3708 // *   R25:     |
3709 // *   R26:     |
3710 // *   R27:     |
3711 // *   R28:  
3712 // *   R29:  c1RunContext (s_runCxt)                                -  Global Scope
3713 // *   R30:  w2-param.action  w0-function return address            -
3714 // *   R31:  System Flags (s_flags)                                 -
3715 // *
3716 // *
3717 // ************************************************************************************
3719     .using cdeScope
3720     .using pktScope
3721     .using lut1Scope
3722     .using secScope
3724 f_c1ParseAuth:
3726 #ifdef PASS_PROC_FIREWALL
3727     // Terminate parsing
3728     mov s_param.action,        SUBS_ACTION_LOOKUP
3729     ret
3730 #endif
3733 #ifdef PASS_PROC_IPSEC  
3735 #ifdef PASS_SKIP_IPSEC
3736    xin  XID_LUT1V3,   s_l1View3bIpsec, SIZE(s_l1View3bIpsec)
3737    set  s_l1View3bIpsec.pktFlags.fIpsec
3738    xout XID_LUT1V3,   s_l1View3bIpsec, SIZE(s_l1View3bIpsec)
3739    set  s_pktCxt.hdrBitmask.SUBS_PA_BIT_HEADER_AUTH
3740    mov  s_param.action, SUBS_ACTION_LOOKUP
3741    ret
3742 #endif
3744    xin  XID_CDEDATA, s_ah,  SIZE(s_ah)
3746    // Populate the lookup views
3747    zero &s_l1View3bIpsec,   SIZE(s_l1View3bIpsec)
3748    mov  s_l1View3bIpsec.spi,    s_ah.spi
3749    set  s_l1View3bIpsec.pktFlags.fIpsecAh
3750    set  s_l1View3bIpsec.pktType.fL3PktTypeIpsec
3751    
3752 #ifndef PASS_PROC_FIREWALL
3753   // Check to see whether virtual link is used 
3754   qbbs l_c1ParseAuth_vLink, s_pktCxt.flags.t_flag_use_vlink
3755     // The previous lookup PDSP ID and LUT1 index is stored in the srcVC field
3756     mov  s_l1View3bIpsec.srcVC,  s_pktCxt.phyLink
3757     jmp  l_c1ParseAuth_link_end
3758 l_c1ParseAuth_vLink:    
3759     mov  s_l1View3bIpsec.srcVC,  s_pktCxt.vlanPri_vLink
3760     and  s_l1View3bIpsec.srcVC.b1, s_l1View3bIpsec.srcVC.b1, NOT_PKT_VLAN_PRI_MASK
3761     // Clear virtual link enable for further look ups
3762     clr s_pktCxt.flags.t_flag_use_vlink
3764 l_c1ParseAuth_link_end:
3765 #else
3766     mov  s_l1View3bIpsec.srcVC,  s_pktCxt.phyLink
3767 #endif   
3768    
3769    xout XID_LUT1V3,   s_l1View3bIpsec, SIZE(s_l1View3bIpsec)
3771    mov  s_pktCxt.espAhOffset,  s_pktCxt.startOffset
3772    set  s_pktCxt.hdrBitmask.SUBS_PA_BIT_HEADER_AUTH
3774    // Handle length. the length field in AH is the authentication length, in 32
3775    // bit values, -2. Since the AH header length is 3 32 bit words the 
3776    // addition of 1 to the length field is used.
3777    add  r0.w0,               s_ah.len,              2
3778    lsl  r0.w0,               r0.w0,                 2
3779    add  s_pktCxt.startOffset,  s_pktCxt.startOffset,  r0.w0
3781 l_c1ParseAuth0:
3783    // Get the next header type and action from the protocol field,
3784    // but the action must be overridden to force a lookup
3785    lbco   r1.b0,             PAMEM_CONST_IP_PROTO,  s_ah.proto,   1
3786    and    s_next.Hdr,        r1.b0,                 0x3f
3787    mov    s_param.action,    SUBS_ACTION_LOOKUP
3789    ret
3790    
3791 #endif   
3793     .leave cdeScope
3794     .leave pktScope
3795     .leave lut1Scope
3796     .leave secScope
3797     
3798 // **************************************************************************************
3799 // * FUNCTION PURPOSE: Parse an SCTP header
3800 // **************************************************************************************
3801 // * DESCRIPTION: The SCTP port number is added to the LUT. There is no information
3802 // *              available about the next header
3803 // *              
3804 // *              The offset is not updated
3805 // *
3806 // *    On entry:
3807 // *            - the CDE is at the start of the SCTP header
3808 // *            - r30.w0 has the function return address
3809 // *            - param.action has SUBS_ACTION_PARSE
3810 // *            - cdeCmdWd.operation has CDE_CMD_WINDOW_ADVNACE
3811 // *
3812 // *    On exit:
3813 // *            - param.action has SUBS_ACTION_LOOKUP
3814 // *            - cdeCmdWd.operation has CDE_CMD_WINDOW_ADVANCE
3815 // *            - CDE View window does not move
3816 // *            - startOffset is adjusted by the size of SCTP header
3817 // *            - s_next.Hdr is set as PA_HDR_UNKNOWN
3818 // *
3819 // *   Register Usage:  
3820 // * 
3821 // *   R0:    scratch
3822 // *   R1:    
3823 // *   R2:    
3824 // *   R3:              b0 - next header type  - pktScope
3825 // *   R4:    |  CDE commands     -  cdeScope
3826 // *   R5:    |                   -
3827 // *   R5:    |                   -
3828 // *   R6:        |                                  |  IPv6 header & option headers
3829 // *   R7:        |                                  |  
3830 // *   R8:        |                                    
3831 // *   R9:        |  LUT1 View   - lut1Scope
3832 // *   R10:       |                                     | 
3833 // *   R11:       |                                     |  LUT1 View3
3834 // *   R12:       |                                     |
3835 // *   R13:       |                                     |
3836 // *   R14:          |  SCTP Header    |  Extended Packet Header                                    
3837 // *   R15:          |                 |                         
3838 // *   R16:          |                 |                         
3839 // *   R17:             | not used     |             
3840 // *   R18:             |              |
3841 // *   R19:             |
3842 // *   R20:           | Checksum contrl block
3843 // *   R21:           |
3844 // *   R22:     |     
3845 // *   R23:     |  Packet context - pktScope   
3846 // *   R24:     |
3847 // *   R25:     |
3848 // *   R26:     |
3849 // *   R27:     |
3850 // *   R28:  
3851 // *   R29:  c1RunContext (s_runCxt)                                -  Global Scope
3852 // *   R30:  w2-param.action  w0-function return address            -
3853 // *   R31:  System Flags (s_flags)                                 -
3854 // *
3855 // *
3856 // **************************************************************************************
3858     .using cdeScope
3859     .using lut1Scope
3860     .using pktScope
3861     .using sctpScope
3863 f_c1ParseSctp:
3865 #ifdef PASS_PROC_FIREWALL
3866     // Read in the SCTP header 
3867     xin  XID_CDEDATA,  s_sctp,    SIZE(s_sctp)
3868    
3869     mov  s_l1View3bIpv6.dstPort,    s_sctp.dst    
3870     mov  s_l1View3bIpv6.srcPort,    s_sctp.src   
3872     xout XID_LUT1V3,  s_l1View3bIpv6.srcPort,  SIZE(s_l1View3bIpv6.srcPort) + SIZE(s_l1View3bIpv6.dstPort)
3874     mov s_param.action, SUBS_ACTION_LOOKUP
3875     
3876     ret
3877     
3878 #else    
3880 #ifdef PASS_PROC_L3
3882    // Read in the SCTP header 
3883    xin  XID_CDEDATA,  s_sctp,    SIZE(s_sctp)
3884    
3885    // Save and update View3
3886    xin XID_LUT1V3,        s_l1View3bIpv6.pktFlags,   SIZE(s_l1View3bIpv6.pktFlags)
3887    set  s_l1View3bIpv6.pktFlags.fSctp
3888    xout XID_LUT1V3,       s_l1View3bIpv6.pktFlags,   SIZE(s_l1View3bIpv6.pktFlags)
3889    
3890    mov  s_l1View3bIpv6.dstPort, s_sctp.dst
3891    xout XID_LUT1V3,     s_l1View3bIpv6.dstPort, SIZE(s_l1View3bIpv6.dstPort)
3892    
3893    mov  s_next.hdr,     PA_HDR_UNKNOWN
3894    mov  s_param.action, SUBS_ACTION_LOOKUP
3895    
3896    // Mark SCTP
3897    set  s_pktCxt.hdrBitmask.SUBS_PA_BIT_HEADER_SCTP
3898    
3899    // Store, clear checksum and Issue CRC checksum command only if enabled
3900    qbbc  l_c1ParseSctp_end, s_runCxt.flags.t_sctpChksum
3901    
3902    mov  s_crcCxt.crc, s_sctp.chksum
3903    add  s_crcCxt.offset, s_pktCxt.startOffset, OFFSET(s_sctp.chksum)
3904    mov  s_crcCxt.crcSize,  4
3905      
3906    zero &s_sctp.chksum, SIZE(s_sctp.chksum)
3907    xout  XID_CDEDATA,  s_sctp.chksum,  SIZE(s_sctp.chksum)
3908    
3909    // Pop the extended info and issue CRC operation
3910    xin   XID_PINFO_A,   s_pktExtDescr,  SIZE(s_pktExtDescr)
3911    
3912    set   s_pktExtDescr.flags.fDoCRC
3913    sub   s_pktExtDescr.crcLength,   s_pktCxt.endOffset,         s_pktCxt.startOffset 
3914    mov   s_pktExtDescr.crcOffset,   s_pktCxt.startOffset
3915    mov32 s_pktExtDescr.crcValue,    0xFFFFFFFF   
3916    
3917    xout  XID_PINFO_A,   s_pktExtDescr,  SIZE(s_pktExtDescr)
3918    
3919    // Set flag to indicate that CRC checksum verification is required
3920    // Append the CRC information to the end of pkt context in the PS Info area
3921    set  s_pktCxt.flags.t_flag_crc_verify
3922    
3923    sbco s_crcCxt,  cCdeOutPkt, SIZE(s_pktDescr) + SIZE(s_pktCxt), SIZE(s_crcCxt) 
3925 l_c1ParseSctp_end:
3926    // Adjust the start offset to end of SCTP header
3927    mov  s_pktCxt.l4Offset,     s_pktCxt.startOffset
3928    add  s_pktCxt.startOffset,  s_pktCxt.startOffset, SCTP_HEADER_LEN_BYTES
3929    ret
3930    
3931 #endif   
3932 #endif
3934     .leave cdeScope
3935     .leave lut1Scope
3936     .leave pktScope
3937     .leave sctpScope
3938     
3939 // * FUNCTION PURPOSE: Parse a UDP header
3940 // **********************************************************************************************
3941 // * DESCRIPTION: The UDP dest port is added to the LUT and the search is initiated
3942 // *
3943 // *    On entry:
3944 // *            - the CDE is at the start of the UDP header
3945 // *            - r30.w0 has the function return address
3946 // *            - param.action has SUBS_ACTION_PARSE
3947 // *            - cdeCmdWd.operation has CDE_CMD_WINDOW_ADVNACE
3948 // *
3949 // *    On exit:
3950 // *            - param.action has SUBS_ACTION_LOOKUP or SUBS_ACTION_PARSE (GTPU only)
3951 // *            - cdeCmdWd.operation has CDE_CMD_WINDOW_ADVANCE
3952 // *            - TBD: the CDE is at the first byte after the UDP header
3953 // *            - TBD: startOffset is adjusted by the UDP header size 
3954 // *            - TBD: s_next.Hdr is set as PA_HDR_UNKNOWN if non-GTPU, otherwise, it is set to PA_HDR_GTPU
3955 // *            
3956 // *   Register Usage:  
3957 // * 
3958 // *   R0:    scratch
3959 // *   R1:    scratch
3960 // *   R2:    scratch
3961 // *   R3:    scratch          
3962 // *   R4:    |  CDE commands     -  cdeScope
3963 // *   R5:    |                   -
3964 // *   R6:        |                                      | UDP header 
3965 // *   R7:        |                                      |  
3966 // *   R8:        |                                      |  
3967 // *   R9:        |  LUT1 View   - lut1Scope             |
3968 // *   R10:       |                                     |
3969 // *   R11:       |                                     |  LUT1 View1
3970 // *   R12:       |                                     |
3971 // *   R13:       |                                     |
3972 // *   R14:          |  (packet extended descriptor)                                        
3973 // *   R15:          |                                          
3974 // *   R16:          |                                          
3975 // *   R17:          |  LUT1 View  - lut1Scope                 
3976 // *   R18:          |                                  |
3977 // *   R19:          |                                  |  LUT1 View3
3978 // *   R20:          |                                  |
3979 // *   R21:          |                                  |
3980 // *   R22:     |     
3981 // *   R23:     |  Packet context - pktScope   
3982 // *   R24:     |
3983 // *   R25:     |
3984 // *   R26:     |
3985 // *   R27:     |
3986 // *   R28:  
3987 // *   R29:  c1RunContext (s_runCxt)                                -  Global Scope
3988 // *   R30:  w2-param.action  w0-function return address            -
3989 // *   R31:  System Flags (s_flags)                                 -
3990 // *
3991 // ***********************************************************************************************
3993     .using cdeScope
3994     .using pktScope
3995     .using udpScope
3996     .using lut1Scope
3998 f_c1ParseUdp:
4000 #ifdef PASS_PROC_LUT1_L4
4001     // Read in the UDP header. Do not advance since there could be a switch to
4002     // custom mode
4003     xin  XID_CDEDATA, s_udp,  SIZE(s_udp)
4004     
4005     mov  s_l1View3dIpv4.dstPort,    s_udp.dst    
4006     mov  s_l1View3dIpv4.srcPort,    s_udp.src   
4008     xout XID_LUT1V3,  s_l1View3dIpv4.srcPort,  SIZE(s_l1View3dIpv4.srcPort) + SIZE(s_l1View3dIpv4.dstPort)
4010     mov s_param.action, SUBS_ACTION_LOOKUP
4012   // When EOAM feature is enabled, check if IP processing is already done
4013   // If done, there is no action
4014   // otherwise initiate a call to have Outer IP for ACL
4015   qbbc  l_c1ParseUdp_1, s_runCxt.flag3.t_eoamEn
4016   
4017 #ifndef PASS_PROC_IP_REASSEM  
4018     // is IP processing done in this stage?
4019     qbbs l_c1ParseUdp_1, s_pktCxt.flags.t_flag_ipProc
4020       // Jmp to submit outer IP information
4021       jmp  f_c1ParseIpForEoamAcl
4023 l_c1ParseUdp_1: 
4024     // Clear the information
4025     clr  s_pktCxt.flags.t_flag_ipProc
4026 #endif
4027     ret
4028     
4029 #else 
4031 #ifdef PASS_PROC_IPSEC_NAT_T
4032     
4033     qbbc  l_c1ParseUdpNatT_end,  s_runCxt.flag2.t_IpsecNatTDetEn
4035     // Read in the UDP header. Do not advance since there could be a switch to
4036     // custom mode
4037     xin  XID_CDEDATA, s_udp,  SIZE(s_udp) + SIZE(s_ipsecNatT)
4038     
4039     // A switch to IPSEC_NAT_T mode is made based on destination or source UDP port
4040     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)
4041     qbeq  l_c1ParseUdpNatT_1,   s_udp.dst,  r0.w0 
4042     qbne  l_c1ParseUdpNatT_end, s_udp.src,  r0.w0
4044 l_c1ParseUdpNatT_1:
4045        // IPSEC NAT_T parsing
4046        // Keepalive packet: UDP length == 9, payload = 0xFF
4047        // Control packet: UDP length > 12 SPI = 0
4048        // IPSEC Data Packet: UDP length > 12 SPI != 0
4049        // Error Packet UDP length <= 12
4050        
4051        // Common Operations for all NAT_T packet
4052        set s_pktCxt.hdrBitmask.SUBS_PA_BIT_HEADER_IPSEC_NAT_T
4053        mov s_next.Hdr,  PA_HDR_UNKNOWN
4054        and s_pktCxt.eId_portNum_nextHdr.b1,  s_pktCxt.eId_portNum_nextHdr.b1,   NOT_PKT_EIDX_MASK
4055        mov s_param.action, SUBS_ACTION_EXIT
4057        qbge l_c1ParseUdpNatT_3, s_udp.len, SIZE(s_udp) + SIZE(s_ipsecNatT) 
4058             qbeq l_c1ParseUdpNatT_2, s_ipsecNatT.spi, 0    
4059                 // IPSEC Data packet
4060                 mov s_next.Hdr,  PA_HDR_ESP
4061                 mov s_param.action, SUBS_ACTION_PARSE
4062                 
4063                 //  Advance past the UDP header.
4064                 mov   s_cdeCmdWd.operation,   CDE_CMD_WINDOW_ADVANCE
4065                 mov   s_cdeCmdWd.byteCount,   SIZE(s_udp)
4066                 xout  XID_CDECTRL,    s_cdeCmdWd,   SIZE(s_cdeCmdWd)
4067                 
4068                 add   s_pktCxt.startOffset, s_pktCxt.startOffset, SIZE(s_udp)
4069                 
4070                 ret   
4071        
4072 l_c1ParseUdpNatT_2: 
4073                 // NAT_T Control packet      
4074                 or  s_pktCxt.eId_portNum_nextHdr.b1,  s_pktCxt.eId_portNum_nextHdr.b1,  EROUTE_NAT_T_CTRL << PKT_EIDX_SHIFT
4075                 ret
4076                 
4077 l_c1ParseUdpNatT_3:
4078             qbne l_c1ParseUdpNatT_4,    s_udp.len,          SIZE(s_udp) + SIZE(s_ipsecNatT2)
4079             qbne l_c1ParseUdpNatT_4,    s_ipsecNatT2.data,  0xFF
4080                 // NAT-T Keepalive Packet
4081                 or  s_pktCxt.eId_portNum_nextHdr.b1,  s_pktCxt.eId_portNum_nextHdr.b1,  EROUTE_NAT_T_KEEPALIVE << PKT_EIDX_SHIFT
4082                 ret
4083        
4084 l_c1ParseUdpNatT_4:       
4085                 // NAT-T Error Packet
4086                 or  s_pktCxt.eId_portNum_nextHdr.b1,  s_pktCxt.eId_portNum_nextHdr.b1,  EROUTE_NAT_T_FAIL << PKT_EIDX_SHIFT
4087                 ret
4088                 
4089 l_c1ParseUdpNatT_end:
4090     // normal UDP packets are sent to Ingress4 for L4 classification
4091     mov s_param.action,  SUBS_ACTION_FWPKT3
4092     ret
4093     
4094 #endif    
4095    
4096 #endif
4097     .leave cdeScope
4098     .leave pktScope
4099     .leave udpScope
4100     .leave lut1Scope
4103 // **********************************************************************************************
4104 // * FUNCTION PURPOSE: Parse a UDP-Lite header
4105 // **********************************************************************************************
4106 // * DESCRIPTION: The UDP-Lite header is parsed
4107 // *
4108 // *    On entry:
4109 // *            - the CDE is at the start of the UDP header
4110 // *            - r30.w0 has the function return address
4111 // *            - param.action has SUBS_ACTION_PARSE
4112 // *            - cdeCmdWd.operation has CDE_CMD_WINDOW_ADVNACE
4113 // *
4114 // *    On exit:
4115 // *            - param.action has SUBS_ACTION_LOOKUP or SUBS_ACTION_PARSE (GTPU only)
4116 // *            - cdeCmdWd.operation has CDE_CMD_WINDOW_ADVANCE
4117 // *            - the CDE is at the first byte after the UDP-lite header
4118 // *            - startOffset is adjusted by the UDP header size 
4119 // *            - s_next.Hdr is set as PA_HDR_UNKNOWN if non-GTPU, otherwise, it is set to PA_HDR_GTPU
4120 // *   Register Usage:  
4121 // * 
4122 // *   R0:    scratch
4123 // *   R1:    scratch
4124 // *   R2:    scratch
4125 // *   R3:    scratch          
4126 // *   R4:    |  CDE commands     -  cdeScope
4127 // *   R5:    |                   -
4128 // *   R6:        |                                      | UDP-Lite Header 
4129 // *   R7:        |                                      |  
4130 // *   R8:        |                                      |  
4131 // *   R9:        |  LUT1 View   - lut1Scope             |
4132 // *   R10:       |                                     |
4133 // *   R11:       |                                     |  LUT1 View1
4134 // *   R12:       |                                     |
4135 // *   R13:       |                                     |
4136 // *   R14:          |  (packet extended descriptor)                                        
4137 // *   R15:          |                                          
4138 // *   R16:          |                                          
4139 // *   R17:          |  LUT1 View  - lut1Scope                 
4140 // *   R18:          |                                  |
4141 // *   R19:          |                                  |  LUT1 View3
4142 // *   R20:          |                                  |
4143 // *   R21:          |                                  |
4144 // *   R22:     |     
4145 // *   R23:     |  Packet context - pktScope   
4146 // *   R24:     |
4147 // *   R25:     |
4148 // *   R26:     |
4149 // *   R27:     |
4150 // *   R28:  
4151 // *   R29:  c1RunContext (s_runCxt)                                -  Global Scope
4152 // *   R30:  w2-param.action  w0-function return address            -
4153 // *   R31:  System Flags (s_flags)                                 -
4154 // *
4155 // ************************************************************************************************
4156     .using cdeScope
4157     .using pktScope
4158     .using udpScope
4159     .using lut1Scope
4161 f_c1ParseUdpLite:
4163 #ifdef PASS_PROC_LUT1_L4
4165     // Read in the UDP lite header. Do not advance since there could be a switch to
4166     // custom mode
4167     xin  XID_CDEDATA, s_udpLite,  SIZE(s_udpLite)
4169 l_c1ParseUdpLite1:
4171     // Do the lookup
4172     mov  s_l1View3dIpv4.dstPort,    s_udpLite.dst    
4173     mov  s_l1View3dIpv4.srcPort,    s_udpLite.src   
4175     xout XID_LUT1V3,  s_l1View3dIpv4.srcPort,  SIZE(s_l1View3dIpv4.srcPort) + SIZE(s_l1View3dIpv4.dstPort)
4176     
4177     mov s_param.action, SUBS_ACTION_LOOKUP
4178 #ifndef PASS_PROC_IP_REASSEM    
4179   // When EOAM feature is enabled, check if IP processing is already done
4180   // If done, there is no action
4181   // otherwise initiate a call to have Outer IP for ACL
4182   qbbc  l_c1ParseUdpLite_1, s_runCxt.flag3.t_eoamEn
4183     // is IP processing done?
4184     qbbs l_c1ParseUdpLite_1, s_pktCxt.flags.t_flag_ipProc
4185       // Jmp to submit outer IP information
4186       jmp  f_c1ParseIpForEoamAcl
4187 l_c1ParseUdpLite_1:     
4188     // Clear the information
4189     clr  s_pktCxt.flags.t_flag_ipProc
4190 #endif
4191     ret
4193 #endif
4195     .leave cdeScope
4196     .leave pktScope
4197     .leave udpScope
4198     .leave lut1Scope
4201 // ***********************************************************************************
4202 // * FUNCTION PURPOSE: Process a TCP header
4203 // ***********************************************************************************
4204 // * DESCRIPTION: The TCP header is parsed and a LUT2 initiated
4205 // *
4206 // *   Register Usage:  
4207 // * 
4208 // *   R0:    scratch
4209 // *   R1:    scratch
4210 // *   R2:    scratch
4211 // *   R3:    scratch          
4212 // *   R4:    |  CDE commands     -  cdeScope
4213 // *   R5:    |                   -
4214 // *   R6:        |                                      | TCP header 
4215 // *   R7:        |                                      |  
4216 // *   R8:        |                                      |  
4217 // *   R9:        |  LUT1 View   - lut1Scope             |
4218 // *   R10:       |                                     || 
4219 // *   R11:       |                                     |  LUT1 View1
4220 // *   R12:       |                                     |
4221 // *   R13:       |                                     |
4222 // *   R14:          |  (packet extended descriptor)                                        
4223 // *   R15:          |                                          
4224 // *   R16:          |                                          
4225 // *   R17:          |  LUT1 View  - lut1Scope                 
4226 // *   R18:          |                                  |
4227 // *   R19:          |                                  |  LUT1 View3
4228 // *   R20:          |                                  |
4229 // *   R21:          |                                  |
4230 // *   R22:     |     
4231 // *   R23:     |  Packet context - pktScope   
4232 // *   R24:     |
4233 // *   R25:     |
4234 // *   R26:     |
4235 // *   R27:     |
4236 // *   R28:  
4237 // *   R29:  c1RunContext (s_runCxt)                                -  Global Scope
4238 // *   R30:  w2-param.action  w0-function return address            -
4239 // *   R31:  System Flags (s_flags)                                 -
4240 // *
4241 // *************************************************************************************
4243     .using cdeScope
4244     .using pktScope
4245     .using tcpScope
4246     .using lut1Scope
4248 f_c1ParseTcp:
4250 #ifdef PASS_PROC_LUT1_L4
4252     // Read in the TCP header
4253     xin  XID_CDEDATA,  s_tcp,  SIZE(s_tcp)
4254     
4255     // Firewall-specific matching of type
4257     // Configure and initiate the lookup
4258     mov  s_l1View3dIpv4.dstPort,    s_tcp.dst    
4259     mov  s_l1View3dIpv4.srcPort,    s_tcp.src   
4260     xout XID_LUT1V3,  s_l1View3dIpv4.srcPort,  SIZE(s_l1View3dIpv4.srcPort) + SIZE(s_l1View3dIpv4.dstPort)
4262     mov  s_param.action,  SUBS_ACTION_LOOKUP
4264 #ifndef PASS_PROC_IP_REASSEM    
4265   // When EOAM feature is enabled, check if IP processing is already done
4266   // If done, there is no action
4267   // otherwise initiate a call to have Outer IP for ACL
4268   qbbc  l_c1ParseTcp_1, s_runCxt.flag3.t_eoamEn
4269     // is IP processing done?
4270     qbbs l_c1ParseTcp_1, s_pktCxt.flags.t_flag_ipProc
4271       // Jmp to submit outer IP information
4272       jmp  f_c1ParseIpForEoamAcl
4274 l_c1ParseTcp_1:   
4275     // Clear the information
4276     clr  s_pktCxt.flags.t_flag_ipProc
4277 #endif
4278     ret
4279     
4280 #endif    
4282     .leave cdeScope
4283     .leave pktScope
4284     .leave tcpScope
4285     .leave lut1Scope
4287 // ************************************************************************************
4288 // * FUNCTION PURPOSE: Unkown header
4289 // ************************************************************************************
4290 // * DESCRIPTION:
4291 // *
4292 // *   Register Usage:  
4293 // * 
4294 // *   R0:    scratch
4295 // *   R1:    
4296 // *   R2:    
4297 // *   R3:              b0 - next header type  - pktScope
4298 // *   R4:    |  CDE commands     -  cdeScope
4299 // *   R5:    |                   -
4300 // *   R6:        |                                      
4301 // *   R7:        |                                      
4302 // *   R8:        |                                      
4303 // *   R9:        |  LUT1 View1   - lut1Scope
4304 // *   R10:       |
4305 // *   R11:       |
4306 // *   R12:       |
4307 // *   R13:       |
4308 // *   R14:          |                                          
4309 // *   R15:          |                                          
4310 // *   R16:          |                                          
4311 // *   R17:          |  LUT1 View2  - lut1Scope                 
4312 // *   R18:          |
4313 // *   R19:          |
4314 // *   R20:          |
4315 // *   R21:          |
4316 // *   R22:     |     
4317 // *   R23:     |  Packet context - pktScope   
4318 // *   R24:     |
4319 // *   R25:     |
4320 // *   R26:     |
4321 // *   R27:     |
4322 // *   R28:  
4323 // *   R29:  c1RunContext (s_runCxt)                                -  Global Scope
4324 // *   R30:  w2-param.action  w0-function return address            -
4325 // *   R31:  System Flags (s_flags)                                 -
4326 // *
4327 // *
4328 // ************************************************************************************
4330     .using pktScope
4332 f_c1ParseUnkn:
4334 #ifdef PASS_PROC_FIREWALL
4335     // Terminate parsing
4336     mov s_param.action,        SUBS_ACTION_LOOKUP
4337     ret
4338 #endif
4340    mov s_stats.value,  PA_STATS_UPDATE_REQ | PA_STATS_PARSE_FAIL
4342    and  s_pktCxt.eId_portNum_nextHdr.b1,  s_pktCxt.eId_portNum_nextHdr.b1,   NOT_PKT_EIDX_MASK
4343    or   s_pktCxt.eId_portNum_nextHdr.b1,  s_pktCxt.eId_portNum_nextHdr.b1,   EROUTE_PARSE_FAIL << PKT_EIDX_SHIFT  
4345 c1pun1:
4346    mov s_param.action, SUBS_ACTION_EXIT
4347    ret
4348    
4349    
4350 #ifdef PASS_PROC_FIREWALL   
4351 fci_c1FirewallException:
4352     // Common processing for unsupported protocols 
4353     set s_runCxt.flags.t_failLookup
4354     mov s_param.action,         SUBS_ACTION_EXIT
4356     ret  
4357 #endif    
4359     .leave pktScope    
4360     
4361