summaryrefslogtreecommitdiffstats
path: root/sys/contrib/ncsw/Peripherals/FM/Pcd/fm_cc.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/contrib/ncsw/Peripherals/FM/Pcd/fm_cc.c')
-rw-r--r--sys/contrib/ncsw/Peripherals/FM/Pcd/fm_cc.c3467
1 files changed, 3467 insertions, 0 deletions
diff --git a/sys/contrib/ncsw/Peripherals/FM/Pcd/fm_cc.c b/sys/contrib/ncsw/Peripherals/FM/Pcd/fm_cc.c
new file mode 100644
index 0000000..fe765a4
--- /dev/null
+++ b/sys/contrib/ncsw/Peripherals/FM/Pcd/fm_cc.c
@@ -0,0 +1,3467 @@
+/* Copyright (c) 2008-2011 Freescale Semiconductor, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Freescale Semiconductor nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/******************************************************************************
+ @File fm_cc.c
+
+ @Description FM CC ...
+*//***************************************************************************/
+#include "std_ext.h"
+#include "error_ext.h"
+#include "string_ext.h"
+#include "debug_ext.h"
+#include "fm_pcd_ext.h"
+#include "fm_muram_ext.h"
+
+#include "fm_common.h"
+#include "fm_hc.h"
+#include "fm_cc.h"
+
+
+#if defined(FM_CAPWAP_SUPPORT)
+#define FM_PCD_CC_MANIP
+#endif /* defined(FM_CAPWAP_SUPPORT) || ... */
+
+
+t_Handle FmPcdCcTreeGetSavedManipParams(t_Handle h_FmTree, uint8_t manipIndx)
+{
+ t_FmPcdCcTree *p_FmPcdCcTree = (t_FmPcdCcTree *)h_FmTree;
+
+ ASSERT_COND(p_FmPcdCcTree);
+
+ return p_FmPcdCcTree->fmPcdCcSavedManipParams[manipIndx];
+}
+
+void FmPcdCcTreeSetSavedManipParams(t_Handle h_FmTree, t_Handle h_SavedManipParams, uint8_t manipIndx)
+{
+ t_FmPcdCcTree *p_FmPcdCcTree = (t_FmPcdCcTree *)h_FmTree;
+
+ ASSERT_COND(p_FmPcdCcTree);
+
+ p_FmPcdCcTree->fmPcdCcSavedManipParams[manipIndx] = h_SavedManipParams;
+}
+
+uint8_t FmPcdCcGetParseCode(t_Handle h_CcNode)
+{
+ t_FmPcdCcNode *p_FmPcdCcNode = (t_FmPcdCcNode *)h_CcNode;
+
+ ASSERT_COND(p_FmPcdCcNode);
+ return p_FmPcdCcNode->parseCode;
+}
+
+uint8_t FmPcdCcGetOffset(t_Handle h_CcNode)
+{
+ t_FmPcdCcNode *p_FmPcdCcNode = (t_FmPcdCcNode *)h_CcNode;
+
+ ASSERT_COND(p_FmPcdCcNode);
+ return p_FmPcdCcNode->offset;
+}
+
+uint16_t FmPcdCcGetNumOfKeys(t_Handle h_CcNode)
+{
+ t_FmPcdCcNode *p_FmPcdCcNode = (t_FmPcdCcNode *)h_CcNode;
+
+ ASSERT_COND(p_FmPcdCcNode);
+ return p_FmPcdCcNode->numOfKeys;
+}
+static void EnqueueNodeInfoToRelevantLst(t_List *p_List, t_CcNodeInformation *p_CcInfo)
+{
+ t_CcNodeInformation *p_CcInformation;
+ uint32_t intFlags;
+
+ p_CcInformation = (t_CcNodeInformation *)XX_Malloc(sizeof(t_CcNodeInformation));
+ if (p_CcInformation)
+ {
+ memset(p_CcInformation, 0, sizeof(t_CcNodeInformation));
+ memcpy(p_CcInformation, p_CcInfo, sizeof(t_CcNodeInformation));
+ INIT_LIST(&p_CcInformation->node);
+
+ intFlags = XX_DisableAllIntr();
+ LIST_AddToTail(&p_CcInformation->node, p_List);
+ XX_RestoreAllIntr(intFlags);
+ }
+ else
+ REPORT_ERROR(MAJOR, E_NO_MEMORY, ("CC Node Information"));
+}
+
+
+static t_CcNodeInformation* FindNodeInfoInReleventLst(t_List *p_List, t_Handle h_Info)
+{
+ t_CcNodeInformation *p_CcInformation;
+ t_List *p_Pos;
+ uint32_t intFlags;
+
+ intFlags = XX_DisableAllIntr();
+ for (p_Pos = NCSW_LIST_FIRST(p_List); p_Pos != (p_List); p_Pos = NCSW_LIST_NEXT(p_Pos))
+ {
+ p_CcInformation = CC_NODE_F_OBJECT(p_Pos);
+ ASSERT_COND(p_CcInformation->h_CcNode);
+ if(p_CcInformation->h_CcNode == h_Info)
+ {
+ XX_RestoreAllIntr(intFlags);
+ return p_CcInformation;
+ }
+ }
+ XX_RestoreAllIntr(intFlags);
+ return NULL;
+}
+
+static void DequeueNodeInfoFromRelevantLst(t_List *p_List, t_Handle h_Info)
+{
+ t_CcNodeInformation *p_CcInformation = NULL;
+ uint32_t intFlags;
+ t_List *p_Pos;
+
+ intFlags = XX_DisableAllIntr();
+ if (LIST_IsEmpty(p_List))
+ {
+ XX_RestoreAllIntr(intFlags);
+ return;
+ }
+
+ for (p_Pos = NCSW_LIST_FIRST(p_List); p_Pos != (p_List); p_Pos = NCSW_LIST_NEXT(p_Pos))
+ {
+ p_CcInformation = CC_NODE_F_OBJECT(p_Pos);
+ ASSERT_COND(p_CcInformation->h_CcNode);
+ if (p_CcInformation->h_CcNode == h_Info)
+ break;
+ }
+ if (p_CcInformation)
+ LIST_DelAndInit(&p_CcInformation->node);
+ XX_RestoreAllIntr(intFlags);
+}
+
+static t_Error FmPcdCcSetRequiredAction(t_Handle h_FmPcd, uint32_t requiredAction, t_FmPcdCcNextEngineAndRequiredActionParams *p_CcNextEngineParamsTmp,
+ t_Handle h_AdTmp, uint16_t numOfEntries, t_Handle h_Tree)
+{
+
+ t_AdOfTypeResult *p_AdTmp = (t_AdOfTypeResult *)h_AdTmp;
+ uint32_t tmpReg32;
+ t_Error err;
+ t_FmPcdCcNode *p_FmPcdCcNode;
+ int i = 0;
+ uint16_t tmp = 0;
+ uint16_t profileId;
+ uint8_t relativeSchemeId, physicalSchemeId;
+ t_CcNodeInformation ccNodeInfo;
+
+ for(i = 0; i < numOfEntries; i++)
+ {
+ if(i == 0)
+ h_AdTmp = PTR_MOVE(h_AdTmp, i*FM_PCD_CC_AD_ENTRY_SIZE);
+ else
+ h_AdTmp = PTR_MOVE(h_AdTmp, FM_PCD_CC_AD_ENTRY_SIZE);
+
+ if(p_CcNextEngineParamsTmp[i].shadowAction & requiredAction)
+ continue;
+ switch(p_CcNextEngineParamsTmp[i].nextEngineParams.nextEngine)
+ {
+ case(e_FM_PCD_CC):
+ if(requiredAction)
+ {
+ p_FmPcdCcNode = p_CcNextEngineParamsTmp[i].nextEngineParams.params.ccParams.h_CcNode;
+ ASSERT_COND(p_FmPcdCcNode);
+ if(p_FmPcdCcNode->shadowAction == requiredAction)
+ break;
+ if((requiredAction & UPDATE_CC_WITH_TREE) && !(p_FmPcdCcNode->shadowAction & UPDATE_CC_WITH_TREE))
+ {
+
+ ASSERT_COND(LIST_NumOfObjs(&p_FmPcdCcNode->ccTreesLst) == 0);
+ if(p_FmPcdCcNode->shadowAction & UPDATE_CC_WITH_DELETE_TREE)
+ p_FmPcdCcNode->shadowAction &= ~UPDATE_CC_WITH_DELETE_TREE;
+ memset(&ccNodeInfo, 0, sizeof(t_CcNodeInformation));
+ ccNodeInfo.h_CcNode = h_Tree;
+ EnqueueNodeInfoToRelevantLst(&p_FmPcdCcNode->ccTreesLst, &ccNodeInfo);
+ p_CcNextEngineParamsTmp[i].shadowAction |= UPDATE_CC_WITH_TREE;
+ }
+ if((requiredAction & UPDATE_CC_WITH_DELETE_TREE) && !(p_FmPcdCcNode->shadowAction & UPDATE_CC_WITH_DELETE_TREE))
+ {
+ ASSERT_COND(LIST_NumOfObjs(&p_FmPcdCcNode->ccTreesLst) == 1);
+ if(p_FmPcdCcNode->shadowAction & UPDATE_CC_WITH_TREE)
+ p_FmPcdCcNode->shadowAction &= ~UPDATE_CC_WITH_TREE;
+ DequeueNodeInfoFromRelevantLst(&p_FmPcdCcNode->ccTreesLst, h_Tree);
+ p_CcNextEngineParamsTmp[i].shadowAction |= UPDATE_CC_WITH_DELETE_TREE;
+ }
+ if(p_FmPcdCcNode->nextEngineAndRequiredAction[p_FmPcdCcNode->numOfKeys].nextEngineParams.nextEngine != e_FM_PCD_INVALID)
+ tmp = (uint8_t)(p_FmPcdCcNode->numOfKeys + 1);
+ else
+ tmp = p_FmPcdCcNode->numOfKeys;
+ err = FmPcdCcSetRequiredAction(h_FmPcd, requiredAction, p_FmPcdCcNode->nextEngineAndRequiredAction, p_FmPcdCcNode->h_AdTable, tmp, h_Tree);
+ if(err != E_OK)
+ return err;
+ p_FmPcdCcNode->shadowAction |= requiredAction;
+ }
+ break;
+
+ case(e_FM_PCD_KG):
+ if((requiredAction & UPDATE_NIA_ENQ_WITHOUT_DMA) && !(p_CcNextEngineParamsTmp[i].shadowAction & UPDATE_NIA_ENQ_WITHOUT_DMA))
+ {
+ physicalSchemeId = (uint8_t)(PTR_TO_UINT(p_CcNextEngineParamsTmp[i].nextEngineParams.params.kgParams.h_DirectScheme)-1);
+ relativeSchemeId = FmPcdKgGetRelativeSchemeId(h_FmPcd, physicalSchemeId);
+ if(relativeSchemeId == FM_PCD_KG_NUM_OF_SCHEMES)
+ RETURN_ERROR(MAJOR, E_NOT_IN_RANGE, NO_MSG);
+ if (!FmPcdKgIsSchemeValidSw(h_FmPcd, relativeSchemeId))
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid direct scheme."));
+ if(!KgIsSchemeAlwaysDirect(h_FmPcd, relativeSchemeId))
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("For this action scheme has to be direct."));
+ err = FmPcdKgCcGetSetParams(h_FmPcd, p_CcNextEngineParamsTmp[i].nextEngineParams.params.kgParams.h_DirectScheme, requiredAction);
+ if(err != E_OK)
+ RETURN_ERROR(MAJOR, err, NO_MSG);
+ p_CcNextEngineParamsTmp[i].shadowAction |= requiredAction;
+ }
+ break;
+
+ case(e_FM_PCD_PLCR):
+ if((requiredAction & UPDATE_NIA_ENQ_WITHOUT_DMA) && !(p_CcNextEngineParamsTmp[i].shadowAction & UPDATE_NIA_ENQ_WITHOUT_DMA))
+ {
+ if(!p_CcNextEngineParamsTmp[i].nextEngineParams.params.plcrParams.overrideParams)
+ RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("In this intialization only overrideFqid can be intiizliaes"));
+ if(!p_CcNextEngineParamsTmp[i].nextEngineParams.params.plcrParams.sharedProfile)
+ RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("In this intialization only overrideFqid can be intiizliaes"));
+ err = FmPcdPlcrGetAbsoluteProfileId(h_FmPcd, e_FM_PCD_PLCR_SHARED, NULL, p_CcNextEngineParamsTmp[i].nextEngineParams.params.plcrParams.newRelativeProfileId, &profileId);
+ if(err!= E_OK)
+ RETURN_ERROR(MAJOR, err, NO_MSG);
+ err = FmPcdPlcrCcGetSetParams(h_FmPcd, profileId, requiredAction);
+ if(err != E_OK)
+ RETURN_ERROR(MAJOR, err, NO_MSG);
+ p_CcNextEngineParamsTmp[i].shadowAction |= requiredAction;
+ }
+ break;
+
+ case(e_FM_PCD_DONE):
+ if((requiredAction & UPDATE_NIA_ENQ_WITHOUT_DMA) && !(p_CcNextEngineParamsTmp[i].shadowAction & UPDATE_NIA_ENQ_WITHOUT_DMA))
+ {
+ tmpReg32 = GET_UINT32(p_AdTmp->nia);
+ if((tmpReg32 & (NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME)) != (NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME))
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Next engine was previosely assigned not as PCD_DONE"));
+ tmpReg32 |= NIA_BMI_AC_ENQ_FRAME_WITHOUT_DMA;
+ WRITE_UINT32(p_AdTmp->nia, tmpReg32);
+ p_CcNextEngineParamsTmp[i].shadowAction |= requiredAction;
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ return E_OK;
+}
+
+static t_Error CcUpdateParam(t_Handle h_FmPcd,
+ t_Handle h_FmPort,
+ t_FmPcdCcNextEngineAndRequiredActionParams *p_CcNextEngineParams,
+ uint16_t numOfEntries,
+ t_Handle h_Ad,
+ bool validate,
+ uint16_t level,
+ t_Handle h_FmTree,
+ bool modify)
+{
+ t_CcNodeInformation *p_CcNodeInfo;
+ t_FmPcdCcNode *p_FmPcdCcNode;
+ t_Error err;
+ uint16_t tmp = 0;
+ int i = 0;
+
+ level++;
+
+ if(numOfEntries)
+ {
+ for(i = 0; i < numOfEntries; i++)
+ {
+ if(i == 0)
+ h_Ad = PTR_MOVE(h_Ad, i*FM_PCD_CC_AD_ENTRY_SIZE);
+ else
+ h_Ad = PTR_MOVE(h_Ad, FM_PCD_CC_AD_ENTRY_SIZE);
+
+ if(p_CcNextEngineParams[i].nextEngineParams.nextEngine == e_FM_PCD_CC)
+ {
+ p_FmPcdCcNode = p_CcNextEngineParams[i].nextEngineParams.params.ccParams.h_CcNode;
+ ASSERT_COND(p_FmPcdCcNode);
+ p_CcNodeInfo = FindNodeInfoInReleventLst(&p_FmPcdCcNode->ccTreesLst,h_FmTree);
+ ASSERT_COND(p_CcNodeInfo);
+ p_CcNodeInfo->index = level;
+#ifdef FM_PCD_CC_MANIP
+ if(p_CcNextEngineParams[i].nextEngineParams.h_Manip)
+ {
+ err = FmPcdManipUpdate(h_FmPcd, h_FmPort, p_CcNextEngineParams[i].nextEngineParams.h_Manip, h_Ad, validate, p_CcNodeInfo->index, h_FmTree, modify);
+ if(err)
+ RETURN_ERROR(MAJOR, err, NO_MSG);
+ }
+#endif /* FM_PCD_CC_MANIP */
+
+ if(p_FmPcdCcNode->nextEngineAndRequiredAction[p_FmPcdCcNode->numOfKeys].nextEngineParams.nextEngine != e_FM_PCD_INVALID)
+ tmp = (uint8_t)(p_FmPcdCcNode->numOfKeys + 1);
+ else
+ tmp = p_FmPcdCcNode->numOfKeys;
+
+ err = CcUpdateParam(h_FmPcd, h_FmPort, p_FmPcdCcNode->nextEngineAndRequiredAction, tmp, p_FmPcdCcNode->h_AdTable, validate,level, h_FmTree, modify);
+ if(err)
+ RETURN_ERROR(MAJOR, err, NO_MSG);
+ }
+#ifdef FM_PCD_CC_MANIP
+ else
+ {
+ if(p_CcNextEngineParams[i].nextEngineParams.h_Manip)
+ {
+ err = FmPcdManipUpdate(h_FmPcd, h_FmPort, p_CcNextEngineParams[i].nextEngineParams.h_Manip, h_Ad, validate, level,h_FmTree, modify);
+ if(err)
+ RETURN_ERROR(MAJOR, err, NO_MSG);
+ }
+ }
+#endif /* FM_PCD_CC_MANIP */
+ }
+ }
+
+ return E_OK;
+}
+static bool IsNodeInModifiedState(t_Handle h_CcNode)
+{
+ t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode;
+
+ ASSERT_COND(p_CcNode);
+
+ return p_CcNode->modifiedState;
+}
+
+static void UpdateNodeWithModifiedState(t_Handle h_CcNode, bool modifiedState)
+{
+ t_FmPcdCcNode *p_FmPcdCcNode = (t_FmPcdCcNode *)h_CcNode;
+
+ ASSERT_COND(p_FmPcdCcNode);
+
+ p_FmPcdCcNode->modifiedState = modifiedState;
+}
+
+static ccPrivateInfo_t IcDefineCode(t_FmPcdCcNodeParams *p_CcNodeParam)
+{
+ switch (p_CcNodeParam->extractCcParams.extractNonHdr.action)
+ {
+ case(e_FM_PCD_ACTION_EXACT_MATCH):
+ switch(p_CcNodeParam->extractCcParams.extractNonHdr.src)
+ {
+ case(e_FM_PCD_EXTRACT_FROM_KEY):
+ return CC_PRIVATE_INFO_IC_KEY_EXACT_MATCH;
+ case(e_FM_PCD_EXTRACT_FROM_HASH):
+ return CC_PRIVATE_INFO_IC_HASH_EXACT_MATCH;
+ default:
+ return CC_PRIVATE_INFO_NONE;
+ }
+ case(e_FM_PCD_ACTION_INDEXED_LOOKUP):
+ switch(p_CcNodeParam->extractCcParams.extractNonHdr.src)
+ {
+ case(e_FM_PCD_EXTRACT_FROM_HASH):
+ return CC_PRIVATE_INFO_IC_HASH_INDEX_LOOKUP;
+ case(e_FM_PCD_EXTRACT_FROM_FLOW_ID):
+ return CC_PRIVATE_INFO_IC_DEQ_FQID_INDEX_LOOKUP;
+ default:
+ return CC_PRIVATE_INFO_NONE;
+ }
+ default:
+ break;
+ }
+ return CC_PRIVATE_INFO_NONE;
+}
+
+static t_CcNodeInformation * DequeueAdditionalInfoFromRelevantLst(t_List *p_List)
+{
+ t_CcNodeInformation *p_CcNodeInfo = NULL;
+ uint32_t intFlags;
+
+ intFlags = XX_DisableAllIntr();
+ if (!LIST_IsEmpty(p_List))
+ {
+ p_CcNodeInfo = CC_NODE_F_OBJECT(p_List->p_Next);
+ LIST_DelAndInit(&p_CcNodeInfo->node);
+ }
+ XX_RestoreAllIntr(intFlags);
+ return p_CcNodeInfo;
+}
+
+static void ReleaseLst(t_List *p_List)
+{
+ t_CcNodeInformation *p_CcNodeInfo = NULL;
+
+ if(!LIST_IsEmpty(p_List))
+ {
+ p_CcNodeInfo = DequeueAdditionalInfoFromRelevantLst(p_List);
+ while (p_CcNodeInfo)
+ {
+ XX_Free(p_CcNodeInfo);
+ p_CcNodeInfo = DequeueAdditionalInfoFromRelevantLst(p_List);
+ }
+ }
+ LIST_DelAndInit(p_List);
+}
+
+void FmPcdCcTreeReleaseLock(t_Handle h_FmPcdCcTree)
+{
+ RELEASE_LOCK(((t_FmPcdCcTree *)h_FmPcdCcTree)->lock);
+}
+
+void FmPcdCcNodeTreeReleaseLock(t_List *p_List)
+{
+ t_List *p_Pos;
+ t_CcNodeInformation *p_CcNodeInfo;
+ t_Handle h_FmPcdCcTree;
+
+ LIST_FOR_EACH(p_Pos, p_List)
+ {
+ p_CcNodeInfo = CC_NODE_F_OBJECT(p_Pos);
+ h_FmPcdCcTree = p_CcNodeInfo->h_CcNode;
+ FmPcdCcTreeReleaseLock(h_FmPcdCcTree);
+ }
+ ReleaseLst(p_List);
+}
+
+static void DeleteNode(t_FmPcdCcNode *p_FmPcdCcNode)
+{
+ if(p_FmPcdCcNode)
+ {
+ if(p_FmPcdCcNode->p_GlblMask)
+ {
+ XX_Free(p_FmPcdCcNode->p_GlblMask);
+ p_FmPcdCcNode->p_GlblMask = NULL;
+ }
+ if(p_FmPcdCcNode->h_KeysMatchTable)
+ {
+ FM_MURAM_FreeMem(FmPcdGetMuramHandle(p_FmPcdCcNode->h_FmPcd), p_FmPcdCcNode->h_KeysMatchTable);
+ p_FmPcdCcNode->h_KeysMatchTable = NULL;
+ }
+ if(p_FmPcdCcNode->h_AdTable)
+ {
+ FM_MURAM_FreeMem(FmPcdGetMuramHandle(p_FmPcdCcNode->h_FmPcd), p_FmPcdCcNode->h_AdTable);
+ p_FmPcdCcNode->h_AdTable = NULL;
+ }
+
+ ReleaseLst(&p_FmPcdCcNode->ccPrevNodesLst);
+ ReleaseLst(&p_FmPcdCcNode->ccTreeIdLst);
+ ReleaseLst(&p_FmPcdCcNode->ccTreesLst);
+
+ XX_Free(p_FmPcdCcNode);
+ }
+}
+
+static void DeleteTree(t_FmPcdCcTree *p_FmPcdTree, t_FmPcd *p_FmPcd)
+{
+ if(p_FmPcdTree)
+ {
+ if(p_FmPcdTree->ccTreeBaseAddr)
+ {
+ FM_MURAM_FreeMem(FmPcdGetMuramHandle(p_FmPcd), UINT_TO_PTR(p_FmPcdTree->ccTreeBaseAddr));
+ p_FmPcdTree->ccTreeBaseAddr = 0;
+ }
+
+ ReleaseLst(&p_FmPcdTree->fmPortsLst);
+
+ XX_Free(p_FmPcdTree);
+ }
+}
+
+static void UpdateNodeOwner(t_FmPcdCcNode *p_FmPcdCcNode, bool add)
+{
+ ASSERT_COND(p_FmPcdCcNode);
+
+ if(add)
+ p_FmPcdCcNode->owners++;
+ else
+ {
+ ASSERT_COND(p_FmPcdCcNode->owners);
+ p_FmPcdCcNode->owners--;
+ }
+}
+
+static void GetCcExtractKeySize(uint8_t parseCodeRealSize, uint8_t *parseCodeCcSize)
+{
+ if((parseCodeRealSize > 0) && (parseCodeRealSize < 2))
+ *parseCodeCcSize = 1;
+ else if(parseCodeRealSize == 2)
+ *parseCodeCcSize = 2;
+ else if((parseCodeRealSize > 2) && (parseCodeRealSize <= 4))
+ *parseCodeCcSize = 4;
+ else if((parseCodeRealSize > 4) && (parseCodeRealSize <= 8))
+ *parseCodeCcSize = 8;
+ else if((parseCodeRealSize > 8) && (parseCodeRealSize <= 16))
+ *parseCodeCcSize = 16;
+ else if((parseCodeRealSize > 16) && (parseCodeRealSize <= 24))
+ *parseCodeCcSize = 24;
+ else if((parseCodeRealSize > 24) && (parseCodeRealSize <= 32))
+ *parseCodeCcSize = 32;
+ else if((parseCodeRealSize > 32) && (parseCodeRealSize <= 40))
+ *parseCodeCcSize = 40;
+ else if((parseCodeRealSize > 40) && (parseCodeRealSize <= 48))
+ *parseCodeCcSize = 48;
+ else if((parseCodeRealSize > 48) && (parseCodeRealSize <= 56))
+ *parseCodeCcSize = 56;
+ else
+ *parseCodeCcSize = 0;
+}
+
+static void GetSizeHeaderField(e_NetHeaderType hdr,t_FmPcdFields field,uint8_t *parseCodeRealSize)
+{
+ switch(hdr)
+ {
+ case (HEADER_TYPE_ETH):
+ switch(field.eth)
+ {
+ case(NET_HEADER_FIELD_ETH_DA):
+ *parseCodeRealSize = 6;
+ break;
+ case(NET_HEADER_FIELD_ETH_SA):
+ *parseCodeRealSize = 6;
+ break;
+ case(NET_HEADER_FIELD_ETH_TYPE):
+ *parseCodeRealSize = 2;
+ break;
+ default:
+ REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported1"));
+ *parseCodeRealSize = CC_SIZE_ILLEGAL;
+ break;
+ }
+ break;
+ case(HEADER_TYPE_PPPoE):
+ switch(field.pppoe)
+ {
+ case(NET_HEADER_FIELD_PPPoE_PID):
+ *parseCodeRealSize = 2;
+ break;
+ default:
+ REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported1"));
+ *parseCodeRealSize = CC_SIZE_ILLEGAL;
+ break;
+ }
+ break;
+ case (HEADER_TYPE_VLAN):
+ switch(field.vlan)
+ {
+ case(NET_HEADER_FIELD_VLAN_TCI):
+ *parseCodeRealSize = 2;
+ break;
+ default:
+ REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported2"));
+ *parseCodeRealSize = CC_SIZE_ILLEGAL;
+ break;
+ }
+ break;
+ case (HEADER_TYPE_MPLS):
+ switch(field.mpls)
+ {
+ case(NET_HEADER_FIELD_MPLS_LABEL_STACK):
+ *parseCodeRealSize = 4;
+ break;
+ default:
+ REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported3"));
+ *parseCodeRealSize = CC_SIZE_ILLEGAL;
+ break;
+ }
+ break;
+ case (HEADER_TYPE_IPv4):
+ switch(field.ipv4)
+ {
+ case(NET_HEADER_FIELD_IPv4_DST_IP):
+ case(NET_HEADER_FIELD_IPv4_SRC_IP):
+ *parseCodeRealSize = 4;
+ break;
+ case(NET_HEADER_FIELD_IPv4_TOS):
+ case(NET_HEADER_FIELD_IPv4_PROTO):
+ *parseCodeRealSize = 1;
+ break;
+ case(NET_HEADER_FIELD_IPv4_DST_IP | NET_HEADER_FIELD_IPv4_SRC_IP):
+ *parseCodeRealSize = 8;
+ break;
+ case(NET_HEADER_FIELD_IPv4_TTL):
+ *parseCodeRealSize = 1;
+ break;
+ default:
+ REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported4"));
+ *parseCodeRealSize = CC_SIZE_ILLEGAL;
+ break;
+ }
+ break;
+ case (HEADER_TYPE_IPv6):
+ switch(field.ipv6)
+ {
+ case(NET_HEADER_FIELD_IPv6_VER | NET_HEADER_FIELD_IPv6_FL | NET_HEADER_FIELD_IPv6_TC):
+ *parseCodeRealSize = 4;
+ break;
+ case(NET_HEADER_FIELD_IPv6_NEXT_HDR):
+ case(NET_HEADER_FIELD_IPv6_HOP_LIMIT):
+ *parseCodeRealSize = 1;
+ break;
+ case(NET_HEADER_FIELD_IPv6_DST_IP):
+ case(NET_HEADER_FIELD_IPv6_SRC_IP):
+ *parseCodeRealSize = 16;
+ break;
+ default:
+ REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported5"));
+ *parseCodeRealSize = CC_SIZE_ILLEGAL;
+ break;
+ }
+ break;
+ case (HEADER_TYPE_GRE):
+ switch(field.gre)
+ {
+ case(NET_HEADER_FIELD_GRE_TYPE):
+ *parseCodeRealSize = 2;
+ break;
+ default:
+ REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported6"));
+ *parseCodeRealSize = CC_SIZE_ILLEGAL;
+ break;
+ }
+ break;
+ case (HEADER_TYPE_MINENCAP):
+ switch(field.minencap)
+ {
+ case(NET_HEADER_FIELD_MINENCAP_TYPE):
+ *parseCodeRealSize = 1;
+ break;
+ case(NET_HEADER_FIELD_MINENCAP_DST_IP):
+ case(NET_HEADER_FIELD_MINENCAP_SRC_IP):
+ *parseCodeRealSize = 4;
+ break;
+ case(NET_HEADER_FIELD_MINENCAP_SRC_IP | NET_HEADER_FIELD_MINENCAP_DST_IP):
+ *parseCodeRealSize = 8;
+ break;
+ default:
+ REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported7"));
+ *parseCodeRealSize = CC_SIZE_ILLEGAL;
+ break;
+ }
+ break;
+ case (HEADER_TYPE_TCP):
+ switch(field.tcp)
+ {
+ case(NET_HEADER_FIELD_TCP_PORT_SRC):
+ case(NET_HEADER_FIELD_TCP_PORT_DST):
+ *parseCodeRealSize = 2;
+ break;
+ case(NET_HEADER_FIELD_TCP_PORT_SRC | NET_HEADER_FIELD_TCP_PORT_DST):
+ *parseCodeRealSize = 4;
+ break;
+ default:
+ REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported8"));
+ *parseCodeRealSize = CC_SIZE_ILLEGAL;
+ break;
+ }
+ break;
+ case (HEADER_TYPE_UDP):
+ switch(field.udp)
+ {
+ case(NET_HEADER_FIELD_UDP_PORT_SRC):
+ case(NET_HEADER_FIELD_UDP_PORT_DST):
+ *parseCodeRealSize = 2;
+ break;
+ case(NET_HEADER_FIELD_UDP_PORT_SRC | NET_HEADER_FIELD_UDP_PORT_DST):
+ *parseCodeRealSize = 4;
+ break;
+ default:
+ REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported9"));
+ *parseCodeRealSize = CC_SIZE_ILLEGAL;
+ break;
+ }
+ break;
+ default:
+ REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported10"));
+ *parseCodeRealSize = CC_SIZE_ILLEGAL;
+ break;
+ }
+}
+
+static t_Error ValidateNextEngineParams(t_Handle h_FmPcd, t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams)
+{
+ uint16_t absoluteProfileId;
+ t_Error err = E_OK;
+ uint8_t relativeSchemeId;
+
+ switch(p_FmPcdCcNextEngineParams->nextEngine)
+ {
+ case(e_FM_PCD_INVALID):
+ err = E_NOT_SUPPORTED;
+ break;
+ case(e_FM_PCD_DONE):
+ if(p_FmPcdCcNextEngineParams->params.enqueueParams.action == e_FM_PCD_ENQ_FRAME)
+ {
+ if(p_FmPcdCcNextEngineParams->params.enqueueParams.overrideFqid &&
+ !p_FmPcdCcNextEngineParams->params.enqueueParams.newFqid)
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("not defined fqid for control flow for BMI next engine "));
+ if(p_FmPcdCcNextEngineParams->params.enqueueParams.newFqid & ~0x00FFFFFF)
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fqidForCtrlFlow must be between 1 and 2^24-1"));
+ }
+ break;
+ case(e_FM_PCD_KG):
+ relativeSchemeId = FmPcdKgGetRelativeSchemeId(h_FmPcd, (uint8_t)(PTR_TO_UINT(p_FmPcdCcNextEngineParams->params.kgParams.h_DirectScheme)-1));
+ if(relativeSchemeId == FM_PCD_KG_NUM_OF_SCHEMES)
+ RETURN_ERROR(MAJOR, E_NOT_IN_RANGE, NO_MSG);
+
+ if(!FmPcdKgIsSchemeValidSw(h_FmPcd, relativeSchemeId))
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("not valid schemeIndex in KG next engine param"));
+ if(!KgIsSchemeAlwaysDirect(h_FmPcd, relativeSchemeId))
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("CC Node may point only to a scheme that is always direct."));
+ break;
+ case(e_FM_PCD_PLCR):
+ if(p_FmPcdCcNextEngineParams->params.plcrParams.overrideParams)
+ {
+ /* if private policer profile, it may be uninitialized yet, therefor no checks are done at this stage */
+ if(p_FmPcdCcNextEngineParams->params.plcrParams.sharedProfile)
+ {
+ err = FmPcdPlcrGetAbsoluteProfileId(h_FmPcd,e_FM_PCD_PLCR_SHARED,NULL,p_FmPcdCcNextEngineParams->params.plcrParams.newRelativeProfileId, &absoluteProfileId);
+ if(err)
+ RETURN_ERROR(MAJOR, err, ("Shared profile offset is out of range"));
+ if(!FmPcdPlcrIsProfileValid(h_FmPcd, absoluteProfileId))
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid profile"));
+ }
+ else
+ {
+ }
+ /* TODO - add check according to the revision of the chip.
+ if(!p_FmPcdCcNextEngineParams->params.plcrParams.newFqid ||
+ (p_FmPcdCcNextEngineParams->params.plcrParams.newFqid & ~0x00FFFFFF))
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("newFqid must be between 1 and 2^24-1"));
+ */
+ }
+ break;
+ case(e_FM_PCD_CC):
+ if(!p_FmPcdCcNextEngineParams->params.ccParams.h_CcNode)
+ RETURN_ERROR(MAJOR, E_NULL_POINTER, ("handler to next Node is NULL"));
+ break;
+ default:
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Next engine is not correct"));
+ }
+ return err;
+}
+
+static uint8_t GetGenParseCode(e_FmPcdExtractFrom src, uint32_t offset, bool glblMask, uint8_t *parseArrayOffset, bool fromIc, ccPrivateInfo_t icCode)
+{
+ if(!fromIc)
+ {
+ switch(src)
+ {
+ case(e_FM_PCD_EXTRACT_FROM_FRAME_START):
+ if(glblMask)
+ return CC_PC_GENERIC_WITH_MASK ;
+ else
+ return CC_PC_GENERIC_WITHOUT_MASK;
+ case(e_FM_PCD_EXTRACT_FROM_CURR_END_OF_PARSE):
+ *parseArrayOffset = CC_PC_PR_NEXT_HEADER_OFFSET;
+ if(offset)
+ return CC_PR_OFFSET;
+ else
+ return CC_PR_WITHOUT_OFFSET;
+ default:
+ REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal 'extract from' src"));
+ return CC_PC_ILLEGAL;
+ }
+ }
+ else
+ {
+ switch (icCode)
+ {
+ case(CC_PRIVATE_INFO_IC_KEY_EXACT_MATCH):
+ *parseArrayOffset = 0x50;
+ return CC_PC_GENERIC_IC_GMASK;
+ case(CC_PRIVATE_INFO_IC_HASH_EXACT_MATCH):
+ *parseArrayOffset = 0x48;
+ return CC_PC_GENERIC_IC_GMASK;
+ case(CC_PRIVATE_INFO_IC_HASH_INDEX_LOOKUP):
+ *parseArrayOffset = 0x48;
+ return CC_PC_GENERIC_IC_HASH_INDEXED;
+ case(CC_PRIVATE_INFO_IC_DEQ_FQID_INDEX_LOOKUP):
+ *parseArrayOffset = 0x16;
+ return CC_PC_GENERIC_IC_HASH_INDEXED;
+ default:
+ REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal 'extract from' src"));
+ break;
+ }
+ }
+ return CC_PC_ILLEGAL;
+}
+
+static uint8_t GetFullFieldParseCode(e_NetHeaderType hdr, e_FmPcdHdrIndex index, t_FmPcdFields field)
+{
+
+ switch(hdr)
+ {
+ case(HEADER_TYPE_NONE):
+ ASSERT_COND(FALSE);
+ return CC_PC_ILLEGAL;
+
+ case(HEADER_TYPE_ETH):
+ switch(field.eth)
+ {
+ case(NET_HEADER_FIELD_ETH_DA):
+ return CC_PC_FF_MACDST;
+ case(NET_HEADER_FIELD_ETH_SA):
+ return CC_PC_FF_MACSRC;
+ case(NET_HEADER_FIELD_ETH_TYPE):
+ return CC_PC_FF_ETYPE;
+ default:
+ REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
+ return CC_PC_ILLEGAL;
+ }
+
+ case(HEADER_TYPE_VLAN):
+ switch(field.vlan)
+ {
+ case(NET_HEADER_FIELD_VLAN_TCI):
+ if((index == e_FM_PCD_HDR_INDEX_NONE) || (index == e_FM_PCD_HDR_INDEX_1))
+ return CC_PC_FF_TCI1;
+ if(index == e_FM_PCD_HDR_INDEX_LAST)
+ return CC_PC_FF_TCI2;
+ REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
+ return CC_PC_ILLEGAL;
+ default:
+ REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
+ return CC_PC_ILLEGAL;
+ }
+
+ case(HEADER_TYPE_MPLS):
+ switch(field.mpls)
+ {
+ case(NET_HEADER_FIELD_MPLS_LABEL_STACK):
+ if((index == e_FM_PCD_HDR_INDEX_NONE) || (index == e_FM_PCD_HDR_INDEX_1))
+ return CC_PC_FF_MPLS1;
+ if(index == e_FM_PCD_HDR_INDEX_LAST)
+ return CC_PC_FF_MPLS_LAST;
+ REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal MPLS index"));
+ return CC_PC_ILLEGAL;
+ default:
+ REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
+ return CC_PC_ILLEGAL;
+ }
+
+ case(HEADER_TYPE_IPv4):
+ switch(field.ipv4)
+ {
+ case(NET_HEADER_FIELD_IPv4_DST_IP):
+ if((index == e_FM_PCD_HDR_INDEX_NONE) || (index == e_FM_PCD_HDR_INDEX_1))
+ return CC_PC_FF_IPV4DST1;
+ if(index == e_FM_PCD_HDR_INDEX_2)
+ return CC_PC_FF_IPV4DST2;
+ REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv4 index"));
+ return CC_PC_ILLEGAL;
+ case(NET_HEADER_FIELD_IPv4_TOS):
+ if((index == e_FM_PCD_HDR_INDEX_NONE) || (index == e_FM_PCD_HDR_INDEX_1))
+ return CC_PC_FF_IPV4IPTOS_TC1;
+ if(index == e_FM_PCD_HDR_INDEX_2)
+ return CC_PC_FF_IPV4IPTOS_TC2;
+ REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv4 index"));
+ return CC_PC_ILLEGAL;
+ case(NET_HEADER_FIELD_IPv4_PROTO):
+ if((index == e_FM_PCD_HDR_INDEX_NONE) || (index == e_FM_PCD_HDR_INDEX_1))
+ return CC_PC_FF_IPV4PTYPE1;
+ if(index == e_FM_PCD_HDR_INDEX_2)
+ return CC_PC_FF_IPV4PTYPE2;
+ REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv4 index"));
+ return CC_PC_ILLEGAL;
+ case(NET_HEADER_FIELD_IPv4_SRC_IP):
+ if((index == e_FM_PCD_HDR_INDEX_NONE) || (index == e_FM_PCD_HDR_INDEX_1))
+ return CC_PC_FF_IPV4SRC1;
+ if(index == e_FM_PCD_HDR_INDEX_2)
+ return CC_PC_FF_IPV4SRC2;
+ REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv4 index"));
+ return CC_PC_ILLEGAL;
+ case(NET_HEADER_FIELD_IPv4_SRC_IP | NET_HEADER_FIELD_IPv4_DST_IP):
+ if((index == e_FM_PCD_HDR_INDEX_NONE) || (index == e_FM_PCD_HDR_INDEX_1))
+ return CC_PC_FF_IPV4SRC1_IPV4DST1;
+ if(index == e_FM_PCD_HDR_INDEX_2)
+ return CC_PC_FF_IPV4SRC2_IPV4DST2;
+ REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv4 index"));
+ return CC_PC_ILLEGAL;
+ case(NET_HEADER_FIELD_IPv4_TTL):
+ return CC_PC_FF_IPV4TTL;
+ default:
+ REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
+ return CC_PC_ILLEGAL;
+ }
+
+ case(HEADER_TYPE_IPv6):
+ switch(field.ipv6)
+ {
+ case(NET_HEADER_FIELD_IPv6_VER | NET_HEADER_FIELD_IPv6_FL | NET_HEADER_FIELD_IPv6_TC):
+ if((index == e_FM_PCD_HDR_INDEX_NONE) || (index == e_FM_PCD_HDR_INDEX_1))
+ return CC_PC_FF_IPTOS_IPV6TC1_IPV6FLOW1;
+ if(index == e_FM_PCD_HDR_INDEX_2)
+ return CC_PC_FF_IPTOS_IPV6TC2_IPV6FLOW2;
+ REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv6 index"));
+ return CC_PC_ILLEGAL;
+ case(NET_HEADER_FIELD_IPv6_NEXT_HDR):
+ if((index == e_FM_PCD_HDR_INDEX_NONE) || (index == e_FM_PCD_HDR_INDEX_1))
+ return CC_PC_FF_IPV6PTYPE1;
+ if(index == e_FM_PCD_HDR_INDEX_2)
+ return CC_PC_FF_IPV6PTYPE2;
+ REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv6 index"));
+ return CC_PC_ILLEGAL;
+ case(NET_HEADER_FIELD_IPv6_DST_IP):
+ if((index == e_FM_PCD_HDR_INDEX_NONE) || (index == e_FM_PCD_HDR_INDEX_1))
+ return CC_PC_FF_IPV6DST1;
+ if(index == e_FM_PCD_HDR_INDEX_2)
+ return CC_PC_FF_IPV6DST2;
+ REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv6 index"));
+ return CC_PC_ILLEGAL;
+ case(NET_HEADER_FIELD_IPv6_SRC_IP):
+ if((index == e_FM_PCD_HDR_INDEX_NONE) || (index == e_FM_PCD_HDR_INDEX_1))
+ return CC_PC_FF_IPV6SRC1;
+ if(index == e_FM_PCD_HDR_INDEX_2)
+ return CC_PC_FF_IPV6SRC2;
+ REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv6 index"));
+ return CC_PC_ILLEGAL;
+ case(NET_HEADER_FIELD_IPv6_HOP_LIMIT):
+ return CC_PC_FF_IPV6HOP_LIMIT;
+ default:
+ REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
+ return CC_PC_ILLEGAL;
+ }
+
+ case(HEADER_TYPE_GRE):
+ switch(field.gre)
+ {
+ case(NET_HEADER_FIELD_GRE_TYPE):
+ return CC_PC_FF_GREPTYPE;
+ default:
+ REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
+ return CC_PC_ILLEGAL;
+ }
+ case(HEADER_TYPE_MINENCAP):
+ switch(field.minencap)
+ {
+ case(NET_HEADER_FIELD_MINENCAP_TYPE):
+ return CC_PC_FF_MINENCAP_PTYPE;
+ case(NET_HEADER_FIELD_MINENCAP_DST_IP):
+ return CC_PC_FF_MINENCAP_IPDST;
+ case(NET_HEADER_FIELD_MINENCAP_SRC_IP):
+ return CC_PC_FF_MINENCAP_IPSRC;
+ case(NET_HEADER_FIELD_MINENCAP_SRC_IP | NET_HEADER_FIELD_MINENCAP_DST_IP):
+ return CC_PC_FF_MINENCAP_IPSRC_IPDST;
+ default:
+ REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
+ return CC_PC_ILLEGAL;
+ }
+
+ case(HEADER_TYPE_TCP):
+ switch(field.tcp)
+ {
+ case(NET_HEADER_FIELD_TCP_PORT_SRC):
+ return CC_PC_FF_L4PSRC;
+ case(NET_HEADER_FIELD_TCP_PORT_DST):
+ return CC_PC_FF_L4PDST;
+ case(NET_HEADER_FIELD_TCP_PORT_DST | NET_HEADER_FIELD_TCP_PORT_SRC):
+ return CC_PC_FF_L4PSRC_L4PDST;
+ default:
+ REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
+ return CC_PC_ILLEGAL;
+ }
+
+ case(HEADER_TYPE_PPPoE):
+ switch(field.pppoe)
+ {
+ case(NET_HEADER_FIELD_PPPoE_PID):
+ return CC_PC_FF_PPPPID;
+ default:
+ REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
+ return CC_PC_ILLEGAL;
+ }
+
+ case(HEADER_TYPE_UDP):
+ switch(field.udp)
+ {
+ case(NET_HEADER_FIELD_UDP_PORT_SRC):
+ return CC_PC_FF_L4PSRC;
+ case(NET_HEADER_FIELD_UDP_PORT_DST):
+ return CC_PC_FF_L4PDST;
+ case(NET_HEADER_FIELD_UDP_PORT_DST | NET_HEADER_FIELD_UDP_PORT_SRC):
+ return CC_PC_FF_L4PSRC_L4PDST;
+ default:
+ REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
+ return CC_PC_ILLEGAL;
+ }
+
+ default:
+ REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
+ return CC_PC_ILLEGAL;
+ }
+}
+
+static uint8_t GetPrParseCode(e_NetHeaderType hdr, e_FmPcdHdrIndex hdrIndex, uint32_t offset, bool glblMask, uint8_t *parseArrayOffset)
+{
+ bool offsetRelevant = FALSE;
+
+ if(offset)
+ offsetRelevant = TRUE;
+
+ switch(hdr){
+ case(HEADER_TYPE_NONE):
+ ASSERT_COND(FALSE);
+ return CC_PC_ILLEGAL;
+ case(HEADER_TYPE_ETH):
+ *parseArrayOffset = (uint8_t)CC_PC_PR_ETH_OFFSET;
+ break;
+ case(HEADER_TYPE_USER_DEFINED_SHIM1):
+ if(offset || glblMask)
+ *parseArrayOffset = (uint8_t)CC_PC_PR_USER_DEFINED_SHIM1_OFFSET;
+ else
+ return CC_PC_PR_SHIM1;
+ break;
+ case(HEADER_TYPE_USER_DEFINED_SHIM2):
+ if(offset || glblMask)
+ *parseArrayOffset = (uint8_t)CC_PC_PR_USER_DEFINED_SHIM2_OFFSET;
+ else
+ return CC_PC_PR_SHIM2;
+ break;
+ case(HEADER_TYPE_LLC_SNAP):
+ *parseArrayOffset = CC_PC_PR_USER_LLC_SNAP_OFFSET;
+ break;
+ case(HEADER_TYPE_PPPoE):
+ *parseArrayOffset = CC_PC_PR_PPPOE_OFFSET;
+ break;
+ case(HEADER_TYPE_MPLS):
+ if((hdrIndex == e_FM_PCD_HDR_INDEX_NONE) || (hdrIndex == e_FM_PCD_HDR_INDEX_1))
+ *parseArrayOffset = CC_PC_PR_MPLS1_OFFSET;
+ else if(hdrIndex == e_FM_PCD_HDR_INDEX_LAST)
+ *parseArrayOffset = CC_PC_PR_MPLS_LAST_OFFSET;
+ else
+ {
+ REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal MPLS header index"));
+ return CC_PC_ILLEGAL;
+ }
+ break;
+ case(HEADER_TYPE_IPv4):
+ case(HEADER_TYPE_IPv6):
+ if((hdrIndex == e_FM_PCD_HDR_INDEX_NONE) || (hdrIndex == e_FM_PCD_HDR_INDEX_1))
+ *parseArrayOffset = CC_PC_PR_IP1_OFFSET;
+ else if(hdrIndex == e_FM_PCD_HDR_INDEX_2)
+ *parseArrayOffset = CC_PC_PR_IP_LAST_OFFSET;
+ else
+ {
+ REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IP header index"));
+ return CC_PC_ILLEGAL;
+
+ }
+ break;
+ case(HEADER_TYPE_MINENCAP):
+ *parseArrayOffset = CC_PC_PR_MINENC_OFFSET;
+ break;
+ case(HEADER_TYPE_GRE):
+ *parseArrayOffset = CC_PC_PR_GRE_OFFSET;
+ break;
+ case(HEADER_TYPE_TCP):
+ case(HEADER_TYPE_UDP):
+ case(HEADER_TYPE_IPSEC_AH):
+ case(HEADER_TYPE_IPSEC_ESP):
+ case(HEADER_TYPE_DCCP):
+ case(HEADER_TYPE_SCTP):
+ *parseArrayOffset = CC_PC_PR_L4_OFFSET;
+ break;
+
+ default:
+ REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IP header for this type of operation"));
+ return CC_PC_ILLEGAL;
+ }
+
+ if(offsetRelevant)
+ return CC_PR_OFFSET;
+ else
+ return CC_PR_WITHOUT_OFFSET;
+}
+
+static uint8_t GetFieldParseCode(e_NetHeaderType hdr, t_FmPcdFields field, uint32_t offset, uint8_t *parseArrayOffset, e_FmPcdHdrIndex hdrIndex)
+{
+ bool offsetRelevant = FALSE;
+
+ if(offset)
+ offsetRelevant = TRUE;
+
+ switch(hdr)
+ {
+ case(HEADER_TYPE_NONE):
+ ASSERT_COND(FALSE);
+ case(HEADER_TYPE_ETH):
+ switch(field.eth)
+ {
+ case(NET_HEADER_FIELD_ETH_TYPE):
+ *parseArrayOffset = CC_PC_PR_ETYPE_LAST_OFFSET;
+ break;
+ default:
+ REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
+ return CC_PC_ILLEGAL;
+ }
+ break;
+ case(HEADER_TYPE_VLAN):
+ switch(field.vlan)
+ {
+ case(NET_HEADER_FIELD_VLAN_TCI):
+ if((hdrIndex == e_FM_PCD_HDR_INDEX_NONE) || (hdrIndex == e_FM_PCD_HDR_INDEX_1))
+ *parseArrayOffset = CC_PC_PR_VLAN1_OFFSET;
+ else if(hdrIndex == e_FM_PCD_HDR_INDEX_LAST)
+ *parseArrayOffset = CC_PC_PR_VLAN2_OFFSET;
+ break;
+ default:
+ REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
+ return CC_PC_ILLEGAL;
+ }
+ break;
+ default:
+ REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal header "));
+ return CC_PC_ILLEGAL;
+ }
+ if(offsetRelevant)
+ return CC_PR_OFFSET;
+ else
+ return CC_PR_WITHOUT_OFFSET;
+}
+
+static void FillAdOfTypeResult(t_Handle p_Ad, t_FmPcd *p_FmPcd, t_FmPcdCcNextEngineParams *p_CcNextEngineParams)
+{
+ t_AdOfTypeResult *p_AdResult = (t_AdOfTypeResult*)p_Ad;
+ uint32_t tmp = 0, tmpNia = 0;
+ uint16_t profileId;
+ t_Handle p_AdNewPtr = NULL;
+
+ p_AdNewPtr = p_AdResult;
+
+#ifdef FM_PCD_CC_MANIP
+ if (p_CcNextEngineParams->h_Manip)
+ FmPcdManipUpdateAdResultForCc(p_CcNextEngineParams->h_Manip, p_Ad, &p_AdNewPtr);
+#endif /* FM_PCD_CC_MANIP */
+
+ if(p_AdNewPtr)
+ {
+ switch(p_CcNextEngineParams->nextEngine)
+ {
+ case(e_FM_PCD_DONE):
+ if(p_CcNextEngineParams->params.enqueueParams.action == e_FM_PCD_ENQ_FRAME)
+ {
+ if(p_CcNextEngineParams->params.enqueueParams.overrideFqid)
+ {
+ tmp = FM_PCD_AD_RESULT_CONTRL_FLOW_TYPE;
+ tmp |= p_CcNextEngineParams->params.enqueueParams.newFqid;
+ }
+ else
+ {
+ tmp = FM_PCD_AD_RESULT_DATA_FLOW_TYPE;
+ tmp |= FM_PCD_AD_RESULT_PLCR_DIS;
+ }
+ }
+ if(p_CcNextEngineParams->params.enqueueParams.action == e_FM_PCD_DROP_FRAME)
+ tmpNia |= (NIA_ENG_BMI |NIA_BMI_AC_DISCARD);
+ else
+ tmpNia |= (NIA_ENG_BMI |NIA_BMI_AC_ENQ_FRAME);
+ if(p_CcNextEngineParams->params.enqueueParams.statisticsEn)
+ tmpNia |= FM_PCD_AD_RESULT_EXTENDED_MODE | FM_PCD_AD_RESULT_STATISTICS_EN;
+ break;
+ case(e_FM_PCD_KG):
+ if(p_CcNextEngineParams->params.kgParams.overrideFqid)
+ {
+ tmp = FM_PCD_AD_RESULT_CONTRL_FLOW_TYPE;
+ tmp |= p_CcNextEngineParams->params.kgParams.newFqid;
+ }
+ else
+ {
+ tmp = FM_PCD_AD_RESULT_DATA_FLOW_TYPE;
+ tmp |= FM_PCD_AD_RESULT_PLCR_DIS;
+ }
+ tmpNia = NIA_KG_DIRECT;
+ tmpNia |= NIA_ENG_KG;
+ tmpNia |= (uint8_t)(PTR_TO_UINT(p_CcNextEngineParams->params.kgParams.h_DirectScheme)-1);
+ if(p_CcNextEngineParams->params.kgParams.statisticsEn)
+ tmpNia |= FM_PCD_AD_RESULT_EXTENDED_MODE | FM_PCD_AD_RESULT_STATISTICS_EN;
+ break;
+ case(e_FM_PCD_PLCR):
+ tmp = 0;
+ if(p_CcNextEngineParams->params.plcrParams.overrideParams)
+ {
+ tmp = FM_PCD_AD_RESULT_CONTRL_FLOW_TYPE;
+
+ /* if private policer profile, it may be uninitialized yet, therefor no checks are done at this stage */
+ if(p_CcNextEngineParams->params.plcrParams.sharedProfile)
+ {
+ tmpNia |= NIA_PLCR_ABSOLUTE;
+ FmPcdPlcrGetAbsoluteProfileId((t_Handle)p_FmPcd,e_FM_PCD_PLCR_SHARED,NULL,p_CcNextEngineParams->params.plcrParams.newRelativeProfileId, &profileId);
+ }
+ else
+ profileId = p_CcNextEngineParams->params.plcrParams.newRelativeProfileId;
+
+ tmp |= p_CcNextEngineParams->params.plcrParams.newFqid;
+ WRITE_UINT32(p_AdResult->plcrProfile,(uint32_t)((uint32_t)profileId << FM_PCD_AD_PROFILEID_FOR_CNTRL_SHIFT));
+ }
+ else
+ tmp = FM_PCD_AD_RESULT_DATA_FLOW_TYPE;
+ tmpNia |= NIA_ENG_PLCR | p_CcNextEngineParams->params.plcrParams.newRelativeProfileId;
+ if(p_CcNextEngineParams->params.kgParams.statisticsEn)
+ tmpNia |= FM_PCD_AD_RESULT_EXTENDED_MODE | FM_PCD_AD_RESULT_STATISTICS_EN;
+ break;
+ default:
+ return;
+ }
+ WRITE_UINT32(p_AdResult->fqid, tmp);
+
+#ifdef FM_PCD_CC_MANIP
+ if(p_CcNextEngineParams->h_Manip)
+ {
+ tmp = GET_UINT32(p_AdResult->plcrProfile);
+ tmp |= (uint32_t)(XX_VirtToPhys(p_AdNewPtr) - (p_FmPcd->physicalMuramBase)) >> 4;
+ WRITE_UINT32(p_AdResult->plcrProfile, tmp);
+
+ tmpNia |= FM_PCD_AD_RESULT_EXTENDED_MODE;
+ tmpNia |= FM_PCD_AD_RESULT_NADEN;
+ }
+#endif /* FM_PCD_CC_MANIP */
+
+ WRITE_UINT32(p_AdResult->nia, tmpNia);
+ }
+}
+
+static void FillAdOfTypeContLookup(t_Handle p_Ad, t_Handle h_FmPcd, t_Handle p_FmPcdCcNode, t_Handle h_Manip)
+{
+ t_FmPcdCcNode *p_Node = (t_FmPcdCcNode *)p_FmPcdCcNode;
+ t_AdOfTypeContLookup *p_AdContLookup = (t_AdOfTypeContLookup *)p_Ad;
+ t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
+ uint32_t tmpReg32;
+ t_Handle p_AdNewPtr = NULL;
+
+ p_AdNewPtr = p_AdContLookup;
+
+#ifdef FM_PCD_CC_MANIP
+ if (h_Manip)
+ FmPcdManipUpdateAdContLookupForCc(h_Manip, p_Ad, &p_AdNewPtr, (uint32_t)((XX_VirtToPhys(p_Node->h_AdTable) - p_FmPcd->physicalMuramBase)));
+#else
+ UNUSED(h_Manip);
+#endif /* FM_PCD_CC_MANIP */
+
+ if(p_AdNewPtr)
+ {
+ tmpReg32 = 0;
+ tmpReg32 |= FM_PCD_AD_CONT_LOOKUP_TYPE;
+ tmpReg32 |= p_Node->sizeOfExtraction ? ((p_Node->sizeOfExtraction - 1) << 24) : 0;
+ tmpReg32 |= (uint32_t)(XX_VirtToPhys(p_Node->h_AdTable) - p_FmPcd->physicalMuramBase);
+ WRITE_UINT32(p_AdContLookup->ccAdBase, tmpReg32);
+
+ tmpReg32 = 0;
+ tmpReg32 |= p_Node->numOfKeys << 24;
+ tmpReg32 |= (p_Node->lclMask ? FM_PCD_AD_CONT_LOOKUP_LCL_MASK : 0);
+ tmpReg32 |= p_Node->h_KeysMatchTable ?
+ (uint32_t)(XX_VirtToPhys(p_Node->h_KeysMatchTable) - p_FmPcd->physicalMuramBase) : 0;
+ WRITE_UINT32(p_AdContLookup->matchTblPtr, tmpReg32);
+
+ tmpReg32 = 0;
+ tmpReg32 |= p_Node->prsArrayOffset << 24;
+ tmpReg32 |= p_Node->offset << 16;
+ tmpReg32 |= p_Node->parseCode;
+ WRITE_UINT32(p_AdContLookup->pcAndOffsets, tmpReg32);
+
+ Mem2IOCpy32((void*)&p_AdContLookup->gmask, p_Node->p_GlblMask, CC_GLBL_MASK_SIZE);
+ }
+}
+
+static void NextStepAd(t_Handle p_Ad, t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams, t_FmPcd *p_FmPcd)
+{
+ switch(p_FmPcdCcNextEngineParams->nextEngine)
+ {
+ case(e_FM_PCD_KG):
+ case(e_FM_PCD_PLCR):
+ case(e_FM_PCD_DONE):
+ FillAdOfTypeResult(p_Ad, p_FmPcd, p_FmPcdCcNextEngineParams);
+ break;
+ case(e_FM_PCD_CC):
+ FillAdOfTypeContLookup(p_Ad,
+ p_FmPcd,
+ p_FmPcdCcNextEngineParams->params.ccParams.h_CcNode,
+#ifdef FM_PCD_CC_MANIP
+ p_FmPcdCcNextEngineParams->h_Manip
+#else
+ NULL
+#endif /* FM_PCD_CC_MANIP */
+ );
+ UpdateNodeOwner (p_FmPcdCcNextEngineParams->params.ccParams.h_CcNode,
+ TRUE);
+ break;
+ default:
+ return;
+ }
+}
+
+
+static void ReleaseNewNodeCommonPart(t_FmPcdModifyCcKeyAdditionalParams *p_AdditionalInfo)
+{
+ if(p_AdditionalInfo->p_AdTableNew)
+ FM_MURAM_FreeMem(FmPcdGetMuramHandle(((t_FmPcdCcNode *)(p_AdditionalInfo->h_CurrentNode))->h_FmPcd), p_AdditionalInfo->p_AdTableNew);
+ if(p_AdditionalInfo->p_KeysMatchTableNew)
+ FM_MURAM_FreeMem(FmPcdGetMuramHandle(((t_FmPcdCcNode *)(p_AdditionalInfo->h_CurrentNode))->h_FmPcd), p_AdditionalInfo->p_KeysMatchTableNew);
+}
+
+static t_Error UpdateGblMask(t_FmPcdCcNode *p_FmPcdCcNode, uint8_t keySize, uint8_t *p_Mask)
+{
+ if (p_Mask &&
+ !p_FmPcdCcNode->glblMaskUpdated &&
+ (keySize <= 4) &&
+ !p_FmPcdCcNode->lclMask )
+ {
+ memcpy(p_FmPcdCcNode->p_GlblMask, p_Mask, (sizeof(uint8_t))*keySize);
+ p_FmPcdCcNode->glblMaskUpdated = TRUE;
+ p_FmPcdCcNode->glblMaskSize = 4;
+ }
+ else if (p_Mask &&
+ (keySize <= 4) &&
+ !p_FmPcdCcNode->lclMask)
+ {
+ if (memcmp(p_FmPcdCcNode->p_GlblMask, p_Mask, keySize) != 0)
+ {
+ p_FmPcdCcNode->lclMask = TRUE;
+ p_FmPcdCcNode->glblMaskSize = 0;
+ }
+ }
+ else if (!p_Mask && (p_FmPcdCcNode->glblMaskUpdated) && (keySize <= 4))
+ {
+ uint32_t tmpMask = 0xffffffff;
+ if (memcmp(p_FmPcdCcNode->p_GlblMask, &tmpMask, 4) != 0)
+ {
+ p_FmPcdCcNode->lclMask = TRUE;
+ p_FmPcdCcNode->glblMaskSize = 0;
+ }
+ }
+ else if (p_Mask)
+ {
+ p_FmPcdCcNode->lclMask = TRUE;
+ p_FmPcdCcNode->glblMaskSize = 0;
+ }
+
+ return E_OK;
+}
+
+static t_Error BuildNewNodeCommonPart(t_FmPcdCcNode *p_FmPcdCcNode,
+ int *size,
+ t_FmPcdModifyCcKeyAdditionalParams *p_AdditionalInfo)
+{
+
+ p_AdditionalInfo->p_AdTableNew = (t_Handle)FM_MURAM_AllocMem(FmPcdGetMuramHandle(p_FmPcdCcNode->h_FmPcd),
+ (uint32_t)( (p_AdditionalInfo->numOfKeys+1) * FM_PCD_CC_AD_ENTRY_SIZE),
+ FM_PCD_CC_AD_TABLE_ALIGN);
+ if(!p_AdditionalInfo->p_AdTableNew)
+ RETURN_ERROR(MAJOR, E_NO_MEMORY, ("No memory in MURAM for AD table "));
+
+ IOMemSet32((uint8_t*)p_AdditionalInfo->p_AdTableNew, 0, (uint32_t)((p_AdditionalInfo->numOfKeys+1) * FM_PCD_CC_AD_ENTRY_SIZE));
+
+ if(p_FmPcdCcNode->lclMask)
+ *size = 2 * p_FmPcdCcNode->ccKeySizeAccExtraction;
+ else
+ *size = p_FmPcdCcNode->ccKeySizeAccExtraction;
+
+ p_AdditionalInfo->p_KeysMatchTableNew =
+ (t_Handle)FM_MURAM_AllocMem(FmPcdGetMuramHandle(p_FmPcdCcNode->h_FmPcd),
+ (uint32_t)(*size * sizeof(uint8_t) * (p_AdditionalInfo->numOfKeys + 1)),
+ FM_PCD_CC_KEYS_MATCH_TABLE_ALIGN);
+ if(!p_AdditionalInfo->p_KeysMatchTableNew)
+ {
+ FM_MURAM_FreeMem(FmPcdGetMuramHandle(p_FmPcdCcNode->h_FmPcd), p_AdditionalInfo->p_AdTableNew);
+ p_AdditionalInfo->p_AdTableNew = NULL;
+ RETURN_ERROR(MAJOR, E_NO_MEMORY, ("No memory in MURAM for KEY MATCH table"));
+ }
+ IOMemSet32((uint8_t*)p_AdditionalInfo->p_KeysMatchTableNew, 0, *size * sizeof(uint8_t) * (p_AdditionalInfo->numOfKeys + 1));
+
+ p_AdditionalInfo->p_AdTableOld = p_FmPcdCcNode->h_AdTable;
+ p_AdditionalInfo->p_KeysMatchTableOld = p_FmPcdCcNode->h_KeysMatchTable;
+
+ return E_OK;
+}
+
+static t_Error BuildNewNodeAddOrMdfyKeyAndNextEngine(t_Handle h_FmPcd ,t_FmPcdCcNode *p_FmPcdCcNode, uint8_t keyIndex, t_FmPcdCcKeyParams *p_KeyParams,t_FmPcdModifyCcKeyAdditionalParams *p_AdditionalInfo, bool add)
+{
+ t_Error err = E_OK;
+ t_Handle p_AdTableNewTmp, p_KeysMatchTableNewTmp;
+ t_Handle p_KeysMatchTableOldTmp, p_AdTableOldTmp;
+ int size;
+ int i = 0, j = 0;
+ t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
+ uint32_t requiredAction = 0;
+ bool prvLclMask;
+ t_CcNodeInformation *p_CcNodeInformation;
+ t_List *p_Pos;
+
+ /*check that new NIA is legal*/
+ err = ValidateNextEngineParams(h_FmPcd, &p_KeyParams->ccNextEngineParams);
+ if(err)
+ RETURN_ERROR(MAJOR, err, NO_MSG);
+
+ prvLclMask = p_FmPcdCcNode->lclMask;
+
+ /*check that new key is not require update of localMask*/
+ err = UpdateGblMask(p_FmPcdCcNode,
+ p_FmPcdCcNode->ccKeySizeAccExtraction,
+ p_KeyParams->p_Mask);
+ if (err != E_OK)
+ RETURN_ERROR(MAJOR, err, NO_MSG);
+
+ /*update internal data structure for next engine per index (index - key)*/
+ memcpy(&p_AdditionalInfo->nextEngineAndRequiredAction[keyIndex].nextEngineParams,&p_KeyParams->ccNextEngineParams, sizeof(t_FmPcdCcNextEngineParams));
+
+ /*update numOfKeys*/
+ if(add)
+ p_AdditionalInfo->numOfKeys = (uint8_t)(p_FmPcdCcNode->numOfKeys + 1);
+ else
+ p_AdditionalInfo->numOfKeys = (uint8_t)p_FmPcdCcNode->numOfKeys;
+ /*function which build in the memory new KeyTbl, AdTbl*/
+ err = BuildNewNodeCommonPart(p_FmPcdCcNode, &size, p_AdditionalInfo);
+ if(err)
+ RETURN_ERROR(MAJOR, err, NO_MSG);
+
+#ifdef FM_PCD_CC_MANIP
+ /*check that manip is legal and what requiredAction is necessary for this manip*/
+ if(p_KeyParams->ccNextEngineParams.h_Manip)
+ {
+ err = FmPcdManipCheckParamsForCcNextEgine(&p_KeyParams->ccNextEngineParams,&requiredAction);
+ if(err)
+ RETURN_ERROR(MAJOR, err, (NO_MSG));
+
+ }
+#endif /* FM_PCD_CC_MANIP */
+
+ p_AdditionalInfo->nextEngineAndRequiredAction[keyIndex].requiredAction = requiredAction;
+
+ p_AdditionalInfo->nextEngineAndRequiredAction[keyIndex].requiredAction |= UPDATE_CC_WITH_TREE;
+
+
+ /*update new Ad and new Key Table according to new requirement*/
+ i = 0;
+ for(j = 0; j < p_AdditionalInfo->numOfKeys; j++)
+ {
+ p_AdTableNewTmp = PTR_MOVE(p_AdditionalInfo->p_AdTableNew, j*FM_PCD_CC_AD_ENTRY_SIZE);
+ if(j == keyIndex)
+ {
+ NextStepAd(p_AdTableNewTmp,&p_KeyParams->ccNextEngineParams, p_FmPcd);
+ p_KeysMatchTableNewTmp = PTR_MOVE(p_AdditionalInfo->p_KeysMatchTableNew, j*size * sizeof(uint8_t));
+ Mem2IOCpy32((void*)p_KeysMatchTableNewTmp, p_KeyParams->p_Key, p_FmPcdCcNode->userSizeOfExtraction);
+ if(p_FmPcdCcNode->lclMask)
+ {
+ if(p_KeyParams->p_Mask)
+ Mem2IOCpy32(PTR_MOVE(p_KeysMatchTableNewTmp, p_FmPcdCcNode->ccKeySizeAccExtraction), p_KeyParams->p_Mask, p_FmPcdCcNode->userSizeOfExtraction);
+ else if (p_FmPcdCcNode->ccKeySizeAccExtraction > 4)
+ IOMemSet32(PTR_MOVE(p_KeysMatchTableNewTmp, p_FmPcdCcNode->ccKeySizeAccExtraction), 0xff, p_FmPcdCcNode->userSizeOfExtraction);
+ else
+ Mem2IOCpy32(PTR_MOVE(p_KeysMatchTableNewTmp, p_FmPcdCcNode->ccKeySizeAccExtraction),p_FmPcdCcNode->p_GlblMask, p_FmPcdCcNode->userSizeOfExtraction);
+ }
+ if(!add)
+ i++;
+ }
+ else
+ {
+ p_AdTableOldTmp = PTR_MOVE(p_AdditionalInfo->p_AdTableOld, i*FM_PCD_CC_AD_ENTRY_SIZE);
+ IO2IOCpy32(p_AdTableNewTmp, p_AdTableOldTmp, FM_PCD_CC_AD_ENTRY_SIZE);
+ p_KeysMatchTableNewTmp = PTR_MOVE(p_AdditionalInfo->p_KeysMatchTableNew, j*size * sizeof(uint8_t));
+ p_KeysMatchTableOldTmp = PTR_MOVE(p_AdditionalInfo->p_KeysMatchTableOld, i*size * sizeof(uint8_t));
+
+ if(p_FmPcdCcNode->lclMask)
+ {
+ if(prvLclMask)
+ IO2IOCpy32(PTR_MOVE(p_KeysMatchTableNewTmp, p_FmPcdCcNode->ccKeySizeAccExtraction),
+ PTR_MOVE(p_KeysMatchTableOldTmp, p_FmPcdCcNode->ccKeySizeAccExtraction),
+ p_FmPcdCcNode->ccKeySizeAccExtraction);
+ else
+ {
+ p_KeysMatchTableOldTmp = PTR_MOVE(p_FmPcdCcNode->h_KeysMatchTable, i*p_FmPcdCcNode->ccKeySizeAccExtraction*sizeof(uint8_t));
+
+ if (p_FmPcdCcNode->ccKeySizeAccExtraction > 4)
+ IOMemSet32(PTR_MOVE(p_KeysMatchTableNewTmp, p_FmPcdCcNode->ccKeySizeAccExtraction), 0xff, p_FmPcdCcNode->userSizeOfExtraction);
+ else
+ IO2IOCpy32(PTR_MOVE(p_KeysMatchTableNewTmp, p_FmPcdCcNode->ccKeySizeAccExtraction), p_FmPcdCcNode->p_GlblMask, p_FmPcdCcNode->userSizeOfExtraction);
+ }
+ }
+ IO2IOCpy32(p_KeysMatchTableNewTmp, p_KeysMatchTableOldTmp, p_FmPcdCcNode->ccKeySizeAccExtraction);
+ i++;
+ }
+ }
+
+ p_AdTableNewTmp = PTR_MOVE(p_AdditionalInfo->p_AdTableNew, j*FM_PCD_CC_AD_ENTRY_SIZE);
+ p_AdTableOldTmp = PTR_MOVE(p_AdditionalInfo->p_AdTableOld, i*FM_PCD_CC_AD_ENTRY_SIZE);
+ IO2IOCpy32(p_AdTableNewTmp, p_AdTableOldTmp, FM_PCD_CC_AD_ENTRY_SIZE);
+
+
+ if(!LIST_IsEmpty(&p_FmPcdCcNode->ccTreesLst))
+ {
+ LIST_FOR_EACH(p_Pos, &p_FmPcdCcNode->ccTreesLst)
+ {
+ p_CcNodeInformation = CC_NODE_F_OBJECT(p_Pos);
+ ASSERT_COND(p_CcNodeInformation->h_CcNode);
+ /*update the manipulation which has to be updated from parameters of the port*/
+ /*it's has to be updated with restrictions defined in the function*/
+ err = FmPcdCcSetRequiredAction(p_FmPcdCcNode->h_FmPcd,
+ p_FmPcdCcNode->shadowAction | p_AdditionalInfo->nextEngineAndRequiredAction[keyIndex].requiredAction,
+ &p_AdditionalInfo->nextEngineAndRequiredAction[keyIndex],
+ PTR_MOVE(p_AdditionalInfo->p_AdTableNew, keyIndex*FM_PCD_CC_AD_ENTRY_SIZE),
+ 1,
+ p_CcNodeInformation->h_CcNode);
+ if (err)
+ RETURN_ERROR(MAJOR, err, (NO_MSG));
+
+ err = CcUpdateParam(p_FmPcdCcNode->h_FmPcd,
+ NULL,
+ &p_AdditionalInfo->nextEngineAndRequiredAction[keyIndex],
+ 1,
+ PTR_MOVE(p_AdditionalInfo->p_AdTableNew, keyIndex*FM_PCD_CC_AD_ENTRY_SIZE),
+ TRUE,
+ p_CcNodeInformation->index,
+ p_CcNodeInformation->h_CcNode,
+ TRUE);
+ if (err)
+ RETURN_ERROR(MAJOR, err, (NO_MSG));
+ }
+ }
+
+ if(p_FmPcdCcNode->lclMask)
+ memset(p_FmPcdCcNode->p_GlblMask, 0xff, CC_GLBL_MASK_SIZE * sizeof(uint8_t));
+
+
+ if(p_KeyParams->ccNextEngineParams.nextEngine == e_FM_PCD_CC)
+ p_AdditionalInfo->h_NodeForAdd = p_KeyParams->ccNextEngineParams.params.ccParams.h_CcNode;
+
+ if(!add)
+ {
+ if(p_FmPcdCcNode->nextEngineAndRequiredAction[keyIndex].nextEngineParams.nextEngine == e_FM_PCD_CC)
+ p_AdditionalInfo->h_NodeForRmv = p_FmPcdCcNode->nextEngineAndRequiredAction[keyIndex].nextEngineParams.params.ccParams.h_CcNode;
+#ifdef FM_PCD_CC_MANIP
+ if(p_FmPcdCcNode->nextEngineAndRequiredAction[keyIndex].nextEngineParams.h_Manip)
+ p_AdditionalInfo->h_ManipForRmv = p_FmPcdCcNode->nextEngineAndRequiredAction[keyIndex].nextEngineParams.h_Manip;
+#endif /* FM_PCD_CC_MANIP */
+ }
+
+ return E_OK;
+}
+
+static t_Error BuildNewNodeRemoveKey(t_FmPcdCcNode *p_FmPcdCcNode, uint8_t keyIndex, t_FmPcdModifyCcKeyAdditionalParams *p_AdditionalInfo)
+{
+ int i = 0, j = 0;
+ t_Handle p_AdTableNewTmp,p_KeysMatchTableNewTmp;
+ t_Handle p_KeysMatchTableOldTmp, p_AdTableOldTmp;
+ int size;
+ t_Error err = E_OK;
+
+ /*save new numOfKeys*/
+ p_AdditionalInfo->numOfKeys = (uint16_t)(p_FmPcdCcNode->numOfKeys - 1);
+
+ /*function which allocates in the memory new KeyTbl, AdTbl*/
+ err = BuildNewNodeCommonPart(p_FmPcdCcNode, &size, p_AdditionalInfo);
+ if(err)
+ RETURN_ERROR(MAJOR, err, NO_MSG);
+
+ /*update new Ad and new Key Table according to new requirement*/
+ for(i = 0, j = 0; j < p_FmPcdCcNode->numOfKeys; i++, j++)
+ {
+ if(j == keyIndex)
+ {
+ p_AdTableOldTmp = PTR_MOVE(p_AdditionalInfo->p_AdTableOld, j*FM_PCD_CC_AD_ENTRY_SIZE);
+ j++;
+ }
+ if(j == p_FmPcdCcNode->numOfKeys)
+ break;
+ p_AdTableNewTmp = PTR_MOVE(p_AdditionalInfo->p_AdTableNew, i*FM_PCD_CC_AD_ENTRY_SIZE);
+ p_AdTableOldTmp = PTR_MOVE(p_AdditionalInfo->p_AdTableOld, j*FM_PCD_CC_AD_ENTRY_SIZE);
+ IO2IOCpy32(p_AdTableNewTmp,p_AdTableOldTmp, FM_PCD_CC_AD_ENTRY_SIZE);
+ p_KeysMatchTableOldTmp = PTR_MOVE(p_AdditionalInfo->p_KeysMatchTableOld, j*size * sizeof(uint8_t));
+ p_KeysMatchTableNewTmp = PTR_MOVE(p_AdditionalInfo->p_KeysMatchTableNew, i*size * sizeof(uint8_t));
+ IO2IOCpy32(p_KeysMatchTableNewTmp,p_KeysMatchTableOldTmp, size * sizeof(uint8_t));
+ }
+
+ p_AdTableNewTmp = PTR_MOVE(p_AdditionalInfo->p_AdTableNew, i*FM_PCD_CC_AD_ENTRY_SIZE);
+ p_AdTableOldTmp = PTR_MOVE(p_AdditionalInfo->p_AdTableOld, j*FM_PCD_CC_AD_ENTRY_SIZE);
+ IO2IOCpy32(p_AdTableNewTmp, p_AdTableOldTmp, FM_PCD_CC_AD_ENTRY_SIZE);
+
+ if(p_FmPcdCcNode->nextEngineAndRequiredAction[keyIndex].nextEngineParams.nextEngine == e_FM_PCD_CC)
+ p_AdditionalInfo->h_NodeForRmv = p_FmPcdCcNode->nextEngineAndRequiredAction[keyIndex].nextEngineParams.params.ccParams.h_CcNode;
+#ifdef FM_PCD_CC_MANIP
+ if(p_FmPcdCcNode->nextEngineAndRequiredAction[keyIndex].nextEngineParams.h_Manip)
+ p_AdditionalInfo->h_ManipForRmv = p_FmPcdCcNode->nextEngineAndRequiredAction[keyIndex].nextEngineParams.h_Manip;
+#endif /* FM_PCD_CC_MANIP */
+
+ return E_OK;
+}
+
+static t_Error BuildNewNodeModifyKey(t_FmPcdCcNode *p_FmPcdCcNode, uint8_t keyIndex, uint8_t *p_Key, uint8_t *p_Mask,t_FmPcdModifyCcKeyAdditionalParams *p_AdditionalInfo)
+{
+ t_Error err = E_OK;
+ t_Handle p_AdTableNewTmp, p_KeysMatchTableNewTmp;
+ t_Handle p_KeysMatchTableOldTmp, p_AdTableOldTmp;
+ int size;
+ int i = 0, j = 0;
+ bool prvLclMask;
+
+ p_AdditionalInfo->numOfKeys = p_FmPcdCcNode->numOfKeys;
+
+ prvLclMask = p_FmPcdCcNode->lclMask;
+
+ /*check that new key is not require update of localMask*/
+ err = UpdateGblMask(p_FmPcdCcNode,
+ p_FmPcdCcNode->sizeOfExtraction,
+ p_Mask);
+ if(err)
+ RETURN_ERROR(MAJOR, err, NO_MSG);
+
+ /*function which build in the memory new KeyTbl, AdTbl*/
+ err = BuildNewNodeCommonPart(p_FmPcdCcNode, &size, p_AdditionalInfo);
+ if(err)
+ RETURN_ERROR(MAJOR, err, NO_MSG);
+
+ /*fill the New AdTable and New KeyTable*/
+ for(j = 0, i = 0; j < p_AdditionalInfo->numOfKeys; j++, i++)
+ {
+ p_AdTableNewTmp = PTR_MOVE(p_AdditionalInfo->p_AdTableNew, j*FM_PCD_CC_AD_ENTRY_SIZE);
+ p_AdTableOldTmp = PTR_MOVE(p_AdditionalInfo->p_AdTableOld, i*FM_PCD_CC_AD_ENTRY_SIZE);
+ IO2IOCpy32(p_AdTableNewTmp, p_AdTableOldTmp, FM_PCD_CC_AD_ENTRY_SIZE);
+ if(j == keyIndex)
+ {
+ p_KeysMatchTableNewTmp = PTR_MOVE(p_AdditionalInfo->p_KeysMatchTableNew, j*size * sizeof(uint8_t));
+ Mem2IOCpy32(p_KeysMatchTableNewTmp, p_Key, p_FmPcdCcNode->userSizeOfExtraction);
+ if(p_FmPcdCcNode->lclMask)
+ {
+ if(p_Mask)
+ Mem2IOCpy32(PTR_MOVE(p_KeysMatchTableNewTmp, p_FmPcdCcNode->ccKeySizeAccExtraction), p_Mask, p_FmPcdCcNode->userSizeOfExtraction);
+ else if (p_FmPcdCcNode->ccKeySizeAccExtraction > 4)
+ IOMemSet32(PTR_MOVE(p_KeysMatchTableNewTmp, p_FmPcdCcNode->ccKeySizeAccExtraction), 0xff, p_FmPcdCcNode->userSizeOfExtraction);
+ else
+ Mem2IOCpy32(PTR_MOVE(p_KeysMatchTableNewTmp, p_FmPcdCcNode->ccKeySizeAccExtraction),p_FmPcdCcNode->p_GlblMask, p_FmPcdCcNode->userSizeOfExtraction);
+ }
+ }
+ else
+ {
+ p_KeysMatchTableNewTmp = PTR_MOVE(p_AdditionalInfo->p_KeysMatchTableNew, j*size * sizeof(uint8_t));
+ p_KeysMatchTableOldTmp = PTR_MOVE(p_FmPcdCcNode->h_KeysMatchTable, i*size * sizeof(uint8_t));
+ if (p_FmPcdCcNode->lclMask)
+ {
+ if(prvLclMask)
+ IO2IOCpy32(PTR_MOVE(p_KeysMatchTableNewTmp, p_FmPcdCcNode->ccKeySizeAccExtraction),
+ PTR_MOVE(p_KeysMatchTableOldTmp, p_FmPcdCcNode->ccKeySizeAccExtraction),
+ p_FmPcdCcNode->userSizeOfExtraction);
+ else
+ {
+ p_KeysMatchTableOldTmp = PTR_MOVE(p_FmPcdCcNode->h_KeysMatchTable, i*p_FmPcdCcNode->ccKeySizeAccExtraction * sizeof(uint8_t));
+
+ if (p_FmPcdCcNode->ccKeySizeAccExtraction > 4)
+ IOMemSet32(PTR_MOVE(p_KeysMatchTableNewTmp, p_FmPcdCcNode->ccKeySizeAccExtraction), 0xff, p_FmPcdCcNode->userSizeOfExtraction);
+ else
+ IO2IOCpy32(PTR_MOVE(p_KeysMatchTableNewTmp, p_FmPcdCcNode->ccKeySizeAccExtraction), p_FmPcdCcNode->p_GlblMask, p_FmPcdCcNode->userSizeOfExtraction);
+ }
+ }
+ IO2IOCpy32((void*)p_KeysMatchTableNewTmp, p_KeysMatchTableOldTmp, p_FmPcdCcNode->ccKeySizeAccExtraction);
+ }
+ }
+
+ p_AdTableNewTmp = PTR_MOVE(p_AdditionalInfo->p_AdTableNew, j*FM_PCD_CC_AD_ENTRY_SIZE);
+ p_AdTableOldTmp = PTR_MOVE(p_FmPcdCcNode->h_AdTable, i*FM_PCD_CC_AD_ENTRY_SIZE);
+ IO2IOCpy32(p_AdTableNewTmp, p_AdTableOldTmp, FM_PCD_CC_AD_ENTRY_SIZE);
+
+ return E_OK;
+}
+
+static t_Error BuildNewNodeModifyNextEngine(t_Handle h_FmPcd ,t_Handle h_FmPcdCcNodeOrTree, uint16_t keyIndex,t_FmPcdCcNextEngineParams *p_CcNextEngineParams, t_List *h_OldLst, t_List *h_NewLst,t_FmPcdModifyCcKeyAdditionalParams *p_AdditionalInfo)
+{
+
+ t_Error err = E_OK;
+ uint32_t requiredAction = 0;
+ t_List *p_Pos;
+ t_CcNodeInformation *p_CcNodeInformation, ccNodeInfo;
+ t_Handle p_Ad;
+ t_FmPcdCcNode *p_FmPcdCcNode1 = NULL;
+ t_FmPcdCcTree *p_FmPcdCcTree = NULL;
+
+ ASSERT_COND(p_CcNextEngineParams);
+ /*check that new NIA is legal*/
+ err = ValidateNextEngineParams(h_FmPcd, p_CcNextEngineParams);
+ if(err)
+ RETURN_ERROR(MAJOR, err, NO_MSG);
+
+ /*update internal data structure for next engine per index (index - key)*/
+ memcpy(&p_AdditionalInfo->nextEngineAndRequiredAction[keyIndex].nextEngineParams,p_CcNextEngineParams, sizeof(t_FmPcdCcNextEngineParams));
+
+#ifdef FM_PCD_CC_MANIP
+ /*check that manip is legal and what requiredAction is necessary for this manip*/
+ if(p_CcNextEngineParams->h_Manip)
+ {
+ err = FmPcdManipCheckParamsForCcNextEgine(p_CcNextEngineParams,&requiredAction);
+ if(err)
+ RETURN_ERROR(MAJOR, err, (NO_MSG));
+
+ }
+#endif /* FM_PCD_CC_MANIP */
+
+ if(!p_AdditionalInfo->tree)
+ {
+ p_FmPcdCcNode1 = (t_FmPcdCcNode *)h_FmPcdCcNodeOrTree;
+ p_Ad = p_FmPcdCcNode1->h_AdTable;
+ if(p_FmPcdCcNode1->nextEngineAndRequiredAction[keyIndex].nextEngineParams.nextEngine == e_FM_PCD_CC)
+ p_AdditionalInfo->h_NodeForRmv = p_FmPcdCcNode1->nextEngineAndRequiredAction[keyIndex].nextEngineParams.params.ccParams.h_CcNode;
+#ifdef FM_PCD_CC_MANIP
+ if(p_FmPcdCcNode1->nextEngineAndRequiredAction[keyIndex].nextEngineParams.h_Manip)
+ p_AdditionalInfo->h_ManipForRmv = p_FmPcdCcNode1->nextEngineAndRequiredAction[keyIndex].nextEngineParams.h_Manip;
+#endif /* FM_PCD_CC_MANIP */
+ }
+ else
+ {
+ p_FmPcdCcTree = (t_FmPcdCcTree *)h_FmPcdCcNodeOrTree;
+ p_Ad = UINT_TO_PTR(p_FmPcdCcTree->ccTreeBaseAddr);
+ if(p_FmPcdCcTree->nextEngineAndRequiredAction[keyIndex].nextEngineParams.nextEngine == e_FM_PCD_CC)
+ p_AdditionalInfo->h_NodeForRmv = p_FmPcdCcTree->nextEngineAndRequiredAction[keyIndex].nextEngineParams.params.ccParams.h_CcNode;
+#ifdef FM_PCD_CC_MANIP
+ if(p_FmPcdCcTree->nextEngineAndRequiredAction[keyIndex].nextEngineParams.h_Manip)
+ p_AdditionalInfo->h_ManipForRmv = p_FmPcdCcTree->nextEngineAndRequiredAction[keyIndex].nextEngineParams.h_Manip;
+#endif /* FM_PCD_CC_MANIP */
+ }
+ ASSERT_COND(p_Ad);
+ memset(&ccNodeInfo, 0, sizeof(t_CcNodeInformation));
+ ccNodeInfo.h_CcNode = PTR_MOVE(p_Ad, keyIndex * FM_PCD_CC_AD_ENTRY_SIZE);
+ EnqueueNodeInfoToRelevantLst(h_OldLst, &ccNodeInfo);
+
+ memset(&ccNodeInfo, 0, sizeof(t_CcNodeInformation));
+ p_Ad = (t_Handle)FM_MURAM_AllocMem(FmPcdGetMuramHandle(h_FmPcd),
+ FM_PCD_CC_AD_ENTRY_SIZE,
+ FM_PCD_CC_AD_TABLE_ALIGN);
+
+ if(!p_Ad)
+ RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Memory allocation in MURAM FAILED"));
+
+ IOMemSet32((uint8_t *)p_Ad, 0, FM_PCD_CC_AD_ENTRY_SIZE);
+ if(p_CcNextEngineParams)
+ NextStepAd(p_Ad,p_CcNextEngineParams, h_FmPcd);
+ ccNodeInfo.h_CcNode = p_Ad;
+ EnqueueNodeInfoToRelevantLst(h_NewLst, &ccNodeInfo);
+
+ p_AdditionalInfo->nextEngineAndRequiredAction[keyIndex].requiredAction = requiredAction;
+
+ p_AdditionalInfo->nextEngineAndRequiredAction[keyIndex].requiredAction |= UPDATE_CC_WITH_TREE;
+
+ if(!p_AdditionalInfo->tree)
+ {
+ ASSERT_COND(p_FmPcdCcNode1);
+ if(!LIST_IsEmpty(&p_FmPcdCcNode1->ccTreesLst))
+ {
+ LIST_FOR_EACH(p_Pos, &p_FmPcdCcNode1->ccTreesLst)
+ {
+ p_CcNodeInformation = CC_NODE_F_OBJECT(p_Pos);
+ ASSERT_COND(p_CcNodeInformation->h_CcNode);
+ /*update the manipulation which has to be updated from parameters of the port*/
+ /*it's has to be updated with restrictions defined in the function*/
+ err = FmPcdCcSetRequiredAction(p_FmPcdCcNode1->h_FmPcd, p_FmPcdCcNode1->shadowAction | p_AdditionalInfo->nextEngineAndRequiredAction[keyIndex].requiredAction, &p_AdditionalInfo->nextEngineAndRequiredAction[keyIndex],
+ p_Ad, 1, p_CcNodeInformation->h_CcNode);
+ if(err)
+ RETURN_ERROR(MAJOR, err, (NO_MSG));
+ err = CcUpdateParam(p_FmPcdCcNode1->h_FmPcd, NULL, &p_AdditionalInfo->nextEngineAndRequiredAction[keyIndex],1, p_Ad, TRUE, p_CcNodeInformation->index, p_CcNodeInformation->h_CcNode, TRUE);
+ if(err)
+ RETURN_ERROR(MAJOR, err, (NO_MSG));
+ }
+ }
+ }
+ else
+ {
+ ASSERT_COND(p_FmPcdCcTree);
+ err = FmPcdCcSetRequiredAction(h_FmPcd, p_FmPcdCcTree->requiredAction | p_AdditionalInfo->nextEngineAndRequiredAction[keyIndex].requiredAction, &p_AdditionalInfo->nextEngineAndRequiredAction[keyIndex],
+ p_Ad, 1, (t_Handle)p_FmPcdCcTree);
+ if(err)
+ RETURN_ERROR(MAJOR, err, (NO_MSG));
+ err = CcUpdateParam(h_FmPcd, NULL, &p_AdditionalInfo->nextEngineAndRequiredAction[keyIndex],1, p_Ad, TRUE, 0, (t_Handle)p_FmPcdCcTree, TRUE);
+ if(err)
+ RETURN_ERROR(MAJOR, err, (NO_MSG));
+ }
+
+ if(p_CcNextEngineParams->nextEngine == e_FM_PCD_CC)
+ p_AdditionalInfo->h_NodeForAdd = p_CcNextEngineParams->params.ccParams.h_CcNode;
+ return E_OK;
+}
+
+static t_Handle BuildNewAd(t_FmPcdModifyCcKeyAdditionalParams *p_FmPcdModifyCcKeyAdditionalParams,
+ t_FmPcdCcNode *p_FmPcdCcNode,
+ t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams)
+{
+
+ t_Handle p_Ad;
+ t_FmPcdCcNode *p_FmPcdCcNodeTmp;
+
+ p_Ad = (t_Handle)FM_MURAM_AllocMem(((t_FmPcd *)(p_FmPcdCcNode->h_FmPcd))->h_FmMuram,
+ FM_PCD_CC_AD_ENTRY_SIZE,
+ FM_PCD_CC_AD_TABLE_ALIGN);
+ if(!p_Ad)
+ {
+ REPORT_ERROR(MAJOR, E_NO_MEMORY, ("MURAM for AD"));
+ return NULL;
+ }
+ IOMemSet32(p_Ad, 0, FM_PCD_CC_AD_ENTRY_SIZE);
+
+ p_FmPcdCcNodeTmp = (t_FmPcdCcNode*)XX_Malloc(sizeof(t_FmPcdCcNode));
+ if(!p_FmPcdCcNodeTmp)
+ {
+ REPORT_ERROR(MAJOR, E_NO_MEMORY, ("p_FmPcdCcNodeTmp"));
+ return NULL;
+ }
+ memset(p_FmPcdCcNodeTmp, 0, sizeof(t_FmPcdCcNode));
+
+ p_FmPcdCcNodeTmp->numOfKeys = p_FmPcdModifyCcKeyAdditionalParams->numOfKeys;
+ p_FmPcdCcNodeTmp->h_KeysMatchTable = p_FmPcdModifyCcKeyAdditionalParams->p_KeysMatchTableNew;
+ p_FmPcdCcNodeTmp->h_AdTable = p_FmPcdModifyCcKeyAdditionalParams->p_AdTableNew;
+
+ p_FmPcdCcNodeTmp->lclMask = p_FmPcdCcNode->lclMask;
+ p_FmPcdCcNodeTmp->parseCode = p_FmPcdCcNode->parseCode;
+ p_FmPcdCcNodeTmp->offset = p_FmPcdCcNode->offset;
+ p_FmPcdCcNodeTmp->prsArrayOffset = p_FmPcdCcNode->prsArrayOffset;
+ p_FmPcdCcNodeTmp->ctrlFlow = p_FmPcdCcNode->ctrlFlow;
+ p_FmPcdCcNodeTmp->ccKeySizeAccExtraction = p_FmPcdCcNode->ccKeySizeAccExtraction;
+ p_FmPcdCcNodeTmp->sizeOfExtraction = p_FmPcdCcNode->sizeOfExtraction;
+ p_FmPcdCcNodeTmp->glblMaskSize = p_FmPcdCcNode->glblMaskSize;
+ p_FmPcdCcNodeTmp->p_GlblMask = p_FmPcdCcNode->p_GlblMask;
+
+ if (p_FmPcdCcNextEngineParams->nextEngine == e_FM_PCD_CC)
+ FillAdOfTypeContLookup(p_Ad,
+ p_FmPcdCcNode->h_FmPcd,
+ p_FmPcdCcNodeTmp,
+#ifdef FM_PCD_CC_MANIP
+ p_FmPcdCcNextEngineParams->h_Manip
+#else
+ NULL
+#endif /* FM_PCD_CC_MANIP */
+ );
+
+ XX_Free(p_FmPcdCcNodeTmp);
+
+ return p_Ad;
+}
+
+static void UpdateAdPtrOfNodesWhichPointsOnCrntMdfNode(t_FmPcdCcNode *p_CrntMdfNode ,t_FmPcdModifyCcKeyAdditionalParams *p_FmPcdModifyCcKeyAdditionalParams, t_List *h_OldLst, t_List *h_NewLst)
+{
+ t_CcNodeInformation *p_CcNodeInformation;
+ t_FmPcdCcNode *p_NodePtrOnCurrentMdfNode = NULL;
+ t_List *p_Pos;
+ int i = 0;
+ t_Handle p_AdTablePtOnCrntCurrentMdfNode, p_AdTableNewModified;
+ t_CcNodeInformation ccNodeInfo;
+
+ LIST_FOR_EACH(p_Pos, &p_CrntMdfNode->ccPrevNodesLst)
+ {
+ p_CcNodeInformation = CC_NODE_F_OBJECT(p_Pos);
+ p_NodePtrOnCurrentMdfNode = (t_FmPcdCcNode *)p_CcNodeInformation->h_CcNode;
+ ASSERT_COND(p_NodePtrOnCurrentMdfNode);
+ /*search in the prev node which exact index points on this current modified node for getting AD */
+ for(i = 0; i < p_NodePtrOnCurrentMdfNode->numOfKeys + 1; i++)
+ {
+ if(p_NodePtrOnCurrentMdfNode->nextEngineAndRequiredAction[i].nextEngineParams.nextEngine == e_FM_PCD_CC)
+ {
+ if(p_NodePtrOnCurrentMdfNode->nextEngineAndRequiredAction[i].nextEngineParams.params.ccParams.h_CcNode == (t_Handle)p_CrntMdfNode)
+ {
+ p_AdTablePtOnCrntCurrentMdfNode = PTR_MOVE(p_NodePtrOnCurrentMdfNode->h_AdTable, i*FM_PCD_CC_AD_ENTRY_SIZE);
+ memset(&ccNodeInfo, 0, sizeof(t_CcNodeInformation));
+ ccNodeInfo.h_CcNode = p_AdTablePtOnCrntCurrentMdfNode;
+ EnqueueNodeInfoToRelevantLst(h_OldLst, &ccNodeInfo);
+
+ p_AdTableNewModified = BuildNewAd(p_FmPcdModifyCcKeyAdditionalParams, p_CrntMdfNode, &p_NodePtrOnCurrentMdfNode->nextEngineAndRequiredAction[i].nextEngineParams);
+ memset(&ccNodeInfo, 0, sizeof(t_CcNodeInformation));
+ ccNodeInfo.h_CcNode = p_AdTableNewModified;
+ EnqueueNodeInfoToRelevantLst(h_NewLst, &ccNodeInfo);
+ }
+ }
+ }
+ ASSERT_COND(i != p_NodePtrOnCurrentMdfNode->numOfKeys);
+ }
+}
+
+static void UpdateAdPtrOfTreesWhichPointsOnCrntMdfNode(t_FmPcdCcNode *p_CrntMdfNode ,t_FmPcdModifyCcKeyAdditionalParams *p_FmPcdModifyCcKeyAdditionalParams, t_List *h_OldLst, t_List *h_NewLst)
+{
+ t_CcNodeInformation *p_CcNodeInformation;
+ t_FmPcdCcTree *p_TreePtrOnCurrentMdfNode = NULL;
+ t_List *p_Pos;
+ int i = 0;
+ t_Handle p_AdTableTmp, p_AdTableTmp1;
+ t_CcNodeInformation ccNodeInfo;
+
+ LIST_FOR_EACH(p_Pos, &p_CrntMdfNode->ccTreeIdLst)
+ {
+ p_CcNodeInformation = CC_NODE_F_OBJECT(p_Pos);
+ p_TreePtrOnCurrentMdfNode = (t_FmPcdCcTree *)p_CcNodeInformation->h_CcNode;
+
+ ASSERT_COND(p_TreePtrOnCurrentMdfNode);
+ /*search in the trees which exact index points on this current modified node for getting AD
+ */
+ for(i = 0; i < p_TreePtrOnCurrentMdfNode->numOfEntries; i++)
+ {
+ if(p_TreePtrOnCurrentMdfNode->nextEngineAndRequiredAction[i].nextEngineParams.nextEngine == e_FM_PCD_CC)
+ {
+ if(p_TreePtrOnCurrentMdfNode->nextEngineAndRequiredAction[i].nextEngineParams.params.ccParams.h_CcNode == (t_Handle)p_CrntMdfNode)
+ {
+ p_AdTableTmp = UINT_TO_PTR(p_TreePtrOnCurrentMdfNode->ccTreeBaseAddr + i*FM_PCD_CC_AD_ENTRY_SIZE);
+ memset(&ccNodeInfo, 0, sizeof(t_CcNodeInformation));
+ ccNodeInfo.h_CcNode = p_AdTableTmp;
+ EnqueueNodeInfoToRelevantLst(h_OldLst, &ccNodeInfo);
+
+ p_AdTableTmp1 = BuildNewAd(p_FmPcdModifyCcKeyAdditionalParams, p_CrntMdfNode, &p_TreePtrOnCurrentMdfNode->nextEngineAndRequiredAction[i].nextEngineParams);
+ memset(&ccNodeInfo, 0, sizeof(t_CcNodeInformation));
+ ccNodeInfo.h_CcNode = p_AdTableTmp1;
+ EnqueueNodeInfoToRelevantLst(h_NewLst, &ccNodeInfo);
+ }
+ }
+ }
+ ASSERT_COND(i == p_TreePtrOnCurrentMdfNode->numOfEntries);
+ }
+}
+
+static t_Error ModifyKeyCommonPart1(t_Handle h_FmPcdCcNodeOrTree, uint16_t keyIndex, t_Handle *h_Params, e_ModifyState modifyState, bool check, bool tree)
+{
+ t_FmPcdModifyCcKeyAdditionalParams *p_FmPcdModifyCcKeyAdditionalParams;
+ int i = 0, j = 0;
+ bool wasUpdate = FALSE;
+ t_FmPcdCcNode *p_FmPcdCcNode = NULL;
+ t_FmPcdCcTree *p_FmPcdCcTree;
+ uint16_t numOfKeys;
+ t_FmPcdCcNextEngineAndRequiredActionParams *p_nextEngineAndRequiredAction = NULL;
+
+ SANITY_CHECK_RETURN_ERROR(h_FmPcdCcNodeOrTree,E_INVALID_HANDLE);
+
+ p_nextEngineAndRequiredAction = XX_Malloc(FM_PCD_MAX_NUM_OF_KEYS * sizeof(*p_nextEngineAndRequiredAction));
+ if(!p_nextEngineAndRequiredAction)
+ RETURN_ERROR(MAJOR, E_NO_MEMORY, ("failed to allocate memory for p_nextEngineAndRequiredAction"));
+
+ memset(p_nextEngineAndRequiredAction, 0, FM_PCD_MAX_NUM_OF_KEYS * sizeof(*p_nextEngineAndRequiredAction));
+
+ if(!tree)
+ {
+ p_FmPcdCcNode = (t_FmPcdCcNode *)h_FmPcdCcNodeOrTree;
+ numOfKeys = p_FmPcdCcNode->numOfKeys;
+
+ /*node has to be pointed by another node or tree*/
+ if (!LIST_NumOfObjs(&p_FmPcdCcNode->ccPrevNodesLst) &&
+ !LIST_NumOfObjs(&p_FmPcdCcNode->ccTreeIdLst))
+ {
+ XX_Free(p_nextEngineAndRequiredAction);
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("node has to be pointed by node or tree"));
+ }
+
+ if(!LIST_NumOfObjs(&p_FmPcdCcNode->ccTreesLst) ||
+ (LIST_NumOfObjs(&p_FmPcdCcNode->ccTreesLst) != 1))
+ {
+ XX_Free(p_nextEngineAndRequiredAction);
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("node has to be belonging to some tree and only to one tree"));
+ }
+
+ memcpy(p_nextEngineAndRequiredAction,
+ p_FmPcdCcNode->nextEngineAndRequiredAction,
+ FM_PCD_MAX_NUM_OF_KEYS * sizeof(t_FmPcdCcNextEngineAndRequiredActionParams));
+
+ if(check)
+ {
+ if((p_FmPcdCcNode->parseCode == CC_PC_FF_IPV4TTL) ||
+ (p_FmPcdCcNode->parseCode == CC_PC_FF_IPV6HOP_LIMIT) ||
+ (p_FmPcdCcNode->parseCode == CC_PC_GENERIC_IC_HASH_INDEXED))
+ {
+ XX_Free(p_nextEngineAndRequiredAction);
+ 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"));
+ }
+ }
+ }
+ else
+ {
+ p_FmPcdCcTree = (t_FmPcdCcTree *)h_FmPcdCcNodeOrTree;
+ numOfKeys = p_FmPcdCcTree->numOfEntries;
+ memcpy(p_nextEngineAndRequiredAction,
+ p_FmPcdCcTree->nextEngineAndRequiredAction,
+ FM_PCD_MAX_NUM_OF_KEYS * sizeof(t_FmPcdCcNextEngineAndRequiredActionParams));
+ }
+
+ p_FmPcdModifyCcKeyAdditionalParams =
+ (t_FmPcdModifyCcKeyAdditionalParams *)XX_Malloc(sizeof(t_FmPcdModifyCcKeyAdditionalParams));
+ if(!p_FmPcdModifyCcKeyAdditionalParams)
+ {
+ XX_Free(p_nextEngineAndRequiredAction);
+ RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Allocation of internal data structure FAILED"));
+ }
+ memset(p_FmPcdModifyCcKeyAdditionalParams, 0, sizeof(t_FmPcdModifyCcKeyAdditionalParams));
+
+ p_FmPcdModifyCcKeyAdditionalParams->h_CurrentNode = h_FmPcdCcNodeOrTree;
+ p_FmPcdModifyCcKeyAdditionalParams->keyIndex = keyIndex;
+
+ while(i < numOfKeys)
+ {
+ if((j == keyIndex) && !wasUpdate)
+ {
+ if(modifyState == e_MODIFY_STATE_ADD)
+ j++;
+ else if(modifyState == e_MODIFY_STATE_REMOVE)
+ i++;
+ wasUpdate = TRUE;
+ }
+ else
+ {
+ memcpy(&p_FmPcdModifyCcKeyAdditionalParams->nextEngineAndRequiredAction[j], &p_nextEngineAndRequiredAction[i], sizeof(t_FmPcdCcNextEngineAndRequiredActionParams));
+ i++;
+ j++;
+ }
+ }
+
+ if (keyIndex == numOfKeys)
+ {
+ if (modifyState == e_MODIFY_STATE_ADD)
+ j++;
+ else if(modifyState == e_MODIFY_STATE_REMOVE)
+ i++;
+ }
+
+ memcpy(&p_FmPcdModifyCcKeyAdditionalParams->nextEngineAndRequiredAction[j], &p_nextEngineAndRequiredAction[numOfKeys], sizeof(t_FmPcdCcNextEngineAndRequiredActionParams));
+
+ XX_Free(p_nextEngineAndRequiredAction);
+ *h_Params = p_FmPcdModifyCcKeyAdditionalParams;
+
+ return E_OK;
+}
+
+static t_Error UpdatePtrWhichPointOnCrntMdfNode(t_FmPcdCcNode *p_FmPcdCcNode, t_FmPcdModifyCcKeyAdditionalParams *p_FmPcdModifyCcKeyAdditionalParams ,t_List *h_OldLst, t_List *h_NewLst)
+{
+ if(!LIST_IsEmpty(&p_FmPcdCcNode->ccPrevNodesLst))
+ UpdateAdPtrOfNodesWhichPointsOnCrntMdfNode(p_FmPcdCcNode, p_FmPcdModifyCcKeyAdditionalParams, h_OldLst, h_NewLst);
+
+ if(!LIST_IsEmpty(&p_FmPcdCcNode->ccTreeIdLst))
+ UpdateAdPtrOfTreesWhichPointsOnCrntMdfNode(p_FmPcdCcNode, p_FmPcdModifyCcKeyAdditionalParams, h_OldLst, h_NewLst);
+
+ return E_OK;
+}
+
+static void FmPcdCcUpdateTreeOwner(t_FmPcdCcTree *p_FmPcdCcTree, bool add)
+{
+ ASSERT_COND(p_FmPcdCcTree);
+
+ if(add)
+ p_FmPcdCcTree->owners++;
+ else
+ {
+ ASSERT_COND(p_FmPcdCcTree->owners);
+ p_FmPcdCcTree->owners--;
+ }
+}
+
+#ifdef FM_PCD_CC_MANIP
+static t_Error CheckAndSetManipParamsWithCcNodeParams(t_FmPcdCcNode *p_FmPcdCcNode)
+{
+ t_Error err = E_OK;
+ int i = 0;
+
+ for(i = 0; i < p_FmPcdCcNode->numOfKeys; i++)
+ {
+ if(p_FmPcdCcNode->nextEngineAndRequiredAction[i].nextEngineParams.h_Manip)
+ {
+ err = FmPcdManipCheckParamsWithCcNodeParams(p_FmPcdCcNode->nextEngineAndRequiredAction[i].nextEngineParams.h_Manip, (t_Handle)p_FmPcdCcNode);
+ if(err)
+ return err;
+ }
+ }
+
+ return err;
+}
+#endif /* FM_PCD_CC_MANIP */
+
+static t_Error CcUpdateParams(t_Handle h_FmPcd,
+ t_Handle h_FmPort,
+ t_Handle h_FmTree,
+ bool validate)
+{
+ t_FmPcdCcTree *p_CcTree = (t_FmPcdCcTree *) h_FmTree;
+
+ return CcUpdateParam(h_FmPcd,
+ h_FmPort,
+ p_CcTree->nextEngineAndRequiredAction,
+ p_CcTree->numOfEntries,
+ UINT_TO_PTR(p_CcTree->ccTreeBaseAddr),
+ validate,
+ 0,
+ h_FmTree,
+ FALSE);
+}
+
+static t_Error CheckParams(t_Handle h_FmPcd,
+ t_FmPcdCcNodeParams *p_CcNodeParam,
+ t_FmPcdCcNode *p_FmPcdCcNode,
+ bool *isKeyTblAlloc)
+{
+ int tmp = 0;
+ t_FmPcdCcKeyParams *p_KeyParams;
+ t_Error err;
+ uint32_t requiredAction = 0;
+
+ err = ValidateNextEngineParams(h_FmPcd, &p_CcNodeParam->keysParams.ccNextEngineParamsForMiss);
+ if(err)
+ RETURN_ERROR(MAJOR, err, ("For this node MissNextEngineParams are not valid"));
+
+#ifdef FM_PCD_CC_MANIP
+ if(p_CcNodeParam->keysParams.ccNextEngineParamsForMiss.h_Manip)
+ {
+ err = FmPcdManipCheckParamsForCcNextEgine(&p_CcNodeParam->keysParams.ccNextEngineParamsForMiss, &requiredAction);
+ if(err)
+ RETURN_ERROR(MAJOR, err, (NO_MSG));
+ }
+#endif /* FM_PCD_CC_MANIP */
+
+ memcpy(&p_FmPcdCcNode->nextEngineAndRequiredAction[p_FmPcdCcNode->numOfKeys].nextEngineParams,&p_CcNodeParam->keysParams.ccNextEngineParamsForMiss, sizeof(t_FmPcdCcNextEngineParams));
+ p_FmPcdCcNode->nextEngineAndRequiredAction[p_FmPcdCcNode->numOfKeys].requiredAction = requiredAction;
+
+ for(tmp = 0 ; tmp < p_FmPcdCcNode->numOfKeys; tmp++)
+ {
+ p_KeyParams = &p_CcNodeParam->keysParams.keyParams[tmp];
+
+ if(!p_KeyParams->p_Key)
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("p_Key is not initialized"));
+
+
+ err = ValidateNextEngineParams(h_FmPcd, &p_KeyParams->ccNextEngineParams);
+ if(err)
+ RETURN_ERROR(MAJOR, err, (NO_MSG));
+
+ err = UpdateGblMask(p_FmPcdCcNode,
+ p_CcNodeParam->keysParams.keySize,
+ p_KeyParams->p_Mask);
+
+#ifdef FM_PCD_CC_MANIP
+ if(p_KeyParams->ccNextEngineParams.h_Manip)
+ {
+ err = FmPcdManipCheckParamsForCcNextEgine(&p_KeyParams->ccNextEngineParams, &requiredAction);
+ if(err)
+ RETURN_ERROR(MAJOR, err, (NO_MSG));
+ }
+#endif /* FM_PCD_CC_MANIP */
+
+ memcpy(&p_FmPcdCcNode->nextEngineAndRequiredAction[tmp],&p_KeyParams->ccNextEngineParams, sizeof(t_FmPcdCcNextEngineParams));
+ p_FmPcdCcNode->nextEngineAndRequiredAction[tmp].requiredAction = requiredAction;
+ }
+
+ *isKeyTblAlloc = TRUE;
+ return E_OK;
+}
+
+static t_Error Ipv4TtlOrIpv6HopLimiCheckParams( t_Handle h_FmPcd,
+ t_FmPcdCcNodeParams *p_CcNodeParam, t_FmPcdCcNode *p_FmPcdCcNode,
+ bool *isKeyTblAlloc)
+{
+ int tmp = 0;
+ t_FmPcdCcKeyParams *p_KeyParams;
+ t_Error err;
+ uint8_t key = 0x01;
+ uint32_t requiredAction = 0;
+
+ if(p_FmPcdCcNode->numOfKeys != 1 )
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("for IPV4TTL and IPV6_HOP_LIMIT has to be only 1 key - TTL = 1, otherwise it's Miss"));
+
+ err = ValidateNextEngineParams(h_FmPcd, &p_CcNodeParam->keysParams.ccNextEngineParamsForMiss);
+ if(err)
+ RETURN_ERROR(MAJOR, err, ("For this node MissNextEngineParams are not valid"));
+
+#ifdef FM_PCD_CC_MANIP
+ if(p_CcNodeParam->keysParams.ccNextEngineParamsForMiss.h_Manip)
+ {
+ err = FmPcdManipCheckParamsForCcNextEgine(&p_CcNodeParam->keysParams.ccNextEngineParamsForMiss, &requiredAction);
+ if(err)
+ RETURN_ERROR(MAJOR, err, (NO_MSG));
+ }
+#endif /* FM_PCD_CC_MANIP */
+
+ memcpy(&p_FmPcdCcNode->nextEngineAndRequiredAction[p_FmPcdCcNode->numOfKeys].nextEngineParams, &p_CcNodeParam->keysParams.ccNextEngineParamsForMiss, sizeof(t_FmPcdCcNextEngineParams));
+ p_FmPcdCcNode->nextEngineAndRequiredAction[p_FmPcdCcNode->numOfKeys].requiredAction = requiredAction;
+
+ for(tmp = 0 ; tmp < p_FmPcdCcNode->numOfKeys; tmp++)
+ {
+ p_KeyParams = &p_CcNodeParam->keysParams.keyParams[tmp];
+ if(p_KeyParams->p_Mask)
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("If node of the type IPV4_TTL or IPV6_HOP_LIMIT p_Mask can not be initialized"));
+ if(memcmp(p_KeyParams->p_Key, &key, 1) != 0)
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("If node of the type IPV4_TTL or IPV6_HOP_LIMIT p_Key has to be 1"));
+ err = ValidateNextEngineParams(h_FmPcd, &p_KeyParams->ccNextEngineParams);
+ if(err)
+ RETURN_ERROR(MAJOR, err, (NO_MSG));
+
+#ifdef FM_PCD_CC_MANIP
+ if(p_KeyParams->ccNextEngineParams.h_Manip)
+ {
+ err = FmPcdManipCheckParamsForCcNextEgine(&p_KeyParams->ccNextEngineParams, &requiredAction);
+ if(err)
+ RETURN_ERROR(MAJOR, err, (NO_MSG));
+ }
+#endif /* FM_PCD_CC_MANIP */
+
+ memcpy(&p_FmPcdCcNode->nextEngineAndRequiredAction[tmp].nextEngineParams, &p_KeyParams->ccNextEngineParams, sizeof(t_FmPcdCcNextEngineParams));
+ p_FmPcdCcNode->nextEngineAndRequiredAction[tmp].requiredAction = requiredAction;
+ }
+
+ *isKeyTblAlloc = FALSE;
+ return E_OK;
+}
+
+static t_Error IcHashIndexedCheckParams(t_Handle h_FmPcd,
+ t_FmPcdCcNodeParams *p_CcNodeParam,
+ t_FmPcdCcNode *p_FmPcdCcNode,
+ /*uint16_t *ccInfo,*/
+ /*t_List *ccNextDifferentNodesLst,*/
+ bool *isKeyTblAlloc)
+{
+ int tmp = 0, countOnes = 0;
+ t_FmPcdCcKeyParams *p_KeyParams;
+ t_Error err;
+ uint16_t glblMask = p_CcNodeParam->extractCcParams.extractNonHdr.icIndxMask;
+ uint16_t countMask = (uint16_t)(glblMask >> 4);
+#ifdef FM_PCD_CC_MANIP
+ uint32_t requiredAction;
+#endif /* FM_PCD_CC_MANIP */
+
+ if (glblMask & 0x000f)
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("icIndxMask has to be with last nibble 0"));
+
+ while (countMask)
+ {
+ countOnes++;
+ countMask=(uint16_t)(countMask>>1);
+ }
+
+ if (!POWER_OF_2(p_FmPcdCcNode->numOfKeys))
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("For Node of the type INDEXED numOfKeys has to be powerOfTwo"));
+ if (p_FmPcdCcNode->numOfKeys != ((uint32_t)1<<countOnes ))
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("For Node of the type IC_HASH_INDEXED numOfKeys has to be powerOfTwo"));
+
+ err = ValidateNextEngineParams(h_FmPcd, &p_CcNodeParam->keysParams.ccNextEngineParamsForMiss);
+ if(GET_ERROR_TYPE(err)!= E_NOT_SUPPORTED)
+ RETURN_ERROR(MAJOR, err, ("MissNextEngineParams for the node of the type IC_INDEX_HASH has to be UnInitialized"));
+
+ for(tmp = 0 ; tmp < p_FmPcdCcNode->numOfKeys; tmp++)
+ {
+ p_KeyParams = &p_CcNodeParam->keysParams.keyParams[tmp];
+ if(p_KeyParams->p_Mask || p_KeyParams->p_Key)
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("For Node of the type IC_HASH_INDEXED p_Key or p_Mask has to be NULL"));
+
+ if((glblMask & (tmp * 16)) == (tmp * 16))
+ {
+ err = ValidateNextEngineParams(h_FmPcd, &p_KeyParams->ccNextEngineParams);
+ if(err)
+ RETURN_ERROR(MAJOR, err, ("This index has to be initialized for the node of the type IC_INDEX_HASH according to settings of GlobalMask "));
+
+#ifdef FM_PCD_CC_MANIP
+ if(p_KeyParams->ccNextEngineParams.h_Manip)
+ {
+ err = FmPcdManipCheckParamsForCcNextEgine(&p_KeyParams->ccNextEngineParams, &requiredAction);
+ if(err)
+ RETURN_ERROR(MAJOR, err, (NO_MSG));
+ }
+ p_FmPcdCcNode->nextEngineAndRequiredAction[tmp].requiredAction = requiredAction;
+#endif /* FM_PCD_CC_MANIP */
+
+ memcpy(&p_FmPcdCcNode->nextEngineAndRequiredAction[tmp].nextEngineParams,&p_KeyParams->ccNextEngineParams, sizeof(t_FmPcdCcNextEngineParams));
+ }
+ else
+ {
+ err = ValidateNextEngineParams(h_FmPcd, &p_KeyParams->ccNextEngineParams);
+ if(GET_ERROR_TYPE(err)!= E_NOT_SUPPORTED)
+ RETURN_ERROR(MAJOR, err, ("This index has to be UnInitialized for the node of the type IC_INDEX_HASH according to settings of GlobalMask"));
+ }
+ }
+ *isKeyTblAlloc = FALSE;
+ memcpy(PTR_MOVE(p_FmPcdCcNode->p_GlblMask, 2), &glblMask, 2);
+
+ return E_OK;
+}
+
+t_Error FmPcdCcModifyNextEngineParamTree(t_Handle h_FmPcd, t_Handle h_FmPcdCcTree, uint8_t grpId, uint8_t index, t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams, t_List *h_OldLst, t_List *h_NewLst, t_Handle *h_AdditionalParams)
+{
+ t_FmPcdCcTree *p_FmPcdCcTree = (t_FmPcdCcTree *)h_FmPcdCcTree;
+ t_Error err = E_OK;
+ uint16_t keyIndex;
+ t_FmPcdModifyCcKeyAdditionalParams *p_ModifyKeyParams;
+
+ SANITY_CHECK_RETURN_ERROR((grpId <= 7),E_INVALID_VALUE);
+ SANITY_CHECK_RETURN_ERROR(h_FmPcdCcTree,E_INVALID_VALUE);
+
+ if(grpId >= p_FmPcdCcTree->numOfGrps)
+ RETURN_ERROR(MAJOR, E_INVALID_HANDLE, ("grpId you asked > numOfGroup of relevant tree"));
+
+ if(index >= p_FmPcdCcTree->fmPcdGroupParam[grpId].numOfEntriesInGroup)
+ RETURN_ERROR(MAJOR, E_INVALID_HANDLE, ("index > numOfEntriesInGroup"));
+
+ keyIndex = (uint16_t)(p_FmPcdCcTree->fmPcdGroupParam[grpId].baseGroupEntry + index);
+
+ err = ModifyKeyCommonPart1(h_FmPcdCcTree, keyIndex, h_AdditionalParams, e_MODIFY_STATE_CHANGE, TRUE, TRUE);
+ if(err)
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
+
+ p_ModifyKeyParams = (t_FmPcdModifyCcKeyAdditionalParams *)*h_AdditionalParams;
+ p_ModifyKeyParams->tree = TRUE;
+
+ err = BuildNewNodeModifyNextEngine (h_FmPcd, h_FmPcdCcTree, keyIndex,p_FmPcdCcNextEngineParams, h_OldLst, h_NewLst, p_ModifyKeyParams);
+ if(err)
+ {
+ XX_Free(p_ModifyKeyParams);
+ RETURN_ERROR(MAJOR, err, NO_MSG);
+ }
+ return E_OK;
+
+}
+
+t_Error FmPcdCcRemoveKey(t_Handle h_FmPcd, t_Handle h_FmPcdCcNode, uint8_t keyIndex, t_List *h_OldLst, t_List *h_NewLst, t_Handle *h_AdditionalParams)
+{
+
+ t_FmPcdCcNode *p_FmPcdCcNode = (t_FmPcdCcNode *) h_FmPcdCcNode;
+ t_Error err = E_OK;
+ t_FmPcdModifyCcKeyAdditionalParams *p_ModifyKeyParams;
+
+ if(keyIndex >= p_FmPcdCcNode->numOfKeys)
+ RETURN_ERROR(MAJOR, E_INVALID_HANDLE, ("impossible to remove key when numOfKeys <= keyIndex"));
+
+ if(!p_FmPcdCcNode->numOfKeys)
+ RETURN_ERROR(MAJOR, E_INVALID_HANDLE, ("keyIndex you asked > numOfKeys of relevant node that was initialized"));
+
+ if(p_FmPcdCcNode->h_FmPcd != h_FmPcd)
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("handler to FmPcd is diferent from one which was assigned to the node in the Init time"));
+
+ err = ModifyKeyCommonPart1(p_FmPcdCcNode, keyIndex, h_AdditionalParams, e_MODIFY_STATE_REMOVE, TRUE, FALSE);
+ if(err)
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
+
+ p_ModifyKeyParams = (t_FmPcdModifyCcKeyAdditionalParams *)*h_AdditionalParams;
+ err = BuildNewNodeRemoveKey (p_FmPcdCcNode, keyIndex, p_ModifyKeyParams);
+ if(err)
+ {
+ XX_Free(p_ModifyKeyParams);
+ RETURN_ERROR(MAJOR, err, NO_MSG);
+ }
+
+ err = UpdatePtrWhichPointOnCrntMdfNode(p_FmPcdCcNode, p_ModifyKeyParams, h_OldLst, h_NewLst);
+ if(err)
+ {
+ ReleaseNewNodeCommonPart(p_ModifyKeyParams);
+ XX_Free(p_ModifyKeyParams);
+ RETURN_ERROR(MAJOR, err, NO_MSG);
+ }
+
+ return E_OK;
+
+}
+
+t_Error FmPcdCcModifyKey(t_Handle h_FmPcd, t_Handle h_FmPcdCcNode, uint8_t keyIndex, uint8_t keySize, uint8_t *p_Key, uint8_t *p_Mask, t_List *h_OldLst, t_List *h_NewLst,t_Handle *h_AdditionalParams)
+{
+ t_FmPcdCcNode *p_FmPcdCcNode = (t_FmPcdCcNode *)h_FmPcdCcNode;
+ t_Error err = E_OK;
+ t_FmPcdModifyCcKeyAdditionalParams *p_ModifyKeyParams;
+
+ if(keyIndex >= p_FmPcdCcNode->numOfKeys)
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("keyIndex > previousely cleared last index + 1"));
+
+ if((p_FmPcdCcNode->numOfKeys + 1) > FM_PCD_MAX_NUM_OF_CC_NODES)
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("numOfKeys with new key can not be larger than 255"));
+
+ if(keySize != p_FmPcdCcNode->userSizeOfExtraction)
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("size for ModifyKey has to be the same as defined in SetNode"));
+
+ if(p_FmPcdCcNode->h_FmPcd != h_FmPcd)
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("handler to FmPcd is diferent from one which was assigned to the node in the Init time"));
+
+ err = ModifyKeyCommonPart1(p_FmPcdCcNode, keyIndex, h_AdditionalParams, e_MODIFY_STATE_CHANGE, TRUE, FALSE);
+ if(err)
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
+
+ p_ModifyKeyParams = (t_FmPcdModifyCcKeyAdditionalParams *)*h_AdditionalParams;
+
+ err = BuildNewNodeModifyKey (p_FmPcdCcNode, keyIndex, p_Key, p_Mask, p_ModifyKeyParams);
+ if(err)
+ {
+ XX_Free(p_ModifyKeyParams);
+ RETURN_ERROR(MAJOR, err, NO_MSG);
+ }
+
+ err = UpdatePtrWhichPointOnCrntMdfNode(p_FmPcdCcNode, p_ModifyKeyParams, h_OldLst, h_NewLst);
+ if(err)
+ {
+ ReleaseNewNodeCommonPart(p_ModifyKeyParams);
+ XX_Free(p_ModifyKeyParams);
+ RETURN_ERROR(MAJOR, err, NO_MSG);
+ }
+ return E_OK;
+}
+
+
+t_Error FmPcdCcModiyNextEngineParamNode(t_Handle h_FmPcd,t_Handle h_FmPcdCcNode, uint8_t keyIndex,t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams,t_List *h_OldPointer, t_List *h_NewPointer,t_Handle *h_AdditionalParams)
+{
+ t_FmPcdCcNode *p_FmPcdCcNode = (t_FmPcdCcNode *)h_FmPcdCcNode;
+ t_Error err = E_OK;
+ t_FmPcdModifyCcKeyAdditionalParams *p_ModifyKeyParams;
+
+ SANITY_CHECK_RETURN_ERROR(h_FmPcd,E_INVALID_VALUE);
+ SANITY_CHECK_RETURN_ERROR(p_FmPcdCcNode,E_INVALID_HANDLE);
+
+ if(keyIndex >= p_FmPcdCcNode->numOfKeys)
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("keyIndex > previousely cleared last index + 1"));
+
+ if((p_FmPcdCcNode->numOfKeys + 1) > FM_PCD_MAX_NUM_OF_CC_NODES)
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("numOfKeys with new key can not be larger than 255"));
+
+ err = ModifyKeyCommonPart1(p_FmPcdCcNode, keyIndex, h_AdditionalParams, e_MODIFY_STATE_CHANGE, FALSE, FALSE);
+ if(err)
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
+
+ p_ModifyKeyParams = (t_FmPcdModifyCcKeyAdditionalParams *)*h_AdditionalParams;
+
+ err = BuildNewNodeModifyNextEngine (h_FmPcd, p_FmPcdCcNode, keyIndex,p_FmPcdCcNextEngineParams, h_OldPointer, h_NewPointer, p_ModifyKeyParams);
+ if(err)
+ {
+ XX_Free(p_ModifyKeyParams);
+ RETURN_ERROR(MAJOR, err, NO_MSG);
+ }
+ return E_OK;
+}
+
+t_Error FmPcdCcModifyMissNextEngineParamNode(t_Handle h_FmPcd,t_Handle h_FmPcdCcNode, t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams,t_List *h_OldPointer, t_List *h_NewPointer,t_Handle *h_AdditionalParams)
+{
+ t_FmPcdCcNode *p_FmPcdCcNode = (t_FmPcdCcNode *)h_FmPcdCcNode;
+ t_Error err = E_OK;
+ uint16_t keyIndex;
+ t_FmPcdModifyCcKeyAdditionalParams *p_ModifyKeyParams;
+
+ SANITY_CHECK_RETURN_ERROR(p_FmPcdCcNode,E_INVALID_VALUE);
+
+ keyIndex = p_FmPcdCcNode->numOfKeys;
+
+ err = ModifyKeyCommonPart1(p_FmPcdCcNode, keyIndex, h_AdditionalParams, e_MODIFY_STATE_CHANGE, TRUE, FALSE);
+ if(err)
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
+
+ p_ModifyKeyParams = (t_FmPcdModifyCcKeyAdditionalParams *)*h_AdditionalParams;
+
+ err = BuildNewNodeModifyNextEngine (h_FmPcd, p_FmPcdCcNode, keyIndex,p_FmPcdCcNextEngineParams, h_OldPointer, h_NewPointer, p_ModifyKeyParams);
+ if(err)
+ {
+ XX_Free(p_ModifyKeyParams);
+ RETURN_ERROR(MAJOR, err, NO_MSG);
+ }
+
+ return E_OK;
+}
+
+t_Error FmPcdCcAddKey(t_Handle h_FmPcd, t_Handle h_FmPcdCcNode, uint8_t keyIndex, uint8_t keySize, t_FmPcdCcKeyParams *p_FmPcdCcKeyParams, t_List *h_OldLst, t_List *h_NewLst, t_Handle *h_AdditionalParams)
+{
+ t_FmPcdCcNode *p_FmPcdCcNode = (t_FmPcdCcNode *)h_FmPcdCcNode;
+ t_FmPcdModifyCcKeyAdditionalParams *p_ModifyKeyParams;
+ t_Error err = E_OK;
+
+ if(keyIndex > p_FmPcdCcNode->numOfKeys)
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("keyIndex > previousely cleared last index + 1"));
+
+ if((p_FmPcdCcNode->numOfKeys + 1) > FM_PCD_MAX_NUM_OF_CC_NODES)
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("numOfKeys with new key can not be larger than 255"));
+
+ if(keySize != p_FmPcdCcNode->userSizeOfExtraction)
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("keySize has to be defined as it was defined in initialization step."));
+
+ if(p_FmPcdCcNode->h_FmPcd != h_FmPcd)
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("handler to FmPcd is diferent from one which was assigned to the node in the Init time"));
+
+ err = ModifyKeyCommonPart1(p_FmPcdCcNode, keyIndex, h_AdditionalParams, e_MODIFY_STATE_ADD, TRUE, FALSE);
+ if(err)
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
+
+ p_ModifyKeyParams = (t_FmPcdModifyCcKeyAdditionalParams *)*h_AdditionalParams;
+ err = BuildNewNodeAddOrMdfyKeyAndNextEngine (h_FmPcd, p_FmPcdCcNode, keyIndex, p_FmPcdCcKeyParams, p_ModifyKeyParams, TRUE);
+ if(err)
+ {
+ XX_Free(p_ModifyKeyParams);
+ RETURN_ERROR(MAJOR, err, NO_MSG);
+ }
+
+ err = UpdatePtrWhichPointOnCrntMdfNode(p_FmPcdCcNode, p_ModifyKeyParams, h_OldLst, h_NewLst);
+ if(err)
+ {
+ ReleaseNewNodeCommonPart(p_ModifyKeyParams);
+ XX_Free(p_ModifyKeyParams);
+ RETURN_ERROR(MAJOR, err, NO_MSG);
+ }
+
+ return E_OK;
+}
+
+t_Error FmPcdCcModifyKeyAndNextEngine(t_Handle h_FmPcd, t_Handle h_FmPcdCcNode, uint8_t keyIndex, uint8_t keySize, t_FmPcdCcKeyParams *p_FmPcdCcKeyParams, t_List *h_OldLst, t_List *h_NewLst, t_Handle *h_AdditionalParams)
+{
+ t_FmPcdCcNode *p_FmPcdCcNode = (t_FmPcdCcNode *)h_FmPcdCcNode;
+ t_FmPcdModifyCcKeyAdditionalParams *p_ModifyKeyParams;
+ t_Error err = E_OK;
+
+ if(keyIndex > p_FmPcdCcNode->numOfKeys)
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("keyIndex > previousely cleared last index + 1"));
+
+ if((p_FmPcdCcNode->numOfKeys + 1) > FM_PCD_MAX_NUM_OF_CC_NODES)
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("numOfKeys with new key can not be larger than 255"));
+
+ if(keySize != p_FmPcdCcNode->userSizeOfExtraction)
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("keySize has to be defined as it was defined in initialization step"));
+
+ if(p_FmPcdCcNode->h_FmPcd != h_FmPcd)
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("handler to FmPcd is diferent from one which was assigned to the node in the Init time"));
+
+ err = ModifyKeyCommonPart1(p_FmPcdCcNode, keyIndex, h_AdditionalParams, e_MODIFY_STATE_CHANGE, TRUE, FALSE);
+ if(err)
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
+
+ p_ModifyKeyParams = (t_FmPcdModifyCcKeyAdditionalParams *)*h_AdditionalParams;
+
+ err = BuildNewNodeAddOrMdfyKeyAndNextEngine (h_FmPcd, p_FmPcdCcNode, keyIndex, p_FmPcdCcKeyParams, p_ModifyKeyParams, FALSE);
+ if(err)
+ {
+ ReleaseNewNodeCommonPart(p_ModifyKeyParams);
+ XX_Free(p_ModifyKeyParams);
+ RETURN_ERROR(MAJOR, err, NO_MSG);
+ }
+
+ err = UpdatePtrWhichPointOnCrntMdfNode(p_FmPcdCcNode, p_ModifyKeyParams, h_OldLst, h_NewLst);
+ if(err)
+ {
+ ReleaseNewNodeCommonPart(p_ModifyKeyParams);
+ XX_Free(p_ModifyKeyParams);
+ RETURN_ERROR(MAJOR, err, NO_MSG);
+ }
+
+ return E_OK;
+}
+
+t_Error FmPcdCcReleaseModifiedDataStructure(t_Handle h_FmPcd, t_List *h_FmPcdOldPointersLst, t_List *h_FmPcdNewPointersLst, uint16_t numOfGoodChanges, t_Handle *h_Params)
+{
+ t_FmPcdModifyCcKeyAdditionalParams *p_CcNewModifyAdditionalParams = (t_FmPcdModifyCcKeyAdditionalParams *)*h_Params;
+ t_List *p_Pos;
+ t_Error err = E_OK;
+ t_CcNodeInformation ccNodeInfo, *p_CcNodeInformation;
+ t_Handle h_Muram;
+ t_FmPcdCcNode *p_FmPcdCcNextNode;
+ t_List *p_UpdateLst;
+
+ UNUSED(numOfGoodChanges);
+
+ SANITY_CHECK_RETURN_ERROR(h_FmPcd,E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_CcNewModifyAdditionalParams->h_CurrentNode,E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(h_FmPcdOldPointersLst,E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(h_FmPcdNewPointersLst,E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR((numOfGoodChanges == LIST_NumOfObjs(h_FmPcdOldPointersLst)),E_INVALID_STATE);
+ SANITY_CHECK_RETURN_ERROR((numOfGoodChanges == LIST_NumOfObjs(h_FmPcdNewPointersLst)),E_INVALID_STATE);
+ SANITY_CHECK_RETURN_ERROR((LIST_NumOfObjs(h_FmPcdOldPointersLst) == LIST_NumOfObjs(h_FmPcdNewPointersLst)),E_INVALID_STATE);
+
+ /*we don't update subtree of the new node with new tree because it was done in the previose stage*/
+ if(p_CcNewModifyAdditionalParams->h_NodeForAdd)
+ {
+ p_FmPcdCcNextNode = (t_FmPcdCcNode*)p_CcNewModifyAdditionalParams->h_NodeForAdd;
+ if(!p_CcNewModifyAdditionalParams->tree)
+ p_UpdateLst = &p_FmPcdCcNextNode->ccPrevNodesLst;
+ else
+ p_UpdateLst = &p_FmPcdCcNextNode->ccTreeIdLst;
+ p_CcNodeInformation = FindNodeInfoInReleventLst(p_UpdateLst, p_CcNewModifyAdditionalParams->h_CurrentNode);
+ if(p_CcNodeInformation)
+ p_CcNodeInformation->index++;
+ else
+ {
+ memset(&ccNodeInfo, 0, sizeof(t_CcNodeInformation));
+ ccNodeInfo.h_CcNode = (t_Handle)p_CcNewModifyAdditionalParams->h_CurrentNode;
+ ccNodeInfo.index = 1;
+ EnqueueNodeInfoToRelevantLst(p_UpdateLst, &ccNodeInfo);
+ }
+ }
+
+ if(p_CcNewModifyAdditionalParams->h_NodeForRmv)
+ {
+
+ p_FmPcdCcNextNode = (t_FmPcdCcNode*)p_CcNewModifyAdditionalParams->h_NodeForRmv;
+ if(!p_CcNewModifyAdditionalParams->tree)
+ {
+ p_UpdateLst = &p_FmPcdCcNextNode->ccPrevNodesLst;
+ LIST_FOR_EACH(p_Pos, &p_FmPcdCcNextNode->ccTreesLst)
+ {
+ p_CcNodeInformation = CC_NODE_F_OBJECT(p_Pos);
+ ASSERT_COND(p_CcNodeInformation->h_CcNode);
+ err = FmPcdCcSetRequiredAction(h_FmPcd,
+ UPDATE_CC_WITH_DELETE_TREE,
+ &((t_FmPcdCcNode *)(p_CcNewModifyAdditionalParams->h_CurrentNode))->nextEngineAndRequiredAction[p_CcNewModifyAdditionalParams->keyIndex],
+ PTR_MOVE(((t_FmPcdCcNode *)(p_CcNewModifyAdditionalParams->h_CurrentNode))->h_AdTable, p_CcNewModifyAdditionalParams->keyIndex*FM_PCD_CC_AD_ENTRY_SIZE),
+ 1,
+ p_CcNodeInformation->h_CcNode);
+ }
+ }
+ else
+ {
+ p_UpdateLst = &p_FmPcdCcNextNode->ccTreeIdLst;
+ err = FmPcdCcSetRequiredAction(h_FmPcd,
+ UPDATE_CC_WITH_DELETE_TREE,
+ &((t_FmPcdCcTree *)(p_CcNewModifyAdditionalParams->h_CurrentNode))->nextEngineAndRequiredAction[p_CcNewModifyAdditionalParams->keyIndex],
+ UINT_TO_PTR(((t_FmPcdCcTree *)(p_CcNewModifyAdditionalParams->h_CurrentNode))->ccTreeBaseAddr + p_CcNewModifyAdditionalParams->keyIndex*FM_PCD_CC_AD_ENTRY_SIZE),
+ 1,
+ p_CcNewModifyAdditionalParams->h_CurrentNode);
+ }
+ if(err)
+ return err;
+
+ /*we remove from the subtree of the removed node tree because it wasn't done in the previose stage*/
+ /*update ccPrevNodesLst or ccTreeIdLst of the removed node*/
+ /*update of the nodeOwner*/
+ p_CcNodeInformation = FindNodeInfoInReleventLst(p_UpdateLst, p_CcNewModifyAdditionalParams->h_CurrentNode);
+ ASSERT_COND(p_CcNodeInformation);
+ ASSERT_COND(p_CcNodeInformation->index);
+ p_CcNodeInformation->index--;
+ if(p_CcNodeInformation->index == 0)
+ DequeueNodeInfoFromRelevantLst(p_UpdateLst,p_CcNewModifyAdditionalParams->h_CurrentNode);
+ ASSERT_COND(LIST_NumOfObjs(&p_FmPcdCcNextNode->ccTreesLst) == 1);
+ UpdateNodeOwner(p_FmPcdCcNextNode, FALSE);
+ }
+
+#ifdef FM_PCD_CC_MANIP
+ if(p_CcNewModifyAdditionalParams->h_ManipForRmv)
+ FmPcdManipUpdateOwner(p_CcNewModifyAdditionalParams->h_ManipForRmv, FALSE);
+#endif /* FM_PCD_CC_MANIP */
+
+ h_Muram = FmPcdGetMuramHandle(h_FmPcd);
+ ASSERT_COND(h_Muram);
+
+ /*we release new AD which was allocated and updated for copy from to actual AD*/
+ LIST_FOR_EACH(p_Pos, h_FmPcdNewPointersLst)
+ {
+ p_CcNodeInformation = CC_NODE_F_OBJECT(p_Pos);
+ ASSERT_COND(p_CcNodeInformation->h_CcNode);
+ FM_MURAM_FreeMem(h_Muram, p_CcNodeInformation->h_CcNode);
+
+ }
+
+ /*free Old data structure if it has to be freed - new data structure was allocated*/
+ if(p_CcNewModifyAdditionalParams->p_AdTableOld)
+ FM_MURAM_FreeMem(h_Muram,p_CcNewModifyAdditionalParams->p_AdTableOld);
+ if(p_CcNewModifyAdditionalParams->p_KeysMatchTableOld)
+ FM_MURAM_FreeMem(h_Muram,p_CcNewModifyAdditionalParams->p_KeysMatchTableOld);
+
+ /*update current modified node with changed fields if it's required*/
+ if(!p_CcNewModifyAdditionalParams->tree)
+ {
+ if(p_CcNewModifyAdditionalParams->p_AdTableNew)
+ ((t_FmPcdCcNode *)(p_CcNewModifyAdditionalParams->h_CurrentNode))->h_AdTable = p_CcNewModifyAdditionalParams->p_AdTableNew;
+ if(p_CcNewModifyAdditionalParams->numOfKeys)
+ ((t_FmPcdCcNode *)(p_CcNewModifyAdditionalParams->h_CurrentNode))->numOfKeys = p_CcNewModifyAdditionalParams->numOfKeys;
+ if(p_CcNewModifyAdditionalParams->p_KeysMatchTableNew)
+ ((t_FmPcdCcNode *)(p_CcNewModifyAdditionalParams->h_CurrentNode))->h_KeysMatchTable = p_CcNewModifyAdditionalParams->p_KeysMatchTableNew;
+ memcpy(((t_FmPcdCcNode *)(p_CcNewModifyAdditionalParams->h_CurrentNode))->nextEngineAndRequiredAction, &p_CcNewModifyAdditionalParams->nextEngineAndRequiredAction, sizeof(t_FmPcdCcNextEngineAndRequiredActionParams) * (FM_PCD_MAX_NUM_OF_KEYS));
+ }
+ else
+ memcpy(&((t_FmPcdCcTree *)(p_CcNewModifyAdditionalParams->h_CurrentNode))->nextEngineAndRequiredAction, &p_CcNewModifyAdditionalParams->nextEngineAndRequiredAction, sizeof(t_FmPcdCcNextEngineAndRequiredActionParams) * (((t_FmPcdCcTree *)(p_CcNewModifyAdditionalParams->h_CurrentNode))->numOfEntries));
+
+ ReleaseLst(h_FmPcdOldPointersLst);
+ ReleaseLst(h_FmPcdNewPointersLst);
+ XX_Free(p_CcNewModifyAdditionalParams);
+
+ return E_OK;
+}
+
+uint32_t FmPcdCcGetNodeAddrOffsetFromNodeInfo(t_Handle h_FmPcd, t_Handle h_Pointer)
+{
+ t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
+ t_CcNodeInformation *p_CcNodeInfo;
+
+ SANITY_CHECK_RETURN_VALUE(h_FmPcd,E_INVALID_HANDLE, (uint32_t)ILLEGAL_BASE);
+
+ p_CcNodeInfo = CC_NODE_F_OBJECT(h_Pointer);
+ return (uint32_t)(XX_VirtToPhys(p_CcNodeInfo->h_CcNode) - p_FmPcd->physicalMuramBase);
+}
+
+t_Error FmPcdCcGetGrpParams(t_Handle h_FmPcdCcTree, uint8_t grpId, uint32_t *p_GrpBits, uint8_t *p_GrpBase)
+{
+ t_FmPcdCcTree *p_FmPcdCcTree = (t_FmPcdCcTree *) h_FmPcdCcTree;
+
+ SANITY_CHECK_RETURN_ERROR(h_FmPcdCcTree, E_INVALID_HANDLE);
+
+ if(grpId >= p_FmPcdCcTree->numOfGrps)
+ RETURN_ERROR(MAJOR, E_INVALID_HANDLE, ("grpId you asked > numOfGroup of relevant tree"));
+ *p_GrpBits = p_FmPcdCcTree->fmPcdGroupParam[grpId].totalBitsMask;
+ *p_GrpBase = p_FmPcdCcTree->fmPcdGroupParam[grpId].baseGroupEntry;
+ return E_OK;
+}
+
+t_Error FmPcdCcBindTree(t_Handle h_FmPcd, t_Handle h_FmPcdCcTree, uint32_t *p_Offset, t_Handle h_FmPort)
+{
+ t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
+ t_FmPcdCcTree *p_FmPcdCcTree = (t_FmPcdCcTree *)h_FmPcdCcTree;
+ t_Error err = E_OK;
+
+ SANITY_CHECK_RETURN_ERROR(p_FmPcd,E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_FmPcdCcTree,E_INVALID_STATE);
+
+ FmPcdCcUpdateTreeOwner(p_FmPcdCcTree, TRUE);
+
+ *p_Offset = (uint32_t)(XX_VirtToPhys(UINT_TO_PTR(p_FmPcdCcTree->ccTreeBaseAddr)) -
+ p_FmPcd->physicalMuramBase);
+
+ err = CcUpdateParams(h_FmPcd, h_FmPort, h_FmPcdCcTree, TRUE);
+
+ return err;
+}
+
+t_Error FmPcdCcUnbindTree(t_Handle h_FmPcd, t_Handle h_FmPcdCcTree)
+{
+ t_FmPcdCcTree *p_FmPcdCcTree = (t_FmPcdCcTree *)h_FmPcdCcTree;
+
+ UNUSED(h_FmPcd);
+
+ SANITY_CHECK_RETURN_ERROR(p_FmPcdCcTree,E_INVALID_HANDLE);
+
+ FmPcdCcUpdateTreeOwner(p_FmPcdCcTree, FALSE);
+
+ return E_OK;
+}
+
+t_Error FmPcdCcTreeTryLock(t_Handle h_FmPcdCcTree)
+{
+ if (TRY_LOCK(NULL, &((t_FmPcdCcTree *)h_FmPcdCcTree)->lock))
+ return E_OK;
+ return ERROR_CODE(E_BUSY);
+}
+
+t_Error FmPcdCcNodeTreeTryLock(t_Handle h_FmPcd,t_Handle h_FmPcdCcNode, t_List *p_List)
+{
+ t_FmPcdCcNode *p_FmPcdCcNode = (t_FmPcdCcNode *)h_FmPcdCcNode;
+ t_List *p_Pos;
+ t_CcNodeInformation *p_CcNodeInfo, nodeInfo;
+ t_Error err = E_OK;
+
+ UNUSED(h_FmPcd);
+
+ if(LIST_IsEmpty(&p_FmPcdCcNode->ccTreesLst))
+ RETURN_ERROR(MAJOR, E_NOT_AVAILABLE, ("asked for more nodes in CC than MAX")) ;
+ LIST_FOR_EACH(p_Pos, &p_FmPcdCcNode->ccTreesLst)
+ {
+ p_CcNodeInfo = CC_NODE_F_OBJECT(p_Pos);
+ ASSERT_COND(p_CcNodeInfo->h_CcNode);
+ err = FmPcdCcTreeTryLock(p_CcNodeInfo->h_CcNode);
+ if(err == E_OK)
+ {
+ memset(&nodeInfo, 0, sizeof(t_CcNodeInformation));
+ nodeInfo.h_CcNode = p_CcNodeInfo->h_CcNode;
+ EnqueueNodeInfoToRelevantLst(p_List, &nodeInfo);
+ }
+ else
+ FmPcdCcNodeTreeReleaseLock(p_List);
+ }
+
+ return err;
+}
+
+t_Handle FM_PCD_CcBuildTree(t_Handle h_FmPcd, t_FmPcdCcTreeParams *p_PcdGroupsParam)
+{
+ t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
+ t_Error err = E_OK;
+ int i = 0, j = 0, k = 0;
+ t_FmPcdCcTree *p_FmPcdCcTree;
+ uint8_t numOfEntries;
+ t_Handle p_CcTreeTmp;
+ t_FmPcdCcGrpParams *p_FmPcdCcGroupParams;
+ t_FmPcdCcNextEngineAndRequiredActionParams params[16];
+ t_NetEnvParams netEnvParams;
+ uint8_t lastOne = 0;
+ uint32_t requiredAction = 0;
+ t_FmPcdCcNode *p_FmPcdCcNextNode;
+ t_CcNodeInformation ccNodeInfo, *p_CcInformation;
+
+ SANITY_CHECK_RETURN_VALUE(h_FmPcd,E_INVALID_HANDLE, NULL);
+ SANITY_CHECK_RETURN_VALUE(p_PcdGroupsParam,E_INVALID_HANDLE, NULL);
+
+ if (p_PcdGroupsParam->numOfGrps > FM_PCD_MAX_NUM_OF_CC_GROUPS)
+ {
+ REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("numOfGrps should not exceed %d", FM_PCD_MAX_NUM_OF_CC_GROUPS));
+ return NULL;
+ }
+
+ p_FmPcdCcTree = (t_FmPcdCcTree*)XX_Malloc(sizeof(t_FmPcdCcTree));
+ if(!p_FmPcdCcTree)
+ {
+ REPORT_ERROR(MAJOR, E_NO_MEMORY, ("PCD tree structure"));
+ return NULL;
+ }
+ memset(p_FmPcdCcTree, 0, sizeof(t_FmPcdCcTree)) ;
+ memset(params, 0, 16 * sizeof(t_FmPcdCcNextEngineParams));
+
+ INIT_LIST(&p_FmPcdCcTree->fmPortsLst);
+
+ numOfEntries = 0;
+ p_FmPcdCcTree->netEnvId = (uint8_t)(PTR_TO_UINT(p_PcdGroupsParam->h_NetEnv)-1);
+ for(i = 0; i < p_PcdGroupsParam->numOfGrps; i++)
+ {
+ p_FmPcdCcGroupParams = &p_PcdGroupsParam->ccGrpParams[i];
+
+ if (p_FmPcdCcGroupParams->numOfDistinctionUnits > FM_PCD_MAX_NUM_OF_CC_UNITS)
+ {
+ DeleteTree(p_FmPcdCcTree,p_FmPcd);
+ REPORT_ERROR(MAJOR, E_INVALID_VALUE,
+ ("numOfDistinctionUnits (group %d) should not exceed %d", i, FM_PCD_MAX_NUM_OF_CC_UNITS));
+ return NULL;
+ }
+
+ p_FmPcdCcTree->fmPcdGroupParam[i].baseGroupEntry = numOfEntries;
+ p_FmPcdCcTree->fmPcdGroupParam[i].numOfEntriesInGroup =(uint8_t)( 0x01 << p_FmPcdCcGroupParams->numOfDistinctionUnits);
+ numOfEntries += p_FmPcdCcTree->fmPcdGroupParam[i].numOfEntriesInGroup;
+ if(numOfEntries > 16)
+ {
+ DeleteTree(p_FmPcdCcTree,p_FmPcd);
+ REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("numOfEntries can not be larger than 16"));
+ return NULL;
+ }
+ if(lastOne)
+ {
+ if(p_FmPcdCcTree->fmPcdGroupParam[i].numOfEntriesInGroup > lastOne)
+ {
+ DeleteTree(p_FmPcdCcTree,p_FmPcd);
+ REPORT_ERROR(MAJOR, E_CONFLICT, ("numOfEntries per group must be set in descending order"));
+ return NULL;
+ }
+ }
+
+ lastOne = p_FmPcdCcTree->fmPcdGroupParam[i].numOfEntriesInGroup;
+
+ netEnvParams.netEnvId = p_FmPcdCcTree->netEnvId;
+ netEnvParams.numOfDistinctionUnits = p_FmPcdCcGroupParams->numOfDistinctionUnits;
+ memcpy(netEnvParams.unitIds, &p_FmPcdCcGroupParams->unitIds, (sizeof(uint8_t)) * p_FmPcdCcGroupParams->numOfDistinctionUnits);
+ err = PcdGetUnitsVector(p_FmPcd, &netEnvParams);
+ if(err)
+ {
+ DeleteTree(p_FmPcdCcTree,p_FmPcd);
+ REPORT_ERROR(MAJOR, err, NO_MSG);
+ return NULL;
+ }
+
+ p_FmPcdCcTree->fmPcdGroupParam[i].totalBitsMask = netEnvParams.vector;
+ for(j = 0; j < p_FmPcdCcTree->fmPcdGroupParam[i].numOfEntriesInGroup; j++)
+ {
+ err = ValidateNextEngineParams(h_FmPcd,&p_FmPcdCcGroupParams->nextEnginePerEntriesInGrp[j]);
+ if(err)
+ {
+ DeleteTree(p_FmPcdCcTree,p_FmPcd);
+ REPORT_ERROR(MAJOR, err, (NO_MSG));
+ return NULL;
+ }
+
+#ifdef FM_PCD_CC_MANIP
+ if(p_FmPcdCcGroupParams->nextEnginePerEntriesInGrp[j].h_Manip)
+ {
+ err = FmPcdManipCheckParamsForCcNextEgine(&p_FmPcdCcGroupParams->nextEnginePerEntriesInGrp[j], &requiredAction);
+ if(err)
+ {
+ DeleteTree(p_FmPcdCcTree,p_FmPcd);
+ REPORT_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
+ return NULL;
+ }
+ }
+#endif /* FM_PCD_CC_MANIP */
+
+ memcpy(&params[k].nextEngineParams, &p_FmPcdCcGroupParams->nextEnginePerEntriesInGrp[j], sizeof(t_FmPcdCcNextEngineParams));
+ requiredAction |= UPDATE_CC_WITH_TREE;
+ params[k].requiredAction = requiredAction;
+ k++;
+ }
+ }
+
+ p_FmPcdCcTree->numOfEntries = (uint8_t)k;
+ p_FmPcdCcTree->numOfGrps = p_PcdGroupsParam->numOfGrps;
+ p_FmPcdCcTree->ccTreeBaseAddr =
+ PTR_TO_UINT(FM_MURAM_AllocMem(FmPcdGetMuramHandle(h_FmPcd),
+ (uint32_t)( k * FM_PCD_CC_AD_ENTRY_SIZE),
+ FM_PCD_CC_AD_TABLE_ALIGN));
+
+ if(!p_FmPcdCcTree->ccTreeBaseAddr)
+ {
+ DeleteTree(p_FmPcdCcTree,p_FmPcd);
+ REPORT_ERROR(MAJOR, E_NO_MEMORY, ("No memory"));
+ return NULL;
+ }
+ IOMemSet32(UINT_TO_PTR(p_FmPcdCcTree->ccTreeBaseAddr), 0, (uint32_t)(k * FM_PCD_CC_AD_ENTRY_SIZE));
+
+ p_CcTreeTmp = UINT_TO_PTR(p_FmPcdCcTree->ccTreeBaseAddr);
+
+ j = 0;
+ for(i = 0; i < numOfEntries; i++)
+ {
+ NextStepAd(p_CcTreeTmp,&params[i].nextEngineParams,p_FmPcd);
+ p_CcTreeTmp = PTR_MOVE(p_CcTreeTmp, FM_PCD_CC_AD_ENTRY_SIZE);
+ memcpy(&p_FmPcdCcTree->nextEngineAndRequiredAction[i], &params[i], sizeof(t_FmPcdCcNextEngineAndRequiredActionParams));
+ if(p_FmPcdCcTree->nextEngineAndRequiredAction[i].nextEngineParams.nextEngine== e_FM_PCD_CC)
+ {
+ p_FmPcdCcNextNode = (t_FmPcdCcNode*)p_FmPcdCcTree->nextEngineAndRequiredAction[i].nextEngineParams.params.ccParams.h_CcNode;
+ if(!IsNodeInModifiedState((t_Handle)p_FmPcdCcNextNode))
+ {
+ memset(&ccNodeInfo, 0, sizeof(t_CcNodeInformation));
+ ccNodeInfo.h_CcNode = (t_Handle)p_FmPcdCcTree;
+ ccNodeInfo.index = 1;
+ EnqueueNodeInfoToRelevantLst(&p_FmPcdCcNextNode->ccTreeIdLst, &ccNodeInfo);
+ UpdateNodeWithModifiedState((t_Handle)p_FmPcdCcNextNode, TRUE);
+ }
+ else
+ {
+ p_CcInformation = FindNodeInfoInReleventLst(&p_FmPcdCcNextNode->ccTreeIdLst,(t_Handle)p_FmPcdCcTree);
+ ASSERT_COND(p_CcInformation);
+ p_CcInformation->index++;
+ }
+ }
+ }
+
+ FmPcdIncNetEnvOwners(h_FmPcd, p_FmPcdCcTree->netEnvId);
+ p_CcTreeTmp = UINT_TO_PTR(p_FmPcdCcTree->ccTreeBaseAddr);
+
+ for(i = 0; i < p_FmPcdCcTree->numOfEntries ; i++)
+ {
+ if(p_FmPcdCcTree->nextEngineAndRequiredAction[i].nextEngineParams.nextEngine == e_FM_PCD_CC)
+ {
+ p_FmPcdCcNextNode = (t_FmPcdCcNode*)p_FmPcdCcTree->nextEngineAndRequiredAction[i].nextEngineParams.params.ccParams.h_CcNode;
+
+ if(IsNodeInModifiedState((t_Handle)p_FmPcdCcNextNode))
+ UpdateNodeWithModifiedState((t_Handle)p_FmPcdCcNextNode, FALSE);
+ }
+ }
+
+ for(i = 0; i < numOfEntries; i++)
+ {
+ if(p_FmPcdCcTree->nextEngineAndRequiredAction[i].requiredAction)
+ {
+ err = FmPcdCcSetRequiredAction(h_FmPcd, p_FmPcdCcTree->nextEngineAndRequiredAction[i].requiredAction, &p_FmPcdCcTree->nextEngineAndRequiredAction[i], p_CcTreeTmp,1, p_FmPcdCcTree);
+ if(err)
+ {
+ DeleteTree(p_FmPcdCcTree,p_FmPcd);
+ REPORT_ERROR(MAJOR, E_NO_MEMORY, ("No memory"));
+ return NULL;
+ }
+ p_CcTreeTmp = PTR_MOVE(p_CcTreeTmp, FM_PCD_CC_AD_ENTRY_SIZE);
+ }
+ }
+
+ return p_FmPcdCcTree;
+}
+
+t_Error FM_PCD_CcDeleteTree(t_Handle h_FmPcd, t_Handle h_CcTree)
+{
+ t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
+ t_FmPcdCcTree *p_CcTree = (t_FmPcdCcTree *)h_CcTree;
+ int i= 0;
+
+ SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_CcTree,E_INVALID_STATE);
+
+ FmPcdDecNetEnvOwners(h_FmPcd, p_CcTree->netEnvId);
+
+ if(p_CcTree->owners)
+ RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("the tree with this ID can not be removed because this tree is occupied, first - unbind this tree"));
+
+ for(i = 0; i <p_CcTree->numOfEntries; i++)
+ {
+ if(p_CcTree->nextEngineAndRequiredAction[i].nextEngineParams.nextEngine == e_FM_PCD_CC)
+ UpdateNodeOwner(p_CcTree->nextEngineAndRequiredAction[i].nextEngineParams.params.ccParams.h_CcNode, FALSE);
+ }
+
+#ifdef FM_PCD_CC_MANIP
+ for(i = 0; i < p_CcTree->numOfEntries; i++)
+ {
+ if(p_CcTree->nextEngineAndRequiredAction[i].nextEngineParams.h_Manip)
+ FmPcdManipUpdateOwner(p_CcTree->nextEngineAndRequiredAction[i].nextEngineParams.h_Manip, FALSE);
+ }
+#endif /* FM_PCD_CC_MANIP */
+
+ DeleteTree(p_CcTree, p_FmPcd);
+ return E_OK;
+}
+
+t_Handle FM_PCD_CcSetNode(t_Handle h_FmPcd, t_FmPcdCcNodeParams *p_CcNodeParam)
+{
+ t_FmPcd *p_FmPcd = (t_FmPcd *) h_FmPcd;
+ t_FmPcdCcNode *p_FmPcdCcNode, *p_FmPcdCcNextNode;
+ t_Error err = E_OK;
+ int tmp, size;
+ bool glblMask = FALSE;
+ t_FmPcdCcKeyParams *p_KeyParams;
+ t_Handle p_KeysMatchTblTmp;
+ t_Handle p_AdTableTmp;
+ bool fullField = FALSE;
+ ccPrivateInfo_t icCode = CC_PRIVATE_INFO_NONE;
+ bool isKeyTblAlloc, fromIc = FALSE;
+ t_CcNodeInformation ccNodeInfo, *p_CcInformation;
+
+ SANITY_CHECK_RETURN_VALUE(h_FmPcd,E_INVALID_HANDLE,NULL);
+
+ /*
+ if (!p_CcNodeParam->keysParams.keySize ||
+ !p_CcNodeParam->keysParams.numOfKeys)
+ {
+ REPORT_ERROR(MAJOR, E_INVALID_STATE, ("At least one key of keySize > 0 must be defined."));
+ return NULL;
+ }
+ */
+ p_FmPcdCcNode = (t_FmPcdCcNode*)XX_Malloc(sizeof(t_FmPcdCcNode));
+ if(!p_FmPcdCcNode)
+ {
+ REPORT_ERROR(MAJOR, E_NO_MEMORY, ("No memory"));
+ return NULL;
+ }
+ memset(p_FmPcdCcNode, 0, sizeof(t_FmPcdCcNode));
+
+ p_FmPcdCcNode->p_GlblMask = (t_Handle)XX_Malloc(CC_GLBL_MASK_SIZE * sizeof(uint8_t));
+ memset(p_FmPcdCcNode->p_GlblMask, 0, CC_GLBL_MASK_SIZE * sizeof(uint8_t));
+
+ p_FmPcdCcNode->numOfKeys = p_CcNodeParam->keysParams.numOfKeys;
+
+ p_FmPcdCcNode->h_FmPcd = h_FmPcd;
+
+ INIT_LIST(&p_FmPcdCcNode->ccPrevNodesLst);
+ INIT_LIST(&p_FmPcdCcNode->ccTreeIdLst);
+ INIT_LIST(&p_FmPcdCcNode->ccTreesLst);
+
+ if((p_CcNodeParam->extractCcParams.type == e_FM_PCD_EXTRACT_BY_HDR) &&
+ ((p_CcNodeParam->extractCcParams.extractByHdr.hdr == HEADER_TYPE_IPv4) ||
+ (p_CcNodeParam->extractCcParams.extractByHdr.hdr == HEADER_TYPE_IPv6)) &&
+ (p_CcNodeParam->extractCcParams.extractByHdr.type == e_FM_PCD_EXTRACT_FULL_FIELD) &&
+ ((p_CcNodeParam->extractCcParams.extractByHdr.extractByHdrType.fullField.ipv6 == NET_HEADER_FIELD_IPv6_HOP_LIMIT) ||
+ (p_CcNodeParam->extractCcParams.extractByHdr.extractByHdrType.fullField.ipv4 == NET_HEADER_FIELD_IPv4_TTL)))
+ {
+ err = Ipv4TtlOrIpv6HopLimiCheckParams(h_FmPcd, p_CcNodeParam, p_FmPcdCcNode, &isKeyTblAlloc);
+ glblMask = FALSE;
+
+ }
+ else if((p_CcNodeParam->extractCcParams.type == e_FM_PCD_EXTRACT_NON_HDR) &&
+ ((p_CcNodeParam->extractCcParams.extractNonHdr.src == e_FM_PCD_EXTRACT_FROM_KEY) ||
+ (p_CcNodeParam->extractCcParams.extractNonHdr.src == e_FM_PCD_EXTRACT_FROM_HASH) ||
+ (p_CcNodeParam->extractCcParams.extractNonHdr.src == e_FM_PCD_EXTRACT_FROM_FLOW_ID)))
+ {
+ if((p_CcNodeParam->extractCcParams.extractNonHdr.src == e_FM_PCD_EXTRACT_FROM_FLOW_ID) &&
+ (p_CcNodeParam->extractCcParams.extractNonHdr.offset != 0))
+ {
+ 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"));
+ return NULL;
+ }
+
+ icCode = IcDefineCode(p_CcNodeParam);
+ fromIc = TRUE;
+ if(icCode == CC_PRIVATE_INFO_NONE)
+ {
+ 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"));
+ return NULL;
+ }
+
+ if((icCode == CC_PRIVATE_INFO_IC_DEQ_FQID_INDEX_LOOKUP) || (icCode == CC_PRIVATE_INFO_IC_HASH_INDEX_LOOKUP))
+ {
+ err = IcHashIndexedCheckParams(h_FmPcd, p_CcNodeParam, p_FmPcdCcNode, &isKeyTblAlloc);
+
+ glblMask = TRUE;
+ }
+ else
+ {
+ err = CheckParams(h_FmPcd, p_CcNodeParam,p_FmPcdCcNode, &isKeyTblAlloc);
+ if(p_FmPcdCcNode->glblMaskSize)
+ glblMask = TRUE;
+ }
+ }
+ else
+ {
+ err = CheckParams(h_FmPcd, p_CcNodeParam,p_FmPcdCcNode, &isKeyTblAlloc);
+ if(p_FmPcdCcNode->glblMaskSize)
+ glblMask = TRUE;
+ }
+
+ if(err)
+ {
+ DeleteNode(p_FmPcdCcNode);
+ REPORT_ERROR(MAJOR, err, NO_MSG);
+ return NULL;
+ }
+
+ switch(p_CcNodeParam->extractCcParams.type)
+ {
+ case(e_FM_PCD_EXTRACT_BY_HDR):
+ switch(p_CcNodeParam->extractCcParams.extractByHdr.type)
+ {
+ case(e_FM_PCD_EXTRACT_FULL_FIELD):
+ p_FmPcdCcNode->parseCode = GetFullFieldParseCode(p_CcNodeParam->extractCcParams.extractByHdr.hdr, p_CcNodeParam->extractCcParams.extractByHdr.hdrIndex,
+ p_CcNodeParam->extractCcParams.extractByHdr.extractByHdrType.fullField);
+ GetSizeHeaderField(p_CcNodeParam->extractCcParams.extractByHdr.hdr, p_CcNodeParam->extractCcParams.extractByHdr.extractByHdrType.fullField, &p_FmPcdCcNode->sizeOfExtraction);
+ fullField = TRUE;
+ if((p_FmPcdCcNode->parseCode != CC_PC_FF_TCI1) && (p_FmPcdCcNode->parseCode != CC_PC_FF_TCI2) &&
+ (p_FmPcdCcNode->parseCode != CC_PC_FF_MPLS1) && (p_FmPcdCcNode->parseCode != CC_PC_FF_MPLS1) &&
+ (p_FmPcdCcNode->parseCode != CC_PC_FF_IPV4IPTOS_TC1) && (p_FmPcdCcNode->parseCode != CC_PC_FF_IPV4IPTOS_TC2) &&
+ (p_FmPcdCcNode->parseCode != CC_PC_FF_IPTOS_IPV6TC1_IPV6FLOW1) && (p_FmPcdCcNode->parseCode != CC_PC_FF_IPTOS_IPV6TC2_IPV6FLOW2) &&
+ glblMask)
+ {
+ glblMask = FALSE;
+ p_FmPcdCcNode->glblMaskSize = 4;
+ p_FmPcdCcNode->lclMask = TRUE;
+ }
+ break;
+ case(e_FM_PCD_EXTRACT_FROM_HDR):
+ p_FmPcdCcNode->sizeOfExtraction = p_CcNodeParam->extractCcParams.extractByHdr.extractByHdrType.fromHdr.size;
+ p_FmPcdCcNode->offset = p_CcNodeParam->extractCcParams.extractByHdr.extractByHdrType.fromHdr.offset;
+ p_FmPcdCcNode->parseCode = GetPrParseCode(p_CcNodeParam->extractCcParams.extractByHdr.hdr, p_CcNodeParam->extractCcParams.extractByHdr.hdrIndex,
+ p_FmPcdCcNode->offset,glblMask, &p_FmPcdCcNode->prsArrayOffset);
+ break;
+ case(e_FM_PCD_EXTRACT_FROM_FIELD):
+ p_FmPcdCcNode->offset = p_CcNodeParam->extractCcParams.extractByHdr.extractByHdrType.fromField.offset;
+ p_FmPcdCcNode->sizeOfExtraction = p_CcNodeParam->extractCcParams.extractByHdr.extractByHdrType.fromField.size;
+ p_FmPcdCcNode->parseCode = GetFieldParseCode(p_CcNodeParam->extractCcParams.extractByHdr.hdr, p_CcNodeParam->extractCcParams.extractByHdr.extractByHdrType.fromField.field,
+ p_FmPcdCcNode->offset,&p_FmPcdCcNode->prsArrayOffset,
+ p_CcNodeParam->extractCcParams.extractByHdr.hdrIndex);
+ break;
+ default:
+ DeleteNode(p_FmPcdCcNode);
+ REPORT_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG);
+ return NULL;
+ }
+ break;
+ case(e_FM_PCD_EXTRACT_NON_HDR):
+ /* get the field code for the generic extract */
+ p_FmPcdCcNode->sizeOfExtraction = p_CcNodeParam->extractCcParams.extractNonHdr.size;
+ p_FmPcdCcNode->offset = p_CcNodeParam->extractCcParams.extractNonHdr.offset;
+ p_FmPcdCcNode->parseCode = GetGenParseCode(p_CcNodeParam->extractCcParams.extractNonHdr.src, p_FmPcdCcNode->offset, glblMask, &p_FmPcdCcNode->prsArrayOffset, fromIc,icCode);
+
+ if(p_FmPcdCcNode->parseCode == CC_PC_GENERIC_IC_HASH_INDEXED)
+ {
+ if((p_FmPcdCcNode->offset + p_FmPcdCcNode->sizeOfExtraction) > 64)
+ {
+ DeleteNode(p_FmPcdCcNode);
+ 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)"));
+ return NULL;
+ }
+ }
+ if((p_FmPcdCcNode->parseCode == CC_PC_GENERIC_IC_GMASK) || (p_FmPcdCcNode->parseCode == CC_PC_GENERIC_IC_HASH_INDEXED))
+ {
+ p_FmPcdCcNode->offset += p_FmPcdCcNode->prsArrayOffset;
+ p_FmPcdCcNode->prsArrayOffset = 0;
+ }
+ break;
+
+ default:
+ DeleteNode(p_FmPcdCcNode);
+ REPORT_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG);
+ return NULL;
+ }
+
+ if(p_FmPcdCcNode->parseCode == CC_PC_ILLEGAL)
+ {
+ DeleteNode(p_FmPcdCcNode);
+ REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("illeagl extraction type"));
+ return NULL;
+ }
+
+ if((p_FmPcdCcNode->sizeOfExtraction > FM_PCD_MAX_SIZE_OF_KEY) || !p_FmPcdCcNode->sizeOfExtraction)
+ {
+ DeleteNode(p_FmPcdCcNode);
+ REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("sizeOfExatrction can not be greater than 56 and not 0"));
+ return NULL;
+ }
+
+ if(p_CcNodeParam->keysParams.keySize != p_FmPcdCcNode->sizeOfExtraction)
+ {
+ DeleteNode(p_FmPcdCcNode);
+ REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("keySize has to be equal to sizeOfExtraction"));
+ return NULL;
+ }
+
+
+ p_FmPcdCcNode->userSizeOfExtraction = p_FmPcdCcNode->sizeOfExtraction;
+
+ if(!glblMask)
+ memset(p_FmPcdCcNode->p_GlblMask, 0xff, CC_GLBL_MASK_SIZE * sizeof(uint8_t));
+
+#ifdef FM_PCD_CC_MANIP
+ err = CheckAndSetManipParamsWithCcNodeParams(p_FmPcdCcNode);
+ if(err != E_OK)
+ {
+ DeleteNode(p_FmPcdCcNode);
+ REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("keySize has to be equal to sizeOfExtraction"));
+ return NULL;
+ }
+#endif /* FM_PCD_CC_MANIP */
+
+ GetCcExtractKeySize(p_FmPcdCcNode->sizeOfExtraction, &p_FmPcdCcNode->ccKeySizeAccExtraction);
+
+ if(p_FmPcdCcNode->lclMask)
+ size = 2 * p_FmPcdCcNode->ccKeySizeAccExtraction;
+ else
+ size = p_FmPcdCcNode->ccKeySizeAccExtraction;
+
+ if(isKeyTblAlloc)
+ {
+ p_FmPcdCcNode->h_KeysMatchTable =(t_Handle)FM_MURAM_AllocMem(FmPcdGetMuramHandle(p_FmPcdCcNode->h_FmPcd),
+ (uint32_t)(size * sizeof(uint8_t) * (p_FmPcdCcNode->numOfKeys + 1)),
+ FM_PCD_CC_KEYS_MATCH_TABLE_ALIGN);
+ if(!p_FmPcdCcNode->h_KeysMatchTable)
+ {
+ DeleteNode(p_FmPcdCcNode);
+ REPORT_ERROR(MAJOR, E_NO_MEMORY, ("No memory in MURAM for KEY MATCH table"));
+ return NULL;
+ }
+ IOMemSet32((uint8_t *)p_FmPcdCcNode->h_KeysMatchTable, 0, size * sizeof(uint8_t) * (p_FmPcdCcNode->numOfKeys + 1));
+ }
+
+ p_FmPcdCcNode->h_AdTable = (t_Handle)FM_MURAM_AllocMem(FmPcdGetMuramHandle(p_FmPcdCcNode->h_FmPcd),
+ (uint32_t)( (p_FmPcdCcNode->numOfKeys+1) * FM_PCD_CC_AD_ENTRY_SIZE),
+ FM_PCD_CC_AD_TABLE_ALIGN);
+ if(!p_FmPcdCcNode->h_AdTable)
+ {
+ DeleteNode(p_FmPcdCcNode);
+ REPORT_ERROR(MAJOR, E_NO_MEMORY, ("No memory in MURAM for AD table "));
+ return NULL;
+ }
+ IOMemSet32((uint8_t *)p_FmPcdCcNode->h_AdTable, 0, (uint32_t)((p_FmPcdCcNode->numOfKeys+1) * FM_PCD_CC_AD_ENTRY_SIZE));
+
+ p_KeysMatchTblTmp = p_FmPcdCcNode->h_KeysMatchTable;
+ p_AdTableTmp = p_FmPcdCcNode->h_AdTable;
+ for(tmp = 0 ; tmp < p_FmPcdCcNode->numOfKeys; tmp++)
+ {
+ p_KeyParams = &p_CcNodeParam->keysParams.keyParams[tmp];
+
+ if(p_KeysMatchTblTmp)
+ {
+ Mem2IOCpy32((void*)p_KeysMatchTblTmp, p_KeyParams->p_Key, p_FmPcdCcNode->sizeOfExtraction);
+
+ if(p_FmPcdCcNode->lclMask && p_KeyParams->p_Mask)
+ Mem2IOCpy32(PTR_MOVE(p_KeysMatchTblTmp, p_FmPcdCcNode->ccKeySizeAccExtraction), p_KeyParams->p_Mask, p_FmPcdCcNode->sizeOfExtraction);
+ else if(p_FmPcdCcNode->lclMask)
+ IOMemSet32(PTR_MOVE(p_KeysMatchTblTmp, p_FmPcdCcNode->ccKeySizeAccExtraction), 0xff, p_FmPcdCcNode->sizeOfExtraction);
+ p_KeysMatchTblTmp = PTR_MOVE(p_KeysMatchTblTmp, size * sizeof(uint8_t));
+ }
+ NextStepAd(p_AdTableTmp,&p_KeyParams->ccNextEngineParams, p_FmPcd);
+
+ p_AdTableTmp = PTR_MOVE(p_AdTableTmp, FM_PCD_CC_AD_ENTRY_SIZE);
+
+ }
+ NextStepAd(p_AdTableTmp,&p_CcNodeParam->keysParams.ccNextEngineParamsForMiss, p_FmPcd);
+
+ if(fullField == TRUE)
+ p_FmPcdCcNode->sizeOfExtraction = 0;
+
+
+ for(tmp = 0; tmp < p_FmPcdCcNode->numOfKeys + 1; tmp++)
+ {
+ if(p_FmPcdCcNode->nextEngineAndRequiredAction[tmp].nextEngineParams.nextEngine == e_FM_PCD_CC)
+ {
+ p_FmPcdCcNextNode = (t_FmPcdCcNode*)p_FmPcdCcNode->nextEngineAndRequiredAction[tmp].nextEngineParams.params.ccParams.h_CcNode;
+
+ if(!IsNodeInModifiedState((t_Handle)p_FmPcdCcNextNode))
+ {
+ memset(&ccNodeInfo, 0, sizeof(t_CcNodeInformation));
+ ccNodeInfo.h_CcNode = (t_Handle)p_FmPcdCcNode;
+ ccNodeInfo.index = 1;
+ EnqueueNodeInfoToRelevantLst(&p_FmPcdCcNextNode->ccPrevNodesLst, &ccNodeInfo);
+ UpdateNodeWithModifiedState((t_Handle)p_FmPcdCcNextNode, TRUE);
+ }
+ else
+ {
+ p_CcInformation = FindNodeInfoInReleventLst(&p_FmPcdCcNextNode->ccPrevNodesLst,(t_Handle)p_FmPcdCcNode);
+ ASSERT_COND(p_CcInformation);
+ p_CcInformation->index++;
+ }
+ }
+
+ }
+
+ for(tmp = 0; tmp < p_FmPcdCcNode->numOfKeys + 1; tmp++)
+ {
+ if(p_FmPcdCcNode->nextEngineAndRequiredAction[tmp].nextEngineParams.nextEngine == e_FM_PCD_CC)
+ {
+ p_FmPcdCcNextNode = (t_FmPcdCcNode*)p_FmPcdCcNode->nextEngineAndRequiredAction[tmp].nextEngineParams.params.ccParams.h_CcNode;
+
+ if(IsNodeInModifiedState((t_Handle)p_FmPcdCcNextNode))
+ UpdateNodeWithModifiedState((t_Handle)p_FmPcdCcNextNode, FALSE);
+ }
+ }
+
+ p_AdTableTmp = p_FmPcdCcNode->h_AdTable;
+ for(tmp = 0; tmp < p_FmPcdCcNode->numOfKeys; tmp++)
+ {
+ if(p_FmPcdCcNode->nextEngineAndRequiredAction[tmp].requiredAction)
+ {
+
+ err = FmPcdCcSetRequiredAction(h_FmPcd, p_FmPcdCcNode->nextEngineAndRequiredAction[tmp].requiredAction, &p_FmPcdCcNode->nextEngineAndRequiredAction[tmp], p_AdTableTmp,1, NULL);
+ if(err)
+ {
+ FM_PCD_CcDeleteNode(h_FmPcd, (t_Handle)p_FmPcdCcNode);
+ REPORT_ERROR(MAJOR, err, NO_MSG);
+ return NULL;
+ }
+ p_AdTableTmp = PTR_MOVE(p_AdTableTmp, FM_PCD_CC_AD_ENTRY_SIZE);
+ }
+ }
+ if(p_FmPcdCcNode->nextEngineAndRequiredAction[tmp].requiredAction)
+ {
+ err = FmPcdCcSetRequiredAction(h_FmPcd, p_FmPcdCcNode->nextEngineAndRequiredAction[tmp].requiredAction, &p_FmPcdCcNode->nextEngineAndRequiredAction[tmp], p_AdTableTmp,1, NULL);
+ if(err)
+ {
+ FM_PCD_CcDeleteNode(h_FmPcd, (t_Handle)p_FmPcdCcNode);
+ REPORT_ERROR(MAJOR, err, NO_MSG);
+ return NULL;
+ }
+
+ }
+
+
+ return p_FmPcdCcNode;
+}
+
+t_Error FM_PCD_CcDeleteNode(t_Handle h_FmPcd, t_Handle h_CcNode)
+{
+ t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode;
+ int i = 0;
+
+ SANITY_CHECK_RETURN_ERROR(h_FmPcd, E_INVALID_HANDLE);
+
+ UNUSED(h_FmPcd);
+ if(!p_CcNode)
+ RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("the node with this ID is not initialized"));
+
+ if(p_CcNode->owners)
+ RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("the node with this ID can not be removed because this node is occupied, first - unbind this node"));
+
+ for(i = 0; i < p_CcNode->numOfKeys; i++)
+ {
+ if(p_CcNode->nextEngineAndRequiredAction[i].nextEngineParams.nextEngine == e_FM_PCD_CC)
+ UpdateNodeOwner(p_CcNode->nextEngineAndRequiredAction[i].nextEngineParams.params.ccParams.h_CcNode, FALSE);
+
+ }
+ if(p_CcNode->nextEngineAndRequiredAction[i].nextEngineParams.nextEngine == e_FM_PCD_CC)
+ UpdateNodeOwner(p_CcNode->nextEngineAndRequiredAction[i].nextEngineParams.params.ccParams.h_CcNode, FALSE);
+
+#ifdef FM_PCD_CC_MANIP
+ for(i = 0; i < p_CcNode->numOfKeys; i++)
+ {
+ if(p_CcNode->nextEngineAndRequiredAction[i].nextEngineParams.h_Manip)
+ FmPcdManipUpdateOwner(p_CcNode->nextEngineAndRequiredAction[i].nextEngineParams.h_Manip, FALSE);
+ }
+ if(p_CcNode->nextEngineAndRequiredAction[i].nextEngineParams.h_Manip)
+ FmPcdManipUpdateOwner(p_CcNode->nextEngineAndRequiredAction[i].nextEngineParams.h_Manip, FALSE);
+#endif /* FM_PCD_CC_MANIP */
+
+ DeleteNode(p_CcNode);
+
+ return E_OK;
+}
+
+t_Error FM_PCD_CcNodeAddKey(t_Handle h_FmPcd, t_Handle h_CcNode, uint8_t keyIndex, uint8_t keySize, t_FmPcdCcKeyParams *p_KeyParams)
+{
+ t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
+
+ SANITY_CHECK_RETURN_ERROR(h_FmPcd, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_FmPcd->h_Hc, E_INVALID_HANDLE);
+
+ return FmHcPcdCcAddKey(p_FmPcd->h_Hc, h_CcNode, keyIndex, keySize, p_KeyParams);
+}
+
+t_Error FM_PCD_CcNodeRemoveKey(t_Handle h_FmPcd, t_Handle h_CcNode, uint8_t keyIndex)
+{
+ t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
+
+ SANITY_CHECK_RETURN_ERROR(h_FmPcd, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_FmPcd->h_Hc, E_INVALID_HANDLE);
+
+ return FmHcPcdCcRemoveKey(p_FmPcd->h_Hc, h_CcNode, keyIndex);
+}
+
+t_Error FM_PCD_CcNodeModifyKey(t_Handle h_FmPcd, t_Handle h_CcNode, uint8_t keyIndex, uint8_t keySize, uint8_t *p_Key, uint8_t *p_Mask)
+{
+ t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
+
+ SANITY_CHECK_RETURN_ERROR(h_FmPcd, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_FmPcd->h_Hc, E_INVALID_HANDLE);
+
+ return FmHcPcdCcModifyKey(p_FmPcd->h_Hc, h_CcNode, keyIndex, keySize, p_Key, p_Mask);
+}
+
+t_Error FM_PCD_CcNodeModifyNextEngine(t_Handle h_FmPcd, t_Handle h_CcNode, uint8_t keyIndex, t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams)
+{
+ t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
+
+ SANITY_CHECK_RETURN_ERROR(h_FmPcd, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_FmPcd->h_Hc, E_INVALID_HANDLE);
+
+ return FmHcPcdCcModifyNodeNextEngine(p_FmPcd->h_Hc, h_CcNode, keyIndex, p_FmPcdCcNextEngineParams);
+}
+
+t_Error FM_PCD_CcNodeModifyMissNextEngine(t_Handle h_FmPcd, t_Handle h_CcNode, t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams)
+{
+ t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
+
+ SANITY_CHECK_RETURN_ERROR(h_FmPcd, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_FmPcd->h_Hc, E_INVALID_HANDLE);
+
+ return FmHcPcdCcModifyNodeMissNextEngine(p_FmPcd->h_Hc, h_CcNode, p_FmPcdCcNextEngineParams);
+}
+
+t_Error FM_PCD_CcTreeModifyNextEngine(t_Handle h_FmPcd, t_Handle h_CcTree, uint8_t grpId, uint8_t index, t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams)
+{
+ t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
+
+ SANITY_CHECK_RETURN_ERROR(h_FmPcd, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_FmPcd->h_Hc, E_INVALID_HANDLE);
+
+ return FmHcPcdCcModifyTreeNextEngine(p_FmPcd->h_Hc, h_CcTree, grpId, index, p_FmPcdCcNextEngineParams);
+}
+
+t_Error FM_PCD_CcNodeModifyKeyAndNextEngine(t_Handle h_FmPcd, t_Handle h_CcNode, uint8_t keyIndex, uint8_t keySize, t_FmPcdCcKeyParams *p_KeyParams)
+{
+ t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
+
+ SANITY_CHECK_RETURN_ERROR(h_FmPcd, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_FmPcd->h_Hc, E_INVALID_HANDLE);
+
+ return FmHcPcdCcModifyKeyAndNextEngine(p_FmPcd->h_Hc, h_CcNode, keyIndex, keySize, p_KeyParams);
+}
+
+uint32_t FM_PCD_CcNodeGetKeyCounter(t_Handle h_FmPcd, t_Handle h_CcNode, uint8_t keyIndex)
+{
+ t_FmPcdCcNode *p_FmPcdCcNode = (t_FmPcdCcNode *)h_CcNode;
+ t_AdOfTypeResult *p_AdResult = NULL;
+
+ SANITY_CHECK_RETURN_ERROR(h_FmPcd, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_VALUE(h_CcNode, E_INVALID_HANDLE, 0);
+#ifdef DISABLE_SANITY_CHECKS
+UNUSED(h_FmPcd);
+#endif /* DISABLE_SANITY_CHECKS */
+
+ if (keyIndex >= p_FmPcdCcNode->numOfKeys)
+ {
+ REPORT_ERROR(MINOR, E_INVALID_STATE,
+ ("keyIndex > numOfKeys defined for this node"));
+ return 0;
+ }
+
+ p_AdResult = PTR_MOVE(p_FmPcdCcNode->h_AdTable, keyIndex*FM_PCD_CC_AD_ENTRY_SIZE);
+ ASSERT_COND(p_AdResult);
+
+ if (p_FmPcdCcNode->nextEngineAndRequiredAction[keyIndex].nextEngineParams.nextEngine == e_FM_PCD_CC)
+ {
+ REPORT_ERROR(MINOR, E_INVALID_STATE,
+ ("statistics updated only for entries where next engine not CC"));
+ return 0;
+ }
+
+ if(((p_FmPcdCcNode->nextEngineAndRequiredAction[keyIndex].nextEngineParams.nextEngine == e_FM_PCD_DONE) &&
+ !p_FmPcdCcNode->nextEngineAndRequiredAction[keyIndex].nextEngineParams.params.enqueueParams.statisticsEn) ||
+ ((p_FmPcdCcNode->nextEngineAndRequiredAction[keyIndex].nextEngineParams.nextEngine == e_FM_PCD_KG) &&
+ !p_FmPcdCcNode->nextEngineAndRequiredAction[keyIndex].nextEngineParams.params.kgParams.statisticsEn) ||
+ ((p_FmPcdCcNode->nextEngineAndRequiredAction[keyIndex].nextEngineParams.nextEngine == e_FM_PCD_PLCR) &&
+ !p_FmPcdCcNode->nextEngineAndRequiredAction[keyIndex].nextEngineParams.params.plcrParams.statisticsEn))
+ {
+ REPORT_ERROR(MINOR, E_INVALID_STATE,
+ ("statistics wasn't enable"));
+ return 0;
+ }
+
+ return GET_UINT32(p_AdResult->res);
+}
OpenPOWER on IntegriCloud