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