xref: /freebsd/sys/contrib/ncsw/Peripherals/FM/Pcd/fm_cc.c (revision ab00ac327a66a53edaac95b536b209db3ae2cd9f)
1 /* Copyright (c) 2008-2011 Freescale Semiconductor, Inc.
2  * All rights reserved.
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  @File          fm_cc.c
35 
36  @Description   FM CC ...
37 *//***************************************************************************/
38 #include "std_ext.h"
39 #include "error_ext.h"
40 #include "string_ext.h"
41 #include "debug_ext.h"
42 #include "fm_pcd_ext.h"
43 #include "fm_muram_ext.h"
44 
45 #include "fm_common.h"
46 #include "fm_hc.h"
47 #include "fm_cc.h"
48 
49 
50 #if defined(FM_CAPWAP_SUPPORT)
51 #define FM_PCD_CC_MANIP
52 #endif /* defined(FM_CAPWAP_SUPPORT) || ... */
53 
54 
55 t_Handle   FmPcdCcTreeGetSavedManipParams(t_Handle h_FmTree, uint8_t manipIndx)
56 {
57     t_FmPcdCcTree *p_FmPcdCcTree = (t_FmPcdCcTree *)h_FmTree;
58 
59     ASSERT_COND(p_FmPcdCcTree);
60 
61     return p_FmPcdCcTree->fmPcdCcSavedManipParams[manipIndx];
62 }
63 
64 void   FmPcdCcTreeSetSavedManipParams(t_Handle h_FmTree, t_Handle h_SavedManipParams, uint8_t   manipIndx)
65 {
66     t_FmPcdCcTree *p_FmPcdCcTree = (t_FmPcdCcTree *)h_FmTree;
67 
68     ASSERT_COND(p_FmPcdCcTree);
69 
70     p_FmPcdCcTree->fmPcdCcSavedManipParams[manipIndx] = h_SavedManipParams;
71 }
72 
73 uint8_t FmPcdCcGetParseCode(t_Handle h_CcNode)
74 {
75     t_FmPcdCcNode *p_FmPcdCcNode = (t_FmPcdCcNode *)h_CcNode;
76 
77     ASSERT_COND(p_FmPcdCcNode);
78     return p_FmPcdCcNode->parseCode;
79 }
80 
81 uint8_t FmPcdCcGetOffset(t_Handle h_CcNode)
82 {
83     t_FmPcdCcNode *p_FmPcdCcNode = (t_FmPcdCcNode *)h_CcNode;
84 
85     ASSERT_COND(p_FmPcdCcNode);
86     return p_FmPcdCcNode->offset;
87 }
88 
89 uint16_t FmPcdCcGetNumOfKeys(t_Handle h_CcNode)
90 {
91     t_FmPcdCcNode *p_FmPcdCcNode = (t_FmPcdCcNode *)h_CcNode;
92 
93     ASSERT_COND(p_FmPcdCcNode);
94     return p_FmPcdCcNode->numOfKeys;
95 }
96 static void EnqueueNodeInfoToRelevantLst(t_List *p_List, t_CcNodeInformation *p_CcInfo)
97 {
98     t_CcNodeInformation *p_CcInformation;
99     uint32_t            intFlags;
100 
101     p_CcInformation = (t_CcNodeInformation *)XX_Malloc(sizeof(t_CcNodeInformation));
102     if (p_CcInformation)
103     {
104         memset(p_CcInformation, 0, sizeof(t_CcNodeInformation));
105         memcpy(p_CcInformation, p_CcInfo, sizeof(t_CcNodeInformation));
106         INIT_LIST(&p_CcInformation->node);
107 
108         intFlags = XX_DisableAllIntr();
109         LIST_AddToTail(&p_CcInformation->node, p_List);
110         XX_RestoreAllIntr(intFlags);
111     }
112     else
113         REPORT_ERROR(MAJOR, E_NO_MEMORY, ("CC Node Information"));
114 }
115 
116 
117 static t_CcNodeInformation* FindNodeInfoInReleventLst(t_List *p_List, t_Handle h_Info)
118 {
119     t_CcNodeInformation *p_CcInformation;
120     t_List *p_Pos;
121     uint32_t            intFlags;
122 
123     intFlags = XX_DisableAllIntr();
124     for (p_Pos = NCSW_LIST_FIRST(p_List); p_Pos != (p_List); p_Pos = NCSW_LIST_NEXT(p_Pos))
125     {
126         p_CcInformation = CC_NODE_F_OBJECT(p_Pos);
127         ASSERT_COND(p_CcInformation->h_CcNode);
128         if(p_CcInformation->h_CcNode == h_Info)
129         {
130             XX_RestoreAllIntr(intFlags);
131             return p_CcInformation;
132         }
133     }
134     XX_RestoreAllIntr(intFlags);
135     return NULL;
136 }
137 
138 static void DequeueNodeInfoFromRelevantLst(t_List *p_List, t_Handle h_Info)
139 {
140     t_CcNodeInformation *p_CcInformation = NULL;
141     uint32_t            intFlags;
142     t_List              *p_Pos;
143 
144     intFlags = XX_DisableAllIntr();
145     if (LIST_IsEmpty(p_List))
146     {
147         XX_RestoreAllIntr(intFlags);
148         return;
149     }
150 
151     for (p_Pos = NCSW_LIST_FIRST(p_List); p_Pos != (p_List); p_Pos = NCSW_LIST_NEXT(p_Pos))
152     {
153         p_CcInformation = CC_NODE_F_OBJECT(p_Pos);
154         ASSERT_COND(p_CcInformation->h_CcNode);
155         if (p_CcInformation->h_CcNode == h_Info)
156             break;
157     }
158     if (p_CcInformation)
159         LIST_DelAndInit(&p_CcInformation->node);
160     XX_RestoreAllIntr(intFlags);
161 }
162 
163 static t_Error FmPcdCcSetRequiredAction(t_Handle h_FmPcd, uint32_t requiredAction, t_FmPcdCcNextEngineAndRequiredActionParams *p_CcNextEngineParamsTmp,
164                                         t_Handle h_AdTmp, uint16_t numOfEntries, t_Handle h_Tree)
165 {
166 
167     t_AdOfTypeResult    *p_AdTmp = (t_AdOfTypeResult *)h_AdTmp;
168     uint32_t            tmpReg32;
169     t_Error             err;
170     t_FmPcdCcNode       *p_FmPcdCcNode;
171     int                 i = 0;
172     uint16_t            tmp = 0;
173     uint16_t            profileId;
174     uint8_t             relativeSchemeId, physicalSchemeId;
175     t_CcNodeInformation ccNodeInfo;
176 
177      for(i = 0; i < numOfEntries; i++)
178      {
179         if(i == 0)
180             h_AdTmp = PTR_MOVE(h_AdTmp, i*FM_PCD_CC_AD_ENTRY_SIZE);
181         else
182             h_AdTmp = PTR_MOVE(h_AdTmp, FM_PCD_CC_AD_ENTRY_SIZE);
183 
184         if(p_CcNextEngineParamsTmp[i].shadowAction & requiredAction)
185             continue;
186         switch(p_CcNextEngineParamsTmp[i].nextEngineParams.nextEngine)
187         {
188             case(e_FM_PCD_CC):
189                 if(requiredAction)
190                 {
191                     p_FmPcdCcNode = p_CcNextEngineParamsTmp[i].nextEngineParams.params.ccParams.h_CcNode;
192                     ASSERT_COND(p_FmPcdCcNode);
193                     if(p_FmPcdCcNode->shadowAction == requiredAction)
194                         break;
195                     if((requiredAction & UPDATE_CC_WITH_TREE) && !(p_FmPcdCcNode->shadowAction & UPDATE_CC_WITH_TREE))
196                     {
197 
198                         ASSERT_COND(LIST_NumOfObjs(&p_FmPcdCcNode->ccTreesLst) == 0);
199                         if(p_FmPcdCcNode->shadowAction & UPDATE_CC_WITH_DELETE_TREE)
200                             p_FmPcdCcNode->shadowAction &= ~UPDATE_CC_WITH_DELETE_TREE;
201                         memset(&ccNodeInfo, 0, sizeof(t_CcNodeInformation));
202                         ccNodeInfo.h_CcNode = h_Tree;
203                         EnqueueNodeInfoToRelevantLst(&p_FmPcdCcNode->ccTreesLst, &ccNodeInfo);
204                         p_CcNextEngineParamsTmp[i].shadowAction |= UPDATE_CC_WITH_TREE;
205                     }
206                     if((requiredAction & UPDATE_CC_WITH_DELETE_TREE) && !(p_FmPcdCcNode->shadowAction & UPDATE_CC_WITH_DELETE_TREE))
207                     {
208                         ASSERT_COND(LIST_NumOfObjs(&p_FmPcdCcNode->ccTreesLst) == 1);
209                         if(p_FmPcdCcNode->shadowAction & UPDATE_CC_WITH_TREE)
210                             p_FmPcdCcNode->shadowAction &= ~UPDATE_CC_WITH_TREE;
211                         DequeueNodeInfoFromRelevantLst(&p_FmPcdCcNode->ccTreesLst, h_Tree);
212                         p_CcNextEngineParamsTmp[i].shadowAction |= UPDATE_CC_WITH_DELETE_TREE;
213                     }
214                     if(p_FmPcdCcNode->nextEngineAndRequiredAction[p_FmPcdCcNode->numOfKeys].nextEngineParams.nextEngine != e_FM_PCD_INVALID)
215                         tmp  = (uint8_t)(p_FmPcdCcNode->numOfKeys + 1);
216                     else
217                         tmp = p_FmPcdCcNode->numOfKeys;
218                     err = FmPcdCcSetRequiredAction(h_FmPcd, requiredAction, p_FmPcdCcNode->nextEngineAndRequiredAction, p_FmPcdCcNode->h_AdTable, tmp, h_Tree);
219                     if(err != E_OK)
220                         return err;
221                     p_FmPcdCcNode->shadowAction |= requiredAction;
222                 }
223                 break;
224 
225             case(e_FM_PCD_KG):
226                 if((requiredAction & UPDATE_NIA_ENQ_WITHOUT_DMA) && !(p_CcNextEngineParamsTmp[i].shadowAction & UPDATE_NIA_ENQ_WITHOUT_DMA))
227                 {
228                     physicalSchemeId = (uint8_t)(PTR_TO_UINT(p_CcNextEngineParamsTmp[i].nextEngineParams.params.kgParams.h_DirectScheme)-1);
229                     relativeSchemeId = FmPcdKgGetRelativeSchemeId(h_FmPcd, physicalSchemeId);
230                     if(relativeSchemeId == FM_PCD_KG_NUM_OF_SCHEMES)
231                         RETURN_ERROR(MAJOR, E_NOT_IN_RANGE, NO_MSG);
232                     if (!FmPcdKgIsSchemeValidSw(h_FmPcd, relativeSchemeId))
233                          RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid direct scheme."));
234                     if(!KgIsSchemeAlwaysDirect(h_FmPcd, relativeSchemeId))
235                         RETURN_ERROR(MAJOR, E_INVALID_STATE, ("For this action scheme has to be direct."));
236                     err = FmPcdKgCcGetSetParams(h_FmPcd, p_CcNextEngineParamsTmp[i].nextEngineParams.params.kgParams.h_DirectScheme, requiredAction);
237                     if(err != E_OK)
238                         RETURN_ERROR(MAJOR, err, NO_MSG);
239                     p_CcNextEngineParamsTmp[i].shadowAction |= requiredAction;
240                 }
241                 break;
242 
243             case(e_FM_PCD_PLCR):
244                 if((requiredAction & UPDATE_NIA_ENQ_WITHOUT_DMA) && !(p_CcNextEngineParamsTmp[i].shadowAction & UPDATE_NIA_ENQ_WITHOUT_DMA))
245                 {
246                     if(!p_CcNextEngineParamsTmp[i].nextEngineParams.params.plcrParams.overrideParams)
247                         RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("In this intialization only overrideFqid can be intiizliaes"));
248                     if(!p_CcNextEngineParamsTmp[i].nextEngineParams.params.plcrParams.sharedProfile)
249                         RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("In this intialization only overrideFqid can be intiizliaes"));
250                     err =  FmPcdPlcrGetAbsoluteProfileId(h_FmPcd, e_FM_PCD_PLCR_SHARED, NULL, p_CcNextEngineParamsTmp[i].nextEngineParams.params.plcrParams.newRelativeProfileId, &profileId);
251                     if(err!= E_OK)
252                         RETURN_ERROR(MAJOR, err, NO_MSG);
253                     err = FmPcdPlcrCcGetSetParams(h_FmPcd, profileId, requiredAction);
254                     if(err != E_OK)
255                         RETURN_ERROR(MAJOR, err, NO_MSG);
256                     p_CcNextEngineParamsTmp[i].shadowAction |= requiredAction;
257                 }
258                 break;
259 
260             case(e_FM_PCD_DONE):
261                 if((requiredAction & UPDATE_NIA_ENQ_WITHOUT_DMA) && !(p_CcNextEngineParamsTmp[i].shadowAction & UPDATE_NIA_ENQ_WITHOUT_DMA))
262                 {
263                     tmpReg32 = GET_UINT32(p_AdTmp->nia);
264                     if((tmpReg32 & (NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME)) != (NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME))
265                         RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Next engine was previosely assigned not as PCD_DONE"));
266                     tmpReg32 |= NIA_BMI_AC_ENQ_FRAME_WITHOUT_DMA;
267                     WRITE_UINT32(p_AdTmp->nia, tmpReg32);
268                     p_CcNextEngineParamsTmp[i].shadowAction |= requiredAction;
269                 }
270                 break;
271 
272             default:
273                 break;
274         }
275      }
276 
277      return E_OK;
278 }
279 
280 static t_Error CcUpdateParam(t_Handle                                   h_FmPcd,
281                              t_Handle                                   h_FmPort,
282                              t_FmPcdCcNextEngineAndRequiredActionParams *p_CcNextEngineParams,
283                              uint16_t                                   numOfEntries,
284                              t_Handle                                   h_Ad,
285                              bool                                       validate,
286                              uint16_t                                   level,
287                              t_Handle                                   h_FmTree,
288                              bool                                       modify)
289 {
290     t_CcNodeInformation *p_CcNodeInfo;
291     t_FmPcdCcNode       *p_FmPcdCcNode;
292     t_Error             err;
293     uint16_t            tmp = 0;
294     int                 i = 0;
295 
296     level++;
297 
298     if(numOfEntries)
299     {
300         for(i = 0; i < numOfEntries; i++)
301         {
302             if(i == 0)
303                 h_Ad = PTR_MOVE(h_Ad, i*FM_PCD_CC_AD_ENTRY_SIZE);
304             else
305                 h_Ad = PTR_MOVE(h_Ad, FM_PCD_CC_AD_ENTRY_SIZE);
306 
307             if(p_CcNextEngineParams[i].nextEngineParams.nextEngine == e_FM_PCD_CC)
308             {
309                 p_FmPcdCcNode = p_CcNextEngineParams[i].nextEngineParams.params.ccParams.h_CcNode;
310                 ASSERT_COND(p_FmPcdCcNode);
311                 p_CcNodeInfo = FindNodeInfoInReleventLst(&p_FmPcdCcNode->ccTreesLst,h_FmTree);
312                 ASSERT_COND(p_CcNodeInfo);
313                 p_CcNodeInfo->index = level;
314 #ifdef FM_PCD_CC_MANIP
315                 if(p_CcNextEngineParams[i].nextEngineParams.h_Manip)
316                 {
317                     err = FmPcdManipUpdate(h_FmPcd, h_FmPort, p_CcNextEngineParams[i].nextEngineParams.h_Manip, h_Ad, validate, p_CcNodeInfo->index, h_FmTree, modify);
318                     if(err)
319                         RETURN_ERROR(MAJOR, err, NO_MSG);
320                 }
321 #endif /* FM_PCD_CC_MANIP */
322 
323                 if(p_FmPcdCcNode->nextEngineAndRequiredAction[p_FmPcdCcNode->numOfKeys].nextEngineParams.nextEngine != e_FM_PCD_INVALID)
324                     tmp  = (uint8_t)(p_FmPcdCcNode->numOfKeys + 1);
325                 else
326                     tmp = p_FmPcdCcNode->numOfKeys;
327 
328                 err = CcUpdateParam(h_FmPcd, h_FmPort, p_FmPcdCcNode->nextEngineAndRequiredAction, tmp, p_FmPcdCcNode->h_AdTable, validate,level, h_FmTree, modify);
329                 if(err)
330                     RETURN_ERROR(MAJOR, err, NO_MSG);
331             }
332 #ifdef FM_PCD_CC_MANIP
333             else
334             {
335                 if(p_CcNextEngineParams[i].nextEngineParams.h_Manip)
336                 {
337                     err = FmPcdManipUpdate(h_FmPcd, h_FmPort, p_CcNextEngineParams[i].nextEngineParams.h_Manip, h_Ad, validate, level,h_FmTree, modify);
338                     if(err)
339                         RETURN_ERROR(MAJOR, err, NO_MSG);
340                 }
341             }
342 #endif /* FM_PCD_CC_MANIP */
343           }
344     }
345 
346     return E_OK;
347 }
348 static bool IsNodeInModifiedState(t_Handle h_CcNode)
349 {
350     t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode;
351 
352     ASSERT_COND(p_CcNode);
353 
354     return p_CcNode->modifiedState;
355 }
356 
357 static void UpdateNodeWithModifiedState(t_Handle h_CcNode, bool modifiedState)
358 {
359     t_FmPcdCcNode *p_FmPcdCcNode = (t_FmPcdCcNode *)h_CcNode;
360 
361     ASSERT_COND(p_FmPcdCcNode);
362 
363     p_FmPcdCcNode->modifiedState = modifiedState;
364 }
365 
366 static ccPrivateInfo_t IcDefineCode(t_FmPcdCcNodeParams *p_CcNodeParam)
367 {
368     switch (p_CcNodeParam->extractCcParams.extractNonHdr.action)
369     {
370         case(e_FM_PCD_ACTION_EXACT_MATCH):
371             switch(p_CcNodeParam->extractCcParams.extractNonHdr.src)
372             {
373                 case(e_FM_PCD_EXTRACT_FROM_KEY):
374                     return CC_PRIVATE_INFO_IC_KEY_EXACT_MATCH;
375                 case(e_FM_PCD_EXTRACT_FROM_HASH):
376                     return CC_PRIVATE_INFO_IC_HASH_EXACT_MATCH;
377                 default:
378                     return CC_PRIVATE_INFO_NONE;
379             }
380         case(e_FM_PCD_ACTION_INDEXED_LOOKUP):
381             switch(p_CcNodeParam->extractCcParams.extractNonHdr.src)
382             {
383                 case(e_FM_PCD_EXTRACT_FROM_HASH):
384                     return CC_PRIVATE_INFO_IC_HASH_INDEX_LOOKUP;
385                 case(e_FM_PCD_EXTRACT_FROM_FLOW_ID):
386                     return CC_PRIVATE_INFO_IC_DEQ_FQID_INDEX_LOOKUP;
387                 default:
388                   return  CC_PRIVATE_INFO_NONE;
389             }
390        default:
391            break;
392     }
393     return CC_PRIVATE_INFO_NONE;
394 }
395 
396 static t_CcNodeInformation * DequeueAdditionalInfoFromRelevantLst(t_List *p_List)
397 {
398     t_CcNodeInformation   *p_CcNodeInfo = NULL;
399     uint32_t        intFlags;
400 
401     intFlags = XX_DisableAllIntr();
402     if (!LIST_IsEmpty(p_List))
403     {
404         p_CcNodeInfo = CC_NODE_F_OBJECT(p_List->p_Next);
405         LIST_DelAndInit(&p_CcNodeInfo->node);
406     }
407     XX_RestoreAllIntr(intFlags);
408     return p_CcNodeInfo;
409 }
410 
411 static void ReleaseLst(t_List *p_List)
412 {
413     t_CcNodeInformation   *p_CcNodeInfo = NULL;
414 
415     if(!LIST_IsEmpty(p_List))
416     {
417         p_CcNodeInfo = DequeueAdditionalInfoFromRelevantLst(p_List);
418         while (p_CcNodeInfo)
419         {
420             XX_Free(p_CcNodeInfo);
421             p_CcNodeInfo = DequeueAdditionalInfoFromRelevantLst(p_List);
422         }
423     }
424     LIST_DelAndInit(p_List);
425 }
426 
427 void FmPcdCcTreeReleaseLock(t_Handle h_FmPcdCcTree)
428 {
429     RELEASE_LOCK(((t_FmPcdCcTree *)h_FmPcdCcTree)->lock);
430 }
431 
432 void FmPcdCcNodeTreeReleaseLock(t_List *p_List)
433 {
434     t_List              *p_Pos;
435     t_CcNodeInformation *p_CcNodeInfo;
436     t_Handle            h_FmPcdCcTree;
437 
438     LIST_FOR_EACH(p_Pos, p_List)
439     {
440         p_CcNodeInfo = CC_NODE_F_OBJECT(p_Pos);
441         h_FmPcdCcTree = p_CcNodeInfo->h_CcNode;
442         FmPcdCcTreeReleaseLock(h_FmPcdCcTree);
443     }
444     ReleaseLst(p_List);
445 }
446 
447 static void DeleteNode(t_FmPcdCcNode *p_FmPcdCcNode)
448 {
449     if(p_FmPcdCcNode)
450     {
451         if(p_FmPcdCcNode->p_GlblMask)
452         {
453             XX_Free(p_FmPcdCcNode->p_GlblMask);
454             p_FmPcdCcNode->p_GlblMask = NULL;
455         }
456         if(p_FmPcdCcNode->h_KeysMatchTable)
457         {
458             FM_MURAM_FreeMem(FmPcdGetMuramHandle(p_FmPcdCcNode->h_FmPcd), p_FmPcdCcNode->h_KeysMatchTable);
459             p_FmPcdCcNode->h_KeysMatchTable = NULL;
460         }
461         if(p_FmPcdCcNode->h_AdTable)
462         {
463             FM_MURAM_FreeMem(FmPcdGetMuramHandle(p_FmPcdCcNode->h_FmPcd), p_FmPcdCcNode->h_AdTable);
464             p_FmPcdCcNode->h_AdTable = NULL;
465         }
466 
467         ReleaseLst(&p_FmPcdCcNode->ccPrevNodesLst);
468         ReleaseLst(&p_FmPcdCcNode->ccTreeIdLst);
469         ReleaseLst(&p_FmPcdCcNode->ccTreesLst);
470 
471         XX_Free(p_FmPcdCcNode);
472     }
473 }
474 
475 static void DeleteTree(t_FmPcdCcTree *p_FmPcdTree, t_FmPcd *p_FmPcd)
476 {
477     if(p_FmPcdTree)
478     {
479         if(p_FmPcdTree->ccTreeBaseAddr)
480         {
481             FM_MURAM_FreeMem(FmPcdGetMuramHandle(p_FmPcd), UINT_TO_PTR(p_FmPcdTree->ccTreeBaseAddr));
482             p_FmPcdTree->ccTreeBaseAddr = 0;
483         }
484 
485         ReleaseLst(&p_FmPcdTree->fmPortsLst);
486 
487         XX_Free(p_FmPcdTree);
488     }
489 }
490 
491 static void  UpdateNodeOwner(t_FmPcdCcNode *p_FmPcdCcNode, bool add)
492 {
493     ASSERT_COND(p_FmPcdCcNode);
494 
495     if(add)
496         p_FmPcdCcNode->owners++;
497     else
498     {
499         ASSERT_COND(p_FmPcdCcNode->owners);
500         p_FmPcdCcNode->owners--;
501     }
502 }
503 
504 static void  GetCcExtractKeySize(uint8_t parseCodeRealSize, uint8_t *parseCodeCcSize)
505 {
506     if((parseCodeRealSize > 0) && (parseCodeRealSize < 2))
507         *parseCodeCcSize = 1;
508     else if(parseCodeRealSize == 2)
509         *parseCodeCcSize = 2;
510     else if((parseCodeRealSize > 2)    && (parseCodeRealSize <= 4))
511         *parseCodeCcSize = 4;
512     else if((parseCodeRealSize > 4)    && (parseCodeRealSize <= 8))
513         *parseCodeCcSize = 8;
514     else if((parseCodeRealSize > 8)    && (parseCodeRealSize <= 16))
515         *parseCodeCcSize = 16;
516     else if((parseCodeRealSize  > 16)  && (parseCodeRealSize <= 24))
517         *parseCodeCcSize = 24;
518     else if((parseCodeRealSize  > 24)  && (parseCodeRealSize <= 32))
519         *parseCodeCcSize = 32;
520     else if((parseCodeRealSize  > 32)  && (parseCodeRealSize <= 40))
521         *parseCodeCcSize = 40;
522     else if((parseCodeRealSize  > 40)  && (parseCodeRealSize <= 48))
523         *parseCodeCcSize = 48;
524     else if((parseCodeRealSize  > 48)  && (parseCodeRealSize <= 56))
525         *parseCodeCcSize = 56;
526     else
527         *parseCodeCcSize = 0;
528 }
529 
530 static void  GetSizeHeaderField(e_NetHeaderType hdr,t_FmPcdFields field,uint8_t *parseCodeRealSize)
531 {
532     switch(hdr)
533     {
534         case (HEADER_TYPE_ETH):
535             switch(field.eth)
536             {
537                 case(NET_HEADER_FIELD_ETH_DA):
538                     *parseCodeRealSize = 6;
539                     break;
540                 case(NET_HEADER_FIELD_ETH_SA):
541                     *parseCodeRealSize = 6;
542                     break;
543                 case(NET_HEADER_FIELD_ETH_TYPE):
544                     *parseCodeRealSize = 2;
545                     break;
546                 default:
547                     REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported1"));
548                     *parseCodeRealSize = CC_SIZE_ILLEGAL;
549                     break;
550             }
551             break;
552         case(HEADER_TYPE_PPPoE):
553             switch(field.pppoe)
554             {
555                 case(NET_HEADER_FIELD_PPPoE_PID):
556                     *parseCodeRealSize = 2;
557                     break;
558                 default:
559                     REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported1"));
560                     *parseCodeRealSize = CC_SIZE_ILLEGAL;
561                     break;
562             }
563             break;
564         case (HEADER_TYPE_VLAN):
565             switch(field.vlan)
566             {
567                case(NET_HEADER_FIELD_VLAN_TCI):
568                     *parseCodeRealSize = 2;
569                     break;
570                 default:
571                     REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported2"));
572                     *parseCodeRealSize = CC_SIZE_ILLEGAL;
573                     break;
574             }
575             break;
576         case (HEADER_TYPE_MPLS):
577             switch(field.mpls)
578             {
579                 case(NET_HEADER_FIELD_MPLS_LABEL_STACK):
580                     *parseCodeRealSize = 4;
581                     break;
582                 default:
583                     REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported3"));
584                     *parseCodeRealSize = CC_SIZE_ILLEGAL;
585                     break;
586             }
587             break;
588         case (HEADER_TYPE_IPv4):
589             switch(field.ipv4)
590             {
591                 case(NET_HEADER_FIELD_IPv4_DST_IP):
592                 case(NET_HEADER_FIELD_IPv4_SRC_IP):
593                     *parseCodeRealSize = 4;
594                     break;
595                 case(NET_HEADER_FIELD_IPv4_TOS):
596                 case(NET_HEADER_FIELD_IPv4_PROTO):
597                     *parseCodeRealSize = 1;
598                     break;
599                 case(NET_HEADER_FIELD_IPv4_DST_IP | NET_HEADER_FIELD_IPv4_SRC_IP):
600                     *parseCodeRealSize = 8;
601                     break;
602                 case(NET_HEADER_FIELD_IPv4_TTL):
603                     *parseCodeRealSize = 1;
604                     break;
605                 default:
606                     REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported4"));
607                     *parseCodeRealSize = CC_SIZE_ILLEGAL;
608                     break;
609             }
610             break;
611         case (HEADER_TYPE_IPv6):
612             switch(field.ipv6)
613             {
614                 case(NET_HEADER_FIELD_IPv6_VER | NET_HEADER_FIELD_IPv6_FL | NET_HEADER_FIELD_IPv6_TC):
615                    *parseCodeRealSize = 4;
616                     break;
617                 case(NET_HEADER_FIELD_IPv6_NEXT_HDR):
618                 case(NET_HEADER_FIELD_IPv6_HOP_LIMIT):
619                    *parseCodeRealSize = 1;
620                     break;
621                 case(NET_HEADER_FIELD_IPv6_DST_IP):
622                 case(NET_HEADER_FIELD_IPv6_SRC_IP):
623                    *parseCodeRealSize = 16;
624                     break;
625                 default:
626                     REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported5"));
627                     *parseCodeRealSize = CC_SIZE_ILLEGAL;
628                     break;
629             }
630             break;
631         case (HEADER_TYPE_GRE):
632             switch(field.gre)
633             {
634                 case(NET_HEADER_FIELD_GRE_TYPE):
635                    *parseCodeRealSize = 2;
636                     break;
637                 default:
638                     REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported6"));
639                     *parseCodeRealSize = CC_SIZE_ILLEGAL;
640                     break;
641             }
642             break;
643         case (HEADER_TYPE_MINENCAP):
644             switch(field.minencap)
645             {
646                 case(NET_HEADER_FIELD_MINENCAP_TYPE):
647                    *parseCodeRealSize = 1;
648                     break;
649                 case(NET_HEADER_FIELD_MINENCAP_DST_IP):
650                  case(NET_HEADER_FIELD_MINENCAP_SRC_IP):
651                   *parseCodeRealSize = 4;
652                     break;
653                  case(NET_HEADER_FIELD_MINENCAP_SRC_IP | NET_HEADER_FIELD_MINENCAP_DST_IP):
654                   *parseCodeRealSize = 8;
655                     break;
656                 default:
657                     REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported7"));
658                     *parseCodeRealSize = CC_SIZE_ILLEGAL;
659                     break;
660             }
661             break;
662         case (HEADER_TYPE_TCP):
663             switch(field.tcp)
664             {
665                 case(NET_HEADER_FIELD_TCP_PORT_SRC):
666                 case(NET_HEADER_FIELD_TCP_PORT_DST):
667                    *parseCodeRealSize = 2;
668                     break;
669                  case(NET_HEADER_FIELD_TCP_PORT_SRC | NET_HEADER_FIELD_TCP_PORT_DST):
670                   *parseCodeRealSize = 4;
671                     break;
672                 default:
673                     REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported8"));
674                     *parseCodeRealSize = CC_SIZE_ILLEGAL;
675                     break;
676             }
677             break;
678         case (HEADER_TYPE_UDP):
679             switch(field.udp)
680             {
681                 case(NET_HEADER_FIELD_UDP_PORT_SRC):
682                 case(NET_HEADER_FIELD_UDP_PORT_DST):
683                    *parseCodeRealSize = 2;
684                     break;
685                  case(NET_HEADER_FIELD_UDP_PORT_SRC | NET_HEADER_FIELD_UDP_PORT_DST):
686                   *parseCodeRealSize = 4;
687                     break;
688                 default:
689                     REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported9"));
690                     *parseCodeRealSize = CC_SIZE_ILLEGAL;
691                     break;
692             }
693             break;
694        default:
695             REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported10"));
696             *parseCodeRealSize = CC_SIZE_ILLEGAL;
697             break;
698     }
699 }
700 
701 static t_Error ValidateNextEngineParams(t_Handle h_FmPcd, t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams)
702 {
703     uint16_t                    absoluteProfileId;
704     t_Error                     err = E_OK;
705     uint8_t                     relativeSchemeId;
706 
707     switch(p_FmPcdCcNextEngineParams->nextEngine)
708     {
709          case(e_FM_PCD_INVALID):
710              err = E_NOT_SUPPORTED;
711              break;
712          case(e_FM_PCD_DONE):
713              if(p_FmPcdCcNextEngineParams->params.enqueueParams.action == e_FM_PCD_ENQ_FRAME)
714              {
715                  if(p_FmPcdCcNextEngineParams->params.enqueueParams.overrideFqid &&
716                          !p_FmPcdCcNextEngineParams->params.enqueueParams.newFqid)
717                      RETURN_ERROR(MAJOR, E_INVALID_STATE, ("not defined fqid for control flow for BMI next engine "));
718                  if(p_FmPcdCcNextEngineParams->params.enqueueParams.newFqid & ~0x00FFFFFF)
719                      RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fqidForCtrlFlow must be between 1 and 2^24-1"));
720              }
721             break;
722         case(e_FM_PCD_KG):
723             relativeSchemeId = FmPcdKgGetRelativeSchemeId(h_FmPcd, (uint8_t)(PTR_TO_UINT(p_FmPcdCcNextEngineParams->params.kgParams.h_DirectScheme)-1));
724             if(relativeSchemeId == FM_PCD_KG_NUM_OF_SCHEMES)
725                 RETURN_ERROR(MAJOR, E_NOT_IN_RANGE, NO_MSG);
726 
727             if(!FmPcdKgIsSchemeValidSw(h_FmPcd, relativeSchemeId))
728                 RETURN_ERROR(MAJOR, E_INVALID_STATE, ("not valid schemeIndex in KG next engine param"));
729             if(!KgIsSchemeAlwaysDirect(h_FmPcd, relativeSchemeId))
730                 RETURN_ERROR(MAJOR, E_INVALID_STATE, ("CC Node may point only to a scheme that is always direct."));
731             break;
732         case(e_FM_PCD_PLCR):
733             if(p_FmPcdCcNextEngineParams->params.plcrParams.overrideParams)
734             {
735                 /* if private policer profile, it may be uninitialized yet, therefor no checks are done at this stage */
736                 if(p_FmPcdCcNextEngineParams->params.plcrParams.sharedProfile)
737                 {
738                     err = FmPcdPlcrGetAbsoluteProfileId(h_FmPcd,e_FM_PCD_PLCR_SHARED,NULL,p_FmPcdCcNextEngineParams->params.plcrParams.newRelativeProfileId, &absoluteProfileId);
739                     if(err)
740                         RETURN_ERROR(MAJOR, err, ("Shared profile offset is out of range"));
741                     if(!FmPcdPlcrIsProfileValid(h_FmPcd, absoluteProfileId))
742                         RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid profile"));
743                 }
744                 else
745                 {
746                 }
747                 /* TODO - add check according to the revision of the chip.
748                 if(!p_FmPcdCcNextEngineParams->params.plcrParams.newFqid ||
749                    (p_FmPcdCcNextEngineParams->params.plcrParams.newFqid & ~0x00FFFFFF))
750                     RETURN_ERROR(MAJOR, E_INVALID_STATE, ("newFqid  must be between 1 and 2^24-1"));
751                 */
752             }
753             break;
754         case(e_FM_PCD_CC):
755             if(!p_FmPcdCcNextEngineParams->params.ccParams.h_CcNode)
756                 RETURN_ERROR(MAJOR, E_NULL_POINTER, ("handler to next Node is NULL"));
757             break;
758         default:
759             RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Next engine is not correct"));
760     }
761     return err;
762 }
763 
764 static uint8_t GetGenParseCode(e_FmPcdExtractFrom src, uint32_t offset, bool glblMask, uint8_t *parseArrayOffset, bool fromIc, ccPrivateInfo_t icCode)
765 {
766     if(!fromIc)
767     {
768         switch(src)
769         {
770             case(e_FM_PCD_EXTRACT_FROM_FRAME_START):
771                 if(glblMask)
772                     return CC_PC_GENERIC_WITH_MASK ;
773                 else
774                   return CC_PC_GENERIC_WITHOUT_MASK;
775             case(e_FM_PCD_EXTRACT_FROM_CURR_END_OF_PARSE):
776                 *parseArrayOffset = CC_PC_PR_NEXT_HEADER_OFFSET;
777                 if(offset)
778                     return CC_PR_OFFSET;
779                 else
780                     return CC_PR_WITHOUT_OFFSET;
781             default:
782                 REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal 'extract from' src"));
783                 return CC_PC_ILLEGAL;
784         }
785     }
786     else
787     {
788         switch (icCode)
789         {
790             case(CC_PRIVATE_INFO_IC_KEY_EXACT_MATCH):
791                  *parseArrayOffset = 0x50;
792                  return CC_PC_GENERIC_IC_GMASK;
793             case(CC_PRIVATE_INFO_IC_HASH_EXACT_MATCH):
794                *parseArrayOffset = 0x48;
795                return CC_PC_GENERIC_IC_GMASK;
796             case(CC_PRIVATE_INFO_IC_HASH_INDEX_LOOKUP):
797                 *parseArrayOffset = 0x48;
798                  return CC_PC_GENERIC_IC_HASH_INDEXED;
799             case(CC_PRIVATE_INFO_IC_DEQ_FQID_INDEX_LOOKUP):
800                 *parseArrayOffset = 0x16;
801                  return CC_PC_GENERIC_IC_HASH_INDEXED;
802             default:
803                 REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal 'extract from' src"));
804                 break;
805         }
806     }
807     return CC_PC_ILLEGAL;
808 }
809 
810 static uint8_t GetFullFieldParseCode(e_NetHeaderType hdr, e_FmPcdHdrIndex index, t_FmPcdFields field)
811 {
812 
813       switch(hdr)
814         {
815             case(HEADER_TYPE_NONE):
816                 ASSERT_COND(FALSE);
817                 return CC_PC_ILLEGAL;
818 
819        case(HEADER_TYPE_ETH):
820                 switch(field.eth)
821                 {
822                     case(NET_HEADER_FIELD_ETH_DA):
823                         return CC_PC_FF_MACDST;
824                     case(NET_HEADER_FIELD_ETH_SA):
825                          return CC_PC_FF_MACSRC;
826                     case(NET_HEADER_FIELD_ETH_TYPE):
827                          return CC_PC_FF_ETYPE;
828                     default:
829                         REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
830                         return CC_PC_ILLEGAL;
831                 }
832 
833          case(HEADER_TYPE_VLAN):
834             switch(field.vlan)
835             {
836                 case(NET_HEADER_FIELD_VLAN_TCI):
837                     if((index == e_FM_PCD_HDR_INDEX_NONE) || (index == e_FM_PCD_HDR_INDEX_1))
838                         return CC_PC_FF_TCI1;
839                     if(index == e_FM_PCD_HDR_INDEX_LAST)
840                         return CC_PC_FF_TCI2;
841                     REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
842                     return CC_PC_ILLEGAL;
843                 default:
844                         REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
845                         return CC_PC_ILLEGAL;
846             }
847 
848         case(HEADER_TYPE_MPLS):
849             switch(field.mpls)
850             {
851                 case(NET_HEADER_FIELD_MPLS_LABEL_STACK):
852                     if((index == e_FM_PCD_HDR_INDEX_NONE) || (index == e_FM_PCD_HDR_INDEX_1))
853                         return CC_PC_FF_MPLS1;
854                     if(index == e_FM_PCD_HDR_INDEX_LAST)
855                         return CC_PC_FF_MPLS_LAST;
856                     REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal MPLS index"));
857                     return CC_PC_ILLEGAL;
858                default:
859                     REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
860                     return CC_PC_ILLEGAL;
861              }
862 
863         case(HEADER_TYPE_IPv4):
864             switch(field.ipv4)
865             {
866                 case(NET_HEADER_FIELD_IPv4_DST_IP):
867                     if((index == e_FM_PCD_HDR_INDEX_NONE) || (index == e_FM_PCD_HDR_INDEX_1))
868                         return CC_PC_FF_IPV4DST1;
869                     if(index == e_FM_PCD_HDR_INDEX_2)
870                         return CC_PC_FF_IPV4DST2;
871                     REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv4 index"));
872                     return CC_PC_ILLEGAL;
873                 case(NET_HEADER_FIELD_IPv4_TOS):
874                     if((index == e_FM_PCD_HDR_INDEX_NONE) || (index == e_FM_PCD_HDR_INDEX_1))
875                         return CC_PC_FF_IPV4IPTOS_TC1;
876                     if(index == e_FM_PCD_HDR_INDEX_2)
877                         return CC_PC_FF_IPV4IPTOS_TC2;
878                     REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv4 index"));
879                     return CC_PC_ILLEGAL;
880                 case(NET_HEADER_FIELD_IPv4_PROTO):
881                     if((index == e_FM_PCD_HDR_INDEX_NONE) || (index == e_FM_PCD_HDR_INDEX_1))
882                         return CC_PC_FF_IPV4PTYPE1;
883                     if(index == e_FM_PCD_HDR_INDEX_2)
884                         return CC_PC_FF_IPV4PTYPE2;
885                     REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv4 index"));
886                     return CC_PC_ILLEGAL;
887                 case(NET_HEADER_FIELD_IPv4_SRC_IP):
888                     if((index == e_FM_PCD_HDR_INDEX_NONE) || (index == e_FM_PCD_HDR_INDEX_1))
889                         return CC_PC_FF_IPV4SRC1;
890                     if(index == e_FM_PCD_HDR_INDEX_2)
891                         return CC_PC_FF_IPV4SRC2;
892                     REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv4 index"));
893                     return CC_PC_ILLEGAL;
894                 case(NET_HEADER_FIELD_IPv4_SRC_IP | NET_HEADER_FIELD_IPv4_DST_IP):
895                     if((index == e_FM_PCD_HDR_INDEX_NONE) || (index == e_FM_PCD_HDR_INDEX_1))
896                         return CC_PC_FF_IPV4SRC1_IPV4DST1;
897                     if(index == e_FM_PCD_HDR_INDEX_2)
898                         return CC_PC_FF_IPV4SRC2_IPV4DST2;
899                     REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv4 index"));
900                     return CC_PC_ILLEGAL;
901                 case(NET_HEADER_FIELD_IPv4_TTL):
902                     return CC_PC_FF_IPV4TTL;
903                 default:
904                     REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
905                     return CC_PC_ILLEGAL;
906             }
907 
908         case(HEADER_TYPE_IPv6):
909              switch(field.ipv6)
910             {
911                 case(NET_HEADER_FIELD_IPv6_VER | NET_HEADER_FIELD_IPv6_FL | NET_HEADER_FIELD_IPv6_TC):
912                     if((index == e_FM_PCD_HDR_INDEX_NONE) || (index == e_FM_PCD_HDR_INDEX_1))
913                         return CC_PC_FF_IPTOS_IPV6TC1_IPV6FLOW1;
914                     if(index == e_FM_PCD_HDR_INDEX_2)
915                         return CC_PC_FF_IPTOS_IPV6TC2_IPV6FLOW2;
916                     REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv6 index"));
917                     return CC_PC_ILLEGAL;
918                 case(NET_HEADER_FIELD_IPv6_NEXT_HDR):
919                     if((index == e_FM_PCD_HDR_INDEX_NONE) || (index == e_FM_PCD_HDR_INDEX_1))
920                         return CC_PC_FF_IPV6PTYPE1;
921                     if(index == e_FM_PCD_HDR_INDEX_2)
922                         return CC_PC_FF_IPV6PTYPE2;
923                     REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv6 index"));
924                     return CC_PC_ILLEGAL;
925                 case(NET_HEADER_FIELD_IPv6_DST_IP):
926                     if((index == e_FM_PCD_HDR_INDEX_NONE) || (index == e_FM_PCD_HDR_INDEX_1))
927                         return CC_PC_FF_IPV6DST1;
928                     if(index == e_FM_PCD_HDR_INDEX_2)
929                         return CC_PC_FF_IPV6DST2;
930                     REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv6 index"));
931                     return CC_PC_ILLEGAL;
932                 case(NET_HEADER_FIELD_IPv6_SRC_IP):
933                     if((index == e_FM_PCD_HDR_INDEX_NONE) || (index == e_FM_PCD_HDR_INDEX_1))
934                         return CC_PC_FF_IPV6SRC1;
935                     if(index == e_FM_PCD_HDR_INDEX_2)
936                         return CC_PC_FF_IPV6SRC2;
937                     REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv6 index"));
938                     return CC_PC_ILLEGAL;
939                 case(NET_HEADER_FIELD_IPv6_HOP_LIMIT):
940                     return CC_PC_FF_IPV6HOP_LIMIT;
941                  default:
942                     REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
943                     return CC_PC_ILLEGAL;
944             }
945 
946         case(HEADER_TYPE_GRE):
947             switch(field.gre)
948             {
949                 case(NET_HEADER_FIELD_GRE_TYPE):
950                     return CC_PC_FF_GREPTYPE;
951                 default:
952                     REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
953                     return CC_PC_ILLEGAL;
954            }
955         case(HEADER_TYPE_MINENCAP):
956             switch(field.minencap)
957             {
958                 case(NET_HEADER_FIELD_MINENCAP_TYPE):
959                     return CC_PC_FF_MINENCAP_PTYPE;
960                 case(NET_HEADER_FIELD_MINENCAP_DST_IP):
961                     return CC_PC_FF_MINENCAP_IPDST;
962                 case(NET_HEADER_FIELD_MINENCAP_SRC_IP):
963                     return CC_PC_FF_MINENCAP_IPSRC;
964                 case(NET_HEADER_FIELD_MINENCAP_SRC_IP | NET_HEADER_FIELD_MINENCAP_DST_IP):
965                     return CC_PC_FF_MINENCAP_IPSRC_IPDST;
966                 default:
967                     REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
968                     return CC_PC_ILLEGAL;
969            }
970 
971         case(HEADER_TYPE_TCP):
972             switch(field.tcp)
973             {
974                 case(NET_HEADER_FIELD_TCP_PORT_SRC):
975                     return CC_PC_FF_L4PSRC;
976                 case(NET_HEADER_FIELD_TCP_PORT_DST):
977                     return CC_PC_FF_L4PDST;
978                 case(NET_HEADER_FIELD_TCP_PORT_DST | NET_HEADER_FIELD_TCP_PORT_SRC):
979                     return CC_PC_FF_L4PSRC_L4PDST;
980                 default:
981                     REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
982                     return CC_PC_ILLEGAL;
983             }
984 
985         case(HEADER_TYPE_PPPoE):
986             switch(field.pppoe)
987             {
988                 case(NET_HEADER_FIELD_PPPoE_PID):
989                     return CC_PC_FF_PPPPID;
990                 default:
991                     REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
992                     return CC_PC_ILLEGAL;
993             }
994 
995         case(HEADER_TYPE_UDP):
996             switch(field.udp)
997             {
998                 case(NET_HEADER_FIELD_UDP_PORT_SRC):
999                     return CC_PC_FF_L4PSRC;
1000                 case(NET_HEADER_FIELD_UDP_PORT_DST):
1001                     return CC_PC_FF_L4PDST;
1002                 case(NET_HEADER_FIELD_UDP_PORT_DST | NET_HEADER_FIELD_UDP_PORT_SRC):
1003                     return CC_PC_FF_L4PSRC_L4PDST;
1004                 default:
1005                     REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
1006                     return CC_PC_ILLEGAL;
1007             }
1008 
1009          default:
1010             REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
1011             return CC_PC_ILLEGAL;
1012     }
1013 }
1014 
1015 static uint8_t GetPrParseCode(e_NetHeaderType hdr, e_FmPcdHdrIndex hdrIndex, uint32_t offset, bool glblMask, uint8_t *parseArrayOffset)
1016 {
1017     bool offsetRelevant = FALSE;
1018 
1019     if(offset)
1020         offsetRelevant = TRUE;
1021 
1022     switch(hdr){
1023         case(HEADER_TYPE_NONE):
1024             ASSERT_COND(FALSE);
1025             return CC_PC_ILLEGAL;
1026         case(HEADER_TYPE_ETH):
1027             *parseArrayOffset = (uint8_t)CC_PC_PR_ETH_OFFSET;
1028             break;
1029         case(HEADER_TYPE_USER_DEFINED_SHIM1):
1030             if(offset || glblMask)
1031                 *parseArrayOffset = (uint8_t)CC_PC_PR_USER_DEFINED_SHIM1_OFFSET;
1032             else
1033                 return CC_PC_PR_SHIM1;
1034             break;
1035         case(HEADER_TYPE_USER_DEFINED_SHIM2):
1036             if(offset || glblMask)
1037                 *parseArrayOffset = (uint8_t)CC_PC_PR_USER_DEFINED_SHIM2_OFFSET;
1038             else
1039                 return CC_PC_PR_SHIM2;
1040             break;
1041       case(HEADER_TYPE_LLC_SNAP):
1042             *parseArrayOffset = CC_PC_PR_USER_LLC_SNAP_OFFSET;
1043             break;
1044         case(HEADER_TYPE_PPPoE):
1045             *parseArrayOffset = CC_PC_PR_PPPOE_OFFSET;
1046             break;
1047             case(HEADER_TYPE_MPLS):
1048                  if((hdrIndex == e_FM_PCD_HDR_INDEX_NONE) || (hdrIndex == e_FM_PCD_HDR_INDEX_1))
1049                         *parseArrayOffset = CC_PC_PR_MPLS1_OFFSET;
1050                 else if(hdrIndex == e_FM_PCD_HDR_INDEX_LAST)
1051                         *parseArrayOffset = CC_PC_PR_MPLS_LAST_OFFSET;
1052                 else
1053                 {
1054                     REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal MPLS header index"));
1055                     return CC_PC_ILLEGAL;
1056                 }
1057                 break;
1058             case(HEADER_TYPE_IPv4):
1059             case(HEADER_TYPE_IPv6):
1060               if((hdrIndex == e_FM_PCD_HDR_INDEX_NONE) || (hdrIndex == e_FM_PCD_HDR_INDEX_1))
1061                     *parseArrayOffset = CC_PC_PR_IP1_OFFSET;
1062               else if(hdrIndex == e_FM_PCD_HDR_INDEX_2)
1063                     *parseArrayOffset = CC_PC_PR_IP_LAST_OFFSET;
1064               else
1065               {
1066                 REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IP header index"));
1067                 return CC_PC_ILLEGAL;
1068 
1069               }
1070                 break;
1071             case(HEADER_TYPE_MINENCAP):
1072                 *parseArrayOffset = CC_PC_PR_MINENC_OFFSET;
1073                 break;
1074             case(HEADER_TYPE_GRE):
1075                 *parseArrayOffset = CC_PC_PR_GRE_OFFSET;
1076                 break;
1077             case(HEADER_TYPE_TCP):
1078             case(HEADER_TYPE_UDP):
1079             case(HEADER_TYPE_IPSEC_AH):
1080             case(HEADER_TYPE_IPSEC_ESP):
1081             case(HEADER_TYPE_DCCP):
1082             case(HEADER_TYPE_SCTP):
1083                 *parseArrayOffset = CC_PC_PR_L4_OFFSET;
1084                 break;
1085 
1086             default:
1087                 REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IP header for this type of operation"));
1088                 return CC_PC_ILLEGAL;
1089      }
1090 
1091         if(offsetRelevant)
1092             return CC_PR_OFFSET;
1093         else
1094             return CC_PR_WITHOUT_OFFSET;
1095 }
1096 
1097 static uint8_t GetFieldParseCode(e_NetHeaderType hdr, t_FmPcdFields field, uint32_t offset, uint8_t *parseArrayOffset, e_FmPcdHdrIndex hdrIndex)
1098 {
1099     bool offsetRelevant = FALSE;
1100 
1101     if(offset)
1102         offsetRelevant = TRUE;
1103 
1104     switch(hdr)
1105     {
1106         case(HEADER_TYPE_NONE):
1107                 ASSERT_COND(FALSE);
1108         case(HEADER_TYPE_ETH):
1109             switch(field.eth)
1110             {
1111                 case(NET_HEADER_FIELD_ETH_TYPE):
1112                     *parseArrayOffset = CC_PC_PR_ETYPE_LAST_OFFSET;
1113                     break;
1114                 default:
1115                     REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
1116                     return CC_PC_ILLEGAL;
1117             }
1118             break;
1119         case(HEADER_TYPE_VLAN):
1120             switch(field.vlan)
1121             {
1122                 case(NET_HEADER_FIELD_VLAN_TCI):
1123                     if((hdrIndex == e_FM_PCD_HDR_INDEX_NONE) || (hdrIndex == e_FM_PCD_HDR_INDEX_1))
1124                         *parseArrayOffset = CC_PC_PR_VLAN1_OFFSET;
1125                     else if(hdrIndex == e_FM_PCD_HDR_INDEX_LAST)
1126                         *parseArrayOffset = CC_PC_PR_VLAN2_OFFSET;
1127                     break;
1128                 default:
1129                     REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
1130                     return CC_PC_ILLEGAL;
1131             }
1132         break;
1133         default:
1134             REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal header "));
1135             return CC_PC_ILLEGAL;
1136     }
1137     if(offsetRelevant)
1138         return CC_PR_OFFSET;
1139     else
1140         return CC_PR_WITHOUT_OFFSET;
1141 }
1142 
1143 static void FillAdOfTypeResult(t_Handle p_Ad, t_FmPcd *p_FmPcd, t_FmPcdCcNextEngineParams *p_CcNextEngineParams)
1144 {
1145     t_AdOfTypeResult                *p_AdResult = (t_AdOfTypeResult*)p_Ad;
1146     uint32_t                        tmp = 0, tmpNia = 0;
1147     uint16_t                        profileId;
1148     t_Handle                        p_AdNewPtr = NULL;
1149 
1150     p_AdNewPtr = p_AdResult;
1151 
1152 #ifdef FM_PCD_CC_MANIP
1153     if (p_CcNextEngineParams->h_Manip)
1154         FmPcdManipUpdateAdResultForCc(p_CcNextEngineParams->h_Manip, p_Ad, &p_AdNewPtr);
1155 #endif /* FM_PCD_CC_MANIP */
1156 
1157     if(p_AdNewPtr)
1158     {
1159         switch(p_CcNextEngineParams->nextEngine)
1160         {
1161             case(e_FM_PCD_DONE):
1162                 if(p_CcNextEngineParams->params.enqueueParams.action == e_FM_PCD_ENQ_FRAME)
1163                 {
1164                     if(p_CcNextEngineParams->params.enqueueParams.overrideFqid)
1165                     {
1166                        tmp = FM_PCD_AD_RESULT_CONTRL_FLOW_TYPE;
1167                        tmp |= p_CcNextEngineParams->params.enqueueParams.newFqid;
1168                     }
1169                     else
1170                     {
1171                        tmp = FM_PCD_AD_RESULT_DATA_FLOW_TYPE;
1172                        tmp |= FM_PCD_AD_RESULT_PLCR_DIS;
1173                     }
1174                 }
1175             if(p_CcNextEngineParams->params.enqueueParams.action == e_FM_PCD_DROP_FRAME)
1176                 tmpNia |= (NIA_ENG_BMI |NIA_BMI_AC_DISCARD);
1177             else
1178                 tmpNia |= (NIA_ENG_BMI |NIA_BMI_AC_ENQ_FRAME);
1179             if(p_CcNextEngineParams->params.enqueueParams.statisticsEn)
1180                 tmpNia |=  FM_PCD_AD_RESULT_EXTENDED_MODE |  FM_PCD_AD_RESULT_STATISTICS_EN;
1181                 break;
1182             case(e_FM_PCD_KG):
1183                 if(p_CcNextEngineParams->params.kgParams.overrideFqid)
1184                 {
1185                     tmp = FM_PCD_AD_RESULT_CONTRL_FLOW_TYPE;
1186                     tmp |= p_CcNextEngineParams->params.kgParams.newFqid;
1187                 }
1188                 else
1189                 {
1190                     tmp = FM_PCD_AD_RESULT_DATA_FLOW_TYPE;
1191                     tmp |= FM_PCD_AD_RESULT_PLCR_DIS;
1192                 }
1193                 tmpNia = NIA_KG_DIRECT;
1194                 tmpNia |= NIA_ENG_KG;
1195                 tmpNia |= (uint8_t)(PTR_TO_UINT(p_CcNextEngineParams->params.kgParams.h_DirectScheme)-1);
1196             if(p_CcNextEngineParams->params.kgParams.statisticsEn)
1197                 tmpNia |=  FM_PCD_AD_RESULT_EXTENDED_MODE |  FM_PCD_AD_RESULT_STATISTICS_EN;
1198             break;
1199             case(e_FM_PCD_PLCR):
1200                 tmp = 0;
1201                 if(p_CcNextEngineParams->params.plcrParams.overrideParams)
1202                 {
1203                     tmp = FM_PCD_AD_RESULT_CONTRL_FLOW_TYPE;
1204 
1205                     /* if private policer profile, it may be uninitialized yet, therefor no checks are done at this stage */
1206                     if(p_CcNextEngineParams->params.plcrParams.sharedProfile)
1207                     {
1208                         tmpNia |= NIA_PLCR_ABSOLUTE;
1209                         FmPcdPlcrGetAbsoluteProfileId((t_Handle)p_FmPcd,e_FM_PCD_PLCR_SHARED,NULL,p_CcNextEngineParams->params.plcrParams.newRelativeProfileId, &profileId);
1210                     }
1211                     else
1212                         profileId = p_CcNextEngineParams->params.plcrParams.newRelativeProfileId;
1213 
1214                     tmp |= p_CcNextEngineParams->params.plcrParams.newFqid;
1215                     WRITE_UINT32(p_AdResult->plcrProfile,(uint32_t)((uint32_t)profileId << FM_PCD_AD_PROFILEID_FOR_CNTRL_SHIFT));
1216                 }
1217                 else
1218                    tmp = FM_PCD_AD_RESULT_DATA_FLOW_TYPE;
1219                 tmpNia |= NIA_ENG_PLCR | p_CcNextEngineParams->params.plcrParams.newRelativeProfileId;
1220             if(p_CcNextEngineParams->params.kgParams.statisticsEn)
1221                 tmpNia |=  FM_PCD_AD_RESULT_EXTENDED_MODE |  FM_PCD_AD_RESULT_STATISTICS_EN;
1222                break;
1223             default:
1224                 return;
1225         }
1226         WRITE_UINT32(p_AdResult->fqid, tmp);
1227 
1228 #ifdef FM_PCD_CC_MANIP
1229         if(p_CcNextEngineParams->h_Manip)
1230         {
1231             tmp = GET_UINT32(p_AdResult->plcrProfile);
1232             tmp |= (uint32_t)(XX_VirtToPhys(p_AdNewPtr) - (p_FmPcd->physicalMuramBase)) >> 4;
1233             WRITE_UINT32(p_AdResult->plcrProfile, tmp);
1234 
1235             tmpNia |= FM_PCD_AD_RESULT_EXTENDED_MODE;
1236             tmpNia |= FM_PCD_AD_RESULT_NADEN;
1237         }
1238 #endif /* FM_PCD_CC_MANIP */
1239 
1240         WRITE_UINT32(p_AdResult->nia, tmpNia);
1241     }
1242 }
1243 
1244 static void FillAdOfTypeContLookup(t_Handle p_Ad,  t_Handle h_FmPcd, t_Handle p_FmPcdCcNode, t_Handle h_Manip)
1245 {
1246     t_FmPcdCcNode           *p_Node = (t_FmPcdCcNode *)p_FmPcdCcNode;
1247     t_AdOfTypeContLookup    *p_AdContLookup = (t_AdOfTypeContLookup *)p_Ad;
1248     t_FmPcd                 *p_FmPcd = (t_FmPcd*)h_FmPcd;
1249     uint32_t                tmpReg32;
1250     t_Handle                p_AdNewPtr = NULL;
1251 
1252     p_AdNewPtr = p_AdContLookup;
1253 
1254 #ifdef FM_PCD_CC_MANIP
1255     if (h_Manip)
1256         FmPcdManipUpdateAdContLookupForCc(h_Manip, p_Ad, &p_AdNewPtr, (uint32_t)((XX_VirtToPhys(p_Node->h_AdTable) - p_FmPcd->physicalMuramBase)));
1257 #else
1258     UNUSED(h_Manip);
1259 #endif /* FM_PCD_CC_MANIP */
1260 
1261     if(p_AdNewPtr)
1262     {
1263         tmpReg32 = 0;
1264         tmpReg32 |= FM_PCD_AD_CONT_LOOKUP_TYPE;
1265         tmpReg32 |= p_Node->sizeOfExtraction ? ((p_Node->sizeOfExtraction - 1) << 24) : 0;
1266         tmpReg32 |= (uint32_t)(XX_VirtToPhys(p_Node->h_AdTable) - p_FmPcd->physicalMuramBase);
1267         WRITE_UINT32(p_AdContLookup->ccAdBase, tmpReg32);
1268 
1269         tmpReg32 = 0;
1270         tmpReg32 |= p_Node->numOfKeys << 24;
1271         tmpReg32 |= (p_Node->lclMask ? FM_PCD_AD_CONT_LOOKUP_LCL_MASK : 0);
1272         tmpReg32 |= p_Node->h_KeysMatchTable ?
1273                         (uint32_t)(XX_VirtToPhys(p_Node->h_KeysMatchTable) - p_FmPcd->physicalMuramBase) : 0;
1274         WRITE_UINT32(p_AdContLookup->matchTblPtr, tmpReg32);
1275 
1276         tmpReg32 = 0;
1277         tmpReg32 |= p_Node->prsArrayOffset << 24;
1278         tmpReg32 |= p_Node->offset << 16;
1279         tmpReg32 |= p_Node->parseCode;
1280         WRITE_UINT32(p_AdContLookup->pcAndOffsets, tmpReg32);
1281 
1282         Mem2IOCpy32((void*)&p_AdContLookup->gmask, p_Node->p_GlblMask, CC_GLBL_MASK_SIZE);
1283     }
1284 }
1285 
1286 static void NextStepAd(t_Handle p_Ad, t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams, t_FmPcd *p_FmPcd)
1287 {
1288     switch(p_FmPcdCcNextEngineParams->nextEngine)
1289     {
1290         case(e_FM_PCD_KG):
1291         case(e_FM_PCD_PLCR):
1292         case(e_FM_PCD_DONE):
1293             FillAdOfTypeResult(p_Ad, p_FmPcd, p_FmPcdCcNextEngineParams);
1294             break;
1295         case(e_FM_PCD_CC):
1296             FillAdOfTypeContLookup(p_Ad,
1297                                    p_FmPcd,
1298                                    p_FmPcdCcNextEngineParams->params.ccParams.h_CcNode,
1299 #ifdef FM_PCD_CC_MANIP
1300                                    p_FmPcdCcNextEngineParams->h_Manip
1301 #else
1302                                    NULL
1303 #endif /* FM_PCD_CC_MANIP */
1304                                    );
1305             UpdateNodeOwner (p_FmPcdCcNextEngineParams->params.ccParams.h_CcNode,
1306                             TRUE);
1307             break;
1308          default:
1309              return;
1310     }
1311 }
1312 
1313 
1314 static void ReleaseNewNodeCommonPart(t_FmPcdModifyCcKeyAdditionalParams *p_AdditionalInfo)
1315 {
1316     if(p_AdditionalInfo->p_AdTableNew)
1317         FM_MURAM_FreeMem(FmPcdGetMuramHandle(((t_FmPcdCcNode *)(p_AdditionalInfo->h_CurrentNode))->h_FmPcd), p_AdditionalInfo->p_AdTableNew);
1318     if(p_AdditionalInfo->p_KeysMatchTableNew)
1319         FM_MURAM_FreeMem(FmPcdGetMuramHandle(((t_FmPcdCcNode *)(p_AdditionalInfo->h_CurrentNode))->h_FmPcd), p_AdditionalInfo->p_KeysMatchTableNew);
1320 }
1321 
1322 static t_Error UpdateGblMask(t_FmPcdCcNode *p_FmPcdCcNode, uint8_t keySize, uint8_t *p_Mask)
1323 {
1324     if (p_Mask &&
1325         !p_FmPcdCcNode->glblMaskUpdated &&
1326         (keySize <= 4) &&
1327         !p_FmPcdCcNode->lclMask )
1328     {
1329         memcpy(p_FmPcdCcNode->p_GlblMask, p_Mask, (sizeof(uint8_t))*keySize);
1330         p_FmPcdCcNode->glblMaskUpdated = TRUE;
1331         p_FmPcdCcNode->glblMaskSize = 4;
1332     }
1333     else if (p_Mask &&
1334              (keySize <= 4) &&
1335              !p_FmPcdCcNode->lclMask)
1336     {
1337         if (memcmp(p_FmPcdCcNode->p_GlblMask, p_Mask, keySize) != 0)
1338         {
1339             p_FmPcdCcNode->lclMask = TRUE;
1340             p_FmPcdCcNode->glblMaskSize = 0;
1341         }
1342     }
1343     else if (!p_Mask && (p_FmPcdCcNode->glblMaskUpdated) && (keySize <= 4))
1344     {
1345         uint32_t tmpMask = 0xffffffff;
1346         if (memcmp(p_FmPcdCcNode->p_GlblMask, &tmpMask, 4) != 0)
1347         {
1348             p_FmPcdCcNode->lclMask = TRUE;
1349             p_FmPcdCcNode->glblMaskSize = 0;
1350         }
1351     }
1352     else if (p_Mask)
1353     {
1354         p_FmPcdCcNode->lclMask = TRUE;
1355         p_FmPcdCcNode->glblMaskSize = 0;
1356     }
1357 
1358     return E_OK;
1359 }
1360 
1361 static t_Error BuildNewNodeCommonPart(t_FmPcdCcNode                         *p_FmPcdCcNode,
1362                                       int                                   *size,
1363                                       t_FmPcdModifyCcKeyAdditionalParams    *p_AdditionalInfo)
1364 {
1365 
1366     p_AdditionalInfo->p_AdTableNew = (t_Handle)FM_MURAM_AllocMem(FmPcdGetMuramHandle(p_FmPcdCcNode->h_FmPcd),
1367                                      (uint32_t)( (p_AdditionalInfo->numOfKeys+1) * FM_PCD_CC_AD_ENTRY_SIZE),
1368                                      FM_PCD_CC_AD_TABLE_ALIGN);
1369     if(!p_AdditionalInfo->p_AdTableNew)
1370         RETURN_ERROR(MAJOR, E_NO_MEMORY, ("No memory in MURAM for AD table "));
1371 
1372     IOMemSet32((uint8_t*)p_AdditionalInfo->p_AdTableNew, 0, (uint32_t)((p_AdditionalInfo->numOfKeys+1) * FM_PCD_CC_AD_ENTRY_SIZE));
1373 
1374     if(p_FmPcdCcNode->lclMask)
1375         *size = 2 * p_FmPcdCcNode->ccKeySizeAccExtraction;
1376     else
1377         *size = p_FmPcdCcNode->ccKeySizeAccExtraction;
1378 
1379     p_AdditionalInfo->p_KeysMatchTableNew =
1380         (t_Handle)FM_MURAM_AllocMem(FmPcdGetMuramHandle(p_FmPcdCcNode->h_FmPcd),
1381                                     (uint32_t)(*size * sizeof(uint8_t) * (p_AdditionalInfo->numOfKeys + 1)),
1382                                     FM_PCD_CC_KEYS_MATCH_TABLE_ALIGN);
1383     if(!p_AdditionalInfo->p_KeysMatchTableNew)
1384     {
1385         FM_MURAM_FreeMem(FmPcdGetMuramHandle(p_FmPcdCcNode->h_FmPcd), p_AdditionalInfo->p_AdTableNew);
1386         p_AdditionalInfo->p_AdTableNew = NULL;
1387         RETURN_ERROR(MAJOR, E_NO_MEMORY, ("No memory in MURAM for KEY MATCH table"));
1388     }
1389     IOMemSet32((uint8_t*)p_AdditionalInfo->p_KeysMatchTableNew, 0, *size * sizeof(uint8_t) * (p_AdditionalInfo->numOfKeys + 1));
1390 
1391     p_AdditionalInfo->p_AdTableOld          = p_FmPcdCcNode->h_AdTable;
1392     p_AdditionalInfo->p_KeysMatchTableOld   = p_FmPcdCcNode->h_KeysMatchTable;
1393 
1394     return E_OK;
1395 }
1396 
1397 static t_Error BuildNewNodeAddOrMdfyKeyAndNextEngine(t_Handle h_FmPcd ,t_FmPcdCcNode *p_FmPcdCcNode, uint8_t keyIndex, t_FmPcdCcKeyParams  *p_KeyParams,t_FmPcdModifyCcKeyAdditionalParams *p_AdditionalInfo, bool add)
1398 {
1399     t_Error                 err = E_OK;
1400     t_Handle                p_AdTableNewTmp, p_KeysMatchTableNewTmp;
1401     t_Handle                p_KeysMatchTableOldTmp, p_AdTableOldTmp;
1402     int                     size;
1403     int                     i = 0, j = 0;
1404     t_FmPcd                 *p_FmPcd = (t_FmPcd*)h_FmPcd;
1405     uint32_t                requiredAction = 0;
1406     bool                    prvLclMask;
1407     t_CcNodeInformation     *p_CcNodeInformation;
1408     t_List                  *p_Pos;
1409 
1410     /*check that new NIA is legal*/
1411     err = ValidateNextEngineParams(h_FmPcd, &p_KeyParams->ccNextEngineParams);
1412     if(err)
1413         RETURN_ERROR(MAJOR, err, NO_MSG);
1414 
1415     prvLclMask = p_FmPcdCcNode->lclMask;
1416 
1417     /*check that new key is not require update of localMask*/
1418     err = UpdateGblMask(p_FmPcdCcNode,
1419                         p_FmPcdCcNode->ccKeySizeAccExtraction,
1420                         p_KeyParams->p_Mask);
1421     if (err != E_OK)
1422         RETURN_ERROR(MAJOR, err, NO_MSG);
1423 
1424     /*update internal data structure for next engine per index (index - key)*/
1425     memcpy(&p_AdditionalInfo->nextEngineAndRequiredAction[keyIndex].nextEngineParams,&p_KeyParams->ccNextEngineParams, sizeof(t_FmPcdCcNextEngineParams));
1426 
1427     /*update numOfKeys*/
1428     if(add)
1429         p_AdditionalInfo->numOfKeys = (uint8_t)(p_FmPcdCcNode->numOfKeys + 1);
1430     else
1431         p_AdditionalInfo->numOfKeys = (uint8_t)p_FmPcdCcNode->numOfKeys;
1432     /*function which build in the memory new KeyTbl, AdTbl*/
1433     err = BuildNewNodeCommonPart(p_FmPcdCcNode, &size, p_AdditionalInfo);
1434     if(err)
1435         RETURN_ERROR(MAJOR, err, NO_MSG);
1436 
1437 #ifdef FM_PCD_CC_MANIP
1438     /*check that manip is legal and what requiredAction is necessary for this manip*/
1439     if(p_KeyParams->ccNextEngineParams.h_Manip)
1440     {
1441         err = FmPcdManipCheckParamsForCcNextEgine(&p_KeyParams->ccNextEngineParams,&requiredAction);
1442         if(err)
1443             RETURN_ERROR(MAJOR, err, (NO_MSG));
1444 
1445     }
1446 #endif /* FM_PCD_CC_MANIP */
1447 
1448     p_AdditionalInfo->nextEngineAndRequiredAction[keyIndex].requiredAction = requiredAction;
1449 
1450     p_AdditionalInfo->nextEngineAndRequiredAction[keyIndex].requiredAction |= UPDATE_CC_WITH_TREE;
1451 
1452 
1453     /*update new Ad and new Key Table according to new requirement*/
1454     i = 0;
1455     for(j = 0; j < p_AdditionalInfo->numOfKeys; j++)
1456     {
1457         p_AdTableNewTmp = PTR_MOVE(p_AdditionalInfo->p_AdTableNew, j*FM_PCD_CC_AD_ENTRY_SIZE);
1458         if(j == keyIndex)
1459          {
1460             NextStepAd(p_AdTableNewTmp,&p_KeyParams->ccNextEngineParams, p_FmPcd);
1461             p_KeysMatchTableNewTmp = PTR_MOVE(p_AdditionalInfo->p_KeysMatchTableNew, j*size * sizeof(uint8_t));
1462             Mem2IOCpy32((void*)p_KeysMatchTableNewTmp, p_KeyParams->p_Key, p_FmPcdCcNode->userSizeOfExtraction);
1463             if(p_FmPcdCcNode->lclMask)
1464             {
1465                 if(p_KeyParams->p_Mask)
1466                     Mem2IOCpy32(PTR_MOVE(p_KeysMatchTableNewTmp, p_FmPcdCcNode->ccKeySizeAccExtraction), p_KeyParams->p_Mask, p_FmPcdCcNode->userSizeOfExtraction);
1467                 else if (p_FmPcdCcNode->ccKeySizeAccExtraction > 4)
1468                     IOMemSet32(PTR_MOVE(p_KeysMatchTableNewTmp, p_FmPcdCcNode->ccKeySizeAccExtraction), 0xff, p_FmPcdCcNode->userSizeOfExtraction);
1469                 else
1470                     Mem2IOCpy32(PTR_MOVE(p_KeysMatchTableNewTmp, p_FmPcdCcNode->ccKeySizeAccExtraction),p_FmPcdCcNode->p_GlblMask, p_FmPcdCcNode->userSizeOfExtraction);
1471             }
1472             if(!add)
1473                 i++;
1474          }
1475          else
1476          {
1477             p_AdTableOldTmp = PTR_MOVE(p_AdditionalInfo->p_AdTableOld, i*FM_PCD_CC_AD_ENTRY_SIZE);
1478             IO2IOCpy32(p_AdTableNewTmp, p_AdTableOldTmp,  FM_PCD_CC_AD_ENTRY_SIZE);
1479             p_KeysMatchTableNewTmp  = PTR_MOVE(p_AdditionalInfo->p_KeysMatchTableNew, j*size * sizeof(uint8_t));
1480             p_KeysMatchTableOldTmp  = PTR_MOVE(p_AdditionalInfo->p_KeysMatchTableOld, i*size * sizeof(uint8_t));
1481 
1482             if(p_FmPcdCcNode->lclMask)
1483             {
1484                 if(prvLclMask)
1485                     IO2IOCpy32(PTR_MOVE(p_KeysMatchTableNewTmp, p_FmPcdCcNode->ccKeySizeAccExtraction),
1486                                PTR_MOVE(p_KeysMatchTableOldTmp, p_FmPcdCcNode->ccKeySizeAccExtraction),
1487                                p_FmPcdCcNode->ccKeySizeAccExtraction);
1488                 else
1489                 {
1490                     p_KeysMatchTableOldTmp  = PTR_MOVE(p_FmPcdCcNode->h_KeysMatchTable, i*p_FmPcdCcNode->ccKeySizeAccExtraction*sizeof(uint8_t));
1491 
1492                     if (p_FmPcdCcNode->ccKeySizeAccExtraction > 4)
1493                         IOMemSet32(PTR_MOVE(p_KeysMatchTableNewTmp, p_FmPcdCcNode->ccKeySizeAccExtraction), 0xff, p_FmPcdCcNode->userSizeOfExtraction);
1494                     else
1495                         IO2IOCpy32(PTR_MOVE(p_KeysMatchTableNewTmp, p_FmPcdCcNode->ccKeySizeAccExtraction), p_FmPcdCcNode->p_GlblMask, p_FmPcdCcNode->userSizeOfExtraction);
1496                 }
1497             }
1498             IO2IOCpy32(p_KeysMatchTableNewTmp, p_KeysMatchTableOldTmp, p_FmPcdCcNode->ccKeySizeAccExtraction);
1499            i++;
1500          }
1501     }
1502 
1503     p_AdTableNewTmp = PTR_MOVE(p_AdditionalInfo->p_AdTableNew, j*FM_PCD_CC_AD_ENTRY_SIZE);
1504     p_AdTableOldTmp = PTR_MOVE(p_AdditionalInfo->p_AdTableOld, i*FM_PCD_CC_AD_ENTRY_SIZE);
1505     IO2IOCpy32(p_AdTableNewTmp, p_AdTableOldTmp, FM_PCD_CC_AD_ENTRY_SIZE);
1506 
1507 
1508     if(!LIST_IsEmpty(&p_FmPcdCcNode->ccTreesLst))
1509     {
1510         LIST_FOR_EACH(p_Pos, &p_FmPcdCcNode->ccTreesLst)
1511         {
1512             p_CcNodeInformation = CC_NODE_F_OBJECT(p_Pos);
1513             ASSERT_COND(p_CcNodeInformation->h_CcNode);
1514             /*update the manipulation which has to be updated from parameters of the port*/
1515             /*it's has to be updated with restrictions defined in the function*/
1516                 err = FmPcdCcSetRequiredAction(p_FmPcdCcNode->h_FmPcd,
1517                                                p_FmPcdCcNode->shadowAction | p_AdditionalInfo->nextEngineAndRequiredAction[keyIndex].requiredAction,
1518                                                &p_AdditionalInfo->nextEngineAndRequiredAction[keyIndex],
1519                                                PTR_MOVE(p_AdditionalInfo->p_AdTableNew, keyIndex*FM_PCD_CC_AD_ENTRY_SIZE),
1520                                                1,
1521                                                p_CcNodeInformation->h_CcNode);
1522                 if (err)
1523                     RETURN_ERROR(MAJOR, err, (NO_MSG));
1524 
1525                 err = CcUpdateParam(p_FmPcdCcNode->h_FmPcd,
1526                                     NULL,
1527                                     &p_AdditionalInfo->nextEngineAndRequiredAction[keyIndex],
1528                                     1,
1529                                     PTR_MOVE(p_AdditionalInfo->p_AdTableNew, keyIndex*FM_PCD_CC_AD_ENTRY_SIZE),
1530                                     TRUE,
1531                                     p_CcNodeInformation->index,
1532                                     p_CcNodeInformation->h_CcNode,
1533                                     TRUE);
1534                 if (err)
1535                     RETURN_ERROR(MAJOR, err, (NO_MSG));
1536         }
1537    }
1538 
1539     if(p_FmPcdCcNode->lclMask)
1540         memset(p_FmPcdCcNode->p_GlblMask, 0xff, CC_GLBL_MASK_SIZE * sizeof(uint8_t));
1541 
1542 
1543     if(p_KeyParams->ccNextEngineParams.nextEngine == e_FM_PCD_CC)
1544         p_AdditionalInfo->h_NodeForAdd = p_KeyParams->ccNextEngineParams.params.ccParams.h_CcNode;
1545 
1546     if(!add)
1547     {
1548         if(p_FmPcdCcNode->nextEngineAndRequiredAction[keyIndex].nextEngineParams.nextEngine == e_FM_PCD_CC)
1549             p_AdditionalInfo->h_NodeForRmv = p_FmPcdCcNode->nextEngineAndRequiredAction[keyIndex].nextEngineParams.params.ccParams.h_CcNode;
1550 #ifdef FM_PCD_CC_MANIP
1551         if(p_FmPcdCcNode->nextEngineAndRequiredAction[keyIndex].nextEngineParams.h_Manip)
1552             p_AdditionalInfo->h_ManipForRmv = p_FmPcdCcNode->nextEngineAndRequiredAction[keyIndex].nextEngineParams.h_Manip;
1553 #endif /* FM_PCD_CC_MANIP */
1554     }
1555 
1556     return E_OK;
1557 }
1558 
1559 static t_Error BuildNewNodeRemoveKey(t_FmPcdCcNode *p_FmPcdCcNode, uint8_t keyIndex, t_FmPcdModifyCcKeyAdditionalParams *p_AdditionalInfo)
1560 {
1561     int         i = 0, j = 0;
1562     t_Handle    p_AdTableNewTmp,p_KeysMatchTableNewTmp;
1563     t_Handle    p_KeysMatchTableOldTmp, p_AdTableOldTmp;
1564     int         size;
1565     t_Error     err = E_OK;
1566 
1567     /*save new numOfKeys*/
1568     p_AdditionalInfo->numOfKeys = (uint16_t)(p_FmPcdCcNode->numOfKeys - 1);
1569 
1570     /*function which allocates in the memory new KeyTbl, AdTbl*/
1571     err = BuildNewNodeCommonPart(p_FmPcdCcNode, &size, p_AdditionalInfo);
1572     if(err)
1573         RETURN_ERROR(MAJOR, err, NO_MSG);
1574 
1575     /*update new Ad and new Key Table according to new requirement*/
1576     for(i = 0, j = 0; j < p_FmPcdCcNode->numOfKeys; i++, j++)
1577     {
1578         if(j == keyIndex)
1579         {
1580             p_AdTableOldTmp = PTR_MOVE(p_AdditionalInfo->p_AdTableOld, j*FM_PCD_CC_AD_ENTRY_SIZE);
1581             j++;
1582         }
1583         if(j == p_FmPcdCcNode->numOfKeys)
1584             break;
1585          p_AdTableNewTmp = PTR_MOVE(p_AdditionalInfo->p_AdTableNew, i*FM_PCD_CC_AD_ENTRY_SIZE);
1586          p_AdTableOldTmp = PTR_MOVE(p_AdditionalInfo->p_AdTableOld, j*FM_PCD_CC_AD_ENTRY_SIZE);
1587          IO2IOCpy32(p_AdTableNewTmp,p_AdTableOldTmp,  FM_PCD_CC_AD_ENTRY_SIZE);
1588          p_KeysMatchTableOldTmp = PTR_MOVE(p_AdditionalInfo->p_KeysMatchTableOld, j*size * sizeof(uint8_t));
1589          p_KeysMatchTableNewTmp = PTR_MOVE(p_AdditionalInfo->p_KeysMatchTableNew, i*size * sizeof(uint8_t));
1590          IO2IOCpy32(p_KeysMatchTableNewTmp,p_KeysMatchTableOldTmp,  size * sizeof(uint8_t));
1591     }
1592 
1593     p_AdTableNewTmp = PTR_MOVE(p_AdditionalInfo->p_AdTableNew, i*FM_PCD_CC_AD_ENTRY_SIZE);
1594     p_AdTableOldTmp = PTR_MOVE(p_AdditionalInfo->p_AdTableOld, j*FM_PCD_CC_AD_ENTRY_SIZE);
1595     IO2IOCpy32(p_AdTableNewTmp, p_AdTableOldTmp,  FM_PCD_CC_AD_ENTRY_SIZE);
1596 
1597     if(p_FmPcdCcNode->nextEngineAndRequiredAction[keyIndex].nextEngineParams.nextEngine == e_FM_PCD_CC)
1598         p_AdditionalInfo->h_NodeForRmv = p_FmPcdCcNode->nextEngineAndRequiredAction[keyIndex].nextEngineParams.params.ccParams.h_CcNode;
1599 #ifdef FM_PCD_CC_MANIP
1600     if(p_FmPcdCcNode->nextEngineAndRequiredAction[keyIndex].nextEngineParams.h_Manip)
1601         p_AdditionalInfo->h_ManipForRmv = p_FmPcdCcNode->nextEngineAndRequiredAction[keyIndex].nextEngineParams.h_Manip;
1602 #endif /* FM_PCD_CC_MANIP */
1603 
1604    return E_OK;
1605 }
1606 
1607 static t_Error BuildNewNodeModifyKey(t_FmPcdCcNode *p_FmPcdCcNode, uint8_t keyIndex, uint8_t  *p_Key, uint8_t *p_Mask,t_FmPcdModifyCcKeyAdditionalParams *p_AdditionalInfo)
1608 {
1609     t_Error                 err = E_OK;
1610     t_Handle                p_AdTableNewTmp, p_KeysMatchTableNewTmp;
1611     t_Handle                p_KeysMatchTableOldTmp, p_AdTableOldTmp;
1612     int                     size;
1613     int                     i = 0, j = 0;
1614     bool                    prvLclMask;
1615 
1616     p_AdditionalInfo->numOfKeys =  p_FmPcdCcNode->numOfKeys;
1617 
1618     prvLclMask = p_FmPcdCcNode->lclMask;
1619 
1620     /*check that new key is not require update of localMask*/
1621     err = UpdateGblMask(p_FmPcdCcNode,
1622                         p_FmPcdCcNode->sizeOfExtraction,
1623                         p_Mask);
1624     if(err)
1625         RETURN_ERROR(MAJOR, err, NO_MSG);
1626 
1627     /*function which build in the memory new KeyTbl, AdTbl*/
1628     err = BuildNewNodeCommonPart(p_FmPcdCcNode, &size,  p_AdditionalInfo);
1629     if(err)
1630         RETURN_ERROR(MAJOR, err, NO_MSG);
1631 
1632     /*fill the New AdTable and New KeyTable*/
1633     for(j = 0, i = 0; j < p_AdditionalInfo->numOfKeys; j++, i++)
1634     {
1635         p_AdTableNewTmp = PTR_MOVE(p_AdditionalInfo->p_AdTableNew, j*FM_PCD_CC_AD_ENTRY_SIZE);
1636         p_AdTableOldTmp = PTR_MOVE(p_AdditionalInfo->p_AdTableOld, i*FM_PCD_CC_AD_ENTRY_SIZE);
1637         IO2IOCpy32(p_AdTableNewTmp, p_AdTableOldTmp,  FM_PCD_CC_AD_ENTRY_SIZE);
1638         if(j == keyIndex)
1639         {
1640             p_KeysMatchTableNewTmp = PTR_MOVE(p_AdditionalInfo->p_KeysMatchTableNew, j*size * sizeof(uint8_t));
1641             Mem2IOCpy32(p_KeysMatchTableNewTmp, p_Key, p_FmPcdCcNode->userSizeOfExtraction);
1642             if(p_FmPcdCcNode->lclMask)
1643             {
1644                 if(p_Mask)
1645                     Mem2IOCpy32(PTR_MOVE(p_KeysMatchTableNewTmp, p_FmPcdCcNode->ccKeySizeAccExtraction), p_Mask, p_FmPcdCcNode->userSizeOfExtraction);
1646                 else if (p_FmPcdCcNode->ccKeySizeAccExtraction > 4)
1647                     IOMemSet32(PTR_MOVE(p_KeysMatchTableNewTmp, p_FmPcdCcNode->ccKeySizeAccExtraction), 0xff, p_FmPcdCcNode->userSizeOfExtraction);
1648                 else
1649                     Mem2IOCpy32(PTR_MOVE(p_KeysMatchTableNewTmp, p_FmPcdCcNode->ccKeySizeAccExtraction),p_FmPcdCcNode->p_GlblMask, p_FmPcdCcNode->userSizeOfExtraction);
1650             }
1651         }
1652         else
1653         {
1654             p_KeysMatchTableNewTmp = PTR_MOVE(p_AdditionalInfo->p_KeysMatchTableNew, j*size * sizeof(uint8_t));
1655             p_KeysMatchTableOldTmp = PTR_MOVE(p_FmPcdCcNode->h_KeysMatchTable, i*size * sizeof(uint8_t));
1656             if (p_FmPcdCcNode->lclMask)
1657             {
1658                 if(prvLclMask)
1659                     IO2IOCpy32(PTR_MOVE(p_KeysMatchTableNewTmp, p_FmPcdCcNode->ccKeySizeAccExtraction),
1660                                PTR_MOVE(p_KeysMatchTableOldTmp, p_FmPcdCcNode->ccKeySizeAccExtraction),
1661                                p_FmPcdCcNode->userSizeOfExtraction);
1662                 else
1663                 {
1664                     p_KeysMatchTableOldTmp = PTR_MOVE(p_FmPcdCcNode->h_KeysMatchTable, i*p_FmPcdCcNode->ccKeySizeAccExtraction * sizeof(uint8_t));
1665 
1666                     if (p_FmPcdCcNode->ccKeySizeAccExtraction > 4)
1667                         IOMemSet32(PTR_MOVE(p_KeysMatchTableNewTmp, p_FmPcdCcNode->ccKeySizeAccExtraction), 0xff, p_FmPcdCcNode->userSizeOfExtraction);
1668                     else
1669                         IO2IOCpy32(PTR_MOVE(p_KeysMatchTableNewTmp, p_FmPcdCcNode->ccKeySizeAccExtraction), p_FmPcdCcNode->p_GlblMask, p_FmPcdCcNode->userSizeOfExtraction);
1670                 }
1671             }
1672             IO2IOCpy32((void*)p_KeysMatchTableNewTmp, p_KeysMatchTableOldTmp, p_FmPcdCcNode->ccKeySizeAccExtraction);
1673         }
1674     }
1675 
1676     p_AdTableNewTmp = PTR_MOVE(p_AdditionalInfo->p_AdTableNew, j*FM_PCD_CC_AD_ENTRY_SIZE);
1677     p_AdTableOldTmp = PTR_MOVE(p_FmPcdCcNode->h_AdTable, i*FM_PCD_CC_AD_ENTRY_SIZE);
1678     IO2IOCpy32(p_AdTableNewTmp, p_AdTableOldTmp, FM_PCD_CC_AD_ENTRY_SIZE);
1679 
1680     return E_OK;
1681 }
1682 
1683 static t_Error BuildNewNodeModifyNextEngine(t_Handle h_FmPcd ,t_Handle h_FmPcdCcNodeOrTree, uint16_t keyIndex,t_FmPcdCcNextEngineParams   *p_CcNextEngineParams, t_List *h_OldLst, t_List *h_NewLst,t_FmPcdModifyCcKeyAdditionalParams *p_AdditionalInfo)
1684 {
1685 
1686     t_Error      err = E_OK;
1687     uint32_t     requiredAction = 0;
1688     t_List       *p_Pos;
1689     t_CcNodeInformation *p_CcNodeInformation, ccNodeInfo;
1690     t_Handle     p_Ad;
1691     t_FmPcdCcNode *p_FmPcdCcNode1 = NULL;
1692     t_FmPcdCcTree *p_FmPcdCcTree = NULL;
1693 
1694     ASSERT_COND(p_CcNextEngineParams);
1695     /*check that new NIA is legal*/
1696     err = ValidateNextEngineParams(h_FmPcd, p_CcNextEngineParams);
1697     if(err)
1698         RETURN_ERROR(MAJOR, err, NO_MSG);
1699 
1700     /*update internal data structure for next engine per index (index - key)*/
1701     memcpy(&p_AdditionalInfo->nextEngineAndRequiredAction[keyIndex].nextEngineParams,p_CcNextEngineParams, sizeof(t_FmPcdCcNextEngineParams));
1702 
1703 #ifdef FM_PCD_CC_MANIP
1704     /*check that manip is legal and what requiredAction is necessary for this manip*/
1705     if(p_CcNextEngineParams->h_Manip)
1706     {
1707         err = FmPcdManipCheckParamsForCcNextEgine(p_CcNextEngineParams,&requiredAction);
1708         if(err)
1709             RETURN_ERROR(MAJOR, err, (NO_MSG));
1710 
1711     }
1712 #endif /* FM_PCD_CC_MANIP */
1713 
1714     if(!p_AdditionalInfo->tree)
1715     {
1716         p_FmPcdCcNode1 = (t_FmPcdCcNode *)h_FmPcdCcNodeOrTree;
1717         p_Ad = p_FmPcdCcNode1->h_AdTable;
1718         if(p_FmPcdCcNode1->nextEngineAndRequiredAction[keyIndex].nextEngineParams.nextEngine == e_FM_PCD_CC)
1719             p_AdditionalInfo->h_NodeForRmv = p_FmPcdCcNode1->nextEngineAndRequiredAction[keyIndex].nextEngineParams.params.ccParams.h_CcNode;
1720 #ifdef FM_PCD_CC_MANIP
1721         if(p_FmPcdCcNode1->nextEngineAndRequiredAction[keyIndex].nextEngineParams.h_Manip)
1722             p_AdditionalInfo->h_ManipForRmv = p_FmPcdCcNode1->nextEngineAndRequiredAction[keyIndex].nextEngineParams.h_Manip;
1723 #endif /* FM_PCD_CC_MANIP */
1724     }
1725     else
1726     {
1727         p_FmPcdCcTree = (t_FmPcdCcTree *)h_FmPcdCcNodeOrTree;
1728         p_Ad = UINT_TO_PTR(p_FmPcdCcTree->ccTreeBaseAddr);
1729         if(p_FmPcdCcTree->nextEngineAndRequiredAction[keyIndex].nextEngineParams.nextEngine == e_FM_PCD_CC)
1730             p_AdditionalInfo->h_NodeForRmv = p_FmPcdCcTree->nextEngineAndRequiredAction[keyIndex].nextEngineParams.params.ccParams.h_CcNode;
1731 #ifdef FM_PCD_CC_MANIP
1732         if(p_FmPcdCcTree->nextEngineAndRequiredAction[keyIndex].nextEngineParams.h_Manip)
1733             p_AdditionalInfo->h_ManipForRmv = p_FmPcdCcTree->nextEngineAndRequiredAction[keyIndex].nextEngineParams.h_Manip;
1734 #endif /* FM_PCD_CC_MANIP */
1735     }
1736     ASSERT_COND(p_Ad);
1737     memset(&ccNodeInfo, 0, sizeof(t_CcNodeInformation));
1738     ccNodeInfo.h_CcNode = PTR_MOVE(p_Ad, keyIndex * FM_PCD_CC_AD_ENTRY_SIZE);
1739     EnqueueNodeInfoToRelevantLst(h_OldLst, &ccNodeInfo);
1740 
1741     memset(&ccNodeInfo, 0, sizeof(t_CcNodeInformation));
1742     p_Ad = (t_Handle)FM_MURAM_AllocMem(FmPcdGetMuramHandle(h_FmPcd),
1743                                          FM_PCD_CC_AD_ENTRY_SIZE,
1744                                          FM_PCD_CC_AD_TABLE_ALIGN);
1745 
1746     if(!p_Ad)
1747         RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Memory allocation in MURAM FAILED"));
1748 
1749     IOMemSet32((uint8_t *)p_Ad, 0,  FM_PCD_CC_AD_ENTRY_SIZE);
1750     if(p_CcNextEngineParams)
1751         NextStepAd(p_Ad,p_CcNextEngineParams, h_FmPcd);
1752     ccNodeInfo.h_CcNode = p_Ad;
1753     EnqueueNodeInfoToRelevantLst(h_NewLst, &ccNodeInfo);
1754 
1755     p_AdditionalInfo->nextEngineAndRequiredAction[keyIndex].requiredAction = requiredAction;
1756 
1757     p_AdditionalInfo->nextEngineAndRequiredAction[keyIndex].requiredAction |= UPDATE_CC_WITH_TREE;
1758 
1759     if(!p_AdditionalInfo->tree)
1760     {
1761         ASSERT_COND(p_FmPcdCcNode1);
1762         if(!LIST_IsEmpty(&p_FmPcdCcNode1->ccTreesLst))
1763         {
1764             LIST_FOR_EACH(p_Pos, &p_FmPcdCcNode1->ccTreesLst)
1765             {
1766                 p_CcNodeInformation = CC_NODE_F_OBJECT(p_Pos);
1767                 ASSERT_COND(p_CcNodeInformation->h_CcNode);
1768                 /*update the manipulation which has to be updated from parameters of the port*/
1769                 /*it's has to be updated with restrictions defined in the function*/
1770                     err = FmPcdCcSetRequiredAction(p_FmPcdCcNode1->h_FmPcd, p_FmPcdCcNode1->shadowAction | p_AdditionalInfo->nextEngineAndRequiredAction[keyIndex].requiredAction, &p_AdditionalInfo->nextEngineAndRequiredAction[keyIndex],
1771                                                    p_Ad, 1, p_CcNodeInformation->h_CcNode);
1772                     if(err)
1773                         RETURN_ERROR(MAJOR, err, (NO_MSG));
1774                      err = CcUpdateParam(p_FmPcdCcNode1->h_FmPcd, NULL, &p_AdditionalInfo->nextEngineAndRequiredAction[keyIndex],1, p_Ad, TRUE, p_CcNodeInformation->index, p_CcNodeInformation->h_CcNode, TRUE);
1775                     if(err)
1776                         RETURN_ERROR(MAJOR, err, (NO_MSG));
1777             }
1778         }
1779     }
1780     else
1781     {
1782        ASSERT_COND(p_FmPcdCcTree);
1783        err = FmPcdCcSetRequiredAction(h_FmPcd, p_FmPcdCcTree->requiredAction | p_AdditionalInfo->nextEngineAndRequiredAction[keyIndex].requiredAction, &p_AdditionalInfo->nextEngineAndRequiredAction[keyIndex],
1784                                        p_Ad, 1, (t_Handle)p_FmPcdCcTree);
1785         if(err)
1786             RETURN_ERROR(MAJOR, err, (NO_MSG));
1787          err = CcUpdateParam(h_FmPcd, NULL, &p_AdditionalInfo->nextEngineAndRequiredAction[keyIndex],1, p_Ad, TRUE, 0, (t_Handle)p_FmPcdCcTree, TRUE);
1788         if(err)
1789             RETURN_ERROR(MAJOR, err, (NO_MSG));
1790     }
1791 
1792     if(p_CcNextEngineParams->nextEngine == e_FM_PCD_CC)
1793         p_AdditionalInfo->h_NodeForAdd = p_CcNextEngineParams->params.ccParams.h_CcNode;
1794     return E_OK;
1795 }
1796 
1797 static t_Handle BuildNewAd(t_FmPcdModifyCcKeyAdditionalParams   *p_FmPcdModifyCcKeyAdditionalParams,
1798                            t_FmPcdCcNode                        *p_FmPcdCcNode,
1799                            t_FmPcdCcNextEngineParams            *p_FmPcdCcNextEngineParams)
1800 {
1801 
1802     t_Handle        p_Ad;
1803     t_FmPcdCcNode   *p_FmPcdCcNodeTmp;
1804 
1805     p_Ad = (t_Handle)FM_MURAM_AllocMem(((t_FmPcd *)(p_FmPcdCcNode->h_FmPcd))->h_FmMuram,
1806                                          FM_PCD_CC_AD_ENTRY_SIZE,
1807                                          FM_PCD_CC_AD_TABLE_ALIGN);
1808     if(!p_Ad)
1809     {
1810         REPORT_ERROR(MAJOR, E_NO_MEMORY, ("MURAM for AD"));
1811         return NULL;
1812     }
1813     IOMemSet32(p_Ad, 0,  FM_PCD_CC_AD_ENTRY_SIZE);
1814 
1815     p_FmPcdCcNodeTmp = (t_FmPcdCcNode*)XX_Malloc(sizeof(t_FmPcdCcNode));
1816     if(!p_FmPcdCcNodeTmp)
1817     {
1818         REPORT_ERROR(MAJOR, E_NO_MEMORY, ("p_FmPcdCcNodeTmp"));
1819         return NULL;
1820     }
1821     memset(p_FmPcdCcNodeTmp, 0, sizeof(t_FmPcdCcNode));
1822 
1823     p_FmPcdCcNodeTmp->numOfKeys = p_FmPcdModifyCcKeyAdditionalParams->numOfKeys;
1824     p_FmPcdCcNodeTmp->h_KeysMatchTable = p_FmPcdModifyCcKeyAdditionalParams->p_KeysMatchTableNew;
1825     p_FmPcdCcNodeTmp->h_AdTable = p_FmPcdModifyCcKeyAdditionalParams->p_AdTableNew;
1826 
1827     p_FmPcdCcNodeTmp->lclMask = p_FmPcdCcNode->lclMask;
1828     p_FmPcdCcNodeTmp->parseCode = p_FmPcdCcNode->parseCode;
1829     p_FmPcdCcNodeTmp->offset = p_FmPcdCcNode->offset;
1830     p_FmPcdCcNodeTmp->prsArrayOffset = p_FmPcdCcNode->prsArrayOffset;
1831     p_FmPcdCcNodeTmp->ctrlFlow = p_FmPcdCcNode->ctrlFlow;
1832     p_FmPcdCcNodeTmp->ccKeySizeAccExtraction = p_FmPcdCcNode->ccKeySizeAccExtraction;
1833     p_FmPcdCcNodeTmp->sizeOfExtraction = p_FmPcdCcNode->sizeOfExtraction;
1834     p_FmPcdCcNodeTmp->glblMaskSize = p_FmPcdCcNode->glblMaskSize;
1835     p_FmPcdCcNodeTmp->p_GlblMask = p_FmPcdCcNode->p_GlblMask;
1836 
1837     if (p_FmPcdCcNextEngineParams->nextEngine == e_FM_PCD_CC)
1838         FillAdOfTypeContLookup(p_Ad,
1839                                p_FmPcdCcNode->h_FmPcd,
1840                                p_FmPcdCcNodeTmp,
1841 #ifdef FM_PCD_CC_MANIP
1842                                p_FmPcdCcNextEngineParams->h_Manip
1843 #else
1844                                NULL
1845 #endif /* FM_PCD_CC_MANIP */
1846                                );
1847 
1848     XX_Free(p_FmPcdCcNodeTmp);
1849 
1850     return p_Ad;
1851 }
1852 
1853 static void UpdateAdPtrOfNodesWhichPointsOnCrntMdfNode(t_FmPcdCcNode *p_CrntMdfNode ,t_FmPcdModifyCcKeyAdditionalParams *p_FmPcdModifyCcKeyAdditionalParams, t_List  *h_OldLst, t_List  *h_NewLst)
1854 {
1855     t_CcNodeInformation     *p_CcNodeInformation;
1856     t_FmPcdCcNode           *p_NodePtrOnCurrentMdfNode = NULL;
1857     t_List                  *p_Pos;
1858     int                     i = 0;
1859     t_Handle                p_AdTablePtOnCrntCurrentMdfNode, p_AdTableNewModified;
1860     t_CcNodeInformation     ccNodeInfo;
1861 
1862     LIST_FOR_EACH(p_Pos, &p_CrntMdfNode->ccPrevNodesLst)
1863     {
1864         p_CcNodeInformation = CC_NODE_F_OBJECT(p_Pos);
1865         p_NodePtrOnCurrentMdfNode = (t_FmPcdCcNode *)p_CcNodeInformation->h_CcNode;
1866         ASSERT_COND(p_NodePtrOnCurrentMdfNode);
1867         /*search in the prev node which exact index points on this current modified node for getting AD */
1868         for(i = 0; i < p_NodePtrOnCurrentMdfNode->numOfKeys + 1; i++)
1869         {
1870             if(p_NodePtrOnCurrentMdfNode->nextEngineAndRequiredAction[i].nextEngineParams.nextEngine == e_FM_PCD_CC)
1871             {
1872                 if(p_NodePtrOnCurrentMdfNode->nextEngineAndRequiredAction[i].nextEngineParams.params.ccParams.h_CcNode == (t_Handle)p_CrntMdfNode)
1873                 {
1874                     p_AdTablePtOnCrntCurrentMdfNode = PTR_MOVE(p_NodePtrOnCurrentMdfNode->h_AdTable, i*FM_PCD_CC_AD_ENTRY_SIZE);
1875                     memset(&ccNodeInfo, 0, sizeof(t_CcNodeInformation));
1876                     ccNodeInfo.h_CcNode = p_AdTablePtOnCrntCurrentMdfNode;
1877                     EnqueueNodeInfoToRelevantLst(h_OldLst, &ccNodeInfo);
1878 
1879                     p_AdTableNewModified = BuildNewAd(p_FmPcdModifyCcKeyAdditionalParams, p_CrntMdfNode, &p_NodePtrOnCurrentMdfNode->nextEngineAndRequiredAction[i].nextEngineParams);
1880                     memset(&ccNodeInfo, 0, sizeof(t_CcNodeInformation));
1881                     ccNodeInfo.h_CcNode = p_AdTableNewModified;
1882                     EnqueueNodeInfoToRelevantLst(h_NewLst, &ccNodeInfo);
1883                 }
1884             }
1885         }
1886         ASSERT_COND(i != p_NodePtrOnCurrentMdfNode->numOfKeys);
1887     }
1888 }
1889 
1890 static void UpdateAdPtrOfTreesWhichPointsOnCrntMdfNode(t_FmPcdCcNode *p_CrntMdfNode ,t_FmPcdModifyCcKeyAdditionalParams *p_FmPcdModifyCcKeyAdditionalParams, t_List  *h_OldLst, t_List  *h_NewLst)
1891 {
1892     t_CcNodeInformation     *p_CcNodeInformation;
1893     t_FmPcdCcTree           *p_TreePtrOnCurrentMdfNode = NULL;
1894     t_List                  *p_Pos;
1895     int                     i = 0;
1896     t_Handle                p_AdTableTmp, p_AdTableTmp1;
1897     t_CcNodeInformation     ccNodeInfo;
1898 
1899     LIST_FOR_EACH(p_Pos, &p_CrntMdfNode->ccTreeIdLst)
1900     {
1901         p_CcNodeInformation = CC_NODE_F_OBJECT(p_Pos);
1902         p_TreePtrOnCurrentMdfNode = (t_FmPcdCcTree *)p_CcNodeInformation->h_CcNode;
1903 
1904         ASSERT_COND(p_TreePtrOnCurrentMdfNode);
1905         /*search in the trees which exact index points on this current modified node for getting AD
1906         */
1907         for(i = 0; i < p_TreePtrOnCurrentMdfNode->numOfEntries; i++)
1908         {
1909             if(p_TreePtrOnCurrentMdfNode->nextEngineAndRequiredAction[i].nextEngineParams.nextEngine == e_FM_PCD_CC)
1910             {
1911                 if(p_TreePtrOnCurrentMdfNode->nextEngineAndRequiredAction[i].nextEngineParams.params.ccParams.h_CcNode == (t_Handle)p_CrntMdfNode)
1912                 {
1913                     p_AdTableTmp = UINT_TO_PTR(p_TreePtrOnCurrentMdfNode->ccTreeBaseAddr + i*FM_PCD_CC_AD_ENTRY_SIZE);
1914                     memset(&ccNodeInfo, 0, sizeof(t_CcNodeInformation));
1915                     ccNodeInfo.h_CcNode = p_AdTableTmp;
1916                     EnqueueNodeInfoToRelevantLst(h_OldLst, &ccNodeInfo);
1917 
1918                     p_AdTableTmp1 = BuildNewAd(p_FmPcdModifyCcKeyAdditionalParams, p_CrntMdfNode, &p_TreePtrOnCurrentMdfNode->nextEngineAndRequiredAction[i].nextEngineParams);
1919                     memset(&ccNodeInfo, 0, sizeof(t_CcNodeInformation));
1920                     ccNodeInfo.h_CcNode = p_AdTableTmp1;
1921                     EnqueueNodeInfoToRelevantLst(h_NewLst, &ccNodeInfo);
1922                 }
1923         }
1924     }
1925         ASSERT_COND(i == p_TreePtrOnCurrentMdfNode->numOfEntries);
1926      }
1927 }
1928 
1929 static t_Error ModifyKeyCommonPart1(t_Handle h_FmPcdCcNodeOrTree,  uint16_t keyIndex, t_Handle *h_Params, e_ModifyState modifyState, bool check, bool tree)
1930 {
1931     t_FmPcdModifyCcKeyAdditionalParams          *p_FmPcdModifyCcKeyAdditionalParams;
1932     int                                         i = 0, j = 0;
1933     bool                                        wasUpdate = FALSE;
1934     t_FmPcdCcNode                               *p_FmPcdCcNode = NULL;
1935     t_FmPcdCcTree                               *p_FmPcdCcTree;
1936     uint16_t                                    numOfKeys;
1937     t_FmPcdCcNextEngineAndRequiredActionParams  *p_nextEngineAndRequiredAction = NULL;
1938 
1939     SANITY_CHECK_RETURN_ERROR(h_FmPcdCcNodeOrTree,E_INVALID_HANDLE);
1940 
1941     p_nextEngineAndRequiredAction = XX_Malloc(FM_PCD_MAX_NUM_OF_KEYS * sizeof(*p_nextEngineAndRequiredAction));
1942     if(!p_nextEngineAndRequiredAction)
1943         RETURN_ERROR(MAJOR, E_NO_MEMORY, ("failed to allocate memory for p_nextEngineAndRequiredAction"));
1944 
1945     memset(p_nextEngineAndRequiredAction, 0, FM_PCD_MAX_NUM_OF_KEYS * sizeof(*p_nextEngineAndRequiredAction));
1946 
1947     if(!tree)
1948     {
1949         p_FmPcdCcNode = (t_FmPcdCcNode *)h_FmPcdCcNodeOrTree;
1950         numOfKeys = p_FmPcdCcNode->numOfKeys;
1951 
1952         /*node has to be pointed by another node or tree*/
1953         if (!LIST_NumOfObjs(&p_FmPcdCcNode->ccPrevNodesLst) &&
1954             !LIST_NumOfObjs(&p_FmPcdCcNode->ccTreeIdLst))
1955         {
1956             XX_Free(p_nextEngineAndRequiredAction);
1957             RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("node has to be pointed by node or tree"));
1958         }
1959 
1960         if(!LIST_NumOfObjs(&p_FmPcdCcNode->ccTreesLst) ||
1961             (LIST_NumOfObjs(&p_FmPcdCcNode->ccTreesLst) != 1))
1962         {
1963             XX_Free(p_nextEngineAndRequiredAction);
1964             RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("node has to be belonging to some tree and only to one tree"));
1965         }
1966 
1967         memcpy(p_nextEngineAndRequiredAction,
1968                p_FmPcdCcNode->nextEngineAndRequiredAction,
1969                FM_PCD_MAX_NUM_OF_KEYS * sizeof(t_FmPcdCcNextEngineAndRequiredActionParams));
1970 
1971         if(check)
1972         {
1973             if((p_FmPcdCcNode->parseCode == CC_PC_FF_IPV4TTL) ||
1974                (p_FmPcdCcNode->parseCode == CC_PC_FF_IPV6HOP_LIMIT) ||
1975                (p_FmPcdCcNode->parseCode == CC_PC_GENERIC_IC_HASH_INDEXED))
1976             {
1977                 XX_Free(p_nextEngineAndRequiredAction);
1978                 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("nodeId of CC_PC_FF_IPV4TTL or CC_PC_FF_IPV6HOP_LIMIT can not be used for addKey, removeKey, modifyKey"));
1979             }
1980         }
1981     }
1982     else
1983     {
1984         p_FmPcdCcTree = (t_FmPcdCcTree *)h_FmPcdCcNodeOrTree;
1985         numOfKeys = p_FmPcdCcTree->numOfEntries;
1986         memcpy(p_nextEngineAndRequiredAction,
1987                p_FmPcdCcTree->nextEngineAndRequiredAction,
1988                FM_PCD_MAX_NUM_OF_KEYS * sizeof(t_FmPcdCcNextEngineAndRequiredActionParams));
1989     }
1990 
1991     p_FmPcdModifyCcKeyAdditionalParams =
1992         (t_FmPcdModifyCcKeyAdditionalParams *)XX_Malloc(sizeof(t_FmPcdModifyCcKeyAdditionalParams));
1993     if(!p_FmPcdModifyCcKeyAdditionalParams)
1994     {
1995         XX_Free(p_nextEngineAndRequiredAction);
1996         RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Allocation of internal data structure FAILED"));
1997     }
1998     memset(p_FmPcdModifyCcKeyAdditionalParams, 0, sizeof(t_FmPcdModifyCcKeyAdditionalParams));
1999 
2000     p_FmPcdModifyCcKeyAdditionalParams->h_CurrentNode = h_FmPcdCcNodeOrTree;
2001     p_FmPcdModifyCcKeyAdditionalParams->keyIndex = keyIndex;
2002 
2003     while(i < numOfKeys)
2004     {
2005         if((j == keyIndex) && !wasUpdate)
2006         {
2007             if(modifyState == e_MODIFY_STATE_ADD)
2008                 j++;
2009             else if(modifyState == e_MODIFY_STATE_REMOVE)
2010                 i++;
2011             wasUpdate = TRUE;
2012         }
2013         else
2014         {
2015             memcpy(&p_FmPcdModifyCcKeyAdditionalParams->nextEngineAndRequiredAction[j], &p_nextEngineAndRequiredAction[i], sizeof(t_FmPcdCcNextEngineAndRequiredActionParams));
2016             i++;
2017             j++;
2018         }
2019     }
2020 
2021     if (keyIndex == numOfKeys)
2022     {
2023         if (modifyState == e_MODIFY_STATE_ADD)
2024             j++;
2025         else if(modifyState == e_MODIFY_STATE_REMOVE)
2026             i++;
2027     }
2028 
2029     memcpy(&p_FmPcdModifyCcKeyAdditionalParams->nextEngineAndRequiredAction[j], &p_nextEngineAndRequiredAction[numOfKeys], sizeof(t_FmPcdCcNextEngineAndRequiredActionParams));
2030 
2031     XX_Free(p_nextEngineAndRequiredAction);
2032     *h_Params = p_FmPcdModifyCcKeyAdditionalParams;
2033 
2034     return E_OK;
2035 }
2036 
2037 static t_Error UpdatePtrWhichPointOnCrntMdfNode(t_FmPcdCcNode *p_FmPcdCcNode, t_FmPcdModifyCcKeyAdditionalParams *p_FmPcdModifyCcKeyAdditionalParams ,t_List *h_OldLst, t_List *h_NewLst)
2038 {
2039     if(!LIST_IsEmpty(&p_FmPcdCcNode->ccPrevNodesLst))
2040         UpdateAdPtrOfNodesWhichPointsOnCrntMdfNode(p_FmPcdCcNode, p_FmPcdModifyCcKeyAdditionalParams, h_OldLst, h_NewLst);
2041 
2042     if(!LIST_IsEmpty(&p_FmPcdCcNode->ccTreeIdLst))
2043         UpdateAdPtrOfTreesWhichPointsOnCrntMdfNode(p_FmPcdCcNode, p_FmPcdModifyCcKeyAdditionalParams, h_OldLst, h_NewLst);
2044 
2045     return E_OK;
2046 }
2047 
2048 static void  FmPcdCcUpdateTreeOwner(t_FmPcdCcTree *p_FmPcdCcTree, bool add)
2049 {
2050     ASSERT_COND(p_FmPcdCcTree);
2051 
2052     if(add)
2053         p_FmPcdCcTree->owners++;
2054     else
2055     {
2056         ASSERT_COND(p_FmPcdCcTree->owners);
2057         p_FmPcdCcTree->owners--;
2058     }
2059 }
2060 
2061 #ifdef FM_PCD_CC_MANIP
2062 static t_Error CheckAndSetManipParamsWithCcNodeParams(t_FmPcdCcNode *p_FmPcdCcNode)
2063 {
2064     t_Error err = E_OK;
2065     int     i = 0;
2066 
2067     for(i = 0; i < p_FmPcdCcNode->numOfKeys; i++)
2068     {
2069         if(p_FmPcdCcNode->nextEngineAndRequiredAction[i].nextEngineParams.h_Manip)
2070         {
2071             err = FmPcdManipCheckParamsWithCcNodeParams(p_FmPcdCcNode->nextEngineAndRequiredAction[i].nextEngineParams.h_Manip, (t_Handle)p_FmPcdCcNode);
2072             if(err)
2073                 return err;
2074         }
2075     }
2076 
2077     return err;
2078 }
2079 #endif /* FM_PCD_CC_MANIP */
2080 
2081 static t_Error CcUpdateParams(t_Handle                         h_FmPcd,
2082                               t_Handle                         h_FmPort,
2083                               t_Handle                         h_FmTree,
2084                               bool                             validate)
2085 {
2086     t_FmPcdCcTree       *p_CcTree = (t_FmPcdCcTree *) h_FmTree;
2087 
2088     return CcUpdateParam(h_FmPcd,
2089                          h_FmPort,
2090                          p_CcTree->nextEngineAndRequiredAction,
2091                          p_CcTree->numOfEntries,
2092                          UINT_TO_PTR(p_CcTree->ccTreeBaseAddr),
2093                          validate,
2094                          0,
2095                          h_FmTree,
2096                          FALSE);
2097 }
2098 
2099 static t_Error CheckParams(t_Handle             h_FmPcd,
2100                            t_FmPcdCcNodeParams  *p_CcNodeParam,
2101                            t_FmPcdCcNode        *p_FmPcdCcNode,
2102                            bool                 *isKeyTblAlloc)
2103 {
2104     int                     tmp = 0;
2105     t_FmPcdCcKeyParams      *p_KeyParams;
2106     t_Error                 err;
2107     uint32_t                requiredAction = 0;
2108 
2109     err = ValidateNextEngineParams(h_FmPcd, &p_CcNodeParam->keysParams.ccNextEngineParamsForMiss);
2110     if(err)
2111         RETURN_ERROR(MAJOR, err, ("For this node MissNextEngineParams are not valid"));
2112 
2113 #ifdef FM_PCD_CC_MANIP
2114     if(p_CcNodeParam->keysParams.ccNextEngineParamsForMiss.h_Manip)
2115     {
2116         err = FmPcdManipCheckParamsForCcNextEgine(&p_CcNodeParam->keysParams.ccNextEngineParamsForMiss, &requiredAction);
2117         if(err)
2118             RETURN_ERROR(MAJOR, err, (NO_MSG));
2119     }
2120 #endif /* FM_PCD_CC_MANIP */
2121 
2122     memcpy(&p_FmPcdCcNode->nextEngineAndRequiredAction[p_FmPcdCcNode->numOfKeys].nextEngineParams,&p_CcNodeParam->keysParams.ccNextEngineParamsForMiss, sizeof(t_FmPcdCcNextEngineParams));
2123     p_FmPcdCcNode->nextEngineAndRequiredAction[p_FmPcdCcNode->numOfKeys].requiredAction = requiredAction;
2124 
2125     for(tmp = 0 ; tmp < p_FmPcdCcNode->numOfKeys; tmp++)
2126     {
2127         p_KeyParams = &p_CcNodeParam->keysParams.keyParams[tmp];
2128 
2129         if(!p_KeyParams->p_Key)
2130             RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("p_Key is not initialized"));
2131 
2132 
2133        err = ValidateNextEngineParams(h_FmPcd, &p_KeyParams->ccNextEngineParams);
2134         if(err)
2135             RETURN_ERROR(MAJOR, err, (NO_MSG));
2136 
2137         err = UpdateGblMask(p_FmPcdCcNode,
2138                             p_CcNodeParam->keysParams.keySize,
2139                             p_KeyParams->p_Mask);
2140 
2141 #ifdef FM_PCD_CC_MANIP
2142         if(p_KeyParams->ccNextEngineParams.h_Manip)
2143         {
2144             err = FmPcdManipCheckParamsForCcNextEgine(&p_KeyParams->ccNextEngineParams, &requiredAction);
2145             if(err)
2146                 RETURN_ERROR(MAJOR, err, (NO_MSG));
2147         }
2148 #endif /* FM_PCD_CC_MANIP */
2149 
2150         memcpy(&p_FmPcdCcNode->nextEngineAndRequiredAction[tmp],&p_KeyParams->ccNextEngineParams, sizeof(t_FmPcdCcNextEngineParams));
2151         p_FmPcdCcNode->nextEngineAndRequiredAction[tmp].requiredAction = requiredAction;
2152     }
2153 
2154     *isKeyTblAlloc = TRUE;
2155     return E_OK;
2156 }
2157 
2158 static t_Error Ipv4TtlOrIpv6HopLimiCheckParams(  t_Handle h_FmPcd,
2159                                                     t_FmPcdCcNodeParams *p_CcNodeParam, t_FmPcdCcNode *p_FmPcdCcNode,
2160                                                     bool *isKeyTblAlloc)
2161 {
2162     int                 tmp = 0;
2163     t_FmPcdCcKeyParams  *p_KeyParams;
2164     t_Error             err;
2165     uint8_t             key = 0x01;
2166     uint32_t            requiredAction = 0;
2167 
2168     if(p_FmPcdCcNode->numOfKeys != 1 )
2169         RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("for IPV4TTL and IPV6_HOP_LIMIT has to be only 1 key - TTL = 1, otherwise it's Miss"));
2170 
2171     err = ValidateNextEngineParams(h_FmPcd, &p_CcNodeParam->keysParams.ccNextEngineParamsForMiss);
2172     if(err)
2173         RETURN_ERROR(MAJOR, err, ("For this node MissNextEngineParams are not valid"));
2174 
2175 #ifdef FM_PCD_CC_MANIP
2176     if(p_CcNodeParam->keysParams.ccNextEngineParamsForMiss.h_Manip)
2177     {
2178         err = FmPcdManipCheckParamsForCcNextEgine(&p_CcNodeParam->keysParams.ccNextEngineParamsForMiss, &requiredAction);
2179         if(err)
2180             RETURN_ERROR(MAJOR, err, (NO_MSG));
2181     }
2182 #endif /* FM_PCD_CC_MANIP */
2183 
2184     memcpy(&p_FmPcdCcNode->nextEngineAndRequiredAction[p_FmPcdCcNode->numOfKeys].nextEngineParams, &p_CcNodeParam->keysParams.ccNextEngineParamsForMiss, sizeof(t_FmPcdCcNextEngineParams));
2185     p_FmPcdCcNode->nextEngineAndRequiredAction[p_FmPcdCcNode->numOfKeys].requiredAction = requiredAction;
2186 
2187     for(tmp = 0 ; tmp < p_FmPcdCcNode->numOfKeys; tmp++)
2188     {
2189         p_KeyParams = &p_CcNodeParam->keysParams.keyParams[tmp];
2190         if(p_KeyParams->p_Mask)
2191             RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("If node of the type IPV4_TTL or IPV6_HOP_LIMIT p_Mask can not be initialized"));
2192         if(memcmp(p_KeyParams->p_Key, &key, 1) != 0)
2193             RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("If node of the type IPV4_TTL or IPV6_HOP_LIMIT p_Key has to be 1"));
2194         err = ValidateNextEngineParams(h_FmPcd, &p_KeyParams->ccNextEngineParams);
2195         if(err)
2196             RETURN_ERROR(MAJOR, err, (NO_MSG));
2197 
2198 #ifdef FM_PCD_CC_MANIP
2199     if(p_KeyParams->ccNextEngineParams.h_Manip)
2200     {
2201         err = FmPcdManipCheckParamsForCcNextEgine(&p_KeyParams->ccNextEngineParams, &requiredAction);
2202         if(err)
2203             RETURN_ERROR(MAJOR, err, (NO_MSG));
2204     }
2205 #endif /* FM_PCD_CC_MANIP */
2206 
2207         memcpy(&p_FmPcdCcNode->nextEngineAndRequiredAction[tmp].nextEngineParams, &p_KeyParams->ccNextEngineParams, sizeof(t_FmPcdCcNextEngineParams));
2208         p_FmPcdCcNode->nextEngineAndRequiredAction[tmp].requiredAction = requiredAction;
2209     }
2210 
2211     *isKeyTblAlloc = FALSE;
2212     return E_OK;
2213 }
2214 
2215 static t_Error IcHashIndexedCheckParams(t_Handle h_FmPcd,
2216                                             t_FmPcdCcNodeParams *p_CcNodeParam,
2217                                             t_FmPcdCcNode *p_FmPcdCcNode,
2218                                             /*uint16_t *ccInfo,*/
2219                                             /*t_List *ccNextDifferentNodesLst,*/
2220                                             bool *isKeyTblAlloc)
2221 {
2222     int                 tmp = 0, countOnes = 0;
2223     t_FmPcdCcKeyParams  *p_KeyParams;
2224     t_Error             err;
2225     uint16_t            glblMask = p_CcNodeParam->extractCcParams.extractNonHdr.icIndxMask;
2226     uint16_t            countMask = (uint16_t)(glblMask >> 4);
2227 #ifdef FM_PCD_CC_MANIP
2228     uint32_t            requiredAction;
2229 #endif /* FM_PCD_CC_MANIP */
2230 
2231     if (glblMask & 0x000f)
2232        RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("icIndxMask has to be with last nibble 0"));
2233 
2234     while (countMask)
2235     {
2236         countOnes++;
2237         countMask=(uint16_t)(countMask>>1);
2238     }
2239 
2240     if (!POWER_OF_2(p_FmPcdCcNode->numOfKeys))
2241         RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("For Node of the type INDEXED numOfKeys has to be powerOfTwo"));
2242     if (p_FmPcdCcNode->numOfKeys != ((uint32_t)1<<countOnes ))
2243         RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("For Node of the type IC_HASH_INDEXED numOfKeys has to be powerOfTwo"));
2244 
2245     err = ValidateNextEngineParams(h_FmPcd, &p_CcNodeParam->keysParams.ccNextEngineParamsForMiss);
2246     if(GET_ERROR_TYPE(err)!= E_NOT_SUPPORTED)
2247         RETURN_ERROR(MAJOR, err, ("MissNextEngineParams for the node of the type IC_INDEX_HASH has to be UnInitialized"));
2248 
2249     for(tmp = 0 ; tmp < p_FmPcdCcNode->numOfKeys; tmp++)
2250     {
2251         p_KeyParams = &p_CcNodeParam->keysParams.keyParams[tmp];
2252         if(p_KeyParams->p_Mask || p_KeyParams->p_Key)
2253             RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("For Node of the type IC_HASH_INDEXED p_Key or p_Mask has to be NULL"));
2254 
2255         if((glblMask & (tmp * 16)) == (tmp * 16))
2256         {
2257             err = ValidateNextEngineParams(h_FmPcd, &p_KeyParams->ccNextEngineParams);
2258             if(err)
2259                 RETURN_ERROR(MAJOR, err, ("This index has to be initialized for the node of the type IC_INDEX_HASH according to settings of GlobalMask "));
2260 
2261 #ifdef FM_PCD_CC_MANIP
2262             if(p_KeyParams->ccNextEngineParams.h_Manip)
2263             {
2264                 err = FmPcdManipCheckParamsForCcNextEgine(&p_KeyParams->ccNextEngineParams, &requiredAction);
2265                 if(err)
2266                     RETURN_ERROR(MAJOR, err, (NO_MSG));
2267             }
2268             p_FmPcdCcNode->nextEngineAndRequiredAction[tmp].requiredAction = requiredAction;
2269 #endif /* FM_PCD_CC_MANIP */
2270 
2271             memcpy(&p_FmPcdCcNode->nextEngineAndRequiredAction[tmp].nextEngineParams,&p_KeyParams->ccNextEngineParams, sizeof(t_FmPcdCcNextEngineParams));
2272         }
2273         else
2274         {
2275             err = ValidateNextEngineParams(h_FmPcd, &p_KeyParams->ccNextEngineParams);
2276             if(GET_ERROR_TYPE(err)!= E_NOT_SUPPORTED)
2277                 RETURN_ERROR(MAJOR, err, ("This index has to be UnInitialized for the node of the type IC_INDEX_HASH according to settings of GlobalMask"));
2278         }
2279     }
2280     *isKeyTblAlloc = FALSE;
2281     memcpy(PTR_MOVE(p_FmPcdCcNode->p_GlblMask, 2), &glblMask, 2);
2282 
2283     return E_OK;
2284 }
2285 
2286 t_Error FmPcdCcModifyNextEngineParamTree(t_Handle h_FmPcd, t_Handle h_FmPcdCcTree, uint8_t grpId, uint8_t index, t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams, t_List *h_OldLst, t_List *h_NewLst, t_Handle *h_AdditionalParams)
2287 {
2288     t_FmPcdCcTree                       *p_FmPcdCcTree = (t_FmPcdCcTree *)h_FmPcdCcTree;
2289     t_Error                             err = E_OK;
2290     uint16_t                            keyIndex;
2291     t_FmPcdModifyCcKeyAdditionalParams *p_ModifyKeyParams;
2292 
2293     SANITY_CHECK_RETURN_ERROR((grpId <= 7),E_INVALID_VALUE);
2294     SANITY_CHECK_RETURN_ERROR(h_FmPcdCcTree,E_INVALID_VALUE);
2295 
2296     if(grpId >= p_FmPcdCcTree->numOfGrps)
2297         RETURN_ERROR(MAJOR, E_INVALID_HANDLE, ("grpId you asked > numOfGroup of relevant tree"));
2298 
2299     if(index >= p_FmPcdCcTree->fmPcdGroupParam[grpId].numOfEntriesInGroup)
2300         RETURN_ERROR(MAJOR, E_INVALID_HANDLE, ("index > numOfEntriesInGroup"));
2301 
2302     keyIndex = (uint16_t)(p_FmPcdCcTree->fmPcdGroupParam[grpId].baseGroupEntry + index);
2303 
2304     err =  ModifyKeyCommonPart1(h_FmPcdCcTree, keyIndex, h_AdditionalParams, e_MODIFY_STATE_CHANGE, TRUE, TRUE);
2305     if(err)
2306         RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
2307 
2308     p_ModifyKeyParams = (t_FmPcdModifyCcKeyAdditionalParams *)*h_AdditionalParams;
2309     p_ModifyKeyParams->tree = TRUE;
2310 
2311     err = BuildNewNodeModifyNextEngine (h_FmPcd, h_FmPcdCcTree, keyIndex,p_FmPcdCcNextEngineParams, h_OldLst, h_NewLst, p_ModifyKeyParams);
2312     if(err)
2313     {
2314         XX_Free(p_ModifyKeyParams);
2315         RETURN_ERROR(MAJOR, err, NO_MSG);
2316     }
2317     return E_OK;
2318 
2319 }
2320 
2321 t_Error FmPcdCcRemoveKey(t_Handle h_FmPcd, t_Handle h_FmPcdCcNode, uint8_t keyIndex, t_List *h_OldLst, t_List *h_NewLst, t_Handle *h_AdditionalParams)
2322 {
2323 
2324     t_FmPcdCcNode                       *p_FmPcdCcNode = (t_FmPcdCcNode *) h_FmPcdCcNode;
2325     t_Error                             err = E_OK;
2326     t_FmPcdModifyCcKeyAdditionalParams  *p_ModifyKeyParams;
2327 
2328     if(keyIndex >= p_FmPcdCcNode->numOfKeys)
2329         RETURN_ERROR(MAJOR, E_INVALID_HANDLE, ("impossible to remove key when numOfKeys <= keyIndex"));
2330 
2331     if(!p_FmPcdCcNode->numOfKeys)
2332         RETURN_ERROR(MAJOR, E_INVALID_HANDLE, ("keyIndex you asked > numOfKeys of relevant node that was initialized"));
2333 
2334     if(p_FmPcdCcNode->h_FmPcd != h_FmPcd)
2335         RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("handler to FmPcd is diferent from one which was assigned to the node in the Init time"));
2336 
2337     err =  ModifyKeyCommonPart1(p_FmPcdCcNode, keyIndex, h_AdditionalParams, e_MODIFY_STATE_REMOVE, TRUE, FALSE);
2338     if(err)
2339         RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
2340 
2341     p_ModifyKeyParams = (t_FmPcdModifyCcKeyAdditionalParams *)*h_AdditionalParams;
2342     err = BuildNewNodeRemoveKey (p_FmPcdCcNode, keyIndex, p_ModifyKeyParams);
2343     if(err)
2344     {
2345         XX_Free(p_ModifyKeyParams);
2346         RETURN_ERROR(MAJOR, err, NO_MSG);
2347     }
2348 
2349     err = UpdatePtrWhichPointOnCrntMdfNode(p_FmPcdCcNode, p_ModifyKeyParams, h_OldLst, h_NewLst);
2350     if(err)
2351     {
2352         ReleaseNewNodeCommonPart(p_ModifyKeyParams);
2353         XX_Free(p_ModifyKeyParams);
2354         RETURN_ERROR(MAJOR, err, NO_MSG);
2355     }
2356 
2357     return E_OK;
2358 
2359 }
2360 
2361 t_Error FmPcdCcModifyKey(t_Handle h_FmPcd, t_Handle h_FmPcdCcNode, uint8_t keyIndex, uint8_t keySize, uint8_t *p_Key, uint8_t *p_Mask, t_List *h_OldLst, t_List *h_NewLst,t_Handle *h_AdditionalParams)
2362 {
2363     t_FmPcdCcNode                       *p_FmPcdCcNode = (t_FmPcdCcNode *)h_FmPcdCcNode;
2364     t_Error                             err = E_OK;
2365     t_FmPcdModifyCcKeyAdditionalParams  *p_ModifyKeyParams;
2366 
2367     if(keyIndex >= p_FmPcdCcNode->numOfKeys)
2368         RETURN_ERROR(MAJOR, E_INVALID_STATE, ("keyIndex > previousely cleared last index + 1"));
2369 
2370     if((p_FmPcdCcNode->numOfKeys + 1) > FM_PCD_MAX_NUM_OF_CC_NODES)
2371         RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("numOfKeys with new key can not be larger than 255"));
2372 
2373     if(keySize != p_FmPcdCcNode->userSizeOfExtraction)
2374         RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("size for ModifyKey has to be the same as defined in SetNode"));
2375 
2376     if(p_FmPcdCcNode->h_FmPcd != h_FmPcd)
2377         RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("handler to FmPcd is diferent from one which was assigned to the node in the Init time"));
2378 
2379     err =  ModifyKeyCommonPart1(p_FmPcdCcNode, keyIndex, h_AdditionalParams, e_MODIFY_STATE_CHANGE, TRUE, FALSE);
2380     if(err)
2381         RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
2382 
2383     p_ModifyKeyParams = (t_FmPcdModifyCcKeyAdditionalParams *)*h_AdditionalParams;
2384 
2385     err = BuildNewNodeModifyKey (p_FmPcdCcNode, keyIndex, p_Key, p_Mask, p_ModifyKeyParams);
2386     if(err)
2387     {
2388         XX_Free(p_ModifyKeyParams);
2389         RETURN_ERROR(MAJOR, err, NO_MSG);
2390     }
2391 
2392     err = UpdatePtrWhichPointOnCrntMdfNode(p_FmPcdCcNode, p_ModifyKeyParams, h_OldLst, h_NewLst);
2393     if(err)
2394     {
2395         ReleaseNewNodeCommonPart(p_ModifyKeyParams);
2396         XX_Free(p_ModifyKeyParams);
2397         RETURN_ERROR(MAJOR, err, NO_MSG);
2398     }
2399     return E_OK;
2400 }
2401 
2402 
2403 t_Error     FmPcdCcModiyNextEngineParamNode(t_Handle h_FmPcd,t_Handle h_FmPcdCcNode, uint8_t keyIndex,t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams,t_List *h_OldPointer, t_List *h_NewPointer,t_Handle *h_AdditionalParams)
2404 {
2405     t_FmPcdCcNode                   *p_FmPcdCcNode = (t_FmPcdCcNode *)h_FmPcdCcNode;
2406     t_Error                         err = E_OK;
2407     t_FmPcdModifyCcKeyAdditionalParams *p_ModifyKeyParams;
2408 
2409     SANITY_CHECK_RETURN_ERROR(h_FmPcd,E_INVALID_VALUE);
2410     SANITY_CHECK_RETURN_ERROR(p_FmPcdCcNode,E_INVALID_HANDLE);
2411 
2412     if(keyIndex >= p_FmPcdCcNode->numOfKeys)
2413         RETURN_ERROR(MAJOR, E_INVALID_STATE, ("keyIndex > previousely cleared last index + 1"));
2414 
2415     if((p_FmPcdCcNode->numOfKeys + 1) > FM_PCD_MAX_NUM_OF_CC_NODES)
2416         RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("numOfKeys with new key can not be larger than 255"));
2417 
2418     err =  ModifyKeyCommonPart1(p_FmPcdCcNode, keyIndex, h_AdditionalParams, e_MODIFY_STATE_CHANGE, FALSE, FALSE);
2419     if(err)
2420         RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
2421 
2422     p_ModifyKeyParams = (t_FmPcdModifyCcKeyAdditionalParams *)*h_AdditionalParams;
2423 
2424     err = BuildNewNodeModifyNextEngine (h_FmPcd, p_FmPcdCcNode, keyIndex,p_FmPcdCcNextEngineParams, h_OldPointer, h_NewPointer, p_ModifyKeyParams);
2425     if(err)
2426     {
2427         XX_Free(p_ModifyKeyParams);
2428         RETURN_ERROR(MAJOR, err, NO_MSG);
2429     }
2430     return E_OK;
2431 }
2432 
2433 t_Error FmPcdCcModifyMissNextEngineParamNode(t_Handle h_FmPcd,t_Handle h_FmPcdCcNode, t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams,t_List *h_OldPointer, t_List *h_NewPointer,t_Handle *h_AdditionalParams)
2434 {
2435     t_FmPcdCcNode                   *p_FmPcdCcNode = (t_FmPcdCcNode *)h_FmPcdCcNode;
2436     t_Error                         err = E_OK;
2437     uint16_t                         keyIndex;
2438     t_FmPcdModifyCcKeyAdditionalParams *p_ModifyKeyParams;
2439 
2440     SANITY_CHECK_RETURN_ERROR(p_FmPcdCcNode,E_INVALID_VALUE);
2441 
2442     keyIndex = p_FmPcdCcNode->numOfKeys;
2443 
2444     err =  ModifyKeyCommonPart1(p_FmPcdCcNode, keyIndex, h_AdditionalParams, e_MODIFY_STATE_CHANGE, TRUE, FALSE);
2445     if(err)
2446         RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
2447 
2448     p_ModifyKeyParams = (t_FmPcdModifyCcKeyAdditionalParams *)*h_AdditionalParams;
2449 
2450     err = BuildNewNodeModifyNextEngine (h_FmPcd, p_FmPcdCcNode, keyIndex,p_FmPcdCcNextEngineParams, h_OldPointer, h_NewPointer, p_ModifyKeyParams);
2451     if(err)
2452     {
2453         XX_Free(p_ModifyKeyParams);
2454         RETURN_ERROR(MAJOR, err, NO_MSG);
2455     }
2456 
2457     return E_OK;
2458 }
2459 
2460 t_Error FmPcdCcAddKey(t_Handle h_FmPcd, t_Handle h_FmPcdCcNode, uint8_t keyIndex, uint8_t keySize, t_FmPcdCcKeyParams *p_FmPcdCcKeyParams, t_List *h_OldLst, t_List *h_NewLst, t_Handle *h_AdditionalParams)
2461 {
2462     t_FmPcdCcNode                       *p_FmPcdCcNode = (t_FmPcdCcNode *)h_FmPcdCcNode;
2463     t_FmPcdModifyCcKeyAdditionalParams  *p_ModifyKeyParams;
2464     t_Error                             err = E_OK;
2465 
2466     if(keyIndex > p_FmPcdCcNode->numOfKeys)
2467         RETURN_ERROR(MAJOR, E_INVALID_STATE, ("keyIndex > previousely cleared last index + 1"));
2468 
2469     if((p_FmPcdCcNode->numOfKeys + 1) > FM_PCD_MAX_NUM_OF_CC_NODES)
2470         RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("numOfKeys with new key can not be larger than 255"));
2471 
2472     if(keySize != p_FmPcdCcNode->userSizeOfExtraction)
2473         RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("keySize has to be defined as it was defined in initialization step."));
2474 
2475     if(p_FmPcdCcNode->h_FmPcd != h_FmPcd)
2476         RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("handler to FmPcd is diferent from one which was assigned to the node in the Init time"));
2477 
2478     err =  ModifyKeyCommonPart1(p_FmPcdCcNode, keyIndex, h_AdditionalParams, e_MODIFY_STATE_ADD, TRUE, FALSE);
2479     if(err)
2480         RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
2481 
2482     p_ModifyKeyParams = (t_FmPcdModifyCcKeyAdditionalParams *)*h_AdditionalParams;
2483     err = BuildNewNodeAddOrMdfyKeyAndNextEngine (h_FmPcd, p_FmPcdCcNode, keyIndex, p_FmPcdCcKeyParams, p_ModifyKeyParams, TRUE);
2484     if(err)
2485     {
2486         XX_Free(p_ModifyKeyParams);
2487         RETURN_ERROR(MAJOR, err, NO_MSG);
2488     }
2489 
2490     err = UpdatePtrWhichPointOnCrntMdfNode(p_FmPcdCcNode, p_ModifyKeyParams, h_OldLst, h_NewLst);
2491                 if(err)
2492     {
2493         ReleaseNewNodeCommonPart(p_ModifyKeyParams);
2494         XX_Free(p_ModifyKeyParams);
2495                     RETURN_ERROR(MAJOR, err, NO_MSG);
2496     }
2497 
2498     return E_OK;
2499 }
2500 
2501 t_Error FmPcdCcModifyKeyAndNextEngine(t_Handle h_FmPcd, t_Handle h_FmPcdCcNode, uint8_t keyIndex, uint8_t keySize, t_FmPcdCcKeyParams *p_FmPcdCcKeyParams, t_List *h_OldLst, t_List *h_NewLst, t_Handle *h_AdditionalParams)
2502 {
2503     t_FmPcdCcNode                       *p_FmPcdCcNode = (t_FmPcdCcNode *)h_FmPcdCcNode;
2504     t_FmPcdModifyCcKeyAdditionalParams  *p_ModifyKeyParams;
2505     t_Error                             err = E_OK;
2506 
2507     if(keyIndex > p_FmPcdCcNode->numOfKeys)
2508         RETURN_ERROR(MAJOR, E_INVALID_STATE, ("keyIndex > previousely cleared last index + 1"));
2509 
2510     if((p_FmPcdCcNode->numOfKeys + 1) > FM_PCD_MAX_NUM_OF_CC_NODES)
2511         RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("numOfKeys with new key can not be larger than 255"));
2512 
2513     if(keySize != p_FmPcdCcNode->userSizeOfExtraction)
2514         RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("keySize has to be defined as it was defined in initialization step"));
2515 
2516     if(p_FmPcdCcNode->h_FmPcd != h_FmPcd)
2517         RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("handler to FmPcd is diferent from one which was assigned to the node in the Init time"));
2518 
2519     err =  ModifyKeyCommonPart1(p_FmPcdCcNode, keyIndex, h_AdditionalParams, e_MODIFY_STATE_CHANGE, TRUE, FALSE);
2520     if(err)
2521         RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
2522 
2523     p_ModifyKeyParams = (t_FmPcdModifyCcKeyAdditionalParams *)*h_AdditionalParams;
2524 
2525     err = BuildNewNodeAddOrMdfyKeyAndNextEngine (h_FmPcd, p_FmPcdCcNode, keyIndex, p_FmPcdCcKeyParams, p_ModifyKeyParams, FALSE);
2526     if(err)
2527     {
2528         ReleaseNewNodeCommonPart(p_ModifyKeyParams);
2529         XX_Free(p_ModifyKeyParams);
2530                         RETURN_ERROR(MAJOR, err, NO_MSG);
2531     }
2532 
2533     err = UpdatePtrWhichPointOnCrntMdfNode(p_FmPcdCcNode, p_ModifyKeyParams, h_OldLst, h_NewLst);
2534     if(err)
2535     {
2536         ReleaseNewNodeCommonPart(p_ModifyKeyParams);
2537         XX_Free(p_ModifyKeyParams);
2538                         RETURN_ERROR(MAJOR, err, NO_MSG);
2539     }
2540 
2541     return E_OK;
2542 }
2543 
2544 t_Error FmPcdCcReleaseModifiedDataStructure(t_Handle h_FmPcd, t_List *h_FmPcdOldPointersLst, t_List *h_FmPcdNewPointersLst, uint16_t numOfGoodChanges, t_Handle *h_Params)
2545 {
2546     t_FmPcdModifyCcKeyAdditionalParams *p_CcNewModifyAdditionalParams = (t_FmPcdModifyCcKeyAdditionalParams *)*h_Params;
2547     t_List                          *p_Pos;
2548     t_Error                         err = E_OK;
2549     t_CcNodeInformation             ccNodeInfo, *p_CcNodeInformation;
2550     t_Handle                        h_Muram;
2551     t_FmPcdCcNode                   *p_FmPcdCcNextNode;
2552     t_List                          *p_UpdateLst;
2553 
2554     UNUSED(numOfGoodChanges);
2555 
2556     SANITY_CHECK_RETURN_ERROR(h_FmPcd,E_INVALID_HANDLE);
2557     SANITY_CHECK_RETURN_ERROR(p_CcNewModifyAdditionalParams->h_CurrentNode,E_INVALID_HANDLE);
2558     SANITY_CHECK_RETURN_ERROR(h_FmPcdOldPointersLst,E_INVALID_HANDLE);
2559     SANITY_CHECK_RETURN_ERROR(h_FmPcdNewPointersLst,E_INVALID_HANDLE);
2560     SANITY_CHECK_RETURN_ERROR((numOfGoodChanges == LIST_NumOfObjs(h_FmPcdOldPointersLst)),E_INVALID_STATE);
2561     SANITY_CHECK_RETURN_ERROR((numOfGoodChanges == LIST_NumOfObjs(h_FmPcdNewPointersLst)),E_INVALID_STATE);
2562     SANITY_CHECK_RETURN_ERROR((LIST_NumOfObjs(h_FmPcdOldPointersLst) == LIST_NumOfObjs(h_FmPcdNewPointersLst)),E_INVALID_STATE);
2563 
2564     /*we don't update subtree of the new node with new tree because it was done in the previose stage*/
2565     if(p_CcNewModifyAdditionalParams->h_NodeForAdd)
2566     {
2567         p_FmPcdCcNextNode = (t_FmPcdCcNode*)p_CcNewModifyAdditionalParams->h_NodeForAdd;
2568         if(!p_CcNewModifyAdditionalParams->tree)
2569             p_UpdateLst = &p_FmPcdCcNextNode->ccPrevNodesLst;
2570         else
2571             p_UpdateLst = &p_FmPcdCcNextNode->ccTreeIdLst;
2572         p_CcNodeInformation = FindNodeInfoInReleventLst(p_UpdateLst, p_CcNewModifyAdditionalParams->h_CurrentNode);
2573         if(p_CcNodeInformation)
2574             p_CcNodeInformation->index++;
2575         else
2576         {
2577             memset(&ccNodeInfo, 0, sizeof(t_CcNodeInformation));
2578             ccNodeInfo.h_CcNode = (t_Handle)p_CcNewModifyAdditionalParams->h_CurrentNode;
2579             ccNodeInfo.index = 1;
2580             EnqueueNodeInfoToRelevantLst(p_UpdateLst, &ccNodeInfo);
2581         }
2582     }
2583 
2584      if(p_CcNewModifyAdditionalParams->h_NodeForRmv)
2585     {
2586 
2587         p_FmPcdCcNextNode = (t_FmPcdCcNode*)p_CcNewModifyAdditionalParams->h_NodeForRmv;
2588         if(!p_CcNewModifyAdditionalParams->tree)
2589         {
2590             p_UpdateLst = &p_FmPcdCcNextNode->ccPrevNodesLst;
2591             LIST_FOR_EACH(p_Pos, &p_FmPcdCcNextNode->ccTreesLst)
2592             {
2593                 p_CcNodeInformation = CC_NODE_F_OBJECT(p_Pos);
2594                 ASSERT_COND(p_CcNodeInformation->h_CcNode);
2595                 err = FmPcdCcSetRequiredAction(h_FmPcd,
2596                                                UPDATE_CC_WITH_DELETE_TREE,
2597                                                &((t_FmPcdCcNode *)(p_CcNewModifyAdditionalParams->h_CurrentNode))->nextEngineAndRequiredAction[p_CcNewModifyAdditionalParams->keyIndex],
2598                                                PTR_MOVE(((t_FmPcdCcNode *)(p_CcNewModifyAdditionalParams->h_CurrentNode))->h_AdTable, p_CcNewModifyAdditionalParams->keyIndex*FM_PCD_CC_AD_ENTRY_SIZE),
2599                                                1,
2600                                                p_CcNodeInformation->h_CcNode);
2601             }
2602         }
2603         else
2604         {
2605             p_UpdateLst = &p_FmPcdCcNextNode->ccTreeIdLst;
2606             err =  FmPcdCcSetRequiredAction(h_FmPcd,
2607                                             UPDATE_CC_WITH_DELETE_TREE,
2608                                             &((t_FmPcdCcTree *)(p_CcNewModifyAdditionalParams->h_CurrentNode))->nextEngineAndRequiredAction[p_CcNewModifyAdditionalParams->keyIndex],
2609                                             UINT_TO_PTR(((t_FmPcdCcTree *)(p_CcNewModifyAdditionalParams->h_CurrentNode))->ccTreeBaseAddr + p_CcNewModifyAdditionalParams->keyIndex*FM_PCD_CC_AD_ENTRY_SIZE),
2610                                             1,
2611                                             p_CcNewModifyAdditionalParams->h_CurrentNode);
2612         }
2613         if(err)
2614             return err;
2615 
2616         /*we remove from the  subtree of the removed node tree because it wasn't done in the previose stage*/
2617         /*update ccPrevNodesLst or ccTreeIdLst of the removed node*/
2618         /*update of the nodeOwner*/
2619         p_CcNodeInformation = FindNodeInfoInReleventLst(p_UpdateLst, p_CcNewModifyAdditionalParams->h_CurrentNode);
2620         ASSERT_COND(p_CcNodeInformation);
2621         ASSERT_COND(p_CcNodeInformation->index);
2622         p_CcNodeInformation->index--;
2623         if(p_CcNodeInformation->index == 0)
2624            DequeueNodeInfoFromRelevantLst(p_UpdateLst,p_CcNewModifyAdditionalParams->h_CurrentNode);
2625         ASSERT_COND(LIST_NumOfObjs(&p_FmPcdCcNextNode->ccTreesLst) == 1);
2626         UpdateNodeOwner(p_FmPcdCcNextNode, FALSE);
2627     }
2628 
2629 #ifdef FM_PCD_CC_MANIP
2630     if(p_CcNewModifyAdditionalParams->h_ManipForRmv)
2631         FmPcdManipUpdateOwner(p_CcNewModifyAdditionalParams->h_ManipForRmv, FALSE);
2632 #endif /* FM_PCD_CC_MANIP */
2633 
2634     h_Muram = FmPcdGetMuramHandle(h_FmPcd);
2635     ASSERT_COND(h_Muram);
2636 
2637     /*we release new AD which was allocated and updated for copy from to actual AD*/
2638     LIST_FOR_EACH(p_Pos, h_FmPcdNewPointersLst)
2639     {
2640         p_CcNodeInformation = CC_NODE_F_OBJECT(p_Pos);
2641         ASSERT_COND(p_CcNodeInformation->h_CcNode);
2642         FM_MURAM_FreeMem(h_Muram, p_CcNodeInformation->h_CcNode);
2643 
2644      }
2645 
2646     /*free Old data structure if it has to be freed - new data structure was allocated*/
2647     if(p_CcNewModifyAdditionalParams->p_AdTableOld)
2648         FM_MURAM_FreeMem(h_Muram,p_CcNewModifyAdditionalParams->p_AdTableOld);
2649     if(p_CcNewModifyAdditionalParams->p_KeysMatchTableOld)
2650         FM_MURAM_FreeMem(h_Muram,p_CcNewModifyAdditionalParams->p_KeysMatchTableOld);
2651 
2652     /*update current modified node with changed fields if it's required*/
2653     if(!p_CcNewModifyAdditionalParams->tree)
2654     {
2655         if(p_CcNewModifyAdditionalParams->p_AdTableNew)
2656             ((t_FmPcdCcNode *)(p_CcNewModifyAdditionalParams->h_CurrentNode))->h_AdTable    = p_CcNewModifyAdditionalParams->p_AdTableNew;
2657         if(p_CcNewModifyAdditionalParams->numOfKeys)
2658             ((t_FmPcdCcNode *)(p_CcNewModifyAdditionalParams->h_CurrentNode))->numOfKeys    = p_CcNewModifyAdditionalParams->numOfKeys;
2659         if(p_CcNewModifyAdditionalParams->p_KeysMatchTableNew)
2660             ((t_FmPcdCcNode *)(p_CcNewModifyAdditionalParams->h_CurrentNode))->h_KeysMatchTable    = p_CcNewModifyAdditionalParams->p_KeysMatchTableNew;
2661         memcpy(((t_FmPcdCcNode *)(p_CcNewModifyAdditionalParams->h_CurrentNode))->nextEngineAndRequiredAction, &p_CcNewModifyAdditionalParams->nextEngineAndRequiredAction, sizeof(t_FmPcdCcNextEngineAndRequiredActionParams) * (FM_PCD_MAX_NUM_OF_KEYS));
2662     }
2663     else
2664         memcpy(&((t_FmPcdCcTree *)(p_CcNewModifyAdditionalParams->h_CurrentNode))->nextEngineAndRequiredAction, &p_CcNewModifyAdditionalParams->nextEngineAndRequiredAction, sizeof(t_FmPcdCcNextEngineAndRequiredActionParams) * (((t_FmPcdCcTree *)(p_CcNewModifyAdditionalParams->h_CurrentNode))->numOfEntries));
2665 
2666     ReleaseLst(h_FmPcdOldPointersLst);
2667     ReleaseLst(h_FmPcdNewPointersLst);
2668     XX_Free(p_CcNewModifyAdditionalParams);
2669 
2670     return E_OK;
2671 }
2672 
2673 uint32_t FmPcdCcGetNodeAddrOffsetFromNodeInfo(t_Handle h_FmPcd, t_Handle h_Pointer)
2674 {
2675     t_FmPcd                         *p_FmPcd = (t_FmPcd *)h_FmPcd;
2676     t_CcNodeInformation             *p_CcNodeInfo;
2677 
2678     SANITY_CHECK_RETURN_VALUE(h_FmPcd,E_INVALID_HANDLE, (uint32_t)ILLEGAL_BASE);
2679 
2680     p_CcNodeInfo = CC_NODE_F_OBJECT(h_Pointer);
2681     return (uint32_t)(XX_VirtToPhys(p_CcNodeInfo->h_CcNode) - p_FmPcd->physicalMuramBase);
2682 }
2683 
2684 t_Error FmPcdCcGetGrpParams(t_Handle h_FmPcdCcTree, uint8_t grpId, uint32_t *p_GrpBits, uint8_t *p_GrpBase)
2685 {
2686     t_FmPcdCcTree *p_FmPcdCcTree = (t_FmPcdCcTree *) h_FmPcdCcTree;
2687 
2688     SANITY_CHECK_RETURN_ERROR(h_FmPcdCcTree, E_INVALID_HANDLE);
2689 
2690     if(grpId >= p_FmPcdCcTree->numOfGrps)
2691         RETURN_ERROR(MAJOR, E_INVALID_HANDLE, ("grpId you asked > numOfGroup of relevant tree"));
2692     *p_GrpBits = p_FmPcdCcTree->fmPcdGroupParam[grpId].totalBitsMask;
2693     *p_GrpBase = p_FmPcdCcTree->fmPcdGroupParam[grpId].baseGroupEntry;
2694     return E_OK;
2695 }
2696 
2697 t_Error  FmPcdCcBindTree(t_Handle h_FmPcd, t_Handle  h_FmPcdCcTree,  uint32_t  *p_Offset, t_Handle h_FmPort)
2698 {
2699     t_FmPcd             *p_FmPcd = (t_FmPcd*)h_FmPcd;
2700     t_FmPcdCcTree       *p_FmPcdCcTree = (t_FmPcdCcTree *)h_FmPcdCcTree;
2701     t_Error             err = E_OK;
2702 
2703     SANITY_CHECK_RETURN_ERROR(p_FmPcd,E_INVALID_HANDLE);
2704     SANITY_CHECK_RETURN_ERROR(p_FmPcdCcTree,E_INVALID_STATE);
2705 
2706     FmPcdCcUpdateTreeOwner(p_FmPcdCcTree, TRUE);
2707 
2708     *p_Offset = (uint32_t)(XX_VirtToPhys(UINT_TO_PTR(p_FmPcdCcTree->ccTreeBaseAddr)) -
2709                            p_FmPcd->physicalMuramBase);
2710 
2711     err = CcUpdateParams(h_FmPcd, h_FmPort, h_FmPcdCcTree, TRUE);
2712 
2713     return err;
2714 }
2715 
2716 t_Error FmPcdCcUnbindTree(t_Handle h_FmPcd, t_Handle  h_FmPcdCcTree)
2717 {
2718     t_FmPcdCcTree       *p_FmPcdCcTree = (t_FmPcdCcTree *)h_FmPcdCcTree;
2719 
2720     UNUSED(h_FmPcd);
2721 
2722     SANITY_CHECK_RETURN_ERROR(p_FmPcdCcTree,E_INVALID_HANDLE);
2723 
2724     FmPcdCcUpdateTreeOwner(p_FmPcdCcTree, FALSE);
2725 
2726     return E_OK;
2727 }
2728 
2729 t_Error FmPcdCcTreeTryLock(t_Handle h_FmPcdCcTree)
2730 {
2731     if (TRY_LOCK(NULL, &((t_FmPcdCcTree *)h_FmPcdCcTree)->lock))
2732         return E_OK;
2733     return ERROR_CODE(E_BUSY);
2734 }
2735 
2736 t_Error FmPcdCcNodeTreeTryLock(t_Handle h_FmPcd,t_Handle h_FmPcdCcNode, t_List *p_List)
2737 {
2738     t_FmPcdCcNode   *p_FmPcdCcNode = (t_FmPcdCcNode *)h_FmPcdCcNode;
2739     t_List          *p_Pos;
2740     t_CcNodeInformation    *p_CcNodeInfo, nodeInfo;
2741     t_Error         err = E_OK;
2742 
2743     UNUSED(h_FmPcd);
2744 
2745     if(LIST_IsEmpty(&p_FmPcdCcNode->ccTreesLst))
2746         RETURN_ERROR(MAJOR, E_NOT_AVAILABLE, ("asked for more nodes in CC than MAX"))  ;
2747     LIST_FOR_EACH(p_Pos, &p_FmPcdCcNode->ccTreesLst)
2748     {
2749         p_CcNodeInfo = CC_NODE_F_OBJECT(p_Pos);
2750         ASSERT_COND(p_CcNodeInfo->h_CcNode);
2751         err = FmPcdCcTreeTryLock(p_CcNodeInfo->h_CcNode);
2752         if(err == E_OK)
2753         {
2754             memset(&nodeInfo, 0, sizeof(t_CcNodeInformation));
2755             nodeInfo.h_CcNode = p_CcNodeInfo->h_CcNode;
2756             EnqueueNodeInfoToRelevantLst(p_List, &nodeInfo);
2757         }
2758         else
2759             FmPcdCcNodeTreeReleaseLock(p_List);
2760     }
2761 
2762     return err;
2763 }
2764 
2765 t_Handle FM_PCD_CcBuildTree(t_Handle h_FmPcd, t_FmPcdCcTreeParams *p_PcdGroupsParam)
2766 {
2767     t_FmPcd                     *p_FmPcd = (t_FmPcd *)h_FmPcd;
2768     t_Error                     err = E_OK;
2769     int                         i = 0, j = 0, k = 0;
2770     t_FmPcdCcTree               *p_FmPcdCcTree;
2771     uint8_t                     numOfEntries;
2772     t_Handle                    p_CcTreeTmp;
2773     t_FmPcdCcGrpParams          *p_FmPcdCcGroupParams;
2774     t_FmPcdCcNextEngineAndRequiredActionParams   params[16];
2775     t_NetEnvParams              netEnvParams;
2776     uint8_t                     lastOne = 0;
2777     uint32_t                    requiredAction = 0;
2778     t_FmPcdCcNode               *p_FmPcdCcNextNode;
2779     t_CcNodeInformation         ccNodeInfo, *p_CcInformation;
2780 
2781     SANITY_CHECK_RETURN_VALUE(h_FmPcd,E_INVALID_HANDLE, NULL);
2782     SANITY_CHECK_RETURN_VALUE(p_PcdGroupsParam,E_INVALID_HANDLE, NULL);
2783 
2784     if (p_PcdGroupsParam->numOfGrps > FM_PCD_MAX_NUM_OF_CC_GROUPS)
2785     {
2786         REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("numOfGrps should not exceed %d", FM_PCD_MAX_NUM_OF_CC_GROUPS));
2787         return NULL;
2788     }
2789 
2790     p_FmPcdCcTree = (t_FmPcdCcTree*)XX_Malloc(sizeof(t_FmPcdCcTree));
2791     if(!p_FmPcdCcTree)
2792     {
2793         REPORT_ERROR(MAJOR, E_NO_MEMORY, ("PCD tree structure"));
2794         return NULL;
2795     }
2796     memset(p_FmPcdCcTree, 0, sizeof(t_FmPcdCcTree)) ;
2797     memset(params, 0, 16 * sizeof(t_FmPcdCcNextEngineParams));
2798 
2799     INIT_LIST(&p_FmPcdCcTree->fmPortsLst);
2800 
2801     numOfEntries = 0;
2802     p_FmPcdCcTree->netEnvId = (uint8_t)(PTR_TO_UINT(p_PcdGroupsParam->h_NetEnv)-1);
2803     for(i = 0; i < p_PcdGroupsParam->numOfGrps; i++)
2804     {
2805         p_FmPcdCcGroupParams = &p_PcdGroupsParam->ccGrpParams[i];
2806 
2807         if (p_FmPcdCcGroupParams->numOfDistinctionUnits > FM_PCD_MAX_NUM_OF_CC_UNITS)
2808         {
2809             DeleteTree(p_FmPcdCcTree,p_FmPcd);
2810             REPORT_ERROR(MAJOR, E_INVALID_VALUE,
2811                          ("numOfDistinctionUnits (group %d) should not exceed %d", i, FM_PCD_MAX_NUM_OF_CC_UNITS));
2812             return NULL;
2813         }
2814 
2815         p_FmPcdCcTree->fmPcdGroupParam[i].baseGroupEntry = numOfEntries;
2816         p_FmPcdCcTree->fmPcdGroupParam[i].numOfEntriesInGroup =(uint8_t)( 0x01 << p_FmPcdCcGroupParams->numOfDistinctionUnits);
2817         numOfEntries += p_FmPcdCcTree->fmPcdGroupParam[i].numOfEntriesInGroup;
2818         if(numOfEntries > 16)
2819         {
2820             DeleteTree(p_FmPcdCcTree,p_FmPcd);
2821             REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("numOfEntries can not be larger than 16"));
2822             return NULL;
2823         }
2824         if(lastOne)
2825         {
2826             if(p_FmPcdCcTree->fmPcdGroupParam[i].numOfEntriesInGroup > lastOne)
2827             {
2828                 DeleteTree(p_FmPcdCcTree,p_FmPcd);
2829                 REPORT_ERROR(MAJOR, E_CONFLICT, ("numOfEntries per group must be set in descending order"));
2830                 return NULL;
2831             }
2832         }
2833 
2834         lastOne = p_FmPcdCcTree->fmPcdGroupParam[i].numOfEntriesInGroup;
2835 
2836         netEnvParams.netEnvId = p_FmPcdCcTree->netEnvId;
2837         netEnvParams.numOfDistinctionUnits = p_FmPcdCcGroupParams->numOfDistinctionUnits;
2838         memcpy(netEnvParams.unitIds, &p_FmPcdCcGroupParams->unitIds, (sizeof(uint8_t)) * p_FmPcdCcGroupParams->numOfDistinctionUnits);
2839         err = PcdGetUnitsVector(p_FmPcd, &netEnvParams);
2840         if(err)
2841         {
2842             DeleteTree(p_FmPcdCcTree,p_FmPcd);
2843             REPORT_ERROR(MAJOR, err, NO_MSG);
2844             return NULL;
2845         }
2846 
2847         p_FmPcdCcTree->fmPcdGroupParam[i].totalBitsMask = netEnvParams.vector;
2848         for(j = 0; j < p_FmPcdCcTree->fmPcdGroupParam[i].numOfEntriesInGroup; j++)
2849         {
2850             err = ValidateNextEngineParams(h_FmPcd,&p_FmPcdCcGroupParams->nextEnginePerEntriesInGrp[j]);
2851             if(err)
2852             {
2853                 DeleteTree(p_FmPcdCcTree,p_FmPcd);
2854                 REPORT_ERROR(MAJOR, err, (NO_MSG));
2855                 return NULL;
2856             }
2857 
2858 #ifdef FM_PCD_CC_MANIP
2859             if(p_FmPcdCcGroupParams->nextEnginePerEntriesInGrp[j].h_Manip)
2860             {
2861                 err = FmPcdManipCheckParamsForCcNextEgine(&p_FmPcdCcGroupParams->nextEnginePerEntriesInGrp[j], &requiredAction);
2862                 if(err)
2863                 {
2864                     DeleteTree(p_FmPcdCcTree,p_FmPcd);
2865                     REPORT_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
2866                     return NULL;
2867                 }
2868            }
2869 #endif /* FM_PCD_CC_MANIP */
2870 
2871            memcpy(&params[k].nextEngineParams, &p_FmPcdCcGroupParams->nextEnginePerEntriesInGrp[j], sizeof(t_FmPcdCcNextEngineParams));
2872            requiredAction |= UPDATE_CC_WITH_TREE;
2873            params[k].requiredAction = requiredAction;
2874            k++;
2875         }
2876     }
2877 
2878     p_FmPcdCcTree->numOfEntries = (uint8_t)k;
2879     p_FmPcdCcTree->numOfGrps = p_PcdGroupsParam->numOfGrps;
2880     p_FmPcdCcTree->ccTreeBaseAddr =
2881         PTR_TO_UINT(FM_MURAM_AllocMem(FmPcdGetMuramHandle(h_FmPcd),
2882                                       (uint32_t)( k * FM_PCD_CC_AD_ENTRY_SIZE),
2883                                       FM_PCD_CC_AD_TABLE_ALIGN));
2884 
2885     if(!p_FmPcdCcTree->ccTreeBaseAddr)
2886     {
2887         DeleteTree(p_FmPcdCcTree,p_FmPcd);
2888         REPORT_ERROR(MAJOR, E_NO_MEMORY, ("No memory"));
2889         return NULL;
2890     }
2891     IOMemSet32(UINT_TO_PTR(p_FmPcdCcTree->ccTreeBaseAddr), 0, (uint32_t)(k * FM_PCD_CC_AD_ENTRY_SIZE));
2892 
2893     p_CcTreeTmp = UINT_TO_PTR(p_FmPcdCcTree->ccTreeBaseAddr);
2894 
2895     j = 0;
2896     for(i = 0; i < numOfEntries; i++)
2897     {
2898         NextStepAd(p_CcTreeTmp,&params[i].nextEngineParams,p_FmPcd);
2899         p_CcTreeTmp = PTR_MOVE(p_CcTreeTmp, FM_PCD_CC_AD_ENTRY_SIZE);
2900         memcpy(&p_FmPcdCcTree->nextEngineAndRequiredAction[i], &params[i], sizeof(t_FmPcdCcNextEngineAndRequiredActionParams));
2901         if(p_FmPcdCcTree->nextEngineAndRequiredAction[i].nextEngineParams.nextEngine== e_FM_PCD_CC)
2902         {
2903             p_FmPcdCcNextNode = (t_FmPcdCcNode*)p_FmPcdCcTree->nextEngineAndRequiredAction[i].nextEngineParams.params.ccParams.h_CcNode;
2904             if(!IsNodeInModifiedState((t_Handle)p_FmPcdCcNextNode))
2905             {
2906                 memset(&ccNodeInfo, 0, sizeof(t_CcNodeInformation));
2907                 ccNodeInfo.h_CcNode = (t_Handle)p_FmPcdCcTree;
2908                 ccNodeInfo.index = 1;
2909                 EnqueueNodeInfoToRelevantLst(&p_FmPcdCcNextNode->ccTreeIdLst, &ccNodeInfo);
2910                 UpdateNodeWithModifiedState((t_Handle)p_FmPcdCcNextNode, TRUE);
2911             }
2912             else
2913             {
2914                 p_CcInformation = FindNodeInfoInReleventLst(&p_FmPcdCcNextNode->ccTreeIdLst,(t_Handle)p_FmPcdCcTree);
2915                 ASSERT_COND(p_CcInformation);
2916                 p_CcInformation->index++;
2917             }
2918         }
2919     }
2920 
2921     FmPcdIncNetEnvOwners(h_FmPcd, p_FmPcdCcTree->netEnvId);
2922     p_CcTreeTmp = UINT_TO_PTR(p_FmPcdCcTree->ccTreeBaseAddr);
2923 
2924     for(i = 0; i < p_FmPcdCcTree->numOfEntries ; i++)
2925     {
2926         if(p_FmPcdCcTree->nextEngineAndRequiredAction[i].nextEngineParams.nextEngine == e_FM_PCD_CC)
2927         {
2928             p_FmPcdCcNextNode = (t_FmPcdCcNode*)p_FmPcdCcTree->nextEngineAndRequiredAction[i].nextEngineParams.params.ccParams.h_CcNode;
2929 
2930             if(IsNodeInModifiedState((t_Handle)p_FmPcdCcNextNode))
2931                 UpdateNodeWithModifiedState((t_Handle)p_FmPcdCcNextNode, FALSE);
2932         }
2933     }
2934 
2935     for(i = 0; i < numOfEntries; i++)
2936     {
2937         if(p_FmPcdCcTree->nextEngineAndRequiredAction[i].requiredAction)
2938         {
2939             err = FmPcdCcSetRequiredAction(h_FmPcd, p_FmPcdCcTree->nextEngineAndRequiredAction[i].requiredAction, &p_FmPcdCcTree->nextEngineAndRequiredAction[i], p_CcTreeTmp,1, p_FmPcdCcTree);
2940             if(err)
2941             {
2942                 DeleteTree(p_FmPcdCcTree,p_FmPcd);
2943                 REPORT_ERROR(MAJOR, E_NO_MEMORY, ("No memory"));
2944                 return NULL;
2945             }
2946             p_CcTreeTmp = PTR_MOVE(p_CcTreeTmp, FM_PCD_CC_AD_ENTRY_SIZE);
2947         }
2948     }
2949 
2950     return p_FmPcdCcTree;
2951 }
2952 
2953 t_Error FM_PCD_CcDeleteTree(t_Handle h_FmPcd, t_Handle h_CcTree)
2954 {
2955     t_FmPcd                     *p_FmPcd = (t_FmPcd *)h_FmPcd;
2956     t_FmPcdCcTree               *p_CcTree = (t_FmPcdCcTree *)h_CcTree;
2957     int                         i= 0;
2958 
2959     SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
2960     SANITY_CHECK_RETURN_ERROR(p_CcTree,E_INVALID_STATE);
2961 
2962     FmPcdDecNetEnvOwners(h_FmPcd, p_CcTree->netEnvId);
2963 
2964     if(p_CcTree->owners)
2965         RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("the tree with this ID can not be removed because this tree is occupied, first - unbind this tree"));
2966 
2967     for(i = 0; i <p_CcTree->numOfEntries; i++)
2968     {
2969         if(p_CcTree->nextEngineAndRequiredAction[i].nextEngineParams.nextEngine == e_FM_PCD_CC)
2970             UpdateNodeOwner(p_CcTree->nextEngineAndRequiredAction[i].nextEngineParams.params.ccParams.h_CcNode, FALSE);
2971     }
2972 
2973 #ifdef FM_PCD_CC_MANIP
2974     for(i = 0; i < p_CcTree->numOfEntries; i++)
2975     {
2976         if(p_CcTree->nextEngineAndRequiredAction[i].nextEngineParams.h_Manip)
2977             FmPcdManipUpdateOwner(p_CcTree->nextEngineAndRequiredAction[i].nextEngineParams.h_Manip, FALSE);
2978     }
2979 #endif /* FM_PCD_CC_MANIP */
2980 
2981     DeleteTree(p_CcTree, p_FmPcd);
2982     return E_OK;
2983 }
2984 
2985 t_Handle FM_PCD_CcSetNode(t_Handle h_FmPcd, t_FmPcdCcNodeParams *p_CcNodeParam)
2986 {
2987     t_FmPcd             *p_FmPcd = (t_FmPcd *) h_FmPcd;
2988     t_FmPcdCcNode       *p_FmPcdCcNode, *p_FmPcdCcNextNode;
2989     t_Error             err = E_OK;
2990     int                 tmp, size;
2991     bool                glblMask = FALSE;
2992     t_FmPcdCcKeyParams  *p_KeyParams;
2993     t_Handle            p_KeysMatchTblTmp;
2994     t_Handle            p_AdTableTmp;
2995     bool                fullField = FALSE;
2996     ccPrivateInfo_t     icCode = CC_PRIVATE_INFO_NONE;
2997     bool                isKeyTblAlloc, fromIc = FALSE;
2998     t_CcNodeInformation ccNodeInfo, *p_CcInformation;
2999 
3000     SANITY_CHECK_RETURN_VALUE(h_FmPcd,E_INVALID_HANDLE,NULL);
3001 
3002     /*
3003     if (!p_CcNodeParam->keysParams.keySize ||
3004         !p_CcNodeParam->keysParams.numOfKeys)
3005     {
3006         REPORT_ERROR(MAJOR, E_INVALID_STATE, ("At least one key of keySize > 0 must be defined."));
3007         return NULL;
3008     }
3009     */
3010     p_FmPcdCcNode = (t_FmPcdCcNode*)XX_Malloc(sizeof(t_FmPcdCcNode));
3011     if(!p_FmPcdCcNode)
3012     {
3013         REPORT_ERROR(MAJOR, E_NO_MEMORY, ("No memory"));
3014         return NULL;
3015     }
3016     memset(p_FmPcdCcNode, 0, sizeof(t_FmPcdCcNode));
3017 
3018     p_FmPcdCcNode->p_GlblMask = (t_Handle)XX_Malloc(CC_GLBL_MASK_SIZE * sizeof(uint8_t));
3019     memset(p_FmPcdCcNode->p_GlblMask, 0, CC_GLBL_MASK_SIZE * sizeof(uint8_t));
3020 
3021     p_FmPcdCcNode->numOfKeys = p_CcNodeParam->keysParams.numOfKeys;
3022 
3023     p_FmPcdCcNode->h_FmPcd = h_FmPcd;
3024 
3025     INIT_LIST(&p_FmPcdCcNode->ccPrevNodesLst);
3026     INIT_LIST(&p_FmPcdCcNode->ccTreeIdLst);
3027     INIT_LIST(&p_FmPcdCcNode->ccTreesLst);
3028 
3029     if((p_CcNodeParam->extractCcParams.type == e_FM_PCD_EXTRACT_BY_HDR) &&
3030         ((p_CcNodeParam->extractCcParams.extractByHdr.hdr == HEADER_TYPE_IPv4) ||
3031         (p_CcNodeParam->extractCcParams.extractByHdr.hdr == HEADER_TYPE_IPv6)) &&
3032         (p_CcNodeParam->extractCcParams.extractByHdr.type == e_FM_PCD_EXTRACT_FULL_FIELD) &&
3033         ((p_CcNodeParam->extractCcParams.extractByHdr.extractByHdrType.fullField.ipv6 == NET_HEADER_FIELD_IPv6_HOP_LIMIT) ||
3034         (p_CcNodeParam->extractCcParams.extractByHdr.extractByHdrType.fullField.ipv4 == NET_HEADER_FIELD_IPv4_TTL)))
3035     {
3036             err = Ipv4TtlOrIpv6HopLimiCheckParams(h_FmPcd, p_CcNodeParam, p_FmPcdCcNode, &isKeyTblAlloc);
3037             glblMask = FALSE;
3038 
3039     }
3040     else if((p_CcNodeParam->extractCcParams.type == e_FM_PCD_EXTRACT_NON_HDR) &&
3041         ((p_CcNodeParam->extractCcParams.extractNonHdr.src == e_FM_PCD_EXTRACT_FROM_KEY) ||
3042            (p_CcNodeParam->extractCcParams.extractNonHdr.src == e_FM_PCD_EXTRACT_FROM_HASH) ||
3043            (p_CcNodeParam->extractCcParams.extractNonHdr.src == e_FM_PCD_EXTRACT_FROM_FLOW_ID)))
3044     {
3045         if((p_CcNodeParam->extractCcParams.extractNonHdr.src == e_FM_PCD_EXTRACT_FROM_FLOW_ID) &&
3046             (p_CcNodeParam->extractCcParams.extractNonHdr.offset != 0))
3047         {
3048             REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("In the case of the extraction from e_FM_PCD_EXTRACT_FROM_FLOW_ID offset has to be 0"));
3049             return NULL;
3050         }
3051 
3052         icCode = IcDefineCode(p_CcNodeParam);
3053         fromIc = TRUE;
3054         if(icCode == CC_PRIVATE_INFO_NONE)
3055         {
3056             REPORT_ERROR(MAJOR, E_INVALID_STATE, ("user asked extraction from IC and field in internal context or action wasn't initialized in the right way"));
3057             return NULL;
3058         }
3059 
3060         if((icCode == CC_PRIVATE_INFO_IC_DEQ_FQID_INDEX_LOOKUP) || (icCode == CC_PRIVATE_INFO_IC_HASH_INDEX_LOOKUP))
3061         {
3062             err = IcHashIndexedCheckParams(h_FmPcd, p_CcNodeParam, p_FmPcdCcNode, &isKeyTblAlloc);
3063 
3064             glblMask = TRUE;
3065         }
3066         else
3067         {
3068             err = CheckParams(h_FmPcd, p_CcNodeParam,p_FmPcdCcNode, &isKeyTblAlloc);
3069             if(p_FmPcdCcNode->glblMaskSize)
3070                 glblMask = TRUE;
3071         }
3072     }
3073     else
3074     {
3075         err = CheckParams(h_FmPcd, p_CcNodeParam,p_FmPcdCcNode, &isKeyTblAlloc);
3076         if(p_FmPcdCcNode->glblMaskSize)
3077             glblMask = TRUE;
3078     }
3079 
3080     if(err)
3081     {
3082         DeleteNode(p_FmPcdCcNode);
3083         REPORT_ERROR(MAJOR, err, NO_MSG);
3084         return NULL;
3085     }
3086 
3087     switch(p_CcNodeParam->extractCcParams.type)
3088     {
3089         case(e_FM_PCD_EXTRACT_BY_HDR):
3090             switch(p_CcNodeParam->extractCcParams.extractByHdr.type)
3091             {
3092                 case(e_FM_PCD_EXTRACT_FULL_FIELD):
3093                     p_FmPcdCcNode->parseCode = GetFullFieldParseCode(p_CcNodeParam->extractCcParams.extractByHdr.hdr, p_CcNodeParam->extractCcParams.extractByHdr.hdrIndex,
3094                                                                     p_CcNodeParam->extractCcParams.extractByHdr.extractByHdrType.fullField);
3095                     GetSizeHeaderField(p_CcNodeParam->extractCcParams.extractByHdr.hdr, p_CcNodeParam->extractCcParams.extractByHdr.extractByHdrType.fullField, &p_FmPcdCcNode->sizeOfExtraction);
3096                     fullField = TRUE;
3097                     if((p_FmPcdCcNode->parseCode != CC_PC_FF_TCI1) && (p_FmPcdCcNode->parseCode != CC_PC_FF_TCI2) &&
3098                        (p_FmPcdCcNode->parseCode != CC_PC_FF_MPLS1) && (p_FmPcdCcNode->parseCode != CC_PC_FF_MPLS1) &&
3099                        (p_FmPcdCcNode->parseCode != CC_PC_FF_IPV4IPTOS_TC1) &&  (p_FmPcdCcNode->parseCode != CC_PC_FF_IPV4IPTOS_TC2) &&
3100                        (p_FmPcdCcNode->parseCode != CC_PC_FF_IPTOS_IPV6TC1_IPV6FLOW1) &&  (p_FmPcdCcNode->parseCode != CC_PC_FF_IPTOS_IPV6TC2_IPV6FLOW2) &&
3101                        glblMask)
3102                     {
3103                         glblMask = FALSE;
3104                         p_FmPcdCcNode->glblMaskSize = 4;
3105                         p_FmPcdCcNode->lclMask = TRUE;
3106                     }
3107                     break;
3108                 case(e_FM_PCD_EXTRACT_FROM_HDR):
3109                         p_FmPcdCcNode->sizeOfExtraction = p_CcNodeParam->extractCcParams.extractByHdr.extractByHdrType.fromHdr.size;
3110                         p_FmPcdCcNode->offset =  p_CcNodeParam->extractCcParams.extractByHdr.extractByHdrType.fromHdr.offset;
3111                         p_FmPcdCcNode->parseCode = GetPrParseCode(p_CcNodeParam->extractCcParams.extractByHdr.hdr, p_CcNodeParam->extractCcParams.extractByHdr.hdrIndex,
3112                                                                 p_FmPcdCcNode->offset,glblMask, &p_FmPcdCcNode->prsArrayOffset);
3113                         break;
3114                 case(e_FM_PCD_EXTRACT_FROM_FIELD):
3115                         p_FmPcdCcNode->offset = p_CcNodeParam->extractCcParams.extractByHdr.extractByHdrType.fromField.offset;
3116                         p_FmPcdCcNode->sizeOfExtraction = p_CcNodeParam->extractCcParams.extractByHdr.extractByHdrType.fromField.size;
3117                         p_FmPcdCcNode->parseCode = GetFieldParseCode(p_CcNodeParam->extractCcParams.extractByHdr.hdr, p_CcNodeParam->extractCcParams.extractByHdr.extractByHdrType.fromField.field,
3118                                                     p_FmPcdCcNode->offset,&p_FmPcdCcNode->prsArrayOffset,
3119                                                     p_CcNodeParam->extractCcParams.extractByHdr.hdrIndex);
3120                         break;
3121                 default:
3122                     DeleteNode(p_FmPcdCcNode);
3123                     REPORT_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG);
3124                     return NULL;
3125             }
3126             break;
3127         case(e_FM_PCD_EXTRACT_NON_HDR):
3128             /* get the field code for the generic extract */
3129             p_FmPcdCcNode->sizeOfExtraction = p_CcNodeParam->extractCcParams.extractNonHdr.size;
3130             p_FmPcdCcNode->offset =  p_CcNodeParam->extractCcParams.extractNonHdr.offset;
3131             p_FmPcdCcNode->parseCode = GetGenParseCode(p_CcNodeParam->extractCcParams.extractNonHdr.src, p_FmPcdCcNode->offset, glblMask, &p_FmPcdCcNode->prsArrayOffset, fromIc,icCode);
3132 
3133             if(p_FmPcdCcNode->parseCode == CC_PC_GENERIC_IC_HASH_INDEXED)
3134             {
3135                 if((p_FmPcdCcNode->offset + p_FmPcdCcNode->sizeOfExtraction) > 64)
3136                 {
3137                      DeleteNode(p_FmPcdCcNode);
3138                      REPORT_ERROR(MAJOR, E_INVALID_SELECTION,("when node of the type CC_PC_GENERIC_IC_HASH_INDEXED offset + size can not be bigger then size of HASH 64 bits (8 bytes)"));
3139                      return NULL;
3140                 }
3141             }
3142             if((p_FmPcdCcNode->parseCode == CC_PC_GENERIC_IC_GMASK) || (p_FmPcdCcNode->parseCode == CC_PC_GENERIC_IC_HASH_INDEXED))
3143             {
3144                 p_FmPcdCcNode->offset +=  p_FmPcdCcNode->prsArrayOffset;
3145                 p_FmPcdCcNode->prsArrayOffset = 0;
3146             }
3147                 break;
3148 
3149        default:
3150             DeleteNode(p_FmPcdCcNode);
3151             REPORT_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG);
3152             return NULL;
3153     }
3154 
3155     if(p_FmPcdCcNode->parseCode == CC_PC_ILLEGAL)
3156     {
3157         DeleteNode(p_FmPcdCcNode);
3158         REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("illeagl extraction type"));
3159         return NULL;
3160     }
3161 
3162     if((p_FmPcdCcNode->sizeOfExtraction > FM_PCD_MAX_SIZE_OF_KEY) || !p_FmPcdCcNode->sizeOfExtraction)
3163     {
3164         DeleteNode(p_FmPcdCcNode);
3165         REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("sizeOfExatrction can not be greater than 56 and not 0"));
3166         return NULL;
3167     }
3168 
3169     if(p_CcNodeParam->keysParams.keySize != p_FmPcdCcNode->sizeOfExtraction)
3170     {
3171         DeleteNode(p_FmPcdCcNode);
3172         REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("keySize has to be equal to sizeOfExtraction"));
3173         return NULL;
3174     }
3175 
3176 
3177     p_FmPcdCcNode->userSizeOfExtraction = p_FmPcdCcNode->sizeOfExtraction;
3178 
3179     if(!glblMask)
3180         memset(p_FmPcdCcNode->p_GlblMask, 0xff, CC_GLBL_MASK_SIZE  * sizeof(uint8_t));
3181 
3182 #ifdef FM_PCD_CC_MANIP
3183     err = CheckAndSetManipParamsWithCcNodeParams(p_FmPcdCcNode);
3184     if(err != E_OK)
3185     {
3186         DeleteNode(p_FmPcdCcNode);
3187         REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("keySize has to be equal to sizeOfExtraction"));
3188         return NULL;
3189     }
3190 #endif /* FM_PCD_CC_MANIP */
3191 
3192     GetCcExtractKeySize(p_FmPcdCcNode->sizeOfExtraction, &p_FmPcdCcNode->ccKeySizeAccExtraction);
3193 
3194     if(p_FmPcdCcNode->lclMask)
3195         size = 2 * p_FmPcdCcNode->ccKeySizeAccExtraction;
3196     else
3197         size = p_FmPcdCcNode->ccKeySizeAccExtraction;
3198 
3199     if(isKeyTblAlloc)
3200     {
3201         p_FmPcdCcNode->h_KeysMatchTable =(t_Handle)FM_MURAM_AllocMem(FmPcdGetMuramHandle(p_FmPcdCcNode->h_FmPcd),
3202                                          (uint32_t)(size * sizeof(uint8_t) * (p_FmPcdCcNode->numOfKeys + 1)),
3203                                          FM_PCD_CC_KEYS_MATCH_TABLE_ALIGN);
3204         if(!p_FmPcdCcNode->h_KeysMatchTable)
3205         {
3206             DeleteNode(p_FmPcdCcNode);
3207             REPORT_ERROR(MAJOR, E_NO_MEMORY, ("No memory in MURAM for KEY MATCH table"));
3208             return NULL;
3209         }
3210         IOMemSet32((uint8_t *)p_FmPcdCcNode->h_KeysMatchTable, 0, size * sizeof(uint8_t) * (p_FmPcdCcNode->numOfKeys + 1));
3211     }
3212 
3213     p_FmPcdCcNode->h_AdTable = (t_Handle)FM_MURAM_AllocMem(FmPcdGetMuramHandle(p_FmPcdCcNode->h_FmPcd),
3214                                      (uint32_t)( (p_FmPcdCcNode->numOfKeys+1) * FM_PCD_CC_AD_ENTRY_SIZE),
3215                                      FM_PCD_CC_AD_TABLE_ALIGN);
3216     if(!p_FmPcdCcNode->h_AdTable)
3217     {
3218         DeleteNode(p_FmPcdCcNode);
3219         REPORT_ERROR(MAJOR, E_NO_MEMORY, ("No memory in MURAM for AD table "));
3220         return NULL;
3221     }
3222     IOMemSet32((uint8_t *)p_FmPcdCcNode->h_AdTable, 0, (uint32_t)((p_FmPcdCcNode->numOfKeys+1) * FM_PCD_CC_AD_ENTRY_SIZE));
3223 
3224     p_KeysMatchTblTmp    = p_FmPcdCcNode->h_KeysMatchTable;
3225     p_AdTableTmp         = p_FmPcdCcNode->h_AdTable;
3226     for(tmp = 0 ; tmp < p_FmPcdCcNode->numOfKeys; tmp++)
3227     {
3228         p_KeyParams = &p_CcNodeParam->keysParams.keyParams[tmp];
3229 
3230         if(p_KeysMatchTblTmp)
3231         {
3232             Mem2IOCpy32((void*)p_KeysMatchTblTmp, p_KeyParams->p_Key, p_FmPcdCcNode->sizeOfExtraction);
3233 
3234             if(p_FmPcdCcNode->lclMask && p_KeyParams->p_Mask)
3235                 Mem2IOCpy32(PTR_MOVE(p_KeysMatchTblTmp, p_FmPcdCcNode->ccKeySizeAccExtraction), p_KeyParams->p_Mask, p_FmPcdCcNode->sizeOfExtraction);
3236             else if(p_FmPcdCcNode->lclMask)
3237                 IOMemSet32(PTR_MOVE(p_KeysMatchTblTmp, p_FmPcdCcNode->ccKeySizeAccExtraction), 0xff, p_FmPcdCcNode->sizeOfExtraction);
3238             p_KeysMatchTblTmp = PTR_MOVE(p_KeysMatchTblTmp, size * sizeof(uint8_t));
3239         }
3240         NextStepAd(p_AdTableTmp,&p_KeyParams->ccNextEngineParams, p_FmPcd);
3241 
3242         p_AdTableTmp = PTR_MOVE(p_AdTableTmp, FM_PCD_CC_AD_ENTRY_SIZE);
3243 
3244     }
3245     NextStepAd(p_AdTableTmp,&p_CcNodeParam->keysParams.ccNextEngineParamsForMiss, p_FmPcd);
3246 
3247     if(fullField == TRUE)
3248         p_FmPcdCcNode->sizeOfExtraction = 0;
3249 
3250 
3251     for(tmp = 0; tmp < p_FmPcdCcNode->numOfKeys + 1; tmp++)
3252     {
3253         if(p_FmPcdCcNode->nextEngineAndRequiredAction[tmp].nextEngineParams.nextEngine == e_FM_PCD_CC)
3254         {
3255             p_FmPcdCcNextNode = (t_FmPcdCcNode*)p_FmPcdCcNode->nextEngineAndRequiredAction[tmp].nextEngineParams.params.ccParams.h_CcNode;
3256 
3257             if(!IsNodeInModifiedState((t_Handle)p_FmPcdCcNextNode))
3258             {
3259                 memset(&ccNodeInfo, 0, sizeof(t_CcNodeInformation));
3260                 ccNodeInfo.h_CcNode = (t_Handle)p_FmPcdCcNode;
3261                 ccNodeInfo.index = 1;
3262                 EnqueueNodeInfoToRelevantLst(&p_FmPcdCcNextNode->ccPrevNodesLst, &ccNodeInfo);
3263                 UpdateNodeWithModifiedState((t_Handle)p_FmPcdCcNextNode, TRUE);
3264             }
3265             else
3266             {
3267                 p_CcInformation = FindNodeInfoInReleventLst(&p_FmPcdCcNextNode->ccPrevNodesLst,(t_Handle)p_FmPcdCcNode);
3268                 ASSERT_COND(p_CcInformation);
3269                 p_CcInformation->index++;
3270             }
3271         }
3272 
3273     }
3274 
3275     for(tmp = 0; tmp < p_FmPcdCcNode->numOfKeys + 1; tmp++)
3276     {
3277         if(p_FmPcdCcNode->nextEngineAndRequiredAction[tmp].nextEngineParams.nextEngine == e_FM_PCD_CC)
3278         {
3279             p_FmPcdCcNextNode = (t_FmPcdCcNode*)p_FmPcdCcNode->nextEngineAndRequiredAction[tmp].nextEngineParams.params.ccParams.h_CcNode;
3280 
3281             if(IsNodeInModifiedState((t_Handle)p_FmPcdCcNextNode))
3282                 UpdateNodeWithModifiedState((t_Handle)p_FmPcdCcNextNode, FALSE);
3283         }
3284     }
3285 
3286     p_AdTableTmp   = p_FmPcdCcNode->h_AdTable;
3287     for(tmp = 0; tmp < p_FmPcdCcNode->numOfKeys; tmp++)
3288     {
3289         if(p_FmPcdCcNode->nextEngineAndRequiredAction[tmp].requiredAction)
3290         {
3291 
3292              err = FmPcdCcSetRequiredAction(h_FmPcd, p_FmPcdCcNode->nextEngineAndRequiredAction[tmp].requiredAction, &p_FmPcdCcNode->nextEngineAndRequiredAction[tmp], p_AdTableTmp,1, NULL);
3293             if(err)
3294             {
3295                 FM_PCD_CcDeleteNode(h_FmPcd, (t_Handle)p_FmPcdCcNode);
3296                 REPORT_ERROR(MAJOR, err, NO_MSG);
3297                 return NULL;
3298             }
3299             p_AdTableTmp = PTR_MOVE(p_AdTableTmp, FM_PCD_CC_AD_ENTRY_SIZE);
3300         }
3301     }
3302     if(p_FmPcdCcNode->nextEngineAndRequiredAction[tmp].requiredAction)
3303     {
3304          err = FmPcdCcSetRequiredAction(h_FmPcd, p_FmPcdCcNode->nextEngineAndRequiredAction[tmp].requiredAction, &p_FmPcdCcNode->nextEngineAndRequiredAction[tmp], p_AdTableTmp,1, NULL);
3305          if(err)
3306         {
3307             FM_PCD_CcDeleteNode(h_FmPcd, (t_Handle)p_FmPcdCcNode);
3308             REPORT_ERROR(MAJOR, err, NO_MSG);
3309             return NULL;
3310         }
3311 
3312     }
3313 
3314 
3315     return p_FmPcdCcNode;
3316 }
3317 
3318 t_Error FM_PCD_CcDeleteNode(t_Handle h_FmPcd, t_Handle h_CcNode)
3319 {
3320     t_FmPcdCcNode               *p_CcNode = (t_FmPcdCcNode *)h_CcNode;
3321     int i = 0;
3322 
3323     SANITY_CHECK_RETURN_ERROR(h_FmPcd, E_INVALID_HANDLE);
3324 
3325     UNUSED(h_FmPcd);
3326     if(!p_CcNode)
3327         RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("the node with this ID is not initialized"));
3328 
3329     if(p_CcNode->owners)
3330         RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("the node with this ID can not be removed because this node is occupied, first - unbind this node"));
3331 
3332    for(i = 0; i < p_CcNode->numOfKeys; i++)
3333    {
3334         if(p_CcNode->nextEngineAndRequiredAction[i].nextEngineParams.nextEngine == e_FM_PCD_CC)
3335             UpdateNodeOwner(p_CcNode->nextEngineAndRequiredAction[i].nextEngineParams.params.ccParams.h_CcNode, FALSE);
3336 
3337     }
3338     if(p_CcNode->nextEngineAndRequiredAction[i].nextEngineParams.nextEngine == e_FM_PCD_CC)
3339         UpdateNodeOwner(p_CcNode->nextEngineAndRequiredAction[i].nextEngineParams.params.ccParams.h_CcNode, FALSE);
3340 
3341 #ifdef FM_PCD_CC_MANIP
3342     for(i = 0; i < p_CcNode->numOfKeys; i++)
3343     {
3344         if(p_CcNode->nextEngineAndRequiredAction[i].nextEngineParams.h_Manip)
3345             FmPcdManipUpdateOwner(p_CcNode->nextEngineAndRequiredAction[i].nextEngineParams.h_Manip, FALSE);
3346     }
3347     if(p_CcNode->nextEngineAndRequiredAction[i].nextEngineParams.h_Manip)
3348         FmPcdManipUpdateOwner(p_CcNode->nextEngineAndRequiredAction[i].nextEngineParams.h_Manip, FALSE);
3349 #endif /* FM_PCD_CC_MANIP */
3350 
3351    DeleteNode(p_CcNode);
3352 
3353     return E_OK;
3354 }
3355 
3356 t_Error FM_PCD_CcNodeAddKey(t_Handle h_FmPcd, t_Handle h_CcNode, uint8_t keyIndex, uint8_t keySize, t_FmPcdCcKeyParams  *p_KeyParams)
3357 {
3358     t_FmPcd                         *p_FmPcd = (t_FmPcd *)h_FmPcd;
3359 
3360     SANITY_CHECK_RETURN_ERROR(h_FmPcd, E_INVALID_HANDLE);
3361     SANITY_CHECK_RETURN_ERROR(p_FmPcd->h_Hc, E_INVALID_HANDLE);
3362 
3363     return FmHcPcdCcAddKey(p_FmPcd->h_Hc, h_CcNode, keyIndex, keySize, p_KeyParams);
3364 }
3365 
3366 t_Error FM_PCD_CcNodeRemoveKey(t_Handle h_FmPcd, t_Handle h_CcNode, uint8_t keyIndex)
3367 {
3368     t_FmPcd                         *p_FmPcd = (t_FmPcd *)h_FmPcd;
3369 
3370     SANITY_CHECK_RETURN_ERROR(h_FmPcd, E_INVALID_HANDLE);
3371     SANITY_CHECK_RETURN_ERROR(p_FmPcd->h_Hc, E_INVALID_HANDLE);
3372 
3373     return FmHcPcdCcRemoveKey(p_FmPcd->h_Hc, h_CcNode, keyIndex);
3374 }
3375 
3376 t_Error FM_PCD_CcNodeModifyKey(t_Handle h_FmPcd, t_Handle h_CcNode, uint8_t keyIndex, uint8_t keySize, uint8_t  *p_Key, uint8_t *p_Mask)
3377 {
3378     t_FmPcd                         *p_FmPcd = (t_FmPcd *)h_FmPcd;
3379 
3380     SANITY_CHECK_RETURN_ERROR(h_FmPcd, E_INVALID_HANDLE);
3381     SANITY_CHECK_RETURN_ERROR(p_FmPcd->h_Hc, E_INVALID_HANDLE);
3382 
3383     return FmHcPcdCcModifyKey(p_FmPcd->h_Hc, h_CcNode, keyIndex, keySize, p_Key, p_Mask);
3384 }
3385 
3386 t_Error FM_PCD_CcNodeModifyNextEngine(t_Handle h_FmPcd, t_Handle h_CcNode, uint8_t keyIndex, t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams)
3387 {
3388     t_FmPcd                         *p_FmPcd = (t_FmPcd *)h_FmPcd;
3389 
3390     SANITY_CHECK_RETURN_ERROR(h_FmPcd, E_INVALID_HANDLE);
3391     SANITY_CHECK_RETURN_ERROR(p_FmPcd->h_Hc, E_INVALID_HANDLE);
3392 
3393     return FmHcPcdCcModifyNodeNextEngine(p_FmPcd->h_Hc, h_CcNode, keyIndex, p_FmPcdCcNextEngineParams);
3394 }
3395 
3396 t_Error FM_PCD_CcNodeModifyMissNextEngine(t_Handle h_FmPcd, t_Handle h_CcNode, t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams)
3397 {
3398     t_FmPcd                         *p_FmPcd = (t_FmPcd *)h_FmPcd;
3399 
3400     SANITY_CHECK_RETURN_ERROR(h_FmPcd, E_INVALID_HANDLE);
3401     SANITY_CHECK_RETURN_ERROR(p_FmPcd->h_Hc, E_INVALID_HANDLE);
3402 
3403     return FmHcPcdCcModifyNodeMissNextEngine(p_FmPcd->h_Hc, h_CcNode, p_FmPcdCcNextEngineParams);
3404 }
3405 
3406 t_Error FM_PCD_CcTreeModifyNextEngine(t_Handle h_FmPcd, t_Handle h_CcTree, uint8_t grpId, uint8_t index, t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams)
3407 {
3408     t_FmPcd                         *p_FmPcd = (t_FmPcd *)h_FmPcd;
3409 
3410     SANITY_CHECK_RETURN_ERROR(h_FmPcd, E_INVALID_HANDLE);
3411     SANITY_CHECK_RETURN_ERROR(p_FmPcd->h_Hc, E_INVALID_HANDLE);
3412 
3413     return FmHcPcdCcModifyTreeNextEngine(p_FmPcd->h_Hc, h_CcTree, grpId, index, p_FmPcdCcNextEngineParams);
3414 }
3415 
3416 t_Error FM_PCD_CcNodeModifyKeyAndNextEngine(t_Handle h_FmPcd, t_Handle h_CcNode, uint8_t keyIndex, uint8_t keySize, t_FmPcdCcKeyParams  *p_KeyParams)
3417 {
3418     t_FmPcd                         *p_FmPcd = (t_FmPcd *)h_FmPcd;
3419 
3420     SANITY_CHECK_RETURN_ERROR(h_FmPcd, E_INVALID_HANDLE);
3421     SANITY_CHECK_RETURN_ERROR(p_FmPcd->h_Hc, E_INVALID_HANDLE);
3422 
3423     return FmHcPcdCcModifyKeyAndNextEngine(p_FmPcd->h_Hc, h_CcNode, keyIndex, keySize, p_KeyParams);
3424 }
3425 
3426 uint32_t FM_PCD_CcNodeGetKeyCounter(t_Handle h_FmPcd, t_Handle h_CcNode, uint8_t keyIndex)
3427 {
3428     t_FmPcdCcNode       *p_FmPcdCcNode = (t_FmPcdCcNode *)h_CcNode;
3429     t_AdOfTypeResult    *p_AdResult = NULL;
3430 
3431     SANITY_CHECK_RETURN_ERROR(h_FmPcd, E_INVALID_HANDLE);
3432     SANITY_CHECK_RETURN_VALUE(h_CcNode, E_INVALID_HANDLE, 0);
3433 #ifdef DISABLE_SANITY_CHECKS
3434 UNUSED(h_FmPcd);
3435 #endif /* DISABLE_SANITY_CHECKS */
3436 
3437     if (keyIndex >= p_FmPcdCcNode->numOfKeys)
3438     {
3439         REPORT_ERROR(MINOR, E_INVALID_STATE,
3440                      ("keyIndex > numOfKeys defined for this node"));
3441         return 0;
3442     }
3443 
3444     p_AdResult = PTR_MOVE(p_FmPcdCcNode->h_AdTable, keyIndex*FM_PCD_CC_AD_ENTRY_SIZE);
3445     ASSERT_COND(p_AdResult);
3446 
3447     if (p_FmPcdCcNode->nextEngineAndRequiredAction[keyIndex].nextEngineParams.nextEngine == e_FM_PCD_CC)
3448     {
3449         REPORT_ERROR(MINOR, E_INVALID_STATE,
3450                      ("statistics updated only for entries where next engine not CC"));
3451         return 0;
3452     }
3453 
3454     if(((p_FmPcdCcNode->nextEngineAndRequiredAction[keyIndex].nextEngineParams.nextEngine == e_FM_PCD_DONE) &&
3455         !p_FmPcdCcNode->nextEngineAndRequiredAction[keyIndex].nextEngineParams.params.enqueueParams.statisticsEn) ||
3456         ((p_FmPcdCcNode->nextEngineAndRequiredAction[keyIndex].nextEngineParams.nextEngine == e_FM_PCD_KG) &&
3457         !p_FmPcdCcNode->nextEngineAndRequiredAction[keyIndex].nextEngineParams.params.kgParams.statisticsEn) ||
3458         ((p_FmPcdCcNode->nextEngineAndRequiredAction[keyIndex].nextEngineParams.nextEngine == e_FM_PCD_PLCR) &&
3459         !p_FmPcdCcNode->nextEngineAndRequiredAction[keyIndex].nextEngineParams.params.plcrParams.statisticsEn))
3460     {
3461         REPORT_ERROR(MINOR, E_INVALID_STATE,
3462                      ("statistics wasn't enable"));
3463         return 0;
3464     }
3465 
3466     return  GET_UINT32(p_AdResult->res);
3467 }
3468