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
55t_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
64void   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
73uint8_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
81uint8_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
89uint16_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}
96static 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
117static 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
138static 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
163static 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
280static 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}
348static 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
357static 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
366static 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
396static 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
411static 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
427void FmPcdCcTreeReleaseLock(t_Handle h_FmPcdCcTree)
428{
429    RELEASE_LOCK(((t_FmPcdCcTree *)h_FmPcdCcTree)->lock);
430}
431
432void 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
447static 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
475static 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
491static 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
504static 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
530static 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
701static 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
764static 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
810static 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
1015static 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
1097static 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
1143static 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
1244static 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
1286static 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
1314static 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
1322static 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
1361static 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
1397static 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
1559static 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
1607static 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
1683static 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
1797static 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
1853static 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
1890static 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
1929static 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
2037static 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
2048static 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
2062static 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
2081static 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
2099static 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
2158static 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
2215static 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
2286t_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
2321t_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
2361t_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
2403t_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
2433t_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
2460t_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
2501t_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
2544t_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
2673uint32_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
2684t_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
2697t_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
2716t_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
2729t_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
2736t_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
2765t_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
2953t_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
2985t_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
3318t_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
3356t_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
3366t_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
3376t_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
3386t_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
3396t_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
3406t_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
3416t_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
3426uint32_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
3434UNUSED(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