xref: /freebsd/sys/contrib/ncsw/Peripherals/FM/Pcd/fm_manip.c (revision 02e9120893770924227138ba49df1edb3896112a)
1 /*
2  * Copyright 2008-2012 Freescale Semiconductor Inc.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are met:
6  *     * Redistributions of source code must retain the above copyright
7  *       notice, this list of conditions and the following disclaimer.
8  *     * Redistributions in binary form must reproduce the above copyright
9  *       notice, this list of conditions and the following disclaimer in the
10  *       documentation and/or other materials provided with the distribution.
11  *     * Neither the name of Freescale Semiconductor nor the
12  *       names of its contributors may be used to endorse or promote products
13  *       derived from this software without specific prior written permission.
14  *
15  *
16  * ALTERNATIVELY, this software may be distributed under the terms of the
17  * GNU General Public License ("GPL") as published by the Free Software
18  * Foundation, either version 2 of that License or (at your option) any
19  * later version.
20  *
21  * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
22  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
23  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
24  * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
25  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
26  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
27  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
28  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
30  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  */
32 
33 
34 /******************************************************************************
35  @File          fm_manip.c
36 
37  @Description   FM PCD manip ...
38  *//***************************************************************************/
39 #include "std_ext.h"
40 #include "error_ext.h"
41 #include "string_ext.h"
42 #include "debug_ext.h"
43 #include "fm_pcd_ext.h"
44 #include "fm_port_ext.h"
45 #include "fm_muram_ext.h"
46 #include "memcpy_ext.h"
47 
48 #include "fm_common.h"
49 #include "fm_hc.h"
50 #include "fm_manip.h"
51 
52 /****************************************/
53 /*       static functions               */
54 /****************************************/
55 static t_Handle GetManipInfo(t_FmPcdManip *p_Manip, e_ManipInfo manipInfo)
56 {
57     t_FmPcdManip *p_CurManip = p_Manip;
58 
59     if (!MANIP_IS_UNIFIED(p_Manip))
60         p_CurManip = p_Manip;
61     else
62     {
63         /* go to first unified */
64         while (MANIP_IS_UNIFIED_NON_FIRST(p_CurManip))
65             p_CurManip = p_CurManip->h_PrevManip;
66     }
67 
68     switch (manipInfo)
69     {
70         case (e_MANIP_HMCT):
71             return p_CurManip->p_Hmct;
72         case (e_MANIP_HMTD):
73             return p_CurManip->h_Ad;
74         case (e_MANIP_HANDLER_TABLE_OWNER):
75             return (t_Handle)p_CurManip;
76         default:
77             return NULL;
78     }
79 }
80 
81 static uint16_t GetHmctSize(t_FmPcdManip *p_Manip)
82 {
83     uint16_t size = 0;
84     t_FmPcdManip *p_CurManip = p_Manip;
85 
86     if (!MANIP_IS_UNIFIED(p_Manip))
87         return p_Manip->tableSize;
88 
89     /* accumulate sizes, starting with the first node */
90     while (MANIP_IS_UNIFIED_NON_FIRST(p_CurManip))
91         p_CurManip = p_CurManip->h_PrevManip;
92 
93     while (MANIP_IS_UNIFIED_NON_LAST(p_CurManip))
94     {
95         size += p_CurManip->tableSize;
96         p_CurManip = (t_FmPcdManip *)p_CurManip->h_NextManip;
97     }
98     size += p_CurManip->tableSize; /* add last size */
99 
100     return (size);
101 }
102 
103 static uint16_t GetDataSize(t_FmPcdManip *p_Manip)
104 {
105     uint16_t size = 0;
106     t_FmPcdManip *p_CurManip = p_Manip;
107 
108     if (!MANIP_IS_UNIFIED(p_Manip))
109         return p_Manip->dataSize;
110 
111     /* accumulate sizes, starting with the first node */
112     while (MANIP_IS_UNIFIED_NON_FIRST(p_CurManip))
113         p_CurManip = p_CurManip->h_PrevManip;
114 
115     while (MANIP_IS_UNIFIED_NON_LAST(p_CurManip))
116     {
117         size += p_CurManip->dataSize;
118         p_CurManip = (t_FmPcdManip *)p_CurManip->h_NextManip;
119     }
120     size += p_CurManip->dataSize; /* add last size */
121 
122     return (size);
123 }
124 
125 static t_Error CalculateTableSize(t_FmPcdManipParams *p_FmPcdManipParams,
126                                   uint16_t *p_TableSize, uint8_t *p_DataSize)
127 {
128     uint8_t localDataSize, remain, tableSize = 0, dataSize = 0;
129 
130     if (p_FmPcdManipParams->u.hdr.rmv)
131     {
132         switch (p_FmPcdManipParams->u.hdr.rmvParams.type)
133         {
134             case (e_FM_PCD_MANIP_RMV_GENERIC):
135                 tableSize += HMCD_BASIC_SIZE;
136                 break;
137             case (e_FM_PCD_MANIP_RMV_BY_HDR):
138                 switch (p_FmPcdManipParams->u.hdr.rmvParams.u.byHdr.type)
139                 {
140                     case (e_FM_PCD_MANIP_RMV_BY_HDR_SPECIFIC_L2):
141 #if (DPAA_VERSION >= 11)
142                     case (e_FM_PCD_MANIP_RMV_BY_HDR_CAPWAP):
143                     case (e_FM_PCD_MANIP_RMV_BY_HDR_FROM_START):
144 #endif /* (DPAA_VERSION >= 11) */
145                         tableSize += HMCD_BASIC_SIZE;
146                         break;
147                     default:
148                         RETURN_ERROR(MINOR, E_INVALID_SELECTION,
149                                      ("Unknown byHdr.type"));
150                 }
151                 break;
152             default:
153                 RETURN_ERROR(MINOR, E_INVALID_SELECTION,
154                              ("Unknown rmvParams.type"));
155         }
156     }
157 
158     if (p_FmPcdManipParams->u.hdr.insrt)
159     {
160         switch (p_FmPcdManipParams->u.hdr.insrtParams.type)
161         {
162             case (e_FM_PCD_MANIP_INSRT_GENERIC):
163                 remain =
164                         (uint8_t)(p_FmPcdManipParams->u.hdr.insrtParams.u.generic.size
165                                 % 4);
166                 if (remain)
167                     localDataSize =
168                             (uint8_t)(p_FmPcdManipParams->u.hdr.insrtParams.u.generic.size
169                                     + 4 - remain);
170                 else
171                     localDataSize =
172                             p_FmPcdManipParams->u.hdr.insrtParams.u.generic.size;
173                 tableSize += (uint8_t)(HMCD_BASIC_SIZE + localDataSize);
174                 break;
175             case (e_FM_PCD_MANIP_INSRT_BY_HDR):
176             {
177                 switch (p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.type)
178                 {
179 
180                     case (e_FM_PCD_MANIP_INSRT_BY_HDR_SPECIFIC_L2):
181                         tableSize += HMCD_BASIC_SIZE + HMCD_PTR_SIZE;
182                         switch (p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.specificL2Params.specificL2)
183                         {
184                             case (e_FM_PCD_MANIP_HDR_INSRT_MPLS):
185                             case (e_FM_PCD_MANIP_HDR_INSRT_PPPOE):
186                                 dataSize +=
187                                         p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.specificL2Params.size;
188                                 break;
189                             default:
190                                 RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
191                         }
192                         break;
193 #if (DPAA_VERSION >= 11)
194                     case (e_FM_PCD_MANIP_INSRT_BY_HDR_IP):
195                         tableSize +=
196                                 (HMCD_BASIC_SIZE + HMCD_PTR_SIZE
197                                         + HMCD_PARAM_SIZE
198                                         + p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.ipParams.insrt.size);
199                         dataSize += 2;
200                         break;
201 
202                     case (e_FM_PCD_MANIP_INSRT_BY_HDR_UDP):
203                     case (e_FM_PCD_MANIP_INSRT_BY_HDR_UDP_LITE):
204                         tableSize += (HMCD_BASIC_SIZE + HMCD_L4_HDR_SIZE);
205 
206                         break;
207 
208                     case (e_FM_PCD_MANIP_INSRT_BY_HDR_CAPWAP):
209                         tableSize +=
210                                 (HMCD_BASIC_SIZE
211                                         + p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.insrt.size);
212                         break;
213 #endif /* (DPAA_VERSION >= 11) */
214                     default:
215                         RETURN_ERROR(MINOR, E_INVALID_SELECTION,
216                                      ("Unknown byHdr.type"));
217                 }
218             }
219                 break;
220             default:
221                 RETURN_ERROR(MINOR, E_INVALID_SELECTION,
222                              ("Unknown insrtParams.type"));
223         }
224     }
225 
226     if (p_FmPcdManipParams->u.hdr.fieldUpdate)
227     {
228         switch (p_FmPcdManipParams->u.hdr.fieldUpdateParams.type)
229         {
230             case (e_FM_PCD_MANIP_HDR_FIELD_UPDATE_VLAN):
231                 tableSize += HMCD_BASIC_SIZE;
232                 if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.vlan.updateType
233                         == e_FM_PCD_MANIP_HDR_FIELD_UPDATE_DSCP_TO_VLAN)
234                 {
235                     tableSize += HMCD_PTR_SIZE;
236                     dataSize += DSCP_TO_VLAN_TABLE_SIZE;
237                 }
238                 break;
239             case (e_FM_PCD_MANIP_HDR_FIELD_UPDATE_IPV4):
240                 tableSize += HMCD_BASIC_SIZE;
241                 if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.validUpdates
242                         & HDR_MANIP_IPV4_ID)
243                 {
244                     tableSize += HMCD_PARAM_SIZE;
245                     dataSize += 2;
246                 }
247                 if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.validUpdates
248                         & HDR_MANIP_IPV4_SRC)
249                     tableSize += HMCD_IPV4_ADDR_SIZE;
250                 if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.validUpdates
251                         & HDR_MANIP_IPV4_DST)
252                     tableSize += HMCD_IPV4_ADDR_SIZE;
253                 break;
254             case (e_FM_PCD_MANIP_HDR_FIELD_UPDATE_IPV6):
255                 tableSize += HMCD_BASIC_SIZE;
256                 if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.validUpdates
257                         & HDR_MANIP_IPV6_SRC)
258                     tableSize += HMCD_IPV6_ADDR_SIZE;
259                 if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.validUpdates
260                         & HDR_MANIP_IPV6_DST)
261                     tableSize += HMCD_IPV6_ADDR_SIZE;
262                 break;
263             case (e_FM_PCD_MANIP_HDR_FIELD_UPDATE_TCP_UDP):
264                 if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.tcpUdp.validUpdates
265                         == HDR_MANIP_TCP_UDP_CHECKSUM)
266                     /* we implement this case with the update-checksum descriptor */
267                     tableSize += HMCD_BASIC_SIZE;
268                 else
269                     /* we implement this case with the TCP/UDP-update descriptor */
270                     tableSize += HMCD_BASIC_SIZE + HMCD_PARAM_SIZE;
271                 break;
272             default:
273                 RETURN_ERROR(MINOR, E_INVALID_SELECTION,
274                              ("Unknown fieldUpdateParams.type"));
275         }
276     }
277 
278     if (p_FmPcdManipParams->u.hdr.custom)
279     {
280         switch (p_FmPcdManipParams->u.hdr.customParams.type)
281         {
282             case (e_FM_PCD_MANIP_HDR_CUSTOM_IP_REPLACE):
283             {
284                 tableSize += HMCD_BASIC_SIZE + HMCD_PARAM_SIZE + HMCD_PARAM_SIZE;
285                 dataSize +=
286                         p_FmPcdManipParams->u.hdr.customParams.u.ipHdrReplace.hdrSize;
287                 if ((p_FmPcdManipParams->u.hdr.customParams.u.ipHdrReplace.replaceType
288                         == e_FM_PCD_MANIP_HDR_CUSTOM_REPLACE_IPV6_BY_IPV4)
289                         && (p_FmPcdManipParams->u.hdr.customParams.u.ipHdrReplace.updateIpv4Id))
290                     dataSize += 2;
291             }
292                 break;
293             case (e_FM_PCD_MANIP_HDR_CUSTOM_GEN_FIELD_REPLACE):
294                 tableSize += HMCD_BASIC_SIZE + HMCD_PARAM_SIZE;
295             break;
296             default:
297                 RETURN_ERROR(MINOR, E_INVALID_SELECTION,
298                              ("Unknown customParams.type"));
299         }
300     }
301 
302     *p_TableSize = tableSize;
303     *p_DataSize = dataSize;
304 
305     return E_OK;
306 }
307 
308 static t_Error GetPrOffsetByHeaderOrField(t_FmManipHdrInfo *p_HdrInfo,
309                                           uint8_t *parseArrayOffset)
310 {
311     e_NetHeaderType hdr = p_HdrInfo->hdr;
312     e_FmPcdHdrIndex hdrIndex = p_HdrInfo->hdrIndex;
313     bool byField = p_HdrInfo->byField;
314     t_FmPcdFields field;
315 
316     if (byField)
317         field = p_HdrInfo->fullField;
318 
319     if (byField)
320     {
321         switch (hdr)
322         {
323             case (HEADER_TYPE_ETH):
324                 switch (field.eth)
325                 {
326                     case (NET_HEADER_FIELD_ETH_TYPE):
327                         *parseArrayOffset = CC_PC_PR_ETYPE_LAST_OFFSET;
328                         break;
329                     default:
330                         RETURN_ERROR(
331                                 MAJOR,
332                                 E_NOT_SUPPORTED,
333                                 ("Header manipulation of the type Ethernet with this field not supported"));
334                 }
335                 break;
336             case (HEADER_TYPE_VLAN):
337                 switch (field.vlan)
338                 {
339                     case (NET_HEADER_FIELD_VLAN_TCI):
340                         if ((hdrIndex == e_FM_PCD_HDR_INDEX_NONE)
341                                 || (hdrIndex == e_FM_PCD_HDR_INDEX_1))
342                             *parseArrayOffset = CC_PC_PR_VLAN1_OFFSET;
343                         else
344                             if (hdrIndex == e_FM_PCD_HDR_INDEX_LAST)
345                                 *parseArrayOffset = CC_PC_PR_VLAN2_OFFSET;
346                         break;
347                     default:
348                         RETURN_ERROR(
349                                 MAJOR,
350                                 E_NOT_SUPPORTED,
351                                 ("Header manipulation of the type VLAN with this field not supported"));
352                 }
353                 break;
354             default:
355                 RETURN_ERROR(
356                         MAJOR,
357                         E_NOT_SUPPORTED,
358                         ("Header manipulation of this header by field not supported"));
359         }
360     }
361     else
362     {
363         switch (hdr)
364         {
365             case (HEADER_TYPE_ETH):
366                 *parseArrayOffset = (uint8_t)CC_PC_PR_ETH_OFFSET;
367                 break;
368             case (HEADER_TYPE_USER_DEFINED_SHIM1):
369                 *parseArrayOffset = (uint8_t)CC_PC_PR_USER_DEFINED_SHIM1_OFFSET;
370                 break;
371             case (HEADER_TYPE_USER_DEFINED_SHIM2):
372                 *parseArrayOffset = (uint8_t)CC_PC_PR_USER_DEFINED_SHIM2_OFFSET;
373                 break;
374             case (HEADER_TYPE_LLC_SNAP):
375                 *parseArrayOffset = CC_PC_PR_USER_LLC_SNAP_OFFSET;
376                 break;
377             case (HEADER_TYPE_PPPoE):
378                 *parseArrayOffset = CC_PC_PR_PPPOE_OFFSET;
379                 break;
380             case (HEADER_TYPE_MPLS):
381                 if ((hdrIndex == e_FM_PCD_HDR_INDEX_NONE)
382                         || (hdrIndex == e_FM_PCD_HDR_INDEX_1))
383                     *parseArrayOffset = CC_PC_PR_MPLS1_OFFSET;
384                 else
385                     if (hdrIndex == e_FM_PCD_HDR_INDEX_LAST)
386                         *parseArrayOffset = CC_PC_PR_MPLS_LAST_OFFSET;
387                 break;
388             case (HEADER_TYPE_IPv4):
389             case (HEADER_TYPE_IPv6):
390                 if ((hdrIndex == e_FM_PCD_HDR_INDEX_NONE)
391                         || (hdrIndex == e_FM_PCD_HDR_INDEX_1))
392                     *parseArrayOffset = CC_PC_PR_IP1_OFFSET;
393                 else
394                     if (hdrIndex == e_FM_PCD_HDR_INDEX_2)
395                         *parseArrayOffset = CC_PC_PR_IP_LAST_OFFSET;
396                 break;
397             case (HEADER_TYPE_MINENCAP):
398                 *parseArrayOffset = CC_PC_PR_MINENC_OFFSET;
399                 break;
400             case (HEADER_TYPE_GRE):
401                 *parseArrayOffset = CC_PC_PR_GRE_OFFSET;
402                 break;
403             case (HEADER_TYPE_TCP):
404             case (HEADER_TYPE_UDP):
405             case (HEADER_TYPE_IPSEC_AH):
406             case (HEADER_TYPE_IPSEC_ESP):
407             case (HEADER_TYPE_DCCP):
408             case (HEADER_TYPE_SCTP):
409                 *parseArrayOffset = CC_PC_PR_L4_OFFSET;
410                 break;
411             case (HEADER_TYPE_CAPWAP):
412             case (HEADER_TYPE_CAPWAP_DTLS):
413                 *parseArrayOffset = CC_PC_PR_NEXT_HEADER_OFFSET;
414                 break;
415             default:
416                 RETURN_ERROR(
417                         MAJOR,
418                         E_NOT_SUPPORTED,
419                         ("Header manipulation of this header is not supported"));
420         }
421     }
422     return E_OK;
423 }
424 
425 static t_Error BuildHmct(t_FmPcdManip *p_Manip,
426                          t_FmPcdManipParams *p_FmPcdManipParams,
427                          uint8_t *p_DestHmct, uint8_t *p_DestData, bool new)
428 {
429     uint32_t *p_TmpHmct = (uint32_t*)p_DestHmct, *p_LocalData;
430     uint32_t tmpReg = 0, *p_Last = NULL, tmp_ipv6_addr;
431     uint8_t remain, i, size = 0, origSize, *p_UsrData = NULL, *p_TmpData =
432             p_DestData;
433     t_Handle h_FmPcd = p_Manip->h_FmPcd;
434     uint8_t j = 0;
435 
436     if (p_FmPcdManipParams->u.hdr.rmv)
437     {
438         if (p_FmPcdManipParams->u.hdr.rmvParams.type
439                 == e_FM_PCD_MANIP_RMV_GENERIC)
440         {
441             /* initialize HMCD */
442             tmpReg = (uint32_t)(HMCD_OPCODE_GENERIC_RMV) << HMCD_OC_SHIFT;
443             /* tmp, should be conditional */
444             tmpReg |= p_FmPcdManipParams->u.hdr.rmvParams.u.generic.offset
445                     << HMCD_RMV_OFFSET_SHIFT;
446             tmpReg |= p_FmPcdManipParams->u.hdr.rmvParams.u.generic.size
447                     << HMCD_RMV_SIZE_SHIFT;
448         }
449         else
450             if (p_FmPcdManipParams->u.hdr.rmvParams.type
451                     == e_FM_PCD_MANIP_RMV_BY_HDR)
452             {
453                 switch (p_FmPcdManipParams->u.hdr.rmvParams.u.byHdr.type)
454                 {
455                     case (e_FM_PCD_MANIP_RMV_BY_HDR_SPECIFIC_L2):
456                     {
457                         uint8_t hmcdOpt;
458 
459                         /* initialize HMCD */
460                         tmpReg = (uint32_t)(HMCD_OPCODE_L2_RMV) << HMCD_OC_SHIFT;
461 
462                         switch (p_FmPcdManipParams->u.hdr.rmvParams.u.byHdr.u.specificL2)
463                         {
464                             case (e_FM_PCD_MANIP_HDR_RMV_ETHERNET):
465                                 hmcdOpt = HMCD_RMV_L2_ETHERNET;
466                                 break;
467                             case (e_FM_PCD_MANIP_HDR_RMV_STACKED_QTAGS):
468                                 hmcdOpt = HMCD_RMV_L2_STACKED_QTAGS;
469                                 break;
470                             case (e_FM_PCD_MANIP_HDR_RMV_ETHERNET_AND_MPLS):
471                                 hmcdOpt = HMCD_RMV_L2_ETHERNET_AND_MPLS;
472                                 break;
473                             case (e_FM_PCD_MANIP_HDR_RMV_MPLS):
474                                 hmcdOpt = HMCD_RMV_L2_MPLS;
475                                 break;
476                             case (e_FM_PCD_MANIP_HDR_RMV_PPPOE):
477                                 hmcdOpt = HMCD_RMV_L2_PPPOE;
478                                 break;
479                             default:
480                                 RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
481                         }
482                         tmpReg |= hmcdOpt << HMCD_L2_MODE_SHIFT;
483                         break;
484                     }
485 #if (DPAA_VERSION >= 11)
486                     case (e_FM_PCD_MANIP_RMV_BY_HDR_CAPWAP):
487                         tmpReg = (uint32_t)(HMCD_OPCODE_CAPWAP_RMV)
488                                 << HMCD_OC_SHIFT;
489                         break;
490                     case (e_FM_PCD_MANIP_RMV_BY_HDR_FROM_START):
491                     {
492                         uint8_t prsArrayOffset;
493                         t_Error err = E_OK;
494 
495                         tmpReg = (uint32_t)(HMCD_OPCODE_RMV_TILL)
496                                 << HMCD_OC_SHIFT;
497 
498                         err =
499                                 GetPrOffsetByHeaderOrField(
500                                         &p_FmPcdManipParams->u.hdr.rmvParams.u.byHdr.u.hdrInfo,
501                                         &prsArrayOffset);
502                         ASSERT_COND(!err);
503                         /* was previously checked */
504 
505                         tmpReg |= ((uint32_t)prsArrayOffset << 16);
506                     }
507                         break;
508 #endif /* (DPAA_VERSION >= 11) */
509                     default:
510                         RETURN_ERROR(MINOR, E_NOT_SUPPORTED,
511                                      ("manip header remove by hdr type!"));
512                 }
513             }
514 
515         WRITE_UINT32(*p_TmpHmct, tmpReg);
516         /* save a pointer to the "last" indication word */
517         p_Last = p_TmpHmct;
518         /* advance to next command */
519         p_TmpHmct += HMCD_BASIC_SIZE / 4;
520     }
521 
522     if (p_FmPcdManipParams->u.hdr.insrt)
523     {
524         if (p_FmPcdManipParams->u.hdr.insrtParams.type
525                 == e_FM_PCD_MANIP_INSRT_GENERIC)
526         {
527             /* initialize HMCD */
528             if (p_FmPcdManipParams->u.hdr.insrtParams.u.generic.replace)
529                 tmpReg = (uint32_t)(HMCD_OPCODE_GENERIC_REPLACE)
530                         << HMCD_OC_SHIFT;
531             else
532                 tmpReg = (uint32_t)(HMCD_OPCODE_GENERIC_INSRT) << HMCD_OC_SHIFT;
533 
534             tmpReg |= p_FmPcdManipParams->u.hdr.insrtParams.u.generic.offset
535                     << HMCD_INSRT_OFFSET_SHIFT;
536             tmpReg |= p_FmPcdManipParams->u.hdr.insrtParams.u.generic.size
537                     << HMCD_INSRT_SIZE_SHIFT;
538 
539             size = p_FmPcdManipParams->u.hdr.insrtParams.u.generic.size;
540             p_UsrData = p_FmPcdManipParams->u.hdr.insrtParams.u.generic.p_Data;
541 
542             WRITE_UINT32(*p_TmpHmct, tmpReg);
543             /* save a pointer to the "last" indication word */
544             p_Last = p_TmpHmct;
545 
546             p_TmpHmct += HMCD_BASIC_SIZE / 4;
547 
548             /* initialize data to be inserted */
549             /* if size is not a multiple of 4, padd with 0's */
550             origSize = size;
551             remain = (uint8_t)(size % 4);
552             if (remain)
553             {
554                 size += (uint8_t)(4 - remain);
555                 p_LocalData = (uint32_t *)XX_Malloc(size);
556                 memset((uint8_t *)p_LocalData, 0, size);
557                 memcpy((uint8_t *)p_LocalData, p_UsrData, origSize);
558             }
559             else
560                 p_LocalData = (uint32_t*)p_UsrData;
561 
562             /* initialize data and advance pointer to next command */
563             MemCpy8(p_TmpHmct, p_LocalData, size);
564             p_TmpHmct += size / sizeof(uint32_t);
565 
566             if (remain)
567                 XX_Free(p_LocalData);
568         }
569 
570         else
571             if (p_FmPcdManipParams->u.hdr.insrtParams.type
572                     == e_FM_PCD_MANIP_INSRT_BY_HDR)
573             {
574                 switch (p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.type)
575                 {
576                     case (e_FM_PCD_MANIP_INSRT_BY_HDR_SPECIFIC_L2):
577                     {
578                         uint8_t hmcdOpt;
579 
580                         /* initialize HMCD */
581                         tmpReg = (uint32_t)(HMCD_OPCODE_L2_INSRT)
582                                 << HMCD_OC_SHIFT;
583 
584                         switch (p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.specificL2Params.specificL2)
585                         {
586                             case (e_FM_PCD_MANIP_HDR_INSRT_MPLS):
587                                 if (p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.specificL2Params.update)
588                                     hmcdOpt = HMCD_INSRT_N_UPDATE_L2_MPLS;
589                                 else
590                                     hmcdOpt = HMCD_INSRT_L2_MPLS;
591                                 break;
592                             case (e_FM_PCD_MANIP_HDR_INSRT_PPPOE):
593                                 hmcdOpt = HMCD_INSRT_L2_PPPOE;
594                                 break;
595                             default:
596                                 RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
597                         }
598                         tmpReg |= hmcdOpt << HMCD_L2_MODE_SHIFT;
599 
600                         WRITE_UINT32(*p_TmpHmct, tmpReg);
601                         /* save a pointer to the "last" indication word */
602                         p_Last = p_TmpHmct;
603 
604                         p_TmpHmct += HMCD_BASIC_SIZE / 4;
605 
606                         /* set size and pointer of user's data */
607                         size =
608                                 (uint8_t)p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.specificL2Params.size;
609 
610                         ASSERT_COND(p_TmpData);
611                         MemCpy8(
612                                 p_TmpData,
613                                 p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.specificL2Params.p_Data,
614                                 size);
615                         tmpReg =
616                                 (size << HMCD_INSRT_L2_SIZE_SHIFT)
617                                         | (uint32_t)(XX_VirtToPhys(p_TmpData)
618                                                 - (((t_FmPcd*)h_FmPcd)->physicalMuramBase));
619                         WRITE_UINT32(*p_TmpHmct, tmpReg);
620                         p_TmpHmct += HMCD_PTR_SIZE / 4;
621                         p_TmpData += size;
622                     }
623                         break;
624 #if (DPAA_VERSION >= 11)
625                     case (e_FM_PCD_MANIP_INSRT_BY_HDR_IP):
626                         tmpReg = (uint32_t)(HMCD_OPCODE_IP_INSRT)
627                                 << HMCD_OC_SHIFT;
628                         if (p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.ipParams.calcL4Checksum)
629                             tmpReg |= HMCD_IP_L4_CS_CALC;
630                         if (p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.ipParams.mappingMode
631                                 == e_FM_PCD_MANIP_HDR_QOS_MAPPING_AS_IS)
632                             tmpReg |= HMCD_IP_OR_QOS;
633                         tmpReg |=
634                                 p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.ipParams.lastPidOffset
635                                         & HMCD_IP_LAST_PID_MASK;
636                         tmpReg |=
637                                 ((p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.ipParams.insrt.size
638                                         << HMCD_IP_SIZE_SHIFT)
639                                         & HMCD_IP_SIZE_MASK);
640                         if (p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.ipParams.dontFragOverwrite)
641                             tmpReg |= HMCD_IP_DF_MODE;
642 
643                         WRITE_UINT32(*p_TmpHmct, tmpReg);
644 
645                         /* save a pointer to the "last" indication word */
646                         p_Last = p_TmpHmct;
647 
648                         p_TmpHmct += HMCD_BASIC_SIZE / 4;
649 
650                         /* set IP id */
651                         ASSERT_COND(p_TmpData);
652                         WRITE_UINT16(
653                                 *(uint16_t*)p_TmpData,
654                                 p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.ipParams.id);
655                         WRITE_UINT32(
656                                 *p_TmpHmct,
657                                 (uint32_t)(XX_VirtToPhys(p_TmpData) - (((t_FmPcd*)p_Manip->h_FmPcd)->physicalMuramBase)));
658                         p_TmpData += 2;
659                         p_TmpHmct += HMCD_PTR_SIZE / 4;
660 
661                         WRITE_UINT8(*p_TmpHmct, p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.ipParams.lastDstOffset);
662                         p_TmpHmct += HMCD_PARAM_SIZE / 4;
663 
664                         MemCpy8(
665                                 p_TmpHmct,
666                                 p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.ipParams.insrt.p_Data,
667                                 p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.ipParams.insrt.size);
668                         p_TmpHmct +=
669                                 p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.ipParams.insrt.size
670                                         / 4;
671                         break;
672                     case (e_FM_PCD_MANIP_INSRT_BY_HDR_UDP_LITE):
673                         tmpReg = HMCD_INSRT_UDP_LITE;
674                     case (e_FM_PCD_MANIP_INSRT_BY_HDR_UDP):
675                         tmpReg |= (uint32_t)(HMCD_OPCODE_UDP_INSRT)
676                                 << HMCD_OC_SHIFT;
677 
678                         WRITE_UINT32(*p_TmpHmct, tmpReg);
679 
680                         /* save a pointer to the "last" indication word */
681                         p_Last = p_TmpHmct;
682 
683                         p_TmpHmct += HMCD_BASIC_SIZE / 4;
684 
685                         MemCpy8(
686                                 p_TmpHmct,
687                                 p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.insrt.p_Data,
688                                 p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.insrt.size);
689                         p_TmpHmct +=
690                                 p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.insrt.size
691                                         / 4;
692                         break;
693                     case (e_FM_PCD_MANIP_INSRT_BY_HDR_CAPWAP):
694                         tmpReg = (uint32_t)(HMCD_OPCODE_CAPWAP_INSRT)
695                                 << HMCD_OC_SHIFT;
696                         tmpReg |= HMCD_CAPWAP_INSRT;
697 
698                         WRITE_UINT32(*p_TmpHmct, tmpReg);
699 
700                         /* save a pointer to the "last" indication word */
701                         p_Last = p_TmpHmct;
702 
703                         p_TmpHmct += HMCD_BASIC_SIZE / 4;
704 
705                         MemCpy8(
706                                 p_TmpHmct,
707                                 p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.insrt.p_Data,
708                                 p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.insrt.size);
709                         p_TmpHmct +=
710                                 p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.insrt.size
711                                         / 4;
712                         break;
713 #endif /* (DPAA_VERSION >= 11) */
714                     default:
715                         RETURN_ERROR(MINOR, E_NOT_SUPPORTED,
716                                      ("manip header insert by header type!"));
717 
718                 }
719             }
720     }
721 
722     if (p_FmPcdManipParams->u.hdr.fieldUpdate)
723     {
724         switch (p_FmPcdManipParams->u.hdr.fieldUpdateParams.type)
725         {
726             case (e_FM_PCD_MANIP_HDR_FIELD_UPDATE_VLAN):
727                 /* set opcode */
728                 tmpReg = (uint32_t)(HMCD_OPCODE_VLAN_PRI_UPDATE)
729                         << HMCD_OC_SHIFT;
730 
731                 /* set mode & table pointer */
732                 if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.vlan.updateType
733                         == e_FM_PCD_MANIP_HDR_FIELD_UPDATE_DSCP_TO_VLAN)
734                 {
735                     /* set Mode */
736                     tmpReg |= (uint32_t)(HMCD_VLAN_PRI_UPDATE_DSCP_TO_VPRI)
737                             << HMCD_VLAN_PRI_REP_MODE_SHIFT;
738                     /* set VPRI default */
739                     tmpReg |=
740                             p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.vlan.u.dscpToVpri.vpriDefVal;
741                     WRITE_UINT32(*p_TmpHmct, tmpReg);
742                     /* save a pointer to the "last" indication word */
743                     p_Last = p_TmpHmct;
744                     /* write the table pointer into the Manip descriptor */
745                     p_TmpHmct += HMCD_BASIC_SIZE / 4;
746 
747                     tmpReg = 0;
748                     ASSERT_COND(p_TmpData);
749                     for (i = 0; i < HMCD_DSCP_VALUES; i++)
750                     {
751                         /* first we build from each 8 values a 32bit register */
752                         tmpReg |=
753                                 (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.vlan.u.dscpToVpri.dscpToVpriTable[i])
754                                         << (32 - 4 * (j + 1));
755                         j++;
756                         /* Than we write this register to the next table word
757                          * (i=7-->word 0, i=15-->word 1,... i=63-->word 7) */
758                         if ((i % 8) == 7)
759                         {
760                             WRITE_UINT32(*((uint32_t*)p_TmpData + (i+1)/8-1),
761                                          tmpReg);
762                             tmpReg = 0;
763                             j = 0;
764                         }
765                     }
766 
767                     WRITE_UINT32(
768                             *p_TmpHmct,
769                             (uint32_t)(XX_VirtToPhys(p_TmpData) - (((t_FmPcd*)h_FmPcd)->physicalMuramBase)));
770                     p_TmpHmct += HMCD_PTR_SIZE / 4;
771 
772                     p_TmpData += DSCP_TO_VLAN_TABLE_SIZE;
773                 }
774                 else
775                     if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.vlan.updateType
776                             == e_FM_PCD_MANIP_HDR_FIELD_UPDATE_VLAN_VPRI)
777                     {
778                         /* set Mode */
779                         /* line commented out as it has no-side-effect ('0' value). */
780                         /*tmpReg |= HMCD_VLAN_PRI_UPDATE << HMCD_VLAN_PRI_REP_MODE_SHIFT*/;
781                         /* set VPRI parameter */
782                         tmpReg |=
783                                 p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.vlan.u.vpri;
784                         WRITE_UINT32(*p_TmpHmct, tmpReg);
785                         /* save a pointer to the "last" indication word */
786                         p_Last = p_TmpHmct;
787                         p_TmpHmct += HMCD_BASIC_SIZE / 4;
788                     }
789                 break;
790 
791             case (e_FM_PCD_MANIP_HDR_FIELD_UPDATE_IPV4):
792                 /* set opcode */
793                 tmpReg = (uint32_t)(HMCD_OPCODE_IPV4_UPDATE) << HMCD_OC_SHIFT;
794                 if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.validUpdates
795                         & HDR_MANIP_IPV4_TTL)
796                     tmpReg |= HMCD_IPV4_UPDATE_TTL;
797                 if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.validUpdates
798                         & HDR_MANIP_IPV4_TOS)
799                 {
800                     tmpReg |= HMCD_IPV4_UPDATE_TOS;
801                     tmpReg |=
802                             p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.tos
803                                     << HMCD_IPV4_UPDATE_TOS_SHIFT;
804                 }
805                 if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.validUpdates
806                         & HDR_MANIP_IPV4_ID)
807                     tmpReg |= HMCD_IPV4_UPDATE_ID;
808                 if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.validUpdates
809                         & HDR_MANIP_IPV4_SRC)
810                     tmpReg |= HMCD_IPV4_UPDATE_SRC;
811                 if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.validUpdates
812                         & HDR_MANIP_IPV4_DST)
813                     tmpReg |= HMCD_IPV4_UPDATE_DST;
814                 /* write the first 4 bytes of the descriptor */
815                 WRITE_UINT32(*p_TmpHmct, tmpReg);
816                 /* save a pointer to the "last" indication word */
817                 p_Last = p_TmpHmct;
818 
819                 p_TmpHmct += HMCD_BASIC_SIZE / 4;
820 
821                 if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.validUpdates
822                         & HDR_MANIP_IPV4_ID)
823                 {
824                     ASSERT_COND(p_TmpData);
825                     WRITE_UINT16(
826                             *(uint16_t*)p_TmpData,
827                             p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.id);
828                     WRITE_UINT32(
829                             *p_TmpHmct,
830                             (uint32_t)(XX_VirtToPhys(p_TmpData) - (((t_FmPcd*)p_Manip->h_FmPcd)->physicalMuramBase)));
831                     p_TmpData += 2;
832                     p_TmpHmct += HMCD_PTR_SIZE / 4;
833                 }
834 
835                 if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.validUpdates
836                         & HDR_MANIP_IPV4_SRC)
837                 {
838                     WRITE_UINT32(
839                             *p_TmpHmct,
840                             p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.src);
841                     p_TmpHmct += HMCD_IPV4_ADDR_SIZE / 4;
842                 }
843 
844                 if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.validUpdates
845                         & HDR_MANIP_IPV4_DST)
846                 {
847                     WRITE_UINT32(
848                             *p_TmpHmct,
849                             p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.dst);
850                     p_TmpHmct += HMCD_IPV4_ADDR_SIZE / 4;
851                 }
852                 break;
853 
854             case (e_FM_PCD_MANIP_HDR_FIELD_UPDATE_IPV6):
855                 /* set opcode */
856                 tmpReg = (uint32_t)(HMCD_OPCODE_IPV6_UPDATE) << HMCD_OC_SHIFT;
857                 if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv6.validUpdates
858                         & HDR_MANIP_IPV6_HL)
859                     tmpReg |= HMCD_IPV6_UPDATE_HL;
860                 if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv6.validUpdates
861                         & HDR_MANIP_IPV6_TC)
862                 {
863                     tmpReg |= HMCD_IPV6_UPDATE_TC;
864                     tmpReg |=
865                             p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv6.trafficClass
866                                     << HMCD_IPV6_UPDATE_TC_SHIFT;
867                 }
868                 if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv6.validUpdates
869                         & HDR_MANIP_IPV6_SRC)
870                     tmpReg |= HMCD_IPV6_UPDATE_SRC;
871                 if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv6.validUpdates
872                         & HDR_MANIP_IPV6_DST)
873                     tmpReg |= HMCD_IPV6_UPDATE_DST;
874                 /* write the first 4 bytes of the descriptor */
875                 WRITE_UINT32(*p_TmpHmct, tmpReg);
876                 /* save a pointer to the "last" indication word */
877                 p_Last = p_TmpHmct;
878 
879                 p_TmpHmct += HMCD_BASIC_SIZE / 4;
880                 if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv6.validUpdates
881                         & HDR_MANIP_IPV6_SRC)
882                 {
883                     for (i = 0; i < NET_HEADER_FIELD_IPv6_ADDR_SIZE; i += 4)
884                     {
885                         memcpy(&tmp_ipv6_addr,
886                                &p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv6.src[i],
887                                sizeof(uint32_t));
888                         WRITE_UINT32(*p_TmpHmct, tmp_ipv6_addr);
889                         p_TmpHmct += HMCD_PTR_SIZE / 4;
890                     }
891                 }
892                 if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv6.validUpdates
893                         & HDR_MANIP_IPV6_DST)
894                 {
895                     for (i = 0; i < NET_HEADER_FIELD_IPv6_ADDR_SIZE; i += 4)
896                     {
897                         memcpy(&tmp_ipv6_addr,
898                                &p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv6.dst[i],
899                                sizeof(uint32_t));
900                         WRITE_UINT32(*p_TmpHmct, tmp_ipv6_addr);
901                         p_TmpHmct += HMCD_PTR_SIZE / 4;
902                     }
903                 }
904                 break;
905 
906             case (e_FM_PCD_MANIP_HDR_FIELD_UPDATE_TCP_UDP):
907                 if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.tcpUdp.validUpdates
908                         == HDR_MANIP_TCP_UDP_CHECKSUM)
909                 {
910                     /* we implement this case with the update-checksum descriptor */
911                     /* set opcode */
912                     tmpReg = (uint32_t)(HMCD_OPCODE_TCP_UDP_CHECKSUM)
913                             << HMCD_OC_SHIFT;
914                     /* write the first 4 bytes of the descriptor */
915                     WRITE_UINT32(*p_TmpHmct, tmpReg);
916                     /* save a pointer to the "last" indication word */
917                     p_Last = p_TmpHmct;
918 
919                     p_TmpHmct += HMCD_BASIC_SIZE / 4;
920                 }
921                 else
922                 {
923                     /* we implement this case with the TCP/UDP update descriptor */
924                     /* set opcode */
925                     tmpReg = (uint32_t)(HMCD_OPCODE_TCP_UDP_UPDATE)
926                             << HMCD_OC_SHIFT;
927                     if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.tcpUdp.validUpdates
928                             & HDR_MANIP_TCP_UDP_DST)
929                         tmpReg |= HMCD_TCP_UDP_UPDATE_DST;
930                     if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.tcpUdp.validUpdates
931                             & HDR_MANIP_TCP_UDP_SRC)
932                         tmpReg |= HMCD_TCP_UDP_UPDATE_SRC;
933                     /* write the first 4 bytes of the descriptor */
934                     WRITE_UINT32(*p_TmpHmct, tmpReg);
935                     /* save a pointer to the "last" indication word */
936                     p_Last = p_TmpHmct;
937 
938                     p_TmpHmct += HMCD_BASIC_SIZE / 4;
939 
940                     tmpReg = 0;
941                     if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.tcpUdp.validUpdates
942                             & HDR_MANIP_TCP_UDP_SRC)
943                         tmpReg |=
944                                 ((uint32_t)p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.tcpUdp.src)
945                                         << HMCD_TCP_UDP_UPDATE_SRC_SHIFT;
946                     if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.tcpUdp.validUpdates
947                             & HDR_MANIP_TCP_UDP_DST)
948                         tmpReg |=
949                                 ((uint32_t)p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.tcpUdp.dst);
950                     WRITE_UINT32(*p_TmpHmct, tmpReg);
951                     p_TmpHmct += HMCD_PTR_SIZE / 4;
952                 }
953                 break;
954 
955             default:
956                 RETURN_ERROR(MINOR, E_INVALID_SELECTION,
957                              ("Unknown fieldUpdateParams.type"));
958         }
959     }
960 
961     if (p_FmPcdManipParams->u.hdr.custom)
962     {
963         switch (p_FmPcdManipParams->u.hdr.customParams.type)
964         {
965             case (e_FM_PCD_MANIP_HDR_CUSTOM_IP_REPLACE):
966                 /* set opcode */
967                 tmpReg = (uint32_t)(HMCD_OPCODE_REPLACE_IP) << HMCD_OC_SHIFT;
968 
969                 if (p_FmPcdManipParams->u.hdr.customParams.u.ipHdrReplace.decTtlHl)
970                     tmpReg |= HMCD_IP_REPLACE_TTL_HL;
971                 if (p_FmPcdManipParams->u.hdr.customParams.u.ipHdrReplace.replaceType
972                         == e_FM_PCD_MANIP_HDR_CUSTOM_REPLACE_IPV4_BY_IPV6)
973                     /* line commented out as it has no-side-effect ('0' value). */
974                     /*tmpReg |= HMCD_IP_REPLACE_REPLACE_IPV4*/;
975                 else
976                     if (p_FmPcdManipParams->u.hdr.customParams.u.ipHdrReplace.replaceType
977                             == e_FM_PCD_MANIP_HDR_CUSTOM_REPLACE_IPV6_BY_IPV4)
978                     {
979                         tmpReg |= HMCD_IP_REPLACE_REPLACE_IPV6;
980                         if (p_FmPcdManipParams->u.hdr.customParams.u.ipHdrReplace.updateIpv4Id)
981                             tmpReg |= HMCD_IP_REPLACE_ID;
982                     }
983                     else
984                         RETURN_ERROR(
985                                 MINOR,
986                                 E_NOT_SUPPORTED,
987                                 ("One flag out of HDR_MANIP_IP_REPLACE_IPV4, HDR_MANIP_IP_REPLACE_IPV6 - must be set."));
988 
989                 /* write the first 4 bytes of the descriptor */
990                 WRITE_UINT32(*p_TmpHmct, tmpReg);
991                 /* save a pointer to the "last" indication word */
992                 p_Last = p_TmpHmct;
993 
994                 p_TmpHmct += HMCD_BASIC_SIZE / 4;
995 
996                 size =
997                         p_FmPcdManipParams->u.hdr.customParams.u.ipHdrReplace.hdrSize;
998                 ASSERT_COND(p_TmpData);
999                 MemCpy8(
1000                         p_TmpData,
1001                         p_FmPcdManipParams->u.hdr.customParams.u.ipHdrReplace.hdr,
1002                         size);
1003                 tmpReg = (uint32_t)(size << HMCD_IP_REPLACE_L3HDRSIZE_SHIFT);
1004                 tmpReg |= (uint32_t)(XX_VirtToPhys(p_TmpData)
1005                         - (((t_FmPcd*)h_FmPcd)->physicalMuramBase));
1006                 WRITE_UINT32(*p_TmpHmct, tmpReg);
1007                 p_TmpHmct += HMCD_PTR_SIZE / 4;
1008                 p_TmpData += size;
1009 
1010                 if ((p_FmPcdManipParams->u.hdr.customParams.u.ipHdrReplace.replaceType
1011                         == e_FM_PCD_MANIP_HDR_CUSTOM_REPLACE_IPV6_BY_IPV4)
1012                         && (p_FmPcdManipParams->u.hdr.customParams.u.ipHdrReplace.updateIpv4Id))
1013                 {
1014                     WRITE_UINT16(
1015                             *(uint16_t*)p_TmpData,
1016                             p_FmPcdManipParams->u.hdr.customParams.u.ipHdrReplace.id);
1017                     WRITE_UINT32(
1018                             *p_TmpHmct,
1019                             (uint32_t)(XX_VirtToPhys(p_TmpData) - (((t_FmPcd*)h_FmPcd)->physicalMuramBase)));
1020                     p_TmpData += 2;
1021                 }
1022                 p_TmpHmct += HMCD_PTR_SIZE / 4;
1023                 break;
1024             case (e_FM_PCD_MANIP_HDR_CUSTOM_GEN_FIELD_REPLACE):
1025                 /* set opcode */
1026                 tmpReg = (uint32_t)(HMCD_OPCODE_GEN_FIELD_REPLACE) << HMCD_OC_SHIFT;
1027                 tmpReg |= p_FmPcdManipParams->u.hdr.customParams.u.genFieldReplace.size << HMCD_GEN_FIELD_SIZE_SHIFT;
1028                 tmpReg |= p_FmPcdManipParams->u.hdr.customParams.u.genFieldReplace.srcOffset << HMCD_GEN_FIELD_SRC_OFF_SHIFT;
1029                 tmpReg |= p_FmPcdManipParams->u.hdr.customParams.u.genFieldReplace.dstOffset << HMCD_GEN_FIELD_DST_OFF_SHIFT;
1030                 if (p_FmPcdManipParams->u.hdr.customParams.u.genFieldReplace.mask)
1031                     tmpReg |= HMCD_GEN_FIELD_MASK_EN;
1032 
1033                 /* write the first 4 bytes of the descriptor */
1034                 WRITE_UINT32(*p_TmpHmct, tmpReg);
1035                 /* save a pointer to the "last" indication word */
1036                 p_Last = p_TmpHmct;
1037 
1038                 p_TmpHmct += HMCD_BASIC_SIZE/4;
1039 
1040                 if (p_FmPcdManipParams->u.hdr.customParams.u.genFieldReplace.mask)
1041                 {
1042                     tmpReg = p_FmPcdManipParams->u.hdr.customParams.u.genFieldReplace.mask << HMCD_GEN_FIELD_MASK_SHIFT;
1043                     tmpReg |= p_FmPcdManipParams->u.hdr.customParams.u.genFieldReplace.maskOffset << HMCD_GEN_FIELD_MASK_OFF_SHIFT;
1044                     /* write the next 4 bytes of the descriptor */
1045                     WRITE_UINT32(*p_TmpHmct, tmpReg);
1046                 }
1047                 p_TmpHmct += HMCD_PARAM_SIZE/4;
1048                 break;
1049             default:
1050                 RETURN_ERROR(MINOR, E_INVALID_SELECTION,
1051                              ("Unknown customParams.type"));
1052         }
1053     }
1054 
1055     /* If this node has a nextManip, and no parsing is required, the old table must be copied to the new table
1056      the old table and should be freed */
1057     if (p_FmPcdManipParams->h_NextManip
1058             && (p_Manip->nextManipType == e_FM_PCD_MANIP_HDR)
1059             && (MANIP_DONT_REPARSE(p_Manip)))
1060     {
1061         if (new)
1062         {
1063             /* If this is the first time this manip is created we need to free unused memory. If it
1064              * is a dynamic changes case, the memory used is either the CC shadow or the existing
1065              * table - no allocation, no free */
1066             MANIP_UPDATE_UNIFIED_POSITION(p_FmPcdManipParams->h_NextManip);
1067 
1068             p_Manip->unifiedPosition = e_MANIP_UNIFIED_FIRST;
1069         }
1070     }
1071     else
1072     {
1073         ASSERT_COND(p_Last);
1074         /* set the "last" indication on the last command of the current table */
1075         WRITE_UINT32(*p_Last, GET_UINT32(*p_Last) | HMCD_LAST);
1076     }
1077 
1078     return E_OK;
1079 }
1080 
1081 static t_Error CreateManipActionNew(t_FmPcdManip *p_Manip,
1082                                     t_FmPcdManipParams *p_FmPcdManipParams)
1083 {
1084     t_FmPcdManip *p_CurManip;
1085     t_Error err;
1086     uint32_t nextSize = 0, totalSize;
1087     uint16_t tmpReg;
1088     uint8_t *p_OldHmct, *p_TmpHmctPtr, *p_TmpDataPtr;
1089 
1090     /* set Manip structure */
1091 
1092     p_Manip->dontParseAfterManip =
1093             p_FmPcdManipParams->u.hdr.dontParseAfterManip;
1094 
1095     if (p_FmPcdManipParams->h_NextManip)
1096     {   /* Next Header manipulation exists */
1097         p_Manip->nextManipType = MANIP_GET_TYPE(p_FmPcdManipParams->h_NextManip);
1098 
1099         if ((p_Manip->nextManipType == e_FM_PCD_MANIP_HDR) && p_Manip->dontParseAfterManip)
1100             nextSize = (uint32_t)(GetHmctSize(p_FmPcdManipParams->h_NextManip)
1101                     + GetDataSize(p_FmPcdManipParams->h_NextManip));
1102         else /* either parsing is required or next manip is Frag; no table merging. */
1103             p_Manip->cascaded = TRUE;
1104         /* pass up the "cascaded" attribute. The whole chain is cascaded
1105          * if something is cascaded along the way. */
1106         if (MANIP_IS_CASCADED(p_FmPcdManipParams->h_NextManip))
1107             p_Manip->cascaded = TRUE;
1108     }
1109 
1110     /* Allocate new table */
1111     /* calculate table size according to manip parameters */
1112     err = CalculateTableSize(p_FmPcdManipParams, &p_Manip->tableSize,
1113                              &p_Manip->dataSize);
1114     if (err)
1115         RETURN_ERROR(MINOR, err, NO_MSG);
1116 
1117     totalSize = (uint16_t)(p_Manip->tableSize + p_Manip->dataSize + nextSize);
1118 
1119     p_Manip->p_Hmct = (uint8_t*)FM_MURAM_AllocMem(
1120             ((t_FmPcd *)p_Manip->h_FmPcd)->h_FmMuram, totalSize, 4);
1121     if (!p_Manip->p_Hmct)
1122         RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM alloc failed"));
1123 
1124     if (p_Manip->dataSize)
1125         p_Manip->p_Data =
1126                 (uint8_t*)PTR_MOVE(p_Manip->p_Hmct, (p_Manip->tableSize + nextSize));
1127 
1128     /* update shadow size to allow runtime replacement of Header manipulation */
1129     /* The allocated shadow is divided as follows:
1130      0 . . .       16 . . .
1131      --------------------------------
1132      |   Shadow   |   Shadow HMTD   |
1133      |   HMTD     |   Match Table   |
1134      | (16 bytes) | (maximal size)  |
1135      --------------------------------
1136      */
1137 
1138     err = FmPcdUpdateCcShadow(p_Manip->h_FmPcd, (uint32_t)(totalSize + 16),
1139                               (uint16_t)FM_PCD_CC_AD_TABLE_ALIGN);
1140     if (err != E_OK)
1141     {
1142         FM_MURAM_FreeMem(p_Manip->h_FmPcd, p_Manip->p_Hmct);
1143         RETURN_ERROR(MAJOR, E_NO_MEMORY,
1144                      ("MURAM allocation for HdrManip node shadow"));
1145     }
1146 
1147     if (p_FmPcdManipParams->h_NextManip
1148             && (p_Manip->nextManipType == e_FM_PCD_MANIP_HDR)
1149             && (MANIP_DONT_REPARSE(p_Manip)))
1150     {
1151         p_OldHmct = (uint8_t *)GetManipInfo(p_FmPcdManipParams->h_NextManip,
1152                                             e_MANIP_HMCT);
1153         p_CurManip = p_FmPcdManipParams->h_NextManip;
1154         /* Run till the last Manip (which is the first to configure) */
1155         while (MANIP_IS_UNIFIED_NON_LAST(p_CurManip))
1156             p_CurManip = p_CurManip->h_NextManip;
1157 
1158         while (p_CurManip)
1159         {
1160             /* If this is a unified table, point to the part of the table
1161              * which is the relative offset in HMCT.
1162              */
1163             p_TmpHmctPtr = (uint8_t*)PTR_MOVE(p_Manip->p_Hmct,
1164                     (p_Manip->tableSize +
1165                             (PTR_TO_UINT(p_CurManip->p_Hmct) -
1166                                     PTR_TO_UINT(p_OldHmct))));
1167             if (p_CurManip->p_Data)
1168                 p_TmpDataPtr = (uint8_t*)PTR_MOVE(p_Manip->p_Hmct,
1169                         (p_Manip->tableSize +
1170                                 (PTR_TO_UINT(p_CurManip->p_Data) -
1171                                         PTR_TO_UINT(p_OldHmct))));
1172             else
1173                 p_TmpDataPtr = NULL;
1174 
1175             BuildHmct(p_CurManip, &p_CurManip->manipParams, p_TmpHmctPtr,
1176                       p_TmpDataPtr, FALSE);
1177             /* update old manip table pointer */
1178             MANIP_SET_HMCT_PTR(p_CurManip, p_TmpHmctPtr);
1179             MANIP_SET_DATA_PTR(p_CurManip, p_TmpDataPtr);
1180 
1181             p_CurManip = p_CurManip->h_PrevManip;
1182         }
1183         /* We copied the HMCT to create a new large HMCT so we can free the old one */
1184         FM_MURAM_FreeMem(MANIP_GET_MURAM(p_FmPcdManipParams->h_NextManip),
1185                          p_OldHmct);
1186     }
1187 
1188     /* Fill table */
1189     err = BuildHmct(p_Manip, p_FmPcdManipParams, p_Manip->p_Hmct,
1190                     p_Manip->p_Data, TRUE);
1191     if (err)
1192     {
1193         FM_MURAM_FreeMem(p_Manip->h_FmPcd, p_Manip->p_Hmct);
1194         RETURN_ERROR(MINOR, err, NO_MSG);
1195     }
1196 
1197     /* Build HMTD (table descriptor) */
1198      tmpReg = HMTD_CFG_TYPE; /* NADEN = 0 */
1199 
1200      /* add parseAfterManip */
1201       if (!p_Manip->dontParseAfterManip)
1202           tmpReg |= HMTD_CFG_PRS_AFTER_HM;
1203 
1204     /* create cascade */
1205     /*if (p_FmPcdManipParams->h_NextManip
1206             && (!MANIP_DONT_REPARSE(p_Manip) || (p_Manip->nextManipType != e_FM_PCD_MANIP_HDR)))*/
1207     if (p_Manip->cascaded)
1208     {
1209         uint16_t nextAd;
1210         /* indicate that there's another HM table descriptor */
1211         tmpReg |= HMTD_CFG_NEXT_AD_EN;
1212         /* get address of next HMTD (table descriptor; h_Ad).
1213          * If the next HMTD was removed due to table unifing, get the address
1214          * of the "next next" as written in the h_Ad of the next h_Manip node.
1215          */
1216         if (p_Manip->unifiedPosition != e_MANIP_UNIFIED_FIRST)
1217             nextAd = (uint16_t)((uint32_t)(XX_VirtToPhys(MANIP_GET_HMTD_PTR(p_FmPcdManipParams->h_NextManip)) - (((t_FmPcd*)p_Manip->h_FmPcd)->physicalMuramBase)) >> 4);
1218         else
1219             nextAd = ((t_Hmtd *)((t_FmPcdManip *)p_FmPcdManipParams->h_NextManip)->h_Ad)->nextAdIdx;
1220 
1221         WRITE_UINT16(((t_Hmtd *)p_Manip->h_Ad)->nextAdIdx, nextAd);
1222     }
1223 
1224     WRITE_UINT16(((t_Hmtd *)p_Manip->h_Ad)->cfg, tmpReg);
1225     WRITE_UINT32(
1226             ((t_Hmtd *)p_Manip->h_Ad)->hmcdBasePtr,
1227             (uint32_t)(XX_VirtToPhys(p_Manip->p_Hmct) - (((t_FmPcd*)p_Manip->h_FmPcd)->physicalMuramBase)));
1228 
1229     WRITE_UINT8(((t_Hmtd *)p_Manip->h_Ad)->opCode, HMAN_OC);
1230 
1231     if (p_Manip->unifiedPosition == e_MANIP_UNIFIED_FIRST)
1232     {
1233         /* The HMTD of the next Manip is never going to be used */
1234         if (((t_FmPcdManip *)p_FmPcdManipParams->h_NextManip)->muramAllocate)
1235             FM_MURAM_FreeMem(
1236                     ((t_FmPcd *)((t_FmPcdManip *)p_FmPcdManipParams->h_NextManip)->h_FmPcd)->h_FmMuram,
1237                     ((t_FmPcdManip *)p_FmPcdManipParams->h_NextManip)->h_Ad);
1238         else
1239             XX_Free(((t_FmPcdManip *)p_FmPcdManipParams->h_NextManip)->h_Ad);
1240         ((t_FmPcdManip *)p_FmPcdManipParams->h_NextManip)->h_Ad = NULL;
1241     }
1242 
1243     return E_OK;
1244 }
1245 
1246 static t_Error CreateManipActionShadow(t_FmPcdManip *p_Manip,
1247                                        t_FmPcdManipParams *p_FmPcdManipParams)
1248 {
1249     uint8_t *p_WholeHmct, *p_TmpHmctPtr, newDataSize, *p_TmpDataPtr = NULL;
1250     uint16_t newSize;
1251     t_FmPcd *p_FmPcd = (t_FmPcd *)p_Manip->h_FmPcd;
1252     t_Error err;
1253     t_FmPcdManip *p_CurManip = p_Manip;
1254 
1255     err = CalculateTableSize(p_FmPcdManipParams, &newSize, &newDataSize);
1256     if (err)
1257         RETURN_ERROR(MINOR, err, NO_MSG);
1258 
1259     /* check coherency of new table parameters */
1260     if (newSize > p_Manip->tableSize)
1261         RETURN_ERROR(
1262                 MINOR,
1263                 E_INVALID_VALUE,
1264                 ("New Hdr Manip configuration requires larger size than current one (command table)."));
1265     if (newDataSize > p_Manip->dataSize)
1266         RETURN_ERROR(
1267                 MINOR,
1268                 E_INVALID_VALUE,
1269                 ("New Hdr Manip configuration requires larger size than current one (data)."));
1270     if (p_FmPcdManipParams->h_NextManip)
1271         RETURN_ERROR(
1272                 MINOR, E_INVALID_VALUE,
1273                 ("New Hdr Manip configuration can not contain h_NextManip."));
1274     if (MANIP_IS_UNIFIED(p_Manip) && (newSize != p_Manip->tableSize))
1275         RETURN_ERROR(
1276                 MINOR,
1277                 E_INVALID_VALUE,
1278                 ("New Hdr Manip configuration in a chained manipulation requires different size than current one."));
1279     if (p_Manip->dontParseAfterManip
1280             != p_FmPcdManipParams->u.hdr.dontParseAfterManip)
1281         RETURN_ERROR(
1282                 MINOR,
1283                 E_INVALID_VALUE,
1284                 ("New Hdr Manip configuration differs in dontParseAfterManip value."));
1285 
1286     p_Manip->tableSize = newSize;
1287     p_Manip->dataSize = newDataSize;
1288 
1289     /* Build the new table in the shadow */
1290     if (!MANIP_IS_UNIFIED(p_Manip))
1291     {
1292         p_TmpHmctPtr = (uint8_t*)PTR_MOVE(p_FmPcd->p_CcShadow, 16);
1293         if (p_Manip->p_Data)
1294             p_TmpDataPtr =
1295                     (uint8_t*)PTR_MOVE(p_TmpHmctPtr,
1296                             (PTR_TO_UINT(p_Manip->p_Data) - PTR_TO_UINT(p_Manip->p_Hmct)));
1297 
1298         BuildHmct(p_Manip, p_FmPcdManipParams, p_TmpHmctPtr, p_Manip->p_Data,
1299                   FALSE);
1300     }
1301     else
1302     {
1303         p_WholeHmct = (uint8_t *)GetManipInfo(p_Manip, e_MANIP_HMCT);
1304         ASSERT_COND(p_WholeHmct);
1305 
1306         /* Run till the last Manip (which is the first to configure) */
1307         while (MANIP_IS_UNIFIED_NON_LAST(p_CurManip))
1308             p_CurManip = p_CurManip->h_NextManip;
1309 
1310         while (p_CurManip)
1311         {
1312             /* If this is a non-head node in a unified table, point to the part of the shadow
1313              * which is the relative offset in HMCT.
1314              * else, point to the beginning of the
1315              * shadow table (we save 16 for the HMTD.
1316              */
1317             p_TmpHmctPtr =
1318                     (uint8_t*)PTR_MOVE(p_FmPcd->p_CcShadow,
1319                             (16 + PTR_TO_UINT(p_CurManip->p_Hmct) - PTR_TO_UINT(p_WholeHmct)));
1320             if (p_CurManip->p_Data)
1321                 p_TmpDataPtr =
1322                         (uint8_t*)PTR_MOVE(p_FmPcd->p_CcShadow,
1323                                 (16 + PTR_TO_UINT(p_CurManip->p_Data) - PTR_TO_UINT(p_WholeHmct)));
1324 
1325             BuildHmct(p_CurManip, &p_CurManip->manipParams, p_TmpHmctPtr,
1326                       p_TmpDataPtr, FALSE);
1327             p_CurManip = p_CurManip->h_PrevManip;
1328         }
1329     }
1330 
1331     return E_OK;
1332 }
1333 
1334 static t_Error CreateManipActionBackToOrig(
1335         t_FmPcdManip *p_Manip, t_FmPcdManipParams *p_FmPcdManipParams)
1336 {
1337     uint8_t *p_WholeHmct = NULL, *p_TmpHmctPtr, *p_TmpDataPtr;
1338     t_FmPcdManip *p_CurManip = p_Manip;
1339 
1340     /* Build the new table in the shadow */
1341     if (!MANIP_IS_UNIFIED(p_Manip))
1342         BuildHmct(p_Manip, p_FmPcdManipParams, p_Manip->p_Hmct, p_Manip->p_Data,
1343                   FALSE);
1344     else
1345     {
1346         p_WholeHmct = (uint8_t *)GetManipInfo(p_Manip, e_MANIP_HMCT);
1347         ASSERT_COND(p_WholeHmct);
1348 
1349         /* Run till the last Manip (which is the first to configure) */
1350         while (MANIP_IS_UNIFIED_NON_LAST(p_CurManip))
1351             p_CurManip = p_CurManip->h_NextManip;
1352 
1353         while (p_CurManip)
1354         {
1355             /* If this is a unified table, point to the part of the table
1356              * which is the relative offset in HMCT.
1357              */
1358             p_TmpHmctPtr = p_CurManip->p_Hmct; /*- (uint32_t)p_WholeHmct*/
1359             p_TmpDataPtr = p_CurManip->p_Data; /*- (uint32_t)p_WholeHmct*/
1360 
1361             BuildHmct(p_CurManip, &p_CurManip->manipParams, p_TmpHmctPtr,
1362                       p_TmpDataPtr, FALSE);
1363 
1364             p_CurManip = p_CurManip->h_PrevManip;
1365         }
1366     }
1367 
1368     return E_OK;
1369 }
1370 
1371 #if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
1372 static t_Error UpdateManipIc(t_Handle h_Manip, uint8_t icOffset)
1373 {
1374     t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_Manip;
1375     t_Handle p_Ad;
1376     uint32_t tmpReg32 = 0;
1377     SANITY_CHECK_RETURN_ERROR(h_Manip, E_INVALID_HANDLE);
1378     SANITY_CHECK_RETURN_ERROR(p_Manip->h_Ad, E_INVALID_HANDLE);
1379 
1380     switch (p_Manip->opcode)
1381     {
1382         case (HMAN_OC_MV_INT_FRAME_HDR_FROM_FRM_TO_BUFFER_PREFFIX):
1383         p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Ad;
1384         if (p_Manip->updateParams & INTERNAL_CONTEXT_OFFSET)
1385         {
1386             tmpReg32 =
1387             *(uint32_t *)&((t_AdOfTypeContLookup *)p_Ad)->pcAndOffsets;
1388             tmpReg32 |= (uint32_t)((uint32_t)icOffset << 16);
1389             *(uint32_t *)&((t_AdOfTypeContLookup *)p_Ad)->pcAndOffsets =
1390             tmpReg32;
1391             p_Manip->updateParams &= ~INTERNAL_CONTEXT_OFFSET;
1392             p_Manip->icOffset = icOffset;
1393         }
1394         else
1395         {
1396             if (p_Manip->icOffset != icOffset)
1397             RETURN_ERROR(
1398                     MAJOR,
1399                     E_INVALID_VALUE,
1400                     ("this manipulation was updated previously by different value"););
1401         }
1402         break;
1403         case (HMAN_OC_CAPWAP_RMV_DTLS_IF_EXIST):
1404         if (p_Manip->h_Frag)
1405         {
1406             if (p_Manip->updateParams & INTERNAL_CONTEXT_OFFSET)
1407             {
1408                 p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Ad;
1409                 tmpReg32 |= GET_UINT32(((t_AdOfTypeContLookup *)p_Ad)->pcAndOffsets);
1410                 tmpReg32 |= (uint32_t)((uint32_t)icOffset << 16);
1411                 WRITE_UINT32(((t_AdOfTypeContLookup *)p_Ad)->pcAndOffsets, tmpReg32);
1412                 p_Manip->updateParams &= ~INTERNAL_CONTEXT_OFFSET;
1413                 p_Manip->icOffset = icOffset;
1414             }
1415             else
1416             {
1417                 if (p_Manip->icOffset != icOffset)
1418                 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("this manipulation was updated previousely by different value"););
1419             }
1420         }
1421         break;
1422     }
1423 
1424     return E_OK;
1425 }
1426 
1427 static t_Error UpdateInitMvIntFrameHeaderFromFrameToBufferPrefix(
1428         t_Handle h_FmPort, t_FmPcdManip *p_Manip, t_Handle h_Ad, bool validate)
1429 {
1430 
1431     t_AdOfTypeContLookup *p_Ad = (t_AdOfTypeContLookup *)h_Ad;
1432     t_FmPortGetSetCcParams fmPortGetSetCcParams;
1433     t_Error err;
1434     uint32_t tmpReg32;
1435 
1436     memset(&fmPortGetSetCcParams, 0, sizeof(t_FmPortGetSetCcParams));
1437 
1438     SANITY_CHECK_RETURN_ERROR(p_Manip, E_INVALID_HANDLE);
1439     SANITY_CHECK_RETURN_ERROR(
1440             (p_Manip->opcode & HMAN_OC_MV_INT_FRAME_HDR_FROM_FRM_TO_BUFFER_PREFFIX),
1441             E_INVALID_STATE);
1442     SANITY_CHECK_RETURN_ERROR(!p_Manip->muramAllocate, E_INVALID_STATE);
1443 
1444     if (p_Manip->updateParams)
1445     {
1446         if ((!(p_Manip->updateParams & OFFSET_OF_PR))
1447                 || (p_Manip->shadowUpdateParams & OFFSET_OF_PR))
1448         RETURN_ERROR(
1449                 MAJOR, E_INVALID_STATE,
1450                 ("in this stage parameters from Port has not be updated"));
1451 
1452         fmPortGetSetCcParams.getCcParams.type = p_Manip->updateParams;
1453         fmPortGetSetCcParams.setCcParams.type = UPDATE_PSO;
1454         fmPortGetSetCcParams.setCcParams.psoSize = 16;
1455 
1456         err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams);
1457         if (err)
1458         RETURN_ERROR(MAJOR, err, NO_MSG);
1459         if (fmPortGetSetCcParams.getCcParams.type & OFFSET_OF_PR)
1460         RETURN_ERROR(
1461                 MAJOR, E_INVALID_STATE,
1462                 ("Parser result offset wasn't configured previousely"));
1463 #ifdef FM_LOCKUP_ALIGNMENT_ERRATA_FMAN_SW004
1464         ASSERT_COND(!(fmPortGetSetCcParams.getCcParams.prOffset % 16));
1465 #endif
1466     }
1467     else
1468     if (validate)
1469     {
1470         if ((!(p_Manip->shadowUpdateParams & OFFSET_OF_PR))
1471                 || (p_Manip->updateParams & OFFSET_OF_PR))
1472         RETURN_ERROR(
1473                 MAJOR, E_INVALID_STATE,
1474                 ("in this stage parameters from Port has be updated"));
1475         fmPortGetSetCcParams.getCcParams.type = p_Manip->shadowUpdateParams;
1476         fmPortGetSetCcParams.setCcParams.type = UPDATE_PSO;
1477         fmPortGetSetCcParams.setCcParams.psoSize = 16;
1478 
1479         err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams);
1480         if (err)
1481         RETURN_ERROR(MAJOR, err, NO_MSG);
1482         if (fmPortGetSetCcParams.getCcParams.type & OFFSET_OF_PR)
1483         RETURN_ERROR(
1484                 MAJOR, E_INVALID_STATE,
1485                 ("Parser result offset wasn't configured previousely"));
1486 
1487     }
1488 
1489     ASSERT_COND(p_Ad);
1490 
1491     if (p_Manip->updateParams & OFFSET_OF_PR)
1492     {
1493         tmpReg32 = 0;
1494         tmpReg32 |= fmPortGetSetCcParams.getCcParams.prOffset;
1495         WRITE_UINT32(p_Ad->matchTblPtr,
1496                 (GET_UINT32(p_Ad->matchTblPtr) | tmpReg32));
1497         p_Manip->updateParams &= ~OFFSET_OF_PR;
1498         p_Manip->shadowUpdateParams |= OFFSET_OF_PR;
1499     }
1500     else
1501     if (validate)
1502     {
1503         tmpReg32 = GET_UINT32(p_Ad->matchTblPtr);
1504         if ((uint8_t)tmpReg32 != fmPortGetSetCcParams.getCcParams.prOffset)
1505         RETURN_ERROR(
1506                 MAJOR,
1507                 E_INVALID_STATE,
1508                 ("this manipulation was updated previousely by different value"););
1509     }
1510 
1511     return E_OK;
1512 }
1513 
1514 static t_Error UpdateModifyCapwapFragmenation(t_FmPcdManip *p_Manip, t_Handle h_Ad, bool validate,t_Handle h_FmTree)
1515 {
1516     t_AdOfTypeContLookup *p_Ad = (t_AdOfTypeContLookup *)h_Ad;
1517     t_FmPcdCcSavedManipParams *p_SavedManipParams = NULL;
1518     uint32_t tmpReg32 = 0;
1519 
1520     SANITY_CHECK_RETURN_ERROR(p_Manip,E_INVALID_HANDLE);
1521     SANITY_CHECK_RETURN_ERROR(p_Manip->h_Frag,E_INVALID_HANDLE);
1522     SANITY_CHECK_RETURN_ERROR(p_Manip->frag,E_INVALID_HANDLE);
1523     SANITY_CHECK_RETURN_ERROR(((p_Manip->opcode == HMAN_OC_CAPWAP_FRAGMENTATION) || (p_Manip->opcode == HMAN_OC_INSRT_HDR_BY_TEMPL_N_OR_FRAG_AFTER)), E_INVALID_STATE);
1524 
1525     p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Frag;
1526 
1527     if (p_Manip->updateParams)
1528     {
1529 
1530         if ((!(p_Manip->updateParams & OFFSET_OF_DATA)) ||
1531                 ((p_Manip->shadowUpdateParams & OFFSET_OF_DATA)))
1532         RETURN_ERROR(MAJOR, E_INVALID_STATE, ("in this stage parameters from Port has not be updated"));
1533         p_SavedManipParams = FmPcdCcTreeGetSavedManipParams(h_FmTree);
1534         if (!p_SavedManipParams)
1535         RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("for this manipulation tree has to be configured previosely with this type"));
1536         p_Manip->capwapFragParams.dataOffset = p_SavedManipParams->capwapParams.dataOffset;
1537 
1538         tmpReg32 = GET_UINT32(p_Ad->pcAndOffsets);
1539         tmpReg32 |= ((uint32_t)p_Manip->capwapFragParams.dataOffset<< 16);
1540         WRITE_UINT32(p_Ad->pcAndOffsets,tmpReg32);
1541 
1542         p_Manip->updateParams &= ~OFFSET_OF_DATA;
1543         p_Manip->shadowUpdateParams |= OFFSET_OF_DATA;
1544     }
1545     else if (validate)
1546     {
1547 
1548         p_SavedManipParams = FmPcdCcTreeGetSavedManipParams(h_FmTree);
1549         if (!p_SavedManipParams)
1550         RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("for this manipulation tree has to be configured previosely with this type"));
1551         if (p_Manip->capwapFragParams.dataOffset != p_SavedManipParams->capwapParams.dataOffset)
1552         RETURN_ERROR(MAJOR, E_INVALID_STATE, ("this manipulation was updated previousely by different value"));
1553     }
1554 
1555     return E_OK;
1556 }
1557 
1558 static t_Error UpdateInitCapwapFragmentation(t_Handle h_FmPort,
1559         t_FmPcdManip *p_Manip,
1560         t_Handle h_Ad,
1561         bool validate,
1562         t_Handle h_FmTree)
1563 {
1564     t_AdOfTypeContLookup *p_Ad;
1565     t_FmPortGetSetCcParams fmPortGetSetCcParams;
1566     t_Error err;
1567     uint32_t tmpReg32 = 0;
1568     t_FmPcdCcSavedManipParams *p_SavedManipParams;
1569 
1570     UNUSED(h_Ad);
1571 
1572     SANITY_CHECK_RETURN_ERROR(p_Manip,E_INVALID_HANDLE);
1573     SANITY_CHECK_RETURN_ERROR(p_Manip->h_Frag,E_INVALID_HANDLE);
1574     SANITY_CHECK_RETURN_ERROR(p_Manip->frag,E_INVALID_HANDLE);
1575     SANITY_CHECK_RETURN_ERROR(((p_Manip->opcode == HMAN_OC_CAPWAP_FRAGMENTATION) ||
1576                     (p_Manip->opcode == HMAN_OC_INSRT_HDR_BY_TEMPL_N_OR_FRAG_AFTER)), E_INVALID_STATE);
1577 
1578     p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Frag;
1579 
1580     if (p_Manip->updateParams)
1581     {
1582         if ((!(p_Manip->updateParams & OFFSET_OF_DATA)) ||
1583                 ((p_Manip->shadowUpdateParams & OFFSET_OF_DATA)))
1584         RETURN_ERROR(MAJOR, E_INVALID_STATE, ("in this stage parameters from Port has not be updated"));
1585         fmPortGetSetCcParams.getCcParams.type = p_Manip->updateParams;
1586         fmPortGetSetCcParams.setCcParams.type = UPDATE_NIA_PNEN | UPDATE_FMFP_PRC_WITH_ONE_RISC_ONLY;
1587         fmPortGetSetCcParams.setCcParams.nia = NIA_FM_CTL_AC_POP_TO_N_STEP | NIA_ENG_FM_CTL;
1588         /* For CAPWAP Rassembly used FMAN_CTRL2 hardcoded - so for fragmentation its better to use FMAN_CTRL1 */
1589         fmPortGetSetCcParams.setCcParams.orFmanCtrl = FPM_PORT_FM_CTL1;
1590 
1591         err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams);
1592         if (err)
1593         RETURN_ERROR(MAJOR, err, NO_MSG);
1594 
1595         if (fmPortGetSetCcParams.getCcParams.type & OFFSET_OF_DATA)
1596         RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Data offset wasn't configured previousely"));
1597 
1598         p_SavedManipParams = (t_FmPcdCcSavedManipParams *)XX_Malloc(sizeof(t_FmPcdCcSavedManipParams));
1599         p_SavedManipParams->capwapParams.dataOffset = fmPortGetSetCcParams.getCcParams.dataOffset;
1600 
1601 #ifdef FM_LOCKUP_ALIGNMENT_ERRATA_FMAN_SW004
1602         ASSERT_COND(!(p_SavedManipParams->capwapParams.dataOffset % 16));
1603 #endif /* FM_LOCKUP_ALIGNMENT_ERRATA_FMAN_SW004 */
1604 
1605         FmPcdCcTreeSetSavedManipParams(h_FmTree, (t_Handle)p_SavedManipParams);
1606     }
1607     else if (validate)
1608     {
1609         if ((!(p_Manip->shadowUpdateParams & OFFSET_OF_DATA)) ||
1610                 ((p_Manip->updateParams & OFFSET_OF_DATA)))
1611         RETURN_ERROR(MAJOR, E_INVALID_STATE, ("in this stage parameters from Port has be updated"));
1612         fmPortGetSetCcParams.getCcParams.type = p_Manip->shadowUpdateParams;
1613         fmPortGetSetCcParams.setCcParams.type = UPDATE_NIA_PNEN | UPDATE_FMFP_PRC_WITH_ONE_RISC_ONLY;
1614         fmPortGetSetCcParams.setCcParams.nia = NIA_FM_CTL_AC_POP_TO_N_STEP | NIA_ENG_FM_CTL;
1615         err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams);
1616         if (err)
1617         RETURN_ERROR(MAJOR, err, NO_MSG);
1618 
1619         if (fmPortGetSetCcParams.getCcParams.type & OFFSET_OF_DATA)
1620         RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Data offset wasn't configured previousely"));
1621     }
1622 
1623     if (p_Manip->updateParams)
1624     {
1625         tmpReg32 = GET_UINT32(p_Ad->pcAndOffsets);
1626         tmpReg32 |= ((uint32_t)fmPortGetSetCcParams.getCcParams.dataOffset<< 16);
1627         WRITE_UINT32(p_Ad->pcAndOffsets,tmpReg32);
1628 
1629         p_Manip->updateParams &= ~OFFSET_OF_DATA;
1630         p_Manip->shadowUpdateParams |= OFFSET_OF_DATA;
1631         p_Manip->capwapFragParams.dataOffset = fmPortGetSetCcParams.getCcParams.dataOffset;
1632     }
1633     else if (validate)
1634     {
1635         if (p_Manip->capwapFragParams.dataOffset != fmPortGetSetCcParams.getCcParams.dataOffset)
1636         RETURN_ERROR(MAJOR, E_INVALID_STATE, ("this manipulation was updated previousely by different value"));
1637     }
1638 
1639     return E_OK;
1640 }
1641 
1642 static t_Error UpdateInitCapwapReasm(t_Handle h_FmPcd,
1643         t_Handle h_FmPort,
1644         t_FmPcdManip *p_Manip,
1645         t_Handle h_Ad,
1646         bool validate)
1647 {
1648     t_CapwapReasmPram *p_ReassmTbl;
1649     t_Error err;
1650     t_FmPortGetSetCcParams fmPortGetSetCcParams;
1651     uint8_t i = 0;
1652     uint16_t size;
1653     uint32_t tmpReg32;
1654     t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
1655     t_FmPcdCcCapwapReassmTimeoutParams ccCapwapReassmTimeoutParams;
1656 
1657     SANITY_CHECK_RETURN_ERROR(p_Manip,E_INVALID_HANDLE);
1658     SANITY_CHECK_RETURN_ERROR(p_Manip->h_Frag,E_INVALID_HANDLE);
1659     SANITY_CHECK_RETURN_ERROR(!p_Manip->frag,E_INVALID_HANDLE);
1660     SANITY_CHECK_RETURN_ERROR((p_Manip->opcode == HMAN_OC_CAPWAP_RMV_DTLS_IF_EXIST), E_INVALID_STATE);
1661     SANITY_CHECK_RETURN_ERROR(h_FmPcd,E_INVALID_HANDLE);
1662     SANITY_CHECK_RETURN_ERROR(p_FmPcd->h_Hc,E_INVALID_HANDLE);
1663 
1664     if (p_Manip->h_FmPcd != h_FmPcd)
1665     RETURN_ERROR(MAJOR, E_INVALID_STATE,
1666             ("handler of PCD previously was initiated by different value"));
1667 
1668     UNUSED(h_Ad);
1669 
1670     memset(&fmPortGetSetCcParams, 0, sizeof(t_FmPortGetSetCcParams));
1671     p_ReassmTbl = (t_CapwapReasmPram *)p_Manip->h_Frag;
1672 
1673     if (p_Manip->updateParams)
1674     {
1675         if ((!(p_Manip->updateParams & NUM_OF_TASKS) &&
1676                         !(p_Manip->updateParams & OFFSET_OF_DATA) &&
1677                         !(p_Manip->updateParams & OFFSET_OF_PR) &&
1678                         !(p_Manip->updateParams & HW_PORT_ID)) ||
1679                 ((p_Manip->shadowUpdateParams & NUM_OF_TASKS) ||
1680                         (p_Manip->shadowUpdateParams & OFFSET_OF_DATA) || (p_Manip->shadowUpdateParams & OFFSET_OF_PR) ||
1681                         (p_Manip->shadowUpdateParams & HW_PORT_ID)))
1682         RETURN_ERROR(MAJOR, E_INVALID_STATE, ("in this stage parameters from Port has not be updated"));
1683 
1684         fmPortGetSetCcParams.getCcParams.type = p_Manip->updateParams;
1685         fmPortGetSetCcParams.setCcParams.type = UPDATE_NIA_PNEN;
1686         fmPortGetSetCcParams.setCcParams.nia = NIA_FM_CTL_AC_POP_TO_N_STEP | NIA_ENG_FM_CTL;
1687 
1688         err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams);
1689         if (err)
1690         RETURN_ERROR(MAJOR, err, NO_MSG);
1691 
1692         if (fmPortGetSetCcParams.getCcParams.type & NUM_OF_TASKS)
1693         RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Num of tasks wasn't configured previousely"));
1694         if (fmPortGetSetCcParams.getCcParams.type & OFFSET_OF_DATA)
1695         RETURN_ERROR(MAJOR, E_INVALID_STATE, ("offset of the data  wasn't configured previousely"));
1696         if (fmPortGetSetCcParams.getCcParams.type & HW_PORT_ID)
1697         RETURN_ERROR(MAJOR, E_INVALID_STATE, ("hwPortId wasn't updated"));
1698 #ifdef FM_LOCKUP_ALIGNMENT_ERRATA_FMAN_SW004
1699         ASSERT_COND((fmPortGetSetCcParams.getCcParams.dataOffset % 16) == 0);
1700 #endif /* FM_LOCKUP_ALIGNMENT_ERRATA_FMAN_SW004 */
1701     }
1702     else if (validate)
1703     {
1704         if ((!(p_Manip->shadowUpdateParams & NUM_OF_TASKS) &&
1705                         !(p_Manip->shadowUpdateParams & OFFSET_OF_DATA) &&
1706                         !(p_Manip->shadowUpdateParams & OFFSET_OF_PR) &&
1707                         !(p_Manip->shadowUpdateParams & HW_PORT_ID)) &&
1708                 ((p_Manip->updateParams & NUM_OF_TASKS) ||
1709                         (p_Manip->updateParams & OFFSET_OF_DATA) || (p_Manip->updateParams & OFFSET_OF_PR) ||
1710                         (p_Manip->updateParams & HW_PORT_ID)))
1711         RETURN_ERROR(MAJOR, E_INVALID_STATE, ("in this stage parameters from Port has be updated"));
1712 
1713         fmPortGetSetCcParams.getCcParams.type = p_Manip->shadowUpdateParams;
1714         fmPortGetSetCcParams.setCcParams.type = UPDATE_NIA_PNEN;
1715         fmPortGetSetCcParams.setCcParams.nia = NIA_FM_CTL_AC_POP_TO_N_STEP | NIA_ENG_FM_CTL;
1716 
1717         err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams);
1718         if (err)
1719         RETURN_ERROR(MAJOR, err, NO_MSG);
1720 
1721         if (fmPortGetSetCcParams.getCcParams.type & NUM_OF_TASKS)
1722         RETURN_ERROR(MAJOR, E_INVALID_STATE, ("NumOfTasks wasn't configured previously"));
1723         if (fmPortGetSetCcParams.getCcParams.type & OFFSET_OF_DATA)
1724         RETURN_ERROR(MAJOR, E_INVALID_STATE, ("offset of the data  wasn't configured previously"));
1725         if (fmPortGetSetCcParams.getCcParams.type & HW_PORT_ID)
1726         RETURN_ERROR(MAJOR, E_INVALID_STATE, ("hwPortId wasn't updated"));
1727     }
1728 
1729     if (p_Manip->updateParams)
1730     {
1731         if (p_Manip->updateParams & NUM_OF_TASKS)
1732         {
1733             /*recommendation of Microcode team - (maxNumFramesInProcess * 2) */
1734             size = (uint16_t)(p_Manip->capwapFragParams.maxNumFramesInProcess*2 + fmPortGetSetCcParams.getCcParams.numOfTasks);
1735             if (size > 255)
1736             RETURN_ERROR(MAJOR,E_INVALID_VALUE, ("numOfOpenReassmEntries + numOfTasks per port can not be greater than 256"));
1737 
1738             p_Manip->capwapFragParams.numOfTasks = fmPortGetSetCcParams.getCcParams.numOfTasks;
1739 
1740             /*p_ReassmFrmDescrIndxPoolTbl*/
1741             p_Manip->capwapFragParams.p_ReassmFrmDescrIndxPoolTbl =
1742             (t_Handle)FM_MURAM_AllocMem(p_FmPcd->h_FmMuram,
1743                     (uint32_t)(size + 1),
1744                     4);
1745             if (!p_Manip->capwapFragParams.p_ReassmFrmDescrIndxPoolTbl)
1746             RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM alloc for CAPWAP Reassembly frame buffer index pool table"));
1747 
1748             MemSet8(p_Manip->capwapFragParams.p_ReassmFrmDescrIndxPoolTbl, 0, (uint32_t)(size + 1));
1749 
1750             for ( i = 0; i < size; i++)
1751             WRITE_UINT8(*(uint8_t *)PTR_MOVE(p_Manip->capwapFragParams.p_ReassmFrmDescrIndxPoolTbl, i), (uint8_t)(i+1));
1752 
1753             tmpReg32 = (uint32_t)(XX_VirtToPhys(p_Manip->capwapFragParams.p_ReassmFrmDescrIndxPoolTbl) - p_FmPcd->physicalMuramBase);
1754 
1755             WRITE_UINT32(p_ReassmTbl->reasmFrmDescIndexPoolTblPtr, tmpReg32);
1756 
1757             /*p_ReassmFrmDescrPoolTbl*/
1758             p_Manip->capwapFragParams.p_ReassmFrmDescrPoolTbl =
1759             (t_Handle)FM_MURAM_AllocMem(p_FmPcd->h_FmMuram,
1760                     (uint32_t)((size + 1) * FM_PCD_MANIP_CAPWAP_REASM_RFD_SIZE),
1761                     4);
1762 
1763             if (!p_Manip->capwapFragParams.p_ReassmFrmDescrPoolTbl)
1764             RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM alloc for CAPWAP Reassembly frame buffer pool table"));
1765 
1766             MemSet8(p_Manip->capwapFragParams.p_ReassmFrmDescrPoolTbl, 0, (uint32_t)((size +1)* FM_PCD_MANIP_CAPWAP_REASM_RFD_SIZE));
1767 
1768             tmpReg32 = (uint32_t)(XX_VirtToPhys(p_Manip->capwapFragParams.p_ReassmFrmDescrPoolTbl) - p_FmPcd->physicalMuramBase);
1769 
1770             WRITE_UINT32(p_ReassmTbl->reasmFrmDescPoolTblPtr, tmpReg32);
1771 
1772             /*p_TimeOutTbl*/
1773 
1774             p_Manip->capwapFragParams.p_TimeOutTbl =
1775             (t_Handle)FM_MURAM_AllocMem(p_FmPcd->h_FmMuram,
1776                     (uint32_t)((size + 1)* FM_PCD_MANIP_CAPWAP_REASM_TIME_OUT_ENTRY_SIZE),
1777                     4);
1778 
1779             if (!p_Manip->capwapFragParams.p_TimeOutTbl)
1780             RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM alloc for CAPWAP Reassembly timeout table"));
1781 
1782             MemSet8(p_Manip->capwapFragParams.p_TimeOutTbl, 0, (uint16_t)((size + 1)*FM_PCD_MANIP_CAPWAP_REASM_TIME_OUT_ENTRY_SIZE));
1783 
1784             tmpReg32 = (uint32_t)(XX_VirtToPhys(p_Manip->capwapFragParams.p_TimeOutTbl) - p_FmPcd->physicalMuramBase);
1785             WRITE_UINT32(p_ReassmTbl->timeOutTblPtr, tmpReg32);
1786 
1787             p_Manip->updateParams &= ~NUM_OF_TASKS;
1788             p_Manip->shadowUpdateParams |= NUM_OF_TASKS;
1789         }
1790 
1791         if (p_Manip->updateParams & OFFSET_OF_DATA)
1792         {
1793             p_Manip->capwapFragParams.dataOffset = fmPortGetSetCcParams.getCcParams.dataOffset;
1794             tmpReg32 = GET_UINT32(p_ReassmTbl->mode);
1795             tmpReg32|= p_Manip->capwapFragParams.dataOffset;
1796             WRITE_UINT32(p_ReassmTbl->mode, tmpReg32);
1797             p_Manip->updateParams &= ~OFFSET_OF_DATA;
1798             p_Manip->shadowUpdateParams |= OFFSET_OF_DATA;
1799         }
1800 
1801         if (!(fmPortGetSetCcParams.getCcParams.type & OFFSET_OF_PR))
1802         {
1803             p_Manip->capwapFragParams.prOffset = fmPortGetSetCcParams.getCcParams.prOffset;
1804 
1805             tmpReg32 = GET_UINT32(p_ReassmTbl->mode);
1806             tmpReg32|= FM_PCD_MANIP_CAPWAP_REASM_PR_COPY;
1807             WRITE_UINT32(p_ReassmTbl->mode, tmpReg32);
1808 
1809             tmpReg32 = GET_UINT32(p_ReassmTbl->intStatsTblPtr);
1810             tmpReg32 |= (uint32_t)p_Manip->capwapFragParams.prOffset << 24;
1811             WRITE_UINT32(p_ReassmTbl->intStatsTblPtr, tmpReg32);
1812             p_Manip->updateParams &= ~OFFSET_OF_PR;
1813             p_Manip->shadowUpdateParams |= OFFSET_OF_PR;
1814         }
1815         else
1816         {
1817             p_Manip->capwapFragParams.prOffset = 0xff;
1818             p_Manip->updateParams &= ~OFFSET_OF_PR;
1819             p_Manip->shadowUpdateParams |= OFFSET_OF_PR;
1820         }
1821 
1822         p_Manip->capwapFragParams.hwPortId = fmPortGetSetCcParams.getCcParams.hardwarePortId;
1823         p_Manip->updateParams &= ~HW_PORT_ID;
1824         p_Manip->shadowUpdateParams |= HW_PORT_ID;
1825 
1826         /*timeout hc */
1827         ccCapwapReassmTimeoutParams.fqidForTimeOutFrames = p_Manip->capwapFragParams.fqidForTimeOutFrames;
1828         ccCapwapReassmTimeoutParams.portIdAndCapwapReassmTbl = (uint32_t)p_Manip->capwapFragParams.hwPortId << 24;
1829         ccCapwapReassmTimeoutParams.portIdAndCapwapReassmTbl |= (uint32_t)((XX_VirtToPhys(p_ReassmTbl) - p_FmPcd->physicalMuramBase));
1830         ccCapwapReassmTimeoutParams.timeoutRequestTime = (((uint32_t)1<<p_Manip->capwapFragParams.bitFor1Micro) * p_Manip->capwapFragParams.timeoutRoutineRequestTime)/2;
1831         return FmHcPcdCcCapwapTimeoutReassm(p_FmPcd->h_Hc,&ccCapwapReassmTimeoutParams);
1832     }
1833 
1834     else if (validate)
1835     {
1836         if (fmPortGetSetCcParams.getCcParams.hardwarePortId != p_Manip->capwapFragParams.hwPortId)
1837         RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Reassembly manipulation previously was assigned to another port"));
1838         if (fmPortGetSetCcParams.getCcParams.numOfTasks != p_Manip->capwapFragParams.numOfTasks)
1839         RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("numOfTasks for this manipulation previously was defined by another value "));
1840 
1841         if (!(fmPortGetSetCcParams.getCcParams.type & OFFSET_OF_PR))
1842         {
1843             if (p_Manip->capwapFragParams.prOffset != fmPortGetSetCcParams.getCcParams.prOffset)
1844             RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Parse result offset previously was defined by another value "));
1845         }
1846         else
1847         {
1848             if (p_Manip->capwapFragParams.prOffset != 0xff)
1849             RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Parse result offset previously was defined by another value "));
1850         }
1851         if (fmPortGetSetCcParams.getCcParams.dataOffset != p_Manip->capwapFragParams.dataOffset)
1852         RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Data offset previously was defined by another value "));
1853     }
1854 
1855     return E_OK;
1856 }
1857 #endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */
1858 
1859 t_Error FmPcdRegisterReassmPort(t_Handle h_FmPcd, t_Handle h_ReasmCommonPramTbl)
1860 {
1861     t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
1862     t_FmPcdCcReassmTimeoutParams ccReassmTimeoutParams = { 0 };
1863     t_Error err = E_OK;
1864     uint8_t result;
1865     uint32_t bitFor1Micro, tsbs, log2num;
1866 
1867     ASSERT_COND(p_FmPcd);
1868     ASSERT_COND(h_ReasmCommonPramTbl);
1869 
1870     bitFor1Micro = FmGetTimeStampScale(p_FmPcd->h_Fm);
1871     if (bitFor1Micro == 0)
1872         RETURN_ERROR(MAJOR, E_NOT_AVAILABLE, ("Timestamp scale"));
1873 
1874     bitFor1Micro = 32 - bitFor1Micro;
1875     LOG2(FM_PCD_MANIP_REASM_TIMEOUT_THREAD_THRESH, log2num);
1876     tsbs = bitFor1Micro - log2num;
1877 
1878     ccReassmTimeoutParams.iprcpt = (uint32_t)(XX_VirtToPhys(
1879             h_ReasmCommonPramTbl) - p_FmPcd->physicalMuramBase);
1880     ccReassmTimeoutParams.tsbs = (uint8_t)tsbs;
1881     ccReassmTimeoutParams.activate = TRUE;
1882     if ((err = FmHcPcdCcTimeoutReassm(p_FmPcd->h_Hc, &ccReassmTimeoutParams,
1883                                       &result)) != E_OK)
1884         RETURN_ERROR(MAJOR, err, NO_MSG);
1885 
1886     switch (result)
1887     {
1888         case (0):
1889             return E_OK;
1890         case (1):
1891             RETURN_ERROR(MAJOR, E_NO_MEMORY, ("failed to allocate TNUM"));
1892         case (2):
1893             RETURN_ERROR(
1894                     MAJOR, E_NO_MEMORY,
1895                     ("failed to allocate internal buffer from the HC-Port"));
1896         case (3):
1897             RETURN_ERROR(MAJOR, E_INVALID_VALUE,
1898                          ("'Disable Timeout Task' with invalid IPRCPT"));
1899         case (4):
1900             RETURN_ERROR(MAJOR, E_FULL, ("too many timeout tasks"));
1901         case (5):
1902             RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("invalid sub command"));
1903         default:
1904             RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG);
1905     }
1906     return E_OK;
1907 }
1908 
1909 static t_Error CreateReassCommonTable(t_FmPcdManip *p_Manip)
1910 {
1911     uint32_t tmpReg32 = 0, i, bitFor1Micro;
1912     uint64_t tmpReg64, size;
1913     t_FmPcd *p_FmPcd = (t_FmPcd *)p_Manip->h_FmPcd;
1914     t_Error err = E_OK;
1915 
1916     bitFor1Micro = FmGetTimeStampScale(p_FmPcd->h_Fm);
1917     if (bitFor1Micro == 0)
1918         RETURN_ERROR(MAJOR, E_NOT_AVAILABLE, ("Timestamp scale"));
1919 
1920     /* Allocation of the Reassembly Common Parameters table. This table is located in the
1921      MURAM. Its size is 64 bytes and its base address should be 8-byte aligned. */
1922     p_Manip->reassmParams.p_ReassCommonTbl =
1923             (t_ReassCommonTbl *)FM_MURAM_AllocMem(
1924                     p_FmPcd->h_FmMuram,
1925                     FM_PCD_MANIP_REASM_COMMON_PARAM_TABLE_SIZE,
1926                     FM_PCD_MANIP_REASM_COMMON_PARAM_TABLE_ALIGN);
1927 
1928     if (!p_Manip->reassmParams.p_ReassCommonTbl)
1929         RETURN_ERROR(MAJOR, E_NO_MEMORY,
1930                      ("MURAM alloc for Reassembly common parameters table"));
1931 
1932     MemSet8(p_Manip->reassmParams.p_ReassCommonTbl, 0,
1933                FM_PCD_MANIP_REASM_COMMON_PARAM_TABLE_SIZE);
1934 
1935     /* Setting the TimeOut Mode.*/
1936     tmpReg32 = 0;
1937     if (p_Manip->reassmParams.timeOutMode
1938             == e_FM_PCD_MANIP_TIME_OUT_BETWEEN_FRAMES)
1939         tmpReg32 |= FM_PCD_MANIP_REASM_TIME_OUT_BETWEEN_FRAMES;
1940 
1941     /* Setting TimeOut FQID - Frames that time out are enqueued to this FQID.
1942      In order to cause TimeOut frames to be discarded, this queue should be configured accordingly*/
1943     tmpReg32 |= p_Manip->reassmParams.fqidForTimeOutFrames;
1944     WRITE_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->timeoutModeAndFqid,
1945                  tmpReg32);
1946 
1947     /* Calculation the size of IP Reassembly Frame Descriptor - number of frames that are allowed to be reassembled simultaneously + 129.*/
1948     size = p_Manip->reassmParams.maxNumFramesInProcess + 129;
1949 
1950     /*Allocation of IP Reassembly Frame Descriptor Indexes Pool - This pool resides in the MURAM */
1951     p_Manip->reassmParams.reassFrmDescrIndxPoolTblAddr =
1952             PTR_TO_UINT(FM_MURAM_AllocMem(p_FmPcd->h_FmMuram,
1953                             (uint32_t)(size * 2),
1954                             256));
1955     if (!p_Manip->reassmParams.reassFrmDescrIndxPoolTblAddr)
1956         RETURN_ERROR(
1957                 MAJOR, E_NO_MEMORY,
1958                 ("MURAM alloc for Reassembly frame descriptor indexes pool"));
1959 
1960     MemSet8(UINT_TO_PTR(p_Manip->reassmParams.reassFrmDescrIndxPoolTblAddr),
1961                0, (uint32_t)(size * 2));
1962 
1963     /* The entries in IP Reassembly Frame Descriptor Indexes Pool contains indexes starting with 1 up to
1964      the maximum number of frames that are allowed to be reassembled simultaneously + 128.
1965      The last entry in this pool must contain the index zero*/
1966     for (i = 0; i < (size - 1); i++)
1967         WRITE_UINT16(
1968                 *(uint16_t *)PTR_MOVE(UINT_TO_PTR(p_Manip->reassmParams.reassFrmDescrIndxPoolTblAddr), (i<<1)),
1969                 (uint16_t)(i+1));
1970 
1971     /* Sets the IP Reassembly Frame Descriptor Indexes Pool offset from MURAM */
1972     tmpReg32 = (uint32_t)(XX_VirtToPhys(
1973             UINT_TO_PTR(p_Manip->reassmParams.reassFrmDescrIndxPoolTblAddr))
1974             - p_FmPcd->physicalMuramBase);
1975     WRITE_UINT32(
1976             p_Manip->reassmParams.p_ReassCommonTbl->reassFrmDescIndexPoolTblPtr,
1977             tmpReg32);
1978 
1979     /* Allocation of the Reassembly Frame Descriptors Pool - This pool resides in external memory.
1980      The number of entries in this pool should be equal to the number of entries in IP Reassembly Frame Descriptor Indexes Pool.*/
1981     p_Manip->reassmParams.reassFrmDescrPoolTblAddr =
1982             PTR_TO_UINT(XX_MallocSmart((uint32_t)(size * 64), p_Manip->reassmParams.dataMemId, 64));
1983 
1984     if (!p_Manip->reassmParams.reassFrmDescrPoolTblAddr)
1985         RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Memory allocation FAILED"));
1986 
1987     MemSet8(UINT_TO_PTR(p_Manip->reassmParams.reassFrmDescrPoolTblAddr), 0,
1988                (uint32_t)(size * 64));
1989 
1990     /* Sets the Reassembly Frame Descriptors Pool and liodn offset*/
1991     tmpReg64 = (uint64_t)(XX_VirtToPhys(
1992             UINT_TO_PTR(p_Manip->reassmParams.reassFrmDescrPoolTblAddr)));
1993     tmpReg64 |= ((uint64_t)(p_Manip->reassmParams.dataLiodnOffset
1994             & FM_PCD_MANIP_REASM_LIODN_MASK)
1995             << (uint64_t)FM_PCD_MANIP_REASM_LIODN_SHIFT);
1996     tmpReg64 |= ((uint64_t)(p_Manip->reassmParams.dataLiodnOffset
1997             & FM_PCD_MANIP_REASM_ELIODN_MASK)
1998             << (uint64_t)FM_PCD_MANIP_REASM_ELIODN_SHIFT);
1999     WRITE_UINT32(
2000             p_Manip->reassmParams.p_ReassCommonTbl->liodnAndReassFrmDescPoolPtrHi,
2001             (uint32_t)(tmpReg64 >> 32));
2002     WRITE_UINT32(
2003             p_Manip->reassmParams.p_ReassCommonTbl->reassFrmDescPoolPtrLow,
2004             (uint32_t)tmpReg64);
2005 
2006     /*Allocation of the TimeOut table - This table resides in the MURAM.
2007      The number of entries in this table is identical to the number of entries in the Reassembly Frame Descriptors Pool*/
2008     p_Manip->reassmParams.timeOutTblAddr =
2009             PTR_TO_UINT(FM_MURAM_AllocMem(p_FmPcd->h_FmMuram, (uint32_t)(size * 8),8));
2010 
2011     if (!p_Manip->reassmParams.timeOutTblAddr)
2012         RETURN_ERROR(MAJOR, E_NO_MEMORY,
2013                      ("MURAM alloc for Reassembly timeout table"));
2014 
2015     MemSet8(UINT_TO_PTR(p_Manip->reassmParams.timeOutTblAddr), 0,
2016                (uint16_t)(size * 8));
2017 
2018     /* Sets the TimeOut table offset from MURAM */
2019     tmpReg32 = (uint32_t)(XX_VirtToPhys(
2020             UINT_TO_PTR(p_Manip->reassmParams.timeOutTblAddr))
2021             - p_FmPcd->physicalMuramBase);
2022     WRITE_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->timeOutTblPtr,
2023                  tmpReg32);
2024 
2025     /* Sets the Expiration Delay */
2026     tmpReg32 = 0;
2027     tmpReg32 |= (((uint32_t)(1 << bitFor1Micro))
2028             * p_Manip->reassmParams.timeoutThresholdForReassmProcess);
2029     WRITE_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->expirationDelay,
2030                  tmpReg32);
2031 
2032     err = FmPcdRegisterReassmPort(p_FmPcd,
2033                                   p_Manip->reassmParams.p_ReassCommonTbl);
2034     if (err != E_OK)
2035     {
2036         FM_MURAM_FreeMem(p_FmPcd->h_FmMuram,
2037                          p_Manip->reassmParams.p_ReassCommonTbl);
2038         RETURN_ERROR(MAJOR, err, ("port registration"));
2039     }
2040 
2041     return err;
2042 }
2043 
2044 static t_Error CreateReassTable(t_FmPcdManip *p_Manip, e_NetHeaderType hdr)
2045 {
2046     t_FmPcd *p_FmPcd = p_Manip->h_FmPcd;
2047     uint32_t tmpReg32, autoLearnHashTblSize;
2048     uint32_t numOfWays, setSize, setSizeCode, keySize;
2049     uint32_t waySize, numOfSets, numOfEntries;
2050     uint64_t tmpReg64;
2051     uint16_t minFragSize;
2052     uint16_t maxReassemSize;
2053     uintptr_t *p_AutoLearnHashTblAddr, *p_AutoLearnSetLockTblAddr;
2054     t_ReassTbl **p_ReassTbl;
2055 
2056     switch (hdr)
2057     {
2058         case HEADER_TYPE_IPv4:
2059             p_ReassTbl = &p_Manip->reassmParams.ip.p_Ipv4ReassTbl;
2060             p_AutoLearnHashTblAddr =
2061                     &p_Manip->reassmParams.ip.ipv4AutoLearnHashTblAddr;
2062             p_AutoLearnSetLockTblAddr =
2063                     &p_Manip->reassmParams.ip.ipv4AutoLearnSetLockTblAddr;
2064             minFragSize = p_Manip->reassmParams.ip.minFragSize[0];
2065             maxReassemSize = 0;
2066             numOfWays = p_Manip->reassmParams.ip.numOfFramesPerHashEntry[0];
2067             keySize = 4 + 4 + 1 + 2; /* 3-tuple + IP-Id */
2068             break;
2069         case HEADER_TYPE_IPv6:
2070             p_ReassTbl = &p_Manip->reassmParams.ip.p_Ipv6ReassTbl;
2071             p_AutoLearnHashTblAddr =
2072                     &p_Manip->reassmParams.ip.ipv6AutoLearnHashTblAddr;
2073             p_AutoLearnSetLockTblAddr =
2074                     &p_Manip->reassmParams.ip.ipv6AutoLearnSetLockTblAddr;
2075             minFragSize = p_Manip->reassmParams.ip.minFragSize[1];
2076             maxReassemSize = 0;
2077             numOfWays = p_Manip->reassmParams.ip.numOfFramesPerHashEntry[1];
2078             keySize = 16 + 16 + 4; /* 2-tuple + IP-Id */
2079             if (numOfWays > e_FM_PCD_MANIP_SIX_WAYS_HASH)
2080                 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("num of ways"));
2081             break;
2082         case HEADER_TYPE_CAPWAP:
2083             p_ReassTbl = &p_Manip->reassmParams.capwap.p_ReassTbl;
2084             p_AutoLearnHashTblAddr =
2085                     &p_Manip->reassmParams.capwap.autoLearnHashTblAddr;
2086             p_AutoLearnSetLockTblAddr =
2087                     &p_Manip->reassmParams.capwap.autoLearnSetLockTblAddr;
2088             minFragSize = 0;
2089             maxReassemSize = p_Manip->reassmParams.capwap.maxRessembledsSize;
2090             numOfWays = p_Manip->reassmParams.capwap.numOfFramesPerHashEntry;
2091             keySize = 4;
2092             break;
2093         default:
2094             RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("header type"));
2095     }
2096     keySize += 2; /* 2 bytes reserved for RFDIndex */
2097 #if (DPAA_VERSION >= 11)
2098     keySize += 2; /* 2 bytes reserved */
2099 #endif /* (DPAA_VERSION >= 11) */
2100     waySize = ROUND_UP(keySize, 8);
2101 
2102     /* Allocates the Reassembly Parameters Table - This table is located in the MURAM.*/
2103     *p_ReassTbl = (t_ReassTbl *)FM_MURAM_AllocMem(
2104             p_FmPcd->h_FmMuram, FM_PCD_MANIP_REASM_TABLE_SIZE,
2105             FM_PCD_MANIP_REASM_TABLE_ALIGN);
2106     if (!*p_ReassTbl)
2107         RETURN_ERROR( MAJOR, E_NO_MEMORY,
2108                      ("MURAM alloc for Reassembly specific parameters table"));
2109     memset(*p_ReassTbl, 0, sizeof(t_ReassTbl));
2110 
2111     /* Sets the Reassembly common Parameters table offset from MURAM in the Reassembly Table descriptor*/
2112     tmpReg32 = (uint32_t)(XX_VirtToPhys(p_Manip->reassmParams.p_ReassCommonTbl)
2113             - p_FmPcd->physicalMuramBase);
2114     WRITE_UINT32((*p_ReassTbl)->reassCommonPrmTblPtr, tmpReg32);
2115 
2116     /* Calculate set size (set size is rounded-up to next power of 2) */
2117     NEXT_POWER_OF_2(numOfWays * waySize, setSize);
2118 
2119     /* Get set size code */
2120     LOG2(setSize, setSizeCode);
2121 
2122     /* Sets ways number and set size code */
2123     WRITE_UINT16((*p_ReassTbl)->waysNumAndSetSize,
2124                  (uint16_t)((numOfWays << 8) | setSizeCode));
2125 
2126     /* It is recommended that the total number of entries in this table
2127      (number of sets * number of ways) will be twice the number of frames that
2128      are expected to be reassembled simultaneously.*/
2129     numOfEntries = (uint32_t)(p_Manip->reassmParams.maxNumFramesInProcess * 2);
2130 
2131     /* sets number calculation - number of entries = number of sets * number of ways */
2132     numOfSets = numOfEntries / numOfWays;
2133 
2134     /* Sets AutoLearnHashKeyMask*/
2135     NEXT_POWER_OF_2(numOfSets, numOfSets);
2136 
2137     WRITE_UINT16((*p_ReassTbl)->autoLearnHashKeyMask,
2138                  (uint16_t)(numOfSets - 1));
2139 
2140     /* Allocation of Reassembly Automatic Learning Hash Table - This table resides in external memory.
2141      The size of this table is determined by the number of sets and the set size.
2142      Table size = set size * number of sets
2143      This table base address should be aligned to SetSize.*/
2144     autoLearnHashTblSize = numOfSets * setSize;
2145 
2146     *p_AutoLearnHashTblAddr =
2147             PTR_TO_UINT(XX_MallocSmart(autoLearnHashTblSize, p_Manip->reassmParams.dataMemId, setSize));
2148     if (!*p_AutoLearnHashTblAddr)
2149     {
2150         FM_MURAM_FreeMem(p_FmPcd->h_FmMuram, *p_ReassTbl);
2151         *p_ReassTbl = NULL;
2152         RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Memory allocation FAILED"));
2153     }
2154     MemSet8(UINT_TO_PTR(*p_AutoLearnHashTblAddr), 0, autoLearnHashTblSize);
2155 
2156     /* Sets the Reassembly Automatic Learning Hash Table and liodn offset */
2157     tmpReg64 = ((uint64_t)(p_Manip->reassmParams.dataLiodnOffset
2158             & FM_PCD_MANIP_REASM_LIODN_MASK)
2159             << (uint64_t)FM_PCD_MANIP_REASM_LIODN_SHIFT);
2160     tmpReg64 |= ((uint64_t)(p_Manip->reassmParams.dataLiodnOffset
2161             & FM_PCD_MANIP_REASM_ELIODN_MASK)
2162             << (uint64_t)FM_PCD_MANIP_REASM_ELIODN_SHIFT);
2163     tmpReg64 |= XX_VirtToPhys(UINT_TO_PTR(*p_AutoLearnHashTblAddr));
2164     WRITE_UINT32( (*p_ReassTbl)->liodnAlAndAutoLearnHashTblPtrHi,
2165                  (uint32_t)(tmpReg64 >> 32));
2166     WRITE_UINT32((*p_ReassTbl)->autoLearnHashTblPtrLow, (uint32_t)tmpReg64);
2167 
2168     /* Allocation of the Set Lock table - This table resides in external memory
2169      The size of this table is (number of sets in the Reassembly Automatic Learning Hash table)*4 bytes.
2170      This table resides in external memory and its base address should be 4-byte aligned */
2171     *p_AutoLearnSetLockTblAddr =
2172             PTR_TO_UINT(XX_MallocSmart((uint32_t)(numOfSets * 4), p_Manip->reassmParams.dataMemId, 4));
2173     if (!*p_AutoLearnSetLockTblAddr)
2174     {
2175         FM_MURAM_FreeMem(p_FmPcd->h_FmMuram, *p_ReassTbl);
2176         *p_ReassTbl = NULL;
2177         XX_FreeSmart(UINT_TO_PTR(*p_AutoLearnHashTblAddr));
2178         *p_AutoLearnHashTblAddr = 0;
2179         RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Memory allocation FAILED"));
2180     }
2181     MemSet8(UINT_TO_PTR(*p_AutoLearnSetLockTblAddr), 0, (numOfSets * 4));
2182 
2183     /* sets Set Lock table pointer and liodn offset*/
2184     tmpReg64 = ((uint64_t)(p_Manip->reassmParams.dataLiodnOffset
2185             & FM_PCD_MANIP_REASM_LIODN_MASK)
2186             << (uint64_t)FM_PCD_MANIP_REASM_LIODN_SHIFT);
2187     tmpReg64 |= ((uint64_t)(p_Manip->reassmParams.dataLiodnOffset
2188             & FM_PCD_MANIP_REASM_ELIODN_MASK)
2189             << (uint64_t)FM_PCD_MANIP_REASM_ELIODN_SHIFT);
2190     tmpReg64 |= XX_VirtToPhys(UINT_TO_PTR(*p_AutoLearnSetLockTblAddr));
2191     WRITE_UINT32( (*p_ReassTbl)->liodnSlAndAutoLearnSetLockTblPtrHi,
2192                  (uint32_t)(tmpReg64 >> 32));
2193     WRITE_UINT32((*p_ReassTbl)->autoLearnSetLockTblPtrLow, (uint32_t)tmpReg64);
2194 
2195     /* Sets user's requested minimum fragment size (in Bytes) for First/Middle fragment */
2196     WRITE_UINT16((*p_ReassTbl)->minFragSize, minFragSize);
2197 
2198     WRITE_UINT16((*p_ReassTbl)->maxReassemblySize, maxReassemSize);
2199 
2200     return E_OK;
2201 }
2202 
2203 static t_Error UpdateInitReasm(t_Handle h_FmPcd, t_Handle h_PcdParams,
2204                                t_Handle h_FmPort, t_FmPcdManip *p_Manip,
2205                                t_Handle h_Ad, bool validate)
2206 {
2207     t_FmPortGetSetCcParams fmPortGetSetCcParams;
2208     uint32_t tmpReg32;
2209     t_Error err;
2210     t_FmPortPcdParams *p_PcdParams = (t_FmPortPcdParams *)h_PcdParams;
2211 #if (DPAA_VERSION >= 11)
2212     t_FmPcdCtrlParamsPage *p_ParamsPage;
2213 #endif /* (DPAA_VERSION >= 11) */
2214 
2215     SANITY_CHECK_RETURN_ERROR(p_Manip, E_INVALID_HANDLE);
2216     SANITY_CHECK_RETURN_ERROR(!p_Manip->frag, E_INVALID_HANDLE);
2217     SANITY_CHECK_RETURN_ERROR(
2218             (p_Manip->opcode == HMAN_OC_IP_REASSEMBLY) || (p_Manip->opcode == HMAN_OC_CAPWAP_REASSEMBLY),
2219             E_INVALID_STATE);
2220     SANITY_CHECK_RETURN_ERROR(h_FmPcd, E_INVALID_HANDLE);
2221     SANITY_CHECK_RETURN_ERROR(!p_Manip->updateParams || h_PcdParams,
2222                               E_INVALID_HANDLE);
2223 
2224     UNUSED(h_Ad);
2225 
2226     if (!p_Manip->updateParams)
2227         return E_OK;
2228 
2229     if (p_Manip->h_FmPcd != h_FmPcd)
2230         RETURN_ERROR(
2231                 MAJOR, E_INVALID_STATE,
2232                 ("handler of PCD previously was initiated by different value"));
2233 
2234     if (p_Manip->updateParams)
2235     {
2236         if ((!(p_Manip->updateParams
2237                 & (NUM_OF_TASKS | NUM_OF_EXTRA_TASKS | DISCARD_MASK)))
2238                 || ((p_Manip->shadowUpdateParams
2239                         & (NUM_OF_TASKS | NUM_OF_EXTRA_TASKS | DISCARD_MASK))))
2240             RETURN_ERROR(
2241                     MAJOR, E_INVALID_STATE,
2242                     ("in this stage parameters from Port has not be updated"));
2243 
2244         fmPortGetSetCcParams.setCcParams.type = 0;
2245         if (p_Manip->opcode == HMAN_OC_CAPWAP_REASSEMBLY)
2246         {
2247             fmPortGetSetCcParams.setCcParams.type |= UPDATE_OFP_DPTE;
2248             fmPortGetSetCcParams.setCcParams.ofpDpde = 0xF;
2249         }
2250         fmPortGetSetCcParams.getCcParams.type = p_Manip->updateParams | FM_REV;
2251         if ((err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams))
2252                 != E_OK)
2253             RETURN_ERROR(MAJOR, err, NO_MSG);
2254         if (fmPortGetSetCcParams.getCcParams.type
2255                 & (NUM_OF_TASKS | NUM_OF_EXTRA_TASKS | DISCARD_MASK | FM_REV))
2256             RETURN_ERROR(MAJOR, E_INVALID_STATE,
2257                          ("offset of the data wasn't configured previously"));
2258         if (p_Manip->updateParams
2259                 & (NUM_OF_TASKS | NUM_OF_EXTRA_TASKS | DISCARD_MASK))
2260         {
2261             t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
2262             uint8_t *p_Ptr, i, totalNumOfTnums;
2263 
2264             totalNumOfTnums =
2265                     (uint8_t)(fmPortGetSetCcParams.getCcParams.numOfTasks
2266                             + fmPortGetSetCcParams.getCcParams.numOfExtraTasks);
2267 
2268             p_Manip->reassmParams.internalBufferPoolAddr =
2269                     PTR_TO_UINT(FM_MURAM_AllocMem(p_FmPcd->h_FmMuram,
2270                                     (uint32_t)(totalNumOfTnums * BMI_FIFO_UNITS),
2271                                     BMI_FIFO_UNITS));
2272             if (!p_Manip->reassmParams.internalBufferPoolAddr)
2273                 RETURN_ERROR(
2274                         MAJOR, E_NO_MEMORY,
2275                         ("MURAM alloc for Reassembly internal buffers pool"));
2276             MemSet8(
2277                     UINT_TO_PTR(p_Manip->reassmParams.internalBufferPoolAddr),
2278                     0, (uint32_t)(totalNumOfTnums * BMI_FIFO_UNITS));
2279 
2280             p_Manip->reassmParams.internalBufferPoolManagementIndexAddr =
2281                     PTR_TO_UINT(FM_MURAM_AllocMem(p_FmPcd->h_FmMuram,
2282                                     (uint32_t)(5 + totalNumOfTnums),
2283                                     4));
2284             if (!p_Manip->reassmParams.internalBufferPoolManagementIndexAddr)
2285                 RETURN_ERROR(
2286                         MAJOR,
2287                         E_NO_MEMORY,
2288                         ("MURAM alloc for Reassembly internal buffers management"));
2289 
2290             p_Ptr =
2291                     (uint8_t*)UINT_TO_PTR(p_Manip->reassmParams.internalBufferPoolManagementIndexAddr);
2292             WRITE_UINT32(
2293                     *(uint32_t*)p_Ptr,
2294                     (uint32_t)(XX_VirtToPhys(UINT_TO_PTR(p_Manip->reassmParams.internalBufferPoolAddr)) - p_FmPcd->physicalMuramBase));
2295             for (i = 0, p_Ptr += 4; i < totalNumOfTnums; i++, p_Ptr++)
2296                 WRITE_UINT8(*p_Ptr, i);
2297             WRITE_UINT8(*p_Ptr, 0xFF);
2298 
2299             tmpReg32 =
2300                     (4 << FM_PCD_MANIP_REASM_COMMON_INT_BUFFER_IDX_SHIFT)
2301                             | ((uint32_t)(XX_VirtToPhys(
2302                                     UINT_TO_PTR(p_Manip->reassmParams.internalBufferPoolManagementIndexAddr))
2303                                     - p_FmPcd->physicalMuramBase));
2304             WRITE_UINT32(
2305                     p_Manip->reassmParams.p_ReassCommonTbl->internalBufferManagement,
2306                     tmpReg32);
2307 
2308             p_Manip->updateParams &= ~(NUM_OF_TASKS | NUM_OF_EXTRA_TASKS
2309                     | DISCARD_MASK);
2310             p_Manip->shadowUpdateParams |= (NUM_OF_TASKS | NUM_OF_EXTRA_TASKS
2311                     | DISCARD_MASK);
2312         }
2313     }
2314 
2315     if (p_Manip->opcode == HMAN_OC_CAPWAP_REASSEMBLY)
2316     {
2317         if (p_Manip->reassmParams.capwap.h_Scheme)
2318         {
2319             p_PcdParams->p_KgParams->h_Schemes[p_PcdParams->p_KgParams->numOfSchemes] =
2320                     p_Manip->reassmParams.capwap.h_Scheme;
2321             p_PcdParams->p_KgParams->numOfSchemes++;
2322         }
2323 
2324     }
2325     else
2326     {
2327         if (p_Manip->reassmParams.ip.h_Ipv4Scheme)
2328         {
2329             p_PcdParams->p_KgParams->h_Schemes[p_PcdParams->p_KgParams->numOfSchemes] =
2330                     p_Manip->reassmParams.ip.h_Ipv4Scheme;
2331             p_PcdParams->p_KgParams->numOfSchemes++;
2332         }
2333         if (p_Manip->reassmParams.ip.h_Ipv6Scheme)
2334         {
2335             p_PcdParams->p_KgParams->h_Schemes[p_PcdParams->p_KgParams->numOfSchemes] =
2336                     p_Manip->reassmParams.ip.h_Ipv6Scheme;
2337             p_PcdParams->p_KgParams->numOfSchemes++;
2338         }
2339 #if (DPAA_VERSION >= 11)
2340         if (fmPortGetSetCcParams.getCcParams.revInfo.majorRev >= 6)
2341         {
2342             if ((err = FmPortSetGprFunc(h_FmPort, e_FM_PORT_GPR_MURAM_PAGE,
2343                                         (void**)&p_ParamsPage)) != E_OK)
2344                 RETURN_ERROR(MAJOR, err, NO_MSG);
2345 
2346             tmpReg32 = NIA_ENG_KG;
2347             if (p_Manip->reassmParams.ip.h_Ipv4Scheme)
2348             {
2349                 tmpReg32 |= NIA_KG_DIRECT;
2350                 tmpReg32 |= NIA_KG_CC_EN;
2351                 tmpReg32 |= FmPcdKgGetSchemeId(
2352                         p_Manip->reassmParams.ip.h_Ipv4Scheme);
2353                 WRITE_UINT32(p_ParamsPage->iprIpv4Nia, tmpReg32);
2354             }
2355             if (p_Manip->reassmParams.ip.h_Ipv6Scheme)
2356             {
2357                 tmpReg32 &= ~NIA_AC_MASK;
2358                 tmpReg32 |= NIA_KG_DIRECT;
2359                 tmpReg32 |= NIA_KG_CC_EN;
2360                 tmpReg32 |= FmPcdKgGetSchemeId(
2361                         p_Manip->reassmParams.ip.h_Ipv6Scheme);
2362                 WRITE_UINT32(p_ParamsPage->iprIpv6Nia, tmpReg32);
2363             }
2364         }
2365 #else
2366         if (fmPortGetSetCcParams.getCcParams.revInfo.majorRev < 6)
2367         {
2368             WRITE_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->discardMask,
2369                     fmPortGetSetCcParams.getCcParams.discardMask);
2370         }
2371 #endif /* (DPAA_VERSION >= 11) */
2372     }
2373     return E_OK;
2374 }
2375 
2376 #if (DPAA_VERSION == 10)
2377 static t_Error FmPcdFragHcScratchPoolFill(t_Handle h_FmPcd, uint8_t scratchBpid)
2378 {
2379     t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
2380     t_FmPcdCcFragScratchPoolCmdParams fmPcdCcFragScratchPoolCmdParams;
2381     t_Error err;
2382 
2383     SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
2384 
2385     memset(&fmPcdCcFragScratchPoolCmdParams, 0, sizeof(t_FmPcdCcFragScratchPoolCmdParams));
2386 
2387     fmPcdCcFragScratchPoolCmdParams.numOfBuffers = NUM_OF_SCRATCH_POOL_BUFFERS;
2388     fmPcdCcFragScratchPoolCmdParams.bufferPoolId = scratchBpid;
2389     if ((err = FmHcPcdCcIpFragScratchPollCmd(p_FmPcd->h_Hc, TRUE, &fmPcdCcFragScratchPoolCmdParams)) != E_OK)
2390     RETURN_ERROR(MAJOR, err, NO_MSG);
2391 
2392     if (fmPcdCcFragScratchPoolCmdParams.numOfBuffers != 0)
2393     RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Fill scratch pool failed,"
2394                     "Failed to release %d buffers to the BM (missing FBPRs)",
2395                     fmPcdCcFragScratchPoolCmdParams.numOfBuffers));
2396 
2397     return E_OK;
2398 }
2399 
2400 static t_Error FmPcdFragHcScratchPoolEmpty(t_Handle h_FmPcd, uint8_t scratchBpid)
2401 {
2402     t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
2403     t_FmPcdCcFragScratchPoolCmdParams fmPcdCcFragScratchPoolCmdParams;
2404     t_Error err;
2405 
2406     SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
2407 
2408     memset(&fmPcdCcFragScratchPoolCmdParams, 0, sizeof(t_FmPcdCcFragScratchPoolCmdParams));
2409 
2410     fmPcdCcFragScratchPoolCmdParams.bufferPoolId = scratchBpid;
2411     if ((err = FmHcPcdCcIpFragScratchPollCmd(p_FmPcd->h_Hc, FALSE, &fmPcdCcFragScratchPoolCmdParams)) != E_OK)
2412     RETURN_ERROR(MAJOR, err, NO_MSG);
2413 
2414     return E_OK;
2415 }
2416 #endif /* (DPAA_VERSION == 10) */
2417 
2418 static void ReleaseManipHandler(t_FmPcdManip *p_Manip, t_FmPcd *p_FmPcd)
2419 {
2420     if (p_Manip->h_Ad)
2421     {
2422         if (p_Manip->muramAllocate)
2423             FM_MURAM_FreeMem(p_FmPcd->h_FmMuram, p_Manip->h_Ad);
2424         else
2425             XX_Free(p_Manip->h_Ad);
2426         p_Manip->h_Ad = NULL;
2427     }
2428     if (p_Manip->p_Template)
2429     {
2430         FM_MURAM_FreeMem(p_FmPcd->h_FmMuram, p_Manip->p_Template);
2431         p_Manip->p_Template = NULL;
2432     }
2433 #if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
2434     if (p_Manip->h_Frag)
2435     {
2436         if (p_Manip->capwapFragParams.p_AutoLearnHashTbl)
2437         FM_MURAM_FreeMem(p_FmPcd->h_FmMuram,
2438                 p_Manip->capwapFragParams.p_AutoLearnHashTbl);
2439         if (p_Manip->capwapFragParams.p_ReassmFrmDescrPoolTbl)
2440         FM_MURAM_FreeMem(p_FmPcd->h_FmMuram,
2441                 p_Manip->capwapFragParams.p_ReassmFrmDescrPoolTbl);
2442         if (p_Manip->capwapFragParams.p_ReassmFrmDescrIndxPoolTbl)
2443         FM_MURAM_FreeMem(p_FmPcd->h_FmMuram,
2444                 p_Manip->capwapFragParams.p_ReassmFrmDescrIndxPoolTbl);
2445         if (p_Manip->capwapFragParams.p_TimeOutTbl)
2446         FM_MURAM_FreeMem(p_FmPcd->h_FmMuram,
2447                 p_Manip->capwapFragParams.p_TimeOutTbl);
2448         FM_MURAM_FreeMem(p_FmPcd->h_FmMuram, p_Manip->h_Frag);
2449 
2450     }
2451 #endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */
2452     if (p_Manip->frag)
2453     {
2454         if (p_Manip->fragParams.p_Frag)
2455         {
2456 #if (DPAA_VERSION == 10)
2457             FmPcdFragHcScratchPoolEmpty((t_Handle)p_FmPcd, p_Manip->fragParams.scratchBpid);
2458 #endif /* (DPAA_VERSION == 10) */
2459 
2460             FM_MURAM_FreeMem(p_FmPcd->h_FmMuram, p_Manip->fragParams.p_Frag);
2461         }
2462     }
2463     else
2464         if (p_Manip->reassm)
2465         {
2466             FmPcdUnregisterReassmPort(p_FmPcd,
2467                                       p_Manip->reassmParams.p_ReassCommonTbl);
2468 
2469             if (p_Manip->reassmParams.timeOutTblAddr)
2470                 FM_MURAM_FreeMem(
2471                         p_FmPcd->h_FmMuram,
2472                         UINT_TO_PTR(p_Manip->reassmParams.timeOutTblAddr));
2473             if (p_Manip->reassmParams.reassFrmDescrPoolTblAddr)
2474                 XX_FreeSmart(
2475                         UINT_TO_PTR(p_Manip->reassmParams.reassFrmDescrPoolTblAddr));
2476             if (p_Manip->reassmParams.p_ReassCommonTbl)
2477                 FM_MURAM_FreeMem(p_FmPcd->h_FmMuram,
2478                                  p_Manip->reassmParams.p_ReassCommonTbl);
2479             if (p_Manip->reassmParams.reassFrmDescrIndxPoolTblAddr)
2480                 FM_MURAM_FreeMem(
2481                         p_FmPcd->h_FmMuram,
2482                         UINT_TO_PTR(p_Manip->reassmParams.reassFrmDescrIndxPoolTblAddr));
2483             if (p_Manip->reassmParams.internalBufferPoolManagementIndexAddr)
2484                 FM_MURAM_FreeMem(
2485                         p_FmPcd->h_FmMuram,
2486                         UINT_TO_PTR(p_Manip->reassmParams.internalBufferPoolManagementIndexAddr));
2487             if (p_Manip->reassmParams.internalBufferPoolAddr)
2488                 FM_MURAM_FreeMem(
2489                         p_FmPcd->h_FmMuram,
2490                         UINT_TO_PTR(p_Manip->reassmParams.internalBufferPoolAddr));
2491             if (p_Manip->reassmParams.hdr == HEADER_TYPE_CAPWAP)
2492             {
2493 
2494             }
2495             else
2496             {
2497                 if (p_Manip->reassmParams.ip.ipv4AutoLearnHashTblAddr)
2498                     XX_FreeSmart(
2499                             UINT_TO_PTR(p_Manip->reassmParams.ip.ipv4AutoLearnHashTblAddr));
2500                 if (p_Manip->reassmParams.ip.ipv6AutoLearnHashTblAddr)
2501                     XX_FreeSmart(
2502                             UINT_TO_PTR(p_Manip->reassmParams.ip.ipv6AutoLearnHashTblAddr));
2503                 if (p_Manip->reassmParams.ip.ipv4AutoLearnSetLockTblAddr)
2504                     XX_FreeSmart(
2505                             UINT_TO_PTR(p_Manip->reassmParams.ip.ipv4AutoLearnSetLockTblAddr));
2506                 if (p_Manip->reassmParams.ip.ipv6AutoLearnSetLockTblAddr)
2507                     XX_FreeSmart(
2508                             UINT_TO_PTR(p_Manip->reassmParams.ip.ipv6AutoLearnSetLockTblAddr));
2509                 if (p_Manip->reassmParams.ip.p_Ipv4ReassTbl)
2510                     FM_MURAM_FreeMem(p_FmPcd->h_FmMuram,
2511                                      p_Manip->reassmParams.ip.p_Ipv4ReassTbl);
2512                 if (p_Manip->reassmParams.ip.p_Ipv6ReassTbl)
2513                     FM_MURAM_FreeMem(p_FmPcd->h_FmMuram,
2514                                      p_Manip->reassmParams.ip.p_Ipv6ReassTbl);
2515                 if (p_Manip->reassmParams.ip.h_Ipv6Ad)
2516                     XX_FreeSmart(p_Manip->reassmParams.ip.h_Ipv6Ad);
2517                 if (p_Manip->reassmParams.ip.h_Ipv4Ad)
2518                     XX_FreeSmart(p_Manip->reassmParams.ip.h_Ipv4Ad);
2519             }
2520         }
2521 
2522     if (p_Manip->p_StatsTbl)
2523         FM_MURAM_FreeMem(p_FmPcd->h_FmMuram, p_Manip->p_StatsTbl);
2524 }
2525 
2526 #if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
2527 static t_Error CheckManipParamsAndSetType(t_FmPcdManip *p_Manip, t_FmPcdManipParams *p_ManipParams)
2528 {
2529     if (p_ManipParams->u.hdr.rmv)
2530     {
2531         switch (p_ManipParams->u.hdr.rmvParams.type)
2532         {
2533             case (e_FM_PCD_MANIP_RMV_BY_HDR):
2534             switch (p_ManipParams->u.hdr.rmvParams.u.byHdr.type)
2535             {
2536                 case (e_FM_PCD_MANIP_RMV_BY_HDR_FROM_START) :
2537                 if (p_ManipParams->u.hdr.rmvParams.u.byHdr.u.fromStartByHdr.include)
2538                 {
2539                     switch (p_ManipParams->u.hdr.rmvParams.u.byHdr.u.fromStartByHdr.hdrInfo.hdr)
2540                     {
2541                         case (HEADER_TYPE_CAPWAP_DTLS) :
2542                         p_Manip->opcode = HMAN_OC_CAPWAP_RMV_DTLS_IF_EXIST;
2543                         p_Manip->muramAllocate = TRUE;
2544                         if (p_ManipParams->u.hdr.insrt)
2545                         RETURN_ERROR(MAJOR, E_INVALID_STATE, ("for  CAPWAP_DTLS_HDR remove can not be insrt manipualtion after"));
2546                         if (p_ManipParams->fragOrReasm)
2547                         {
2548                             if (!p_ManipParams->fragOrReasmParams.frag)
2549                             {
2550                                 switch (p_ManipParams->fragOrReasmParams.hdr)
2551                                 {
2552                                     case (HEADER_TYPE_CAPWAP):
2553                                     p_Manip->opcode = HMAN_OC_CAPWAP_REASSEMBLY;
2554                                     break;
2555                                     default:
2556                                     RETURN_ERROR(MAJOR, E_INVALID_STATE, ("unsupported header for Reassembly"));
2557                                 }
2558                             }
2559                             else
2560                             RETURN_ERROR(MAJOR, E_INVALID_STATE, ("for this type of manipulation frag can not be TRUE"));
2561                         }
2562                         break;
2563                         default:
2564                         RETURN_ERROR(MAJOR, E_INVALID_STATE, ("non valid net header of remove location"));
2565                     }
2566                 }
2567                 else
2568                 {
2569                     switch (p_ManipParams->u.hdr.rmvParams.u.byHdr.u.fromStartByHdr.hdrInfo.hdr)
2570                     {
2571                         case (HEADER_TYPE_CAPWAP_DTLS) :
2572                         case (HEADER_TYPE_CAPWAP) :
2573                         if (p_ManipParams->fragOrReasm || p_ManipParams->u.hdr.insrt)
2574                         RETURN_ERROR(MAJOR, E_INVALID_STATE, ("for the type of remove e_FM_PCD_MANIP_RMV_FROM_START_OF_FRAME_TILL_CAPWAP can not be insert or fragOrReasm TRUE"));
2575                         p_Manip->opcode = HMAN_OC_RMV_N_OR_INSRT_INT_FRM_HDR;
2576                         p_Manip->muramAllocate = TRUE;
2577                         p_ManipParams->u.hdr.insrt = TRUE; //internal frame header
2578                         break;
2579                         default :
2580                         RETURN_ERROR(MAJOR, E_INVALID_STATE, ("invalid type of remove manipulation"));
2581                     }
2582                 }
2583                 break;
2584                 default :
2585                 RETURN_ERROR(MAJOR, E_INVALID_STATE, ("invalid type of remove manipulation"));
2586             }
2587             break;
2588             default:
2589             RETURN_ERROR(MAJOR, E_INVALID_STATE, ("invalid type of remove manipulation"));
2590         }
2591     }
2592     else if (p_ManipParams->u.hdr.insrt)
2593     {
2594         switch (p_ManipParams->u.hdr.insrtParams.type)
2595         {
2596             case (e_FM_PCD_MANIP_INSRT_BY_TEMPLATE) :
2597 
2598             p_Manip->opcode = HMAN_OC_INSRT_HDR_BY_TEMPL_N_OR_FRAG_AFTER;
2599             p_Manip->muramAllocate = FALSE;
2600             if (p_ManipParams->fragOrReasm)
2601             {
2602                 if (p_ManipParams->fragOrReasmParams.frag)
2603                 {
2604                     switch (p_ManipParams->fragOrReasmParams.hdr)
2605                     {
2606                         case (HEADER_TYPE_CAPWAP):
2607                         p_Manip->opcode = HMAN_OC_CAPWAP_FRAGMENTATION;
2608                         break;
2609                         default:
2610                         RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid header for fragmentation"));
2611                     }
2612                 }
2613                 else
2614                 RETURN_ERROR(MAJOR, E_INVALID_STATE,("can not reach this point"));
2615             }
2616             break;
2617 
2618             default:
2619             RETURN_ERROR(MAJOR, E_INVALID_STATE, ("for only isert manipulation unsupported type"));
2620         }
2621     }
2622     else if (p_ManipParams->fragOrReasm)
2623     {
2624         if (p_ManipParams->fragOrReasmParams.frag)
2625         {
2626             switch (p_ManipParams->fragOrReasmParams.hdr)
2627             {
2628                 case (HEADER_TYPE_CAPWAP):
2629                 p_Manip->opcode = HMAN_OC_CAPWAP_FRAGMENTATION;
2630                 p_Manip->muramAllocate = FALSE;
2631                 break;
2632                 default:
2633                 RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Unsupported header for fragmentation"));
2634             }
2635         }
2636         else
2637         {
2638             switch (p_ManipParams->fragOrReasmParams.hdr)
2639             {
2640                 case (HEADER_TYPE_CAPWAP):
2641                 RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Reassembly has to be with additional operation - rmv = TRUE, type of remove - e_FM_PCD_MANIP_RMV_FROM_START_OF_FRAME_INCLUDE_SPECIFIC_LOCATION,type = e_FM_PCD_MANIP_LOC_BY_HDR, hdr = HEADER_TYPE_CAPWAP_DTLS"));
2642                 default:
2643                 RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Unsupported header for reassembly"));
2644             }
2645         }
2646 
2647     }
2648     else
2649     RETURN_ERROR(MAJOR, E_INVALID_STATE, ("User didn't ask for any manipulation"));
2650 
2651     p_Manip->insrt = p_ManipParams->u.hdr.insrt;
2652     p_Manip->rmv = p_ManipParams->u.hdr.rmv;
2653 
2654     return E_OK;
2655 }
2656 
2657 #else /* not (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */
2658 static t_Error CheckManipParamsAndSetType(t_FmPcdManip *p_Manip,
2659                                           t_FmPcdManipParams *p_ManipParams)
2660 {
2661     switch (p_ManipParams->type)
2662     {
2663         case e_FM_PCD_MANIP_HDR:
2664             /* Check that next-manip is not already used */
2665             if (p_ManipParams->h_NextManip)
2666             {
2667                 if (!MANIP_IS_FIRST(p_ManipParams->h_NextManip))
2668                     RETURN_ERROR(
2669                             MAJOR, E_INVALID_STATE,
2670                             ("h_NextManip is already a part of another chain"));
2671                 if ((MANIP_GET_TYPE(p_ManipParams->h_NextManip)
2672                         != e_FM_PCD_MANIP_HDR) &&
2673                         (MANIP_GET_TYPE(p_ManipParams->h_NextManip)
2674                         != e_FM_PCD_MANIP_FRAG))
2675                     RETURN_ERROR(
2676                             MAJOR,
2677                             E_NOT_SUPPORTED,
2678                             ("For a Header Manipulation node - no support of h_NextManip of type other than Header Manipulation or Fragmentation."));
2679             }
2680 
2681             if (p_ManipParams->u.hdr.rmv)
2682             {
2683                 switch (p_ManipParams->u.hdr.rmvParams.type)
2684                 {
2685                     case (e_FM_PCD_MANIP_RMV_BY_HDR):
2686                         switch (p_ManipParams->u.hdr.rmvParams.u.byHdr.type)
2687                         {
2688                             case (e_FM_PCD_MANIP_RMV_BY_HDR_SPECIFIC_L2):
2689                                 break;
2690 #if (DPAA_VERSION >= 11)
2691                             case (e_FM_PCD_MANIP_RMV_BY_HDR_CAPWAP):
2692                                 break;
2693                             case (e_FM_PCD_MANIP_RMV_BY_HDR_FROM_START):
2694                             {
2695                                 t_Error err;
2696                                 uint8_t prsArrayOffset;
2697 
2698                                 err =
2699                                         GetPrOffsetByHeaderOrField(
2700                                                 &p_ManipParams->u.hdr.rmvParams.u.byHdr.u.hdrInfo,
2701                                                 &prsArrayOffset);
2702                                 if (err)
2703                                     RETURN_ERROR(MAJOR, err, NO_MSG);
2704                                 break;
2705                             }
2706 #endif /* (DPAA_VERSION >= 11) */
2707                             default:
2708                                 RETURN_ERROR(
2709                                         MAJOR,
2710                                         E_INVALID_STATE,
2711                                         ("invalid type of remove manipulation"));
2712                         }
2713                         break;
2714                     case (e_FM_PCD_MANIP_RMV_GENERIC):
2715                         break;
2716                     default:
2717                         RETURN_ERROR(MAJOR, E_INVALID_STATE,
2718                                      ("invalid type of remove manipulation"));
2719                 }
2720                 p_Manip->opcode = HMAN_OC;
2721                 p_Manip->muramAllocate = TRUE;
2722                 p_Manip->rmv = TRUE;
2723             }
2724             else
2725                 if (p_ManipParams->u.hdr.insrt)
2726                 {
2727                     switch (p_ManipParams->u.hdr.insrtParams.type)
2728                     {
2729                         case (e_FM_PCD_MANIP_INSRT_BY_HDR):
2730                         {
2731                             switch (p_ManipParams->u.hdr.insrtParams.u.byHdr.type)
2732                             {
2733                                 case (e_FM_PCD_MANIP_INSRT_BY_HDR_SPECIFIC_L2):
2734                                     /* nothing to check */
2735                                     break;
2736 #if (DPAA_VERSION >= 11)
2737                                 case (e_FM_PCD_MANIP_INSRT_BY_HDR_IP):
2738                                     if (p_ManipParams->u.hdr.insrtParams.u.byHdr.u.ipParams.insrt.size
2739                                             % 4)
2740                                         RETURN_ERROR(
2741                                                 MAJOR,
2742                                                 E_INVALID_VALUE,
2743                                                 ("IP inserted header must be of size which is a multiple of four bytes"));
2744                                     break;
2745                                 case (e_FM_PCD_MANIP_INSRT_BY_HDR_CAPWAP):
2746                                     if (p_ManipParams->u.hdr.insrtParams.u.byHdr.u.insrt.size
2747                                             % 4)
2748                                         RETURN_ERROR(
2749                                                 MAJOR,
2750                                                 E_INVALID_VALUE,
2751                                                 ("CAPWAP inserted header must be of size which is a multiple of four bytes"));
2752                                     break;
2753                                 case (e_FM_PCD_MANIP_INSRT_BY_HDR_UDP):
2754                                 case (e_FM_PCD_MANIP_INSRT_BY_HDR_UDP_LITE):
2755                                     if (p_ManipParams->u.hdr.insrtParams.u.byHdr.u.insrt.size
2756                                             != 8)
2757                                         RETURN_ERROR(
2758                                                 MAJOR,
2759                                                 E_INVALID_VALUE,
2760                                                 ("Inserted header must be of size 8"));
2761                                     break;
2762 #endif /* (DPAA_VERSION >= 11) */
2763                                 default:
2764                                     RETURN_ERROR(
2765                                             MAJOR,
2766                                             E_INVALID_STATE,
2767                                             ("unsupported insert by header type"));
2768                             }
2769                         }
2770                         case (e_FM_PCD_MANIP_INSRT_GENERIC):
2771                             break;
2772                         default:
2773                             RETURN_ERROR(
2774                                     MAJOR,
2775                                     E_INVALID_STATE,
2776                                     ("for only insert manipulation unsupported type"));
2777                     }
2778                     p_Manip->opcode = HMAN_OC;
2779                     p_Manip->muramAllocate = TRUE;
2780                     p_Manip->insrt = TRUE;
2781                 }
2782                 else
2783                     if (p_ManipParams->u.hdr.fieldUpdate)
2784                     {
2785                         /* Check parameters */
2786                         if (p_ManipParams->u.hdr.fieldUpdateParams.type
2787                                 == e_FM_PCD_MANIP_HDR_FIELD_UPDATE_VLAN)
2788                         {
2789                             if ((p_ManipParams->u.hdr.fieldUpdateParams.u.vlan.updateType
2790                                     == e_FM_PCD_MANIP_HDR_FIELD_UPDATE_VLAN_VPRI)
2791                                     && (p_ManipParams->u.hdr.fieldUpdateParams.u.vlan.u.vpri
2792                                             > 7))
2793                                 RETURN_ERROR(
2794                                         MAJOR, E_INVALID_VALUE,
2795                                         ("vpri should get values of 0-7 "));
2796                             if (p_ManipParams->u.hdr.fieldUpdateParams.u.vlan.updateType
2797                                     == e_FM_PCD_MANIP_HDR_FIELD_UPDATE_DSCP_TO_VLAN)
2798                             {
2799                                 int i;
2800 
2801                                 if (p_ManipParams->u.hdr.fieldUpdateParams.u.vlan.u.dscpToVpri.vpriDefVal
2802                                         > 7)
2803                                     RETURN_ERROR(
2804                                             MAJOR,
2805                                             E_INVALID_VALUE,
2806                                             ("vpriDefVal should get values of 0-7 "));
2807                                 for (i = 0; i < FM_PCD_MANIP_DSCP_TO_VLAN_TRANS;
2808                                         i++)
2809                                     if (p_ManipParams->u.hdr.fieldUpdateParams.u.vlan.u.dscpToVpri.dscpToVpriTable[i]
2810                                             & 0xf0)
2811                                         RETURN_ERROR(
2812                                                 MAJOR,
2813                                                 E_INVALID_VALUE,
2814                                                 ("dscpToVpriTabl value out of range (0-15)"));
2815                             }
2816 
2817                         }
2818 
2819                         p_Manip->opcode = HMAN_OC;
2820                         p_Manip->muramAllocate = TRUE;
2821                         p_Manip->fieldUpdate = TRUE;
2822                     }
2823                     else
2824                         if (p_ManipParams->u.hdr.custom)
2825                         {
2826                             if (p_ManipParams->u.hdr.customParams.type == e_FM_PCD_MANIP_HDR_CUSTOM_GEN_FIELD_REPLACE)
2827                             {
2828 
2829                             if ((p_ManipParams->u.hdr.customParams.u.genFieldReplace.size == 0) ||
2830                                     (p_ManipParams->u.hdr.customParams.u.genFieldReplace.size > 8))
2831                                 RETURN_ERROR(
2832                                         MAJOR, E_INVALID_VALUE,
2833                                         ("size should get values of 1-8 "));
2834 
2835                             if (p_ManipParams->u.hdr.customParams.u.genFieldReplace.srcOffset > 7)
2836                                 RETURN_ERROR(
2837                                         MAJOR, E_INVALID_VALUE,
2838                                         ("srcOffset should be <= 7"));
2839 
2840                             if ((p_ManipParams->u.hdr.customParams.u.genFieldReplace.srcOffset +
2841                                     p_ManipParams->u.hdr.customParams.u.genFieldReplace.size) > 8)
2842                                 RETURN_ERROR(
2843                                         MAJOR, E_INVALID_VALUE,
2844                                         ("(srcOffset + size) should be <= 8"));
2845 
2846                             if ((p_ManipParams->u.hdr.customParams.u.genFieldReplace.dstOffset +
2847                                     p_ManipParams->u.hdr.customParams.u.genFieldReplace.size) > 256)
2848                                 RETURN_ERROR(
2849                                         MAJOR, E_INVALID_VALUE,
2850                                         ("(dstOffset + size) should be <= 256"));
2851 
2852                             }
2853 
2854                             p_Manip->opcode = HMAN_OC;
2855                             p_Manip->muramAllocate = TRUE;
2856                             p_Manip->custom = TRUE;
2857                         }
2858             break;
2859         case e_FM_PCD_MANIP_REASSEM:
2860             if (p_ManipParams->h_NextManip)
2861                 RETURN_ERROR(MAJOR, E_NOT_SUPPORTED,
2862                              ("next manip with reassembly"));
2863             switch (p_ManipParams->u.reassem.hdr)
2864             {
2865                 case (HEADER_TYPE_IPv4):
2866                     p_Manip->reassmParams.hdr = HEADER_TYPE_IPv4;
2867                     p_Manip->opcode = HMAN_OC_IP_REASSEMBLY;
2868                     break;
2869                 case (HEADER_TYPE_IPv6):
2870                     p_Manip->reassmParams.hdr = HEADER_TYPE_IPv6;
2871                     p_Manip->opcode = HMAN_OC_IP_REASSEMBLY;
2872                     break;
2873 #if (DPAA_VERSION >= 11)
2874                 case (HEADER_TYPE_CAPWAP):
2875                     p_Manip->reassmParams.hdr = HEADER_TYPE_CAPWAP;
2876                     p_Manip->opcode = HMAN_OC_CAPWAP_REASSEMBLY;
2877                     break;
2878 #endif /* (DPAA_VERSION >= 11) */
2879                 default:
2880                     RETURN_ERROR(MAJOR, E_NOT_SUPPORTED,
2881                                  ("header for reassembly"));
2882             }
2883             break;
2884         case e_FM_PCD_MANIP_FRAG:
2885             if (p_ManipParams->h_NextManip)
2886                 RETURN_ERROR(MAJOR, E_NOT_SUPPORTED,
2887                              ("next manip with fragmentation"));
2888             switch (p_ManipParams->u.frag.hdr)
2889             {
2890                 case (HEADER_TYPE_IPv4):
2891                 case (HEADER_TYPE_IPv6):
2892                     p_Manip->opcode = HMAN_OC_IP_FRAGMENTATION;
2893                     break;
2894 #if (DPAA_VERSION >= 11)
2895                 case (HEADER_TYPE_CAPWAP):
2896                     p_Manip->opcode = HMAN_OC_CAPWAP_FRAGMENTATION;
2897                     break;
2898 #endif /* (DPAA_VERSION >= 11) */
2899                 default:
2900                     RETURN_ERROR(MAJOR, E_NOT_SUPPORTED,
2901                                  ("header for fragmentation"));
2902             }
2903             p_Manip->muramAllocate = TRUE;
2904             break;
2905         case e_FM_PCD_MANIP_SPECIAL_OFFLOAD:
2906             switch (p_ManipParams->u.specialOffload.type)
2907             {
2908                 case (e_FM_PCD_MANIP_SPECIAL_OFFLOAD_IPSEC):
2909                     p_Manip->opcode = HMAN_OC_IPSEC_MANIP;
2910                     p_Manip->muramAllocate = TRUE;
2911                     break;
2912 #if (DPAA_VERSION >= 11)
2913                 case (e_FM_PCD_MANIP_SPECIAL_OFFLOAD_CAPWAP):
2914                     p_Manip->opcode = HMAN_OC_CAPWAP_MANIP;
2915                     p_Manip->muramAllocate = TRUE;
2916                     break;
2917 #endif /* (DPAA_VERSION >= 11) */
2918                 default:
2919                     RETURN_ERROR(MAJOR, E_NOT_SUPPORTED,
2920                                  ("special offload type"));
2921             }
2922             break;
2923         default:
2924             RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("manip type"));
2925     }
2926 
2927     return E_OK;
2928 }
2929 #endif /* not (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */
2930 
2931 #if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
2932 
2933 static t_Error UpdateIndxStats(t_Handle h_FmPcd,
2934         t_Handle h_FmPort,
2935         t_FmPcdManip *p_Manip)
2936 {
2937     t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
2938     uint32_t tmpReg32 = 0;
2939     t_AdOfTypeContLookup *p_Ad;
2940     t_FmPortGetSetCcParams fmPortGetSetCcParams;
2941     t_Error err;
2942 
2943     SANITY_CHECK_RETURN_ERROR(p_Manip,E_INVALID_HANDLE);
2944     SANITY_CHECK_RETURN_ERROR(p_Manip->h_Ad,E_INVALID_HANDLE);
2945 
2946     p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Ad;
2947     if (p_Manip->h_FmPcd != h_FmPcd)
2948     RETURN_ERROR(MAJOR, E_INVALID_STATE,
2949             ("handler of PCD previously was initiated by different value"));
2950 
2951     memset(&fmPortGetSetCcParams, 0, sizeof(t_FmPortGetSetCcParams));
2952 
2953     if (!p_Manip->p_StatsTbl)
2954     {
2955 
2956         fmPortGetSetCcParams.setCcParams.type = UPDATE_NIA_PNDN;
2957         fmPortGetSetCcParams.setCcParams.nia = NIA_FM_CTL_AC_CC;
2958         err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams);
2959         if (err)
2960         RETURN_ERROR(MAJOR, err, NO_MSG);
2961 
2962         tmpReg32 = GET_UINT32(p_Ad->ccAdBase);
2963 
2964         p_Manip->p_StatsTbl =
2965         (t_Handle)FM_MURAM_AllocMem(p_FmPcd->h_FmMuram,
2966                 (uint32_t)p_Manip->owner * FM_PCD_MANIP_INDEXED_STATS_ENTRY_SIZE,
2967                 4);
2968         if (!p_Manip->p_StatsTbl)
2969         RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM alloc for Manipulation indexed statistics table"));
2970 
2971         MemSet8(p_Manip->p_StatsTbl, 0, (uint32_t)(p_Manip->owner * 4));
2972 
2973         tmpReg32 |= (uint32_t)(XX_VirtToPhys(p_Manip->p_StatsTbl) - p_FmPcd->physicalMuramBase);
2974 
2975         if (p_Manip->cnia)
2976         tmpReg32 |= FM_PCD_MANIP_INDEXED_STATS_CNIA;
2977 
2978         tmpReg32 |= FM_PCD_MANIP_INDEXED_STATS_DPD;
2979         WRITE_UINT32(p_Ad->ccAdBase, tmpReg32);
2980     }
2981     else
2982     {
2983         fmPortGetSetCcParams.setCcParams.type = UPDATE_NIA_PNDN;
2984         fmPortGetSetCcParams.setCcParams.nia = NIA_FM_CTL_AC_CC;
2985         err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams);
2986         if (err)
2987         RETURN_ERROR(MAJOR, err, NO_MSG);
2988     }
2989 
2990     return E_OK;
2991 }
2992 
2993 static t_Error RmvHdrTillSpecLocNOrInsrtIntFrmHdr(t_FmPcdManipHdrRmvParams *p_ManipParams, t_FmPcdManip *p_Manip)
2994 {
2995     t_AdOfTypeContLookup *p_Ad;
2996     uint32_t tmpReg32 = 0;
2997     uint8_t prsArrayOffset = 0;
2998     t_Error err;
2999 
3000     SANITY_CHECK_RETURN_ERROR(p_Manip,E_NULL_POINTER);
3001     SANITY_CHECK_RETURN_ERROR(p_ManipParams,E_NULL_POINTER);
3002     SANITY_CHECK_RETURN_ERROR(p_Manip->h_Ad,E_INVALID_HANDLE);
3003 
3004     p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Ad;
3005     if (p_Manip->rmv)
3006     {
3007         err = GetPrOffsetByHeaderOrField(&p_ManipParams->u.byHdr.u.fromStartByHdr.hdrInfo, &prsArrayOffset);
3008         if (err)
3009         RETURN_ERROR(MAJOR, err, NO_MSG);
3010 
3011         tmpReg32 |= (uint32_t)prsArrayOffset << 24;
3012         tmpReg32 |= HMAN_RMV_HDR;
3013     }
3014 
3015     if (p_Manip->insrt)
3016     tmpReg32 |= HMAN_INSRT_INT_FRM_HDR;
3017 
3018     tmpReg32 |= (uint32_t)HMAN_OC_RMV_N_OR_INSRT_INT_FRM_HDR;
3019 
3020     WRITE_UINT32(p_Ad->pcAndOffsets, tmpReg32);
3021 
3022     tmpReg32 = 0;
3023     tmpReg32 |= FM_PCD_AD_CONT_LOOKUP_TYPE;
3024     WRITE_UINT32(p_Ad->ccAdBase, tmpReg32);
3025 
3026     return E_OK;
3027 }
3028 
3029 static t_Error MvIntFrameHeaderFromFrameToBufferPrefix(t_FmPcdManip *p_Manip,
3030         bool caamUsed)
3031 {
3032     t_AdOfTypeContLookup *p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Ad;
3033     uint32_t tmpReg32 = 0;
3034 
3035     SANITY_CHECK_RETURN_ERROR(p_Ad, E_INVALID_HANDLE);
3036 
3037     p_Manip->updateParams |= OFFSET_OF_PR | INTERNAL_CONTEXT_OFFSET;
3038 
3039     tmpReg32 = 0;
3040     tmpReg32 |= FM_PCD_AD_CONT_LOOKUP_TYPE;
3041     *(uint32_t *)&p_Ad->ccAdBase = tmpReg32;
3042 
3043     tmpReg32 = 0;
3044     tmpReg32 |= HMAN_OC_MV_INT_FRAME_HDR_FROM_FRM_TO_BUFFER_PREFFIX;
3045     tmpReg32 |= (uint32_t)0x16 << 16;
3046     *(uint32_t *)&p_Ad->pcAndOffsets = tmpReg32;
3047 
3048     if (caamUsed)
3049     *(uint32_t *)&p_Ad->gmask = 0xf0000000;
3050 
3051     return E_OK;
3052 }
3053 
3054 static t_Error CapwapRmvDtlsHdr(t_FmPcd *p_FmPcd, t_FmPcdManip *p_Manip)
3055 {
3056     t_AdOfTypeContLookup *p_Ad;
3057     uint32_t tmpReg32 = 0;
3058     t_Error err = E_OK;
3059 
3060     SANITY_CHECK_RETURN_ERROR(p_Manip->h_Ad,E_INVALID_HANDLE);
3061 
3062     p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Ad;
3063 
3064     tmpReg32 = 0;
3065     tmpReg32 |= (uint32_t)HMAN_OC_CAPWAP_RMV_DTLS_IF_EXIST;
3066     WRITE_UINT32(p_Ad->pcAndOffsets, tmpReg32);
3067 
3068     tmpReg32 = 0;
3069     tmpReg32 |= FM_PCD_AD_CONT_LOOKUP_TYPE;
3070 
3071 
3072     if (p_Manip->h_Frag)
3073     {
3074         p_Manip->updateParams |= INTERNAL_CONTEXT_OFFSET;
3075         tmpReg32 |= (uint32_t)(XX_VirtToPhys(p_Manip->h_Frag) - (p_FmPcd->physicalMuramBase));
3076     }
3077 
3078     WRITE_UINT32(p_Ad->ccAdBase, tmpReg32);
3079 
3080     return err;
3081 }
3082 
3083 static t_Error CapwapReassembly(t_CapwapReassemblyParams *p_ManipParams,
3084         t_FmPcdManip *p_Manip,
3085         t_FmPcd *p_FmPcd,
3086         uint8_t poolId)
3087 {
3088     t_Handle p_Table;
3089     uint32_t tmpReg32 = 0;
3090     int i = 0;
3091     uint8_t log2Num;
3092     uint8_t numOfSets;
3093     uint32_t j = 0;
3094     uint32_t bitFor1Micro;
3095 
3096     SANITY_CHECK_RETURN_ERROR(p_Manip->h_Ad, E_INVALID_HANDLE);
3097     SANITY_CHECK_RETURN_ERROR(p_FmPcd->h_Hc, E_INVALID_HANDLE);
3098 
3099     if (!p_FmPcd->h_Hc)
3100         RETURN_ERROR(MAJOR, E_INVALID_VALUE,("hc port has to be initialized in this mode"));
3101     if (!POWER_OF_2(p_ManipParams->timeoutRoutineRequestTime))
3102         RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("timeoutRoutineRequestTime has to be power of 2"));
3103     if (!POWER_OF_2(p_ManipParams->maxNumFramesInProcess))
3104         RETURN_ERROR(MAJOR, E_INVALID_VALUE,("maxNumFramesInProcess has to be power of 2"));
3105     if (!p_ManipParams->timeoutRoutineRequestTime && p_ManipParams->timeoutThresholdForReassmProcess)
3106         DBG(WARNING, ("if timeoutRoutineRequestTime 0,  timeoutThresholdForReassmProcess is uselessly"));
3107     if (p_ManipParams->numOfFramesPerHashEntry == e_FM_PCD_MANIP_FOUR_WAYS_HASH)
3108     {
3109         if ((p_ManipParams->maxNumFramesInProcess < 4) ||
3110                 (p_ManipParams->maxNumFramesInProcess > 512))
3111         RETURN_ERROR(MAJOR,E_INVALID_VALUE, ("In the case of numOfFramesPerHashEntry = e_FM_PCD_MANIP_EIGHT_WAYS_HASH maxNumFramesInProcess has to be in the range 4-512"));
3112     }
3113     else
3114     {
3115         if ((p_ManipParams->maxNumFramesInProcess < 8) ||
3116                 (p_ManipParams->maxNumFramesInProcess > 2048))
3117         RETURN_ERROR(MAJOR,E_INVALID_VALUE, ("In the case of numOfFramesPerHashEntry = e_FM_PCD_MANIP_FOUR_WAYS_HASH maxNumFramesInProcess has to be in the range 8-2048"));
3118     }
3119 
3120     bitFor1Micro = FmGetTimeStampScale(p_FmPcd->h_Fm);
3121     if (bitFor1Micro == 0)
3122         RETURN_ERROR(MAJOR, E_NOT_AVAILABLE, ("Timestamp scale"));
3123 
3124     p_Manip->updateParams |= (NUM_OF_TASKS | OFFSET_OF_PR | OFFSET_OF_DATA | HW_PORT_ID);
3125 
3126     p_Manip->h_Frag = (t_Handle)FM_MURAM_AllocMem(p_FmPcd->h_FmMuram,
3127             FM_PCD_MANIP_CAPWAP_REASM_TABLE_SIZE,
3128             FM_PCD_MANIP_CAPWAP_REASM_TABLE_ALIGN);
3129     if (!p_Manip->h_Frag)
3130         RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM alloc CAPWAP reassembly parameters table"));
3131 
3132     MemSet8(p_Manip->h_Frag, 0, FM_PCD_MANIP_CAPWAP_REASM_TABLE_SIZE);
3133 
3134     p_Table = (t_CapwapReasmPram *)p_Manip->h_Frag;
3135 
3136     p_Manip->capwapFragParams.p_AutoLearnHashTbl =
3137     (t_Handle)FM_MURAM_AllocMem(p_FmPcd->h_FmMuram,
3138             (uint32_t)(p_ManipParams->maxNumFramesInProcess * 2 * FM_PCD_MANIP_CAPWAP_REASM_AUTO_LEARNING_HASH_ENTRY_SIZE),
3139             FM_PCD_MANIP_CAPWAP_REASM_TABLE_ALIGN);
3140 
3141     if (!p_Manip->capwapFragParams.p_AutoLearnHashTbl)
3142         RETURN_ERROR(MAJOR, E_NO_MEMORY,("MURAM alloc for CAPWAP automatic learning hash table"));
3143 
3144     MemSet8(p_Manip->capwapFragParams.p_AutoLearnHashTbl, 0, (uint32_t)(p_ManipParams->maxNumFramesInProcess * 2 * FM_PCD_MANIP_CAPWAP_REASM_AUTO_LEARNING_HASH_ENTRY_SIZE));
3145 
3146     tmpReg32 = (uint32_t)(XX_VirtToPhys(p_Manip->capwapFragParams.p_AutoLearnHashTbl) - p_FmPcd->physicalMuramBase);
3147 
3148     WRITE_UINT32(((t_CapwapReasmPram *)p_Table)->autoLearnHashTblPtr, tmpReg32);
3149 
3150     tmpReg32 = 0;
3151     if (p_ManipParams->timeOutMode == e_FM_PCD_MANIP_TIME_OUT_BETWEEN_FRAMES)
3152         tmpReg32 |= FM_PCD_MANIP_CAPWAP_REASM_TIME_OUT_BETWEEN_FRAMES;
3153     if (p_ManipParams->haltOnDuplicationFrag)
3154         tmpReg32 |= FM_PCD_MANIP_CAPWAP_REASM_HALT_ON_DUPLICATE_FRAG;
3155     if (p_ManipParams->numOfFramesPerHashEntry == e_FM_PCD_MANIP_EIGHT_WAYS_HASH)
3156     {
3157         i = 8;
3158         tmpReg32 |= FM_PCD_MANIP_CAPWAP_REASM_AUTOMATIC_LEARNIN_HASH_8_WAYS;
3159     }
3160     else
3161     i = 4;
3162 
3163     numOfSets = (uint8_t)((p_ManipParams->maxNumFramesInProcess * 2) / i);
3164     LOG2(numOfSets, log2Num);
3165     tmpReg32 |= (uint32_t)(log2Num - 1) << 24;
3166 
3167     WRITE_UINT32(((t_CapwapReasmPram *)p_Table)->mode, tmpReg32);
3168 
3169     for (j=0; j<p_ManipParams->maxNumFramesInProcess*2; j++)
3170         if (((j / i) % 2)== 0)
3171             WRITE_UINT32(*(uint32_t *)PTR_MOVE(p_Manip->capwapFragParams.p_AutoLearnHashTbl, j * FM_PCD_MANIP_CAPWAP_REASM_AUTO_LEARNING_HASH_ENTRY_SIZE), 0x80000000);
3172 
3173     tmpReg32 = 0x00008000;
3174     tmpReg32 |= (uint32_t)poolId << 16;
3175     WRITE_UINT32(((t_CapwapReasmPram *)p_Table)->bufferPoolIdAndRisc1SetIndexes, tmpReg32);
3176     WRITE_UINT32(((t_CapwapReasmPram *)p_Table)->risc23SetIndexes, 0x80008000);
3177     WRITE_UINT32(((t_CapwapReasmPram *)p_Table)->risc4SetIndexesAndExtendedStatsTblPtr, 0x80000000);
3178 
3179     p_Manip->capwapFragParams.maxNumFramesInProcess = p_ManipParams->maxNumFramesInProcess;
3180 
3181     p_Manip->capwapFragParams.sgBpid = poolId;
3182 
3183     p_Manip->capwapFragParams.fqidForTimeOutFrames = p_ManipParams->fqidForTimeOutFrames;
3184     p_Manip->capwapFragParams.timeoutRoutineRequestTime = p_ManipParams->timeoutRoutineRequestTime;
3185     p_Manip->capwapFragParams.bitFor1Micro = bitFor1Micro;
3186 
3187     tmpReg32 = 0;
3188     tmpReg32 |= (((uint32_t)1<<p_Manip->capwapFragParams.bitFor1Micro) * p_ManipParams->timeoutThresholdForReassmProcess);
3189     WRITE_UINT32(((t_CapwapReasmPram *)p_Table)->expirationDelay, tmpReg32);
3190 
3191     return E_OK;
3192 }
3193 
3194 static t_Error CapwapFragmentation(t_CapwapFragmentationParams *p_ManipParams,
3195         t_FmPcdManip *p_Manip,
3196         t_FmPcd *p_FmPcd,
3197         uint8_t poolId)
3198 {
3199     t_AdOfTypeContLookup *p_Ad;
3200     uint32_t tmpReg32 = 0;
3201 
3202     SANITY_CHECK_RETURN_ERROR(p_Manip->h_Ad,E_INVALID_HANDLE);
3203 
3204     p_Manip->updateParams |= OFFSET_OF_DATA;
3205 
3206     p_Manip->frag = TRUE;
3207 
3208     p_Manip->h_Frag = (t_Handle)FM_MURAM_AllocMem(p_FmPcd->h_FmMuram,
3209             FM_PCD_CC_AD_ENTRY_SIZE,
3210             FM_PCD_CC_AD_TABLE_ALIGN);
3211     if (!p_Manip->h_Frag)
3212     RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM alloc for CAPWAP fragmentation table descriptor"));
3213 
3214     MemSet8(p_Manip->h_Frag, 0, FM_PCD_CC_AD_ENTRY_SIZE);
3215 
3216     p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Frag;
3217 
3218     tmpReg32 = 0;
3219     tmpReg32 |= (uint32_t)HMAN_OC_CAPWAP_FRAGMENTATION;
3220 
3221     if (p_ManipParams->headerOptionsCompr)
3222     tmpReg32 |= FM_PCD_MANIP_CAPWAP_FRAG_COMPR_OPTION_FIELD_EN;
3223     tmpReg32 |= ((uint32_t)poolId << 8);
3224     WRITE_UINT32(p_Ad->pcAndOffsets, tmpReg32);
3225 
3226     tmpReg32 = 0;
3227     tmpReg32 |= FM_PCD_AD_CONT_LOOKUP_TYPE;
3228     WRITE_UINT32(p_Ad->ccAdBase, tmpReg32);
3229 
3230     p_Manip->sizeForFragmentation = p_ManipParams->sizeForFragmentation;
3231     p_Manip->capwapFragParams.sgBpid = poolId;
3232 
3233     return E_OK;
3234 }
3235 
3236 static t_Error IndxStats(t_FmPcdStatsParams *p_StatsParams,t_FmPcdManip *p_Manip,t_FmPcd *p_FmPcd)
3237 {
3238     t_AdOfTypeContLookup *p_Ad;
3239     uint32_t tmpReg32 = 0;
3240 
3241     SANITY_CHECK_RETURN_ERROR(p_Manip->h_Ad,E_INVALID_HANDLE);
3242 
3243     UNUSED(p_FmPcd);
3244 
3245     p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Ad;
3246 
3247     tmpReg32 = 0;
3248     tmpReg32 |= (uint32_t)HMAN_OC_CAPWAP_INDEXED_STATS;
3249     if (p_StatsParams->type == e_FM_PCD_STATS_PER_FLOWID)
3250     tmpReg32 |= (uint32_t)0x16 << 16;
3251     WRITE_UINT32(p_Ad->pcAndOffsets, tmpReg32);
3252 
3253     tmpReg32 = 0;
3254     tmpReg32 |= FM_PCD_AD_CONT_LOOKUP_TYPE;
3255     WRITE_UINT32(p_Ad->ccAdBase, tmpReg32);
3256 
3257     return E_OK;
3258 }
3259 
3260 static t_Error InsrtHdrByTempl(t_FmPcdManipHdrInsrtParams *p_ManipParams, t_FmPcdManip *p_Manip, t_FmPcd *p_FmPcd)
3261 {
3262     t_FmPcdManipHdrInsrtByTemplateParams *p_InsrtByTemplate = &p_ManipParams->u.byTemplate;
3263     uint8_t tmpReg8 = 0xff;
3264     t_AdOfTypeContLookup *p_Ad;
3265     bool ipModify = FALSE;
3266     uint32_t tmpReg32 = 0, tmpRegNia = 0;
3267     uint16_t tmpReg16 = 0;
3268     t_Error err = E_OK;
3269     uint8_t extraAddedBytes = 0, blockSize = 0, extraAddedBytesAlignedToBlockSize = 0, log2Num = 0;
3270     uint8_t *p_Template = NULL;
3271 
3272     SANITY_CHECK_RETURN_ERROR(p_ManipParams,E_NULL_POINTER);
3273     SANITY_CHECK_RETURN_ERROR(p_Manip,E_NULL_POINTER);
3274     SANITY_CHECK_RETURN_ERROR(p_Manip->h_Ad,E_INVALID_HANDLE);
3275     SANITY_CHECK_RETURN_ERROR(p_FmPcd,E_NULL_POINTER);
3276 
3277     p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Ad;
3278     if (p_Manip->insrt)
3279     {
3280         if ((!p_InsrtByTemplate->size && p_InsrtByTemplate->modifyOuterIp) ||
3281                 (!p_InsrtByTemplate->size && p_InsrtByTemplate->modifyOuterVlan))
3282         RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Inconsistent parameters : asking for header template modifications with no template for insertion (template size)"));
3283 
3284         if (p_InsrtByTemplate->size && p_InsrtByTemplate->modifyOuterIp && (p_InsrtByTemplate->size <= p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset))
3285         RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Inconsistent parameters : size of template < ipOuterOffset"));
3286 
3287         if (p_InsrtByTemplate->size > 128)
3288         RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Size of header template for insertion can not be more than 128"));
3289 
3290         if (p_InsrtByTemplate->size)
3291         {
3292             p_Manip->p_Template = (uint8_t *)FM_MURAM_AllocMem(p_FmPcd->h_FmMuram,
3293                     p_InsrtByTemplate->size,
3294                     FM_PCD_CC_AD_TABLE_ALIGN);
3295             if(!p_Manip->p_Template)
3296             RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Memory allocation in MURAM FAILED"));
3297 
3298             tmpReg32 = (uint32_t)(XX_VirtToPhys(p_Manip->p_Template) - (p_FmPcd->physicalMuramBase));
3299             tmpReg32 |= (uint32_t)p_InsrtByTemplate->size << 24;
3300             *(uint32_t *)&p_Ad->matchTblPtr = tmpReg32;
3301         }
3302 
3303         tmpReg32 = 0;
3304 
3305         p_Template = (uint8_t *)XX_Malloc(p_InsrtByTemplate->size * sizeof(uint8_t));
3306 
3307         if (!p_Template)
3308         RETURN_ERROR(MAJOR, E_NO_MEMORY, ("XX_Malloc allocation FAILED"));
3309 
3310         memcpy(p_Template, p_InsrtByTemplate->hdrTemplate, p_InsrtByTemplate->size * sizeof(uint8_t));
3311 
3312         if (p_InsrtByTemplate->modifyOuterIp)
3313         {
3314             ipModify = TRUE;
3315 
3316             tmpReg8 = (uint8_t)p_Template[p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset];
3317 
3318             if((tmpReg8 & 0xf0) == 0x40)
3319             tmpReg8 = 4;
3320             else if((tmpReg8 & 0xf0) == 0x60)
3321             tmpReg8 = 6;
3322             else
3323             tmpReg8 = 0xff;
3324 
3325             if (tmpReg8 != 0xff)
3326             {
3327                 if(p_InsrtByTemplate->modifyOuterIpParams.dscpEcn & 0xff00)
3328                 RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Inconsistent parameters : IPV4 present in header template, dscpEcn has to be only 1 byte"));
3329                 if(p_InsrtByTemplate->modifyOuterIpParams.recalculateLength)
3330                 {
3331 
3332                     if((p_InsrtByTemplate->modifyOuterIpParams.recalculateLengthParams.extraBytesAddedAlignedToBlockSize + p_InsrtByTemplate->modifyOuterIpParams.recalculateLengthParams.extraBytesAddedNotAlignedToBlockSize) > 255)
3333                     RETURN_ERROR(MAJOR, E_INVALID_STATE, ("extra Byte added can not be more than 256 bytes"));
3334                     extraAddedBytes = (uint8_t) (p_InsrtByTemplate->modifyOuterIpParams.recalculateLengthParams.extraBytesAddedAlignedToBlockSize + p_InsrtByTemplate->modifyOuterIpParams.recalculateLengthParams.extraBytesAddedNotAlignedToBlockSize);
3335                     blockSize = p_InsrtByTemplate->modifyOuterIpParams.recalculateLengthParams.blockSize;
3336                     extraAddedBytesAlignedToBlockSize = p_InsrtByTemplate->modifyOuterIpParams.recalculateLengthParams.extraBytesAddedAlignedToBlockSize;
3337                     /*IP header template - IP totalLength -
3338                      (1 byte) extraByteForIp = headerTemplateSize - ipOffset + insertedBytesAfterThisStage ,
3339                      in the case of SEC insertedBytesAfterThisStage - SEC trailer (21/31) + header(13)
3340                      second byte - extraByteForIp = headerTemplate - ipOffset + insertedBytesAfterThisStage*/
3341                 }
3342                 if (blockSize)
3343                 {
3344                     if (!POWER_OF_2(blockSize))
3345                     RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("inputFrmPaddingUpToBlockSize has to be power of 2"));
3346                 }
3347 
3348             }
3349             if (tmpReg8 == 4)
3350             {
3351                 if ((IPv4_HDRCHECKSUM_FIELD_OFFSET_FROM_IP + p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset) > p_InsrtByTemplate->size)
3352                 RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Inconsistent parameters : IP present in header template, user asked for IP modifications but ipOffset + ipTotalLengthFieldOffset in header template bigger than template size"));
3353 
3354                 p_Template[p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset + IPv4_DSCECN_FIELD_OFFSET_FROM_IP] = (uint8_t)p_InsrtByTemplate->modifyOuterIpParams.dscpEcn;
3355 
3356                 if (blockSize)
3357                 blockSize -= 1;
3358 
3359                 if ((p_InsrtByTemplate->size - p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset + extraAddedBytes) > 255)
3360                 RETURN_ERROR(MAJOR, E_INVALID_STATE, ("p_InsrtByTemplate->size - p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset + extraAddedBytes has to be less than 255"));
3361 
3362                 p_Template[p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset + IPv4_TOTALLENGTH_FIELD_OFFSET_FROM_IP + 1] = blockSize; // IPV6 - in AD instead of SEQ IND
3363                 p_Template[p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset + IPv4_TOTALLENGTH_FIELD_OFFSET_FROM_IP] = (uint8_t)(p_InsrtByTemplate->size - p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset + extraAddedBytes);// for IPV6 decrement additional 40 bytes of IPV6 heade size
3364 
3365                 p_Template[p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset + IPv4_ID_FIELD_OFFSET_FROM_IP] = 0x00;
3366                 p_Template[p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset + IPv4_ID_FIELD_OFFSET_FROM_IP + 1] = extraAddedBytesAlignedToBlockSize;
3367 
3368                 /*IP header template - relevant only for ipv4 CheckSum = 0*/
3369                 p_Template[p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset + IPv4_HDRCHECKSUM_FIELD_OFFSET_FROM_IP] = 0x00;
3370                 p_Template[p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset + IPv4_HDRCHECKSUM_FIELD_OFFSET_FROM_IP + 1] = 0x00;
3371 
3372                 /*UDP checksum has to be 0*/
3373                 if (p_InsrtByTemplate->modifyOuterIpParams.udpPresent)
3374                 {
3375                     if ((p_InsrtByTemplate->modifyOuterIpParams.udpOffset + UDP_CHECKSUM_FIELD_OFFSET_FROM_UDP + UDP_CHECKSUM_FIELD_SIZE) > p_InsrtByTemplate->size)
3376                     RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Inconsistent parameters : UDP present according to user but (UDP offset + UDP header size) < size of header template"));
3377 
3378                     p_Template[p_InsrtByTemplate->modifyOuterIpParams.udpOffset + UDP_CHECKSUM_FIELD_OFFSET_FROM_UDP ] = 0x00;
3379                     p_Template[p_InsrtByTemplate->modifyOuterIpParams.udpOffset + UDP_CHECKSUM_FIELD_OFFSET_FROM_UDP + 1] = 0x00;
3380 
3381                 }
3382 
3383                 if (p_InsrtByTemplate->modifyOuterIpParams.ipIdentGenId > 7)
3384                 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("ipIdentGenId has to be one out of 8 sequence number generators (0 - 7) for IP identification field"));
3385 
3386                 tmpRegNia |= (uint32_t)p_InsrtByTemplate->modifyOuterIpParams.ipIdentGenId<<24;
3387             }
3388             else if (tmpReg8 == 6)
3389             {
3390                 /*TODO - add check for maximum value of blockSize;*/
3391                 if (blockSize)
3392                 LOG2(blockSize, log2Num);
3393                 tmpRegNia |= (uint32_t)log2Num << 24;
3394 
3395                 // for IPV6 decrement additional 40 bytes of IPV6 heade size - because IPV6 header size is not included in payloadLength
3396                 p_Template[p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset + IPv6_PAYLOAD_LENGTH_OFFSET_FROM_IP] = (uint8_t)(p_InsrtByTemplate->size - p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset + extraAddedBytes - 40);
3397                 p_Template[p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset + IPv6_PAYLOAD_LENGTH_OFFSET_FROM_IP + 1] = extraAddedBytesAlignedToBlockSize;
3398                 if (p_InsrtByTemplate->modifyOuterIpParams.udpPresent)
3399                 {
3400                     if ((p_InsrtByTemplate->modifyOuterIpParams.udpOffset + UDP_CHECKSUM_FIELD_OFFSET_FROM_UDP + UDP_CHECKSUM_FIELD_SIZE) > p_InsrtByTemplate->size)
3401                     RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Inconsistent parameters : UDP present according to user but (UDP offset + UDP header size) < size of header template"));
3402                     if (p_Template[p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset + IPv6_NEXT_HEADER_OFFSET_FROM_IP] != 0x88)
3403                     RETURN_ERROR(MAJOR, E_INVALID_STATE, ("OUr suppport is only IPv6/UDPLite"));
3404                     p_Template[p_InsrtByTemplate->modifyOuterIpParams.udpOffset + UDP_LENGTH_FIELD_OFFSET_FROM_UDP] = 0x00;
3405                     p_Template[p_InsrtByTemplate->modifyOuterIpParams.udpOffset + UDP_LENGTH_FIELD_OFFSET_FROM_UDP + 1] = 0x08;
3406                     p_Template[p_InsrtByTemplate->modifyOuterIpParams.udpOffset + UDP_CHECKSUM_FIELD_OFFSET_FROM_UDP] = 0x00;
3407                     p_Template[p_InsrtByTemplate->modifyOuterIpParams.udpOffset + UDP_CHECKSUM_FIELD_OFFSET_FROM_UDP + 1] = 0x00;
3408                 }
3409             }
3410             else
3411             RETURN_ERROR(MAJOR, E_INVALID_STATE, ("IP version supported only IPV4"));
3412         }
3413 
3414         tmpReg32 = tmpReg16 = tmpReg8 = 0;
3415         /*TODO - check it*/
3416         if (p_InsrtByTemplate->modifyOuterVlan)
3417         {
3418             if (p_InsrtByTemplate->modifyOuterVlanParams.vpri & ~0x07)
3419             RETURN_ERROR(MAJOR, E_INVALID_STATE,("Inconsistent parameters : user asked for VLAN modifications but VPRI more than 3 bits"));
3420 
3421             memcpy(&tmpReg16, &p_Template[VLAN_TAG_FIELD_OFFSET_FROM_ETH], 2*(sizeof(uint8_t)));
3422             if ((tmpReg16 != 0x9100) && (tmpReg16!= 0x9200) && (tmpReg16 != 0x8100))
3423             RETURN_ERROR(MAJOR, E_INVALID_STATE,("Inconsistent parameters : user asked for VLAN modifications but Tag Protocol identifier is not VLAN "));
3424 
3425             memcpy(&tmpReg8, &p_Template[14],1*(sizeof(uint8_t)));
3426             tmpReg8 &= 0x1f;
3427             tmpReg8 |= (uint8_t)(p_InsrtByTemplate->modifyOuterVlanParams.vpri << 5);
3428 
3429             p_Template[14] = tmpReg8;
3430         }
3431 
3432         MemCpy8(p_Manip->p_Template, p_Template, p_InsrtByTemplate->size);
3433 
3434         XX_Free(p_Template);
3435     }
3436 
3437     tmpReg32 = 0;
3438     if (p_Manip->h_Frag)
3439     {
3440         tmpRegNia |= (uint32_t)(XX_VirtToPhys(p_Manip->h_Frag) - (p_FmPcd->physicalMuramBase));
3441         tmpReg32 |= (uint32_t)p_Manip->sizeForFragmentation << 16;
3442     }
3443     else
3444     tmpReg32 = 0xffff0000;
3445 
3446     if (ipModify)
3447     tmpReg32 |= (uint32_t)p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset << 8;
3448     else
3449     tmpReg32 |= (uint32_t)0x0000ff00;
3450 
3451     tmpReg32 |= (uint32_t)HMAN_OC_INSRT_HDR_BY_TEMPL_N_OR_FRAG_AFTER;
3452     *(uint32_t *)&p_Ad->pcAndOffsets = tmpReg32;
3453 
3454     tmpRegNia |= FM_PCD_AD_CONT_LOOKUP_TYPE;
3455     *(uint32_t *)&p_Ad->ccAdBase = tmpRegNia;
3456 
3457     return err;
3458 }
3459 
3460 static t_Error CheckStatsParamsAndSetType(t_FmPcdManip *p_Manip, t_FmPcdStatsParams *p_StatsParams)
3461 {
3462 
3463     switch (p_StatsParams->type)
3464     {
3465         case (e_FM_PCD_STATS_PER_FLOWID):
3466         p_Manip->opcode = HMAN_OC_CAPWAP_INDEXED_STATS;
3467         p_Manip->muramAllocate = TRUE;
3468         break;
3469         default:
3470         RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Unsupported statistics type"));
3471     }
3472 
3473     return E_OK;
3474 }
3475 #endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */
3476 
3477 static t_Error FillReassmManipParams(t_FmPcdManip *p_Manip, e_NetHeaderType hdr)
3478 {
3479     t_AdOfTypeContLookup *p_Ad;
3480     t_FmPcd *p_FmPcd = (t_FmPcd *)p_Manip->h_FmPcd;
3481     uint32_t tmpReg32;
3482     t_Error err = E_OK;
3483 
3484     /* Creates the Reassembly Parameters table. It contains parameters that are specific to either the IPv4 reassembly
3485      function or to the IPv6 reassembly function. If both IPv4 reassembly and IPv6 reassembly are required, then
3486      two separate IP Reassembly Parameter tables are required.*/
3487     if ((err = CreateReassTable(p_Manip, hdr)) != E_OK)
3488         RETURN_ERROR(MAJOR, err, NO_MSG);
3489 
3490     /* Sets the first Ad register (ccAdBase) - Action Descriptor Type and Pointer to the Reassembly Parameters Table offset from MURAM*/
3491     tmpReg32 = 0;
3492     tmpReg32 |= FM_PCD_AD_CONT_LOOKUP_TYPE;
3493 
3494     /* Gets the required Action descriptor table pointer */
3495     switch (hdr)
3496     {
3497         case HEADER_TYPE_IPv4:
3498             p_Ad = (t_AdOfTypeContLookup *)p_Manip->reassmParams.ip.h_Ipv4Ad;
3499             tmpReg32 |= (uint32_t)(XX_VirtToPhys(
3500                     p_Manip->reassmParams.ip.p_Ipv4ReassTbl)
3501                     - (p_FmPcd->physicalMuramBase));
3502             break;
3503         case HEADER_TYPE_IPv6:
3504             p_Ad = (t_AdOfTypeContLookup *)p_Manip->reassmParams.ip.h_Ipv6Ad;
3505             tmpReg32 |= (uint32_t)(XX_VirtToPhys(
3506                     p_Manip->reassmParams.ip.p_Ipv6ReassTbl)
3507                     - (p_FmPcd->physicalMuramBase));
3508             break;
3509         case HEADER_TYPE_CAPWAP:
3510             p_Ad = (t_AdOfTypeContLookup *)p_Manip->reassmParams.capwap.h_Ad;
3511             tmpReg32 |= (uint32_t)(XX_VirtToPhys(
3512                     p_Manip->reassmParams.capwap.p_ReassTbl)
3513                     - (p_FmPcd->physicalMuramBase));
3514             break;
3515         default:
3516             RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("header type"));
3517     }
3518 
3519     WRITE_UINT32(p_Ad->ccAdBase, tmpReg32);
3520 
3521     /* Sets the second Ad register (matchTblPtr) - Buffer pool ID (BPID for V2) and Scatter/Gather table offset*/
3522     /* mark the Scatter/Gather table offset to be set later on when the port will be known */
3523     p_Manip->updateParams = (NUM_OF_TASKS | NUM_OF_EXTRA_TASKS | DISCARD_MASK);
3524 
3525     if ((hdr == HEADER_TYPE_IPv6) || (hdr == HEADER_TYPE_IPv4))
3526     {
3527 #if (DPAA_VERSION == 10)
3528         tmpReg32 = (uint32_t)(p_Manip->reassmParams.sgBpid << 8);
3529         WRITE_UINT32(p_Ad->matchTblPtr, tmpReg32);
3530 #endif /* (DPAA_VERSION == 10) */
3531 #if (DPAA_VERSION >= 11)
3532         if (p_Manip->reassmParams.ip.nonConsistentSpFqid != 0)
3533         {
3534             tmpReg32 = FM_PCD_AD_NCSPFQIDM_MASK
3535                     | (uint32_t)(p_Manip->reassmParams.ip.nonConsistentSpFqid);
3536             WRITE_UINT32(p_Ad->gmask, tmpReg32);
3537         }
3538 #endif /* (DPAA_VERSION >= 11) */
3539         /* Sets the third Ad register (pcAndOffsets)- IP Reassemble Operation Code*/
3540         tmpReg32 = 0;
3541         tmpReg32 |= (uint32_t)HMAN_OC_IP_REASSEMBLY;
3542     }
3543 #if (DPAA_VERSION >= 11)
3544     else
3545         if (hdr == HEADER_TYPE_CAPWAP)
3546         {
3547             tmpReg32 = 0;
3548             tmpReg32 |= (uint32_t)HMAN_OC_CAPWAP_REASSEMBLY;
3549         }
3550 #endif /* (DPAA_VERSION >= 11) */
3551 
3552     WRITE_UINT32(p_Ad->pcAndOffsets, tmpReg32);
3553 
3554     p_Manip->reassm = TRUE;
3555 
3556     return E_OK;
3557 }
3558 
3559 static t_Error SetIpv4ReassmManip(t_FmPcdManip *p_Manip)
3560 {
3561     t_FmPcd *p_FmPcd = (t_FmPcd *)p_Manip->h_FmPcd;
3562 
3563     /* Allocation if IPv4 Action descriptor */
3564     p_Manip->reassmParams.ip.h_Ipv4Ad = (t_Handle)XX_MallocSmart(
3565             FM_PCD_CC_AD_ENTRY_SIZE, p_Manip->reassmParams.dataMemId,
3566             FM_PCD_CC_AD_TABLE_ALIGN);
3567     if (!p_Manip->reassmParams.ip.h_Ipv4Ad)
3568     {
3569         ReleaseManipHandler(p_Manip, p_FmPcd);
3570         RETURN_ERROR(MAJOR, E_NO_MEMORY,
3571                      ("Allocation of IPv4 table descriptor"));
3572     }
3573 
3574     memset(p_Manip->reassmParams.ip.h_Ipv4Ad, 0, FM_PCD_CC_AD_ENTRY_SIZE);
3575 
3576     /* Fill reassembly manipulation parameter in the IP Reassembly Action Descriptor */
3577     return FillReassmManipParams(p_Manip, HEADER_TYPE_IPv4);
3578 }
3579 
3580 static t_Error SetIpv6ReassmManip(t_FmPcdManip *p_Manip)
3581 {
3582     t_FmPcd *p_FmPcd = (t_FmPcd *)p_Manip->h_FmPcd;
3583 
3584     /* Allocation if IPv6 Action descriptor */
3585     p_Manip->reassmParams.ip.h_Ipv6Ad = (t_Handle)XX_MallocSmart(
3586             FM_PCD_CC_AD_ENTRY_SIZE, p_Manip->reassmParams.dataMemId,
3587             FM_PCD_CC_AD_TABLE_ALIGN);
3588     if (!p_Manip->reassmParams.ip.h_Ipv6Ad)
3589     {
3590         ReleaseManipHandler(p_Manip, p_FmPcd);
3591         RETURN_ERROR(MAJOR, E_NO_MEMORY,
3592                      ("Allocation of IPv6 table descriptor"));
3593     }
3594 
3595     memset(p_Manip->reassmParams.ip.h_Ipv6Ad, 0, FM_PCD_CC_AD_ENTRY_SIZE);
3596 
3597     /* Fill reassembly manipulation parameter in the IP Reassembly Action Descriptor */
3598     return FillReassmManipParams(p_Manip, HEADER_TYPE_IPv6);
3599 }
3600 
3601 static t_Error IpReassembly(t_FmPcdManipReassemParams *p_ManipReassmParams,
3602                             t_FmPcdManip *p_Manip)
3603 {
3604     uint32_t maxSetNumber = 10000;
3605     t_FmPcdManipReassemIpParams reassmManipParams =
3606             p_ManipReassmParams->u.ipReassem;
3607     t_Error res;
3608 
3609     SANITY_CHECK_RETURN_ERROR(p_Manip->h_FmPcd, E_INVALID_HANDLE);
3610     SANITY_CHECK_RETURN_ERROR(((t_FmPcd *)p_Manip->h_FmPcd)->h_Hc,
3611                               E_INVALID_HANDLE);
3612 
3613     /* Check validation of user's parameter.*/
3614     if ((reassmManipParams.timeoutThresholdForReassmProcess < 1000)
3615             || (reassmManipParams.timeoutThresholdForReassmProcess > 8000000))
3616         RETURN_ERROR(
3617                 MAJOR, E_INVALID_VALUE,
3618                 ("timeoutThresholdForReassmProcess should be 1msec - 8sec"));
3619     /* It is recommended that the total number of entries in this table (number of sets * number of ways)
3620      will be twice the number of frames that are expected to be reassembled simultaneously.*/
3621     if (reassmManipParams.maxNumFramesInProcess
3622             > (reassmManipParams.maxNumFramesInProcess * maxSetNumber / 2))
3623         RETURN_ERROR(
3624                 MAJOR,
3625                 E_INVALID_VALUE,
3626                 ("maxNumFramesInProcess has to be less than (maximun set number * number of ways / 2)"));
3627 
3628     if ((p_ManipReassmParams->hdr == HEADER_TYPE_IPv6)
3629             && (reassmManipParams.minFragSize[1] < 256))
3630         RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("minFragSize[1] must be >= 256"));
3631 
3632     /* Saves user's reassembly manipulation parameters */
3633     p_Manip->reassmParams.ip.relativeSchemeId[0] =
3634             reassmManipParams.relativeSchemeId[0];
3635     p_Manip->reassmParams.ip.relativeSchemeId[1] =
3636             reassmManipParams.relativeSchemeId[1];
3637     p_Manip->reassmParams.ip.numOfFramesPerHashEntry[0] =
3638             reassmManipParams.numOfFramesPerHashEntry[0];
3639     p_Manip->reassmParams.ip.numOfFramesPerHashEntry[1] =
3640             reassmManipParams.numOfFramesPerHashEntry[1];
3641     p_Manip->reassmParams.ip.minFragSize[0] = reassmManipParams.minFragSize[0];
3642     p_Manip->reassmParams.ip.minFragSize[1] = reassmManipParams.minFragSize[1];
3643     p_Manip->reassmParams.maxNumFramesInProcess =
3644             reassmManipParams.maxNumFramesInProcess;
3645     p_Manip->reassmParams.timeOutMode = reassmManipParams.timeOutMode;
3646     p_Manip->reassmParams.fqidForTimeOutFrames =
3647             reassmManipParams.fqidForTimeOutFrames;
3648     p_Manip->reassmParams.timeoutThresholdForReassmProcess =
3649             reassmManipParams.timeoutThresholdForReassmProcess;
3650     p_Manip->reassmParams.dataMemId = reassmManipParams.dataMemId;
3651     p_Manip->reassmParams.dataLiodnOffset = reassmManipParams.dataLiodnOffset;
3652 #if (DPAA_VERSION == 10)
3653     p_Manip->reassmParams.sgBpid = reassmManipParams.sgBpid;
3654 #endif /* (DPAA_VERSION == 10) */
3655 #if (DPAA_VERSION >= 11)
3656     if (reassmManipParams.nonConsistentSpFqid != 0)
3657     {
3658         p_Manip->reassmParams.ip.nonConsistentSpFqid =
3659                 reassmManipParams.nonConsistentSpFqid;
3660     }
3661 #endif /* (DPAA_VERSION >= 11) */
3662 
3663     /* Creates and initializes the IP Reassembly common parameter table */
3664     CreateReassCommonTable(p_Manip);
3665 
3666     /* Creation of IPv4 reassembly manipulation */
3667     if ((p_Manip->reassmParams.hdr == HEADER_TYPE_IPv6)
3668             || (p_Manip->reassmParams.hdr == HEADER_TYPE_IPv4))
3669     {
3670         res = SetIpv4ReassmManip(p_Manip);
3671         if (res != E_OK)
3672             return res;
3673     }
3674 
3675     /* Creation of IPv6 reassembly manipulation */
3676     if (p_Manip->reassmParams.hdr == HEADER_TYPE_IPv6)
3677     {
3678         res = SetIpv6ReassmManip(p_Manip);
3679         if (res != E_OK)
3680             return res;
3681     }
3682 
3683     return E_OK;
3684 }
3685 
3686 static void setIpReassmSchemeParams(t_FmPcd* p_FmPcd,
3687                                     t_FmPcdKgSchemeParams *p_Scheme,
3688                                     t_Handle h_CcTree, bool ipv4,
3689                                     uint8_t groupId)
3690 {
3691     uint32_t j;
3692     uint8_t res;
3693 
3694     /* Configures scheme's network environment parameters */
3695     p_Scheme->netEnvParams.numOfDistinctionUnits = 2;
3696     if (ipv4)
3697         res = FmPcdNetEnvGetUnitId(
3698                 p_FmPcd, FmPcdGetNetEnvId(p_Scheme->netEnvParams.h_NetEnv),
3699                 HEADER_TYPE_IPv4, FALSE, 0);
3700     else
3701         res = FmPcdNetEnvGetUnitId(
3702                 p_FmPcd, FmPcdGetNetEnvId(p_Scheme->netEnvParams.h_NetEnv),
3703                 HEADER_TYPE_IPv6, FALSE, 0);
3704     ASSERT_COND(res != FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS);
3705     p_Scheme->netEnvParams.unitIds[0] = res;
3706 
3707     res = FmPcdNetEnvGetUnitId(
3708             p_FmPcd, FmPcdGetNetEnvId(p_Scheme->netEnvParams.h_NetEnv),
3709             HEADER_TYPE_USER_DEFINED_SHIM2, FALSE, 0);
3710     ASSERT_COND(res != FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS);
3711     p_Scheme->netEnvParams.unitIds[1] = res;
3712 
3713     /* Configures scheme's next engine parameters*/
3714     p_Scheme->nextEngine = e_FM_PCD_CC;
3715     p_Scheme->kgNextEngineParams.cc.h_CcTree = h_CcTree;
3716     p_Scheme->kgNextEngineParams.cc.grpId = groupId;
3717     p_Scheme->useHash = TRUE;
3718 
3719     /* Configures scheme's key*/
3720     if (ipv4 == TRUE)
3721     {
3722         p_Scheme->keyExtractAndHashParams.numOfUsedExtracts = 4;
3723         p_Scheme->keyExtractAndHashParams.extractArray[0].type =
3724                 e_FM_PCD_EXTRACT_BY_HDR;
3725         p_Scheme->keyExtractAndHashParams.extractArray[0].extractByHdr.type =
3726                 e_FM_PCD_EXTRACT_FULL_FIELD;
3727         p_Scheme->keyExtractAndHashParams.extractArray[0].extractByHdr.hdr =
3728                 HEADER_TYPE_IPv4;
3729         p_Scheme->keyExtractAndHashParams.extractArray[0].extractByHdr.extractByHdrType.fullField.ipv4 =
3730                 NET_HEADER_FIELD_IPv4_DST_IP;
3731         p_Scheme->keyExtractAndHashParams.extractArray[1].type =
3732                 e_FM_PCD_EXTRACT_BY_HDR;
3733         p_Scheme->keyExtractAndHashParams.extractArray[1].extractByHdr.type =
3734                 e_FM_PCD_EXTRACT_FULL_FIELD;
3735         p_Scheme->keyExtractAndHashParams.extractArray[1].extractByHdr.hdr =
3736                 HEADER_TYPE_IPv4;
3737         p_Scheme->keyExtractAndHashParams.extractArray[1].extractByHdr.extractByHdrType.fullField.ipv4 =
3738                 NET_HEADER_FIELD_IPv4_SRC_IP;
3739         p_Scheme->keyExtractAndHashParams.extractArray[2].type =
3740                 e_FM_PCD_EXTRACT_BY_HDR;
3741         p_Scheme->keyExtractAndHashParams.extractArray[2].extractByHdr.type =
3742                 e_FM_PCD_EXTRACT_FULL_FIELD;
3743         p_Scheme->keyExtractAndHashParams.extractArray[2].extractByHdr.hdr =
3744                 HEADER_TYPE_IPv4;
3745         p_Scheme->keyExtractAndHashParams.extractArray[2].extractByHdr.extractByHdrType.fullField.ipv4 =
3746                 NET_HEADER_FIELD_IPv4_PROTO;
3747         p_Scheme->keyExtractAndHashParams.extractArray[3].type =
3748                 e_FM_PCD_EXTRACT_BY_HDR;
3749         p_Scheme->keyExtractAndHashParams.extractArray[3].extractByHdr.hdr =
3750                 HEADER_TYPE_IPv4;
3751         p_Scheme->keyExtractAndHashParams.extractArray[3].extractByHdr.type =
3752                 e_FM_PCD_EXTRACT_FROM_HDR;
3753         p_Scheme->keyExtractAndHashParams.extractArray[3].extractByHdr.ignoreProtocolValidation =
3754                 FALSE;
3755         p_Scheme->keyExtractAndHashParams.extractArray[3].extractByHdr.extractByHdrType.fromHdr.size =
3756                 2;
3757         p_Scheme->keyExtractAndHashParams.extractArray[3].extractByHdr.extractByHdrType.fromHdr.offset =
3758                 4;
3759     }
3760     else /* IPv6 */
3761     {
3762         p_Scheme->keyExtractAndHashParams.numOfUsedExtracts = 3;
3763         p_Scheme->keyExtractAndHashParams.extractArray[0].type =
3764                 e_FM_PCD_EXTRACT_BY_HDR;
3765         p_Scheme->keyExtractAndHashParams.extractArray[0].extractByHdr.type =
3766                 e_FM_PCD_EXTRACT_FULL_FIELD;
3767         p_Scheme->keyExtractAndHashParams.extractArray[0].extractByHdr.hdr =
3768                 HEADER_TYPE_IPv6;
3769         p_Scheme->keyExtractAndHashParams.extractArray[0].extractByHdr.extractByHdrType.fullField.ipv6 =
3770                 NET_HEADER_FIELD_IPv6_DST_IP;
3771         p_Scheme->keyExtractAndHashParams.extractArray[1].type =
3772                 e_FM_PCD_EXTRACT_BY_HDR;
3773         p_Scheme->keyExtractAndHashParams.extractArray[1].extractByHdr.type =
3774                 e_FM_PCD_EXTRACT_FULL_FIELD;
3775         p_Scheme->keyExtractAndHashParams.extractArray[1].extractByHdr.hdr =
3776                 HEADER_TYPE_IPv6;
3777         p_Scheme->keyExtractAndHashParams.extractArray[1].extractByHdr.extractByHdrType.fullField.ipv6 =
3778                 NET_HEADER_FIELD_IPv6_SRC_IP;
3779         p_Scheme->keyExtractAndHashParams.extractArray[2].type =
3780                 e_FM_PCD_EXTRACT_BY_HDR;
3781         p_Scheme->keyExtractAndHashParams.extractArray[2].extractByHdr.hdr =
3782                 HEADER_TYPE_USER_DEFINED_SHIM2;
3783         p_Scheme->keyExtractAndHashParams.extractArray[2].extractByHdr.type =
3784                 e_FM_PCD_EXTRACT_FROM_HDR;
3785         p_Scheme->keyExtractAndHashParams.extractArray[2].extractByHdr.extractByHdrType.fromHdr.size =
3786                 4;
3787         p_Scheme->keyExtractAndHashParams.extractArray[2].extractByHdr.extractByHdrType.fromHdr.offset =
3788                 4;
3789         p_Scheme->keyExtractAndHashParams.extractArray[2].extractByHdr.ignoreProtocolValidation =
3790                 TRUE;
3791     }
3792 
3793     p_Scheme->keyExtractAndHashParams.privateDflt0 = 0x01020304;
3794     p_Scheme->keyExtractAndHashParams.privateDflt1 = 0x11121314;
3795     p_Scheme->keyExtractAndHashParams.numOfUsedDflts =
3796             FM_PCD_KG_NUM_OF_DEFAULT_GROUPS;
3797     for (j = 0; j < FM_PCD_KG_NUM_OF_DEFAULT_GROUPS; j++)
3798     {
3799         p_Scheme->keyExtractAndHashParams.dflts[j].type =
3800                 (e_FmPcdKgKnownFieldsDfltTypes)j; /* all types */
3801         p_Scheme->keyExtractAndHashParams.dflts[j].dfltSelect =
3802                 e_FM_PCD_KG_DFLT_GBL_0;
3803     }
3804 }
3805 
3806 static t_Error IpReassemblyStats(t_FmPcdManip *p_Manip,
3807                                  t_FmPcdManipReassemIpStats *p_Stats)
3808 {
3809     ASSERT_COND(p_Manip);
3810     ASSERT_COND(p_Stats);
3811     ASSERT_COND(p_Manip->reassmParams.p_ReassCommonTbl);
3812 
3813     p_Stats->timeout =
3814             GET_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->totalTimeOutCounter);
3815     p_Stats->rfdPoolBusy =
3816             GET_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->totalRfdPoolBusyCounter);
3817     p_Stats->internalBufferBusy =
3818             GET_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->totalInternalBufferBusy);
3819     p_Stats->externalBufferBusy =
3820             GET_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->totalExternalBufferBusy);
3821     p_Stats->sgFragments =
3822             GET_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->totalSgFragmentCounter);
3823     p_Stats->dmaSemaphoreDepletion =
3824             GET_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->totalDmaSemaphoreDepletionCounter);
3825 #if (DPAA_VERSION >= 11)
3826     p_Stats->nonConsistentSp =
3827             GET_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->totalNCSPCounter);
3828 #endif /* (DPAA_VERSION >= 11) */
3829 
3830     if (p_Manip->reassmParams.ip.p_Ipv4ReassTbl)
3831     {
3832         p_Stats->specificHdrStatistics[0].successfullyReassembled =
3833                 GET_UINT32(p_Manip->reassmParams.ip.p_Ipv4ReassTbl->totalSuccessfullyReasmFramesCounter);
3834         p_Stats->specificHdrStatistics[0].validFragments =
3835                 GET_UINT32(p_Manip->reassmParams.ip.p_Ipv4ReassTbl->totalValidFragmentCounter);
3836         p_Stats->specificHdrStatistics[0].processedFragments =
3837                 GET_UINT32(p_Manip->reassmParams.ip.p_Ipv4ReassTbl->totalProcessedFragCounter);
3838         p_Stats->specificHdrStatistics[0].malformedFragments =
3839                 GET_UINT32(p_Manip->reassmParams.ip.p_Ipv4ReassTbl->totalMalformdFragCounter);
3840         p_Stats->specificHdrStatistics[0].autoLearnBusy =
3841                 GET_UINT32(p_Manip->reassmParams.ip.p_Ipv4ReassTbl->totalSetBusyCounter);
3842         p_Stats->specificHdrStatistics[0].discardedFragments =
3843                 GET_UINT32(p_Manip->reassmParams.ip.p_Ipv4ReassTbl->totalDiscardedFragsCounter);
3844         p_Stats->specificHdrStatistics[0].moreThan16Fragments =
3845                 GET_UINT32(p_Manip->reassmParams.ip.p_Ipv4ReassTbl->totalMoreThan16FramesCounter);
3846     }
3847     if (p_Manip->reassmParams.ip.p_Ipv6ReassTbl)
3848     {
3849         p_Stats->specificHdrStatistics[1].successfullyReassembled =
3850                 GET_UINT32(p_Manip->reassmParams.ip.p_Ipv6ReassTbl->totalSuccessfullyReasmFramesCounter);
3851         p_Stats->specificHdrStatistics[1].validFragments =
3852                 GET_UINT32(p_Manip->reassmParams.ip.p_Ipv6ReassTbl->totalValidFragmentCounter);
3853         p_Stats->specificHdrStatistics[1].processedFragments =
3854                 GET_UINT32(p_Manip->reassmParams.ip.p_Ipv6ReassTbl->totalProcessedFragCounter);
3855         p_Stats->specificHdrStatistics[1].malformedFragments =
3856                 GET_UINT32(p_Manip->reassmParams.ip.p_Ipv6ReassTbl->totalMalformdFragCounter);
3857         p_Stats->specificHdrStatistics[1].autoLearnBusy =
3858                 GET_UINT32(p_Manip->reassmParams.ip.p_Ipv6ReassTbl->totalSetBusyCounter);
3859         p_Stats->specificHdrStatistics[1].discardedFragments =
3860                 GET_UINT32(p_Manip->reassmParams.ip.p_Ipv6ReassTbl->totalDiscardedFragsCounter);
3861         p_Stats->specificHdrStatistics[1].moreThan16Fragments =
3862                 GET_UINT32(p_Manip->reassmParams.ip.p_Ipv6ReassTbl->totalMoreThan16FramesCounter);
3863     }
3864     return E_OK;
3865 }
3866 
3867 static t_Error IpFragmentationStats(t_FmPcdManip *p_Manip,
3868                                     t_FmPcdManipFragIpStats *p_Stats)
3869 {
3870     t_AdOfTypeContLookup *p_Ad;
3871 
3872     ASSERT_COND(p_Manip);
3873     ASSERT_COND(p_Stats);
3874     ASSERT_COND(p_Manip->h_Ad);
3875     ASSERT_COND(p_Manip->fragParams.p_Frag);
3876 
3877     p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Ad;
3878 
3879     p_Stats->totalFrames = GET_UINT32(p_Ad->gmask);
3880     p_Stats->fragmentedFrames = GET_UINT32(p_Manip->fragParams.p_Frag->ccAdBase)
3881             & 0x00ffffff;
3882     p_Stats->generatedFragments =
3883             GET_UINT32(p_Manip->fragParams.p_Frag->matchTblPtr);
3884 
3885     return E_OK;
3886 }
3887 
3888 static t_Error IpFragmentation(t_FmPcdManipFragIpParams *p_ManipParams,
3889                                t_FmPcdManip *p_Manip)
3890 {
3891     uint32_t pcAndOffsetsReg = 0, ccAdBaseReg = 0, gmaskReg = 0;
3892     t_FmPcd *p_FmPcd;
3893 #if (DPAA_VERSION == 10)
3894     t_Error err = E_OK;
3895 #endif /* (DPAA_VERSION == 10) */
3896 
3897     SANITY_CHECK_RETURN_ERROR(p_Manip->h_Ad, E_INVALID_HANDLE);
3898     SANITY_CHECK_RETURN_ERROR(p_ManipParams->sizeForFragmentation != 0xFFFF,
3899                               E_INVALID_VALUE);
3900 
3901     p_FmPcd = p_Manip->h_FmPcd;
3902     /* Allocation of fragmentation Action Descriptor */
3903     p_Manip->fragParams.p_Frag = (t_AdOfTypeContLookup *)FM_MURAM_AllocMem(
3904             p_FmPcd->h_FmMuram, FM_PCD_CC_AD_ENTRY_SIZE,
3905             FM_PCD_CC_AD_TABLE_ALIGN);
3906     if (!p_Manip->fragParams.p_Frag)
3907         RETURN_ERROR(MAJOR, E_NO_MEMORY,
3908                      ("MURAM alloc for Fragmentation table descriptor"));
3909     MemSet8(p_Manip->fragParams.p_Frag, 0, FM_PCD_CC_AD_ENTRY_SIZE);
3910 
3911     /* Prepare the third Ad register (pcAndOffsets)- OperationCode */
3912     pcAndOffsetsReg = (uint32_t)HMAN_OC_IP_FRAGMENTATION;
3913 
3914     /* Prepare the first Ad register (ccAdBase) - Don't frag action and Action descriptor type*/
3915     ccAdBaseReg = FM_PCD_AD_CONT_LOOKUP_TYPE;
3916     ccAdBaseReg |= (p_ManipParams->dontFragAction
3917             << FM_PCD_MANIP_IP_FRAG_DF_SHIFT);
3918 
3919 
3920     /* Set Scatter/Gather BPid */
3921     if (p_ManipParams->sgBpidEn)
3922     {
3923         ccAdBaseReg |= FM_PCD_MANIP_IP_FRAG_SG_BDID_EN;
3924         pcAndOffsetsReg |= ((p_ManipParams->sgBpid
3925                 << FM_PCD_MANIP_IP_FRAG_SG_BDID_SHIFT)
3926                 & FM_PCD_MANIP_IP_FRAG_SG_BDID_MASK);
3927     }
3928 
3929     /* Prepare the first Ad register (gmask) - scratch buffer pool id and Pointer to fragment ID */
3930     gmaskReg = (uint32_t)(XX_VirtToPhys(UINT_TO_PTR(p_FmPcd->ipv6FrameIdAddr))
3931             - p_FmPcd->physicalMuramBase);
3932 #if (DPAA_VERSION == 10)
3933     gmaskReg |= p_ManipParams->scratchBpid << FM_PCD_MANIP_IP_FRAG_SCRATCH_BPID;
3934 #else
3935     gmaskReg |= (0xFF) << FM_PCD_MANIP_IP_FRAG_SCRATCH_BPID;
3936 #endif /* (DPAA_VERSION == 10) */
3937 
3938     /* Set all Ad registers */
3939     WRITE_UINT32(p_Manip->fragParams.p_Frag->pcAndOffsets, pcAndOffsetsReg);
3940     WRITE_UINT32(p_Manip->fragParams.p_Frag->ccAdBase, ccAdBaseReg);
3941     WRITE_UINT32(p_Manip->fragParams.p_Frag->gmask, gmaskReg);
3942 
3943     /* Saves user's fragmentation manipulation parameters */
3944     p_Manip->frag = TRUE;
3945     p_Manip->sizeForFragmentation = p_ManipParams->sizeForFragmentation;
3946 
3947 #if (DPAA_VERSION == 10)
3948     p_Manip->fragParams.scratchBpid = p_ManipParams->scratchBpid;
3949 
3950     /* scratch buffer pool initialization */
3951     if ((err = FmPcdFragHcScratchPoolFill((t_Handle)p_FmPcd, p_ManipParams->scratchBpid)) != E_OK)
3952     {
3953         FM_MURAM_FreeMem(p_FmPcd->h_FmMuram, p_Manip->fragParams.p_Frag);
3954         p_Manip->fragParams.p_Frag = NULL;
3955         RETURN_ERROR(MAJOR, err, NO_MSG);
3956     }
3957 #endif /* (DPAA_VERSION == 10) */
3958 
3959     return E_OK;
3960 }
3961 
3962 static t_Error IPManip(t_FmPcdManip *p_Manip)
3963 {
3964     t_Error err = E_OK;
3965     t_FmPcd *p_FmPcd;
3966     t_AdOfTypeContLookup *p_Ad;
3967     uint32_t tmpReg32 = 0, tmpRegNia = 0;
3968 
3969     SANITY_CHECK_RETURN_ERROR(p_Manip, E_INVALID_HANDLE);
3970     p_FmPcd = p_Manip->h_FmPcd;
3971     SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
3972 
3973     p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Ad;
3974 
3975     tmpReg32 = FM_PCD_MANIP_IP_NO_FRAGMENTATION;
3976     if (p_Manip->frag == TRUE)
3977     {
3978         tmpRegNia = (uint32_t)(XX_VirtToPhys(p_Manip->fragParams.p_Frag)
3979                 - (p_FmPcd->physicalMuramBase));
3980         tmpReg32 = (uint32_t)p_Manip->sizeForFragmentation
3981                 << FM_PCD_MANIP_IP_MTU_SHIFT;
3982     }
3983 
3984     tmpRegNia |= FM_PCD_AD_CONT_LOOKUP_TYPE;
3985     tmpReg32 |= HMAN_OC_IP_MANIP;
3986 
3987 #if (DPAA_VERSION >= 11)
3988     tmpRegNia |= FM_PCD_MANIP_IP_CNIA;
3989 #endif /* (DPAA_VERSION >= 11) */
3990 
3991     WRITE_UINT32(p_Ad->pcAndOffsets, tmpReg32);
3992     WRITE_UINT32(p_Ad->ccAdBase, tmpRegNia);
3993     WRITE_UINT32(p_Ad->gmask, 0);
3994     /* Total frame counter - MUST be initialized to zero.*/
3995 
3996     return err;
3997 }
3998 
3999 static t_Error UpdateInitIpFrag(t_Handle h_FmPcd, t_Handle h_PcdParams,
4000                                 t_Handle h_FmPort, t_FmPcdManip *p_Manip,
4001                                 t_Handle h_Ad, bool validate)
4002 {
4003     t_FmPortGetSetCcParams fmPortGetSetCcParams;
4004     t_Error err;
4005 
4006     SANITY_CHECK_RETURN_ERROR(p_Manip, E_INVALID_HANDLE);
4007     SANITY_CHECK_RETURN_ERROR((p_Manip->opcode == HMAN_OC_IP_FRAGMENTATION),
4008                               E_INVALID_STATE);
4009     SANITY_CHECK_RETURN_ERROR(h_FmPcd, E_INVALID_HANDLE);
4010     SANITY_CHECK_RETURN_ERROR(h_FmPort, E_INVALID_HANDLE);
4011 
4012     UNUSED(h_FmPcd);
4013     UNUSED(h_Ad);
4014     UNUSED(h_PcdParams);
4015     UNUSED(validate);
4016     UNUSED(p_Manip);
4017 
4018     fmPortGetSetCcParams.setCcParams.type = 0;
4019     fmPortGetSetCcParams.getCcParams.type = MANIP_EXTRA_SPACE;
4020     if ((err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams)) != E_OK)
4021         RETURN_ERROR(MAJOR, err, NO_MSG);
4022 
4023     if (!fmPortGetSetCcParams.getCcParams.internalBufferOffset)
4024         DBG(WARNING, ("manipExtraSpace must be larger than '0'"));
4025 
4026     return E_OK;
4027 }
4028 
4029 static t_Error IPSecManip(t_FmPcdManipParams *p_ManipParams,
4030                           t_FmPcdManip *p_Manip)
4031 {
4032     t_AdOfTypeContLookup *p_Ad;
4033     t_FmPcdManipSpecialOffloadIPSecParams *p_IPSecParams;
4034     t_Error err = E_OK;
4035     uint32_t tmpReg32 = 0;
4036     uint32_t power;
4037 
4038     SANITY_CHECK_RETURN_ERROR(p_Manip, E_INVALID_HANDLE);
4039     SANITY_CHECK_RETURN_ERROR(p_ManipParams, E_INVALID_HANDLE);
4040 
4041     p_IPSecParams = &p_ManipParams->u.specialOffload.u.ipsec;
4042 
4043     SANITY_CHECK_RETURN_ERROR(
4044             !p_IPSecParams->variableIpHdrLen || p_IPSecParams->decryption,
4045             E_INVALID_VALUE);
4046     SANITY_CHECK_RETURN_ERROR(
4047             !p_IPSecParams->variableIpVersion || !p_IPSecParams->decryption,
4048             E_INVALID_VALUE);
4049     SANITY_CHECK_RETURN_ERROR(
4050             !p_IPSecParams->variableIpVersion || p_IPSecParams->outerIPHdrLen,
4051             E_INVALID_VALUE);
4052     SANITY_CHECK_RETURN_ERROR(
4053             !p_IPSecParams->arwSize || p_IPSecParams->arwAddr,
4054             E_INVALID_VALUE);
4055     SANITY_CHECK_RETURN_ERROR(
4056             !p_IPSecParams->arwSize || p_IPSecParams->decryption,
4057             E_INVALID_VALUE);
4058     SANITY_CHECK_RETURN_ERROR((p_IPSecParams->arwSize % 16) == 0, E_INVALID_VALUE);
4059 
4060     p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Ad;
4061 
4062     tmpReg32 |= FM_PCD_AD_CONT_LOOKUP_TYPE;
4063     tmpReg32 |= (p_IPSecParams->decryption) ? FM_PCD_MANIP_IPSEC_DEC : 0;
4064     tmpReg32 |= (p_IPSecParams->ecnCopy) ? FM_PCD_MANIP_IPSEC_ECN_EN : 0;
4065     tmpReg32 |= (p_IPSecParams->dscpCopy) ? FM_PCD_MANIP_IPSEC_DSCP_EN : 0;
4066     tmpReg32 |=
4067             (p_IPSecParams->variableIpHdrLen) ? FM_PCD_MANIP_IPSEC_VIPL_EN : 0;
4068     tmpReg32 |=
4069             (p_IPSecParams->variableIpVersion) ? FM_PCD_MANIP_IPSEC_VIPV_EN : 0;
4070     if (p_IPSecParams->arwSize)
4071         tmpReg32 |= (uint32_t)((XX_VirtToPhys(UINT_TO_PTR(p_IPSecParams->arwAddr))-FM_MM_MURAM)
4072                 & (FM_MURAM_SIZE-1));
4073     WRITE_UINT32(p_Ad->ccAdBase, tmpReg32);
4074 
4075     tmpReg32 = 0;
4076     if (p_IPSecParams->arwSize) {
4077         NEXT_POWER_OF_2((p_IPSecParams->arwSize + 32), power);
4078         LOG2(power, power);
4079         tmpReg32 = (p_IPSecParams->arwSize | (power - 5)) << FM_PCD_MANIP_IPSEC_ARW_SIZE_SHIFT;
4080     }
4081 
4082     if (p_ManipParams->h_NextManip)
4083         tmpReg32 |=
4084                 (uint32_t)(XX_VirtToPhys(((t_FmPcdManip *)p_ManipParams->h_NextManip)->h_Ad)-
4085                         (((t_FmPcd *)p_Manip->h_FmPcd)->physicalMuramBase)) >> 4;
4086     WRITE_UINT32(p_Ad->matchTblPtr, tmpReg32);
4087 
4088     tmpReg32 = HMAN_OC_IPSEC_MANIP;
4089     tmpReg32 |= p_IPSecParams->outerIPHdrLen
4090             << FM_PCD_MANIP_IPSEC_IP_HDR_LEN_SHIFT;
4091     if (p_ManipParams->h_NextManip)
4092         tmpReg32 |= FM_PCD_MANIP_IPSEC_NADEN;
4093     WRITE_UINT32(p_Ad->pcAndOffsets, tmpReg32);
4094 
4095     return err;
4096 }
4097 
4098 static t_Error SetCapwapReassmManip(t_FmPcdManip *p_Manip)
4099 {
4100     t_FmPcd *p_FmPcd = (t_FmPcd *)p_Manip->h_FmPcd;
4101 
4102     /* Allocation if CAPWAP Action descriptor */
4103     p_Manip->reassmParams.capwap.h_Ad = (t_Handle)XX_MallocSmart(
4104             FM_PCD_CC_AD_ENTRY_SIZE, p_Manip->reassmParams.dataMemId,
4105             FM_PCD_CC_AD_TABLE_ALIGN);
4106     if (!p_Manip->reassmParams.capwap.h_Ad)
4107     {
4108         ReleaseManipHandler(p_Manip, p_FmPcd);
4109         RETURN_ERROR(MAJOR, E_NO_MEMORY,
4110                      ("Allocation of CAPWAP table descriptor"));
4111     }
4112 
4113     memset(p_Manip->reassmParams.capwap.h_Ad, 0, FM_PCD_CC_AD_ENTRY_SIZE);
4114 
4115     /* Fill reassembly manipulation parameter in the Reassembly Action Descriptor */
4116     return FillReassmManipParams(p_Manip, HEADER_TYPE_CAPWAP);
4117 }
4118 
4119 static void setCapwapReassmSchemeParams(t_FmPcd* p_FmPcd,
4120                                         t_FmPcdKgSchemeParams *p_Scheme,
4121                                         t_Handle h_CcTree, uint8_t groupId)
4122 {
4123     uint8_t res;
4124 
4125     /* Configures scheme's network environment parameters */
4126     p_Scheme->netEnvParams.numOfDistinctionUnits = 1;
4127     res = FmPcdNetEnvGetUnitId(
4128             p_FmPcd, FmPcdGetNetEnvId(p_Scheme->netEnvParams.h_NetEnv),
4129             HEADER_TYPE_USER_DEFINED_SHIM2, FALSE, 0);
4130     ASSERT_COND(res != FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS);
4131     p_Scheme->netEnvParams.unitIds[0] = res;
4132 
4133     /* Configures scheme's next engine parameters*/
4134     p_Scheme->nextEngine = e_FM_PCD_CC;
4135     p_Scheme->kgNextEngineParams.cc.h_CcTree = h_CcTree;
4136     p_Scheme->kgNextEngineParams.cc.grpId = groupId;
4137     p_Scheme->useHash = TRUE;
4138 
4139     /* Configures scheme's key*/
4140     p_Scheme->keyExtractAndHashParams.numOfUsedExtracts = 2;
4141     p_Scheme->keyExtractAndHashParams.extractArray[0].type =
4142             e_FM_PCD_EXTRACT_NON_HDR;
4143     p_Scheme->keyExtractAndHashParams.extractArray[0].extractNonHdr.src =
4144             e_FM_PCD_EXTRACT_FROM_PARSE_RESULT;
4145     p_Scheme->keyExtractAndHashParams.extractArray[0].extractNonHdr.action =
4146             e_FM_PCD_ACTION_NONE;
4147     p_Scheme->keyExtractAndHashParams.extractArray[0].extractNonHdr.offset = 20;
4148     p_Scheme->keyExtractAndHashParams.extractArray[0].extractNonHdr.size = 4;
4149     p_Scheme->keyExtractAndHashParams.extractArray[1].type =
4150             e_FM_PCD_EXTRACT_NON_HDR;
4151     p_Scheme->keyExtractAndHashParams.extractArray[1].extractNonHdr.src =
4152             e_FM_PCD_EXTRACT_FROM_DFLT_VALUE;
4153     p_Scheme->keyExtractAndHashParams.extractArray[1].extractNonHdr.action =
4154             e_FM_PCD_ACTION_NONE;
4155     p_Scheme->keyExtractAndHashParams.extractArray[1].extractNonHdr.offset = 0;
4156     p_Scheme->keyExtractAndHashParams.extractArray[1].extractNonHdr.size = 1;
4157 
4158     p_Scheme->keyExtractAndHashParams.privateDflt0 = 0x0;
4159     p_Scheme->keyExtractAndHashParams.privateDflt1 = 0x0;
4160     p_Scheme->keyExtractAndHashParams.numOfUsedDflts = 1;
4161     p_Scheme->keyExtractAndHashParams.dflts[0].type = e_FM_PCD_KG_GENERIC_NOT_FROM_DATA;
4162     p_Scheme->keyExtractAndHashParams.dflts[0].dfltSelect = e_FM_PCD_KG_DFLT_PRIVATE_0;
4163 }
4164 
4165 #if (DPAA_VERSION >= 11)
4166 static t_Error CapwapReassemblyStats(t_FmPcdManip *p_Manip,
4167                                      t_FmPcdManipReassemCapwapStats *p_Stats)
4168 {
4169     ASSERT_COND(p_Manip);
4170     ASSERT_COND(p_Stats);
4171     ASSERT_COND(p_Manip->reassmParams.p_ReassCommonTbl);
4172 
4173     p_Stats->timeout =
4174             GET_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->totalTimeOutCounter);
4175     p_Stats->rfdPoolBusy =
4176             GET_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->totalRfdPoolBusyCounter);
4177     p_Stats->internalBufferBusy =
4178             GET_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->totalInternalBufferBusy);
4179     p_Stats->externalBufferBusy =
4180             GET_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->totalExternalBufferBusy);
4181     p_Stats->sgFragments =
4182             GET_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->totalSgFragmentCounter);
4183     p_Stats->dmaSemaphoreDepletion =
4184             GET_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->totalDmaSemaphoreDepletionCounter);
4185     p_Stats->exceedMaxReassemblyFrameLen =
4186             GET_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->totalNCSPCounter);
4187 
4188     p_Stats->successfullyReassembled =
4189             GET_UINT32(p_Manip->reassmParams.capwap.p_ReassTbl->totalSuccessfullyReasmFramesCounter);
4190     p_Stats->validFragments =
4191             GET_UINT32(p_Manip->reassmParams.capwap.p_ReassTbl->totalValidFragmentCounter);
4192     p_Stats->processedFragments =
4193             GET_UINT32(p_Manip->reassmParams.capwap.p_ReassTbl->totalProcessedFragCounter);
4194     p_Stats->malformedFragments =
4195             GET_UINT32(p_Manip->reassmParams.capwap.p_ReassTbl->totalMalformdFragCounter);
4196     p_Stats->autoLearnBusy =
4197             GET_UINT32(p_Manip->reassmParams.capwap.p_ReassTbl->totalSetBusyCounter);
4198     p_Stats->discardedFragments =
4199             GET_UINT32(p_Manip->reassmParams.capwap.p_ReassTbl->totalDiscardedFragsCounter);
4200     p_Stats->moreThan16Fragments =
4201             GET_UINT32(p_Manip->reassmParams.capwap.p_ReassTbl->totalMoreThan16FramesCounter);
4202 
4203     return E_OK;
4204 }
4205 
4206 static t_Error CapwapFragmentationStats(t_FmPcdManip *p_Manip,
4207 		t_FmPcdManipFragCapwapStats *p_Stats)
4208 {
4209 	t_AdOfTypeContLookup *p_Ad;
4210 
4211 	ASSERT_COND(p_Manip);
4212 	ASSERT_COND(p_Stats);
4213 	ASSERT_COND(p_Manip->h_Ad);
4214 	ASSERT_COND(p_Manip->fragParams.p_Frag);
4215 
4216 	p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Ad;
4217 
4218 	p_Stats->totalFrames = GET_UINT32(p_Ad->gmask);
4219 
4220 	return E_OK;
4221 }
4222 
4223 static t_Error CapwapReassembly(t_FmPcdManipReassemParams *p_ManipReassmParams,
4224                                 t_FmPcdManip *p_Manip)
4225 {
4226     uint32_t maxSetNumber = 10000;
4227     t_FmPcdManipReassemCapwapParams reassmManipParams =
4228             p_ManipReassmParams->u.capwapReassem;
4229     t_Error res;
4230 
4231     SANITY_CHECK_RETURN_ERROR(p_Manip->h_FmPcd, E_INVALID_HANDLE);
4232     SANITY_CHECK_RETURN_ERROR(((t_FmPcd *)p_Manip->h_FmPcd)->h_Hc,
4233                               E_INVALID_HANDLE);
4234 
4235     /* Check validation of user's parameter.*/
4236     if ((reassmManipParams.timeoutThresholdForReassmProcess < 1000)
4237             || (reassmManipParams.timeoutThresholdForReassmProcess > 8000000))
4238         RETURN_ERROR(
4239                 MAJOR, E_INVALID_VALUE,
4240                 ("timeoutThresholdForReassmProcess should be 1msec - 8sec"));
4241     /* It is recommended that the total number of entries in this table (number of sets * number of ways)
4242      will be twice the number of frames that are expected to be reassembled simultaneously.*/
4243     if (reassmManipParams.maxNumFramesInProcess
4244             > (reassmManipParams.maxNumFramesInProcess * maxSetNumber / 2))
4245         RETURN_ERROR(
4246                 MAJOR,
4247                 E_INVALID_VALUE,
4248                 ("maxNumFramesInProcess has to be less than (maximun set number * number of ways / 2)"));
4249 
4250     /* Saves user's reassembly manipulation parameters */
4251     p_Manip->reassmParams.capwap.relativeSchemeId =
4252             reassmManipParams.relativeSchemeId;
4253     p_Manip->reassmParams.capwap.numOfFramesPerHashEntry =
4254             reassmManipParams.numOfFramesPerHashEntry;
4255     p_Manip->reassmParams.capwap.maxRessembledsSize =
4256             reassmManipParams.maxReassembledFrameLength;
4257     p_Manip->reassmParams.maxNumFramesInProcess =
4258             reassmManipParams.maxNumFramesInProcess;
4259     p_Manip->reassmParams.timeOutMode = reassmManipParams.timeOutMode;
4260     p_Manip->reassmParams.fqidForTimeOutFrames =
4261             reassmManipParams.fqidForTimeOutFrames;
4262     p_Manip->reassmParams.timeoutThresholdForReassmProcess =
4263             reassmManipParams.timeoutThresholdForReassmProcess;
4264     p_Manip->reassmParams.dataMemId = reassmManipParams.dataMemId;
4265     p_Manip->reassmParams.dataLiodnOffset = reassmManipParams.dataLiodnOffset;
4266 
4267     /* Creates and initializes the Reassembly common parameter table */
4268     CreateReassCommonTable(p_Manip);
4269 
4270     res = SetCapwapReassmManip(p_Manip);
4271     if (res != E_OK)
4272         return res;
4273 
4274     return E_OK;
4275 }
4276 
4277 static t_Error CapwapFragmentation(t_FmPcdManipFragCapwapParams *p_ManipParams,
4278                                    t_FmPcdManip *p_Manip)
4279 {
4280     t_FmPcd *p_FmPcd;
4281     t_AdOfTypeContLookup *p_Ad;
4282     uint32_t pcAndOffsetsReg = 0, ccAdBaseReg = 0, gmaskReg = 0;
4283     uint32_t tmpReg32 = 0, tmpRegNia = 0;
4284 
4285     SANITY_CHECK_RETURN_ERROR(p_Manip->h_Ad, E_INVALID_HANDLE);
4286     SANITY_CHECK_RETURN_ERROR(p_ManipParams->sizeForFragmentation != 0xFFFF,
4287                               E_INVALID_VALUE);
4288     p_FmPcd = p_Manip->h_FmPcd;
4289     SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
4290 
4291     /* Allocation of fragmentation Action Descriptor */
4292     p_Manip->fragParams.p_Frag = (t_AdOfTypeContLookup *)FM_MURAM_AllocMem(
4293             p_FmPcd->h_FmMuram, FM_PCD_CC_AD_ENTRY_SIZE,
4294             FM_PCD_CC_AD_TABLE_ALIGN);
4295     if (!p_Manip->fragParams.p_Frag)
4296         RETURN_ERROR(MAJOR, E_NO_MEMORY,
4297                      ("MURAM alloc for Fragmentation table descriptor"));
4298     MemSet8(p_Manip->fragParams.p_Frag, 0, FM_PCD_CC_AD_ENTRY_SIZE);
4299 
4300     /* Prepare the third Ad register (pcAndOffsets)- OperationCode */
4301     pcAndOffsetsReg = (uint32_t)HMAN_OC_CAPWAP_FRAGMENTATION;
4302 
4303     /* Prepare the first Ad register (ccAdBase) - Don't frag action and Action descriptor type*/
4304     ccAdBaseReg = FM_PCD_AD_CONT_LOOKUP_TYPE;
4305     ccAdBaseReg |=
4306             (p_ManipParams->compressModeEn) ? FM_PCD_MANIP_CAPWAP_FRAG_COMPRESS_EN :
4307                     0;
4308 
4309     /* Set Scatter/Gather BPid */
4310     if (p_ManipParams->sgBpidEn)
4311     {
4312         ccAdBaseReg |= FM_PCD_MANIP_CAPWAP_FRAG_SG_BDID_EN;
4313         pcAndOffsetsReg |= ((p_ManipParams->sgBpid
4314                 << FM_PCD_MANIP_CAPWAP_FRAG_SG_BDID_SHIFT)
4315                 & FM_PCD_MANIP_CAPWAP_FRAG_SG_BDID_MASK);
4316     }
4317 
4318     /* Prepare the first Ad register (gmask) - scratch buffer pool id and Pointer to fragment ID */
4319     gmaskReg = (uint32_t)(XX_VirtToPhys(UINT_TO_PTR(p_FmPcd->capwapFrameIdAddr))
4320             - p_FmPcd->physicalMuramBase);
4321     gmaskReg |= (0xFF) << FM_PCD_MANIP_IP_FRAG_SCRATCH_BPID;
4322 
4323     /* Set all Ad registers */
4324     WRITE_UINT32(p_Manip->fragParams.p_Frag->pcAndOffsets, pcAndOffsetsReg);
4325     WRITE_UINT32(p_Manip->fragParams.p_Frag->ccAdBase, ccAdBaseReg);
4326     WRITE_UINT32(p_Manip->fragParams.p_Frag->gmask, gmaskReg);
4327 
4328     /* Saves user's fragmentation manipulation parameters */
4329     p_Manip->frag = TRUE;
4330     p_Manip->sizeForFragmentation = p_ManipParams->sizeForFragmentation;
4331 
4332     p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Ad;
4333 
4334     tmpRegNia = (uint32_t)(XX_VirtToPhys(p_Manip->fragParams.p_Frag)
4335             - (p_FmPcd->physicalMuramBase));
4336     tmpReg32 = (uint32_t)p_Manip->sizeForFragmentation
4337             << FM_PCD_MANIP_CAPWAP_FRAG_CHECK_MTU_SHIFT;
4338 
4339     tmpRegNia |= FM_PCD_AD_CONT_LOOKUP_TYPE;
4340     tmpReg32 |= HMAN_OC_CAPWAP_FRAG_CHECK;
4341 
4342     tmpRegNia |= FM_PCD_MANIP_CAPWAP_FRAG_CHECK_CNIA;
4343 
4344     WRITE_UINT32(p_Ad->pcAndOffsets, tmpReg32);
4345     WRITE_UINT32(p_Ad->ccAdBase, tmpRegNia);
4346     WRITE_UINT32(p_Ad->gmask, 0);
4347     /* Total frame counter - MUST be initialized to zero.*/
4348 
4349     return E_OK;
4350 }
4351 
4352 static t_Error UpdateInitCapwapFrag(t_Handle h_FmPcd, t_Handle h_PcdParams,
4353                                     t_Handle h_FmPort, t_FmPcdManip *p_Manip,
4354                                     t_Handle h_Ad, bool validate)
4355 {
4356     t_FmPortGetSetCcParams fmPortGetSetCcParams;
4357     t_Error err;
4358 
4359     SANITY_CHECK_RETURN_ERROR(p_Manip, E_INVALID_HANDLE);
4360     SANITY_CHECK_RETURN_ERROR((p_Manip->opcode == HMAN_OC_CAPWAP_FRAGMENTATION),
4361                               E_INVALID_STATE);
4362     SANITY_CHECK_RETURN_ERROR(h_FmPcd, E_INVALID_HANDLE);
4363     SANITY_CHECK_RETURN_ERROR(h_FmPort, E_INVALID_HANDLE);
4364 
4365     UNUSED(h_FmPcd);
4366     UNUSED(h_Ad);
4367     UNUSED(h_PcdParams);
4368     UNUSED(validate);
4369     UNUSED(p_Manip);
4370 
4371     fmPortGetSetCcParams.setCcParams.type = 0;
4372     fmPortGetSetCcParams.getCcParams.type = MANIP_EXTRA_SPACE;
4373     if ((err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams)) != E_OK)
4374         RETURN_ERROR(MAJOR, err, NO_MSG);
4375 
4376     if (!fmPortGetSetCcParams.getCcParams.internalBufferOffset)
4377         DBG(WARNING, ("manipExtraSpace must be larger than '0'"));
4378 
4379     return E_OK;
4380 }
4381 
4382 static t_Error CapwapManip(t_FmPcdManipParams *p_ManipParams,
4383                            t_FmPcdManip *p_Manip)
4384 {
4385     t_AdOfTypeContLookup *p_Ad;
4386     t_FmPcdManipSpecialOffloadCapwapParams *p_Params;
4387     t_Error err = E_OK;
4388     uint32_t tmpReg32 = 0;
4389 
4390     SANITY_CHECK_RETURN_ERROR(p_Manip, E_INVALID_HANDLE);
4391     SANITY_CHECK_RETURN_ERROR(p_ManipParams, E_INVALID_HANDLE);
4392 
4393     p_Params = &p_ManipParams->u.specialOffload.u.capwap;
4394 
4395     p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Ad;
4396     tmpReg32 |= FM_PCD_AD_CONT_LOOKUP_TYPE;
4397     tmpReg32 |= (p_Params->dtls) ? FM_PCD_MANIP_CAPWAP_DTLS : 0;
4398     /* TODO - add 'qosSrc' */
4399     WRITE_UINT32(p_Ad->ccAdBase, tmpReg32);
4400 
4401     tmpReg32 = HMAN_OC_CAPWAP_MANIP;
4402     if (p_ManipParams->h_NextManip)
4403     {
4404         WRITE_UINT32(
4405                 p_Ad->matchTblPtr,
4406                 (uint32_t)(XX_VirtToPhys(((t_FmPcdManip *)p_ManipParams->h_NextManip)->h_Ad)- (((t_FmPcd *)p_Manip->h_FmPcd)->physicalMuramBase)) >> 4);
4407 
4408         tmpReg32 |= FM_PCD_MANIP_CAPWAP_NADEN;
4409     }
4410 
4411     WRITE_UINT32(p_Ad->pcAndOffsets, tmpReg32);
4412 
4413     return err;
4414 }
4415 #endif /* (DPAA_VERSION >= 11) */
4416 
4417 static t_Handle ManipOrStatsSetNode(t_Handle h_FmPcd, t_Handle *p_Params,
4418                                     bool stats)
4419 {
4420     t_FmPcdManip *p_Manip;
4421     t_Error err;
4422     t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
4423 
4424     p_Manip = (t_FmPcdManip*)XX_Malloc(sizeof(t_FmPcdManip));
4425     if (!p_Manip)
4426     {
4427         REPORT_ERROR(MAJOR, E_NO_MEMORY, ("No memory"));
4428         return NULL;
4429     }
4430     memset(p_Manip, 0, sizeof(t_FmPcdManip));
4431 
4432     p_Manip->type = ((t_FmPcdManipParams *)p_Params)->type;
4433     memcpy((uint8_t*)&p_Manip->manipParams, p_Params,
4434            sizeof(p_Manip->manipParams));
4435 
4436     if (!stats)
4437         err = CheckManipParamsAndSetType(p_Manip,
4438                                          (t_FmPcdManipParams *)p_Params);
4439 #if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
4440     else
4441         err = CheckStatsParamsAndSetType(p_Manip, (t_FmPcdStatsParams *)p_Params);
4442 #else /* not (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */
4443     else
4444     {
4445         REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Statistics node!"));
4446         XX_Free(p_Manip);
4447         return NULL;
4448     }
4449 #endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */
4450     if (err)
4451     {
4452         REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("Invalid header manipulation type"));
4453         XX_Free(p_Manip);
4454         return NULL;
4455     }
4456 
4457     if ((p_Manip->opcode != HMAN_OC_IP_REASSEMBLY) && (p_Manip->opcode != HMAN_OC_CAPWAP_REASSEMBLY))
4458     {
4459         /* In Case of reassembly manipulation the reassembly action descriptor will
4460          be defines later on */
4461         if (p_Manip->muramAllocate)
4462         {
4463             p_Manip->h_Ad = (t_Handle)FM_MURAM_AllocMem(
4464                     p_FmPcd->h_FmMuram, FM_PCD_CC_AD_ENTRY_SIZE,
4465                     FM_PCD_CC_AD_TABLE_ALIGN);
4466             if (!p_Manip->h_Ad)
4467             {
4468                 REPORT_ERROR(MAJOR, E_NO_MEMORY, ("MURAM alloc for Manipulation action descriptor"));
4469                 ReleaseManipHandler(p_Manip, p_FmPcd);
4470                 XX_Free(p_Manip);
4471                 return NULL;
4472             }
4473 
4474             MemSet8(p_Manip->h_Ad, 0, FM_PCD_CC_AD_ENTRY_SIZE);
4475         }
4476         else
4477         {
4478             p_Manip->h_Ad = (t_Handle)XX_Malloc(
4479                     FM_PCD_CC_AD_ENTRY_SIZE * sizeof(uint8_t));
4480             if (!p_Manip->h_Ad)
4481             {
4482                 REPORT_ERROR(MAJOR, E_NO_MEMORY, ("Allocation of Manipulation action descriptor"));
4483                 ReleaseManipHandler(p_Manip, p_FmPcd);
4484                 XX_Free(p_Manip);
4485                 return NULL;
4486             }
4487 
4488             memset(p_Manip->h_Ad, 0, FM_PCD_CC_AD_ENTRY_SIZE * sizeof(uint8_t));
4489         }
4490     }
4491 
4492     p_Manip->h_FmPcd = h_FmPcd;
4493 
4494     return p_Manip;
4495 }
4496 
4497 static void UpdateAdPtrOfNodesWhichPointsOnCrntMdfManip(
4498         t_FmPcdManip *p_CrntMdfManip, t_List *h_NodesLst)
4499 {
4500     t_CcNodeInformation *p_CcNodeInformation;
4501     t_FmPcdCcNode *p_NodePtrOnCurrentMdfManip = NULL;
4502     t_List *p_Pos;
4503     int i = 0;
4504     t_Handle p_AdTablePtOnCrntCurrentMdfNode/*, p_AdTableNewModified*/;
4505     t_CcNodeInformation ccNodeInfo;
4506 
4507     NCSW_LIST_FOR_EACH(p_Pos, &p_CrntMdfManip->nodesLst)
4508     {
4509         p_CcNodeInformation = CC_NODE_F_OBJECT(p_Pos);
4510         p_NodePtrOnCurrentMdfManip =
4511                 (t_FmPcdCcNode *)p_CcNodeInformation->h_CcNode;
4512 
4513         ASSERT_COND(p_NodePtrOnCurrentMdfManip);
4514 
4515         /* Search in the previous node which exact index points on this current modified node for getting AD */
4516         for (i = 0; i < p_NodePtrOnCurrentMdfManip->numOfKeys + 1; i++)
4517         {
4518             if (p_NodePtrOnCurrentMdfManip->keyAndNextEngineParams[i].nextEngineParams.nextEngine
4519                     == e_FM_PCD_CC)
4520             {
4521                 if (p_NodePtrOnCurrentMdfManip->keyAndNextEngineParams[i].nextEngineParams.h_Manip
4522                         == (t_Handle)p_CrntMdfManip)
4523                 {
4524                     if (p_NodePtrOnCurrentMdfManip->keyAndNextEngineParams[i].p_StatsObj)
4525                         p_AdTablePtOnCrntCurrentMdfNode =
4526                                 p_NodePtrOnCurrentMdfManip->keyAndNextEngineParams[i].p_StatsObj->h_StatsAd;
4527                     else
4528                         p_AdTablePtOnCrntCurrentMdfNode =
4529                                 PTR_MOVE(p_NodePtrOnCurrentMdfManip->h_AdTable, i*FM_PCD_CC_AD_ENTRY_SIZE);
4530 
4531                     memset(&ccNodeInfo, 0, sizeof(t_CcNodeInformation));
4532                     ccNodeInfo.h_CcNode = p_AdTablePtOnCrntCurrentMdfNode;
4533                     EnqueueNodeInfoToRelevantLst(h_NodesLst, &ccNodeInfo, NULL);
4534                 }
4535             }
4536         }
4537 
4538         ASSERT_COND(i != p_NodePtrOnCurrentMdfManip->numOfKeys);
4539     }
4540 }
4541 
4542 static void BuildHmtd(uint8_t *p_Dest, uint8_t *p_Src, uint8_t *p_Hmcd,
4543                       t_FmPcd *p_FmPcd)
4544 {
4545     t_Error err;
4546 
4547     /* Copy the HMTD */
4548     MemCpy8(p_Dest, (uint8_t*)p_Src, 16);
4549     /* Replace the HMCT table pointer  */
4550     WRITE_UINT32(
4551             ((t_Hmtd *)p_Dest)->hmcdBasePtr,
4552             (uint32_t)(XX_VirtToPhys(p_Hmcd) - ((t_FmPcd*)p_FmPcd)->physicalMuramBase));
4553     /* Call Host Command to replace HMTD by a new HMTD */
4554     err = FmHcPcdCcDoDynamicChange(
4555             p_FmPcd->h_Hc,
4556             (uint32_t)(XX_VirtToPhys(p_Src) - p_FmPcd->physicalMuramBase),
4557             (uint32_t)(XX_VirtToPhys(p_Dest) - p_FmPcd->physicalMuramBase));
4558     if (err)
4559         REPORT_ERROR(MINOR, err, ("Failed in dynamic manip change, continued to the rest of the owners."));
4560 }
4561 
4562 static t_Error FmPcdManipInitUpdate(t_Handle h_FmPcd, t_Handle h_PcdParams,
4563                                     t_Handle h_FmPort, t_Handle h_Manip,
4564                                     t_Handle h_Ad, bool validate, int level,
4565                                     t_Handle h_FmTree)
4566 {
4567     t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_Manip;
4568     t_Error err = E_OK;
4569 
4570     SANITY_CHECK_RETURN_ERROR(h_Manip, E_INVALID_HANDLE);
4571 
4572     UNUSED(level);
4573     UNUSED(h_FmTree);
4574 
4575     switch (p_Manip->opcode)
4576     {
4577 #if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
4578         case (HMAN_OC_MV_INT_FRAME_HDR_FROM_FRM_TO_BUFFER_PREFFIX):
4579         err = UpdateInitMvIntFrameHeaderFromFrameToBufferPrefix(h_FmPort,
4580                 p_Manip,
4581                 h_Ad,
4582                 validate);
4583         break;
4584         case (HMAN_OC_INSRT_HDR_BY_TEMPL_N_OR_FRAG_AFTER):
4585         if (!p_Manip->h_Frag)
4586         break;
4587         case (HMAN_OC_CAPWAP_FRAGMENTATION):
4588         err = UpdateInitCapwapFragmentation(h_FmPort, p_Manip, h_Ad, validate, h_FmTree);
4589         break;
4590         case (HMAN_OC_CAPWAP_RMV_DTLS_IF_EXIST):
4591         if (p_Manip->h_Frag)
4592         err = UpdateInitCapwapReasm(h_FmPcd, h_FmPort, p_Manip, h_Ad, validate);
4593         break;
4594         case (HMAN_OC_CAPWAP_INDEXED_STATS):
4595         err = UpdateIndxStats(h_FmPcd, h_FmPort, p_Manip);
4596         break;
4597 #endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */
4598         case (HMAN_OC_IP_REASSEMBLY):
4599             err = UpdateInitReasm(h_FmPcd, h_PcdParams, h_FmPort, p_Manip, h_Ad,
4600                                   validate);
4601             break;
4602         case (HMAN_OC_IP_FRAGMENTATION):
4603             err = UpdateInitIpFrag(h_FmPcd, h_PcdParams, h_FmPort, p_Manip,
4604                                    h_Ad, validate);
4605             break;
4606 #if (DPAA_VERSION >= 11)
4607         case (HMAN_OC_CAPWAP_FRAGMENTATION):
4608             err = UpdateInitCapwapFrag(h_FmPcd, h_PcdParams, h_FmPort, p_Manip,
4609                                        h_Ad, validate);
4610             break;
4611         case (HMAN_OC_CAPWAP_REASSEMBLY):
4612             err = UpdateInitReasm(h_FmPcd, h_PcdParams, h_FmPort, p_Manip, h_Ad,
4613                                   validate);
4614             break;
4615 #endif /* (DPAA_VERSION >= 11) */
4616         default:
4617             return E_OK;
4618     }
4619 
4620     return err;
4621 }
4622 
4623 static t_Error FmPcdManipModifyUpdate(t_Handle h_Manip, t_Handle h_Ad,
4624                                       bool validate, int level,
4625                                       t_Handle h_FmTree)
4626 {
4627 
4628     t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_Manip;
4629     t_Error err = E_OK;
4630 
4631     UNUSED(level);
4632 
4633     switch (p_Manip->opcode)
4634     {
4635 #if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
4636         case (HMAN_OC_MV_INT_FRAME_HDR_FROM_FRM_TO_BUFFER_PREFFIX):
4637         RETURN_ERROR(
4638                 MAJOR,
4639                 E_INVALID_STATE,
4640                 ("modify node with this type of manipulation  is not suppported"));
4641         case (HMAN_OC_CAPWAP_RMV_DTLS_IF_EXIST):
4642 
4643         if (p_Manip->h_Frag)
4644         {
4645             if (!(p_Manip->shadowUpdateParams & NUM_OF_TASKS)
4646                     && !(p_Manip->shadowUpdateParams & OFFSET_OF_DATA)
4647                     && !(p_Manip->shadowUpdateParams & OFFSET_OF_PR))
4648             RETURN_ERROR(
4649                     MAJOR,
4650                     E_INVALID_STATE,
4651                     ("modify node with this type of manipulation requires manipulation be updated previously in SetPcd function"));
4652         }
4653         break;
4654         case (HMAN_OC_INSRT_HDR_BY_TEMPL_N_OR_FRAG_AFTER):
4655         if (p_Manip->h_Frag)
4656         err = UpdateModifyCapwapFragmenation(p_Manip, h_Ad, validate, h_FmTree);
4657         break;
4658 #endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */
4659         default:
4660             return E_OK;
4661     }
4662 
4663     return err;
4664 }
4665 
4666 /*****************************************************************************/
4667 /*              Inter-module API routines                                    */
4668 /*****************************************************************************/
4669 
4670 t_Error FmPcdManipUpdate(t_Handle h_FmPcd, t_Handle h_PcdParams,
4671                          t_Handle h_FmPort, t_Handle h_Manip, t_Handle h_Ad,
4672                          bool validate, int level, t_Handle h_FmTree,
4673                          bool modify)
4674 {
4675     t_Error err;
4676 
4677     if (!modify)
4678         err = FmPcdManipInitUpdate(h_FmPcd, h_PcdParams, h_FmPort, h_Manip,
4679                                    h_Ad, validate, level, h_FmTree);
4680     else
4681         err = FmPcdManipModifyUpdate(h_Manip, h_Ad, validate, level, h_FmTree);
4682 
4683     return err;
4684 }
4685 
4686 void FmPcdManipUpdateOwner(t_Handle h_Manip, bool add)
4687 {
4688 
4689     uint32_t intFlags;
4690 
4691     intFlags = XX_LockIntrSpinlock(((t_FmPcdManip *)h_Manip)->h_Spinlock);
4692     if (add)
4693         ((t_FmPcdManip *)h_Manip)->owner++;
4694     else
4695     {
4696         ASSERT_COND(((t_FmPcdManip *)h_Manip)->owner);
4697         ((t_FmPcdManip *)h_Manip)->owner--;
4698     }
4699     XX_UnlockIntrSpinlock(((t_FmPcdManip *)h_Manip)->h_Spinlock, intFlags);
4700 }
4701 
4702 t_List *FmPcdManipGetNodeLstPointedOnThisManip(t_Handle h_Manip)
4703 {
4704     ASSERT_COND(h_Manip);
4705     return &((t_FmPcdManip *)h_Manip)->nodesLst;
4706 }
4707 
4708 t_List *FmPcdManipGetSpinlock(t_Handle h_Manip)
4709 {
4710     ASSERT_COND(h_Manip);
4711     return ((t_FmPcdManip *)h_Manip)->h_Spinlock;
4712 }
4713 
4714 t_Error FmPcdManipCheckParamsForCcNextEngine(
4715         t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams,
4716         uint32_t *requiredAction)
4717 {
4718     t_FmPcdManip *p_Manip;
4719 #if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
4720     t_Error err = E_OK;
4721 #endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))*/
4722     bool pointFromCc = TRUE;
4723 
4724     SANITY_CHECK_RETURN_ERROR(p_FmPcdCcNextEngineParams, E_NULL_POINTER);
4725     SANITY_CHECK_RETURN_ERROR(p_FmPcdCcNextEngineParams->h_Manip,
4726                               E_NULL_POINTER);
4727 
4728     p_Manip = (t_FmPcdManip *)(p_FmPcdCcNextEngineParams->h_Manip);
4729     *requiredAction = 0;
4730 
4731     while (p_Manip)
4732     {
4733         switch (p_Manip->opcode)
4734         {
4735 #if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
4736             case (HMAN_OC_CAPWAP_INDEXED_STATS):
4737                 if (p_FmPcdCcNextEngineParams->nextEngine != e_FM_PCD_DONE)
4738                     RETURN_ERROR(MAJOR,	E_INVALID_STATE, ("For this type of header manipulation has to be nextEngine e_FM_PCD_DONE"));
4739                 if (p_FmPcdCcNextEngineParams->params.enqueueParams.overrideFqid)
4740                     p_Manip->cnia = TRUE;
4741             case (HMAN_OC_CAPWAP_RMV_DTLS_IF_EXIST):
4742                 *requiredAction = UPDATE_NIA_ENQ_WITHOUT_DMA;
4743             case (HMAN_OC_RMV_N_OR_INSRT_INT_FRM_HDR):
4744                 p_Manip->ownerTmp++;
4745                 break;
4746             case (HMAN_OC_INSRT_HDR_BY_TEMPL_N_OR_FRAG_AFTER):
4747                 if ((p_FmPcdCcNextEngineParams->nextEngine != e_FM_PCD_DONE)
4748                     && !p_FmPcdCcNextEngineParams->params.enqueueParams.overrideFqid)
4749                     RETURN_ERROR(
4750                         MAJOR,
4751                         E_INVALID_STATE,
4752                         ("For this type of header manipulation has to be nextEngine e_FM_PCD_DONE with fqidForCtrlFlow FALSE"));
4753                 p_Manip->ownerTmp++;
4754                 break;
4755             case (HMAN_OC_MV_INT_FRAME_HDR_FROM_FRM_TO_BUFFER_PREFFIX):
4756                 if ((p_FmPcdCcNextEngineParams->nextEngine != e_FM_PCD_CC)
4757                     && (FmPcdCcGetParseCode(p_FmPcdCcNextEngineParams->params.ccParams.h_CcNode)
4758                         != CC_PC_GENERIC_IC_HASH_INDEXED))
4759                     RETURN_ERROR(MAJOR, E_INVALID_STATE, ("For this type of header manipulation next engine has to be CC and action = e_FM_PCD_ACTION_INDEXED_LOOKUP"));
4760                 err = UpdateManipIc(p_FmPcdCcNextEngineParams->h_Manip,
4761                                     FmPcdCcGetOffset(p_FmPcdCcNextEngineParams->params.ccParams.h_CcNode));
4762                 if (err)
4763                     RETURN_ERROR(MAJOR, err, NO_MSG);
4764                 *requiredAction = UPDATE_NIA_ENQ_WITHOUT_DMA;
4765                 break;
4766  #endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */
4767             case (HMAN_OC_IP_FRAGMENTATION):
4768             case (HMAN_OC_IP_REASSEMBLY):
4769 #if (DPAA_VERSION >= 11)
4770             case (HMAN_OC_CAPWAP_REASSEMBLY):
4771             case (HMAN_OC_CAPWAP_FRAGMENTATION):
4772 #endif /* (DPAA_VERSION >= 11) */
4773                 if (p_FmPcdCcNextEngineParams->nextEngine != e_FM_PCD_DONE)
4774                     RETURN_ERROR(
4775                             MAJOR,
4776                             E_INVALID_STATE,
4777                             ("For this type of header manipulation has to be nextEngine e_FM_PCD_DONE"));
4778                 p_Manip->ownerTmp++;
4779                 break;
4780             case (HMAN_OC_IPSEC_MANIP):
4781 #if (DPAA_VERSION >= 11)
4782             case (HMAN_OC_CAPWAP_MANIP):
4783 #endif /* (DPAA_VERSION >= 11) */
4784                 p_Manip->ownerTmp++;
4785                 break;
4786             case (HMAN_OC):
4787                 if ((p_FmPcdCcNextEngineParams->nextEngine == e_FM_PCD_CC)
4788                         && MANIP_IS_CASCADED(p_Manip))
4789                     RETURN_ERROR(
4790                             MINOR,
4791                             E_INVALID_STATE,
4792                             ("Can't have a cascaded manipulation when and Next Engine is CC"));
4793                 if (!MANIP_IS_FIRST(p_Manip) && pointFromCc)
4794                     RETURN_ERROR(
4795                             MAJOR,
4796                             E_INVALID_STATE,
4797                             ("h_Manip is already used and may not be shared (no sharing of non-head manip nodes)"));
4798                 break;
4799             default:
4800                 RETURN_ERROR(
4801                         MAJOR, E_INVALID_STATE,
4802                         ("invalid type of header manipulation for this state"));
4803         }
4804         p_Manip = p_Manip->h_NextManip;
4805         pointFromCc = FALSE;
4806     }
4807     return E_OK;
4808 }
4809 
4810 
4811 t_Error FmPcdManipCheckParamsWithCcNodeParams(t_Handle h_Manip,
4812                                               t_Handle h_FmPcdCcNode)
4813 {
4814     t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_Manip;
4815     t_Error err = E_OK;
4816 
4817     SANITY_CHECK_RETURN_ERROR(h_Manip, E_INVALID_HANDLE);
4818     SANITY_CHECK_RETURN_ERROR(h_FmPcdCcNode, E_INVALID_HANDLE);
4819 
4820     switch (p_Manip->opcode)
4821     {
4822 #if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
4823         case (HMAN_OC_CAPWAP_INDEXED_STATS):
4824         if (p_Manip->ownerTmp != FmPcdCcGetNumOfKeys(h_FmPcdCcNode))
4825         RETURN_ERROR(
4826                 MAJOR,
4827                 E_INVALID_VALUE,
4828                 ("The manipulation of the type statistics flowId if exist has to be pointed by all numOfKeys"));
4829         break;
4830         case (HMAN_OC_CAPWAP_RMV_DTLS_IF_EXIST):
4831         if (p_Manip->h_Frag)
4832         {
4833             if (p_Manip->ownerTmp != FmPcdCcGetNumOfKeys(h_FmPcdCcNode))
4834             RETURN_ERROR(
4835                     MAJOR,
4836                     E_INVALID_VALUE,
4837                     ("The manipulation of the type remove DTLS if exist has to be pointed by all numOfKeys"));
4838             err = UpdateManipIc(h_Manip, FmPcdCcGetOffset(h_FmPcdCcNode));
4839             if (err)
4840             RETURN_ERROR(MAJOR, err, NO_MSG);
4841         }
4842         break;
4843 #endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */
4844         default:
4845             break;
4846     }
4847 
4848     return err;
4849 }
4850 
4851 void FmPcdManipUpdateAdResultForCc(
4852         t_Handle h_Manip, t_FmPcdCcNextEngineParams *p_CcNextEngineParams,
4853         t_Handle p_Ad, t_Handle *p_AdNewPtr)
4854 {
4855     t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_Manip;
4856 
4857     /* This routine creates a Manip AD and can return in "p_AdNewPtr"
4858      * either the new descriptor or NULL if it writes the Manip AD into p_AD (into the match table) */
4859 
4860     ASSERT_COND(p_Manip);
4861     ASSERT_COND(p_CcNextEngineParams);
4862     ASSERT_COND(p_Ad);
4863     ASSERT_COND(p_AdNewPtr);
4864 
4865     FmPcdManipUpdateOwner(h_Manip, TRUE);
4866 
4867     /* According to "type", either build & initialize a new AD (p_AdNew) or initialize
4868      * p_Ad ( the AD in the match table) and set p_AdNew = NULL. */
4869     switch (p_Manip->opcode)
4870     {
4871 #if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
4872         case (HMAN_OC_RMV_N_OR_INSRT_INT_FRM_HDR):
4873         case (HMAN_OC_CAPWAP_RMV_DTLS_IF_EXIST):
4874         case (HMAN_OC_CAPWAP_INDEXED_STATS):
4875         *p_AdNewPtr = p_Manip->h_Ad;
4876         break;
4877         case (HMAN_OC_INSRT_HDR_BY_TEMPL_N_OR_FRAG_AFTER):
4878         case (HMAN_OC_CAPWAP_FRAGMENTATION):
4879         WRITE_UINT32(((t_AdOfTypeResult *)p_Ad)->fqid,
4880                 ((t_AdOfTypeResult *)(p_Manip->h_Ad))->fqid);
4881         WRITE_UINT32(((t_AdOfTypeResult *)p_Ad)->plcrProfile,
4882                 ((t_AdOfTypeResult *)(p_Manip->h_Ad))->plcrProfile);
4883         WRITE_UINT32(((t_AdOfTypeResult *)p_Ad)->nia,
4884                 ((t_AdOfTypeResult *)(p_Manip->h_Ad))->nia);
4885         *p_AdNewPtr = NULL;
4886         break;
4887 #endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */
4888         case (HMAN_OC_IPSEC_MANIP):
4889 #if (DPAA_VERSION >= 11)
4890         case (HMAN_OC_CAPWAP_MANIP):
4891 #endif /* (DPAA_VERSION >= 11) */
4892             *p_AdNewPtr = p_Manip->h_Ad;
4893             break;
4894         case (HMAN_OC_IP_FRAGMENTATION):
4895 #if (DPAA_VERSION >= 11)
4896         case (HMAN_OC_CAPWAP_FRAGMENTATION):
4897 #endif /* (DPAA_VERSION >= 11) */
4898             if ((p_CcNextEngineParams->nextEngine == e_FM_PCD_DONE)
4899                     && (!p_CcNextEngineParams->params.enqueueParams.overrideFqid))
4900             {
4901                 memcpy((uint8_t *)p_Ad, (uint8_t *)p_Manip->h_Ad,
4902                        sizeof(t_AdOfTypeContLookup));
4903 #if (DPAA_VERSION >= 11)
4904                 WRITE_UINT32(
4905                         ((t_AdOfTypeContLookup *)p_Ad)->ccAdBase,
4906                         GET_UINT32(((t_AdOfTypeContLookup *)p_Ad)->ccAdBase) & ~FM_PCD_MANIP_IP_CNIA);
4907 #endif /* (DPAA_VERSION >= 11) */
4908                 *p_AdNewPtr = NULL;
4909             }
4910             else
4911                 *p_AdNewPtr = p_Manip->h_Ad;
4912             break;
4913         case (HMAN_OC_IP_REASSEMBLY):
4914             if (FmPcdManipIpReassmIsIpv6Hdr(p_Manip))
4915             {
4916                 if (!p_Manip->reassmParams.ip.ipv6Assigned)
4917                 {
4918                     *p_AdNewPtr = p_Manip->reassmParams.ip.h_Ipv6Ad;
4919                     p_Manip->reassmParams.ip.ipv6Assigned = TRUE;
4920                     FmPcdManipUpdateOwner(h_Manip, FALSE);
4921                 }
4922                 else
4923                 {
4924                     *p_AdNewPtr = p_Manip->reassmParams.ip.h_Ipv4Ad;
4925                     p_Manip->reassmParams.ip.ipv6Assigned = FALSE;
4926                 }
4927             }
4928             else
4929                 *p_AdNewPtr = p_Manip->reassmParams.ip.h_Ipv4Ad;
4930             memcpy((uint8_t *)p_Ad, (uint8_t *)*p_AdNewPtr,
4931                    sizeof(t_AdOfTypeContLookup));
4932             *p_AdNewPtr = NULL;
4933             break;
4934 #if (DPAA_VERSION >= 11)
4935         case (HMAN_OC_CAPWAP_REASSEMBLY):
4936             *p_AdNewPtr = p_Manip->reassmParams.capwap.h_Ad;
4937             memcpy((uint8_t *)p_Ad, (uint8_t *)*p_AdNewPtr,
4938                    sizeof(t_AdOfTypeContLookup));
4939             *p_AdNewPtr = NULL;
4940             break;
4941 #endif /* (DPAA_VERSION >= 11) */
4942         case (HMAN_OC):
4943             /* Allocate and initialize HMTD */
4944             *p_AdNewPtr = p_Manip->h_Ad;
4945             break;
4946         default:
4947             break;
4948     }
4949 }
4950 
4951 void FmPcdManipUpdateAdContLookupForCc(t_Handle h_Manip, t_Handle p_Ad,
4952                                        t_Handle *p_AdNewPtr,
4953                                        uint32_t adTableOffset)
4954 {
4955     t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_Manip;
4956 
4957     /* This routine creates a Manip AD and can return in "p_AdNewPtr"
4958      * either the new descriptor or NULL if it writes the Manip AD into p_AD (into the match table) */
4959     ASSERT_COND(p_Manip);
4960 
4961     FmPcdManipUpdateOwner(h_Manip, TRUE);
4962 
4963     switch (p_Manip->opcode)
4964     {
4965 #if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
4966         case (HMAN_OC_MV_INT_FRAME_HDR_FROM_FRM_TO_BUFFER_PREFFIX):
4967         WRITE_UINT32(((t_AdOfTypeContLookup *)p_Ad)->ccAdBase,
4968                 ((t_AdOfTypeContLookup *)(p_Manip->h_Ad))->ccAdBase);
4969         WRITE_UINT32(
4970                 ((t_AdOfTypeContLookup *)p_Ad)->matchTblPtr,
4971                 ((t_AdOfTypeContLookup *)(p_Manip->h_Ad))->matchTblPtr);
4972         WRITE_UINT32(
4973                 ((t_AdOfTypeContLookup *)p_Ad)->pcAndOffsets,
4974                 ((t_AdOfTypeContLookup *)(p_Manip->h_Ad))->pcAndOffsets);
4975         WRITE_UINT32(((t_AdOfTypeContLookup *)p_Ad)->gmask,
4976                 ((t_AdOfTypeContLookup *)(p_Manip->h_Ad))->gmask);
4977         WRITE_UINT32(
4978                 ((t_AdOfTypeContLookup *)p_Ad)->ccAdBase,
4979                 (GET_UINT32(((t_AdOfTypeContLookup *)p_Ad)->ccAdBase) | adTableOffset));
4980         *p_AdNewPtr = NULL;
4981         break;
4982 #endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */
4983         case (HMAN_OC):
4984             /* Initialize HMTD within the match table*/
4985             MemSet8(p_Ad, 0, FM_PCD_CC_AD_ENTRY_SIZE);
4986             /* copy the existing HMTD *//* ask Alla - memcpy??? */
4987             memcpy((uint8_t*)p_Ad, p_Manip->h_Ad, sizeof(t_Hmtd));
4988             /* update NADEN to be "1"*/
4989             WRITE_UINT16(
4990                     ((t_Hmtd *)p_Ad)->cfg,
4991                     (uint16_t)(GET_UINT16(((t_Hmtd *)p_Ad)->cfg) | HMTD_CFG_NEXT_AD_EN));
4992             /* update next action descriptor */
4993             WRITE_UINT16(((t_Hmtd *)p_Ad)->nextAdIdx,
4994                          (uint16_t)(adTableOffset >> 4));
4995             /* mark that Manip's HMTD is not used */
4996             *p_AdNewPtr = NULL;
4997             break;
4998 
4999         default:
5000             break;
5001     }
5002 }
5003 
5004 t_Error FmPcdManipBuildIpReassmScheme(t_FmPcd *p_FmPcd, t_Handle h_NetEnv,
5005                                       t_Handle h_CcTree, t_Handle h_Manip,
5006                                       bool isIpv4, uint8_t groupId)
5007 {
5008     t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_Manip;
5009     t_FmPcdKgSchemeParams *p_SchemeParams = NULL;
5010     t_Handle h_Scheme;
5011 
5012     ASSERT_COND(p_FmPcd);
5013     ASSERT_COND(h_NetEnv);
5014     ASSERT_COND(p_Manip);
5015 
5016     /* scheme was already build, no need to check for IPv6 */
5017     if (p_Manip->reassmParams.ip.h_Ipv4Scheme)
5018         return E_OK;
5019 
5020     if (isIpv4) {
5021         h_Scheme = FmPcdKgGetSchemeHandle(p_FmPcd, p_Manip->reassmParams.ip.relativeSchemeId[0]);
5022         if (h_Scheme) {
5023             /* scheme was found */
5024             p_Manip->reassmParams.ip.h_Ipv4Scheme = h_Scheme;
5025             return E_OK;
5026         }
5027     } else {
5028         h_Scheme = FmPcdKgGetSchemeHandle(p_FmPcd, p_Manip->reassmParams.ip.relativeSchemeId[1]);
5029         if (h_Scheme) {
5030             /* scheme was found */
5031             p_Manip->reassmParams.ip.h_Ipv6Scheme = h_Scheme;
5032             return E_OK;
5033         }
5034     }
5035 
5036      p_SchemeParams = XX_Malloc(sizeof(t_FmPcdKgSchemeParams));
5037     if (!p_SchemeParams)
5038         RETURN_ERROR(MAJOR, E_NO_MEMORY,
5039                      ("Memory allocation failed for scheme"));
5040 
5041     /* Configures the IPv4 or IPv6 scheme*/
5042     memset(p_SchemeParams, 0, sizeof(t_FmPcdKgSchemeParams));
5043     p_SchemeParams->netEnvParams.h_NetEnv = h_NetEnv;
5044     p_SchemeParams->id.relativeSchemeId = (uint8_t)(
5045             (isIpv4 == TRUE) ? p_Manip->reassmParams.ip.relativeSchemeId[0] :
5046                     p_Manip->reassmParams.ip.relativeSchemeId[1]);
5047     p_SchemeParams->schemeCounter.update = TRUE;
5048 #if (DPAA_VERSION >= 11)
5049     p_SchemeParams->alwaysDirect = TRUE;
5050     p_SchemeParams->bypassFqidGeneration = TRUE;
5051 #else
5052     p_SchemeParams->keyExtractAndHashParams.hashDistributionNumOfFqids = 1;
5053     p_SchemeParams->baseFqid = 0xFFFFFF; /*TODO- baseFqid*/
5054 #endif /* (DPAA_VERSION >= 11) */
5055 
5056     setIpReassmSchemeParams(p_FmPcd, p_SchemeParams, h_CcTree, isIpv4, groupId);
5057 
5058     /* Sets the new scheme */
5059     if (isIpv4)
5060         p_Manip->reassmParams.ip.h_Ipv4Scheme = FM_PCD_KgSchemeSet(
5061                 p_FmPcd, p_SchemeParams);
5062     else
5063         p_Manip->reassmParams.ip.h_Ipv6Scheme = FM_PCD_KgSchemeSet(
5064                 p_FmPcd, p_SchemeParams);
5065 
5066     XX_Free(p_SchemeParams);
5067 
5068     return E_OK;
5069 }
5070 
5071 t_Error FmPcdManipDeleteIpReassmSchemes(t_Handle h_Manip)
5072 {
5073     t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_Manip;
5074 
5075     ASSERT_COND(p_Manip);
5076 
5077     if ((p_Manip->reassmParams.ip.h_Ipv4Scheme) &&
5078         !FmPcdKgIsSchemeHasOwners(p_Manip->reassmParams.ip.h_Ipv4Scheme))
5079         FM_PCD_KgSchemeDelete(p_Manip->reassmParams.ip.h_Ipv4Scheme);
5080 
5081     if ((p_Manip->reassmParams.ip.h_Ipv6Scheme) &&
5082         !FmPcdKgIsSchemeHasOwners(p_Manip->reassmParams.ip.h_Ipv6Scheme))
5083         FM_PCD_KgSchemeDelete(p_Manip->reassmParams.ip.h_Ipv6Scheme);
5084 
5085     return E_OK;
5086 }
5087 
5088 bool FmPcdManipIpReassmIsIpv6Hdr(t_Handle h_Manip)
5089 {
5090     t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_Manip;
5091 
5092     ASSERT_COND(p_Manip);
5093 
5094     return (p_Manip->reassmParams.hdr == HEADER_TYPE_IPv6);
5095 }
5096 
5097 t_Error FmPcdManipBuildCapwapReassmScheme(t_FmPcd *p_FmPcd, t_Handle h_NetEnv,
5098                                           t_Handle h_CcTree, t_Handle h_Manip,
5099                                           uint8_t groupId)
5100 {
5101     t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_Manip;
5102     t_FmPcdKgSchemeParams *p_SchemeParams = NULL;
5103 
5104     ASSERT_COND(p_FmPcd);
5105     ASSERT_COND(h_NetEnv);
5106     ASSERT_COND(p_Manip);
5107 
5108     /* scheme was already build, no need to check for IPv6 */
5109     if (p_Manip->reassmParams.capwap.h_Scheme)
5110         return E_OK;
5111 
5112     p_SchemeParams = XX_Malloc(sizeof(t_FmPcdKgSchemeParams));
5113     if (!p_SchemeParams)
5114         RETURN_ERROR(MAJOR, E_NO_MEMORY,
5115                      ("Memory allocation failed for scheme"));
5116 
5117     memset(p_SchemeParams, 0, sizeof(t_FmPcdKgSchemeParams));
5118     p_SchemeParams->netEnvParams.h_NetEnv = h_NetEnv;
5119     p_SchemeParams->id.relativeSchemeId =
5120             (uint8_t)p_Manip->reassmParams.capwap.relativeSchemeId;
5121     p_SchemeParams->schemeCounter.update = TRUE;
5122     p_SchemeParams->bypassFqidGeneration = TRUE;
5123 
5124     setCapwapReassmSchemeParams(p_FmPcd, p_SchemeParams, h_CcTree, groupId);
5125 
5126     p_Manip->reassmParams.capwap.h_Scheme = FM_PCD_KgSchemeSet(p_FmPcd,
5127                                                                p_SchemeParams);
5128 
5129     XX_Free(p_SchemeParams);
5130 
5131     return E_OK;
5132 }
5133 
5134 t_Error FmPcdManipDeleteCapwapReassmSchemes(t_Handle h_Manip)
5135 {
5136     t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_Manip;
5137 
5138     ASSERT_COND(p_Manip);
5139 
5140     if (p_Manip->reassmParams.capwap.h_Scheme)
5141         FM_PCD_KgSchemeDelete(p_Manip->reassmParams.capwap.h_Scheme);
5142 
5143     return E_OK;
5144 }
5145 
5146 #if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
5147 t_Handle FmPcdManipApplSpecificBuild(void)
5148 {
5149     t_FmPcdManip *p_Manip;
5150 
5151     p_Manip = (t_FmPcdManip*)XX_Malloc(sizeof(t_FmPcdManip));
5152     if (!p_Manip)
5153     {
5154         REPORT_ERROR(MAJOR, E_NO_MEMORY, ("No memory"));
5155         return NULL;
5156     }
5157     memset(p_Manip, 0, sizeof(t_FmPcdManip));
5158 
5159     p_Manip->opcode = HMAN_OC_MV_INT_FRAME_HDR_FROM_FRM_TO_BUFFER_PREFFIX;
5160     p_Manip->muramAllocate = FALSE;
5161 
5162     p_Manip->h_Ad = (t_Handle)XX_Malloc(FM_PCD_CC_AD_ENTRY_SIZE * sizeof(uint8_t));
5163     if (!p_Manip->h_Ad)
5164     {
5165         REPORT_ERROR(MAJOR, E_NO_MEMORY, ("Allocation of Manipulation action descriptor"));
5166         XX_Free(p_Manip);
5167         return NULL;
5168     }
5169 
5170     memset(p_Manip->h_Ad, 0, FM_PCD_CC_AD_ENTRY_SIZE * sizeof(uint8_t));
5171 
5172     /*treatFdStatusFieldsAsErrors = TRUE hardcoded - assumption its always come after CAAM*/
5173     /*Application specific = type of flowId index, move internal frame header from data to IC,
5174      SEC errors check*/
5175     if (MvIntFrameHeaderFromFrameToBufferPrefix(p_Manip, TRUE)!= E_OK)
5176     {
5177         XX_Free(p_Manip->h_Ad);
5178         XX_Free(p_Manip);
5179         return NULL;
5180     }
5181     return p_Manip;
5182 }
5183 
5184 bool FmPcdManipIsCapwapApplSpecific(t_Handle h_Manip)
5185 {
5186     t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_Manip;
5187     ASSERT_COND(h_Manip);
5188 
5189     return (bool)((p_Manip->opcode == HMAN_OC_CAPWAP_RMV_DTLS_IF_EXIST) ? TRUE : FALSE);
5190 }
5191 #endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */
5192 /*********************** End of inter-module routines ************************/
5193 
5194 /****************************************/
5195 /*       API Init unit functions        */
5196 /****************************************/
5197 
5198 t_Handle FM_PCD_ManipNodeSet(t_Handle h_FmPcd,
5199                              t_FmPcdManipParams *p_ManipParams)
5200 {
5201     t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
5202     t_FmPcdManip *p_Manip;
5203     t_Error err;
5204 
5205     SANITY_CHECK_RETURN_VALUE(h_FmPcd, E_INVALID_HANDLE, NULL);
5206     SANITY_CHECK_RETURN_VALUE(p_ManipParams, E_INVALID_HANDLE, NULL);
5207 
5208     p_Manip = ManipOrStatsSetNode(h_FmPcd, (t_Handle)p_ManipParams, FALSE);
5209     if (!p_Manip)
5210         return NULL;
5211 
5212     if (((p_Manip->opcode == HMAN_OC_IP_REASSEMBLY)
5213             || (p_Manip->opcode == HMAN_OC_IP_FRAGMENTATION)
5214             || (p_Manip->opcode == HMAN_OC)
5215             || (p_Manip->opcode == HMAN_OC_IPSEC_MANIP)
5216 #if (DPAA_VERSION >= 11)
5217             || (p_Manip->opcode == HMAN_OC_CAPWAP_MANIP)
5218             || (p_Manip->opcode == HMAN_OC_CAPWAP_FRAGMENTATION)
5219             || (p_Manip->opcode == HMAN_OC_CAPWAP_REASSEMBLY)
5220 #endif /* (DPAA_VERSION >= 11) */
5221             ) && (!FmPcdIsAdvancedOffloadSupported(p_FmPcd)))
5222     {
5223         REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Advanced-offload must be enabled"));
5224         XX_Free(p_Manip);
5225         return NULL;
5226     }
5227     p_Manip->h_Spinlock = XX_InitSpinlock();
5228     if (!p_Manip->h_Spinlock)
5229     {
5230         REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("UNSUPPORTED HEADER MANIPULATION TYPE"));
5231         ReleaseManipHandler(p_Manip, p_FmPcd);
5232         XX_Free(p_Manip);
5233         return NULL;
5234     }INIT_LIST(&p_Manip->nodesLst);
5235 
5236     switch (p_Manip->opcode)
5237     {
5238         case (HMAN_OC_IP_REASSEMBLY):
5239             /* IpReassembly */
5240             err = IpReassembly(&p_ManipParams->u.reassem, p_Manip);
5241             break;
5242         case (HMAN_OC_IP_FRAGMENTATION):
5243             /* IpFragmentation */
5244             err = IpFragmentation(&p_ManipParams->u.frag.u.ipFrag, p_Manip);
5245             if (err)
5246                 break;
5247             err = IPManip(p_Manip);
5248             break;
5249         case (HMAN_OC_IPSEC_MANIP):
5250             err = IPSecManip(p_ManipParams, p_Manip);
5251             break;
5252 #if (DPAA_VERSION >= 11)
5253         case (HMAN_OC_CAPWAP_REASSEMBLY):
5254             /* CapwapReassembly */
5255             err = CapwapReassembly(&p_ManipParams->u.reassem, p_Manip);
5256             break;
5257         case (HMAN_OC_CAPWAP_FRAGMENTATION):
5258             /* CapwapFragmentation */
5259             err = CapwapFragmentation(&p_ManipParams->u.frag.u.capwapFrag,
5260                                       p_Manip);
5261             break;
5262         case (HMAN_OC_CAPWAP_MANIP):
5263             err = CapwapManip(p_ManipParams, p_Manip);
5264             break;
5265 #endif /* (DPAA_VERSION >= 11) */
5266 #if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
5267             case (HMAN_OC_RMV_N_OR_INSRT_INT_FRM_HDR):
5268             /* HmanType1 */
5269             err = RmvHdrTillSpecLocNOrInsrtIntFrmHdr(&p_ManipParams->u.hdr.rmvParams, p_Manip);
5270             break;
5271             case (HMAN_OC_CAPWAP_FRAGMENTATION):
5272             err = CapwapFragmentation(&p_ManipParams->fragOrReasmParams.u.capwapFragParams,
5273                     p_Manip,
5274                     p_FmPcd,
5275                     p_ManipParams->fragOrReasmParams.sgBpid);
5276             if (err)
5277             {
5278                 REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("UNSUPPORTED HEADER MANIPULATION TYPE"));
5279                 ReleaseManipHandler(p_Manip, p_FmPcd);
5280                 XX_Free(p_Manip);
5281                 return NULL;
5282             }
5283             if (p_Manip->insrt)
5284             p_Manip->opcode = HMAN_OC_INSRT_HDR_BY_TEMPL_N_OR_FRAG_AFTER;
5285             case (HMAN_OC_INSRT_HDR_BY_TEMPL_N_OR_FRAG_AFTER):
5286             /* HmanType2 + if user asked only for fragmentation still need to allocate HmanType2 */
5287             err = InsrtHdrByTempl(&p_ManipParams->u.hdr.insrtParams, p_Manip, p_FmPcd);
5288             break;
5289             case (HMAN_OC_CAPWAP_REASSEMBLY):
5290             err = CapwapReassembly(&p_ManipParams->fragOrReasmParams.u.capwapReasmParams,
5291                     p_Manip,
5292                     p_FmPcd,
5293                     p_ManipParams->fragOrReasmParams.sgBpid);
5294             if (err)
5295             {
5296                 REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("UNSUPPORTED HEADER MANIPULATION TYPE"));
5297                 ReleaseManipHandler(p_Manip, p_FmPcd);
5298                 XX_Free(p_Manip);
5299                 return NULL;
5300             }
5301             if (p_Manip->rmv)
5302             p_Manip->opcode = HMAN_OC_CAPWAP_RMV_DTLS_IF_EXIST;
5303             case (HMAN_OC_CAPWAP_RMV_DTLS_IF_EXIST):
5304             /*CAPWAP decapsulation + if user asked only for reassembly still need to allocate CAPWAP decapsulation*/
5305             err = CapwapRmvDtlsHdr(p_FmPcd, p_Manip);
5306             break;
5307             case (HMAN_OC_MV_INT_FRAME_HDR_FROM_FRM_TO_BUFFER_PREFFIX):
5308             /*Application Specific type 1*/
5309             err = MvIntFrameHeaderFromFrameToBufferPrefix(p_Manip, TRUE);
5310             break;
5311 #endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */
5312         case (HMAN_OC):
5313             /* New Manip */
5314             err = CreateManipActionNew(p_Manip, p_ManipParams);
5315             break;
5316         default:
5317             REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("UNSUPPORTED HEADER MANIPULATION TYPE"));
5318             ReleaseManipHandler(p_Manip, p_FmPcd);
5319             XX_Free(p_Manip);
5320             return NULL;
5321     }
5322 
5323     if (err)
5324     {
5325         REPORT_ERROR(MAJOR, err, NO_MSG);
5326         ReleaseManipHandler(p_Manip, p_FmPcd);
5327         XX_Free(p_Manip);
5328         return NULL;
5329     }
5330 
5331     if (p_ManipParams->h_NextManip)
5332     {
5333         /* in the check routine we've verified that h_NextManip has no owners
5334          * and that only supported types are allowed. */
5335         p_Manip->h_NextManip = p_ManipParams->h_NextManip;
5336         /* save a "prev" pointer in h_NextManip */
5337         MANIP_SET_PREV(p_Manip->h_NextManip, p_Manip);
5338         FmPcdManipUpdateOwner(p_Manip->h_NextManip, TRUE);
5339     }
5340 
5341     return p_Manip;
5342 }
5343 
5344 t_Error FM_PCD_ManipNodeReplace(t_Handle h_Manip,
5345                                 t_FmPcdManipParams *p_ManipParams)
5346 {
5347     t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_Manip, *p_FirstManip;
5348     t_FmPcd *p_FmPcd = (t_FmPcd *)(p_Manip->h_FmPcd);
5349     t_Error err;
5350     uint8_t *p_WholeHmct = NULL, *p_ShadowHmct = NULL, *p_Hmtd = NULL;
5351     t_List lstOfNodeshichPointsOnCrntMdfManip, *p_Pos;
5352     t_CcNodeInformation *p_CcNodeInfo;
5353     SANITY_CHECK_RETURN_ERROR(h_Manip, E_INVALID_HANDLE);
5354     SANITY_CHECK_RETURN_ERROR(p_ManipParams, E_INVALID_HANDLE);
5355 
5356     INIT_LIST(&lstOfNodeshichPointsOnCrntMdfManip);
5357 
5358     if ((p_ManipParams->type != e_FM_PCD_MANIP_HDR)
5359             || (p_Manip->type != e_FM_PCD_MANIP_HDR))
5360         RETURN_ERROR(
5361                 MINOR,
5362                 E_NOT_SUPPORTED,
5363                 ("FM_PCD_ManipNodeReplace Functionality supported only for Header Manipulation."));
5364 
5365     ASSERT_COND(p_Manip->opcode == HMAN_OC);
5366     ASSERT_COND(p_Manip->manipParams.h_NextManip == p_Manip->h_NextManip);
5367     memcpy((uint8_t*)&p_Manip->manipParams, p_ManipParams,
5368            sizeof(p_Manip->manipParams));
5369     p_Manip->manipParams.h_NextManip = p_Manip->h_NextManip;
5370 
5371     /* The replacement of the HdrManip depends on the node type.*/
5372     /*
5373      * (1) If this is an independent node, all its owners should be updated.
5374      *
5375      * (2) If it is the head of a cascaded chain (it does not have a "prev" but
5376      * it has a "next" and it has a "cascaded" indication), the next
5377      * node remains unchanged, and the behavior is as in (1).
5378      *
5379      * (3) If it is not the head, but a part of a cascaded chain, in can be
5380      * also replaced as a regular node with just one owner.
5381      *
5382      * (4) If it is a part of a chain implemented as a unified table, the
5383      * whole table is replaced and the owners of the head node must be updated.
5384      *
5385      */
5386     /* lock shadow */
5387     if (!p_FmPcd->p_CcShadow)
5388         RETURN_ERROR(MAJOR, E_NO_MEMORY, ("CC Shadow not allocated"));
5389 
5390     if (!TRY_LOCK(p_FmPcd->h_ShadowSpinlock, &p_FmPcd->shadowLock))
5391         return ERROR_CODE(E_BUSY);
5392 
5393     /* this routine creates a new manip action in the CC Shadow. */
5394     err = CreateManipActionShadow(p_Manip, p_ManipParams);
5395     if (err)
5396         RETURN_ERROR(MINOR, err, NO_MSG);
5397 
5398     /* If the owners list is empty (these are NOT the "owners" counter, but pointers from CC)
5399      * replace only HMTD and no lcok is required. Otherwise
5400      * lock the whole PCD
5401      * In case 4 MANIP_IS_UNIFIED_NON_FIRST(p_Manip) - Use the head node instead. */
5402     if (!FmPcdLockTryLockAll(p_FmPcd))
5403     {
5404         DBG(TRACE, ("FmPcdLockTryLockAll failed"));
5405         return ERROR_CODE(E_BUSY);
5406     }
5407 
5408     p_ShadowHmct = (uint8_t*)PTR_MOVE(p_FmPcd->p_CcShadow, 16);
5409 
5410     p_FirstManip = (t_FmPcdManip*)GetManipInfo(p_Manip,
5411                                                e_MANIP_HANDLER_TABLE_OWNER);
5412     ASSERT_COND(p_FirstManip);
5413 
5414     if (!NCSW_LIST_IsEmpty(&p_FirstManip->nodesLst))
5415         UpdateAdPtrOfNodesWhichPointsOnCrntMdfManip(
5416                 p_FirstManip, &lstOfNodeshichPointsOnCrntMdfManip);
5417 
5418     p_Hmtd = (uint8_t *)GetManipInfo(p_Manip, e_MANIP_HMTD);
5419     ASSERT_COND(p_Hmtd);
5420     BuildHmtd(p_FmPcd->p_CcShadow, (uint8_t *)p_Hmtd, p_ShadowHmct,
5421               ((t_FmPcd*)(p_Manip->h_FmPcd)));
5422 
5423     NCSW_LIST_FOR_EACH(p_Pos, &lstOfNodeshichPointsOnCrntMdfManip)
5424     {
5425         p_CcNodeInfo = CC_NODE_F_OBJECT(p_Pos);
5426         BuildHmtd(p_FmPcd->p_CcShadow, (uint8_t *)p_CcNodeInfo->h_CcNode,
5427                   p_ShadowHmct, ((t_FmPcd*)(p_Manip->h_FmPcd)));
5428     }
5429 
5430     p_WholeHmct = (uint8_t *)GetManipInfo(p_Manip, e_MANIP_HMCT);
5431     ASSERT_COND(p_WholeHmct);
5432 
5433     /* re-build the HMCT n the original location */
5434     err = CreateManipActionBackToOrig(p_Manip, p_ManipParams);
5435     if (err)
5436     {
5437         RELEASE_LOCK(p_FmPcd->shadowLock);
5438         RETURN_ERROR(MINOR, err, NO_MSG);
5439     }
5440 
5441     p_Hmtd = (uint8_t *)GetManipInfo(p_Manip, e_MANIP_HMTD);
5442     ASSERT_COND(p_Hmtd);
5443     BuildHmtd(p_FmPcd->p_CcShadow, (uint8_t *)p_Hmtd, p_WholeHmct,
5444               ((t_FmPcd*)p_Manip->h_FmPcd));
5445 
5446     /* If NCSW_LIST > 0, create a list of p_Ad's that point to the HMCT. Join also t_HMTD to this list.
5447      * For each p_Hmct (from list+fixed):
5448      * call Host Command to replace HMTD by a new one */NCSW_LIST_FOR_EACH(p_Pos, &lstOfNodeshichPointsOnCrntMdfManip)
5449     {
5450         p_CcNodeInfo = CC_NODE_F_OBJECT(p_Pos);
5451         BuildHmtd(p_FmPcd->p_CcShadow, (uint8_t *)p_CcNodeInfo->h_CcNode,
5452                   p_WholeHmct, ((t_FmPcd*)(p_Manip->h_FmPcd)));
5453     }
5454 
5455 
5456     ReleaseLst(&lstOfNodeshichPointsOnCrntMdfManip);
5457 
5458     FmPcdLockUnlockAll(p_FmPcd);
5459 
5460     /* unlock shadow */
5461     RELEASE_LOCK(p_FmPcd->shadowLock);
5462 
5463     return E_OK;
5464 }
5465 
5466 t_Error FM_PCD_ManipNodeDelete(t_Handle h_ManipNode)
5467 {
5468     t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_ManipNode;
5469 
5470     SANITY_CHECK_RETURN_ERROR(p_Manip, E_INVALID_HANDLE);
5471 
5472     if (p_Manip->owner)
5473         RETURN_ERROR(
5474                 MAJOR,
5475                 E_INVALID_STATE,
5476                 ("This manipulation node not be removed because this node is occupied, first - unbind this node "));
5477 
5478     if (p_Manip->h_NextManip)
5479     {
5480         MANIP_SET_PREV(p_Manip->h_NextManip, NULL);
5481         FmPcdManipUpdateOwner(p_Manip->h_NextManip, FALSE);
5482     }
5483 
5484     if (p_Manip->p_Hmct
5485             && (MANIP_IS_UNIFIED_FIRST(p_Manip) || !MANIP_IS_UNIFIED(p_Manip)))
5486         FM_MURAM_FreeMem(((t_FmPcd *)p_Manip->h_FmPcd)->h_FmMuram,
5487                          p_Manip->p_Hmct);
5488 
5489     if (p_Manip->h_Spinlock)
5490     {
5491         XX_FreeSpinlock(p_Manip->h_Spinlock);
5492         p_Manip->h_Spinlock = NULL;
5493     }
5494 
5495     ReleaseManipHandler(p_Manip, p_Manip->h_FmPcd);
5496 
5497     XX_Free(h_ManipNode);
5498 
5499     return E_OK;
5500 }
5501 
5502 t_Error FM_PCD_ManipGetStatistics(t_Handle h_ManipNode,
5503                                   t_FmPcdManipStats *p_FmPcdManipStats)
5504 {
5505     t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_ManipNode;
5506 
5507     SANITY_CHECK_RETURN_ERROR(p_Manip, E_INVALID_HANDLE);
5508     SANITY_CHECK_RETURN_ERROR(p_FmPcdManipStats, E_NULL_POINTER);
5509 
5510     switch (p_Manip->opcode)
5511     {
5512         case (HMAN_OC_IP_REASSEMBLY):
5513             return IpReassemblyStats(p_Manip,
5514                                      &p_FmPcdManipStats->u.reassem.u.ipReassem);
5515         case (HMAN_OC_IP_FRAGMENTATION):
5516             return IpFragmentationStats(p_Manip,
5517                                         &p_FmPcdManipStats->u.frag.u.ipFrag);
5518 #if (DPAA_VERSION >= 11)
5519         case (HMAN_OC_CAPWAP_REASSEMBLY):
5520             return CapwapReassemblyStats(
5521                     p_Manip, &p_FmPcdManipStats->u.reassem.u.capwapReassem);
5522 	case (HMAN_OC_CAPWAP_FRAGMENTATION):
5523 		return CapwapFragmentationStats(
5524 			p_Manip, &p_FmPcdManipStats->u.frag.u.capwapFrag);
5525 #endif /* (DPAA_VERSION >= 11) */
5526         default:
5527             RETURN_ERROR(MAJOR, E_NOT_SUPPORTED,
5528                          ("no statistics to this type of manip"));
5529     }
5530 
5531     return E_OK;
5532 }
5533 
5534 #if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
5535 t_Handle FM_PCD_StatisticsSetNode(t_Handle h_FmPcd, t_FmPcdStatsParams *p_StatsParams)
5536 {
5537     t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
5538     t_FmPcdManip *p_Manip;
5539     t_Error err;
5540 
5541     SANITY_CHECK_RETURN_VALUE(h_FmPcd,E_INVALID_HANDLE,NULL);
5542     SANITY_CHECK_RETURN_VALUE(p_StatsParams,E_INVALID_HANDLE,NULL);
5543 
5544     p_Manip = ManipOrStatsSetNode(h_FmPcd, (t_Handle)p_StatsParams, TRUE);
5545     if (!p_Manip)
5546     return NULL;
5547 
5548     switch (p_Manip->opcode)
5549     {
5550         case (HMAN_OC_CAPWAP_INDEXED_STATS):
5551         /* Indexed statistics */
5552         err = IndxStats(p_StatsParams, p_Manip, p_FmPcd);
5553         break;
5554         default:
5555         REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("UNSUPPORTED Statistics type"));
5556         ReleaseManipHandler(p_Manip, p_FmPcd);
5557         XX_Free(p_Manip);
5558         return NULL;
5559     }
5560 
5561     if (err)
5562     {
5563         REPORT_ERROR(MAJOR, err, NO_MSG);
5564         ReleaseManipHandler(p_Manip, p_FmPcd);
5565         XX_Free(p_Manip);
5566         return NULL;
5567     }
5568 
5569     return p_Manip;
5570 }
5571 #endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */
5572