diff options
author | J. German Rivera <Jose.G.Rivera@freescale.com> | 2013-08-27 19:19:56 (GMT) |
---|---|---|
committer | J. German Rivera <German.Rivera@freescale.com> | 2013-08-27 19:19:56 (GMT) |
commit | a133e4d9e7412890f61a978a24f80fc085b4eca5 (patch) | |
tree | 560a7268eb1d72b32a30c6875f2317697da612aa /drivers/net/ethernet/freescale/fman | |
parent | a4460591eff829d4805dfe2bdf43c041899ad4f2 (diff) | |
parent | 0ec09b835c42ccdd05745ecb3f086df57f9b50b9 (diff) | |
download | linux-fsl-qoriq-a133e4d9e7412890f61a978a24f80fc085b4eca5.tar.xz |
Merge branch 'sdk-v1.4.x' into sdk-kernel-3.8
Diffstat (limited to 'drivers/net/ethernet/freescale/fman')
8 files changed, 830 insertions, 438 deletions
diff --git a/drivers/net/ethernet/freescale/fman/Peripherals/FM/Pcd/fm_cc.c b/drivers/net/ethernet/freescale/fman/Peripherals/FM/Pcd/fm_cc.c index a68ff12..a8a52b2 100644 --- a/drivers/net/ethernet/freescale/fman/Peripherals/FM/Pcd/fm_cc.c +++ b/drivers/net/ethernet/freescale/fman/Peripherals/FM/Pcd/fm_cc.c @@ -1192,6 +1192,10 @@ static void DeleteNode(t_FmPcdCcNode *p_CcNode) p_CcNode->h_Spinlock = NULL; } + /* Restore the original counters pointer instead of the mutual pointer (mutual to all hash buckets) */ + if (p_CcNode->isHashBucket && (p_CcNode->statisticsMode != e_FM_PCD_CC_STATS_MODE_NONE)) + p_CcNode->keyAndNextEngineParams[p_CcNode->numOfKeys].p_StatsObj->h_StatsCounters = p_CcNode->h_PrivMissStatsCounters; + /* Releasing all currently used statistics objects, including 'miss' entry */ for (i = 0; i < p_CcNode->numOfKeys + 1; i++) if (p_CcNode->keyAndNextEngineParams[i].p_StatsObj) @@ -1200,7 +1204,6 @@ static void DeleteNode(t_FmPcdCcNode *p_CcNode) if (!LIST_IsEmpty(&p_CcNode->availableStatsLst)) { t_Handle h_FmMuram = FmPcdGetMuramHandle(p_CcNode->h_FmPcd); - ASSERT_COND(h_FmMuram); FreeStatObjects(&p_CcNode->availableStatsLst, h_FmMuram); @@ -1490,7 +1493,7 @@ t_Error ValidateNextEngineParams(t_Handle h_FmPcd, (p_FmPcdCcNextEngineParams->statisticsEn)) RETURN_ERROR(MAJOR, E_CONFLICT, ("Statistics are requested for a key, but statistics mode was set" - "to 'NONE' upon initialization of this match table")); + "to 'NONE' upon initialization")); switch (p_FmPcdCcNextEngineParams->nextEngine) { @@ -3397,13 +3400,18 @@ static t_Error ValidateAndCalcStatsParams(t_FmPcdCcNode *p_CcNode, uint32_t *p_NumOfRanges, uint32_t *p_CountersArraySize) { - e_FmPcdCcStatsMode statisticsMode = p_CcNode->statisticsMode; + e_FmPcdCcStatsMode statisticsMode = p_CcNode->statisticsMode; + uint32_t i; UNUSED(p_CcNodeParam); switch (statisticsMode) { case e_FM_PCD_CC_STATS_MODE_NONE: + for (i = 0; i < p_CcNode->numOfKeys; i++) + if (p_CcNodeParam->keysParams.keyParams[i].ccNextEngineParams.statisticsEn) + RETURN_ERROR(MAJOR, E_INVALID_VALUE, + ("Statistics cannot be enabled for key %d when statistics mode was set to 'NONE'", i)); return E_OK; case e_FM_PCD_CC_STATS_MODE_FRAME: @@ -3983,9 +3991,6 @@ static t_Error MatchTableGetKeyStatistics(t_FmPcdCcNode *p_CcNode, if (p_CcNode->statisticsMode == e_FM_PCD_CC_STATS_MODE_NONE) RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Statistics were not enabled for this match table")); - if (keyIndex >= p_CcNode->numOfKeys) - RETURN_ERROR(MAJOR, E_INVALID_STATE, ("The provided keyIndex exceeds the number of keys in this match table")); - if (!p_CcNode->keyAndNextEngineParams[keyIndex].p_StatsObj) RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Statistics were not enabled for this key")); @@ -5014,377 +5019,11 @@ void FmPcdCcGetAdTablesThatPointOnReplicGroup(t_Handle h_Node, ASSERT_COND(i != p_CurrentNode->numOfKeys); } #endif /* (DPAA_VERSION >= 11) */ -/*********************** End of inter-module routines ************************/ - -/****************************************/ -/* API Init unit functions */ -/****************************************/ - -t_Handle FM_PCD_CcRootBuild(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_FmPcdCcKeyAndNextEngineParams *p_Params, *p_KeyAndNextEngineParams; - 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)); - p_FmPcdCcTree->h_FmPcd = h_FmPcd; - - p_Params = (t_FmPcdCcKeyAndNextEngineParams*)XX_Malloc(FM_PCD_MAX_NUM_OF_CC_GROUPS * sizeof(t_FmPcdCcKeyAndNextEngineParams)); - memset(p_Params, 0, FM_PCD_MAX_NUM_OF_CC_GROUPS * sizeof(t_FmPcdCcKeyAndNextEngineParams)); - - INIT_LIST(&p_FmPcdCcTree->fmPortsLst); - -#ifdef FM_CAPWAP_SUPPORT - if ((p_PcdGroupsParam->numOfGrps == 1) && - (p_PcdGroupsParam->ccGrpParams[0].numOfDistinctionUnits == 0) && - (p_PcdGroupsParam->ccGrpParams[0].nextEnginePerEntriesInGrp[0].nextEngine == e_FM_PCD_CC) && - p_PcdGroupsParam->ccGrpParams[0].nextEnginePerEntriesInGrp[0].params.ccParams.h_CcNode && - IsCapwapApplSpecific(p_PcdGroupsParam->ccGrpParams[0].nextEnginePerEntriesInGrp[0].params.ccParams.h_CcNode)) - { - p_PcdGroupsParam->ccGrpParams[0].nextEnginePerEntriesInGrp[0].h_Manip = FmPcdManipApplSpecificBuild(); - if (!p_PcdGroupsParam->ccGrpParams[0].nextEnginePerEntriesInGrp[0].h_Manip) - { - DeleteTree(p_FmPcdCcTree,p_FmPcd); - XX_Free(p_Params); - REPORT_ERROR(MAJOR, E_INVALID_STATE, NO_MSG); - return NULL; - } - } -#endif /* FM_CAPWAP_SUPPORT */ - - numOfEntries = 0; - p_FmPcdCcTree->netEnvId = FmPcdGetNetEnvId(p_PcdGroupsParam->h_NetEnv); - - 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); - XX_Free(p_Params); - 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 > FM_PCD_MAX_NUM_OF_CC_GROUPS) - { - DeleteTree(p_FmPcdCcTree,p_FmPcd); - XX_Free(p_Params); - REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("numOfEntries can not be larger than %d", FM_PCD_MAX_NUM_OF_CC_GROUPS)); - return NULL; - } - - if (lastOne) - { - if (p_FmPcdCcTree->fmPcdGroupParam[i].numOfEntriesInGroup > lastOne) - { - DeleteTree(p_FmPcdCcTree,p_FmPcd); - XX_Free(p_Params); - 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); - XX_Free(p_Params); - 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], - e_FM_PCD_CC_STATS_MODE_NONE); - if (err) - { - DeleteTree(p_FmPcdCcTree,p_FmPcd); - XX_Free(p_Params); - REPORT_ERROR(MAJOR, err, (NO_MSG)); - return NULL; - } - - if (p_FmPcdCcGroupParams->nextEnginePerEntriesInGrp[j].h_Manip) - { - err = FmPcdManipCheckParamsForCcNextEngine(&p_FmPcdCcGroupParams->nextEnginePerEntriesInGrp[j], &requiredAction); - if (err) - { - DeleteTree(p_FmPcdCcTree,p_FmPcd); - XX_Free(p_Params); - REPORT_ERROR(MAJOR, E_INVALID_STATE, NO_MSG); - return NULL; - } - } - p_KeyAndNextEngineParams = p_Params+k; - - memcpy(&p_KeyAndNextEngineParams->nextEngineParams, - &p_FmPcdCcGroupParams->nextEnginePerEntriesInGrp[j], - sizeof(t_FmPcdCcNextEngineParams)); - - if ((p_KeyAndNextEngineParams->nextEngineParams.nextEngine == e_FM_PCD_CC) - && p_KeyAndNextEngineParams->nextEngineParams.h_Manip) - { - err = AllocAndFillAdForContLookupManip(p_KeyAndNextEngineParams->nextEngineParams.params.ccParams.h_CcNode); - if (err) - { - DeleteTree(p_FmPcdCcTree,p_FmPcd); - XX_Free(p_Params); - REPORT_ERROR(MAJOR, E_NO_MEMORY, ("MURAM allocation for CC Tree")); - return NULL; - } - } - - requiredAction |= UPDATE_CC_WITH_TREE; - p_KeyAndNextEngineParams->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)( FM_PCD_MAX_NUM_OF_CC_GROUPS * FM_PCD_CC_AD_ENTRY_SIZE), - FM_PCD_CC_TREE_ADDR_ALIGN)); - if (!p_FmPcdCcTree->ccTreeBaseAddr) - { - DeleteTree(p_FmPcdCcTree,p_FmPcd); - XX_Free(p_Params); - REPORT_ERROR(MAJOR, E_NO_MEMORY, ("MURAM allocation for CC Tree")); - return NULL; - } - IOMemSet32(UINT_TO_PTR(p_FmPcdCcTree->ccTreeBaseAddr), 0, (uint32_t)(FM_PCD_MAX_NUM_OF_CC_GROUPS * FM_PCD_CC_AD_ENTRY_SIZE)); - - p_CcTreeTmp = UINT_TO_PTR(p_FmPcdCcTree->ccTreeBaseAddr); - - j = 0; - for (i = 0; i < numOfEntries; i++) - { - p_KeyAndNextEngineParams = p_Params + i; - - NextStepAd(p_CcTreeTmp, - NULL, - &p_KeyAndNextEngineParams->nextEngineParams, - p_FmPcd); - - p_CcTreeTmp = PTR_MOVE(p_CcTreeTmp, FM_PCD_CC_AD_ENTRY_SIZE); - - memcpy(&p_FmPcdCcTree->keyAndNextEngineParams[i], - p_KeyAndNextEngineParams, - sizeof(t_FmPcdCcKeyAndNextEngineParams)); - - if (p_FmPcdCcTree->keyAndNextEngineParams[i].nextEngineParams.nextEngine== e_FM_PCD_CC) - { - p_FmPcdCcNextNode = (t_FmPcdCcNode*)p_FmPcdCcTree->keyAndNextEngineParams[i].nextEngineParams.params.ccParams.h_CcNode; - p_CcInformation = FindNodeInfoInReleventLst(&p_FmPcdCcNextNode->ccTreeIdLst, - (t_Handle)p_FmPcdCcTree, - p_FmPcdCcNextNode->h_Spinlock); - - if (!p_CcInformation) - { - memset(&ccNodeInfo, 0, sizeof(t_CcNodeInformation)); - ccNodeInfo.h_CcNode = (t_Handle)p_FmPcdCcTree; - ccNodeInfo.index = 1; - EnqueueNodeInfoToRelevantLst(&p_FmPcdCcNextNode->ccTreeIdLst, - &ccNodeInfo, - p_FmPcdCcNextNode->h_Spinlock); - } - else - p_CcInformation->index++; - } - } - - FmPcdIncNetEnvOwners(h_FmPcd, p_FmPcdCcTree->netEnvId); - p_CcTreeTmp = UINT_TO_PTR(p_FmPcdCcTree->ccTreeBaseAddr); - - if (!FmPcdLockTryLockAll(p_FmPcd)) - { - FM_PCD_CcRootDelete(p_FmPcdCcTree); - XX_Free(p_Params); - DBG(TRACE, ("FmPcdLockTryLockAll failed")); - return NULL; - } - - for (i = 0; i < numOfEntries; i++) - { - if (p_FmPcdCcTree->keyAndNextEngineParams[i].requiredAction) - { - err = SetRequiredAction(h_FmPcd, - p_FmPcdCcTree->keyAndNextEngineParams[i].requiredAction, - &p_FmPcdCcTree->keyAndNextEngineParams[i], - p_CcTreeTmp, - 1, - p_FmPcdCcTree); - if (err) - { - FmPcdLockUnlockAll(p_FmPcd); - FM_PCD_CcRootDelete(p_FmPcdCcTree); - XX_Free(p_Params); - REPORT_ERROR(MAJOR, E_NO_MEMORY, ("No memory")); - return NULL; - } - p_CcTreeTmp = PTR_MOVE(p_CcTreeTmp, FM_PCD_CC_AD_ENTRY_SIZE); - } - } - - FmPcdLockUnlockAll(p_FmPcd); - p_FmPcdCcTree->p_Lock = FmPcdAcquireLock(p_FmPcd); - if (!p_FmPcdCcTree->p_Lock) - { - FM_PCD_CcRootDelete(p_FmPcdCcTree); - XX_Free(p_Params); - REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM CC lock")); - return NULL; - } - - XX_Free(p_Params); - - return p_FmPcdCcTree; -} - -t_Error FM_PCD_CcRootDelete(t_Handle h_CcTree) -{ - t_FmPcd *p_FmPcd; - t_FmPcdCcTree *p_CcTree = (t_FmPcdCcTree *)h_CcTree; - int i= 0; - - SANITY_CHECK_RETURN_ERROR(p_CcTree,E_INVALID_STATE); - p_FmPcd = (t_FmPcd *)p_CcTree->h_FmPcd; - SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE); - - FmPcdDecNetEnvOwners(p_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")); - - /* Delete reassembly schemes if exist */ - if (p_CcTree->h_IpReassemblyManip) - { - FmPcdManipDeleteIpReassmSchemes(p_CcTree->h_IpReassemblyManip); - FmPcdManipUpdateOwner(p_CcTree->h_IpReassemblyManip, FALSE); - } - - for (i = 0; i <p_CcTree->numOfEntries; i++) - { - if (p_CcTree->keyAndNextEngineParams[i].nextEngineParams.nextEngine == e_FM_PCD_CC) - UpdateNodeOwner(p_CcTree->keyAndNextEngineParams[i].nextEngineParams.params.ccParams.h_CcNode, FALSE); - - if (p_CcTree->keyAndNextEngineParams[i].nextEngineParams.h_Manip) - FmPcdManipUpdateOwner(p_CcTree->keyAndNextEngineParams[i].nextEngineParams.h_Manip, FALSE); - -#ifdef FM_CAPWAP_SUPPORT - if ((p_CcTree->numOfGrps == 1) && - (p_CcTree->fmPcdGroupParam[0].numOfEntriesInGroup == 1) && - (p_CcTree->keyAndNextEngineParams[0].nextEngineParams.nextEngine == e_FM_PCD_CC) && - p_CcTree->keyAndNextEngineParams[0].nextEngineParams.params.ccParams.h_CcNode && - IsCapwapApplSpecific(p_CcTree->keyAndNextEngineParams[0].nextEngineParams.params.ccParams.h_CcNode)) - { - if (FM_PCD_ManipNodeDelete(p_CcTree->keyAndNextEngineParams[0].nextEngineParams.h_Manip) != E_OK) - return E_INVALID_STATE; - } -#endif /* FM_CAPWAP_SUPPORT */ - -#if (DPAA_VERSION >= 11) - if ((p_CcTree->keyAndNextEngineParams[i].nextEngineParams.nextEngine == e_FM_PCD_FR) && - (p_CcTree->keyAndNextEngineParams[i].nextEngineParams.params.frParams.h_FrmReplic)) - FrmReplicGroupUpdateOwner(p_CcTree->keyAndNextEngineParams[i].nextEngineParams.params.frParams.h_FrmReplic, - FALSE); -#endif /* (DPAA_VERSION >= 11) */ - } - - if (p_CcTree->p_Lock) - FmPcdReleaseLock(p_CcTree->h_FmPcd, p_CcTree->p_Lock); - - DeleteTree(p_CcTree, p_FmPcd); - - return E_OK; -} - -t_Error FM_PCD_CcRootModifyNextEngine(t_Handle h_CcTree, - uint8_t grpId, - uint8_t index, - t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams) -{ - t_FmPcd *p_FmPcd; - t_FmPcdCcTree *p_CcTree = (t_FmPcdCcTree *)h_CcTree; - t_Error err = E_OK; - - SANITY_CHECK_RETURN_ERROR(p_FmPcdCcNextEngineParams, E_NULL_POINTER); - SANITY_CHECK_RETURN_ERROR(p_CcTree,E_INVALID_STATE); - p_FmPcd = (t_FmPcd *)p_CcTree->h_FmPcd; - SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE); - - if (!FmPcdLockTryLockAll(p_FmPcd)) - { - DBG(TRACE, ("FmPcdLockTryLockAll failed")); - return ERROR_CODE(E_BUSY); - } - - err = FmPcdCcModifyNextEngineParamTree(p_FmPcd, - p_CcTree, - grpId, - index, - p_FmPcdCcNextEngineParams); - FmPcdLockUnlockAll(p_FmPcd); - - if (err) - { - RETURN_ERROR(MAJOR, err, NO_MSG); - } - - return E_OK; -} - -t_Handle FM_PCD_MatchTableSet(t_Handle h_FmPcd, t_FmPcdCcNodeParams *p_CcNodeParam) +t_Error FmPcdCcMatchTableSet(t_Handle h_FmPcd, t_FmPcdCcNode *p_CcNode, t_FmPcdCcNodeParams *p_CcNodeParam) { t_FmPcd *p_FmPcd = (t_FmPcd *) h_FmPcd; - t_FmPcdCcNode *p_CcNode, *p_FmPcdCcNextNode; + t_FmPcdCcNode *p_FmPcdCcNextNode; t_Error err = E_OK; uint32_t tmp, keySize; bool glblMask = FALSE; @@ -5402,15 +5041,9 @@ t_Handle FM_PCD_MatchTableSet(t_Handle h_FmPcd, t_FmPcdCcNodeParams *p_CcNodePar t_FmPcdCcStatsParams statsParams = {0}; t_Handle h_Manip; - SANITY_CHECK_RETURN_VALUE(h_FmPcd,E_INVALID_HANDLE,NULL); - - p_CcNode = (t_FmPcdCcNode*)XX_Malloc(sizeof(t_FmPcdCcNode)); - if (!p_CcNode) - { - REPORT_ERROR(MAJOR, E_NO_MEMORY, ("No memory")); - return NULL; - } - memset(p_CcNode, 0, sizeof(t_FmPcdCcNode)); + ASSERT_COND(h_FmPcd); + ASSERT_COND(p_CcNode); + ASSERT_COND(p_CcNodeParam); p_CcNode->p_GlblMask = (t_Handle)XX_Malloc(CC_GLBL_MASK_SIZE * sizeof(uint8_t)); memset(p_CcNode->p_GlblMask, 0, CC_GLBL_MASK_SIZE * sizeof(uint8_t)); @@ -5430,10 +5063,7 @@ t_Handle FM_PCD_MatchTableSet(t_Handle h_FmPcd, t_FmPcdCcNodeParams *p_CcNodePar h_FmMuram = FmPcdGetMuramHandle(h_FmPcd); if (!h_FmMuram) - { - REPORT_ERROR(MAJOR, E_INVALID_HANDLE, ("FM MURAM")); - return NULL; - } + RETURN_ERROR(MAJOR, E_INVALID_HANDLE, ("FM MURAM")); INIT_LIST(&p_CcNode->ccPrevNodesLst); INIT_LIST(&p_CcNode->ccTreeIdLst); @@ -5444,8 +5074,7 @@ t_Handle FM_PCD_MatchTableSet(t_Handle h_FmPcd, t_FmPcdCcNodeParams *p_CcNodePar if (!p_CcNode->h_Spinlock) { DeleteNode(p_CcNode); - REPORT_ERROR(MAJOR, E_NO_MEMORY, ("CC node spinlock")); - return NULL; + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("CC node spinlock")); } if ((p_CcNodeParam->extractCcParams.type == e_FM_PCD_EXTRACT_BY_HDR) && @@ -5466,18 +5095,18 @@ t_Handle FM_PCD_MatchTableSet(t_Handle h_FmPcd, t_FmPcdCcNodeParams *p_CcNodePar 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, + DeleteNode(p_CcNode); + RETURN_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, + DeleteNode(p_CcNode); + RETURN_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) || @@ -5503,8 +5132,7 @@ t_Handle FM_PCD_MatchTableSet(t_Handle h_FmPcd, t_FmPcdCcNodeParams *p_CcNodePar if (err) { DeleteNode(p_CcNode); - REPORT_ERROR(MAJOR, err, NO_MSG); - return NULL; + RETURN_ERROR(MAJOR, err, NO_MSG); } switch (p_CcNodeParam->extractCcParams.type) @@ -5564,8 +5192,7 @@ t_Handle FM_PCD_MatchTableSet(t_Handle h_FmPcd, t_FmPcdCcNodeParams *p_CcNodePar default: DeleteNode(p_CcNode); - REPORT_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG); - return NULL; + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG); } break; @@ -5587,8 +5214,7 @@ t_Handle FM_PCD_MatchTableSet(t_Handle h_FmPcd, t_FmPcdCcNodeParams *p_CcNodePar if ((p_CcNode->offset + p_CcNode->sizeOfExtraction) > 8) { DeleteNode(p_CcNode); - 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; + RETURN_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)")); } } if ((p_CcNode->parseCode == CC_PC_GENERIC_IC_GMASK) || @@ -5601,30 +5227,26 @@ t_Handle FM_PCD_MatchTableSet(t_Handle h_FmPcd, t_FmPcdCcNodeParams *p_CcNodePar default: DeleteNode(p_CcNode); - REPORT_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG); - return NULL; + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG); } if (p_CcNode->parseCode == CC_PC_ILLEGAL) { DeleteNode(p_CcNode); - REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("illegal extraction type")); - return NULL; + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("illegal extraction type")); } if ((p_CcNode->sizeOfExtraction > FM_PCD_MAX_SIZE_OF_KEY) || !p_CcNode->sizeOfExtraction) { DeleteNode(p_CcNode); - REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("sizeOfExatrction can not be greater than 56 and not 0")); - return NULL; + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("sizeOfExatrction can not be greater than 56 and not 0")); } if (p_CcNodeParam->keysParams.keySize != p_CcNode->sizeOfExtraction) { DeleteNode(p_CcNode); - REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("keySize has to be equal to sizeOfExtraction")); - return NULL; + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("keySize has to be equal to sizeOfExtraction")); } p_CcNode->userSizeOfExtraction = p_CcNode->sizeOfExtraction; @@ -5636,8 +5258,7 @@ t_Handle FM_PCD_MatchTableSet(t_Handle h_FmPcd, t_FmPcdCcNodeParams *p_CcNodePar if (err != E_OK) { DeleteNode(p_CcNode); - REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("keySize has to be equal to sizeOfExtraction")); - return NULL; + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("keySize has to be equal to sizeOfExtraction")); } /* Calculating matching table entry size by rounding up the user-defined size of extraction to valid entry size */ @@ -5659,8 +5280,7 @@ t_Handle FM_PCD_MatchTableSet(t_Handle h_FmPcd, t_FmPcdCcNodeParams *p_CcNodePar if (err != E_OK) { DeleteNode(p_CcNode); - REPORT_ERROR(MAJOR, err, NO_MSG); - return NULL; + RETURN_ERROR(MAJOR, err, NO_MSG); } p_CcNode->keysMatchTableMaxSize = matchTableSize; @@ -5671,8 +5291,7 @@ t_Handle FM_PCD_MatchTableSet(t_Handle h_FmPcd, t_FmPcdCcNodeParams *p_CcNodePar if (err != E_OK) { DeleteNode(p_CcNode); - REPORT_ERROR(MAJOR, err, NO_MSG); - return NULL; + RETURN_ERROR(MAJOR, err, NO_MSG); } } @@ -5685,8 +5304,7 @@ t_Handle FM_PCD_MatchTableSet(t_Handle h_FmPcd, t_FmPcdCcNodeParams *p_CcNodePar if (!p_CcNode->h_TmpAd) { DeleteNode(p_CcNode); - REPORT_ERROR(MAJOR, E_NO_MEMORY, ("MURAM allocation for CC action descriptor")); - return NULL; + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM allocation for CC action descriptor")); } } else @@ -5710,8 +5328,7 @@ t_Handle FM_PCD_MatchTableSet(t_Handle h_FmPcd, t_FmPcdCcNodeParams *p_CcNodePar if (!p_CcNode->h_StatsFLRs) { DeleteNode(p_CcNode); - REPORT_ERROR(MAJOR, E_NO_MEMORY, ("MURAM allocation for CC frame length ranges array")); - return NULL; + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM allocation for CC frame length ranges array")); } /* Initialize using value received from the user */ @@ -5742,8 +5359,7 @@ t_Handle FM_PCD_MatchTableSet(t_Handle h_FmPcd, t_FmPcdCcNodeParams *p_CcNodePar if (!p_CcNode->h_KeysMatchTable) { DeleteNode(p_CcNode); - REPORT_ERROR(MAJOR, E_NO_MEMORY, ("MURAM allocation for CC node key match table")); - return NULL; + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM allocation for CC node key match table")); } IOMemSet32((uint8_t *)p_CcNode->h_KeysMatchTable, 0, @@ -5758,8 +5374,7 @@ t_Handle FM_PCD_MatchTableSet(t_Handle h_FmPcd, t_FmPcdCcNodeParams *p_CcNodePar if (!p_CcNode->h_AdTable) { DeleteNode(p_CcNode); - REPORT_ERROR(MAJOR, E_NO_MEMORY, ("MURAM allocation for CC node action descriptors table")); - return NULL; + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM allocation for CC node action descriptors table")); } IOMemSet32((uint8_t *)p_CcNode->h_AdTable, 0, adTableSize); @@ -5833,6 +5448,18 @@ t_Handle FM_PCD_MatchTableSet(t_Handle h_FmPcd, t_FmPcdCcNodeParams *p_CcNodePar p_StatsObj = GetStatsObj(p_CcNode); ASSERT_COND(p_StatsObj); + /* All 'bucket' nodes of a hash table should share the same statistics counters, + allocated by the hash table. So, if this node is a bucket of a hash table, + we'll replace the locally allocated counters with the shared counters. */ + if (p_CcNode->isHashBucket) + { + ASSERT_COND(p_CcNode->h_MissStatsCounters); + + /* Store original counters pointer and replace it with mutual preallocated pointer */ + p_CcNode->h_PrivMissStatsCounters = p_StatsObj->h_StatsCounters; + p_StatsObj->h_StatsCounters = p_CcNode->h_MissStatsCounters; + } + statsParams.h_StatsAd = p_StatsObj->h_StatsAd; statsParams.h_StatsCounters = p_StatsObj->h_StatsCounters; #if (DPAA_VERSION >= 11) @@ -5909,7 +5536,7 @@ t_Handle FM_PCD_MatchTableSet(t_Handle h_FmPcd, t_FmPcdCcNodeParams *p_CcNodePar { FM_PCD_MatchTableDelete((t_Handle)p_CcNode); DBG(TRACE, ("FmPcdLockTryLockAll failed")); - return NULL; + return ERROR_CODE(E_BUSY); } /* Required action for each next engine */ @@ -5927,8 +5554,7 @@ t_Handle FM_PCD_MatchTableSet(t_Handle h_FmPcd, t_FmPcdCcNodeParams *p_CcNodePar { FmPcdLockUnlockAll(h_FmPcd); FM_PCD_MatchTableDelete((t_Handle)p_CcNode); - REPORT_ERROR(MAJOR, err, NO_MSG); - return NULL; + RETURN_ERROR(MAJOR, err, NO_MSG); } p_AdTableTmp = PTR_MOVE(p_AdTableTmp, FM_PCD_CC_AD_ENTRY_SIZE); } @@ -5936,6 +5562,407 @@ t_Handle FM_PCD_MatchTableSet(t_Handle h_FmPcd, t_FmPcdCcNodeParams *p_CcNodePar FmPcdLockUnlockAll(h_FmPcd); + return E_OK; +} +/*********************** End of inter-module routines ************************/ + + +/****************************************/ +/* API Init unit functions */ +/****************************************/ + +t_Handle FM_PCD_CcRootBuild(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_FmPcdCcKeyAndNextEngineParams *p_Params, *p_KeyAndNextEngineParams; + 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)); + p_FmPcdCcTree->h_FmPcd = h_FmPcd; + + p_Params = (t_FmPcdCcKeyAndNextEngineParams*)XX_Malloc(FM_PCD_MAX_NUM_OF_CC_GROUPS * sizeof(t_FmPcdCcKeyAndNextEngineParams)); + memset(p_Params, 0, FM_PCD_MAX_NUM_OF_CC_GROUPS * sizeof(t_FmPcdCcKeyAndNextEngineParams)); + + INIT_LIST(&p_FmPcdCcTree->fmPortsLst); + +#ifdef FM_CAPWAP_SUPPORT + if ((p_PcdGroupsParam->numOfGrps == 1) && + (p_PcdGroupsParam->ccGrpParams[0].numOfDistinctionUnits == 0) && + (p_PcdGroupsParam->ccGrpParams[0].nextEnginePerEntriesInGrp[0].nextEngine == e_FM_PCD_CC) && + p_PcdGroupsParam->ccGrpParams[0].nextEnginePerEntriesInGrp[0].params.ccParams.h_CcNode && + IsCapwapApplSpecific(p_PcdGroupsParam->ccGrpParams[0].nextEnginePerEntriesInGrp[0].params.ccParams.h_CcNode)) + { + p_PcdGroupsParam->ccGrpParams[0].nextEnginePerEntriesInGrp[0].h_Manip = FmPcdManipApplSpecificBuild(); + if (!p_PcdGroupsParam->ccGrpParams[0].nextEnginePerEntriesInGrp[0].h_Manip) + { + DeleteTree(p_FmPcdCcTree,p_FmPcd); + XX_Free(p_Params); + REPORT_ERROR(MAJOR, E_INVALID_STATE, NO_MSG); + return NULL; + } + } +#endif /* FM_CAPWAP_SUPPORT */ + + numOfEntries = 0; + p_FmPcdCcTree->netEnvId = FmPcdGetNetEnvId(p_PcdGroupsParam->h_NetEnv); + + 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); + XX_Free(p_Params); + 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 > FM_PCD_MAX_NUM_OF_CC_GROUPS) + { + DeleteTree(p_FmPcdCcTree,p_FmPcd); + XX_Free(p_Params); + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("numOfEntries can not be larger than %d", FM_PCD_MAX_NUM_OF_CC_GROUPS)); + return NULL; + } + + if (lastOne) + { + if (p_FmPcdCcTree->fmPcdGroupParam[i].numOfEntriesInGroup > lastOne) + { + DeleteTree(p_FmPcdCcTree,p_FmPcd); + XX_Free(p_Params); + 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); + XX_Free(p_Params); + 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], + e_FM_PCD_CC_STATS_MODE_NONE); + if (err) + { + DeleteTree(p_FmPcdCcTree,p_FmPcd); + XX_Free(p_Params); + REPORT_ERROR(MAJOR, err, (NO_MSG)); + return NULL; + } + + if (p_FmPcdCcGroupParams->nextEnginePerEntriesInGrp[j].h_Manip) + { + err = FmPcdManipCheckParamsForCcNextEngine(&p_FmPcdCcGroupParams->nextEnginePerEntriesInGrp[j], &requiredAction); + if (err) + { + DeleteTree(p_FmPcdCcTree,p_FmPcd); + XX_Free(p_Params); + REPORT_ERROR(MAJOR, E_INVALID_STATE, NO_MSG); + return NULL; + } + } + p_KeyAndNextEngineParams = p_Params+k; + + memcpy(&p_KeyAndNextEngineParams->nextEngineParams, + &p_FmPcdCcGroupParams->nextEnginePerEntriesInGrp[j], + sizeof(t_FmPcdCcNextEngineParams)); + + if ((p_KeyAndNextEngineParams->nextEngineParams.nextEngine == e_FM_PCD_CC) + && p_KeyAndNextEngineParams->nextEngineParams.h_Manip) + { + err = AllocAndFillAdForContLookupManip(p_KeyAndNextEngineParams->nextEngineParams.params.ccParams.h_CcNode); + if (err) + { + DeleteTree(p_FmPcdCcTree,p_FmPcd); + XX_Free(p_Params); + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("MURAM allocation for CC Tree")); + return NULL; + } + } + + requiredAction |= UPDATE_CC_WITH_TREE; + p_KeyAndNextEngineParams->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)( FM_PCD_MAX_NUM_OF_CC_GROUPS * FM_PCD_CC_AD_ENTRY_SIZE), + FM_PCD_CC_TREE_ADDR_ALIGN)); + if (!p_FmPcdCcTree->ccTreeBaseAddr) + { + DeleteTree(p_FmPcdCcTree,p_FmPcd); + XX_Free(p_Params); + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("MURAM allocation for CC Tree")); + return NULL; + } + IOMemSet32(UINT_TO_PTR(p_FmPcdCcTree->ccTreeBaseAddr), 0, (uint32_t)(FM_PCD_MAX_NUM_OF_CC_GROUPS * FM_PCD_CC_AD_ENTRY_SIZE)); + + p_CcTreeTmp = UINT_TO_PTR(p_FmPcdCcTree->ccTreeBaseAddr); + + j = 0; + for (i = 0; i < numOfEntries; i++) + { + p_KeyAndNextEngineParams = p_Params + i; + + NextStepAd(p_CcTreeTmp, + NULL, + &p_KeyAndNextEngineParams->nextEngineParams, + p_FmPcd); + + p_CcTreeTmp = PTR_MOVE(p_CcTreeTmp, FM_PCD_CC_AD_ENTRY_SIZE); + + memcpy(&p_FmPcdCcTree->keyAndNextEngineParams[i], + p_KeyAndNextEngineParams, + sizeof(t_FmPcdCcKeyAndNextEngineParams)); + + if (p_FmPcdCcTree->keyAndNextEngineParams[i].nextEngineParams.nextEngine== e_FM_PCD_CC) + { + p_FmPcdCcNextNode = (t_FmPcdCcNode*)p_FmPcdCcTree->keyAndNextEngineParams[i].nextEngineParams.params.ccParams.h_CcNode; + p_CcInformation = FindNodeInfoInReleventLst(&p_FmPcdCcNextNode->ccTreeIdLst, + (t_Handle)p_FmPcdCcTree, + p_FmPcdCcNextNode->h_Spinlock); + + if (!p_CcInformation) + { + memset(&ccNodeInfo, 0, sizeof(t_CcNodeInformation)); + ccNodeInfo.h_CcNode = (t_Handle)p_FmPcdCcTree; + ccNodeInfo.index = 1; + EnqueueNodeInfoToRelevantLst(&p_FmPcdCcNextNode->ccTreeIdLst, + &ccNodeInfo, + p_FmPcdCcNextNode->h_Spinlock); + } + else + p_CcInformation->index++; + } + } + + FmPcdIncNetEnvOwners(h_FmPcd, p_FmPcdCcTree->netEnvId); + p_CcTreeTmp = UINT_TO_PTR(p_FmPcdCcTree->ccTreeBaseAddr); + + if (!FmPcdLockTryLockAll(p_FmPcd)) + { + FM_PCD_CcRootDelete(p_FmPcdCcTree); + XX_Free(p_Params); + DBG(TRACE, ("FmPcdLockTryLockAll failed")); + return NULL; + } + + for (i = 0; i < numOfEntries; i++) + { + if (p_FmPcdCcTree->keyAndNextEngineParams[i].requiredAction) + { + err = SetRequiredAction(h_FmPcd, + p_FmPcdCcTree->keyAndNextEngineParams[i].requiredAction, + &p_FmPcdCcTree->keyAndNextEngineParams[i], + p_CcTreeTmp, + 1, + p_FmPcdCcTree); + if (err) + { + FmPcdLockUnlockAll(p_FmPcd); + FM_PCD_CcRootDelete(p_FmPcdCcTree); + XX_Free(p_Params); + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("No memory")); + return NULL; + } + p_CcTreeTmp = PTR_MOVE(p_CcTreeTmp, FM_PCD_CC_AD_ENTRY_SIZE); + } + } + + FmPcdLockUnlockAll(p_FmPcd); + p_FmPcdCcTree->p_Lock = FmPcdAcquireLock(p_FmPcd); + if (!p_FmPcdCcTree->p_Lock) + { + FM_PCD_CcRootDelete(p_FmPcdCcTree); + XX_Free(p_Params); + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM CC lock")); + return NULL; + } + + XX_Free(p_Params); + + return p_FmPcdCcTree; +} + +t_Error FM_PCD_CcRootDelete(t_Handle h_CcTree) +{ + t_FmPcd *p_FmPcd; + t_FmPcdCcTree *p_CcTree = (t_FmPcdCcTree *)h_CcTree; + int i= 0; + + SANITY_CHECK_RETURN_ERROR(p_CcTree,E_INVALID_STATE); + p_FmPcd = (t_FmPcd *)p_CcTree->h_FmPcd; + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE); + + FmPcdDecNetEnvOwners(p_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")); + + /* Delete reassembly schemes if exist */ + if (p_CcTree->h_IpReassemblyManip) + { + FmPcdManipDeleteIpReassmSchemes(p_CcTree->h_IpReassemblyManip); + FmPcdManipUpdateOwner(p_CcTree->h_IpReassemblyManip, FALSE); + } + + for (i = 0; i <p_CcTree->numOfEntries; i++) + { + if (p_CcTree->keyAndNextEngineParams[i].nextEngineParams.nextEngine == e_FM_PCD_CC) + UpdateNodeOwner(p_CcTree->keyAndNextEngineParams[i].nextEngineParams.params.ccParams.h_CcNode, FALSE); + + if (p_CcTree->keyAndNextEngineParams[i].nextEngineParams.h_Manip) + FmPcdManipUpdateOwner(p_CcTree->keyAndNextEngineParams[i].nextEngineParams.h_Manip, FALSE); + +#ifdef FM_CAPWAP_SUPPORT + if ((p_CcTree->numOfGrps == 1) && + (p_CcTree->fmPcdGroupParam[0].numOfEntriesInGroup == 1) && + (p_CcTree->keyAndNextEngineParams[0].nextEngineParams.nextEngine == e_FM_PCD_CC) && + p_CcTree->keyAndNextEngineParams[0].nextEngineParams.params.ccParams.h_CcNode && + IsCapwapApplSpecific(p_CcTree->keyAndNextEngineParams[0].nextEngineParams.params.ccParams.h_CcNode)) + { + if (FM_PCD_ManipNodeDelete(p_CcTree->keyAndNextEngineParams[0].nextEngineParams.h_Manip) != E_OK) + return E_INVALID_STATE; + } +#endif /* FM_CAPWAP_SUPPORT */ + +#if (DPAA_VERSION >= 11) + if ((p_CcTree->keyAndNextEngineParams[i].nextEngineParams.nextEngine == e_FM_PCD_FR) && + (p_CcTree->keyAndNextEngineParams[i].nextEngineParams.params.frParams.h_FrmReplic)) + FrmReplicGroupUpdateOwner(p_CcTree->keyAndNextEngineParams[i].nextEngineParams.params.frParams.h_FrmReplic, + FALSE); +#endif /* (DPAA_VERSION >= 11) */ + } + + if (p_CcTree->p_Lock) + FmPcdReleaseLock(p_CcTree->h_FmPcd, p_CcTree->p_Lock); + + DeleteTree(p_CcTree, p_FmPcd); + + return E_OK; +} + +t_Error FM_PCD_CcRootModifyNextEngine(t_Handle h_CcTree, + uint8_t grpId, + uint8_t index, + t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams) +{ + t_FmPcd *p_FmPcd; + t_FmPcdCcTree *p_CcTree = (t_FmPcdCcTree *)h_CcTree; + t_Error err = E_OK; + + SANITY_CHECK_RETURN_ERROR(p_FmPcdCcNextEngineParams, E_NULL_POINTER); + SANITY_CHECK_RETURN_ERROR(p_CcTree,E_INVALID_STATE); + p_FmPcd = (t_FmPcd *)p_CcTree->h_FmPcd; + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE); + + if (!FmPcdLockTryLockAll(p_FmPcd)) + { + DBG(TRACE, ("FmPcdLockTryLockAll failed")); + return ERROR_CODE(E_BUSY); + } + + err = FmPcdCcModifyNextEngineParamTree(p_FmPcd, + p_CcTree, + grpId, + index, + p_FmPcdCcNextEngineParams); + FmPcdLockUnlockAll(p_FmPcd); + + if (err) + { + RETURN_ERROR(MAJOR, err, NO_MSG); + } + + return E_OK; +} + +t_Handle FM_PCD_MatchTableSet(t_Handle h_FmPcd, t_FmPcdCcNodeParams *p_CcNodeParam) +{ + t_FmPcdCcNode *p_CcNode; + t_Error err; + + SANITY_CHECK_RETURN_VALUE(h_FmPcd, E_INVALID_HANDLE, NULL); + SANITY_CHECK_RETURN_VALUE(p_CcNodeParam, E_NULL_POINTER, NULL); + + p_CcNode = (t_FmPcdCcNode*)XX_Malloc(sizeof(t_FmPcdCcNode)); + if (!p_CcNode) + { + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("No memory")); + return NULL; + } + memset(p_CcNode, 0, sizeof(t_FmPcdCcNode)); + + err = FmPcdCcMatchTableSet(h_FmPcd, p_CcNode, p_CcNodeParam); + + switch (GET_ERROR_TYPE(err)) + { + case E_OK: + break; + + case E_BUSY: + DBG(TRACE, ("E_BUSY error")); + return NULL; + + default: + REPORT_ERROR(MAJOR, err, NO_MSG); + return NULL; + } + return p_CcNode; } @@ -6536,6 +6563,9 @@ t_Error FM_PCD_MatchTableGetKeyStatistics(t_Handle h_CcNode, intFlags = XX_LockIntrSpinlock(p_CcNode->h_Spinlock); + if (keyIndex >= p_CcNode->numOfKeys) + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("The provided keyIndex exceeds the number of keys in this match table")); + err = MatchTableGetKeyStatistics(p_CcNode, keyIndex, p_KeyStatistics); @@ -6548,6 +6578,30 @@ t_Error FM_PCD_MatchTableGetKeyStatistics(t_Handle h_CcNode, return E_OK; } +t_Error FM_PCD_MatchTableGetMissStatistics(t_Handle h_CcNode, + t_FmPcdCcKeyStatistics *p_MissStatistics) +{ + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode; + uint32_t intFlags; + t_Error err; + + SANITY_CHECK_RETURN_ERROR(h_CcNode, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(p_MissStatistics, E_NULL_POINTER); + + intFlags = XX_LockIntrSpinlock(p_CcNode->h_Spinlock); + + err = MatchTableGetKeyStatistics(p_CcNode, + p_CcNode->numOfKeys, + p_MissStatistics); + + XX_UnlockIntrSpinlock(p_CcNode->h_Spinlock, intFlags); + + if (err != E_OK) + RETURN_ERROR(MAJOR, err, NO_MSG); + + return E_OK; +} + t_Error FM_PCD_MatchTableFindNGetKeyStatistics(t_Handle h_CcNode, uint8_t keySize, uint8_t *p_Key, @@ -6572,6 +6626,8 @@ t_Error FM_PCD_MatchTableFindNGetKeyStatistics(t_Handle h_CcNode "match table of the provided node")); } + ASSERT_COND(keyIndex < p_CcNode->numOfKeys); + err = MatchTableGetKeyStatistics(p_CcNode, keyIndex, p_KeyStatistics); @@ -6624,10 +6680,13 @@ t_Handle FM_PCD_HashTableSet(t_Handle h_FmPcd, t_FmPcdHashTableParams *p_Param) { t_FmPcdCcNode *p_CcNodeHashTbl; t_FmPcdCcNodeParams *p_IndxHashCcNodeParam, *p_ExactMatchCcNodeParam; - t_Handle h_CcNode; + t_FmPcdCcNode *p_CcNode; + t_Handle h_MissStatsCounters = NULL; t_FmPcdCcKeyParams *p_HashKeyParams; int i; uint16_t numOfSets, numOfWays, countMask, onesCount = 0; + bool statsEnForMiss = FALSE; + t_Error err; SANITY_CHECK_RETURN_VALUE(h_FmPcd, E_INVALID_HANDLE, NULL); SANITY_CHECK_RETURN_VALUE(p_Param, E_NULL_POINTER, NULL); @@ -6684,6 +6743,28 @@ t_Handle FM_PCD_HashTableSet(t_Handle h_FmPcd, t_FmPcdHashTableParams *p_Param) if (p_Param->maxNumOfKeys % numOfSets) DBG(INFO, ("'maxNumOfKeys' is not a multiple of hash number of ways, so number of ways will be rounded up")); + if ((p_Param->statisticsMode == e_FM_PCD_CC_STATS_MODE_FRAME) || + (p_Param->statisticsMode == e_FM_PCD_CC_STATS_MODE_BYTE_AND_FRAME)) + { + /* Allocating a statistics counters table that will be used by all + 'miss' entries of the hash table */ + h_MissStatsCounters = (t_Handle)FM_MURAM_AllocMem(FmPcdGetMuramHandle(h_FmPcd), + 2 * FM_PCD_CC_STATS_COUNTER_SIZE, + FM_PCD_CC_AD_TABLE_ALIGN); + if (!h_MissStatsCounters) + { + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("MURAM allocation for statistics table for hash miss")); + return NULL; + } + memset(h_MissStatsCounters, 0, (2 * FM_PCD_CC_STATS_COUNTER_SIZE)); + + /* Always enable statistics for 'miss', so that a statistics AD will be + initialized from the start. We'll store the requested 'statistics enable' + value and it will be used when statistics are read by the user. */ + statsEnForMiss = p_Param->ccNextEngineParamsForMiss.statisticsEn; + p_Param->ccNextEngineParamsForMiss.statisticsEn = TRUE; + } + /* Building exact-match node params, will be used to create the hash buckets */ p_ExactMatchCcNodeParam->extractCcParams.type = e_FM_PCD_EXTRACT_NON_HDR; @@ -6703,13 +6784,23 @@ t_Handle FM_PCD_HashTableSet(t_Handle h_FmPcd, t_FmPcdHashTableParams *p_Param) for (i = 0; i < numOfSets; i++) { - h_CcNode = FM_PCD_MatchTableSet(h_FmPcd, p_ExactMatchCcNodeParam); - if (!h_CcNode) + /* Each exact-match node will be marked as a 'bucket' and provided with a pointer to statistics counters, + to be used for 'miss' entry statistics */ + p_CcNode = (t_FmPcdCcNode *)XX_Malloc(sizeof(t_FmPcdCcNode)); + if (!p_CcNode) + break; + memset(p_CcNode, 0, sizeof(t_FmPcdCcNode)); + + p_CcNode->isHashBucket = TRUE; + p_CcNode->h_MissStatsCounters = h_MissStatsCounters; + + err = FmPcdCcMatchTableSet(h_FmPcd, p_CcNode, p_ExactMatchCcNodeParam); + if (err) break; p_HashKeyParams[i].ccNextEngineParams.nextEngine = e_FM_PCD_CC; p_HashKeyParams[i].ccNextEngineParams.statisticsEn = FALSE; - p_HashKeyParams[i].ccNextEngineParams.params.ccParams.h_CcNode = h_CcNode; + p_HashKeyParams[i].ccNextEngineParams.params.ccParams.h_CcNode = p_CcNode; } if (i < numOfSets) @@ -6717,6 +6808,8 @@ t_Handle FM_PCD_HashTableSet(t_Handle h_FmPcd, t_FmPcdHashTableParams *p_Param) for (i = i-1; i >=0; i--) FM_PCD_MatchTableDelete(p_HashKeyParams[i].ccNextEngineParams.params.ccParams.h_CcNode); + FM_MURAM_FreeMem(FmPcdGetMuramHandle(h_FmPcd), h_MissStatsCounters); + REPORT_ERROR(MAJOR, E_NULL_POINTER, NO_MSG); XX_Free(p_IndxHashCcNodeParam); XX_Free(p_ExactMatchCcNodeParam); @@ -6738,10 +6831,17 @@ t_Handle FM_PCD_HashTableSet(t_Handle h_FmPcd, t_FmPcdHashTableParams *p_Param) p_IndxHashCcNodeParam->keysParams.keySize = 2; p_CcNodeHashTbl = FM_PCD_MatchTableSet(h_FmPcd, p_IndxHashCcNodeParam); - + if (p_CcNodeHashTbl) p_CcNodeHashTbl->kgHashShift = p_Param->kgHashShift; - + + /* Storing the allocated counters for buckets 'miss' in the hash table + and is statistics for miss wre enabled. */ + p_CcNodeHashTbl->h_MissStatsCounters = h_MissStatsCounters; + p_CcNodeHashTbl->statsEnForMiss = statsEnForMiss; + + XX_Print("Hash 0x%x: 0x%x\n", p_CcNodeHashTbl, h_MissStatsCounters); + XX_Free(p_IndxHashCcNodeParam); XX_Free(p_ExactMatchCcNodeParam); @@ -6751,12 +6851,14 @@ t_Handle FM_PCD_HashTableSet(t_Handle h_FmPcd, t_FmPcdHashTableParams *p_Param) t_Error FM_PCD_HashTableDelete(t_Handle h_HashTbl) { t_FmPcdCcNode *p_HashTbl = (t_FmPcdCcNode *)h_HashTbl; - t_Handle *p_HashBuckets; + t_Handle h_FmPcd; + t_Handle *p_HashBuckets, h_MissStatsCounters; uint16_t i, numOfBuckets; t_Error err; SANITY_CHECK_RETURN_ERROR(p_HashTbl, E_INVALID_HANDLE); + /* Store all hash buckets before the hash is freed */ numOfBuckets = p_HashTbl->numOfKeys; p_HashBuckets = (t_Handle *)XX_Malloc(numOfBuckets * sizeof(t_Handle)); @@ -6766,14 +6868,23 @@ t_Error FM_PCD_HashTableDelete(t_Handle h_HashTbl) for (i = 0; i < numOfBuckets; i++) p_HashBuckets[i] = p_HashTbl->keyAndNextEngineParams[i].nextEngineParams.params.ccParams.h_CcNode; + h_FmPcd = p_HashTbl->h_FmPcd; + h_MissStatsCounters = p_HashTbl->h_MissStatsCounters; + + /* Free the hash */ err = FM_PCD_MatchTableDelete(p_HashTbl); + /* Free each hash bucket */ for (i = 0; i < numOfBuckets; i++) err |= FM_PCD_MatchTableDelete(p_HashBuckets[i]); if (err) RETURN_ERROR(MAJOR, err, NO_MSG); + /* Free statistics counters for 'miss', id these were allocated */ + if (h_MissStatsCounters) + FM_MURAM_FreeMem(FmPcdGetMuramHandle(h_FmPcd), h_MissStatsCounters); + XX_Free(p_HashBuckets); return E_OK; @@ -6879,11 +6990,29 @@ t_Error FM_PCD_HashTableModifyMissNextEngine(t_Handle h_HashTbl t_FmPcdCcNode *p_HashTbl = (t_FmPcdCcNode *)h_HashTbl; t_Handle h_HashBucket; uint8_t i; + bool nullifyMissStats = FALSE; t_Error err; SANITY_CHECK_RETURN_ERROR(h_HashTbl, E_INVALID_HANDLE); SANITY_CHECK_RETURN_ERROR(p_FmPcdCcNextEngineParams, E_NULL_POINTER); + if ((!p_HashTbl->h_MissStatsCounters) && (p_FmPcdCcNextEngineParams->statisticsEn)) + RETURN_ERROR(MAJOR, E_CONFLICT, + ("Statistics are requested for a key, but statistics mode was set" + "to 'NONE' upon initialization")); + + if (p_HashTbl->h_MissStatsCounters) + { + if ((!p_HashTbl->statsEnForMiss) && (p_FmPcdCcNextEngineParams->statisticsEn)) + nullifyMissStats = TRUE; + + if ((p_HashTbl->statsEnForMiss) && (!p_FmPcdCcNextEngineParams->statisticsEn)) + { + p_HashTbl->statsEnForMiss = FALSE; + p_FmPcdCcNextEngineParams->statisticsEn = TRUE; + } + } + for (i = 0; i < p_HashTbl->numOfKeys; i++) { h_HashBucket = p_HashTbl->keyAndNextEngineParams[i].nextEngineParams.params.ccParams.h_CcNode; @@ -6894,6 +7023,13 @@ t_Error FM_PCD_HashTableModifyMissNextEngine(t_Handle h_HashTbl RETURN_ERROR(MAJOR, err, NO_MSG); } + if (nullifyMissStats) + { + memset(p_HashTbl->h_MissStatsCounters, 0, (2 * FM_PCD_CC_STATS_COUNTER_SIZE)); + memset(p_HashTbl->h_MissStatsCounters, 0, (2 * FM_PCD_CC_STATS_COUNTER_SIZE)); + p_HashTbl->statsEnForMiss = TRUE; + } + return E_OK; } @@ -6947,3 +7083,21 @@ t_Error FM_PCD_HashTableFindNGetKeyStatistics(t_Handle h_HashTbl NULL, p_KeyStatistics); } + +t_Error FM_PCD_HashTableGetMissStatistics(t_Handle h_HashTbl, + t_FmPcdCcKeyStatistics *p_MissStatistics) +{ + t_FmPcdCcNode *p_HashTbl = (t_FmPcdCcNode *)h_HashTbl; + t_Handle h_HashBucket; + + SANITY_CHECK_RETURN_ERROR(p_HashTbl, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(p_MissStatistics, E_NULL_POINTER); + + if (!p_HashTbl->statsEnForMiss) + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Statistics were not enabled for miss")); + + h_HashBucket = p_HashTbl->keyAndNextEngineParams[0].nextEngineParams.params.ccParams.h_CcNode; + + return FM_PCD_MatchTableGetMissStatistics(h_HashBucket, + p_MissStatistics); +} diff --git a/drivers/net/ethernet/freescale/fman/Peripherals/FM/Pcd/fm_cc.h b/drivers/net/ethernet/freescale/fman/Peripherals/FM/Pcd/fm_cc.h index eeb43a2..997eb5d 100644 --- a/drivers/net/ethernet/freescale/fman/Peripherals/FM/Pcd/fm_cc.h +++ b/drivers/net/ethernet/freescale/fman/Peripherals/FM/Pcd/fm_cc.h @@ -310,6 +310,17 @@ typedef struct uint32_t numOfStatsFLRs; uint32_t countersArraySize; + bool isHashBucket; /**< Valid for match table node that is a bucket of a hash table only */ + t_Handle h_MissStatsCounters; /**< Valid for hash table node and match table that is a bucket; + Holds the statistics counters allocated by the hash table and + are shared by all hash table buckets; */ + t_Handle h_PrivMissStatsCounters; /**< Valid for match table node that is a bucket of a hash table only; + Holds the statistics counters that were allocated for this node + and replaced by the shared counters (allocated by the hash table); */ + bool statsEnForMiss; /**< Valid for hash table node only; TRUE is statistics are currently + enabled for hash 'miss', FALSE otherwise; This parameter effects the + returned statistics count to user, statistics AD always present for 'miss' + for all hash buckets; */ bool glblMaskUpdated; t_Handle p_GlblMask; bool lclMask; diff --git a/drivers/net/ethernet/freescale/fman/inc/Peripherals/fm_pcd_ext.h b/drivers/net/ethernet/freescale/fman/inc/Peripherals/fm_pcd_ext.h index e2199e4..00750ba 100644 --- a/drivers/net/ethernet/freescale/fman/inc/Peripherals/fm_pcd_ext.h +++ b/drivers/net/ethernet/freescale/fman/inc/Peripherals/fm_pcd_ext.h @@ -1058,7 +1058,9 @@ typedef enum e_FmPcdPlcrRateMode { *//***************************************************************************/ typedef enum e_FmPcdDoneAction { e_FM_PCD_ENQ_FRAME = 0, /**< Enqueue frame */ - e_FM_PCD_DROP_FRAME /**< Drop frame */ + e_FM_PCD_DROP_FRAME /**< Mark this frame as error frame and continue + to error flow; 'FM_PORT_FRM_ERR_CLS_DISCARD' + flag will be set for this frame. */ } e_FmPcdDoneAction; /**************************************************************************//** @@ -2070,8 +2072,7 @@ typedef struct t_FmPcdPlcrProfileParams { /**************************************************************************//** @Description Parameters for selecting a location for requested manipulation *//***************************************************************************/ -typedef struct t_FmManipHdrInfo -{ +typedef struct t_FmManipHdrInfo { e_NetHeaderType hdr; /**< Header selection */ e_FmPcdHdrIndex hdrIndex; /**< Relevant only for MPLS, VLAN and tunneled IP. Otherwise should be cleared. */ bool byField; /**< TRUE if the location of manipulation is according to some field in the specific header*/ @@ -2565,7 +2566,7 @@ typedef struct t_FmPcdManipParams { *//***************************************************************************/ typedef struct t_FmPcdManipReassemIpStats { /* common counters for both IPv4 and IPv6 */ - uint32_t timeout; /**< Counts the number of TimeOut occurrences */ + uint32_t timeout; /**< Counts the number of timeout occurrences */ uint32_t rfdPoolBusy; /**< Counts the number of failed attempts to allocate a Reassembly Frame Descriptor */ uint32_t internalBufferBusy; /**< Counts the number of times an internal buffer busy occurred */ @@ -2932,7 +2933,8 @@ t_Error FM_PCD_MatchTableDelete(t_Handle h_CcNode); @Return E_OK on success; Error code otherwise. - @Cautions Allowed only following FM_PCD_MatchTableSet(). + @Cautions Allowed only following FM_PCD_MatchTableSet(); + Not relevant in the case the node is of type 'INDEXED_LOOKUP'. *//***************************************************************************/ t_Error FM_PCD_MatchTableModifyMissNextEngine(t_Handle h_CcNode, t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams); @@ -3185,6 +3187,29 @@ t_Error FM_PCD_MatchTableGetKeyStatistics(t_Handle h_CcNode, t_FmPcdCcKeyStatistics *p_KeyStatistics); /**************************************************************************//** + @Function FM_PCD_MatchTableGetMissStatistics + + @Description This routine may be used to get statistics counters of miss entry + in a CC Node. + + If 'e_FM_PCD_CC_STATS_MODE_FRAME' and + 'e_FM_PCD_CC_STATS_MODE_BYTE_AND_FRAME' were set for this node, + these counters reflect how many frames were not matched to any + existing key and therefore passed through the miss entry; The + total frames count will be returned in the counter of the + first range (as only one frame length range was defined). + + @Param[in] h_CcNode A handle to the node + @Param[out] p_MissStatistics Statistics counters for 'miss' + + @Return The statistics for 'miss'. + + @Cautions Allowed only following FM_PCD_MatchTableSet(). +*//***************************************************************************/ +t_Error FM_PCD_MatchTableGetMissStatistics(t_Handle h_CcNode, + t_FmPcdCcKeyStatistics *p_MissStatistics); + +/**************************************************************************//** @Function FM_PCD_MatchTableFindNGetKeyStatistics @Description This routine may be used to get statistics counters of specific key @@ -3436,6 +3461,27 @@ t_Error FM_PCD_HashTableFindNGetKeyStatistics(t_Handle h_HashTbl t_FmPcdCcKeyStatistics *p_KeyStatistics); /**************************************************************************//** + @Function FM_PCD_HashTableGetMissStatistics + + @Description This routine may be used to get statistics counters of 'miss' + entry of the a hash table. + + If 'e_FM_PCD_CC_STATS_MODE_FRAME' and + 'e_FM_PCD_CC_STATS_MODE_BYTE_AND_FRAME' were set for this node, + these counters reflect how many frames were not matched to any + existing key and therefore passed through the miss entry; + + @Param[in] h_HashTbl A handle to a hash table + @Param[out] p_MissStatistics Statistics counters for 'miss' + + @Return The statistics for 'miss'. + + @Cautions Allowed only following FM_PCD_HashTableSet(). +*//***************************************************************************/ +t_Error FM_PCD_HashTableGetMissStatistics(t_Handle h_HashTbl, + t_FmPcdCcKeyStatistics *p_MissStatistics); + +/**************************************************************************//** @Function FM_PCD_ManipNodeSet @Description This routine should be called for defining a manipulation diff --git a/drivers/net/ethernet/freescale/fman/inc/integrations/T4240/dpaa_integration_ext.h b/drivers/net/ethernet/freescale/fman/inc/integrations/T4240/dpaa_integration_ext.h index 52ed8f8..b6780b9 100644 --- a/drivers/net/ethernet/freescale/fman/inc/integrations/T4240/dpaa_integration_ext.h +++ b/drivers/net/ethernet/freescale/fman/inc/integrations/T4240/dpaa_integration_ext.h @@ -256,6 +256,9 @@ typedef enum #define FM_DEQ_PIPELINE_PARAMS_FOR_OP #define FM_QMI_NO_SINGLE_ECC_EXCEPTION + +#define FM_NO_GUARANTEED_RESET_VALUES + /* FM errata */ #define FM_HEAVY_TRAFFIC_HANG_ERRATA_FMAN_A005669 #define FM_WRONG_RESET_VALUES_ERRATA_FMAN_A005127 diff --git a/drivers/net/ethernet/freescale/fman/src/inc/wrapper/lnxwrp_exp_sym.h b/drivers/net/ethernet/freescale/fman/src/inc/wrapper/lnxwrp_exp_sym.h index 4c60893..13c61d2 100644 --- a/drivers/net/ethernet/freescale/fman/src/inc/wrapper/lnxwrp_exp_sym.h +++ b/drivers/net/ethernet/freescale/fman/src/inc/wrapper/lnxwrp_exp_sym.h @@ -88,6 +88,8 @@ EXPORT_SYMBOL(FM_PCD_MatchTableGetNextEngine); EXPORT_SYMBOL(FM_PCD_MatchTableGetKeyCounter); EXPORT_SYMBOL(FM_PCD_MatchTableGetKeyStatistics); EXPORT_SYMBOL(FM_PCD_MatchTableFindNGetKeyStatistics); +EXPORT_SYMBOL(FM_PCD_MatchTableGetMissStatistics); +EXPORT_SYMBOL(FM_PCD_HashTableGetMissStatistics); EXPORT_SYMBOL(FM_PCD_HashTableSet); EXPORT_SYMBOL(FM_PCD_HashTableDelete); EXPORT_SYMBOL(FM_PCD_HashTableAddKey); diff --git a/drivers/net/ethernet/freescale/fman/src/wrapper/lnxwrp_ioctls_fm.c b/drivers/net/ethernet/freescale/fman/src/wrapper/lnxwrp_ioctls_fm.c index 519c443..3104385 100644 --- a/drivers/net/ethernet/freescale/fman/src/wrapper/lnxwrp_ioctls_fm.c +++ b/drivers/net/ethernet/freescale/fman/src/wrapper/lnxwrp_ioctls_fm.c @@ -1932,6 +1932,155 @@ invalid_port_id: XX_Free(param); break; } + + +#if defined(CONFIG_COMPAT) + case FM_PCD_IOC_MATCH_TABLE_GET_MISS_STAT_COMPAT: +#endif + case FM_PCD_IOC_MATCH_TABLE_GET_MISS_STAT: + { + ioc_fm_pcd_cc_tbl_get_miss_params_t param; + +#if defined(CONFIG_COMPAT) + if (compat) + { + ioc_compat_fm_pcd_cc_tbl_get_miss_params_t *compat_param; + + compat_param = (ioc_compat_fm_pcd_cc_tbl_get_miss_params_t *) XX_Malloc( + sizeof(ioc_compat_fm_pcd_cc_tbl_get_miss_params_t)); + if (!compat_param) + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD")); + + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_cc_tbl_get_miss_params_t)); + if (copy_from_user(compat_param, + (ioc_compat_fm_pcd_cc_tbl_get_miss_params_t *)compat_ptr(arg), + sizeof(ioc_compat_fm_pcd_cc_tbl_get_miss_params_t))) + { + XX_Free(compat_param); + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG); + } + + compat_copy_fm_pcd_cc_tbl_get_miss(compat_param, ¶m, COMPAT_US_TO_K); + + XX_Free(compat_param); + } + else +#endif + { + if (copy_from_user(¶m, (ioc_fm_pcd_cc_tbl_get_miss_params_t *)arg, + sizeof(ioc_fm_pcd_cc_tbl_get_miss_params_t))) + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG); + } + + + err = FM_PCD_MatchTableGetMissStatistics((t_Handle) param.id, + (t_FmPcdCcKeyStatistics *) ¶m.miss_statistics); + +#if defined(CONFIG_COMPAT) + if (compat) + { + ioc_compat_fm_pcd_cc_tbl_get_miss_params_t *compat_param; + + compat_param = (ioc_compat_fm_pcd_cc_tbl_get_miss_params_t*) XX_Malloc( + sizeof(ioc_compat_fm_pcd_cc_tbl_get_miss_params_t)); + if (!compat_param) + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD")); + + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_cc_tbl_get_miss_params_t)); + compat_copy_fm_pcd_cc_tbl_get_miss(compat_param, ¶m, COMPAT_K_TO_US); + if (copy_to_user((ioc_compat_fm_pcd_cc_tbl_get_miss_params_t*) compat_ptr(arg), + compat_param, + sizeof(ioc_compat_fm_pcd_cc_tbl_get_miss_params_t))) + RETURN_ERROR(MINOR, E_READ_FAILED, NO_MSG); + + XX_Free(compat_param); + } + else +#endif + { + if (copy_to_user((ioc_fm_pcd_hash_table_params_t *)arg, + ¶m, + sizeof(ioc_fm_pcd_cc_tbl_get_miss_params_t))) + RETURN_ERROR(MINOR, E_READ_FAILED, NO_MSG); + } + + break; + } + + +#if defined(CONFIG_COMPAT) + case FM_PCD_IOC_HASH_TABLE_GET_MISS_STAT_COMPAT: +#endif + case FM_PCD_IOC_HASH_TABLE_GET_MISS_STAT: + { + ioc_fm_pcd_cc_tbl_get_miss_params_t param; + +#if defined(CONFIG_COMPAT) + if (compat) + { + ioc_compat_fm_pcd_cc_tbl_get_miss_params_t *compat_param; + + compat_param = (ioc_compat_fm_pcd_cc_tbl_get_miss_params_t *) XX_Malloc( + sizeof(ioc_compat_fm_pcd_cc_tbl_get_miss_params_t)); + if (!compat_param) + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD")); + + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_cc_tbl_get_miss_params_t)); + if (copy_from_user(compat_param, + (ioc_compat_fm_pcd_cc_tbl_get_miss_params_t *)compat_ptr(arg), + sizeof(ioc_compat_fm_pcd_cc_tbl_get_miss_params_t))) + { + XX_Free(compat_param); + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG); + } + + compat_copy_fm_pcd_cc_tbl_get_miss(compat_param, ¶m, COMPAT_US_TO_K); + + XX_Free(compat_param); + } + else +#endif + { + if (copy_from_user(¶m, (ioc_fm_pcd_cc_tbl_get_miss_params_t *)arg, + sizeof(ioc_fm_pcd_cc_tbl_get_miss_params_t))) + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG); + } + + + err = FM_PCD_HashTableGetMissStatistics((t_Handle) param.id, + (t_FmPcdCcKeyStatistics *) ¶m.miss_statistics); + +#if defined(CONFIG_COMPAT) + if (compat) + { + ioc_compat_fm_pcd_cc_tbl_get_miss_params_t *compat_param; + + compat_param = (ioc_compat_fm_pcd_cc_tbl_get_miss_params_t*) XX_Malloc( + sizeof(ioc_compat_fm_pcd_cc_tbl_get_miss_params_t)); + if (!compat_param) + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD")); + + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_cc_tbl_get_miss_params_t)); + compat_copy_fm_pcd_cc_tbl_get_miss(compat_param, ¶m, COMPAT_K_TO_US); + if (copy_to_user((ioc_compat_fm_pcd_cc_tbl_get_miss_params_t*) compat_ptr(arg), + compat_param, + sizeof(ioc_compat_fm_pcd_cc_tbl_get_miss_params_t))) + RETURN_ERROR(MINOR, E_READ_FAILED, NO_MSG); + + XX_Free(compat_param); + } + else +#endif + { + if (copy_to_user((ioc_fm_pcd_hash_table_params_t *)arg, + ¶m, + sizeof(ioc_fm_pcd_cc_tbl_get_miss_params_t))) + RETURN_ERROR(MINOR, E_READ_FAILED, NO_MSG); + } + + break; + } + #if defined(CONFIG_COMPAT) case FM_PCD_IOC_HASH_TABLE_SET_COMPAT: #endif diff --git a/drivers/net/ethernet/freescale/fman/src/wrapper/lnxwrp_ioctls_fm_compat.c b/drivers/net/ethernet/freescale/fman/src/wrapper/lnxwrp_ioctls_fm_compat.c index 68142b6..3c1ac30 100644 --- a/drivers/net/ethernet/freescale/fman/src/wrapper/lnxwrp_ioctls_fm_compat.c +++ b/drivers/net/ethernet/freescale/fman/src/wrapper/lnxwrp_ioctls_fm_compat.c @@ -506,7 +506,7 @@ void compat_copy_fm_pcd_hash_table( { if (compat == COMPAT_US_TO_K) { - param-> max_num_of_keys = compat_param->max_num_of_keys; + param->max_num_of_keys = compat_param->max_num_of_keys; param->statistics_mode = compat_param->statistics_mode; param->kg_hash_shift = compat_param->kg_hash_shift; param->hash_res_mask = compat_param->hash_res_mask; @@ -516,7 +516,7 @@ void compat_copy_fm_pcd_hash_table( } else { - compat_param-> max_num_of_keys = param->max_num_of_keys; + compat_param->max_num_of_keys = param->max_num_of_keys; compat_param->statistics_mode = param->statistics_mode; compat_param->kg_hash_shift = param->kg_hash_shift; compat_param->hash_res_mask = param->hash_res_mask; @@ -844,6 +844,22 @@ void compat_copy_fm_port_vsp_alloc_params( } #endif /* (DPAA_VERSION >= 11) */ +void compat_copy_fm_pcd_cc_tbl_get_miss( + ioc_compat_fm_pcd_cc_tbl_get_miss_params_t *compat_param, + ioc_fm_pcd_cc_tbl_get_miss_params_t *param, + uint8_t compat) +{ + if (compat == COMPAT_US_TO_K) + { + param->id = compat_pcd_id2ptr(compat_param->id); + memcpy(¶m->miss_statistics, &compat_param->miss_statistics, sizeof(ioc_fm_pcd_cc_key_statistics_t)); + } else { + compat_param->id = compat_add_ptr2id(param->id, FM_MAP_TYPE_PCD_NODE); + memcpy(&compat_param->miss_statistics, ¶m->miss_statistics, sizeof(ioc_fm_pcd_cc_key_statistics_t)); + } +} + + void compat_copy_fm_pcd_net_env( ioc_compat_fm_pcd_net_env_params_t *compat_param, ioc_fm_pcd_net_env_params_t *param, diff --git a/drivers/net/ethernet/freescale/fman/src/wrapper/lnxwrp_ioctls_fm_compat.h b/drivers/net/ethernet/freescale/fman/src/wrapper/lnxwrp_ioctls_fm_compat.h index f8655db..ae19b68 100644 --- a/drivers/net/ethernet/freescale/fman/src/wrapper/lnxwrp_ioctls_fm_compat.h +++ b/drivers/net/ethernet/freescale/fman/src/wrapper/lnxwrp_ioctls_fm_compat.h @@ -521,6 +521,12 @@ typedef struct ioc_compat_fm_ctrl_mon_counters_params_t { compat_uptr_t p_mon; } ioc_compat_fm_ctrl_mon_counters_params_t; +typedef struct ioc_compat_fm_pcd_cc_tbl_get_miss_params_t { + compat_uptr_t id; + ioc_fm_pcd_cc_key_statistics_t miss_statistics; +} ioc_compat_fm_pcd_cc_tbl_get_miss_params_t; + + /* } pcd compat structures */ void compat_obj_delete( @@ -568,6 +574,11 @@ void compat_copy_fm_pcd_cc_tree( ioc_fm_pcd_cc_tree_params_t *param, uint8_t compat); +void compat_copy_fm_pcd_cc_tbl_get_miss( + ioc_compat_fm_pcd_cc_tbl_get_miss_params_t *compat_param, + ioc_fm_pcd_cc_tbl_get_miss_params_t *param, + uint8_t compat); + void compat_fm_pcd_prs_sw( ioc_compat_fm_pcd_prs_sw_params_t *compat_param, ioc_fm_pcd_prs_sw_params_t *param, |