xref: /freebsd/sys/contrib/ncsw/Peripherals/FM/Pcd/fm_pcd.c (revision 7fdf597e96a02165cfe22ff357b857d5fa15ed8a)
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_pcd.c
36 
37  @Description   FM PCD ...
38 *//***************************************************************************/
39 #include "std_ext.h"
40 #include "error_ext.h"
41 #include "string_ext.h"
42 #include "xx_ext.h"
43 #include "sprint_ext.h"
44 #include "debug_ext.h"
45 #include "net_ext.h"
46 #include "fm_ext.h"
47 #include "fm_pcd_ext.h"
48 
49 #include "fm_common.h"
50 #include "fm_pcd.h"
51 #include "fm_pcd_ipc.h"
52 #include "fm_hc.h"
53 #include "fm_muram_ext.h"
54 
55 
56 /****************************************/
57 /*       static functions               */
58 /****************************************/
59 
60 static t_Error CheckFmPcdParameters(t_FmPcd *p_FmPcd)
61 {
62     if (!p_FmPcd->h_Fm)
63          RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("h_Fm has to be initialized"));
64 
65     if (p_FmPcd->guestId == NCSW_MASTER_ID)
66     {
67         if (p_FmPcd->p_FmPcdKg && !p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs)
68             RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Something WRONG"));
69 
70         if (p_FmPcd->p_FmPcdPlcr && !p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs)
71             RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Something WRONG"));
72 
73         if (!p_FmPcd->f_Exception)
74             RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("f_FmPcdExceptions has to be initialized"));
75 
76         if ((!p_FmPcd->f_FmPcdIndexedException) && (p_FmPcd->p_FmPcdPlcr || p_FmPcd->p_FmPcdKg))
77             RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("f_FmPcdIndexedException has to be initialized"));
78 
79         if (p_FmPcd->p_FmPcdDriverParam->prsMaxParseCycleLimit > PRS_MAX_CYCLE_LIMIT)
80             RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("prsMaxParseCycleLimit has to be less than 8191"));
81     }
82 
83     return E_OK;
84 }
85 
86 static volatile bool blockingFlag = FALSE;
87 static void IpcMsgCompletionCB(t_Handle   h_FmPcd,
88                                uint8_t    *p_Msg,
89                                uint8_t    *p_Reply,
90                                uint32_t   replyLength,
91                                t_Error    status)
92 {
93     UNUSED(h_FmPcd);UNUSED(p_Msg);UNUSED(p_Reply);UNUSED(replyLength);UNUSED(status);
94     blockingFlag = FALSE;
95 }
96 
97 static t_Error IpcMsgHandlerCB(t_Handle  h_FmPcd,
98                                uint8_t   *p_Msg,
99                                uint32_t  msgLength,
100                                uint8_t   *p_Reply,
101                                uint32_t  *p_ReplyLength)
102 {
103     t_FmPcd             *p_FmPcd = (t_FmPcd*)h_FmPcd;
104     t_Error             err = E_OK;
105     t_FmPcdIpcMsg       *p_IpcMsg   = (t_FmPcdIpcMsg*)p_Msg;
106     t_FmPcdIpcReply     *p_IpcReply = (t_FmPcdIpcReply*)p_Reply;
107 
108     SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
109     SANITY_CHECK_RETURN_ERROR((msgLength >= sizeof(uint32_t)), E_INVALID_VALUE);
110 
111 #ifdef DISABLE_SANITY_CHECKS
112     UNUSED(msgLength);
113 #endif /* DISABLE_SANITY_CHECKS */
114 
115     ASSERT_COND(p_Msg);
116 
117     memset(p_IpcReply, 0, (sizeof(uint8_t) * FM_PCD_MAX_REPLY_SIZE));
118     *p_ReplyLength = 0;
119 
120     switch (p_IpcMsg->msgId)
121     {
122         case (FM_PCD_MASTER_IS_ALIVE):
123             *(uint8_t*)(p_IpcReply->replyBody) = 1;
124             p_IpcReply->error = E_OK;
125             *p_ReplyLength = sizeof(uint32_t) + sizeof(uint8_t);
126             break;
127         case (FM_PCD_MASTER_IS_ENABLED):
128             /* count partitions registrations */
129             if (p_FmPcd->enabled)
130                 p_FmPcd->numOfEnabledGuestPartitionsPcds++;
131             *(uint8_t*)(p_IpcReply->replyBody)  = (uint8_t)p_FmPcd->enabled;
132             p_IpcReply->error = E_OK;
133             *p_ReplyLength = sizeof(uint32_t) + sizeof(uint8_t);
134             break;
135         case (FM_PCD_GUEST_DISABLE):
136             if (p_FmPcd->numOfEnabledGuestPartitionsPcds)
137             {
138                 p_FmPcd->numOfEnabledGuestPartitionsPcds--;
139                 p_IpcReply->error = E_OK;
140             }
141             else
142             {
143                 REPORT_ERROR(MINOR, E_INVALID_STATE,("Trying to disable an unregistered partition"));
144                 p_IpcReply->error = E_INVALID_STATE;
145             }
146             *p_ReplyLength = sizeof(uint32_t);
147             break;
148         case (FM_PCD_GET_COUNTER):
149         {
150             e_FmPcdCounters inCounter;
151             uint32_t        outCounter;
152 
153             memcpy((uint8_t*)&inCounter, p_IpcMsg->msgBody, sizeof(uint32_t));
154             outCounter = FM_PCD_GetCounter(h_FmPcd, inCounter);
155             memcpy(p_IpcReply->replyBody, (uint8_t*)&outCounter, sizeof(uint32_t));
156             p_IpcReply->error = E_OK;
157             *p_ReplyLength = sizeof(uint32_t) + sizeof(uint32_t);
158             break;
159         }
160         case (FM_PCD_ALLOC_KG_SCHEMES):
161         {
162             t_FmPcdIpcKgSchemesParams   ipcSchemesParams;
163 
164             memcpy((uint8_t*)&ipcSchemesParams, p_IpcMsg->msgBody, sizeof(t_FmPcdIpcKgSchemesParams));
165             err = FmPcdKgAllocSchemes(h_FmPcd,
166                                       ipcSchemesParams.numOfSchemes,
167                                       ipcSchemesParams.guestId,
168                                       p_IpcReply->replyBody);
169             p_IpcReply->error = err;
170             *p_ReplyLength = sizeof(uint32_t) + ipcSchemesParams.numOfSchemes*sizeof(uint8_t);
171             break;
172         }
173         case (FM_PCD_FREE_KG_SCHEMES):
174         {
175             t_FmPcdIpcKgSchemesParams   ipcSchemesParams;
176 
177             memcpy((uint8_t*)&ipcSchemesParams, p_IpcMsg->msgBody, sizeof(t_FmPcdIpcKgSchemesParams));
178             err = FmPcdKgFreeSchemes(h_FmPcd,
179                                      ipcSchemesParams.numOfSchemes,
180                                      ipcSchemesParams.guestId,
181                                      ipcSchemesParams.schemesIds);
182             p_IpcReply->error = err;
183             *p_ReplyLength = sizeof(uint32_t);
184             break;
185         }
186         case (FM_PCD_ALLOC_KG_CLSPLAN):
187         {
188             t_FmPcdIpcKgClsPlanParams   ipcKgClsPlanParams;
189 
190             memcpy((uint8_t*)&ipcKgClsPlanParams, p_IpcMsg->msgBody, sizeof(t_FmPcdIpcKgClsPlanParams));
191             err = KgAllocClsPlanEntries(h_FmPcd,
192                                         ipcKgClsPlanParams.numOfClsPlanEntries,
193                                         ipcKgClsPlanParams.guestId,
194                                         p_IpcReply->replyBody);
195             p_IpcReply->error = err;
196             *p_ReplyLength =  sizeof(uint32_t) + sizeof(uint8_t);
197             break;
198         }
199         case (FM_PCD_FREE_KG_CLSPLAN):
200         {
201             t_FmPcdIpcKgClsPlanParams   ipcKgClsPlanParams;
202 
203             memcpy((uint8_t*)&ipcKgClsPlanParams, p_IpcMsg->msgBody, sizeof(t_FmPcdIpcKgClsPlanParams));
204             KgFreeClsPlanEntries(h_FmPcd,
205                                  ipcKgClsPlanParams.numOfClsPlanEntries,
206                                  ipcKgClsPlanParams.guestId,
207                                  ipcKgClsPlanParams.clsPlanBase);
208             *p_ReplyLength = sizeof(uint32_t);
209             break;
210         }
211         case (FM_PCD_ALLOC_PROFILES):
212         {
213             t_FmIpcResourceAllocParams      ipcAllocParams;
214             uint16_t                        base;
215             memcpy(&ipcAllocParams, p_IpcMsg->msgBody, sizeof(t_FmIpcResourceAllocParams));
216             base =  PlcrAllocProfilesForPartition(h_FmPcd,
217                                                   ipcAllocParams.base,
218                                                   ipcAllocParams.num,
219                                                   ipcAllocParams.guestId);
220             memcpy(p_IpcReply->replyBody, (uint16_t*)&base, sizeof(uint16_t));
221             *p_ReplyLength = sizeof(uint32_t) + sizeof(uint16_t);
222             break;
223         }
224         case (FM_PCD_FREE_PROFILES):
225         {
226             t_FmIpcResourceAllocParams   ipcAllocParams;
227             memcpy(&ipcAllocParams, p_IpcMsg->msgBody, sizeof(t_FmIpcResourceAllocParams));
228             PlcrFreeProfilesForPartition(h_FmPcd,
229                                          ipcAllocParams.base,
230                                          ipcAllocParams.num,
231                                          ipcAllocParams.guestId);
232             break;
233         }
234         case (FM_PCD_SET_PORT_PROFILES):
235         {
236             t_FmIpcResourceAllocParams   ipcAllocParams;
237             memcpy(&ipcAllocParams, p_IpcMsg->msgBody, sizeof(t_FmIpcResourceAllocParams));
238             PlcrSetPortProfiles(h_FmPcd,
239                                 ipcAllocParams.guestId,
240                                 ipcAllocParams.num,
241                                 ipcAllocParams.base);
242             break;
243         }
244         case (FM_PCD_CLEAR_PORT_PROFILES):
245         {
246             t_FmIpcResourceAllocParams   ipcAllocParams;
247             memcpy(&ipcAllocParams, p_IpcMsg->msgBody, sizeof(t_FmIpcResourceAllocParams));
248             PlcrClearPortProfiles(h_FmPcd,
249                                   ipcAllocParams.guestId);
250             break;
251         }
252         case (FM_PCD_GET_SW_PRS_OFFSET):
253         {
254             t_FmPcdIpcSwPrsLable   ipcSwPrsLable;
255             uint32_t               swPrsOffset;
256 
257             memcpy((uint8_t*)&ipcSwPrsLable, p_IpcMsg->msgBody, sizeof(t_FmPcdIpcSwPrsLable));
258             swPrsOffset =
259                 FmPcdGetSwPrsOffset(h_FmPcd,
260                                     (e_NetHeaderType)ipcSwPrsLable.enumHdr,
261                                     ipcSwPrsLable.indexPerHdr);
262             memcpy(p_IpcReply->replyBody, (uint8_t*)&swPrsOffset, sizeof(uint32_t));
263             *p_ReplyLength = sizeof(uint32_t) + sizeof(uint32_t);
264             break;
265         }
266         case (FM_PCD_PRS_INC_PORT_STATS):
267         {
268             t_FmPcdIpcPrsIncludePort   ipcPrsIncludePort;
269 
270             memcpy((uint8_t*)&ipcPrsIncludePort, p_IpcMsg->msgBody, sizeof(t_FmPcdIpcPrsIncludePort));
271             PrsIncludePortInStatistics(h_FmPcd,
272                                        ipcPrsIncludePort.hardwarePortId,
273                                        ipcPrsIncludePort.include);
274            break;
275         }
276         default:
277             *p_ReplyLength = 0;
278             RETURN_ERROR(MINOR, E_INVALID_SELECTION, ("command not found!!!"));
279     }
280     return E_OK;
281 }
282 
283 static uint32_t NetEnvLock(t_Handle h_NetEnv)
284 {
285     ASSERT_COND(h_NetEnv);
286     return XX_LockIntrSpinlock(((t_FmPcdNetEnv*)h_NetEnv)->h_Spinlock);
287 }
288 
289 static void NetEnvUnlock(t_Handle h_NetEnv, uint32_t intFlags)
290 {
291     ASSERT_COND(h_NetEnv);
292     XX_UnlockIntrSpinlock(((t_FmPcdNetEnv*)h_NetEnv)->h_Spinlock, intFlags);
293 }
294 
295 static void EnqueueLockToFreeLst(t_FmPcd *p_FmPcd, t_FmPcdLock *p_Lock)
296 {
297     uint32_t   intFlags;
298 
299     intFlags = XX_LockIntrSpinlock(p_FmPcd->h_Spinlock);
300     NCSW_LIST_AddToTail(&p_Lock->node, &p_FmPcd->freeLocksLst);
301     XX_UnlockIntrSpinlock(p_FmPcd->h_Spinlock, intFlags);
302 }
303 
304 static t_FmPcdLock * DequeueLockFromFreeLst(t_FmPcd *p_FmPcd)
305 {
306     t_FmPcdLock *p_Lock = NULL;
307     uint32_t    intFlags;
308 
309     intFlags = XX_LockIntrSpinlock(p_FmPcd->h_Spinlock);
310     if (!NCSW_LIST_IsEmpty(&p_FmPcd->freeLocksLst))
311     {
312         p_Lock = FM_PCD_LOCK_OBJ(p_FmPcd->freeLocksLst.p_Next);
313         NCSW_LIST_DelAndInit(&p_Lock->node);
314     }
315     if (p_FmPcd->h_Spinlock)
316     	XX_UnlockIntrSpinlock(p_FmPcd->h_Spinlock, intFlags);
317 
318     return p_Lock;
319 }
320 
321 static void EnqueueLockToAcquiredLst(t_FmPcd *p_FmPcd, t_FmPcdLock *p_Lock)
322 {
323     uint32_t   intFlags;
324 
325     intFlags = XX_LockIntrSpinlock(p_FmPcd->h_Spinlock);
326     NCSW_LIST_AddToTail(&p_Lock->node, &p_FmPcd->acquiredLocksLst);
327     XX_UnlockIntrSpinlock(p_FmPcd->h_Spinlock, intFlags);
328 }
329 
330 static t_Error FillFreeLocksLst(t_FmPcd *p_FmPcd)
331 {
332     t_FmPcdLock *p_Lock;
333     int         i;
334 
335     for (i=0; i<10; i++)
336     {
337         p_Lock = (t_FmPcdLock *)XX_Malloc(sizeof(t_FmPcdLock));
338         if (!p_Lock)
339             RETURN_ERROR(MINOR, E_NO_MEMORY, ("FM-PCD lock obj!"));
340         memset(p_Lock, 0, sizeof(t_FmPcdLock));
341         INIT_LIST(&p_Lock->node);
342         p_Lock->h_Spinlock = XX_InitSpinlock();
343         if (!p_Lock->h_Spinlock)
344         {
345             XX_Free(p_Lock);
346             RETURN_ERROR(MINOR, E_INVALID_STATE, ("FM-PCD spinlock obj!"));
347         }
348         EnqueueLockToFreeLst(p_FmPcd, p_Lock);
349     }
350 
351     return E_OK;
352 }
353 
354 static void ReleaseFreeLocksLst(t_FmPcd *p_FmPcd)
355 {
356     t_FmPcdLock *p_Lock;
357 
358     p_Lock = DequeueLockFromFreeLst(p_FmPcd);
359     while (p_Lock)
360     {
361         XX_FreeSpinlock(p_Lock->h_Spinlock);
362         XX_Free(p_Lock);
363         p_Lock = DequeueLockFromFreeLst(p_FmPcd);
364     }
365 }
366 
367 
368 
369 /*****************************************************************************/
370 /*              Inter-module API routines                                    */
371 /*****************************************************************************/
372 
373 void FmPcdSetClsPlanGrpId(t_FmPcd *p_FmPcd, uint8_t netEnvId, uint8_t clsPlanGrpId)
374 {
375     ASSERT_COND(p_FmPcd);
376     p_FmPcd->netEnvs[netEnvId].clsPlanGrpId = clsPlanGrpId;
377 }
378 
379 t_Error PcdGetClsPlanGrpParams(t_FmPcd *p_FmPcd, t_FmPcdKgInterModuleClsPlanGrpParams *p_GrpParams)
380 {
381     uint8_t netEnvId = p_GrpParams->netEnvId;
382     int     i, k, j;
383 
384     ASSERT_COND(p_FmPcd);
385     if (p_FmPcd->netEnvs[netEnvId].clsPlanGrpId != ILLEGAL_CLS_PLAN)
386     {
387         p_GrpParams->grpExists = TRUE;
388         p_GrpParams->clsPlanGrpId = p_FmPcd->netEnvs[netEnvId].clsPlanGrpId;
389         return E_OK;
390     }
391 
392     for (i=0; ((i < FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS) &&
393               (p_FmPcd->netEnvs[netEnvId].units[i].hdrs[0].hdr != HEADER_TYPE_NONE)); i++)
394     {
395         for (k=0; ((k < FM_PCD_MAX_NUM_OF_INTERCHANGEABLE_HDRS) &&
396                    (p_FmPcd->netEnvs[netEnvId].units[i].hdrs[k].hdr != HEADER_TYPE_NONE)); k++)
397         {
398             /* if an option exists, add it to the opts list */
399             if (p_FmPcd->netEnvs[netEnvId].units[i].hdrs[k].opt)
400             {
401                 /* check if this option already exists, add if it doesn't */
402                 for (j = 0;j<p_GrpParams->numOfOptions;j++)
403                 {
404                     if (p_GrpParams->options[j] == p_FmPcd->netEnvs[netEnvId].units[i].hdrs[k].opt)
405                         break;
406                 }
407                 p_GrpParams->optVectors[j] |= p_FmPcd->netEnvs[netEnvId].unitsVectors[i];
408                 if (j == p_GrpParams->numOfOptions)
409                 {
410                     p_GrpParams->options[p_GrpParams->numOfOptions] = p_FmPcd->netEnvs[netEnvId].units[i].hdrs[k].opt;
411                     p_GrpParams->numOfOptions++;
412                 }
413             }
414         }
415     }
416 
417     if (p_GrpParams->numOfOptions == 0)
418     {
419         if (p_FmPcd->p_FmPcdKg->emptyClsPlanGrpId != ILLEGAL_CLS_PLAN)
420         {
421             p_GrpParams->grpExists = TRUE;
422             p_GrpParams->clsPlanGrpId = p_FmPcd->p_FmPcdKg->emptyClsPlanGrpId;
423         }
424     }
425 
426     return E_OK;
427 
428 }
429 
430 t_Error PcdGetVectorForOpt(t_FmPcd *p_FmPcd, uint8_t netEnvId, protocolOpt_t opt, uint32_t *p_Vector)
431 {
432     uint8_t     j,k;
433 
434     *p_Vector = 0;
435 
436     ASSERT_COND(p_FmPcd);
437     for (j=0; ((j < FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS) &&
438               (p_FmPcd->netEnvs[netEnvId].units[j].hdrs[0].hdr != HEADER_TYPE_NONE)); j++)
439     {
440         for (k=0; ((k < FM_PCD_MAX_NUM_OF_INTERCHANGEABLE_HDRS) &&
441                   (p_FmPcd->netEnvs[netEnvId].units[j].hdrs[k].hdr != HEADER_TYPE_NONE)); k++)
442         {
443             if (p_FmPcd->netEnvs[netEnvId].units[j].hdrs[k].opt == opt)
444                 *p_Vector |= p_FmPcd->netEnvs[netEnvId].unitsVectors[j];
445         }
446     }
447 
448     if (!*p_Vector)
449         RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Requested option was not defined for this Network Environment Characteristics module"));
450     else
451         return E_OK;
452 }
453 
454 t_Error PcdGetUnitsVector(t_FmPcd *p_FmPcd, t_NetEnvParams *p_Params)
455 {
456     int                     i;
457 
458     ASSERT_COND(p_FmPcd);
459     ASSERT_COND(p_Params->netEnvId < FM_MAX_NUM_OF_PORTS);
460 
461     p_Params->vector = 0;
462     for (i=0; i<p_Params->numOfDistinctionUnits ;i++)
463     {
464         if (p_FmPcd->netEnvs[p_Params->netEnvId].units[p_Params->unitIds[i]].hdrs[0].hdr == HEADER_TYPE_NONE)
465             RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Requested unit was not defined for this Network Environment Characteristics module"));
466         ASSERT_COND(p_FmPcd->netEnvs[p_Params->netEnvId].unitsVectors[p_Params->unitIds[i]]);
467         p_Params->vector |= p_FmPcd->netEnvs[p_Params->netEnvId].unitsVectors[p_Params->unitIds[i]];
468     }
469 
470     return E_OK;
471 }
472 
473 bool PcdNetEnvIsUnitWithoutOpts(t_FmPcd *p_FmPcd, uint8_t netEnvId, uint32_t unitVector)
474 {
475     int     i=0, k;
476 
477     ASSERT_COND(p_FmPcd);
478     /* check whether a given unit may be used by non-clsPlan users. */
479     /* first, recognize the unit by its vector */
480     while (p_FmPcd->netEnvs[netEnvId].units[i].hdrs[0].hdr != HEADER_TYPE_NONE)
481     {
482         if (p_FmPcd->netEnvs[netEnvId].unitsVectors[i] == unitVector)
483         {
484             for (k=0;
485                  ((k < FM_PCD_MAX_NUM_OF_INTERCHANGEABLE_HDRS) &&
486                   (p_FmPcd->netEnvs[netEnvId].units[i].hdrs[k].hdr != HEADER_TYPE_NONE));
487                  k++)
488                 /* check that no option exists */
489                 if ((protocolOpt_t)p_FmPcd->netEnvs[netEnvId].units[i].hdrs[k].opt)
490                     return FALSE;
491             break;
492         }
493         i++;
494     }
495     /* assert that a unit was found to mach the vector */
496     ASSERT_COND(p_FmPcd->netEnvs[netEnvId].units[i].hdrs[0].hdr != HEADER_TYPE_NONE);
497 
498     return TRUE;
499 }
500 bool  FmPcdNetEnvIsHdrExist(t_Handle h_FmPcd, uint8_t netEnvId, e_NetHeaderType hdr)
501 {
502     t_FmPcd     *p_FmPcd = (t_FmPcd*)h_FmPcd;
503     int         i, k;
504 
505     ASSERT_COND(p_FmPcd);
506 
507     for (i=0; ((i < FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS) &&
508               (p_FmPcd->netEnvs[netEnvId].units[i].hdrs[0].hdr != HEADER_TYPE_NONE)); i++)
509     {
510         for (k=0; ((k < FM_PCD_MAX_NUM_OF_INTERCHANGEABLE_HDRS) &&
511                   (p_FmPcd->netEnvs[netEnvId].units[i].hdrs[k].hdr != HEADER_TYPE_NONE)); k++)
512             if (p_FmPcd->netEnvs[netEnvId].units[i].hdrs[k].hdr == hdr)
513                 return TRUE;
514     }
515     for (i=0; ((i < FM_PCD_MAX_NUM_OF_ALIAS_HDRS) &&
516               (p_FmPcd->netEnvs[netEnvId].aliasHdrs[i].hdr != HEADER_TYPE_NONE)); i++)
517     {
518         if (p_FmPcd->netEnvs[netEnvId].aliasHdrs[i].hdr == hdr)
519             return TRUE;
520     }
521 
522     return FALSE;
523 }
524 
525 uint8_t FmPcdNetEnvGetUnitId(t_FmPcd *p_FmPcd, uint8_t netEnvId, e_NetHeaderType hdr, bool interchangeable, protocolOpt_t opt)
526 {
527     uint8_t     i, k;
528 
529     ASSERT_COND(p_FmPcd);
530 
531     if (interchangeable)
532     {
533         for (i=0; (i < FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS) &&
534                  (p_FmPcd->netEnvs[netEnvId].units[i].hdrs[0].hdr != HEADER_TYPE_NONE); i++)
535         {
536             for (k=0; (k < FM_PCD_MAX_NUM_OF_INTERCHANGEABLE_HDRS) &&
537                      (p_FmPcd->netEnvs[netEnvId].units[i].hdrs[k].hdr != HEADER_TYPE_NONE); k++)
538             {
539                 if ((p_FmPcd->netEnvs[netEnvId].units[i].hdrs[k].hdr == hdr) &&
540                     (p_FmPcd->netEnvs[netEnvId].units[i].hdrs[k].opt == opt))
541 
542                 return i;
543             }
544         }
545     }
546     else
547     {
548         for (i=0; (i < FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS) &&
549                  (p_FmPcd->netEnvs[netEnvId].units[i].hdrs[0].hdr != HEADER_TYPE_NONE); i++)
550             if ((p_FmPcd->netEnvs[netEnvId].units[i].hdrs[0].hdr == hdr) &&
551                 (p_FmPcd->netEnvs[netEnvId].units[i].hdrs[0].opt == opt) &&
552                 (p_FmPcd->netEnvs[netEnvId].units[i].hdrs[1].hdr == HEADER_TYPE_NONE))
553                     return i;
554 
555         for (i=0; (i < FM_PCD_MAX_NUM_OF_ALIAS_HDRS) &&
556                  (p_FmPcd->netEnvs[netEnvId].aliasHdrs[i].hdr != HEADER_TYPE_NONE); i++)
557             if ((p_FmPcd->netEnvs[netEnvId].aliasHdrs[i].hdr == hdr) &&
558                 (p_FmPcd->netEnvs[netEnvId].aliasHdrs[i].opt == opt))
559                 return p_FmPcd->netEnvs[netEnvId].aliasHdrs[i].aliasHdr;
560     }
561 
562     return FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS;
563 }
564 
565 t_Error FmPcdUnregisterReassmPort(t_Handle h_FmPcd, t_Handle h_ReasmCommonPramTbl)
566 {
567     t_FmPcd                         *p_FmPcd = (t_FmPcd*)h_FmPcd;
568     t_FmPcdCcReassmTimeoutParams    ccReassmTimeoutParams = {0};
569     uint8_t                         result;
570     t_Error                         err = E_OK;
571 
572     ASSERT_COND(p_FmPcd);
573     ASSERT_COND(h_ReasmCommonPramTbl);
574 
575     ccReassmTimeoutParams.iprcpt   = (uint32_t)(XX_VirtToPhys(h_ReasmCommonPramTbl) - p_FmPcd->physicalMuramBase);
576     ccReassmTimeoutParams.activate = FALSE; /*Disable Timeout Task*/
577 
578     if ((err = FmHcPcdCcTimeoutReassm(p_FmPcd->h_Hc, &ccReassmTimeoutParams, &result)) != E_OK)
579         RETURN_ERROR(MAJOR, err, NO_MSG);
580 
581     switch (result)
582     {
583         case (0):
584             return E_OK;
585         case (1):
586             RETURN_ERROR(MAJOR, E_INVALID_STATE, (""));
587         case (2):
588             RETURN_ERROR(MAJOR, E_INVALID_STATE, (""));
589         case (3):
590             RETURN_ERROR(MAJOR, E_INVALID_HANDLE, ("Disable Timeout Task with invalid IPRCPT"));
591         default:
592             RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG);
593     }
594 
595     return E_OK;
596 }
597 
598 e_NetHeaderType FmPcdGetAliasHdr(t_FmPcd *p_FmPcd, uint8_t netEnvId, e_NetHeaderType hdr)
599 {
600     int         i;
601 
602     ASSERT_COND(p_FmPcd);
603     ASSERT_COND(netEnvId < FM_MAX_NUM_OF_PORTS);
604 
605     for (i=0; (i < FM_PCD_MAX_NUM_OF_ALIAS_HDRS)
606         && (p_FmPcd->netEnvs[netEnvId].aliasHdrs[i].hdr != HEADER_TYPE_NONE); i++)
607     {
608         if (p_FmPcd->netEnvs[netEnvId].aliasHdrs[i].hdr == hdr)
609             return p_FmPcd->netEnvs[netEnvId].aliasHdrs[i].aliasHdr;
610     }
611 
612     return HEADER_TYPE_NONE;
613 }
614 
615 void   FmPcdPortRegister(t_Handle h_FmPcd, t_Handle h_FmPort, uint8_t hardwarePortId)
616 {
617     t_FmPcd         *p_FmPcd = (t_FmPcd*)h_FmPcd;
618     uint16_t        swPortIndex = 0;
619 
620     ASSERT_COND(h_FmPcd);
621     HW_PORT_ID_TO_SW_PORT_INDX(swPortIndex, hardwarePortId);
622     p_FmPcd->p_FmPcdPlcr->portsMapping[swPortIndex].h_FmPort = h_FmPort;
623 }
624 
625 uint32_t FmPcdGetLcv(t_Handle h_FmPcd, uint32_t netEnvId, uint8_t hdrNum)
626 {
627     t_FmPcd     *p_FmPcd = (t_FmPcd*)h_FmPcd;
628 
629     ASSERT_COND(h_FmPcd);
630     return p_FmPcd->netEnvs[netEnvId].lcvs[hdrNum];
631 }
632 
633 uint32_t FmPcdGetMacsecLcv(t_Handle h_FmPcd, uint32_t netEnvId)
634 {
635     t_FmPcd     *p_FmPcd = (t_FmPcd*)h_FmPcd;
636 
637     ASSERT_COND(h_FmPcd);
638     return p_FmPcd->netEnvs[netEnvId].macsecVector;
639 }
640 
641 uint8_t FmPcdGetNetEnvId(t_Handle h_NetEnv)
642 {
643     return ((t_FmPcdNetEnv*)h_NetEnv)->netEnvId;
644 }
645 
646 void FmPcdIncNetEnvOwners(t_Handle h_FmPcd, uint8_t netEnvId)
647 {
648     uint32_t    intFlags;
649 
650     ASSERT_COND(h_FmPcd);
651 
652     intFlags = NetEnvLock(&((t_FmPcd*)h_FmPcd)->netEnvs[netEnvId]);
653     ((t_FmPcd*)h_FmPcd)->netEnvs[netEnvId].owners++;
654     NetEnvUnlock(&((t_FmPcd*)h_FmPcd)->netEnvs[netEnvId], intFlags);
655 }
656 
657 void FmPcdDecNetEnvOwners(t_Handle h_FmPcd, uint8_t netEnvId)
658 {
659     uint32_t    intFlags;
660 
661     ASSERT_COND(h_FmPcd);
662     ASSERT_COND(((t_FmPcd*)h_FmPcd)->netEnvs[netEnvId].owners);
663 
664     intFlags = NetEnvLock(&((t_FmPcd*)h_FmPcd)->netEnvs[netEnvId]);
665     ((t_FmPcd*)h_FmPcd)->netEnvs[netEnvId].owners--;
666     NetEnvUnlock(&((t_FmPcd*)h_FmPcd)->netEnvs[netEnvId], intFlags);
667 }
668 
669 uint32_t FmPcdLock(t_Handle h_FmPcd)
670 {
671     ASSERT_COND(h_FmPcd);
672     return XX_LockIntrSpinlock(((t_FmPcd*)h_FmPcd)->h_Spinlock);
673 }
674 
675 void FmPcdUnlock(t_Handle h_FmPcd, uint32_t intFlags)
676 {
677     ASSERT_COND(h_FmPcd);
678     XX_UnlockIntrSpinlock(((t_FmPcd*)h_FmPcd)->h_Spinlock, intFlags);
679 }
680 
681 t_FmPcdLock * FmPcdAcquireLock(t_Handle h_FmPcd)
682 {
683     t_FmPcdLock *p_Lock;
684     ASSERT_COND(h_FmPcd);
685     p_Lock = DequeueLockFromFreeLst((t_FmPcd*)h_FmPcd);
686     if (!p_Lock)
687     {
688         FillFreeLocksLst(h_FmPcd);
689         p_Lock = DequeueLockFromFreeLst((t_FmPcd*)h_FmPcd);
690     }
691 
692     if (p_Lock)
693         EnqueueLockToAcquiredLst((t_FmPcd*)h_FmPcd, p_Lock);
694     return p_Lock;
695 }
696 
697 void FmPcdReleaseLock(t_Handle h_FmPcd, t_FmPcdLock *p_Lock)
698 {
699     uint32_t intFlags;
700     ASSERT_COND(h_FmPcd);
701     intFlags = FmPcdLock(h_FmPcd);
702     NCSW_LIST_DelAndInit(&p_Lock->node);
703     FmPcdUnlock(h_FmPcd, intFlags);
704     EnqueueLockToFreeLst((t_FmPcd*)h_FmPcd, p_Lock);
705 }
706 
707 bool FmPcdLockTryLockAll(t_Handle h_FmPcd)
708 {
709     uint32_t    intFlags;
710     t_List      *p_Pos, *p_SavedPos=NULL;
711 
712     ASSERT_COND(h_FmPcd);
713     intFlags = FmPcdLock(h_FmPcd);
714     NCSW_LIST_FOR_EACH(p_Pos, &((t_FmPcd*)h_FmPcd)->acquiredLocksLst)
715     {
716         t_FmPcdLock *p_Lock = FM_PCD_LOCK_OBJ(p_Pos);
717         if (!FmPcdLockTryLock(p_Lock))
718         {
719             p_SavedPos = p_Pos;
720             break;
721         }
722     }
723     if (p_SavedPos)
724     {
725         NCSW_LIST_FOR_EACH(p_Pos, &((t_FmPcd*)h_FmPcd)->acquiredLocksLst)
726         {
727             t_FmPcdLock *p_Lock = FM_PCD_LOCK_OBJ(p_Pos);
728             if (p_Pos == p_SavedPos)
729                 break;
730             FmPcdLockUnlock(p_Lock);
731         }
732     }
733     FmPcdUnlock(h_FmPcd, intFlags);
734 
735     CORE_MemoryBarrier();
736 
737     if (p_SavedPos)
738         return FALSE;
739 
740     return TRUE;
741 }
742 
743 void FmPcdLockUnlockAll(t_Handle h_FmPcd)
744 {
745     uint32_t    intFlags;
746     t_List      *p_Pos;
747 
748     ASSERT_COND(h_FmPcd);
749     intFlags = FmPcdLock(h_FmPcd);
750     NCSW_LIST_FOR_EACH(p_Pos, &((t_FmPcd*)h_FmPcd)->acquiredLocksLst)
751     {
752         t_FmPcdLock *p_Lock = FM_PCD_LOCK_OBJ(p_Pos);
753         p_Lock->flag = FALSE;
754     }
755     FmPcdUnlock(h_FmPcd, intFlags);
756 
757     CORE_MemoryBarrier();
758 }
759 
760 t_Error FmPcdHcSync(t_Handle h_FmPcd)
761 {
762     ASSERT_COND(h_FmPcd);
763     ASSERT_COND(((t_FmPcd*)h_FmPcd)->h_Hc);
764 
765     return FmHcPcdSync(((t_FmPcd*)h_FmPcd)->h_Hc);
766 }
767 
768 t_Handle FmPcdGetHcHandle(t_Handle h_FmPcd)
769 {
770     ASSERT_COND(h_FmPcd);
771     return ((t_FmPcd*)h_FmPcd)->h_Hc;
772 }
773 
774 bool FmPcdIsAdvancedOffloadSupported(t_Handle h_FmPcd)
775 {
776     ASSERT_COND(h_FmPcd);
777     return ((t_FmPcd*)h_FmPcd)->advancedOffloadSupport;
778 }
779 /*********************** End of inter-module routines ************************/
780 
781 
782 /****************************************/
783 /*       API Init unit functions        */
784 /****************************************/
785 
786 t_Handle FM_PCD_Config(t_FmPcdParams *p_FmPcdParams)
787 {
788     t_FmPcd             *p_FmPcd = NULL;
789     t_FmPhysAddr        physicalMuramBase;
790     uint8_t             i;
791 
792     SANITY_CHECK_RETURN_VALUE(p_FmPcdParams, E_INVALID_HANDLE,NULL);
793 
794     p_FmPcd = (t_FmPcd *) XX_Malloc(sizeof(t_FmPcd));
795     if (!p_FmPcd)
796     {
797         REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM PCD"));
798         return NULL;
799     }
800     memset(p_FmPcd, 0, sizeof(t_FmPcd));
801 
802     p_FmPcd->p_FmPcdDriverParam = (t_FmPcdDriverParam *) XX_Malloc(sizeof(t_FmPcdDriverParam));
803     if (!p_FmPcd->p_FmPcdDriverParam)
804     {
805         XX_Free(p_FmPcd);
806         REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM PCD Driver Param"));
807         return NULL;
808     }
809     memset(p_FmPcd->p_FmPcdDriverParam, 0, sizeof(t_FmPcdDriverParam));
810 
811     p_FmPcd->h_Fm = p_FmPcdParams->h_Fm;
812     p_FmPcd->guestId = FmGetGuestId(p_FmPcd->h_Fm);
813     p_FmPcd->h_FmMuram = FmGetMuramHandle(p_FmPcd->h_Fm);
814     if (p_FmPcd->h_FmMuram)
815     {
816         FmGetPhysicalMuramBase(p_FmPcdParams->h_Fm, &physicalMuramBase);
817         p_FmPcd->physicalMuramBase = (uint64_t)((uint64_t)(&physicalMuramBase)->low | ((uint64_t)(&physicalMuramBase)->high << 32));
818     }
819 
820     for (i = 0; i<FM_MAX_NUM_OF_PORTS; i++)
821         p_FmPcd->netEnvs[i].clsPlanGrpId = ILLEGAL_CLS_PLAN;
822 
823     if (p_FmPcdParams->useHostCommand)
824     {
825         t_FmHcParams    hcParams;
826 
827         memset(&hcParams, 0, sizeof(hcParams));
828         hcParams.h_Fm = p_FmPcd->h_Fm;
829         hcParams.h_FmPcd = (t_Handle)p_FmPcd;
830         memcpy((uint8_t*)&hcParams.params, (uint8_t*)&p_FmPcdParams->hc, sizeof(t_FmPcdHcParams));
831         p_FmPcd->h_Hc = FmHcConfigAndInit(&hcParams);
832         if (!p_FmPcd->h_Hc)
833         {
834             REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM PCD HC"));
835             FM_PCD_Free(p_FmPcd);
836             return NULL;
837         }
838     }
839     else if (p_FmPcd->guestId != NCSW_MASTER_ID)
840         REPORT_ERROR(MAJOR, E_INVALID_STATE, ("No Host Command defined for a guest partition."));
841 
842     if (p_FmPcdParams->kgSupport)
843     {
844         p_FmPcd->p_FmPcdKg = (t_FmPcdKg *)KgConfig(p_FmPcd, p_FmPcdParams);
845         if (!p_FmPcd->p_FmPcdKg)
846         {
847             REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM PCD Keygen"));
848             FM_PCD_Free(p_FmPcd);
849             return NULL;
850         }
851     }
852 
853     if (p_FmPcdParams->plcrSupport)
854     {
855         p_FmPcd->p_FmPcdPlcr = (t_FmPcdPlcr *)PlcrConfig(p_FmPcd, p_FmPcdParams);
856         if (!p_FmPcd->p_FmPcdPlcr)
857         {
858             REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM PCD Policer"));
859             FM_PCD_Free(p_FmPcd);
860             return NULL;
861         }
862     }
863 
864     if (p_FmPcdParams->prsSupport)
865     {
866         p_FmPcd->p_FmPcdPrs = (t_FmPcdPrs *)PrsConfig(p_FmPcd, p_FmPcdParams);
867         if (!p_FmPcd->p_FmPcdPrs)
868         {
869             REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM PCD Parser"));
870             FM_PCD_Free(p_FmPcd);
871             return NULL;
872         }
873     }
874 
875     p_FmPcd->h_Spinlock = XX_InitSpinlock();
876     if (!p_FmPcd->h_Spinlock)
877     {
878         REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM PCD spinlock"));
879         FM_PCD_Free(p_FmPcd);
880         return NULL;
881     }
882     INIT_LIST(&p_FmPcd->freeLocksLst);
883     INIT_LIST(&p_FmPcd->acquiredLocksLst);
884 
885     p_FmPcd->numOfEnabledGuestPartitionsPcds = 0;
886 
887     p_FmPcd->f_Exception                = p_FmPcdParams->f_Exception;
888     p_FmPcd->f_FmPcdIndexedException    = p_FmPcdParams->f_ExceptionId;
889     p_FmPcd->h_App                      = p_FmPcdParams->h_App;
890 
891     p_FmPcd->p_CcShadow                 = NULL;
892     p_FmPcd->ccShadowSize               = 0;
893     p_FmPcd->ccShadowAlign              = 0;
894 
895     p_FmPcd->h_ShadowSpinlock = XX_InitSpinlock();
896     if (!p_FmPcd->h_ShadowSpinlock)
897     {
898         REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM PCD shadow spinlock"));
899         FM_PCD_Free(p_FmPcd);
900         return NULL;
901     }
902 
903     return p_FmPcd;
904 }
905 
906 t_Error FM_PCD_Init(t_Handle h_FmPcd)
907 {
908     t_FmPcd         *p_FmPcd = (t_FmPcd*)h_FmPcd;
909     t_Error         err = E_OK;
910     t_FmPcdIpcMsg   msg;
911 
912     SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
913     SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdDriverParam, E_INVALID_HANDLE);
914 
915     FM_GetRevision(p_FmPcd->h_Fm, &p_FmPcd->fmRevInfo);
916 
917     if (p_FmPcd->guestId != NCSW_MASTER_ID)
918     {
919         memset(p_FmPcd->fmPcdIpcHandlerModuleName, 0, (sizeof(char)) * MODULE_NAME_SIZE);
920         if (Sprint (p_FmPcd->fmPcdIpcHandlerModuleName, "FM_PCD_%d_%d", FmGetId(p_FmPcd->h_Fm), NCSW_MASTER_ID) != 10)
921             RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Sprint failed"));
922         memset(p_FmPcd->fmPcdModuleName, 0, (sizeof(char)) * MODULE_NAME_SIZE);
923         if (Sprint (p_FmPcd->fmPcdModuleName, "FM_PCD_%d_%d",FmGetId(p_FmPcd->h_Fm), p_FmPcd->guestId) != (p_FmPcd->guestId<10 ? 10:11))
924             RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Sprint failed"));
925 
926         p_FmPcd->h_IpcSession = XX_IpcInitSession(p_FmPcd->fmPcdIpcHandlerModuleName, p_FmPcd->fmPcdModuleName);
927         if (p_FmPcd->h_IpcSession)
928         {
929             t_FmPcdIpcReply         reply;
930             uint32_t                replyLength;
931             uint8_t                 isMasterAlive = 0;
932 
933             memset(&msg, 0, sizeof(msg));
934             memset(&reply, 0, sizeof(reply));
935             msg.msgId = FM_PCD_MASTER_IS_ALIVE;
936             msg.msgBody[0] = p_FmPcd->guestId;
937             blockingFlag = TRUE;
938 
939             do
940             {
941                 replyLength = sizeof(uint32_t) + sizeof(isMasterAlive);
942                 if ((err = XX_IpcSendMessage(p_FmPcd->h_IpcSession,
943                                              (uint8_t*)&msg,
944                                              sizeof(msg.msgId)+sizeof(p_FmPcd->guestId),
945                                              (uint8_t*)&reply,
946                                              &replyLength,
947                                              IpcMsgCompletionCB,
948                                              h_FmPcd)) != E_OK)
949                     REPORT_ERROR(MAJOR, err, NO_MSG);
950                 while (blockingFlag) ;
951                 if (replyLength != (sizeof(uint32_t) + sizeof(isMasterAlive)))
952                     REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
953                 isMasterAlive = *(uint8_t*)(reply.replyBody);
954             } while (!isMasterAlive);
955         }
956     }
957 
958     CHECK_INIT_PARAMETERS(p_FmPcd, CheckFmPcdParameters);
959 
960     if (p_FmPcd->p_FmPcdKg)
961     {
962         err = KgInit(p_FmPcd);
963         if (err)
964             RETURN_ERROR(MAJOR, err, NO_MSG);
965     }
966 
967     if (p_FmPcd->p_FmPcdPlcr)
968     {
969         err = PlcrInit(p_FmPcd);
970         if (err)
971             RETURN_ERROR(MAJOR, err, NO_MSG);
972     }
973 
974     if (p_FmPcd->p_FmPcdPrs)
975     {
976         err = PrsInit(p_FmPcd);
977         if (err)
978             RETURN_ERROR(MAJOR, err, NO_MSG);
979     }
980 
981     if (p_FmPcd->guestId == NCSW_MASTER_ID)
982     {
983          /* register to inter-core messaging mechanism */
984         memset(p_FmPcd->fmPcdModuleName, 0, (sizeof(char)) * MODULE_NAME_SIZE);
985         if (Sprint (p_FmPcd->fmPcdModuleName, "FM_PCD_%d_%d",FmGetId(p_FmPcd->h_Fm),NCSW_MASTER_ID) != 10)
986             RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Sprint failed"));
987         err = XX_IpcRegisterMsgHandler(p_FmPcd->fmPcdModuleName, IpcMsgHandlerCB, p_FmPcd, FM_PCD_MAX_REPLY_SIZE);
988         if (err)
989             RETURN_ERROR(MAJOR, err, NO_MSG);
990     }
991 
992     /* IPv6 Frame-Id used for fragmentation */
993     p_FmPcd->ipv6FrameIdAddr = PTR_TO_UINT(FM_MURAM_AllocMem(p_FmPcd->h_FmMuram, 4, 4));
994     if (!p_FmPcd->ipv6FrameIdAddr)
995     {
996         FM_PCD_Free(p_FmPcd);
997         RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM allocation for IPv6 Frame-Id"));
998     }
999     IOMemSet32(UINT_TO_PTR(p_FmPcd->ipv6FrameIdAddr), 0,  4);
1000 
1001     /* CAPWAP Frame-Id used for fragmentation */
1002     p_FmPcd->capwapFrameIdAddr = PTR_TO_UINT(FM_MURAM_AllocMem(p_FmPcd->h_FmMuram, 2, 4));
1003     if (!p_FmPcd->capwapFrameIdAddr)
1004     {
1005         FM_PCD_Free(p_FmPcd);
1006         RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM allocation for CAPWAP Frame-Id"));
1007     }
1008     IOMemSet32(UINT_TO_PTR(p_FmPcd->capwapFrameIdAddr), 0,  2);
1009 
1010     XX_Free(p_FmPcd->p_FmPcdDriverParam);
1011     p_FmPcd->p_FmPcdDriverParam = NULL;
1012 
1013     FmRegisterPcd(p_FmPcd->h_Fm, p_FmPcd);
1014 
1015     return E_OK;
1016 }
1017 
1018 t_Error FM_PCD_Free(t_Handle h_FmPcd)
1019 {
1020     t_FmPcd                             *p_FmPcd =(t_FmPcd *)h_FmPcd;
1021     t_Error                             err = E_OK;
1022 
1023     if (p_FmPcd->ipv6FrameIdAddr)
1024         FM_MURAM_FreeMem(p_FmPcd->h_FmMuram, UINT_TO_PTR(p_FmPcd->ipv6FrameIdAddr));
1025 
1026     if (p_FmPcd->capwapFrameIdAddr)
1027         FM_MURAM_FreeMem(p_FmPcd->h_FmMuram, UINT_TO_PTR(p_FmPcd->capwapFrameIdAddr));
1028 
1029     if (p_FmPcd->enabled)
1030         FM_PCD_Disable(p_FmPcd);
1031 
1032     if (p_FmPcd->p_FmPcdDriverParam)
1033     {
1034         XX_Free(p_FmPcd->p_FmPcdDriverParam);
1035         p_FmPcd->p_FmPcdDriverParam = NULL;
1036     }
1037 
1038     if (p_FmPcd->p_FmPcdKg)
1039     {
1040         if ((err = KgFree(p_FmPcd)) != E_OK)
1041             RETURN_ERROR(MINOR, err, NO_MSG);
1042         XX_Free(p_FmPcd->p_FmPcdKg);
1043         p_FmPcd->p_FmPcdKg = NULL;
1044     }
1045 
1046     if (p_FmPcd->p_FmPcdPlcr)
1047     {
1048         PlcrFree(p_FmPcd);
1049         XX_Free(p_FmPcd->p_FmPcdPlcr);
1050         p_FmPcd->p_FmPcdPlcr = NULL;
1051     }
1052 
1053     if (p_FmPcd->p_FmPcdPrs)
1054     {
1055         if (p_FmPcd->guestId == NCSW_MASTER_ID)
1056             PrsFree(p_FmPcd);
1057         XX_Free(p_FmPcd->p_FmPcdPrs);
1058         p_FmPcd->p_FmPcdPrs = NULL;
1059     }
1060 
1061     if (p_FmPcd->h_Hc)
1062     {
1063         FmHcFree(p_FmPcd->h_Hc);
1064         p_FmPcd->h_Hc = NULL;
1065     }
1066 
1067     XX_IpcUnregisterMsgHandler(p_FmPcd->fmPcdModuleName);
1068 
1069     FmUnregisterPcd(p_FmPcd->h_Fm);
1070 
1071     ReleaseFreeLocksLst(p_FmPcd);
1072 
1073     if (p_FmPcd->h_Spinlock)
1074         XX_FreeSpinlock(p_FmPcd->h_Spinlock);
1075 
1076     if (p_FmPcd->h_ShadowSpinlock)
1077         XX_FreeSpinlock(p_FmPcd->h_ShadowSpinlock);
1078 
1079     XX_Free(p_FmPcd);
1080 
1081     return E_OK;
1082 }
1083 
1084 t_Error FM_PCD_ConfigException(t_Handle h_FmPcd, e_FmPcdExceptions exception, bool enable)
1085 {
1086     t_FmPcd         *p_FmPcd = (t_FmPcd*)h_FmPcd;
1087     uint32_t        bitMask = 0;
1088 
1089     SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
1090 
1091     if (p_FmPcd->guestId != NCSW_MASTER_ID)
1092         RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("FM_PCD_ConfigException - guest mode!"));
1093 
1094     GET_FM_PCD_EXCEPTION_FLAG(bitMask, exception);
1095     if (bitMask)
1096     {
1097         if (enable)
1098             p_FmPcd->exceptions |= bitMask;
1099         else
1100             p_FmPcd->exceptions &= ~bitMask;
1101    }
1102     else
1103         RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined exception"));
1104 
1105     return E_OK;
1106 }
1107 
1108 t_Error FM_PCD_ConfigHcFramesDataMemory(t_Handle h_FmPcd, uint8_t memId)
1109 {
1110     t_FmPcd         *p_FmPcd = (t_FmPcd*)h_FmPcd;
1111 
1112     SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
1113     SANITY_CHECK_RETURN_ERROR(p_FmPcd->h_Hc, E_INVALID_HANDLE);
1114 
1115     return FmHcSetFramesDataMemory(p_FmPcd->h_Hc, memId);
1116 }
1117 
1118 t_Error FM_PCD_Enable(t_Handle h_FmPcd)
1119 {
1120     t_FmPcd             *p_FmPcd = (t_FmPcd*)h_FmPcd;
1121     t_Error             err = E_OK;
1122 
1123     SANITY_CHECK_RETURN_ERROR(h_FmPcd, E_INVALID_HANDLE);
1124 
1125     if (p_FmPcd->enabled)
1126         return E_OK;
1127 
1128     if ((p_FmPcd->guestId != NCSW_MASTER_ID) &&
1129         p_FmPcd->h_IpcSession)
1130     {
1131         uint8_t         enabled;
1132         t_FmPcdIpcMsg   msg;
1133         t_FmPcdIpcReply reply;
1134         uint32_t        replyLength;
1135 
1136         memset(&reply, 0, sizeof(reply));
1137         memset(&msg, 0, sizeof(msg));
1138         msg.msgId = FM_PCD_MASTER_IS_ENABLED;
1139         replyLength = sizeof(uint32_t) + sizeof(enabled);
1140         if ((err = XX_IpcSendMessage(p_FmPcd->h_IpcSession,
1141                                      (uint8_t*)&msg,
1142                                      sizeof(msg.msgId),
1143                                      (uint8_t*)&reply,
1144                                      &replyLength,
1145                                      NULL,
1146                                      NULL)) != E_OK)
1147             RETURN_ERROR(MAJOR, err, NO_MSG);
1148         if (replyLength != sizeof(uint32_t) + sizeof(enabled))
1149             RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
1150         p_FmPcd->enabled = (bool)!!(*(uint8_t*)(reply.replyBody));
1151         if (!p_FmPcd->enabled)
1152             RETURN_ERROR(MAJOR, E_INVALID_STATE, ("FM-PCD master should be enabled first!"));
1153 
1154         return E_OK;
1155     }
1156     else if (p_FmPcd->guestId != NCSW_MASTER_ID)
1157         RETURN_ERROR(MINOR, E_NOT_SUPPORTED,
1158                      ("running in guest-mode without IPC!"));
1159 
1160     if (p_FmPcd->p_FmPcdKg)
1161         KgEnable(p_FmPcd);
1162 
1163     if (p_FmPcd->p_FmPcdPlcr)
1164         PlcrEnable(p_FmPcd);
1165 
1166     if (p_FmPcd->p_FmPcdPrs)
1167         PrsEnable(p_FmPcd);
1168 
1169     p_FmPcd->enabled = TRUE;
1170 
1171     return E_OK;
1172 }
1173 
1174 t_Error FM_PCD_Disable(t_Handle h_FmPcd)
1175 {
1176     t_FmPcd             *p_FmPcd = (t_FmPcd*)h_FmPcd;
1177     t_Error             err = E_OK;
1178 
1179     SANITY_CHECK_RETURN_ERROR(h_FmPcd, E_INVALID_HANDLE);
1180 
1181     if (!p_FmPcd->enabled)
1182         return E_OK;
1183 
1184     if ((p_FmPcd->guestId != NCSW_MASTER_ID) &&
1185         p_FmPcd->h_IpcSession)
1186     {
1187         t_FmPcdIpcMsg       msg;
1188         t_FmPcdIpcReply     reply;
1189         uint32_t            replyLength;
1190 
1191         memset(&reply, 0, sizeof(reply));
1192         memset(&msg, 0, sizeof(msg));
1193         msg.msgId = FM_PCD_GUEST_DISABLE;
1194         replyLength = sizeof(uint32_t);
1195         if ((err = XX_IpcSendMessage(p_FmPcd->h_IpcSession,
1196                                      (uint8_t*)&msg,
1197                                      sizeof(msg.msgId),
1198                                      (uint8_t*)&reply,
1199                                      &replyLength,
1200                                      NULL,
1201                                      NULL)) != E_OK)
1202             RETURN_ERROR(MAJOR, err, NO_MSG);
1203         if (replyLength != sizeof(uint32_t))
1204             RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
1205         if (reply.error == E_OK)
1206             p_FmPcd->enabled = FALSE;
1207 
1208         return (t_Error)(reply.error);
1209     }
1210     else if (p_FmPcd->guestId != NCSW_MASTER_ID)
1211         RETURN_ERROR(MINOR, E_NOT_SUPPORTED,
1212                      ("running in guest-mode without IPC!"));
1213 
1214     if (p_FmPcd->numOfEnabledGuestPartitionsPcds != 0)
1215         RETURN_ERROR(MAJOR, E_INVALID_STATE,
1216                      ("Trying to disable a master partition PCD while"
1217                       "guest partitions are still enabled!"));
1218 
1219     if (p_FmPcd->p_FmPcdKg)
1220          KgDisable(p_FmPcd);
1221 
1222     if (p_FmPcd->p_FmPcdPlcr)
1223         PlcrDisable(p_FmPcd);
1224 
1225     if (p_FmPcd->p_FmPcdPrs)
1226         PrsDisable(p_FmPcd);
1227 
1228     p_FmPcd->enabled = FALSE;
1229 
1230     return E_OK;
1231 }
1232 
1233 t_Handle FM_PCD_NetEnvCharacteristicsSet(t_Handle h_FmPcd, t_FmPcdNetEnvParams  *p_NetEnvParams)
1234 {
1235     t_FmPcd                 *p_FmPcd = (t_FmPcd*)h_FmPcd;
1236     uint32_t                intFlags, specialUnits = 0;
1237     uint8_t                 bitId = 0;
1238     uint8_t                 i, j, k;
1239     uint8_t                 netEnvCurrId;
1240     uint8_t                 ipsecAhUnit = 0,ipsecEspUnit = 0;
1241     bool                    ipsecAhExists = FALSE, ipsecEspExists = FALSE, shim1Selected = FALSE;
1242     uint8_t                 hdrNum;
1243     t_FmPcdNetEnvParams     *p_ModifiedNetEnvParams;
1244 
1245     SANITY_CHECK_RETURN_VALUE(h_FmPcd, E_INVALID_STATE, NULL);
1246     SANITY_CHECK_RETURN_VALUE(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_STATE, NULL);
1247     SANITY_CHECK_RETURN_VALUE(p_NetEnvParams, E_NULL_POINTER, NULL);
1248 
1249     intFlags = FmPcdLock(p_FmPcd);
1250 
1251     /* find a new netEnv */
1252     for (i = 0; i < FM_MAX_NUM_OF_PORTS; i++)
1253         if (!p_FmPcd->netEnvs[i].used)
1254             break;
1255 
1256     if (i== FM_MAX_NUM_OF_PORTS)
1257     {
1258         REPORT_ERROR(MAJOR, E_FULL,("No more than %d netEnv's allowed.", FM_MAX_NUM_OF_PORTS));
1259         FmPcdUnlock(p_FmPcd, intFlags);
1260         return NULL;
1261     }
1262 
1263     p_FmPcd->netEnvs[i].used = TRUE;
1264     FmPcdUnlock(p_FmPcd, intFlags);
1265 
1266     /* As anyone doesn't have handle of this netEnv yet, no need
1267        to protect it with spinlocks */
1268 
1269     p_ModifiedNetEnvParams = (t_FmPcdNetEnvParams *)XX_Malloc(sizeof(t_FmPcdNetEnvParams));
1270     if (!p_ModifiedNetEnvParams)
1271     {
1272         REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FmPcdNetEnvParams"));
1273         return NULL;
1274     }
1275 
1276     memcpy(p_ModifiedNetEnvParams, p_NetEnvParams, sizeof(t_FmPcdNetEnvParams));
1277     p_NetEnvParams = p_ModifiedNetEnvParams;
1278 
1279     netEnvCurrId = (uint8_t)i;
1280 
1281     /* clear from previous use */
1282     memset(&p_FmPcd->netEnvs[netEnvCurrId].units, 0, FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS * sizeof(t_FmPcdIntDistinctionUnit));
1283     memset(&p_FmPcd->netEnvs[netEnvCurrId].aliasHdrs, 0, FM_PCD_MAX_NUM_OF_ALIAS_HDRS * sizeof(t_FmPcdNetEnvAliases));
1284     memcpy(&p_FmPcd->netEnvs[netEnvCurrId].units, p_NetEnvParams->units, p_NetEnvParams->numOfDistinctionUnits*sizeof(t_FmPcdIntDistinctionUnit));
1285 
1286     p_FmPcd->netEnvs[netEnvCurrId].netEnvId = netEnvCurrId;
1287     p_FmPcd->netEnvs[netEnvCurrId].h_FmPcd = p_FmPcd;
1288 
1289     p_FmPcd->netEnvs[netEnvCurrId].clsPlanGrpId = ILLEGAL_CLS_PLAN;
1290 
1291     /* check that header with opt is not interchanged with the same header */
1292     for (i = 0; (i < FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS)
1293             && (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[0].hdr != HEADER_TYPE_NONE); i++)
1294     {
1295         for (k = 0; (k < FM_PCD_MAX_NUM_OF_INTERCHANGEABLE_HDRS)
1296             && (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr != HEADER_TYPE_NONE); k++)
1297         {
1298             /* if an option exists, check that other headers are not the same header
1299             without option */
1300             if (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].opt)
1301             {
1302                 for (j = 0; (j < FM_PCD_MAX_NUM_OF_INTERCHANGEABLE_HDRS)
1303                         && (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[j].hdr != HEADER_TYPE_NONE); j++)
1304                 {
1305                     if ((p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[j].hdr == p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr) &&
1306                         !p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[j].opt)
1307                     {
1308                         REPORT_ERROR(MINOR, E_FULL,
1309                                 ("Illegal unit - header with opt may not be interchangeable with the same header without opt"));
1310                         XX_Free(p_ModifiedNetEnvParams);
1311                         return NULL;
1312                     }
1313                 }
1314             }
1315         }
1316     }
1317 
1318     /* Specific headers checking  */
1319     for (i = 0; (i < FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS)
1320         && (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[0].hdr != HEADER_TYPE_NONE); i++)
1321     {
1322         for (k = 0; (k < FM_PCD_MAX_NUM_OF_INTERCHANGEABLE_HDRS)
1323             && (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr != HEADER_TYPE_NONE); k++)
1324         {
1325             /* Some headers pairs may not be defined on different units as the parser
1326             doesn't distinguish */
1327             /* IPSEC_AH and IPSEC_SPI can't be 2 units,  */
1328             /* check that header with opt is not interchanged with the same header */
1329             if (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr == HEADER_TYPE_IPSEC_AH)
1330             {
1331                 if (ipsecEspExists && (ipsecEspUnit != i))
1332                 {
1333                     REPORT_ERROR(MINOR, E_INVALID_STATE, ("HEADER_TYPE_IPSEC_AH and HEADER_TYPE_IPSEC_ESP may not be defined in separate units"));
1334                     XX_Free(p_ModifiedNetEnvParams);
1335                     return NULL;
1336                 }
1337                 else
1338                 {
1339                     ipsecAhUnit = i;
1340                     ipsecAhExists = TRUE;
1341                 }
1342             }
1343             if (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr == HEADER_TYPE_IPSEC_ESP)
1344             {
1345                 if (ipsecAhExists && (ipsecAhUnit != i))
1346                 {
1347                     REPORT_ERROR(MINOR, E_INVALID_STATE, ("HEADER_TYPE_IPSEC_AH and HEADER_TYPE_IPSEC_ESP may not be defined in separate units"));
1348                     XX_Free(p_ModifiedNetEnvParams);
1349                     return NULL;
1350                 }
1351                 else
1352                 {
1353                     ipsecEspUnit = i;
1354                     ipsecEspExists = TRUE;
1355                 }
1356             }
1357             /* ENCAP_ESP  */
1358             if (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr == HEADER_TYPE_UDP_ENCAP_ESP)
1359             {
1360                 /* IPSec UDP encapsulation is currently set to use SHIM1 */
1361                 p_FmPcd->netEnvs[netEnvCurrId].aliasHdrs[specialUnits].hdr = HEADER_TYPE_UDP_ENCAP_ESP;
1362                 p_FmPcd->netEnvs[netEnvCurrId].aliasHdrs[specialUnits++].aliasHdr = HEADER_TYPE_USER_DEFINED_SHIM1;
1363                 p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr = HEADER_TYPE_USER_DEFINED_SHIM1;
1364                 p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].opt = 0;
1365             }
1366 #if (DPAA_VERSION >= 11) || ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT))
1367             /* UDP_LITE  */
1368             if (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr == HEADER_TYPE_UDP_LITE)
1369             {
1370                 p_FmPcd->netEnvs[netEnvCurrId].aliasHdrs[specialUnits].hdr = HEADER_TYPE_UDP_LITE;
1371                 p_FmPcd->netEnvs[netEnvCurrId].aliasHdrs[specialUnits++].aliasHdr = HEADER_TYPE_UDP;
1372                 p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr = HEADER_TYPE_UDP;
1373                 p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].opt = 0;
1374             }
1375 #endif /* (DPAA_VERSION >= 11) || ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT)) */
1376 
1377             /* IP FRAG  */
1378             if ((p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr == HEADER_TYPE_IPv4) &&
1379                 (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].opt == IPV4_FRAG_1))
1380             {
1381                 /* If IPv4+Frag, we need to set 2 units - SHIM 2 and IPv4. We first set SHIM2, and than check if
1382                  * IPv4 exists. If so we don't need to set an extra unit
1383                  * We consider as "having IPv4" any IPv4 without interchangable headers
1384                  * but including any options.  */
1385                 p_FmPcd->netEnvs[netEnvCurrId].aliasHdrs[specialUnits].hdr = HEADER_TYPE_IPv4;
1386                 p_FmPcd->netEnvs[netEnvCurrId].aliasHdrs[specialUnits].opt = IPV4_FRAG_1;
1387                 p_FmPcd->netEnvs[netEnvCurrId].aliasHdrs[specialUnits++].aliasHdr = HEADER_TYPE_USER_DEFINED_SHIM2;
1388                 p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr = HEADER_TYPE_USER_DEFINED_SHIM2;
1389                 p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].opt = 0;
1390 
1391                 /* check if IPv4 header exists by itself */
1392                 if (FmPcdNetEnvGetUnitId(p_FmPcd, netEnvCurrId, HEADER_TYPE_IPv4, FALSE, 0) == FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS)
1393                 {
1394                     p_FmPcd->netEnvs[netEnvCurrId].units[p_NetEnvParams->numOfDistinctionUnits].hdrs[0].hdr = HEADER_TYPE_IPv4;
1395                     p_FmPcd->netEnvs[netEnvCurrId].units[p_NetEnvParams->numOfDistinctionUnits++].hdrs[0].opt = 0;
1396                 }
1397             }
1398             if ((p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr == HEADER_TYPE_IPv6) &&
1399                 (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].opt == IPV6_FRAG_1))
1400             {
1401                 /* If IPv6+Frag, we need to set 2 units - SHIM 2 and IPv6. We first set SHIM2, and than check if
1402                  * IPv4 exists. If so we don't need to set an extra unit
1403                  * We consider as "having IPv6" any IPv6 without interchangable headers
1404                  * but including any options.  */
1405                 p_FmPcd->netEnvs[netEnvCurrId].aliasHdrs[specialUnits].hdr = HEADER_TYPE_IPv6;
1406                 p_FmPcd->netEnvs[netEnvCurrId].aliasHdrs[specialUnits].opt = IPV6_FRAG_1;
1407                 p_FmPcd->netEnvs[netEnvCurrId].aliasHdrs[specialUnits++].aliasHdr = HEADER_TYPE_USER_DEFINED_SHIM2;
1408                 p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr = HEADER_TYPE_USER_DEFINED_SHIM2;
1409                 p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].opt = 0;
1410 
1411                 /* check if IPv6 header exists by itself */
1412                 if (FmPcdNetEnvGetUnitId(p_FmPcd, netEnvCurrId, HEADER_TYPE_IPv6, FALSE, 0) == FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS)
1413                 {
1414                     p_FmPcd->netEnvs[netEnvCurrId].units[p_NetEnvParams->numOfDistinctionUnits].hdrs[0].hdr = HEADER_TYPE_IPv6;
1415                     p_FmPcd->netEnvs[netEnvCurrId].units[p_NetEnvParams->numOfDistinctionUnits++].hdrs[0].opt = 0;
1416                 }
1417             }
1418 #if (DPAA_VERSION >= 11)
1419             /* CAPWAP FRAG  */
1420             if ((p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr == HEADER_TYPE_CAPWAP) &&
1421                 (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].opt == CAPWAP_FRAG_1))
1422             {
1423                 p_FmPcd->netEnvs[netEnvCurrId].aliasHdrs[specialUnits].hdr = HEADER_TYPE_CAPWAP;
1424                 p_FmPcd->netEnvs[netEnvCurrId].aliasHdrs[specialUnits].opt = CAPWAP_FRAG_1;
1425                 p_FmPcd->netEnvs[netEnvCurrId].aliasHdrs[specialUnits++].aliasHdr = HEADER_TYPE_USER_DEFINED_SHIM2;
1426                 p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr = HEADER_TYPE_USER_DEFINED_SHIM2;
1427                 p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].opt = 0;
1428             }
1429 #endif /* (DPAA_VERSION >= 11) */
1430         }
1431     }
1432 
1433     /* if private header (shim), check that no other headers specified */
1434     for (i = 0; (i < FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS)
1435         && (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[0].hdr != HEADER_TYPE_NONE); i++)
1436     {
1437         if (IS_PRIVATE_HEADER(p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[0].hdr))
1438             if (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[1].hdr != HEADER_TYPE_NONE)
1439             {
1440                 REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("SHIM header may not be interchanged with other headers"));
1441                 XX_Free(p_ModifiedNetEnvParams);
1442                 return NULL;
1443             }
1444     }
1445 
1446     for (i = 0; i < p_NetEnvParams->numOfDistinctionUnits; i++)
1447     {
1448         if (IS_PRIVATE_HEADER(p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[0].hdr))
1449             switch (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[0].hdr)
1450             {
1451                 case (HEADER_TYPE_USER_DEFINED_SHIM1):
1452                     if (shim1Selected)
1453                     {
1454                         REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("SHIM header cannot be selected with UDP_IPSEC_ESP"));
1455                         XX_Free(p_ModifiedNetEnvParams);
1456                         return NULL;
1457                     }
1458                     shim1Selected = TRUE;
1459                     p_FmPcd->netEnvs[netEnvCurrId].unitsVectors[i] = 0x00000001;
1460                     break;
1461                 case (HEADER_TYPE_USER_DEFINED_SHIM2):
1462                     p_FmPcd->netEnvs[netEnvCurrId].unitsVectors[i] = 0x00000002;
1463                     break;
1464                 default:
1465                     REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Requested SHIM not supported"));
1466             }
1467         else
1468         {
1469             p_FmPcd->netEnvs[netEnvCurrId].unitsVectors[i] = (uint32_t)(0x80000000 >> bitId++);
1470 
1471             if (IS_SPECIAL_HEADER(p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[0].hdr))
1472                 p_FmPcd->netEnvs[netEnvCurrId].macsecVector = p_FmPcd->netEnvs[netEnvCurrId].unitsVectors[i];
1473         }
1474     }
1475 
1476     /* define a set of hardware parser LCV's according to the defined netenv */
1477 
1478     /* set an array of LCV's for each header in the netEnv */
1479     for (i = 0; (i < FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS)
1480         && (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[0].hdr != HEADER_TYPE_NONE); i++)
1481     {
1482         /* private headers have no LCV in the hard parser */
1483         if (!IS_PRIVATE_HEADER(p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[0].hdr))
1484         {
1485             for (k = 0; (k < FM_PCD_MAX_NUM_OF_INTERCHANGEABLE_HDRS)
1486                     && (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr != HEADER_TYPE_NONE); k++)
1487             {
1488                 hdrNum = GetPrsHdrNum(p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr);
1489                 if ((hdrNum == ILLEGAL_HDR_NUM) || (hdrNum == NO_HDR_NUM))
1490                 {
1491                     REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, NO_MSG);
1492                     XX_Free(p_ModifiedNetEnvParams);
1493                     return NULL;
1494                 }
1495                 p_FmPcd->netEnvs[netEnvCurrId].lcvs[hdrNum] |= p_FmPcd->netEnvs[netEnvCurrId].unitsVectors[i];
1496             }
1497         }
1498     }
1499     XX_Free(p_ModifiedNetEnvParams);
1500 
1501     p_FmPcd->netEnvs[netEnvCurrId].h_Spinlock = XX_InitSpinlock();
1502     if (!p_FmPcd->netEnvs[netEnvCurrId].h_Spinlock)
1503     {
1504         REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM Pcd NetEnv spinlock"));
1505         return NULL;
1506     }
1507     return &p_FmPcd->netEnvs[netEnvCurrId];
1508 }
1509 
1510 t_Error FM_PCD_NetEnvCharacteristicsDelete(t_Handle h_NetEnv)
1511 {
1512     t_FmPcdNetEnv   *p_NetEnv = (t_FmPcdNetEnv*)h_NetEnv;
1513     t_FmPcd         *p_FmPcd = p_NetEnv->h_FmPcd;
1514     uint32_t        intFlags;
1515     uint8_t         netEnvId = p_NetEnv->netEnvId;
1516 
1517     SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_STATE);
1518     SANITY_CHECK_RETURN_ERROR(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_STATE);
1519 
1520     /* check that no port is bound to this netEnv */
1521     if (p_FmPcd->netEnvs[netEnvId].owners)
1522     {
1523         RETURN_ERROR(MINOR, E_INVALID_STATE,
1524                 ("Trying to delete a netEnv that has ports/schemes/trees/clsPlanGrps bound to"));
1525     }
1526 
1527     intFlags = FmPcdLock(p_FmPcd);
1528 
1529     p_FmPcd->netEnvs[netEnvId].used = FALSE;
1530     p_FmPcd->netEnvs[netEnvId].clsPlanGrpId = ILLEGAL_CLS_PLAN;
1531 
1532     memset(p_FmPcd->netEnvs[netEnvId].units, 0, sizeof(t_FmPcdIntDistinctionUnit)*FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS);
1533     memset(p_FmPcd->netEnvs[netEnvId].unitsVectors, 0, sizeof(uint32_t)*FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS);
1534     memset(p_FmPcd->netEnvs[netEnvId].lcvs, 0, sizeof(uint32_t)*FM_PCD_PRS_NUM_OF_HDRS);
1535 
1536     if (p_FmPcd->netEnvs[netEnvId].h_Spinlock)
1537         XX_FreeSpinlock(p_FmPcd->netEnvs[netEnvId].h_Spinlock);
1538 
1539     FmPcdUnlock(p_FmPcd, intFlags);
1540     return E_OK;
1541 }
1542 
1543 void FM_PCD_HcTxConf(t_Handle h_FmPcd, t_DpaaFD *p_Fd)
1544 {
1545     t_FmPcd                 *p_FmPcd = (t_FmPcd*)h_FmPcd;
1546 
1547     SANITY_CHECK_RETURN(h_FmPcd, E_INVALID_STATE);
1548 
1549     FmHcTxConf(p_FmPcd->h_Hc, p_Fd);
1550 }
1551 
1552 t_Error FM_PCD_SetAdvancedOffloadSupport(t_Handle h_FmPcd)
1553 {
1554     t_FmPcd                     *p_FmPcd = (t_FmPcd*)h_FmPcd;
1555     t_FmCtrlCodeRevisionInfo    revInfo;
1556     t_Error                     err;
1557 
1558     SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
1559     SANITY_CHECK_RETURN_ERROR(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_STATE);
1560     SANITY_CHECK_RETURN_ERROR(!p_FmPcd->enabled, E_INVALID_STATE);
1561 
1562     if ((err = FM_GetFmanCtrlCodeRevision(p_FmPcd->h_Fm, &revInfo)) != E_OK)
1563     {
1564         DBG(WARNING, ("FM in guest-mode without IPC, can't validate firmware revision."));
1565         revInfo.packageRev = IP_OFFLOAD_PACKAGE_NUMBER;
1566     }
1567     if (!IS_OFFLOAD_PACKAGE(revInfo.packageRev))
1568         RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("Fman ctrl code package"));
1569 
1570     if (!p_FmPcd->h_Hc)
1571         RETURN_ERROR(MAJOR, E_INVALID_HANDLE, ("HC must be initialized in this mode"));
1572 
1573     p_FmPcd->advancedOffloadSupport = TRUE;
1574 
1575     return E_OK;
1576 }
1577 
1578 uint32_t FM_PCD_GetCounter(t_Handle h_FmPcd, e_FmPcdCounters counter)
1579 {
1580     t_FmPcd                 *p_FmPcd = (t_FmPcd*)h_FmPcd;
1581     uint32_t                outCounter = 0;
1582     t_Error                 err;
1583 
1584     SANITY_CHECK_RETURN_VALUE(h_FmPcd, E_INVALID_HANDLE, 0);
1585     SANITY_CHECK_RETURN_VALUE(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_STATE, 0);
1586 
1587     switch (counter)
1588     {
1589         case (e_FM_PCD_KG_COUNTERS_TOTAL):
1590             if (!p_FmPcd->p_FmPcdKg)
1591             {
1592                 REPORT_ERROR(MAJOR, E_INVALID_STATE, ("KeyGen is not activated"));
1593                 return 0;
1594             }
1595             if ((p_FmPcd->guestId != NCSW_MASTER_ID) &&
1596                 !p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs &&
1597                 !p_FmPcd->h_IpcSession)
1598             {
1599                 REPORT_ERROR(MINOR, E_NOT_SUPPORTED,
1600                              ("running in guest-mode without neither IPC nor mapped register!"));
1601                 return 0;
1602             }
1603             break;
1604 
1605         case (e_FM_PCD_PLCR_COUNTERS_YELLOW):
1606         case (e_FM_PCD_PLCR_COUNTERS_RED):
1607         case (e_FM_PCD_PLCR_COUNTERS_RECOLORED_TO_RED):
1608         case (e_FM_PCD_PLCR_COUNTERS_RECOLORED_TO_YELLOW):
1609         case (e_FM_PCD_PLCR_COUNTERS_TOTAL):
1610         case (e_FM_PCD_PLCR_COUNTERS_LENGTH_MISMATCH):
1611             if (!p_FmPcd->p_FmPcdPlcr)
1612             {
1613                 REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Policer is not activated"));
1614                 return 0;
1615             }
1616             if ((p_FmPcd->guestId != NCSW_MASTER_ID) &&
1617                 !p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs &&
1618                 !p_FmPcd->h_IpcSession)
1619             {
1620                 REPORT_ERROR(MINOR, E_NOT_SUPPORTED,
1621                              ("running in \"guest-mode\" without neither IPC nor mapped register!"));
1622                 return 0;
1623             }
1624 
1625             /* check that counters are enabled */
1626             if (p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs &&
1627                 !(GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_gcr) & FM_PCD_PLCR_GCR_STEN))
1628             {
1629                 REPORT_ERROR(MINOR, E_INVALID_STATE, ("Requested counter was not enabled"));
1630                 return 0;
1631             }
1632             ASSERT_COND(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs ||
1633                         ((p_FmPcd->guestId != NCSW_MASTER_ID) && p_FmPcd->h_IpcSession));
1634             break;
1635 
1636         case (e_FM_PCD_PRS_COUNTERS_PARSE_DISPATCH):
1637         case (e_FM_PCD_PRS_COUNTERS_L2_PARSE_RESULT_RETURNED):
1638         case (e_FM_PCD_PRS_COUNTERS_L3_PARSE_RESULT_RETURNED):
1639         case (e_FM_PCD_PRS_COUNTERS_L4_PARSE_RESULT_RETURNED):
1640         case (e_FM_PCD_PRS_COUNTERS_SHIM_PARSE_RESULT_RETURNED):
1641         case (e_FM_PCD_PRS_COUNTERS_L2_PARSE_RESULT_RETURNED_WITH_ERR):
1642         case (e_FM_PCD_PRS_COUNTERS_L3_PARSE_RESULT_RETURNED_WITH_ERR):
1643         case (e_FM_PCD_PRS_COUNTERS_L4_PARSE_RESULT_RETURNED_WITH_ERR):
1644         case (e_FM_PCD_PRS_COUNTERS_SHIM_PARSE_RESULT_RETURNED_WITH_ERR):
1645         case (e_FM_PCD_PRS_COUNTERS_SOFT_PRS_CYCLES):
1646         case (e_FM_PCD_PRS_COUNTERS_SOFT_PRS_STALL_CYCLES):
1647         case (e_FM_PCD_PRS_COUNTERS_HARD_PRS_CYCLE_INCL_STALL_CYCLES):
1648         case (e_FM_PCD_PRS_COUNTERS_MURAM_READ_CYCLES):
1649         case (e_FM_PCD_PRS_COUNTERS_MURAM_READ_STALL_CYCLES):
1650         case (e_FM_PCD_PRS_COUNTERS_MURAM_WRITE_CYCLES):
1651         case (e_FM_PCD_PRS_COUNTERS_MURAM_WRITE_STALL_CYCLES):
1652         case (e_FM_PCD_PRS_COUNTERS_FPM_COMMAND_STALL_CYCLES):
1653             if (!p_FmPcd->p_FmPcdPrs)
1654             {
1655                 REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Parser is not activated"));
1656                 return 0;
1657             }
1658             if ((p_FmPcd->guestId != NCSW_MASTER_ID) &&
1659                 !p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs &&
1660                 !p_FmPcd->h_IpcSession)
1661             {
1662                 REPORT_ERROR(MINOR, E_NOT_SUPPORTED,
1663                              ("running in guest-mode without neither IPC nor mapped register!"));
1664                 return 0;
1665             }
1666             break;
1667         default:
1668             REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Unsupported type of counter"));
1669             return 0;
1670     }
1671 
1672     if ((p_FmPcd->guestId != NCSW_MASTER_ID) &&
1673         p_FmPcd->h_IpcSession)
1674     {
1675         t_FmPcdIpcMsg           msg;
1676         t_FmPcdIpcReply         reply;
1677         uint32_t                replyLength;
1678 
1679         memset(&msg, 0, sizeof(msg));
1680         memset(&reply, 0, sizeof(reply));
1681         msg.msgId = FM_PCD_GET_COUNTER;
1682         memcpy(msg.msgBody, (uint8_t *)&counter, sizeof(uint32_t));
1683         replyLength = sizeof(uint32_t) + sizeof(uint32_t);
1684         if ((err = XX_IpcSendMessage(p_FmPcd->h_IpcSession,
1685                                      (uint8_t*)&msg,
1686                                      sizeof(msg.msgId) +sizeof(uint32_t),
1687                                      (uint8_t*)&reply,
1688                                      &replyLength,
1689                                      NULL,
1690                                      NULL)) != E_OK)
1691             RETURN_ERROR(MAJOR, err, NO_MSG);
1692         if (replyLength != sizeof(uint32_t) + sizeof(uint32_t))
1693             RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
1694 
1695         memcpy((uint8_t*)&outCounter, reply.replyBody, sizeof(uint32_t));
1696         return outCounter;
1697     }
1698 
1699     switch (counter)
1700     {
1701         /* Parser statistics */
1702         case (e_FM_PCD_PRS_COUNTERS_PARSE_DISPATCH):
1703                return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_pds);
1704         case (e_FM_PCD_PRS_COUNTERS_L2_PARSE_RESULT_RETURNED):
1705                return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_l2rrs);
1706         case (e_FM_PCD_PRS_COUNTERS_L3_PARSE_RESULT_RETURNED):
1707                return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_l3rrs);
1708         case (e_FM_PCD_PRS_COUNTERS_L4_PARSE_RESULT_RETURNED):
1709                return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_l4rrs);
1710         case (e_FM_PCD_PRS_COUNTERS_SHIM_PARSE_RESULT_RETURNED):
1711                return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_srrs);
1712         case (e_FM_PCD_PRS_COUNTERS_L2_PARSE_RESULT_RETURNED_WITH_ERR):
1713                return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_l2rres);
1714         case (e_FM_PCD_PRS_COUNTERS_L3_PARSE_RESULT_RETURNED_WITH_ERR):
1715                return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_l3rres);
1716         case (e_FM_PCD_PRS_COUNTERS_L4_PARSE_RESULT_RETURNED_WITH_ERR):
1717                return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_l4rres);
1718         case (e_FM_PCD_PRS_COUNTERS_SHIM_PARSE_RESULT_RETURNED_WITH_ERR):
1719                return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_srres);
1720         case (e_FM_PCD_PRS_COUNTERS_SOFT_PRS_CYCLES):
1721                return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_spcs);
1722         case (e_FM_PCD_PRS_COUNTERS_SOFT_PRS_STALL_CYCLES):
1723                return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_spscs);
1724         case (e_FM_PCD_PRS_COUNTERS_HARD_PRS_CYCLE_INCL_STALL_CYCLES):
1725                return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_hxscs);
1726         case (e_FM_PCD_PRS_COUNTERS_MURAM_READ_CYCLES):
1727                return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_mrcs);
1728         case (e_FM_PCD_PRS_COUNTERS_MURAM_READ_STALL_CYCLES):
1729                return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_mrscs);
1730         case (e_FM_PCD_PRS_COUNTERS_MURAM_WRITE_CYCLES):
1731                return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_mwcs);
1732         case (e_FM_PCD_PRS_COUNTERS_MURAM_WRITE_STALL_CYCLES):
1733                return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_mwscs);
1734         case (e_FM_PCD_PRS_COUNTERS_FPM_COMMAND_STALL_CYCLES):
1735                return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_fcscs);
1736         case (e_FM_PCD_KG_COUNTERS_TOTAL):
1737                return GET_UINT32(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->fmkg_tpc);
1738 
1739         /* Policer statistics */
1740         case (e_FM_PCD_PLCR_COUNTERS_YELLOW):
1741                 return GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_ypcnt);
1742         case (e_FM_PCD_PLCR_COUNTERS_RED):
1743                 return GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_rpcnt);
1744         case (e_FM_PCD_PLCR_COUNTERS_RECOLORED_TO_RED):
1745                 return GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_rrpcnt);
1746         case (e_FM_PCD_PLCR_COUNTERS_RECOLORED_TO_YELLOW):
1747                 return GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_rypcnt);
1748         case (e_FM_PCD_PLCR_COUNTERS_TOTAL):
1749                 return GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_tpcnt);
1750         case (e_FM_PCD_PLCR_COUNTERS_LENGTH_MISMATCH):
1751                 return GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_flmcnt);
1752     }
1753     return 0;
1754 }
1755 
1756 t_Error FM_PCD_SetException(t_Handle h_FmPcd, e_FmPcdExceptions exception, bool enable)
1757 {
1758     t_FmPcd         *p_FmPcd = (t_FmPcd*)h_FmPcd;
1759     uint32_t        bitMask = 0, tmpReg;
1760 
1761     SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
1762     SANITY_CHECK_RETURN_ERROR(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_STATE);
1763 
1764     if (p_FmPcd->guestId != NCSW_MASTER_ID)
1765         RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("FM_PCD_SetException - guest mode!"));
1766 
1767     GET_FM_PCD_EXCEPTION_FLAG(bitMask, exception);
1768 
1769     if (bitMask)
1770     {
1771         if (enable)
1772             p_FmPcd->exceptions |= bitMask;
1773         else
1774             p_FmPcd->exceptions &= ~bitMask;
1775 
1776         switch (exception)
1777         {
1778             case (e_FM_PCD_KG_EXCEPTION_DOUBLE_ECC):
1779             case (e_FM_PCD_KG_EXCEPTION_KEYSIZE_OVERFLOW):
1780                 if (!p_FmPcd->p_FmPcdKg)
1781                     RETURN_ERROR(MINOR, E_INVALID_STATE, ("Can't ask for this interrupt - keygen is not working"));
1782                 break;
1783             case (e_FM_PCD_PLCR_EXCEPTION_DOUBLE_ECC):
1784             case (e_FM_PCD_PLCR_EXCEPTION_INIT_ENTRY_ERROR):
1785             case (e_FM_PCD_PLCR_EXCEPTION_PRAM_SELF_INIT_COMPLETE):
1786             case (e_FM_PCD_PLCR_EXCEPTION_ATOMIC_ACTION_COMPLETE):
1787                 if (!p_FmPcd->p_FmPcdPlcr)
1788                     RETURN_ERROR(MINOR, E_INVALID_STATE, ("Can't ask for this interrupt - policer is not working"));
1789                 break;
1790             case (e_FM_PCD_PRS_EXCEPTION_DOUBLE_ECC):
1791             case (e_FM_PCD_PRS_EXCEPTION_SINGLE_ECC):
1792                 if (!p_FmPcd->p_FmPcdPrs)
1793                     RETURN_ERROR(MINOR, E_INVALID_STATE, ("Can't ask for this interrupt - parser is not working"));
1794                 break;
1795         }
1796 
1797         switch (exception)
1798         {
1799             case (e_FM_PCD_KG_EXCEPTION_DOUBLE_ECC):
1800                 tmpReg = GET_UINT32(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->fmkg_eeer);
1801                 if (enable)
1802                     tmpReg |= FM_EX_KG_DOUBLE_ECC;
1803                 else
1804                     tmpReg &= ~FM_EX_KG_DOUBLE_ECC;
1805                 WRITE_UINT32(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->fmkg_eeer, tmpReg);
1806                 break;
1807             case (e_FM_PCD_KG_EXCEPTION_KEYSIZE_OVERFLOW):
1808                 tmpReg = GET_UINT32(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->fmkg_eeer);
1809                 if (enable)
1810                     tmpReg |= FM_EX_KG_KEYSIZE_OVERFLOW;
1811                 else
1812                     tmpReg &= ~FM_EX_KG_KEYSIZE_OVERFLOW;
1813                 WRITE_UINT32(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->fmkg_eeer, tmpReg);
1814                 break;
1815             case (e_FM_PCD_PRS_EXCEPTION_DOUBLE_ECC):
1816                 tmpReg = GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_perer);
1817                 if (enable)
1818                     tmpReg |= FM_PCD_PRS_DOUBLE_ECC;
1819                 else
1820                     tmpReg &= ~FM_PCD_PRS_DOUBLE_ECC;
1821                 WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_perer, tmpReg);
1822                 break;
1823             case (e_FM_PCD_PRS_EXCEPTION_SINGLE_ECC):
1824                 tmpReg = GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_pever);
1825                 if (enable)
1826                     tmpReg |= FM_PCD_PRS_SINGLE_ECC;
1827                 else
1828                     tmpReg &= ~FM_PCD_PRS_SINGLE_ECC;
1829                 WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_pever, tmpReg);
1830                 break;
1831             case (e_FM_PCD_PLCR_EXCEPTION_DOUBLE_ECC):
1832                 tmpReg = GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_eier);
1833                 if (enable)
1834                     tmpReg |= FM_PCD_PLCR_DOUBLE_ECC;
1835                 else
1836                     tmpReg &= ~FM_PCD_PLCR_DOUBLE_ECC;
1837                 WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_eier, tmpReg);
1838                 break;
1839             case (e_FM_PCD_PLCR_EXCEPTION_INIT_ENTRY_ERROR):
1840                 tmpReg = GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_eier);
1841                 if (enable)
1842                     tmpReg |= FM_PCD_PLCR_INIT_ENTRY_ERROR;
1843                 else
1844                     tmpReg &= ~FM_PCD_PLCR_INIT_ENTRY_ERROR;
1845                 WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_eier, tmpReg);
1846                 break;
1847             case (e_FM_PCD_PLCR_EXCEPTION_PRAM_SELF_INIT_COMPLETE):
1848                 tmpReg = GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_ier);
1849                 if (enable)
1850                     tmpReg |= FM_PCD_PLCR_PRAM_SELF_INIT_COMPLETE;
1851                 else
1852                     tmpReg &= ~FM_PCD_PLCR_PRAM_SELF_INIT_COMPLETE;
1853                 WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_ier, tmpReg);
1854                 break;
1855             case (e_FM_PCD_PLCR_EXCEPTION_ATOMIC_ACTION_COMPLETE):
1856                 tmpReg = GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_ier);
1857                 if (enable)
1858                     tmpReg |= FM_PCD_PLCR_ATOMIC_ACTION_COMPLETE;
1859                 else
1860                     tmpReg &= ~FM_PCD_PLCR_ATOMIC_ACTION_COMPLETE;
1861                 WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_ier, tmpReg);
1862                 break;
1863         }
1864         /* for ECC exceptions driver automatically enables ECC mechanism, if disabled.
1865            Driver may disable them automatically, depending on driver's status */
1866         if (enable && ((exception == e_FM_PCD_KG_EXCEPTION_DOUBLE_ECC) |
1867                        (exception == e_FM_PCD_PLCR_EXCEPTION_DOUBLE_ECC) |
1868                        (exception == e_FM_PCD_PRS_EXCEPTION_DOUBLE_ECC) |
1869                        (exception == e_FM_PCD_PRS_EXCEPTION_SINGLE_ECC)))
1870             FmEnableRamsEcc(p_FmPcd->h_Fm);
1871         if (!enable && ((exception == e_FM_PCD_KG_EXCEPTION_DOUBLE_ECC) |
1872                        (exception == e_FM_PCD_PLCR_EXCEPTION_DOUBLE_ECC) |
1873                        (exception == e_FM_PCD_PRS_EXCEPTION_DOUBLE_ECC) |
1874                        (exception == e_FM_PCD_PRS_EXCEPTION_SINGLE_ECC)))
1875             FmDisableRamsEcc(p_FmPcd->h_Fm);
1876     }
1877 
1878     return E_OK;
1879 }
1880 
1881 t_Error FM_PCD_ForceIntr (t_Handle h_FmPcd, e_FmPcdExceptions exception)
1882 {
1883     t_FmPcd            *p_FmPcd = (t_FmPcd*)h_FmPcd;
1884 
1885     SANITY_CHECK_RETURN_ERROR(h_FmPcd, E_INVALID_HANDLE);
1886     SANITY_CHECK_RETURN_ERROR(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_STATE);
1887 
1888     if (p_FmPcd->guestId != NCSW_MASTER_ID)
1889         RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("FM_PCD_ForceIntr - guest mode!"));
1890 
1891     switch (exception)
1892     {
1893         case (e_FM_PCD_KG_EXCEPTION_DOUBLE_ECC):
1894         case (e_FM_PCD_KG_EXCEPTION_KEYSIZE_OVERFLOW):
1895             if (!p_FmPcd->p_FmPcdKg)
1896                 RETURN_ERROR(MINOR, E_INVALID_STATE, ("Can't ask for this interrupt - keygen is not working"));
1897             break;
1898         case (e_FM_PCD_PLCR_EXCEPTION_DOUBLE_ECC):
1899         case (e_FM_PCD_PLCR_EXCEPTION_INIT_ENTRY_ERROR):
1900         case (e_FM_PCD_PLCR_EXCEPTION_PRAM_SELF_INIT_COMPLETE):
1901         case (e_FM_PCD_PLCR_EXCEPTION_ATOMIC_ACTION_COMPLETE):
1902             if (!p_FmPcd->p_FmPcdPlcr)
1903                 RETURN_ERROR(MINOR, E_INVALID_STATE, ("Can't ask for this interrupt - policer is not working"));
1904             break;
1905         case (e_FM_PCD_PRS_EXCEPTION_DOUBLE_ECC):
1906         case (e_FM_PCD_PRS_EXCEPTION_SINGLE_ECC):
1907            if (!p_FmPcd->p_FmPcdPrs)
1908                 RETURN_ERROR(MINOR, E_INVALID_STATE, ("Can't ask for this interrupt -parsrer is not working"));
1909             break;
1910         default:
1911             RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid interrupt requested"));
1912     }
1913     switch (exception)
1914     {
1915         case e_FM_PCD_PRS_EXCEPTION_DOUBLE_ECC:
1916             if (!(p_FmPcd->exceptions & FM_PCD_EX_PRS_DOUBLE_ECC))
1917                 RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked"));
1918             break;
1919         case e_FM_PCD_PRS_EXCEPTION_SINGLE_ECC:
1920             if (!(p_FmPcd->exceptions & FM_PCD_EX_PRS_SINGLE_ECC))
1921                 RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked"));
1922             break;
1923         case e_FM_PCD_KG_EXCEPTION_DOUBLE_ECC:
1924             if (!(p_FmPcd->exceptions & FM_EX_KG_DOUBLE_ECC))
1925                 RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked"));
1926             WRITE_UINT32(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->fmkg_feer, FM_EX_KG_DOUBLE_ECC);
1927             break;
1928         case e_FM_PCD_KG_EXCEPTION_KEYSIZE_OVERFLOW:
1929             if (!(p_FmPcd->exceptions & FM_EX_KG_KEYSIZE_OVERFLOW))
1930                 RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked"));
1931             WRITE_UINT32(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->fmkg_feer, FM_EX_KG_KEYSIZE_OVERFLOW);
1932             break;
1933         case e_FM_PCD_PLCR_EXCEPTION_DOUBLE_ECC:
1934             if (!(p_FmPcd->exceptions & FM_PCD_EX_PLCR_DOUBLE_ECC))
1935                 RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked"));
1936             WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_eifr, FM_PCD_PLCR_DOUBLE_ECC);
1937             break;
1938         case e_FM_PCD_PLCR_EXCEPTION_INIT_ENTRY_ERROR:
1939             if (!(p_FmPcd->exceptions & FM_PCD_EX_PLCR_INIT_ENTRY_ERROR))
1940                 RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked"));
1941             WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_eifr, FM_PCD_PLCR_INIT_ENTRY_ERROR);
1942             break;
1943         case e_FM_PCD_PLCR_EXCEPTION_PRAM_SELF_INIT_COMPLETE:
1944             if (!(p_FmPcd->exceptions & FM_PCD_EX_PLCR_PRAM_SELF_INIT_COMPLETE))
1945                 RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked"));
1946             WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_ifr, FM_PCD_PLCR_PRAM_SELF_INIT_COMPLETE);
1947             break;
1948         case e_FM_PCD_PLCR_EXCEPTION_ATOMIC_ACTION_COMPLETE:
1949             if (!(p_FmPcd->exceptions & FM_PCD_EX_PLCR_ATOMIC_ACTION_COMPLETE))
1950                 RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked"));
1951             WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_ifr, FM_PCD_PLCR_ATOMIC_ACTION_COMPLETE);
1952             break;
1953     }
1954 
1955     return E_OK;
1956 }
1957 
1958 
1959 t_Error FM_PCD_ModifyCounter(t_Handle h_FmPcd, e_FmPcdCounters counter, uint32_t value)
1960 {
1961     t_FmPcd            *p_FmPcd = (t_FmPcd*)h_FmPcd;
1962 
1963     SANITY_CHECK_RETURN_ERROR(h_FmPcd, E_INVALID_HANDLE);
1964     SANITY_CHECK_RETURN_ERROR(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_STATE);
1965 
1966     if (p_FmPcd->guestId != NCSW_MASTER_ID)
1967         RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("FM_PCD_ModifyCounter - guest mode!"));
1968 
1969     switch (counter)
1970     {
1971         case (e_FM_PCD_KG_COUNTERS_TOTAL):
1972             if (!p_FmPcd->p_FmPcdKg)
1973                 RETURN_ERROR(MINOR, E_INVALID_STATE, ("Invalid counters - KeyGen is not working"));
1974             break;
1975         case (e_FM_PCD_PLCR_COUNTERS_YELLOW):
1976         case (e_FM_PCD_PLCR_COUNTERS_RED):
1977         case (e_FM_PCD_PLCR_COUNTERS_RECOLORED_TO_RED):
1978         case (e_FM_PCD_PLCR_COUNTERS_RECOLORED_TO_YELLOW):
1979         case (e_FM_PCD_PLCR_COUNTERS_TOTAL):
1980         case (e_FM_PCD_PLCR_COUNTERS_LENGTH_MISMATCH):
1981             if (!p_FmPcd->p_FmPcdPlcr)
1982                 RETURN_ERROR(MINOR, E_INVALID_STATE, ("Invalid counters - Policer is not working"));
1983             if (!(GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_gcr) & FM_PCD_PLCR_GCR_STEN))
1984                 RETURN_ERROR(MINOR, E_INVALID_STATE, ("Requested counter was not enabled"));
1985             break;
1986         case (e_FM_PCD_PRS_COUNTERS_PARSE_DISPATCH):
1987         case (e_FM_PCD_PRS_COUNTERS_L2_PARSE_RESULT_RETURNED):
1988         case (e_FM_PCD_PRS_COUNTERS_L3_PARSE_RESULT_RETURNED):
1989         case (e_FM_PCD_PRS_COUNTERS_L4_PARSE_RESULT_RETURNED):
1990         case (e_FM_PCD_PRS_COUNTERS_SHIM_PARSE_RESULT_RETURNED):
1991         case (e_FM_PCD_PRS_COUNTERS_L2_PARSE_RESULT_RETURNED_WITH_ERR):
1992         case (e_FM_PCD_PRS_COUNTERS_L3_PARSE_RESULT_RETURNED_WITH_ERR):
1993         case (e_FM_PCD_PRS_COUNTERS_L4_PARSE_RESULT_RETURNED_WITH_ERR):
1994         case (e_FM_PCD_PRS_COUNTERS_SHIM_PARSE_RESULT_RETURNED_WITH_ERR):
1995         case (e_FM_PCD_PRS_COUNTERS_SOFT_PRS_CYCLES):
1996         case (e_FM_PCD_PRS_COUNTERS_SOFT_PRS_STALL_CYCLES):
1997         case (e_FM_PCD_PRS_COUNTERS_HARD_PRS_CYCLE_INCL_STALL_CYCLES):
1998         case (e_FM_PCD_PRS_COUNTERS_MURAM_READ_CYCLES):
1999         case (e_FM_PCD_PRS_COUNTERS_MURAM_READ_STALL_CYCLES):
2000         case (e_FM_PCD_PRS_COUNTERS_MURAM_WRITE_CYCLES):
2001         case (e_FM_PCD_PRS_COUNTERS_MURAM_WRITE_STALL_CYCLES):
2002         case (e_FM_PCD_PRS_COUNTERS_FPM_COMMAND_STALL_CYCLES):
2003             if (!p_FmPcd->p_FmPcdPrs)
2004                 RETURN_ERROR(MINOR, E_INVALID_STATE, ("Unsupported type of counter"));
2005             break;
2006         default:
2007             RETURN_ERROR(MINOR, E_INVALID_STATE, ("Unsupported type of counter"));
2008     }
2009     switch (counter)
2010     {
2011         case (e_FM_PCD_PRS_COUNTERS_PARSE_DISPATCH):
2012                WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_pds, value);
2013             break;
2014         case (e_FM_PCD_PRS_COUNTERS_L2_PARSE_RESULT_RETURNED):
2015                WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_l2rrs, value);
2016             break;
2017         case (e_FM_PCD_PRS_COUNTERS_L3_PARSE_RESULT_RETURNED):
2018                WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_l3rrs, value);
2019              break;
2020        case (e_FM_PCD_PRS_COUNTERS_L4_PARSE_RESULT_RETURNED):
2021                WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_l4rrs, value);
2022             break;
2023         case (e_FM_PCD_PRS_COUNTERS_SHIM_PARSE_RESULT_RETURNED):
2024                WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_srrs, value);
2025             break;
2026         case (e_FM_PCD_PRS_COUNTERS_L2_PARSE_RESULT_RETURNED_WITH_ERR):
2027                WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_l2rres, value);
2028             break;
2029         case (e_FM_PCD_PRS_COUNTERS_L3_PARSE_RESULT_RETURNED_WITH_ERR):
2030                WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_l3rres, value);
2031             break;
2032         case (e_FM_PCD_PRS_COUNTERS_L4_PARSE_RESULT_RETURNED_WITH_ERR):
2033                WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_l4rres, value);
2034             break;
2035         case (e_FM_PCD_PRS_COUNTERS_SHIM_PARSE_RESULT_RETURNED_WITH_ERR):
2036                WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_srres, value);
2037             break;
2038         case (e_FM_PCD_PRS_COUNTERS_SOFT_PRS_CYCLES):
2039                WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_spcs, value);
2040             break;
2041         case (e_FM_PCD_PRS_COUNTERS_SOFT_PRS_STALL_CYCLES):
2042                WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_spscs, value);
2043             break;
2044         case (e_FM_PCD_PRS_COUNTERS_HARD_PRS_CYCLE_INCL_STALL_CYCLES):
2045                WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_hxscs, value);
2046             break;
2047         case (e_FM_PCD_PRS_COUNTERS_MURAM_READ_CYCLES):
2048                WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_mrcs, value);
2049             break;
2050         case (e_FM_PCD_PRS_COUNTERS_MURAM_READ_STALL_CYCLES):
2051                WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_mrscs, value);
2052             break;
2053         case (e_FM_PCD_PRS_COUNTERS_MURAM_WRITE_CYCLES):
2054                WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_mwcs, value);
2055             break;
2056         case (e_FM_PCD_PRS_COUNTERS_MURAM_WRITE_STALL_CYCLES):
2057                WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_mwscs, value);
2058             break;
2059         case (e_FM_PCD_PRS_COUNTERS_FPM_COMMAND_STALL_CYCLES):
2060                WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_fcscs, value);
2061              break;
2062         case (e_FM_PCD_KG_COUNTERS_TOTAL):
2063             WRITE_UINT32(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->fmkg_tpc,value);
2064             break;
2065 
2066         /*Policer counters*/
2067         case (e_FM_PCD_PLCR_COUNTERS_YELLOW):
2068             WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_ypcnt, value);
2069             break;
2070         case (e_FM_PCD_PLCR_COUNTERS_RED):
2071             WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_rpcnt, value);
2072             break;
2073         case (e_FM_PCD_PLCR_COUNTERS_RECOLORED_TO_RED):
2074              WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_rrpcnt, value);
2075             break;
2076         case (e_FM_PCD_PLCR_COUNTERS_RECOLORED_TO_YELLOW):
2077               WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_rypcnt, value);
2078             break;
2079         case (e_FM_PCD_PLCR_COUNTERS_TOTAL):
2080               WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_tpcnt, value);
2081             break;
2082         case (e_FM_PCD_PLCR_COUNTERS_LENGTH_MISMATCH):
2083               WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_flmcnt, value);
2084             break;
2085     }
2086 
2087     return E_OK;
2088 }
2089 
2090 t_Handle FM_PCD_GetHcPort(t_Handle h_FmPcd)
2091 {
2092     t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
2093     return FmHcGetPort(p_FmPcd->h_Hc);
2094 }
2095 
2096