diff options
author | Mandy Lavi <mandy.lavi@freescale.com> | 2015-07-28 16:03:27 (GMT) |
---|---|---|
committer | Mandy Lavi <mandy.lavi@freescale.com> | 2015-11-02 12:46:49 (GMT) |
commit | dedb4b3bdc6c4d96fd10ad6b0c30d49b752bcbe6 (patch) | |
tree | 03e8136ba8245ef0e61954f53deb0be61a57867f /drivers/net/ethernet/freescale/fman/Peripherals/FM | |
parent | 05060535f0a7401b92177c2417b7e3eb8c3317a8 (diff) | |
download | linux-fsl-qoriq-dedb4b3bdc6c4d96fd10ad6b0c30d49b752bcbe6.tar.xz |
fmd: support aging in CC
Signed-off-by: Mandy Lavi <mandy.lavi@freescale.com>
Diffstat (limited to 'drivers/net/ethernet/freescale/fman/Peripherals/FM')
5 files changed, 372 insertions, 44 deletions
diff --git a/drivers/net/ethernet/freescale/fman/Peripherals/FM/HC/hc.c b/drivers/net/ethernet/freescale/fman/Peripherals/FM/HC/hc.c index 8bc0889..633eb3a 100644 --- a/drivers/net/ethernet/freescale/fman/Peripherals/FM/HC/hc.c +++ b/drivers/net/ethernet/freescale/fman/Peripherals/FM/HC/hc.c @@ -49,15 +49,22 @@ #define HC_HCOR_OPCODE_KG_SCM 0x1 #define HC_HCOR_OPCODE_SYNC 0x2 #define HC_HCOR_OPCODE_CC 0x3 +#define HC_HCOR_OPCODE_CC_AGE_MASK 0x4 #define HC_HCOR_OPCODE_CC_CAPWAP_REASSM_TIMEOUT 0x5 #define HC_HCOR_OPCODE_CC_REASSM_TIMEOUT 0x10 #define HC_HCOR_OPCODE_CC_IP_FRAG_INITIALIZATION 0x11 -#define HC_HCOR_ACTION_REG_REASSM_TIMEOUT_ACTIVE_SHIFT 24 -#define HC_HCOR_EXTRA_REG_REASSM_TIMEOUT_TSBS_SHIFT 24 -#define HC_HCOR_ACTION_REG_REASSM_TIMEOUT_RES_SHIFT 16 -#define HC_HCOR_ACTION_REG_REASSM_TIMEOUT_RES_MASK 0xF -#define HC_HCOR_ACTION_REG_IP_FRAG_SCRATCH_POOL_CMD_SHIFT 24 -#define HC_HCOR_ACTION_REG_IP_FRAG_SCRATCH_POOL_BPID 16 +#define HC_HCOR_OPCODE_CC_UPDATE_WITH_AGING 0x13 +#define HC_HCOR_ACTION_REG_REASSM_TIMEOUT_ACTIVE_SHIFT 24 +#define HC_HCOR_EXTRA_REG_REASSM_TIMEOUT_TSBS_SHIFT 24 +#define HC_HCOR_EXTRA_REG_CC_AGING_ADD 0x80000000 +#define HC_HCOR_EXTRA_REG_CC_AGING_REMOVE 0x40000000 +#define HC_HCOR_EXTRA_REG_CC_AGING_CHANGE_MASK 0xC0000000 +#define HC_HCOR_EXTRA_REG_CC_REMOVE_INDX_SHIFT 24 +#define HC_HCOR_EXTRA_REG_CC_REMOVE_INDX_MASK 0x1F000000 +#define HC_HCOR_ACTION_REG_REASSM_TIMEOUT_RES_SHIFT 16 +#define HC_HCOR_ACTION_REG_REASSM_TIMEOUT_RES_MASK 0xF +#define HC_HCOR_ACTION_REG_IP_FRAG_SCRATCH_POOL_CMD_SHIFT 24 +#define HC_HCOR_ACTION_REG_IP_FRAG_SCRATCH_POOL_BPID 16 #define HC_HCOR_GBL 0x20000000 @@ -110,7 +117,7 @@ typedef struct t_HcFrame { t_FmPcdCcCapwapReassmTimeoutParams ccCapwapReassmTimeout; t_FmPcdCcReassmTimeoutParams ccReassmTimeout; } hcSpecificData; -} _PackedType t_HcFrame; +} t_HcFrame; #if defined(__MWERKS__) && !defined(__GNUC__) #pragma pack(pop) @@ -277,6 +284,7 @@ t_Handle FmHcConfigAndInit(t_FmHcParams *p_FmHcParams) } err = FM_PORT_ConfigMaxFrameLength(p_FmHc->h_HcPortDev, (uint16_t)sizeof(t_HcFrame)); + if (err != E_OK) { REPORT_ERROR(MAJOR, err, ("FM HC port init!")); @@ -647,11 +655,10 @@ t_Error FmHcPcdKgSetClsPlan(t_Handle h_FmHc, t_FmPcdKgInterModuleClsPlanSet *p_S p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_KG_SCM); p_HcFrame->actionReg = FmPcdKgBuildWriteClsPlanBlockActionReg((uint8_t)(i / CLS_PLAN_NUM_PER_GRP)); p_HcFrame->extraReg = HC_HCOR_KG_SCHEME_REGS_MASK; - ASSERT_COND(IN_RANGE(0, (i-p_Set->baseEntry) ,FM_PCD_MAX_NUM_OF_CLS_PLANS-1)); + idx = (uint8_t)(i - p_Set->baseEntry); ASSERT_COND(idx < FM_PCD_MAX_NUM_OF_CLS_PLANS); memcpy(&p_HcFrame->hcSpecificData.clsPlanEntries, &p_Set->vectors[idx], CLS_PLAN_NUM_PER_GRP*sizeof(uint32_t)); - p_HcFrame->commandSequence = seqNum; BUILD_FD(sizeof(t_HcFrame)); @@ -1185,6 +1192,97 @@ t_Error FmHcPcdCcDoDynamicChange(t_Handle h_FmHc, uint32_t oldAdAddrOffset, uint return E_OK; } +t_Error FmHcPcdCcDoDynamicChangeWithAging(t_Handle h_FmHc, + uint32_t oldAdAddrOffset, + uint32_t newAdAddrOffset, + e_FmCcModifyState modifyState, + uint16_t keyIndex) +{ + t_FmHc *p_FmHc = (t_FmHc*)h_FmHc; + t_HcFrame *p_HcFrame; + t_DpaaFD fmFd; + t_Error err = E_OK; + uint32_t seqNum; + + SANITY_CHECK_RETURN_ERROR(p_FmHc, E_INVALID_HANDLE); + + p_HcFrame = GetBuf(p_FmHc, &seqNum); + if (!p_HcFrame) + RETURN_ERROR(MINOR, E_NO_MEMORY, ("HC Frame object")); + memset(p_HcFrame, 0, sizeof(t_HcFrame)); + + p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_CC_UPDATE_WITH_AGING); + p_HcFrame->actionReg = newAdAddrOffset; + p_HcFrame->actionReg |= 0xc0000000; + p_HcFrame->extraReg = oldAdAddrOffset; + + switch (modifyState) + { + case e_MODIFY_STATE_ADD: + p_HcFrame->extraReg |= HC_HCOR_EXTRA_REG_CC_AGING_ADD; + break; + + case e_MODIFY_STATE_REMOVE: + p_HcFrame->extraReg |= HC_HCOR_EXTRA_REG_CC_AGING_REMOVE; + p_HcFrame->extraReg |= ((keyIndex << HC_HCOR_EXTRA_REG_CC_REMOVE_INDX_SHIFT) & HC_HCOR_EXTRA_REG_CC_REMOVE_INDX_MASK); + break; + + case e_MODIFY_STATE_CHANGE: + p_HcFrame->extraReg &= ~HC_HCOR_EXTRA_REG_CC_AGING_CHANGE_MASK; + break; + } + + p_HcFrame->commandSequence = seqNum; + + BUILD_FD(SIZE_OF_HC_FRAME_READ_OR_CC_DYNAMIC); + + err = EnQFrm(p_FmHc, &fmFd, seqNum); + + PutBuf(p_FmHc, p_HcFrame, seqNum); + + if (err != E_OK) + RETURN_ERROR(MAJOR, err, NO_MSG); + + return E_OK; +} + +t_Error FmHcPcdCcResetAgingMask(t_Handle h_FmHc, uint32_t adAddrOffset, uint32_t newAgeMask, uint32_t *p_OldAgeMask) +{ + t_FmHc *p_FmHc = (t_FmHc*)h_FmHc; + t_HcFrame *p_HcFrame; + t_DpaaFD fmFd; + t_Error err = E_OK; + uint32_t seqNum; + + SANITY_CHECK_RETURN_ERROR(p_FmHc, E_INVALID_HANDLE); + + p_HcFrame = GetBuf(p_FmHc, &seqNum); + if (!p_HcFrame) + RETURN_ERROR(MINOR, E_NO_MEMORY, ("HC Frame object")); + memset(p_HcFrame, 0, sizeof(t_HcFrame)); + + p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_CC_AGE_MASK); + p_HcFrame->actionReg = adAddrOffset; + p_HcFrame->extraReg = newAgeMask; + p_HcFrame->commandSequence = seqNum; + + BUILD_FD(SIZE_OF_HC_FRAME_READ_OR_CC_DYNAMIC); + + err = EnQFrm(p_FmHc, &fmFd, seqNum); + + /* On command completion the FMC writes to HCER the 'aging-mask' field + before it was updated by this command. This way the user may identify + which bits were cleared by FMC before setting them. */ + *p_OldAgeMask = p_HcFrame->extraReg; + + PutBuf(p_FmHc, p_HcFrame, seqNum); + + if (err != E_OK) + RETURN_ERROR(MAJOR, err, NO_MSG); + + return E_OK; +} + t_Error FmHcPcdSync(t_Handle h_FmHc) { t_FmHc *p_FmHc = (t_FmHc*)h_FmHc; 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 863b61d..f439167 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 @@ -270,7 +270,7 @@ static void FillAdOfTypeContLookup(t_Handle h_Ad, t_AdOfTypeContLookup *p_AdContLookup = (t_AdOfTypeContLookup *)h_Ad; t_Handle h_TmpAd; t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; - uint32_t tmpReg32; + uint32_t tmpReg32, agingMask; t_Handle p_AdNewPtr = NULL; UNUSED(h_Manip); @@ -367,8 +367,16 @@ static void FillAdOfTypeContLookup(t_Handle h_Ad, tmpReg32 |= p_Node->parseCode; WRITE_UINT32(p_AdContLookup->pcAndOffsets, tmpReg32); - Mem2IOCpy32((void*)&p_AdContLookup->gmask, p_Node->p_GlblMask, - CC_GLBL_MASK_SIZE); + if (p_Node->agingSupport) + { + /* Building a mask of 1-s for all node's keys */ + agingMask = CC_BUILD_AGING_MASK(p_Node->numOfKeys); + Mem2IOCpy32((void*)&p_AdContLookup->gmask, &agingMask, + CC_AGING_MASK_SIZE); + } + else + Mem2IOCpy32((void*)&p_AdContLookup->gmask, p_Node->p_GlblMask, + CC_GLBL_MASK_SIZE); } } @@ -851,6 +859,7 @@ static t_Handle BuildNewAd( p_FmPcdCcNodeTmp->h_AdTable = p_FmPcdModifyCcKeyAdditionalParams->p_AdTableNew; + p_FmPcdCcNodeTmp->agingSupport = p_CcNode->agingSupport; p_FmPcdCcNodeTmp->lclMask = p_CcNode->lclMask; p_FmPcdCcNodeTmp->parseCode = p_CcNode->parseCode; p_FmPcdCcNodeTmp->offset = p_CcNode->offset; @@ -897,7 +906,8 @@ static t_Handle BuildNewAd( static t_Error DynamicChangeHc( t_Handle h_FmPcd, t_List *h_OldPointersLst, t_List *h_NewPointersLst, t_FmPcdModifyCcKeyAdditionalParams *p_AdditionalParams, - bool useShadowStructs) + bool useShadowStructs, + e_FmCcModifyState modifyState) { t_List *p_PosOld, *p_PosNew; uint32_t oldAdAddrOffset, newAdAddrOffset; @@ -942,7 +952,15 @@ static t_Error DynamicChangeHc( } /* Invoke host command to copy from new AD to old AD */ - err = FmHcPcdCcDoDynamicChange(((t_FmPcd *)h_FmPcd)->h_Hc, + if ((!p_AdditionalParams->tree) && + (((t_FmPcdCcNode *)(p_AdditionalParams->h_CurrentNode))->agingSupport)) + err = FmHcPcdCcDoDynamicChangeWithAging(((t_FmPcd *)h_FmPcd)->h_Hc, + oldAdAddrOffset, + newAdAddrOffset, + modifyState, + p_AdditionalParams->savedKeyIndex); + else + err = FmHcPcdCcDoDynamicChange(((t_FmPcd *)h_FmPcd)->h_Hc, oldAdAddrOffset, newAdAddrOffset); if (err) { @@ -990,7 +1008,8 @@ static t_Error DoDynamicChange( /* Invoke host-command to copy from the new Ad to existing Ads */ err = DynamicChangeHc(h_FmPcd, h_OldPointersLst, h_NewPointersLst, - p_AdditionalParams, useShadowStructs); + p_AdditionalParams, useShadowStructs, + p_AdditionalParams->modifyState); if (err) RETURN_ERROR(MAJOR, err, NO_MSG); @@ -1029,7 +1048,8 @@ static t_Error DoDynamicChange( /* HC to copy from the new Ad (old updated structures) to current Ad (uses shadow structures) */ err = DynamicChangeHc(h_FmPcd, h_OldPointersLst, h_NewPointersLst, - p_AdditionalParams, useShadowStructs); + p_AdditionalParams, useShadowStructs, + e_MODIFY_STATE_CHANGE); if (err) RETURN_ERROR(MAJOR, err, NO_MSG); } @@ -1693,7 +1713,8 @@ t_Error ValidateNextEngineParams( static uint8_t GetGenParseCode(e_FmPcdExtractFrom src, uint32_t offset, bool glblMask, uint8_t *parseArrayOffset, bool fromIc, - ccPrivateInfo_t icCode) + ccPrivateInfo_t icCode, + bool aging) { if (!fromIc) { @@ -1723,7 +1744,10 @@ static uint8_t GetGenParseCode(e_FmPcdExtractFrom src, { case (CC_PRIVATE_INFO_IC_KEY_EXACT_MATCH): *parseArrayOffset = 0x50; - return CC_PC_GENERIC_IC_GMASK; + if (aging) + return CC_PC_GENERIC_IC_AGING_MASK; + else + return CC_PC_GENERIC_IC_GMASK; case (CC_PRIVATE_INFO_IC_HASH_EXACT_MATCH): *parseArrayOffset = 0x48; @@ -3420,7 +3444,7 @@ static void UpdateAdPtrOfTreesWhichPointsOnCrntMdfNode( static t_FmPcdModifyCcKeyAdditionalParams * ModifyNodeCommonPart( t_Handle h_FmPcdCcNodeOrTree, uint16_t keyIndex, - e_ModifyState modifyState, bool ttlCheck, bool hashCheck, bool tree) + e_FmCcModifyState modifyState, bool ttlCheck, bool hashCheck, bool tree) { t_FmPcdModifyCcKeyAdditionalParams *p_FmPcdModifyCcKeyAdditionalParams; int i = 0, j = 0; @@ -3503,6 +3527,7 @@ static t_FmPcdModifyCcKeyAdditionalParams * ModifyNodeCommonPart( p_FmPcdModifyCcKeyAdditionalParams->h_CurrentNode = h_FmPcdCcNodeOrTree; p_FmPcdModifyCcKeyAdditionalParams->savedKeyIndex = keyIndex; + p_FmPcdModifyCcKeyAdditionalParams->modifyState = modifyState; while (i < numOfKeys) { @@ -4527,7 +4552,7 @@ static t_Error MatchTableSet(t_Handle h_FmPcd, t_FmPcdCcNode *p_CcNode, p_CcNode->parseCode = GetGenParseCode( p_CcNodeParam->extractCcParams.extractNonHdr.src, p_CcNode->offset, glblMask, &p_CcNode->prsArrayOffset, - fromIc, icCode); + fromIc, icCode, p_CcNode->agingSupport); if (p_CcNode->parseCode == CC_PC_GENERIC_IC_HASH_INDEXED) { @@ -4541,6 +4566,7 @@ static t_Error MatchTableSet(t_Handle h_FmPcd, t_FmPcdCcNode *p_CcNode, } } if ((p_CcNode->parseCode == CC_PC_GENERIC_IC_GMASK) + || (p_CcNode->parseCode == CC_PC_GENERIC_IC_AGING_MASK) || (p_CcNode->parseCode == CC_PC_GENERIC_IC_HASH_INDEXED)) { p_CcNode->offset += p_CcNode->prsArrayOffset; @@ -5735,6 +5761,58 @@ t_Error FmPcdCcModifyKeyAndNextEngine(t_Handle h_FmPcd, t_Handle h_FmPcdCcNode, return err; } +static t_Error FmPcdCcGetAgingMask(t_Handle h_FmPcd, + t_Handle h_FmPcdCcNode, + uint16_t keyIndex, + bool reset, + uint32_t *p_Mask) +{ + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd; + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_FmPcdCcNode; + t_FmPcdCcNextEngineParams *p_NextEngineParams = NULL; + t_List h_NodesLst; + uint32_t newAgingMask, oldAgingMask, adAddrOffset; + t_AdOfTypeContLookup *p_AdContLookup; + t_Error err; + + INIT_LIST(&h_NodesLst); + + /* Building a list of all action descriptors that point to this node. + No sharing on AD with aging, so there should be only one parent. */ + if (!LIST_IsEmpty(&p_CcNode->ccPrevNodesLst)) + UpdateAdPtrOfNodesWhichPointsOnCrntMdfNode(p_CcNode, &h_NodesLst, + &p_NextEngineParams); + ASSERT_COND(LIST_NumOfObjs(&h_NodesLst) == 1); + + adAddrOffset = FmPcdCcGetNodeAddrOffsetFromNodeInfo(p_FmPcd, LIST_FIRST(&h_NodesLst)); + + if (reset) + { + if (keyIndex == FM_PCD_LAST_KEY_INDEX) + /* If no specific key index provided the entire aging mask will be reset */ + newAgingMask = CC_BUILD_AGING_MASK(p_CcNode->numOfKeys); + else + /* Only the bit that corresponds to the provided index is reset, + other bits in the mask will be preserved */ + newAgingMask = (0x80000000 >> keyIndex); + + err = FmHcPcdCcResetAgingMask(p_FmPcd->h_Hc, adAddrOffset, newAgingMask, &oldAgingMask); + if (err) + RETURN_ERROR(MAJOR, err, NO_MSG); + + *p_Mask = (oldAgingMask & newAgingMask); + } + else + { + p_AdContLookup = (t_AdOfTypeContLookup *)(PTR_MOVE(XX_PhysToVirt(p_FmPcd->physicalMuramBase), adAddrOffset)); + *p_Mask = GET_UINT32(p_AdContLookup->gmask); + } + + ReleaseLst(&h_NodesLst); + + return E_OK; +} + uint32_t FmPcdCcGetNodeAddrOffsetFromNodeInfo(t_Handle h_FmPcd, t_Handle h_Pointer) { @@ -7167,6 +7245,14 @@ 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->agingSupport) && (numOfWays > 31)) + { + XX_Free(p_ExactMatchCcNodeParam); + REPORT_ERROR(MAJOR, E_INVALID_VALUE, + ("Aging supported enabled and %d keys requested per hash bucket. Aging cannot be supported when more then 31 keys", numOfWays)); + return NULL; + } + if ((p_Param->statisticsMode == e_FM_PCD_CC_STATS_MODE_FRAME) || (p_Param->statisticsMode == e_FM_PCD_CC_STATS_MODE_BYTE_AND_FRAME)) { @@ -7215,14 +7301,16 @@ t_Handle FM_PCD_HashTableSet(t_Handle h_FmPcd, t_FmPcdHashTableParams *p_Param) for (i = 0; i < numOfSets; i++) { - /* 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 */ + /* 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->agingSupport = p_Param->agingSupport; p_CcNode->h_MissStatsCounters = h_MissStatsCounters; err = MatchTableSet(h_FmPcd, p_CcNode, p_ExactMatchCcNodeParam); @@ -7529,3 +7617,138 @@ t_Error FM_PCD_HashTableGetMissStatistics( return FM_PCD_MatchTableGetMissStatistics(h_HashBucket, p_MissStatistics); } + +t_Error FM_PCD_HashTableGetKeyAging(t_Handle h_HashTbl, + uint8_t *p_Key, + uint8_t keySize, + bool reset, + bool *p_KeyAging) +{ + t_FmPcdCcNode *p_HashTbl = (t_FmPcdCcNode *)h_HashTbl; + t_FmPcd *p_FmPcd; + t_Handle h_HashBucket; + uint8_t bucketIndex; + uint16_t lastIndex, keyIndex; + uint32_t agingMask, keyAgingBit; + t_Error err; + + SANITY_CHECK_RETURN_ERROR(p_HashTbl, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(p_Key, E_NULL_POINTER); + SANITY_CHECK_RETURN_ERROR(p_KeyAging, E_NULL_POINTER); + p_FmPcd = (t_FmPcd *)p_HashTbl->h_FmPcd; + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(p_FmPcd->h_Hc, E_INVALID_HANDLE); + + err = FM_PCD_MatchTableGetIndexedHashBucket(p_HashTbl, keySize, p_Key, + p_HashTbl->kgHashShift, + &h_HashBucket, &bucketIndex, + &lastIndex); + if (err) + RETURN_ERROR(MAJOR, err, NO_MSG); + + if (!((t_FmPcdCcNode *)h_HashBucket)->agingSupport) + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Aging support was not enabled for this hash table")); + + if (!FmPcdLockTryLockAll(p_FmPcd)) + { + DBG(TRACE, ("FmPcdLockTryLockAll failed")); + return ERROR_CODE(E_BUSY); + } + + err = FindKeyIndex(h_HashBucket, keySize, p_Key, NULL, &keyIndex); + if (GET_ERROR_TYPE(err) != E_OK) + { + FmPcdLockUnlockAll(p_FmPcd); + RETURN_ERROR( + MAJOR, + err, + ("The received key and mask pair was not found in the match table of the provided node")); + } + + err = FmPcdCcGetAgingMask(p_FmPcd, h_HashBucket, keyIndex, reset, &agingMask); + + keyAgingBit = (0x80000000 >> keyIndex); + *p_KeyAging = ((agingMask & keyAgingBit) ? TRUE : FALSE); + + FmPcdLockUnlockAll(p_FmPcd); + + switch(GET_ERROR_TYPE(err)) + { + case E_OK: + return E_OK; + + case E_BUSY: + DBG(TRACE, ("E_BUSY error")); + return ERROR_CODE(E_BUSY); + + default: + RETURN_ERROR(MAJOR, err, NO_MSG); + } +} + +t_Error FM_PCD_HashTableGetBucketAging(t_Handle h_HashTbl, + uint16_t bucketId, + bool reset, + uint32_t *p_BucketAgingMask, + uint8_t *agedKeysArray[31]) +{ + t_FmPcdCcNode *p_HashTbl = (t_FmPcdCcNode *)h_HashTbl; + t_FmPcd *p_FmPcd; + t_FmPcdCcNode *p_HashBucket; + uint32_t tmpMask, keyIndex = 0, indx = 0; + t_Error err; + + SANITY_CHECK_RETURN_ERROR(p_HashTbl, E_INVALID_HANDLE); + p_FmPcd = (t_FmPcd *)p_HashTbl->h_FmPcd; + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(p_FmPcd->h_Hc, E_INVALID_HANDLE); + + p_HashBucket = (t_FmPcdCcNode *)(p_HashTbl->keyAndNextEngineParams[bucketId].nextEngineParams.params.ccParams.h_CcNode); + + if (!p_HashBucket->agingSupport) + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Aging support was not enabled for this hash table")); + + if (!FmPcdLockTryLockAll(p_FmPcd)) + { + DBG(TRACE, ("FmPcdLockTryLockAll failed")); + return ERROR_CODE(E_BUSY); + } + + err = FmPcdCcGetAgingMask(p_FmPcd, p_HashBucket, FM_PCD_LAST_KEY_INDEX, reset, p_BucketAgingMask); + + /* If the user provided a valid pointer, the aged keys will be copied + into the provided array of pointers */ + if ((agedKeysArray) && (*p_BucketAgingMask)) + { + tmpMask = *p_BucketAgingMask; + + while (tmpMask) + { + /* If a bit is set in the aging mask and it doesn't correspond to miss entry, + copy the key into the aged keys array */ + if ((tmpMask & 0x80000000) && (keyIndex != p_HashBucket->numOfKeys)) + { + memcpy(agedKeysArray[indx], p_HashBucket->keyAndNextEngineParams[keyIndex].key, p_HashBucket->userSizeOfExtraction); + indx++; + } + + tmpMask = (tmpMask << 1); + keyIndex++; + } + } + + FmPcdLockUnlockAll(p_FmPcd); + + switch(GET_ERROR_TYPE(err)) + { + case E_OK: + return E_OK; + + case E_BUSY: + DBG(TRACE, ("E_BUSY error")); + return ERROR_CODE(E_BUSY); + + default: + RETURN_ERROR(MAJOR, err, NO_MSG); + } +} 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 3bc7585..00d3f05 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 @@ -107,6 +107,7 @@ #define CC_PC_GENERIC_WITH_MASK 0x28 #define CC_PC_GENERIC_IC_GMASK 0x2B #define CC_PC_GENERIC_IC_HASH_INDEXED 0x2C +#define CC_PC_GENERIC_IC_AGING_MASK 0x2D #define CC_PR_OFFSET 0x25 #define CC_PR_WITHOUT_OFFSET 0x26 @@ -174,6 +175,7 @@ #define GLBL_MASK_FOR_HASH_INDEXED 0xfff00000 #define CC_GLBL_MASK_SIZE 4 +#define CC_AGING_MASK_SIZE 4 typedef uint32_t ccPrivateInfo_t; /**< private info of CC: */ @@ -183,6 +185,7 @@ typedef uint32_t ccPrivateInfo_t; /**< private info of CC: */ #define CC_PRIVATE_INFO_IC_KEY_EXACT_MATCH 0x20000000 #define CC_PRIVATE_INFO_IC_DEQ_FQID_INDEX_LOOKUP 0x10000000 +#define CC_BUILD_AGING_MASK(numOfKeys) ((((1LL << ((numOfKeys) + 1)) - 1)) << (31 - (numOfKeys))) /***********************************************************************/ /* Memory map */ /***********************************************************************/ @@ -229,13 +232,6 @@ typedef union /* Driver's internal structures */ /***********************************************************************/ -typedef enum e_ModifyState -{ - e_MODIFY_STATE_ADD = 0, - e_MODIFY_STATE_REMOVE, - e_MODIFY_STATE_CHANGE -} e_ModifyState; - typedef struct t_FmPcdStatsObj { t_Handle h_StatsAd; @@ -271,23 +267,24 @@ typedef struct typedef struct { - t_Handle p_AdTableNew; - t_Handle p_KeysMatchTableNew; - t_Handle p_AdTableOld; - t_Handle p_KeysMatchTableOld; - uint16_t numOfKeys; - t_Handle h_CurrentNode; - uint16_t savedKeyIndex; - t_Handle h_NodeForAdd; - t_Handle h_NodeForRmv; - t_Handle h_ManipForRmv; - t_Handle h_ManipForAdd; - t_FmPcdStatsObj *p_StatsObjForRmv; + t_Handle p_AdTableNew; + t_Handle p_KeysMatchTableNew; + t_Handle p_AdTableOld; + t_Handle p_KeysMatchTableOld; + uint16_t numOfKeys; + t_Handle h_CurrentNode; + uint16_t savedKeyIndex; + t_Handle h_NodeForAdd; + t_Handle h_NodeForRmv; + t_Handle h_ManipForRmv; + t_Handle h_ManipForAdd; + t_FmPcdStatsObj *p_StatsObjForRmv; #if (DPAA_VERSION >= 11) - t_Handle h_FrmReplicForAdd; - t_Handle h_FrmReplicForRmv; + t_Handle h_FrmReplicForAdd; + t_Handle h_FrmReplicForRmv; #endif /* (DPAA_VERSION >= 11) */ - bool tree; + bool tree; + e_FmCcModifyState modifyState; t_FmPcdCcKeyAndNextEngineParams keyAndNextEngineParams[CC_MAX_NUM_OF_KEYS]; } t_FmPcdModifyCcKeyAdditionalParams; @@ -311,6 +308,7 @@ typedef struct uint32_t countersArraySize; bool isHashBucket; /**< Valid for match table node that is a bucket of a hash table only */ + bool agingSupport; /**< 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; */ diff --git a/drivers/net/ethernet/freescale/fman/Peripherals/FM/inc/fm_common.h b/drivers/net/ethernet/freescale/fman/Peripherals/FM/inc/fm_common.h index 30eae1b..654294d 100644 --- a/drivers/net/ethernet/freescale/fman/Peripherals/FM/inc/fm_common.h +++ b/drivers/net/ethernet/freescale/fman/Peripherals/FM/inc/fm_common.h @@ -230,6 +230,13 @@ typedef struct }t_CcNodeInformation; #define CC_NODE_F_OBJECT(ptr) LIST_OBJECT(ptr, t_CcNodeInformation, node) +typedef enum e_FmCcModifyState +{ + e_MODIFY_STATE_ADD = 0, + e_MODIFY_STATE_REMOVE, + e_MODIFY_STATE_CHANGE +} e_FmCcModifyState; + typedef struct { t_Handle h_Manip; diff --git a/drivers/net/ethernet/freescale/fman/Peripherals/FM/inc/fm_hc.h b/drivers/net/ethernet/freescale/fman/Peripherals/FM/inc/fm_hc.h index 492aa8a..c4f62d7 100644 --- a/drivers/net/ethernet/freescale/fman/Peripherals/FM/inc/fm_hc.h +++ b/drivers/net/ethernet/freescale/fman/Peripherals/FM/inc/fm_hc.h @@ -71,6 +71,8 @@ t_Error FmHcPcdKgSetSchemeCounter(t_Handle h_FmHc, t_Handle h_Scheme, uint32 uint32_t FmHcPcdKgGetSchemeCounter(t_Handle h_FmHc, t_Handle h_Scheme); t_Error FmHcPcdCcDoDynamicChange(t_Handle h_FmHc, uint32_t oldAdAddrOffset, uint32_t newAdAddrOffset); +t_Error FmHcPcdCcDoDynamicChangeWithAging(t_Handle h_FmHc, uint32_t oldAdAddrOffset, uint32_t newAdAddrOffset, e_FmCcModifyState modifyState, uint16_t keyIndex); +t_Error FmHcPcdCcResetAgingMask(t_Handle h_FmHc, uint32_t adAddrOffset, uint32_t newAgeMask, uint32_t *p_OldAgeMask); t_Error FmHcPcdPlcrSetProfile(t_Handle h_FmHc, t_Handle h_Profile, t_FmPcdPlcrProfileRegs *p_PlcrRegs); t_Error FmHcPcdPlcrDeleteProfile(t_Handle h_FmHc, t_Handle h_Profile); |