1/* Copyright (c) 2008-2011 Freescale Semiconductor, Inc.
2 * All rights reserved.
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 @File          fm_pcd.c
35
36 @Description   FM PCD ...
37*//***************************************************************************/
38#include "std_ext.h"
39#include "error_ext.h"
40#include "string_ext.h"
41#include "xx_ext.h"
42#include "sprint_ext.h"
43#include "debug_ext.h"
44#include "net_ext.h"
45#include "fm_ext.h"
46#include "fm_pcd_ext.h"
47
48#include "fm_common.h"
49#include "fm_pcd.h"
50#include "fm_pcd_ipc.h"
51#include "fm_hc.h"
52
53
54static t_Error CheckFmPcdParameters(t_FmPcd *p_FmPcd)
55{
56    if(!p_FmPcd->h_Fm)
57         RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("h_Fm has to be initialized"));
58
59    if(p_FmPcd->guestId == NCSW_MASTER_ID)
60    {
61        if(p_FmPcd->p_FmPcdKg && !p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs)
62            RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Something WRONG"));
63
64        if(p_FmPcd->p_FmPcdPlcr && !p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs)
65            RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Something WRONG"));
66
67        if(!p_FmPcd->f_Exception)
68            RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("f_FmPcdExceptions has to be initialized"));
69
70        if((!p_FmPcd->f_FmPcdIndexedException) && (p_FmPcd->p_FmPcdPlcr || p_FmPcd->p_FmPcdKg))
71            RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("f_FmPcdIndexedException has to be initialized"));
72
73        if(p_FmPcd->p_FmPcdDriverParam->prsMaxParseCycleLimit > PRS_MAX_CYCLE_LIMIT)
74            RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("prsMaxParseCycleLimit has to be less than 8191"));
75    }
76
77    return E_OK;
78}
79
80static volatile bool blockingFlag = FALSE;
81static void FmPcdIpcMsgCompletionCB(t_Handle   h_FmPcd,
82                                    uint8_t    *p_Msg,
83                                    uint8_t    *p_Reply,
84                                    uint32_t   replyLength,
85                                    t_Error    status)
86{
87    UNUSED(h_FmPcd);UNUSED(p_Msg);UNUSED(p_Reply);UNUSED(replyLength);UNUSED(status);
88    blockingFlag = FALSE;
89}
90
91static t_Error FmPcdHandleIpcMsgCB(t_Handle  h_FmPcd,
92                                   uint8_t   *p_Msg,
93                                   uint32_t  msgLength,
94                                   uint8_t   *p_Reply,
95                                   uint32_t  *p_ReplyLength)
96{
97    t_FmPcd             *p_FmPcd = (t_FmPcd*)h_FmPcd;
98    t_Error             err = E_OK;
99    t_FmPcdIpcMsg       *p_IpcMsg   = (t_FmPcdIpcMsg*)p_Msg;
100    t_FmPcdIpcReply     *p_IpcReply = (t_FmPcdIpcReply*)p_Reply;
101
102    SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
103    SANITY_CHECK_RETURN_ERROR((msgLength >= sizeof(uint32_t)), E_INVALID_VALUE);
104
105#ifdef DISABLE_SANITY_CHECKS
106    UNUSED(msgLength);
107#endif /* DISABLE_SANITY_CHECKS */
108
109    ASSERT_COND(p_Msg);
110
111    memset(p_IpcReply, 0, (sizeof(uint8_t) * FM_PCD_MAX_REPLY_SIZE));
112    *p_ReplyLength = 0;
113
114    switch(p_IpcMsg->msgId)
115    {
116        case (FM_PCD_MASTER_IS_ALIVE):
117            *(uint8_t*)(p_IpcReply->replyBody) = 1;
118            p_IpcReply->error = E_OK;
119            *p_ReplyLength = sizeof(uint32_t) + sizeof(uint8_t);
120            break;
121        case (FM_PCD_MASTER_IS_ENABLED):
122            /* count partitions registrations */
123            if(p_FmPcd->enabled)
124                p_FmPcd->numOfEnabledGuestPartitionsPcds++;
125            *(uint8_t*)(p_IpcReply->replyBody)  = (uint8_t)p_FmPcd->enabled;
126            p_IpcReply->error = E_OK;
127            *p_ReplyLength = sizeof(uint32_t) + sizeof(uint8_t);
128            break;
129        case (FM_PCD_GUEST_DISABLE):
130            if(p_FmPcd->numOfEnabledGuestPartitionsPcds)
131            {
132                p_FmPcd->numOfEnabledGuestPartitionsPcds--;
133                p_IpcReply->error = E_OK;
134            }
135            else
136            {
137                REPORT_ERROR(MINOR, E_INVALID_STATE,("Trying to disable an unregistered partition"));
138                p_IpcReply->error = E_INVALID_STATE;
139            }
140            *p_ReplyLength = sizeof(uint32_t);
141            break;
142        case(FM_PCD_GET_COUNTER):
143        {
144            e_FmPcdCounters inCounter;
145            uint32_t        outCounter;
146
147            memcpy((uint8_t*)&inCounter, p_IpcMsg->msgBody, sizeof(uint32_t));
148            outCounter = FM_PCD_GetCounter(h_FmPcd, inCounter);
149            memcpy(p_IpcReply->replyBody, (uint8_t*)&outCounter, sizeof(uint32_t));
150            p_IpcReply->error = E_OK;
151            *p_ReplyLength = sizeof(uint32_t) + sizeof(uint32_t);
152            break;
153        }
154        case (FM_PCD_ALLOC_KG_SCHEMES):
155        {
156            t_FmPcdIpcKgSchemesParams   ipcSchemesParams;
157
158            memcpy((uint8_t*)&ipcSchemesParams, p_IpcMsg->msgBody, sizeof(t_FmPcdIpcKgSchemesParams));
159            err = FmPcdKgAllocSchemes(h_FmPcd,
160                                      ipcSchemesParams.numOfSchemes,
161                                      ipcSchemesParams.guestId,
162                                      p_IpcReply->replyBody);
163            p_IpcReply->error = err;
164            *p_ReplyLength = sizeof(uint32_t) + ipcSchemesParams.numOfSchemes*sizeof(uint8_t);
165            break;
166        }
167        case (FM_PCD_FREE_KG_SCHEMES):
168        {
169            t_FmPcdIpcKgSchemesParams   ipcSchemesParams;
170
171            memcpy((uint8_t*)&ipcSchemesParams, p_IpcMsg->msgBody, sizeof(t_FmPcdIpcKgSchemesParams));
172            err = FmPcdKgFreeSchemes(h_FmPcd,
173                                     ipcSchemesParams.numOfSchemes,
174                                     ipcSchemesParams.guestId,
175                                     ipcSchemesParams.schemesIds);
176            p_IpcReply->error = err;
177            *p_ReplyLength = sizeof(uint32_t);
178            break;
179        }
180        case (FM_PCD_ALLOC_KG_CLSPLAN):
181        {
182            t_FmPcdIpcKgClsPlanParams   ipcKgClsPlanParams;
183
184            memcpy((uint8_t*)&ipcKgClsPlanParams, p_IpcMsg->msgBody, sizeof(t_FmPcdIpcKgClsPlanParams));
185            err = KgAllocClsPlanEntries(h_FmPcd,
186                                        ipcKgClsPlanParams.numOfClsPlanEntries,
187                                        ipcKgClsPlanParams.guestId,
188                                        p_IpcReply->replyBody);
189            p_IpcReply->error = err;
190            *p_ReplyLength =  sizeof(uint32_t) + sizeof(uint8_t);
191            break;
192        }
193        case (FM_PCD_FREE_KG_CLSPLAN):
194        {
195            t_FmPcdIpcKgClsPlanParams   ipcKgClsPlanParams;
196
197            memcpy((uint8_t*)&ipcKgClsPlanParams, p_IpcMsg->msgBody, sizeof(t_FmPcdIpcKgClsPlanParams));
198            KgFreeClsPlanEntries(h_FmPcd,
199                                       ipcKgClsPlanParams.numOfClsPlanEntries,
200                                       ipcKgClsPlanParams.guestId,
201                                       ipcKgClsPlanParams.clsPlanBase);
202            *p_ReplyLength = sizeof(uint32_t);
203            break;
204        }
205        case (FM_PCD_ALLOC_PROFILES):
206        {
207            t_FmPcdIpcPlcrAllocParams   ipcPlcrAllocParams;
208            uint16_t                    profilesBase;
209
210            memcpy((uint8_t*)&ipcPlcrAllocParams, p_IpcMsg->msgBody, sizeof(t_FmPcdIpcPlcrAllocParams));
211            err = PlcrAllocProfiles(h_FmPcd,
212                                    ipcPlcrAllocParams.hardwarePortId,
213                                    ipcPlcrAllocParams.num,
214                                    &profilesBase);
215            memcpy(p_IpcReply->replyBody, (uint8_t*)&profilesBase, sizeof(uint16_t));
216            p_IpcReply->error = err;
217            *p_ReplyLength = sizeof(uint32_t) + sizeof(uint16_t);
218            break;
219        }
220        case (FM_PCD_FREE_PROFILES):
221        {
222            t_FmPcdIpcPlcrAllocParams   ipcPlcrAllocParams;
223
224            memcpy((uint8_t*)&ipcPlcrAllocParams, p_IpcMsg->msgBody, sizeof(t_FmPcdIpcPlcrAllocParams));
225            err = PlcrFreeProfiles(h_FmPcd,
226                                   ipcPlcrAllocParams.hardwarePortId,
227                                   ipcPlcrAllocParams.num,
228                                   ipcPlcrAllocParams.plcrProfilesBase);
229            p_IpcReply->error = err;
230            *p_ReplyLength = sizeof(uint32_t);
231            break;
232        }
233        case (FM_PCD_ALLOC_SHARED_PROFILES):
234        {
235            uint16_t            numOfProfiles;
236            uint16_t            profilesIds[FM_PCD_PLCR_NUM_ENTRIES];
237            uint32_t            profilesMask[FM_PCD_PLCR_NUM_ENTRIES/32];
238            int                 i;
239
240            memset(profilesMask, 0, FM_PCD_PLCR_NUM_ENTRIES/32 * sizeof(uint32_t));
241            memcpy((uint8_t*)&numOfProfiles, p_IpcMsg->msgBody, sizeof(uint16_t));
242            err =  PlcrAllocSharedProfiles(h_FmPcd,
243                                           numOfProfiles,
244                                           profilesIds);
245            p_IpcReply->error = err;
246
247            /* translate the allocated profile id's to a 32bit * 8regs mask */
248            for(i = 0;i<numOfProfiles;i++)
249                profilesMask[profilesIds[i]/32] |= (0x80000000 >> (profilesIds[i] % 32));
250
251            memcpy(p_IpcReply->replyBody, (uint8_t*)&profilesMask, sizeof(profilesMask));
252            *p_ReplyLength = sizeof(uint32_t) + sizeof(profilesMask); /* num-of-shared-profiles */
253            break;
254        }
255        case (FM_PCD_FREE_SHARED_PROFILES):
256        {
257            t_FmPcdIpcSharedPlcrAllocParams     ipcSharedPlcrAllocParams;
258            uint16_t                            profilesIds[FM_PCD_PLCR_NUM_ENTRIES];
259            int                                 i,j, index = 0;
260            uint32_t                            walking1Mask = 0x80000000;
261
262            memset(profilesIds, 0, FM_PCD_PLCR_NUM_ENTRIES*sizeof(uint16_t));
263            memcpy((uint8_t*)&ipcSharedPlcrAllocParams, p_IpcMsg->msgBody, sizeof(t_FmPcdIpcSharedPlcrAllocParams));
264            for(i = 0; i<FM_PCD_PLCR_NUM_ENTRIES/32 ; i++)
265            {
266                if(ipcSharedPlcrAllocParams.sharedProfilesMask[i])
267                {
268                    for(j = 0 ; j<32 ; j++)
269                    {
270                        if(ipcSharedPlcrAllocParams.sharedProfilesMask[i] & walking1Mask)
271                            profilesIds[index++] = (uint16_t)(i*32+j);
272                        walking1Mask >>= 1;
273                    }
274                    walking1Mask = 0x80000000;
275                }
276            }
277
278            PlcrFreeSharedProfiles(h_FmPcd,
279                                   ipcSharedPlcrAllocParams.num,
280                                   profilesIds);
281            break;
282        }
283        case(FM_PCD_GET_SW_PRS_OFFSET):
284        {
285            t_FmPcdIpcSwPrsLable   ipcSwPrsLable;
286            uint32_t               swPrsOffset;
287
288            memcpy((uint8_t*)&ipcSwPrsLable, p_IpcMsg->msgBody, sizeof(t_FmPcdIpcSwPrsLable));
289            swPrsOffset =
290                FmPcdGetSwPrsOffset(h_FmPcd,
291                                    (e_NetHeaderType)ipcSwPrsLable.enumHdr,
292                                    ipcSwPrsLable.indexPerHdr);
293            memcpy(p_IpcReply->replyBody, (uint8_t*)&swPrsOffset, sizeof(uint32_t));
294            *p_ReplyLength = sizeof(uint32_t) + sizeof(uint32_t);
295            break;
296        }
297        case(FM_PCD_PRS_INC_PORT_STATS):
298        {
299            t_FmPcdIpcPrsIncludePort   ipcPrsIncludePort;
300
301            memcpy((uint8_t*)&ipcPrsIncludePort, p_IpcMsg->msgBody, sizeof(t_FmPcdIpcPrsIncludePort));
302            PrsIncludePortInStatistics(h_FmPcd,
303                                       ipcPrsIncludePort.hardwarePortId,
304                                       ipcPrsIncludePort.include);
305           break;
306        }
307#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
308       case(FM_PCD_DUMP_REGS):
309            if((err = FM_PCD_DumpRegs(h_FmPcd)) != E_OK)
310                REPORT_ERROR(MINOR, err, NO_MSG);
311            break;
312       case(FM_PCD_KG_DUMP_REGS):
313            if((err = FM_PCD_KgDumpRegs(h_FmPcd)) != E_OK)
314                REPORT_ERROR(MINOR, err, NO_MSG);
315            break;
316       case(FM_PCD_PLCR_DUMP_REGS):
317            if((err = FM_PCD_PlcrDumpRegs(h_FmPcd)) != E_OK)
318                REPORT_ERROR(MINOR, err, NO_MSG);
319            break;
320       case(FM_PCD_PLCR_PROFILE_DUMP_REGS):
321       {
322            t_Handle h_Profile;
323            memcpy((uint8_t*)&h_Profile, p_IpcMsg->msgBody, sizeof(t_Handle));
324            if((err = FM_PCD_PlcrProfileDumpRegs(h_FmPcd, h_Profile)) != E_OK)
325                REPORT_ERROR(MINOR, err, NO_MSG);
326            break;
327
328       }
329       case(FM_PCD_PRS_DUMP_REGS):
330            if((err = FM_PCD_PrsDumpRegs(h_FmPcd)) != E_OK)
331                REPORT_ERROR(MINOR, err, NO_MSG);
332            break;
333#endif /* (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0)) */
334        default:
335            *p_ReplyLength = 0;
336            RETURN_ERROR(MINOR, E_INVALID_SELECTION, ("command not found!!!"));
337    }
338    return E_OK;
339}
340
341void FmPcdSetClsPlanGrpId(t_FmPcd *p_FmPcd, uint8_t netEnvId, uint8_t clsPlanGrpId)
342{
343    p_FmPcd->netEnvs[netEnvId].clsPlanGrpId = clsPlanGrpId;
344}
345
346t_Error PcdGetClsPlanGrpParams(t_FmPcd *p_FmPcd, t_FmPcdKgInterModuleClsPlanGrpParams *p_GrpParams)
347{
348    uint8_t netEnvId = p_GrpParams->netEnvId;
349    int     i, k, j;
350
351    if(p_FmPcd->netEnvs[netEnvId].clsPlanGrpId != ILLEGAL_CLS_PLAN)
352    {
353        p_GrpParams->grpExists = TRUE;
354        p_GrpParams->clsPlanGrpId = p_FmPcd->netEnvs[netEnvId].clsPlanGrpId;
355        return E_OK;
356    }
357
358    for (i=0; ((i < FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS) &&
359              (p_FmPcd->netEnvs[netEnvId].units[i].hdrs[0].hdr != HEADER_TYPE_NONE)); i++)
360    {
361        for (k=0; ((k < FM_PCD_MAX_NUM_OF_INTERCHANGEABLE_HDRS) &&
362                   (p_FmPcd->netEnvs[netEnvId].units[i].hdrs[k].hdr != HEADER_TYPE_NONE)); k++)
363        {
364            /* if an option exists, add it to the opts list */
365            if(p_FmPcd->netEnvs[netEnvId].units[i].hdrs[k].opt)
366            {
367                /* check if this option already exists, add if it doesn't */
368                for(j = 0;j<p_GrpParams->numOfOptions;j++)
369                {
370                    if(p_GrpParams->options[j] == p_FmPcd->netEnvs[netEnvId].units[i].hdrs[k].opt)
371                        break;
372                }
373                p_GrpParams->optVectors[j] |= p_FmPcd->netEnvs[netEnvId].unitsVectors[i];
374                if(j == p_GrpParams->numOfOptions)
375                {
376                    p_GrpParams->options[p_GrpParams->numOfOptions] = p_FmPcd->netEnvs[netEnvId].units[i].hdrs[k].opt;
377                    p_GrpParams->numOfOptions++;
378                }
379            }
380        }
381    }
382
383    if(p_GrpParams->numOfOptions == 0)
384    {
385        if(p_FmPcd->p_FmPcdKg->emptyClsPlanGrpId != ILLEGAL_CLS_PLAN)
386        {
387            p_GrpParams->grpExists = TRUE;
388            p_GrpParams->clsPlanGrpId = p_FmPcd->p_FmPcdKg->emptyClsPlanGrpId;
389        }
390    }
391
392    return E_OK;
393
394}
395
396t_Error PcdGetVectorForOpt(t_FmPcd *p_FmPcd, uint8_t netEnvId, protocolOpt_t opt, uint32_t *p_Vector)
397{
398    uint8_t     j,k;
399
400    *p_Vector = 0;
401
402    for (j=0; ((j < FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS) &&
403              (p_FmPcd->netEnvs[netEnvId].units[j].hdrs[0].hdr != HEADER_TYPE_NONE)); j++)
404    {
405        for (k=0; ((k < FM_PCD_MAX_NUM_OF_INTERCHANGEABLE_HDRS) &&
406                  (p_FmPcd->netEnvs[netEnvId].units[j].hdrs[k].hdr != HEADER_TYPE_NONE)); k++)
407        {
408            if (p_FmPcd->netEnvs[netEnvId].units[j].hdrs[k].opt == opt)
409                *p_Vector |= p_FmPcd->netEnvs[netEnvId].unitsVectors[j];
410        }
411    }
412
413    if (!*p_Vector)
414        RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Requested option was not defined for this Network Environment Characteristics module"));
415    else
416        return E_OK;
417}
418
419t_Error PcdGetUnitsVector(t_FmPcd *p_FmPcd, t_NetEnvParams *p_Params)
420{
421    int                     i;
422
423    p_Params->vector = 0;
424    for(i=0; i<p_Params->numOfDistinctionUnits ;i++)
425    {
426        if(p_FmPcd->netEnvs[p_Params->netEnvId].units[p_Params->unitIds[i]].hdrs[0].hdr == HEADER_TYPE_NONE)
427            RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Requested unit was not defined for this Network Environment Characteristics module"));
428        ASSERT_COND(p_FmPcd->netEnvs[p_Params->netEnvId].unitsVectors[p_Params->unitIds[i]]);
429        p_Params->vector |= p_FmPcd->netEnvs[p_Params->netEnvId].unitsVectors[p_Params->unitIds[i]];
430    }
431
432    return E_OK;
433}
434
435bool PcdNetEnvIsUnitWithoutOpts(t_FmPcd *p_FmPcd, uint8_t netEnvId, uint32_t unitVector)
436{
437    int     i=0, k;
438    /* check whether a given unit may be used by non-clsPlan users. */
439    /* first, recognize the unit by its vector */
440    while (p_FmPcd->netEnvs[netEnvId].units[i].hdrs[0].hdr != HEADER_TYPE_NONE)
441    {
442        if (p_FmPcd->netEnvs[netEnvId].unitsVectors[i] == unitVector)
443        {
444            for (k=0;
445                 ((k < FM_PCD_MAX_NUM_OF_INTERCHANGEABLE_HDRS) &&
446                  (p_FmPcd->netEnvs[netEnvId].units[i].hdrs[k].hdr != HEADER_TYPE_NONE));
447                 k++)
448                /* check that no option exists */
449                if((protocolOpt_t)p_FmPcd->netEnvs[netEnvId].units[i].hdrs[k].opt)
450                    return FALSE;
451            break;
452        }
453        i++;
454    }
455    /* assert that a unit was found to mach the vector */
456    ASSERT_COND(p_FmPcd->netEnvs[netEnvId].units[i].hdrs[0].hdr != HEADER_TYPE_NONE);
457
458    return TRUE;
459}
460bool  FmPcdNetEnvIsHdrExist(t_Handle h_FmPcd, uint8_t netEnvId, e_NetHeaderType hdr)
461{
462    t_FmPcd     *p_FmPcd = (t_FmPcd*)h_FmPcd;
463    int         i, k;
464
465    ASSERT_COND(p_FmPcd);
466
467    for (i=0; ((i < FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS) &&
468              (p_FmPcd->netEnvs[netEnvId].units[i].hdrs[0].hdr != HEADER_TYPE_NONE)); i++)
469    {
470        for (k=0; ((k < FM_PCD_MAX_NUM_OF_INTERCHANGEABLE_HDRS) &&
471                  (p_FmPcd->netEnvs[netEnvId].units[i].hdrs[k].hdr != HEADER_TYPE_NONE)); k++)
472            if (p_FmPcd->netEnvs[netEnvId].units[i].hdrs[k].hdr == hdr)
473                return TRUE;
474    }
475    for (i=0; ((i < FM_PCD_MAX_NUM_OF_PRIVATE_HDRS) &&
476              (p_FmPcd->netEnvs[netEnvId].aliasHdrs[i].hdr != HEADER_TYPE_NONE)); i++)
477    {
478        if (p_FmPcd->netEnvs[netEnvId].aliasHdrs[i].hdr == hdr)
479            return TRUE;
480    }
481
482    return FALSE;
483}
484
485e_NetHeaderType FmPcdGetAliasHdr(t_FmPcd *p_FmPcd, uint8_t netEnvId, e_NetHeaderType hdr)
486{
487    int         i;
488
489    ASSERT_COND(p_FmPcd);
490
491    for (i=0; (i < FM_PCD_MAX_NUM_OF_PRIVATE_HDRS)
492        && (p_FmPcd->netEnvs[netEnvId].aliasHdrs[i].hdr != HEADER_TYPE_NONE); i++)
493    {
494        if (p_FmPcd->netEnvs[netEnvId].aliasHdrs[i].hdr == hdr)
495            return p_FmPcd->netEnvs[netEnvId].aliasHdrs[i].aliasHdr;
496    }
497
498    return HEADER_TYPE_NONE;
499}
500
501void   FmPcdPortRegister(t_Handle h_FmPcd, t_Handle h_FmPort, uint8_t hardwarePortId)
502{
503    t_FmPcd         *p_FmPcd = (t_FmPcd*)h_FmPcd;
504    uint16_t        swPortIndex = 0;
505
506    HW_PORT_ID_TO_SW_PORT_INDX(swPortIndex, hardwarePortId);
507
508    p_FmPcd->p_FmPcdPlcr->portsMapping[swPortIndex].h_FmPort = h_FmPort;
509}
510
511uint32_t FmPcdGetLcv(t_Handle h_FmPcd, uint32_t netEnvId, uint8_t hdrNum)
512{
513    t_FmPcd     *p_FmPcd = (t_FmPcd*)h_FmPcd;
514
515    return p_FmPcd->netEnvs[netEnvId].lcvs[hdrNum];
516}
517
518uint32_t FmPcdGetMacsecLcv(t_Handle h_FmPcd, uint32_t netEnvId)
519{
520    t_FmPcd     *p_FmPcd = (t_FmPcd*)h_FmPcd;
521
522    return p_FmPcd->netEnvs[netEnvId].macsecVector;
523}
524
525void FmPcdIncNetEnvOwners(t_Handle h_FmPcd, uint8_t netEnvId)
526{
527    ((t_FmPcd*)h_FmPcd)->netEnvs[netEnvId].owners++;
528}
529
530void FmPcdDecNetEnvOwners(t_Handle h_FmPcd, uint8_t netEnvId)
531{
532    ASSERT_COND(((t_FmPcd*)h_FmPcd)->netEnvs[netEnvId].owners);
533    ((t_FmPcd*)h_FmPcd)->netEnvs[netEnvId].owners--;
534}
535
536uint32_t FmPcdLock(t_Handle h_FmPcd)
537{
538    return XX_LockIntrSpinlock(((t_FmPcd*)h_FmPcd)->h_Spinlock);
539}
540
541void FmPcdUnlock(t_Handle h_FmPcd, uint32_t intFlags)
542{
543    XX_UnlockIntrSpinlock(((t_FmPcd*)h_FmPcd)->h_Spinlock, intFlags);
544}
545
546t_Handle FmPcdGetHcHandle(t_Handle h_FmPcd)
547{
548    ASSERT_COND(h_FmPcd);
549    SANITY_CHECK_RETURN_VALUE(((t_FmPcd*)h_FmPcd)->h_Hc, E_INVALID_HANDLE, NULL);
550    return ((t_FmPcd*)h_FmPcd)->h_Hc;
551}
552
553/**********************************************************************************************************/
554/*              API                                                                                       */
555/**********************************************************************************************************/
556
557t_Handle FM_PCD_Config(t_FmPcdParams *p_FmPcdParams)
558{
559    t_FmPcd             *p_FmPcd = NULL;
560    t_FmPhysAddr        physicalMuramBase;
561    uint8_t             i;
562
563    SANITY_CHECK_RETURN_VALUE(p_FmPcdParams, E_INVALID_HANDLE,NULL);
564
565    p_FmPcd = (t_FmPcd *) XX_Malloc(sizeof(t_FmPcd));
566    if (!p_FmPcd)
567    {
568        REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM Pcd"));
569        return NULL;
570    }
571    memset(p_FmPcd, 0, sizeof(t_FmPcd));
572
573    p_FmPcd->p_FmPcdDriverParam = (t_FmPcdDriverParam *) XX_Malloc(sizeof(t_FmPcdDriverParam));
574    if (!p_FmPcd->p_FmPcdDriverParam)
575    {
576        XX_Free(p_FmPcd);
577        REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM Pcd Driver Param"));
578        return NULL;
579    }
580    memset(p_FmPcd->p_FmPcdDriverParam, 0, sizeof(t_FmPcdDriverParam));
581
582    p_FmPcd->h_Fm = p_FmPcdParams->h_Fm;
583    p_FmPcd->guestId = FmGetGuestId(p_FmPcd->h_Fm);
584    p_FmPcd->h_FmMuram = FmGetMuramHandle(p_FmPcd->h_Fm);
585    FmGetPhysicalMuramBase(p_FmPcdParams->h_Fm, &physicalMuramBase);
586    p_FmPcd->physicalMuramBase = (uint64_t)((uint64_t)(&physicalMuramBase)->low | ((uint64_t)(&physicalMuramBase)->high << 32));
587
588    for(i = 0; i<FM_MAX_NUM_OF_PORTS; i++)
589        p_FmPcd->netEnvs[i].clsPlanGrpId = ILLEGAL_CLS_PLAN;
590
591    if (p_FmPcdParams->useHostCommand)
592    {
593        t_FmHcParams    hcParams;
594
595        memset(&hcParams, 0, sizeof(hcParams));
596        hcParams.h_Fm = p_FmPcd->h_Fm;
597        hcParams.h_FmPcd = (t_Handle)p_FmPcd;
598        memcpy((uint8_t*)&hcParams.params, (uint8_t*)&p_FmPcdParams->hc, sizeof(t_FmPcdHcParams));
599        p_FmPcd->h_Hc = FmHcConfigAndInit(&hcParams);
600        if (!p_FmPcd->h_Hc)
601        {
602            REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM Pcd HC"));
603            FM_PCD_Free(p_FmPcd);
604            return NULL;
605        }
606    }
607    else if(p_FmPcd->guestId != NCSW_MASTER_ID)
608        REPORT_ERROR(MAJOR, E_INVALID_STATE, ("No Host Command defined for a guest partition."));
609
610    if(p_FmPcdParams->kgSupport)
611    {
612        p_FmPcd->p_FmPcdKg = (t_FmPcdKg *)KgConfig(p_FmPcd, p_FmPcdParams);
613        if(!p_FmPcd->p_FmPcdKg)
614        {
615            REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM Pcd Keygen"));
616            FM_PCD_Free(p_FmPcd);
617            return NULL;
618        }
619    }
620
621    if(p_FmPcdParams->plcrSupport)
622    {
623        p_FmPcd->p_FmPcdPlcr = (t_FmPcdPlcr *)PlcrConfig(p_FmPcd, p_FmPcdParams);
624        if(!p_FmPcd->p_FmPcdPlcr)
625        {
626            REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM Pcd Policer"));
627            FM_PCD_Free(p_FmPcd);
628            return NULL;
629        }
630    }
631
632    if(p_FmPcdParams->prsSupport)
633    {
634        p_FmPcd->p_FmPcdPrs = (t_FmPcdPrs *)PrsConfig(p_FmPcd, p_FmPcdParams);
635        if(!p_FmPcd->p_FmPcdPrs)
636        {
637            REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM Pcd Parser"));
638            FM_PCD_Free(p_FmPcd);
639            return NULL;
640        }
641    }
642
643    p_FmPcd->h_Spinlock = XX_InitSpinlock();
644    if (!p_FmPcd->h_Spinlock)
645    {
646        REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM Pcd spinlock"));
647        FM_PCD_Free(p_FmPcd);
648        return NULL;
649    }
650
651    p_FmPcd->numOfEnabledGuestPartitionsPcds = 0;
652
653    p_FmPcd->f_Exception                = p_FmPcdParams->f_Exception;
654    p_FmPcd->f_FmPcdIndexedException    = p_FmPcdParams->f_ExceptionId;
655    p_FmPcd->h_App                      = p_FmPcdParams->h_App;
656
657    return p_FmPcd;
658}
659
660t_Error FM_PCD_Init(t_Handle h_FmPcd)
661{
662    t_FmPcd         *p_FmPcd = (t_FmPcd*)h_FmPcd;
663    t_Error         err = E_OK;
664    t_FmPcdIpcMsg   msg;
665
666    SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
667    SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdDriverParam, E_INVALID_HANDLE);
668
669    if(p_FmPcd->guestId != NCSW_MASTER_ID)
670    {
671        uint8_t                 isMasterAlive = 0;
672        t_FmPcdIpcReply         reply;
673        uint32_t                replyLength;
674
675        memset(p_FmPcd->fmPcdIpcHandlerModuleName, 0, (sizeof(char)) * MODULE_NAME_SIZE);
676        if(Sprint (p_FmPcd->fmPcdIpcHandlerModuleName, "FM_PCD_%d_%d", FmGetId(p_FmPcd->h_Fm), NCSW_MASTER_ID) != 10)
677            RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Sprint failed"));
678        memset(p_FmPcd->fmPcdModuleName, 0, (sizeof(char)) * MODULE_NAME_SIZE);
679        if(Sprint (p_FmPcd->fmPcdModuleName, "FM_PCD_%d_%d",FmGetId(p_FmPcd->h_Fm), p_FmPcd->guestId) != (p_FmPcd->guestId<10 ? 10:11))
680            RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Sprint failed"));
681
682        p_FmPcd->h_IpcSession = XX_IpcInitSession(p_FmPcd->fmPcdIpcHandlerModuleName, p_FmPcd->fmPcdModuleName);
683        if (p_FmPcd->h_IpcSession == NULL)
684            RETURN_ERROR(MAJOR, E_NOT_AVAILABLE, ("FM PCD Guest %d IPC session", p_FmPcd->guestId));
685
686        memset(&msg, 0, sizeof(msg));
687        memset(&reply, 0, sizeof(reply));
688        msg.msgId = FM_PCD_MASTER_IS_ALIVE;
689        msg.msgBody[0] = p_FmPcd->guestId;
690        blockingFlag = TRUE;
691
692        do
693        {
694            replyLength = sizeof(uint32_t) + sizeof(isMasterAlive);
695            if ((err = XX_IpcSendMessage(p_FmPcd->h_IpcSession,
696                                         (uint8_t*)&msg,
697                                         sizeof(msg.msgId)+sizeof(p_FmPcd->guestId),
698                                         (uint8_t*)&reply,
699                                         &replyLength,
700                                         FmPcdIpcMsgCompletionCB,
701                                         h_FmPcd)) != E_OK)
702                REPORT_ERROR(MAJOR, err, NO_MSG);
703            while(blockingFlag) ;
704            if(replyLength != (sizeof(uint32_t) + sizeof(isMasterAlive)))
705                REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
706            isMasterAlive = *(uint8_t*)(reply.replyBody);
707        } while (!isMasterAlive);
708    }
709
710    CHECK_INIT_PARAMETERS(p_FmPcd, CheckFmPcdParameters);
711
712    if(p_FmPcd->p_FmPcdKg)
713    {
714        err = KgInit(p_FmPcd);
715        if(err)
716            RETURN_ERROR(MAJOR, err, NO_MSG);
717    }
718
719    if(p_FmPcd->p_FmPcdPlcr)
720    {
721        err = PlcrInit(p_FmPcd);
722        if(err)
723            RETURN_ERROR(MAJOR, err, NO_MSG);
724    }
725
726    if(p_FmPcd->p_FmPcdPrs)
727    {
728        err = PrsInit(p_FmPcd);
729        if(err)
730            RETURN_ERROR(MAJOR, err, NO_MSG);
731    }
732
733    if(p_FmPcd->guestId == NCSW_MASTER_ID)
734    {
735         /* register to inter-core messaging mechanism */
736        memset(p_FmPcd->fmPcdModuleName, 0, (sizeof(char)) * MODULE_NAME_SIZE);
737        if(Sprint (p_FmPcd->fmPcdModuleName, "FM_PCD_%d_%d",FmGetId(p_FmPcd->h_Fm),NCSW_MASTER_ID) != 10)
738            RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Sprint failed"));
739        err = XX_IpcRegisterMsgHandler(p_FmPcd->fmPcdModuleName, FmPcdHandleIpcMsgCB, p_FmPcd, FM_PCD_MAX_REPLY_SIZE);
740        if(err)
741            RETURN_ERROR(MAJOR, err, NO_MSG);
742    }
743
744    XX_Free(p_FmPcd->p_FmPcdDriverParam);
745    p_FmPcd->p_FmPcdDriverParam = NULL;
746
747    FmRegisterPcd(p_FmPcd->h_Fm, p_FmPcd);
748
749    return E_OK;
750}
751
752t_Error FM_PCD_Free(t_Handle h_FmPcd)
753{
754    t_FmPcd                             *p_FmPcd =(t_FmPcd *)h_FmPcd;
755    t_Error                             err = E_OK;
756
757    if(p_FmPcd->enabled)
758        FM_PCD_Disable(p_FmPcd);
759
760    if (p_FmPcd->h_Spinlock)
761        XX_FreeSpinlock(p_FmPcd->h_Spinlock);
762
763    if(p_FmPcd->p_FmPcdDriverParam)
764    {
765        XX_Free(p_FmPcd->p_FmPcdDriverParam);
766        p_FmPcd->p_FmPcdDriverParam = NULL;
767    }
768    if(p_FmPcd->p_FmPcdKg)
769    {
770        if((err = KgFree(p_FmPcd)) != E_OK)
771            RETURN_ERROR(MINOR, err, NO_MSG);
772        XX_Free(p_FmPcd->p_FmPcdKg);
773        p_FmPcd->p_FmPcdKg = NULL;
774    }
775
776    if(p_FmPcd->p_FmPcdPlcr)
777    {
778        if((err = PlcrFree(p_FmPcd)) != E_OK)
779            RETURN_ERROR(MINOR, err, NO_MSG);
780        XX_Free(p_FmPcd->p_FmPcdPlcr);
781        p_FmPcd->p_FmPcdPlcr = NULL;
782    }
783
784    if(p_FmPcd->p_FmPcdPrs)
785    {
786        if(p_FmPcd->guestId == NCSW_MASTER_ID)
787            PrsFree(p_FmPcd);
788        XX_Free(p_FmPcd->p_FmPcdPrs);
789        p_FmPcd->p_FmPcdPrs = NULL;
790    }
791
792    if (p_FmPcd->h_Hc)
793    {
794        FmHcFree(p_FmPcd->h_Hc);
795        p_FmPcd->h_Hc = NULL;
796    }
797
798    XX_IpcUnregisterMsgHandler(p_FmPcd->fmPcdModuleName);
799
800    FmUnregisterPcd(p_FmPcd->h_Fm);
801
802    XX_Free(p_FmPcd);
803    return E_OK;
804}
805
806t_Error FM_PCD_Enable(t_Handle h_FmPcd)
807{
808    t_FmPcd             *p_FmPcd = (t_FmPcd*)h_FmPcd;
809    t_Error             err = E_OK;
810
811    SANITY_CHECK_RETURN_ERROR(h_FmPcd, E_INVALID_HANDLE);
812
813    if(p_FmPcd->guestId == NCSW_MASTER_ID)
814    {
815        if(p_FmPcd->p_FmPcdKg)
816            KgEnable(p_FmPcd);
817
818        if(p_FmPcd->p_FmPcdPlcr)
819            PlcrEnable(p_FmPcd);
820
821        if(p_FmPcd->p_FmPcdPrs)
822            PrsEnable(p_FmPcd);
823
824        p_FmPcd->enabled = TRUE;
825    }
826    else
827    {
828        uint8_t         enabled;
829        t_FmPcdIpcMsg   msg;
830        t_FmPcdIpcReply reply;
831        uint32_t        replyLength;
832
833        memset(&msg, 0, sizeof(msg));
834        memset(&reply, 0, sizeof(reply));
835        msg.msgId = FM_PCD_MASTER_IS_ENABLED;
836        replyLength = sizeof(uint32_t) + sizeof(enabled);
837        if ((err = XX_IpcSendMessage(p_FmPcd->h_IpcSession,
838                                     (uint8_t*)&msg,
839                                     sizeof(msg.msgId),
840                                     (uint8_t*)&reply,
841                                     &replyLength,
842                                     NULL,
843                                     NULL)) != E_OK)
844            RETURN_ERROR(MAJOR, err, NO_MSG);
845        if (replyLength != sizeof(uint32_t) + sizeof(enabled))
846            RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
847        p_FmPcd->enabled = (bool)!!(*(uint8_t*)(reply.replyBody));
848        if (!p_FmPcd->enabled)
849            RETURN_ERROR(MAJOR, E_INVALID_STATE, ("FM-PCD master should be enabled first!"));
850    }
851
852    return E_OK;
853}
854
855t_Error FM_PCD_Disable(t_Handle h_FmPcd)
856{
857    t_FmPcd             *p_FmPcd = (t_FmPcd*)h_FmPcd;
858    t_Error             err = E_OK;
859    t_FmPcdIpcMsg       msg;
860    t_FmPcdIpcReply     reply;
861    uint32_t            replyLength;
862
863    SANITY_CHECK_RETURN_ERROR(h_FmPcd, E_INVALID_HANDLE);
864
865    if(p_FmPcd->guestId == NCSW_MASTER_ID)
866    {
867        if(p_FmPcd->numOfEnabledGuestPartitionsPcds != 0)
868            RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Trying to disable a master partition PCD while guest partitions are still enabled."));
869
870        if(p_FmPcd->p_FmPcdKg)
871             KgDisable(p_FmPcd);
872
873        if(p_FmPcd->p_FmPcdPlcr)
874            PlcrDisable(p_FmPcd);
875
876        if(p_FmPcd->p_FmPcdPrs)
877            PrsDisable(p_FmPcd);
878
879        p_FmPcd->enabled = FALSE;
880
881        return E_OK;
882    }
883
884    memset(&msg, 0, sizeof(msg));
885    msg.msgId = FM_PCD_GUEST_DISABLE;
886    memset(&reply, 0, sizeof(reply));
887    replyLength = sizeof(uint32_t);
888    if ((err = XX_IpcSendMessage(p_FmPcd->h_IpcSession,
889                                 (uint8_t*)&msg,
890                                 sizeof(msg.msgId),
891                                 (uint8_t*)&reply,
892                                 &replyLength,
893                                 NULL,
894                                 NULL)) != E_OK)
895        RETURN_ERROR(MAJOR, err, NO_MSG);
896    if (replyLength != sizeof(uint32_t))
897        RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
898
899    return (t_Error)(reply.error);
900}
901
902t_Handle FM_PCD_SetNetEnvCharacteristics(t_Handle h_FmPcd, t_FmPcdNetEnvParams  *p_NetEnvParams)
903{
904    t_FmPcd                 *p_FmPcd = (t_FmPcd*)h_FmPcd;
905    uint32_t                intFlags, specialUnits = 0;
906    uint8_t                 bitId = 0;
907    uint8_t                 i, j, k;
908    uint8_t                 netEnvCurrId;
909    uint8_t                 ipsecAhUnit = 0,ipsecEspUnit = 0;
910    bool                    ipsecAhExists = FALSE, ipsecEspExists = FALSE, shim1Selected = FALSE;
911    uint8_t                 hdrNum;
912
913    SANITY_CHECK_RETURN_VALUE(h_FmPcd, E_INVALID_STATE, NULL);
914    SANITY_CHECK_RETURN_VALUE(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_STATE, NULL);
915
916    intFlags = FmPcdLock(p_FmPcd);
917
918    /* find a new netEnv */
919    for(i = 0;i<FM_MAX_NUM_OF_PORTS;i++)
920        if(!p_FmPcd->netEnvs[i].used)
921            break;
922
923    if(i== FM_MAX_NUM_OF_PORTS)
924    {
925        REPORT_ERROR(MAJOR, E_FULL,("No more than %d netEnv's allowed.", FM_MAX_NUM_OF_PORTS));
926        FmPcdUnlock(p_FmPcd, intFlags);
927        return NULL;
928    }
929
930    p_FmPcd->netEnvs[i].used = TRUE;
931
932    if (!TRY_LOCK(NULL, &p_FmPcd->netEnvs[i].lock))
933    {
934        FmPcdUnlock(p_FmPcd, intFlags);
935        return NULL;
936    }
937    FmPcdUnlock(p_FmPcd, intFlags);
938
939    netEnvCurrId = (uint8_t)i;
940
941    /* clear from previous use */
942    memset(&p_FmPcd->netEnvs[netEnvCurrId].units, 0, FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS * sizeof(t_FmPcdIntDistinctionUnit));
943    memset(&p_FmPcd->netEnvs[netEnvCurrId].aliasHdrs, 0, FM_PCD_MAX_NUM_OF_PRIVATE_HDRS * sizeof(t_FmPcdNetEnvAliases));
944    memcpy(&p_FmPcd->netEnvs[netEnvCurrId].units, p_NetEnvParams->units, p_NetEnvParams->numOfDistinctionUnits*sizeof(t_FmPcdIntDistinctionUnit));
945    p_FmPcd->netEnvs[netEnvCurrId].clsPlanGrpId = ILLEGAL_CLS_PLAN;
946
947    /* check that header with opt is not interchanged with the same header */
948    for (i=0; (i < FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS)
949            && (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[0].hdr != HEADER_TYPE_NONE); i++)
950    {
951        for (k=0; (k < FM_PCD_MAX_NUM_OF_INTERCHANGEABLE_HDRS)
952            && (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr != HEADER_TYPE_NONE); k++)
953        {
954            /* if an option exists, check that other headers are not the same header
955            without option */
956            if(p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].opt)
957            {
958                for (j=0; (j < FM_PCD_MAX_NUM_OF_INTERCHANGEABLE_HDRS)
959                        && (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[j].hdr != HEADER_TYPE_NONE); j++)
960                    if((p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[j].hdr == p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr) &&
961                        !p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[j].opt)
962                    {
963                        REPORT_ERROR(MINOR, E_FULL, ("Illegal unit - header with opt may not be interchangeable with the same header without opt"));
964                        RELEASE_LOCK(p_FmPcd->netEnvs[netEnvCurrId].lock);
965                        return NULL;
966                    }
967            }
968        }
969    }
970
971    /* IPSEC_AH and IPSEC_SPI can't be 2 units,  */
972    /* check that header with opt is not interchanged with the same header */
973    for(i=0; (i < FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS)
974        && (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[0].hdr != HEADER_TYPE_NONE); i++)
975    {
976        for(k=0; (k < FM_PCD_MAX_NUM_OF_INTERCHANGEABLE_HDRS)
977            && (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr != HEADER_TYPE_NONE); k++)
978        {
979            /* Some headers pairs may not be defined on different units as the parser
980            doesn't distinguish */
981            if(p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr == HEADER_TYPE_IPSEC_AH)
982            {
983                if (ipsecEspExists && (ipsecEspUnit != i))
984                {
985                    REPORT_ERROR(MINOR, E_INVALID_STATE, ("HEADER_TYPE_IPSEC_AH and HEADER_TYPE_IPSEC_ESP may not be defined in separate units"));
986                    RELEASE_LOCK(p_FmPcd->netEnvs[netEnvCurrId].lock);
987                   return NULL;
988                }
989                else
990                {
991                    ipsecAhUnit = i;
992                    ipsecAhExists = TRUE;
993                }
994            }
995            if(p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr == HEADER_TYPE_IPSEC_ESP)
996            {
997                if (ipsecAhExists && (ipsecAhUnit != i))
998                {
999                    REPORT_ERROR(MINOR, E_INVALID_STATE, ("HEADER_TYPE_IPSEC_AH and HEADER_TYPE_IPSEC_ESP may not be defined in separate units"));
1000                    RELEASE_LOCK(p_FmPcd->netEnvs[netEnvCurrId].lock);
1001                    return NULL;
1002                }
1003                else
1004                {
1005                    ipsecEspUnit = i;
1006                    ipsecEspExists = TRUE;
1007                }
1008            }
1009            if(p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr == HEADER_TYPE_UDP_ENCAP_ESP)
1010            {
1011                /* TODO - general coding. choose the free shim header */
1012                p_FmPcd->netEnvs[netEnvCurrId].aliasHdrs[specialUnits].hdr = HEADER_TYPE_UDP_ENCAP_ESP;
1013                p_FmPcd->netEnvs[netEnvCurrId].aliasHdrs[specialUnits++].aliasHdr = HEADER_TYPE_USER_DEFINED_SHIM1;
1014                p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr = HEADER_TYPE_USER_DEFINED_SHIM1;
1015                p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].opt = 0;
1016            }
1017        }
1018    }
1019
1020    /* if private header (shim), check that no other headers specified */
1021    for (i=0; (i < FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS)
1022        && (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[0].hdr != HEADER_TYPE_NONE); i++)
1023    {
1024        if(IS_PRIVATE_HEADER(p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[0].hdr))
1025            if(p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[1].hdr != HEADER_TYPE_NONE)
1026            {
1027                REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("SHIM header may not be interchanged with other headers"));
1028                RELEASE_LOCK(p_FmPcd->netEnvs[netEnvCurrId].lock);
1029                return NULL;
1030            }
1031    }
1032
1033    for(i=0; i<p_NetEnvParams->numOfDistinctionUnits;i++)
1034    {
1035        if (IS_PRIVATE_HEADER(p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[0].hdr))
1036            switch(p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[0].hdr)
1037            {
1038                case(HEADER_TYPE_USER_DEFINED_SHIM1):
1039                    if (shim1Selected)
1040                    {
1041                        REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("SHIM header cannot be selected with UDP_IPSEC_ESP"));
1042                        RELEASE_LOCK(p_FmPcd->netEnvs[netEnvCurrId].lock);
1043                        return NULL;
1044                    }
1045                    shim1Selected = TRUE;
1046                    p_FmPcd->netEnvs[netEnvCurrId].unitsVectors[i] = 0x00000001;
1047                break;
1048                case(HEADER_TYPE_USER_DEFINED_SHIM2):
1049                    p_FmPcd->netEnvs[netEnvCurrId].unitsVectors[i] = 0x00000002;
1050                    break;
1051                default:
1052                    REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Requested SHIM not supported"));
1053            }
1054        else
1055        {
1056            p_FmPcd->netEnvs[netEnvCurrId].unitsVectors[i] = (uint32_t)(0x80000000 >> bitId++);
1057
1058            if(IS_SPECIAL_HEADER(p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[0].hdr))
1059                p_FmPcd->netEnvs[netEnvCurrId].macsecVector = p_FmPcd->netEnvs[netEnvCurrId].unitsVectors[i];
1060        }
1061    }
1062
1063    /* define a set of hardware parser LCV's according to the defined netenv */
1064
1065    /* set an array of LCV's for each header in the netEnv */
1066    for (i=0; (i < FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS)
1067        && (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[0].hdr != HEADER_TYPE_NONE); i++)
1068    {
1069        /* private headers have no LCV in the hard parser */
1070        if (!IS_PRIVATE_HEADER(p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[0].hdr))
1071        {
1072            for (k=0; (k < FM_PCD_MAX_NUM_OF_INTERCHANGEABLE_HDRS)
1073                    && (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr != HEADER_TYPE_NONE); k++)
1074            {
1075                GET_PRS_HDR_NUM(hdrNum, p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr);
1076                if ((hdrNum == ILLEGAL_HDR_NUM) || (hdrNum == NO_HDR_NUM))
1077                {
1078                    REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, NO_MSG);
1079                    RELEASE_LOCK(p_FmPcd->netEnvs[netEnvCurrId].lock);
1080                    return NULL;
1081                }
1082                p_FmPcd->netEnvs[netEnvCurrId].lcvs[hdrNum] |= p_FmPcd->netEnvs[netEnvCurrId].unitsVectors[i];
1083            }
1084        }
1085    }
1086
1087    RELEASE_LOCK(p_FmPcd->netEnvs[netEnvCurrId].lock);
1088
1089    return UINT_TO_PTR((uint64_t)netEnvCurrId+1);
1090}
1091
1092t_Error FM_PCD_DeleteNetEnvCharacteristics(t_Handle h_FmPcd, t_Handle h_NetEnv)
1093{
1094    t_FmPcd     *p_FmPcd = (t_FmPcd*)h_FmPcd;
1095    uint8_t     netEnvId = (uint8_t)(PTR_TO_UINT(h_NetEnv)-1);
1096
1097    SANITY_CHECK_RETURN_ERROR(h_FmPcd, E_INVALID_STATE);
1098    SANITY_CHECK_RETURN_ERROR(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_STATE);
1099
1100    if (!TRY_LOCK(p_FmPcd->h_Spinlock, &p_FmPcd->netEnvs[netEnvId].lock))
1101        return ERROR_CODE(E_BUSY);
1102    /* check that no port is bound to this netEnv */
1103    if(p_FmPcd->netEnvs[netEnvId].owners)
1104    {
1105       RELEASE_LOCK(p_FmPcd->netEnvs[netEnvId].lock);
1106       RETURN_ERROR(MINOR, E_INVALID_STATE, ("Trying to delete a netEnv that has ports/schemes/trees/clsPlanGrps bound to"));
1107    }
1108    p_FmPcd->netEnvs[netEnvId].used= FALSE;
1109    p_FmPcd->netEnvs[netEnvId].clsPlanGrpId = ILLEGAL_CLS_PLAN;
1110
1111    memset(p_FmPcd->netEnvs[netEnvId].units, 0, sizeof(t_FmPcdIntDistinctionUnit)*FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS);
1112    memset(p_FmPcd->netEnvs[netEnvId].unitsVectors, 0, sizeof(uint32_t)*FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS);
1113    memset(p_FmPcd->netEnvs[netEnvId].lcvs, 0, sizeof(uint32_t)*FM_PCD_PRS_NUM_OF_HDRS);
1114
1115    RELEASE_LOCK(p_FmPcd->netEnvs[netEnvId].lock);
1116
1117    return E_OK;
1118}
1119
1120void FM_PCD_HcTxConf(t_Handle h_FmPcd, t_DpaaFD *p_Fd)
1121{
1122    t_FmPcd                 *p_FmPcd = (t_FmPcd*)h_FmPcd;
1123
1124    SANITY_CHECK_RETURN(h_FmPcd, E_INVALID_STATE);
1125
1126    FmHcTxConf(p_FmPcd->h_Hc, p_Fd);
1127}
1128
1129uint32_t FM_PCD_GetCounter(t_Handle h_FmPcd, e_FmPcdCounters counter)
1130{
1131    t_FmPcd                 *p_FmPcd = (t_FmPcd*)h_FmPcd;
1132    uint32_t                replyLength, outCounter = 0;
1133    t_FmPcdIpcMsg           msg;
1134    t_Error                 err;
1135    t_FmPcdIpcReply         reply;
1136
1137    SANITY_CHECK_RETURN_VALUE(h_FmPcd, E_INVALID_HANDLE, 0);
1138    SANITY_CHECK_RETURN_VALUE(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_STATE, 0);
1139
1140    if(p_FmPcd->guestId != NCSW_MASTER_ID)
1141    {
1142        memset(&msg, 0, sizeof(msg));
1143        memset(&reply, 0, sizeof(reply));
1144        msg.msgId = FM_PCD_GET_COUNTER;
1145        memcpy(msg.msgBody, (uint8_t *)&counter, sizeof(uint32_t));
1146        replyLength = sizeof(uint32_t) + sizeof(uint32_t);
1147        if ((err = XX_IpcSendMessage(p_FmPcd->h_IpcSession,
1148                                     (uint8_t*)&msg,
1149                                     sizeof(msg.msgId) +sizeof(uint32_t),
1150                                     (uint8_t*)&reply,
1151                                     &replyLength,
1152                                     NULL,
1153                                     NULL)) != E_OK)
1154            RETURN_ERROR(MAJOR, err, NO_MSG);
1155        if (replyLength != sizeof(uint32_t) + sizeof(uint32_t))
1156            RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
1157
1158        memcpy((uint8_t*)&outCounter, reply.replyBody, sizeof(uint32_t));
1159        return outCounter;
1160    }
1161
1162    switch(counter)
1163    {
1164        case(e_FM_PCD_KG_COUNTERS_TOTAL):
1165            if(!p_FmPcd->p_FmPcdKg)
1166            {
1167                REPORT_ERROR(MINOR, E_INVALID_STATE, ("Can't ask for this counters"));
1168                return 0;
1169            }
1170            break;
1171        case(e_FM_PCD_PLCR_COUNTERS_YELLOW):
1172        case(e_FM_PCD_PLCR_COUNTERS_RED):
1173        case(e_FM_PCD_PLCR_COUNTERS_RECOLORED_TO_RED):
1174        case(e_FM_PCD_PLCR_COUNTERS_RECOLORED_TO_YELLOW):
1175        case(e_FM_PCD_PLCR_COUNTERS_TOTAL):
1176        case(e_FM_PCD_PLCR_COUNTERS_LENGTH_MISMATCH):
1177            if(!p_FmPcd->p_FmPcdPlcr)
1178            {
1179                REPORT_ERROR(MINOR, E_INVALID_STATE, ("Can't ask for this counters"));
1180                return 0;
1181            }
1182            /* check that counters are enabled */
1183            if(!(GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_gcr) & FM_PCD_PLCR_GCR_STEN))
1184            {
1185                REPORT_ERROR(MINOR, E_INVALID_STATE, ("Requested counter was not enabled"));
1186                return 0;
1187            }
1188            break;
1189        case(e_FM_PCD_PRS_COUNTERS_PARSE_DISPATCH):
1190        case(e_FM_PCD_PRS_COUNTERS_L2_PARSE_RESULT_RETURNED):
1191        case(e_FM_PCD_PRS_COUNTERS_L3_PARSE_RESULT_RETURNED):
1192        case(e_FM_PCD_PRS_COUNTERS_L4_PARSE_RESULT_RETURNED):
1193        case(e_FM_PCD_PRS_COUNTERS_SHIM_PARSE_RESULT_RETURNED):
1194        case(e_FM_PCD_PRS_COUNTERS_L2_PARSE_RESULT_RETURNED_WITH_ERR):
1195        case(e_FM_PCD_PRS_COUNTERS_L3_PARSE_RESULT_RETURNED_WITH_ERR):
1196        case(e_FM_PCD_PRS_COUNTERS_L4_PARSE_RESULT_RETURNED_WITH_ERR):
1197        case(e_FM_PCD_PRS_COUNTERS_SHIM_PARSE_RESULT_RETURNED_WITH_ERR):
1198        case(e_FM_PCD_PRS_COUNTERS_SOFT_PRS_CYCLES):
1199        case(e_FM_PCD_PRS_COUNTERS_SOFT_PRS_STALL_CYCLES):
1200        case(e_FM_PCD_PRS_COUNTERS_HARD_PRS_CYCLE_INCL_STALL_CYCLES):
1201        case(e_FM_PCD_PRS_COUNTERS_MURAM_READ_CYCLES):
1202        case(e_FM_PCD_PRS_COUNTERS_MURAM_READ_STALL_CYCLES):
1203        case(e_FM_PCD_PRS_COUNTERS_MURAM_WRITE_CYCLES):
1204        case(e_FM_PCD_PRS_COUNTERS_MURAM_WRITE_STALL_CYCLES):
1205        case(e_FM_PCD_PRS_COUNTERS_FPM_COMMAND_STALL_CYCLES):
1206            if(!p_FmPcd->p_FmPcdPrs)
1207            {
1208                REPORT_ERROR(MINOR, E_INVALID_STATE, ("Can't ask for this counters"));
1209                return 0;
1210            }
1211            break;
1212        default:
1213            REPORT_ERROR(MINOR, E_INVALID_STATE, ("Unsupported type of counter"));
1214            return 0;
1215    }
1216    switch(counter)
1217    {
1218        case(e_FM_PCD_PRS_COUNTERS_PARSE_DISPATCH):
1219               return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->pds);
1220        case(e_FM_PCD_PRS_COUNTERS_L2_PARSE_RESULT_RETURNED):
1221               return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->l2rrs);
1222        case(e_FM_PCD_PRS_COUNTERS_L3_PARSE_RESULT_RETURNED):
1223               return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->l3rrs);
1224        case(e_FM_PCD_PRS_COUNTERS_L4_PARSE_RESULT_RETURNED):
1225               return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->l4rrs);
1226        case(e_FM_PCD_PRS_COUNTERS_SHIM_PARSE_RESULT_RETURNED):
1227               return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->srrs);
1228        case(e_FM_PCD_PRS_COUNTERS_L2_PARSE_RESULT_RETURNED_WITH_ERR):
1229               return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->l2rres);
1230        case(e_FM_PCD_PRS_COUNTERS_L3_PARSE_RESULT_RETURNED_WITH_ERR):
1231               return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->l3rres);
1232        case(e_FM_PCD_PRS_COUNTERS_L4_PARSE_RESULT_RETURNED_WITH_ERR):
1233               return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->l4rres);
1234        case(e_FM_PCD_PRS_COUNTERS_SHIM_PARSE_RESULT_RETURNED_WITH_ERR):
1235               return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->srres);
1236        case(e_FM_PCD_PRS_COUNTERS_SOFT_PRS_CYCLES):
1237               return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->spcs);
1238        case(e_FM_PCD_PRS_COUNTERS_SOFT_PRS_STALL_CYCLES):
1239               return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->spscs);
1240        case(e_FM_PCD_PRS_COUNTERS_HARD_PRS_CYCLE_INCL_STALL_CYCLES):
1241               return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->hxscs);
1242        case(e_FM_PCD_PRS_COUNTERS_MURAM_READ_CYCLES):
1243               return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->mrcs);
1244        case(e_FM_PCD_PRS_COUNTERS_MURAM_READ_STALL_CYCLES):
1245               return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->mrscs);
1246        case(e_FM_PCD_PRS_COUNTERS_MURAM_WRITE_CYCLES):
1247               return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->mwcs);
1248        case(e_FM_PCD_PRS_COUNTERS_MURAM_WRITE_STALL_CYCLES):
1249               return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->mwscs);
1250        case(e_FM_PCD_PRS_COUNTERS_FPM_COMMAND_STALL_CYCLES):
1251               return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fcscs);
1252        case(e_FM_PCD_KG_COUNTERS_TOTAL):
1253               return GET_UINT32(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->kgtpc);
1254
1255        /*Policer statictics*/
1256        case(e_FM_PCD_PLCR_COUNTERS_YELLOW):
1257                return GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_ypcnt);
1258        case(e_FM_PCD_PLCR_COUNTERS_RED):
1259                return GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_rpcnt);
1260        case(e_FM_PCD_PLCR_COUNTERS_RECOLORED_TO_RED):
1261                return GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_rrpcnt);
1262        case(e_FM_PCD_PLCR_COUNTERS_RECOLORED_TO_YELLOW):
1263                return GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_rypcnt);
1264        case(e_FM_PCD_PLCR_COUNTERS_TOTAL):
1265                return GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_tpcnt);
1266        case(e_FM_PCD_PLCR_COUNTERS_LENGTH_MISMATCH):
1267                return GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_flmcnt);
1268
1269        default:
1270            REPORT_ERROR(MINOR, E_INVALID_STATE, ("Unsupported type of counter"));
1271            return 0;
1272    }
1273}
1274
1275#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
1276t_Error FM_PCD_DumpRegs(t_Handle h_FmPcd)
1277{
1278    t_FmPcd             *p_FmPcd = (t_FmPcd*)h_FmPcd;
1279    t_FmPcdIpcMsg       msg;
1280
1281    DECLARE_DUMP;
1282
1283    SANITY_CHECK_RETURN_ERROR(h_FmPcd, E_INVALID_HANDLE);
1284    SANITY_CHECK_RETURN_ERROR(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_STATE);
1285
1286    if(p_FmPcd->guestId != NCSW_MASTER_ID)
1287    {
1288        memset(&msg, 0, sizeof(msg));
1289        msg.msgId = FM_PCD_DUMP_REGS;
1290        return XX_IpcSendMessage(p_FmPcd->h_IpcSession,
1291                                 (uint8_t*)&msg,
1292                                 sizeof(msg.msgId),
1293                                 NULL,
1294                                 NULL,
1295                                 NULL,
1296                                 NULL);
1297    }
1298    if (p_FmPcd->p_FmPcdKg)
1299        return FM_PCD_KgDumpRegs(h_FmPcd);
1300    if (p_FmPcd->p_FmPcdPlcr)
1301        return FM_PCD_PlcrDumpRegs(h_FmPcd);
1302    if (p_FmPcd->p_FmPcdPrs)
1303        return FM_PCD_PrsDumpRegs(h_FmPcd);
1304    return E_OK;
1305}
1306
1307t_Error     FM_PCD_HcDumpRegs(t_Handle h_FmPcd)
1308{
1309    t_FmPcd             *p_FmPcd = (t_FmPcd*)h_FmPcd;
1310
1311    DECLARE_DUMP;
1312
1313    SANITY_CHECK_RETURN_ERROR(h_FmPcd, E_INVALID_HANDLE);
1314    SANITY_CHECK_RETURN_ERROR(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_STATE);
1315    SANITY_CHECK_RETURN_ERROR(p_FmPcd->h_Hc, E_INVALID_STATE);
1316
1317    return FmHcDumpRegs(p_FmPcd->h_Hc);
1318}
1319
1320#endif /* (defined(DEBUG_ERRORS) && ... */
1321
1322t_Error FM_PCD_ConfigException(t_Handle h_FmPcd, e_FmPcdExceptions exception, bool enable)
1323{
1324    t_FmPcd         *p_FmPcd = (t_FmPcd*)h_FmPcd;
1325    uint32_t        bitMask = 0;
1326
1327    SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
1328
1329    if(p_FmPcd->guestId != NCSW_MASTER_ID)
1330        RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("FM_PCD_ConfigException - guest mode!"));
1331
1332    GET_FM_PCD_EXCEPTION_FLAG(bitMask, exception);
1333    if(bitMask)
1334    {
1335        if (enable)
1336            p_FmPcd->exceptions |= bitMask;
1337        else
1338            p_FmPcd->exceptions &= ~bitMask;
1339   }
1340    else
1341        RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined exception"));
1342
1343    return E_OK;
1344}
1345
1346t_Error FM_PCD_SetException(t_Handle h_FmPcd, e_FmPcdExceptions exception, bool enable)
1347{
1348    t_FmPcd         *p_FmPcd = (t_FmPcd*)h_FmPcd;
1349    uint32_t        bitMask = 0, tmpReg;
1350
1351    SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
1352    SANITY_CHECK_RETURN_ERROR(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_STATE);
1353
1354    if(p_FmPcd->guestId != NCSW_MASTER_ID)
1355        RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("FM_PCD_SetException - guest mode!"));
1356
1357    GET_FM_PCD_EXCEPTION_FLAG(bitMask, exception);
1358
1359    if(bitMask)
1360    {
1361        if (enable)
1362            p_FmPcd->exceptions |= bitMask;
1363        else
1364            p_FmPcd->exceptions &= ~bitMask;
1365
1366        switch(exception)
1367        {
1368            case(e_FM_PCD_KG_EXCEPTION_DOUBLE_ECC):
1369            case(e_FM_PCD_KG_EXCEPTION_KEYSIZE_OVERFLOW):
1370                if(!p_FmPcd->p_FmPcdKg)
1371                    RETURN_ERROR(MINOR, E_INVALID_STATE, ("Can't ask for this interrupt - keygen is not working"));
1372                break;
1373            case(e_FM_PCD_PLCR_EXCEPTION_DOUBLE_ECC):
1374            case(e_FM_PCD_PLCR_EXCEPTION_INIT_ENTRY_ERROR):
1375            case(e_FM_PCD_PLCR_EXCEPTION_PRAM_SELF_INIT_COMPLETE):
1376            case(e_FM_PCD_PLCR_EXCEPTION_ATOMIC_ACTION_COMPLETE):
1377                if(!p_FmPcd->p_FmPcdPlcr)
1378                    RETURN_ERROR(MINOR, E_INVALID_STATE, ("Can't ask for this interrupt - policer is not working"));
1379            break;
1380            case(e_FM_PCD_PRS_EXCEPTION_DOUBLE_ECC):
1381            case(e_FM_PCD_PRS_EXCEPTION_SINGLE_ECC):
1382                if(!p_FmPcd->p_FmPcdPrs)
1383                    RETURN_ERROR(MINOR, E_INVALID_STATE, ("Can't ask for this interrupt - parser is not working"));
1384            break;
1385            default:
1386                RETURN_ERROR(MINOR, E_INVALID_STATE, ("Unsupported exception"));
1387
1388        }
1389
1390        switch(exception)
1391        {
1392            case(e_FM_PCD_KG_EXCEPTION_DOUBLE_ECC):
1393                tmpReg = GET_UINT32(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->kgeeer);
1394                if(enable)
1395                    tmpReg |= FM_PCD_KG_DOUBLE_ECC;
1396                else
1397                    tmpReg &= ~FM_PCD_KG_DOUBLE_ECC;
1398                WRITE_UINT32(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->kgeeer, tmpReg);
1399                break;
1400            case(e_FM_PCD_KG_EXCEPTION_KEYSIZE_OVERFLOW):
1401                tmpReg = GET_UINT32(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->kgeeer);
1402                if(enable)
1403                    tmpReg |= FM_PCD_KG_KEYSIZE_OVERFLOW;
1404                else
1405                    tmpReg &= ~FM_PCD_KG_KEYSIZE_OVERFLOW;
1406                WRITE_UINT32(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->kgeeer, tmpReg);
1407                break;
1408            case(e_FM_PCD_PRS_EXCEPTION_DOUBLE_ECC):
1409                tmpReg = GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->perer);
1410                if(enable)
1411                    tmpReg |= FM_PCD_PRS_DOUBLE_ECC;
1412                else
1413                    tmpReg &= ~FM_PCD_PRS_DOUBLE_ECC;
1414                WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->perer, tmpReg);
1415                break;
1416            case(e_FM_PCD_PRS_EXCEPTION_SINGLE_ECC):
1417                tmpReg = GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->pever);
1418                if(enable)
1419                    tmpReg |= FM_PCD_PRS_SINGLE_ECC;
1420                else
1421                    tmpReg &= ~FM_PCD_PRS_SINGLE_ECC;
1422                WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->pever, tmpReg);
1423                break;
1424            case(e_FM_PCD_PLCR_EXCEPTION_DOUBLE_ECC):
1425                tmpReg = GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_eier);
1426                if(enable)
1427                    tmpReg |= FM_PCD_PLCR_DOUBLE_ECC;
1428                else
1429                    tmpReg &= ~FM_PCD_PLCR_DOUBLE_ECC;
1430                WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_eier, tmpReg);
1431                break;
1432            case(e_FM_PCD_PLCR_EXCEPTION_INIT_ENTRY_ERROR):
1433                tmpReg = GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_eier);
1434                if(enable)
1435                    tmpReg |= FM_PCD_PLCR_INIT_ENTRY_ERROR;
1436                else
1437                    tmpReg &= ~FM_PCD_PLCR_INIT_ENTRY_ERROR;
1438                WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_eier, tmpReg);
1439                break;
1440            case(e_FM_PCD_PLCR_EXCEPTION_PRAM_SELF_INIT_COMPLETE):
1441                tmpReg = GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_ier);
1442                if(enable)
1443                    tmpReg |= FM_PCD_PLCR_PRAM_SELF_INIT_COMPLETE;
1444                else
1445                    tmpReg &= ~FM_PCD_PLCR_PRAM_SELF_INIT_COMPLETE;
1446                WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_ier, tmpReg);
1447                break;
1448            case(e_FM_PCD_PLCR_EXCEPTION_ATOMIC_ACTION_COMPLETE):
1449                tmpReg = GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_ier);
1450                if(enable)
1451                    tmpReg |= FM_PCD_PLCR_ATOMIC_ACTION_COMPLETE;
1452                else
1453                    tmpReg &= ~FM_PCD_PLCR_ATOMIC_ACTION_COMPLETE;
1454                WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_ier, tmpReg);
1455                break;
1456             default:
1457                RETURN_ERROR(MINOR, E_INVALID_STATE, ("Unsupported exception"));
1458        }
1459        /* for ECC exceptions driver automatically enables ECC mechanism, if disabled.
1460           Driver may disable them automatically, depending on driver's status */
1461        if(enable && ( (exception == e_FM_PCD_KG_EXCEPTION_DOUBLE_ECC) |
1462                       (exception == e_FM_PCD_PLCR_EXCEPTION_DOUBLE_ECC) |
1463                       (exception == e_FM_PCD_PRS_EXCEPTION_DOUBLE_ECC) |
1464                       (exception == e_FM_PCD_PRS_EXCEPTION_SINGLE_ECC)))
1465            FmEnableRamsEcc(p_FmPcd->h_Fm);
1466        if(!enable && ( (exception == e_FM_PCD_KG_EXCEPTION_DOUBLE_ECC) |
1467                       (exception == e_FM_PCD_PLCR_EXCEPTION_DOUBLE_ECC) |
1468                       (exception == e_FM_PCD_PRS_EXCEPTION_DOUBLE_ECC) |
1469                       (exception == e_FM_PCD_PRS_EXCEPTION_SINGLE_ECC)))
1470            FmDisableRamsEcc(p_FmPcd->h_Fm);
1471    }
1472    else
1473        RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined exception"));
1474
1475    return E_OK;
1476}
1477
1478t_Error FM_PCD_ForceIntr (t_Handle h_FmPcd, e_FmPcdExceptions exception)
1479{
1480    t_FmPcd            *p_FmPcd = (t_FmPcd*)h_FmPcd;
1481
1482    SANITY_CHECK_RETURN_ERROR(h_FmPcd, E_INVALID_HANDLE);
1483    SANITY_CHECK_RETURN_ERROR(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_STATE);
1484
1485    if(p_FmPcd->guestId != NCSW_MASTER_ID)
1486        RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("FM_PCD_ForceIntr - guest mode!"));
1487
1488    switch(exception)
1489    {
1490        case(e_FM_PCD_KG_EXCEPTION_DOUBLE_ECC):
1491        case(e_FM_PCD_KG_EXCEPTION_KEYSIZE_OVERFLOW):
1492            if(!p_FmPcd->p_FmPcdKg)
1493                RETURN_ERROR(MINOR, E_INVALID_STATE, ("Can't ask for this interrupt - keygen is not working"));
1494            break;
1495        case(e_FM_PCD_PLCR_EXCEPTION_DOUBLE_ECC):
1496        case(e_FM_PCD_PLCR_EXCEPTION_INIT_ENTRY_ERROR):
1497        case(e_FM_PCD_PLCR_EXCEPTION_PRAM_SELF_INIT_COMPLETE):
1498        case(e_FM_PCD_PLCR_EXCEPTION_ATOMIC_ACTION_COMPLETE):
1499            if(!p_FmPcd->p_FmPcdPlcr)
1500                RETURN_ERROR(MINOR, E_INVALID_STATE, ("Can't ask for this interrupt - policer is not working"));
1501            break;
1502        case(e_FM_PCD_PRS_EXCEPTION_DOUBLE_ECC):
1503        case(e_FM_PCD_PRS_EXCEPTION_SINGLE_ECC):
1504           if(!p_FmPcd->p_FmPcdPrs)
1505                RETURN_ERROR(MINOR, E_INVALID_STATE, ("Can't ask for this interrupt -parsrer is not working"));
1506            break;
1507        default:
1508            RETURN_ERROR(MINOR, E_INVALID_STATE, ("Invalid interrupt requested"));
1509
1510    }
1511    switch(exception)
1512    {
1513        case e_FM_PCD_PRS_EXCEPTION_DOUBLE_ECC:
1514            if (!(p_FmPcd->exceptions & FM_PCD_EX_PRS_DOUBLE_ECC))
1515                RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked"));
1516            WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->perfr, FM_PCD_PRS_DOUBLE_ECC);
1517            break;
1518        case e_FM_PCD_PRS_EXCEPTION_SINGLE_ECC:
1519            if (!(p_FmPcd->exceptions & FM_PCD_EX_PRS_SINGLE_ECC))
1520                RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked"));
1521            WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->pevfr, FM_PCD_PRS_SINGLE_ECC);
1522            break;
1523        case e_FM_PCD_KG_EXCEPTION_DOUBLE_ECC:
1524            if (!(p_FmPcd->exceptions & FM_PCD_EX_KG_DOUBLE_ECC))
1525                RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked"));
1526            WRITE_UINT32(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->kgfeer, FM_PCD_KG_DOUBLE_ECC);
1527            break;
1528        case e_FM_PCD_KG_EXCEPTION_KEYSIZE_OVERFLOW:
1529            if (!(p_FmPcd->exceptions & FM_PCD_EX_KG_KEYSIZE_OVERFLOW))
1530                RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked"));
1531            WRITE_UINT32(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->kgfeer, FM_PCD_KG_KEYSIZE_OVERFLOW);
1532            break;
1533        case e_FM_PCD_PLCR_EXCEPTION_DOUBLE_ECC:
1534            if (!(p_FmPcd->exceptions & FM_PCD_EX_PLCR_DOUBLE_ECC))
1535                RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked"));
1536            WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_eifr, FM_PCD_PLCR_DOUBLE_ECC);
1537            break;
1538        case e_FM_PCD_PLCR_EXCEPTION_INIT_ENTRY_ERROR:
1539            if (!(p_FmPcd->exceptions & FM_PCD_EX_PLCR_INIT_ENTRY_ERROR))
1540                RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked"));
1541            WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_eifr, FM_PCD_PLCR_INIT_ENTRY_ERROR);
1542            break;
1543        case e_FM_PCD_PLCR_EXCEPTION_PRAM_SELF_INIT_COMPLETE:
1544            if (!(p_FmPcd->exceptions & FM_PCD_EX_PLCR_PRAM_SELF_INIT_COMPLETE))
1545                RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked"));
1546            WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_ifr, FM_PCD_PLCR_PRAM_SELF_INIT_COMPLETE);
1547            break;
1548        case e_FM_PCD_PLCR_EXCEPTION_ATOMIC_ACTION_COMPLETE:
1549            if (!(p_FmPcd->exceptions & FM_PCD_EX_PLCR_ATOMIC_ACTION_COMPLETE))
1550                RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked"));
1551            WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_ifr, FM_PCD_PLCR_ATOMIC_ACTION_COMPLETE);
1552            break;
1553        default:
1554            RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception may not be forced"));
1555    }
1556
1557    return E_OK;
1558}
1559
1560
1561t_Error FM_PCD_ModifyCounter(t_Handle h_FmPcd, e_FmPcdCounters counter, uint32_t value)
1562{
1563    t_FmPcd            *p_FmPcd = (t_FmPcd*)h_FmPcd;
1564
1565    SANITY_CHECK_RETURN_ERROR(h_FmPcd, E_INVALID_HANDLE);
1566    SANITY_CHECK_RETURN_ERROR(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_STATE);
1567
1568    if(p_FmPcd->guestId != NCSW_MASTER_ID)
1569        RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("FM_PCD_ModifyCounter - guest mode!"));
1570
1571    switch(counter)
1572    {
1573        case(e_FM_PCD_KG_COUNTERS_TOTAL):
1574            if(!p_FmPcd->p_FmPcdKg)
1575                RETURN_ERROR(MINOR, E_INVALID_STATE, ("Can't ask for this counters - keygen is not working"));
1576            break;
1577        case(e_FM_PCD_PLCR_COUNTERS_YELLOW):
1578        case(e_FM_PCD_PLCR_COUNTERS_RED):
1579        case(e_FM_PCD_PLCR_COUNTERS_RECOLORED_TO_RED):
1580        case(e_FM_PCD_PLCR_COUNTERS_RECOLORED_TO_YELLOW):
1581        case(e_FM_PCD_PLCR_COUNTERS_TOTAL):
1582        case(e_FM_PCD_PLCR_COUNTERS_LENGTH_MISMATCH):
1583            if(!p_FmPcd->p_FmPcdPlcr)
1584                RETURN_ERROR(MINOR, E_INVALID_STATE, ("Can't ask for this counters - Policer is not working"));
1585            if(!(GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_gcr) & FM_PCD_PLCR_GCR_STEN))
1586                RETURN_ERROR(MINOR, E_INVALID_STATE, ("Requested counter was not enabled"));
1587            break;
1588        case(e_FM_PCD_PRS_COUNTERS_PARSE_DISPATCH):
1589        case(e_FM_PCD_PRS_COUNTERS_L2_PARSE_RESULT_RETURNED):
1590        case(e_FM_PCD_PRS_COUNTERS_L3_PARSE_RESULT_RETURNED):
1591        case(e_FM_PCD_PRS_COUNTERS_L4_PARSE_RESULT_RETURNED):
1592        case(e_FM_PCD_PRS_COUNTERS_SHIM_PARSE_RESULT_RETURNED):
1593        case(e_FM_PCD_PRS_COUNTERS_L2_PARSE_RESULT_RETURNED_WITH_ERR):
1594        case(e_FM_PCD_PRS_COUNTERS_L3_PARSE_RESULT_RETURNED_WITH_ERR):
1595        case(e_FM_PCD_PRS_COUNTERS_L4_PARSE_RESULT_RETURNED_WITH_ERR):
1596        case(e_FM_PCD_PRS_COUNTERS_SHIM_PARSE_RESULT_RETURNED_WITH_ERR):
1597        case(e_FM_PCD_PRS_COUNTERS_SOFT_PRS_CYCLES):
1598        case(e_FM_PCD_PRS_COUNTERS_SOFT_PRS_STALL_CYCLES):
1599        case(e_FM_PCD_PRS_COUNTERS_HARD_PRS_CYCLE_INCL_STALL_CYCLES):
1600        case(e_FM_PCD_PRS_COUNTERS_MURAM_READ_CYCLES):
1601        case(e_FM_PCD_PRS_COUNTERS_MURAM_READ_STALL_CYCLES):
1602        case(e_FM_PCD_PRS_COUNTERS_MURAM_WRITE_CYCLES):
1603        case(e_FM_PCD_PRS_COUNTERS_MURAM_WRITE_STALL_CYCLES):
1604        case(e_FM_PCD_PRS_COUNTERS_FPM_COMMAND_STALL_CYCLES):
1605            if(!p_FmPcd->p_FmPcdPrs)
1606                RETURN_ERROR(MINOR, E_INVALID_STATE, ("Unsupported type of counter"));
1607            break;
1608        default:
1609            RETURN_ERROR(MINOR, E_INVALID_STATE, ("Unsupported type of counter"));
1610    }
1611    switch(counter)
1612    {
1613        case(e_FM_PCD_PRS_COUNTERS_PARSE_DISPATCH):
1614               WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->pds, value);
1615            break;
1616        case(e_FM_PCD_PRS_COUNTERS_L2_PARSE_RESULT_RETURNED):
1617               WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->l2rrs, value);
1618            break;
1619        case(e_FM_PCD_PRS_COUNTERS_L3_PARSE_RESULT_RETURNED):
1620               WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->l3rrs, value);
1621             break;
1622       case(e_FM_PCD_PRS_COUNTERS_L4_PARSE_RESULT_RETURNED):
1623               WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->l4rrs, value);
1624            break;
1625        case(e_FM_PCD_PRS_COUNTERS_SHIM_PARSE_RESULT_RETURNED):
1626               WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->srrs, value);
1627            break;
1628        case(e_FM_PCD_PRS_COUNTERS_L2_PARSE_RESULT_RETURNED_WITH_ERR):
1629               WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->l2rres, value);
1630            break;
1631        case(e_FM_PCD_PRS_COUNTERS_L3_PARSE_RESULT_RETURNED_WITH_ERR):
1632               WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->l3rres, value);
1633            break;
1634        case(e_FM_PCD_PRS_COUNTERS_L4_PARSE_RESULT_RETURNED_WITH_ERR):
1635               WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->l4rres, value);
1636            break;
1637        case(e_FM_PCD_PRS_COUNTERS_SHIM_PARSE_RESULT_RETURNED_WITH_ERR):
1638               WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->srres, value);
1639            break;
1640        case(e_FM_PCD_PRS_COUNTERS_SOFT_PRS_CYCLES):
1641               WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->spcs, value);
1642            break;
1643        case(e_FM_PCD_PRS_COUNTERS_SOFT_PRS_STALL_CYCLES):
1644               WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->spscs, value);
1645            break;
1646        case(e_FM_PCD_PRS_COUNTERS_HARD_PRS_CYCLE_INCL_STALL_CYCLES):
1647               WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->hxscs, value);
1648            break;
1649        case(e_FM_PCD_PRS_COUNTERS_MURAM_READ_CYCLES):
1650               WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->mrcs, value);
1651            break;
1652        case(e_FM_PCD_PRS_COUNTERS_MURAM_READ_STALL_CYCLES):
1653               WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->mrscs, value);
1654            break;
1655        case(e_FM_PCD_PRS_COUNTERS_MURAM_WRITE_CYCLES):
1656               WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->mwcs, value);
1657            break;
1658        case(e_FM_PCD_PRS_COUNTERS_MURAM_WRITE_STALL_CYCLES):
1659               WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->mwscs, value);
1660            break;
1661        case(e_FM_PCD_PRS_COUNTERS_FPM_COMMAND_STALL_CYCLES):
1662               WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fcscs, value);
1663             break;
1664        case(e_FM_PCD_KG_COUNTERS_TOTAL):
1665            WRITE_UINT32(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->kgtpc,value);
1666            break;
1667
1668        /*Policer counters*/
1669        case(e_FM_PCD_PLCR_COUNTERS_YELLOW):
1670            WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_ypcnt, value);
1671            break;
1672        case(e_FM_PCD_PLCR_COUNTERS_RED):
1673            WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_rpcnt, value);
1674            break;
1675        case(e_FM_PCD_PLCR_COUNTERS_RECOLORED_TO_RED):
1676             WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_rrpcnt, value);
1677            break;
1678        case(e_FM_PCD_PLCR_COUNTERS_RECOLORED_TO_YELLOW):
1679              WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_rypcnt, value);
1680            break;
1681        case(e_FM_PCD_PLCR_COUNTERS_TOTAL):
1682              WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_tpcnt, value);
1683            break;
1684        case(e_FM_PCD_PLCR_COUNTERS_LENGTH_MISMATCH):
1685              WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_flmcnt, value);
1686            break;
1687        default:
1688            RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Unsupported type of counter"));
1689    }
1690
1691return E_OK;
1692}
1693
1694