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
CcRootTryLock(t_Handle h_FmPcdCcTree)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
CcRootReleaseLock(t_Handle h_FmPcdCcTree)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
UpdateNodeOwner(t_FmPcdCcNode * p_CcNode,bool add)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
DequeueStatsObj(t_List * p_List)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
EnqueueStatsObj(t_List * p_List,t_FmPcdStatsObj * p_StatsObj)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
FreeStatObjects(t_List * p_List,t_Handle h_FmMuram)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
GetStatsObj(t_FmPcdCcNode * p_CcNode)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
PutStatsObj(t_FmPcdCcNode * p_CcNode,t_FmPcdStatsObj * p_StatsObj)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
SetStatsCounters(t_AdOfTypeStats * p_StatsAd,uint32_t statsCountersAddr)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
UpdateStatsAd(t_FmPcdCcStatsParams * p_FmPcdCcStatsParams,t_Handle h_Ad,uint64_t physicalMuramBase)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
FillAdOfTypeContLookup(t_Handle h_Ad,t_FmPcdCcStatsParams * p_FmPcdCcStatsParams,t_Handle h_FmPcd,t_Handle p_CcNode,t_Handle h_Manip,t_Handle h_FrmReplic)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
AllocAndFillAdForContLookupManip(t_Handle h_CcNode)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
SetRequiredAction1(t_Handle h_FmPcd,uint32_t requiredAction,t_FmPcdCcKeyAndNextEngineParams * p_CcKeyAndNextEngineParamsTmp,t_Handle h_AdTmp,uint16_t numOfEntries,t_Handle h_Tree)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
SetRequiredAction(t_Handle h_FmPcd,uint32_t requiredAction,t_FmPcdCcKeyAndNextEngineParams * p_CcKeyAndNextEngineParamsTmp,t_Handle h_AdTmp,uint16_t numOfEntries,t_Handle h_Tree)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
ReleaseModifiedDataStructure(t_Handle h_FmPcd,t_List * h_FmPcdOldPointersLst,t_List * h_FmPcdNewPointersLst,t_FmPcdModifyCcKeyAdditionalParams * p_AdditionalParams,bool useShadowStructs)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
BuildNewAd(t_Handle h_Ad,t_FmPcdModifyCcKeyAdditionalParams * p_FmPcdModifyCcKeyAdditionalParams,t_FmPcdCcNode * p_CcNode,t_FmPcdCcNextEngineParams * p_FmPcdCcNextEngineParams)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 NULL;
899 }
900
DynamicChangeHc(t_Handle h_FmPcd,t_List * h_OldPointersLst,t_List * h_NewPointersLst,t_FmPcdModifyCcKeyAdditionalParams * p_AdditionalParams,bool useShadowStructs)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
DoDynamicChange(t_Handle h_FmPcd,t_List * h_OldPointersLst,t_List * h_NewPointersLst,t_FmPcdModifyCcKeyAdditionalParams * p_AdditionalParams,bool useShadowStructs)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
IsCapwapApplSpecific(t_Handle h_Node)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
CcUpdateParam(t_Handle h_FmPcd,t_Handle h_PcdParams,t_Handle h_FmPort,t_FmPcdCcKeyAndNextEngineParams * p_CcKeyAndNextEngineParams,uint16_t numOfEntries,t_Handle h_Ad,bool validate,uint16_t level,t_Handle h_FmTree,bool modify)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
IcDefineCode(t_FmPcdCcNodeParams * p_CcNodeParam)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
DequeueAdditionalInfoFromRelevantLst(t_List * p_List)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
ReleaseLst(t_List * p_List)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
DeleteNode(t_FmPcdCcNode * p_CcNode)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
DeleteTree(t_FmPcdCcTree * p_FmPcdTree,t_FmPcd * p_FmPcd)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
GetCcExtractKeySize(uint8_t parseCodeRealSize,uint8_t * parseCodeCcSize)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
GetSizeHeaderField(e_NetHeaderType hdr,t_FmPcdFields field,uint8_t * parseCodeRealSize)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
ValidateNextEngineParams(t_Handle h_FmPcd,t_FmPcdCcNextEngineParams * p_FmPcdCcNextEngineParams,e_FmPcdCcStatsMode statsMode)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
GetGenParseCode(e_FmPcdExtractFrom src,uint32_t offset,bool glblMask,uint8_t * parseArrayOffset,bool fromIc,ccPrivateInfo_t icCode)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
GetFullFieldParseCode(e_NetHeaderType hdr,e_FmPcdHdrIndex index,t_FmPcdFields field)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
GetPrParseCode(e_NetHeaderType hdr,e_FmPcdHdrIndex hdrIndex,uint32_t offset,bool glblMask,uint8_t * parseArrayOffset)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
GetFieldParseCode(e_NetHeaderType hdr,t_FmPcdFields field,uint32_t offset,uint8_t * parseArrayOffset,e_FmPcdHdrIndex hdrIndex)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
FillAdOfTypeResult(t_Handle h_Ad,t_FmPcdCcStatsParams * p_FmPcdCcStatsParams,t_FmPcd * p_FmPcd,t_FmPcdCcNextEngineParams * p_CcNextEngineParams)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
CcUpdateParams(t_Handle h_FmPcd,t_Handle h_PcdParams,t_Handle h_FmPort,t_Handle h_FmTree,bool validate)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
ReleaseNewNodeCommonPart(t_FmPcdModifyCcKeyAdditionalParams * p_AdditionalInfo)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
UpdateGblMask(t_FmPcdCcNode * p_CcNode,uint8_t keySize,uint8_t * p_Mask)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
GetNewAd(t_Handle h_FmPcdCcNodeOrTree,bool isTree)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
BuildNewNodeCommonPart(t_FmPcdCcNode * p_CcNode,int * size,t_FmPcdModifyCcKeyAdditionalParams * p_AdditionalInfo)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
BuildNewNodeAddOrMdfyKeyAndNextEngine(t_Handle h_FmPcd,t_FmPcdCcNode * p_CcNode,uint16_t keyIndex,t_FmPcdCcKeyParams * p_KeyParams,t_FmPcdModifyCcKeyAdditionalParams * p_AdditionalInfo,bool add)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
BuildNewNodeRemoveKey(t_FmPcdCcNode * p_CcNode,uint16_t keyIndex,t_FmPcdModifyCcKeyAdditionalParams * p_AdditionalInfo)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
BuildNewNodeModifyKey(t_FmPcdCcNode * p_CcNode,uint16_t keyIndex,uint8_t * p_Key,uint8_t * p_Mask,t_FmPcdModifyCcKeyAdditionalParams * p_AdditionalInfo)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
BuildNewNodeModifyNextEngine(t_Handle h_FmPcd,t_Handle h_FmPcdCcNodeOrTree,uint16_t keyIndex,t_FmPcdCcNextEngineParams * p_CcNextEngineParams,t_List * h_OldLst,t_List * h_NewLst,t_FmPcdModifyCcKeyAdditionalParams * p_AdditionalInfo)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
UpdateAdPtrOfNodesWhichPointsOnCrntMdfNode(t_FmPcdCcNode * p_CrntMdfNode,t_List * h_OldLst,t_FmPcdCcNextEngineParams ** p_NextEngineParams)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
UpdateAdPtrOfTreesWhichPointsOnCrntMdfNode(t_FmPcdCcNode * p_CrntMdfNode,t_List * h_OldLst,t_FmPcdCcNextEngineParams ** p_NextEngineParams)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
ModifyNodeCommonPart(t_Handle h_FmPcdCcNodeOrTree,uint16_t keyIndex,e_ModifyState modifyState,bool ttlCheck,bool hashCheck,bool tree)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
UpdatePtrWhichPointOnCrntMdfNode(t_FmPcdCcNode * p_CcNode,t_FmPcdModifyCcKeyAdditionalParams * p_FmPcdModifyCcKeyAdditionalParams,t_List * h_OldLst,t_List * h_NewLst)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
UpdateCcRootOwner(t_FmPcdCcTree * p_FmPcdCcTree,bool add)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
CheckAndSetManipParamsWithCcNodeParams(t_FmPcdCcNode * p_CcNode)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 }
ValidateAndCalcStatsParams(t_FmPcdCcNode * p_CcNode,t_FmPcdCcNodeParams * p_CcNodeParam,uint32_t * p_NumOfRanges,uint32_t * p_CountersArraySize)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
CheckParams(t_Handle h_FmPcd,t_FmPcdCcNodeParams * p_CcNodeParam,t_FmPcdCcNode * p_CcNode,bool * isKeyTblAlloc)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
Ipv4TtlOrIpv6HopLimitCheckParams(t_Handle h_FmPcd,t_FmPcdCcNodeParams * p_CcNodeParam,t_FmPcdCcNode * p_CcNode,bool * isKeyTblAlloc)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
IcHashIndexedCheckParams(t_Handle h_FmPcd,t_FmPcdCcNodeParams * p_CcNodeParam,t_FmPcdCcNode * p_CcNode,bool * isKeyTblAlloc)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
ModifyNextEngineParamNode(t_Handle h_FmPcd,t_Handle h_FmPcdCcNode,uint16_t keyIndex,t_FmPcdCcNextEngineParams * p_FmPcdCcNextEngineParams)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
FindKeyIndex(t_Handle h_CcNode,uint8_t keySize,uint8_t * p_Key,uint8_t * p_Mask,uint16_t * p_KeyIndex)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
CalcAndUpdateCcShadow(t_FmPcdCcNode * p_CcNode,bool isKeyTblAlloc,uint32_t * p_MatchTableSize,uint32_t * p_AdTableSize)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
AllocStatsObjs(t_FmPcdCcNode * p_CcNode)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
MatchTableGetKeyStatistics(t_FmPcdCcNode * p_CcNode,uint16_t keyIndex,t_FmPcdCcKeyStatistics * p_KeyStatistics)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
MatchTableSet(t_Handle h_FmPcd,t_FmPcdCcNode * p_CcNode,t_FmPcdCcNodeParams * p_CcNodeParam)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
FindNodeInfoInReleventLst(t_List * p_List,t_Handle h_Info,t_Handle h_Spinlock)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
EnqueueNodeInfoToRelevantLst(t_List * p_List,t_CcNodeInformation * p_CcInfo,t_Handle h_Spinlock)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
DequeueNodeInfoFromRelevantLst(t_List * p_List,t_Handle h_Info,t_Handle h_Spinlock)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
NextStepAd(t_Handle h_Ad,t_FmPcdCcStatsParams * p_FmPcdCcStatsParams,t_FmPcdCcNextEngineParams * p_FmPcdCcNextEngineParams,t_FmPcd * p_FmPcd)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
FmPcdCcTreeAddIPR(t_Handle h_FmPcd,t_Handle h_FmTree,t_Handle h_NetEnv,t_Handle h_IpReassemblyManip,bool createSchemes)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
FmPcdCcTreeAddCPR(t_Handle h_FmPcd,t_Handle h_FmTree,t_Handle h_NetEnv,t_Handle h_ReassemblyManip,bool createSchemes)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
FmPcdCcTreeGetSavedManipParams(t_Handle h_FmTree)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
FmPcdCcTreeSetSavedManipParams(t_Handle h_FmTree,t_Handle h_SavedManipParams)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
FmPcdCcGetParseCode(t_Handle h_CcNode)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
FmPcdCcGetOffset(t_Handle h_CcNode)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
FmPcdCcGetNumOfKeys(t_Handle h_CcNode)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
FmPcdCcModifyNextEngineParamTree(t_Handle h_FmPcd,t_Handle h_FmPcdCcTree,uint8_t grpId,uint8_t index,t_FmPcdCcNextEngineParams * p_FmPcdCcNextEngineParams)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
FmPcdCcRemoveKey(t_Handle h_FmPcd,t_Handle h_FmPcdCcNode,uint16_t keyIndex)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
FmPcdCcModifyKey(t_Handle h_FmPcd,t_Handle h_FmPcdCcNode,uint16_t keyIndex,uint8_t keySize,uint8_t * p_Key,uint8_t * p_Mask)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
FmPcdCcModifyMissNextEngineParamNode(t_Handle h_FmPcd,t_Handle h_FmPcdCcNode,t_FmPcdCcNextEngineParams * p_FmPcdCcNextEngineParams)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
FmPcdCcAddKey(t_Handle h_FmPcd,t_Handle h_FmPcdCcNode,uint16_t keyIndex,uint8_t keySize,t_FmPcdCcKeyParams * p_FmPcdCcKeyParams)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
FmPcdCcModifyKeyAndNextEngine(t_Handle h_FmPcd,t_Handle h_FmPcdCcNode,uint16_t keyIndex,uint8_t keySize,t_FmPcdCcKeyParams * p_FmPcdCcKeyParams)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
FmPcdCcGetNodeAddrOffsetFromNodeInfo(t_Handle h_FmPcd,t_Handle h_Pointer)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
FmPcdCcGetGrpParams(t_Handle h_FmPcdCcTree,uint8_t grpId,uint32_t * p_GrpBits,uint8_t * p_GrpBase)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
FmPcdCcBindTree(t_Handle h_FmPcd,t_Handle h_PcdParams,t_Handle h_FmPcdCcTree,uint32_t * p_Offset,t_Handle h_FmPort)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
FmPcdCcUnbindTree(t_Handle h_FmPcd,t_Handle h_FmPcdCcTree)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
FmPcdCcNodeTreeTryLock(t_Handle h_FmPcd,t_Handle h_FmPcdCcNode,t_List * p_List)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
FmPcdCcNodeTreeReleaseLock(t_Handle h_FmPcd,t_List * p_List)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
FmPcdUpdateCcShadow(t_FmPcd * p_FmPcd,uint32_t size,uint32_t align)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)
FmPcdCcGetAdTablesThatPointOnReplicGroup(t_Handle h_Node,t_Handle h_ReplicGroup,t_List * p_AdTables,uint32_t * p_NumOfAdTables)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
FM_PCD_CcRootBuild(t_Handle h_FmPcd,t_FmPcdCcTreeParams * p_PcdGroupsParam)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
FM_PCD_CcRootDelete(t_Handle h_CcTree)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
FM_PCD_CcRootModifyNextEngine(t_Handle h_CcTree,uint8_t grpId,uint8_t index,t_FmPcdCcNextEngineParams * p_FmPcdCcNextEngineParams)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
FM_PCD_MatchTableSet(t_Handle h_FmPcd,t_FmPcdCcNodeParams * p_CcNodeParam)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
FM_PCD_MatchTableDelete(t_Handle h_CcNode)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
FM_PCD_MatchTableAddKey(t_Handle h_CcNode,uint16_t keyIndex,uint8_t keySize,t_FmPcdCcKeyParams * p_KeyParams)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
FM_PCD_MatchTableRemoveKey(t_Handle h_CcNode,uint16_t keyIndex)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
FM_PCD_MatchTableModifyKey(t_Handle h_CcNode,uint16_t keyIndex,uint8_t keySize,uint8_t * p_Key,uint8_t * p_Mask)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
FM_PCD_MatchTableModifyNextEngine(t_Handle h_CcNode,uint16_t keyIndex,t_FmPcdCcNextEngineParams * p_FmPcdCcNextEngineParams)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
FM_PCD_MatchTableModifyMissNextEngine(t_Handle h_CcNode,t_FmPcdCcNextEngineParams * p_FmPcdCcNextEngineParams)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
FM_PCD_MatchTableModifyKeyAndNextEngine(t_Handle h_CcNode,uint16_t keyIndex,uint8_t keySize,t_FmPcdCcKeyParams * p_KeyParams)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
FM_PCD_MatchTableFindNRemoveKey(t_Handle h_CcNode,uint8_t keySize,uint8_t * p_Key,uint8_t * p_Mask)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
FM_PCD_MatchTableFindNModifyNextEngine(t_Handle h_CcNode,uint8_t keySize,uint8_t * p_Key,uint8_t * p_Mask,t_FmPcdCcNextEngineParams * p_FmPcdCcNextEngineParams)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
FM_PCD_MatchTableFindNModifyKeyAndNextEngine(t_Handle h_CcNode,uint8_t keySize,uint8_t * p_Key,uint8_t * p_Mask,t_FmPcdCcKeyParams * p_KeyParams)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
FM_PCD_MatchTableFindNModifyKey(t_Handle h_CcNode,uint8_t keySize,uint8_t * p_Key,uint8_t * p_Mask,uint8_t * p_NewKey,uint8_t * p_NewMask)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
FM_PCD_MatchTableGetNextEngine(t_Handle h_CcNode,uint16_t keyIndex,t_FmPcdCcNextEngineParams * p_FmPcdCcNextEngineParams)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
FM_PCD_MatchTableGetKeyCounter(t_Handle h_CcNode,uint16_t keyIndex)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
FM_PCD_MatchTableGetKeyStatistics(t_Handle h_CcNode,uint16_t keyIndex,t_FmPcdCcKeyStatistics * p_KeyStatistics)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
FM_PCD_MatchTableGetMissStatistics(t_Handle h_CcNode,t_FmPcdCcKeyStatistics * p_MissStatistics)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
FM_PCD_MatchTableFindNGetKeyStatistics(t_Handle h_CcNode,uint8_t keySize,uint8_t * p_Key,uint8_t * p_Mask,t_FmPcdCcKeyStatistics * p_KeyStatistics)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
FM_PCD_MatchTableGetIndexedHashBucket(t_Handle h_CcNode,uint8_t keySize,uint8_t * p_Key,uint8_t hashShift,t_Handle * p_CcNodeBucketHandle,uint8_t * p_BucketIndex,uint16_t * p_LastIndex)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
FM_PCD_HashTableSet(t_Handle h_FmPcd,t_FmPcdHashTableParams * p_Param)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
FM_PCD_HashTableDelete(t_Handle h_HashTbl)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
FM_PCD_HashTableAddKey(t_Handle h_HashTbl,uint8_t keySize,t_FmPcdCcKeyParams * p_KeyParams)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
FM_PCD_HashTableRemoveKey(t_Handle h_HashTbl,uint8_t keySize,uint8_t * p_Key)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
FM_PCD_HashTableModifyNextEngine(t_Handle h_HashTbl,uint8_t keySize,uint8_t * p_Key,t_FmPcdCcNextEngineParams * p_FmPcdCcNextEngineParams)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
FM_PCD_HashTableModifyMissNextEngine(t_Handle h_HashTbl,t_FmPcdCcNextEngineParams * p_FmPcdCcNextEngineParams)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
FM_PCD_HashTableGetMissNextEngine(t_Handle h_HashTbl,t_FmPcdCcNextEngineParams * p_FmPcdCcNextEngineParams)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
FM_PCD_HashTableFindNGetKeyStatistics(t_Handle h_HashTbl,uint8_t keySize,uint8_t * p_Key,t_FmPcdCcKeyStatistics * p_KeyStatistics)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
FM_PCD_HashTableGetMissStatistics(t_Handle h_HashTbl,t_FmPcdCcKeyStatistics * p_MissStatistics)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