fm_prs.c revision 302408
1193323Sed/* Copyright (c) 2008-2011 Freescale Semiconductor, Inc.
2193323Sed * All rights reserved.
3193323Sed *
4193323Sed * Redistribution and use in source and binary forms, with or without
5193323Sed * modification, are permitted provided that the following conditions are met:
6193323Sed *     * Redistributions of source code must retain the above copyright
7193323Sed *       notice, this list of conditions and the following disclaimer.
8193323Sed *     * Redistributions in binary form must reproduce the above copyright
9193323Sed *       notice, this list of conditions and the following disclaimer in the
10193323Sed *       documentation and/or other materials provided with the distribution.
11193323Sed *     * Neither the name of Freescale Semiconductor nor the
12193323Sed *       names of its contributors may be used to endorse or promote products
13193323Sed *       derived from this software without specific prior written permission.
14193323Sed *
15193323Sed *
16193323Sed * ALTERNATIVELY, this software may be distributed under the terms of the
17193323Sed * GNU General Public License ("GPL") as published by the Free Software
18193323Sed * Foundation, either version 2 of that License or (at your option) any
19193323Sed * later version.
20193323Sed *
21249423Sdim * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
22218893Sdim * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
23193323Sed * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
24193323Sed * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
25193323Sed * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
26224145Sdim * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
27202375Srdivacky * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
28193323Sed * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29193323Sed * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
30193323Sed * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31193323Sed */
32193323Sed
33193323Sed/******************************************************************************
34193323Sed @File          fm_pcd.c
35195340Sed
36195340Sed @Description   FM PCD ...
37203954Srdivacky*//***************************************************************************/
38239462Sdim#include "std_ext.h"
39234353Sdim#include "error_ext.h"
40193323Sed#include "string_ext.h"
41193323Sed#include "debug_ext.h"
42193323Sed#include "net_ext.h"
43193323Sed
44193323Sed#include "fm_common.h"
45193323Sed#include "fm_pcd.h"
46249423Sdim#include "fm_pcd_ipc.h"
47193323Sed
48193323Sed
49249423Sdimt_Handle PrsConfig(t_FmPcd *p_FmPcd,t_FmPcdParams *p_FmPcdParams)
50193323Sed{
51249423Sdim    t_FmPcdPrs  *p_FmPcdPrs;
52249423Sdim    uintptr_t   baseAddr;
53249423Sdim
54249423Sdim    UNUSED(p_FmPcd);
55193323Sed    UNUSED(p_FmPcdParams);
56193323Sed
57193323Sed    p_FmPcdPrs = (t_FmPcdPrs *) XX_Malloc(sizeof(t_FmPcdPrs));
58221345Sdim    if (!p_FmPcdPrs)
59193323Sed    {
60193323Sed        REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM Parser structure allocation FAILED"));
61193323Sed        return NULL;
62193323Sed    }
63193323Sed    memset(p_FmPcdPrs, 0, sizeof(t_FmPcdPrs));
64193323Sed
65193323Sed    if (p_FmPcd->guestId == NCSW_MASTER_ID)
66193323Sed    {
67193323Sed        baseAddr = FmGetPcdPrsBaseAddr(p_FmPcdParams->h_Fm);
68249423Sdim        p_FmPcdPrs->p_SwPrsCode  = (uint32_t *)UINT_TO_PTR(baseAddr);
69249423Sdim        p_FmPcdPrs->p_FmPcdPrsRegs  = (t_FmPcdPrsRegs *)UINT_TO_PTR(baseAddr + PRS_REGS_OFFSET);
70249423Sdim    }
71249423Sdim
72249423Sdim    p_FmPcdPrs->fmPcdPrsPortIdStatistics             = 0;
73249423Sdim    p_FmPcd->p_FmPcdDriverParam->prsMaxParseCycleLimit   = DEFAULT_prsMaxParseCycleLimit;
74249423Sdim    p_FmPcd->exceptions |= (DEFAULT_fmPcdPrsErrorExceptions | DEFAULT_fmPcdPrsExceptions);
75249423Sdim
76249423Sdim    return p_FmPcdPrs;
77249423Sdim}
78193323Sed
79193323Sedstatic void PcdPrsErrorException(t_Handle h_FmPcd)
80193323Sed{
81193323Sed    t_FmPcd                 *p_FmPcd = (t_FmPcd *)h_FmPcd;
82193323Sed    uint32_t                event, mask, force;
83193323Sed
84249423Sdim    ASSERT_COND(p_FmPcd->guestId == NCSW_MASTER_ID);
85193323Sed    event = GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->perr);
86193323Sed    mask = GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->perer);
87193323Sed
88224145Sdim    event &= mask;
89249423Sdim
90224145Sdim    /* clear the forced events */
91224145Sdim    force = GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->perfr);
92224145Sdim    if(force & event)
93193323Sed        WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->perfr, force & ~event);
94249423Sdim
95193323Sed    WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->perr, event);
96193323Sed
97193323Sed    DBG(TRACE, ("parser error - 0x%08x\n",event));
98195098Sed
99195098Sed    if(event & FM_PCD_PRS_DOUBLE_ECC)
100249423Sdim        p_FmPcd->f_Exception(p_FmPcd->h_App,e_FM_PCD_PRS_EXCEPTION_DOUBLE_ECC);
101193323Sed}
102193323Sed
103193323Sedstatic void PcdPrsException(t_Handle h_FmPcd)
104223017Sdim{
105249423Sdim    t_FmPcd             *p_FmPcd = (t_FmPcd *)h_FmPcd;
106193323Sed    uint32_t            event, force;
107193323Sed
108193323Sed    ASSERT_COND(p_FmPcd->guestId == NCSW_MASTER_ID);
109193323Sed    event = GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->pevr);
110195098Sed    event &= GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->pever);
111195098Sed
112249423Sdim    ASSERT_COND(event & FM_PCD_PRS_SINGLE_ECC);
113193323Sed
114193323Sed    DBG(TRACE, ("parser event - 0x%08x\n",event));
115193323Sed
116239462Sdim    /* clear the forced events */
117239462Sdim    force = GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->pevfr);
118249423Sdim    if(force & event)
119249423Sdim        WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->pevfr, force & ~event);
120239462Sdim
121239462Sdim    WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->pevr, event);
122239462Sdim
123195098Sed    p_FmPcd->f_Exception(p_FmPcd->h_App,e_FM_PCD_PRS_EXCEPTION_SINGLE_ECC);
124195098Sed}
125249423Sdim
126193323Sedstatic uint32_t GetSwPrsOffset(t_Handle h_FmPcd,  e_NetHeaderType hdr, uint8_t  indexPerHdr)
127193323Sed{
128193323Sed    t_FmPcd                 *p_FmPcd = (t_FmPcd*)h_FmPcd;
129207618Srdivacky    int                     i;
130195098Sed    t_FmPcdPrsLabelParams   *p_Label;
131195098Sed
132249423Sdim    SANITY_CHECK_RETURN_VALUE(p_FmPcd, E_INVALID_HANDLE, 0);
133193323Sed    SANITY_CHECK_RETURN_VALUE(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_HANDLE, 0);
134193323Sed
135193323Sed    ASSERT_COND(p_FmPcd->guestId == NCSW_MASTER_ID);
136193323Sed    ASSERT_COND(p_FmPcd->p_FmPcdPrs->currLabel < FM_PCD_PRS_NUM_OF_LABELS);
137195098Sed
138249423Sdim    for (i=0; i < p_FmPcd->p_FmPcdPrs->currLabel; i++)
139193323Sed    {
140193323Sed        p_Label = &p_FmPcd->p_FmPcdPrs->labelsTable[i];
141193323Sed
142249423Sdim        if ((hdr == p_Label->hdr) && (indexPerHdr == p_Label->indexPerHdr))
143249423Sdim            return p_Label->instructionOffset;
144249423Sdim    }
145249423Sdim
146249423Sdim    REPORT_ERROR(MAJOR, E_NOT_FOUND, ("Sw Parser attachment Not found"));
147249423Sdim    return (uint32_t)ILLEGAL_BASE;
148249423Sdim}
149234353Sdim
150249423Sdimt_Error PrsInit(t_FmPcd *p_FmPcd)
151234353Sdim{
152234353Sdim    t_FmPcdDriverParam  *p_Param = p_FmPcd->p_FmPcdDriverParam;
153234353Sdim    t_FmPcdPrsRegs      *p_Regs = p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs;
154198090Srdivacky    uint32_t            tmpReg;
155249423Sdim
156193323Sed    if(p_FmPcd->guestId != NCSW_MASTER_ID)
157193323Sed        return E_OK;
158193323Sed
159218893Sdim    ASSERT_COND(p_FmPcd->guestId == NCSW_MASTER_ID);
160218893Sdim
161218893Sdim#ifdef FM_PRS_MEM_ERRATA_FMAN_SW003
162218893Sdim    {
163218893Sdim        uint32_t            i;
164218893Sdim        uint32_t            regsToGlobalOffset = 0x840;
165218893Sdim        uint32_t            firstPortToGlobalOffset = 0x45800;
166193323Sed        uint64_t            globalAddr = PTR_TO_UINT(p_Regs) - regsToGlobalOffset;
167249423Sdim        uint32_t            firstPortAddr = (uint32_t)(globalAddr - (uint64_t)firstPortToGlobalOffset);
168193323Sed        uint32_t            portSize = 0x1000;
169193323Sed        t_FmRevisionInfo    revInfo;
170202375Srdivacky
171204642Srdivacky        FM_GetRevision(p_FmPcd->h_Fm, &revInfo);
172249423Sdim        if ((revInfo.majorRev == 1) && (revInfo.minorRev == 0))
173202375Srdivacky        {
174202375Srdivacky            /* clear all parser memory */
175205218Srdivacky            IOMemSet32(UINT_TO_PTR(globalAddr), 0x00000000, 0x800);
176205218Srdivacky            for(i = 0;i<16;i++)
177249423Sdim                IOMemSet32(UINT_TO_PTR(firstPortAddr+i*portSize), (uint8_t)0x00000000, (uint32_t)0x80);
178205218Srdivacky        }
179205218Srdivacky    }
180218893Sdim#endif /* FM_PRS_MEM_ERRATA_FMAN_SW003 */
181221345Sdim
182221345Sdim    /**********************RPCLIM******************/
183221345Sdim    WRITE_UINT32(p_Regs->rpclim, (uint32_t)p_Param->prsMaxParseCycleLimit);
184221345Sdim    /**********************FMPL_RPCLIM******************/
185221345Sdim
186221345Sdim    /* register even if no interrupts enabled, to allow future enablement */
187221345Sdim    FmRegisterIntr(p_FmPcd->h_Fm, e_FM_MOD_PRS, 0, e_FM_INTR_TYPE_ERR, PcdPrsErrorException, p_FmPcd);
188221345Sdim
189221345Sdim    /* register even if no interrupts enabled, to allow future enablement */
190221345Sdim    FmRegisterIntr(p_FmPcd->h_Fm, e_FM_MOD_PRS, 0, e_FM_INTR_TYPE_NORMAL, PcdPrsException, p_FmPcd);
191218893Sdim
192243830Sdim    /**********************PEVR******************/
193243830Sdim    WRITE_UINT32(p_Regs->pevr, (FM_PCD_PRS_SINGLE_ECC | FM_PCD_PRS_PORT_IDLE_STS) );
194218893Sdim    /**********************PEVR******************/
195218893Sdim
196218893Sdim    /**********************PEVER******************/
197218893Sdim    if(p_FmPcd->exceptions & FM_PCD_EX_PRS_SINGLE_ECC)
198218893Sdim    {
199243830Sdim        FmEnableRamsEcc(p_FmPcd->h_Fm);
200243830Sdim        WRITE_UINT32(p_Regs->pever, FM_PCD_PRS_SINGLE_ECC);
201243830Sdim    }
202243830Sdim    else
203243830Sdim        WRITE_UINT32(p_Regs->pever, 0);
204243830Sdim    /**********************PEVER******************/
205243830Sdim
206243830Sdim    /**********************PERR******************/
207243830Sdim    WRITE_UINT32(p_Regs->perr, FM_PCD_PRS_DOUBLE_ECC);
208243830Sdim
209243830Sdim    /**********************PERR******************/
210218893Sdim
211218893Sdim    /**********************PERER******************/
212249423Sdim    tmpReg = 0;
213249423Sdim    if(p_FmPcd->exceptions & FM_PCD_EX_PRS_DOUBLE_ECC)
214249423Sdim    {
215249423Sdim        FmEnableRamsEcc(p_FmPcd->h_Fm);
216249423Sdim        tmpReg |= FM_PCD_PRS_DOUBLE_ECC;
217249423Sdim    }
218193323Sed    WRITE_UINT32(p_Regs->perer, tmpReg);
219193323Sed    /**********************PERER******************/
220193323Sed
221193323Sed    /**********************PPCS******************/
222193323Sed    WRITE_UINT32(p_Regs->ppsc, p_FmPcd->p_FmPcdPrs->fmPcdPrsPortIdStatistics);
223193323Sed    /**********************PPCS******************/
224193323Sed
225224145Sdim#ifdef FM_PRS_L4_SHELL_ERRATA_FMANb
226249423Sdim    {
227193323Sed        uint32_t            i, j;
228193323Sed        t_FmRevisionInfo    revInfo;
229193323Sed        uint8_t             swPrsL4Patch[] = SW_PRS_L4_PATCH;
230193323Sed
231193323Sed        FM_GetRevision(p_FmPcd->h_Fm, &revInfo);
232193323Sed        if ((revInfo.majorRev == 1) && (revInfo.minorRev == 0))
233193323Sed        {
234224145Sdim            /* load sw parser L4 patch */
235193323Sed            for(i=0;i<sizeof(swPrsL4Patch)/4;i++)
236249423Sdim            {
237193323Sed               tmpReg = 0;
238193323Sed               for(j =0;j<4;j++)
239193323Sed               {
240193323Sed                  tmpReg <<= 8;
241193323Sed                  tmpReg |= swPrsL4Patch[i*4+j];
242193323Sed
243193323Sed               }
244193323Sed                WRITE_UINT32(*(p_FmPcd->p_FmPcdPrs->p_SwPrsCode+ FM_PCD_PRS_SW_OFFSET/4 + i), tmpReg);
245193323Sed            }
246193323Sed            p_FmPcd->p_FmPcdPrs->p_CurrSwPrs = FM_PCD_PRS_SW_OFFSET/4 + p_FmPcd->p_FmPcdPrs->p_SwPrsCode+sizeof(swPrsL4Patch)/4;
247224145Sdim        }
248193323Sed    }
249249423Sdim#endif /* FM_PRS_L4_SHELL_ERRATA_FMANb */
250249423Sdim
251193323Sed    return E_OK;
252249423Sdim}
253193323Sed
254193323Sedvoid PrsFree(t_FmPcd *p_FmPcd )
255234353Sdim{
256234353Sdim    ASSERT_COND(p_FmPcd->guestId == NCSW_MASTER_ID);
257234353Sdim    FmUnregisterIntr(p_FmPcd->h_Fm, e_FM_MOD_PRS, 0, e_FM_INTR_TYPE_ERR);
258234353Sdim    /* register even if no interrupts enabled, to allow future enablement */
259234353Sdim    FmUnregisterIntr(p_FmPcd->h_Fm, e_FM_MOD_PRS, 0, e_FM_INTR_TYPE_NORMAL);
260249423Sdim}
261249423Sdim
262234353Sdimvoid PrsEnable(t_FmPcd *p_FmPcd )
263249423Sdim{
264234353Sdim    t_FmPcdPrsRegs      *p_Regs = p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs;
265234353Sdim
266234353Sdim    ASSERT_COND(p_FmPcd->guestId == NCSW_MASTER_ID);
267234353Sdim    WRITE_UINT32(p_Regs->rpimac, GET_UINT32(p_Regs->rpimac) | FM_PCD_PRS_RPIMAC_EN);
268234353Sdim}
269234353Sdim
270234353Sdimvoid PrsDisable(t_FmPcd *p_FmPcd )
271234353Sdim{
272234353Sdim    t_FmPcdPrsRegs      *p_Regs = p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs;
273234353Sdim
274234353Sdim    ASSERT_COND(p_FmPcd->guestId == NCSW_MASTER_ID);
275234353Sdim    WRITE_UINT32(p_Regs->rpimac, GET_UINT32(p_Regs->rpimac) & ~FM_PCD_PRS_RPIMAC_EN);
276234353Sdim}
277234353Sdim
278234353Sdimt_Error PrsIncludePortInStatistics(t_FmPcd *p_FmPcd, uint8_t hardwarePortId, bool include)
279234353Sdim{
280193323Sed    uint32_t    bitMask = 0;
281193323Sed    uint8_t     prsPortId;
282193323Sed
283193323Sed    SANITY_CHECK_RETURN_ERROR((hardwarePortId >=1 && hardwarePortId <= 16), E_INVALID_VALUE);
284193323Sed    SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
285193323Sed    SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdPrs, E_INVALID_HANDLE);
286193323Sed
287224145Sdim    GET_FM_PCD_PRS_PORT_ID(prsPortId, hardwarePortId);
288249423Sdim    GET_FM_PCD_INDEX_FLAG(bitMask, prsPortId);
289249423Sdim
290193323Sed    if(include)
291249423Sdim        p_FmPcd->p_FmPcdPrs->fmPcdPrsPortIdStatistics |= bitMask;
292193323Sed    else
293193323Sed        p_FmPcd->p_FmPcdPrs->fmPcdPrsPortIdStatistics &= ~bitMask;
294234353Sdim
295234353Sdim    WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->ppsc, p_FmPcd->p_FmPcdPrs->fmPcdPrsPortIdStatistics);
296234353Sdim
297234353Sdim    return E_OK;
298249423Sdim}
299249423Sdim
300234353Sdimt_Error FmPcdPrsIncludePortInStatistics(t_Handle h_FmPcd, uint8_t hardwarePortId, bool include)
301249423Sdim{
302234353Sdim    t_FmPcd                     *p_FmPcd = (t_FmPcd *)h_FmPcd;
303234353Sdim    t_FmPcdIpcPrsIncludePort    prsIncludePortParams;
304234353Sdim    t_FmPcdIpcMsg               msg;
305234353Sdim    t_Error                     err;
306234353Sdim
307234353Sdim    SANITY_CHECK_RETURN_ERROR((hardwarePortId >=1 && hardwarePortId <= 16), E_INVALID_VALUE);
308234353Sdim    SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
309234353Sdim    SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdPrs, E_INVALID_HANDLE);
310234353Sdim
311234353Sdim    if(p_FmPcd->guestId != NCSW_MASTER_ID)
312234353Sdim    {
313234353Sdim        prsIncludePortParams.hardwarePortId = hardwarePortId;
314234353Sdim        prsIncludePortParams.include = include;
315234353Sdim        memset(&msg, 0, sizeof(msg));
316234353Sdim        msg.msgId = FM_PCD_PRS_INC_PORT_STATS;
317193323Sed        memcpy(msg.msgBody, &prsIncludePortParams, sizeof(prsIncludePortParams));
318193323Sed        if ((err = XX_IpcSendMessage(p_FmPcd->h_IpcSession,
319193323Sed                                     (uint8_t*)&msg,
320193323Sed                                     sizeof(msg.msgId) +sizeof(prsIncludePortParams),
321193323Sed                                     NULL,
322193323Sed                                     NULL,
323224145Sdim                                     NULL,
324224145Sdim                                     NULL)) != E_OK)
325193323Sed            RETURN_ERROR(MAJOR, err, NO_MSG);
326193323Sed        return E_OK;
327193323Sed    }
328193323Sed    return PrsIncludePortInStatistics(p_FmPcd, hardwarePortId, include);
329198090Srdivacky}
330193323Sed
331193323Seduint32_t FmPcdGetSwPrsOffset(t_Handle h_FmPcd, e_NetHeaderType hdr, uint8_t indexPerHdr)
332193323Sed{
333224145Sdim    t_FmPcd                 *p_FmPcd = (t_FmPcd *)h_FmPcd;
334193323Sed    t_Error                 err = E_OK;
335224145Sdim    t_FmPcdIpcSwPrsLable    labelParams;
336193323Sed    t_FmPcdIpcMsg           msg;
337193323Sed    uint32_t                prsOffset = 0;
338263508Sdim    t_FmPcdIpcReply         reply;
339263508Sdim    uint32_t                replyLength;
340263508Sdim
341263508Sdim    if(p_FmPcd->guestId != NCSW_MASTER_ID)
342263508Sdim    {
343263508Sdim        memset(&reply, 0, sizeof(reply));
344263508Sdim        memset(&msg, 0, sizeof(msg));
345263508Sdim        labelParams.enumHdr = (uint32_t)hdr;
346263508Sdim        labelParams.indexPerHdr = indexPerHdr;
347263508Sdim        msg.msgId = FM_PCD_GET_SW_PRS_OFFSET;
348263508Sdim        memcpy(msg.msgBody, &labelParams, sizeof(labelParams));
349263508Sdim        replyLength = sizeof(uint32_t) + sizeof(uint32_t);
350263508Sdim        if ((err = XX_IpcSendMessage(p_FmPcd->h_IpcSession,
351263508Sdim                                     (uint8_t*)&msg,
352263508Sdim                                     sizeof(msg.msgId) +sizeof(labelParams),
353263508Sdim                                     (uint8_t*)&reply,
354263508Sdim                                     &replyLength,
355263508Sdim                                     NULL,
356263508Sdim                                     NULL)) != E_OK)
357263508Sdim            RETURN_ERROR(MAJOR, err, NO_MSG);
358263508Sdim        if(replyLength != sizeof(uint32_t) + sizeof(uint32_t))
359263508Sdim            RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
360263508Sdim
361263508Sdim        memcpy((uint8_t*)&prsOffset, reply.replyBody, sizeof(uint32_t));
362263508Sdim        return prsOffset;
363263508Sdim    }
364263508Sdim
365263508Sdim    return GetSwPrsOffset(h_FmPcd, hdr, indexPerHdr);
366263508Sdim}
367263508Sdim
368263508Sdimvoid FM_PCD_SetPrsStatistics(t_Handle h_FmPcd, bool enable)
369263508Sdim{
370263508Sdim    t_FmPcd             *p_FmPcd = (t_FmPcd*)h_FmPcd;
371263508Sdim
372263508Sdim    SANITY_CHECK_RETURN(p_FmPcd, E_INVALID_HANDLE);
373263508Sdim    SANITY_CHECK_RETURN(p_FmPcd->p_FmPcdPrs, E_INVALID_HANDLE);
374263508Sdim
375263508Sdim    if(p_FmPcd->guestId != NCSW_MASTER_ID)
376263508Sdim    {
377263508Sdim        REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("FM_PCD_SetPrsStatistics - guest mode!"));
378263508Sdim        return;
379263508Sdim    }
380263508Sdim    if(enable)
381263508Sdim        WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->ppsc, FM_PCD_PRS_PPSC_ALL_PORTS);
382263508Sdim    else
383193323Sed        WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->ppsc, 0);
384193323Sed
385193323Sed}
386193323Sed
387193323Sedt_Error FM_PCD_PrsLoadSw(t_Handle h_FmPcd, t_FmPcdPrsSwParams *p_SwPrs)
388193323Sed{
389193323Sed    t_FmPcd                 *p_FmPcd = (t_FmPcd*)h_FmPcd;
390193323Sed    uint32_t                *p_LoadTarget, tmpReg;
391193323Sed    int                     i, j;
392193323Sed
393193323Sed    SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
394193323Sed    SANITY_CHECK_RETURN_ERROR(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_STATE);
395195340Sed    SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdPrs, E_INVALID_STATE);
396195340Sed    SANITY_CHECK_RETURN_ERROR(p_SwPrs, E_INVALID_HANDLE);
397195340Sed    SANITY_CHECK_RETURN_ERROR(!p_FmPcd->enabled, E_INVALID_HANDLE);
398239462Sdim
399239462Sdim    if(p_FmPcd->guestId != NCSW_MASTER_ID)
400239462Sdim        RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("FM_PCD_PrsLoadSw - guest mode!"));
401249423Sdim
402249423Sdim    if(!p_SwPrs->override)
403249423Sdim    {
404193323Sed        if(p_FmPcd->p_FmPcdPrs->p_CurrSwPrs > p_FmPcd->p_FmPcdPrs->p_SwPrsCode + p_SwPrs->base*2/4)
405249423Sdim            RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("SW parser base must be larger than current loaded code"));
406249423Sdim    }
407249423Sdim    if(p_SwPrs->size > FM_PCD_SW_PRS_SIZE - FM_PCD_PRS_SW_TAIL_SIZE - p_SwPrs->base*2)
408249423Sdim        RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("p_SwPrs->size may not be larger than MAX_SW_PRS_CODE_SIZE"));
409249423Sdim    if(p_SwPrs->size % 4)
410249423Sdim        RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("p_SwPrs->size must be divisible by 4"));
411249423Sdim
412249423Sdim    /* save sw parser labels */
413249423Sdim    if(p_SwPrs->override)
414249423Sdim        p_FmPcd->p_FmPcdPrs->currLabel = 0;
415249423Sdim    if(p_FmPcd->p_FmPcdPrs->currLabel+ p_SwPrs->numOfLabels > FM_PCD_PRS_NUM_OF_LABELS)
416249423Sdim        RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Exceeded number of labels allowed "));
417249423Sdim    memcpy(&p_FmPcd->p_FmPcdPrs->labelsTable[p_FmPcd->p_FmPcdPrs->currLabel], p_SwPrs->labelsTable, p_SwPrs->numOfLabels*sizeof(t_FmPcdPrsLabelParams));
418249423Sdim    p_FmPcd->p_FmPcdPrs->currLabel += p_SwPrs->numOfLabels;
419249423Sdim    /* load sw parser code */
420249423Sdim    p_LoadTarget = p_FmPcd->p_FmPcdPrs->p_SwPrsCode + p_SwPrs->base*2/4;
421249423Sdim    for(i=0;i<p_SwPrs->size/4;i++)
422249423Sdim    {
423249423Sdim        tmpReg = 0;
424249423Sdim        for(j =0;j<4;j++)
425249423Sdim        {
426249423Sdim            tmpReg <<= 8;
427249423Sdim            tmpReg |= *(p_SwPrs->p_Code+i*4+j);
428249423Sdim        }
429249423Sdim        WRITE_UINT32(*(p_LoadTarget + i), tmpReg);
430249423Sdim    }
431249423Sdim    p_FmPcd->p_FmPcdPrs->p_CurrSwPrs = p_FmPcd->p_FmPcdPrs->p_SwPrsCode + p_SwPrs->base*2/4 + p_SwPrs->size/4;
432249423Sdim
433249423Sdim    /* copy data parameters */
434249423Sdim    for(i=0;i<FM_PCD_PRS_NUM_OF_HDRS;i++)
435249423Sdim        WRITE_UINT32(*(p_FmPcd->p_FmPcdPrs->p_SwPrsCode+PRS_SW_DATA/4+i), p_SwPrs->swPrsDataParams[i]);
436249423Sdim
437249423Sdim
438249423Sdim    /* Clear last 4 bytes */
439249423Sdim    WRITE_UINT32(*(p_FmPcd->p_FmPcdPrs->p_SwPrsCode+(PRS_SW_DATA-FM_PCD_PRS_SW_TAIL_SIZE)/4), 0);
440249423Sdim
441249423Sdim    return E_OK;
442249423Sdim}
443249423Sdim
444249423Sdimt_Error FM_PCD_ConfigPrsMaxCycleLimit(t_Handle h_FmPcd,uint16_t value)
445249423Sdim{
446249423Sdim    t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
447249423Sdim
448249423Sdim    SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
449249423Sdim    SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdDriverParam, E_INVALID_HANDLE);
450249423Sdim
451249423Sdim    if(p_FmPcd->guestId != NCSW_MASTER_ID)
452249423Sdim        RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("FM_PCD_ConfigPrsMaxCycleLimit - guest mode!"));
453249423Sdim
454249423Sdim    p_FmPcd->p_FmPcdDriverParam->prsMaxParseCycleLimit = value;
455249423Sdim
456249423Sdim    return E_OK;
457249423Sdim}
458249423Sdim
459249423Sdim
460249423Sdim#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
461249423Sdimt_Error FM_PCD_PrsDumpRegs(t_Handle h_FmPcd)
462249423Sdim{
463249423Sdim    t_FmPcd             *p_FmPcd = (t_FmPcd*)h_FmPcd;
464249423Sdim    t_FmPcdIpcMsg       msg;
465249423Sdim
466249423Sdim    DECLARE_DUMP;
467249423Sdim
468249423Sdim    SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
469249423Sdim    SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdPrs, E_INVALID_HANDLE);
470249423Sdim    SANITY_CHECK_RETURN_ERROR(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_STATE);
471249423Sdim
472249423Sdim    if(p_FmPcd->guestId != NCSW_MASTER_ID)
473249423Sdim    {
474249423Sdim        memset(&msg, 0, sizeof(msg));
475249423Sdim        msg.msgId = FM_PCD_PRS_DUMP_REGS;
476249423Sdim        return XX_IpcSendMessage(p_FmPcd->h_IpcSession,
477249423Sdim                                    (uint8_t*)&msg,
478249423Sdim                                    sizeof(msg.msgId),
479249423Sdim                                    NULL,
480249423Sdim                                    NULL,
481249423Sdim                                    NULL,
482249423Sdim                                    NULL);
483249423Sdim    }
484249423Sdim    DUMP_SUBTITLE(("\n"));
485249423Sdim    DUMP_TITLE(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs, ("FmPcdPrsRegs Regs"));
486249423Sdim
487249423Sdim    DUMP_VAR(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs,rpclim);
488249423Sdim    DUMP_VAR(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs,rpimac);
489249423Sdim    DUMP_VAR(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs,pmeec);
490193323Sed    DUMP_VAR(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs,pevr);
491193323Sed    DUMP_VAR(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs,pever);
492193323Sed    DUMP_VAR(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs,pevfr);
493    DUMP_VAR(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs,perr);
494    DUMP_VAR(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs,perer);
495    DUMP_VAR(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs,perfr);
496    DUMP_VAR(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs,ppsc);
497    DUMP_VAR(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs,pds);
498    DUMP_VAR(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs,l2rrs);
499    DUMP_VAR(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs,l3rrs);
500    DUMP_VAR(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs,l4rrs);
501    DUMP_VAR(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs,srrs);
502    DUMP_VAR(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs,l2rres);
503    DUMP_VAR(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs,l3rres);
504    DUMP_VAR(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs,l4rres);
505    DUMP_VAR(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs,srres);
506    DUMP_VAR(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs,spcs);
507    DUMP_VAR(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs,spscs);
508    DUMP_VAR(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs,hxscs);
509    DUMP_VAR(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs,mrcs);
510    DUMP_VAR(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs,mwcs);
511    DUMP_VAR(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs,mrscs);
512    DUMP_VAR(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs,mwscs);
513    DUMP_VAR(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs,fcscs);
514
515    return E_OK;
516}
517#endif /* (defined(DEBUG_ERRORS) && ... */
518