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
60static 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
86static volatile bool blockingFlag = FALSE;
87static 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
97static 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
283static 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
289static 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
295static 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
304static 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
321static 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
330static 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
354static 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
373void 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
379t_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
430t_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
454t_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
473bool 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}
500bool  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
525uint8_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
565t_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
598e_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
615void   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
625uint32_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
633uint32_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
641uint8_t FmPcdGetNetEnvId(t_Handle h_NetEnv)
642{
643    return ((t_FmPcdNetEnv*)h_NetEnv)->netEnvId;
644}
645
646void 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
657void 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
669uint32_t FmPcdLock(t_Handle h_FmPcd)
670{
671    ASSERT_COND(h_FmPcd);
672    return XX_LockIntrSpinlock(((t_FmPcd*)h_FmPcd)->h_Spinlock);
673}
674
675void 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
681t_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
697void 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
707bool 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
743void 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
760t_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
768t_Handle FmPcdGetHcHandle(t_Handle h_FmPcd)
769{
770    ASSERT_COND(h_FmPcd);
771    return ((t_FmPcd*)h_FmPcd)->h_Hc;
772}
773
774bool 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
786t_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
906t_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
1018t_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
1084t_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
1108t_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
1118t_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
1174t_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
1233t_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
1510t_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
1543void 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
1552t_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
1578uint32_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
1756t_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
1881t_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
1959t_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
2090t_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