/* 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<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(¶ms[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,¶ms[i].nextEngineParams,p_FmPcd); p_CcTreeTmp = PTR_MOVE(p_CcTreeTmp, FM_PCD_CC_AD_ENTRY_SIZE); memcpy(&p_FmPcdCcTree->nextEngineAndRequiredAction[i], ¶ms[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 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); }