1 /* 2 * Copyright 2008-2012 Freescale Semiconductor Inc. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions are met: 6 * * Redistributions of source code must retain the above copyright 7 * notice, this list of conditions and the following disclaimer. 8 * * Redistributions in binary form must reproduce the above copyright 9 * notice, this list of conditions and the following disclaimer in the 10 * documentation and/or other materials provided with the distribution. 11 * * Neither the name of Freescale Semiconductor nor the 12 * names of its contributors may be used to endorse or promote products 13 * derived from this software without specific prior written permission. 14 * 15 * 16 * ALTERNATIVELY, this software may be distributed under the terms of the 17 * GNU General Public License ("GPL") as published by the Free Software 18 * Foundation, either version 2 of that License or (at your option) any 19 * later version. 20 * 21 * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY 22 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 23 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 24 * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY 25 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 26 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 27 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 28 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 30 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 */ 32 33 34 /****************************************************************************** 35 @File fm_cc.c 36 37 @Description FM Coarse Classifier implementation 38 *//***************************************************************************/ 39 #include <sys/cdefs.h> 40 #include <sys/endian.h> 41 #include "std_ext.h" 42 #include "error_ext.h" 43 #include "string_ext.h" 44 #include "debug_ext.h" 45 #include "fm_pcd_ext.h" 46 #include "fm_muram_ext.h" 47 48 #include "fm_common.h" 49 #include "fm_pcd.h" 50 #include "fm_hc.h" 51 #include "fm_cc.h" 52 #include "crc64.h" 53 54 /****************************************/ 55 /* static functions */ 56 /****************************************/ 57 58 59 static t_Error CcRootTryLock(t_Handle h_FmPcdCcTree) 60 { 61 t_FmPcdCcTree *p_FmPcdCcTree = (t_FmPcdCcTree *)h_FmPcdCcTree; 62 63 ASSERT_COND(h_FmPcdCcTree); 64 65 if (FmPcdLockTryLock(p_FmPcdCcTree->p_Lock)) 66 return E_OK; 67 68 return ERROR_CODE(E_BUSY); 69 } 70 71 static void CcRootReleaseLock(t_Handle h_FmPcdCcTree) 72 { 73 t_FmPcdCcTree *p_FmPcdCcTree = (t_FmPcdCcTree *)h_FmPcdCcTree; 74 75 ASSERT_COND(h_FmPcdCcTree); 76 77 FmPcdLockUnlock(p_FmPcdCcTree->p_Lock); 78 } 79 80 static void UpdateNodeOwner(t_FmPcdCcNode *p_CcNode, bool add) 81 { 82 uint32_t intFlags; 83 84 ASSERT_COND(p_CcNode); 85 86 intFlags = XX_LockIntrSpinlock(p_CcNode->h_Spinlock); 87 88 if (add) 89 p_CcNode->owners++; 90 else 91 { 92 ASSERT_COND(p_CcNode->owners); 93 p_CcNode->owners--; 94 } 95 96 XX_UnlockIntrSpinlock(p_CcNode->h_Spinlock, intFlags); 97 } 98 99 static __inline__ t_FmPcdStatsObj* DequeueStatsObj(t_List *p_List) 100 { 101 t_FmPcdStatsObj *p_StatsObj = NULL; 102 t_List *p_Next; 103 104 if (!NCSW_LIST_IsEmpty(p_List)) 105 { 106 p_Next = NCSW_LIST_FIRST(p_List); 107 p_StatsObj = NCSW_LIST_OBJECT(p_Next, t_FmPcdStatsObj, node); 108 ASSERT_COND(p_StatsObj); 109 NCSW_LIST_DelAndInit(p_Next); 110 } 111 112 return p_StatsObj; 113 } 114 115 static __inline__ void EnqueueStatsObj(t_List *p_List, 116 t_FmPcdStatsObj *p_StatsObj) 117 { 118 NCSW_LIST_AddToTail(&p_StatsObj->node, p_List); 119 } 120 121 static void FreeStatObjects(t_List *p_List, t_Handle h_FmMuram) 122 { 123 t_FmPcdStatsObj *p_StatsObj; 124 125 while (!NCSW_LIST_IsEmpty(p_List)) 126 { 127 p_StatsObj = DequeueStatsObj(p_List); 128 ASSERT_COND(p_StatsObj); 129 130 FM_MURAM_FreeMem(h_FmMuram, p_StatsObj->h_StatsAd); 131 FM_MURAM_FreeMem(h_FmMuram, p_StatsObj->h_StatsCounters); 132 133 XX_Free(p_StatsObj); 134 } 135 } 136 137 static t_FmPcdStatsObj* GetStatsObj(t_FmPcdCcNode *p_CcNode) 138 { 139 t_FmPcdStatsObj* p_StatsObj; 140 t_Handle h_FmMuram; 141 142 ASSERT_COND(p_CcNode); 143 144 /* If 'maxNumOfKeys' was passed, all statistics object were preallocated 145 upon node initialization */ 146 if (p_CcNode->maxNumOfKeys) 147 { 148 p_StatsObj = DequeueStatsObj(&p_CcNode->availableStatsLst); 149 } 150 else 151 { 152 h_FmMuram = ((t_FmPcd *)(p_CcNode->h_FmPcd))->h_FmMuram; 153 ASSERT_COND(h_FmMuram); 154 155 p_StatsObj = XX_Malloc(sizeof(t_FmPcdStatsObj)); 156 if (!p_StatsObj) 157 { 158 REPORT_ERROR(MAJOR, E_NO_MEMORY, ("statistics object")); 159 return NULL; 160 } 161 162 p_StatsObj->h_StatsAd = (t_Handle)FM_MURAM_AllocMem( 163 h_FmMuram, FM_PCD_CC_AD_ENTRY_SIZE, FM_PCD_CC_AD_TABLE_ALIGN); 164 if (!p_StatsObj->h_StatsAd) 165 { 166 XX_Free(p_StatsObj); 167 REPORT_ERROR(MAJOR, E_NO_MEMORY, ("MURAM allocation for statistics ADs")); 168 return NULL; 169 } 170 MemSet8(p_StatsObj->h_StatsAd, 0, FM_PCD_CC_AD_ENTRY_SIZE); 171 172 p_StatsObj->h_StatsCounters = (t_Handle)FM_MURAM_AllocMem( 173 h_FmMuram, p_CcNode->countersArraySize, 174 FM_PCD_CC_AD_TABLE_ALIGN); 175 if (!p_StatsObj->h_StatsCounters) 176 { 177 FM_MURAM_FreeMem(h_FmMuram, p_StatsObj->h_StatsAd); 178 XX_Free(p_StatsObj); 179 REPORT_ERROR(MAJOR, E_NO_MEMORY, ("MURAM allocation for statistics counters")); 180 return NULL; 181 } 182 MemSet8(p_StatsObj->h_StatsCounters, 0, p_CcNode->countersArraySize); 183 } 184 185 return p_StatsObj; 186 } 187 188 static void PutStatsObj(t_FmPcdCcNode *p_CcNode, t_FmPcdStatsObj *p_StatsObj) 189 { 190 t_Handle h_FmMuram; 191 192 ASSERT_COND(p_CcNode); 193 ASSERT_COND(p_StatsObj); 194 195 /* If 'maxNumOfKeys' was passed, all statistics object were preallocated 196 upon node initialization and now will be enqueued back to the list */ 197 if (p_CcNode->maxNumOfKeys) 198 { 199 /* Nullify counters */ 200 MemSet8(p_StatsObj->h_StatsCounters, 0, p_CcNode->countersArraySize); 201 202 EnqueueStatsObj(&p_CcNode->availableStatsLst, p_StatsObj); 203 } 204 else 205 { 206 h_FmMuram = ((t_FmPcd *)(p_CcNode->h_FmPcd))->h_FmMuram; 207 ASSERT_COND(h_FmMuram); 208 209 FM_MURAM_FreeMem(h_FmMuram, p_StatsObj->h_StatsAd); 210 FM_MURAM_FreeMem(h_FmMuram, p_StatsObj->h_StatsCounters); 211 212 XX_Free(p_StatsObj); 213 } 214 } 215 216 static void SetStatsCounters(t_AdOfTypeStats *p_StatsAd, 217 uint32_t statsCountersAddr) 218 { 219 uint32_t tmp = (statsCountersAddr & FM_PCD_AD_STATS_COUNTERS_ADDR_MASK); 220 221 WRITE_UINT32(p_StatsAd->statsTableAddr, tmp); 222 } 223 224 225 static void UpdateStatsAd(t_FmPcdCcStatsParams *p_FmPcdCcStatsParams, 226 t_Handle h_Ad, uint64_t physicalMuramBase) 227 { 228 t_AdOfTypeStats *p_StatsAd; 229 uint32_t statsCountersAddr, nextActionAddr, tmp; 230 #if (DPAA_VERSION >= 11) 231 uint32_t frameLengthRangesAddr; 232 #endif /* (DPAA_VERSION >= 11) */ 233 234 p_StatsAd = (t_AdOfTypeStats *)p_FmPcdCcStatsParams->h_StatsAd; 235 236 tmp = FM_PCD_AD_STATS_TYPE; 237 238 #if (DPAA_VERSION >= 11) 239 if (p_FmPcdCcStatsParams->h_StatsFLRs) 240 { 241 frameLengthRangesAddr = (uint32_t)((XX_VirtToPhys( 242 p_FmPcdCcStatsParams->h_StatsFLRs) - physicalMuramBase)); 243 tmp |= (frameLengthRangesAddr & FM_PCD_AD_STATS_FLR_ADDR_MASK); 244 } 245 #endif /* (DPAA_VERSION >= 11) */ 246 WRITE_UINT32(p_StatsAd->profileTableAddr, tmp); 247 248 nextActionAddr = (uint32_t)((XX_VirtToPhys(h_Ad) - physicalMuramBase)); 249 tmp = 0; 250 tmp |= (uint32_t)((nextActionAddr << FM_PCD_AD_STATS_NEXT_ACTION_SHIFT) 251 & FM_PCD_AD_STATS_NEXT_ACTION_MASK); 252 tmp |= (FM_PCD_AD_STATS_NAD_EN | FM_PCD_AD_STATS_OP_CODE); 253 254 #if (DPAA_VERSION >= 11) 255 if (p_FmPcdCcStatsParams->h_StatsFLRs) 256 tmp |= FM_PCD_AD_STATS_FLR_EN; 257 #endif /* (DPAA_VERSION >= 11) */ 258 259 WRITE_UINT32(p_StatsAd->nextActionIndx, tmp); 260 261 statsCountersAddr = (uint32_t)((XX_VirtToPhys( 262 p_FmPcdCcStatsParams->h_StatsCounters) - physicalMuramBase)); 263 SetStatsCounters(p_StatsAd, statsCountersAddr); 264 } 265 266 static void FillAdOfTypeContLookup(t_Handle h_Ad, 267 t_FmPcdCcStatsParams *p_FmPcdCcStatsParams, 268 t_Handle h_FmPcd, t_Handle p_CcNode, 269 t_Handle h_Manip, t_Handle h_FrmReplic) 270 { 271 t_FmPcdCcNode *p_Node = (t_FmPcdCcNode *)p_CcNode; 272 t_AdOfTypeContLookup *p_AdContLookup = (t_AdOfTypeContLookup *)h_Ad; 273 t_Handle h_TmpAd; 274 t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; 275 uint32_t tmpReg32; 276 t_Handle p_AdNewPtr = NULL; 277 278 UNUSED(h_Manip); 279 UNUSED(h_FrmReplic); 280 281 /* there are 3 cases handled in this routine of building a "Continue lookup" type AD. 282 * Case 1: No Manip. The action descriptor is built within the match table. 283 * p_AdResult = p_AdNewPtr; 284 * Case 2: Manip exists. A new AD is created - p_AdNewPtr. It is initialized 285 * either in the FmPcdManipUpdateAdResultForCc routine or it was already 286 * initialized and returned here. 287 * p_AdResult (within the match table) will be initialized after 288 * this routine returns and point to the existing AD. 289 * Case 3: Manip exists. The action descriptor is built within the match table. 290 * FmPcdManipUpdateAdContLookupForCc returns a NULL p_AdNewPtr. 291 */ 292 293 /* As default, the "new" ptr is the current one. i.e. the content of the result 294 * AD will be written into the match table itself (case (1))*/ 295 p_AdNewPtr = p_AdContLookup; 296 297 /* Initialize an action descriptor, if current statistics mode requires an Ad */ 298 if (p_FmPcdCcStatsParams) 299 { 300 ASSERT_COND(p_FmPcdCcStatsParams->h_StatsAd); 301 ASSERT_COND(p_FmPcdCcStatsParams->h_StatsCounters); 302 303 /* Swapping addresses between statistics Ad and the current lookup AD */ 304 h_TmpAd = p_FmPcdCcStatsParams->h_StatsAd; 305 p_FmPcdCcStatsParams->h_StatsAd = h_Ad; 306 h_Ad = h_TmpAd; 307 308 p_AdNewPtr = h_Ad; 309 p_AdContLookup = h_Ad; 310 311 /* Init statistics Ad and connect current lookup AD as 'next action' from statistics Ad */ 312 UpdateStatsAd(p_FmPcdCcStatsParams, h_Ad, p_FmPcd->physicalMuramBase); 313 } 314 315 #if DPAA_VERSION >= 11 316 if (h_Manip && h_FrmReplic) 317 FmPcdManipUpdateAdContLookupForCc( 318 h_Manip, 319 h_Ad, 320 &p_AdNewPtr, 321 (uint32_t)((XX_VirtToPhys( 322 FrmReplicGroupGetSourceTableDescriptor(h_FrmReplic)) 323 - p_FmPcd->physicalMuramBase))); 324 else 325 if (h_FrmReplic) 326 FrmReplicGroupUpdateAd(h_FrmReplic, h_Ad, &p_AdNewPtr); 327 else 328 #endif /* (DPAA_VERSION >= 11) */ 329 if (h_Manip) 330 FmPcdManipUpdateAdContLookupForCc( 331 h_Manip, 332 h_Ad, 333 &p_AdNewPtr, 334 335 #ifdef FM_CAPWAP_SUPPORT 336 /*no check for opcode of manip - this step can be reached only with capwap_applic_specific*/ 337 (uint32_t)((XX_VirtToPhys(p_Node->h_AdTable) - p_FmPcd->physicalMuramBase)) 338 #else /* not FM_CAPWAP_SUPPORT */ 339 (uint32_t)((XX_VirtToPhys(p_Node->h_Ad) 340 - p_FmPcd->physicalMuramBase)) 341 #endif /* not FM_CAPWAP_SUPPORT */ 342 ); 343 344 /* if (p_AdNewPtr = NULL) --> Done. (case (3)) */ 345 if (p_AdNewPtr) 346 { 347 /* cases (1) & (2) */ 348 tmpReg32 = 0; 349 tmpReg32 |= FM_PCD_AD_CONT_LOOKUP_TYPE; 350 tmpReg32 |= 351 p_Node->sizeOfExtraction ? ((p_Node->sizeOfExtraction - 1) << 24) : 352 0; 353 tmpReg32 |= (uint32_t)(XX_VirtToPhys(p_Node->h_AdTable) 354 - p_FmPcd->physicalMuramBase); 355 WRITE_UINT32(p_AdContLookup->ccAdBase, tmpReg32); 356 357 tmpReg32 = 0; 358 tmpReg32 |= p_Node->numOfKeys << 24; 359 tmpReg32 |= (p_Node->lclMask ? FM_PCD_AD_CONT_LOOKUP_LCL_MASK : 0); 360 tmpReg32 |= 361 p_Node->h_KeysMatchTable ? (uint32_t)(XX_VirtToPhys( 362 p_Node->h_KeysMatchTable) - p_FmPcd->physicalMuramBase) : 363 0; 364 WRITE_UINT32(p_AdContLookup->matchTblPtr, tmpReg32); 365 366 tmpReg32 = 0; 367 tmpReg32 |= p_Node->prsArrayOffset << 24; 368 tmpReg32 |= p_Node->offset << 16; 369 tmpReg32 |= p_Node->parseCode; 370 WRITE_UINT32(p_AdContLookup->pcAndOffsets, tmpReg32); 371 372 MemCpy8((void*)&p_AdContLookup->gmask, p_Node->p_GlblMask, 373 CC_GLBL_MASK_SIZE); 374 } 375 } 376 377 static t_Error AllocAndFillAdForContLookupManip(t_Handle h_CcNode) 378 { 379 t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode; 380 uint32_t intFlags; 381 382 ASSERT_COND(p_CcNode); 383 384 intFlags = XX_LockIntrSpinlock(p_CcNode->h_Spinlock); 385 386 if (!p_CcNode->h_Ad) 387 { 388 if (p_CcNode->maxNumOfKeys) 389 p_CcNode->h_Ad = p_CcNode->h_TmpAd; 390 else 391 p_CcNode->h_Ad = (t_Handle)FM_MURAM_AllocMem( 392 ((t_FmPcd *)(p_CcNode->h_FmPcd))->h_FmMuram, 393 FM_PCD_CC_AD_ENTRY_SIZE, FM_PCD_CC_AD_TABLE_ALIGN); 394 395 XX_UnlockIntrSpinlock(p_CcNode->h_Spinlock, intFlags); 396 397 if (!p_CcNode->h_Ad) 398 RETURN_ERROR(MAJOR, E_NO_MEMORY, 399 ("MURAM allocation for CC action descriptor")); 400 401 MemSet8(p_CcNode->h_Ad, 0, FM_PCD_CC_AD_ENTRY_SIZE); 402 403 FillAdOfTypeContLookup(p_CcNode->h_Ad, NULL, p_CcNode->h_FmPcd, 404 p_CcNode, NULL, NULL); 405 } 406 else 407 XX_UnlockIntrSpinlock(p_CcNode->h_Spinlock, intFlags); 408 409 return E_OK; 410 } 411 412 static t_Error SetRequiredAction1( 413 t_Handle h_FmPcd, uint32_t requiredAction, 414 t_FmPcdCcKeyAndNextEngineParams *p_CcKeyAndNextEngineParamsTmp, 415 t_Handle h_AdTmp, uint16_t numOfEntries, t_Handle h_Tree) 416 { 417 t_AdOfTypeResult *p_AdTmp = (t_AdOfTypeResult *)h_AdTmp; 418 uint32_t tmpReg32; 419 t_Error err; 420 t_FmPcdCcNode *p_CcNode; 421 int i = 0; 422 uint16_t tmp = 0; 423 uint16_t profileId; 424 uint8_t relativeSchemeId, physicalSchemeId; 425 t_CcNodeInformation ccNodeInfo; 426 427 for (i = 0; i < numOfEntries; i++) 428 { 429 if (i == 0) 430 h_AdTmp = PTR_MOVE(h_AdTmp, i*FM_PCD_CC_AD_ENTRY_SIZE); 431 else 432 h_AdTmp = PTR_MOVE(h_AdTmp, FM_PCD_CC_AD_ENTRY_SIZE); 433 434 switch (p_CcKeyAndNextEngineParamsTmp[i].nextEngineParams.nextEngine) 435 { 436 case (e_FM_PCD_CC): 437 if (requiredAction) 438 { 439 p_CcNode = 440 p_CcKeyAndNextEngineParamsTmp[i].nextEngineParams.params.ccParams.h_CcNode; 441 ASSERT_COND(p_CcNode); 442 if (p_CcNode->shadowAction == requiredAction) 443 break; 444 if ((requiredAction & UPDATE_CC_WITH_TREE) 445 && !(p_CcNode->shadowAction & UPDATE_CC_WITH_TREE)) 446 { 447 448 memset(&ccNodeInfo, 0, sizeof(t_CcNodeInformation)); 449 ccNodeInfo.h_CcNode = h_Tree; 450 EnqueueNodeInfoToRelevantLst(&p_CcNode->ccTreesLst, 451 &ccNodeInfo, NULL); 452 p_CcKeyAndNextEngineParamsTmp[i].shadowAction |= 453 UPDATE_CC_WITH_TREE; 454 } 455 if ((requiredAction & UPDATE_CC_SHADOW_CLEAR) 456 && !(p_CcNode->shadowAction & UPDATE_CC_SHADOW_CLEAR)) 457 { 458 459 p_CcNode->shadowAction = 0; 460 } 461 462 if ((requiredAction & UPDATE_CC_WITH_DELETE_TREE) 463 && !(p_CcNode->shadowAction 464 & UPDATE_CC_WITH_DELETE_TREE)) 465 { 466 DequeueNodeInfoFromRelevantLst(&p_CcNode->ccTreesLst, 467 h_Tree, NULL); 468 p_CcKeyAndNextEngineParamsTmp[i].shadowAction |= 469 UPDATE_CC_WITH_DELETE_TREE; 470 } 471 if (p_CcNode->keyAndNextEngineParams[p_CcNode->numOfKeys].nextEngineParams.nextEngine 472 != e_FM_PCD_INVALID) 473 tmp = (uint8_t)(p_CcNode->numOfKeys + 1); 474 else 475 tmp = p_CcNode->numOfKeys; 476 err = SetRequiredAction1(h_FmPcd, requiredAction, 477 p_CcNode->keyAndNextEngineParams, 478 p_CcNode->h_AdTable, tmp, h_Tree); 479 if (err != E_OK) 480 return err; 481 if (requiredAction != UPDATE_CC_SHADOW_CLEAR) 482 p_CcNode->shadowAction |= requiredAction; 483 } 484 break; 485 486 case (e_FM_PCD_KG): 487 if ((requiredAction & UPDATE_NIA_ENQ_WITHOUT_DMA) 488 && !(p_CcKeyAndNextEngineParamsTmp[i].shadowAction 489 & UPDATE_NIA_ENQ_WITHOUT_DMA)) 490 { 491 physicalSchemeId = 492 FmPcdKgGetSchemeId( 493 p_CcKeyAndNextEngineParamsTmp[i].nextEngineParams.params.kgParams.h_DirectScheme); 494 relativeSchemeId = FmPcdKgGetRelativeSchemeId( 495 h_FmPcd, physicalSchemeId); 496 if (relativeSchemeId == FM_PCD_KG_NUM_OF_SCHEMES) 497 RETURN_ERROR(MAJOR, E_NOT_IN_RANGE, NO_MSG); 498 if (!FmPcdKgIsSchemeValidSw( 499 p_CcKeyAndNextEngineParamsTmp[i].nextEngineParams.params.kgParams.h_DirectScheme)) 500 RETURN_ERROR(MAJOR, E_INVALID_STATE, 501 ("Invalid direct scheme.")); 502 if (!KgIsSchemeAlwaysDirect(h_FmPcd, relativeSchemeId)) 503 RETURN_ERROR( 504 MAJOR, E_INVALID_STATE, 505 ("For this action scheme has to be direct.")); 506 err = 507 FmPcdKgCcGetSetParams( 508 h_FmPcd, 509 p_CcKeyAndNextEngineParamsTmp[i].nextEngineParams.params.kgParams.h_DirectScheme, 510 requiredAction, 0); 511 if (err != E_OK) 512 RETURN_ERROR(MAJOR, err, NO_MSG); 513 p_CcKeyAndNextEngineParamsTmp[i].shadowAction |= 514 requiredAction; 515 } 516 break; 517 518 case (e_FM_PCD_PLCR): 519 if ((requiredAction & UPDATE_NIA_ENQ_WITHOUT_DMA) 520 && !(p_CcKeyAndNextEngineParamsTmp[i].shadowAction 521 & UPDATE_NIA_ENQ_WITHOUT_DMA)) 522 { 523 if (!p_CcKeyAndNextEngineParamsTmp[i].nextEngineParams.params.plcrParams.overrideParams) 524 RETURN_ERROR( 525 MAJOR, 526 E_NOT_SUPPORTED, 527 ("In this initialization only overrideFqid can be initialized")); 528 if (!p_CcKeyAndNextEngineParamsTmp[i].nextEngineParams.params.plcrParams.sharedProfile) 529 RETURN_ERROR( 530 MAJOR, 531 E_NOT_SUPPORTED, 532 ("In this initialization only overrideFqid can be initialized")); 533 err = 534 FmPcdPlcrGetAbsoluteIdByProfileParams( 535 h_FmPcd, 536 e_FM_PCD_PLCR_SHARED, 537 NULL, 538 p_CcKeyAndNextEngineParamsTmp[i].nextEngineParams.params.plcrParams.newRelativeProfileId, 539 &profileId); 540 if (err != E_OK) 541 RETURN_ERROR(MAJOR, err, NO_MSG); 542 err = FmPcdPlcrCcGetSetParams(h_FmPcd, profileId, 543 requiredAction); 544 if (err != E_OK) 545 RETURN_ERROR(MAJOR, err, NO_MSG); 546 p_CcKeyAndNextEngineParamsTmp[i].shadowAction |= 547 requiredAction; 548 } 549 break; 550 551 case (e_FM_PCD_DONE): 552 if ((requiredAction & UPDATE_NIA_ENQ_WITHOUT_DMA) 553 && !(p_CcKeyAndNextEngineParamsTmp[i].shadowAction 554 & UPDATE_NIA_ENQ_WITHOUT_DMA)) 555 { 556 tmpReg32 = GET_UINT32(p_AdTmp->nia); 557 if ((tmpReg32 & GET_NIA_BMI_AC_ENQ_FRAME(h_FmPcd)) 558 != GET_NIA_BMI_AC_ENQ_FRAME(h_FmPcd)) 559 RETURN_ERROR( 560 MAJOR, 561 E_INVALID_STATE, 562 ("Next engine was previously assigned not as PCD_DONE")); 563 tmpReg32 |= NIA_BMI_AC_ENQ_FRAME_WITHOUT_DMA; 564 WRITE_UINT32(p_AdTmp->nia, tmpReg32); 565 p_CcKeyAndNextEngineParamsTmp[i].shadowAction |= 566 requiredAction; 567 } 568 break; 569 570 default: 571 break; 572 } 573 } 574 575 return E_OK; 576 } 577 578 static t_Error SetRequiredAction( 579 t_Handle h_FmPcd, uint32_t requiredAction, 580 t_FmPcdCcKeyAndNextEngineParams *p_CcKeyAndNextEngineParamsTmp, 581 t_Handle h_AdTmp, uint16_t numOfEntries, t_Handle h_Tree) 582 { 583 t_Error err = SetRequiredAction1(h_FmPcd, requiredAction, 584 p_CcKeyAndNextEngineParamsTmp, h_AdTmp, 585 numOfEntries, h_Tree); 586 if (err != E_OK) 587 return err; 588 return SetRequiredAction1(h_FmPcd, UPDATE_CC_SHADOW_CLEAR, 589 p_CcKeyAndNextEngineParamsTmp, h_AdTmp, 590 numOfEntries, h_Tree); 591 } 592 593 static t_Error ReleaseModifiedDataStructure( 594 t_Handle h_FmPcd, t_List *h_FmPcdOldPointersLst, 595 t_List *h_FmPcdNewPointersLst, 596 t_FmPcdModifyCcKeyAdditionalParams *p_AdditionalParams, 597 bool useShadowStructs) 598 { 599 t_List *p_Pos; 600 t_Error err = E_OK; 601 t_CcNodeInformation ccNodeInfo, *p_CcNodeInformation; 602 t_Handle h_Muram; 603 t_FmPcdCcNode *p_FmPcdCcNextNode, *p_FmPcdCcWorkingOnNode; 604 t_List *p_UpdateLst; 605 uint32_t intFlags; 606 607 SANITY_CHECK_RETURN_ERROR(h_FmPcd, E_INVALID_HANDLE); 608 SANITY_CHECK_RETURN_ERROR(p_AdditionalParams->h_CurrentNode, 609 E_INVALID_HANDLE); 610 SANITY_CHECK_RETURN_ERROR(h_FmPcdOldPointersLst, E_INVALID_HANDLE); 611 SANITY_CHECK_RETURN_ERROR(h_FmPcdNewPointersLst, E_INVALID_HANDLE); 612 613 /* We don't update subtree of the new node with new tree because it was done in the previous stage */ 614 if (p_AdditionalParams->h_NodeForAdd) 615 { 616 p_FmPcdCcNextNode = (t_FmPcdCcNode*)p_AdditionalParams->h_NodeForAdd; 617 618 if (!p_AdditionalParams->tree) 619 p_UpdateLst = &p_FmPcdCcNextNode->ccPrevNodesLst; 620 else 621 p_UpdateLst = &p_FmPcdCcNextNode->ccTreeIdLst; 622 623 p_CcNodeInformation = FindNodeInfoInReleventLst( 624 p_UpdateLst, p_AdditionalParams->h_CurrentNode, 625 p_FmPcdCcNextNode->h_Spinlock); 626 627 if (p_CcNodeInformation) 628 p_CcNodeInformation->index++; 629 else 630 { 631 memset(&ccNodeInfo, 0, sizeof(t_CcNodeInformation)); 632 ccNodeInfo.h_CcNode = (t_Handle)p_AdditionalParams->h_CurrentNode; 633 ccNodeInfo.index = 1; 634 EnqueueNodeInfoToRelevantLst(p_UpdateLst, &ccNodeInfo, 635 p_FmPcdCcNextNode->h_Spinlock); 636 } 637 if (p_AdditionalParams->h_ManipForAdd) 638 { 639 p_CcNodeInformation = FindNodeInfoInReleventLst( 640 FmPcdManipGetNodeLstPointedOnThisManip( 641 p_AdditionalParams->h_ManipForAdd), 642 p_AdditionalParams->h_CurrentNode, 643 FmPcdManipGetSpinlock(p_AdditionalParams->h_ManipForAdd)); 644 645 if (p_CcNodeInformation) 646 p_CcNodeInformation->index++; 647 else 648 { 649 memset(&ccNodeInfo, 0, sizeof(t_CcNodeInformation)); 650 ccNodeInfo.h_CcNode = 651 (t_Handle)p_AdditionalParams->h_CurrentNode; 652 ccNodeInfo.index = 1; 653 EnqueueNodeInfoToRelevantLst( 654 FmPcdManipGetNodeLstPointedOnThisManip( 655 p_AdditionalParams->h_ManipForAdd), 656 &ccNodeInfo, 657 FmPcdManipGetSpinlock( 658 p_AdditionalParams->h_ManipForAdd)); 659 } 660 } 661 } 662 663 if (p_AdditionalParams->h_NodeForRmv) 664 { 665 p_FmPcdCcNextNode = (t_FmPcdCcNode*)p_AdditionalParams->h_NodeForRmv; 666 667 if (!p_AdditionalParams->tree) 668 { 669 p_UpdateLst = &p_FmPcdCcNextNode->ccPrevNodesLst; 670 p_FmPcdCcWorkingOnNode = 671 (t_FmPcdCcNode *)(p_AdditionalParams->h_CurrentNode); 672 673 for (p_Pos = NCSW_LIST_FIRST(&p_FmPcdCcWorkingOnNode->ccTreesLst); 674 p_Pos != (&p_FmPcdCcWorkingOnNode->ccTreesLst); p_Pos = 675 NCSW_LIST_NEXT(p_Pos)) 676 { 677 p_CcNodeInformation = CC_NODE_F_OBJECT(p_Pos); 678 679 ASSERT_COND(p_CcNodeInformation->h_CcNode); 680 681 err = 682 SetRequiredAction( 683 h_FmPcd, 684 UPDATE_CC_WITH_DELETE_TREE, 685 &((t_FmPcdCcNode *)(p_AdditionalParams->h_CurrentNode))->keyAndNextEngineParams[p_AdditionalParams->savedKeyIndex], 686 PTR_MOVE(((t_FmPcdCcNode *)(p_AdditionalParams->h_CurrentNode))->h_AdTable, p_AdditionalParams->savedKeyIndex*FM_PCD_CC_AD_ENTRY_SIZE), 687 1, p_CcNodeInformation->h_CcNode); 688 } 689 } 690 else 691 { 692 p_UpdateLst = &p_FmPcdCcNextNode->ccTreeIdLst; 693 694 err = 695 SetRequiredAction( 696 h_FmPcd, 697 UPDATE_CC_WITH_DELETE_TREE, 698 &((t_FmPcdCcTree *)(p_AdditionalParams->h_CurrentNode))->keyAndNextEngineParams[p_AdditionalParams->savedKeyIndex], 699 UINT_TO_PTR(((t_FmPcdCcTree *)(p_AdditionalParams->h_CurrentNode))->ccTreeBaseAddr + p_AdditionalParams->savedKeyIndex*FM_PCD_CC_AD_ENTRY_SIZE), 700 1, p_AdditionalParams->h_CurrentNode); 701 } 702 if (err) 703 return err; 704 705 /* We remove from the subtree of the removed node tree because it wasn't done in the previous stage 706 Update ccPrevNodesLst or ccTreeIdLst of the removed node 707 Update of the node owner */ 708 p_CcNodeInformation = FindNodeInfoInReleventLst( 709 p_UpdateLst, p_AdditionalParams->h_CurrentNode, 710 p_FmPcdCcNextNode->h_Spinlock); 711 712 ASSERT_COND(p_CcNodeInformation); 713 ASSERT_COND(p_CcNodeInformation->index); 714 715 p_CcNodeInformation->index--; 716 717 if (p_CcNodeInformation->index == 0) 718 DequeueNodeInfoFromRelevantLst(p_UpdateLst, 719 p_AdditionalParams->h_CurrentNode, 720 p_FmPcdCcNextNode->h_Spinlock); 721 722 UpdateNodeOwner(p_FmPcdCcNextNode, FALSE); 723 724 if (p_AdditionalParams->h_ManipForRmv) 725 { 726 p_CcNodeInformation = FindNodeInfoInReleventLst( 727 FmPcdManipGetNodeLstPointedOnThisManip( 728 p_AdditionalParams->h_ManipForRmv), 729 p_AdditionalParams->h_CurrentNode, 730 FmPcdManipGetSpinlock(p_AdditionalParams->h_ManipForRmv)); 731 732 ASSERT_COND(p_CcNodeInformation); 733 ASSERT_COND(p_CcNodeInformation->index); 734 735 p_CcNodeInformation->index--; 736 737 if (p_CcNodeInformation->index == 0) 738 DequeueNodeInfoFromRelevantLst( 739 FmPcdManipGetNodeLstPointedOnThisManip( 740 p_AdditionalParams->h_ManipForRmv), 741 p_AdditionalParams->h_CurrentNode, 742 FmPcdManipGetSpinlock( 743 p_AdditionalParams->h_ManipForRmv)); 744 } 745 } 746 747 if (p_AdditionalParams->h_ManipForRmv) 748 FmPcdManipUpdateOwner(p_AdditionalParams->h_ManipForRmv, FALSE); 749 750 if (p_AdditionalParams->p_StatsObjForRmv) 751 PutStatsObj((t_FmPcdCcNode *)(p_AdditionalParams->h_CurrentNode), 752 p_AdditionalParams->p_StatsObjForRmv); 753 754 #if (DPAA_VERSION >= 11) 755 if (p_AdditionalParams->h_FrmReplicForRmv) 756 FrmReplicGroupUpdateOwner(p_AdditionalParams->h_FrmReplicForRmv, 757 FALSE/* remove */); 758 #endif /* (DPAA_VERSION >= 11) */ 759 760 if (!useShadowStructs) 761 { 762 h_Muram = FmPcdGetMuramHandle(h_FmPcd); 763 ASSERT_COND(h_Muram); 764 765 if ((p_AdditionalParams->tree && !((t_FmPcd *)h_FmPcd)->p_CcShadow) 766 || (!p_AdditionalParams->tree 767 && !((t_FmPcdCcNode *)(p_AdditionalParams->h_CurrentNode))->maxNumOfKeys)) 768 { 769 /* We release new AD which was allocated and updated for copy from to actual AD */ 770 for (p_Pos = NCSW_LIST_FIRST(h_FmPcdNewPointersLst); 771 p_Pos != (h_FmPcdNewPointersLst); p_Pos = NCSW_LIST_NEXT(p_Pos)) 772 { 773 774 p_CcNodeInformation = CC_NODE_F_OBJECT(p_Pos); 775 ASSERT_COND(p_CcNodeInformation->h_CcNode); 776 FM_MURAM_FreeMem(h_Muram, p_CcNodeInformation->h_CcNode); 777 } 778 } 779 780 /* Free Old data structure if it has to be freed - new data structure was allocated*/ 781 if (p_AdditionalParams->p_AdTableOld) 782 FM_MURAM_FreeMem(h_Muram, p_AdditionalParams->p_AdTableOld); 783 784 if (p_AdditionalParams->p_KeysMatchTableOld) 785 FM_MURAM_FreeMem(h_Muram, p_AdditionalParams->p_KeysMatchTableOld); 786 } 787 788 /* Update current modified node with changed fields if it's required*/ 789 if (!p_AdditionalParams->tree) 790 { 791 if (p_AdditionalParams->p_AdTableNew) 792 ((t_FmPcdCcNode *)(p_AdditionalParams->h_CurrentNode))->h_AdTable = 793 p_AdditionalParams->p_AdTableNew; 794 795 if (p_AdditionalParams->p_KeysMatchTableNew) 796 ((t_FmPcdCcNode *)(p_AdditionalParams->h_CurrentNode))->h_KeysMatchTable = 797 p_AdditionalParams->p_KeysMatchTableNew; 798 799 /* Locking node's spinlock before updating 'keys and next engine' structure, 800 as it maybe used to retrieve keys statistics */ 801 intFlags = 802 XX_LockIntrSpinlock( 803 ((t_FmPcdCcNode *)(p_AdditionalParams->h_CurrentNode))->h_Spinlock); 804 805 ((t_FmPcdCcNode *)(p_AdditionalParams->h_CurrentNode))->numOfKeys = 806 p_AdditionalParams->numOfKeys; 807 808 memcpy(((t_FmPcdCcNode *)(p_AdditionalParams->h_CurrentNode))->keyAndNextEngineParams, 809 &p_AdditionalParams->keyAndNextEngineParams, 810 sizeof(t_FmPcdCcKeyAndNextEngineParams) * (CC_MAX_NUM_OF_KEYS)); 811 812 XX_UnlockIntrSpinlock( 813 ((t_FmPcdCcNode *)(p_AdditionalParams->h_CurrentNode))->h_Spinlock, 814 intFlags); 815 } 816 else 817 { 818 uint8_t numEntries = 819 ((t_FmPcdCcTree *)(p_AdditionalParams->h_CurrentNode))->numOfEntries; 820 ASSERT_COND(numEntries < FM_PCD_MAX_NUM_OF_CC_GROUPS); 821 memcpy(&((t_FmPcdCcTree *)(p_AdditionalParams->h_CurrentNode))->keyAndNextEngineParams, 822 &p_AdditionalParams->keyAndNextEngineParams, 823 sizeof(t_FmPcdCcKeyAndNextEngineParams) * numEntries); 824 } 825 826 ReleaseLst(h_FmPcdOldPointersLst); 827 ReleaseLst(h_FmPcdNewPointersLst); 828 829 XX_Free(p_AdditionalParams); 830 831 return E_OK; 832 } 833 834 static t_Handle BuildNewAd( 835 t_Handle h_Ad, 836 t_FmPcdModifyCcKeyAdditionalParams *p_FmPcdModifyCcKeyAdditionalParams, 837 t_FmPcdCcNode *p_CcNode, 838 t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams) 839 { 840 t_FmPcdCcNode *p_FmPcdCcNodeTmp; 841 t_Handle h_OrigAd = NULL; 842 843 p_FmPcdCcNodeTmp = (t_FmPcdCcNode*)XX_Malloc(sizeof(t_FmPcdCcNode)); 844 if (!p_FmPcdCcNodeTmp) 845 { 846 REPORT_ERROR(MAJOR, E_NO_MEMORY, ("p_FmPcdCcNodeTmp")); 847 return NULL; 848 } 849 memset(p_FmPcdCcNodeTmp, 0, sizeof(t_FmPcdCcNode)); 850 851 p_FmPcdCcNodeTmp->numOfKeys = p_FmPcdModifyCcKeyAdditionalParams->numOfKeys; 852 p_FmPcdCcNodeTmp->h_KeysMatchTable = 853 p_FmPcdModifyCcKeyAdditionalParams->p_KeysMatchTableNew; 854 p_FmPcdCcNodeTmp->h_AdTable = 855 p_FmPcdModifyCcKeyAdditionalParams->p_AdTableNew; 856 857 p_FmPcdCcNodeTmp->lclMask = p_CcNode->lclMask; 858 p_FmPcdCcNodeTmp->parseCode = p_CcNode->parseCode; 859 p_FmPcdCcNodeTmp->offset = p_CcNode->offset; 860 p_FmPcdCcNodeTmp->prsArrayOffset = p_CcNode->prsArrayOffset; 861 p_FmPcdCcNodeTmp->ctrlFlow = p_CcNode->ctrlFlow; 862 p_FmPcdCcNodeTmp->ccKeySizeAccExtraction = p_CcNode->ccKeySizeAccExtraction; 863 p_FmPcdCcNodeTmp->sizeOfExtraction = p_CcNode->sizeOfExtraction; 864 p_FmPcdCcNodeTmp->glblMaskSize = p_CcNode->glblMaskSize; 865 p_FmPcdCcNodeTmp->p_GlblMask = p_CcNode->p_GlblMask; 866 867 if (p_FmPcdCcNextEngineParams->nextEngine == e_FM_PCD_CC) 868 { 869 if (p_FmPcdCcNextEngineParams->h_Manip) 870 { 871 h_OrigAd = p_CcNode->h_Ad; 872 if (AllocAndFillAdForContLookupManip( 873 p_FmPcdCcNextEngineParams->params.ccParams.h_CcNode) 874 != E_OK) 875 { 876 REPORT_ERROR(MAJOR, E_INVALID_STATE, NO_MSG); 877 XX_Free(p_FmPcdCcNodeTmp); 878 return NULL; 879 } 880 } 881 FillAdOfTypeContLookup(h_Ad, NULL, p_CcNode->h_FmPcd, p_FmPcdCcNodeTmp, 882 h_OrigAd ? NULL : p_FmPcdCcNextEngineParams->h_Manip, NULL); 883 } 884 885 #if (DPAA_VERSION >= 11) 886 if ((p_FmPcdCcNextEngineParams->nextEngine == e_FM_PCD_FR) 887 && (p_FmPcdCcNextEngineParams->params.frParams.h_FrmReplic)) 888 { 889 FillAdOfTypeContLookup( 890 h_Ad, NULL, p_CcNode->h_FmPcd, p_FmPcdCcNodeTmp, 891 p_FmPcdCcNextEngineParams->h_Manip, 892 p_FmPcdCcNextEngineParams->params.frParams.h_FrmReplic); 893 } 894 #endif /* (DPAA_VERSION >= 11) */ 895 896 XX_Free(p_FmPcdCcNodeTmp); 897 898 return E_OK; 899 } 900 901 static t_Error DynamicChangeHc( 902 t_Handle h_FmPcd, t_List *h_OldPointersLst, t_List *h_NewPointersLst, 903 t_FmPcdModifyCcKeyAdditionalParams *p_AdditionalParams, 904 bool useShadowStructs) 905 { 906 t_List *p_PosOld, *p_PosNew; 907 uint32_t oldAdAddrOffset, newAdAddrOffset; 908 uint16_t i = 0; 909 t_Error err = E_OK; 910 uint8_t numOfModifiedPtr; 911 912 ASSERT_COND(h_FmPcd); 913 ASSERT_COND(h_OldPointersLst); 914 ASSERT_COND(h_NewPointersLst); 915 916 numOfModifiedPtr = (uint8_t)NCSW_LIST_NumOfObjs(h_OldPointersLst); 917 918 if (numOfModifiedPtr) 919 { 920 p_PosNew = NCSW_LIST_FIRST(h_NewPointersLst); 921 p_PosOld = NCSW_LIST_FIRST(h_OldPointersLst); 922 923 /* Retrieve address of new AD */ 924 newAdAddrOffset = FmPcdCcGetNodeAddrOffsetFromNodeInfo(h_FmPcd, 925 p_PosNew); 926 if (newAdAddrOffset == (uint32_t)ILLEGAL_BASE) 927 { 928 ReleaseModifiedDataStructure(h_FmPcd, h_OldPointersLst, 929 h_NewPointersLst, 930 p_AdditionalParams, useShadowStructs); 931 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("New AD address")); 932 } 933 934 for (i = 0; i < numOfModifiedPtr; i++) 935 { 936 /* Retrieve address of current AD */ 937 oldAdAddrOffset = FmPcdCcGetNodeAddrOffsetFromNodeInfo(h_FmPcd, 938 p_PosOld); 939 if (oldAdAddrOffset == (uint32_t)ILLEGAL_BASE) 940 { 941 ReleaseModifiedDataStructure(h_FmPcd, h_OldPointersLst, 942 h_NewPointersLst, 943 p_AdditionalParams, 944 useShadowStructs); 945 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Old AD address")); 946 } 947 948 /* Invoke host command to copy from new AD to old AD */ 949 err = FmHcPcdCcDoDynamicChange(((t_FmPcd *)h_FmPcd)->h_Hc, 950 oldAdAddrOffset, newAdAddrOffset); 951 if (err) 952 { 953 ReleaseModifiedDataStructure(h_FmPcd, h_OldPointersLst, 954 h_NewPointersLst, 955 p_AdditionalParams, 956 useShadowStructs); 957 RETURN_ERROR( 958 MAJOR, 959 err, 960 ("For part of nodes changes are done - situation is danger")); 961 } 962 963 p_PosOld = NCSW_LIST_NEXT(p_PosOld); 964 } 965 } 966 return E_OK; 967 } 968 969 static t_Error DoDynamicChange( 970 t_Handle h_FmPcd, t_List *h_OldPointersLst, t_List *h_NewPointersLst, 971 t_FmPcdModifyCcKeyAdditionalParams *p_AdditionalParams, 972 bool useShadowStructs) 973 { 974 t_FmPcdCcNode *p_CcNode = 975 (t_FmPcdCcNode *)(p_AdditionalParams->h_CurrentNode); 976 t_List *p_PosNew; 977 t_CcNodeInformation *p_CcNodeInfo; 978 t_FmPcdCcNextEngineParams nextEngineParams; 979 t_Handle h_Ad; 980 uint32_t keySize; 981 t_Error err = E_OK; 982 uint8_t numOfModifiedPtr; 983 984 ASSERT_COND(h_FmPcd); 985 986 memset(&nextEngineParams, 0, sizeof(t_FmPcdCcNextEngineParams)); 987 988 numOfModifiedPtr = (uint8_t)NCSW_LIST_NumOfObjs(h_OldPointersLst); 989 990 if (numOfModifiedPtr) 991 { 992 993 p_PosNew = NCSW_LIST_FIRST(h_NewPointersLst); 994 995 /* Invoke host-command to copy from the new Ad to existing Ads */ 996 err = DynamicChangeHc(h_FmPcd, h_OldPointersLst, h_NewPointersLst, 997 p_AdditionalParams, useShadowStructs); 998 if (err) 999 RETURN_ERROR(MAJOR, err, NO_MSG); 1000 1001 if (useShadowStructs) 1002 { 1003 /* When the host-command above has ended, the old structures are 'free'and we can update 1004 them by copying from the new shadow structures. */ 1005 if (p_CcNode->lclMask) 1006 keySize = (uint32_t)(2 * p_CcNode->ccKeySizeAccExtraction); 1007 else 1008 keySize = p_CcNode->ccKeySizeAccExtraction; 1009 1010 MemCpy8(p_AdditionalParams->p_KeysMatchTableOld, 1011 p_AdditionalParams->p_KeysMatchTableNew, 1012 p_CcNode->maxNumOfKeys * keySize * sizeof(uint8_t)); 1013 1014 MemCpy8( 1015 p_AdditionalParams->p_AdTableOld, 1016 p_AdditionalParams->p_AdTableNew, 1017 (uint32_t)((p_CcNode->maxNumOfKeys + 1) 1018 * FM_PCD_CC_AD_ENTRY_SIZE)); 1019 1020 /* Retrieve the address of the allocated Ad */ 1021 p_CcNodeInfo = CC_NODE_F_OBJECT(p_PosNew); 1022 h_Ad = p_CcNodeInfo->h_CcNode; 1023 1024 /* Build a new Ad that holds the old (now updated) structures */ 1025 p_AdditionalParams->p_KeysMatchTableNew = 1026 p_AdditionalParams->p_KeysMatchTableOld; 1027 p_AdditionalParams->p_AdTableNew = p_AdditionalParams->p_AdTableOld; 1028 1029 nextEngineParams.nextEngine = e_FM_PCD_CC; 1030 nextEngineParams.params.ccParams.h_CcNode = (t_Handle)p_CcNode; 1031 1032 BuildNewAd(h_Ad, p_AdditionalParams, p_CcNode, &nextEngineParams); 1033 1034 /* HC to copy from the new Ad (old updated structures) to current Ad (uses shadow structures) */ 1035 err = DynamicChangeHc(h_FmPcd, h_OldPointersLst, h_NewPointersLst, 1036 p_AdditionalParams, useShadowStructs); 1037 if (err) 1038 RETURN_ERROR(MAJOR, err, NO_MSG); 1039 } 1040 } 1041 1042 err = ReleaseModifiedDataStructure(h_FmPcd, h_OldPointersLst, 1043 h_NewPointersLst, 1044 p_AdditionalParams, useShadowStructs); 1045 if (err) 1046 RETURN_ERROR(MAJOR, err, NO_MSG); 1047 1048 return E_OK; 1049 } 1050 1051 #ifdef FM_CAPWAP_SUPPORT 1052 static bool IsCapwapApplSpecific(t_Handle h_Node) 1053 { 1054 t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_Node; 1055 bool isManipForCapwapApplSpecificBuild = FALSE; 1056 int i = 0; 1057 1058 ASSERT_COND(h_Node); 1059 /* assumption that this function called only for INDEXED_FLOW_ID - so no miss*/ 1060 for (i = 0; i < p_CcNode->numOfKeys; i++) 1061 { 1062 if ( p_CcNode->keyAndNextEngineParams[i].nextEngineParams.h_Manip && 1063 FmPcdManipIsCapwapApplSpecific(p_CcNode->keyAndNextEngineParams[i].nextEngineParams.h_Manip)) 1064 { 1065 isManipForCapwapApplSpecificBuild = TRUE; 1066 break; 1067 } 1068 } 1069 return isManipForCapwapApplSpecificBuild; 1070 1071 } 1072 #endif /* FM_CAPWAP_SUPPORT */ 1073 1074 static t_Error CcUpdateParam( 1075 t_Handle h_FmPcd, t_Handle h_PcdParams, t_Handle h_FmPort, 1076 t_FmPcdCcKeyAndNextEngineParams *p_CcKeyAndNextEngineParams, 1077 uint16_t numOfEntries, t_Handle h_Ad, bool validate, uint16_t level, 1078 t_Handle h_FmTree, bool modify) 1079 { 1080 t_FmPcdCcNode *p_CcNode; 1081 t_Error err; 1082 uint16_t tmp = 0; 1083 int i = 0; 1084 t_FmPcdCcTree *p_CcTree = (t_FmPcdCcTree *)h_FmTree; 1085 1086 level++; 1087 1088 if (p_CcTree->h_IpReassemblyManip) 1089 { 1090 err = FmPcdManipUpdate(h_FmPcd, h_PcdParams, h_FmPort, 1091 p_CcTree->h_IpReassemblyManip, NULL, validate, 1092 level, h_FmTree, modify); 1093 if (err) 1094 RETURN_ERROR(MAJOR, err, NO_MSG); 1095 } 1096 1097 if (p_CcTree->h_CapwapReassemblyManip) 1098 { 1099 err = FmPcdManipUpdate(h_FmPcd, h_PcdParams, h_FmPort, 1100 p_CcTree->h_CapwapReassemblyManip, NULL, validate, 1101 level, h_FmTree, modify); 1102 if (err) 1103 RETURN_ERROR(MAJOR, err, NO_MSG); 1104 } 1105 1106 if (numOfEntries) 1107 { 1108 for (i = 0; i < numOfEntries; i++) 1109 { 1110 if (i == 0) 1111 h_Ad = PTR_MOVE(h_Ad, i*FM_PCD_CC_AD_ENTRY_SIZE); 1112 else 1113 h_Ad = PTR_MOVE(h_Ad, FM_PCD_CC_AD_ENTRY_SIZE); 1114 1115 if (p_CcKeyAndNextEngineParams[i].nextEngineParams.nextEngine 1116 == e_FM_PCD_CC) 1117 { 1118 p_CcNode = 1119 p_CcKeyAndNextEngineParams[i].nextEngineParams.params.ccParams.h_CcNode; 1120 ASSERT_COND(p_CcNode); 1121 1122 if (p_CcKeyAndNextEngineParams[i].nextEngineParams.h_Manip) 1123 { 1124 err = 1125 FmPcdManipUpdate( 1126 h_FmPcd, 1127 NULL, 1128 h_FmPort, 1129 p_CcKeyAndNextEngineParams[i].nextEngineParams.h_Manip, 1130 h_Ad, validate, level, h_FmTree, modify); 1131 if (err) 1132 RETURN_ERROR(MAJOR, err, NO_MSG); 1133 } 1134 1135 if (p_CcNode->keyAndNextEngineParams[p_CcNode->numOfKeys].nextEngineParams.nextEngine 1136 != e_FM_PCD_INVALID) 1137 tmp = (uint8_t)(p_CcNode->numOfKeys + 1); 1138 else 1139 tmp = p_CcNode->numOfKeys; 1140 1141 err = CcUpdateParam(h_FmPcd, h_PcdParams, h_FmPort, 1142 p_CcNode->keyAndNextEngineParams, tmp, 1143 p_CcNode->h_AdTable, validate, level, 1144 h_FmTree, modify); 1145 if (err) 1146 RETURN_ERROR(MAJOR, err, NO_MSG); 1147 } 1148 else 1149 { 1150 if (p_CcKeyAndNextEngineParams[i].nextEngineParams.h_Manip) 1151 { 1152 err = 1153 FmPcdManipUpdate( 1154 h_FmPcd, 1155 NULL, 1156 h_FmPort, 1157 p_CcKeyAndNextEngineParams[i].nextEngineParams.h_Manip, 1158 h_Ad, validate, level, h_FmTree, modify); 1159 if (err) 1160 RETURN_ERROR(MAJOR, err, NO_MSG); 1161 } 1162 } 1163 } 1164 } 1165 1166 return E_OK; 1167 } 1168 1169 static ccPrivateInfo_t IcDefineCode(t_FmPcdCcNodeParams *p_CcNodeParam) 1170 { 1171 switch (p_CcNodeParam->extractCcParams.extractNonHdr.action) 1172 { 1173 case (e_FM_PCD_ACTION_EXACT_MATCH): 1174 switch (p_CcNodeParam->extractCcParams.extractNonHdr.src) 1175 { 1176 case (e_FM_PCD_EXTRACT_FROM_KEY): 1177 return CC_PRIVATE_INFO_IC_KEY_EXACT_MATCH; 1178 case (e_FM_PCD_EXTRACT_FROM_HASH): 1179 return CC_PRIVATE_INFO_IC_HASH_EXACT_MATCH; 1180 default: 1181 return CC_PRIVATE_INFO_NONE; 1182 } 1183 1184 case (e_FM_PCD_ACTION_INDEXED_LOOKUP): 1185 switch (p_CcNodeParam->extractCcParams.extractNonHdr.src) 1186 { 1187 case (e_FM_PCD_EXTRACT_FROM_HASH): 1188 return CC_PRIVATE_INFO_IC_HASH_INDEX_LOOKUP; 1189 case (e_FM_PCD_EXTRACT_FROM_FLOW_ID): 1190 return CC_PRIVATE_INFO_IC_DEQ_FQID_INDEX_LOOKUP; 1191 default: 1192 return CC_PRIVATE_INFO_NONE; 1193 } 1194 1195 default: 1196 break; 1197 } 1198 1199 return CC_PRIVATE_INFO_NONE; 1200 } 1201 1202 static t_CcNodeInformation * DequeueAdditionalInfoFromRelevantLst( 1203 t_List *p_List) 1204 { 1205 t_CcNodeInformation *p_CcNodeInfo = NULL; 1206 1207 if (!NCSW_LIST_IsEmpty(p_List)) 1208 { 1209 p_CcNodeInfo = CC_NODE_F_OBJECT(p_List->p_Next); 1210 NCSW_LIST_DelAndInit(&p_CcNodeInfo->node); 1211 } 1212 1213 return p_CcNodeInfo; 1214 } 1215 1216 void ReleaseLst(t_List *p_List) 1217 { 1218 t_CcNodeInformation *p_CcNodeInfo = NULL; 1219 1220 if (!NCSW_LIST_IsEmpty(p_List)) 1221 { 1222 p_CcNodeInfo = DequeueAdditionalInfoFromRelevantLst(p_List); 1223 while (p_CcNodeInfo) 1224 { 1225 XX_Free(p_CcNodeInfo); 1226 p_CcNodeInfo = DequeueAdditionalInfoFromRelevantLst(p_List); 1227 } 1228 } 1229 1230 NCSW_LIST_Del(p_List); 1231 } 1232 1233 static void DeleteNode(t_FmPcdCcNode *p_CcNode) 1234 { 1235 uint32_t i; 1236 1237 if (!p_CcNode) 1238 return; 1239 1240 if (p_CcNode->p_GlblMask) 1241 { 1242 XX_Free(p_CcNode->p_GlblMask); 1243 p_CcNode->p_GlblMask = NULL; 1244 } 1245 1246 if (p_CcNode->h_KeysMatchTable) 1247 { 1248 FM_MURAM_FreeMem(FmPcdGetMuramHandle(p_CcNode->h_FmPcd), 1249 p_CcNode->h_KeysMatchTable); 1250 p_CcNode->h_KeysMatchTable = NULL; 1251 } 1252 1253 if (p_CcNode->h_AdTable) 1254 { 1255 FM_MURAM_FreeMem(FmPcdGetMuramHandle(p_CcNode->h_FmPcd), 1256 p_CcNode->h_AdTable); 1257 p_CcNode->h_AdTable = NULL; 1258 } 1259 1260 if (p_CcNode->h_Ad) 1261 { 1262 FM_MURAM_FreeMem(FmPcdGetMuramHandle(p_CcNode->h_FmPcd), 1263 p_CcNode->h_Ad); 1264 p_CcNode->h_Ad = NULL; 1265 p_CcNode->h_TmpAd = NULL; 1266 } 1267 1268 if (p_CcNode->h_StatsFLRs) 1269 { 1270 FM_MURAM_FreeMem(FmPcdGetMuramHandle(p_CcNode->h_FmPcd), 1271 p_CcNode->h_StatsFLRs); 1272 p_CcNode->h_StatsFLRs = NULL; 1273 } 1274 1275 if (p_CcNode->h_Spinlock) 1276 { 1277 XX_FreeSpinlock(p_CcNode->h_Spinlock); 1278 p_CcNode->h_Spinlock = NULL; 1279 } 1280 1281 /* Restore the original counters pointer instead of the mutual pointer (mutual to all hash buckets) */ 1282 if (p_CcNode->isHashBucket 1283 && (p_CcNode->statisticsMode != e_FM_PCD_CC_STATS_MODE_NONE)) 1284 p_CcNode->keyAndNextEngineParams[p_CcNode->numOfKeys].p_StatsObj->h_StatsCounters = 1285 p_CcNode->h_PrivMissStatsCounters; 1286 1287 /* Releasing all currently used statistics objects, including 'miss' entry */ 1288 for (i = 0; i < p_CcNode->numOfKeys + 1; i++) 1289 if (p_CcNode->keyAndNextEngineParams[i].p_StatsObj) 1290 PutStatsObj(p_CcNode, 1291 p_CcNode->keyAndNextEngineParams[i].p_StatsObj); 1292 1293 if (!NCSW_LIST_IsEmpty(&p_CcNode->availableStatsLst)) 1294 { 1295 t_Handle h_FmMuram = FmPcdGetMuramHandle(p_CcNode->h_FmPcd); 1296 ASSERT_COND(h_FmMuram); 1297 1298 FreeStatObjects(&p_CcNode->availableStatsLst, h_FmMuram); 1299 } 1300 1301 NCSW_LIST_Del(&p_CcNode->availableStatsLst); 1302 1303 ReleaseLst(&p_CcNode->ccPrevNodesLst); 1304 ReleaseLst(&p_CcNode->ccTreeIdLst); 1305 ReleaseLst(&p_CcNode->ccTreesLst); 1306 1307 XX_Free(p_CcNode); 1308 } 1309 1310 static void DeleteTree(t_FmPcdCcTree *p_FmPcdTree, t_FmPcd *p_FmPcd) 1311 { 1312 if (p_FmPcdTree) 1313 { 1314 if (p_FmPcdTree->ccTreeBaseAddr) 1315 { 1316 FM_MURAM_FreeMem(FmPcdGetMuramHandle(p_FmPcd), 1317 UINT_TO_PTR(p_FmPcdTree->ccTreeBaseAddr)); 1318 p_FmPcdTree->ccTreeBaseAddr = 0; 1319 } 1320 1321 ReleaseLst(&p_FmPcdTree->fmPortsLst); 1322 1323 XX_Free(p_FmPcdTree); 1324 } 1325 } 1326 1327 static void GetCcExtractKeySize(uint8_t parseCodeRealSize, 1328 uint8_t *parseCodeCcSize) 1329 { 1330 if ((parseCodeRealSize > 0) && (parseCodeRealSize < 2)) 1331 *parseCodeCcSize = 1; 1332 else 1333 if (parseCodeRealSize == 2) 1334 *parseCodeCcSize = 2; 1335 else 1336 if ((parseCodeRealSize > 2) && (parseCodeRealSize <= 4)) 1337 *parseCodeCcSize = 4; 1338 else 1339 if ((parseCodeRealSize > 4) && (parseCodeRealSize <= 8)) 1340 *parseCodeCcSize = 8; 1341 else 1342 if ((parseCodeRealSize > 8) && (parseCodeRealSize <= 16)) 1343 *parseCodeCcSize = 16; 1344 else 1345 if ((parseCodeRealSize > 16) 1346 && (parseCodeRealSize <= 24)) 1347 *parseCodeCcSize = 24; 1348 else 1349 if ((parseCodeRealSize > 24) 1350 && (parseCodeRealSize <= 32)) 1351 *parseCodeCcSize = 32; 1352 else 1353 if ((parseCodeRealSize > 32) 1354 && (parseCodeRealSize <= 40)) 1355 *parseCodeCcSize = 40; 1356 else 1357 if ((parseCodeRealSize > 40) 1358 && (parseCodeRealSize <= 48)) 1359 *parseCodeCcSize = 48; 1360 else 1361 if ((parseCodeRealSize > 48) 1362 && (parseCodeRealSize <= 56)) 1363 *parseCodeCcSize = 56; 1364 else 1365 *parseCodeCcSize = 0; 1366 } 1367 1368 static void GetSizeHeaderField(e_NetHeaderType hdr, t_FmPcdFields field, 1369 uint8_t *parseCodeRealSize) 1370 { 1371 switch (hdr) 1372 { 1373 case (HEADER_TYPE_ETH): 1374 switch (field.eth) 1375 { 1376 case (NET_HEADER_FIELD_ETH_DA): 1377 *parseCodeRealSize = 6; 1378 break; 1379 1380 case (NET_HEADER_FIELD_ETH_SA): 1381 *parseCodeRealSize = 6; 1382 break; 1383 1384 case (NET_HEADER_FIELD_ETH_TYPE): 1385 *parseCodeRealSize = 2; 1386 break; 1387 1388 default: 1389 REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported1")); 1390 *parseCodeRealSize = CC_SIZE_ILLEGAL; 1391 break; 1392 } 1393 break; 1394 1395 case (HEADER_TYPE_PPPoE): 1396 switch (field.pppoe) 1397 { 1398 case (NET_HEADER_FIELD_PPPoE_PID): 1399 *parseCodeRealSize = 2; 1400 break; 1401 1402 default: 1403 REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported1")); 1404 *parseCodeRealSize = CC_SIZE_ILLEGAL; 1405 break; 1406 } 1407 break; 1408 1409 case (HEADER_TYPE_VLAN): 1410 switch (field.vlan) 1411 { 1412 case (NET_HEADER_FIELD_VLAN_TCI): 1413 *parseCodeRealSize = 2; 1414 break; 1415 1416 default: 1417 REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported2")); 1418 *parseCodeRealSize = CC_SIZE_ILLEGAL; 1419 break; 1420 } 1421 break; 1422 1423 case (HEADER_TYPE_MPLS): 1424 switch (field.mpls) 1425 { 1426 case (NET_HEADER_FIELD_MPLS_LABEL_STACK): 1427 *parseCodeRealSize = 4; 1428 break; 1429 1430 default: 1431 REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported3")); 1432 *parseCodeRealSize = CC_SIZE_ILLEGAL; 1433 break; 1434 } 1435 break; 1436 1437 case (HEADER_TYPE_IPv4): 1438 switch (field.ipv4) 1439 { 1440 case (NET_HEADER_FIELD_IPv4_DST_IP): 1441 case (NET_HEADER_FIELD_IPv4_SRC_IP): 1442 *parseCodeRealSize = 4; 1443 break; 1444 1445 case (NET_HEADER_FIELD_IPv4_TOS): 1446 case (NET_HEADER_FIELD_IPv4_PROTO): 1447 *parseCodeRealSize = 1; 1448 break; 1449 1450 case (NET_HEADER_FIELD_IPv4_DST_IP 1451 | NET_HEADER_FIELD_IPv4_SRC_IP): 1452 *parseCodeRealSize = 8; 1453 break; 1454 1455 case (NET_HEADER_FIELD_IPv4_TTL): 1456 *parseCodeRealSize = 1; 1457 break; 1458 1459 default: 1460 REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported4")); 1461 *parseCodeRealSize = CC_SIZE_ILLEGAL; 1462 break; 1463 } 1464 break; 1465 1466 case (HEADER_TYPE_IPv6): 1467 switch (field.ipv6) 1468 { 1469 case (NET_HEADER_FIELD_IPv6_VER | NET_HEADER_FIELD_IPv6_FL 1470 | NET_HEADER_FIELD_IPv6_TC): 1471 *parseCodeRealSize = 4; 1472 break; 1473 1474 case (NET_HEADER_FIELD_IPv6_NEXT_HDR): 1475 case (NET_HEADER_FIELD_IPv6_HOP_LIMIT): 1476 *parseCodeRealSize = 1; 1477 break; 1478 1479 case (NET_HEADER_FIELD_IPv6_DST_IP): 1480 case (NET_HEADER_FIELD_IPv6_SRC_IP): 1481 *parseCodeRealSize = 16; 1482 break; 1483 1484 default: 1485 REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported5")); 1486 *parseCodeRealSize = CC_SIZE_ILLEGAL; 1487 break; 1488 } 1489 break; 1490 1491 case (HEADER_TYPE_IP): 1492 switch (field.ip) 1493 { 1494 case (NET_HEADER_FIELD_IP_DSCP): 1495 case (NET_HEADER_FIELD_IP_PROTO): 1496 *parseCodeRealSize = 1; 1497 break; 1498 1499 default: 1500 REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported5")); 1501 *parseCodeRealSize = CC_SIZE_ILLEGAL; 1502 break; 1503 } 1504 break; 1505 1506 case (HEADER_TYPE_GRE): 1507 switch (field.gre) 1508 { 1509 case (NET_HEADER_FIELD_GRE_TYPE): 1510 *parseCodeRealSize = 2; 1511 break; 1512 1513 default: 1514 REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported6")); 1515 *parseCodeRealSize = CC_SIZE_ILLEGAL; 1516 break; 1517 } 1518 break; 1519 1520 case (HEADER_TYPE_MINENCAP): 1521 switch (field.minencap) 1522 { 1523 case (NET_HEADER_FIELD_MINENCAP_TYPE): 1524 *parseCodeRealSize = 1; 1525 break; 1526 1527 case (NET_HEADER_FIELD_MINENCAP_DST_IP): 1528 case (NET_HEADER_FIELD_MINENCAP_SRC_IP): 1529 *parseCodeRealSize = 4; 1530 break; 1531 1532 case (NET_HEADER_FIELD_MINENCAP_SRC_IP 1533 | NET_HEADER_FIELD_MINENCAP_DST_IP): 1534 *parseCodeRealSize = 8; 1535 break; 1536 1537 default: 1538 REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported7")); 1539 *parseCodeRealSize = CC_SIZE_ILLEGAL; 1540 break; 1541 } 1542 break; 1543 1544 case (HEADER_TYPE_TCP): 1545 switch (field.tcp) 1546 { 1547 case (NET_HEADER_FIELD_TCP_PORT_SRC): 1548 case (NET_HEADER_FIELD_TCP_PORT_DST): 1549 *parseCodeRealSize = 2; 1550 break; 1551 1552 case (NET_HEADER_FIELD_TCP_PORT_SRC 1553 | NET_HEADER_FIELD_TCP_PORT_DST): 1554 *parseCodeRealSize = 4; 1555 break; 1556 1557 default: 1558 REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported8")); 1559 *parseCodeRealSize = CC_SIZE_ILLEGAL; 1560 break; 1561 } 1562 break; 1563 1564 case (HEADER_TYPE_UDP): 1565 switch (field.udp) 1566 { 1567 case (NET_HEADER_FIELD_UDP_PORT_SRC): 1568 case (NET_HEADER_FIELD_UDP_PORT_DST): 1569 *parseCodeRealSize = 2; 1570 break; 1571 1572 case (NET_HEADER_FIELD_UDP_PORT_SRC 1573 | NET_HEADER_FIELD_UDP_PORT_DST): 1574 *parseCodeRealSize = 4; 1575 break; 1576 1577 default: 1578 REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported9")); 1579 *parseCodeRealSize = CC_SIZE_ILLEGAL; 1580 break; 1581 } 1582 break; 1583 1584 default: 1585 REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported10")); 1586 *parseCodeRealSize = CC_SIZE_ILLEGAL; 1587 break; 1588 } 1589 } 1590 1591 t_Error ValidateNextEngineParams( 1592 t_Handle h_FmPcd, t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams, 1593 e_FmPcdCcStatsMode statsMode) 1594 { 1595 uint16_t absoluteProfileId; 1596 t_Error err = E_OK; 1597 uint8_t relativeSchemeId; 1598 1599 if ((statsMode == e_FM_PCD_CC_STATS_MODE_NONE) 1600 && (p_FmPcdCcNextEngineParams->statisticsEn)) 1601 RETURN_ERROR( 1602 MAJOR, 1603 E_CONFLICT, 1604 ("Statistics are requested for a key, but statistics mode was set" 1605 "to 'NONE' upon initialization")); 1606 1607 switch (p_FmPcdCcNextEngineParams->nextEngine) 1608 { 1609 case (e_FM_PCD_INVALID): 1610 err = E_NOT_SUPPORTED; 1611 break; 1612 1613 case (e_FM_PCD_DONE): 1614 if ((p_FmPcdCcNextEngineParams->params.enqueueParams.action 1615 == e_FM_PCD_ENQ_FRAME) 1616 && p_FmPcdCcNextEngineParams->params.enqueueParams.overrideFqid) 1617 { 1618 if (!p_FmPcdCcNextEngineParams->params.enqueueParams.newFqid) 1619 RETURN_ERROR( 1620 MAJOR, 1621 E_CONFLICT, 1622 ("When overrideFqid is set, newFqid must not be zero")); 1623 if (p_FmPcdCcNextEngineParams->params.enqueueParams.newFqid 1624 & ~0x00FFFFFF) 1625 RETURN_ERROR( 1626 MAJOR, E_INVALID_VALUE, 1627 ("fqidForCtrlFlow must be between 1 and 2^24-1")); 1628 } 1629 break; 1630 1631 case (e_FM_PCD_KG): 1632 relativeSchemeId = 1633 FmPcdKgGetRelativeSchemeId( 1634 h_FmPcd, 1635 FmPcdKgGetSchemeId( 1636 p_FmPcdCcNextEngineParams->params.kgParams.h_DirectScheme)); 1637 if (relativeSchemeId == FM_PCD_KG_NUM_OF_SCHEMES) 1638 RETURN_ERROR(MAJOR, E_NOT_IN_RANGE, NO_MSG); 1639 if (!FmPcdKgIsSchemeValidSw( 1640 p_FmPcdCcNextEngineParams->params.kgParams.h_DirectScheme)) 1641 RETURN_ERROR(MAJOR, E_INVALID_STATE, 1642 ("not valid schemeIndex in KG next engine param")); 1643 if (!KgIsSchemeAlwaysDirect(h_FmPcd, relativeSchemeId)) 1644 RETURN_ERROR( 1645 MAJOR, 1646 E_INVALID_STATE, 1647 ("CC Node may point only to a scheme that is always direct.")); 1648 break; 1649 1650 case (e_FM_PCD_PLCR): 1651 if (p_FmPcdCcNextEngineParams->params.plcrParams.overrideParams) 1652 { 1653 /* if private policer profile, it may be uninitialized yet, therefore no checks are done at this stage */ 1654 if (p_FmPcdCcNextEngineParams->params.plcrParams.sharedProfile) 1655 { 1656 err = 1657 FmPcdPlcrGetAbsoluteIdByProfileParams( 1658 h_FmPcd, 1659 e_FM_PCD_PLCR_SHARED, 1660 NULL, 1661 p_FmPcdCcNextEngineParams->params.plcrParams.newRelativeProfileId, 1662 &absoluteProfileId); 1663 if (err) 1664 RETURN_ERROR(MAJOR, err, 1665 ("Shared profile offset is out of range")); 1666 if (!FmPcdPlcrIsProfileValid(h_FmPcd, absoluteProfileId)) 1667 RETURN_ERROR(MAJOR, E_INVALID_STATE, 1668 ("Invalid profile")); 1669 } 1670 } 1671 break; 1672 1673 case (e_FM_PCD_HASH): 1674 p_FmPcdCcNextEngineParams->nextEngine = e_FM_PCD_CC; 1675 case (e_FM_PCD_CC): 1676 if (!p_FmPcdCcNextEngineParams->params.ccParams.h_CcNode) 1677 RETURN_ERROR(MAJOR, E_NULL_POINTER, 1678 ("handler to next Node is NULL")); 1679 break; 1680 1681 #if (DPAA_VERSION >= 11) 1682 case (e_FM_PCD_FR): 1683 if (!p_FmPcdCcNextEngineParams->params.frParams.h_FrmReplic) 1684 err = E_NOT_SUPPORTED; 1685 break; 1686 #endif /* (DPAA_VERSION >= 11) */ 1687 1688 default: 1689 RETURN_ERROR(MAJOR, E_INVALID_STATE, 1690 ("Next engine is not correct")); 1691 } 1692 1693 1694 return err; 1695 } 1696 1697 static uint8_t GetGenParseCode(e_FmPcdExtractFrom src, 1698 uint32_t offset, bool glblMask, 1699 uint8_t *parseArrayOffset, bool fromIc, 1700 ccPrivateInfo_t icCode) 1701 { 1702 if (!fromIc) 1703 { 1704 switch (src) 1705 { 1706 case (e_FM_PCD_EXTRACT_FROM_FRAME_START): 1707 if (glblMask) 1708 return CC_PC_GENERIC_WITH_MASK; 1709 else 1710 return CC_PC_GENERIC_WITHOUT_MASK; 1711 1712 case (e_FM_PCD_EXTRACT_FROM_CURR_END_OF_PARSE): 1713 *parseArrayOffset = CC_PC_PR_NEXT_HEADER_OFFSET; 1714 if (offset) 1715 return CC_PR_OFFSET; 1716 else 1717 return CC_PR_WITHOUT_OFFSET; 1718 1719 default: 1720 REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal 'extract from' src")); 1721 return CC_PC_ILLEGAL; 1722 } 1723 } 1724 else 1725 { 1726 switch (icCode) 1727 { 1728 case (CC_PRIVATE_INFO_IC_KEY_EXACT_MATCH): 1729 *parseArrayOffset = 0x50; 1730 return CC_PC_GENERIC_IC_GMASK; 1731 1732 case (CC_PRIVATE_INFO_IC_HASH_EXACT_MATCH): 1733 *parseArrayOffset = 0x48; 1734 return CC_PC_GENERIC_IC_GMASK; 1735 1736 case (CC_PRIVATE_INFO_IC_HASH_INDEX_LOOKUP): 1737 *parseArrayOffset = 0x48; 1738 return CC_PC_GENERIC_IC_HASH_INDEXED; 1739 1740 case (CC_PRIVATE_INFO_IC_DEQ_FQID_INDEX_LOOKUP): 1741 *parseArrayOffset = 0x16; 1742 return CC_PC_GENERIC_IC_HASH_INDEXED; 1743 1744 default: 1745 REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal 'extract from' src")); 1746 break; 1747 } 1748 } 1749 1750 return CC_PC_ILLEGAL; 1751 } 1752 1753 static uint8_t GetFullFieldParseCode(e_NetHeaderType hdr, e_FmPcdHdrIndex index, 1754 t_FmPcdFields field) 1755 { 1756 switch (hdr) 1757 { 1758 case (HEADER_TYPE_NONE): 1759 ASSERT_COND(FALSE); 1760 return CC_PC_ILLEGAL; 1761 1762 case (HEADER_TYPE_ETH): 1763 switch (field.eth) 1764 { 1765 case (NET_HEADER_FIELD_ETH_DA): 1766 return CC_PC_FF_MACDST; 1767 case (NET_HEADER_FIELD_ETH_SA): 1768 return CC_PC_FF_MACSRC; 1769 case (NET_HEADER_FIELD_ETH_TYPE): 1770 return CC_PC_FF_ETYPE; 1771 default: 1772 REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported")); 1773 return CC_PC_ILLEGAL; 1774 } 1775 1776 case (HEADER_TYPE_VLAN): 1777 switch (field.vlan) 1778 { 1779 case (NET_HEADER_FIELD_VLAN_TCI): 1780 if ((index == e_FM_PCD_HDR_INDEX_NONE) 1781 || (index == e_FM_PCD_HDR_INDEX_1)) 1782 return CC_PC_FF_TCI1; 1783 if (index == e_FM_PCD_HDR_INDEX_LAST) 1784 return CC_PC_FF_TCI2; 1785 REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported")); 1786 return CC_PC_ILLEGAL; 1787 default: 1788 REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported")); 1789 return CC_PC_ILLEGAL; 1790 } 1791 1792 case (HEADER_TYPE_MPLS): 1793 switch (field.mpls) 1794 { 1795 case (NET_HEADER_FIELD_MPLS_LABEL_STACK): 1796 if ((index == e_FM_PCD_HDR_INDEX_NONE) 1797 || (index == e_FM_PCD_HDR_INDEX_1)) 1798 return CC_PC_FF_MPLS1; 1799 if (index == e_FM_PCD_HDR_INDEX_LAST) 1800 return CC_PC_FF_MPLS_LAST; 1801 REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal MPLS index")); 1802 return CC_PC_ILLEGAL; 1803 default: 1804 REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported")); 1805 return CC_PC_ILLEGAL; 1806 } 1807 1808 case (HEADER_TYPE_IPv4): 1809 switch (field.ipv4) 1810 { 1811 case (NET_HEADER_FIELD_IPv4_DST_IP): 1812 if ((index == e_FM_PCD_HDR_INDEX_NONE) 1813 || (index == e_FM_PCD_HDR_INDEX_1)) 1814 return CC_PC_FF_IPV4DST1; 1815 if (index == e_FM_PCD_HDR_INDEX_2) 1816 return CC_PC_FF_IPV4DST2; 1817 REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv4 index")); 1818 return CC_PC_ILLEGAL; 1819 case (NET_HEADER_FIELD_IPv4_TOS): 1820 if ((index == e_FM_PCD_HDR_INDEX_NONE) 1821 || (index == e_FM_PCD_HDR_INDEX_1)) 1822 return CC_PC_FF_IPV4IPTOS_TC1; 1823 if (index == e_FM_PCD_HDR_INDEX_2) 1824 return CC_PC_FF_IPV4IPTOS_TC2; 1825 REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv4 index")); 1826 return CC_PC_ILLEGAL; 1827 case (NET_HEADER_FIELD_IPv4_PROTO): 1828 if ((index == e_FM_PCD_HDR_INDEX_NONE) 1829 || (index == e_FM_PCD_HDR_INDEX_1)) 1830 return CC_PC_FF_IPV4PTYPE1; 1831 if (index == e_FM_PCD_HDR_INDEX_2) 1832 return CC_PC_FF_IPV4PTYPE2; 1833 REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv4 index")); 1834 return CC_PC_ILLEGAL; 1835 case (NET_HEADER_FIELD_IPv4_SRC_IP): 1836 if ((index == e_FM_PCD_HDR_INDEX_NONE) 1837 || (index == e_FM_PCD_HDR_INDEX_1)) 1838 return CC_PC_FF_IPV4SRC1; 1839 if (index == e_FM_PCD_HDR_INDEX_2) 1840 return CC_PC_FF_IPV4SRC2; 1841 REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv4 index")); 1842 return CC_PC_ILLEGAL; 1843 case (NET_HEADER_FIELD_IPv4_SRC_IP 1844 | NET_HEADER_FIELD_IPv4_DST_IP): 1845 if ((index == e_FM_PCD_HDR_INDEX_NONE) 1846 || (index == e_FM_PCD_HDR_INDEX_1)) 1847 return CC_PC_FF_IPV4SRC1_IPV4DST1; 1848 if (index == e_FM_PCD_HDR_INDEX_2) 1849 return CC_PC_FF_IPV4SRC2_IPV4DST2; 1850 REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv4 index")); 1851 return CC_PC_ILLEGAL; 1852 case (NET_HEADER_FIELD_IPv4_TTL): 1853 return CC_PC_FF_IPV4TTL; 1854 default: 1855 REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported")); 1856 return CC_PC_ILLEGAL; 1857 } 1858 1859 case (HEADER_TYPE_IPv6): 1860 switch (field.ipv6) 1861 { 1862 case (NET_HEADER_FIELD_IPv6_VER | NET_HEADER_FIELD_IPv6_FL 1863 | NET_HEADER_FIELD_IPv6_TC): 1864 if ((index == e_FM_PCD_HDR_INDEX_NONE) 1865 || (index == e_FM_PCD_HDR_INDEX_1)) 1866 return CC_PC_FF_IPTOS_IPV6TC1_IPV6FLOW1; 1867 if (index == e_FM_PCD_HDR_INDEX_2) 1868 return CC_PC_FF_IPTOS_IPV6TC2_IPV6FLOW2; 1869 REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv6 index")); 1870 return CC_PC_ILLEGAL; 1871 1872 case (NET_HEADER_FIELD_IPv6_NEXT_HDR): 1873 if ((index == e_FM_PCD_HDR_INDEX_NONE) 1874 || (index == e_FM_PCD_HDR_INDEX_1)) 1875 return CC_PC_FF_IPV6PTYPE1; 1876 if (index == e_FM_PCD_HDR_INDEX_2) 1877 return CC_PC_FF_IPV6PTYPE2; 1878 if (index == e_FM_PCD_HDR_INDEX_LAST) 1879 return CC_PC_FF_IPPID; 1880 REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv6 index")); 1881 return CC_PC_ILLEGAL; 1882 1883 case (NET_HEADER_FIELD_IPv6_DST_IP): 1884 if ((index == e_FM_PCD_HDR_INDEX_NONE) 1885 || (index == e_FM_PCD_HDR_INDEX_1)) 1886 return CC_PC_FF_IPV6DST1; 1887 if (index == e_FM_PCD_HDR_INDEX_2) 1888 return CC_PC_FF_IPV6DST2; 1889 REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv6 index")); 1890 return CC_PC_ILLEGAL; 1891 1892 case (NET_HEADER_FIELD_IPv6_SRC_IP): 1893 if ((index == e_FM_PCD_HDR_INDEX_NONE) 1894 || (index == e_FM_PCD_HDR_INDEX_1)) 1895 return CC_PC_FF_IPV6SRC1; 1896 if (index == e_FM_PCD_HDR_INDEX_2) 1897 return CC_PC_FF_IPV6SRC2; 1898 REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv6 index")); 1899 return CC_PC_ILLEGAL; 1900 1901 case (NET_HEADER_FIELD_IPv6_HOP_LIMIT): 1902 return CC_PC_FF_IPV6HOP_LIMIT; 1903 1904 default: 1905 REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported")); 1906 return CC_PC_ILLEGAL; 1907 } 1908 1909 case (HEADER_TYPE_IP): 1910 switch (field.ip) 1911 { 1912 case (NET_HEADER_FIELD_IP_DSCP): 1913 if ((index == e_FM_PCD_HDR_INDEX_NONE) 1914 || (index == e_FM_PCD_HDR_INDEX_1)) 1915 return CC_PC_FF_IPDSCP; 1916 REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IP index")); 1917 return CC_PC_ILLEGAL; 1918 1919 case (NET_HEADER_FIELD_IP_PROTO): 1920 if (index == e_FM_PCD_HDR_INDEX_LAST) 1921 return CC_PC_FF_IPPID; 1922 REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IP index")); 1923 return CC_PC_ILLEGAL; 1924 1925 default: 1926 REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported")); 1927 return CC_PC_ILLEGAL; 1928 } 1929 1930 case (HEADER_TYPE_GRE): 1931 switch (field.gre) 1932 { 1933 case (NET_HEADER_FIELD_GRE_TYPE): 1934 return CC_PC_FF_GREPTYPE; 1935 1936 default: 1937 REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported")); 1938 return CC_PC_ILLEGAL; 1939 } 1940 1941 case (HEADER_TYPE_MINENCAP): 1942 switch (field.minencap) 1943 { 1944 case (NET_HEADER_FIELD_MINENCAP_TYPE): 1945 return CC_PC_FF_MINENCAP_PTYPE; 1946 1947 case (NET_HEADER_FIELD_MINENCAP_DST_IP): 1948 return CC_PC_FF_MINENCAP_IPDST; 1949 1950 case (NET_HEADER_FIELD_MINENCAP_SRC_IP): 1951 return CC_PC_FF_MINENCAP_IPSRC; 1952 1953 case (NET_HEADER_FIELD_MINENCAP_SRC_IP 1954 | NET_HEADER_FIELD_MINENCAP_DST_IP): 1955 return CC_PC_FF_MINENCAP_IPSRC_IPDST; 1956 1957 default: 1958 REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported")); 1959 return CC_PC_ILLEGAL; 1960 } 1961 1962 case (HEADER_TYPE_TCP): 1963 switch (field.tcp) 1964 { 1965 case (NET_HEADER_FIELD_TCP_PORT_SRC): 1966 return CC_PC_FF_L4PSRC; 1967 1968 case (NET_HEADER_FIELD_TCP_PORT_DST): 1969 return CC_PC_FF_L4PDST; 1970 1971 case (NET_HEADER_FIELD_TCP_PORT_DST 1972 | NET_HEADER_FIELD_TCP_PORT_SRC): 1973 return CC_PC_FF_L4PSRC_L4PDST; 1974 1975 default: 1976 REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported")); 1977 return CC_PC_ILLEGAL; 1978 } 1979 1980 case (HEADER_TYPE_PPPoE): 1981 switch (field.pppoe) 1982 { 1983 case (NET_HEADER_FIELD_PPPoE_PID): 1984 return CC_PC_FF_PPPPID; 1985 1986 default: 1987 REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported")); 1988 return CC_PC_ILLEGAL; 1989 } 1990 1991 case (HEADER_TYPE_UDP): 1992 switch (field.udp) 1993 { 1994 case (NET_HEADER_FIELD_UDP_PORT_SRC): 1995 return CC_PC_FF_L4PSRC; 1996 1997 case (NET_HEADER_FIELD_UDP_PORT_DST): 1998 return CC_PC_FF_L4PDST; 1999 2000 case (NET_HEADER_FIELD_UDP_PORT_DST 2001 | NET_HEADER_FIELD_UDP_PORT_SRC): 2002 return CC_PC_FF_L4PSRC_L4PDST; 2003 2004 default: 2005 REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported")); 2006 return CC_PC_ILLEGAL; 2007 } 2008 2009 default: 2010 REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported")); 2011 return CC_PC_ILLEGAL; 2012 } 2013 } 2014 2015 static uint8_t GetPrParseCode(e_NetHeaderType hdr, e_FmPcdHdrIndex hdrIndex, 2016 uint32_t offset, bool glblMask, 2017 uint8_t *parseArrayOffset) 2018 { 2019 bool offsetRelevant = FALSE; 2020 2021 if (offset) 2022 offsetRelevant = TRUE; 2023 2024 switch (hdr) 2025 { 2026 case (HEADER_TYPE_NONE): 2027 ASSERT_COND(FALSE); 2028 return CC_PC_ILLEGAL; 2029 2030 case (HEADER_TYPE_ETH): 2031 *parseArrayOffset = (uint8_t)CC_PC_PR_ETH_OFFSET; 2032 break; 2033 2034 case (HEADER_TYPE_USER_DEFINED_SHIM1): 2035 if (offset || glblMask) 2036 *parseArrayOffset = (uint8_t)CC_PC_PR_USER_DEFINED_SHIM1_OFFSET; 2037 else 2038 return CC_PC_PR_SHIM1; 2039 break; 2040 2041 case (HEADER_TYPE_USER_DEFINED_SHIM2): 2042 if (offset || glblMask) 2043 *parseArrayOffset = (uint8_t)CC_PC_PR_USER_DEFINED_SHIM2_OFFSET; 2044 else 2045 return CC_PC_PR_SHIM2; 2046 break; 2047 2048 case (HEADER_TYPE_LLC_SNAP): 2049 *parseArrayOffset = CC_PC_PR_USER_LLC_SNAP_OFFSET; 2050 break; 2051 2052 case (HEADER_TYPE_PPPoE): 2053 *parseArrayOffset = CC_PC_PR_PPPOE_OFFSET; 2054 break; 2055 2056 case (HEADER_TYPE_MPLS): 2057 if ((hdrIndex == e_FM_PCD_HDR_INDEX_NONE) 2058 || (hdrIndex == e_FM_PCD_HDR_INDEX_1)) 2059 *parseArrayOffset = CC_PC_PR_MPLS1_OFFSET; 2060 else 2061 if (hdrIndex == e_FM_PCD_HDR_INDEX_LAST) 2062 *parseArrayOffset = CC_PC_PR_MPLS_LAST_OFFSET; 2063 else 2064 { 2065 REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal MPLS header index")); 2066 return CC_PC_ILLEGAL; 2067 } 2068 break; 2069 2070 case (HEADER_TYPE_IPv4): 2071 case (HEADER_TYPE_IPv6): 2072 if ((hdrIndex == e_FM_PCD_HDR_INDEX_NONE) 2073 || (hdrIndex == e_FM_PCD_HDR_INDEX_1)) 2074 *parseArrayOffset = CC_PC_PR_IP1_OFFSET; 2075 else 2076 if (hdrIndex == e_FM_PCD_HDR_INDEX_2) 2077 *parseArrayOffset = CC_PC_PR_IP_LAST_OFFSET; 2078 else 2079 { 2080 REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IP header index")); 2081 return CC_PC_ILLEGAL; 2082 } 2083 break; 2084 2085 case (HEADER_TYPE_MINENCAP): 2086 *parseArrayOffset = CC_PC_PR_MINENC_OFFSET; 2087 break; 2088 2089 case (HEADER_TYPE_GRE): 2090 *parseArrayOffset = CC_PC_PR_GRE_OFFSET; 2091 break; 2092 2093 case (HEADER_TYPE_TCP): 2094 case (HEADER_TYPE_UDP): 2095 case (HEADER_TYPE_IPSEC_AH): 2096 case (HEADER_TYPE_IPSEC_ESP): 2097 case (HEADER_TYPE_DCCP): 2098 case (HEADER_TYPE_SCTP): 2099 *parseArrayOffset = CC_PC_PR_L4_OFFSET; 2100 break; 2101 2102 default: 2103 REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IP header for this type of operation")); 2104 return CC_PC_ILLEGAL; 2105 } 2106 2107 if (offsetRelevant) 2108 return CC_PR_OFFSET; 2109 else 2110 return CC_PR_WITHOUT_OFFSET; 2111 } 2112 2113 static uint8_t GetFieldParseCode(e_NetHeaderType hdr, t_FmPcdFields field, 2114 uint32_t offset, uint8_t *parseArrayOffset, 2115 e_FmPcdHdrIndex hdrIndex) 2116 { 2117 bool offsetRelevant = FALSE; 2118 2119 if (offset) 2120 offsetRelevant = TRUE; 2121 2122 switch (hdr) 2123 { 2124 case (HEADER_TYPE_NONE): 2125 ASSERT_COND(FALSE); 2126 break; 2127 case (HEADER_TYPE_ETH): 2128 switch (field.eth) 2129 { 2130 case (NET_HEADER_FIELD_ETH_TYPE): 2131 *parseArrayOffset = CC_PC_PR_ETYPE_LAST_OFFSET; 2132 break; 2133 2134 default: 2135 REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported")); 2136 return CC_PC_ILLEGAL; 2137 } 2138 break; 2139 2140 case (HEADER_TYPE_VLAN): 2141 switch (field.vlan) 2142 { 2143 case (NET_HEADER_FIELD_VLAN_TCI): 2144 if ((hdrIndex == e_FM_PCD_HDR_INDEX_NONE) 2145 || (hdrIndex == e_FM_PCD_HDR_INDEX_1)) 2146 *parseArrayOffset = CC_PC_PR_VLAN1_OFFSET; 2147 else 2148 if (hdrIndex == e_FM_PCD_HDR_INDEX_LAST) 2149 *parseArrayOffset = CC_PC_PR_VLAN2_OFFSET; 2150 break; 2151 2152 default: 2153 REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported")); 2154 return CC_PC_ILLEGAL; 2155 } 2156 break; 2157 2158 default: 2159 REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal header ")); 2160 return CC_PC_ILLEGAL; 2161 } 2162 2163 if (offsetRelevant) 2164 return CC_PR_OFFSET; 2165 else 2166 return CC_PR_WITHOUT_OFFSET; 2167 } 2168 2169 static void FillAdOfTypeResult(t_Handle h_Ad, 2170 t_FmPcdCcStatsParams *p_FmPcdCcStatsParams, 2171 t_FmPcd *p_FmPcd, 2172 t_FmPcdCcNextEngineParams *p_CcNextEngineParams) 2173 { 2174 t_AdOfTypeResult *p_AdResult = (t_AdOfTypeResult *)h_Ad; 2175 t_Handle h_TmpAd; 2176 uint32_t tmp = 0, tmpNia = 0; 2177 uint16_t profileId; 2178 t_Handle p_AdNewPtr = NULL; 2179 t_Error err = E_OK; 2180 2181 /* There are 3 cases handled in this routine of building a "result" type AD. 2182 * Case 1: No Manip. The action descriptor is built within the match table. 2183 * Case 2: Manip exists. A new AD is created - p_AdNewPtr. It is initialized 2184 * either in the FmPcdManipUpdateAdResultForCc routine or it was already 2185 * initialized and returned here. 2186 * p_AdResult (within the match table) will be initialized after 2187 * this routine returns and point to the existing AD. 2188 * Case 3: Manip exists. The action descriptor is built within the match table. 2189 * FmPcdManipUpdateAdResultForCc returns a NULL p_AdNewPtr. 2190 * 2191 * If statistics were enabled and the statistics mode of this node requires 2192 * a statistics Ad, it will be placed after the result Ad and before the 2193 * manip Ad, if manip Ad exists here. 2194 */ 2195 2196 /* As default, the "new" ptr is the current one. i.e. the content of the result 2197 * AD will be written into the match table itself (case (1))*/ 2198 p_AdNewPtr = p_AdResult; 2199 2200 /* Initialize an action descriptor, if current statistics mode requires an Ad */ 2201 if (p_FmPcdCcStatsParams) 2202 { 2203 ASSERT_COND(p_FmPcdCcStatsParams->h_StatsAd); 2204 ASSERT_COND(p_FmPcdCcStatsParams->h_StatsCounters); 2205 2206 /* Swapping addresses between statistics Ad and the current lookup AD addresses */ 2207 h_TmpAd = p_FmPcdCcStatsParams->h_StatsAd; 2208 p_FmPcdCcStatsParams->h_StatsAd = h_Ad; 2209 h_Ad = h_TmpAd; 2210 2211 p_AdNewPtr = h_Ad; 2212 p_AdResult = h_Ad; 2213 2214 /* Init statistics Ad and connect current lookup AD as 'next action' from statistics Ad */ 2215 UpdateStatsAd(p_FmPcdCcStatsParams, h_Ad, p_FmPcd->physicalMuramBase); 2216 } 2217 2218 /* Create manip and return p_AdNewPtr to either a new descriptor or NULL */ 2219 if (p_CcNextEngineParams->h_Manip) 2220 FmPcdManipUpdateAdResultForCc(p_CcNextEngineParams->h_Manip, 2221 p_CcNextEngineParams, h_Ad, &p_AdNewPtr); 2222 2223 /* if (p_AdNewPtr = NULL) --> Done. (case (3)) */ 2224 if (p_AdNewPtr) 2225 { 2226 /* case (1) and (2) */ 2227 switch (p_CcNextEngineParams->nextEngine) 2228 { 2229 case (e_FM_PCD_DONE): 2230 if (p_CcNextEngineParams->params.enqueueParams.action 2231 == e_FM_PCD_ENQ_FRAME) 2232 { 2233 if (p_CcNextEngineParams->params.enqueueParams.overrideFqid) 2234 { 2235 tmp = FM_PCD_AD_RESULT_CONTRL_FLOW_TYPE; 2236 tmp |= 2237 p_CcNextEngineParams->params.enqueueParams.newFqid; 2238 #if (DPAA_VERSION >= 11) 2239 tmp |= 2240 (p_CcNextEngineParams->params.enqueueParams.newRelativeStorageProfileId 2241 & FM_PCD_AD_RESULT_VSP_MASK) 2242 << FM_PCD_AD_RESULT_VSP_SHIFT; 2243 #endif /* (DPAA_VERSION >= 11) */ 2244 } 2245 else 2246 { 2247 tmp = FM_PCD_AD_RESULT_DATA_FLOW_TYPE; 2248 tmp |= FM_PCD_AD_RESULT_PLCR_DIS; 2249 } 2250 } 2251 2252 if (p_CcNextEngineParams->params.enqueueParams.action 2253 == e_FM_PCD_DROP_FRAME) 2254 tmpNia |= GET_NIA_BMI_AC_DISCARD_FRAME(p_FmPcd); 2255 else 2256 tmpNia |= GET_NIA_BMI_AC_ENQ_FRAME(p_FmPcd); 2257 break; 2258 2259 case (e_FM_PCD_KG): 2260 if (p_CcNextEngineParams->params.kgParams.overrideFqid) 2261 { 2262 tmp = FM_PCD_AD_RESULT_CONTRL_FLOW_TYPE; 2263 tmp |= p_CcNextEngineParams->params.kgParams.newFqid; 2264 #if (DPAA_VERSION >= 11) 2265 tmp |= 2266 (p_CcNextEngineParams->params.kgParams.newRelativeStorageProfileId 2267 & FM_PCD_AD_RESULT_VSP_MASK) 2268 << FM_PCD_AD_RESULT_VSP_SHIFT; 2269 #endif /* (DPAA_VERSION >= 11) */ 2270 } 2271 else 2272 { 2273 tmp = FM_PCD_AD_RESULT_DATA_FLOW_TYPE; 2274 tmp |= FM_PCD_AD_RESULT_PLCR_DIS; 2275 } 2276 tmpNia = NIA_KG_DIRECT; 2277 tmpNia |= NIA_ENG_KG; 2278 tmpNia |= NIA_KG_CC_EN; 2279 tmpNia |= FmPcdKgGetSchemeId( 2280 p_CcNextEngineParams->params.kgParams.h_DirectScheme); 2281 break; 2282 2283 case (e_FM_PCD_PLCR): 2284 if (p_CcNextEngineParams->params.plcrParams.overrideParams) 2285 { 2286 tmp = FM_PCD_AD_RESULT_CONTRL_FLOW_TYPE; 2287 2288 /* if private policer profile, it may be uninitialized yet, therefore no checks are done at this stage */ 2289 if (p_CcNextEngineParams->params.plcrParams.sharedProfile) 2290 { 2291 tmpNia |= NIA_PLCR_ABSOLUTE; 2292 err = FmPcdPlcrGetAbsoluteIdByProfileParams( 2293 (t_Handle)p_FmPcd, 2294 e_FM_PCD_PLCR_SHARED, 2295 NULL, 2296 p_CcNextEngineParams->params.plcrParams.newRelativeProfileId, 2297 &profileId); 2298 if (err != E_OK) 2299 return; 2300 2301 } 2302 else 2303 profileId = 2304 p_CcNextEngineParams->params.plcrParams.newRelativeProfileId; 2305 2306 tmp |= p_CcNextEngineParams->params.plcrParams.newFqid; 2307 #if (DPAA_VERSION >= 11) 2308 tmp |= 2309 (p_CcNextEngineParams->params.plcrParams.newRelativeStorageProfileId 2310 & FM_PCD_AD_RESULT_VSP_MASK) 2311 << FM_PCD_AD_RESULT_VSP_SHIFT; 2312 #endif /* (DPAA_VERSION >= 11) */ 2313 WRITE_UINT32( 2314 p_AdResult->plcrProfile, 2315 (uint32_t)((uint32_t)profileId << FM_PCD_AD_PROFILEID_FOR_CNTRL_SHIFT)); 2316 } 2317 else 2318 tmp = FM_PCD_AD_RESULT_DATA_FLOW_TYPE; 2319 2320 tmpNia |= 2321 NIA_ENG_PLCR 2322 | p_CcNextEngineParams->params.plcrParams.newRelativeProfileId; 2323 break; 2324 2325 default: 2326 return; 2327 }WRITE_UINT32(p_AdResult->fqid, tmp); 2328 2329 if (p_CcNextEngineParams->h_Manip) 2330 { 2331 tmp = GET_UINT32(p_AdResult->plcrProfile); 2332 tmp |= (uint32_t)(XX_VirtToPhys(p_AdNewPtr) 2333 - (p_FmPcd->physicalMuramBase)) >> 4; 2334 WRITE_UINT32(p_AdResult->plcrProfile, tmp); 2335 2336 tmpNia |= FM_PCD_AD_RESULT_EXTENDED_MODE; 2337 tmpNia |= FM_PCD_AD_RESULT_NADEN; 2338 } 2339 2340 #if (DPAA_VERSION >= 11) 2341 tmpNia |= FM_PCD_AD_RESULT_NO_OM_VSPE; 2342 #endif /* (DPAA_VERSION >= 11) */ 2343 WRITE_UINT32(p_AdResult->nia, tmpNia); 2344 } 2345 } 2346 2347 static t_Error CcUpdateParams(t_Handle h_FmPcd, t_Handle h_PcdParams, 2348 t_Handle h_FmPort, t_Handle h_FmTree, 2349 bool validate) 2350 { 2351 t_FmPcdCcTree *p_CcTree = (t_FmPcdCcTree *)h_FmTree; 2352 2353 return CcUpdateParam(h_FmPcd, h_PcdParams, h_FmPort, 2354 p_CcTree->keyAndNextEngineParams, 2355 p_CcTree->numOfEntries, 2356 UINT_TO_PTR(p_CcTree->ccTreeBaseAddr), validate, 0, 2357 h_FmTree, FALSE); 2358 } 2359 2360 2361 static void ReleaseNewNodeCommonPart( 2362 t_FmPcdModifyCcKeyAdditionalParams *p_AdditionalInfo) 2363 { 2364 if (p_AdditionalInfo->p_AdTableNew) 2365 FM_MURAM_FreeMem( 2366 FmPcdGetMuramHandle( 2367 ((t_FmPcdCcNode *)(p_AdditionalInfo->h_CurrentNode))->h_FmPcd), 2368 p_AdditionalInfo->p_AdTableNew); 2369 2370 if (p_AdditionalInfo->p_KeysMatchTableNew) 2371 FM_MURAM_FreeMem( 2372 FmPcdGetMuramHandle( 2373 ((t_FmPcdCcNode *)(p_AdditionalInfo->h_CurrentNode))->h_FmPcd), 2374 p_AdditionalInfo->p_KeysMatchTableNew); 2375 } 2376 2377 static t_Error UpdateGblMask(t_FmPcdCcNode *p_CcNode, uint8_t keySize, 2378 uint8_t *p_Mask) 2379 { 2380 uint8_t prvGlblMaskSize = p_CcNode->glblMaskSize; 2381 2382 if (p_Mask && !p_CcNode->glblMaskUpdated && (keySize <= 4) 2383 && !p_CcNode->lclMask) 2384 { 2385 if (p_CcNode->parseCode && (p_CcNode->parseCode != CC_PC_FF_TCI1) 2386 && (p_CcNode->parseCode != CC_PC_FF_TCI2) 2387 && (p_CcNode->parseCode != CC_PC_FF_MPLS1) 2388 && (p_CcNode->parseCode != CC_PC_FF_MPLS_LAST) 2389 && (p_CcNode->parseCode != CC_PC_FF_IPV4IPTOS_TC1) 2390 && (p_CcNode->parseCode != CC_PC_FF_IPV4IPTOS_TC2) 2391 && (p_CcNode->parseCode != CC_PC_FF_IPTOS_IPV6TC1_IPV6FLOW1) 2392 && (p_CcNode->parseCode != CC_PC_FF_IPDSCP) 2393 && (p_CcNode->parseCode != CC_PC_FF_IPTOS_IPV6TC2_IPV6FLOW2)) 2394 { 2395 p_CcNode->glblMaskSize = 0; 2396 p_CcNode->lclMask = TRUE; 2397 } 2398 else 2399 { 2400 memcpy(p_CcNode->p_GlblMask, p_Mask, (sizeof(uint8_t)) * keySize); 2401 p_CcNode->glblMaskUpdated = TRUE; 2402 p_CcNode->glblMaskSize = 4; 2403 } 2404 } 2405 else 2406 if (p_Mask && (keySize <= 4) && !p_CcNode->lclMask) 2407 { 2408 if (memcmp(p_CcNode->p_GlblMask, p_Mask, keySize) != 0) 2409 { 2410 p_CcNode->lclMask = TRUE; 2411 p_CcNode->glblMaskSize = 0; 2412 } 2413 } 2414 else 2415 if (!p_Mask && p_CcNode->glblMaskUpdated && (keySize <= 4)) 2416 { 2417 uint32_t tmpMask = 0xffffffff; 2418 if (memcmp(p_CcNode->p_GlblMask, &tmpMask, 4) != 0) 2419 { 2420 p_CcNode->lclMask = TRUE; 2421 p_CcNode->glblMaskSize = 0; 2422 } 2423 } 2424 else 2425 if (p_Mask) 2426 { 2427 p_CcNode->lclMask = TRUE; 2428 p_CcNode->glblMaskSize = 0; 2429 } 2430 2431 /* In static mode (maxNumOfKeys > 0), local mask is supported 2432 only is mask support was enabled at initialization */ 2433 if (p_CcNode->maxNumOfKeys && (!p_CcNode->maskSupport) && p_CcNode->lclMask) 2434 { 2435 p_CcNode->lclMask = FALSE; 2436 p_CcNode->glblMaskSize = prvGlblMaskSize; 2437 return ERROR_CODE(E_NOT_SUPPORTED); 2438 } 2439 2440 return E_OK; 2441 } 2442 2443 static __inline__ t_Handle GetNewAd(t_Handle h_FmPcdCcNodeOrTree, bool isTree) 2444 { 2445 t_FmPcd *p_FmPcd; 2446 t_Handle h_Ad; 2447 2448 if (isTree) 2449 p_FmPcd = (t_FmPcd *)(((t_FmPcdCcTree *)h_FmPcdCcNodeOrTree)->h_FmPcd); 2450 else 2451 p_FmPcd = (t_FmPcd *)(((t_FmPcdCcNode *)h_FmPcdCcNodeOrTree)->h_FmPcd); 2452 2453 if ((isTree && p_FmPcd->p_CcShadow) 2454 || (!isTree && ((t_FmPcdCcNode *)h_FmPcdCcNodeOrTree)->maxNumOfKeys)) 2455 { 2456 /* The allocated shadow is divided as follows: 2457 0 . . . 16 . . . 2458 --------------------------------------------------- 2459 | Shadow | Shadow Keys | Shadow Next | 2460 | Ad | Match Table | Engine Table | 2461 | (16 bytes) | (maximal size) | (maximal size) | 2462 --------------------------------------------------- 2463 */ 2464 if (!p_FmPcd->p_CcShadow) 2465 { 2466 REPORT_ERROR(MAJOR, E_NO_MEMORY, ("CC Shadow not allocated")); 2467 return NULL; 2468 } 2469 2470 h_Ad = p_FmPcd->p_CcShadow; 2471 } 2472 else 2473 { 2474 h_Ad = (t_Handle)FM_MURAM_AllocMem(FmPcdGetMuramHandle(p_FmPcd), 2475 FM_PCD_CC_AD_ENTRY_SIZE, 2476 FM_PCD_CC_AD_TABLE_ALIGN); 2477 if (!h_Ad) 2478 { 2479 REPORT_ERROR(MAJOR, E_NO_MEMORY, ("MURAM allocation for CC node action descriptor")); 2480 return NULL; 2481 } 2482 } 2483 2484 return h_Ad; 2485 } 2486 2487 static t_Error BuildNewNodeCommonPart( 2488 t_FmPcdCcNode *p_CcNode, int *size, 2489 t_FmPcdModifyCcKeyAdditionalParams *p_AdditionalInfo) 2490 { 2491 t_FmPcd *p_FmPcd = (t_FmPcd *)p_CcNode->h_FmPcd; 2492 2493 if (p_CcNode->lclMask) 2494 *size = 2 * p_CcNode->ccKeySizeAccExtraction; 2495 else 2496 *size = p_CcNode->ccKeySizeAccExtraction; 2497 2498 if (p_CcNode->maxNumOfKeys == 0) 2499 { 2500 p_AdditionalInfo->p_AdTableNew = (t_Handle)FM_MURAM_AllocMem( 2501 FmPcdGetMuramHandle(p_FmPcd), 2502 (uint32_t)((p_AdditionalInfo->numOfKeys + 1) 2503 * FM_PCD_CC_AD_ENTRY_SIZE), 2504 FM_PCD_CC_AD_TABLE_ALIGN); 2505 if (!p_AdditionalInfo->p_AdTableNew) 2506 RETURN_ERROR( 2507 MAJOR, E_NO_MEMORY, 2508 ("MURAM allocation for CC node action descriptors table")); 2509 2510 p_AdditionalInfo->p_KeysMatchTableNew = (t_Handle)FM_MURAM_AllocMem( 2511 FmPcdGetMuramHandle(p_FmPcd), 2512 (uint32_t)(*size * sizeof(uint8_t) 2513 * (p_AdditionalInfo->numOfKeys + 1)), 2514 FM_PCD_CC_KEYS_MATCH_TABLE_ALIGN); 2515 if (!p_AdditionalInfo->p_KeysMatchTableNew) 2516 { 2517 FM_MURAM_FreeMem(FmPcdGetMuramHandle(p_CcNode->h_FmPcd), 2518 p_AdditionalInfo->p_AdTableNew); 2519 p_AdditionalInfo->p_AdTableNew = NULL; 2520 RETURN_ERROR(MAJOR, E_NO_MEMORY, 2521 ("MURAM allocation for CC node key match table")); 2522 } 2523 2524 MemSet8( 2525 (uint8_t*)p_AdditionalInfo->p_AdTableNew, 2526 0, 2527 (uint32_t)((p_AdditionalInfo->numOfKeys + 1) 2528 * FM_PCD_CC_AD_ENTRY_SIZE)); 2529 MemSet8((uint8_t*)p_AdditionalInfo->p_KeysMatchTableNew, 0, 2530 *size * sizeof(uint8_t) * (p_AdditionalInfo->numOfKeys + 1)); 2531 } 2532 else 2533 { 2534 /* The allocated shadow is divided as follows: 2535 0 . . . 16 . . . 2536 --------------------------------------------------- 2537 | Shadow | Shadow Keys | Shadow Next | 2538 | Ad | Match Table | Engine Table | 2539 | (16 bytes) | (maximal size) | (maximal size) | 2540 --------------------------------------------------- 2541 */ 2542 2543 if (!p_FmPcd->p_CcShadow) 2544 RETURN_ERROR(MAJOR, E_NO_MEMORY, ("CC Shadow not allocated")); 2545 2546 p_AdditionalInfo->p_KeysMatchTableNew = 2547 PTR_MOVE(p_FmPcd->p_CcShadow, FM_PCD_CC_AD_ENTRY_SIZE); 2548 p_AdditionalInfo->p_AdTableNew = 2549 PTR_MOVE(p_AdditionalInfo->p_KeysMatchTableNew, p_CcNode->keysMatchTableMaxSize); 2550 2551 MemSet8( 2552 (uint8_t*)p_AdditionalInfo->p_AdTableNew, 2553 0, 2554 (uint32_t)((p_CcNode->maxNumOfKeys + 1) 2555 * FM_PCD_CC_AD_ENTRY_SIZE)); 2556 MemSet8((uint8_t*)p_AdditionalInfo->p_KeysMatchTableNew, 0, 2557 (*size) * sizeof(uint8_t) * (p_CcNode->maxNumOfKeys)); 2558 } 2559 2560 p_AdditionalInfo->p_AdTableOld = p_CcNode->h_AdTable; 2561 p_AdditionalInfo->p_KeysMatchTableOld = p_CcNode->h_KeysMatchTable; 2562 2563 return E_OK; 2564 } 2565 2566 static t_Error BuildNewNodeAddOrMdfyKeyAndNextEngine( 2567 t_Handle h_FmPcd, t_FmPcdCcNode *p_CcNode, uint16_t keyIndex, 2568 t_FmPcdCcKeyParams *p_KeyParams, 2569 t_FmPcdModifyCcKeyAdditionalParams *p_AdditionalInfo, bool add) 2570 { 2571 t_Error err = E_OK; 2572 t_Handle p_AdTableNewTmp, p_KeysMatchTableNewTmp; 2573 t_Handle p_KeysMatchTableOldTmp, p_AdTableOldTmp; 2574 int size; 2575 int i = 0, j = 0; 2576 t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; 2577 uint32_t requiredAction = 0; 2578 bool prvLclMask; 2579 t_CcNodeInformation *p_CcNodeInformation; 2580 t_FmPcdCcStatsParams statsParams = { 0 }; 2581 t_List *p_Pos; 2582 t_FmPcdStatsObj *p_StatsObj; 2583 2584 /* Check that new NIA is legal */ 2585 err = ValidateNextEngineParams(h_FmPcd, &p_KeyParams->ccNextEngineParams, 2586 p_CcNode->statisticsMode); 2587 if (err) 2588 RETURN_ERROR(MAJOR, err, NO_MSG); 2589 2590 prvLclMask = p_CcNode->lclMask; 2591 2592 /* Check that new key is not require update of localMask */ 2593 err = UpdateGblMask(p_CcNode, p_CcNode->ccKeySizeAccExtraction, 2594 p_KeyParams->p_Mask); 2595 if (err) 2596 RETURN_ERROR(MAJOR, err, (NO_MSG)); 2597 2598 /* Update internal data structure with new next engine for the given index */ 2599 memcpy(&p_AdditionalInfo->keyAndNextEngineParams[keyIndex].nextEngineParams, 2600 &p_KeyParams->ccNextEngineParams, sizeof(t_FmPcdCcNextEngineParams)); 2601 2602 memcpy(p_AdditionalInfo->keyAndNextEngineParams[keyIndex].key, 2603 p_KeyParams->p_Key, p_CcNode->userSizeOfExtraction); 2604 2605 if ((p_AdditionalInfo->keyAndNextEngineParams[keyIndex].nextEngineParams.nextEngine 2606 == e_FM_PCD_CC) 2607 && p_AdditionalInfo->keyAndNextEngineParams[keyIndex].nextEngineParams.h_Manip) 2608 { 2609 err = 2610 AllocAndFillAdForContLookupManip( 2611 p_AdditionalInfo->keyAndNextEngineParams[keyIndex].nextEngineParams.params.ccParams.h_CcNode); 2612 if (err) 2613 RETURN_ERROR(MAJOR, err, (NO_MSG)); 2614 } 2615 2616 if (p_KeyParams->p_Mask) 2617 memcpy(p_AdditionalInfo->keyAndNextEngineParams[keyIndex].mask, 2618 p_KeyParams->p_Mask, p_CcNode->userSizeOfExtraction); 2619 else 2620 memset(p_AdditionalInfo->keyAndNextEngineParams[keyIndex].mask, 0xFF, 2621 p_CcNode->userSizeOfExtraction); 2622 2623 /* Update numOfKeys */ 2624 if (add) 2625 p_AdditionalInfo->numOfKeys = (uint8_t)(p_CcNode->numOfKeys + 1); 2626 else 2627 p_AdditionalInfo->numOfKeys = (uint8_t)p_CcNode->numOfKeys; 2628 2629 /* Allocate new tables in MURAM: keys match table and action descriptors table */ 2630 err = BuildNewNodeCommonPart(p_CcNode, &size, p_AdditionalInfo); 2631 if (err) 2632 RETURN_ERROR(MAJOR, err, NO_MSG); 2633 2634 /* Check that manip is legal and what requiredAction is necessary for this manip */ 2635 if (p_KeyParams->ccNextEngineParams.h_Manip) 2636 { 2637 err = FmPcdManipCheckParamsForCcNextEngine( 2638 &p_KeyParams->ccNextEngineParams, &requiredAction); 2639 if (err) 2640 RETURN_ERROR(MAJOR, err, (NO_MSG)); 2641 } 2642 2643 p_AdditionalInfo->keyAndNextEngineParams[keyIndex].requiredAction = 2644 requiredAction; 2645 p_AdditionalInfo->keyAndNextEngineParams[keyIndex].requiredAction |= 2646 UPDATE_CC_WITH_TREE; 2647 2648 /* Update new Ad and new Key Table according to new requirement */ 2649 i = 0; 2650 for (j = 0; j < p_AdditionalInfo->numOfKeys; j++) 2651 { 2652 p_AdTableNewTmp = 2653 PTR_MOVE(p_AdditionalInfo->p_AdTableNew, j*FM_PCD_CC_AD_ENTRY_SIZE); 2654 2655 if (j == keyIndex) 2656 { 2657 if (p_KeyParams->ccNextEngineParams.statisticsEn) 2658 { 2659 /* Allocate a statistics object that holds statistics AD and counters. 2660 - For added key - New statistics AD and counters pointer need to be allocated 2661 new statistics object. If statistics were enabled, we need to replace the 2662 existing descriptor with a new descriptor with nullified counters. 2663 */ 2664 p_StatsObj = GetStatsObj(p_CcNode); 2665 ASSERT_COND(p_StatsObj); 2666 2667 /* Store allocated statistics object */ 2668 ASSERT_COND(keyIndex < CC_MAX_NUM_OF_KEYS); 2669 p_AdditionalInfo->keyAndNextEngineParams[keyIndex].p_StatsObj = 2670 p_StatsObj; 2671 2672 statsParams.h_StatsAd = p_StatsObj->h_StatsAd; 2673 statsParams.h_StatsCounters = p_StatsObj->h_StatsCounters; 2674 #if (DPAA_VERSION >= 11) 2675 statsParams.h_StatsFLRs = p_CcNode->h_StatsFLRs; 2676 2677 #endif /* (DPAA_VERSION >= 11) */ 2678 2679 /* Building action descriptor for the received new key */ 2680 NextStepAd(p_AdTableNewTmp, &statsParams, 2681 &p_KeyParams->ccNextEngineParams, p_FmPcd); 2682 } 2683 else 2684 { 2685 /* Building action descriptor for the received new key */ 2686 NextStepAd(p_AdTableNewTmp, NULL, 2687 &p_KeyParams->ccNextEngineParams, p_FmPcd); 2688 } 2689 2690 /* Copy the received new key into keys match table */ 2691 p_KeysMatchTableNewTmp = 2692 PTR_MOVE(p_AdditionalInfo->p_KeysMatchTableNew, j*size*sizeof(uint8_t)); 2693 2694 MemCpy8((void*)p_KeysMatchTableNewTmp, p_KeyParams->p_Key, 2695 p_CcNode->userSizeOfExtraction); 2696 2697 /* Update mask for the received new key */ 2698 if (p_CcNode->lclMask) 2699 { 2700 if (p_KeyParams->p_Mask) 2701 { 2702 MemCpy8(PTR_MOVE(p_KeysMatchTableNewTmp, 2703 p_CcNode->ccKeySizeAccExtraction), 2704 p_KeyParams->p_Mask, 2705 p_CcNode->userSizeOfExtraction); 2706 } 2707 else 2708 if (p_CcNode->ccKeySizeAccExtraction > 4) 2709 { 2710 MemSet8(PTR_MOVE(p_KeysMatchTableNewTmp, 2711 p_CcNode->ccKeySizeAccExtraction), 2712 0xff, p_CcNode->userSizeOfExtraction); 2713 } 2714 else 2715 { 2716 MemCpy8(PTR_MOVE(p_KeysMatchTableNewTmp, 2717 p_CcNode->ccKeySizeAccExtraction), 2718 p_CcNode->p_GlblMask, 2719 p_CcNode->userSizeOfExtraction); 2720 } 2721 } 2722 2723 /* If key modification requested, the old entry is omitted and replaced by the new parameters */ 2724 if (!add) 2725 i++; 2726 } 2727 else 2728 { 2729 /* Copy existing action descriptors to the newly allocated Ad table */ 2730 p_AdTableOldTmp = 2731 PTR_MOVE(p_AdditionalInfo->p_AdTableOld, i*FM_PCD_CC_AD_ENTRY_SIZE); 2732 MemCpy8(p_AdTableNewTmp, p_AdTableOldTmp, 2733 FM_PCD_CC_AD_ENTRY_SIZE); 2734 2735 /* Copy existing keys and their masks to the newly allocated keys match table */ 2736 p_KeysMatchTableNewTmp = 2737 PTR_MOVE(p_AdditionalInfo->p_KeysMatchTableNew, j * size * sizeof(uint8_t)); 2738 p_KeysMatchTableOldTmp = 2739 PTR_MOVE(p_AdditionalInfo->p_KeysMatchTableOld, i * size * sizeof(uint8_t)); 2740 2741 if (p_CcNode->lclMask) 2742 { 2743 if (prvLclMask) 2744 { 2745 MemCpy8( 2746 PTR_MOVE(p_KeysMatchTableNewTmp, p_CcNode->ccKeySizeAccExtraction), 2747 PTR_MOVE(p_KeysMatchTableOldTmp, p_CcNode->ccKeySizeAccExtraction), 2748 p_CcNode->ccKeySizeAccExtraction); 2749 } 2750 else 2751 { 2752 p_KeysMatchTableOldTmp = 2753 PTR_MOVE(p_CcNode->h_KeysMatchTable, 2754 i * (int)p_CcNode->ccKeySizeAccExtraction * sizeof(uint8_t)); 2755 2756 if (p_CcNode->ccKeySizeAccExtraction > 4) 2757 { 2758 MemSet8(PTR_MOVE(p_KeysMatchTableNewTmp, 2759 p_CcNode->ccKeySizeAccExtraction), 2760 0xff, p_CcNode->userSizeOfExtraction); 2761 } 2762 else 2763 { 2764 MemCpy8(PTR_MOVE(p_KeysMatchTableNewTmp, 2765 p_CcNode->ccKeySizeAccExtraction), 2766 p_CcNode->p_GlblMask, 2767 p_CcNode->userSizeOfExtraction); 2768 } 2769 } 2770 } 2771 2772 MemCpy8(p_KeysMatchTableNewTmp, p_KeysMatchTableOldTmp, 2773 p_CcNode->ccKeySizeAccExtraction); 2774 2775 i++; 2776 } 2777 } 2778 2779 /* Miss action descriptor */ 2780 p_AdTableNewTmp = 2781 PTR_MOVE(p_AdditionalInfo->p_AdTableNew, j * FM_PCD_CC_AD_ENTRY_SIZE); 2782 p_AdTableOldTmp = 2783 PTR_MOVE(p_AdditionalInfo->p_AdTableOld, i * FM_PCD_CC_AD_ENTRY_SIZE); 2784 MemCpy8(p_AdTableNewTmp, p_AdTableOldTmp, FM_PCD_CC_AD_ENTRY_SIZE); 2785 2786 if (!NCSW_LIST_IsEmpty(&p_CcNode->ccTreesLst)) 2787 { 2788 NCSW_LIST_FOR_EACH(p_Pos, &p_CcNode->ccTreesLst) 2789 { 2790 p_CcNodeInformation = CC_NODE_F_OBJECT(p_Pos); 2791 ASSERT_COND(p_CcNodeInformation->h_CcNode); 2792 /* Update the manipulation which has to be updated from parameters of the port */ 2793 /* It's has to be updated with restrictions defined in the function */ 2794 err = 2795 SetRequiredAction( 2796 p_CcNode->h_FmPcd, 2797 p_CcNode->shadowAction 2798 | p_AdditionalInfo->keyAndNextEngineParams[keyIndex].requiredAction, 2799 &p_AdditionalInfo->keyAndNextEngineParams[keyIndex], 2800 PTR_MOVE(p_AdditionalInfo->p_AdTableNew, keyIndex*FM_PCD_CC_AD_ENTRY_SIZE), 2801 1, p_CcNodeInformation->h_CcNode); 2802 if (err) 2803 RETURN_ERROR(MAJOR, err, (NO_MSG)); 2804 2805 err = 2806 CcUpdateParam( 2807 p_CcNode->h_FmPcd, 2808 NULL, 2809 NULL, 2810 &p_AdditionalInfo->keyAndNextEngineParams[keyIndex], 2811 1, 2812 PTR_MOVE(p_AdditionalInfo->p_AdTableNew, keyIndex*FM_PCD_CC_AD_ENTRY_SIZE), 2813 TRUE, p_CcNodeInformation->index, 2814 p_CcNodeInformation->h_CcNode, TRUE); 2815 if (err) 2816 RETURN_ERROR(MAJOR, err, (NO_MSG)); 2817 } 2818 } 2819 2820 if (p_CcNode->lclMask) 2821 memset(p_CcNode->p_GlblMask, 0xff, CC_GLBL_MASK_SIZE * sizeof(uint8_t)); 2822 2823 if (p_KeyParams->ccNextEngineParams.nextEngine == e_FM_PCD_CC) 2824 p_AdditionalInfo->h_NodeForAdd = 2825 p_KeyParams->ccNextEngineParams.params.ccParams.h_CcNode; 2826 if (p_KeyParams->ccNextEngineParams.h_Manip) 2827 p_AdditionalInfo->h_ManipForAdd = 2828 p_KeyParams->ccNextEngineParams.h_Manip; 2829 2830 #if (DPAA_VERSION >= 11) 2831 if ((p_KeyParams->ccNextEngineParams.nextEngine == e_FM_PCD_FR) 2832 && (p_KeyParams->ccNextEngineParams.params.frParams.h_FrmReplic)) 2833 p_AdditionalInfo->h_FrmReplicForAdd = 2834 p_KeyParams->ccNextEngineParams.params.frParams.h_FrmReplic; 2835 #endif /* (DPAA_VERSION >= 11) */ 2836 2837 if (!add) 2838 { 2839 if (p_CcNode->keyAndNextEngineParams[keyIndex].nextEngineParams.nextEngine 2840 == e_FM_PCD_CC) 2841 p_AdditionalInfo->h_NodeForRmv = 2842 p_CcNode->keyAndNextEngineParams[keyIndex].nextEngineParams.params.ccParams.h_CcNode; 2843 2844 if (p_CcNode->keyAndNextEngineParams[keyIndex].nextEngineParams.h_Manip) 2845 p_AdditionalInfo->h_ManipForRmv = 2846 p_CcNode->keyAndNextEngineParams[keyIndex].nextEngineParams.h_Manip; 2847 2848 /* If statistics were previously enabled, store the old statistics object to be released */ 2849 if (p_CcNode->keyAndNextEngineParams[keyIndex].p_StatsObj) 2850 { 2851 p_AdditionalInfo->p_StatsObjForRmv = 2852 p_CcNode->keyAndNextEngineParams[keyIndex].p_StatsObj; 2853 } 2854 2855 #if (DPAA_VERSION >= 11) 2856 if ((p_CcNode->keyAndNextEngineParams[keyIndex].nextEngineParams.nextEngine 2857 == e_FM_PCD_FR) 2858 && (p_CcNode->keyAndNextEngineParams[keyIndex].nextEngineParams.params.frParams.h_FrmReplic)) 2859 p_AdditionalInfo->h_FrmReplicForRmv = 2860 p_CcNode->keyAndNextEngineParams[keyIndex].nextEngineParams.params.frParams.h_FrmReplic; 2861 #endif /* (DPAA_VERSION >= 11) */ 2862 } 2863 2864 return E_OK; 2865 } 2866 2867 static t_Error BuildNewNodeRemoveKey( 2868 t_FmPcdCcNode *p_CcNode, uint16_t keyIndex, 2869 t_FmPcdModifyCcKeyAdditionalParams *p_AdditionalInfo) 2870 { 2871 int i = 0, j = 0; 2872 t_Handle p_AdTableNewTmp, p_KeysMatchTableNewTmp; 2873 t_Handle p_KeysMatchTableOldTmp, p_AdTableOldTmp; 2874 int size; 2875 t_Error err = E_OK; 2876 2877 /*save new numOfKeys*/ 2878 p_AdditionalInfo->numOfKeys = (uint16_t)(p_CcNode->numOfKeys - 1); 2879 2880 /*function which allocates in the memory new KeyTbl, AdTbl*/ 2881 err = BuildNewNodeCommonPart(p_CcNode, &size, p_AdditionalInfo); 2882 if (err) 2883 RETURN_ERROR(MAJOR, err, NO_MSG); 2884 2885 /*update new Ad and new Key Table according to new requirement*/ 2886 for (i = 0, j = 0; j < p_CcNode->numOfKeys; i++, j++) 2887 { 2888 if (j == keyIndex) 2889 j++; 2890 2891 if (j == p_CcNode->numOfKeys) 2892 break; 2893 p_AdTableNewTmp = 2894 PTR_MOVE(p_AdditionalInfo->p_AdTableNew, i * FM_PCD_CC_AD_ENTRY_SIZE); 2895 p_AdTableOldTmp = 2896 PTR_MOVE(p_AdditionalInfo->p_AdTableOld, j * FM_PCD_CC_AD_ENTRY_SIZE); 2897 MemCpy8(p_AdTableNewTmp, p_AdTableOldTmp, FM_PCD_CC_AD_ENTRY_SIZE); 2898 2899 p_KeysMatchTableOldTmp = 2900 PTR_MOVE(p_AdditionalInfo->p_KeysMatchTableOld, j * size * sizeof(uint8_t)); 2901 p_KeysMatchTableNewTmp = 2902 PTR_MOVE(p_AdditionalInfo->p_KeysMatchTableNew, i * size * sizeof(uint8_t)); 2903 MemCpy8(p_KeysMatchTableNewTmp, p_KeysMatchTableOldTmp, 2904 size * sizeof(uint8_t)); 2905 } 2906 2907 p_AdTableNewTmp = 2908 PTR_MOVE(p_AdditionalInfo->p_AdTableNew, i * FM_PCD_CC_AD_ENTRY_SIZE); 2909 p_AdTableOldTmp = 2910 PTR_MOVE(p_AdditionalInfo->p_AdTableOld, j * FM_PCD_CC_AD_ENTRY_SIZE); 2911 MemCpy8(p_AdTableNewTmp, p_AdTableOldTmp, FM_PCD_CC_AD_ENTRY_SIZE); 2912 2913 if (p_CcNode->keyAndNextEngineParams[keyIndex].nextEngineParams.nextEngine 2914 == e_FM_PCD_CC) 2915 p_AdditionalInfo->h_NodeForRmv = 2916 p_CcNode->keyAndNextEngineParams[keyIndex].nextEngineParams.params.ccParams.h_CcNode; 2917 2918 if (p_CcNode->keyAndNextEngineParams[keyIndex].nextEngineParams.h_Manip) 2919 p_AdditionalInfo->h_ManipForRmv = 2920 p_CcNode->keyAndNextEngineParams[keyIndex].nextEngineParams.h_Manip; 2921 2922 /* If statistics were previously enabled, store the old statistics object to be released */ 2923 if (p_CcNode->keyAndNextEngineParams[keyIndex].p_StatsObj) 2924 { 2925 p_AdditionalInfo->p_StatsObjForRmv = 2926 p_CcNode->keyAndNextEngineParams[keyIndex].p_StatsObj; 2927 } 2928 2929 #if (DPAA_VERSION >= 11) 2930 if ((p_CcNode->keyAndNextEngineParams[keyIndex].nextEngineParams.nextEngine 2931 == e_FM_PCD_FR) 2932 && (p_CcNode->keyAndNextEngineParams[keyIndex].nextEngineParams.params.frParams.h_FrmReplic)) 2933 p_AdditionalInfo->h_FrmReplicForRmv = 2934 p_CcNode->keyAndNextEngineParams[keyIndex].nextEngineParams.params.frParams.h_FrmReplic; 2935 #endif /* (DPAA_VERSION >= 11) */ 2936 2937 return E_OK; 2938 } 2939 2940 static t_Error BuildNewNodeModifyKey( 2941 t_FmPcdCcNode *p_CcNode, uint16_t keyIndex, uint8_t *p_Key, 2942 uint8_t *p_Mask, t_FmPcdModifyCcKeyAdditionalParams *p_AdditionalInfo) 2943 { 2944 t_FmPcd *p_FmPcd = (t_FmPcd *)p_CcNode->h_FmPcd; 2945 t_Error err = E_OK; 2946 t_Handle p_AdTableNewTmp, p_KeysMatchTableNewTmp; 2947 t_Handle p_KeysMatchTableOldTmp, p_AdTableOldTmp; 2948 int size; 2949 int i = 0, j = 0; 2950 bool prvLclMask; 2951 t_FmPcdStatsObj *p_StatsObj, tmpStatsObj; 2952 p_AdditionalInfo->numOfKeys = p_CcNode->numOfKeys; 2953 2954 prvLclMask = p_CcNode->lclMask; 2955 2956 /* Check that new key is not require update of localMask */ 2957 err = UpdateGblMask(p_CcNode, p_CcNode->ccKeySizeAccExtraction, p_Mask); 2958 if (err) 2959 RETURN_ERROR(MAJOR, err, (NO_MSG)); 2960 2961 /* Update internal data structure with new next engine for the given index */ 2962 memcpy(p_AdditionalInfo->keyAndNextEngineParams[keyIndex].key, p_Key, 2963 p_CcNode->userSizeOfExtraction); 2964 2965 if (p_Mask) 2966 memcpy(p_AdditionalInfo->keyAndNextEngineParams[keyIndex].mask, p_Mask, 2967 p_CcNode->userSizeOfExtraction); 2968 else 2969 memset(p_AdditionalInfo->keyAndNextEngineParams[keyIndex].mask, 0xFF, 2970 p_CcNode->userSizeOfExtraction); 2971 2972 /*function which build in the memory new KeyTbl, AdTbl*/ 2973 err = BuildNewNodeCommonPart(p_CcNode, &size, p_AdditionalInfo); 2974 if (err) 2975 RETURN_ERROR(MAJOR, err, NO_MSG); 2976 2977 /*fill the New AdTable and New KeyTable*/ 2978 for (j = 0, i = 0; j < p_AdditionalInfo->numOfKeys; j++, i++) 2979 { 2980 p_AdTableNewTmp = 2981 PTR_MOVE(p_AdditionalInfo->p_AdTableNew, j*FM_PCD_CC_AD_ENTRY_SIZE); 2982 p_AdTableOldTmp = 2983 PTR_MOVE(p_AdditionalInfo->p_AdTableOld, i*FM_PCD_CC_AD_ENTRY_SIZE); 2984 2985 MemCpy8(p_AdTableNewTmp, p_AdTableOldTmp, FM_PCD_CC_AD_ENTRY_SIZE); 2986 2987 if (j == keyIndex) 2988 { 2989 ASSERT_COND(keyIndex < CC_MAX_NUM_OF_KEYS); 2990 if (p_CcNode->keyAndNextEngineParams[keyIndex].p_StatsObj) 2991 { 2992 /* As statistics were enabled, we need to update the existing 2993 statistics descriptor with a new nullified counters. */ 2994 p_StatsObj = GetStatsObj(p_CcNode); 2995 ASSERT_COND(p_StatsObj); 2996 2997 SetStatsCounters( 2998 p_AdTableNewTmp, 2999 (uint32_t)((XX_VirtToPhys(p_StatsObj->h_StatsCounters) 3000 - p_FmPcd->physicalMuramBase))); 3001 3002 tmpStatsObj.h_StatsAd = p_StatsObj->h_StatsAd; 3003 tmpStatsObj.h_StatsCounters = p_StatsObj->h_StatsCounters; 3004 3005 /* As we need to replace only the counters, we build a new statistics 3006 object that holds the old AD and the new counters - this will be the 3007 currently used statistics object. 3008 The newly allocated AD is not required and may be released back to 3009 the available objects with the previous counters pointer. */ 3010 p_StatsObj->h_StatsAd = 3011 p_CcNode->keyAndNextEngineParams[keyIndex].p_StatsObj->h_StatsAd; 3012 3013 p_CcNode->keyAndNextEngineParams[keyIndex].p_StatsObj->h_StatsAd = 3014 tmpStatsObj.h_StatsAd; 3015 3016 /* Store allocated statistics object */ 3017 p_AdditionalInfo->keyAndNextEngineParams[keyIndex].p_StatsObj = 3018 p_StatsObj; 3019 3020 /* As statistics were previously enabled, store the old statistics object to be released */ 3021 p_AdditionalInfo->p_StatsObjForRmv = 3022 p_CcNode->keyAndNextEngineParams[keyIndex].p_StatsObj; 3023 } 3024 3025 p_KeysMatchTableNewTmp = 3026 PTR_MOVE(p_AdditionalInfo->p_KeysMatchTableNew, j * size * sizeof(uint8_t)); 3027 3028 MemCpy8(p_KeysMatchTableNewTmp, p_Key, 3029 p_CcNode->userSizeOfExtraction); 3030 3031 if (p_CcNode->lclMask) 3032 { 3033 if (p_Mask) 3034 MemCpy8(PTR_MOVE(p_KeysMatchTableNewTmp, 3035 p_CcNode->ccKeySizeAccExtraction), 3036 p_Mask, p_CcNode->userSizeOfExtraction); 3037 else 3038 if (p_CcNode->ccKeySizeAccExtraction > 4) 3039 MemSet8(PTR_MOVE(p_KeysMatchTableNewTmp, 3040 p_CcNode->ccKeySizeAccExtraction), 3041 0xff, p_CcNode->userSizeOfExtraction); 3042 else 3043 MemCpy8(PTR_MOVE(p_KeysMatchTableNewTmp, 3044 p_CcNode->ccKeySizeAccExtraction), 3045 p_CcNode->p_GlblMask, 3046 p_CcNode->userSizeOfExtraction); 3047 } 3048 } 3049 else 3050 { 3051 p_KeysMatchTableNewTmp = 3052 PTR_MOVE(p_AdditionalInfo->p_KeysMatchTableNew, j * size * sizeof(uint8_t)); 3053 p_KeysMatchTableOldTmp = 3054 PTR_MOVE(p_CcNode->h_KeysMatchTable, i * size * sizeof(uint8_t)); 3055 3056 if (p_CcNode->lclMask) 3057 { 3058 if (prvLclMask) 3059 MemCpy8( 3060 PTR_MOVE(p_KeysMatchTableNewTmp, p_CcNode->ccKeySizeAccExtraction), 3061 PTR_MOVE(p_KeysMatchTableOldTmp, p_CcNode->ccKeySizeAccExtraction), 3062 p_CcNode->userSizeOfExtraction); 3063 else 3064 { 3065 p_KeysMatchTableOldTmp = 3066 PTR_MOVE(p_CcNode->h_KeysMatchTable, 3067 i * (int)p_CcNode->ccKeySizeAccExtraction * sizeof(uint8_t)); 3068 3069 if (p_CcNode->ccKeySizeAccExtraction > 4) 3070 MemSet8(PTR_MOVE(p_KeysMatchTableNewTmp, 3071 p_CcNode->ccKeySizeAccExtraction), 3072 0xff, p_CcNode->userSizeOfExtraction); 3073 else 3074 MemCpy8( 3075 PTR_MOVE(p_KeysMatchTableNewTmp, p_CcNode->ccKeySizeAccExtraction), 3076 p_CcNode->p_GlblMask, 3077 p_CcNode->userSizeOfExtraction); 3078 } 3079 } 3080 MemCpy8((void*)p_KeysMatchTableNewTmp, p_KeysMatchTableOldTmp, 3081 p_CcNode->ccKeySizeAccExtraction); 3082 } 3083 } 3084 3085 p_AdTableNewTmp = 3086 PTR_MOVE(p_AdditionalInfo->p_AdTableNew, j * FM_PCD_CC_AD_ENTRY_SIZE); 3087 p_AdTableOldTmp = PTR_MOVE(p_CcNode->h_AdTable, i * FM_PCD_CC_AD_ENTRY_SIZE); 3088 3089 MemCpy8(p_AdTableNewTmp, p_AdTableOldTmp, FM_PCD_CC_AD_ENTRY_SIZE); 3090 3091 return E_OK; 3092 } 3093 3094 static t_Error BuildNewNodeModifyNextEngine( 3095 t_Handle h_FmPcd, t_Handle h_FmPcdCcNodeOrTree, uint16_t keyIndex, 3096 t_FmPcdCcNextEngineParams *p_CcNextEngineParams, t_List *h_OldLst, 3097 t_List *h_NewLst, t_FmPcdModifyCcKeyAdditionalParams *p_AdditionalInfo) 3098 { 3099 t_Error err = E_OK; 3100 uint32_t requiredAction = 0; 3101 t_List *p_Pos; 3102 t_CcNodeInformation *p_CcNodeInformation, ccNodeInfo; 3103 t_Handle p_Ad; 3104 t_FmPcdCcNode *p_FmPcdCcNode1 = NULL; 3105 t_FmPcdCcTree *p_FmPcdCcTree = NULL; 3106 t_FmPcdStatsObj *p_StatsObj; 3107 t_FmPcdCcStatsParams statsParams = { 0 }; 3108 3109 ASSERT_COND(p_CcNextEngineParams); 3110 3111 /* check that new NIA is legal */ 3112 if (!p_AdditionalInfo->tree) 3113 err = ValidateNextEngineParams( 3114 h_FmPcd, p_CcNextEngineParams, 3115 ((t_FmPcdCcNode *)h_FmPcdCcNodeOrTree)->statisticsMode); 3116 else 3117 /* Statistics are not supported for CC root */ 3118 err = ValidateNextEngineParams(h_FmPcd, p_CcNextEngineParams, 3119 e_FM_PCD_CC_STATS_MODE_NONE); 3120 if (err) 3121 RETURN_ERROR(MAJOR, err, NO_MSG); 3122 3123 /* Update internal data structure for next engine per index (index - key) */ 3124 memcpy(&p_AdditionalInfo->keyAndNextEngineParams[keyIndex].nextEngineParams, 3125 p_CcNextEngineParams, sizeof(t_FmPcdCcNextEngineParams)); 3126 3127 /* Check that manip is legal and what requiredAction is necessary for this manip */ 3128 if (p_CcNextEngineParams->h_Manip) 3129 { 3130 err = FmPcdManipCheckParamsForCcNextEngine(p_CcNextEngineParams, 3131 &requiredAction); 3132 if (err) 3133 RETURN_ERROR(MAJOR, err, (NO_MSG)); 3134 } 3135 3136 if (!p_AdditionalInfo->tree) 3137 { 3138 p_FmPcdCcNode1 = (t_FmPcdCcNode *)h_FmPcdCcNodeOrTree; 3139 p_AdditionalInfo->numOfKeys = p_FmPcdCcNode1->numOfKeys; 3140 p_Ad = p_FmPcdCcNode1->h_AdTable; 3141 3142 if (p_FmPcdCcNode1->keyAndNextEngineParams[keyIndex].nextEngineParams.nextEngine 3143 == e_FM_PCD_CC) 3144 p_AdditionalInfo->h_NodeForRmv = 3145 p_FmPcdCcNode1->keyAndNextEngineParams[keyIndex].nextEngineParams.params.ccParams.h_CcNode; 3146 3147 if (p_FmPcdCcNode1->keyAndNextEngineParams[keyIndex].nextEngineParams.h_Manip) 3148 p_AdditionalInfo->h_ManipForRmv = 3149 p_FmPcdCcNode1->keyAndNextEngineParams[keyIndex].nextEngineParams.h_Manip; 3150 3151 #if (DPAA_VERSION >= 11) 3152 if ((p_FmPcdCcNode1->keyAndNextEngineParams[keyIndex].nextEngineParams.nextEngine 3153 == e_FM_PCD_FR) 3154 && (p_FmPcdCcNode1->keyAndNextEngineParams[keyIndex].nextEngineParams.params.frParams.h_FrmReplic)) 3155 p_AdditionalInfo->h_FrmReplicForRmv = 3156 p_FmPcdCcNode1->keyAndNextEngineParams[keyIndex].nextEngineParams.params.frParams.h_FrmReplic; 3157 #endif /* (DPAA_VERSION >= 11) */ 3158 } 3159 else 3160 { 3161 p_FmPcdCcTree = (t_FmPcdCcTree *)h_FmPcdCcNodeOrTree; 3162 p_Ad = UINT_TO_PTR(p_FmPcdCcTree->ccTreeBaseAddr); 3163 3164 if (p_FmPcdCcTree->keyAndNextEngineParams[keyIndex].nextEngineParams.nextEngine 3165 == e_FM_PCD_CC) 3166 p_AdditionalInfo->h_NodeForRmv = 3167 p_FmPcdCcTree->keyAndNextEngineParams[keyIndex].nextEngineParams.params.ccParams.h_CcNode; 3168 3169 if (p_FmPcdCcTree->keyAndNextEngineParams[keyIndex].nextEngineParams.h_Manip) 3170 p_AdditionalInfo->h_ManipForRmv = 3171 p_FmPcdCcTree->keyAndNextEngineParams[keyIndex].nextEngineParams.h_Manip; 3172 3173 #if (DPAA_VERSION >= 11) 3174 if ((p_FmPcdCcTree->keyAndNextEngineParams[keyIndex].nextEngineParams.nextEngine 3175 == e_FM_PCD_FR) 3176 && (p_FmPcdCcTree->keyAndNextEngineParams[keyIndex].nextEngineParams.params.frParams.h_FrmReplic)) 3177 p_AdditionalInfo->h_FrmReplicForRmv = 3178 p_FmPcdCcTree->keyAndNextEngineParams[keyIndex].nextEngineParams.params.frParams.h_FrmReplic; 3179 #endif /* (DPAA_VERSION >= 11) */ 3180 } 3181 3182 if ((p_CcNextEngineParams->nextEngine == e_FM_PCD_CC) 3183 && p_CcNextEngineParams->h_Manip) 3184 { 3185 err = AllocAndFillAdForContLookupManip( 3186 p_CcNextEngineParams->params.ccParams.h_CcNode); 3187 if (err) 3188 RETURN_ERROR(MAJOR, err, (NO_MSG)); 3189 } 3190 3191 ASSERT_COND(p_Ad); 3192 3193 memset(&ccNodeInfo, 0, sizeof(t_CcNodeInformation)); 3194 ccNodeInfo.h_CcNode = PTR_MOVE(p_Ad, keyIndex * FM_PCD_CC_AD_ENTRY_SIZE); 3195 3196 /* If statistics were enabled, this Ad is the statistics Ad. Need to follow its 3197 nextAction to retrieve the actual Nia-Ad. If statistics should remain enabled, 3198 only the actual Nia-Ad should be modified. */ 3199 if ((!p_AdditionalInfo->tree) 3200 && (((t_FmPcdCcNode *)h_FmPcdCcNodeOrTree)->keyAndNextEngineParams[keyIndex].p_StatsObj) 3201 && (p_CcNextEngineParams->statisticsEn)) 3202 ccNodeInfo.h_CcNode = 3203 ((t_FmPcdCcNode *)h_FmPcdCcNodeOrTree)->keyAndNextEngineParams[keyIndex].p_StatsObj->h_StatsAd; 3204 3205 EnqueueNodeInfoToRelevantLst(h_OldLst, &ccNodeInfo, NULL); 3206 3207 memset(&ccNodeInfo, 0, sizeof(t_CcNodeInformation)); 3208 p_Ad = GetNewAd(h_FmPcdCcNodeOrTree, p_AdditionalInfo->tree); 3209 if (!p_Ad) 3210 RETURN_ERROR(MAJOR, E_NO_MEMORY, 3211 ("MURAM allocation for CC node action descriptor")); 3212 MemSet8((uint8_t *)p_Ad, 0, FM_PCD_CC_AD_ENTRY_SIZE); 3213 3214 /* If statistics were not enabled before, but requested now - Allocate a statistics 3215 object that holds statistics AD and counters. */ 3216 if ((!p_AdditionalInfo->tree) 3217 && (!((t_FmPcdCcNode *)h_FmPcdCcNodeOrTree)->keyAndNextEngineParams[keyIndex].p_StatsObj) 3218 && (p_CcNextEngineParams->statisticsEn)) 3219 { 3220 p_StatsObj = GetStatsObj((t_FmPcdCcNode *)h_FmPcdCcNodeOrTree); 3221 ASSERT_COND(p_StatsObj); 3222 3223 /* Store allocated statistics object */ 3224 p_AdditionalInfo->keyAndNextEngineParams[keyIndex].p_StatsObj = 3225 p_StatsObj; 3226 3227 statsParams.h_StatsAd = p_StatsObj->h_StatsAd; 3228 statsParams.h_StatsCounters = p_StatsObj->h_StatsCounters; 3229 3230 #if (DPAA_VERSION >= 11) 3231 statsParams.h_StatsFLRs = 3232 ((t_FmPcdCcNode *)h_FmPcdCcNodeOrTree)->h_StatsFLRs; 3233 3234 #endif /* (DPAA_VERSION >= 11) */ 3235 3236 NextStepAd(p_Ad, &statsParams, p_CcNextEngineParams, h_FmPcd); 3237 } 3238 else 3239 NextStepAd(p_Ad, NULL, p_CcNextEngineParams, h_FmPcd); 3240 3241 ccNodeInfo.h_CcNode = p_Ad; 3242 EnqueueNodeInfoToRelevantLst(h_NewLst, &ccNodeInfo, NULL); 3243 3244 p_AdditionalInfo->keyAndNextEngineParams[keyIndex].requiredAction = 3245 requiredAction; 3246 p_AdditionalInfo->keyAndNextEngineParams[keyIndex].requiredAction |= 3247 UPDATE_CC_WITH_TREE; 3248 3249 if (!p_AdditionalInfo->tree) 3250 { 3251 ASSERT_COND(p_FmPcdCcNode1); 3252 if (!NCSW_LIST_IsEmpty(&p_FmPcdCcNode1->ccTreesLst)) 3253 { 3254 NCSW_LIST_FOR_EACH(p_Pos, &p_FmPcdCcNode1->ccTreesLst) 3255 { 3256 p_CcNodeInformation = CC_NODE_F_OBJECT(p_Pos); 3257 3258 ASSERT_COND(p_CcNodeInformation->h_CcNode); 3259 /* Update the manipulation which has to be updated from parameters of the port 3260 it's has to be updated with restrictions defined in the function */ 3261 3262 err = 3263 SetRequiredAction( 3264 p_FmPcdCcNode1->h_FmPcd, 3265 p_FmPcdCcNode1->shadowAction 3266 | p_AdditionalInfo->keyAndNextEngineParams[keyIndex].requiredAction, 3267 &p_AdditionalInfo->keyAndNextEngineParams[keyIndex], 3268 p_Ad, 1, p_CcNodeInformation->h_CcNode); 3269 if (err) 3270 RETURN_ERROR(MAJOR, err, (NO_MSG)); 3271 3272 err = CcUpdateParam( 3273 p_FmPcdCcNode1->h_FmPcd, NULL, NULL, 3274 &p_AdditionalInfo->keyAndNextEngineParams[keyIndex], 1, 3275 p_Ad, TRUE, p_CcNodeInformation->index, 3276 p_CcNodeInformation->h_CcNode, TRUE); 3277 if (err) 3278 RETURN_ERROR(MAJOR, err, (NO_MSG)); 3279 } 3280 } 3281 } 3282 else 3283 { 3284 ASSERT_COND(p_FmPcdCcTree); 3285 3286 err = 3287 SetRequiredAction( 3288 h_FmPcd, 3289 p_FmPcdCcTree->requiredAction 3290 | p_AdditionalInfo->keyAndNextEngineParams[keyIndex].requiredAction, 3291 &p_AdditionalInfo->keyAndNextEngineParams[keyIndex], 3292 p_Ad, 1, (t_Handle)p_FmPcdCcTree); 3293 if (err) 3294 RETURN_ERROR(MAJOR, err, (NO_MSG)); 3295 3296 err = CcUpdateParam(h_FmPcd, NULL, NULL, 3297 &p_AdditionalInfo->keyAndNextEngineParams[keyIndex], 3298 1, p_Ad, TRUE, 0, (t_Handle)p_FmPcdCcTree, TRUE); 3299 if (err) 3300 RETURN_ERROR(MAJOR, err, (NO_MSG)); 3301 } 3302 3303 if (p_CcNextEngineParams->nextEngine == e_FM_PCD_CC) 3304 p_AdditionalInfo->h_NodeForAdd = 3305 p_CcNextEngineParams->params.ccParams.h_CcNode; 3306 if (p_CcNextEngineParams->h_Manip) 3307 p_AdditionalInfo->h_ManipForAdd = p_CcNextEngineParams->h_Manip; 3308 3309 /* If statistics were previously enabled, but now are disabled, 3310 store the old statistics object to be released */ 3311 if ((!p_AdditionalInfo->tree) 3312 && (((t_FmPcdCcNode *)h_FmPcdCcNodeOrTree)->keyAndNextEngineParams[keyIndex].p_StatsObj) 3313 && (!p_CcNextEngineParams->statisticsEn)) 3314 { 3315 p_AdditionalInfo->p_StatsObjForRmv = 3316 ((t_FmPcdCcNode *)h_FmPcdCcNodeOrTree)->keyAndNextEngineParams[keyIndex].p_StatsObj; 3317 3318 3319 p_AdditionalInfo->keyAndNextEngineParams[keyIndex].p_StatsObj = NULL; 3320 } 3321 #if (DPAA_VERSION >= 11) 3322 if ((p_CcNextEngineParams->nextEngine == e_FM_PCD_FR) 3323 && (p_CcNextEngineParams->params.frParams.h_FrmReplic)) 3324 p_AdditionalInfo->h_FrmReplicForAdd = 3325 p_CcNextEngineParams->params.frParams.h_FrmReplic; 3326 #endif /* (DPAA_VERSION >= 11) */ 3327 3328 return E_OK; 3329 } 3330 3331 static void UpdateAdPtrOfNodesWhichPointsOnCrntMdfNode( 3332 t_FmPcdCcNode *p_CrntMdfNode, t_List *h_OldLst, 3333 t_FmPcdCcNextEngineParams **p_NextEngineParams) 3334 { 3335 t_CcNodeInformation *p_CcNodeInformation; 3336 t_FmPcdCcNode *p_NodePtrOnCurrentMdfNode = NULL; 3337 t_List *p_Pos; 3338 int i = 0; 3339 t_Handle p_AdTablePtOnCrntCurrentMdfNode/*, p_AdTableNewModified*/; 3340 t_CcNodeInformation ccNodeInfo; 3341 3342 NCSW_LIST_FOR_EACH(p_Pos, &p_CrntMdfNode->ccPrevNodesLst) 3343 { 3344 p_CcNodeInformation = CC_NODE_F_OBJECT(p_Pos); 3345 p_NodePtrOnCurrentMdfNode = 3346 (t_FmPcdCcNode *)p_CcNodeInformation->h_CcNode; 3347 3348 ASSERT_COND(p_NodePtrOnCurrentMdfNode); 3349 3350 /* Search in the previous node which exact index points on this current modified node for getting AD */ 3351 for (i = 0; i < p_NodePtrOnCurrentMdfNode->numOfKeys + 1; i++) 3352 { 3353 if (p_NodePtrOnCurrentMdfNode->keyAndNextEngineParams[i].nextEngineParams.nextEngine 3354 == e_FM_PCD_CC) 3355 { 3356 if (p_NodePtrOnCurrentMdfNode->keyAndNextEngineParams[i].nextEngineParams.params.ccParams.h_CcNode 3357 == (t_Handle)p_CrntMdfNode) 3358 { 3359 if (p_NodePtrOnCurrentMdfNode->keyAndNextEngineParams[i].nextEngineParams.h_Manip) 3360 p_AdTablePtOnCrntCurrentMdfNode = p_CrntMdfNode->h_Ad; 3361 else 3362 if (p_NodePtrOnCurrentMdfNode->keyAndNextEngineParams[i].p_StatsObj) 3363 p_AdTablePtOnCrntCurrentMdfNode = 3364 p_NodePtrOnCurrentMdfNode->keyAndNextEngineParams[i].p_StatsObj->h_StatsAd; 3365 else 3366 p_AdTablePtOnCrntCurrentMdfNode = 3367 PTR_MOVE(p_NodePtrOnCurrentMdfNode->h_AdTable, i*FM_PCD_CC_AD_ENTRY_SIZE); 3368 3369 memset(&ccNodeInfo, 0, sizeof(t_CcNodeInformation)); 3370 ccNodeInfo.h_CcNode = p_AdTablePtOnCrntCurrentMdfNode; 3371 EnqueueNodeInfoToRelevantLst(h_OldLst, &ccNodeInfo, NULL); 3372 3373 if (!(*p_NextEngineParams)) 3374 *p_NextEngineParams = 3375 &p_NodePtrOnCurrentMdfNode->keyAndNextEngineParams[i].nextEngineParams; 3376 } 3377 } 3378 } 3379 3380 ASSERT_COND(i != p_NodePtrOnCurrentMdfNode->numOfKeys); 3381 } 3382 } 3383 3384 static void UpdateAdPtrOfTreesWhichPointsOnCrntMdfNode( 3385 t_FmPcdCcNode *p_CrntMdfNode, t_List *h_OldLst, 3386 t_FmPcdCcNextEngineParams **p_NextEngineParams) 3387 { 3388 t_CcNodeInformation *p_CcNodeInformation; 3389 t_FmPcdCcTree *p_TreePtrOnCurrentMdfNode = NULL; 3390 t_List *p_Pos; 3391 int i = 0; 3392 t_Handle p_AdTableTmp; 3393 t_CcNodeInformation ccNodeInfo; 3394 3395 NCSW_LIST_FOR_EACH(p_Pos, &p_CrntMdfNode->ccTreeIdLst) 3396 { 3397 p_CcNodeInformation = CC_NODE_F_OBJECT(p_Pos); 3398 p_TreePtrOnCurrentMdfNode = 3399 (t_FmPcdCcTree *)p_CcNodeInformation->h_CcNode; 3400 3401 ASSERT_COND(p_TreePtrOnCurrentMdfNode); 3402 3403 /*search in the trees which exact index points on this current modified node for getting AD */ 3404 for (i = 0; i < p_TreePtrOnCurrentMdfNode->numOfEntries; i++) 3405 { 3406 if (p_TreePtrOnCurrentMdfNode->keyAndNextEngineParams[i].nextEngineParams.nextEngine 3407 == e_FM_PCD_CC) 3408 { 3409 if (p_TreePtrOnCurrentMdfNode->keyAndNextEngineParams[i].nextEngineParams.params.ccParams.h_CcNode 3410 == (t_Handle)p_CrntMdfNode) 3411 { 3412 p_AdTableTmp = 3413 UINT_TO_PTR(p_TreePtrOnCurrentMdfNode->ccTreeBaseAddr + i*FM_PCD_CC_AD_ENTRY_SIZE); 3414 memset(&ccNodeInfo, 0, sizeof(t_CcNodeInformation)); 3415 ccNodeInfo.h_CcNode = p_AdTableTmp; 3416 EnqueueNodeInfoToRelevantLst(h_OldLst, &ccNodeInfo, NULL); 3417 3418 if (!(*p_NextEngineParams)) 3419 *p_NextEngineParams = 3420 &p_TreePtrOnCurrentMdfNode->keyAndNextEngineParams[i].nextEngineParams; 3421 } 3422 } 3423 } 3424 3425 ASSERT_COND(i == p_TreePtrOnCurrentMdfNode->numOfEntries); 3426 } 3427 } 3428 3429 static t_FmPcdModifyCcKeyAdditionalParams * ModifyNodeCommonPart( 3430 t_Handle h_FmPcdCcNodeOrTree, uint16_t keyIndex, 3431 e_ModifyState modifyState, bool ttlCheck, bool hashCheck, bool tree) 3432 { 3433 t_FmPcdModifyCcKeyAdditionalParams *p_FmPcdModifyCcKeyAdditionalParams; 3434 int i = 0, j = 0; 3435 bool wasUpdate = FALSE; 3436 t_FmPcdCcNode *p_CcNode = NULL; 3437 t_FmPcdCcTree *p_FmPcdCcTree; 3438 uint16_t numOfKeys; 3439 t_FmPcdCcKeyAndNextEngineParams *p_KeyAndNextEngineParams; 3440 3441 SANITY_CHECK_RETURN_VALUE(h_FmPcdCcNodeOrTree, E_INVALID_HANDLE, NULL); 3442 3443 if (!tree) 3444 { 3445 p_CcNode = (t_FmPcdCcNode *)h_FmPcdCcNodeOrTree; 3446 numOfKeys = p_CcNode->numOfKeys; 3447 3448 /* node has to be pointed by another node or tree */ 3449 3450 p_KeyAndNextEngineParams = (t_FmPcdCcKeyAndNextEngineParams *)XX_Malloc( 3451 sizeof(t_FmPcdCcKeyAndNextEngineParams) * (numOfKeys + 1)); 3452 if (!p_KeyAndNextEngineParams) 3453 { 3454 REPORT_ERROR(MAJOR, E_NO_MEMORY, ("Next engine and required action structure")); 3455 return NULL; 3456 } 3457 memcpy(p_KeyAndNextEngineParams, p_CcNode->keyAndNextEngineParams, 3458 (numOfKeys + 1) * sizeof(t_FmPcdCcKeyAndNextEngineParams)); 3459 3460 if (ttlCheck) 3461 { 3462 if ((p_CcNode->parseCode == CC_PC_FF_IPV4TTL) 3463 || (p_CcNode->parseCode == CC_PC_FF_IPV6HOP_LIMIT)) 3464 { 3465 XX_Free(p_KeyAndNextEngineParams); 3466 REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("nodeId of CC_PC_FF_IPV4TTL or CC_PC_FF_IPV6HOP_LIMIT can not be used for this operation")); 3467 return NULL; 3468 } 3469 } 3470 3471 if (hashCheck) 3472 { 3473 if (p_CcNode->parseCode == CC_PC_GENERIC_IC_HASH_INDEXED) 3474 { 3475 XX_Free(p_KeyAndNextEngineParams); 3476 REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("nodeId of CC_PC_GENERIC_IC_HASH_INDEXED can not be used for this operation")); 3477 return NULL; 3478 } 3479 } 3480 } 3481 else 3482 { 3483 p_FmPcdCcTree = (t_FmPcdCcTree *)h_FmPcdCcNodeOrTree; 3484 numOfKeys = p_FmPcdCcTree->numOfEntries; 3485 3486 p_KeyAndNextEngineParams = (t_FmPcdCcKeyAndNextEngineParams *)XX_Malloc( 3487 sizeof(t_FmPcdCcKeyAndNextEngineParams) 3488 * FM_PCD_MAX_NUM_OF_CC_GROUPS); 3489 if (!p_KeyAndNextEngineParams) 3490 { 3491 REPORT_ERROR(MAJOR, E_NO_MEMORY, ("Next engine and required action structure")); 3492 return NULL; 3493 } 3494 memcpy(p_KeyAndNextEngineParams, 3495 p_FmPcdCcTree->keyAndNextEngineParams, 3496 FM_PCD_MAX_NUM_OF_CC_GROUPS 3497 * sizeof(t_FmPcdCcKeyAndNextEngineParams)); 3498 } 3499 3500 p_FmPcdModifyCcKeyAdditionalParams = 3501 (t_FmPcdModifyCcKeyAdditionalParams *)XX_Malloc( 3502 sizeof(t_FmPcdModifyCcKeyAdditionalParams)); 3503 if (!p_FmPcdModifyCcKeyAdditionalParams) 3504 { 3505 XX_Free(p_KeyAndNextEngineParams); 3506 REPORT_ERROR(MAJOR, E_NO_MEMORY, ("Allocation of internal data structure FAILED")); 3507 return NULL; 3508 } 3509 memset(p_FmPcdModifyCcKeyAdditionalParams, 0, 3510 sizeof(t_FmPcdModifyCcKeyAdditionalParams)); 3511 3512 p_FmPcdModifyCcKeyAdditionalParams->h_CurrentNode = h_FmPcdCcNodeOrTree; 3513 p_FmPcdModifyCcKeyAdditionalParams->savedKeyIndex = keyIndex; 3514 3515 while (i < numOfKeys) 3516 { 3517 if ((j == keyIndex) && !wasUpdate) 3518 { 3519 if (modifyState == e_MODIFY_STATE_ADD) 3520 j++; 3521 else 3522 if (modifyState == e_MODIFY_STATE_REMOVE) 3523 i++; 3524 wasUpdate = TRUE; 3525 } 3526 else 3527 { 3528 memcpy(&p_FmPcdModifyCcKeyAdditionalParams->keyAndNextEngineParams[j], 3529 p_KeyAndNextEngineParams + i, 3530 sizeof(t_FmPcdCcKeyAndNextEngineParams)); 3531 i++; 3532 j++; 3533 } 3534 } 3535 3536 if (keyIndex == numOfKeys) 3537 { 3538 if (modifyState == e_MODIFY_STATE_ADD) 3539 j++; 3540 } 3541 3542 memcpy(&p_FmPcdModifyCcKeyAdditionalParams->keyAndNextEngineParams[j], 3543 p_KeyAndNextEngineParams + numOfKeys, 3544 sizeof(t_FmPcdCcKeyAndNextEngineParams)); 3545 3546 XX_Free(p_KeyAndNextEngineParams); 3547 3548 return p_FmPcdModifyCcKeyAdditionalParams; 3549 } 3550 3551 static t_Error UpdatePtrWhichPointOnCrntMdfNode( 3552 t_FmPcdCcNode *p_CcNode, 3553 t_FmPcdModifyCcKeyAdditionalParams *p_FmPcdModifyCcKeyAdditionalParams, 3554 t_List *h_OldLst, t_List *h_NewLst) 3555 { 3556 t_FmPcdCcNextEngineParams *p_NextEngineParams = NULL; 3557 t_CcNodeInformation ccNodeInfo = { 0 }; 3558 t_Handle h_NewAd; 3559 t_Handle h_OrigAd = NULL; 3560 3561 /* Building a list of all action descriptors that point to the previous node */ 3562 if (!NCSW_LIST_IsEmpty(&p_CcNode->ccPrevNodesLst)) 3563 UpdateAdPtrOfNodesWhichPointsOnCrntMdfNode(p_CcNode, h_OldLst, 3564 &p_NextEngineParams); 3565 3566 if (!NCSW_LIST_IsEmpty(&p_CcNode->ccTreeIdLst)) 3567 UpdateAdPtrOfTreesWhichPointsOnCrntMdfNode(p_CcNode, h_OldLst, 3568 &p_NextEngineParams); 3569 3570 /* This node must be found as next engine of one of its previous nodes or trees*/ 3571 if (p_NextEngineParams) 3572 { 3573 /* Building a new action descriptor that points to the modified node */ 3574 h_NewAd = GetNewAd(p_CcNode, FALSE); 3575 if (!h_NewAd) 3576 RETURN_ERROR(MAJOR, E_NO_MEMORY, NO_MSG); 3577 MemSet8(h_NewAd, 0, FM_PCD_CC_AD_ENTRY_SIZE); 3578 3579 h_OrigAd = p_CcNode->h_Ad; 3580 BuildNewAd(h_NewAd, p_FmPcdModifyCcKeyAdditionalParams, p_CcNode, 3581 p_NextEngineParams); 3582 3583 ccNodeInfo.h_CcNode = h_NewAd; 3584 EnqueueNodeInfoToRelevantLst(h_NewLst, &ccNodeInfo, NULL); 3585 3586 if (p_NextEngineParams->h_Manip && !h_OrigAd) 3587 FmPcdManipUpdateOwner(p_NextEngineParams->h_Manip, FALSE); 3588 } 3589 return E_OK; 3590 } 3591 3592 static void UpdateCcRootOwner(t_FmPcdCcTree *p_FmPcdCcTree, bool add) 3593 { 3594 ASSERT_COND(p_FmPcdCcTree); 3595 3596 /* this routine must be protected by the calling routine! */ 3597 3598 if (add) 3599 p_FmPcdCcTree->owners++; 3600 else 3601 { 3602 ASSERT_COND(p_FmPcdCcTree->owners); 3603 p_FmPcdCcTree->owners--; 3604 } 3605 } 3606 3607 static t_Error CheckAndSetManipParamsWithCcNodeParams(t_FmPcdCcNode *p_CcNode) 3608 { 3609 t_Error err = E_OK; 3610 int i = 0; 3611 3612 for (i = 0; i < p_CcNode->numOfKeys; i++) 3613 { 3614 if (p_CcNode->keyAndNextEngineParams[i].nextEngineParams.h_Manip) 3615 { 3616 err = 3617 FmPcdManipCheckParamsWithCcNodeParams( 3618 p_CcNode->keyAndNextEngineParams[i].nextEngineParams.h_Manip, 3619 (t_Handle)p_CcNode); 3620 if (err) 3621 return err; 3622 } 3623 } 3624 3625 return err; 3626 } 3627 static t_Error ValidateAndCalcStatsParams(t_FmPcdCcNode *p_CcNode, 3628 t_FmPcdCcNodeParams *p_CcNodeParam, 3629 uint32_t *p_NumOfRanges, 3630 uint32_t *p_CountersArraySize) 3631 { 3632 e_FmPcdCcStatsMode statisticsMode = p_CcNode->statisticsMode; 3633 uint32_t i; 3634 3635 UNUSED(p_CcNodeParam); 3636 3637 switch (statisticsMode) 3638 { 3639 case e_FM_PCD_CC_STATS_MODE_NONE: 3640 for (i = 0; i < p_CcNode->numOfKeys; i++) 3641 if (p_CcNodeParam->keysParams.keyParams[i].ccNextEngineParams.statisticsEn) 3642 RETURN_ERROR( 3643 MAJOR, 3644 E_INVALID_VALUE, 3645 ("Statistics cannot be enabled for key %d when statistics mode was set to 'NONE'", i)); 3646 return E_OK; 3647 3648 case e_FM_PCD_CC_STATS_MODE_FRAME: 3649 case e_FM_PCD_CC_STATS_MODE_BYTE_AND_FRAME: 3650 *p_NumOfRanges = 1; 3651 *p_CountersArraySize = 2 * FM_PCD_CC_STATS_COUNTER_SIZE; 3652 return E_OK; 3653 3654 #if (DPAA_VERSION >= 11) 3655 case e_FM_PCD_CC_STATS_MODE_RMON: 3656 { 3657 uint16_t *p_FrameLengthRanges = 3658 p_CcNodeParam->keysParams.frameLengthRanges; 3659 uint32_t i; 3660 3661 if (p_FrameLengthRanges[0] <= 0) 3662 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Statistics mode")); 3663 3664 if (p_FrameLengthRanges[0] == 0xFFFF) 3665 { 3666 *p_NumOfRanges = 1; 3667 *p_CountersArraySize = 2 * FM_PCD_CC_STATS_COUNTER_SIZE; 3668 return E_OK; 3669 } 3670 3671 for (i = 1; i < FM_PCD_CC_STATS_MAX_NUM_OF_FLR; i++) 3672 { 3673 if (p_FrameLengthRanges[i - 1] >= p_FrameLengthRanges[i]) 3674 RETURN_ERROR( 3675 MAJOR, 3676 E_INVALID_VALUE, 3677 ("Frame length range must be larger at least by 1 from preceding range")); 3678 3679 /* Stop when last range is reached */ 3680 if (p_FrameLengthRanges[i] == 0xFFFF) 3681 break; 3682 } 3683 3684 if ((i >= FM_PCD_CC_STATS_MAX_NUM_OF_FLR) 3685 || (p_FrameLengthRanges[i] != 0xFFFF)) 3686 RETURN_ERROR(MAJOR, E_INVALID_VALUE, 3687 ("Last Frame length range must be 0xFFFF")); 3688 3689 *p_NumOfRanges = i + 1; 3690 3691 /* Allocate an extra counter for byte count, as counters 3692 array always begins with byte count */ 3693 *p_CountersArraySize = (*p_NumOfRanges + 1) 3694 * FM_PCD_CC_STATS_COUNTER_SIZE; 3695 3696 } 3697 return E_OK; 3698 #endif /* (DPAA_VERSION >= 11) */ 3699 3700 default: 3701 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Statistics mode")); 3702 } 3703 } 3704 3705 static t_Error CheckParams(t_Handle h_FmPcd, t_FmPcdCcNodeParams *p_CcNodeParam, 3706 t_FmPcdCcNode *p_CcNode, bool *isKeyTblAlloc) 3707 { 3708 int tmp = 0; 3709 t_FmPcdCcKeyParams *p_KeyParams; 3710 t_Error err; 3711 uint32_t requiredAction = 0; 3712 3713 /* Validate statistics parameters */ 3714 err = ValidateAndCalcStatsParams(p_CcNode, p_CcNodeParam, 3715 &(p_CcNode->numOfStatsFLRs), 3716 &(p_CcNode->countersArraySize)); 3717 if (err) 3718 RETURN_ERROR(MAJOR, err, ("Invalid statistics parameters")); 3719 3720 /* Validate next engine parameters on Miss */ 3721 err = ValidateNextEngineParams( 3722 h_FmPcd, &p_CcNodeParam->keysParams.ccNextEngineParamsForMiss, 3723 p_CcNode->statisticsMode); 3724 if (err) 3725 RETURN_ERROR(MAJOR, err, 3726 ("For this node MissNextEngineParams are not valid")); 3727 3728 if (p_CcNodeParam->keysParams.ccNextEngineParamsForMiss.h_Manip) 3729 { 3730 err = FmPcdManipCheckParamsForCcNextEngine( 3731 &p_CcNodeParam->keysParams.ccNextEngineParamsForMiss, 3732 &requiredAction); 3733 if (err) 3734 RETURN_ERROR(MAJOR, err, (NO_MSG)); 3735 } 3736 3737 memcpy(&p_CcNode->keyAndNextEngineParams[p_CcNode->numOfKeys].nextEngineParams, 3738 &p_CcNodeParam->keysParams.ccNextEngineParamsForMiss, 3739 sizeof(t_FmPcdCcNextEngineParams)); 3740 3741 p_CcNode->keyAndNextEngineParams[p_CcNode->numOfKeys].requiredAction = 3742 requiredAction; 3743 3744 if ((p_CcNode->keyAndNextEngineParams[p_CcNode->numOfKeys].nextEngineParams.nextEngine 3745 == e_FM_PCD_CC) 3746 && p_CcNode->keyAndNextEngineParams[p_CcNode->numOfKeys].nextEngineParams.h_Manip) 3747 { 3748 err = 3749 AllocAndFillAdForContLookupManip( 3750 p_CcNode->keyAndNextEngineParams[p_CcNode->numOfKeys].nextEngineParams.params.ccParams.h_CcNode); 3751 if (err) 3752 RETURN_ERROR(MAJOR, err, (NO_MSG)); 3753 } 3754 3755 for (tmp = 0; tmp < p_CcNode->numOfKeys; tmp++) 3756 { 3757 p_KeyParams = &p_CcNodeParam->keysParams.keyParams[tmp]; 3758 3759 if (!p_KeyParams->p_Key) 3760 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("p_Key is not initialized")); 3761 3762 err = ValidateNextEngineParams(h_FmPcd, 3763 &p_KeyParams->ccNextEngineParams, 3764 p_CcNode->statisticsMode); 3765 if (err) 3766 RETURN_ERROR(MAJOR, err, (NO_MSG)); 3767 3768 err = UpdateGblMask(p_CcNode, p_CcNodeParam->keysParams.keySize, 3769 p_KeyParams->p_Mask); 3770 if (err) 3771 RETURN_ERROR(MAJOR, err, (NO_MSG)); 3772 3773 if (p_KeyParams->ccNextEngineParams.h_Manip) 3774 { 3775 err = FmPcdManipCheckParamsForCcNextEngine( 3776 &p_KeyParams->ccNextEngineParams, &requiredAction); 3777 if (err) 3778 RETURN_ERROR(MAJOR, err, (NO_MSG)); 3779 } 3780 3781 /* Store 'key' parameters - key, mask (if passed by the user) */ 3782 memcpy(p_CcNode->keyAndNextEngineParams[tmp].key, p_KeyParams->p_Key, 3783 p_CcNodeParam->keysParams.keySize); 3784 3785 if (p_KeyParams->p_Mask) 3786 memcpy(p_CcNode->keyAndNextEngineParams[tmp].mask, 3787 p_KeyParams->p_Mask, p_CcNodeParam->keysParams.keySize); 3788 else 3789 memset((void *)(p_CcNode->keyAndNextEngineParams[tmp].mask), 0xFF, 3790 p_CcNodeParam->keysParams.keySize); 3791 3792 /* Store next engine parameters */ 3793 memcpy(&p_CcNode->keyAndNextEngineParams[tmp].nextEngineParams, 3794 &p_KeyParams->ccNextEngineParams, 3795 sizeof(t_FmPcdCcNextEngineParams)); 3796 3797 p_CcNode->keyAndNextEngineParams[tmp].requiredAction = requiredAction; 3798 3799 if ((p_CcNode->keyAndNextEngineParams[tmp].nextEngineParams.nextEngine 3800 == e_FM_PCD_CC) 3801 && p_CcNode->keyAndNextEngineParams[tmp].nextEngineParams.h_Manip) 3802 { 3803 err = 3804 AllocAndFillAdForContLookupManip( 3805 p_CcNode->keyAndNextEngineParams[tmp].nextEngineParams.params.ccParams.h_CcNode); 3806 if (err) 3807 RETURN_ERROR(MAJOR, err, (NO_MSG)); 3808 } 3809 } 3810 3811 if (p_CcNode->maxNumOfKeys) 3812 { 3813 if (p_CcNode->maxNumOfKeys < p_CcNode->numOfKeys) 3814 RETURN_ERROR( 3815 MAJOR, 3816 E_INVALID_VALUE, 3817 ("Number of keys exceed the provided maximal number of keys")); 3818 } 3819 3820 *isKeyTblAlloc = TRUE; 3821 3822 return E_OK; 3823 } 3824 3825 static t_Error Ipv4TtlOrIpv6HopLimitCheckParams( 3826 t_Handle h_FmPcd, t_FmPcdCcNodeParams *p_CcNodeParam, 3827 t_FmPcdCcNode *p_CcNode, bool *isKeyTblAlloc) 3828 { 3829 int tmp = 0; 3830 t_FmPcdCcKeyParams *p_KeyParams; 3831 t_Error err; 3832 uint8_t key = 0x01; 3833 uint32_t requiredAction = 0; 3834 3835 if (p_CcNode->numOfKeys != 1) 3836 RETURN_ERROR( 3837 MAJOR, 3838 E_INVALID_VALUE, 3839 ("For node of the type IPV4_TTL or IPV6_HOP_LIMIT the maximal supported 'numOfKeys' is 1")); 3840 3841 if ((p_CcNodeParam->keysParams.maxNumOfKeys) 3842 && (p_CcNodeParam->keysParams.maxNumOfKeys != 1)) 3843 RETURN_ERROR( 3844 MAJOR, 3845 E_INVALID_VALUE, 3846 ("For node of the type IPV4_TTL or IPV6_HOP_LIMIT the maximal supported 'maxNumOfKeys' is 1")); 3847 3848 /* Validate statistics parameters */ 3849 err = ValidateAndCalcStatsParams(p_CcNode, p_CcNodeParam, 3850 &(p_CcNode->numOfStatsFLRs), 3851 &(p_CcNode->countersArraySize)); 3852 if (err) 3853 RETURN_ERROR(MAJOR, err, ("Invalid statistics parameters")); 3854 3855 err = ValidateNextEngineParams( 3856 h_FmPcd, &p_CcNodeParam->keysParams.ccNextEngineParamsForMiss, 3857 p_CcNodeParam->keysParams.statisticsMode); 3858 if (err) 3859 RETURN_ERROR(MAJOR, err, 3860 ("For this node MissNextEngineParams are not valid")); 3861 3862 if (p_CcNodeParam->keysParams.ccNextEngineParamsForMiss.h_Manip) 3863 { 3864 err = FmPcdManipCheckParamsForCcNextEngine( 3865 &p_CcNodeParam->keysParams.ccNextEngineParamsForMiss, 3866 &requiredAction); 3867 if (err) 3868 RETURN_ERROR(MAJOR, err, (NO_MSG)); 3869 } 3870 3871 memcpy(&p_CcNode->keyAndNextEngineParams[p_CcNode->numOfKeys].nextEngineParams, 3872 &p_CcNodeParam->keysParams.ccNextEngineParamsForMiss, 3873 sizeof(t_FmPcdCcNextEngineParams)); 3874 3875 p_CcNode->keyAndNextEngineParams[p_CcNode->numOfKeys].requiredAction = 3876 requiredAction; 3877 3878 if ((p_CcNode->keyAndNextEngineParams[p_CcNode->numOfKeys].nextEngineParams.nextEngine 3879 == e_FM_PCD_CC) 3880 && p_CcNode->keyAndNextEngineParams[p_CcNode->numOfKeys].nextEngineParams.h_Manip) 3881 { 3882 err = 3883 AllocAndFillAdForContLookupManip( 3884 p_CcNode->keyAndNextEngineParams[p_CcNode->numOfKeys].nextEngineParams.params.ccParams.h_CcNode); 3885 if (err) 3886 RETURN_ERROR(MAJOR, err, (NO_MSG)); 3887 } 3888 3889 for (tmp = 0; tmp < p_CcNode->numOfKeys; tmp++) 3890 { 3891 p_KeyParams = &p_CcNodeParam->keysParams.keyParams[tmp]; 3892 3893 if (p_KeyParams->p_Mask) 3894 RETURN_ERROR( 3895 MAJOR, 3896 E_INVALID_VALUE, 3897 ("For node of the type IPV4_TTL or IPV6_HOP_LIMIT p_Mask can not be initialized")); 3898 3899 if (memcmp(p_KeyParams->p_Key, &key, 1) != 0) 3900 RETURN_ERROR( 3901 MAJOR, 3902 E_INVALID_VALUE, 3903 ("For node of the type IPV4_TTL or IPV6_HOP_LIMIT p_Key has to be 1")); 3904 3905 err = ValidateNextEngineParams(h_FmPcd, 3906 &p_KeyParams->ccNextEngineParams, 3907 p_CcNode->statisticsMode); 3908 if (err) 3909 RETURN_ERROR(MAJOR, err, (NO_MSG)); 3910 3911 if (p_KeyParams->ccNextEngineParams.h_Manip) 3912 { 3913 err = FmPcdManipCheckParamsForCcNextEngine( 3914 &p_KeyParams->ccNextEngineParams, &requiredAction); 3915 if (err) 3916 RETURN_ERROR(MAJOR, err, (NO_MSG)); 3917 } 3918 3919 /* Store 'key' parameters - key (fixed to 0x01), key size of 1 byte and full mask */ 3920 p_CcNode->keyAndNextEngineParams[tmp].key[0] = key; 3921 p_CcNode->keyAndNextEngineParams[tmp].mask[0] = 0xFF; 3922 3923 /* Store NextEngine parameters */ 3924 memcpy(&p_CcNode->keyAndNextEngineParams[tmp].nextEngineParams, 3925 &p_KeyParams->ccNextEngineParams, 3926 sizeof(t_FmPcdCcNextEngineParams)); 3927 3928 if ((p_CcNode->keyAndNextEngineParams[tmp].nextEngineParams.nextEngine 3929 == e_FM_PCD_CC) 3930 && p_CcNode->keyAndNextEngineParams[tmp].nextEngineParams.h_Manip) 3931 { 3932 err = 3933 AllocAndFillAdForContLookupManip( 3934 p_CcNode->keyAndNextEngineParams[tmp].nextEngineParams.params.ccParams.h_CcNode); 3935 if (err) 3936 RETURN_ERROR(MAJOR, err, (NO_MSG)); 3937 } 3938 p_CcNode->keyAndNextEngineParams[tmp].requiredAction = requiredAction; 3939 } 3940 3941 *isKeyTblAlloc = FALSE; 3942 3943 return E_OK; 3944 } 3945 3946 static t_Error IcHashIndexedCheckParams(t_Handle h_FmPcd, 3947 t_FmPcdCcNodeParams *p_CcNodeParam, 3948 t_FmPcdCcNode *p_CcNode, 3949 bool *isKeyTblAlloc) 3950 { 3951 int tmp = 0, countOnes = 0; 3952 t_FmPcdCcKeyParams *p_KeyParams; 3953 t_Error err; 3954 uint16_t glblMask = p_CcNodeParam->extractCcParams.extractNonHdr.icIndxMask; 3955 uint16_t countMask = (uint16_t)(glblMask >> 4); 3956 uint32_t requiredAction = 0; 3957 3958 if (glblMask & 0x000f) 3959 RETURN_ERROR(MAJOR, E_INVALID_VALUE, 3960 ("icIndxMask has to be with last nibble 0")); 3961 3962 while (countMask) 3963 { 3964 countOnes++; 3965 countMask = (uint16_t)(countMask >> 1); 3966 } 3967 3968 if (!POWER_OF_2(p_CcNode->numOfKeys)) 3969 RETURN_ERROR( 3970 MAJOR, 3971 E_INVALID_VALUE, 3972 ("For Node of the type INDEXED numOfKeys has to be powerOfTwo")); 3973 3974 if (p_CcNode->numOfKeys != ((uint32_t)1 << countOnes)) 3975 RETURN_ERROR( 3976 MAJOR, 3977 E_INVALID_VALUE, 3978 ("For Node of the type IC_HASH_INDEXED numOfKeys has to be powerOfTwo")); 3979 3980 if (p_CcNodeParam->keysParams.maxNumOfKeys 3981 && (p_CcNodeParam->keysParams.maxNumOfKeys != p_CcNode->numOfKeys)) 3982 RETURN_ERROR( 3983 MAJOR, 3984 E_INVALID_VALUE, 3985 ("For Node of the type INDEXED 'maxNumOfKeys' should be 0 or equal 'numOfKeys'")); 3986 3987 /* Validate statistics parameters */ 3988 err = ValidateAndCalcStatsParams(p_CcNode, p_CcNodeParam, 3989 &(p_CcNode->numOfStatsFLRs), 3990 &(p_CcNode->countersArraySize)); 3991 if (err) 3992 RETURN_ERROR(MAJOR, err, ("Invalid statistics parameters")); 3993 3994 err = ValidateNextEngineParams( 3995 h_FmPcd, &p_CcNodeParam->keysParams.ccNextEngineParamsForMiss, 3996 p_CcNode->statisticsMode); 3997 if (GET_ERROR_TYPE(err) != E_NOT_SUPPORTED) 3998 RETURN_ERROR( 3999 MAJOR, 4000 err, 4001 ("MissNextEngineParams for the node of the type IC_INDEX_HASH has to be UnInitialized")); 4002 4003 for (tmp = 0; tmp < p_CcNode->numOfKeys; tmp++) 4004 { 4005 p_KeyParams = &p_CcNodeParam->keysParams.keyParams[tmp]; 4006 4007 if (p_KeyParams->p_Mask || p_KeyParams->p_Key) 4008 RETURN_ERROR( 4009 MAJOR, 4010 E_INVALID_VALUE, 4011 ("For Node of the type IC_HASH_INDEXED p_Key or p_Mask has to be NULL")); 4012 4013 if ((glblMask & (tmp * 16)) == (tmp * 16)) 4014 { 4015 err = ValidateNextEngineParams(h_FmPcd, 4016 &p_KeyParams->ccNextEngineParams, 4017 p_CcNode->statisticsMode); 4018 if (err) 4019 RETURN_ERROR( 4020 MAJOR, 4021 err, 4022 ("This index has to be initialized for the node of the type IC_INDEX_HASH according to settings of GlobalMask ")); 4023 4024 if (p_KeyParams->ccNextEngineParams.h_Manip) 4025 { 4026 err = FmPcdManipCheckParamsForCcNextEngine( 4027 &p_KeyParams->ccNextEngineParams, &requiredAction); 4028 if (err) 4029 RETURN_ERROR(MAJOR, err, (NO_MSG)); 4030 p_CcNode->keyAndNextEngineParams[tmp].requiredAction = 4031 requiredAction; 4032 } 4033 4034 memcpy(&p_CcNode->keyAndNextEngineParams[tmp].nextEngineParams, 4035 &p_KeyParams->ccNextEngineParams, 4036 sizeof(t_FmPcdCcNextEngineParams)); 4037 4038 if ((p_CcNode->keyAndNextEngineParams[tmp].nextEngineParams.nextEngine 4039 == e_FM_PCD_CC) 4040 && p_CcNode->keyAndNextEngineParams[tmp].nextEngineParams.h_Manip) 4041 { 4042 err = 4043 AllocAndFillAdForContLookupManip( 4044 p_CcNode->keyAndNextEngineParams[tmp].nextEngineParams.params.ccParams.h_CcNode); 4045 if (err) 4046 RETURN_ERROR(MAJOR, err, (NO_MSG)); 4047 } 4048 } 4049 else 4050 { 4051 err = ValidateNextEngineParams(h_FmPcd, 4052 &p_KeyParams->ccNextEngineParams, 4053 p_CcNode->statisticsMode); 4054 if (GET_ERROR_TYPE(err) != E_NOT_SUPPORTED) 4055 RETURN_ERROR( 4056 MAJOR, 4057 err, 4058 ("This index has to be UnInitialized for the node of the type IC_INDEX_HASH according to settings of GlobalMask")); 4059 } 4060 } 4061 4062 *isKeyTblAlloc = FALSE; 4063 glblMask = htobe16(glblMask); 4064 memcpy(PTR_MOVE(p_CcNode->p_GlblMask, 2), &glblMask, 2); 4065 4066 return E_OK; 4067 } 4068 4069 static t_Error ModifyNextEngineParamNode( 4070 t_Handle h_FmPcd, t_Handle h_FmPcdCcNode, uint16_t keyIndex, 4071 t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams) 4072 { 4073 t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_FmPcdCcNode; 4074 t_FmPcd *p_FmPcd; 4075 t_List h_OldPointersLst, h_NewPointersLst; 4076 t_FmPcdModifyCcKeyAdditionalParams *p_ModifyKeyParams; 4077 t_Error err = E_OK; 4078 4079 SANITY_CHECK_RETURN_ERROR(h_FmPcd, E_INVALID_VALUE); 4080 SANITY_CHECK_RETURN_ERROR(p_CcNode, E_INVALID_HANDLE); 4081 4082 if (keyIndex >= p_CcNode->numOfKeys) 4083 RETURN_ERROR(MAJOR, E_INVALID_STATE, 4084 ("keyIndex > previously cleared last index + 1")); 4085 4086 p_FmPcd = (t_FmPcd *)p_CcNode->h_FmPcd; 4087 4088 INIT_LIST(&h_OldPointersLst); 4089 INIT_LIST(&h_NewPointersLst); 4090 4091 p_ModifyKeyParams = ModifyNodeCommonPart(p_CcNode, keyIndex, 4092 e_MODIFY_STATE_CHANGE, FALSE, 4093 FALSE, FALSE); 4094 if (!p_ModifyKeyParams) 4095 RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG); 4096 4097 if (p_CcNode->maxNumOfKeys 4098 && !TRY_LOCK(p_FmPcd->h_ShadowSpinlock, &p_FmPcd->shadowLock)) 4099 { 4100 XX_Free(p_ModifyKeyParams); 4101 return ERROR_CODE(E_BUSY); 4102 } 4103 4104 err = BuildNewNodeModifyNextEngine(h_FmPcd, p_CcNode, keyIndex, 4105 p_FmPcdCcNextEngineParams, 4106 &h_OldPointersLst, &h_NewPointersLst, 4107 p_ModifyKeyParams); 4108 if (err) 4109 { 4110 XX_Free(p_ModifyKeyParams); 4111 if (p_CcNode->maxNumOfKeys) 4112 RELEASE_LOCK(p_FmPcd->shadowLock); 4113 RETURN_ERROR(MAJOR, err, NO_MSG); 4114 } 4115 4116 err = DoDynamicChange(p_FmPcd, &h_OldPointersLst, &h_NewPointersLst, 4117 p_ModifyKeyParams, FALSE); 4118 4119 if (p_CcNode->maxNumOfKeys) 4120 RELEASE_LOCK(p_FmPcd->shadowLock); 4121 4122 return err; 4123 } 4124 4125 static t_Error FindKeyIndex(t_Handle h_CcNode, uint8_t keySize, uint8_t *p_Key, 4126 uint8_t *p_Mask, uint16_t *p_KeyIndex) 4127 { 4128 t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode; 4129 uint8_t tmpMask[FM_PCD_MAX_SIZE_OF_KEY]; 4130 uint16_t i; 4131 4132 ASSERT_COND(p_Key); 4133 ASSERT_COND(p_KeyIndex); 4134 ASSERT_COND(keySize < FM_PCD_MAX_SIZE_OF_KEY); 4135 4136 if (keySize != p_CcNode->userSizeOfExtraction) 4137 RETURN_ERROR( 4138 MINOR, E_INVALID_VALUE, 4139 ("Key size doesn't match the extraction size of the node")); 4140 4141 /* If user didn't pass a mask for this key, we'll look for full extraction mask */ 4142 if (!p_Mask) 4143 memset(tmpMask, 0xFF, keySize); 4144 4145 for (i = 0; i < p_CcNode->numOfKeys; i++) 4146 { 4147 /* Comparing received key */ 4148 if (memcmp(p_Key, p_CcNode->keyAndNextEngineParams[i].key, keySize) 4149 == 0) 4150 { 4151 if (p_Mask) 4152 { 4153 /* If a user passed a mask for this key, it must match to the existing key's mask for a correct match */ 4154 if (memcmp(p_Mask, p_CcNode->keyAndNextEngineParams[i].mask, 4155 keySize) == 0) 4156 { 4157 *p_KeyIndex = i; 4158 return E_OK; 4159 } 4160 } 4161 else 4162 { 4163 /* If user didn't pass a mask for this key, check if the existing key mask is full extraction */ 4164 if (memcmp(tmpMask, p_CcNode->keyAndNextEngineParams[i].mask, 4165 keySize) == 0) 4166 { 4167 *p_KeyIndex = i; 4168 return E_OK; 4169 } 4170 } 4171 } 4172 } 4173 4174 return ERROR_CODE(E_NOT_FOUND); 4175 } 4176 4177 static t_Error CalcAndUpdateCcShadow(t_FmPcdCcNode *p_CcNode, 4178 bool isKeyTblAlloc, 4179 uint32_t *p_MatchTableSize, 4180 uint32_t *p_AdTableSize) 4181 { 4182 uint32_t shadowSize; 4183 t_Error err; 4184 4185 /* Calculate keys table maximal size - each entry consists of a key and a mask, 4186 (if local mask support is requested) */ 4187 *p_MatchTableSize = p_CcNode->ccKeySizeAccExtraction * sizeof(uint8_t) 4188 * p_CcNode->maxNumOfKeys; 4189 4190 if (p_CcNode->maskSupport) 4191 *p_MatchTableSize *= 2; 4192 4193 /* Calculate next action descriptors table, including one more entry for miss */ 4194 *p_AdTableSize = (uint32_t)((p_CcNode->maxNumOfKeys + 1) 4195 * FM_PCD_CC_AD_ENTRY_SIZE); 4196 4197 /* Calculate maximal shadow size of this node. 4198 All shadow structures will be used for runtime modifications host command. If 4199 keys table was allocated for this node, the keys table and next engines table may 4200 be modified in run time (entries added or removed), so shadow tables are requires. 4201 Otherwise, the only supported runtime modification is a specific next engine update 4202 and this requires shadow memory of a single AD */ 4203 4204 /* Shadow size should be enough to hold the following 3 structures: 4205 * 1 - an action descriptor */ 4206 shadowSize = FM_PCD_CC_AD_ENTRY_SIZE; 4207 4208 /* 2 - keys match table, if was allocated for the current node */ 4209 if (isKeyTblAlloc) 4210 shadowSize += *p_MatchTableSize; 4211 4212 /* 3 - next action descriptors table */ 4213 shadowSize += *p_AdTableSize; 4214 4215 /* Update shadow to the calculated size */ 4216 err = FmPcdUpdateCcShadow(p_CcNode->h_FmPcd, (uint32_t)shadowSize, 4217 FM_PCD_CC_AD_TABLE_ALIGN); 4218 if (err != E_OK) 4219 { 4220 DeleteNode(p_CcNode); 4221 RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM allocation for CC node shadow")); 4222 } 4223 4224 return E_OK; 4225 } 4226 4227 static t_Error AllocStatsObjs(t_FmPcdCcNode *p_CcNode) 4228 { 4229 t_FmPcdStatsObj *p_StatsObj; 4230 t_Handle h_FmMuram, h_StatsAd, h_StatsCounters; 4231 uint32_t i; 4232 4233 h_FmMuram = FmPcdGetMuramHandle(p_CcNode->h_FmPcd); 4234 if (!h_FmMuram) 4235 RETURN_ERROR(MAJOR, E_INVALID_HANDLE, ("FM MURAM")); 4236 4237 /* Allocate statistics ADs and statistics counter. An extra pair (AD + counters) 4238 will be allocated to support runtime modifications */ 4239 for (i = 0; i < p_CcNode->maxNumOfKeys + 2; i++) 4240 { 4241 /* Allocate list object structure */ 4242 p_StatsObj = XX_Malloc(sizeof(t_FmPcdStatsObj)); 4243 if (!p_StatsObj) 4244 { 4245 FreeStatObjects(&p_CcNode->availableStatsLst, h_FmMuram); 4246 RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Statistics object")); 4247 } 4248 memset(p_StatsObj, 0, sizeof(t_FmPcdStatsObj)); 4249 4250 /* Allocate statistics AD from MURAM */ 4251 h_StatsAd = (t_Handle)FM_MURAM_AllocMem(h_FmMuram, 4252 FM_PCD_CC_AD_ENTRY_SIZE, 4253 FM_PCD_CC_AD_TABLE_ALIGN); 4254 if (!h_StatsAd) 4255 { 4256 FreeStatObjects(&p_CcNode->availableStatsLst, h_FmMuram); 4257 XX_Free(p_StatsObj); 4258 RETURN_ERROR(MAJOR, E_NO_MEMORY, 4259 ("MURAM allocation for statistics ADs")); 4260 } 4261 MemSet8(h_StatsAd, 0, FM_PCD_CC_AD_ENTRY_SIZE); 4262 4263 /* Allocate statistics counters from MURAM */ 4264 h_StatsCounters = (t_Handle)FM_MURAM_AllocMem( 4265 h_FmMuram, p_CcNode->countersArraySize, 4266 FM_PCD_CC_AD_TABLE_ALIGN); 4267 if (!h_StatsCounters) 4268 { 4269 FreeStatObjects(&p_CcNode->availableStatsLst, h_FmMuram); 4270 FM_MURAM_FreeMem(h_FmMuram, h_StatsAd); 4271 XX_Free(p_StatsObj); 4272 RETURN_ERROR(MAJOR, E_NO_MEMORY, 4273 ("MURAM allocation for statistics counters")); 4274 } 4275 MemSet8(h_StatsCounters, 0, p_CcNode->countersArraySize); 4276 4277 p_StatsObj->h_StatsAd = h_StatsAd; 4278 p_StatsObj->h_StatsCounters = h_StatsCounters; 4279 4280 EnqueueStatsObj(&p_CcNode->availableStatsLst, p_StatsObj); 4281 } 4282 4283 return E_OK; 4284 } 4285 4286 static t_Error MatchTableGetKeyStatistics( 4287 t_FmPcdCcNode *p_CcNode, uint16_t keyIndex, 4288 t_FmPcdCcKeyStatistics *p_KeyStatistics) 4289 { 4290 uint32_t *p_StatsCounters, i; 4291 4292 if (p_CcNode->statisticsMode == e_FM_PCD_CC_STATS_MODE_NONE) 4293 RETURN_ERROR(MAJOR, E_INVALID_STATE, 4294 ("Statistics were not enabled for this match table")); 4295 4296 if (!p_CcNode->keyAndNextEngineParams[keyIndex].p_StatsObj) 4297 RETURN_ERROR(MAJOR, E_INVALID_STATE, 4298 ("Statistics were not enabled for this key")); 4299 4300 memset(p_KeyStatistics, 0, sizeof(t_FmPcdCcKeyStatistics)); 4301 4302 p_StatsCounters = 4303 p_CcNode->keyAndNextEngineParams[keyIndex].p_StatsObj->h_StatsCounters; 4304 ASSERT_COND(p_StatsCounters); 4305 4306 p_KeyStatistics->byteCount = GET_UINT32(*p_StatsCounters); 4307 4308 for (i = 1; i <= p_CcNode->numOfStatsFLRs; i++) 4309 { 4310 p_StatsCounters = 4311 PTR_MOVE(p_StatsCounters, FM_PCD_CC_STATS_COUNTER_SIZE); 4312 4313 p_KeyStatistics->frameCount += GET_UINT32(*p_StatsCounters); 4314 4315 #if (DPAA_VERSION >= 11) 4316 p_KeyStatistics->frameLengthRangeCount[i - 1] = 4317 GET_UINT32(*p_StatsCounters); 4318 #endif /* (DPAA_VERSION >= 11) */ 4319 } 4320 4321 return E_OK; 4322 } 4323 4324 static t_Error MatchTableSet(t_Handle h_FmPcd, t_FmPcdCcNode *p_CcNode, 4325 t_FmPcdCcNodeParams *p_CcNodeParam) 4326 { 4327 t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd; 4328 t_FmPcdCcNode *p_FmPcdCcNextNode; 4329 t_Error err = E_OK; 4330 uint32_t tmp, keySize; 4331 bool glblMask = FALSE; 4332 t_FmPcdCcKeyParams *p_KeyParams; 4333 t_Handle h_FmMuram, p_KeysMatchTblTmp, p_AdTableTmp; 4334 #if (DPAA_VERSION >= 11) 4335 t_Handle h_StatsFLRs; 4336 #endif /* (DPAA_VERSION >= 11) */ 4337 bool fullField = FALSE; 4338 ccPrivateInfo_t icCode = CC_PRIVATE_INFO_NONE; 4339 bool isKeyTblAlloc, fromIc = FALSE; 4340 uint32_t matchTableSize, adTableSize; 4341 t_CcNodeInformation ccNodeInfo, *p_CcInformation; 4342 t_FmPcdStatsObj *p_StatsObj; 4343 t_FmPcdCcStatsParams statsParams = { 0 }; 4344 t_Handle h_Manip; 4345 4346 ASSERT_COND(h_FmPcd); 4347 ASSERT_COND(p_CcNode); 4348 ASSERT_COND(p_CcNodeParam); 4349 4350 p_CcNode->p_GlblMask = (t_Handle)XX_Malloc( 4351 CC_GLBL_MASK_SIZE * sizeof(uint8_t)); 4352 memset(p_CcNode->p_GlblMask, 0, CC_GLBL_MASK_SIZE * sizeof(uint8_t)); 4353 4354 p_CcNode->h_FmPcd = h_FmPcd; 4355 p_CcNode->numOfKeys = p_CcNodeParam->keysParams.numOfKeys; 4356 p_CcNode->maxNumOfKeys = p_CcNodeParam->keysParams.maxNumOfKeys; 4357 p_CcNode->maskSupport = p_CcNodeParam->keysParams.maskSupport; 4358 p_CcNode->statisticsMode = p_CcNodeParam->keysParams.statisticsMode; 4359 4360 /* For backward compatibility - even if statistics mode is nullified, 4361 we'll fix it to frame mode so we can support per-key request for 4362 statistics using 'statisticsEn' in next engine parameters */ 4363 if (!p_CcNode->maxNumOfKeys 4364 && (p_CcNode->statisticsMode == e_FM_PCD_CC_STATS_MODE_NONE)) 4365 p_CcNode->statisticsMode = e_FM_PCD_CC_STATS_MODE_FRAME; 4366 4367 h_FmMuram = FmPcdGetMuramHandle(h_FmPcd); 4368 if (!h_FmMuram) 4369 RETURN_ERROR(MAJOR, E_INVALID_HANDLE, ("FM MURAM")); 4370 4371 INIT_LIST(&p_CcNode->ccPrevNodesLst); 4372 INIT_LIST(&p_CcNode->ccTreeIdLst); 4373 INIT_LIST(&p_CcNode->ccTreesLst); 4374 INIT_LIST(&p_CcNode->availableStatsLst); 4375 4376 p_CcNode->h_Spinlock = XX_InitSpinlock(); 4377 if (!p_CcNode->h_Spinlock) 4378 { 4379 DeleteNode(p_CcNode); 4380 RETURN_ERROR(MAJOR, E_NO_MEMORY, ("CC node spinlock")); 4381 } 4382 4383 if ((p_CcNodeParam->extractCcParams.type == e_FM_PCD_EXTRACT_BY_HDR) 4384 && ((p_CcNodeParam->extractCcParams.extractByHdr.hdr 4385 == HEADER_TYPE_IPv4) 4386 || (p_CcNodeParam->extractCcParams.extractByHdr.hdr 4387 == HEADER_TYPE_IPv6)) 4388 && (p_CcNodeParam->extractCcParams.extractByHdr.type 4389 == e_FM_PCD_EXTRACT_FULL_FIELD) 4390 && ((p_CcNodeParam->extractCcParams.extractByHdr.extractByHdrType.fullField.ipv6 4391 == NET_HEADER_FIELD_IPv6_HOP_LIMIT) 4392 || (p_CcNodeParam->extractCcParams.extractByHdr.extractByHdrType.fullField.ipv4 4393 == NET_HEADER_FIELD_IPv4_TTL))) 4394 { 4395 err = Ipv4TtlOrIpv6HopLimitCheckParams(h_FmPcd, p_CcNodeParam, p_CcNode, 4396 &isKeyTblAlloc); 4397 glblMask = FALSE; 4398 } 4399 else 4400 if ((p_CcNodeParam->extractCcParams.type == e_FM_PCD_EXTRACT_NON_HDR) 4401 && ((p_CcNodeParam->extractCcParams.extractNonHdr.src 4402 == e_FM_PCD_EXTRACT_FROM_KEY) 4403 || (p_CcNodeParam->extractCcParams.extractNonHdr.src 4404 == e_FM_PCD_EXTRACT_FROM_HASH) 4405 || (p_CcNodeParam->extractCcParams.extractNonHdr.src 4406 == e_FM_PCD_EXTRACT_FROM_FLOW_ID))) 4407 { 4408 if ((p_CcNodeParam->extractCcParams.extractNonHdr.src 4409 == e_FM_PCD_EXTRACT_FROM_FLOW_ID) 4410 && (p_CcNodeParam->extractCcParams.extractNonHdr.offset != 0)) 4411 { 4412 DeleteNode(p_CcNode); 4413 RETURN_ERROR( 4414 MAJOR, 4415 E_INVALID_VALUE, 4416 ("In the case of the extraction from e_FM_PCD_EXTRACT_FROM_FLOW_ID offset has to be 0")); 4417 } 4418 4419 icCode = IcDefineCode(p_CcNodeParam); 4420 fromIc = TRUE; 4421 if (icCode == CC_PRIVATE_INFO_NONE) 4422 { 4423 DeleteNode(p_CcNode); 4424 RETURN_ERROR( 4425 MAJOR, 4426 E_INVALID_STATE, 4427 ("user asked extraction from IC and field in internal context or action wasn't initialized in the right way")); 4428 } 4429 4430 if ((icCode == CC_PRIVATE_INFO_IC_DEQ_FQID_INDEX_LOOKUP) 4431 || (icCode == CC_PRIVATE_INFO_IC_HASH_INDEX_LOOKUP)) 4432 { 4433 err = IcHashIndexedCheckParams(h_FmPcd, p_CcNodeParam, p_CcNode, 4434 &isKeyTblAlloc); 4435 glblMask = TRUE; 4436 } 4437 else 4438 { 4439 err = CheckParams(h_FmPcd, p_CcNodeParam, p_CcNode, 4440 &isKeyTblAlloc); 4441 if (p_CcNode->glblMaskSize) 4442 glblMask = TRUE; 4443 } 4444 } 4445 else 4446 { 4447 err = CheckParams(h_FmPcd, p_CcNodeParam, p_CcNode, &isKeyTblAlloc); 4448 if (p_CcNode->glblMaskSize) 4449 glblMask = TRUE; 4450 } 4451 4452 if (err) 4453 { 4454 DeleteNode(p_CcNode); 4455 RETURN_ERROR(MAJOR, err, NO_MSG); 4456 } 4457 4458 switch (p_CcNodeParam->extractCcParams.type) 4459 { 4460 case (e_FM_PCD_EXTRACT_BY_HDR): 4461 switch (p_CcNodeParam->extractCcParams.extractByHdr.type) 4462 { 4463 case (e_FM_PCD_EXTRACT_FULL_FIELD): 4464 p_CcNode->parseCode = 4465 GetFullFieldParseCode( 4466 p_CcNodeParam->extractCcParams.extractByHdr.hdr, 4467 p_CcNodeParam->extractCcParams.extractByHdr.hdrIndex, 4468 p_CcNodeParam->extractCcParams.extractByHdr.extractByHdrType.fullField); 4469 GetSizeHeaderField( 4470 p_CcNodeParam->extractCcParams.extractByHdr.hdr, 4471 p_CcNodeParam->extractCcParams.extractByHdr.extractByHdrType.fullField, 4472 &p_CcNode->sizeOfExtraction); 4473 fullField = TRUE; 4474 if ((p_CcNode->parseCode != CC_PC_FF_TCI1) 4475 && (p_CcNode->parseCode != CC_PC_FF_TCI2) 4476 && (p_CcNode->parseCode != CC_PC_FF_MPLS1) 4477 && (p_CcNode->parseCode != CC_PC_FF_MPLS_LAST) 4478 && (p_CcNode->parseCode != CC_PC_FF_IPV4IPTOS_TC1) 4479 && (p_CcNode->parseCode != CC_PC_FF_IPV4IPTOS_TC2) 4480 && (p_CcNode->parseCode 4481 != CC_PC_FF_IPTOS_IPV6TC1_IPV6FLOW1) 4482 && (p_CcNode->parseCode != CC_PC_FF_IPDSCP) 4483 && (p_CcNode->parseCode 4484 != CC_PC_FF_IPTOS_IPV6TC2_IPV6FLOW2) 4485 && glblMask) 4486 { 4487 glblMask = FALSE; 4488 p_CcNode->glblMaskSize = 4; 4489 p_CcNode->lclMask = TRUE; 4490 } 4491 break; 4492 4493 case (e_FM_PCD_EXTRACT_FROM_HDR): 4494 p_CcNode->sizeOfExtraction = 4495 p_CcNodeParam->extractCcParams.extractByHdr.extractByHdrType.fromHdr.size; 4496 p_CcNode->offset = 4497 p_CcNodeParam->extractCcParams.extractByHdr.extractByHdrType.fromHdr.offset; 4498 p_CcNode->userOffset = 4499 p_CcNodeParam->extractCcParams.extractByHdr.extractByHdrType.fromHdr.offset; 4500 p_CcNode->parseCode = 4501 GetPrParseCode( 4502 p_CcNodeParam->extractCcParams.extractByHdr.hdr, 4503 p_CcNodeParam->extractCcParams.extractByHdr.hdrIndex, 4504 p_CcNode->offset, glblMask, 4505 &p_CcNode->prsArrayOffset); 4506 break; 4507 4508 case (e_FM_PCD_EXTRACT_FROM_FIELD): 4509 p_CcNode->offset = 4510 p_CcNodeParam->extractCcParams.extractByHdr.extractByHdrType.fromField.offset; 4511 p_CcNode->userOffset = 4512 p_CcNodeParam->extractCcParams.extractByHdr.extractByHdrType.fromField.offset; 4513 p_CcNode->sizeOfExtraction = 4514 p_CcNodeParam->extractCcParams.extractByHdr.extractByHdrType.fromField.size; 4515 p_CcNode->parseCode = 4516 GetFieldParseCode( 4517 p_CcNodeParam->extractCcParams.extractByHdr.hdr, 4518 p_CcNodeParam->extractCcParams.extractByHdr.extractByHdrType.fromField.field, 4519 p_CcNode->offset, 4520 &p_CcNode->prsArrayOffset, 4521 p_CcNodeParam->extractCcParams.extractByHdr.hdrIndex); 4522 break; 4523 4524 default: 4525 DeleteNode(p_CcNode); 4526 RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG); 4527 } 4528 break; 4529 4530 case (e_FM_PCD_EXTRACT_NON_HDR): 4531 /* get the field code for the generic extract */ 4532 p_CcNode->sizeOfExtraction = 4533 p_CcNodeParam->extractCcParams.extractNonHdr.size; 4534 p_CcNode->offset = 4535 p_CcNodeParam->extractCcParams.extractNonHdr.offset; 4536 p_CcNode->userOffset = 4537 p_CcNodeParam->extractCcParams.extractNonHdr.offset; 4538 p_CcNode->parseCode = GetGenParseCode( 4539 p_CcNodeParam->extractCcParams.extractNonHdr.src, 4540 p_CcNode->offset, glblMask, &p_CcNode->prsArrayOffset, 4541 fromIc, icCode); 4542 4543 if (p_CcNode->parseCode == CC_PC_GENERIC_IC_HASH_INDEXED) 4544 { 4545 if ((p_CcNode->offset + p_CcNode->sizeOfExtraction) > 8) 4546 { 4547 DeleteNode(p_CcNode); 4548 RETURN_ERROR( 4549 MAJOR, 4550 E_INVALID_SELECTION, 4551 ("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)")); 4552 } 4553 } 4554 if ((p_CcNode->parseCode == CC_PC_GENERIC_IC_GMASK) 4555 || (p_CcNode->parseCode == CC_PC_GENERIC_IC_HASH_INDEXED)) 4556 { 4557 p_CcNode->offset += p_CcNode->prsArrayOffset; 4558 p_CcNode->prsArrayOffset = 0; 4559 } 4560 break; 4561 4562 default: 4563 DeleteNode(p_CcNode); 4564 RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG); 4565 } 4566 4567 if (p_CcNode->parseCode == CC_PC_ILLEGAL) 4568 { 4569 DeleteNode(p_CcNode); 4570 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("illegal extraction type")); 4571 } 4572 4573 if ((p_CcNode->sizeOfExtraction > FM_PCD_MAX_SIZE_OF_KEY) 4574 || !p_CcNode->sizeOfExtraction) 4575 { 4576 DeleteNode(p_CcNode); 4577 RETURN_ERROR(MAJOR, E_INVALID_VALUE, 4578 ("sizeOfExatrction can not be greater than 56 and not 0")); 4579 } 4580 4581 if (p_CcNodeParam->keysParams.keySize != p_CcNode->sizeOfExtraction) 4582 { 4583 DeleteNode(p_CcNode); 4584 RETURN_ERROR(MAJOR, E_INVALID_VALUE, 4585 ("keySize has to be equal to sizeOfExtraction")); 4586 } 4587 4588 p_CcNode->userSizeOfExtraction = p_CcNode->sizeOfExtraction; 4589 4590 if (!glblMask) 4591 memset(p_CcNode->p_GlblMask, 0xff, CC_GLBL_MASK_SIZE * sizeof(uint8_t)); 4592 4593 err = CheckAndSetManipParamsWithCcNodeParams(p_CcNode); 4594 if (err != E_OK) 4595 { 4596 DeleteNode(p_CcNode); 4597 RETURN_ERROR(MAJOR, E_INVALID_VALUE, 4598 ("keySize has to be equal to sizeOfExtraction")); 4599 } 4600 4601 /* Calculating matching table entry size by rounding up the user-defined size of extraction to valid entry size */ 4602 GetCcExtractKeySize(p_CcNode->sizeOfExtraction, 4603 &p_CcNode->ccKeySizeAccExtraction); 4604 4605 /* If local mask is used, it is stored next to each key in the keys match table */ 4606 if (p_CcNode->lclMask) 4607 keySize = (uint32_t)(2 * p_CcNode->ccKeySizeAccExtraction); 4608 else 4609 keySize = p_CcNode->ccKeySizeAccExtraction; 4610 4611 /* Update CC shadow with maximal size required by this node */ 4612 if (p_CcNode->maxNumOfKeys) 4613 { 4614 err = CalcAndUpdateCcShadow(p_CcNode, isKeyTblAlloc, &matchTableSize, 4615 &adTableSize); 4616 if (err != E_OK) 4617 { 4618 DeleteNode(p_CcNode); 4619 RETURN_ERROR(MAJOR, err, NO_MSG); 4620 } 4621 4622 p_CcNode->keysMatchTableMaxSize = matchTableSize; 4623 4624 if (p_CcNode->statisticsMode != e_FM_PCD_CC_STATS_MODE_NONE) 4625 { 4626 err = AllocStatsObjs(p_CcNode); 4627 if (err != E_OK) 4628 { 4629 DeleteNode(p_CcNode); 4630 RETURN_ERROR(MAJOR, err, NO_MSG); 4631 } 4632 } 4633 4634 /* If manipulation will be initialized before this node, it will use the table 4635 descriptor in the AD table of previous node and this node will need an extra 4636 AD as his table descriptor. */ 4637 p_CcNode->h_TmpAd = (t_Handle)FM_MURAM_AllocMem( 4638 h_FmMuram, FM_PCD_CC_AD_ENTRY_SIZE, FM_PCD_CC_AD_TABLE_ALIGN); 4639 if (!p_CcNode->h_TmpAd) 4640 { 4641 DeleteNode(p_CcNode); 4642 RETURN_ERROR(MAJOR, E_NO_MEMORY, 4643 ("MURAM allocation for CC action descriptor")); 4644 } 4645 } 4646 else 4647 { 4648 matchTableSize = (uint32_t)(keySize * sizeof(uint8_t) 4649 * (p_CcNode->numOfKeys + 1)); 4650 adTableSize = (uint32_t)(FM_PCD_CC_AD_ENTRY_SIZE 4651 * (p_CcNode->numOfKeys + 1)); 4652 } 4653 4654 #if (DPAA_VERSION >= 11) 4655 switch (p_CcNode->statisticsMode) 4656 { 4657 4658 case e_FM_PCD_CC_STATS_MODE_RMON: 4659 /* If RMON statistics or RMON conditional statistics modes are requested, 4660 allocate frame length ranges array */ 4661 p_CcNode->h_StatsFLRs = FM_MURAM_AllocMem( 4662 h_FmMuram, 4663 (uint32_t)(p_CcNode->numOfStatsFLRs) 4664 * FM_PCD_CC_STATS_FLR_SIZE, 4665 FM_PCD_CC_AD_TABLE_ALIGN); 4666 4667 if (!p_CcNode->h_StatsFLRs) 4668 { 4669 DeleteNode(p_CcNode); 4670 RETURN_ERROR( 4671 MAJOR, E_NO_MEMORY, 4672 ("MURAM allocation for CC frame length ranges array")); 4673 } 4674 4675 /* Initialize using value received from the user */ 4676 for (tmp = 0; tmp < p_CcNode->numOfStatsFLRs; tmp++) 4677 { 4678 uint16_t flr = 4679 cpu_to_be16(p_CcNodeParam->keysParams.frameLengthRanges[tmp]); 4680 4681 h_StatsFLRs = 4682 PTR_MOVE(p_CcNode->h_StatsFLRs, tmp * FM_PCD_CC_STATS_FLR_SIZE); 4683 4684 MemCpy8(h_StatsFLRs, 4685 &flr, 4686 FM_PCD_CC_STATS_FLR_SIZE); 4687 } 4688 break; 4689 4690 default: 4691 break; 4692 } 4693 #endif /* (DPAA_VERSION >= 11) */ 4694 4695 /* Allocate keys match table. Not required for some CC nodes, for example for IPv4 TTL 4696 identification, IPv6 hop count identification, etc. */ 4697 if (isKeyTblAlloc) 4698 { 4699 p_CcNode->h_KeysMatchTable = (t_Handle)FM_MURAM_AllocMem( 4700 h_FmMuram, matchTableSize, FM_PCD_CC_KEYS_MATCH_TABLE_ALIGN); 4701 if (!p_CcNode->h_KeysMatchTable) 4702 { 4703 DeleteNode(p_CcNode); 4704 RETURN_ERROR(MAJOR, E_NO_MEMORY, 4705 ("MURAM allocation for CC node key match table")); 4706 } 4707 MemSet8((uint8_t *)p_CcNode->h_KeysMatchTable, 0, matchTableSize); 4708 } 4709 4710 /* Allocate action descriptors table */ 4711 p_CcNode->h_AdTable = (t_Handle)FM_MURAM_AllocMem(h_FmMuram, adTableSize, 4712 FM_PCD_CC_AD_TABLE_ALIGN); 4713 if (!p_CcNode->h_AdTable) 4714 { 4715 DeleteNode(p_CcNode); 4716 RETURN_ERROR(MAJOR, E_NO_MEMORY, 4717 ("MURAM allocation for CC node action descriptors table")); 4718 } 4719 MemSet8((uint8_t *)p_CcNode->h_AdTable, 0, adTableSize); 4720 4721 p_KeysMatchTblTmp = p_CcNode->h_KeysMatchTable; 4722 p_AdTableTmp = p_CcNode->h_AdTable; 4723 4724 /* For each key, create the key and the next step AD */ 4725 for (tmp = 0; tmp < p_CcNode->numOfKeys; tmp++) 4726 { 4727 p_KeyParams = &p_CcNodeParam->keysParams.keyParams[tmp]; 4728 4729 if (p_KeysMatchTblTmp) 4730 { 4731 /* Copy the key */ 4732 MemCpy8((void*)p_KeysMatchTblTmp, p_KeyParams->p_Key, 4733 p_CcNode->sizeOfExtraction); 4734 4735 /* Copy the key mask or initialize it to 0xFF..F */ 4736 if (p_CcNode->lclMask && p_KeyParams->p_Mask) 4737 { 4738 MemCpy8(PTR_MOVE(p_KeysMatchTblTmp, 4739 p_CcNode->ccKeySizeAccExtraction), /* User's size of extraction rounded up to a valid matching table entry size */ 4740 p_KeyParams->p_Mask, p_CcNode->sizeOfExtraction); /* Exact size of extraction as received from the user */ 4741 } 4742 else 4743 if (p_CcNode->lclMask) 4744 { 4745 MemSet8(PTR_MOVE(p_KeysMatchTblTmp, 4746 p_CcNode->ccKeySizeAccExtraction), /* User's size of extraction rounded up to a valid matching table entry size */ 4747 0xff, p_CcNode->sizeOfExtraction); /* Exact size of extraction as received from the user */ 4748 } 4749 4750 p_KeysMatchTblTmp = 4751 PTR_MOVE(p_KeysMatchTblTmp, keySize * sizeof(uint8_t)); 4752 } 4753 4754 /* Create the next action descriptor in the match table */ 4755 if (p_KeyParams->ccNextEngineParams.statisticsEn) 4756 { 4757 p_StatsObj = GetStatsObj(p_CcNode); 4758 ASSERT_COND(p_StatsObj); 4759 4760 statsParams.h_StatsAd = p_StatsObj->h_StatsAd; 4761 statsParams.h_StatsCounters = p_StatsObj->h_StatsCounters; 4762 #if (DPAA_VERSION >= 11) 4763 statsParams.h_StatsFLRs = p_CcNode->h_StatsFLRs; 4764 4765 #endif /* (DPAA_VERSION >= 11) */ 4766 NextStepAd(p_AdTableTmp, &statsParams, 4767 &p_KeyParams->ccNextEngineParams, p_FmPcd); 4768 4769 p_CcNode->keyAndNextEngineParams[tmp].p_StatsObj = p_StatsObj; 4770 } 4771 else 4772 { 4773 NextStepAd(p_AdTableTmp, NULL, &p_KeyParams->ccNextEngineParams, 4774 p_FmPcd); 4775 4776 p_CcNode->keyAndNextEngineParams[tmp].p_StatsObj = NULL; 4777 } 4778 4779 p_AdTableTmp = PTR_MOVE(p_AdTableTmp, FM_PCD_CC_AD_ENTRY_SIZE); 4780 } 4781 4782 /* Update next engine for the 'miss' entry */ 4783 if (p_CcNodeParam->keysParams.ccNextEngineParamsForMiss.statisticsEn) 4784 { 4785 p_StatsObj = GetStatsObj(p_CcNode); 4786 ASSERT_COND(p_StatsObj); 4787 4788 /* All 'bucket' nodes of a hash table should share the same statistics counters, 4789 allocated by the hash table. So, if this node is a bucket of a hash table, 4790 we'll replace the locally allocated counters with the shared counters. */ 4791 if (p_CcNode->isHashBucket) 4792 { 4793 ASSERT_COND(p_CcNode->h_MissStatsCounters); 4794 4795 /* Store original counters pointer and replace it with mutual preallocated pointer */ 4796 p_CcNode->h_PrivMissStatsCounters = p_StatsObj->h_StatsCounters; 4797 p_StatsObj->h_StatsCounters = p_CcNode->h_MissStatsCounters; 4798 } 4799 4800 statsParams.h_StatsAd = p_StatsObj->h_StatsAd; 4801 statsParams.h_StatsCounters = p_StatsObj->h_StatsCounters; 4802 #if (DPAA_VERSION >= 11) 4803 statsParams.h_StatsFLRs = p_CcNode->h_StatsFLRs; 4804 4805 #endif /* (DPAA_VERSION >= 11) */ 4806 4807 NextStepAd(p_AdTableTmp, &statsParams, 4808 &p_CcNodeParam->keysParams.ccNextEngineParamsForMiss, 4809 p_FmPcd); 4810 4811 p_CcNode->keyAndNextEngineParams[tmp].p_StatsObj = p_StatsObj; 4812 } 4813 else 4814 { 4815 NextStepAd(p_AdTableTmp, NULL, 4816 &p_CcNodeParam->keysParams.ccNextEngineParamsForMiss, 4817 p_FmPcd); 4818 4819 p_CcNode->keyAndNextEngineParams[tmp].p_StatsObj = NULL; 4820 } 4821 4822 /* This parameter will be used to initialize the "key length" field in the action descriptor 4823 that points to this node and it should be 0 for full field extraction */ 4824 if (fullField == TRUE) 4825 p_CcNode->sizeOfExtraction = 0; 4826 4827 for (tmp = 0; tmp < MIN(p_CcNode->numOfKeys + 1, CC_MAX_NUM_OF_KEYS); tmp++) 4828 { 4829 if (p_CcNode->keyAndNextEngineParams[tmp].nextEngineParams.nextEngine 4830 == e_FM_PCD_CC) 4831 { 4832 p_FmPcdCcNextNode = 4833 (t_FmPcdCcNode*)p_CcNode->keyAndNextEngineParams[tmp].nextEngineParams.params.ccParams.h_CcNode; 4834 p_CcInformation = FindNodeInfoInReleventLst( 4835 &p_FmPcdCcNextNode->ccPrevNodesLst, (t_Handle)p_CcNode, 4836 p_FmPcdCcNextNode->h_Spinlock); 4837 if (!p_CcInformation) 4838 { 4839 memset(&ccNodeInfo, 0, sizeof(t_CcNodeInformation)); 4840 ccNodeInfo.h_CcNode = (t_Handle)p_CcNode; 4841 ccNodeInfo.index = 1; 4842 EnqueueNodeInfoToRelevantLst(&p_FmPcdCcNextNode->ccPrevNodesLst, 4843 &ccNodeInfo, 4844 p_FmPcdCcNextNode->h_Spinlock); 4845 } 4846 else 4847 p_CcInformation->index++; 4848 4849 if (p_CcNode->keyAndNextEngineParams[tmp].nextEngineParams.h_Manip) 4850 { 4851 h_Manip = 4852 p_CcNode->keyAndNextEngineParams[tmp].nextEngineParams.h_Manip; 4853 p_CcInformation = FindNodeInfoInReleventLst( 4854 FmPcdManipGetNodeLstPointedOnThisManip(h_Manip), 4855 (t_Handle)p_CcNode, FmPcdManipGetSpinlock(h_Manip)); 4856 if (!p_CcInformation) 4857 { 4858 memset(&ccNodeInfo, 0, sizeof(t_CcNodeInformation)); 4859 ccNodeInfo.h_CcNode = (t_Handle)p_CcNode; 4860 ccNodeInfo.index = 1; 4861 EnqueueNodeInfoToRelevantLst( 4862 FmPcdManipGetNodeLstPointedOnThisManip(h_Manip), 4863 &ccNodeInfo, FmPcdManipGetSpinlock(h_Manip)); 4864 } 4865 else 4866 p_CcInformation->index++; 4867 } 4868 } 4869 } 4870 4871 p_AdTableTmp = p_CcNode->h_AdTable; 4872 4873 if (!FmPcdLockTryLockAll(h_FmPcd)) 4874 { 4875 FM_PCD_MatchTableDelete((t_Handle)p_CcNode); 4876 DBG(TRACE, ("FmPcdLockTryLockAll failed")); 4877 return ERROR_CODE(E_BUSY); 4878 } 4879 4880 /* Required action for each next engine */ 4881 for (tmp = 0; tmp < MIN(p_CcNode->numOfKeys + 1, CC_MAX_NUM_OF_KEYS); tmp++) 4882 { 4883 if (p_CcNode->keyAndNextEngineParams[tmp].requiredAction) 4884 { 4885 err = SetRequiredAction( 4886 h_FmPcd, 4887 p_CcNode->keyAndNextEngineParams[tmp].requiredAction, 4888 &p_CcNode->keyAndNextEngineParams[tmp], p_AdTableTmp, 1, 4889 NULL); 4890 if (err) 4891 { 4892 FmPcdLockUnlockAll(h_FmPcd); 4893 FM_PCD_MatchTableDelete((t_Handle)p_CcNode); 4894 RETURN_ERROR(MAJOR, err, NO_MSG); 4895 } 4896 p_AdTableTmp = PTR_MOVE(p_AdTableTmp, FM_PCD_CC_AD_ENTRY_SIZE); 4897 } 4898 } 4899 4900 FmPcdLockUnlockAll(h_FmPcd); 4901 4902 return E_OK; 4903 } 4904 /************************** End of static functions **************************/ 4905 4906 /*****************************************************************************/ 4907 /* Inter-module API routines */ 4908 /*****************************************************************************/ 4909 4910 t_CcNodeInformation* FindNodeInfoInReleventLst(t_List *p_List, t_Handle h_Info, 4911 t_Handle h_Spinlock) 4912 { 4913 t_CcNodeInformation *p_CcInformation; 4914 t_List *p_Pos; 4915 uint32_t intFlags; 4916 4917 intFlags = XX_LockIntrSpinlock(h_Spinlock); 4918 4919 for (p_Pos = NCSW_LIST_FIRST(p_List); p_Pos != (p_List); 4920 p_Pos = NCSW_LIST_NEXT(p_Pos)) 4921 { 4922 p_CcInformation = CC_NODE_F_OBJECT(p_Pos); 4923 4924 ASSERT_COND(p_CcInformation->h_CcNode); 4925 4926 if (p_CcInformation->h_CcNode == h_Info) 4927 { 4928 XX_UnlockIntrSpinlock(h_Spinlock, intFlags); 4929 return p_CcInformation; 4930 } 4931 } 4932 4933 XX_UnlockIntrSpinlock(h_Spinlock, intFlags); 4934 4935 return NULL; 4936 } 4937 4938 void EnqueueNodeInfoToRelevantLst(t_List *p_List, t_CcNodeInformation *p_CcInfo, 4939 t_Handle h_Spinlock) 4940 { 4941 t_CcNodeInformation *p_CcInformation; 4942 uint32_t intFlags = 0; 4943 4944 p_CcInformation = (t_CcNodeInformation *)XX_Malloc( 4945 sizeof(t_CcNodeInformation)); 4946 4947 if (p_CcInformation) 4948 { 4949 memset(p_CcInformation, 0, sizeof(t_CcNodeInformation)); 4950 memcpy(p_CcInformation, p_CcInfo, sizeof(t_CcNodeInformation)); 4951 INIT_LIST(&p_CcInformation->node); 4952 4953 if (h_Spinlock) 4954 intFlags = XX_LockIntrSpinlock(h_Spinlock); 4955 4956 NCSW_LIST_AddToTail(&p_CcInformation->node, p_List); 4957 4958 if (h_Spinlock) 4959 XX_UnlockIntrSpinlock(h_Spinlock, intFlags); 4960 } 4961 else 4962 REPORT_ERROR(MAJOR, E_NO_MEMORY, ("CC Node Information")); 4963 } 4964 4965 void DequeueNodeInfoFromRelevantLst(t_List *p_List, t_Handle h_Info, 4966 t_Handle h_Spinlock) 4967 { 4968 t_CcNodeInformation *p_CcInformation = NULL; 4969 uint32_t intFlags = 0; 4970 t_List *p_Pos; 4971 4972 if (h_Spinlock) 4973 intFlags = XX_LockIntrSpinlock(h_Spinlock); 4974 4975 if (NCSW_LIST_IsEmpty(p_List)) 4976 { 4977 XX_RestoreAllIntr(intFlags); 4978 return; 4979 } 4980 4981 for (p_Pos = NCSW_LIST_FIRST(p_List); p_Pos != (p_List); 4982 p_Pos = NCSW_LIST_NEXT(p_Pos)) 4983 { 4984 p_CcInformation = CC_NODE_F_OBJECT(p_Pos); 4985 ASSERT_COND(p_CcInformation); 4986 ASSERT_COND(p_CcInformation->h_CcNode); 4987 if (p_CcInformation->h_CcNode == h_Info) 4988 break; 4989 } 4990 4991 if (p_CcInformation) 4992 { 4993 NCSW_LIST_DelAndInit(&p_CcInformation->node); 4994 XX_Free(p_CcInformation); 4995 } 4996 4997 if (h_Spinlock) 4998 XX_UnlockIntrSpinlock(h_Spinlock, intFlags); 4999 } 5000 5001 void NextStepAd(t_Handle h_Ad, t_FmPcdCcStatsParams *p_FmPcdCcStatsParams, 5002 t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams, 5003 t_FmPcd *p_FmPcd) 5004 { 5005 switch (p_FmPcdCcNextEngineParams->nextEngine) 5006 { 5007 case (e_FM_PCD_KG): 5008 case (e_FM_PCD_PLCR): 5009 case (e_FM_PCD_DONE): 5010 /* if NIA is not CC, create a "result" type AD */ 5011 FillAdOfTypeResult(h_Ad, p_FmPcdCcStatsParams, p_FmPcd, 5012 p_FmPcdCcNextEngineParams); 5013 break; 5014 #if (DPAA_VERSION >= 11) 5015 case (e_FM_PCD_FR): 5016 if (p_FmPcdCcNextEngineParams->params.frParams.h_FrmReplic) 5017 { 5018 FillAdOfTypeContLookup( 5019 h_Ad, p_FmPcdCcStatsParams, p_FmPcd, 5020 p_FmPcdCcNextEngineParams->params.ccParams.h_CcNode, 5021 p_FmPcdCcNextEngineParams->h_Manip, 5022 p_FmPcdCcNextEngineParams->params.frParams.h_FrmReplic); 5023 FrmReplicGroupUpdateOwner( 5024 p_FmPcdCcNextEngineParams->params.frParams.h_FrmReplic, 5025 TRUE/* add */); 5026 } 5027 break; 5028 #endif /* (DPAA_VERSION >= 11) */ 5029 5030 case (e_FM_PCD_CC): 5031 /* if NIA is not CC, create a TD to continue the CC lookup */ 5032 FillAdOfTypeContLookup( 5033 h_Ad, p_FmPcdCcStatsParams, p_FmPcd, 5034 p_FmPcdCcNextEngineParams->params.ccParams.h_CcNode, 5035 p_FmPcdCcNextEngineParams->h_Manip, NULL); 5036 5037 UpdateNodeOwner(p_FmPcdCcNextEngineParams->params.ccParams.h_CcNode, 5038 TRUE); 5039 break; 5040 5041 default: 5042 return; 5043 } 5044 } 5045 5046 t_Error FmPcdCcTreeAddIPR(t_Handle h_FmPcd, t_Handle h_FmTree, 5047 t_Handle h_NetEnv, t_Handle h_IpReassemblyManip, 5048 bool createSchemes) 5049 { 5050 t_FmPcdCcTree *p_FmPcdCcTree = (t_FmPcdCcTree *)h_FmTree; 5051 t_FmPcdCcNextEngineParams nextEngineParams; 5052 t_NetEnvParams netEnvParams; 5053 t_Handle h_Ad; 5054 bool isIpv6Present; 5055 uint8_t ipv4GroupId, ipv6GroupId; 5056 t_Error err; 5057 5058 ASSERT_COND(p_FmPcdCcTree); 5059 5060 /* this routine must be protected by the calling routine! */ 5061 5062 memset(&nextEngineParams, 0, sizeof(t_FmPcdCcNextEngineParams)); 5063 memset(&netEnvParams, 0, sizeof(t_NetEnvParams)); 5064 5065 h_Ad = UINT_TO_PTR(p_FmPcdCcTree->ccTreeBaseAddr); 5066 5067 isIpv6Present = FmPcdManipIpReassmIsIpv6Hdr(h_IpReassemblyManip); 5068 5069 if (isIpv6Present 5070 && (p_FmPcdCcTree->numOfEntries > (FM_PCD_MAX_NUM_OF_CC_GROUPS - 2))) 5071 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("need two free entries for IPR")); 5072 5073 if (p_FmPcdCcTree->numOfEntries > (FM_PCD_MAX_NUM_OF_CC_GROUPS - 1)) 5074 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("need two free entries for IPR")); 5075 5076 nextEngineParams.nextEngine = e_FM_PCD_DONE; 5077 nextEngineParams.h_Manip = h_IpReassemblyManip; 5078 5079 /* Lock tree */ 5080 err = CcRootTryLock(p_FmPcdCcTree); 5081 if (err) 5082 return ERROR_CODE(E_BUSY); 5083 5084 if (p_FmPcdCcTree->h_IpReassemblyManip == h_IpReassemblyManip) 5085 { 5086 CcRootReleaseLock(p_FmPcdCcTree); 5087 return E_OK; 5088 } 5089 5090 if ((p_FmPcdCcTree->h_IpReassemblyManip) 5091 && (p_FmPcdCcTree->h_IpReassemblyManip != h_IpReassemblyManip)) 5092 { 5093 CcRootReleaseLock(p_FmPcdCcTree); 5094 RETURN_ERROR(MAJOR, E_INVALID_STATE, 5095 ("This tree was previously updated with different IPR")); 5096 } 5097 5098 /* Initialize IPR for the first time for this tree */ 5099 if (isIpv6Present) 5100 { 5101 ipv6GroupId = p_FmPcdCcTree->numOfGrps++; 5102 p_FmPcdCcTree->fmPcdGroupParam[ipv6GroupId].baseGroupEntry = 5103 (FM_PCD_MAX_NUM_OF_CC_GROUPS - 2); 5104 5105 if (createSchemes) 5106 { 5107 err = FmPcdManipBuildIpReassmScheme(h_FmPcd, h_NetEnv, 5108 p_FmPcdCcTree, 5109 h_IpReassemblyManip, FALSE, 5110 ipv6GroupId); 5111 if (err) 5112 { 5113 p_FmPcdCcTree->numOfGrps--; 5114 CcRootReleaseLock(p_FmPcdCcTree); 5115 RETURN_ERROR(MAJOR, err, NO_MSG); 5116 } 5117 } 5118 5119 NextStepAd( 5120 PTR_MOVE(h_Ad, (FM_PCD_MAX_NUM_OF_CC_GROUPS-2) * FM_PCD_CC_AD_ENTRY_SIZE), 5121 NULL, &nextEngineParams, h_FmPcd); 5122 } 5123 5124 ipv4GroupId = p_FmPcdCcTree->numOfGrps++; 5125 p_FmPcdCcTree->fmPcdGroupParam[ipv4GroupId].totalBitsMask = 0; 5126 p_FmPcdCcTree->fmPcdGroupParam[ipv4GroupId].baseGroupEntry = 5127 (FM_PCD_MAX_NUM_OF_CC_GROUPS - 1); 5128 5129 if (createSchemes) 5130 { 5131 err = FmPcdManipBuildIpReassmScheme(h_FmPcd, h_NetEnv, p_FmPcdCcTree, 5132 h_IpReassemblyManip, TRUE, 5133 ipv4GroupId); 5134 if (err) 5135 { 5136 p_FmPcdCcTree->numOfGrps--; 5137 if (isIpv6Present) 5138 { 5139 p_FmPcdCcTree->numOfGrps--; 5140 FmPcdManipDeleteIpReassmSchemes(h_IpReassemblyManip); 5141 } 5142 CcRootReleaseLock(p_FmPcdCcTree); 5143 RETURN_ERROR(MAJOR, err, NO_MSG); 5144 } 5145 } 5146 5147 NextStepAd( 5148 PTR_MOVE(h_Ad, (FM_PCD_MAX_NUM_OF_CC_GROUPS-1) * FM_PCD_CC_AD_ENTRY_SIZE), 5149 NULL, &nextEngineParams, h_FmPcd); 5150 5151 p_FmPcdCcTree->h_IpReassemblyManip = h_IpReassemblyManip; 5152 5153 CcRootReleaseLock(p_FmPcdCcTree); 5154 5155 return E_OK; 5156 } 5157 5158 t_Error FmPcdCcTreeAddCPR(t_Handle h_FmPcd, t_Handle h_FmTree, 5159 t_Handle h_NetEnv, t_Handle h_ReassemblyManip, 5160 bool createSchemes) 5161 { 5162 t_FmPcdCcTree *p_FmPcdCcTree = (t_FmPcdCcTree *)h_FmTree; 5163 t_FmPcdCcNextEngineParams nextEngineParams; 5164 t_NetEnvParams netEnvParams; 5165 t_Handle h_Ad; 5166 uint8_t groupId; 5167 t_Error err; 5168 5169 ASSERT_COND(p_FmPcdCcTree); 5170 5171 /* this routine must be protected by the calling routine! */ 5172 memset(&nextEngineParams, 0, sizeof(t_FmPcdCcNextEngineParams)); 5173 memset(&netEnvParams, 0, sizeof(t_NetEnvParams)); 5174 5175 h_Ad = UINT_TO_PTR(p_FmPcdCcTree->ccTreeBaseAddr); 5176 5177 if (p_FmPcdCcTree->numOfEntries > (FM_PCD_MAX_NUM_OF_CC_GROUPS - 1)) 5178 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("need one free entries for CPR")); 5179 5180 nextEngineParams.nextEngine = e_FM_PCD_DONE; 5181 nextEngineParams.h_Manip = h_ReassemblyManip; 5182 5183 /* Lock tree */ 5184 err = CcRootTryLock(p_FmPcdCcTree); 5185 if (err) 5186 return ERROR_CODE(E_BUSY); 5187 5188 if (p_FmPcdCcTree->h_CapwapReassemblyManip == h_ReassemblyManip) 5189 { 5190 CcRootReleaseLock(p_FmPcdCcTree); 5191 return E_OK; 5192 } 5193 5194 if ((p_FmPcdCcTree->h_CapwapReassemblyManip) 5195 && (p_FmPcdCcTree->h_CapwapReassemblyManip != h_ReassemblyManip)) 5196 { 5197 CcRootReleaseLock(p_FmPcdCcTree); 5198 RETURN_ERROR(MAJOR, E_INVALID_STATE, 5199 ("This tree was previously updated with different CPR")); 5200 } 5201 5202 groupId = p_FmPcdCcTree->numOfGrps++; 5203 p_FmPcdCcTree->fmPcdGroupParam[groupId].baseGroupEntry = 5204 (FM_PCD_MAX_NUM_OF_CC_GROUPS - 1); 5205 5206 if (createSchemes) 5207 { 5208 err = FmPcdManipBuildCapwapReassmScheme(h_FmPcd, h_NetEnv, 5209 p_FmPcdCcTree, 5210 h_ReassemblyManip, groupId); 5211 if (err) 5212 { 5213 p_FmPcdCcTree->numOfGrps--; 5214 CcRootReleaseLock(p_FmPcdCcTree); 5215 RETURN_ERROR(MAJOR, err, NO_MSG); 5216 } 5217 } 5218 5219 NextStepAd( 5220 PTR_MOVE(h_Ad, (FM_PCD_MAX_NUM_OF_CC_GROUPS-1) * FM_PCD_CC_AD_ENTRY_SIZE), 5221 NULL, &nextEngineParams, h_FmPcd); 5222 5223 p_FmPcdCcTree->h_CapwapReassemblyManip = h_ReassemblyManip; 5224 5225 CcRootReleaseLock(p_FmPcdCcTree); 5226 5227 return E_OK; 5228 } 5229 5230 t_Handle FmPcdCcTreeGetSavedManipParams(t_Handle h_FmTree) 5231 { 5232 t_FmPcdCcTree *p_FmPcdCcTree = (t_FmPcdCcTree *)h_FmTree; 5233 5234 ASSERT_COND(p_FmPcdCcTree); 5235 5236 return p_FmPcdCcTree->h_FmPcdCcSavedManipParams; 5237 } 5238 5239 void FmPcdCcTreeSetSavedManipParams(t_Handle h_FmTree, 5240 t_Handle h_SavedManipParams) 5241 { 5242 t_FmPcdCcTree *p_FmPcdCcTree = (t_FmPcdCcTree *)h_FmTree; 5243 5244 ASSERT_COND(p_FmPcdCcTree); 5245 5246 p_FmPcdCcTree->h_FmPcdCcSavedManipParams = h_SavedManipParams; 5247 } 5248 5249 uint8_t FmPcdCcGetParseCode(t_Handle h_CcNode) 5250 { 5251 t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode; 5252 5253 ASSERT_COND(p_CcNode); 5254 5255 return p_CcNode->parseCode; 5256 } 5257 5258 uint8_t FmPcdCcGetOffset(t_Handle h_CcNode) 5259 { 5260 t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode; 5261 5262 ASSERT_COND(p_CcNode); 5263 5264 return p_CcNode->offset; 5265 } 5266 5267 uint16_t FmPcdCcGetNumOfKeys(t_Handle h_CcNode) 5268 { 5269 t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode; 5270 5271 ASSERT_COND(p_CcNode); 5272 5273 return p_CcNode->numOfKeys; 5274 } 5275 5276 t_Error FmPcdCcModifyNextEngineParamTree( 5277 t_Handle h_FmPcd, t_Handle h_FmPcdCcTree, uint8_t grpId, uint8_t index, 5278 t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams) 5279 { 5280 t_FmPcdCcTree *p_FmPcdCcTree = (t_FmPcdCcTree *)h_FmPcdCcTree; 5281 t_FmPcd *p_FmPcd; 5282 t_List h_OldPointersLst, h_NewPointersLst; 5283 uint16_t keyIndex; 5284 t_FmPcdModifyCcKeyAdditionalParams *p_ModifyKeyParams; 5285 t_Error err = E_OK; 5286 5287 SANITY_CHECK_RETURN_ERROR(h_FmPcd, E_INVALID_HANDLE); 5288 SANITY_CHECK_RETURN_ERROR(h_FmPcdCcTree, E_INVALID_HANDLE); 5289 SANITY_CHECK_RETURN_ERROR((grpId <= 7), E_INVALID_VALUE); 5290 5291 if (grpId >= p_FmPcdCcTree->numOfGrps) 5292 RETURN_ERROR(MAJOR, E_INVALID_HANDLE, 5293 ("grpId you asked > numOfGroup of relevant tree")); 5294 5295 if (index >= p_FmPcdCcTree->fmPcdGroupParam[grpId].numOfEntriesInGroup) 5296 RETURN_ERROR(MAJOR, E_INVALID_HANDLE, ("index > numOfEntriesInGroup")); 5297 5298 p_FmPcd = (t_FmPcd *)h_FmPcd; 5299 5300 INIT_LIST(&h_OldPointersLst); 5301 INIT_LIST(&h_NewPointersLst); 5302 5303 keyIndex = (uint16_t)(p_FmPcdCcTree->fmPcdGroupParam[grpId].baseGroupEntry 5304 + index); 5305 5306 p_ModifyKeyParams = ModifyNodeCommonPart(p_FmPcdCcTree, keyIndex, 5307 e_MODIFY_STATE_CHANGE, FALSE, 5308 FALSE, TRUE); 5309 if (!p_ModifyKeyParams) 5310 RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG); 5311 5312 p_ModifyKeyParams->tree = TRUE; 5313 5314 if (p_FmPcd->p_CcShadow 5315 && !TRY_LOCK(p_FmPcd->h_ShadowSpinlock, &p_FmPcd->shadowLock)) 5316 { 5317 XX_Free(p_ModifyKeyParams); 5318 return ERROR_CODE(E_BUSY); 5319 } 5320 5321 err = BuildNewNodeModifyNextEngine(p_FmPcd, p_FmPcdCcTree, keyIndex, 5322 p_FmPcdCcNextEngineParams, 5323 &h_OldPointersLst, &h_NewPointersLst, 5324 p_ModifyKeyParams); 5325 if (err) 5326 { 5327 XX_Free(p_ModifyKeyParams); 5328 RETURN_ERROR(MAJOR, err, NO_MSG); 5329 } 5330 5331 err = DoDynamicChange(p_FmPcd, &h_OldPointersLst, &h_NewPointersLst, 5332 p_ModifyKeyParams, FALSE); 5333 5334 if (p_FmPcd->p_CcShadow) 5335 RELEASE_LOCK(p_FmPcd->shadowLock); 5336 5337 return err; 5338 5339 } 5340 5341 t_Error FmPcdCcRemoveKey(t_Handle h_FmPcd, t_Handle h_FmPcdCcNode, 5342 uint16_t keyIndex) 5343 { 5344 5345 t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_FmPcdCcNode; 5346 t_FmPcd *p_FmPcd; 5347 t_FmPcdModifyCcKeyAdditionalParams *p_ModifyKeyParams; 5348 t_List h_OldPointersLst, h_NewPointersLst; 5349 bool useShadowStructs = FALSE; 5350 t_Error err = E_OK; 5351 5352 if (keyIndex >= p_CcNode->numOfKeys) 5353 RETURN_ERROR(MAJOR, E_INVALID_VALUE, 5354 ("impossible to remove key when numOfKeys <= keyIndex")); 5355 5356 if (p_CcNode->h_FmPcd != h_FmPcd) 5357 RETURN_ERROR( 5358 MAJOR, 5359 E_INVALID_VALUE, 5360 ("handler to FmPcd is different from the handle provided at node initialization time")); 5361 5362 p_FmPcd = (t_FmPcd *)p_CcNode->h_FmPcd; 5363 5364 INIT_LIST(&h_OldPointersLst); 5365 INIT_LIST(&h_NewPointersLst); 5366 5367 p_ModifyKeyParams = ModifyNodeCommonPart(p_CcNode, keyIndex, 5368 e_MODIFY_STATE_REMOVE, TRUE, TRUE, 5369 FALSE); 5370 if (!p_ModifyKeyParams) 5371 RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG); 5372 5373 if (p_CcNode->maxNumOfKeys) 5374 { 5375 if (!TRY_LOCK(p_FmPcd->h_ShadowSpinlock, &p_FmPcd->shadowLock)) 5376 { 5377 XX_Free(p_ModifyKeyParams); 5378 return ERROR_CODE(E_BUSY); 5379 } 5380 5381 useShadowStructs = TRUE; 5382 } 5383 5384 err = BuildNewNodeRemoveKey(p_CcNode, keyIndex, p_ModifyKeyParams); 5385 if (err) 5386 { 5387 XX_Free(p_ModifyKeyParams); 5388 if (p_CcNode->maxNumOfKeys) 5389 RELEASE_LOCK(p_FmPcd->shadowLock); 5390 RETURN_ERROR(MAJOR, err, NO_MSG); 5391 } 5392 5393 err = UpdatePtrWhichPointOnCrntMdfNode(p_CcNode, p_ModifyKeyParams, 5394 &h_OldPointersLst, 5395 &h_NewPointersLst); 5396 if (err) 5397 { 5398 ReleaseNewNodeCommonPart(p_ModifyKeyParams); 5399 XX_Free(p_ModifyKeyParams); 5400 if (p_CcNode->maxNumOfKeys) 5401 RELEASE_LOCK(p_FmPcd->shadowLock); 5402 RETURN_ERROR(MAJOR, err, NO_MSG); 5403 } 5404 5405 err = DoDynamicChange(p_FmPcd, &h_OldPointersLst, &h_NewPointersLst, 5406 p_ModifyKeyParams, useShadowStructs); 5407 5408 if (p_CcNode->maxNumOfKeys) 5409 RELEASE_LOCK(p_FmPcd->shadowLock); 5410 5411 return err; 5412 } 5413 5414 t_Error FmPcdCcModifyKey(t_Handle h_FmPcd, t_Handle h_FmPcdCcNode, 5415 uint16_t keyIndex, uint8_t keySize, uint8_t *p_Key, 5416 uint8_t *p_Mask) 5417 { 5418 t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_FmPcdCcNode; 5419 t_FmPcd *p_FmPcd; 5420 t_List h_OldPointersLst, h_NewPointersLst; 5421 t_FmPcdModifyCcKeyAdditionalParams *p_ModifyKeyParams; 5422 uint16_t tmpKeyIndex; 5423 bool useShadowStructs = FALSE; 5424 t_Error err = E_OK; 5425 5426 if (keyIndex >= p_CcNode->numOfKeys) 5427 RETURN_ERROR(MAJOR, E_INVALID_STATE, 5428 ("keyIndex > previously cleared last index + 1")); 5429 5430 if (keySize != p_CcNode->userSizeOfExtraction) 5431 RETURN_ERROR( 5432 MAJOR, 5433 E_INVALID_VALUE, 5434 ("size for ModifyKey has to be the same as defined in SetNode")); 5435 5436 if (p_CcNode->h_FmPcd != h_FmPcd) 5437 RETURN_ERROR( 5438 MAJOR, 5439 E_INVALID_VALUE, 5440 ("handler to FmPcd is different from the handle provided at node initialization time")); 5441 5442 err = FindKeyIndex(h_FmPcdCcNode, keySize, p_Key, p_Mask, &tmpKeyIndex); 5443 if (GET_ERROR_TYPE(err) != E_NOT_FOUND) 5444 RETURN_ERROR( 5445 MINOR, 5446 E_ALREADY_EXISTS, 5447 ("The received key and mask pair was already found in the match table of the provided node")); 5448 5449 p_FmPcd = (t_FmPcd *)p_CcNode->h_FmPcd; 5450 5451 INIT_LIST(&h_OldPointersLst); 5452 INIT_LIST(&h_NewPointersLst); 5453 5454 p_ModifyKeyParams = ModifyNodeCommonPart(p_CcNode, keyIndex, 5455 e_MODIFY_STATE_CHANGE, TRUE, TRUE, 5456 FALSE); 5457 if (!p_ModifyKeyParams) 5458 RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG); 5459 5460 if (p_CcNode->maxNumOfKeys) 5461 { 5462 if (!TRY_LOCK(p_FmPcd->h_ShadowSpinlock, &p_FmPcd->shadowLock)) 5463 { 5464 XX_Free(p_ModifyKeyParams); 5465 return ERROR_CODE(E_BUSY); 5466 } 5467 5468 useShadowStructs = TRUE; 5469 } 5470 5471 err = BuildNewNodeModifyKey(p_CcNode, keyIndex, p_Key, p_Mask, 5472 p_ModifyKeyParams); 5473 if (err) 5474 { 5475 XX_Free(p_ModifyKeyParams); 5476 if (p_CcNode->maxNumOfKeys) 5477 RELEASE_LOCK(p_FmPcd->shadowLock); 5478 RETURN_ERROR(MAJOR, err, NO_MSG); 5479 } 5480 5481 err = UpdatePtrWhichPointOnCrntMdfNode(p_CcNode, p_ModifyKeyParams, 5482 &h_OldPointersLst, 5483 &h_NewPointersLst); 5484 if (err) 5485 { 5486 ReleaseNewNodeCommonPart(p_ModifyKeyParams); 5487 XX_Free(p_ModifyKeyParams); 5488 if (p_CcNode->maxNumOfKeys) 5489 RELEASE_LOCK(p_FmPcd->shadowLock); 5490 RETURN_ERROR(MAJOR, err, NO_MSG); 5491 } 5492 5493 err = DoDynamicChange(p_FmPcd, &h_OldPointersLst, &h_NewPointersLst, 5494 p_ModifyKeyParams, useShadowStructs); 5495 5496 if (p_CcNode->maxNumOfKeys) 5497 RELEASE_LOCK(p_FmPcd->shadowLock); 5498 5499 return err; 5500 } 5501 5502 t_Error FmPcdCcModifyMissNextEngineParamNode( 5503 t_Handle h_FmPcd, t_Handle h_FmPcdCcNode, 5504 t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams) 5505 { 5506 t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_FmPcdCcNode; 5507 t_FmPcd *p_FmPcd; 5508 t_List h_OldPointersLst, h_NewPointersLst; 5509 uint16_t keyIndex; 5510 t_FmPcdModifyCcKeyAdditionalParams *p_ModifyKeyParams; 5511 t_Error err = E_OK; 5512 5513 SANITY_CHECK_RETURN_ERROR(p_CcNode, E_INVALID_VALUE); 5514 5515 keyIndex = p_CcNode->numOfKeys; 5516 5517 p_FmPcd = (t_FmPcd *)p_CcNode->h_FmPcd; 5518 5519 INIT_LIST(&h_OldPointersLst); 5520 INIT_LIST(&h_NewPointersLst); 5521 5522 p_ModifyKeyParams = ModifyNodeCommonPart(p_CcNode, keyIndex, 5523 e_MODIFY_STATE_CHANGE, FALSE, TRUE, 5524 FALSE); 5525 if (!p_ModifyKeyParams) 5526 RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG); 5527 5528 if (p_CcNode->maxNumOfKeys 5529 && !TRY_LOCK(p_FmPcd->h_ShadowSpinlock, &p_FmPcd->shadowLock)) 5530 { 5531 XX_Free(p_ModifyKeyParams); 5532 return ERROR_CODE(E_BUSY); 5533 } 5534 5535 err = BuildNewNodeModifyNextEngine(h_FmPcd, p_CcNode, keyIndex, 5536 p_FmPcdCcNextEngineParams, 5537 &h_OldPointersLst, &h_NewPointersLst, 5538 p_ModifyKeyParams); 5539 if (err) 5540 { 5541 XX_Free(p_ModifyKeyParams); 5542 if (p_CcNode->maxNumOfKeys) 5543 RELEASE_LOCK(p_FmPcd->shadowLock); 5544 RETURN_ERROR(MAJOR, err, NO_MSG); 5545 } 5546 5547 err = DoDynamicChange(p_FmPcd, &h_OldPointersLst, &h_NewPointersLst, 5548 p_ModifyKeyParams, FALSE); 5549 5550 if (p_CcNode->maxNumOfKeys) 5551 RELEASE_LOCK(p_FmPcd->shadowLock); 5552 5553 return err; 5554 } 5555 5556 t_Error FmPcdCcAddKey(t_Handle h_FmPcd, t_Handle h_FmPcdCcNode, 5557 uint16_t keyIndex, uint8_t keySize, 5558 t_FmPcdCcKeyParams *p_FmPcdCcKeyParams) 5559 { 5560 t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_FmPcdCcNode; 5561 t_FmPcd *p_FmPcd; 5562 t_FmPcdModifyCcKeyAdditionalParams *p_ModifyKeyParams; 5563 t_List h_OldPointersLst, h_NewPointersLst; 5564 bool useShadowStructs = FALSE; 5565 uint16_t tmpKeyIndex; 5566 t_Error err = E_OK; 5567 5568 if (keyIndex > p_CcNode->numOfKeys) 5569 RETURN_ERROR(MAJOR, E_NOT_IN_RANGE, 5570 ("keyIndex > previously cleared last index + 1")); 5571 5572 if (keySize != p_CcNode->userSizeOfExtraction) 5573 RETURN_ERROR( 5574 MAJOR, 5575 E_INVALID_VALUE, 5576 ("keySize has to be defined as it was defined in initialization step")); 5577 5578 if (p_CcNode->h_FmPcd != h_FmPcd) 5579 RETURN_ERROR( 5580 MAJOR, 5581 E_INVALID_VALUE, 5582 ("handler to FmPcd is different from the handle provided at node initialization time")); 5583 5584 if (p_CcNode->maxNumOfKeys) 5585 { 5586 if (p_CcNode->numOfKeys == p_CcNode->maxNumOfKeys) 5587 RETURN_ERROR( 5588 MAJOR, 5589 E_FULL, 5590 ("number of keys exceeds the maximal number of keys provided at node initialization time")); 5591 } 5592 else 5593 if (p_CcNode->numOfKeys == FM_PCD_MAX_NUM_OF_KEYS) 5594 RETURN_ERROR( 5595 MAJOR, 5596 E_INVALID_VALUE, 5597 ("number of keys can not be larger than %d", FM_PCD_MAX_NUM_OF_KEYS)); 5598 5599 err = FindKeyIndex(h_FmPcdCcNode, keySize, p_FmPcdCcKeyParams->p_Key, 5600 p_FmPcdCcKeyParams->p_Mask, &tmpKeyIndex); 5601 if (GET_ERROR_TYPE(err) != E_NOT_FOUND) 5602 RETURN_ERROR( 5603 MAJOR, 5604 E_ALREADY_EXISTS, 5605 ("The received key and mask pair was already found in the match table of the provided node")); 5606 5607 p_FmPcd = (t_FmPcd *)p_CcNode->h_FmPcd; 5608 5609 INIT_LIST(&h_OldPointersLst); 5610 INIT_LIST(&h_NewPointersLst); 5611 5612 p_ModifyKeyParams = ModifyNodeCommonPart(p_CcNode, keyIndex, 5613 e_MODIFY_STATE_ADD, TRUE, TRUE, 5614 FALSE); 5615 if (!p_ModifyKeyParams) 5616 RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG); 5617 5618 if (p_CcNode->maxNumOfKeys) 5619 { 5620 if (!TRY_LOCK(p_FmPcd->h_ShadowSpinlock, &p_FmPcd->shadowLock)) 5621 { 5622 XX_Free(p_ModifyKeyParams); 5623 return ERROR_CODE(E_BUSY); 5624 } 5625 5626 useShadowStructs = TRUE; 5627 } 5628 5629 err = BuildNewNodeAddOrMdfyKeyAndNextEngine(h_FmPcd, p_CcNode, keyIndex, 5630 p_FmPcdCcKeyParams, 5631 p_ModifyKeyParams, TRUE); 5632 if (err) 5633 { 5634 ReleaseNewNodeCommonPart(p_ModifyKeyParams); 5635 XX_Free(p_ModifyKeyParams); 5636 if (p_CcNode->maxNumOfKeys) 5637 RELEASE_LOCK(p_FmPcd->shadowLock); 5638 RETURN_ERROR(MAJOR, err, NO_MSG); 5639 } 5640 5641 err = UpdatePtrWhichPointOnCrntMdfNode(p_CcNode, p_ModifyKeyParams, 5642 &h_OldPointersLst, 5643 &h_NewPointersLst); 5644 if (err) 5645 { 5646 ReleaseNewNodeCommonPart(p_ModifyKeyParams); 5647 XX_Free(p_ModifyKeyParams); 5648 if (p_CcNode->maxNumOfKeys) 5649 RELEASE_LOCK(p_FmPcd->shadowLock); 5650 RETURN_ERROR(MAJOR, err, NO_MSG); 5651 } 5652 5653 err = DoDynamicChange(p_FmPcd, &h_OldPointersLst, &h_NewPointersLst, 5654 p_ModifyKeyParams, useShadowStructs); 5655 if (p_CcNode->maxNumOfKeys) 5656 RELEASE_LOCK(p_FmPcd->shadowLock); 5657 5658 return err; 5659 } 5660 5661 t_Error FmPcdCcModifyKeyAndNextEngine(t_Handle h_FmPcd, t_Handle h_FmPcdCcNode, 5662 uint16_t keyIndex, uint8_t keySize, 5663 t_FmPcdCcKeyParams *p_FmPcdCcKeyParams) 5664 { 5665 t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_FmPcdCcNode; 5666 t_FmPcd *p_FmPcd; 5667 t_List h_OldPointersLst, h_NewPointersLst; 5668 t_FmPcdModifyCcKeyAdditionalParams *p_ModifyKeyParams; 5669 uint16_t tmpKeyIndex; 5670 bool useShadowStructs = FALSE; 5671 t_Error err = E_OK; 5672 5673 if (keyIndex > p_CcNode->numOfKeys) 5674 RETURN_ERROR(MAJOR, E_INVALID_STATE, 5675 ("keyIndex > previously cleared last index + 1")); 5676 5677 if (keySize != p_CcNode->userSizeOfExtraction) 5678 RETURN_ERROR( 5679 MAJOR, 5680 E_INVALID_VALUE, 5681 ("keySize has to be defined as it was defined in initialization step")); 5682 5683 if (p_CcNode->h_FmPcd != h_FmPcd) 5684 RETURN_ERROR( 5685 MAJOR, 5686 E_INVALID_VALUE, 5687 ("handler to FmPcd is different from the handle provided at node initialization time")); 5688 5689 err = FindKeyIndex(h_FmPcdCcNode, keySize, p_FmPcdCcKeyParams->p_Key, 5690 p_FmPcdCcKeyParams->p_Mask, &tmpKeyIndex); 5691 if (GET_ERROR_TYPE(err) != E_NOT_FOUND) 5692 RETURN_ERROR( 5693 MINOR, 5694 E_ALREADY_EXISTS, 5695 ("The received key and mask pair was already found in the match table of the provided node")); 5696 5697 p_FmPcd = (t_FmPcd *)p_CcNode->h_FmPcd; 5698 5699 INIT_LIST(&h_OldPointersLst); 5700 INIT_LIST(&h_NewPointersLst); 5701 5702 p_ModifyKeyParams = ModifyNodeCommonPart(p_CcNode, keyIndex, 5703 e_MODIFY_STATE_CHANGE, TRUE, TRUE, 5704 FALSE); 5705 if (!p_ModifyKeyParams) 5706 RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG); 5707 5708 if (p_CcNode->maxNumOfKeys) 5709 { 5710 if (!TRY_LOCK(p_FmPcd->h_ShadowSpinlock, &p_FmPcd->shadowLock)) 5711 { 5712 XX_Free(p_ModifyKeyParams); 5713 return ERROR_CODE(E_BUSY); 5714 } 5715 5716 useShadowStructs = TRUE; 5717 } 5718 5719 err = BuildNewNodeAddOrMdfyKeyAndNextEngine(h_FmPcd, p_CcNode, keyIndex, 5720 p_FmPcdCcKeyParams, 5721 p_ModifyKeyParams, FALSE); 5722 if (err) 5723 { 5724 ReleaseNewNodeCommonPart(p_ModifyKeyParams); 5725 XX_Free(p_ModifyKeyParams); 5726 if (p_CcNode->maxNumOfKeys) 5727 RELEASE_LOCK(p_FmPcd->shadowLock); 5728 RETURN_ERROR(MAJOR, err, NO_MSG); 5729 } 5730 5731 err = UpdatePtrWhichPointOnCrntMdfNode(p_CcNode, p_ModifyKeyParams, 5732 &h_OldPointersLst, 5733 &h_NewPointersLst); 5734 if (err) 5735 { 5736 ReleaseNewNodeCommonPart(p_ModifyKeyParams); 5737 XX_Free(p_ModifyKeyParams); 5738 if (p_CcNode->maxNumOfKeys) 5739 RELEASE_LOCK(p_FmPcd->shadowLock); 5740 RETURN_ERROR(MAJOR, err, NO_MSG); 5741 } 5742 5743 err = DoDynamicChange(p_FmPcd, &h_OldPointersLst, &h_NewPointersLst, 5744 p_ModifyKeyParams, useShadowStructs); 5745 5746 if (p_CcNode->maxNumOfKeys) 5747 RELEASE_LOCK(p_FmPcd->shadowLock); 5748 5749 return err; 5750 } 5751 5752 uint32_t FmPcdCcGetNodeAddrOffsetFromNodeInfo(t_Handle h_FmPcd, 5753 t_Handle h_Pointer) 5754 { 5755 t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd; 5756 t_CcNodeInformation *p_CcNodeInfo; 5757 5758 SANITY_CHECK_RETURN_VALUE(h_FmPcd, E_INVALID_HANDLE, 5759 (uint32_t)ILLEGAL_BASE); 5760 5761 p_CcNodeInfo = CC_NODE_F_OBJECT(h_Pointer); 5762 5763 return (uint32_t)(XX_VirtToPhys(p_CcNodeInfo->h_CcNode) 5764 - p_FmPcd->physicalMuramBase); 5765 } 5766 5767 t_Error FmPcdCcGetGrpParams(t_Handle h_FmPcdCcTree, uint8_t grpId, 5768 uint32_t *p_GrpBits, uint8_t *p_GrpBase) 5769 { 5770 t_FmPcdCcTree *p_FmPcdCcTree = (t_FmPcdCcTree *)h_FmPcdCcTree; 5771 5772 SANITY_CHECK_RETURN_ERROR(h_FmPcdCcTree, E_INVALID_HANDLE); 5773 5774 if (grpId >= p_FmPcdCcTree->numOfGrps) 5775 RETURN_ERROR(MAJOR, E_INVALID_HANDLE, 5776 ("grpId you asked > numOfGroup of relevant tree")); 5777 5778 *p_GrpBits = p_FmPcdCcTree->fmPcdGroupParam[grpId].totalBitsMask; 5779 *p_GrpBase = p_FmPcdCcTree->fmPcdGroupParam[grpId].baseGroupEntry; 5780 5781 return E_OK; 5782 } 5783 5784 t_Error FmPcdCcBindTree(t_Handle h_FmPcd, t_Handle h_PcdParams, 5785 t_Handle h_FmPcdCcTree, uint32_t *p_Offset, 5786 t_Handle h_FmPort) 5787 { 5788 t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; 5789 t_FmPcdCcTree *p_FmPcdCcTree = (t_FmPcdCcTree *)h_FmPcdCcTree; 5790 t_Error err = E_OK; 5791 5792 SANITY_CHECK_RETURN_ERROR(h_FmPcd, E_INVALID_HANDLE); 5793 SANITY_CHECK_RETURN_ERROR(h_FmPcdCcTree, E_INVALID_HANDLE); 5794 5795 /* this routine must be protected by the calling routine by locking all PCD modules! */ 5796 5797 err = CcUpdateParams(h_FmPcd, h_PcdParams, h_FmPort, h_FmPcdCcTree, TRUE); 5798 5799 if (err == E_OK) 5800 UpdateCcRootOwner(p_FmPcdCcTree, TRUE); 5801 5802 *p_Offset = (uint32_t)(XX_VirtToPhys( 5803 UINT_TO_PTR(p_FmPcdCcTree->ccTreeBaseAddr)) 5804 - p_FmPcd->physicalMuramBase); 5805 5806 return err; 5807 } 5808 5809 t_Error FmPcdCcUnbindTree(t_Handle h_FmPcd, t_Handle h_FmPcdCcTree) 5810 { 5811 t_FmPcdCcTree *p_FmPcdCcTree = (t_FmPcdCcTree *)h_FmPcdCcTree; 5812 5813 /* this routine must be protected by the calling routine by locking all PCD modules! */ 5814 5815 UNUSED(h_FmPcd); 5816 5817 SANITY_CHECK_RETURN_ERROR(h_FmPcdCcTree, E_INVALID_HANDLE); 5818 5819 UpdateCcRootOwner(p_FmPcdCcTree, FALSE); 5820 5821 return E_OK; 5822 } 5823 5824 t_Error FmPcdCcNodeTreeTryLock(t_Handle h_FmPcd, t_Handle h_FmPcdCcNode, 5825 t_List *p_List) 5826 { 5827 t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_FmPcdCcNode; 5828 t_List *p_Pos, *p_Tmp; 5829 t_CcNodeInformation *p_CcNodeInfo, nodeInfo; 5830 uint32_t intFlags; 5831 t_Error err = E_OK; 5832 5833 intFlags = FmPcdLock(h_FmPcd); 5834 5835 NCSW_LIST_FOR_EACH(p_Pos, &p_CcNode->ccTreesLst) 5836 { 5837 p_CcNodeInfo = CC_NODE_F_OBJECT(p_Pos); 5838 ASSERT_COND(p_CcNodeInfo->h_CcNode); 5839 5840 err = CcRootTryLock(p_CcNodeInfo->h_CcNode); 5841 5842 if (err) 5843 { 5844 NCSW_LIST_FOR_EACH(p_Tmp, &p_CcNode->ccTreesLst) 5845 { 5846 if (p_Tmp == p_Pos) 5847 break; 5848 5849 CcRootReleaseLock(p_CcNodeInfo->h_CcNode); 5850 } 5851 break; 5852 } 5853 5854 memset(&nodeInfo, 0, sizeof(t_CcNodeInformation)); 5855 nodeInfo.h_CcNode = p_CcNodeInfo->h_CcNode; 5856 EnqueueNodeInfoToRelevantLst(p_List, &nodeInfo, NULL); 5857 } 5858 5859 FmPcdUnlock(h_FmPcd, intFlags); 5860 CORE_MemoryBarrier(); 5861 5862 return err; 5863 } 5864 5865 void FmPcdCcNodeTreeReleaseLock(t_Handle h_FmPcd, t_List *p_List) 5866 { 5867 t_List *p_Pos; 5868 t_CcNodeInformation *p_CcNodeInfo; 5869 t_Handle h_FmPcdCcTree; 5870 uint32_t intFlags; 5871 5872 intFlags = FmPcdLock(h_FmPcd); 5873 5874 NCSW_LIST_FOR_EACH(p_Pos, p_List) 5875 { 5876 p_CcNodeInfo = CC_NODE_F_OBJECT(p_Pos); 5877 h_FmPcdCcTree = p_CcNodeInfo->h_CcNode; 5878 CcRootReleaseLock(h_FmPcdCcTree); 5879 } 5880 5881 ReleaseLst(p_List); 5882 5883 FmPcdUnlock(h_FmPcd, intFlags); 5884 CORE_MemoryBarrier(); 5885 } 5886 5887 t_Error FmPcdUpdateCcShadow(t_FmPcd *p_FmPcd, uint32_t size, uint32_t align) 5888 { 5889 uint32_t intFlags; 5890 uint32_t newSize = 0, newAlign = 0; 5891 bool allocFail = FALSE; 5892 5893 ASSERT_COND(p_FmPcd); 5894 5895 if (!size) 5896 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("size must be larger then 0")); 5897 5898 if (!POWER_OF_2(align)) 5899 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("alignment must be power of 2")); 5900 5901 newSize = p_FmPcd->ccShadowSize; 5902 newAlign = p_FmPcd->ccShadowAlign; 5903 5904 /* Check if current shadow is large enough to hold the requested size */ 5905 if (size > p_FmPcd->ccShadowSize) 5906 newSize = size; 5907 5908 /* Check if current shadow matches the requested alignment */ 5909 if (align > p_FmPcd->ccShadowAlign) 5910 newAlign = align; 5911 5912 /* If a bigger shadow size or bigger shadow alignment are required, 5913 a new shadow will be allocated */ 5914 if ((newSize != p_FmPcd->ccShadowSize) 5915 || (newAlign != p_FmPcd->ccShadowAlign)) 5916 { 5917 intFlags = FmPcdLock(p_FmPcd); 5918 5919 if (p_FmPcd->p_CcShadow) 5920 { 5921 FM_MURAM_FreeMem(FmPcdGetMuramHandle(p_FmPcd), p_FmPcd->p_CcShadow); 5922 p_FmPcd->ccShadowSize = 0; 5923 p_FmPcd->ccShadowAlign = 0; 5924 } 5925 5926 p_FmPcd->p_CcShadow = FM_MURAM_AllocMem(FmPcdGetMuramHandle(p_FmPcd), 5927 newSize, newAlign); 5928 if (!p_FmPcd->p_CcShadow) 5929 { 5930 allocFail = TRUE; 5931 5932 /* If new shadow size allocation failed, 5933 re-allocate with previous parameters */ 5934 p_FmPcd->p_CcShadow = FM_MURAM_AllocMem( 5935 FmPcdGetMuramHandle(p_FmPcd), p_FmPcd->ccShadowSize, 5936 p_FmPcd->ccShadowAlign); 5937 } 5938 5939 FmPcdUnlock(p_FmPcd, intFlags); 5940 5941 if (allocFail) 5942 RETURN_ERROR(MAJOR, E_NO_MEMORY, 5943 ("MURAM allocation for CC Shadow memory")); 5944 5945 p_FmPcd->ccShadowSize = newSize; 5946 p_FmPcd->ccShadowAlign = newAlign; 5947 } 5948 5949 return E_OK; 5950 } 5951 5952 #if (DPAA_VERSION >= 11) 5953 void FmPcdCcGetAdTablesThatPointOnReplicGroup(t_Handle h_Node, 5954 t_Handle h_ReplicGroup, 5955 t_List *p_AdTables, 5956 uint32_t *p_NumOfAdTables) 5957 { 5958 t_FmPcdCcNode *p_CurrentNode = (t_FmPcdCcNode *)h_Node; 5959 int i = 0; 5960 void * p_AdTable; 5961 t_CcNodeInformation ccNodeInfo; 5962 5963 ASSERT_COND(h_Node); 5964 *p_NumOfAdTables = 0; 5965 5966 /* search in the current node which exact index points on this current replicator group for getting AD */ 5967 for (i = 0; i < p_CurrentNode->numOfKeys + 1; i++) 5968 { 5969 if ((p_CurrentNode->keyAndNextEngineParams[i].nextEngineParams.nextEngine 5970 == e_FM_PCD_FR) 5971 && ((p_CurrentNode->keyAndNextEngineParams[i].nextEngineParams.params.frParams.h_FrmReplic 5972 == (t_Handle)h_ReplicGroup))) 5973 { 5974 /* save the current ad table in the list */ 5975 /* this entry uses the input replicator group */ 5976 p_AdTable = 5977 PTR_MOVE(p_CurrentNode->h_AdTable, i*FM_PCD_CC_AD_ENTRY_SIZE); 5978 memset(&ccNodeInfo, 0, sizeof(t_CcNodeInformation)); 5979 ccNodeInfo.h_CcNode = p_AdTable; 5980 EnqueueNodeInfoToRelevantLst(p_AdTables, &ccNodeInfo, NULL); 5981 (*p_NumOfAdTables)++; 5982 } 5983 } 5984 5985 ASSERT_COND(i != p_CurrentNode->numOfKeys); 5986 } 5987 #endif /* (DPAA_VERSION >= 11) */ 5988 /*********************** End of inter-module routines ************************/ 5989 5990 /****************************************/ 5991 /* API Init unit functions */ 5992 /****************************************/ 5993 5994 t_Handle FM_PCD_CcRootBuild(t_Handle h_FmPcd, 5995 t_FmPcdCcTreeParams *p_PcdGroupsParam) 5996 { 5997 t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd; 5998 t_Error err = E_OK; 5999 int i = 0, j = 0, k = 0; 6000 t_FmPcdCcTree *p_FmPcdCcTree; 6001 uint8_t numOfEntries; 6002 t_Handle p_CcTreeTmp; 6003 t_FmPcdCcGrpParams *p_FmPcdCcGroupParams; 6004 t_FmPcdCcKeyAndNextEngineParams *p_Params, *p_KeyAndNextEngineParams; 6005 t_NetEnvParams netEnvParams; 6006 uint8_t lastOne = 0; 6007 uint32_t requiredAction = 0; 6008 t_FmPcdCcNode *p_FmPcdCcNextNode; 6009 t_CcNodeInformation ccNodeInfo, *p_CcInformation; 6010 6011 SANITY_CHECK_RETURN_VALUE(h_FmPcd, E_INVALID_HANDLE, NULL); 6012 SANITY_CHECK_RETURN_VALUE(p_PcdGroupsParam, E_INVALID_HANDLE, NULL); 6013 6014 if (p_PcdGroupsParam->numOfGrps > FM_PCD_MAX_NUM_OF_CC_GROUPS) 6015 { 6016 REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("numOfGrps should not exceed %d", FM_PCD_MAX_NUM_OF_CC_GROUPS)); 6017 return NULL; 6018 } 6019 6020 p_FmPcdCcTree = (t_FmPcdCcTree*)XX_Malloc(sizeof(t_FmPcdCcTree)); 6021 if (!p_FmPcdCcTree) 6022 { 6023 REPORT_ERROR(MAJOR, E_NO_MEMORY, ("PCD tree structure")); 6024 return NULL; 6025 } 6026 memset(p_FmPcdCcTree, 0, sizeof(t_FmPcdCcTree)); 6027 p_FmPcdCcTree->h_FmPcd = h_FmPcd; 6028 6029 p_Params = (t_FmPcdCcKeyAndNextEngineParams*)XX_Malloc( 6030 FM_PCD_MAX_NUM_OF_CC_GROUPS 6031 * sizeof(t_FmPcdCcKeyAndNextEngineParams)); 6032 memset(p_Params, 6033 0, 6034 FM_PCD_MAX_NUM_OF_CC_GROUPS 6035 * sizeof(t_FmPcdCcKeyAndNextEngineParams)); 6036 6037 INIT_LIST(&p_FmPcdCcTree->fmPortsLst); 6038 6039 #ifdef FM_CAPWAP_SUPPORT 6040 if ((p_PcdGroupsParam->numOfGrps == 1) && 6041 (p_PcdGroupsParam->ccGrpParams[0].numOfDistinctionUnits == 0) && 6042 (p_PcdGroupsParam->ccGrpParams[0].nextEnginePerEntriesInGrp[0].nextEngine == e_FM_PCD_CC) && 6043 p_PcdGroupsParam->ccGrpParams[0].nextEnginePerEntriesInGrp[0].params.ccParams.h_CcNode && 6044 IsCapwapApplSpecific(p_PcdGroupsParam->ccGrpParams[0].nextEnginePerEntriesInGrp[0].params.ccParams.h_CcNode)) 6045 { 6046 p_PcdGroupsParam->ccGrpParams[0].nextEnginePerEntriesInGrp[0].h_Manip = FmPcdManipApplSpecificBuild(); 6047 if (!p_PcdGroupsParam->ccGrpParams[0].nextEnginePerEntriesInGrp[0].h_Manip) 6048 { 6049 DeleteTree(p_FmPcdCcTree,p_FmPcd); 6050 XX_Free(p_Params); 6051 REPORT_ERROR(MAJOR, E_INVALID_STATE, NO_MSG); 6052 return NULL; 6053 } 6054 } 6055 #endif /* FM_CAPWAP_SUPPORT */ 6056 6057 numOfEntries = 0; 6058 p_FmPcdCcTree->netEnvId = FmPcdGetNetEnvId(p_PcdGroupsParam->h_NetEnv); 6059 6060 for (i = 0; i < p_PcdGroupsParam->numOfGrps; i++) 6061 { 6062 p_FmPcdCcGroupParams = &p_PcdGroupsParam->ccGrpParams[i]; 6063 6064 if (p_FmPcdCcGroupParams->numOfDistinctionUnits 6065 > FM_PCD_MAX_NUM_OF_CC_UNITS) 6066 { 6067 DeleteTree(p_FmPcdCcTree, p_FmPcd); 6068 XX_Free(p_Params); 6069 REPORT_ERROR(MAJOR, E_INVALID_VALUE, 6070 ("numOfDistinctionUnits (group %d) should not exceed %d", i, FM_PCD_MAX_NUM_OF_CC_UNITS)); 6071 return NULL; 6072 } 6073 6074 p_FmPcdCcTree->fmPcdGroupParam[i].baseGroupEntry = numOfEntries; 6075 p_FmPcdCcTree->fmPcdGroupParam[i].numOfEntriesInGroup = (uint8_t)(0x01 6076 << p_FmPcdCcGroupParams->numOfDistinctionUnits); 6077 numOfEntries += p_FmPcdCcTree->fmPcdGroupParam[i].numOfEntriesInGroup; 6078 if (numOfEntries > FM_PCD_MAX_NUM_OF_CC_GROUPS) 6079 { 6080 DeleteTree(p_FmPcdCcTree, p_FmPcd); 6081 XX_Free(p_Params); 6082 REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("numOfEntries can not be larger than %d", FM_PCD_MAX_NUM_OF_CC_GROUPS)); 6083 return NULL; 6084 } 6085 6086 if (lastOne) 6087 { 6088 if (p_FmPcdCcTree->fmPcdGroupParam[i].numOfEntriesInGroup > lastOne) 6089 { 6090 DeleteTree(p_FmPcdCcTree, p_FmPcd); 6091 XX_Free(p_Params); 6092 REPORT_ERROR(MAJOR, E_CONFLICT, ("numOfEntries per group must be set in descending order")); 6093 return NULL; 6094 } 6095 } 6096 6097 lastOne = p_FmPcdCcTree->fmPcdGroupParam[i].numOfEntriesInGroup; 6098 6099 netEnvParams.netEnvId = p_FmPcdCcTree->netEnvId; 6100 netEnvParams.numOfDistinctionUnits = 6101 p_FmPcdCcGroupParams->numOfDistinctionUnits; 6102 6103 memcpy(netEnvParams.unitIds, &p_FmPcdCcGroupParams->unitIds, 6104 (sizeof(uint8_t)) * p_FmPcdCcGroupParams->numOfDistinctionUnits); 6105 6106 err = PcdGetUnitsVector(p_FmPcd, &netEnvParams); 6107 if (err) 6108 { 6109 DeleteTree(p_FmPcdCcTree, p_FmPcd); 6110 XX_Free(p_Params); 6111 REPORT_ERROR(MAJOR, err, NO_MSG); 6112 return NULL; 6113 } 6114 6115 p_FmPcdCcTree->fmPcdGroupParam[i].totalBitsMask = netEnvParams.vector; 6116 for (j = 0; j < p_FmPcdCcTree->fmPcdGroupParam[i].numOfEntriesInGroup; 6117 j++) 6118 { 6119 err = ValidateNextEngineParams( 6120 h_FmPcd, 6121 &p_FmPcdCcGroupParams->nextEnginePerEntriesInGrp[j], 6122 e_FM_PCD_CC_STATS_MODE_NONE); 6123 if (err) 6124 { 6125 DeleteTree(p_FmPcdCcTree, p_FmPcd); 6126 XX_Free(p_Params); 6127 REPORT_ERROR(MAJOR, err, (NO_MSG)); 6128 return NULL; 6129 } 6130 6131 if (p_FmPcdCcGroupParams->nextEnginePerEntriesInGrp[j].h_Manip) 6132 { 6133 err = FmPcdManipCheckParamsForCcNextEngine( 6134 &p_FmPcdCcGroupParams->nextEnginePerEntriesInGrp[j], 6135 &requiredAction); 6136 if (err) 6137 { 6138 DeleteTree(p_FmPcdCcTree, p_FmPcd); 6139 XX_Free(p_Params); 6140 REPORT_ERROR(MAJOR, E_INVALID_STATE, NO_MSG); 6141 return NULL; 6142 } 6143 } 6144 p_KeyAndNextEngineParams = p_Params + k; 6145 6146 memcpy(&p_KeyAndNextEngineParams->nextEngineParams, 6147 &p_FmPcdCcGroupParams->nextEnginePerEntriesInGrp[j], 6148 sizeof(t_FmPcdCcNextEngineParams)); 6149 6150 if ((p_KeyAndNextEngineParams->nextEngineParams.nextEngine 6151 == e_FM_PCD_CC) 6152 && p_KeyAndNextEngineParams->nextEngineParams.h_Manip) 6153 { 6154 err = 6155 AllocAndFillAdForContLookupManip( 6156 p_KeyAndNextEngineParams->nextEngineParams.params.ccParams.h_CcNode); 6157 if (err) 6158 { 6159 DeleteTree(p_FmPcdCcTree, p_FmPcd); 6160 XX_Free(p_Params); 6161 REPORT_ERROR(MAJOR, E_NO_MEMORY, ("MURAM allocation for CC Tree")); 6162 return NULL; 6163 } 6164 } 6165 6166 requiredAction |= UPDATE_CC_WITH_TREE; 6167 p_KeyAndNextEngineParams->requiredAction = requiredAction; 6168 6169 k++; 6170 } 6171 } 6172 6173 p_FmPcdCcTree->numOfEntries = (uint8_t)k; 6174 p_FmPcdCcTree->numOfGrps = p_PcdGroupsParam->numOfGrps; 6175 6176 p_FmPcdCcTree->ccTreeBaseAddr = 6177 PTR_TO_UINT(FM_MURAM_AllocMem(FmPcdGetMuramHandle(h_FmPcd), 6178 (uint32_t)( FM_PCD_MAX_NUM_OF_CC_GROUPS * FM_PCD_CC_AD_ENTRY_SIZE), 6179 FM_PCD_CC_TREE_ADDR_ALIGN)); 6180 if (!p_FmPcdCcTree->ccTreeBaseAddr) 6181 { 6182 DeleteTree(p_FmPcdCcTree, p_FmPcd); 6183 XX_Free(p_Params); 6184 REPORT_ERROR(MAJOR, E_NO_MEMORY, ("MURAM allocation for CC Tree")); 6185 return NULL; 6186 } 6187 MemSet8( 6188 UINT_TO_PTR(p_FmPcdCcTree->ccTreeBaseAddr), 0, 6189 (uint32_t)(FM_PCD_MAX_NUM_OF_CC_GROUPS * FM_PCD_CC_AD_ENTRY_SIZE)); 6190 6191 p_CcTreeTmp = UINT_TO_PTR(p_FmPcdCcTree->ccTreeBaseAddr); 6192 6193 for (i = 0; i < numOfEntries; i++) 6194 { 6195 p_KeyAndNextEngineParams = p_Params + i; 6196 6197 NextStepAd(p_CcTreeTmp, NULL, 6198 &p_KeyAndNextEngineParams->nextEngineParams, p_FmPcd); 6199 6200 p_CcTreeTmp = PTR_MOVE(p_CcTreeTmp, FM_PCD_CC_AD_ENTRY_SIZE); 6201 6202 memcpy(&p_FmPcdCcTree->keyAndNextEngineParams[i], 6203 p_KeyAndNextEngineParams, 6204 sizeof(t_FmPcdCcKeyAndNextEngineParams)); 6205 6206 if (p_FmPcdCcTree->keyAndNextEngineParams[i].nextEngineParams.nextEngine 6207 == e_FM_PCD_CC) 6208 { 6209 p_FmPcdCcNextNode = 6210 (t_FmPcdCcNode*)p_FmPcdCcTree->keyAndNextEngineParams[i].nextEngineParams.params.ccParams.h_CcNode; 6211 p_CcInformation = FindNodeInfoInReleventLst( 6212 &p_FmPcdCcNextNode->ccTreeIdLst, (t_Handle)p_FmPcdCcTree, 6213 p_FmPcdCcNextNode->h_Spinlock); 6214 6215 if (!p_CcInformation) 6216 { 6217 memset(&ccNodeInfo, 0, sizeof(t_CcNodeInformation)); 6218 ccNodeInfo.h_CcNode = (t_Handle)p_FmPcdCcTree; 6219 ccNodeInfo.index = 1; 6220 EnqueueNodeInfoToRelevantLst(&p_FmPcdCcNextNode->ccTreeIdLst, 6221 &ccNodeInfo, 6222 p_FmPcdCcNextNode->h_Spinlock); 6223 } 6224 else 6225 p_CcInformation->index++; 6226 } 6227 } 6228 6229 FmPcdIncNetEnvOwners(h_FmPcd, p_FmPcdCcTree->netEnvId); 6230 p_CcTreeTmp = UINT_TO_PTR(p_FmPcdCcTree->ccTreeBaseAddr); 6231 6232 if (!FmPcdLockTryLockAll(p_FmPcd)) 6233 { 6234 FM_PCD_CcRootDelete(p_FmPcdCcTree); 6235 XX_Free(p_Params); 6236 DBG(TRACE, ("FmPcdLockTryLockAll failed")); 6237 return NULL; 6238 } 6239 6240 for (i = 0; i < numOfEntries; i++) 6241 { 6242 if (p_FmPcdCcTree->keyAndNextEngineParams[i].requiredAction) 6243 { 6244 err = SetRequiredAction( 6245 h_FmPcd, 6246 p_FmPcdCcTree->keyAndNextEngineParams[i].requiredAction, 6247 &p_FmPcdCcTree->keyAndNextEngineParams[i], p_CcTreeTmp, 1, 6248 p_FmPcdCcTree); 6249 if (err) 6250 { 6251 FmPcdLockUnlockAll(p_FmPcd); 6252 FM_PCD_CcRootDelete(p_FmPcdCcTree); 6253 XX_Free(p_Params); 6254 REPORT_ERROR(MAJOR, E_NO_MEMORY, ("No memory")); 6255 return NULL; 6256 } 6257 p_CcTreeTmp = PTR_MOVE(p_CcTreeTmp, FM_PCD_CC_AD_ENTRY_SIZE); 6258 } 6259 } 6260 6261 FmPcdLockUnlockAll(p_FmPcd); 6262 p_FmPcdCcTree->p_Lock = FmPcdAcquireLock(p_FmPcd); 6263 if (!p_FmPcdCcTree->p_Lock) 6264 { 6265 FM_PCD_CcRootDelete(p_FmPcdCcTree); 6266 XX_Free(p_Params); 6267 REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM CC lock")); 6268 return NULL; 6269 } 6270 6271 XX_Free(p_Params); 6272 6273 return p_FmPcdCcTree; 6274 } 6275 6276 t_Error FM_PCD_CcRootDelete(t_Handle h_CcTree) 6277 { 6278 t_FmPcd *p_FmPcd; 6279 t_FmPcdCcTree *p_CcTree = (t_FmPcdCcTree *)h_CcTree; 6280 int i = 0; 6281 6282 SANITY_CHECK_RETURN_ERROR(p_CcTree, E_INVALID_STATE); 6283 p_FmPcd = (t_FmPcd *)p_CcTree->h_FmPcd; 6284 SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE); 6285 6286 FmPcdDecNetEnvOwners(p_FmPcd, p_CcTree->netEnvId); 6287 6288 if (p_CcTree->owners) 6289 RETURN_ERROR( 6290 MAJOR, 6291 E_INVALID_SELECTION, 6292 ("the tree with this ID can not be removed because this tree is occupied, first - unbind this tree")); 6293 6294 /* Delete ip-reassembly schemes if exist */ 6295 if (p_CcTree->h_IpReassemblyManip) 6296 { 6297 FmPcdManipDeleteIpReassmSchemes(p_CcTree->h_IpReassemblyManip); 6298 FmPcdManipUpdateOwner(p_CcTree->h_IpReassemblyManip, FALSE); 6299 } 6300 6301 /* Delete capwap-reassembly schemes if exist */ 6302 if (p_CcTree->h_CapwapReassemblyManip) 6303 { 6304 FmPcdManipDeleteCapwapReassmSchemes(p_CcTree->h_CapwapReassemblyManip); 6305 FmPcdManipUpdateOwner(p_CcTree->h_CapwapReassemblyManip, FALSE); 6306 } 6307 6308 for (i = 0; i < p_CcTree->numOfEntries; i++) 6309 { 6310 if (p_CcTree->keyAndNextEngineParams[i].nextEngineParams.nextEngine 6311 == e_FM_PCD_CC) 6312 UpdateNodeOwner( 6313 p_CcTree->keyAndNextEngineParams[i].nextEngineParams.params.ccParams.h_CcNode, 6314 FALSE); 6315 6316 if (p_CcTree->keyAndNextEngineParams[i].nextEngineParams.h_Manip) 6317 FmPcdManipUpdateOwner( 6318 p_CcTree->keyAndNextEngineParams[i].nextEngineParams.h_Manip, 6319 FALSE); 6320 6321 #ifdef FM_CAPWAP_SUPPORT 6322 if ((p_CcTree->numOfGrps == 1) && 6323 (p_CcTree->fmPcdGroupParam[0].numOfEntriesInGroup == 1) && 6324 (p_CcTree->keyAndNextEngineParams[0].nextEngineParams.nextEngine == e_FM_PCD_CC) && 6325 p_CcTree->keyAndNextEngineParams[0].nextEngineParams.params.ccParams.h_CcNode && 6326 IsCapwapApplSpecific(p_CcTree->keyAndNextEngineParams[0].nextEngineParams.params.ccParams.h_CcNode)) 6327 { 6328 if (FM_PCD_ManipNodeDelete(p_CcTree->keyAndNextEngineParams[0].nextEngineParams.h_Manip) != E_OK) 6329 return E_INVALID_STATE; 6330 } 6331 #endif /* FM_CAPWAP_SUPPORT */ 6332 6333 #if (DPAA_VERSION >= 11) 6334 if ((p_CcTree->keyAndNextEngineParams[i].nextEngineParams.nextEngine 6335 == e_FM_PCD_FR) 6336 && (p_CcTree->keyAndNextEngineParams[i].nextEngineParams.params.frParams.h_FrmReplic)) 6337 FrmReplicGroupUpdateOwner( 6338 p_CcTree->keyAndNextEngineParams[i].nextEngineParams.params.frParams.h_FrmReplic, 6339 FALSE); 6340 #endif /* (DPAA_VERSION >= 11) */ 6341 } 6342 6343 if (p_CcTree->p_Lock) 6344 FmPcdReleaseLock(p_CcTree->h_FmPcd, p_CcTree->p_Lock); 6345 6346 DeleteTree(p_CcTree, p_FmPcd); 6347 6348 return E_OK; 6349 } 6350 6351 t_Error FM_PCD_CcRootModifyNextEngine( 6352 t_Handle h_CcTree, uint8_t grpId, uint8_t index, 6353 t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams) 6354 { 6355 t_FmPcd *p_FmPcd; 6356 t_FmPcdCcTree *p_CcTree = (t_FmPcdCcTree *)h_CcTree; 6357 t_Error err = E_OK; 6358 6359 SANITY_CHECK_RETURN_ERROR(p_FmPcdCcNextEngineParams, E_NULL_POINTER); 6360 SANITY_CHECK_RETURN_ERROR(p_CcTree, E_INVALID_STATE); 6361 p_FmPcd = (t_FmPcd *)p_CcTree->h_FmPcd; 6362 SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE); 6363 6364 if (!FmPcdLockTryLockAll(p_FmPcd)) 6365 { 6366 DBG(TRACE, ("FmPcdLockTryLockAll failed")); 6367 return ERROR_CODE(E_BUSY); 6368 } 6369 6370 err = FmPcdCcModifyNextEngineParamTree(p_FmPcd, p_CcTree, grpId, index, 6371 p_FmPcdCcNextEngineParams); 6372 FmPcdLockUnlockAll(p_FmPcd); 6373 6374 if (err) 6375 { 6376 RETURN_ERROR(MAJOR, err, NO_MSG); 6377 } 6378 6379 return E_OK; 6380 } 6381 6382 t_Handle FM_PCD_MatchTableSet(t_Handle h_FmPcd, 6383 t_FmPcdCcNodeParams *p_CcNodeParam) 6384 { 6385 t_FmPcdCcNode *p_CcNode; 6386 t_Error err; 6387 6388 SANITY_CHECK_RETURN_VALUE(h_FmPcd, E_INVALID_HANDLE, NULL); 6389 SANITY_CHECK_RETURN_VALUE(p_CcNodeParam, E_NULL_POINTER, NULL); 6390 6391 p_CcNode = (t_FmPcdCcNode*)XX_Malloc(sizeof(t_FmPcdCcNode)); 6392 if (!p_CcNode) 6393 { 6394 REPORT_ERROR(MAJOR, E_NO_MEMORY, ("No memory")); 6395 return NULL; 6396 } 6397 memset(p_CcNode, 0, sizeof(t_FmPcdCcNode)); 6398 6399 err = MatchTableSet(h_FmPcd, p_CcNode, p_CcNodeParam); 6400 6401 switch(GET_ERROR_TYPE(err) 6402 ) { 6403 case E_OK: 6404 break; 6405 6406 case E_BUSY: 6407 DBG(TRACE, ("E_BUSY error")); 6408 return NULL; 6409 6410 default: 6411 REPORT_ERROR(MAJOR, err, NO_MSG); 6412 return NULL; 6413 } 6414 6415 return p_CcNode; 6416 } 6417 6418 t_Error FM_PCD_MatchTableDelete(t_Handle h_CcNode) 6419 { 6420 t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode; 6421 int i = 0; 6422 6423 SANITY_CHECK_RETURN_ERROR(p_CcNode, E_INVALID_HANDLE); 6424 SANITY_CHECK_RETURN_ERROR(p_CcNode->h_FmPcd, E_INVALID_HANDLE); 6425 6426 if (p_CcNode->owners) 6427 RETURN_ERROR( 6428 MAJOR, 6429 E_INVALID_STATE, 6430 ("This node cannot be removed because it is occupied; first unbind this node")); 6431 6432 for (i = 0; i < p_CcNode->numOfKeys; i++) 6433 if (p_CcNode->keyAndNextEngineParams[i].nextEngineParams.nextEngine 6434 == e_FM_PCD_CC) 6435 UpdateNodeOwner( 6436 p_CcNode->keyAndNextEngineParams[i].nextEngineParams.params.ccParams.h_CcNode, 6437 FALSE); 6438 6439 if (p_CcNode->keyAndNextEngineParams[i].nextEngineParams.nextEngine 6440 == e_FM_PCD_CC) 6441 UpdateNodeOwner( 6442 p_CcNode->keyAndNextEngineParams[i].nextEngineParams.params.ccParams.h_CcNode, 6443 FALSE); 6444 6445 /* Handle also Miss entry */ 6446 for (i = 0; i < p_CcNode->numOfKeys + 1; i++) 6447 { 6448 if (p_CcNode->keyAndNextEngineParams[i].nextEngineParams.h_Manip) 6449 FmPcdManipUpdateOwner( 6450 p_CcNode->keyAndNextEngineParams[i].nextEngineParams.h_Manip, 6451 FALSE); 6452 6453 #if (DPAA_VERSION >= 11) 6454 if ((p_CcNode->keyAndNextEngineParams[i].nextEngineParams.nextEngine 6455 == e_FM_PCD_FR) 6456 && (p_CcNode->keyAndNextEngineParams[i].nextEngineParams.params.frParams.h_FrmReplic)) 6457 { 6458 FrmReplicGroupUpdateOwner( 6459 p_CcNode->keyAndNextEngineParams[i].nextEngineParams.params.frParams.h_FrmReplic, 6460 FALSE); 6461 } 6462 #endif /* (DPAA_VERSION >= 11) */ 6463 } 6464 6465 DeleteNode(p_CcNode); 6466 6467 return E_OK; 6468 } 6469 6470 t_Error FM_PCD_MatchTableAddKey(t_Handle h_CcNode, uint16_t keyIndex, 6471 uint8_t keySize, 6472 t_FmPcdCcKeyParams *p_KeyParams) 6473 { 6474 t_FmPcd *p_FmPcd; 6475 t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode; 6476 t_Error err = E_OK; 6477 6478 SANITY_CHECK_RETURN_ERROR(p_KeyParams, E_NULL_POINTER); 6479 SANITY_CHECK_RETURN_ERROR(p_CcNode, E_INVALID_HANDLE); 6480 p_FmPcd = (t_FmPcd *)p_CcNode->h_FmPcd; 6481 SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE); 6482 SANITY_CHECK_RETURN_ERROR(p_FmPcd->h_Hc, E_INVALID_HANDLE); 6483 6484 if (keyIndex == FM_PCD_LAST_KEY_INDEX) 6485 keyIndex = p_CcNode->numOfKeys; 6486 6487 if (!FmPcdLockTryLockAll(p_FmPcd)) 6488 { 6489 DBG(TRACE, ("FmPcdLockTryLockAll failed")); 6490 return ERROR_CODE(E_BUSY); 6491 } 6492 6493 err = FmPcdCcAddKey(p_FmPcd, p_CcNode, keyIndex, keySize, p_KeyParams); 6494 6495 FmPcdLockUnlockAll(p_FmPcd); 6496 6497 switch(GET_ERROR_TYPE(err) 6498 ) { 6499 case E_OK: 6500 return E_OK; 6501 6502 case E_BUSY: 6503 DBG(TRACE, ("E_BUSY error")); 6504 return ERROR_CODE(E_BUSY); 6505 6506 default: 6507 RETURN_ERROR(MAJOR, err, NO_MSG); 6508 } 6509 } 6510 6511 t_Error FM_PCD_MatchTableRemoveKey(t_Handle h_CcNode, uint16_t keyIndex) 6512 { 6513 t_FmPcd *p_FmPcd; 6514 t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode; 6515 t_Error err = E_OK; 6516 6517 SANITY_CHECK_RETURN_ERROR(p_CcNode, E_INVALID_HANDLE); 6518 p_FmPcd = (t_FmPcd *)p_CcNode->h_FmPcd; 6519 SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE); 6520 SANITY_CHECK_RETURN_ERROR(p_FmPcd->h_Hc, E_INVALID_HANDLE); 6521 6522 if (!FmPcdLockTryLockAll(p_FmPcd)) 6523 { 6524 DBG(TRACE, ("FmPcdLockTryLockAll failed")); 6525 return ERROR_CODE(E_BUSY); 6526 } 6527 6528 err = FmPcdCcRemoveKey(p_FmPcd, p_CcNode, keyIndex); 6529 6530 FmPcdLockUnlockAll(p_FmPcd); 6531 6532 switch(GET_ERROR_TYPE(err) 6533 ) { 6534 case E_OK: 6535 return E_OK; 6536 6537 case E_BUSY: 6538 DBG(TRACE, ("E_BUSY error")); 6539 return ERROR_CODE(E_BUSY); 6540 6541 default: 6542 RETURN_ERROR(MAJOR, err, NO_MSG); 6543 } 6544 6545 return E_OK; 6546 } 6547 6548 t_Error FM_PCD_MatchTableModifyKey(t_Handle h_CcNode, uint16_t keyIndex, 6549 uint8_t keySize, uint8_t *p_Key, 6550 uint8_t *p_Mask) 6551 { 6552 t_FmPcd *p_FmPcd; 6553 t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode; 6554 t_Error err = E_OK; 6555 6556 SANITY_CHECK_RETURN_ERROR(p_CcNode, E_INVALID_HANDLE); 6557 SANITY_CHECK_RETURN_ERROR(p_Key, E_NULL_POINTER); 6558 p_FmPcd = (t_FmPcd *)p_CcNode->h_FmPcd; 6559 SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE); 6560 SANITY_CHECK_RETURN_ERROR(p_FmPcd->h_Hc, E_INVALID_HANDLE); 6561 6562 6563 if (!FmPcdLockTryLockAll(p_FmPcd)) 6564 { 6565 DBG(TRACE, ("FmPcdLockTryLockAll failed")); 6566 return ERROR_CODE(E_BUSY); 6567 } 6568 6569 err = FmPcdCcModifyKey(p_FmPcd, p_CcNode, keyIndex, keySize, p_Key, p_Mask); 6570 6571 FmPcdLockUnlockAll(p_FmPcd); 6572 6573 switch(GET_ERROR_TYPE(err) 6574 ) { 6575 case E_OK: 6576 return E_OK; 6577 6578 case E_BUSY: 6579 DBG(TRACE, ("E_BUSY error")); 6580 return ERROR_CODE(E_BUSY); 6581 6582 default: 6583 RETURN_ERROR(MAJOR, err, NO_MSG); 6584 } 6585 } 6586 6587 t_Error FM_PCD_MatchTableModifyNextEngine( 6588 t_Handle h_CcNode, uint16_t keyIndex, 6589 t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams) 6590 { 6591 t_FmPcd *p_FmPcd; 6592 t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode; 6593 t_Error err = E_OK; 6594 6595 SANITY_CHECK_RETURN_ERROR(p_FmPcdCcNextEngineParams, E_NULL_POINTER); 6596 SANITY_CHECK_RETURN_ERROR(p_CcNode, E_INVALID_HANDLE); 6597 p_FmPcd = (t_FmPcd *)p_CcNode->h_FmPcd; 6598 SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE); 6599 SANITY_CHECK_RETURN_ERROR(p_FmPcd->h_Hc, E_INVALID_HANDLE); 6600 6601 if (!FmPcdLockTryLockAll(p_FmPcd)) 6602 { 6603 DBG(TRACE, ("FmPcdLockTryLockAll failed")); 6604 return ERROR_CODE(E_BUSY); 6605 } 6606 6607 err = ModifyNextEngineParamNode(p_FmPcd, p_CcNode, keyIndex, 6608 p_FmPcdCcNextEngineParams); 6609 6610 FmPcdLockUnlockAll(p_FmPcd); 6611 6612 switch(GET_ERROR_TYPE(err) 6613 ) { 6614 case E_OK: 6615 return E_OK; 6616 6617 case E_BUSY: 6618 DBG(TRACE, ("E_BUSY error")); 6619 return ERROR_CODE(E_BUSY); 6620 6621 default: 6622 RETURN_ERROR(MAJOR, err, NO_MSG); 6623 } 6624 } 6625 6626 t_Error FM_PCD_MatchTableModifyMissNextEngine( 6627 t_Handle h_CcNode, t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams) 6628 { 6629 t_FmPcd *p_FmPcd; 6630 t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode; 6631 t_Error err = E_OK; 6632 6633 SANITY_CHECK_RETURN_ERROR(p_FmPcdCcNextEngineParams, E_NULL_POINTER); 6634 SANITY_CHECK_RETURN_ERROR(p_CcNode, E_INVALID_HANDLE); 6635 p_FmPcd = (t_FmPcd *)p_CcNode->h_FmPcd; 6636 SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE); 6637 SANITY_CHECK_RETURN_ERROR(p_FmPcd->h_Hc, E_INVALID_HANDLE); 6638 6639 if (!FmPcdLockTryLockAll(p_FmPcd)) 6640 { 6641 DBG(TRACE, ("FmPcdLockTryLockAll failed")); 6642 return ERROR_CODE(E_BUSY); 6643 } 6644 6645 err = FmPcdCcModifyMissNextEngineParamNode(p_FmPcd, p_CcNode, 6646 p_FmPcdCcNextEngineParams); 6647 6648 FmPcdLockUnlockAll(p_FmPcd); 6649 6650 switch(GET_ERROR_TYPE(err) 6651 ) { 6652 case E_OK: 6653 return E_OK; 6654 6655 case E_BUSY: 6656 DBG(TRACE, ("E_BUSY error")); 6657 return ERROR_CODE(E_BUSY); 6658 6659 default: 6660 RETURN_ERROR(MAJOR, err, NO_MSG); 6661 } 6662 } 6663 6664 t_Error FM_PCD_MatchTableModifyKeyAndNextEngine(t_Handle h_CcNode, 6665 uint16_t keyIndex, 6666 uint8_t keySize, 6667 t_FmPcdCcKeyParams *p_KeyParams) 6668 { 6669 t_FmPcd *p_FmPcd; 6670 t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode; 6671 t_Error err = E_OK; 6672 6673 SANITY_CHECK_RETURN_ERROR(p_KeyParams, E_NULL_POINTER); 6674 SANITY_CHECK_RETURN_ERROR(p_CcNode, E_INVALID_HANDLE); 6675 p_FmPcd = (t_FmPcd *)p_CcNode->h_FmPcd; 6676 SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE); 6677 SANITY_CHECK_RETURN_ERROR(p_FmPcd->h_Hc, E_INVALID_HANDLE); 6678 6679 if (!FmPcdLockTryLockAll(p_FmPcd)) 6680 { 6681 DBG(TRACE, ("FmPcdLockTryLockAll failed")); 6682 return ERROR_CODE(E_BUSY); 6683 } 6684 6685 err = FmPcdCcModifyKeyAndNextEngine(p_FmPcd, p_CcNode, keyIndex, keySize, 6686 p_KeyParams); 6687 6688 FmPcdLockUnlockAll(p_FmPcd); 6689 6690 switch(GET_ERROR_TYPE(err) 6691 ) { 6692 case E_OK: 6693 return E_OK; 6694 6695 case E_BUSY: 6696 DBG(TRACE, ("E_BUSY error")); 6697 return ERROR_CODE(E_BUSY); 6698 6699 default: 6700 RETURN_ERROR(MAJOR, err, NO_MSG); 6701 } 6702 } 6703 6704 t_Error FM_PCD_MatchTableFindNRemoveKey(t_Handle h_CcNode, uint8_t keySize, 6705 uint8_t *p_Key, uint8_t *p_Mask) 6706 { 6707 t_FmPcd *p_FmPcd; 6708 t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode; 6709 uint16_t keyIndex; 6710 t_Error err; 6711 6712 SANITY_CHECK_RETURN_ERROR(p_Key, E_NULL_POINTER); 6713 SANITY_CHECK_RETURN_ERROR(p_CcNode, E_INVALID_HANDLE); 6714 p_FmPcd = (t_FmPcd *)p_CcNode->h_FmPcd; 6715 SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE); 6716 SANITY_CHECK_RETURN_ERROR(p_FmPcd->h_Hc, E_INVALID_HANDLE); 6717 6718 if (!FmPcdLockTryLockAll(p_FmPcd)) 6719 { 6720 DBG(TRACE, ("FmPcdLockTryLockAll failed")); 6721 return ERROR_CODE(E_BUSY); 6722 } 6723 6724 err = FindKeyIndex(p_CcNode, keySize, p_Key, p_Mask, &keyIndex); 6725 if (GET_ERROR_TYPE(err) != E_OK) 6726 { 6727 FmPcdLockUnlockAll(p_FmPcd); 6728 RETURN_ERROR( 6729 MAJOR, 6730 err, 6731 ("The received key and mask pair was not found in the match table of the provided node")); 6732 } 6733 6734 err = FmPcdCcRemoveKey(p_FmPcd, p_CcNode, keyIndex); 6735 6736 FmPcdLockUnlockAll(p_FmPcd); 6737 6738 switch(GET_ERROR_TYPE(err) 6739 ) { 6740 case E_OK: 6741 return E_OK; 6742 6743 case E_BUSY: 6744 DBG(TRACE, ("E_BUSY error")); 6745 return ERROR_CODE(E_BUSY); 6746 6747 default: 6748 RETURN_ERROR(MAJOR, err, NO_MSG); 6749 } 6750 } 6751 6752 t_Error FM_PCD_MatchTableFindNModifyNextEngine( 6753 t_Handle h_CcNode, uint8_t keySize, uint8_t *p_Key, uint8_t *p_Mask, 6754 t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams) 6755 { 6756 t_FmPcd *p_FmPcd; 6757 t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode; 6758 uint16_t keyIndex; 6759 t_Error err; 6760 6761 SANITY_CHECK_RETURN_ERROR(p_Key, E_NULL_POINTER); 6762 SANITY_CHECK_RETURN_ERROR(p_FmPcdCcNextEngineParams, E_NULL_POINTER); 6763 SANITY_CHECK_RETURN_ERROR(p_CcNode, E_INVALID_HANDLE); 6764 p_FmPcd = (t_FmPcd *)p_CcNode->h_FmPcd; 6765 SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE); 6766 SANITY_CHECK_RETURN_ERROR(p_FmPcd->h_Hc, E_INVALID_HANDLE); 6767 6768 if (!FmPcdLockTryLockAll(p_FmPcd)) 6769 { 6770 DBG(TRACE, ("FmPcdLockTryLockAll failed")); 6771 return ERROR_CODE(E_BUSY); 6772 } 6773 6774 err = FindKeyIndex(p_CcNode, keySize, p_Key, p_Mask, &keyIndex); 6775 if (GET_ERROR_TYPE(err) != E_OK) 6776 { 6777 FmPcdLockUnlockAll(p_FmPcd); 6778 RETURN_ERROR( 6779 MAJOR, 6780 err, 6781 ("The received key and mask pair was not found in the match table of the provided node")); 6782 } 6783 6784 err = ModifyNextEngineParamNode(p_FmPcd, p_CcNode, keyIndex, 6785 p_FmPcdCcNextEngineParams); 6786 6787 FmPcdLockUnlockAll(p_FmPcd); 6788 6789 switch(GET_ERROR_TYPE(err) 6790 ) { 6791 case E_OK: 6792 return E_OK; 6793 6794 case E_BUSY: 6795 DBG(TRACE, ("E_BUSY error")); 6796 return ERROR_CODE(E_BUSY); 6797 6798 default: 6799 RETURN_ERROR(MAJOR, err, NO_MSG); 6800 } 6801 } 6802 6803 t_Error FM_PCD_MatchTableFindNModifyKeyAndNextEngine( 6804 t_Handle h_CcNode, uint8_t keySize, uint8_t *p_Key, uint8_t *p_Mask, 6805 t_FmPcdCcKeyParams *p_KeyParams) 6806 { 6807 t_FmPcd *p_FmPcd; 6808 t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode; 6809 uint16_t keyIndex; 6810 t_Error err; 6811 6812 SANITY_CHECK_RETURN_ERROR(p_Key, E_NULL_POINTER); 6813 SANITY_CHECK_RETURN_ERROR(p_KeyParams, E_NULL_POINTER); 6814 SANITY_CHECK_RETURN_ERROR(p_CcNode, E_INVALID_HANDLE); 6815 p_FmPcd = (t_FmPcd *)p_CcNode->h_FmPcd; 6816 SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE); 6817 SANITY_CHECK_RETURN_ERROR(p_FmPcd->h_Hc, E_INVALID_HANDLE); 6818 6819 if (!FmPcdLockTryLockAll(p_FmPcd)) 6820 { 6821 DBG(TRACE, ("FmPcdLockTryLockAll failed")); 6822 return ERROR_CODE(E_BUSY); 6823 } 6824 6825 err = FindKeyIndex(p_CcNode, keySize, p_Key, p_Mask, &keyIndex); 6826 if (GET_ERROR_TYPE(err) != E_OK) 6827 { 6828 FmPcdLockUnlockAll(p_FmPcd); 6829 RETURN_ERROR( 6830 MAJOR, 6831 err, 6832 ("The received key and mask pair was not found in the match table of the provided node")); 6833 } 6834 6835 err = FmPcdCcModifyKeyAndNextEngine(p_FmPcd, h_CcNode, keyIndex, keySize, 6836 p_KeyParams); 6837 6838 FmPcdLockUnlockAll(p_FmPcd); 6839 6840 switch(GET_ERROR_TYPE(err) 6841 ) { 6842 case E_OK: 6843 return E_OK; 6844 6845 case E_BUSY: 6846 DBG(TRACE, ("E_BUSY error")); 6847 return ERROR_CODE(E_BUSY); 6848 6849 default: 6850 RETURN_ERROR(MAJOR, err, NO_MSG); 6851 } 6852 } 6853 6854 t_Error FM_PCD_MatchTableFindNModifyKey(t_Handle h_CcNode, uint8_t keySize, 6855 uint8_t *p_Key, uint8_t *p_Mask, 6856 uint8_t *p_NewKey, uint8_t *p_NewMask) 6857 { 6858 t_FmPcd *p_FmPcd; 6859 t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode; 6860 t_List h_List; 6861 uint16_t keyIndex; 6862 t_Error err; 6863 6864 SANITY_CHECK_RETURN_ERROR(p_Key, E_NULL_POINTER); 6865 SANITY_CHECK_RETURN_ERROR(p_NewKey, E_NULL_POINTER); 6866 SANITY_CHECK_RETURN_ERROR(p_CcNode, E_INVALID_HANDLE); 6867 p_FmPcd = (t_FmPcd *)p_CcNode->h_FmPcd; 6868 SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE); 6869 SANITY_CHECK_RETURN_ERROR(p_FmPcd->h_Hc, E_INVALID_HANDLE); 6870 6871 INIT_LIST(&h_List); 6872 6873 err = FmPcdCcNodeTreeTryLock(p_FmPcd, p_CcNode, &h_List); 6874 if (err) 6875 { 6876 DBG(TRACE, ("Node's trees lock failed")); 6877 return ERROR_CODE(E_BUSY); 6878 } 6879 6880 err = FindKeyIndex(p_CcNode, keySize, p_Key, p_Mask, &keyIndex); 6881 if (GET_ERROR_TYPE(err) != E_OK) 6882 { 6883 FmPcdCcNodeTreeReleaseLock(p_FmPcd, &h_List); 6884 RETURN_ERROR(MAJOR, err, 6885 ("The received key and mask pair was not found in the " 6886 "match table of the provided node")); 6887 } 6888 6889 err = FmPcdCcModifyKey(p_FmPcd, p_CcNode, keyIndex, keySize, p_NewKey, 6890 p_NewMask); 6891 6892 FmPcdCcNodeTreeReleaseLock(p_FmPcd, &h_List); 6893 6894 switch(GET_ERROR_TYPE(err) 6895 ) { 6896 case E_OK: 6897 return E_OK; 6898 6899 case E_BUSY: 6900 DBG(TRACE, ("E_BUSY error")); 6901 return ERROR_CODE(E_BUSY); 6902 6903 default: 6904 RETURN_ERROR(MAJOR, err, NO_MSG); 6905 } 6906 } 6907 6908 t_Error FM_PCD_MatchTableGetNextEngine( 6909 t_Handle h_CcNode, uint16_t keyIndex, 6910 t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams) 6911 { 6912 t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode; 6913 6914 SANITY_CHECK_RETURN_ERROR(p_CcNode, E_INVALID_HANDLE); 6915 SANITY_CHECK_RETURN_ERROR(p_FmPcdCcNextEngineParams, E_NULL_POINTER); 6916 6917 if (keyIndex >= p_CcNode->numOfKeys) 6918 RETURN_ERROR(MAJOR, E_INVALID_STATE, 6919 ("keyIndex exceeds current number of keys")); 6920 6921 if (keyIndex > (FM_PCD_MAX_NUM_OF_KEYS - 1)) 6922 RETURN_ERROR( 6923 MAJOR, 6924 E_INVALID_VALUE, 6925 ("keyIndex can not be larger than %d", (FM_PCD_MAX_NUM_OF_KEYS - 1))); 6926 6927 memcpy(p_FmPcdCcNextEngineParams, 6928 &p_CcNode->keyAndNextEngineParams[keyIndex].nextEngineParams, 6929 sizeof(t_FmPcdCcNextEngineParams)); 6930 6931 return E_OK; 6932 } 6933 6934 6935 uint32_t FM_PCD_MatchTableGetKeyCounter(t_Handle h_CcNode, uint16_t keyIndex) 6936 { 6937 t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode; 6938 uint32_t *p_StatsCounters, frameCount; 6939 uint32_t intFlags; 6940 6941 SANITY_CHECK_RETURN_VALUE(p_CcNode, E_INVALID_HANDLE, 0); 6942 6943 if (p_CcNode->statisticsMode == e_FM_PCD_CC_STATS_MODE_NONE) 6944 { 6945 REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Statistics were not enabled for this match table")); 6946 return 0; 6947 } 6948 6949 if ((p_CcNode->statisticsMode != e_FM_PCD_CC_STATS_MODE_FRAME) 6950 && (p_CcNode->statisticsMode 6951 != e_FM_PCD_CC_STATS_MODE_BYTE_AND_FRAME)) 6952 { 6953 REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Frame count is not supported in the statistics mode of this match table")); 6954 return 0; 6955 } 6956 6957 intFlags = XX_LockIntrSpinlock(p_CcNode->h_Spinlock); 6958 6959 if (keyIndex >= p_CcNode->numOfKeys) 6960 { 6961 XX_UnlockIntrSpinlock(p_CcNode->h_Spinlock, intFlags); 6962 REPORT_ERROR(MAJOR, E_INVALID_STATE, ("The provided keyIndex exceeds the number of keys in this match table")); 6963 return 0; 6964 } 6965 6966 if (!p_CcNode->keyAndNextEngineParams[keyIndex].p_StatsObj) 6967 { 6968 XX_UnlockIntrSpinlock(p_CcNode->h_Spinlock, intFlags); 6969 REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Statistics were not enabled for this key")); 6970 return 0; 6971 } 6972 6973 p_StatsCounters = 6974 p_CcNode->keyAndNextEngineParams[keyIndex].p_StatsObj->h_StatsCounters; 6975 ASSERT_COND(p_StatsCounters); 6976 6977 /* The first counter is byte counter, so we need to advance to the next counter */ 6978 frameCount = GET_UINT32(*(uint32_t *)(PTR_MOVE(p_StatsCounters, 6979 FM_PCD_CC_STATS_COUNTER_SIZE))); 6980 6981 XX_UnlockIntrSpinlock(p_CcNode->h_Spinlock, intFlags); 6982 6983 return frameCount; 6984 } 6985 6986 t_Error FM_PCD_MatchTableGetKeyStatistics( 6987 t_Handle h_CcNode, uint16_t keyIndex, 6988 t_FmPcdCcKeyStatistics *p_KeyStatistics) 6989 { 6990 t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode; 6991 uint32_t intFlags; 6992 t_Error err; 6993 6994 SANITY_CHECK_RETURN_ERROR(h_CcNode, E_INVALID_HANDLE); 6995 SANITY_CHECK_RETURN_ERROR(p_KeyStatistics, E_NULL_POINTER); 6996 6997 intFlags = XX_LockIntrSpinlock(p_CcNode->h_Spinlock); 6998 6999 if (keyIndex >= p_CcNode->numOfKeys) 7000 RETURN_ERROR( 7001 MAJOR, 7002 E_INVALID_STATE, 7003 ("The provided keyIndex exceeds the number of keys in this match table")); 7004 7005 err = MatchTableGetKeyStatistics(p_CcNode, keyIndex, p_KeyStatistics); 7006 7007 XX_UnlockIntrSpinlock(p_CcNode->h_Spinlock, intFlags); 7008 7009 if (err != E_OK) 7010 RETURN_ERROR(MAJOR, err, NO_MSG); 7011 7012 return E_OK; 7013 } 7014 7015 t_Error FM_PCD_MatchTableGetMissStatistics( 7016 t_Handle h_CcNode, t_FmPcdCcKeyStatistics *p_MissStatistics) 7017 { 7018 t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode; 7019 uint32_t intFlags; 7020 t_Error err; 7021 7022 SANITY_CHECK_RETURN_ERROR(h_CcNode, E_INVALID_HANDLE); 7023 SANITY_CHECK_RETURN_ERROR(p_MissStatistics, E_NULL_POINTER); 7024 7025 intFlags = XX_LockIntrSpinlock(p_CcNode->h_Spinlock); 7026 7027 err = MatchTableGetKeyStatistics(p_CcNode, p_CcNode->numOfKeys, 7028 p_MissStatistics); 7029 7030 XX_UnlockIntrSpinlock(p_CcNode->h_Spinlock, intFlags); 7031 7032 if (err != E_OK) 7033 RETURN_ERROR(MAJOR, err, NO_MSG); 7034 7035 return E_OK; 7036 } 7037 7038 t_Error FM_PCD_MatchTableFindNGetKeyStatistics( 7039 t_Handle h_CcNode, uint8_t keySize, uint8_t *p_Key, uint8_t *p_Mask, 7040 t_FmPcdCcKeyStatistics *p_KeyStatistics) 7041 { 7042 t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode; 7043 uint16_t keyIndex; 7044 uint32_t intFlags; 7045 t_Error err; 7046 7047 SANITY_CHECK_RETURN_ERROR(p_Key, E_NULL_POINTER); 7048 SANITY_CHECK_RETURN_ERROR(p_KeyStatistics, E_NULL_POINTER); 7049 7050 intFlags = XX_LockIntrSpinlock(p_CcNode->h_Spinlock); 7051 7052 err = FindKeyIndex(p_CcNode, keySize, p_Key, p_Mask, &keyIndex); 7053 if (GET_ERROR_TYPE(err) != E_OK) 7054 { 7055 XX_UnlockIntrSpinlock(p_CcNode->h_Spinlock, intFlags); 7056 RETURN_ERROR(MAJOR, err, 7057 ("The received key and mask pair was not found in the " 7058 "match table of the provided node")); 7059 } 7060 7061 ASSERT_COND(keyIndex < p_CcNode->numOfKeys); 7062 7063 err = MatchTableGetKeyStatistics(p_CcNode, keyIndex, p_KeyStatistics); 7064 7065 XX_UnlockIntrSpinlock(p_CcNode->h_Spinlock, intFlags); 7066 7067 if (err != E_OK) 7068 RETURN_ERROR(MAJOR, err, NO_MSG); 7069 7070 return E_OK; 7071 } 7072 7073 t_Error FM_PCD_MatchTableGetIndexedHashBucket(t_Handle h_CcNode, 7074 uint8_t keySize, uint8_t *p_Key, 7075 uint8_t hashShift, 7076 t_Handle *p_CcNodeBucketHandle, 7077 uint8_t *p_BucketIndex, 7078 uint16_t *p_LastIndex) 7079 { 7080 t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode; 7081 uint16_t glblMask; 7082 uint64_t crc64 = 0; 7083 7084 SANITY_CHECK_RETURN_ERROR(h_CcNode, E_INVALID_HANDLE); 7085 SANITY_CHECK_RETURN_ERROR( 7086 p_CcNode->parseCode == CC_PC_GENERIC_IC_HASH_INDEXED, 7087 E_INVALID_STATE); 7088 SANITY_CHECK_RETURN_ERROR(p_Key, E_NULL_POINTER); 7089 SANITY_CHECK_RETURN_ERROR(p_CcNodeBucketHandle, E_NULL_POINTER); 7090 7091 memcpy(&glblMask, PTR_MOVE(p_CcNode->p_GlblMask, 2), 2); 7092 glblMask = be16toh(glblMask); 7093 7094 crc64 = crc64_init(); 7095 crc64 = crc64_compute(p_Key, keySize, crc64); 7096 crc64 >>= hashShift; 7097 7098 *p_BucketIndex = (uint8_t)(((crc64 >> (8 * (6 - p_CcNode->userOffset))) 7099 & glblMask) >> 4); 7100 if (*p_BucketIndex >= p_CcNode->numOfKeys) 7101 RETURN_ERROR(MINOR, E_NOT_IN_RANGE, ("bucket index!")); 7102 7103 *p_CcNodeBucketHandle = 7104 p_CcNode->keyAndNextEngineParams[*p_BucketIndex].nextEngineParams.params.ccParams.h_CcNode; 7105 if (!*p_CcNodeBucketHandle) 7106 RETURN_ERROR(MINOR, E_NOT_FOUND, ("bucket!")); 7107 7108 *p_LastIndex = ((t_FmPcdCcNode *)*p_CcNodeBucketHandle)->numOfKeys; 7109 7110 return E_OK; 7111 } 7112 7113 t_Handle FM_PCD_HashTableSet(t_Handle h_FmPcd, t_FmPcdHashTableParams *p_Param) 7114 { 7115 t_FmPcdCcNode *p_CcNodeHashTbl; 7116 t_FmPcdCcNodeParams *p_IndxHashCcNodeParam, *p_ExactMatchCcNodeParam; 7117 t_FmPcdCcNode *p_CcNode; 7118 t_Handle h_MissStatsCounters = NULL; 7119 t_FmPcdCcKeyParams *p_HashKeyParams; 7120 int i; 7121 uint16_t numOfSets, numOfWays, countMask, onesCount = 0; 7122 bool statsEnForMiss = FALSE; 7123 t_Error err; 7124 7125 SANITY_CHECK_RETURN_VALUE(h_FmPcd, E_INVALID_HANDLE, NULL); 7126 SANITY_CHECK_RETURN_VALUE(p_Param, E_NULL_POINTER, NULL); 7127 7128 if (p_Param->maxNumOfKeys == 0) 7129 { 7130 REPORT_ERROR(MINOR, E_INVALID_VALUE, ("Max number of keys must be higher then 0")); 7131 return NULL; 7132 } 7133 7134 if (p_Param->hashResMask == 0) 7135 { 7136 REPORT_ERROR(MINOR, E_INVALID_VALUE, ("Hash result mask must differ from 0")); 7137 return NULL; 7138 } 7139 7140 /*Fix: QorIQ SDK / QSDK-2131*/ 7141 if (p_Param->ccNextEngineParamsForMiss.nextEngine == e_FM_PCD_INVALID) 7142 { 7143 REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("Next PCD Engine for on-miss entry is invalid. On-miss entry is always required. You can use e_FM_PCD_DONE.")); 7144 return NULL; 7145 } 7146 7147 #if (DPAA_VERSION >= 11) 7148 if (p_Param->statisticsMode == e_FM_PCD_CC_STATS_MODE_RMON) 7149 { 7150 REPORT_ERROR(MAJOR, E_INVALID_VALUE, 7151 ("RMON statistics mode is not supported for hash table")); 7152 return NULL; 7153 } 7154 #endif /* (DPAA_VERSION >= 11) */ 7155 7156 p_ExactMatchCcNodeParam = (t_FmPcdCcNodeParams*)XX_Malloc( 7157 sizeof(t_FmPcdCcNodeParams)); 7158 if (!p_ExactMatchCcNodeParam) 7159 { 7160 REPORT_ERROR(MAJOR, E_NO_MEMORY, ("p_ExactMatchCcNodeParam")); 7161 return NULL; 7162 } 7163 memset(p_ExactMatchCcNodeParam, 0, sizeof(t_FmPcdCcNodeParams)); 7164 7165 p_IndxHashCcNodeParam = (t_FmPcdCcNodeParams*)XX_Malloc( 7166 sizeof(t_FmPcdCcNodeParams)); 7167 if (!p_IndxHashCcNodeParam) 7168 { 7169 XX_Free(p_ExactMatchCcNodeParam); 7170 REPORT_ERROR(MAJOR, E_NO_MEMORY, ("p_IndxHashCcNodeParam")); 7171 return NULL; 7172 } 7173 memset(p_IndxHashCcNodeParam, 0, sizeof(t_FmPcdCcNodeParams)); 7174 7175 /* Calculate number of sets and number of ways of the hash table */ 7176 countMask = (uint16_t)(p_Param->hashResMask >> 4); 7177 while (countMask) 7178 { 7179 onesCount++; 7180 countMask = (uint16_t)(countMask >> 1); 7181 } 7182 7183 numOfSets = (uint16_t)(1 << onesCount); 7184 numOfWays = (uint16_t)DIV_CEIL(p_Param->maxNumOfKeys, numOfSets); 7185 7186 if (p_Param->maxNumOfKeys % numOfSets) 7187 DBG(INFO, ("'maxNumOfKeys' is not a multiple of hash number of ways, so number of ways will be rounded up")); 7188 7189 if ((p_Param->statisticsMode == e_FM_PCD_CC_STATS_MODE_FRAME) 7190 || (p_Param->statisticsMode == e_FM_PCD_CC_STATS_MODE_BYTE_AND_FRAME)) 7191 { 7192 /* Allocating a statistics counters table that will be used by all 7193 'miss' entries of the hash table */ 7194 h_MissStatsCounters = (t_Handle)FM_MURAM_AllocMem( 7195 FmPcdGetMuramHandle(h_FmPcd), 2 * FM_PCD_CC_STATS_COUNTER_SIZE, 7196 FM_PCD_CC_AD_TABLE_ALIGN); 7197 if (!h_MissStatsCounters) 7198 { 7199 REPORT_ERROR(MAJOR, E_NO_MEMORY, ("MURAM allocation for statistics table for hash miss")); 7200 XX_Free(p_IndxHashCcNodeParam); 7201 XX_Free(p_ExactMatchCcNodeParam); 7202 return NULL; 7203 } 7204 memset(h_MissStatsCounters, 0, (2 * FM_PCD_CC_STATS_COUNTER_SIZE)); 7205 7206 /* Always enable statistics for 'miss', so that a statistics AD will be 7207 initialized from the start. We'll store the requested 'statistics enable' 7208 value and it will be used when statistics are read by the user. */ 7209 statsEnForMiss = p_Param->ccNextEngineParamsForMiss.statisticsEn; 7210 p_Param->ccNextEngineParamsForMiss.statisticsEn = TRUE; 7211 } 7212 7213 /* Building exact-match node params, will be used to create the hash buckets */ 7214 p_ExactMatchCcNodeParam->extractCcParams.type = e_FM_PCD_EXTRACT_NON_HDR; 7215 7216 p_ExactMatchCcNodeParam->extractCcParams.extractNonHdr.src = 7217 e_FM_PCD_EXTRACT_FROM_KEY; 7218 p_ExactMatchCcNodeParam->extractCcParams.extractNonHdr.action = 7219 e_FM_PCD_ACTION_EXACT_MATCH; 7220 p_ExactMatchCcNodeParam->extractCcParams.extractNonHdr.offset = 0; 7221 p_ExactMatchCcNodeParam->extractCcParams.extractNonHdr.size = 7222 p_Param->matchKeySize; 7223 7224 p_ExactMatchCcNodeParam->keysParams.maxNumOfKeys = numOfWays; 7225 p_ExactMatchCcNodeParam->keysParams.maskSupport = FALSE; 7226 p_ExactMatchCcNodeParam->keysParams.statisticsMode = 7227 p_Param->statisticsMode; 7228 p_ExactMatchCcNodeParam->keysParams.numOfKeys = 0; 7229 p_ExactMatchCcNodeParam->keysParams.keySize = p_Param->matchKeySize; 7230 p_ExactMatchCcNodeParam->keysParams.ccNextEngineParamsForMiss = 7231 p_Param->ccNextEngineParamsForMiss; 7232 7233 p_HashKeyParams = p_IndxHashCcNodeParam->keysParams.keyParams; 7234 7235 for (i = 0; i < numOfSets; i++) 7236 { 7237 /* Each exact-match node will be marked as a 'bucket' and provided with 7238 a pointer to statistics counters, to be used for 'miss' entry 7239 statistics */ 7240 p_CcNode = (t_FmPcdCcNode *)XX_Malloc(sizeof(t_FmPcdCcNode)); 7241 if (!p_CcNode) 7242 break; 7243 memset(p_CcNode, 0, sizeof(t_FmPcdCcNode)); 7244 7245 p_CcNode->isHashBucket = TRUE; 7246 p_CcNode->h_MissStatsCounters = h_MissStatsCounters; 7247 7248 err = MatchTableSet(h_FmPcd, p_CcNode, p_ExactMatchCcNodeParam); 7249 if (err) 7250 break; 7251 7252 p_HashKeyParams[i].ccNextEngineParams.nextEngine = e_FM_PCD_CC; 7253 p_HashKeyParams[i].ccNextEngineParams.statisticsEn = FALSE; 7254 p_HashKeyParams[i].ccNextEngineParams.params.ccParams.h_CcNode = 7255 p_CcNode; 7256 } 7257 7258 if (i < numOfSets) 7259 { 7260 for (i = i - 1; i >= 0; i--) 7261 FM_PCD_MatchTableDelete( 7262 p_HashKeyParams[i].ccNextEngineParams.params.ccParams.h_CcNode); 7263 7264 FM_MURAM_FreeMem(FmPcdGetMuramHandle(h_FmPcd), h_MissStatsCounters); 7265 7266 REPORT_ERROR(MAJOR, E_NULL_POINTER, NO_MSG); 7267 XX_Free(p_IndxHashCcNodeParam); 7268 XX_Free(p_ExactMatchCcNodeParam); 7269 return NULL; 7270 } 7271 7272 /* Creating indexed-hash CC node */ 7273 p_IndxHashCcNodeParam->extractCcParams.type = e_FM_PCD_EXTRACT_NON_HDR; 7274 p_IndxHashCcNodeParam->extractCcParams.extractNonHdr.src = 7275 e_FM_PCD_EXTRACT_FROM_HASH; 7276 p_IndxHashCcNodeParam->extractCcParams.extractNonHdr.action = 7277 e_FM_PCD_ACTION_INDEXED_LOOKUP; 7278 p_IndxHashCcNodeParam->extractCcParams.extractNonHdr.icIndxMask = 7279 p_Param->hashResMask; 7280 p_IndxHashCcNodeParam->extractCcParams.extractNonHdr.offset = 7281 p_Param->hashShift; 7282 p_IndxHashCcNodeParam->extractCcParams.extractNonHdr.size = 2; 7283 7284 p_IndxHashCcNodeParam->keysParams.maxNumOfKeys = numOfSets; 7285 p_IndxHashCcNodeParam->keysParams.maskSupport = FALSE; 7286 p_IndxHashCcNodeParam->keysParams.statisticsMode = 7287 e_FM_PCD_CC_STATS_MODE_NONE; 7288 /* Number of keys of this node is number of sets of the hash */ 7289 p_IndxHashCcNodeParam->keysParams.numOfKeys = numOfSets; 7290 p_IndxHashCcNodeParam->keysParams.keySize = 2; 7291 7292 p_CcNodeHashTbl = FM_PCD_MatchTableSet(h_FmPcd, p_IndxHashCcNodeParam); 7293 7294 if (p_CcNodeHashTbl) 7295 { 7296 p_CcNodeHashTbl->kgHashShift = p_Param->kgHashShift; 7297 7298 /* Storing the allocated counters for buckets 'miss' in the hash table 7299 and if statistics for miss were enabled. */ 7300 p_CcNodeHashTbl->h_MissStatsCounters = h_MissStatsCounters; 7301 p_CcNodeHashTbl->statsEnForMiss = statsEnForMiss; 7302 } 7303 7304 XX_Free(p_IndxHashCcNodeParam); 7305 XX_Free(p_ExactMatchCcNodeParam); 7306 7307 return p_CcNodeHashTbl; 7308 } 7309 7310 t_Error FM_PCD_HashTableDelete(t_Handle h_HashTbl) 7311 { 7312 t_FmPcdCcNode *p_HashTbl = (t_FmPcdCcNode *)h_HashTbl; 7313 t_Handle h_FmPcd; 7314 t_Handle *p_HashBuckets, h_MissStatsCounters; 7315 uint16_t i, numOfBuckets; 7316 t_Error err; 7317 7318 SANITY_CHECK_RETURN_ERROR(p_HashTbl, E_INVALID_HANDLE); 7319 7320 /* Store all hash buckets before the hash is freed */ 7321 numOfBuckets = p_HashTbl->numOfKeys; 7322 7323 p_HashBuckets = (t_Handle *)XX_Malloc(numOfBuckets * sizeof(t_Handle)); 7324 if (!p_HashBuckets) 7325 RETURN_ERROR(MAJOR, E_NO_MEMORY, NO_MSG); 7326 7327 for (i = 0; i < numOfBuckets; i++) 7328 p_HashBuckets[i] = 7329 p_HashTbl->keyAndNextEngineParams[i].nextEngineParams.params.ccParams.h_CcNode; 7330 7331 h_FmPcd = p_HashTbl->h_FmPcd; 7332 h_MissStatsCounters = p_HashTbl->h_MissStatsCounters; 7333 7334 /* Free the hash */ 7335 err = FM_PCD_MatchTableDelete(p_HashTbl); 7336 7337 /* Free each hash bucket */ 7338 for (i = 0; i < numOfBuckets; i++) 7339 err |= FM_PCD_MatchTableDelete(p_HashBuckets[i]); 7340 7341 XX_Free(p_HashBuckets); 7342 7343 /* Free statistics counters for 'miss', if these were allocated */ 7344 if (h_MissStatsCounters) 7345 FM_MURAM_FreeMem(FmPcdGetMuramHandle(h_FmPcd), h_MissStatsCounters); 7346 7347 if (err) 7348 RETURN_ERROR(MAJOR, err, NO_MSG); 7349 7350 return E_OK; 7351 } 7352 7353 t_Error FM_PCD_HashTableAddKey(t_Handle h_HashTbl, uint8_t keySize, 7354 t_FmPcdCcKeyParams *p_KeyParams) 7355 { 7356 t_FmPcdCcNode *p_HashTbl = (t_FmPcdCcNode *)h_HashTbl; 7357 t_Handle h_HashBucket; 7358 uint8_t bucketIndex; 7359 uint16_t lastIndex; 7360 t_Error err; 7361 7362 SANITY_CHECK_RETURN_ERROR(p_HashTbl, E_INVALID_HANDLE); 7363 SANITY_CHECK_RETURN_ERROR(p_KeyParams, E_NULL_POINTER); 7364 SANITY_CHECK_RETURN_ERROR(p_KeyParams->p_Key, E_NULL_POINTER); 7365 7366 if (p_KeyParams->p_Mask) 7367 RETURN_ERROR(MAJOR, E_INVALID_VALUE, 7368 ("Keys masks not supported for hash table")); 7369 7370 err = FM_PCD_MatchTableGetIndexedHashBucket(p_HashTbl, keySize, 7371 p_KeyParams->p_Key, 7372 p_HashTbl->kgHashShift, 7373 &h_HashBucket, &bucketIndex, 7374 &lastIndex); 7375 if (err) 7376 RETURN_ERROR(MAJOR, err, NO_MSG); 7377 7378 return FM_PCD_MatchTableAddKey(h_HashBucket, FM_PCD_LAST_KEY_INDEX, keySize, 7379 p_KeyParams); 7380 } 7381 7382 t_Error FM_PCD_HashTableRemoveKey(t_Handle h_HashTbl, uint8_t keySize, 7383 uint8_t *p_Key) 7384 { 7385 t_FmPcdCcNode *p_HashTbl = (t_FmPcdCcNode *)h_HashTbl; 7386 t_Handle h_HashBucket; 7387 uint8_t bucketIndex; 7388 uint16_t lastIndex; 7389 t_Error err; 7390 7391 SANITY_CHECK_RETURN_ERROR(p_HashTbl, E_INVALID_HANDLE); 7392 SANITY_CHECK_RETURN_ERROR(p_Key, E_NULL_POINTER); 7393 7394 err = FM_PCD_MatchTableGetIndexedHashBucket(p_HashTbl, keySize, p_Key, 7395 p_HashTbl->kgHashShift, 7396 &h_HashBucket, &bucketIndex, 7397 &lastIndex); 7398 if (err) 7399 RETURN_ERROR(MAJOR, err, NO_MSG); 7400 7401 return FM_PCD_MatchTableFindNRemoveKey(h_HashBucket, keySize, p_Key, NULL); 7402 } 7403 7404 t_Error FM_PCD_HashTableModifyNextEngine( 7405 t_Handle h_HashTbl, uint8_t keySize, uint8_t *p_Key, 7406 t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams) 7407 { 7408 t_FmPcdCcNode *p_HashTbl = (t_FmPcdCcNode *)h_HashTbl; 7409 t_Handle h_HashBucket; 7410 uint8_t bucketIndex; 7411 uint16_t lastIndex; 7412 t_Error err; 7413 7414 SANITY_CHECK_RETURN_ERROR(p_HashTbl, E_INVALID_HANDLE); 7415 SANITY_CHECK_RETURN_ERROR(p_Key, E_NULL_POINTER); 7416 SANITY_CHECK_RETURN_ERROR(p_FmPcdCcNextEngineParams, E_NULL_POINTER); 7417 7418 err = FM_PCD_MatchTableGetIndexedHashBucket(p_HashTbl, keySize, p_Key, 7419 p_HashTbl->kgHashShift, 7420 &h_HashBucket, &bucketIndex, 7421 &lastIndex); 7422 if (err) 7423 RETURN_ERROR(MAJOR, err, NO_MSG); 7424 7425 return FM_PCD_MatchTableFindNModifyNextEngine(h_HashBucket, keySize, p_Key, 7426 NULL, 7427 p_FmPcdCcNextEngineParams); 7428 } 7429 7430 t_Error FM_PCD_HashTableModifyMissNextEngine( 7431 t_Handle h_HashTbl, 7432 t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams) 7433 { 7434 t_FmPcdCcNode *p_HashTbl = (t_FmPcdCcNode *)h_HashTbl; 7435 t_Handle h_HashBucket; 7436 uint8_t i; 7437 bool nullifyMissStats = FALSE; 7438 t_Error err; 7439 7440 SANITY_CHECK_RETURN_ERROR(h_HashTbl, E_INVALID_HANDLE); 7441 SANITY_CHECK_RETURN_ERROR(p_FmPcdCcNextEngineParams, E_NULL_POINTER); 7442 7443 if ((!p_HashTbl->h_MissStatsCounters) 7444 && (p_FmPcdCcNextEngineParams->statisticsEn)) 7445 RETURN_ERROR( 7446 MAJOR, 7447 E_CONFLICT, 7448 ("Statistics are requested for a key, but statistics mode was set" 7449 "to 'NONE' upon initialization")); 7450 7451 if (p_HashTbl->h_MissStatsCounters) 7452 { 7453 if ((!p_HashTbl->statsEnForMiss) 7454 && (p_FmPcdCcNextEngineParams->statisticsEn)) 7455 nullifyMissStats = TRUE; 7456 7457 if ((p_HashTbl->statsEnForMiss) 7458 && (!p_FmPcdCcNextEngineParams->statisticsEn)) 7459 { 7460 p_HashTbl->statsEnForMiss = FALSE; 7461 p_FmPcdCcNextEngineParams->statisticsEn = TRUE; 7462 } 7463 } 7464 7465 for (i = 0; i < p_HashTbl->numOfKeys; i++) 7466 { 7467 h_HashBucket = 7468 p_HashTbl->keyAndNextEngineParams[i].nextEngineParams.params.ccParams.h_CcNode; 7469 7470 err = FM_PCD_MatchTableModifyMissNextEngine(h_HashBucket, 7471 p_FmPcdCcNextEngineParams); 7472 if (err) 7473 RETURN_ERROR(MAJOR, err, NO_MSG); 7474 } 7475 7476 if (nullifyMissStats) 7477 { 7478 memset(p_HashTbl->h_MissStatsCounters, 0, 7479 (2 * FM_PCD_CC_STATS_COUNTER_SIZE)); 7480 memset(p_HashTbl->h_MissStatsCounters, 0, 7481 (2 * FM_PCD_CC_STATS_COUNTER_SIZE)); 7482 p_HashTbl->statsEnForMiss = TRUE; 7483 } 7484 7485 return E_OK; 7486 } 7487 7488 7489 t_Error FM_PCD_HashTableGetMissNextEngine( 7490 t_Handle h_HashTbl, 7491 t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams) 7492 { 7493 t_FmPcdCcNode *p_HashTbl = (t_FmPcdCcNode *)h_HashTbl; 7494 t_FmPcdCcNode *p_HashBucket; 7495 7496 SANITY_CHECK_RETURN_ERROR(p_HashTbl, E_INVALID_HANDLE); 7497 7498 /* Miss next engine of each bucket was initialized with the next engine of the hash table */ 7499 p_HashBucket = 7500 p_HashTbl->keyAndNextEngineParams[0].nextEngineParams.params.ccParams.h_CcNode; 7501 7502 memcpy(p_FmPcdCcNextEngineParams, 7503 &p_HashBucket->keyAndNextEngineParams[p_HashBucket->numOfKeys].nextEngineParams, 7504 sizeof(t_FmPcdCcNextEngineParams)); 7505 7506 return E_OK; 7507 } 7508 7509 t_Error FM_PCD_HashTableFindNGetKeyStatistics( 7510 t_Handle h_HashTbl, uint8_t keySize, uint8_t *p_Key, 7511 t_FmPcdCcKeyStatistics *p_KeyStatistics) 7512 { 7513 t_FmPcdCcNode *p_HashTbl = (t_FmPcdCcNode *)h_HashTbl; 7514 t_Handle h_HashBucket; 7515 uint8_t bucketIndex; 7516 uint16_t lastIndex; 7517 t_Error err; 7518 7519 SANITY_CHECK_RETURN_ERROR(p_HashTbl, E_INVALID_HANDLE); 7520 SANITY_CHECK_RETURN_ERROR(p_Key, E_NULL_POINTER); 7521 SANITY_CHECK_RETURN_ERROR(p_KeyStatistics, E_NULL_POINTER); 7522 7523 err = FM_PCD_MatchTableGetIndexedHashBucket(p_HashTbl, keySize, p_Key, 7524 p_HashTbl->kgHashShift, 7525 &h_HashBucket, &bucketIndex, 7526 &lastIndex); 7527 if (err) 7528 RETURN_ERROR(MAJOR, err, NO_MSG); 7529 7530 return FM_PCD_MatchTableFindNGetKeyStatistics(h_HashBucket, keySize, p_Key, 7531 NULL, p_KeyStatistics); 7532 } 7533 7534 t_Error FM_PCD_HashTableGetMissStatistics( 7535 t_Handle h_HashTbl, t_FmPcdCcKeyStatistics *p_MissStatistics) 7536 { 7537 t_FmPcdCcNode *p_HashTbl = (t_FmPcdCcNode *)h_HashTbl; 7538 t_Handle h_HashBucket; 7539 7540 SANITY_CHECK_RETURN_ERROR(p_HashTbl, E_INVALID_HANDLE); 7541 SANITY_CHECK_RETURN_ERROR(p_MissStatistics, E_NULL_POINTER); 7542 7543 if (!p_HashTbl->statsEnForMiss) 7544 RETURN_ERROR(MAJOR, E_INVALID_STATE, 7545 ("Statistics were not enabled for miss")); 7546 7547 h_HashBucket = 7548 p_HashTbl->keyAndNextEngineParams[0].nextEngineParams.params.ccParams.h_CcNode; 7549 7550 return FM_PCD_MatchTableGetMissStatistics(h_HashBucket, p_MissStatistics); 7551 } 7552