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.c
35
36 @Description   FM driver routines implementation.
37*//***************************************************************************/
38#include "std_ext.h"
39#include "error_ext.h"
40#include "xx_ext.h"
41#include "string_ext.h"
42#include "sprint_ext.h"
43#include "debug_ext.h"
44#include "fm_muram_ext.h"
45
46#include "fm_common.h"
47#include "fm_ipc.h"
48#include "fm.h"
49
50
51/****************************************/
52/*       static functions               */
53/****************************************/
54
55static volatile bool blockingFlag = FALSE;
56static void IpcMsgCompletionCB(t_Handle   h_Fm,
57                               uint8_t    *p_Msg,
58                               uint8_t    *p_Reply,
59                               uint32_t   replyLength,
60                               t_Error    status)
61{
62    UNUSED(h_Fm);UNUSED(p_Msg);UNUSED(p_Reply);UNUSED(replyLength);UNUSED(status);
63    blockingFlag = FALSE;
64}
65
66static bool IsFmanCtrlCodeLoaded(t_Fm *p_Fm)
67{
68    t_FMIramRegs    *p_Iram;
69
70    ASSERT_COND(p_Fm);
71    p_Iram = (t_FMIramRegs *)UINT_TO_PTR(p_Fm->baseAddr + FM_MM_IMEM);
72
73    return (bool)!!(GET_UINT32(p_Iram->iready) & IRAM_READY);
74}
75
76static t_Error CheckFmParameters(t_Fm *p_Fm)
77{
78    if (IsFmanCtrlCodeLoaded(p_Fm) && !p_Fm->p_FmDriverParam->resetOnInit)
79        RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Old FMan CTRL code is loaded; FM must be reset!"));
80    if(!p_Fm->p_FmDriverParam->dmaAxiDbgNumOfBeats || (p_Fm->p_FmDriverParam->dmaAxiDbgNumOfBeats > DMA_MODE_MAX_AXI_DBG_NUM_OF_BEATS))
81        RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("axiDbgNumOfBeats has to be in the range 1 - %d", DMA_MODE_MAX_AXI_DBG_NUM_OF_BEATS));
82    if(p_Fm->p_FmDriverParam->dmaCamNumOfEntries % DMA_CAM_UNITS)
83        RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dmaCamNumOfEntries has to be divisble by %d", DMA_CAM_UNITS));
84    if(!p_Fm->p_FmDriverParam->dmaCamNumOfEntries || (p_Fm->p_FmDriverParam->dmaCamNumOfEntries > DMA_MODE_MAX_CAM_NUM_OF_ENTRIES))
85        RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dmaCamNumOfEntries has to be in the range 1 - %d", DMA_MODE_MAX_CAM_NUM_OF_ENTRIES));
86    if(p_Fm->p_FmDriverParam->dmaCommQThresholds.assertEmergency > DMA_THRESH_MAX_COMMQ)
87        RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dmaCommQThresholds.assertEmergency can not be larger than %d", DMA_THRESH_MAX_COMMQ));
88    if(p_Fm->p_FmDriverParam->dmaCommQThresholds.clearEmergency > DMA_THRESH_MAX_COMMQ)
89        RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dmaCommQThresholds.clearEmergency can not be larger than %d", DMA_THRESH_MAX_COMMQ));
90    if(p_Fm->p_FmDriverParam->dmaCommQThresholds.clearEmergency >= p_Fm->p_FmDriverParam->dmaCommQThresholds.assertEmergency)
91        RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dmaCommQThresholds.clearEmergency must be smaller than dmaCommQThresholds.assertEmergency"));
92    if(p_Fm->p_FmDriverParam->dmaReadBufThresholds.assertEmergency > DMA_THRESH_MAX_BUF)
93        RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dmaReadBufThresholds.assertEmergency can not be larger than %d", DMA_THRESH_MAX_BUF));
94    if(p_Fm->p_FmDriverParam->dmaReadBufThresholds.clearEmergency > DMA_THRESH_MAX_BUF)
95        RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dmaReadBufThresholds.clearEmergency can not be larger than %d", DMA_THRESH_MAX_BUF));
96    if(p_Fm->p_FmDriverParam->dmaReadBufThresholds.clearEmergency >= p_Fm->p_FmDriverParam->dmaReadBufThresholds.assertEmergency)
97        RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dmaReadBufThresholds.clearEmergency must be smaller than dmaReadBufThresholds.assertEmergency"));
98    if(p_Fm->p_FmDriverParam->dmaWriteBufThresholds.assertEmergency > DMA_THRESH_MAX_BUF)
99        RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dmaWriteBufThresholds.assertEmergency can not be larger than %d", DMA_THRESH_MAX_BUF));
100    if(p_Fm->p_FmDriverParam->dmaWriteBufThresholds.clearEmergency > DMA_THRESH_MAX_BUF)
101        RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dmaWriteBufThresholds.clearEmergency can not be larger than %d", DMA_THRESH_MAX_BUF));
102    if(p_Fm->p_FmDriverParam->dmaWriteBufThresholds.clearEmergency >= p_Fm->p_FmDriverParam->dmaWriteBufThresholds.assertEmergency)
103        RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dmaWriteBufThresholds.clearEmergency must be smaller than dmaWriteBufThresholds.assertEmergency"));
104
105    if(!p_Fm->p_FmStateStruct->fmClkFreq)
106        RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fmClkFreq must be set."));
107    if (USEC_TO_CLK(p_Fm->p_FmDriverParam->dmaWatchdog, p_Fm->p_FmStateStruct->fmClkFreq) > DMA_MAX_WATCHDOG)
108        RETURN_ERROR(MAJOR, E_INVALID_VALUE,
109                     ("dmaWatchdog depends on FM clock. dmaWatchdog(in microseconds) * clk (in Mhz), may not exceed 0x08x", DMA_MAX_WATCHDOG));
110
111#ifdef FM_PARTITION_ARRAY
112    {
113        t_FmRevisionInfo revInfo;
114        uint8_t     i;
115
116        FM_GetRevision(p_Fm, &revInfo);
117        if ((revInfo.majorRev == 1) && (revInfo.minorRev == 0))
118            for (i=0; i<FM_SIZE_OF_LIODN_TABLE; i++)
119                if (p_Fm->p_FmDriverParam->liodnBasePerPort[i] & ~FM_LIODN_BASE_MASK)
120                    RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("liodn number is out of range"));
121    }
122#endif /* FM_PARTITION_ARRAY */
123
124    if(p_Fm->p_FmStateStruct->totalFifoSize % BMI_FIFO_UNITS)
125        RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("totalFifoSize number has to be divisible by %d", BMI_FIFO_UNITS));
126    if(!p_Fm->p_FmStateStruct->totalFifoSize || (p_Fm->p_FmStateStruct->totalFifoSize > BMI_MAX_FIFO_SIZE))
127        RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("totalFifoSize number has to be in the range 256 - %d", BMI_MAX_FIFO_SIZE));
128    if(!p_Fm->p_FmStateStruct->totalNumOfTasks || (p_Fm->p_FmStateStruct->totalNumOfTasks > BMI_MAX_NUM_OF_TASKS))
129        RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("totalNumOfTasks number has to be in the range 1 - %d", BMI_MAX_NUM_OF_TASKS));
130    if(!p_Fm->p_FmStateStruct->maxNumOfOpenDmas || (p_Fm->p_FmStateStruct->maxNumOfOpenDmas > BMI_MAX_NUM_OF_DMAS))
131        RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("maxNumOfOpenDmas number has to be in the range 1 - %d", BMI_MAX_NUM_OF_DMAS));
132
133    if(p_Fm->p_FmDriverParam->thresholds.dispLimit > FPM_MAX_DISP_LIMIT)
134        RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("thresholds.dispLimit can't be greater than %d", FPM_MAX_DISP_LIMIT));
135
136    if(!p_Fm->f_Exception)
137        RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Exceptions callback not provided"));
138    if(!p_Fm->f_BusError)
139        RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Exceptions callback not provided"));
140
141    return E_OK;
142}
143
144static void SendIpcIsr(t_Fm *p_Fm, uint32_t macEvent, uint32_t pendingReg)
145{
146    t_Error     err;
147    t_FmIpcIsr  fmIpcIsr;
148    t_FmIpcMsg  msg;
149
150    ASSERT_COND(p_Fm->guestId == NCSW_MASTER_ID);
151    ASSERT_COND(p_Fm->h_IpcSessions[p_Fm->intrMng[macEvent].guestId]);
152    if (p_Fm->intrMng[macEvent].guestId != NCSW_MASTER_ID)
153    {
154        memset(&msg, 0, sizeof(msg));
155        msg.msgId = FM_GUEST_ISR;
156        fmIpcIsr.pendingReg = pendingReg;
157        fmIpcIsr.boolErr = FALSE;
158        memcpy(msg.msgBody, &fmIpcIsr, sizeof(fmIpcIsr));
159        if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[p_Fm->intrMng[macEvent].guestId],
160                                     (uint8_t*)&msg,
161                                     sizeof(msg.msgId) + sizeof(fmIpcIsr),
162                                     NULL,
163                                     NULL,
164                                     NULL,
165                                     NULL)) != E_OK)
166            REPORT_ERROR(MINOR, err, NO_MSG);
167        return;
168    }
169    else
170        p_Fm->intrMng[macEvent].f_Isr(p_Fm->intrMng[macEvent].h_SrcHandle);
171}
172
173static void    BmiErrEvent(t_Fm *p_Fm)
174{
175    uint32_t    event, mask, force;
176
177    event = GET_UINT32(p_Fm->p_FmBmiRegs->fmbm_ievr);
178    mask = GET_UINT32(p_Fm->p_FmBmiRegs->fmbm_ier);
179    event &= mask;
180
181    /* clear the forced events */
182    force = GET_UINT32(p_Fm->p_FmBmiRegs->fmbm_ifr);
183    if(force & event)
184        WRITE_UINT32(p_Fm->p_FmBmiRegs->fmbm_ifr, force & ~event);
185
186
187    /* clear the acknowledged events */
188    WRITE_UINT32(p_Fm->p_FmBmiRegs->fmbm_ievr, event);
189
190    if(event & BMI_ERR_INTR_EN_PIPELINE_ECC)
191        p_Fm->f_Exception(p_Fm->h_App,e_FM_EX_BMI_PIPELINE_ECC);
192    if(event & BMI_ERR_INTR_EN_LIST_RAM_ECC)
193        p_Fm->f_Exception(p_Fm->h_App,e_FM_EX_BMI_LIST_RAM_ECC);
194    if(event & BMI_ERR_INTR_EN_STATISTICS_RAM_ECC)
195        p_Fm->f_Exception(p_Fm->h_App,e_FM_EX_BMI_STATISTICS_RAM_ECC);
196    if(event & BMI_ERR_INTR_EN_DISPATCH_RAM_ECC)
197        p_Fm->f_Exception(p_Fm->h_App,e_FM_EX_BMI_DISPATCH_RAM_ECC);
198}
199
200static void    QmiErrEvent(t_Fm *p_Fm)
201{
202    uint32_t    event, mask, force;
203
204    event = GET_UINT32(p_Fm->p_FmQmiRegs->fmqm_eie);
205    mask = GET_UINT32(p_Fm->p_FmQmiRegs->fmqm_eien);
206
207    event &= mask;
208
209    /* clear the forced events */
210    force = GET_UINT32(p_Fm->p_FmQmiRegs->fmqm_eif);
211    if(force & event)
212        WRITE_UINT32(p_Fm->p_FmQmiRegs->fmqm_eif, force & ~event);
213
214    /* clear the acknowledged events */
215    WRITE_UINT32(p_Fm->p_FmQmiRegs->fmqm_eie, event);
216
217    if(event & QMI_ERR_INTR_EN_DOUBLE_ECC)
218        p_Fm->f_Exception(p_Fm->h_App,e_FM_EX_QMI_DOUBLE_ECC);
219    if(event & QMI_ERR_INTR_EN_DEQ_FROM_DEF)
220        p_Fm->f_Exception(p_Fm->h_App,e_FM_EX_QMI_DEQ_FROM_UNKNOWN_PORTID);
221}
222
223static void    DmaErrEvent(t_Fm *p_Fm)
224{
225    uint64_t            addr=0;
226    uint32_t            status, mask, tmpReg=0;
227    uint8_t             tnum;
228    uint8_t             hardwarePortId;
229    uint8_t             relativePortId;
230    uint16_t            liodn;
231
232    status = GET_UINT32(p_Fm->p_FmDmaRegs->fmdmsr);
233    mask = GET_UINT32(p_Fm->p_FmDmaRegs->fmdmmr);
234
235    /* get bus error regs befor clearing BER */
236    if ((status & DMA_STATUS_BUS_ERR) && (mask & DMA_MODE_BER))
237    {
238        addr = (uint64_t)GET_UINT32(p_Fm->p_FmDmaRegs->fmdmtal);
239        addr |= ((uint64_t)(GET_UINT32(p_Fm->p_FmDmaRegs->fmdmtah)) << 32);
240
241        /* get information about the owner of that bus error */
242        tmpReg = GET_UINT32(p_Fm->p_FmDmaRegs->fmdmtcid);
243    }
244
245    /* clear set events */
246    WRITE_UINT32(p_Fm->p_FmDmaRegs->fmdmsr, status);
247
248    if ((status & DMA_STATUS_BUS_ERR) && (mask & DMA_MODE_BER))
249    {
250        hardwarePortId = (uint8_t)(((tmpReg & DMA_TRANSFER_PORTID_MASK) >> DMA_TRANSFER_PORTID_SHIFT));
251        HW_PORT_ID_TO_SW_PORT_ID(relativePortId, hardwarePortId);
252        tnum = (uint8_t)((tmpReg & DMA_TRANSFER_TNUM_MASK) >> DMA_TRANSFER_TNUM_SHIFT);
253        liodn = (uint16_t)(tmpReg & DMA_TRANSFER_LIODN_MASK);
254        ASSERT_COND(p_Fm->p_FmStateStruct->portsTypes[hardwarePortId] != e_FM_PORT_TYPE_DUMMY);
255        p_Fm->f_BusError(p_Fm->h_App, p_Fm->p_FmStateStruct->portsTypes[hardwarePortId], relativePortId, addr, tnum, liodn);
256    }
257    if(mask & DMA_MODE_ECC)
258    {
259        if (status & DMA_STATUS_READ_ECC)
260            p_Fm->f_Exception(p_Fm->h_App, e_FM_EX_DMA_READ_ECC);
261        if (status & DMA_STATUS_SYSTEM_WRITE_ECC)
262            p_Fm->f_Exception(p_Fm->h_App, e_FM_EX_DMA_SYSTEM_WRITE_ECC);
263        if (status & DMA_STATUS_FM_WRITE_ECC)
264            p_Fm->f_Exception(p_Fm->h_App, e_FM_EX_DMA_FM_WRITE_ECC);
265    }
266}
267
268static void    FpmErrEvent(t_Fm *p_Fm)
269{
270    uint32_t    event;
271
272    event = GET_UINT32(p_Fm->p_FmFpmRegs->fpmem);
273
274    /* clear the all occurred events */
275    WRITE_UINT32(p_Fm->p_FmFpmRegs->fpmem, event);
276
277    if((event  & FPM_EV_MASK_DOUBLE_ECC) && (event & FPM_EV_MASK_DOUBLE_ECC_EN))
278        p_Fm->f_Exception(p_Fm->h_App,e_FM_EX_FPM_DOUBLE_ECC);
279    if((event  & FPM_EV_MASK_STALL) && (event & FPM_EV_MASK_STALL_EN))
280        p_Fm->f_Exception(p_Fm->h_App,e_FM_EX_FPM_STALL_ON_TASKS);
281    if((event  & FPM_EV_MASK_SINGLE_ECC) && (event & FPM_EV_MASK_SINGLE_ECC_EN))
282        p_Fm->f_Exception(p_Fm->h_App,e_FM_EX_FPM_SINGLE_ECC);
283}
284
285static void    MuramErrIntr(t_Fm *p_Fm)
286{
287    uint32_t    event, mask;
288
289    event = GET_UINT32(p_Fm->p_FmFpmRegs->fmrcr);
290    mask = GET_UINT32(p_Fm->p_FmFpmRegs->fmrie);
291
292    /* clear MURAM event bit */
293    WRITE_UINT32(p_Fm->p_FmFpmRegs->fmrcr, event & ~FPM_RAM_CTL_IRAM_ECC);
294
295    ASSERT_COND(event & FPM_RAM_CTL_MURAM_ECC);
296    ASSERT_COND(event & FPM_RAM_CTL_RAMS_ECC_EN);
297
298    if ((mask & FPM_MURAM_ECC_ERR_EX_EN))
299        p_Fm->f_Exception(p_Fm->h_App, e_FM_EX_MURAM_ECC);
300}
301
302static void IramErrIntr(t_Fm *p_Fm)
303{
304    uint32_t    event, mask;
305
306    event = GET_UINT32(p_Fm->p_FmFpmRegs->fmrcr) ;
307    mask = GET_UINT32(p_Fm->p_FmFpmRegs->fmrie);
308    /* clear the acknowledged events (do not clear IRAM event) */
309    WRITE_UINT32(p_Fm->p_FmFpmRegs->fmrcr, event & ~FPM_RAM_CTL_MURAM_ECC);
310
311    ASSERT_COND(event & FPM_RAM_CTL_IRAM_ECC);
312    ASSERT_COND(event & FPM_RAM_CTL_IRAM_ECC_EN);
313
314    if ((mask & FPM_IRAM_ECC_ERR_EX_EN))
315        p_Fm->f_Exception(p_Fm->h_App, e_FM_EX_IRAM_ECC);
316}
317
318static void QmiEvent(t_Fm *p_Fm)
319{
320    uint32_t    event, mask, force;
321
322    event = GET_UINT32(p_Fm->p_FmQmiRegs->fmqm_ie);
323    mask = GET_UINT32(p_Fm->p_FmQmiRegs->fmqm_ien);
324
325    event &= mask;
326
327    /* clear the forced events */
328    force = GET_UINT32(p_Fm->p_FmQmiRegs->fmqm_if);
329    if(force & event)
330        WRITE_UINT32(p_Fm->p_FmQmiRegs->fmqm_if, force & ~event);
331
332    /* clear the acknowledged events */
333    WRITE_UINT32(p_Fm->p_FmQmiRegs->fmqm_ie, event);
334
335    if(event & QMI_INTR_EN_SINGLE_ECC)
336        p_Fm->f_Exception(p_Fm->h_App,e_FM_EX_QMI_SINGLE_ECC);
337}
338
339static void UnimplementedIsr(t_Handle h_Arg)
340{
341    UNUSED(h_Arg);
342
343    REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Unimplemented Isr!"));
344}
345
346static void UnimplementedFmanCtrlIsr(t_Handle h_Arg, uint32_t event)
347{
348    UNUSED(h_Arg); UNUSED(event);
349
350    REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Unimplemented FmCtl Isr!"));
351}
352
353static void FmEnableTimeStamp(t_Fm *p_Fm)
354{
355    uint32_t                tmpReg;
356    uint64_t                fraction;
357    uint32_t                integer;
358    uint8_t                 count1MicroBit = 8;
359    uint32_t                tsFrequency = (uint32_t)(1<<count1MicroBit); /* in Mhz */
360
361    /* configure timestamp so that bit 8 will count 1 microsecond */
362    /* Find effective count rate at TIMESTAMP least significant bits:
363       Effective_Count_Rate = 1MHz x 2^8 = 256MHz
364       Find frequency ratio between effective count rate and the clock:
365       Effective_Count_Rate / CLK e.g. for 600 MHz clock:
366       256/600 = 0.4266666... */
367    integer = tsFrequency/p_Fm->p_FmStateStruct->fmClkFreq;
368    /* we multiply by 2^16 to keep the fraction of the division */
369    /* we do not divid back, since we write this value as fraction - see spec */
370    fraction = ((tsFrequency << 16) - (integer << 16)*p_Fm->p_FmStateStruct->fmClkFreq)/p_Fm->p_FmStateStruct->fmClkFreq;
371    /* we check remainder of the division in order to round up if not integer */
372    if(((tsFrequency << 16) - (integer << 16)*p_Fm->p_FmStateStruct->fmClkFreq) % p_Fm->p_FmStateStruct->fmClkFreq)
373        fraction++;
374
375    tmpReg = (integer << FPM_TS_INT_SHIFT) | (uint16_t)fraction;
376    WRITE_UINT32(p_Fm->p_FmFpmRegs->fpmtsc2, tmpReg);
377
378    /* enable timestamp with original clock */
379    WRITE_UINT32(p_Fm->p_FmFpmRegs->fpmtsc1, FPM_TS_CTL_EN);
380
381    p_Fm->p_FmStateStruct->count1MicroBit = count1MicroBit;
382    p_Fm->p_FmStateStruct->enabledTimeStamp = TRUE;
383}
384
385static void FreeInitResources(t_Fm *p_Fm)
386{
387    if (p_Fm->camBaseAddr)
388       FM_MURAM_FreeMem(p_Fm->h_FmMuram, UINT_TO_PTR(p_Fm->camBaseAddr));
389    if (p_Fm->fifoBaseAddr)
390       FM_MURAM_FreeMem(p_Fm->h_FmMuram, UINT_TO_PTR(p_Fm->fifoBaseAddr));
391    if (p_Fm->resAddr)
392       FM_MURAM_FreeMem(p_Fm->h_FmMuram, UINT_TO_PTR(p_Fm->resAddr));
393}
394
395static t_Error ClearIRam(t_Fm *p_Fm)
396{
397    t_FMIramRegs    *p_Iram;
398    int             i;
399
400    ASSERT_COND(p_Fm);
401    p_Iram = (t_FMIramRegs *)UINT_TO_PTR(p_Fm->baseAddr + FM_MM_IMEM);
402
403    /* Enable the auto-increment */
404    WRITE_UINT32(p_Iram->iadd, IRAM_IADD_AIE);
405    while (GET_UINT32(p_Iram->iadd) != IRAM_IADD_AIE) ;
406
407    for (i=0; i < (FM_IRAM_SIZE/4); i++)
408        WRITE_UINT32(p_Iram->idata, 0xffffffff);
409
410    WRITE_UINT32(p_Iram->iadd, FM_IRAM_SIZE - 4);
411    CORE_MemoryBarrier();
412    while (GET_UINT32(p_Iram->idata) != 0xffffffff) ;
413
414    return E_OK;
415}
416
417static t_Error LoadFmanCtrlCode(t_Fm *p_Fm)
418{
419    t_FMIramRegs    *p_Iram;
420    int             i;
421    uint32_t        tmp;
422    uint8_t         compTo16;
423
424    ASSERT_COND(p_Fm);
425    p_Iram = (t_FMIramRegs *)UINT_TO_PTR(p_Fm->baseAddr + FM_MM_IMEM);
426
427    /* Enable the auto-increment */
428    WRITE_UINT32(p_Iram->iadd, IRAM_IADD_AIE);
429    while (GET_UINT32(p_Iram->iadd) != IRAM_IADD_AIE) ;
430
431    for (i=0; i < (p_Fm->p_FmDriverParam->firmware.size / 4); i++)
432        WRITE_UINT32(p_Iram->idata, p_Fm->p_FmDriverParam->firmware.p_Code[i]);
433
434    compTo16 = (uint8_t)(p_Fm->p_FmDriverParam->firmware.size % 16);
435    if(compTo16)
436        for (i=0; i < ((16-compTo16) / 4); i++)
437            WRITE_UINT32(p_Iram->idata, 0xffffffff);
438
439    WRITE_UINT32(p_Iram->iadd,p_Fm->p_FmDriverParam->firmware.size-4);
440    while(GET_UINT32(p_Iram->iadd) != (p_Fm->p_FmDriverParam->firmware.size-4)) ;
441
442    /* verify that writing has completed */
443    while (GET_UINT32(p_Iram->idata) != p_Fm->p_FmDriverParam->firmware.p_Code[(p_Fm->p_FmDriverParam->firmware.size / 4)-1]) ;
444
445    if (p_Fm->p_FmDriverParam->fwVerify)
446    {
447        WRITE_UINT32(p_Iram->iadd, IRAM_IADD_AIE);
448        while (GET_UINT32(p_Iram->iadd) != IRAM_IADD_AIE) ;
449        for (i=0; i < (p_Fm->p_FmDriverParam->firmware.size / 4); i++)
450            if ((tmp=GET_UINT32(p_Iram->idata)) != p_Fm->p_FmDriverParam->firmware.p_Code[i])
451                RETURN_ERROR(MAJOR, E_WRITE_FAILED,
452                             ("UCode write error : write 0x%x, read 0x%x",
453                              p_Fm->p_FmDriverParam->firmware.p_Code[i],tmp));
454        WRITE_UINT32(p_Iram->iadd, 0x0);
455    }
456
457    /* Enable patch from IRAM */
458    WRITE_UINT32(p_Iram->iready, IRAM_READY);
459    XX_UDelay(1000);
460
461    DBG(INFO, ("FMan-Controller code (ver %d.%d) loaded to IRAM.",
462               ((uint8_t *)p_Fm->p_FmDriverParam->firmware.p_Code)[5],
463               ((uint8_t *)p_Fm->p_FmDriverParam->firmware.p_Code)[7]));
464
465    return E_OK;
466}
467
468static void GuestErrorIsr(t_Fm *p_Fm, uint32_t pending)
469{
470#define FM_G_CALL_1G_MAC_ERR_ISR(_id)   \
471do {                                    \
472    p_Fm->intrMng[(e_FmInterModuleEvent)(e_FM_EV_ERR_1G_MAC0+_id)].f_Isr(p_Fm->intrMng[(e_FmInterModuleEvent)(e_FM_EV_ERR_1G_MAC0+_id)].h_SrcHandle);\
473} while (0)
474#define FM_G_CALL_10G_MAC_ERR_ISR(_id)  \
475do {                                    \
476    p_Fm->intrMng[(e_FmInterModuleEvent)(e_FM_EV_ERR_10G_MAC0+_id)].f_Isr(p_Fm->intrMng[(e_FmInterModuleEvent)(e_FM_EV_ERR_10G_MAC0+_id)].h_SrcHandle);\
477} while (0)
478
479    /* error interrupts */
480    if (pending & ERR_INTR_EN_1G_MAC0)
481        FM_G_CALL_1G_MAC_ERR_ISR(0);
482    if (pending & ERR_INTR_EN_1G_MAC1)
483        FM_G_CALL_1G_MAC_ERR_ISR(1);
484    if (pending & ERR_INTR_EN_1G_MAC2)
485        FM_G_CALL_1G_MAC_ERR_ISR(2);
486    if (pending & ERR_INTR_EN_1G_MAC3)
487        FM_G_CALL_1G_MAC_ERR_ISR(3);
488    if (pending & ERR_INTR_EN_1G_MAC4)
489        FM_G_CALL_1G_MAC_ERR_ISR(4);
490    if (pending & ERR_INTR_EN_10G_MAC0)
491        FM_G_CALL_10G_MAC_ERR_ISR(0);
492}
493
494static void GuestEventIsr(t_Fm *p_Fm, uint32_t pending)
495{
496#define FM_G_CALL_1G_MAC_TMR_ISR(_id)   \
497do {                                    \
498    p_Fm->intrMng[(e_FmInterModuleEvent)(e_FM_EV_1G_MAC0_TMR+_id)].f_Isr(p_Fm->intrMng[(e_FmInterModuleEvent)(e_FM_EV_1G_MAC0_TMR+_id)].h_SrcHandle);\
499} while (0)
500
501    if (pending & INTR_EN_1G_MAC0_TMR)
502        FM_G_CALL_1G_MAC_TMR_ISR(0);
503    if (pending & INTR_EN_1G_MAC1_TMR)
504        FM_G_CALL_1G_MAC_TMR_ISR(1);
505    if (pending & INTR_EN_1G_MAC2_TMR)
506        FM_G_CALL_1G_MAC_TMR_ISR(2);
507    if (pending & INTR_EN_1G_MAC3_TMR)
508        FM_G_CALL_1G_MAC_TMR_ISR(3);
509    if (pending & INTR_EN_1G_MAC4_TMR)
510        FM_G_CALL_1G_MAC_TMR_ISR(4);
511    if(pending & INTR_EN_TMR)
512        p_Fm->intrMng[e_FM_EV_TMR].f_Isr(p_Fm->intrMng[e_FM_EV_TMR].h_SrcHandle);
513}
514
515
516/****************************************/
517/*       Inter-Module functions         */
518/****************************************/
519static t_Error FmGuestHandleIpcMsgCB(t_Handle  h_Fm,
520                                     uint8_t   *p_Msg,
521                                     uint32_t  msgLength,
522                                     uint8_t   *p_Reply,
523                                     uint32_t  *p_ReplyLength)
524{
525    t_Fm            *p_Fm       = (t_Fm*)h_Fm;
526    t_FmIpcMsg      *p_IpcMsg   = (t_FmIpcMsg*)p_Msg;
527
528    UNUSED(p_Reply);
529    SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
530    SANITY_CHECK_RETURN_ERROR((msgLength > sizeof(uint32_t)), E_INVALID_VALUE);
531
532#ifdef DISABLE_SANITY_CHECKS
533    UNUSED(msgLength);
534#endif /* DISABLE_SANITY_CHECKS */
535
536    ASSERT_COND(p_Msg);
537
538    *p_ReplyLength = 0;
539
540    switch(p_IpcMsg->msgId)
541    {
542        case (FM_GUEST_ISR):
543        {
544            t_FmIpcIsr ipcIsr;
545
546            memcpy((uint8_t*)&ipcIsr, p_IpcMsg->msgBody, sizeof(t_FmIpcIsr));
547            if(ipcIsr.boolErr)
548                GuestErrorIsr(p_Fm, ipcIsr.pendingReg);
549            else
550                GuestEventIsr(p_Fm, ipcIsr.pendingReg);
551            break;
552        }
553        default:
554            *p_ReplyLength = 0;
555            RETURN_ERROR(MINOR, E_INVALID_SELECTION, ("command not found!!!"));
556    }
557    return E_OK;
558}
559
560static t_Error FmHandleIpcMsgCB(t_Handle  h_Fm,
561                                uint8_t   *p_Msg,
562                                uint32_t  msgLength,
563                                uint8_t   *p_Reply,
564                                uint32_t  *p_ReplyLength)
565{
566    t_Fm            *p_Fm       = (t_Fm*)h_Fm;
567    t_FmIpcMsg      *p_IpcMsg   = (t_FmIpcMsg*)p_Msg;
568    t_FmIpcReply    *p_IpcReply = (t_FmIpcReply*)p_Reply;
569
570    SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
571    SANITY_CHECK_RETURN_ERROR((msgLength >= sizeof(uint32_t)), E_INVALID_VALUE);
572
573#ifdef DISABLE_SANITY_CHECKS
574    UNUSED(msgLength);
575#endif /* DISABLE_SANITY_CHECKS */
576
577    ASSERT_COND(p_IpcMsg);
578
579    memset(p_IpcReply, 0, (sizeof(uint8_t) * FM_IPC_MAX_REPLY_SIZE));
580    *p_ReplyLength = 0;
581
582    switch(p_IpcMsg->msgId)
583    {
584        case (FM_GET_SET_PORT_PARAMS):
585        {
586            t_FmIpcPortInInitParams         ipcInitParams;
587            t_FmInterModulePortInitParams   initParams;
588            t_FmIpcPhysAddr                 ipcPhysAddr;
589
590            memcpy((uint8_t*)&ipcInitParams, p_IpcMsg->msgBody, sizeof(t_FmIpcPortInInitParams));
591            initParams.hardwarePortId = ipcInitParams.hardwarePortId;
592            initParams.portType = (e_FmPortType)ipcInitParams.enumPortType;
593            initParams.independentMode = (bool)(ipcInitParams.boolIndependentMode);
594            initParams.liodnOffset = ipcInitParams.liodnOffset;
595            initParams.numOfTasks = ipcInitParams.numOfTasks;
596            initParams.numOfExtraTasks = ipcInitParams.numOfExtraTasks;
597            initParams.numOfOpenDmas = ipcInitParams.numOfOpenDmas;
598            initParams.numOfExtraOpenDmas = ipcInitParams.numOfExtraOpenDmas;
599            initParams.sizeOfFifo = ipcInitParams.sizeOfFifo;
600            initParams.extraSizeOfFifo = ipcInitParams.extraSizeOfFifo;
601            initParams.deqPipelineDepth = ipcInitParams.deqPipelineDepth;
602            initParams.liodnBase = ipcInitParams.liodnBase;
603
604            p_IpcReply->error = (uint32_t)FmGetSetPortParams(h_Fm, &initParams);
605            ipcPhysAddr.high = initParams.fmMuramPhysBaseAddr.high;
606            ipcPhysAddr.low = initParams.fmMuramPhysBaseAddr.low;
607            memcpy(p_IpcReply->replyBody, (uint8_t*)&ipcPhysAddr, sizeof(t_FmIpcPhysAddr));
608            *p_ReplyLength = sizeof(uint32_t) + sizeof(t_FmIpcPhysAddr);
609            break;
610        }
611        case (FM_SET_SIZE_OF_FIFO):
612        {
613            t_FmIpcPortFifoParams               ipcPortFifoParams;
614            t_FmInterModulePortRxPoolsParams    rxPoolsParams;
615
616            memcpy((uint8_t*)&ipcPortFifoParams, p_IpcMsg->msgBody, sizeof(t_FmIpcPortFifoParams));
617            rxPoolsParams.numOfPools = ipcPortFifoParams.numOfPools;
618            rxPoolsParams.secondLargestBufSize = ipcPortFifoParams.secondLargestBufSize;
619            rxPoolsParams.largestBufSize = ipcPortFifoParams.largestBufSize;
620
621            p_IpcReply->error = (uint32_t)FmSetSizeOfFifo(h_Fm, ipcPortFifoParams.rsrcParams.hardwarePortId,
622                                                (e_FmPortType)ipcPortFifoParams.enumPortType,
623                                                (bool)ipcPortFifoParams.boolIndependentMode,
624                                                &ipcPortFifoParams.rsrcParams.val,
625                                                ipcPortFifoParams.rsrcParams.extra,
626                                                ipcPortFifoParams.deqPipelineDepth,
627                                                &rxPoolsParams,
628                                                (bool)ipcPortFifoParams.boolInitialConfig);
629            memcpy(p_IpcReply->replyBody, (uint8_t*)&ipcPortFifoParams.rsrcParams.val, sizeof(uint32_t));
630            *p_ReplyLength = sizeof(uint32_t) + sizeof(uint32_t);
631            break;
632        }
633        case (FM_SET_NUM_OF_TASKS):
634        {
635            t_FmIpcPortRsrcParams   ipcPortRsrcParams;
636
637            memcpy((uint8_t*)&ipcPortRsrcParams, p_IpcMsg->msgBody, sizeof(t_FmIpcPortRsrcParams));
638            p_IpcReply->error = (uint32_t)FmSetNumOfTasks(h_Fm, ipcPortRsrcParams.hardwarePortId,
639                                                          (uint8_t)ipcPortRsrcParams.val,
640                                                          (uint8_t)ipcPortRsrcParams.extra,
641                                                          (bool)ipcPortRsrcParams.boolInitialConfig);
642            *p_ReplyLength = sizeof(uint32_t);
643            break;
644        }
645        case (FM_SET_NUM_OF_OPEN_DMAS):
646        {
647            t_FmIpcPortRsrcParams   ipcPortRsrcParams;
648
649            memcpy((uint8_t*)&ipcPortRsrcParams, p_IpcMsg->msgBody, sizeof(t_FmIpcPortRsrcParams));
650            p_IpcReply->error = (uint32_t)FmSetNumOfOpenDmas(h_Fm, ipcPortRsrcParams.hardwarePortId,
651                                                               (uint8_t)ipcPortRsrcParams.val,
652                                                               (uint8_t)ipcPortRsrcParams.extra,
653                                                               (bool)ipcPortRsrcParams.boolInitialConfig);
654            *p_ReplyLength = sizeof(uint32_t);
655            break;
656        }
657        case (FM_RESUME_STALLED_PORT):
658            *p_ReplyLength = sizeof(uint32_t);
659            p_IpcReply->error = (uint32_t)FmResumeStalledPort(h_Fm, p_IpcMsg->msgBody[0]);
660            break;
661        case (FM_MASTER_IS_ALIVE):
662        {
663            uint8_t guestId = p_IpcMsg->msgBody[0];
664            /* build the FM master partition IPC address */
665            memset(p_Fm->fmIpcHandlerModuleName[guestId], 0, (sizeof(char)) * MODULE_NAME_SIZE);
666            if(Sprint (p_Fm->fmIpcHandlerModuleName[guestId], "FM_%d_%d",p_Fm->p_FmStateStruct->fmId, guestId) != (guestId<10 ? 6:7))
667                RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Sprint failed"));
668            p_Fm->h_IpcSessions[guestId] = XX_IpcInitSession(p_Fm->fmIpcHandlerModuleName[guestId], p_Fm->fmModuleName);
669            if (p_Fm->h_IpcSessions[guestId] == NULL)
670                RETURN_ERROR(MAJOR, E_NOT_AVAILABLE, ("FM Master IPC session for guest %d", guestId));
671            *(uint8_t*)(p_IpcReply->replyBody) = 1;
672            *p_ReplyLength = sizeof(uint32_t) + sizeof(uint8_t);
673            break;
674        }
675        case (FM_IS_PORT_STALLED):
676        {
677            bool tmp;
678
679            p_IpcReply->error = (uint32_t)FmIsPortStalled(h_Fm, p_IpcMsg->msgBody[0], &tmp);
680            *(uint8_t*)(p_IpcReply->replyBody) = (uint8_t)tmp;
681            *p_ReplyLength = sizeof(uint32_t) + sizeof(uint8_t);
682            break;
683        }
684        case (FM_RESET_MAC):
685        {
686            t_FmIpcMacParams    ipcMacParams;
687
688            memcpy((uint8_t*)&ipcMacParams, p_IpcMsg->msgBody, sizeof(t_FmIpcMacParams));
689            p_IpcReply->error = (uint32_t)FmResetMac(p_Fm,
690                                                     (e_FmMacType)(ipcMacParams.enumType),
691                                                     ipcMacParams.id);
692            *p_ReplyLength = sizeof(uint32_t);
693            break;
694        }
695        case (FM_SET_MAC_MAX_FRAME):
696        {
697            t_Error                     err;
698            t_FmIpcMacMaxFrameParams    ipcMacMaxFrameParams;
699
700            memcpy((uint8_t*)&ipcMacMaxFrameParams, p_IpcMsg->msgBody, sizeof(t_FmIpcMacMaxFrameParams));
701            if ((err = FmSetMacMaxFrame(p_Fm,
702                                        (e_FmMacType)(ipcMacMaxFrameParams.macParams.enumType),
703                                        ipcMacMaxFrameParams.macParams.id,
704                                        ipcMacMaxFrameParams.maxFrameLength)) != E_OK)
705                REPORT_ERROR(MINOR, err, NO_MSG);
706            break;
707        }
708        case (FM_GET_CLK_FREQ):
709            memcpy(p_IpcReply->replyBody, (uint8_t*)&p_Fm->p_FmStateStruct->fmClkFreq, sizeof(uint16_t));
710            *p_ReplyLength = sizeof(uint32_t) + sizeof(uint16_t);
711            break;
712        case (FM_FREE_PORT):
713        {
714            t_FmInterModulePortFreeParams   portParams;
715            t_FmIpcPortFreeParams           ipcPortParams;
716
717            memcpy((uint8_t*)&ipcPortParams, p_IpcMsg->msgBody, sizeof(t_FmIpcPortFreeParams));
718            portParams.hardwarePortId = ipcPortParams.hardwarePortId;
719            portParams.portType = (e_FmPortType)(ipcPortParams.enumPortType);
720#ifdef FM_QMI_DEQ_OPTIONS_SUPPORT
721            portParams.deqPipelineDepth = ipcPortParams.deqPipelineDepth;
722#endif /* FM_QMI_DEQ_OPTIONS_SUPPORT */
723            FmFreePortParams(h_Fm, &portParams);
724            break;
725        }
726        case (FM_REGISTER_INTR):
727        {
728            t_FmIpcRegisterIntr ipcRegIntr;
729
730            memcpy((uint8_t*)&ipcRegIntr, p_IpcMsg->msgBody, sizeof(ipcRegIntr));
731            p_Fm->intrMng[ipcRegIntr.event].guestId = ipcRegIntr.guestId;
732            break;
733        }
734#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
735        case (FM_DUMP_REGS):
736        {
737            t_Error     err;
738            if ((err = FM_DumpRegs(h_Fm)) != E_OK)
739                REPORT_ERROR(MINOR, err, NO_MSG);
740            break;
741        }
742        case (FM_DUMP_PORT_REGS):
743        {
744            t_Error     err;
745
746            if ((err = FmDumpPortRegs(h_Fm, p_IpcMsg->msgBody[0])) != E_OK)
747                REPORT_ERROR(MINOR, err, NO_MSG);
748            break;
749        }
750#endif /* (defined(DEBUG_ERRORS) && ... */
751        case (FM_GET_REV):
752        {
753            t_FmRevisionInfo    revInfo;
754            t_FmIpcRevisionInfo ipcRevInfo;
755
756            p_IpcReply->error = (uint32_t)FM_GetRevision(h_Fm, &revInfo);
757            ipcRevInfo.majorRev = revInfo.majorRev;
758            ipcRevInfo.minorRev = revInfo.minorRev;
759            memcpy(p_IpcReply->replyBody, (uint8_t*)&ipcRevInfo, sizeof(t_FmIpcRevisionInfo));
760            *p_ReplyLength = sizeof(uint32_t) + sizeof(t_FmIpcRevisionInfo);
761            break;
762        }
763        case (FM_DMA_STAT):
764        {
765            t_FmDmaStatus       dmaStatus;
766            t_FmIpcDmaStatus    ipcDmaStatus;
767
768            FM_GetDmaStatus(h_Fm, &dmaStatus);
769            ipcDmaStatus.boolCmqNotEmpty = (uint8_t)dmaStatus.cmqNotEmpty;
770            ipcDmaStatus.boolBusError = (uint8_t)dmaStatus.busError;
771            ipcDmaStatus.boolReadBufEccError = (uint8_t)dmaStatus.readBufEccError;
772            ipcDmaStatus.boolWriteBufEccSysError = (uint8_t)dmaStatus.writeBufEccSysError;
773            ipcDmaStatus.boolWriteBufEccFmError = (uint8_t)dmaStatus.writeBufEccFmError;
774            memcpy(p_IpcReply->replyBody, (uint8_t*)&ipcDmaStatus, sizeof(t_FmIpcDmaStatus));
775            *p_ReplyLength = sizeof(uint32_t) + sizeof(t_FmIpcDmaStatus);
776            break;
777        }
778        case (FM_ALLOC_FMAN_CTRL_EVENT_REG):
779            p_IpcReply->error = (uint32_t)FmAllocFmanCtrlEventReg(h_Fm, (uint8_t*)p_IpcReply->replyBody);
780            *p_ReplyLength = sizeof(uint32_t) + sizeof(uint8_t);
781            break;
782        case (FM_FREE_FMAN_CTRL_EVENT_REG):
783            FmFreeFmanCtrlEventReg(h_Fm, p_IpcMsg->msgBody[0]);
784            break;
785        case (FM_GET_TIMESTAMP_SCALE):
786        {
787            uint32_t    timeStamp = FmGetTimeStampScale(h_Fm);
788
789            memcpy(p_IpcReply->replyBody, (uint8_t*)&timeStamp, sizeof(uint32_t));
790            *p_ReplyLength = sizeof(uint32_t) + sizeof(uint32_t);
791            break;
792        }
793        case (FM_GET_COUNTER):
794        {
795            e_FmCounters    inCounter;
796            uint32_t        outCounter;
797
798            memcpy((uint8_t*)&inCounter, p_IpcMsg->msgBody, sizeof(uint32_t));
799            outCounter = FM_GetCounter(h_Fm, inCounter);
800            memcpy(p_IpcReply->replyBody, (uint8_t*)&outCounter, sizeof(uint32_t));
801            *p_ReplyLength = sizeof(uint32_t) + sizeof(uint32_t);
802            break;
803        }
804        case (FM_SET_FMAN_CTRL_EVENTS_ENABLE):
805        {
806            t_FmIpcFmanEvents ipcFmanEvents;
807
808            memcpy((uint8_t*)&ipcFmanEvents, p_IpcMsg->msgBody, sizeof(t_FmIpcFmanEvents));
809            FmSetFmanCtrlIntr(h_Fm,
810                              ipcFmanEvents.eventRegId,
811                              ipcFmanEvents.enableEvents);
812            break;
813        }
814        case (FM_GET_FMAN_CTRL_EVENTS_ENABLE):
815        {
816            uint32_t    tmp = FmGetFmanCtrlIntr(h_Fm, p_IpcMsg->msgBody[0]);
817
818            memcpy(p_IpcReply->replyBody, (uint8_t*)&tmp, sizeof(uint32_t));
819            *p_ReplyLength = sizeof(uint32_t) + sizeof(uint32_t);
820            break;
821        }
822        case (FM_GET_PHYS_MURAM_BASE):
823        {
824            t_FmPhysAddr        physAddr;
825            t_FmIpcPhysAddr     ipcPhysAddr;
826
827            FmGetPhysicalMuramBase(h_Fm, &physAddr);
828            ipcPhysAddr.high    = physAddr.high;
829            ipcPhysAddr.low     = physAddr.low;
830            memcpy(p_IpcReply->replyBody, (uint8_t*)&ipcPhysAddr, sizeof(t_FmIpcPhysAddr));
831            *p_ReplyLength = sizeof(uint32_t) + sizeof(t_FmIpcPhysAddr);
832            break;
833        }
834        case (FM_ENABLE_RAM_ECC):
835        {
836            t_Error     err;
837
838            if (((err = FM_EnableRamsEcc(h_Fm)) != E_OK) ||
839                ((err = FM_SetException(h_Fm, e_FM_EX_IRAM_ECC, TRUE)) != E_OK) ||
840                ((err = FM_SetException(h_Fm, e_FM_EX_MURAM_ECC, TRUE)) != E_OK))
841                REPORT_ERROR(MINOR, err, NO_MSG);
842            break;
843        }
844        case (FM_DISABLE_RAM_ECC):
845        {
846            t_Error     err;
847
848            if (((err = FM_SetException(h_Fm, e_FM_EX_IRAM_ECC, FALSE)) != E_OK) ||
849                ((err = FM_SetException(h_Fm, e_FM_EX_MURAM_ECC, FALSE)) != E_OK) ||
850                ((err = FM_DisableRamsEcc(h_Fm)) != E_OK))
851                REPORT_ERROR(MINOR, err, NO_MSG);
852            break;
853        }
854        case (FM_SET_NUM_OF_FMAN_CTRL):
855        {
856            t_Error                     err;
857            t_FmIpcPortNumOfFmanCtrls   ipcPortNumOfFmanCtrls;
858
859            memcpy((uint8_t*)&ipcPortNumOfFmanCtrls, p_IpcMsg->msgBody, sizeof(t_FmIpcPortNumOfFmanCtrls));
860            if ((err = FmSetNumOfRiscsPerPort(h_Fm,
861                                              ipcPortNumOfFmanCtrls.hardwarePortId,
862                                              ipcPortNumOfFmanCtrls.numOfFmanCtrls)) != E_OK)
863                REPORT_ERROR(MINOR, err, NO_MSG);
864            break;
865        }
866#ifdef FM_TX_ECC_FRMS_ERRATA_10GMAC_A004
867        case (FM_10G_TX_ECC_WA):
868            p_IpcReply->error = (uint32_t)Fm10GTxEccWorkaround(h_Fm, p_IpcMsg->msgBody[0]);
869            *p_ReplyLength = sizeof(uint32_t);
870            break;
871#endif /* FM_TX_ECC_FRMS_ERRATA_10GMAC_A004 */
872        default:
873            *p_ReplyLength = 0;
874            RETURN_ERROR(MINOR, E_INVALID_SELECTION, ("command not found!!!"));
875    }
876    return E_OK;
877}
878
879static void ErrorIsrCB(t_Handle h_Fm)
880{
881#define FM_M_CALL_1G_MAC_ERR_ISR(_id)   \
882    {                                   \
883       if (p_Fm->guestId != p_Fm->intrMng[(e_FmInterModuleEvent)(e_FM_EV_ERR_1G_MAC0+_id)].guestId) \
884            SendIpcIsr(p_Fm, (e_FmInterModuleEvent)(e_FM_EV_ERR_1G_MAC0+_id), pending);             \
885       else                                                                                         \
886            p_Fm->intrMng[(e_FmInterModuleEvent)(e_FM_EV_ERR_1G_MAC0+_id)].f_Isr(p_Fm->intrMng[(e_FmInterModuleEvent)(e_FM_EV_ERR_1G_MAC0+_id)].h_SrcHandle);\
887    }
888    t_Fm                    *p_Fm = (t_Fm*)h_Fm;
889    uint32_t                pending;
890
891    SANITY_CHECK_RETURN(h_Fm, E_INVALID_HANDLE);
892
893    /* error interrupts */
894    pending = GET_UINT32(p_Fm->p_FmFpmRegs->fmepi);
895    if (!pending)
896        return;
897
898    if(pending & ERR_INTR_EN_BMI)
899        BmiErrEvent(p_Fm);
900    if(pending & ERR_INTR_EN_QMI)
901        QmiErrEvent(p_Fm);
902    if(pending & ERR_INTR_EN_FPM)
903        FpmErrEvent(p_Fm);
904    if(pending & ERR_INTR_EN_DMA)
905        DmaErrEvent(p_Fm);
906    if(pending & ERR_INTR_EN_IRAM)
907        IramErrIntr(p_Fm);
908    if(pending & ERR_INTR_EN_MURAM)
909        MuramErrIntr(p_Fm);
910    if(pending & ERR_INTR_EN_PRS)
911        p_Fm->intrMng[e_FM_EV_ERR_PRS].f_Isr(p_Fm->intrMng[e_FM_EV_ERR_PRS].h_SrcHandle);
912    if(pending & ERR_INTR_EN_PLCR)
913        p_Fm->intrMng[e_FM_EV_ERR_PLCR].f_Isr(p_Fm->intrMng[e_FM_EV_ERR_PLCR].h_SrcHandle);
914    if(pending & ERR_INTR_EN_KG)
915        p_Fm->intrMng[e_FM_EV_ERR_KG].f_Isr(p_Fm->intrMng[e_FM_EV_ERR_KG].h_SrcHandle);
916
917    /* MAC events may belong to different partitions */
918    if(pending & ERR_INTR_EN_1G_MAC0)
919        FM_M_CALL_1G_MAC_ERR_ISR(0);
920    if(pending & ERR_INTR_EN_1G_MAC1)
921        FM_M_CALL_1G_MAC_ERR_ISR(1);
922    if(pending & ERR_INTR_EN_1G_MAC2)
923        FM_M_CALL_1G_MAC_ERR_ISR(2);
924    if(pending & ERR_INTR_EN_1G_MAC3)
925        FM_M_CALL_1G_MAC_ERR_ISR(3);
926    if(pending & ERR_INTR_EN_1G_MAC4)
927        FM_M_CALL_1G_MAC_ERR_ISR(4);
928    if(pending & ERR_INTR_EN_10G_MAC0)
929    {
930       if (p_Fm->guestId != p_Fm->intrMng[e_FM_EV_ERR_10G_MAC0].guestId)
931            SendIpcIsr(p_Fm, e_FM_EV_ERR_10G_MAC0, pending);
932        else
933            p_Fm->intrMng[e_FM_EV_ERR_10G_MAC0].f_Isr(p_Fm->intrMng[e_FM_EV_ERR_10G_MAC0].h_SrcHandle);
934    }
935}
936
937
938#ifdef FM_TX_ECC_FRMS_ERRATA_10GMAC_A004
939t_Error Fm10GTxEccWorkaround(t_Handle h_Fm, uint8_t macId)
940{
941    t_Fm            *p_Fm = (t_Fm*)h_Fm;
942    int             timeout = 1000;
943    t_Error         err = E_OK;
944    t_FmIpcMsg      msg;
945    t_FmIpcReply    reply;
946    uint32_t        replyLength;
947    uint8_t         rxHardwarePortId, txHardwarePortId;
948
949    if(p_Fm->guestId != NCSW_MASTER_ID)
950    {
951        memset(&msg, 0, sizeof(msg));
952        memset(&reply, 0, sizeof(reply));
953        msg.msgId = FM_10G_TX_ECC_WA;
954        msg.msgBody[0] = macId;
955        replyLength = sizeof(uint32_t);
956        if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
957                                     (uint8_t*)&msg,
958                                     sizeof(msg.msgId)+sizeof(macId),
959                                     (uint8_t*)&reply,
960                                     &replyLength,
961                                     NULL,
962                                     NULL)) != E_OK)
963            RETURN_ERROR(MINOR, err, NO_MSG);
964        if (replyLength != sizeof(uint32_t))
965            RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
966        return (t_Error)(reply.error);
967    }
968
969    SANITY_CHECK_RETURN_ERROR((macId == 0), E_NOT_SUPPORTED);
970    SANITY_CHECK_RETURN_ERROR(IsFmanCtrlCodeLoaded(p_Fm), E_INVALID_STATE);
971
972    SW_PORT_ID_TO_HW_PORT_ID(rxHardwarePortId, e_FM_PORT_TYPE_RX_10G, macId);
973    SW_PORT_ID_TO_HW_PORT_ID(txHardwarePortId, e_FM_PORT_TYPE_TX_10G, macId);
974    if ((p_Fm->p_FmStateStruct->portsTypes[rxHardwarePortId] != e_FM_PORT_TYPE_DUMMY) ||
975        (p_Fm->p_FmStateStruct->portsTypes[txHardwarePortId] != e_FM_PORT_TYPE_DUMMY))
976        RETURN_ERROR(MAJOR, E_INVALID_STATE,
977                     ("MAC should be initialized prior to rx and tx ports!"));
978    WRITE_UINT32(p_Fm->p_FmFpmRegs->fpmextc, 0x40000000);
979    CORE_MemoryBarrier();
980    while ((GET_UINT32(p_Fm->p_FmFpmRegs->fpmextc) & 0x40000000) &&
981           --timeout) ;
982    if (!timeout)
983        return ERROR_CODE(E_TIMEOUT);
984    return E_OK;
985}
986#endif /* FM_TX_ECC_FRMS_ERRATA_10GMAC_A004 */
987
988uintptr_t FmGetPcdPrsBaseAddr(t_Handle h_Fm)
989{
990    t_Fm        *p_Fm = (t_Fm*)h_Fm;
991
992    SANITY_CHECK_RETURN_VALUE(p_Fm, E_INVALID_HANDLE, 0);
993
994    if(p_Fm->guestId != NCSW_MASTER_ID)
995        REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Guset"));
996
997    return (p_Fm->baseAddr + FM_MM_PRS);
998}
999
1000uintptr_t FmGetPcdKgBaseAddr(t_Handle h_Fm)
1001{
1002    t_Fm        *p_Fm = (t_Fm*)h_Fm;
1003
1004    SANITY_CHECK_RETURN_VALUE(p_Fm, E_INVALID_HANDLE, 0);
1005
1006    if(p_Fm->guestId != NCSW_MASTER_ID)
1007        REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Guset"));
1008
1009    return (p_Fm->baseAddr + FM_MM_KG);
1010}
1011
1012uintptr_t FmGetPcdPlcrBaseAddr(t_Handle h_Fm)
1013{
1014    t_Fm        *p_Fm = (t_Fm*)h_Fm;
1015
1016    SANITY_CHECK_RETURN_VALUE(p_Fm, E_INVALID_HANDLE, 0);
1017
1018    if(p_Fm->guestId != NCSW_MASTER_ID)
1019        REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Guset"));
1020
1021    return (p_Fm->baseAddr + FM_MM_PLCR);
1022}
1023
1024t_Handle FmGetMuramHandle(t_Handle h_Fm)
1025{
1026    t_Fm        *p_Fm = (t_Fm*)h_Fm;
1027
1028    SANITY_CHECK_RETURN_VALUE(p_Fm, E_INVALID_HANDLE, NULL);
1029
1030    return (p_Fm->h_FmMuram);
1031}
1032
1033void FmGetPhysicalMuramBase(t_Handle h_Fm, t_FmPhysAddr *p_FmPhysAddr)
1034{
1035    t_Fm            *p_Fm = (t_Fm*)h_Fm;
1036    t_Error         err;
1037    t_FmIpcMsg      msg;
1038    t_FmIpcReply    reply;
1039    uint32_t        replyLength;
1040    t_FmIpcPhysAddr ipcPhysAddr;
1041
1042    if(p_Fm->guestId != NCSW_MASTER_ID)
1043    {
1044        memset(&msg, 0, sizeof(msg));
1045        memset(&reply, 0, sizeof(reply));
1046        msg.msgId = FM_GET_PHYS_MURAM_BASE;
1047        replyLength = sizeof(uint32_t) + sizeof(t_FmPhysAddr);
1048        if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
1049                                     (uint8_t*)&msg,
1050                                     sizeof(msg.msgId),
1051                                     (uint8_t*)&reply,
1052                                     &replyLength,
1053                                     NULL,
1054                                     NULL)) != E_OK)
1055        {
1056            REPORT_ERROR(MINOR, err, NO_MSG);
1057            return;
1058        }
1059        if (replyLength != (sizeof(uint32_t) + sizeof(t_FmPhysAddr)))
1060        {
1061            REPORT_ERROR(MINOR, E_INVALID_VALUE,("IPC reply length mismatch"));
1062            return;
1063        }
1064        memcpy((uint8_t*)&ipcPhysAddr, reply.replyBody, sizeof(t_FmIpcPhysAddr));
1065        p_FmPhysAddr->high = ipcPhysAddr.high;
1066        p_FmPhysAddr->low  = ipcPhysAddr.low;
1067        return ;
1068    }
1069
1070    /* General FM driver initialization */
1071    p_FmPhysAddr->low = (uint32_t)p_Fm->fmMuramPhysBaseAddr;
1072    p_FmPhysAddr->high = (uint8_t)((p_Fm->fmMuramPhysBaseAddr & 0x000000ff00000000LL) >> 32);
1073}
1074
1075t_Error FmAllocFmanCtrlEventReg(t_Handle h_Fm, uint8_t *p_EventId)
1076{
1077    t_Fm            *p_Fm = (t_Fm*)h_Fm;
1078    uint8_t         i;
1079    t_Error         err;
1080    t_FmIpcMsg      msg;
1081    t_FmIpcReply    reply;
1082    uint32_t        replyLength;
1083
1084    if(p_Fm->guestId != NCSW_MASTER_ID)
1085    {
1086        memset(&msg, 0, sizeof(msg));
1087        memset(&reply, 0, sizeof(reply));
1088        msg.msgId = FM_ALLOC_FMAN_CTRL_EVENT_REG;
1089        replyLength = sizeof(uint32_t) + sizeof(uint8_t);
1090        if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
1091                                     (uint8_t*)&msg,
1092                                     sizeof(msg.msgId),
1093                                     (uint8_t*)&reply,
1094                                     &replyLength,
1095                                     NULL,
1096                                     NULL)) != E_OK)
1097            RETURN_ERROR(MAJOR, err, NO_MSG);
1098        if (replyLength != (sizeof(uint32_t) + sizeof(uint8_t)))
1099            RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
1100
1101        *p_EventId = *(uint8_t*)(reply.replyBody);
1102
1103        return (t_Error)(reply.error);
1104    }
1105
1106    for(i=0;i<FM_NUM_OF_FMAN_CTRL_EVENT_REGS;i++)
1107        if (!p_Fm->usedEventRegs[i])
1108        {
1109            p_Fm->usedEventRegs[i] = TRUE;
1110            *p_EventId = i;
1111            break;
1112        }
1113
1114    if (i==FM_NUM_OF_FMAN_CTRL_EVENT_REGS)
1115        RETURN_ERROR(MAJOR, E_BUSY, ("No resource - Fman controller event register."));
1116
1117    return E_OK;
1118}
1119
1120void FmFreeFmanCtrlEventReg(t_Handle h_Fm, uint8_t eventId)
1121{
1122    t_Fm        *p_Fm = (t_Fm*)h_Fm;
1123    t_Error     err;
1124    t_FmIpcMsg  msg;
1125
1126    if(((t_Fm *)h_Fm)->guestId != NCSW_MASTER_ID)
1127    {
1128        memset(&msg, 0, sizeof(msg));
1129        msg.msgId = FM_FREE_FMAN_CTRL_EVENT_REG;
1130        msg.msgBody[0] = eventId;
1131        if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
1132                                     (uint8_t*)&msg,
1133                                     sizeof(msg.msgId)+sizeof(eventId),
1134                                     NULL,
1135                                     NULL,
1136                                     NULL,
1137                                     NULL)) != E_OK)
1138            REPORT_ERROR(MINOR, err, NO_MSG);
1139        return;
1140    }
1141
1142    ((t_Fm*)h_Fm)->usedEventRegs[eventId] = FALSE;
1143}
1144
1145void FmRegisterIntr(t_Handle h_Fm,
1146                        e_FmEventModules        module,
1147                        uint8_t                 modId,
1148                        e_FmIntrType            intrType,
1149                        void (*f_Isr) (t_Handle h_Arg),
1150                        t_Handle    h_Arg)
1151{
1152    t_Fm                *p_Fm = (t_Fm*)h_Fm;
1153    uint8_t             event= 0;
1154    t_FmIpcRegisterIntr fmIpcRegisterIntr;
1155    t_Error             err;
1156    t_FmIpcMsg          msg;
1157
1158    ASSERT_COND(h_Fm);
1159
1160    GET_FM_MODULE_EVENT(module, modId,intrType, event);
1161
1162    /* register in local FM structure */
1163    ASSERT_COND(event != e_FM_EV_DUMMY_LAST);
1164    p_Fm->intrMng[event].f_Isr = f_Isr;
1165    p_Fm->intrMng[event].h_SrcHandle = h_Arg;
1166
1167    if(p_Fm->guestId != NCSW_MASTER_ID)
1168    {
1169        if(p_Fm->h_IpcSessions[0])
1170        {
1171            /* register in Master FM structure */
1172            fmIpcRegisterIntr.event = event;
1173            fmIpcRegisterIntr.guestId = p_Fm->guestId;
1174            memset(&msg, 0, sizeof(msg));
1175            msg.msgId = FM_REGISTER_INTR;
1176            memcpy(msg.msgBody, &fmIpcRegisterIntr, sizeof(fmIpcRegisterIntr));
1177            if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
1178                                         (uint8_t*)&msg,
1179                                         sizeof(msg.msgId) + sizeof(fmIpcRegisterIntr),
1180                                         NULL,
1181                                         NULL,
1182                                         NULL,
1183                                         NULL)) != E_OK)
1184                REPORT_ERROR(MINOR, err, NO_MSG);
1185        }
1186        else
1187            DBG(WARNING,("'Register interrupt' - unavailable - No IPC"));
1188    }
1189
1190}
1191
1192void FmUnregisterIntr(t_Handle h_Fm,
1193                        e_FmEventModules        module,
1194                        uint8_t                 modId,
1195                        e_FmIntrType            intrType)
1196{
1197    t_Fm       *p_Fm = (t_Fm*)h_Fm;
1198    uint8_t     event= 0;
1199
1200    ASSERT_COND(h_Fm);
1201
1202    GET_FM_MODULE_EVENT(module, modId,intrType, event);
1203
1204    ASSERT_COND(event != e_FM_EV_DUMMY_LAST);
1205    p_Fm->intrMng[event].f_Isr = UnimplementedIsr;
1206    p_Fm->intrMng[event].h_SrcHandle = NULL;
1207}
1208
1209void FmSetFmanCtrlIntr(t_Handle h_Fm, uint8_t   eventRegId, uint32_t enableEvents)
1210{
1211    t_Fm                *p_Fm = (t_Fm*)h_Fm;
1212    t_FmIpcFmanEvents   fmanCtrl;
1213    t_Error             err;
1214    t_FmIpcMsg          msg;
1215
1216    if(p_Fm->guestId != NCSW_MASTER_ID)
1217    {
1218        fmanCtrl.eventRegId = eventRegId;
1219        fmanCtrl.enableEvents = enableEvents;
1220        memset(&msg, 0, sizeof(msg));
1221        msg.msgId = FM_SET_FMAN_CTRL_EVENTS_ENABLE;
1222        memcpy(msg.msgBody, &fmanCtrl, sizeof(fmanCtrl));
1223        if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
1224                                     (uint8_t*)&msg,
1225                                     sizeof(msg.msgId)+sizeof(fmanCtrl),
1226                                     NULL,
1227                                     NULL,
1228                                     NULL,
1229                                     NULL)) != E_OK)
1230            REPORT_ERROR(MINOR, err, NO_MSG);
1231        return;
1232    }
1233
1234    ASSERT_COND(eventRegId < FM_NUM_OF_FMAN_CTRL_EVENT_REGS);
1235    WRITE_UINT32(p_Fm->p_FmFpmRegs->fmfpfcee[eventRegId], enableEvents);
1236}
1237
1238uint32_t FmGetFmanCtrlIntr(t_Handle h_Fm, uint8_t eventRegId)
1239{
1240    t_Fm            *p_Fm = (t_Fm*)h_Fm;
1241    t_Error         err;
1242    t_FmIpcMsg      msg;
1243    t_FmIpcReply    reply;
1244    uint32_t        replyLength, ctrlIntr;
1245
1246    if(p_Fm->guestId != NCSW_MASTER_ID)
1247    {
1248        memset(&msg, 0, sizeof(msg));
1249        memset(&reply, 0, sizeof(reply));
1250        msg.msgId = FM_GET_FMAN_CTRL_EVENTS_ENABLE;
1251        msg.msgBody[0] = eventRegId;
1252        replyLength = sizeof(uint32_t) + sizeof(uint32_t);
1253        if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
1254                                     (uint8_t*)&msg,
1255                                     sizeof(msg.msgId)+sizeof(eventRegId),
1256                                     (uint8_t*)&reply,
1257                                     &replyLength,
1258                                     NULL,
1259                                     NULL)) != E_OK)
1260        {
1261            REPORT_ERROR(MINOR, err, NO_MSG);
1262            return 0;
1263        }
1264        if (replyLength != (sizeof(uint32_t) + sizeof(uint32_t)))
1265        {
1266            REPORT_ERROR(MINOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
1267            return 0;
1268        }
1269        memcpy((uint8_t*)&ctrlIntr, reply.replyBody, sizeof(uint32_t));
1270        return ctrlIntr;
1271    }
1272
1273    return GET_UINT32(p_Fm->p_FmFpmRegs->fmfpfcee[eventRegId]);
1274}
1275
1276void  FmRegisterFmanCtrlIntr(t_Handle h_Fm, uint8_t eventRegId, void (*f_Isr) (t_Handle h_Arg, uint32_t event), t_Handle    h_Arg)
1277{
1278    t_Fm       *p_Fm = (t_Fm*)h_Fm;
1279
1280    ASSERT_COND(eventRegId<FM_NUM_OF_FMAN_CTRL_EVENT_REGS);
1281
1282    if(p_Fm->guestId != NCSW_MASTER_ID)
1283    {
1284        ASSERT_COND(0);
1285        /* TODO */
1286    }
1287
1288    p_Fm->fmanCtrlIntr[eventRegId].f_Isr = f_Isr;
1289    p_Fm->fmanCtrlIntr[eventRegId].h_SrcHandle = h_Arg;
1290}
1291
1292void  FmUnregisterFmanCtrlIntr(t_Handle h_Fm, uint8_t eventRegId)
1293{
1294    t_Fm       *p_Fm = (t_Fm*)h_Fm;
1295
1296    ASSERT_COND(eventRegId<FM_NUM_OF_FMAN_CTRL_EVENT_REGS);
1297
1298    if(p_Fm->guestId != NCSW_MASTER_ID)
1299    {
1300        ASSERT_COND(0);
1301        /* TODO */
1302    }
1303
1304    p_Fm->fmanCtrlIntr[eventRegId].f_Isr = UnimplementedFmanCtrlIsr;
1305    p_Fm->fmanCtrlIntr[eventRegId].h_SrcHandle = NULL;
1306}
1307
1308void  FmRegisterPcd(t_Handle h_Fm, t_Handle h_FmPcd)
1309{
1310    t_Fm       *p_Fm = (t_Fm*)h_Fm;
1311
1312    if(p_Fm->h_Pcd)
1313        REPORT_ERROR(MAJOR, E_ALREADY_EXISTS, ("PCD already set"));
1314
1315    p_Fm->h_Pcd = h_FmPcd;
1316
1317}
1318
1319void  FmUnregisterPcd(t_Handle h_Fm)
1320{
1321    t_Fm       *p_Fm = (t_Fm*)h_Fm;
1322
1323    if(!p_Fm->h_Pcd)
1324        REPORT_ERROR(MAJOR, E_ALREADY_EXISTS, ("No PCD"));
1325
1326    p_Fm->h_Pcd = NULL;
1327
1328}
1329
1330t_Handle  FmGetPcdHandle(t_Handle h_Fm)
1331{
1332    t_Fm       *p_Fm = (t_Fm*)h_Fm;
1333
1334    return p_Fm->h_Pcd;
1335}
1336
1337uint8_t FmGetId(t_Handle h_Fm)
1338{
1339    t_Fm *p_Fm = (t_Fm*)h_Fm;
1340
1341    SANITY_CHECK_RETURN_VALUE(p_Fm, E_INVALID_HANDLE, 0xff);
1342
1343    return p_Fm->p_FmStateStruct->fmId;
1344}
1345
1346t_Error FmSetNumOfRiscsPerPort(t_Handle h_Fm, uint8_t hardwarePortId, uint8_t numOfFmanCtrls)
1347{
1348
1349    t_Fm                        *p_Fm = (t_Fm*)h_Fm;
1350    uint32_t                    tmpReg = 0;
1351    t_Error                     err;
1352    t_FmIpcPortNumOfFmanCtrls   params;
1353    t_FmIpcMsg                  msg;
1354
1355    SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
1356    SANITY_CHECK_RETURN_ERROR(((numOfFmanCtrls > 0) && (numOfFmanCtrls < 3)) , E_INVALID_HANDLE);
1357
1358    if(p_Fm->guestId != NCSW_MASTER_ID)
1359    {
1360        memset(&msg, 0, sizeof(msg));
1361        params.hardwarePortId = hardwarePortId;
1362        params.numOfFmanCtrls = numOfFmanCtrls;
1363        msg.msgId = FM_SET_NUM_OF_FMAN_CTRL;
1364        memcpy(msg.msgBody, &params, sizeof(params));
1365        if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
1366                                     (uint8_t*)&msg,
1367                                     sizeof(msg.msgId) +sizeof(params),
1368                                     NULL,
1369                                     NULL,
1370                                     NULL,
1371                                     NULL)) != E_OK)
1372            RETURN_ERROR(MINOR, err, NO_MSG);
1373
1374        return E_OK;
1375    }
1376
1377    XX_LockSpinlock(p_Fm->h_Spinlock);
1378
1379    tmpReg = (uint32_t)(hardwarePortId << FPM_PORT_FM_CTL_PORTID_SHIFT);
1380
1381    /*TODO - maybe to put CTL# according to another criteria*/
1382
1383    if(numOfFmanCtrls == 2)
1384        tmpReg = FPM_PORT_FM_CTL2 | FPM_PORT_FM_CTL1;
1385
1386    /* order restoration */
1387    if(hardwarePortId%2)
1388        tmpReg |= (FPM_PORT_FM_CTL1 << FPM_PRC_ORA_FM_CTL_SEL_SHIFT) | FPM_PORT_FM_CTL1;
1389    else
1390        tmpReg |= (FPM_PORT_FM_CTL2 << FPM_PRC_ORA_FM_CTL_SEL_SHIFT) | FPM_PORT_FM_CTL2;
1391
1392    WRITE_UINT32(p_Fm->p_FmFpmRegs->fpmpr, tmpReg);
1393    XX_UnlockSpinlock(p_Fm->h_Spinlock);
1394
1395    return E_OK;
1396}
1397
1398t_Error FmGetSetPortParams(t_Handle h_Fm,t_FmInterModulePortInitParams *p_PortParams)
1399{
1400    t_Fm                    *p_Fm = (t_Fm*)h_Fm;
1401    uint32_t                tmpReg;
1402    uint8_t                 hardwarePortId = p_PortParams->hardwarePortId;
1403    t_FmIpcPortInInitParams portInParams;
1404    t_FmIpcPhysAddr         ipcPhysAddr;
1405    t_Error                 err;
1406    t_FmIpcMsg              msg;
1407    t_FmIpcReply            reply;
1408    uint32_t                replyLength;
1409
1410    if(p_Fm->guestId != NCSW_MASTER_ID)
1411    {
1412        portInParams.hardwarePortId = p_PortParams->hardwarePortId;
1413        portInParams.enumPortType = (uint32_t)p_PortParams->portType;
1414        portInParams.boolIndependentMode = (uint8_t)p_PortParams->independentMode;
1415        portInParams.liodnOffset = p_PortParams->liodnOffset;
1416        portInParams.numOfTasks = p_PortParams->numOfTasks;
1417        portInParams.numOfExtraTasks = p_PortParams->numOfExtraTasks;
1418        portInParams.numOfOpenDmas = p_PortParams->numOfOpenDmas;
1419        portInParams.numOfExtraOpenDmas = p_PortParams->numOfExtraOpenDmas;
1420        portInParams.sizeOfFifo = p_PortParams->sizeOfFifo;
1421        portInParams.extraSizeOfFifo = p_PortParams->extraSizeOfFifo;
1422        portInParams.deqPipelineDepth = p_PortParams->deqPipelineDepth;
1423        portInParams.liodnBase = p_PortParams->liodnBase;
1424        memset(&msg, 0, sizeof(msg));
1425        memset(&reply, 0, sizeof(reply));
1426        msg.msgId = FM_GET_SET_PORT_PARAMS;
1427        memcpy(msg.msgBody, &portInParams, sizeof(portInParams));
1428        replyLength = (sizeof(uint32_t) + sizeof(p_PortParams->fmMuramPhysBaseAddr));
1429        if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
1430                                     (uint8_t*)&msg,
1431                                     sizeof(msg.msgId) +sizeof(portInParams),
1432                                     (uint8_t*)&reply,
1433                                     &replyLength,
1434                                     NULL,
1435                                     NULL)) != E_OK)
1436            RETURN_ERROR(MINOR, err, NO_MSG);
1437        if (replyLength != (sizeof(uint32_t) + sizeof(p_PortParams->fmMuramPhysBaseAddr)))
1438            RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
1439        memcpy((uint8_t*)&ipcPhysAddr, reply.replyBody, sizeof(t_FmIpcPhysAddr));
1440        p_PortParams->fmMuramPhysBaseAddr.high = ipcPhysAddr.high;
1441        p_PortParams->fmMuramPhysBaseAddr.low  = ipcPhysAddr.low;
1442
1443        return (t_Error)(reply.error);
1444    }
1445
1446    ASSERT_COND(IN_RANGE(1, hardwarePortId, 63));
1447    XX_LockSpinlock(p_Fm->h_Spinlock);
1448
1449    if(p_PortParams->independentMode)
1450    {
1451        /* set port parameters */
1452        p_Fm->independentMode = p_PortParams->independentMode;
1453        /* disable dispatch limit */
1454        WRITE_UINT32(p_Fm->p_FmFpmRegs->fpmflc, 0);
1455    }
1456
1457    if(p_PortParams->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND)
1458    {
1459        if(p_Fm->hcPortInitialized)
1460        {
1461            XX_UnlockSpinlock(p_Fm->h_Spinlock);
1462            RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Only one host command port is allowed."));
1463        }
1464        else
1465            p_Fm->hcPortInitialized = TRUE;
1466    }
1467    p_Fm->p_FmStateStruct->portsTypes[hardwarePortId] = p_PortParams->portType;
1468
1469    err = FmSetNumOfTasks(p_Fm, p_PortParams->hardwarePortId, p_PortParams->numOfTasks, p_PortParams->numOfExtraTasks, TRUE);
1470    if(err)
1471    {
1472        XX_UnlockSpinlock(p_Fm->h_Spinlock);
1473        RETURN_ERROR(MAJOR, err, NO_MSG);
1474    }
1475
1476#ifdef FM_QMI_DEQ_OPTIONS_SUPPORT
1477    if((p_PortParams->portType != e_FM_PORT_TYPE_RX) && (p_PortParams->portType != e_FM_PORT_TYPE_RX_10G))
1478    /* for transmit & O/H ports */
1479    {
1480        uint8_t     enqTh;
1481        uint8_t     deqTh;
1482        bool        update = FALSE;
1483
1484        /* update qmi ENQ/DEQ threshold */
1485        p_Fm->p_FmStateStruct->accumulatedNumOfDeqTnums += p_PortParams->deqPipelineDepth;
1486        tmpReg = GET_UINT32(p_Fm->p_FmQmiRegs->fmqm_gc);
1487        enqTh = (uint8_t)(tmpReg>>8);
1488        /* if enqTh is too big, we reduce it to the max value that is still OK */
1489        if(enqTh >= (QMI_MAX_NUM_OF_TNUMS - p_Fm->p_FmStateStruct->accumulatedNumOfDeqTnums))
1490        {
1491            enqTh = (uint8_t)(QMI_MAX_NUM_OF_TNUMS - p_Fm->p_FmStateStruct->accumulatedNumOfDeqTnums - 1);
1492            tmpReg &= ~QMI_CFG_ENQ_MASK;
1493            tmpReg |= ((uint32_t)enqTh << 8);
1494            update = TRUE;
1495        }
1496
1497        deqTh = (uint8_t)tmpReg;
1498        /* if deqTh is too small, we enlarge it to the min value that is still OK.
1499         deqTh may not be larger than 63 (QMI_MAX_NUM_OF_TNUMS-1). */
1500        if((deqTh <= p_Fm->p_FmStateStruct->accumulatedNumOfDeqTnums)  && (deqTh < QMI_MAX_NUM_OF_TNUMS-1))
1501        {
1502            deqTh = (uint8_t)(p_Fm->p_FmStateStruct->accumulatedNumOfDeqTnums + 1);
1503            tmpReg &= ~QMI_CFG_DEQ_MASK;
1504            tmpReg |= (uint32_t)deqTh;
1505            update = TRUE;
1506        }
1507        if(update)
1508            WRITE_UINT32(p_Fm->p_FmQmiRegs->fmqm_gc, tmpReg);
1509    }
1510#endif /* FM_QMI_DEQ_OPTIONS_SUPPORT */
1511
1512#ifdef FM_LOW_END_RESTRICTION
1513    if((hardwarePortId==0x1) || (hardwarePortId==0x29))
1514    {
1515        if(p_Fm->p_FmStateStruct->lowEndRestriction)
1516        {
1517            XX_UnlockSpinlock(p_Fm->h_Spinlock);
1518            RETURN_ERROR(MAJOR, E_NOT_AVAILABLE, ("OP #0 cannot work with Tx Port #1."));
1519        }
1520        else
1521            p_Fm->p_FmStateStruct->lowEndRestriction = TRUE;
1522    }
1523#endif /* FM_LOW_END_RESTRICTION */
1524
1525    err = FmSetSizeOfFifo(p_Fm,
1526                            p_PortParams->hardwarePortId,
1527                            p_PortParams->portType,
1528                            p_PortParams->independentMode,
1529                            &p_PortParams->sizeOfFifo,
1530                            p_PortParams->extraSizeOfFifo,
1531                            p_PortParams->deqPipelineDepth,
1532                            NULL,
1533                            TRUE);
1534    if(err)
1535    {
1536        XX_UnlockSpinlock(p_Fm->h_Spinlock);
1537        RETURN_ERROR(MAJOR, err, NO_MSG);
1538    }
1539
1540    err = FmSetNumOfOpenDmas(p_Fm, p_PortParams->hardwarePortId, p_PortParams->numOfOpenDmas, p_PortParams->numOfExtraOpenDmas, TRUE);
1541    if(err)
1542    {
1543        XX_UnlockSpinlock(p_Fm->h_Spinlock);
1544        RETURN_ERROR(MAJOR, err, NO_MSG);
1545    }
1546
1547    WRITE_UINT32(p_Fm->p_FmBmiRegs->fmbm_ppid[hardwarePortId-1], (uint32_t)p_PortParams->liodnOffset);
1548
1549    tmpReg = (uint32_t)(hardwarePortId << FPM_PORT_FM_CTL_PORTID_SHIFT);
1550    if(p_PortParams->independentMode)
1551    {
1552        if((p_PortParams->portType==e_FM_PORT_TYPE_RX) || (p_PortParams->portType==e_FM_PORT_TYPE_RX_10G))
1553            tmpReg |= (FPM_PORT_FM_CTL1 << FPM_PRC_ORA_FM_CTL_SEL_SHIFT) |FPM_PORT_FM_CTL1;
1554        else
1555            tmpReg |= (FPM_PORT_FM_CTL2 << FPM_PRC_ORA_FM_CTL_SEL_SHIFT) |FPM_PORT_FM_CTL2;
1556    }
1557    else
1558    {
1559        tmpReg |= (FPM_PORT_FM_CTL2|FPM_PORT_FM_CTL1);
1560
1561        /* order restoration */
1562        if(hardwarePortId%2)
1563            tmpReg |= (FPM_PORT_FM_CTL1 << FPM_PRC_ORA_FM_CTL_SEL_SHIFT);
1564        else
1565            tmpReg |= (FPM_PORT_FM_CTL2 << FPM_PRC_ORA_FM_CTL_SEL_SHIFT);
1566    }
1567    WRITE_UINT32(p_Fm->p_FmFpmRegs->fpmpr, tmpReg);
1568
1569    {
1570#ifdef FM_PARTITION_ARRAY
1571        t_FmRevisionInfo revInfo;
1572
1573        FM_GetRevision(p_Fm, &revInfo);
1574        if (revInfo.majorRev >= 2)
1575#endif /* FM_PARTITION_ARRAY */
1576        {
1577            /* set LIODN base for this port */
1578            tmpReg = GET_UINT32(p_Fm->p_FmDmaRegs->fmdmplr[hardwarePortId/2]);
1579            if(hardwarePortId%2)
1580            {
1581                tmpReg &= ~FM_LIODN_BASE_MASK;
1582                tmpReg |= (uint32_t)p_PortParams->liodnBase;
1583            }
1584            else
1585            {
1586                tmpReg &= ~(FM_LIODN_BASE_MASK<< DMA_LIODN_SHIFT);
1587                tmpReg |= (uint32_t)p_PortParams->liodnBase << DMA_LIODN_SHIFT;
1588            }
1589            WRITE_UINT32(p_Fm->p_FmDmaRegs->fmdmplr[hardwarePortId/2], tmpReg);
1590        }
1591    }
1592
1593    FmGetPhysicalMuramBase(p_Fm, &p_PortParams->fmMuramPhysBaseAddr);
1594    XX_UnlockSpinlock(p_Fm->h_Spinlock);
1595
1596    return E_OK;
1597}
1598
1599void FmFreePortParams(t_Handle h_Fm,t_FmInterModulePortFreeParams *p_PortParams)
1600{
1601    t_Fm                    *p_Fm = (t_Fm*)h_Fm;
1602    uint32_t                tmpReg;
1603    uint8_t                 hardwarePortId = p_PortParams->hardwarePortId;
1604    uint8_t                 numOfTasks;
1605    t_Error                 err;
1606    t_FmIpcPortFreeParams   portParams;
1607    t_FmIpcMsg              msg;
1608
1609    if(p_Fm->guestId != NCSW_MASTER_ID)
1610    {
1611        portParams.hardwarePortId = p_PortParams->hardwarePortId;
1612        portParams.enumPortType = (uint32_t)p_PortParams->portType;
1613#ifdef FM_QMI_DEQ_OPTIONS_SUPPORT
1614        portParams.deqPipelineDepth = p_PortParams->deqPipelineDepth;
1615#endif /* FM_QMI_DEQ_OPTIONS_SUPPORT */
1616        memset(&msg, 0, sizeof(msg));
1617        msg.msgId = FM_FREE_PORT;
1618        memcpy(msg.msgBody, &portParams, sizeof(portParams));
1619        if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
1620                                     (uint8_t*)&msg,
1621                                     sizeof(msg.msgId)+sizeof(portParams),
1622                                     NULL,
1623                                     NULL,
1624                                     NULL,
1625                                     NULL)) != E_OK)
1626            REPORT_ERROR(MINOR, err, NO_MSG);
1627        return;
1628    }
1629
1630    ASSERT_COND(IN_RANGE(1, hardwarePortId, 63));
1631    XX_LockSpinlock(p_Fm->h_Spinlock);
1632
1633
1634    if(p_PortParams->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND)
1635    {
1636        ASSERT_COND(p_Fm->hcPortInitialized);
1637        p_Fm->hcPortInitialized = FALSE;
1638    }
1639
1640    p_Fm->p_FmStateStruct->portsTypes[hardwarePortId] = e_FM_PORT_TYPE_DUMMY;
1641
1642    tmpReg = GET_UINT32(p_Fm->p_FmBmiRegs->fmbm_pp[hardwarePortId-1]);
1643    /* free numOfTasks */
1644    numOfTasks = (uint8_t)(((tmpReg & BMI_NUM_OF_TASKS_MASK) >> BMI_NUM_OF_TASKS_SHIFT) + 1);
1645    ASSERT_COND(p_Fm->p_FmStateStruct->accumulatedNumOfTasks >= numOfTasks);
1646    p_Fm->p_FmStateStruct->accumulatedNumOfTasks -= numOfTasks;
1647
1648    /* free numOfOpenDmas */
1649    ASSERT_COND(p_Fm->p_FmStateStruct->accumulatedNumOfOpenDmas >= ((tmpReg & BMI_NUM_OF_DMAS_MASK) >> BMI_NUM_OF_DMAS_SHIFT) + 1);
1650    p_Fm->p_FmStateStruct->accumulatedNumOfOpenDmas -= (((tmpReg & BMI_NUM_OF_DMAS_MASK) >> BMI_NUM_OF_DMAS_SHIFT) + 1);
1651
1652    /* update total num of DMA's with committed number of open DMAS, and max uncommitted pool. */
1653    tmpReg = GET_UINT32(p_Fm->p_FmBmiRegs->fmbm_cfg2) & ~BMI_CFG2_DMAS_MASK;
1654    tmpReg |= (uint32_t)(p_Fm->p_FmStateStruct->accumulatedNumOfOpenDmas + p_Fm->p_FmStateStruct->extraOpenDmasPoolSize - 1) << BMI_CFG2_DMAS_SHIFT;
1655    WRITE_UINT32(p_Fm->p_FmBmiRegs->fmbm_cfg2,  tmpReg);
1656
1657    /* free sizeOfFifo */
1658    tmpReg = GET_UINT32(p_Fm->p_FmBmiRegs->fmbm_pfs[hardwarePortId-1]);
1659    ASSERT_COND(p_Fm->p_FmStateStruct->accumulatedFifoSize >=
1660                (((tmpReg & BMI_FIFO_SIZE_MASK) + 1) * BMI_FIFO_UNITS));
1661    p_Fm->p_FmStateStruct->accumulatedFifoSize -=
1662        (((tmpReg & BMI_FIFO_SIZE_MASK) + 1) * BMI_FIFO_UNITS);
1663
1664    /* clear registers */
1665    WRITE_UINT32(p_Fm->p_FmBmiRegs->fmbm_pp[hardwarePortId-1], 0);
1666    WRITE_UINT32(p_Fm->p_FmBmiRegs->fmbm_pfs[hardwarePortId-1], 0);
1667    /* WRITE_UINT32(p_Fm->p_FmBmiRegs->fmbm_ppid[hardwarePortId-1], 0); */
1668
1669#ifdef FM_PORT_DISABLED_ERRATA_FMANx9
1670    /* this errata means that when a port is taken down, other port may not use its
1671     * resources for a while as it may still be using it (in case of reject).
1672     */
1673        {
1674            t_FmRevisionInfo revInfo;
1675            FM_GetRevision(p_Fm, &revInfo);
1676            if ((revInfo.majorRev == 1) && (revInfo.minorRev == 0))
1677                XX_UDelay(100000);
1678        }
1679#endif /* FM_PORT_DISABLED_ERRATA_FMANx9 */
1680
1681#ifdef FM_QMI_DEQ_OPTIONS_SUPPORT
1682    if((p_PortParams->portType != e_FM_PORT_TYPE_RX) && (p_PortParams->portType != e_FM_PORT_TYPE_RX_10G))
1683    /* for transmit & O/H ports */
1684    {
1685        uint8_t     enqTh;
1686        uint8_t     deqTh;
1687
1688        tmpReg = GET_UINT32(p_Fm->p_FmQmiRegs->fmqm_gc);
1689        /* update qmi ENQ/DEQ threshold */
1690        p_Fm->p_FmStateStruct->accumulatedNumOfDeqTnums -= p_PortParams->deqPipelineDepth;
1691
1692        /* p_Fm->p_FmStateStruct->accumulatedNumOfDeqTnums is now smaller,
1693           so we can enlarge enqTh */
1694        enqTh = (uint8_t)(QMI_MAX_NUM_OF_TNUMS - p_Fm->p_FmStateStruct->accumulatedNumOfDeqTnums - 1);
1695        tmpReg &= ~QMI_CFG_ENQ_MASK;
1696        tmpReg |= ((uint32_t)enqTh << QMI_CFG_ENQ_SHIFT);
1697
1698         /* p_Fm->p_FmStateStruct->accumulatedNumOfDeqTnums is now smaller,
1699           so we can reduce deqTh */
1700        deqTh = (uint8_t)(p_Fm->p_FmStateStruct->accumulatedNumOfDeqTnums + 1);
1701        tmpReg &= ~QMI_CFG_DEQ_MASK;
1702        tmpReg |= (uint32_t)deqTh;
1703
1704        WRITE_UINT32(p_Fm->p_FmQmiRegs->fmqm_gc, tmpReg);
1705    }
1706#endif /* FM_QMI_DEQ_OPTIONS_SUPPORT */
1707
1708#ifdef FM_LOW_END_RESTRICTION
1709    if((hardwarePortId==0x1) || (hardwarePortId==0x29))
1710        p_Fm->p_FmStateStruct->lowEndRestriction = FALSE;
1711#endif /* FM_LOW_END_RESTRICTION */
1712    XX_UnlockSpinlock(p_Fm->h_Spinlock);
1713}
1714
1715t_Error FmIsPortStalled(t_Handle h_Fm, uint8_t hardwarePortId, bool *p_IsStalled)
1716{
1717    t_Fm            *p_Fm = (t_Fm*)h_Fm;
1718    uint32_t        tmpReg;
1719    t_Error         err;
1720    t_FmIpcMsg      msg;
1721    t_FmIpcReply    reply;
1722    uint32_t        replyLength;
1723
1724    if(p_Fm->guestId != NCSW_MASTER_ID)
1725    {
1726        memset(&msg, 0, sizeof(msg));
1727        memset(&reply, 0, sizeof(reply));
1728        msg.msgId = FM_IS_PORT_STALLED;
1729        msg.msgBody[0] = hardwarePortId;
1730        replyLength = sizeof(uint32_t) + sizeof(uint8_t);
1731        if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
1732                                     (uint8_t*)&msg,
1733                                     sizeof(msg.msgId)+sizeof(hardwarePortId),
1734                                     (uint8_t*)&reply,
1735                                     &replyLength,
1736                                     NULL,
1737                                     NULL)) != E_OK)
1738            RETURN_ERROR(MINOR, err, NO_MSG);
1739        if (replyLength != (sizeof(uint32_t) + sizeof(uint8_t)))
1740            RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
1741
1742        *p_IsStalled = (bool)!!(*(uint8_t*)(reply.replyBody));
1743
1744        return (t_Error)(reply.error);
1745    }
1746
1747    tmpReg = GET_UINT32(p_Fm->p_FmFpmRegs->fmfp_ps[hardwarePortId]);
1748    *p_IsStalled = (bool)!!(tmpReg & FPM_PS_STALLED);
1749
1750    return E_OK;
1751}
1752
1753t_Error FmResumeStalledPort(t_Handle h_Fm, uint8_t hardwarePortId)
1754{
1755    t_Fm            *p_Fm = (t_Fm*)h_Fm;
1756    uint32_t        tmpReg;
1757    t_Error         err;
1758    bool            isStalled;
1759    t_FmIpcMsg      msg;
1760    t_FmIpcReply    reply;
1761    uint32_t        replyLength;
1762
1763    if(p_Fm->guestId != NCSW_MASTER_ID)
1764    {
1765        memset(&msg, 0, sizeof(msg));
1766        memset(&reply, 0, sizeof(reply));
1767        msg.msgId = FM_RESUME_STALLED_PORT;
1768        msg.msgBody[0] = hardwarePortId;
1769        replyLength = sizeof(uint32_t);
1770        if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
1771                                     (uint8_t*)&msg,
1772                                     sizeof(msg.msgId) + sizeof(hardwarePortId),
1773                                     (uint8_t*)&reply,
1774                                     &replyLength,
1775                                     NULL,
1776                                     NULL)) != E_OK)
1777            RETURN_ERROR(MINOR, err, NO_MSG);
1778        if (replyLength != sizeof(uint32_t))
1779            RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
1780        return (t_Error)(reply.error);
1781    }
1782
1783    /* Get port status */
1784    err = FmIsPortStalled(h_Fm, hardwarePortId, &isStalled);
1785    if(err)
1786        RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Can't get port status"));
1787    if (!isStalled)
1788        RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Port is not stalled"));
1789
1790    tmpReg = (uint32_t)((hardwarePortId << FPM_PORT_FM_CTL_PORTID_SHIFT) | FPM_PRC_REALSE_STALLED);
1791    WRITE_UINT32(p_Fm->p_FmFpmRegs->fpmpr, tmpReg);
1792
1793    return E_OK;
1794}
1795
1796t_Error FmResetMac(t_Handle h_Fm, e_FmMacType type, uint8_t macId)
1797{
1798    t_Fm                *p_Fm = (t_Fm*)h_Fm;
1799    uint32_t            bitMask, timeout = 1000;
1800    t_FmIpcMacParams    macParams;
1801    t_Error             err;
1802    t_FmIpcMsg          msg;
1803    t_FmIpcReply        reply;
1804    uint32_t            replyLength;
1805
1806    if(p_Fm->guestId != NCSW_MASTER_ID)
1807    {
1808        if(p_Fm->h_IpcSessions[0])
1809        {
1810            memset(&msg, 0, sizeof(msg));
1811            memset(&reply, 0, sizeof(reply));
1812            macParams.id = macId;
1813            macParams.enumType = (uint32_t)type;
1814            msg.msgId = FM_RESET_MAC;
1815            memcpy(msg.msgBody,  &macParams, sizeof(macParams));
1816            replyLength = sizeof(uint32_t);
1817            if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
1818                                         (uint8_t*)&msg,
1819                                         sizeof(msg.msgId)+sizeof(macParams),
1820                                         (uint8_t*)&reply,
1821                                         &replyLength,
1822                                         NULL,
1823                                         NULL)) != E_OK)
1824                RETURN_ERROR(MINOR, err, NO_MSG);
1825            if (replyLength != sizeof(uint32_t))
1826                RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
1827            return (t_Error)(reply.error);
1828        }
1829        else
1830            if(!p_Fm->p_FmFpmRegs)
1831                RETURN_ERROR(MINOR, E_INVALID_STATE, ("No IPC and no registers address"));
1832    }
1833
1834    /* Get the relevant bit mask */
1835    if (type == e_FM_MAC_10G)
1836    {
1837        switch(macId)
1838        {
1839            case(0):
1840                bitMask = FPM_RSTC_10G0_RESET;
1841                break;
1842            default:
1843                RETURN_ERROR(MINOR, E_INVALID_VALUE, ("Illegal MAC Id"));
1844        }
1845    }
1846    else
1847    {
1848        switch(macId)
1849        {
1850            case(0):
1851                bitMask = FPM_RSTC_1G0_RESET;
1852                break;
1853            case(1):
1854                bitMask = FPM_RSTC_1G1_RESET;
1855                break;
1856            case(2):
1857                bitMask = FPM_RSTC_1G2_RESET;
1858                break;
1859            case(3):
1860                bitMask = FPM_RSTC_1G3_RESET;
1861                break;
1862            case(4):
1863                bitMask = FPM_RSTC_1G4_RESET;
1864                break;
1865            default:
1866                RETURN_ERROR(MINOR, E_INVALID_VALUE, ("Illegal MAC Id"));
1867        }
1868    }
1869
1870    /* reset */
1871    WRITE_UINT32(p_Fm->p_FmFpmRegs->fmrstc, bitMask);
1872    while ((GET_UINT32(p_Fm->p_FmFpmRegs->fmrstc) & bitMask) &&
1873           --timeout) ;
1874    if (!timeout)
1875        return ERROR_CODE(E_TIMEOUT);
1876    return E_OK;
1877}
1878
1879t_Error FmSetMacMaxFrame(t_Handle h_Fm, e_FmMacType type, uint8_t macId, uint16_t mtu)
1880{
1881    t_Fm                        *p_Fm = (t_Fm*)h_Fm;
1882    t_FmIpcMacMaxFrameParams    macMaxFrameLengthParams;
1883    t_Error                     err;
1884    t_FmIpcMsg                  msg;
1885
1886    if(p_Fm->guestId != NCSW_MASTER_ID)
1887    {
1888        memset(&msg, 0, sizeof(msg));
1889        macMaxFrameLengthParams.macParams.id = macId;
1890        macMaxFrameLengthParams.macParams.enumType = (uint32_t)type;
1891        macMaxFrameLengthParams.maxFrameLength = (uint16_t)mtu;
1892        msg.msgId = FM_SET_MAC_MAX_FRAME;
1893        memcpy(msg.msgBody,  &macMaxFrameLengthParams, sizeof(macMaxFrameLengthParams));
1894        if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
1895                                     (uint8_t*)&msg,
1896                                     sizeof(msg.msgId)+sizeof(macMaxFrameLengthParams),
1897                                     NULL,
1898                                     NULL,
1899                                     NULL,
1900                                     NULL)) != E_OK)
1901            RETURN_ERROR(MINOR, err, NO_MSG);
1902        return E_OK;
1903    }
1904
1905#if (defined(FM_MAX_NUM_OF_10G_MACS) && (FM_MAX_NUM_OF_10G_MACS))
1906    if (type == e_FM_MAC_10G)
1907        p_Fm->p_FmStateStruct->macMaxFrameLengths10G[macId] = mtu;
1908    else
1909#else
1910    UNUSED(type);
1911#endif /* (defined(FM_MAX_NUM_OF_10G_MACS) && ... */
1912        p_Fm->p_FmStateStruct->macMaxFrameLengths1G[macId] = mtu;
1913
1914    return E_OK;
1915}
1916
1917uint16_t FmGetClockFreq(t_Handle h_Fm)
1918{
1919    t_Fm *p_Fm = (t_Fm*)h_Fm;
1920    /* for MC environment: this depends on the
1921     * fact that fmClkFreq was properly initialized at "init". */
1922    return p_Fm->p_FmStateStruct->fmClkFreq;
1923}
1924
1925uint32_t FmGetTimeStampScale(t_Handle h_Fm)
1926{
1927    t_Fm                *p_Fm = (t_Fm*)h_Fm;
1928    t_Error             err;
1929    t_FmIpcMsg          msg;
1930    t_FmIpcReply        reply;
1931    uint32_t            replyLength, timeStamp;
1932
1933    if(p_Fm->guestId != NCSW_MASTER_ID)
1934    {
1935        memset(&msg, 0, sizeof(msg));
1936        memset(&reply, 0, sizeof(reply));
1937        msg.msgId = FM_GET_TIMESTAMP_SCALE;
1938        replyLength = sizeof(uint32_t) + sizeof(uint32_t);
1939        if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
1940                                     (uint8_t*)&msg,
1941                                     sizeof(msg.msgId),
1942                                     (uint8_t*)&reply,
1943                                     &replyLength,
1944                                     NULL,
1945                                     NULL)) != E_OK)
1946            RETURN_ERROR(MINOR, err, NO_MSG);
1947        if(replyLength != (sizeof(uint32_t) + sizeof(uint32_t)))
1948            RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
1949
1950        memcpy((uint8_t*)&timeStamp, reply.replyBody, sizeof(uint32_t));
1951        return timeStamp;
1952    }
1953
1954    if(!p_Fm->p_FmStateStruct->enabledTimeStamp)
1955        FmEnableTimeStamp(p_Fm);
1956
1957    return p_Fm->p_FmStateStruct->count1MicroBit;
1958}
1959
1960bool FmRamsEccIsExternalCtl(t_Handle h_Fm)
1961{
1962    t_Fm        *p_Fm = (t_Fm*)h_Fm;
1963    uint32_t    tmpReg;
1964
1965    tmpReg = GET_UINT32(p_Fm->p_FmFpmRegs->fmrcr);
1966    if(tmpReg & FPM_RAM_CTL_RAMS_ECC_EN_SRC_SEL)
1967        return TRUE;
1968    else
1969        return FALSE;
1970}
1971
1972t_Error FmEnableRamsEcc(t_Handle h_Fm)
1973{
1974    t_Fm        *p_Fm = (t_Fm*)h_Fm;
1975
1976    SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
1977
1978    p_Fm->p_FmStateStruct->ramsEccOwners++;
1979    p_Fm->p_FmStateStruct->internalCall = TRUE;
1980
1981    return FM_EnableRamsEcc(p_Fm);
1982}
1983
1984t_Error FmDisableRamsEcc(t_Handle h_Fm)
1985{
1986    t_Fm        *p_Fm = (t_Fm*)h_Fm;
1987
1988    SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
1989
1990    ASSERT_COND(p_Fm->p_FmStateStruct->ramsEccOwners);
1991    p_Fm->p_FmStateStruct->ramsEccOwners--;
1992
1993    if(p_Fm->p_FmStateStruct->ramsEccOwners==0)
1994    {
1995        p_Fm->p_FmStateStruct->internalCall = TRUE;
1996        return FM_DisableRamsEcc(p_Fm);
1997    }
1998    return E_OK;
1999}
2000
2001uint8_t FmGetGuestId(t_Handle h_Fm)
2002{
2003    t_Fm     *p_Fm = (t_Fm*)h_Fm;
2004
2005    return p_Fm->guestId;
2006}
2007
2008bool FmIsMaster(t_Handle h_Fm)
2009{
2010    t_Fm     *p_Fm = (t_Fm*)h_Fm;
2011
2012    return (p_Fm->guestId == NCSW_MASTER_ID);
2013}
2014
2015t_Error FmSetSizeOfFifo(t_Handle                            h_Fm,
2016                        uint8_t                             hardwarePortId,
2017                        e_FmPortType                        portType,
2018                        bool                                independentMode,
2019                        uint32_t                            *p_SizeOfFifo,
2020                        uint32_t                            extraSizeOfFifo,
2021                        uint8_t                             deqPipelineDepth,
2022                        t_FmInterModulePortRxPoolsParams    *p_RxPoolsParams,
2023                        bool                                initialConfig)
2024{
2025    t_Fm                    *p_Fm = (t_Fm*)h_Fm;
2026    uint8_t                 relativePortId;
2027    uint16_t                macMaxFrameLength = 0, oldVal;
2028    uint32_t                minFifoSizeRequired = 0, sizeOfFifo, tmpReg = 0;
2029    t_FmIpcPortFifoParams   fifoParams;
2030    t_Error                 err;
2031
2032    ASSERT_COND(IN_RANGE(1, hardwarePortId, 63));
2033    ASSERT_COND(initialConfig || p_RxPoolsParams);
2034
2035    if(p_Fm->guestId != NCSW_MASTER_ID)
2036    {
2037        t_FmIpcMsg          msg;
2038        t_FmIpcReply        reply;
2039        uint32_t            replyLength;
2040
2041        ASSERT_COND(p_RxPoolsParams);
2042
2043        memset(&fifoParams, 0, sizeof(fifoParams));
2044        fifoParams.rsrcParams.hardwarePortId = hardwarePortId;
2045        fifoParams.rsrcParams.val = *p_SizeOfFifo;
2046        fifoParams.rsrcParams.extra = extraSizeOfFifo;
2047        fifoParams.enumPortType = (uint32_t)portType;
2048        fifoParams.boolIndependentMode = (uint8_t)independentMode;
2049        fifoParams.deqPipelineDepth = deqPipelineDepth;
2050        fifoParams.numOfPools = p_RxPoolsParams->numOfPools;
2051        fifoParams.secondLargestBufSize = p_RxPoolsParams->secondLargestBufSize;
2052        fifoParams.largestBufSize = p_RxPoolsParams->largestBufSize;
2053        fifoParams.boolInitialConfig = (uint8_t)initialConfig;
2054
2055        memset(&msg, 0, sizeof(msg));
2056        memset(&reply, 0, sizeof(reply));
2057        msg.msgId = FM_SET_SIZE_OF_FIFO;
2058        memcpy(msg.msgBody, &fifoParams, sizeof(fifoParams));
2059        replyLength = sizeof(uint32_t) + sizeof(uint32_t);
2060        if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
2061                                     (uint8_t*)&msg,
2062                                     sizeof(msg.msgId) + sizeof(fifoParams),
2063                                     (uint8_t*)&reply,
2064                                     &replyLength,
2065                                     NULL,
2066                                     NULL)) != E_OK)
2067            RETURN_ERROR(MINOR, err, NO_MSG);
2068        if (replyLength != (sizeof(uint32_t) + sizeof(uint32_t)))
2069            RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
2070        memcpy((uint8_t*)p_SizeOfFifo, reply.replyBody, sizeof(uint32_t));
2071
2072        return (t_Error)(reply.error);
2073    }
2074    sizeOfFifo = *p_SizeOfFifo;
2075    /* if neseccary (cases where frame length is relevant), update sizeOfFifo field. */
2076    if((portType == e_FM_PORT_TYPE_TX) || ((portType == e_FM_PORT_TYPE_RX) && independentMode))
2077    {
2078        HW_PORT_ID_TO_SW_PORT_ID(relativePortId, hardwarePortId);
2079        ASSERT_COND(relativePortId < FM_MAX_NUM_OF_1G_MACS);
2080        macMaxFrameLength = p_Fm->p_FmStateStruct->macMaxFrameLengths1G[relativePortId];
2081    }
2082
2083#if (defined(FM_MAX_NUM_OF_10G_MACS) && (FM_MAX_NUM_OF_10G_MACS))
2084    if((portType == e_FM_PORT_TYPE_TX_10G) || ((portType == e_FM_PORT_TYPE_RX_10G)  && independentMode))
2085    {
2086        HW_PORT_ID_TO_SW_PORT_ID(relativePortId, hardwarePortId);
2087        ASSERT_COND(relativePortId < FM_MAX_NUM_OF_10G_MACS);
2088        macMaxFrameLength = p_Fm->p_FmStateStruct->macMaxFrameLengths10G[relativePortId];
2089    }
2090#endif /* (defined(FM_MAX_NUM_OF_10G_MACS) && ... */
2091
2092    /*************************/
2093    /*    TX PORTS           */
2094    /*************************/
2095    if((portType == e_FM_PORT_TYPE_TX) || (portType == e_FM_PORT_TYPE_TX_10G))
2096    {
2097        if(independentMode)
2098            minFifoSizeRequired = (uint32_t)((macMaxFrameLength % BMI_FIFO_UNITS ?
2099                                (macMaxFrameLength/BMI_FIFO_UNITS + 1) * BMI_FIFO_UNITS :
2100                                macMaxFrameLength) +
2101                                (3*BMI_FIFO_UNITS));
2102        else
2103            minFifoSizeRequired = (uint32_t)((macMaxFrameLength % BMI_FIFO_UNITS ?
2104                                   (macMaxFrameLength/BMI_FIFO_UNITS + 1) * BMI_FIFO_UNITS :
2105                                   macMaxFrameLength) +
2106                                   (deqPipelineDepth+3)*BMI_FIFO_UNITS);
2107    }
2108    /*************************/
2109    /*    RX IM PORTS        */
2110    /*************************/
2111    else if(((portType == e_FM_PORT_TYPE_RX) || (portType == e_FM_PORT_TYPE_RX_10G)) && independentMode)
2112        minFifoSizeRequired = (uint32_t)(((macMaxFrameLength % BMI_FIFO_UNITS) ?
2113                                         ((macMaxFrameLength/BMI_FIFO_UNITS + 1) * BMI_FIFO_UNITS) :
2114                                         macMaxFrameLength) +
2115                                         (4*BMI_FIFO_UNITS));
2116
2117    /* for Rx (non-Im) ports or OP, buffer pools are relevant for fifo size.
2118       If this routine is called as part of the "GetSet" routine, initialConfig is TRUE
2119       and these checks where done in the port routine.
2120       If it is called by an explicit user request ("SetSizeOfFifo"), than these parameters
2121       should be checked/updated */
2122    if(!initialConfig &&
2123      ((portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING) ||
2124      (((portType == e_FM_PORT_TYPE_RX) || (portType == e_FM_PORT_TYPE_RX_10G)) && !independentMode)))
2125    {
2126        if((portType == e_FM_PORT_TYPE_RX) || (portType == e_FM_PORT_TYPE_RX_10G))
2127        {
2128            /*************************/
2129            /*    RX non-IM PORTS    */
2130            /*************************/
2131#ifdef FM_FIFO_ALLOCATION_OLD_ALG
2132            t_FmRevisionInfo revInfo;
2133
2134            FM_GetRevision(p_Fm, &revInfo);
2135            if(revInfo.majorRev != 4)
2136                minFifoSizeRequired = (uint32_t)(((p_RxPoolsParams->largestBufSize % BMI_FIFO_UNITS) ?
2137                                        ((p_RxPoolsParams->largestBufSize/BMI_FIFO_UNITS + 1) * BMI_FIFO_UNITS) :
2138                                        p_RxPoolsParams->largestBufSize) +
2139                                        (7*BMI_FIFO_UNITS));
2140            else
2141#endif /* FM_FIFO_ALLOCATION_OLD_ALG */
2142            {
2143                if(p_RxPoolsParams->numOfPools == 1)
2144                    minFifoSizeRequired = 8*BMI_FIFO_UNITS;
2145                else
2146                {
2147                    minFifoSizeRequired = (uint32_t)(((p_RxPoolsParams->secondLargestBufSize % BMI_FIFO_UNITS) ?
2148                                        ((p_RxPoolsParams->secondLargestBufSize/BMI_FIFO_UNITS + 1) * BMI_FIFO_UNITS) :
2149                                        p_RxPoolsParams->secondLargestBufSize) +
2150                                        (7*BMI_FIFO_UNITS));
2151                    if((sizeOfFifo < minFifoSizeRequired))
2152                    {
2153                        DBG(WARNING, ("User set FIFO size for Rx port is not optimized. (not modified by driver)"));
2154                        minFifoSizeRequired = 8*BMI_FIFO_UNITS;
2155                    }
2156                }
2157            }
2158        }
2159        else
2160        {
2161            /*************************/
2162            /*    OP PORTS           */
2163            /*************************/
2164            /* check if pool size is not too big */
2165            if(p_RxPoolsParams->largestBufSize > sizeOfFifo )
2166                RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Largest pool size is bigger than ports committed fifo size"));
2167        }
2168    }
2169
2170
2171    if (minFifoSizeRequired && (sizeOfFifo < minFifoSizeRequired))
2172    {
2173        sizeOfFifo = minFifoSizeRequired;
2174        DBG(WARNING, ("FIFO size enlarged to %d for port %#x", minFifoSizeRequired, hardwarePortId));
2175    }
2176
2177    if(initialConfig)
2178        oldVal = 0;
2179    else
2180    {
2181        tmpReg = GET_UINT32(p_Fm->p_FmBmiRegs->fmbm_pfs[hardwarePortId-1]);
2182        /* read into oldVal the current extra fifo size */
2183        oldVal = (uint16_t)((((tmpReg & BMI_EXTRA_FIFO_SIZE_MASK) + 1)*BMI_FIFO_UNITS) >> BMI_EXTRA_FIFO_SIZE_SHIFT);
2184    }
2185
2186    if(extraSizeOfFifo > oldVal)
2187        p_Fm->p_FmStateStruct->extraFifoPoolSize = NCSW_MAX(p_Fm->p_FmStateStruct->extraFifoPoolSize, extraSizeOfFifo);
2188
2189    if(!initialConfig)
2190        /* read into oldVal the current num of tasks */
2191        oldVal = (uint16_t)(((tmpReg & BMI_FIFO_SIZE_MASK) + 1)*BMI_FIFO_UNITS);
2192
2193    /* check that there are enough uncommitted fifo size */
2194    if((p_Fm->p_FmStateStruct->accumulatedFifoSize - oldVal + sizeOfFifo) >
2195       (p_Fm->p_FmStateStruct->totalFifoSize - p_Fm->p_FmStateStruct->extraFifoPoolSize))
2196        RETURN_ERROR(MAJOR, E_NOT_AVAILABLE, ("Requested fifo size and extra size exceed total FIFO size."));
2197    else
2198    {
2199        /* update acummulated */
2200        ASSERT_COND(p_Fm->p_FmStateStruct->accumulatedFifoSize >= oldVal);
2201        p_Fm->p_FmStateStruct->accumulatedFifoSize -= oldVal;
2202        p_Fm->p_FmStateStruct->accumulatedFifoSize += sizeOfFifo;
2203        /* calculate reg */
2204        tmpReg = (uint32_t)((sizeOfFifo/BMI_FIFO_UNITS - 1) |
2205                            ((extraSizeOfFifo/BMI_FIFO_UNITS) << BMI_EXTRA_FIFO_SIZE_SHIFT));
2206        WRITE_UINT32(p_Fm->p_FmBmiRegs->fmbm_pfs[hardwarePortId-1], tmpReg);
2207    }
2208    *p_SizeOfFifo = sizeOfFifo;
2209
2210    return E_OK;
2211}
2212
2213t_Error FmSetNumOfTasks(t_Handle    h_Fm,
2214                        uint8_t     hardwarePortId,
2215                        uint8_t     numOfTasks,
2216                        uint8_t     numOfExtraTasks,
2217                        bool        initialConfig)
2218{
2219    t_Fm                    *p_Fm = (t_Fm *)h_Fm;
2220    uint8_t                 oldVal;
2221    uint32_t                tmpReg = 0;
2222    t_FmIpcPortRsrcParams   rsrcParams;
2223    t_Error                 err;
2224
2225    if(p_Fm->guestId != NCSW_MASTER_ID)
2226    {
2227        t_FmIpcMsg          msg;
2228        t_FmIpcReply        reply;
2229        uint32_t            replyLength;
2230
2231        rsrcParams.hardwarePortId = hardwarePortId;
2232        rsrcParams.val = numOfTasks;
2233        rsrcParams.extra = numOfExtraTasks;
2234        rsrcParams.boolInitialConfig = (uint8_t)initialConfig;
2235
2236        memset(&msg, 0, sizeof(msg));
2237        memset(&reply, 0, sizeof(reply));
2238        msg.msgId = FM_SET_NUM_OF_TASKS;
2239        memcpy(msg.msgBody, &rsrcParams, sizeof(rsrcParams));
2240        replyLength = sizeof(uint32_t);
2241        if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
2242                                     (uint8_t*)&msg,
2243                                     sizeof(msg.msgId) + sizeof(rsrcParams),
2244                                     (uint8_t*)&reply,
2245                                     &replyLength,
2246                                     NULL,
2247                                     NULL)) != E_OK)
2248            RETURN_ERROR(MINOR, err, NO_MSG);
2249        if (replyLength != sizeof(uint32_t))
2250            RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
2251        return (t_Error)(reply.error);
2252    }
2253
2254    ASSERT_COND(IN_RANGE(1, hardwarePortId, 63));
2255
2256    if(initialConfig)
2257        oldVal = 0;
2258    else
2259    {
2260        tmpReg = GET_UINT32(p_Fm->p_FmBmiRegs->fmbm_pp[hardwarePortId-1]);
2261        /* read into oldVal the current extra tasks */
2262        oldVal = (uint8_t)((tmpReg & BMI_NUM_OF_EXTRA_TASKS_MASK) >> BMI_EXTRA_NUM_OF_TASKS_SHIFT);
2263    }
2264
2265    if(numOfExtraTasks > oldVal)
2266        p_Fm->p_FmStateStruct->extraTasksPoolSize = (uint8_t)NCSW_MAX(p_Fm->p_FmStateStruct->extraTasksPoolSize, numOfExtraTasks);
2267
2268    if(!initialConfig)
2269        /* read into oldVal the current num of tasks */
2270        oldVal = (uint8_t)(((tmpReg & BMI_NUM_OF_TASKS_MASK) >> BMI_NUM_OF_TASKS_SHIFT) + 1);
2271
2272    /* check that there are enough uncommitted tasks */
2273    if((p_Fm->p_FmStateStruct->accumulatedNumOfTasks - oldVal + numOfTasks) >
2274       (p_Fm->p_FmStateStruct->totalNumOfTasks - p_Fm->p_FmStateStruct->extraTasksPoolSize))
2275        RETURN_ERROR(MAJOR, E_NOT_AVAILABLE,
2276                     ("Requested numOfTasks and extra tasks pool for fm%d exceed total numOfTasks.",
2277                      p_Fm->p_FmStateStruct->fmId));
2278    else
2279    {
2280        ASSERT_COND(p_Fm->p_FmStateStruct->accumulatedNumOfTasks >= oldVal);
2281        /* update acummulated */
2282        p_Fm->p_FmStateStruct->accumulatedNumOfTasks -= oldVal;
2283        p_Fm->p_FmStateStruct->accumulatedNumOfTasks += numOfTasks;
2284        /* calculate reg */
2285        tmpReg = GET_UINT32(p_Fm->p_FmBmiRegs->fmbm_pp[hardwarePortId-1]) & ~(BMI_NUM_OF_TASKS_MASK | BMI_NUM_OF_EXTRA_TASKS_MASK);
2286        tmpReg |= (uint32_t)(((numOfTasks-1) << BMI_NUM_OF_TASKS_SHIFT) |
2287                    (numOfExtraTasks << BMI_EXTRA_NUM_OF_TASKS_SHIFT));
2288        WRITE_UINT32(p_Fm->p_FmBmiRegs->fmbm_pp[hardwarePortId-1],tmpReg);
2289    }
2290
2291    return E_OK;
2292}
2293
2294t_Error FmSetNumOfOpenDmas(t_Handle h_Fm,
2295                            uint8_t hardwarePortId,
2296                            uint8_t numOfOpenDmas,
2297                            uint8_t numOfExtraOpenDmas,
2298                            bool    initialConfig)
2299
2300{
2301    t_Fm                    *p_Fm = (t_Fm *)h_Fm;
2302    uint8_t                 oldVal;
2303    uint32_t                tmpReg = 0;
2304    t_FmIpcPortRsrcParams   rsrcParams;
2305    t_Error                 err;
2306
2307    if(p_Fm->guestId != NCSW_MASTER_ID)
2308    {
2309        t_FmIpcMsg          msg;
2310        t_FmIpcReply        reply;
2311        uint32_t            replyLength;
2312
2313        rsrcParams.hardwarePortId = hardwarePortId;
2314        rsrcParams.val = numOfOpenDmas;
2315        rsrcParams.extra = numOfExtraOpenDmas;
2316        rsrcParams.boolInitialConfig = (uint8_t)initialConfig;
2317
2318        memset(&msg, 0, sizeof(msg));
2319        memset(&reply, 0, sizeof(reply));
2320        msg.msgId = FM_SET_NUM_OF_OPEN_DMAS;
2321        memcpy(msg.msgBody, &rsrcParams, sizeof(rsrcParams));
2322        replyLength = sizeof(uint32_t);
2323        if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
2324                                     (uint8_t*)&msg,
2325                                     sizeof(msg.msgId) + sizeof(rsrcParams),
2326                                     (uint8_t*)&reply,
2327                                     &replyLength,
2328                                     NULL,
2329                                     NULL)) != E_OK)
2330            RETURN_ERROR(MINOR, err, NO_MSG);
2331        if (replyLength != sizeof(uint32_t))
2332            RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
2333        return (t_Error)(reply.error);
2334    }
2335
2336    ASSERT_COND(IN_RANGE(1, hardwarePortId, 63));
2337
2338    if(initialConfig)
2339        oldVal = 0;
2340    else
2341    {
2342        tmpReg = GET_UINT32(p_Fm->p_FmBmiRegs->fmbm_pp[hardwarePortId-1]);
2343        /* read into oldVal the current extra tasks */
2344        oldVal = (uint8_t)((tmpReg & BMI_NUM_OF_EXTRA_DMAS_MASK) >> BMI_EXTRA_NUM_OF_DMAS_SHIFT);
2345    }
2346
2347    if(numOfExtraOpenDmas > oldVal)
2348        p_Fm->p_FmStateStruct->extraOpenDmasPoolSize = (uint8_t)NCSW_MAX(p_Fm->p_FmStateStruct->extraOpenDmasPoolSize, numOfExtraOpenDmas);
2349
2350    if(!initialConfig)
2351        /* read into oldVal the current num of tasks */
2352        oldVal = (uint8_t)(((tmpReg & BMI_NUM_OF_DMAS_MASK) >> BMI_NUM_OF_DMAS_SHIFT) + 1);
2353
2354    /* check that there are enough uncommitted open DMA's */
2355    ASSERT_COND(p_Fm->p_FmStateStruct->accumulatedNumOfOpenDmas >= oldVal);
2356    if((p_Fm->p_FmStateStruct->accumulatedNumOfOpenDmas - oldVal + numOfOpenDmas) >
2357       p_Fm->p_FmStateStruct->maxNumOfOpenDmas)
2358        RETURN_ERROR(MAJOR, E_NOT_AVAILABLE,
2359                     ("Requested numOfOpenDmas for fm%d exceeds total numOfOpenDmas.",
2360                      p_Fm->p_FmStateStruct->fmId));
2361    else
2362    {
2363        /* update acummulated */
2364        p_Fm->p_FmStateStruct->accumulatedNumOfOpenDmas -= oldVal;
2365        p_Fm->p_FmStateStruct->accumulatedNumOfOpenDmas += numOfOpenDmas;
2366        /* calculate reg */
2367        tmpReg = GET_UINT32(p_Fm->p_FmBmiRegs->fmbm_pp[hardwarePortId-1]) & ~(BMI_NUM_OF_DMAS_MASK | BMI_NUM_OF_EXTRA_DMAS_MASK);
2368        tmpReg |= (uint32_t)(((numOfOpenDmas-1) << BMI_NUM_OF_DMAS_SHIFT) |
2369                    (numOfExtraOpenDmas << BMI_EXTRA_NUM_OF_DMAS_SHIFT));
2370        WRITE_UINT32(p_Fm->p_FmBmiRegs->fmbm_pp[hardwarePortId-1], tmpReg);
2371
2372        /* update total num of DMA's with committed number of open DMAS, and max uncommitted pool. */
2373        tmpReg = GET_UINT32(p_Fm->p_FmBmiRegs->fmbm_cfg2) & ~BMI_CFG2_DMAS_MASK;
2374        tmpReg |= (uint32_t)(p_Fm->p_FmStateStruct->accumulatedNumOfOpenDmas + p_Fm->p_FmStateStruct->extraOpenDmasPoolSize - 1) << BMI_CFG2_DMAS_SHIFT;
2375        WRITE_UINT32(p_Fm->p_FmBmiRegs->fmbm_cfg2,  tmpReg);
2376    }
2377
2378    return E_OK;
2379}
2380
2381#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
2382t_Error FmDumpPortRegs (t_Handle h_Fm,uint8_t hardwarePortId)
2383{
2384    t_Fm            *p_Fm = (t_Fm *)h_Fm;
2385    t_FmIpcMsg      msg;
2386    t_Error         err;
2387
2388    DECLARE_DUMP;
2389
2390    if(p_Fm->guestId != NCSW_MASTER_ID)
2391    {
2392        memset(&msg, 0, sizeof(msg));
2393        msg.msgId = FM_DUMP_PORT_REGS;
2394        msg.msgBody[0] = hardwarePortId;
2395        if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
2396                                    (uint8_t*)&msg,
2397                                    sizeof(msg.msgId)+sizeof(hardwarePortId),
2398                                    NULL,
2399                                    NULL,
2400                                    NULL,
2401                                    NULL)) != E_OK)
2402            RETURN_ERROR(MINOR, err, NO_MSG);
2403        return E_OK;
2404    }
2405
2406    SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
2407
2408    DUMP_TITLE(&p_Fm->p_FmBmiRegs->fmbm_pp[hardwarePortId-1], ("fmbm_pp for port %u", (hardwarePortId)));
2409    DUMP_MEMORY(&p_Fm->p_FmBmiRegs->fmbm_pp[hardwarePortId-1], sizeof(uint32_t));
2410
2411    DUMP_TITLE(&p_Fm->p_FmBmiRegs->fmbm_pfs[hardwarePortId-1], ("fmbm_pfs for port %u", (hardwarePortId )));
2412    DUMP_MEMORY(&p_Fm->p_FmBmiRegs->fmbm_pfs[hardwarePortId-1], sizeof(uint32_t));
2413
2414    DUMP_TITLE(&p_Fm->p_FmBmiRegs->fmbm_ppid[hardwarePortId-1], ("bm_ppid for port %u", (hardwarePortId)));
2415    DUMP_MEMORY(&p_Fm->p_FmBmiRegs->fmbm_ppid[hardwarePortId-1], sizeof(uint32_t));
2416
2417    return E_OK;
2418}
2419#endif /* (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0)) */
2420
2421
2422/*****************************************************************************/
2423/*                      API Init unit functions                              */
2424/*****************************************************************************/
2425t_Handle FM_Config(t_FmParams *p_FmParam)
2426{
2427    t_Fm        *p_Fm;
2428    uint8_t     i;
2429    uintptr_t   baseAddr;
2430
2431    SANITY_CHECK_RETURN_VALUE(p_FmParam, E_NULL_POINTER, NULL);
2432    SANITY_CHECK_RETURN_VALUE(((p_FmParam->firmware.p_Code && p_FmParam->firmware.size) ||
2433                               (!p_FmParam->firmware.p_Code && !p_FmParam->firmware.size)),
2434                              E_INVALID_VALUE, NULL);
2435
2436    baseAddr = p_FmParam->baseAddr;
2437
2438    /* Allocate FM structure */
2439    p_Fm = (t_Fm *) XX_Malloc(sizeof(t_Fm));
2440    if (!p_Fm)
2441    {
2442        REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM driver structure"));
2443        return NULL;
2444    }
2445    memset(p_Fm, 0, sizeof(t_Fm));
2446
2447    p_Fm->p_FmStateStruct = (t_FmStateStruct *) XX_Malloc(sizeof(t_FmStateStruct));
2448    if (!p_Fm->p_FmStateStruct)
2449    {
2450        XX_Free(p_Fm);
2451        REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM Status structure"));
2452        return NULL;
2453    }
2454    memset(p_Fm->p_FmStateStruct, 0, sizeof(t_FmStateStruct));
2455
2456    /* Initialize FM parameters which will be kept by the driver */
2457    p_Fm->p_FmStateStruct->fmId = p_FmParam->fmId;
2458    p_Fm->guestId               = p_FmParam->guestId;
2459
2460    for(i=0; i<FM_MAX_NUM_OF_HW_PORT_IDS; i++)
2461        p_Fm->p_FmStateStruct->portsTypes[i] = e_FM_PORT_TYPE_DUMMY;
2462
2463    /* Allocate the FM driver's parameters structure */
2464    p_Fm->p_FmDriverParam = (t_FmDriverParam *)XX_Malloc(sizeof(t_FmDriverParam));
2465    if (!p_Fm->p_FmDriverParam)
2466    {
2467        XX_Free(p_Fm->p_FmStateStruct);
2468        XX_Free(p_Fm);
2469        REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM driver parameters"));
2470        return NULL;
2471    }
2472    memset(p_Fm->p_FmDriverParam, 0, sizeof(t_FmDriverParam));
2473
2474    /* Initialize FM parameters which will be kept by the driver */
2475    p_Fm->p_FmStateStruct->fmId              = p_FmParam->fmId;
2476    p_Fm->h_FmMuram         = p_FmParam->h_FmMuram;
2477    p_Fm->h_App             = p_FmParam->h_App;
2478    p_Fm->p_FmStateStruct->fmClkFreq         = p_FmParam->fmClkFreq;
2479    p_Fm->f_Exception       = p_FmParam->f_Exception;
2480    p_Fm->f_BusError        = p_FmParam->f_BusError;
2481    p_Fm->p_FmFpmRegs       = (t_FmFpmRegs *)UINT_TO_PTR(baseAddr + FM_MM_FPM);
2482    p_Fm->p_FmBmiRegs       = (t_FmBmiRegs *)UINT_TO_PTR(baseAddr + FM_MM_BMI);
2483    p_Fm->p_FmQmiRegs       = (t_FmQmiRegs *)UINT_TO_PTR(baseAddr + FM_MM_QMI);
2484    p_Fm->p_FmDmaRegs       = (t_FmDmaRegs *)UINT_TO_PTR(baseAddr + FM_MM_DMA);
2485    p_Fm->baseAddr          = baseAddr;
2486    p_Fm->p_FmStateStruct->irq               = p_FmParam->irq;
2487    p_Fm->p_FmStateStruct->errIrq            = p_FmParam->errIrq;
2488    p_Fm->hcPortInitialized = FALSE;
2489    p_Fm->independentMode   = FALSE;
2490    p_Fm->p_FmStateStruct->ramsEccEnable     = FALSE;
2491    p_Fm->p_FmStateStruct->totalNumOfTasks   = DEFAULT_totalNumOfTasks;
2492    p_Fm->p_FmStateStruct->totalFifoSize     = DEFAULT_totalFifoSize;
2493    p_Fm->p_FmStateStruct->maxNumOfOpenDmas  = DEFAULT_maxNumOfOpenDmas;
2494    p_Fm->p_FmStateStruct->extraFifoPoolSize = FM_MAX_NUM_OF_RX_PORTS*BMI_FIFO_UNITS;
2495    p_Fm->p_FmStateStruct->exceptions        = DEFAULT_exceptions;
2496    for(i = 0;i<FM_MAX_NUM_OF_1G_MACS;i++)
2497        p_Fm->p_FmStateStruct->macMaxFrameLengths1G[i] = DEFAULT_mtu;
2498#if defined(FM_MAX_NUM_OF_10G_MACS) && (FM_MAX_NUM_OF_10G_MACS)
2499    for(i = 0;i<FM_MAX_NUM_OF_10G_MACS;i++)
2500        p_Fm->p_FmStateStruct->macMaxFrameLengths10G[i] = DEFAULT_mtu;
2501#endif /*defined(FM_MAX_NUM_OF_10G_MACS) && (FM_MAX_NUM_OF_10G_MACS)*/
2502
2503    p_Fm->h_Spinlock = XX_InitSpinlock();
2504    if (!p_Fm->h_Spinlock)
2505    {
2506        XX_Free(p_Fm->p_FmDriverParam);
2507        XX_Free(p_Fm->p_FmStateStruct);
2508        XX_Free(p_Fm);
2509        REPORT_ERROR(MAJOR, E_INVALID_STATE, ("cant allocate spinlock!"));
2510        return NULL;
2511    }
2512
2513#ifdef FM_PARTITION_ARRAY
2514    /* Initialize FM driver parameters parameters (for initialization phase only) */
2515    memcpy(p_Fm->p_FmDriverParam->liodnBasePerPort, p_FmParam->liodnBasePerPort, FM_SIZE_OF_LIODN_TABLE*sizeof(uint16_t));
2516#endif /* FM_PARTITION_ARRAY */
2517
2518    /*p_Fm->p_FmDriverParam->numOfPartitions                      = p_FmParam->numOfPartitions;    */
2519    p_Fm->p_FmDriverParam->enCounters                           = FALSE;
2520
2521    p_Fm->p_FmDriverParam->resetOnInit                          = DEFAULT_resetOnInit;
2522
2523    p_Fm->p_FmDriverParam->thresholds.dispLimit                 = DEFAULT_dispLimit;
2524    p_Fm->p_FmDriverParam->thresholds.prsDispTh                 = DEFAULT_prsDispTh;
2525    p_Fm->p_FmDriverParam->thresholds.plcrDispTh                = DEFAULT_plcrDispTh;
2526    p_Fm->p_FmDriverParam->thresholds.kgDispTh                  = DEFAULT_kgDispTh;
2527    p_Fm->p_FmDriverParam->thresholds.bmiDispTh                 = DEFAULT_bmiDispTh;
2528    p_Fm->p_FmDriverParam->thresholds.qmiEnqDispTh              = DEFAULT_qmiEnqDispTh;
2529    p_Fm->p_FmDriverParam->thresholds.qmiDeqDispTh              = DEFAULT_qmiDeqDispTh;
2530    p_Fm->p_FmDriverParam->thresholds.fmCtl1DispTh              = DEFAULT_fmCtl1DispTh;
2531    p_Fm->p_FmDriverParam->thresholds.fmCtl2DispTh              = DEFAULT_fmCtl2DispTh;
2532
2533    p_Fm->p_FmDriverParam->dmaStopOnBusError                    = DEFAULT_dmaStopOnBusError;
2534
2535    p_Fm->p_FmDriverParam->dmaCacheOverride                     = DEFAULT_cacheOverride;
2536    p_Fm->p_FmDriverParam->dmaAidMode                           = DEFAULT_aidMode;
2537    p_Fm->p_FmDriverParam->dmaAidOverride                       = DEFAULT_aidOverride;
2538    p_Fm->p_FmDriverParam->dmaAxiDbgNumOfBeats                  = DEFAULT_axiDbgNumOfBeats;
2539    p_Fm->p_FmDriverParam->dmaCamNumOfEntries                   = DEFAULT_dmaCamNumOfEntries;
2540    p_Fm->p_FmDriverParam->dmaWatchdog                          = DEFAULT_dmaWatchdog;
2541
2542    p_Fm->p_FmDriverParam->dmaCommQThresholds.clearEmergency        = DEFAULT_dmaCommQLow;
2543    p_Fm->p_FmDriverParam->dmaCommQThresholds.assertEmergency       = DEFAULT_dmaCommQHigh;
2544    p_Fm->p_FmDriverParam->dmaReadBufThresholds.clearEmergency      = DEFAULT_dmaReadIntBufLow;
2545    p_Fm->p_FmDriverParam->dmaReadBufThresholds.assertEmergency     = DEFAULT_dmaReadIntBufHigh;
2546    p_Fm->p_FmDriverParam->dmaWriteBufThresholds.clearEmergency     = DEFAULT_dmaWriteIntBufLow;
2547    p_Fm->p_FmDriverParam->dmaWriteBufThresholds.assertEmergency    = DEFAULT_dmaWriteIntBufHigh;
2548    p_Fm->p_FmDriverParam->dmaSosEmergency                          = DEFAULT_dmaSosEmergency;
2549
2550    p_Fm->p_FmDriverParam->dmaDbgCntMode                        = DEFAULT_dmaDbgCntMode;
2551
2552    p_Fm->p_FmDriverParam->dmaEnEmergency                       = FALSE;
2553    p_Fm->p_FmDriverParam->dmaEnEmergencySmoother               = FALSE;
2554    p_Fm->p_FmDriverParam->catastrophicErr                      = DEFAULT_catastrophicErr;
2555    p_Fm->p_FmDriverParam->dmaErr                               = DEFAULT_dmaErr;
2556    p_Fm->p_FmDriverParam->haltOnExternalActivation             = DEFAULT_haltOnExternalActivation;
2557    p_Fm->p_FmDriverParam->haltOnUnrecoverableEccError          = DEFAULT_haltOnUnrecoverableEccError;
2558    p_Fm->p_FmDriverParam->enIramTestMode                       = FALSE;
2559    p_Fm->p_FmDriverParam->enMuramTestMode                      = FALSE;
2560    p_Fm->p_FmDriverParam->externalEccRamsEnable                = DEFAULT_externalEccRamsEnable;
2561
2562    p_Fm->p_FmDriverParam->fwVerify                             = DEFAULT_VerifyUcode;
2563    p_Fm->p_FmDriverParam->firmware.size                        = p_FmParam->firmware.size;
2564    if (p_Fm->p_FmDriverParam->firmware.size)
2565    {
2566        p_Fm->p_FmDriverParam->firmware.p_Code = (uint32_t *)XX_Malloc(p_Fm->p_FmDriverParam->firmware.size);
2567        if (!p_Fm->p_FmDriverParam->firmware.p_Code)
2568        {
2569            XX_FreeSpinlock(p_Fm->h_Spinlock);
2570            XX_Free(p_Fm->p_FmStateStruct);
2571            XX_Free(p_Fm->p_FmDriverParam);
2572            XX_Free(p_Fm);
2573            REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM firmware code"));
2574            return NULL;
2575        }
2576        memcpy(p_Fm->p_FmDriverParam->firmware.p_Code, p_FmParam->firmware.p_Code, p_Fm->p_FmDriverParam->firmware.size);
2577    }
2578
2579    return p_Fm;
2580}
2581
2582/**************************************************************************//**
2583 @Function      FM_Init
2584
2585 @Description   Initializes the FM module
2586
2587 @Param[in]     h_Fm - FM module descriptor
2588
2589 @Return        E_OK on success; Error code otherwise.
2590*//***************************************************************************/
2591t_Error FM_Init(t_Handle h_Fm)
2592{
2593    t_Fm                    *p_Fm = (t_Fm*)h_Fm;
2594    t_FmDriverParam         *p_FmDriverParam = NULL;
2595    t_Error                 err = E_OK;
2596    uint32_t                tmpReg, cfgReg = 0;
2597    int                     i;
2598    uint16_t                periodInFmClocks;
2599    uint8_t                 remainder;
2600    t_FmRevisionInfo        revInfo;
2601
2602    SANITY_CHECK_RETURN_ERROR(h_Fm, E_INVALID_HANDLE);
2603
2604    if(p_Fm->guestId != NCSW_MASTER_ID)
2605    {
2606        uint8_t             isMasterAlive;
2607        t_FmIpcMsg          msg;
2608        t_FmIpcReply        reply;
2609        uint32_t            replyLength;
2610
2611        /* build the FM guest partition IPC address */
2612        if(Sprint (p_Fm->fmModuleName, "FM_%d_%d",p_Fm->p_FmStateStruct->fmId, p_Fm->guestId) != (p_Fm->guestId<10 ? 6:7))
2613            RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Sprint failed"));
2614
2615        /* build the FM master partition IPC address */
2616        memset(p_Fm->fmIpcHandlerModuleName, 0, (sizeof(char)) * MODULE_NAME_SIZE);
2617        if(Sprint (p_Fm->fmIpcHandlerModuleName[0], "FM_%d_%d",p_Fm->p_FmStateStruct->fmId, NCSW_MASTER_ID) != 6)
2618            RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Sprint failed"));
2619
2620        for(i=0;i<e_FM_EV_DUMMY_LAST;i++)
2621            p_Fm->intrMng[i].f_Isr = UnimplementedIsr;
2622
2623        p_Fm->h_IpcSessions[0] = XX_IpcInitSession(p_Fm->fmIpcHandlerModuleName[0], p_Fm->fmModuleName);
2624        if (p_Fm->h_IpcSessions[0])
2625        {
2626            err = XX_IpcRegisterMsgHandler(p_Fm->fmModuleName, FmGuestHandleIpcMsgCB, p_Fm, FM_IPC_MAX_REPLY_SIZE);
2627            if(err)
2628                RETURN_ERROR(MAJOR, err, NO_MSG);
2629
2630            memset(&msg, 0, sizeof(msg));
2631            memset(&reply, 0, sizeof(reply));
2632            msg.msgId = FM_MASTER_IS_ALIVE;
2633            msg.msgBody[0] = p_Fm->guestId;
2634            replyLength = sizeof(uint32_t) + sizeof(uint8_t);
2635            do
2636            {
2637                blockingFlag = TRUE;
2638                if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
2639                                             (uint8_t*)&msg,
2640                                             sizeof(msg.msgId)+sizeof(p_Fm->guestId),
2641                                             (uint8_t*)&reply,
2642                                             &replyLength,
2643                                             IpcMsgCompletionCB,
2644                                             h_Fm)) != E_OK)
2645                    REPORT_ERROR(MINOR, err, NO_MSG);
2646                while(blockingFlag) ;
2647                if(replyLength != (sizeof(uint32_t) + sizeof(uint8_t)))
2648                    REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
2649                isMasterAlive = *(uint8_t*)(reply.replyBody);
2650            } while (!isMasterAlive);
2651
2652            memset(&msg, 0, sizeof(msg));
2653            memset(&reply, 0, sizeof(reply));
2654            msg.msgId = FM_GET_CLK_FREQ;
2655            replyLength = sizeof(uint32_t) + sizeof(p_Fm->p_FmStateStruct->fmClkFreq);
2656            if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
2657                                         (uint8_t*)&msg,
2658                                         sizeof(msg.msgId),
2659                                         (uint8_t*)&reply,
2660                                         &replyLength,
2661                                         NULL,
2662                                         NULL)) != E_OK)
2663                RETURN_ERROR(MAJOR, err, NO_MSG);
2664            if(replyLength != (sizeof(uint32_t) + sizeof(p_Fm->p_FmStateStruct->fmClkFreq)))
2665                RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
2666            memcpy((uint8_t*)&p_Fm->p_FmStateStruct->fmClkFreq, reply.replyBody, sizeof(uint16_t));
2667        }
2668        else
2669        {
2670            DBG(WARNING, ("FM Guest mode - without IPC"));
2671            if(!p_Fm->p_FmStateStruct->fmClkFreq )
2672                RETURN_ERROR(MAJOR, E_INVALID_STATE, ("No fmClkFreq configured for guest without IPC"));
2673            if(!p_Fm->baseAddr)
2674                RETURN_ERROR(MAJOR, E_INVALID_STATE, ("No baseAddr configured for guest without IPC"));
2675        }
2676
2677        XX_Free(p_Fm->p_FmDriverParam);
2678        p_Fm->p_FmDriverParam = NULL;
2679
2680        if ((p_Fm->guestId == NCSW_MASTER_ID) ||
2681            (p_Fm->h_IpcSessions[0]))
2682        {
2683            FM_DisableRamsEcc(p_Fm);
2684            FmMuramClear(p_Fm->h_FmMuram);
2685            FM_EnableRamsEcc(p_Fm);
2686        }
2687
2688        return E_OK;
2689    }
2690
2691    SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
2692
2693    FM_GetRevision(p_Fm, &revInfo);
2694
2695#ifdef FM_NO_DISPATCH_RAM_ECC
2696    if (revInfo.majorRev != 4)
2697        p_Fm->p_FmStateStruct->exceptions &= ~FM_EX_BMI_DISPATCH_RAM_ECC;
2698#endif /* FM_NO_DISPATCH_RAM_ECC */
2699
2700#ifdef FM_RAM_LIST_ERR_IRQ_ERRATA_FMAN8
2701    if ((revInfo.majorRev == 1) && (revInfo.minorRev == 0))
2702        p_Fm->p_FmStateStruct->exceptions  &= ~FM_EX_BMI_LIST_RAM_ECC;
2703#endif   /* FM_RAM_LIST_ERR_IRQ_ERRATA_FMAN8 */
2704
2705#ifdef FM_BMI_PIPELINE_ERR_IRQ_ERRATA_FMAN9
2706    if ((revInfo.majorRev == 1) && (revInfo.minorRev == 0))
2707        p_Fm->p_FmStateStruct->exceptions  &= ~FM_EX_BMI_PIPELINE_ECC;
2708#endif /* FM_BMI_PIPELINE_ERR_IRQ_ERRATA_FMAN9 */
2709
2710#ifdef FM_QMI_NO_ECC_EXCEPTIONS
2711    if (revInfo.majorRev == 4)
2712        p_Fm->p_FmStateStruct->exceptions  &= ~(FM_EX_QMI_SINGLE_ECC | FM_EX_QMI_DOUBLE_ECC);
2713#endif /* FM_QMI_NO_ECC_EXCEPTIONS */
2714
2715    CHECK_INIT_PARAMETERS(p_Fm, CheckFmParameters);
2716
2717    p_FmDriverParam = p_Fm->p_FmDriverParam;
2718
2719    FmMuramClear(p_Fm->h_FmMuram);
2720
2721#ifdef FM_UCODE_NOT_RESET_ERRATA_BUGZILLA6173
2722    if (p_FmDriverParam->resetOnInit)
2723    {
2724        t_FMIramRegs    *p_Iram = (t_FMIramRegs *)UINT_TO_PTR(p_Fm->baseAddr + FM_MM_IMEM);
2725        uint32_t        debug_reg;
2726
2727        /* write to IRAM first location the debug instruction */
2728        WRITE_UINT32(p_Iram->iadd, 0);
2729        while (GET_UINT32(p_Iram->iadd) != 0) ;
2730        WRITE_UINT32(p_Iram->idata, FM_UCODE_DEBUG_INSTRUCTION);
2731
2732        WRITE_UINT32(p_Iram->iadd, 0);
2733        while (GET_UINT32(p_Iram->iadd) != 0) ;
2734        while (GET_UINT32(p_Iram->idata) != FM_UCODE_DEBUG_INSTRUCTION) ;
2735
2736        /* Enable patch from IRAM */
2737        WRITE_UINT32(p_Iram->iready, IRAM_READY);
2738        XX_UDelay(100);
2739
2740        /* reset FMAN */
2741        WRITE_UINT32(p_Fm->p_FmFpmRegs->fmrstc, FPM_RSTC_FM_RESET);
2742        XX_UDelay(100);
2743
2744        /* verify breakpoint debug status register */
2745        debug_reg = GET_UINT32(*(uint32_t *)UINT_TO_PTR(p_Fm->baseAddr + FM_DEBUG_STATUS_REGISTER_OFFSET));
2746#ifndef NCSW_LINUX
2747        if(!debug_reg)
2748            RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Invalid debug status register value = 0"));
2749#else
2750        if(!debug_reg)
2751            DBG(INFO,("Invalid debug status register value = 0"));
2752#endif
2753        /*************************************/
2754        /* Load FMan-Controller code to Iram */
2755        /*************************************/
2756        if (ClearIRam(p_Fm) != E_OK)
2757            RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
2758        if (p_Fm->p_FmDriverParam->firmware.p_Code &&
2759            (LoadFmanCtrlCode(p_Fm) != E_OK))
2760            RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
2761         XX_UDelay(100);
2762
2763        /* reset FMAN again to start the microcode */
2764        WRITE_UINT32(p_Fm->p_FmFpmRegs->fmrstc, FPM_RSTC_FM_RESET);
2765        XX_UDelay(1000);
2766    }
2767    else
2768    {
2769#endif /* FM_UCODE_NOT_RESET_ERRATA_BUGZILLA6173 */
2770    if(p_FmDriverParam->resetOnInit)
2771    {
2772        WRITE_UINT32(p_Fm->p_FmFpmRegs->fmrstc, FPM_RSTC_FM_RESET);
2773        XX_UDelay(100);
2774    }
2775
2776    /*************************************/
2777    /* Load FMan-Controller code to Iram */
2778    /*************************************/
2779    if (ClearIRam(p_Fm) != E_OK)
2780        RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
2781    if (p_Fm->p_FmDriverParam->firmware.p_Code &&
2782        (LoadFmanCtrlCode(p_Fm) != E_OK))
2783        RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
2784#ifdef FM_UCODE_NOT_RESET_ERRATA_BUGZILLA6173
2785    }
2786#endif /* FM_UCODE_NOT_RESET_ERRATA_BUGZILLA6173 */
2787
2788#ifdef FM_CAPWAP_SUPPORT
2789    /* save first 256 byte in MURAM */
2790    p_Fm->resAddr = PTR_TO_UINT(FM_MURAM_AllocMem(p_Fm->h_FmMuram, 256, 0));
2791    if (!p_Fm->resAddr)
2792        RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM alloc for reserved Area failed"));
2793
2794    WRITE_BLOCK(UINT_TO_PTR(p_Fm->resAddr), 0, 256);
2795#endif /* FM_CAPWAP_SUPPORT */
2796
2797    /* General FM driver initialization */
2798    p_Fm->fmMuramPhysBaseAddr = (uint64_t)(XX_VirtToPhys(UINT_TO_PTR(p_Fm->baseAddr + FM_MM_MURAM)));
2799    for(i=0;i<e_FM_EV_DUMMY_LAST;i++)
2800        p_Fm->intrMng[i].f_Isr = UnimplementedIsr;
2801    for(i=0;i<FM_NUM_OF_FMAN_CTRL_EVENT_REGS;i++)
2802        p_Fm->fmanCtrlIntr[i].f_Isr = UnimplementedFmanCtrlIsr;
2803
2804    /**********************/
2805    /* Init DMA Registers */
2806    /**********************/
2807    /* clear status reg events */
2808    tmpReg = (DMA_STATUS_BUS_ERR | DMA_STATUS_READ_ECC | DMA_STATUS_SYSTEM_WRITE_ECC | DMA_STATUS_FM_WRITE_ECC);
2809    /*tmpReg |= (DMA_STATUS_SYSTEM_DPEXT_ECC | DMA_STATUS_FM_DPEXT_ECC | DMA_STATUS_SYSTEM_DPDAT_ECC | DMA_STATUS_FM_DPDAT_ECC | DMA_STATUS_FM_SPDAT_ECC);*/
2810    WRITE_UINT32(p_Fm->p_FmDmaRegs->fmdmsr, GET_UINT32(p_Fm->p_FmDmaRegs->fmdmsr) | tmpReg);
2811
2812    /* configure mode register */
2813    tmpReg = 0;
2814    tmpReg |= p_FmDriverParam->dmaCacheOverride << DMA_MODE_CACHE_OR_SHIFT;
2815    if(p_FmDriverParam->dmaAidOverride)
2816        tmpReg |= DMA_MODE_AID_OR;
2817    if (p_Fm->p_FmStateStruct->exceptions & FM_EX_DMA_BUS_ERROR)
2818        tmpReg |= DMA_MODE_BER;
2819    if ((p_Fm->p_FmStateStruct->exceptions & FM_EX_DMA_SYSTEM_WRITE_ECC) | (p_Fm->p_FmStateStruct->exceptions & FM_EX_DMA_READ_ECC) | (p_Fm->p_FmStateStruct->exceptions & FM_EX_DMA_FM_WRITE_ECC))
2820        tmpReg |= DMA_MODE_ECC;
2821    if(p_FmDriverParam->dmaStopOnBusError)
2822        tmpReg |= DMA_MODE_SBER;
2823    tmpReg |= (uint32_t)(p_FmDriverParam->dmaAxiDbgNumOfBeats - 1) << DMA_MODE_AXI_DBG_SHIFT;
2824    if (p_FmDriverParam->dmaEnEmergency)
2825    {
2826        tmpReg |= p_FmDriverParam->dmaEmergency.emergencyBusSelect;
2827        tmpReg |= p_FmDriverParam->dmaEmergency.emergencyLevel << DMA_MODE_EMERGENCY_LEVEL_SHIFT;
2828        if(p_FmDriverParam->dmaEnEmergencySmoother)
2829            WRITE_UINT32(p_Fm->p_FmDmaRegs->fmdmemsr, p_FmDriverParam->dmaEmergencySwitchCounter);
2830     }
2831    tmpReg |= ((p_FmDriverParam->dmaCamNumOfEntries/DMA_CAM_UNITS) - 1) << DMA_MODE_CEN_SHIFT;
2832
2833    tmpReg |= DMA_MODE_SECURE_PROT;
2834    tmpReg |= p_FmDriverParam->dmaDbgCntMode << DMA_MODE_DBG_SHIFT;
2835    tmpReg |= p_FmDriverParam->dmaAidMode << DMA_MODE_AID_MODE_SHIFT;
2836
2837#ifdef FM_PEDANTIC_DMA
2838    tmpReg |= DMA_MODE_EMERGENCY_READ;
2839#endif /* FM_PEDANTIC_DMA */
2840
2841    WRITE_UINT32(p_Fm->p_FmDmaRegs->fmdmmr, tmpReg);
2842
2843    /* configure thresholds register */
2844    tmpReg = ((uint32_t)p_FmDriverParam->dmaCommQThresholds.assertEmergency << DMA_THRESH_COMMQ_SHIFT) |
2845                ((uint32_t)p_FmDriverParam->dmaReadBufThresholds.assertEmergency << DMA_THRESH_READ_INT_BUF_SHIFT) |
2846                ((uint32_t)p_FmDriverParam->dmaWriteBufThresholds.assertEmergency);
2847    WRITE_UINT32(p_Fm->p_FmDmaRegs->fmdmtr, tmpReg);
2848
2849    /* configure hysteresis register */
2850    tmpReg = ((uint32_t)p_FmDriverParam->dmaCommQThresholds.clearEmergency << DMA_THRESH_COMMQ_SHIFT) |
2851                ((uint32_t)p_FmDriverParam->dmaReadBufThresholds.clearEmergency << DMA_THRESH_READ_INT_BUF_SHIFT) |
2852                ((uint32_t)p_FmDriverParam->dmaWriteBufThresholds.clearEmergency);
2853    WRITE_UINT32(p_Fm->p_FmDmaRegs->fmdmhy, tmpReg);
2854
2855    /* configure emergency threshold */
2856    WRITE_UINT32(p_Fm->p_FmDmaRegs->fmdmsetr, p_FmDriverParam->dmaSosEmergency);
2857
2858    /* configure Watchdog */
2859    WRITE_UINT32(p_Fm->p_FmDmaRegs->fmdmwcr, USEC_TO_CLK(p_FmDriverParam->dmaWatchdog, p_Fm->p_FmStateStruct->fmClkFreq));
2860
2861    /* Allocate MURAM for CAM */
2862    p_Fm->camBaseAddr = PTR_TO_UINT(FM_MURAM_AllocMem(p_Fm->h_FmMuram,
2863                                                      (uint32_t)(p_FmDriverParam->dmaCamNumOfEntries*DMA_CAM_SIZEOF_ENTRY),
2864                                                      DMA_CAM_ALIGN));
2865    if (!p_Fm->camBaseAddr )
2866        RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM alloc for DMA CAM failed"));
2867
2868    WRITE_BLOCK(UINT_TO_PTR(p_Fm->camBaseAddr), 0, (uint32_t)(p_FmDriverParam->dmaCamNumOfEntries*DMA_CAM_SIZEOF_ENTRY));
2869
2870    /* VirtToPhys */
2871    WRITE_UINT32(p_Fm->p_FmDmaRegs->fmdmebcr,
2872                 (uint32_t)(XX_VirtToPhys(UINT_TO_PTR(p_Fm->camBaseAddr)) - p_Fm->fmMuramPhysBaseAddr));
2873
2874#ifdef FM_PARTITION_ARRAY
2875    {
2876        t_FmRevisionInfo revInfo;
2877        FM_GetRevision(p_Fm, &revInfo);
2878        if ((revInfo.majorRev == 1) && (revInfo.minorRev == 0))
2879            /* liodn-partitions */
2880            for (i=0 ; i<FM_SIZE_OF_LIODN_TABLE ; i+=2)
2881            {
2882                tmpReg = (((uint32_t)p_FmDriverParam->liodnBasePerPort[i] << DMA_LIODN_SHIFT) |
2883                            (uint32_t)p_FmDriverParam->liodnBasePerPort[i+1]);
2884                WRITE_UINT32(p_Fm->p_FmDmaRegs->fmdmplr[i/2], tmpReg);
2885            }
2886    }
2887#endif /* FM_PARTITION_ARRAY */
2888
2889    /**********************/
2890    /* Init FPM Registers */
2891    /**********************/
2892    tmpReg = (uint32_t)(p_FmDriverParam->thresholds.dispLimit << FPM_DISP_LIMIT_SHIFT);
2893    WRITE_UINT32(p_Fm->p_FmFpmRegs->fpmflc, tmpReg);
2894
2895    tmpReg =   (((uint32_t)p_FmDriverParam->thresholds.prsDispTh  << FPM_THR1_PRS_SHIFT) |
2896                ((uint32_t)p_FmDriverParam->thresholds.kgDispTh  << FPM_THR1_KG_SHIFT) |
2897                ((uint32_t)p_FmDriverParam->thresholds.plcrDispTh  << FPM_THR1_PLCR_SHIFT) |
2898                ((uint32_t)p_FmDriverParam->thresholds.bmiDispTh  << FPM_THR1_BMI_SHIFT));
2899    WRITE_UINT32(p_Fm->p_FmFpmRegs->fpmdis1, tmpReg);
2900
2901    tmpReg =   (((uint32_t)p_FmDriverParam->thresholds.qmiEnqDispTh  << FPM_THR2_QMI_ENQ_SHIFT) |
2902                ((uint32_t)p_FmDriverParam->thresholds.qmiDeqDispTh  << FPM_THR2_QMI_DEQ_SHIFT) |
2903                ((uint32_t)p_FmDriverParam->thresholds.fmCtl1DispTh  << FPM_THR2_FM_CTL1_SHIFT) |
2904                ((uint32_t)p_FmDriverParam->thresholds.fmCtl2DispTh  << FPM_THR2_FM_CTL2_SHIFT));
2905    WRITE_UINT32(p_Fm->p_FmFpmRegs->fpmdis2, tmpReg);
2906
2907    /* define exceptions and error behavior */
2908    tmpReg = 0;
2909    /* Clear events */
2910    tmpReg |= (FPM_EV_MASK_STALL | FPM_EV_MASK_DOUBLE_ECC | FPM_EV_MASK_SINGLE_ECC);
2911    /* enable interrupts */
2912    if(p_Fm->p_FmStateStruct->exceptions & FM_EX_FPM_STALL_ON_TASKS)
2913        tmpReg |= FPM_EV_MASK_STALL_EN;
2914    if(p_Fm->p_FmStateStruct->exceptions & FM_EX_FPM_SINGLE_ECC)
2915        tmpReg |= FPM_EV_MASK_SINGLE_ECC_EN;
2916    if(p_Fm->p_FmStateStruct->exceptions & FM_EX_FPM_DOUBLE_ECC)
2917        tmpReg |= FPM_EV_MASK_DOUBLE_ECC_EN;
2918    tmpReg |= (p_Fm->p_FmDriverParam->catastrophicErr  << FPM_EV_MASK_CAT_ERR_SHIFT);
2919    tmpReg |= (p_Fm->p_FmDriverParam->dmaErr << FPM_EV_MASK_DMA_ERR_SHIFT);
2920    if(!p_Fm->p_FmDriverParam->haltOnExternalActivation)
2921        tmpReg |= FPM_EV_MASK_EXTERNAL_HALT;
2922    if(!p_Fm->p_FmDriverParam->haltOnUnrecoverableEccError)
2923        tmpReg |= FPM_EV_MASK_ECC_ERR_HALT;
2924    WRITE_UINT32(p_Fm->p_FmFpmRegs->fpmem, tmpReg);
2925
2926    /* clear all fmCtls event registers */
2927    for(i=0;i<FM_NUM_OF_FMAN_CTRL_EVENT_REGS;i++)
2928        WRITE_UINT32(p_Fm->p_FmFpmRegs->fpmcev[i], 0xFFFFFFFF);
2929
2930    /* RAM ECC -  enable and clear events*/
2931    /* first we need to clear all parser memory, as it is uninitialized and
2932    may cause ECC errors */
2933    tmpReg = 0;
2934    /* event bits */
2935    tmpReg = (FPM_RAM_CTL_MURAM_ECC | FPM_RAM_CTL_IRAM_ECC);
2936    /* Rams enable is not effected by the RCR bit, but by a COP configuration */
2937    if(p_Fm->p_FmDriverParam->externalEccRamsEnable)
2938        tmpReg |= FPM_RAM_CTL_RAMS_ECC_EN_SRC_SEL;
2939
2940    /* enable test mode */
2941    if(p_FmDriverParam->enMuramTestMode)
2942        tmpReg |= FPM_RAM_CTL_MURAM_TEST_ECC;
2943    if(p_FmDriverParam->enIramTestMode)
2944        tmpReg |= FPM_RAM_CTL_IRAM_TEST_ECC;
2945    WRITE_UINT32(p_Fm->p_FmFpmRegs->fmrcr, tmpReg);
2946
2947    tmpReg = 0;
2948    if(p_Fm->p_FmStateStruct->exceptions & FM_EX_IRAM_ECC)
2949    {
2950        tmpReg |= FPM_IRAM_ECC_ERR_EX_EN;
2951        FmEnableRamsEcc(p_Fm);
2952    }
2953    if(p_Fm->p_FmStateStruct->exceptions & FM_EX_NURAM_ECC)
2954    {
2955        tmpReg |= FPM_MURAM_ECC_ERR_EX_EN;
2956        FmEnableRamsEcc(p_Fm);
2957    }
2958    WRITE_UINT32(p_Fm->p_FmFpmRegs->fmrie, tmpReg);
2959
2960    /**********************/
2961    /* Init BMI Registers */
2962    /**********************/
2963
2964    /* define common resources */
2965    /* allocate MURAM for FIFO according to total size */
2966    p_Fm->fifoBaseAddr = PTR_TO_UINT(FM_MURAM_AllocMem(p_Fm->h_FmMuram,
2967                                                       p_Fm->p_FmStateStruct->totalFifoSize,
2968                                                       BMI_FIFO_ALIGN));
2969    if (!p_Fm->fifoBaseAddr)
2970    {
2971        FreeInitResources(p_Fm);
2972        RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM alloc for FIFO failed"));
2973    }
2974
2975    tmpReg = (uint32_t)(XX_VirtToPhys(UINT_TO_PTR(p_Fm->fifoBaseAddr)) - p_Fm->fmMuramPhysBaseAddr);
2976    tmpReg = tmpReg / BMI_FIFO_ALIGN;
2977
2978    tmpReg |= ((p_Fm->p_FmStateStruct->totalFifoSize/BMI_FIFO_UNITS - 1) << BMI_CFG1_FIFO_SIZE_SHIFT);
2979    WRITE_UINT32(p_Fm->p_FmBmiRegs->fmbm_cfg1, tmpReg);
2980
2981    tmpReg =  ((uint32_t)(p_Fm->p_FmStateStruct->totalNumOfTasks - 1) << BMI_CFG2_TASKS_SHIFT );
2982    /* num of DMA's will be dynamically updated when each port is set */
2983    WRITE_UINT32(p_Fm->p_FmBmiRegs->fmbm_cfg2, tmpReg);
2984
2985    /* define unmaskable exceptions, enable and clear events */
2986    tmpReg = 0;
2987    WRITE_UINT32(p_Fm->p_FmBmiRegs->fmbm_ievr, (BMI_ERR_INTR_EN_LIST_RAM_ECC |
2988                                                BMI_ERR_INTR_EN_PIPELINE_ECC |
2989                                                BMI_ERR_INTR_EN_STATISTICS_RAM_ECC |
2990                                                BMI_ERR_INTR_EN_DISPATCH_RAM_ECC));
2991    if(p_Fm->p_FmStateStruct->exceptions & FM_EX_BMI_LIST_RAM_ECC)
2992        tmpReg |= BMI_ERR_INTR_EN_LIST_RAM_ECC;
2993    if(p_Fm->p_FmStateStruct->exceptions & FM_EX_BMI_PIPELINE_ECC)
2994        tmpReg |= BMI_ERR_INTR_EN_PIPELINE_ECC;
2995    if(p_Fm->p_FmStateStruct->exceptions & FM_EX_BMI_STATISTICS_RAM_ECC)
2996        tmpReg |= BMI_ERR_INTR_EN_STATISTICS_RAM_ECC;
2997    if(p_Fm->p_FmStateStruct->exceptions & FM_EX_BMI_DISPATCH_RAM_ECC)
2998        tmpReg |= BMI_ERR_INTR_EN_DISPATCH_RAM_ECC;
2999    WRITE_UINT32(p_Fm->p_FmBmiRegs->fmbm_ier, tmpReg);
3000
3001    /**********************/
3002    /* Init QMI Registers */
3003    /**********************/
3004     /* Clear error interrupt events */
3005    WRITE_UINT32(p_Fm->p_FmQmiRegs->fmqm_eie, (QMI_ERR_INTR_EN_DOUBLE_ECC | QMI_ERR_INTR_EN_DEQ_FROM_DEF));
3006    tmpReg = 0;
3007    if(p_Fm->p_FmStateStruct->exceptions & FM_EX_QMI_DEQ_FROM_UNKNOWN_PORTID)
3008        tmpReg |= QMI_ERR_INTR_EN_DEQ_FROM_DEF;
3009    if(p_Fm->p_FmStateStruct->exceptions & FM_EX_QMI_DOUBLE_ECC)
3010        tmpReg |= QMI_ERR_INTR_EN_DOUBLE_ECC;
3011    /* enable events */
3012    WRITE_UINT32(p_Fm->p_FmQmiRegs->fmqm_eien, tmpReg);
3013
3014    if(p_Fm->p_FmDriverParam->tnumAgingPeriod)
3015    {
3016        /* tnumAgingPeriod is in units of microseconds, p_FmClockFreq is in Mhz */
3017        periodInFmClocks = (uint16_t)(p_Fm->p_FmDriverParam->tnumAgingPeriod*p_Fm->p_FmStateStruct->fmClkFreq);
3018        /* periodInFmClocks must be a 64 multiply */
3019        remainder = (uint8_t)(periodInFmClocks % 64);
3020        if (remainder > 64)
3021            tmpReg = (uint32_t)((periodInFmClocks/64) + 1);
3022        else
3023        {
3024            tmpReg = (uint32_t)(periodInFmClocks/64);
3025            if(!tmpReg)
3026                tmpReg = 1;
3027        }
3028        tmpReg <<= QMI_TAPC_TAP;
3029        WRITE_UINT32(p_Fm->p_FmQmiRegs->fmqm_tapc, tmpReg);
3030
3031    }
3032    tmpReg = 0;
3033    /* Clear interrupt events */
3034    WRITE_UINT32(p_Fm->p_FmQmiRegs->fmqm_ie, QMI_INTR_EN_SINGLE_ECC);
3035    if(p_Fm->p_FmStateStruct->exceptions & FM_EX_QMI_SINGLE_ECC)
3036        tmpReg |= QMI_INTR_EN_SINGLE_ECC;
3037    /* enable events */
3038    WRITE_UINT32(p_Fm->p_FmQmiRegs->fmqm_ien, tmpReg);
3039
3040    /* clear & enable global counters  - calculate reg and save for later,
3041       because it's the same reg for QMI enable */
3042    if(p_Fm->p_FmDriverParam->enCounters)
3043        cfgReg = QMI_CFG_EN_COUNTERS;
3044#ifdef FM_QMI_DEQ_OPTIONS_SUPPORT
3045    cfgReg |= (uint32_t)(((QMI_DEF_TNUMS_THRESH) << 8) |  (uint32_t)QMI_DEF_TNUMS_THRESH);
3046#endif /* FM_QMI_DEQ_OPTIONS_SUPPORT */
3047
3048    if (p_Fm->p_FmStateStruct->irq != NO_IRQ)
3049    {
3050        XX_SetIntr(p_Fm->p_FmStateStruct->irq, FM_EventIsr, p_Fm);
3051        XX_EnableIntr(p_Fm->p_FmStateStruct->irq);
3052    }
3053
3054    if (p_Fm->p_FmStateStruct->errIrq != NO_IRQ)
3055    {
3056        XX_SetIntr(p_Fm->p_FmStateStruct->errIrq, ErrorIsrCB, p_Fm);
3057        XX_EnableIntr(p_Fm->p_FmStateStruct->errIrq);
3058    }
3059
3060    /* build the FM master partition IPC address */
3061    if (Sprint (p_Fm->fmModuleName, "FM_%d_%d",p_Fm->p_FmStateStruct->fmId, NCSW_MASTER_ID) != 6)
3062        RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Sprint failed"));
3063
3064    err = XX_IpcRegisterMsgHandler(p_Fm->fmModuleName, FmHandleIpcMsgCB, p_Fm, FM_IPC_MAX_REPLY_SIZE);
3065    if(err)
3066        RETURN_ERROR(MAJOR, err, NO_MSG);
3067
3068    /**********************/
3069    /* Enable all modules */
3070    /**********************/
3071    WRITE_UINT32(p_Fm->p_FmBmiRegs->fmbm_init, BMI_INIT_START);
3072    WRITE_UINT32(p_Fm->p_FmQmiRegs->fmqm_gc, cfgReg | QMI_CFG_ENQ_EN | QMI_CFG_DEQ_EN);
3073
3074    if (p_Fm->p_FmDriverParam->firmware.p_Code)
3075    {
3076        XX_Free(p_Fm->p_FmDriverParam->firmware.p_Code);
3077        p_Fm->p_FmDriverParam->firmware.p_Code = NULL;
3078    }
3079
3080    XX_Free(p_Fm->p_FmDriverParam);
3081    p_Fm->p_FmDriverParam = NULL;
3082
3083    return E_OK;
3084}
3085
3086/**************************************************************************//**
3087 @Function      FM_Free
3088
3089 @Description   Frees all resources that were assigned to FM module.
3090
3091                Calling this routine invalidates the descriptor.
3092
3093 @Param[in]     h_Fm - FM module descriptor
3094
3095 @Return        E_OK on success; Error code otherwise.
3096*//***************************************************************************/
3097t_Error FM_Free(t_Handle h_Fm)
3098{
3099    t_Fm        *p_Fm = (t_Fm*)h_Fm;
3100
3101    SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
3102
3103    if (p_Fm->guestId != NCSW_MASTER_ID)
3104    {
3105        XX_IpcUnregisterMsgHandler(p_Fm->fmModuleName);
3106
3107        if(!p_Fm->recoveryMode)
3108            XX_Free(p_Fm->p_FmStateStruct);
3109
3110        XX_Free(p_Fm);
3111
3112        return E_OK;
3113    }
3114
3115    /* disable BMI and QMI */
3116    WRITE_UINT32(p_Fm->p_FmBmiRegs->fmbm_init, 0);
3117    WRITE_UINT32(p_Fm->p_FmQmiRegs->fmqm_gc, 0);
3118
3119    /* release BMI resources */
3120    WRITE_UINT32(p_Fm->p_FmBmiRegs->fmbm_cfg2, 0);
3121    WRITE_UINT32(p_Fm->p_FmBmiRegs->fmbm_cfg1, 0);
3122
3123    /* disable ECC */
3124    WRITE_UINT32(p_Fm->p_FmFpmRegs->fmrcr, 0);
3125
3126    if ((p_Fm->guestId == NCSW_MASTER_ID) && (p_Fm->fmModuleName[0] != 0))
3127        XX_IpcUnregisterMsgHandler(p_Fm->fmModuleName);
3128
3129    if (p_Fm->p_FmStateStruct)
3130    {
3131        if (p_Fm->p_FmStateStruct->irq != NO_IRQ)
3132        {
3133            XX_DisableIntr(p_Fm->p_FmStateStruct->irq);
3134            XX_FreeIntr(p_Fm->p_FmStateStruct->irq);
3135        }
3136        if (p_Fm->p_FmStateStruct->errIrq != NO_IRQ)
3137        {
3138            XX_DisableIntr(p_Fm->p_FmStateStruct->errIrq);
3139            XX_FreeIntr(p_Fm->p_FmStateStruct->errIrq);
3140        }
3141    }
3142
3143    if (p_Fm->h_Spinlock)
3144        XX_FreeSpinlock(p_Fm->h_Spinlock);
3145
3146    if (p_Fm->p_FmDriverParam)
3147    {
3148        if (p_Fm->p_FmDriverParam->firmware.p_Code)
3149            XX_Free(p_Fm->p_FmDriverParam->firmware.p_Code);
3150        XX_Free(p_Fm->p_FmDriverParam);
3151        p_Fm->p_FmDriverParam = NULL;
3152    }
3153
3154    FreeInitResources(p_Fm);
3155
3156    if (!p_Fm->recoveryMode && p_Fm->p_FmStateStruct)
3157        XX_Free(p_Fm->p_FmStateStruct);
3158
3159    XX_Free(p_Fm);
3160
3161    return E_OK;
3162}
3163
3164/*************************************************/
3165/*       API Advanced Init unit functions        */
3166/*************************************************/
3167
3168t_Error FM_ConfigResetOnInit(t_Handle h_Fm, bool enable)
3169{
3170
3171    t_Fm *p_Fm = (t_Fm*)h_Fm;
3172
3173    SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
3174    SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
3175
3176    p_Fm->p_FmDriverParam->resetOnInit = enable;
3177
3178    return E_OK;
3179}
3180
3181
3182t_Error FM_ConfigTotalNumOfTasks(t_Handle h_Fm, uint8_t totalNumOfTasks)
3183{
3184    t_Fm *p_Fm = (t_Fm*)h_Fm;
3185
3186    SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
3187    SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
3188
3189    p_Fm->p_FmStateStruct->totalNumOfTasks = totalNumOfTasks;
3190
3191    return E_OK;
3192}
3193
3194t_Error FM_ConfigTotalFifoSize(t_Handle h_Fm, uint32_t totalFifoSize)
3195{
3196    t_Fm *p_Fm = (t_Fm*)h_Fm;
3197
3198    SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
3199    SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
3200
3201    p_Fm->p_FmStateStruct->totalFifoSize = totalFifoSize;
3202
3203    return E_OK;
3204}
3205
3206t_Error FM_ConfigMaxNumOfOpenDmas(t_Handle h_Fm, uint8_t maxNumOfOpenDmas)
3207{
3208    t_Fm *p_Fm = (t_Fm*)h_Fm;
3209
3210    SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
3211    SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
3212
3213    p_Fm->p_FmStateStruct->maxNumOfOpenDmas = maxNumOfOpenDmas;
3214
3215    return E_OK;
3216}
3217
3218t_Error FM_ConfigThresholds(t_Handle h_Fm, t_FmThresholds *p_FmThresholds)
3219{
3220    t_Fm *p_Fm = (t_Fm*)h_Fm;
3221
3222    SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
3223    SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
3224
3225    memcpy(&p_Fm->p_FmDriverParam->thresholds, p_FmThresholds, sizeof(t_FmThresholds));
3226
3227    return E_OK;
3228}
3229
3230t_Error FM_ConfigDmaCacheOverride(t_Handle h_Fm, e_FmDmaCacheOverride cacheOverride)
3231{
3232    t_Fm *p_Fm = (t_Fm*)h_Fm;
3233
3234    SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
3235    SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
3236
3237    p_Fm->p_FmDriverParam->dmaCacheOverride = cacheOverride;
3238
3239    return E_OK;
3240}
3241
3242t_Error FM_ConfigDmaAidOverride(t_Handle h_Fm, bool aidOverride)
3243{
3244    t_Fm *p_Fm = (t_Fm*)h_Fm;
3245
3246    SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
3247    SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
3248
3249    p_Fm->p_FmDriverParam->dmaAidOverride = aidOverride;
3250
3251    return E_OK;
3252}
3253
3254t_Error FM_ConfigDmaAidMode(t_Handle h_Fm, e_FmDmaAidMode aidMode)
3255{
3256    t_Fm *p_Fm = (t_Fm*)h_Fm;
3257
3258    SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
3259    SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
3260
3261    p_Fm->p_FmDriverParam->dmaAidMode = aidMode;
3262
3263    return E_OK;
3264}
3265
3266t_Error FM_ConfigDmaAxiDbgNumOfBeats(t_Handle h_Fm, uint8_t axiDbgNumOfBeats)
3267{
3268    t_Fm *p_Fm = (t_Fm*)h_Fm;
3269
3270    SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
3271    SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
3272
3273    p_Fm->p_FmDriverParam->dmaAxiDbgNumOfBeats = axiDbgNumOfBeats;
3274
3275    return E_OK;
3276}
3277
3278t_Error FM_ConfigDmaCamNumOfEntries(t_Handle h_Fm, uint8_t numOfEntries)
3279{
3280    t_Fm *p_Fm = (t_Fm*)h_Fm;
3281
3282    SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
3283    SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
3284
3285    p_Fm->p_FmDriverParam->dmaCamNumOfEntries = numOfEntries;
3286
3287    return E_OK;
3288}
3289
3290t_Error FM_ConfigDmaWatchdog(t_Handle h_Fm, uint32_t watchdogValue)
3291{
3292    t_Fm                *p_Fm = (t_Fm*)h_Fm;
3293
3294    SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
3295    SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
3296
3297#ifdef FM_NO_WATCHDOG
3298    {
3299        t_FmRevisionInfo    revInfo;
3300        FM_GetRevision(h_Fm, &revInfo);
3301        if (revInfo.majorRev != 4)
3302            RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("watchdog!"));
3303    }
3304#endif /* FM_NO_WATCHDOG */
3305
3306    p_Fm->p_FmDriverParam->dmaWatchdog = watchdogValue;
3307
3308    return E_OK;
3309}
3310
3311t_Error FM_ConfigDmaWriteBufThresholds(t_Handle h_Fm, t_FmDmaThresholds *p_FmDmaThresholds)
3312
3313{
3314    t_Fm *p_Fm = (t_Fm*)h_Fm;
3315
3316    SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
3317    SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
3318
3319    memcpy(&p_Fm->p_FmDriverParam->dmaWriteBufThresholds, p_FmDmaThresholds, sizeof(t_FmDmaThresholds));
3320
3321    return E_OK;
3322}
3323
3324t_Error FM_ConfigDmaCommQThresholds(t_Handle h_Fm, t_FmDmaThresholds *p_FmDmaThresholds)
3325{
3326    t_Fm *p_Fm = (t_Fm*)h_Fm;
3327
3328    SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
3329    SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
3330
3331    memcpy(&p_Fm->p_FmDriverParam->dmaCommQThresholds, p_FmDmaThresholds, sizeof(t_FmDmaThresholds));
3332
3333    return E_OK;
3334}
3335
3336t_Error FM_ConfigDmaReadBufThresholds(t_Handle h_Fm, t_FmDmaThresholds *p_FmDmaThresholds)
3337{
3338    t_Fm *p_Fm = (t_Fm*)h_Fm;
3339
3340    SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
3341    SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
3342
3343    memcpy(&p_Fm->p_FmDriverParam->dmaReadBufThresholds, p_FmDmaThresholds, sizeof(t_FmDmaThresholds));
3344
3345    return E_OK;
3346}
3347
3348t_Error FM_ConfigDmaEmergency(t_Handle h_Fm, t_FmDmaEmergency *p_Emergency)
3349{
3350    t_Fm *p_Fm = (t_Fm*)h_Fm;
3351
3352    SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
3353    SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
3354
3355    p_Fm->p_FmDriverParam->dmaEnEmergency = TRUE;
3356    memcpy(&p_Fm->p_FmDriverParam->dmaEmergency, p_Emergency, sizeof(t_FmDmaEmergency));
3357
3358    return E_OK;
3359}
3360
3361t_Error FM_ConfigDmaEmergencySmoother(t_Handle h_Fm, uint32_t emergencyCnt)
3362{
3363    t_Fm *p_Fm = (t_Fm*)h_Fm;
3364
3365    SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
3366    SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
3367
3368    if(!p_Fm->p_FmDriverParam->dmaEnEmergency)
3369        RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("FM_ConfigEnDmaEmergencySmoother may be called only after FM_ConfigEnDmaEmergency"));
3370
3371    p_Fm->p_FmDriverParam->dmaEnEmergencySmoother = TRUE;
3372    p_Fm->p_FmDriverParam->dmaEmergencySwitchCounter = emergencyCnt;
3373
3374    return E_OK;
3375}
3376
3377t_Error FM_ConfigDmaDbgCounter(t_Handle h_Fm, e_FmDmaDbgCntMode fmDmaDbgCntMode)
3378{
3379    t_Fm *p_Fm = (t_Fm*)h_Fm;
3380
3381    SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
3382    SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
3383
3384    p_Fm->p_FmDriverParam->dmaDbgCntMode = fmDmaDbgCntMode;
3385
3386    return E_OK;
3387}
3388
3389t_Error FM_ConfigDmaStopOnBusErr(t_Handle h_Fm, bool stop)
3390{
3391    t_Fm *p_Fm = (t_Fm*)h_Fm;
3392
3393    SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
3394    SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
3395
3396    p_Fm->p_FmDriverParam->dmaStopOnBusError = stop;
3397
3398    return E_OK;
3399}
3400
3401t_Error FM_ConfigDmaSosEmergencyThreshold(t_Handle h_Fm, uint32_t dmaSosEmergency)
3402{
3403    t_Fm *p_Fm = (t_Fm*)h_Fm;
3404
3405    SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
3406    SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
3407
3408    p_Fm->p_FmDriverParam->dmaSosEmergency = dmaSosEmergency;
3409
3410    return E_OK;
3411}
3412
3413t_Error FM_ConfigEnableCounters(t_Handle h_Fm)
3414{
3415    t_Fm *p_Fm = (t_Fm*)h_Fm;
3416
3417    SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
3418    SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
3419
3420    p_Fm->p_FmDriverParam->enCounters = TRUE;
3421
3422    return E_OK;
3423}
3424
3425t_Error FM_ConfigDmaErr(t_Handle h_Fm, e_FmDmaErr dmaErr)
3426{
3427    t_Fm *p_Fm = (t_Fm*)h_Fm;
3428
3429    SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
3430    SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
3431
3432    p_Fm->p_FmDriverParam->dmaErr = dmaErr;
3433
3434    return E_OK;
3435}
3436
3437t_Error FM_ConfigCatastrophicErr(t_Handle h_Fm, e_FmCatastrophicErr catastrophicErr)
3438{
3439    t_Fm *p_Fm = (t_Fm*)h_Fm;
3440
3441    SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
3442    SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
3443
3444    p_Fm->p_FmDriverParam->catastrophicErr = catastrophicErr;
3445
3446    return E_OK;
3447}
3448
3449t_Error FM_ConfigEnableMuramTestMode(t_Handle h_Fm)
3450{
3451    t_Fm *p_Fm = (t_Fm*)h_Fm;
3452
3453    SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
3454    SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
3455
3456    p_Fm->p_FmDriverParam->enMuramTestMode = TRUE;
3457
3458    return E_OK;
3459}
3460
3461t_Error FM_ConfigEnableIramTestMode(t_Handle h_Fm)
3462{
3463    t_Fm *p_Fm = (t_Fm*)h_Fm;
3464
3465    SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
3466    SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
3467
3468    p_Fm->p_FmDriverParam->enIramTestMode = TRUE;
3469
3470    return E_OK;
3471}
3472
3473t_Error FM_ConfigHaltOnExternalActivation(t_Handle h_Fm, bool enable)
3474{
3475    t_Fm *p_Fm = (t_Fm*)h_Fm;
3476
3477    SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
3478    SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
3479
3480#ifdef FM_HALT_SIG_ERRATA_GEN12
3481    {
3482        t_FmRevisionInfo revInfo;
3483        FM_GetRevision(h_Fm, &revInfo);
3484        if ((revInfo.majorRev == 1) && (revInfo.minorRev == 0))
3485            RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("HaltOnExternalActivation!"));
3486    }
3487#endif /* FM_HALT_SIG_ERRATA_GEN12 */
3488
3489    p_Fm->p_FmDriverParam->haltOnExternalActivation = enable;
3490
3491    return E_OK;
3492}
3493
3494t_Error FM_ConfigHaltOnUnrecoverableEccError(t_Handle h_Fm, bool enable)
3495{
3496    t_Fm *p_Fm = (t_Fm*)h_Fm;
3497
3498    SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
3499    SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
3500
3501#ifdef FM_ECC_HALT_NO_SYNC_ERRATA_10GMAC_A008
3502    RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("HaltOnEccError!"));
3503#endif /* FM_ECC_HALT_NO_SYNC_ERRATA_10GMAC_A008 */
3504
3505    p_Fm->p_FmDriverParam->haltOnUnrecoverableEccError = enable;
3506
3507    return E_OK;
3508}
3509
3510t_Error FM_ConfigException(t_Handle h_Fm, e_FmExceptions exception, bool enable)
3511{
3512    t_Fm                *p_Fm = (t_Fm*)h_Fm;
3513    uint32_t            bitMask = 0;
3514    t_FmRevisionInfo    revInfo;
3515
3516    SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
3517
3518    FM_GetRevision(p_Fm, &revInfo);
3519#ifdef FM_BMI_PIPELINE_ERR_IRQ_ERRATA_FMAN9
3520    if((exception == e_FM_EX_BMI_PIPELINE_ECC) && (enable))
3521    {
3522        if ((revInfo.majorRev == 1) && (revInfo.minorRev == 0))
3523        {
3524            REPORT_ERROR(MINOR, E_NOT_SUPPORTED, ("e_FM_EX_BMI_PIPELINE_ECC!"));
3525            return E_OK;
3526        }
3527    }
3528#endif /* FM_BMI_PIPELINE_ERR_IRQ_ERRATA_FMAN9 */
3529#ifdef FM_RAM_LIST_ERR_IRQ_ERRATA_FMAN8
3530    if((exception == e_FM_EX_BMI_LIST_RAM_ECC) && (enable))
3531    {
3532        if ((revInfo.majorRev == 1) && (revInfo.minorRev == 0))
3533        {
3534            REPORT_ERROR(MINOR, E_NOT_SUPPORTED, ("e_FM_EX_BMI_LIST_RAM_ECC!"));
3535            return E_OK;
3536        }
3537    }
3538#endif   /* FM_RAM_LIST_ERR_IRQ_ERRATA_FMAN8 */
3539#ifdef FM_QMI_NO_ECC_EXCEPTIONS
3540    if(((exception == e_FM_EX_QMI_SINGLE_ECC) || (exception == e_FM_EX_QMI_DOUBLE_ECC)) &&
3541            enable)
3542    {
3543        if (revInfo.majorRev == 4)
3544        {
3545            REPORT_ERROR(MINOR, E_NOT_SUPPORTED, ("QMI ECC exception!"));
3546            return E_OK;
3547        }
3548    }
3549#endif   /* FM_QMI_NO_ECC_EXCEPTIONS */
3550#ifdef FM_NO_DISPATCH_RAM_ECC
3551    if((exception == e_FM_EX_BMI_DISPATCH_RAM_ECC) && (enable))
3552    {
3553        if (revInfo.majorRev != 4)
3554        {
3555            REPORT_ERROR(MINOR, E_NOT_SUPPORTED, ("e_FM_EX_BMI_DISPATCH_RAM_ECC!"));
3556            return E_OK;
3557        }
3558    }
3559#endif   /* FM_NO_DISPATCH_RAM_ECC */
3560
3561    GET_EXCEPTION_FLAG(bitMask, exception);
3562    if(bitMask)
3563    {
3564        if (enable)
3565            p_Fm->p_FmStateStruct->exceptions |= bitMask;
3566        else
3567            p_Fm->p_FmStateStruct->exceptions &= ~bitMask;
3568   }
3569    else
3570        RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined exception"));
3571
3572    return E_OK;
3573}
3574
3575t_Error FM_ConfigExternalEccRamsEnable(t_Handle h_Fm, bool enable)
3576{
3577    t_Fm        *p_Fm = (t_Fm*)h_Fm;
3578
3579    SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
3580
3581    p_Fm->p_FmDriverParam->externalEccRamsEnable = enable;
3582
3583    return E_OK;
3584}
3585
3586t_Error FM_ConfigTnumAgingPeriod(t_Handle h_Fm, uint16_t tnumAgingPeriod)
3587{
3588    t_Fm             *p_Fm = (t_Fm*)h_Fm;
3589#ifdef FM_NO_TNUM_AGING
3590    t_FmRevisionInfo revInfo;
3591#endif /* FM_NO_TNUM_AGING */
3592
3593    SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
3594
3595#ifdef FM_NO_TNUM_AGING
3596    FM_GetRevision(h_Fm, &revInfo);
3597    if (revInfo.majorRev != 4)
3598        RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("FM_ConfigTnumAgingPeriod!"));
3599#endif /* FM_NO_TNUM_AGING */
3600
3601    p_Fm->p_FmDriverParam->tnumAgingPeriod = tnumAgingPeriod;
3602
3603    return E_OK;
3604
3605}
3606
3607/****************************************************/
3608/*       API Run-time Control uint functions        */
3609/****************************************************/
3610t_Handle FM_GetPcdHandle(t_Handle h_Fm)
3611{
3612    SANITY_CHECK_RETURN_VALUE(h_Fm, E_INVALID_HANDLE, NULL);
3613    SANITY_CHECK_RETURN_VALUE(!((t_Fm*)h_Fm)->p_FmDriverParam, E_INVALID_STATE, NULL);
3614
3615    return ((t_Fm*)h_Fm)->h_Pcd;
3616}
3617
3618void FM_EventIsr(t_Handle h_Fm)
3619{
3620#define FM_M_CALL_1G_MAC_TMR_ISR(_id)   \
3621    {                                   \
3622        if (p_Fm->guestId != p_Fm->intrMng[(e_FmInterModuleEvent)(e_FM_EV_1G_MAC0_TMR+_id)].guestId)    \
3623            SendIpcIsr(p_Fm, (e_FmInterModuleEvent)(e_FM_EV_1G_MAC0_TMR+_id), pending);                 \
3624        else                                                                                            \
3625            p_Fm->intrMng[(e_FmInterModuleEvent)(e_FM_EV_1G_MAC0_TMR+_id)].f_Isr(p_Fm->intrMng[(e_FmInterModuleEvent)(e_FM_EV_1G_MAC0_TMR+_id)].h_SrcHandle);\
3626    }
3627    t_Fm                    *p_Fm = (t_Fm*)h_Fm;
3628    uint32_t                pending, event;
3629
3630    SANITY_CHECK_RETURN(h_Fm, E_INVALID_HANDLE);
3631
3632    /* normal interrupts */
3633    pending = GET_UINT32(p_Fm->p_FmFpmRegs->fmnpi);
3634    ASSERT_COND(pending);
3635    if (pending & INTR_EN_BMI)
3636        REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("BMI Event - undefined!"));
3637    if (pending & INTR_EN_QMI)
3638        QmiEvent(p_Fm);
3639    if (pending & INTR_EN_PRS)
3640        p_Fm->intrMng[e_FM_EV_PRS].f_Isr(p_Fm->intrMng[e_FM_EV_PRS].h_SrcHandle);
3641    if (pending & INTR_EN_PLCR)
3642        p_Fm->intrMng[e_FM_EV_PLCR].f_Isr(p_Fm->intrMng[e_FM_EV_PLCR].h_SrcHandle);
3643    if (pending & INTR_EN_KG)
3644        p_Fm->intrMng[e_FM_EV_KG].f_Isr(p_Fm->intrMng[e_FM_EV_KG].h_SrcHandle);
3645    if (pending & INTR_EN_TMR)
3646            p_Fm->intrMng[e_FM_EV_TMR].f_Isr(p_Fm->intrMng[e_FM_EV_TMR].h_SrcHandle);
3647
3648    /* MAC events may belong to different partitions */
3649    if (pending & INTR_EN_1G_MAC0_TMR)
3650        FM_M_CALL_1G_MAC_TMR_ISR(0);
3651    if (pending & INTR_EN_1G_MAC1_TMR)
3652        FM_M_CALL_1G_MAC_TMR_ISR(1);
3653    if (pending & INTR_EN_1G_MAC2_TMR)
3654        FM_M_CALL_1G_MAC_TMR_ISR(2);
3655    if (pending & INTR_EN_1G_MAC3_TMR)
3656        FM_M_CALL_1G_MAC_TMR_ISR(3);
3657    if (pending & INTR_EN_1G_MAC4_TMR)
3658        FM_M_CALL_1G_MAC_TMR_ISR(4);
3659
3660    /* IM port events may belong to different partitions */
3661    if (pending & INTR_EN_REV0)
3662    {
3663        event = GET_UINT32(p_Fm->p_FmFpmRegs->fmfpfcev[0]) & GET_UINT32(p_Fm->p_FmFpmRegs->fmfpfcee[0]);
3664        WRITE_UINT32(p_Fm->p_FmFpmRegs->fpmcev[0], event);
3665        if (p_Fm->guestId != p_Fm->intrMng[e_FM_EV_FMAN_CTRL_0].guestId)
3666            /*TODO IPC ISR For Fman Ctrl */
3667            ASSERT_COND(0);
3668            /* SendIpcIsr(p_Fm, e_FM_EV_FMAN_CTRL_0, pending); */
3669        else
3670            p_Fm->fmanCtrlIntr[0].f_Isr(p_Fm->fmanCtrlIntr[0].h_SrcHandle, event);
3671
3672    }
3673    if (pending & INTR_EN_REV1)
3674    {
3675        event = GET_UINT32(p_Fm->p_FmFpmRegs->fmfpfcev[1]) & GET_UINT32(p_Fm->p_FmFpmRegs->fmfpfcee[1]);
3676        WRITE_UINT32(p_Fm->p_FmFpmRegs->fpmcev[1], event);
3677        if (p_Fm->guestId != p_Fm->intrMng[e_FM_EV_FMAN_CTRL_1].guestId)
3678            /*TODO IPC ISR For Fman Ctrl */
3679            ASSERT_COND(0);
3680            /* SendIpcIsr(p_Fm, e_FM_EV_FMAN_CTRL_1, pending); */
3681        else
3682            p_Fm->fmanCtrlIntr[1].f_Isr(p_Fm->fmanCtrlIntr[1].h_SrcHandle, event);
3683
3684    }
3685    if (pending & INTR_EN_REV2)
3686    {
3687        event = GET_UINT32(p_Fm->p_FmFpmRegs->fmfpfcev[2]) & GET_UINT32(p_Fm->p_FmFpmRegs->fmfpfcee[2]);
3688        WRITE_UINT32(p_Fm->p_FmFpmRegs->fpmcev[2], event);
3689        if (p_Fm->guestId != p_Fm->intrMng[e_FM_EV_FMAN_CTRL_2].guestId)
3690            /*TODO IPC ISR For Fman Ctrl */
3691            ASSERT_COND(0);
3692            /* SendIpcIsr(p_Fm, e_FM_EV_FMAN_CTRL_2, pending); */
3693        else
3694           p_Fm->fmanCtrlIntr[2].f_Isr(p_Fm->fmanCtrlIntr[2].h_SrcHandle, event);
3695    }
3696    if (pending & INTR_EN_REV3)
3697    {
3698        event = GET_UINT32(p_Fm->p_FmFpmRegs->fmfpfcev[3]) & GET_UINT32(p_Fm->p_FmFpmRegs->fmfpfcee[3]);
3699        WRITE_UINT32(p_Fm->p_FmFpmRegs->fpmcev[3], event);
3700        if (p_Fm->guestId != p_Fm->intrMng[e_FM_EV_FMAN_CTRL_3].guestId)
3701            /*TODO IPC ISR For Fman Ctrl */
3702            ASSERT_COND(0);
3703            /* SendIpcIsr(p_Fm, e_FM_EV_FMAN_CTRL_2, pendin3); */
3704        else
3705            p_Fm->fmanCtrlIntr[3].f_Isr(p_Fm->fmanCtrlIntr[3].h_SrcHandle, event);
3706    }
3707}
3708
3709t_Error FM_ErrorIsr(t_Handle h_Fm)
3710{
3711    t_Fm                    *p_Fm = (t_Fm*)h_Fm;
3712
3713    SANITY_CHECK_RETURN_ERROR(h_Fm, E_INVALID_HANDLE);
3714
3715    /* error interrupts */
3716    if (GET_UINT32(p_Fm->p_FmFpmRegs->fmepi) == 0)
3717        return ERROR_CODE(E_EMPTY);
3718
3719    ErrorIsrCB(p_Fm);
3720    return E_OK;
3721}
3722
3723t_Error FM_SetPortsBandwidth(t_Handle h_Fm, t_FmPortsBandwidthParams *p_PortsBandwidth)
3724{
3725    t_Fm        *p_Fm = (t_Fm*)h_Fm;
3726    int         i;
3727    uint8_t     sum;
3728    uint8_t     hardwarePortId;
3729    uint32_t    tmpRegs[8] = {0,0,0,0,0,0,0,0};
3730    uint8_t     relativePortId, shift, weight, maxPercent = 0;
3731
3732    SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
3733    SANITY_CHECK_RETURN_ERROR(!p_Fm->p_FmDriverParam, E_INVALID_STATE);
3734
3735    /* check that all ports add up to 100% */
3736    sum = 0;
3737    for (i=0;i<p_PortsBandwidth->numOfPorts;i++)
3738        sum +=p_PortsBandwidth->portsBandwidths[i].bandwidth;
3739    if (sum != 100)
3740        RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Sum of ports bandwidth differ from 100%"));
3741
3742    /* find highest precent */
3743    for (i=0;i<p_PortsBandwidth->numOfPorts;i++)
3744    {
3745        if (p_PortsBandwidth->portsBandwidths[i].bandwidth > maxPercent)
3746            maxPercent = p_PortsBandwidth->portsBandwidths[i].bandwidth;
3747    }
3748
3749    /* calculate weight for each port */
3750    for (i=0;i<p_PortsBandwidth->numOfPorts;i++)
3751    {
3752        weight = (uint8_t)((p_PortsBandwidth->portsBandwidths[i].bandwidth * PORT_MAX_WEIGHT )/maxPercent);
3753        /* we want even division between 1-to-PORT_MAX_WEIGHT. so if exect division
3754           is not reached, we round up so that:
3755           0 until maxPercent/PORT_MAX_WEIGHT get "1"
3756           maxPercent/PORT_MAX_WEIGHT+1 until (maxPercent/PORT_MAX_WEIGHT)*2 get "2"
3757           ...
3758           maxPercent - maxPercent/PORT_MAX_WEIGHT until maxPercent get "PORT_MAX_WEIGHT: */
3759        if ((uint8_t)((p_PortsBandwidth->portsBandwidths[i].bandwidth * PORT_MAX_WEIGHT ) % maxPercent))
3760            weight++;
3761
3762        /* find the location of this port within the register */
3763        SW_PORT_ID_TO_HW_PORT_ID(hardwarePortId,
3764                                 p_PortsBandwidth->portsBandwidths[i].type,
3765                                 p_PortsBandwidth->portsBandwidths[i].relativePortId);
3766        relativePortId = (uint8_t)(hardwarePortId % 8);
3767        shift = (uint8_t)(32-4*(relativePortId+1));
3768
3769
3770        if(weight > 1)
3771            /* Add this port to tmpReg */
3772            /* (each 8 ports result in one register)*/
3773            tmpRegs[hardwarePortId/8] |= ((weight-1) << shift);
3774    }
3775
3776    for(i=0;i<8;i++)
3777        if(tmpRegs[i])
3778            WRITE_UINT32(p_Fm->p_FmBmiRegs->fmbm_arb[i], tmpRegs[i]);
3779
3780    return E_OK;
3781}
3782
3783t_Error FM_EnableRamsEcc(t_Handle h_Fm)
3784{
3785    t_Fm        *p_Fm = (t_Fm*)h_Fm;
3786    uint32_t    tmpReg;
3787
3788    SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
3789
3790    if(p_Fm->guestId != NCSW_MASTER_ID)
3791    {
3792        t_FmIpcMsg      msg;
3793        t_Error         err;
3794
3795        memset(&msg, 0, sizeof(msg));
3796        msg.msgId = FM_ENABLE_RAM_ECC;
3797        if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
3798                                     (uint8_t*)&msg,
3799                                     sizeof(msg.msgId),
3800                                     NULL,
3801                                     NULL,
3802                                     NULL,
3803                                     NULL)) != E_OK)
3804            RETURN_ERROR(MINOR, err, NO_MSG);
3805        return E_OK;
3806    }
3807
3808    if(!p_Fm->p_FmStateStruct->internalCall)
3809        p_Fm->p_FmStateStruct->explicitEnable = TRUE;
3810    p_Fm->p_FmStateStruct->internalCall = FALSE;
3811
3812    if(p_Fm->p_FmStateStruct->ramsEccEnable)
3813        return E_OK;
3814    else
3815    {
3816        tmpReg = GET_UINT32(p_Fm->p_FmFpmRegs->fmrcr);
3817        if(tmpReg & FPM_RAM_CTL_RAMS_ECC_EN_SRC_SEL)
3818        {
3819            DBG(WARNING, ("Rams ECC is configured to be controlled through JTAG"));
3820            WRITE_UINT32(p_Fm->p_FmFpmRegs->fmrcr, tmpReg | FPM_RAM_CTL_IRAM_ECC_EN);
3821        }
3822        else
3823            WRITE_UINT32(p_Fm->p_FmFpmRegs->fmrcr, tmpReg | (FPM_RAM_CTL_RAMS_ECC_EN | FPM_RAM_CTL_IRAM_ECC_EN));
3824        p_Fm->p_FmStateStruct->ramsEccEnable = TRUE;
3825    }
3826
3827    return E_OK;
3828}
3829
3830t_Error FM_DisableRamsEcc(t_Handle h_Fm)
3831{
3832    t_Fm        *p_Fm = (t_Fm*)h_Fm;
3833    uint32_t    tmpReg;
3834    bool        explicitDisable = FALSE;
3835
3836    SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
3837    SANITY_CHECK_RETURN_ERROR(!p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
3838
3839    if(p_Fm->guestId != NCSW_MASTER_ID)
3840    {
3841        t_Error             err;
3842        t_FmIpcMsg          msg;
3843
3844        memset(&msg, 0, sizeof(msg));
3845        msg.msgId = FM_DISABLE_RAM_ECC;
3846        if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
3847                                     (uint8_t*)&msg,
3848                                     sizeof(msg.msgId),
3849                                     NULL,
3850                                     NULL,
3851                                     NULL,
3852                                     NULL)) != E_OK)
3853            RETURN_ERROR(MINOR, err, NO_MSG);
3854        return E_OK;
3855    }
3856
3857    if(!p_Fm->p_FmStateStruct->internalCall)
3858        explicitDisable = TRUE;
3859    p_Fm->p_FmStateStruct->internalCall = FALSE;
3860
3861    /* if rams are already disabled, or if rams were explicitly enabled and are
3862       currently called indirectly (not explicitly), ignore this call. */
3863    if(!p_Fm->p_FmStateStruct->ramsEccEnable || (p_Fm->p_FmStateStruct->explicitEnable && !explicitDisable))
3864        return E_OK;
3865    else
3866    {
3867        if(p_Fm->p_FmStateStruct->explicitEnable)
3868            /* This is the case were both explicit are TRUE.
3869               Turn off this flag for cases were following ramsEnable
3870               routines are called */
3871            p_Fm->p_FmStateStruct->explicitEnable = FALSE;
3872
3873        tmpReg = GET_UINT32(p_Fm->p_FmFpmRegs->fmrcr);
3874        if(tmpReg & FPM_RAM_CTL_RAMS_ECC_EN_SRC_SEL)
3875        {
3876            DBG(WARNING, ("Rams ECC is configured to be controlled through JTAG"));
3877            WRITE_UINT32(p_Fm->p_FmFpmRegs->fmrcr, tmpReg & ~FPM_RAM_CTL_IRAM_ECC_EN);
3878        }
3879        else
3880            WRITE_UINT32(p_Fm->p_FmFpmRegs->fmrcr, tmpReg & ~(FPM_RAM_CTL_RAMS_ECC_EN | FPM_RAM_CTL_IRAM_ECC_EN));
3881        p_Fm->p_FmStateStruct->ramsEccEnable = FALSE;
3882    }
3883
3884    return E_OK;
3885}
3886
3887t_Error FM_SetException(t_Handle h_Fm, e_FmExceptions exception, bool enable)
3888{
3889    t_Fm        *p_Fm = (t_Fm*)h_Fm;
3890    uint32_t    bitMask = 0;
3891    uint32_t    tmpReg;
3892
3893    SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
3894    SANITY_CHECK_RETURN_ERROR(!p_Fm->p_FmDriverParam, E_INVALID_STATE);
3895
3896    GET_EXCEPTION_FLAG(bitMask, exception);
3897    if(bitMask)
3898    {
3899        if (enable)
3900            p_Fm->p_FmStateStruct->exceptions |= bitMask;
3901        else
3902            p_Fm->p_FmStateStruct->exceptions &= ~bitMask;
3903
3904        switch(exception)
3905        {
3906             case(e_FM_EX_DMA_BUS_ERROR):
3907                tmpReg = GET_UINT32(p_Fm->p_FmDmaRegs->fmdmmr);
3908                if(enable)
3909                    tmpReg |= DMA_MODE_BER;
3910                else
3911                    tmpReg &= ~DMA_MODE_BER;
3912                /* disable bus error */
3913                WRITE_UINT32(p_Fm->p_FmDmaRegs->fmdmmr, tmpReg);
3914                break;
3915             case(e_FM_EX_DMA_READ_ECC):
3916             case(e_FM_EX_DMA_SYSTEM_WRITE_ECC):
3917             case(e_FM_EX_DMA_FM_WRITE_ECC):
3918                tmpReg = GET_UINT32(p_Fm->p_FmDmaRegs->fmdmmr);
3919                if(enable)
3920                    tmpReg |= DMA_MODE_ECC;
3921                else
3922                    tmpReg &= ~DMA_MODE_ECC;
3923                WRITE_UINT32(p_Fm->p_FmDmaRegs->fmdmmr, tmpReg);
3924                break;
3925             case(e_FM_EX_FPM_STALL_ON_TASKS):
3926                tmpReg = GET_UINT32(p_Fm->p_FmFpmRegs->fpmem);
3927                if(enable)
3928                    tmpReg |= FPM_EV_MASK_STALL_EN;
3929                else
3930                    tmpReg &= ~FPM_EV_MASK_STALL_EN;
3931                WRITE_UINT32(p_Fm->p_FmFpmRegs->fpmem, tmpReg);
3932                break;
3933             case(e_FM_EX_FPM_SINGLE_ECC):
3934                tmpReg = GET_UINT32(p_Fm->p_FmFpmRegs->fpmem);
3935                if(enable)
3936                    tmpReg |= FPM_EV_MASK_SINGLE_ECC_EN;
3937                else
3938                    tmpReg &= ~FPM_EV_MASK_SINGLE_ECC_EN;
3939                WRITE_UINT32(p_Fm->p_FmFpmRegs->fpmem, tmpReg);
3940                break;
3941            case( e_FM_EX_FPM_DOUBLE_ECC):
3942                tmpReg = GET_UINT32(p_Fm->p_FmFpmRegs->fpmem);
3943                if(enable)
3944                    tmpReg |= FPM_EV_MASK_DOUBLE_ECC_EN;
3945                else
3946                    tmpReg &= ~FPM_EV_MASK_DOUBLE_ECC_EN;
3947                WRITE_UINT32(p_Fm->p_FmFpmRegs->fpmem, tmpReg);
3948                break;
3949            case( e_FM_EX_QMI_SINGLE_ECC):
3950                tmpReg = GET_UINT32(p_Fm->p_FmQmiRegs->fmqm_ien);
3951                if(enable)
3952                {
3953#ifdef FM_QMI_NO_ECC_EXCEPTIONS
3954                    t_FmRevisionInfo revInfo;
3955                    FM_GetRevision(p_Fm, &revInfo);
3956                    if (revInfo.majorRev == 4)
3957                    {
3958                       REPORT_ERROR(MINOR, E_NOT_SUPPORTED, ("e_FM_EX_QMI_SINGLE_ECC"));
3959                       return E_OK;
3960                    }
3961#endif   /* FM_QMI_NO_ECC_EXCEPTIONS */
3962                    tmpReg |= QMI_INTR_EN_SINGLE_ECC;
3963                }
3964                else
3965                    tmpReg &= ~QMI_INTR_EN_SINGLE_ECC;
3966                WRITE_UINT32(p_Fm->p_FmQmiRegs->fmqm_ien, tmpReg);
3967                break;
3968             case(e_FM_EX_QMI_DOUBLE_ECC):
3969                tmpReg = GET_UINT32(p_Fm->p_FmQmiRegs->fmqm_eien);
3970                if(enable)
3971                {
3972#ifdef FM_QMI_NO_ECC_EXCEPTIONS
3973                    t_FmRevisionInfo revInfo;
3974                    FM_GetRevision(p_Fm, &revInfo);
3975                    if (revInfo.majorRev == 4)
3976                    {
3977                       REPORT_ERROR(MINOR, E_NOT_SUPPORTED, ("e_FM_EX_QMI_DOUBLE_ECC"));
3978                       return E_OK;
3979                    }
3980#endif   /* FM_QMI_NO_ECC_EXCEPTIONS */
3981                    tmpReg |= QMI_ERR_INTR_EN_DOUBLE_ECC;
3982                }
3983                else
3984                    tmpReg &= ~QMI_ERR_INTR_EN_DOUBLE_ECC;
3985                WRITE_UINT32(p_Fm->p_FmQmiRegs->fmqm_eien, tmpReg);
3986                break;
3987             case(e_FM_EX_QMI_DEQ_FROM_UNKNOWN_PORTID):
3988                tmpReg = GET_UINT32(p_Fm->p_FmQmiRegs->fmqm_eien);
3989                if(enable)
3990                    tmpReg |= QMI_ERR_INTR_EN_DEQ_FROM_DEF;
3991                else
3992                    tmpReg &= ~QMI_ERR_INTR_EN_DEQ_FROM_DEF;
3993                WRITE_UINT32(p_Fm->p_FmQmiRegs->fmqm_eien, tmpReg);
3994                break;
3995             case(e_FM_EX_BMI_LIST_RAM_ECC):
3996                tmpReg = GET_UINT32(p_Fm->p_FmBmiRegs->fmbm_ier);
3997                if(enable)
3998                {
3999#ifdef FM_RAM_LIST_ERR_IRQ_ERRATA_FMAN8
4000                    t_FmRevisionInfo revInfo;
4001                    FM_GetRevision(p_Fm, &revInfo);
4002                    if ((revInfo.majorRev == 1) && (revInfo.minorRev == 0))
4003                    {
4004                       REPORT_ERROR(MINOR, E_NOT_SUPPORTED, ("e_FM_EX_BMI_LIST_RAM_ECC"));
4005                       return E_OK;
4006                    }
4007#endif   /* FM_RAM_LIST_ERR_IRQ_ERRATA_FMAN8 */
4008                    tmpReg |= BMI_ERR_INTR_EN_LIST_RAM_ECC;
4009                }
4010                else
4011                    tmpReg &= ~BMI_ERR_INTR_EN_LIST_RAM_ECC;
4012                WRITE_UINT32(p_Fm->p_FmBmiRegs->fmbm_ier, tmpReg);
4013                break;
4014             case(e_FM_EX_BMI_PIPELINE_ECC):
4015                tmpReg = GET_UINT32(p_Fm->p_FmBmiRegs->fmbm_ier);
4016                if(enable)
4017                {
4018#ifdef FM_BMI_PIPELINE_ERR_IRQ_ERRATA_FMAN9
4019                    t_FmRevisionInfo revInfo;
4020                    FM_GetRevision(p_Fm, &revInfo);
4021                    if ((revInfo.majorRev == 1) && (revInfo.minorRev == 0))
4022                    {
4023                       REPORT_ERROR(MINOR, E_NOT_SUPPORTED, ("e_FM_EX_BMI_PIPELINE_ECCBMI_LIST_RAM_ECC"));
4024                       return E_OK;
4025                    }
4026#endif /* FM_BMI_PIPELINE_ERR_IRQ_ERRATA_FMAN9 */
4027                    tmpReg |= BMI_ERR_INTR_EN_PIPELINE_ECC;
4028                }
4029                else
4030                    tmpReg &= ~BMI_ERR_INTR_EN_PIPELINE_ECC;
4031                WRITE_UINT32(p_Fm->p_FmBmiRegs->fmbm_ier, tmpReg);
4032                break;
4033             case(e_FM_EX_BMI_STATISTICS_RAM_ECC):
4034                tmpReg = GET_UINT32(p_Fm->p_FmBmiRegs->fmbm_ier);
4035                if(enable)
4036                    tmpReg |= BMI_ERR_INTR_EN_STATISTICS_RAM_ECC;
4037                else
4038                    tmpReg &= ~BMI_ERR_INTR_EN_STATISTICS_RAM_ECC;
4039                WRITE_UINT32(p_Fm->p_FmBmiRegs->fmbm_ier, tmpReg);
4040                break;
4041             case(e_FM_EX_BMI_DISPATCH_RAM_ECC):
4042               tmpReg = GET_UINT32(p_Fm->p_FmBmiRegs->fmbm_ier);
4043               if(enable)
4044               {
4045#ifdef FM_NO_DISPATCH_RAM_ECC
4046                   t_FmRevisionInfo     revInfo;
4047                   FM_GetRevision(p_Fm, &revInfo);
4048                   if (revInfo.majorRev != 4)
4049                   {
4050                       REPORT_ERROR(MINOR, E_NOT_SUPPORTED, ("e_FM_EX_BMI_DISPATCH_RAM_ECC"));
4051                       return E_OK;
4052                   }
4053#endif /* FM_NO_DISPATCH_RAM_ECC */
4054                   tmpReg |= BMI_ERR_INTR_EN_DISPATCH_RAM_ECC;
4055               }
4056               else
4057                   tmpReg &= ~BMI_ERR_INTR_EN_DISPATCH_RAM_ECC;
4058               WRITE_UINT32(p_Fm->p_FmBmiRegs->fmbm_ier, tmpReg);
4059               break;
4060             case(e_FM_EX_IRAM_ECC):
4061                 tmpReg = GET_UINT32(p_Fm->p_FmFpmRegs->fmrie);
4062                if(enable)
4063                {
4064                    /* enable ECC if not enabled */
4065                    FmEnableRamsEcc(p_Fm);
4066                    /* enable ECC interrupts */
4067                    tmpReg |= FPM_IRAM_ECC_ERR_EX_EN;
4068                }
4069                else
4070                {
4071                    /* ECC mechanism may be disabled, depending on driver status  */
4072                    FmDisableRamsEcc(p_Fm);
4073                    tmpReg &= ~FPM_IRAM_ECC_ERR_EX_EN;
4074                }
4075                WRITE_UINT32(p_Fm->p_FmFpmRegs->fmrie, tmpReg);
4076                break;
4077
4078             case(e_FM_EX_MURAM_ECC):
4079                tmpReg = GET_UINT32(p_Fm->p_FmFpmRegs->fmrie);
4080                if(enable)
4081                {
4082                    /* enable ECC if not enabled */
4083                    FmEnableRamsEcc(p_Fm);
4084                    /* enable ECC interrupts */
4085                    tmpReg |= FPM_MURAM_ECC_ERR_EX_EN;
4086                }
4087                else
4088                {
4089                    /* ECC mechanism may be disabled, depending on driver status  */
4090                    FmDisableRamsEcc(p_Fm);
4091                    tmpReg &= ~FPM_MURAM_ECC_ERR_EX_EN;
4092                }
4093
4094                WRITE_UINT32(p_Fm->p_FmFpmRegs->fmrie, tmpReg);
4095                break;
4096            default:
4097                RETURN_ERROR(MINOR, E_INVALID_SELECTION, NO_MSG);
4098        }
4099    }
4100    else
4101        RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined exception"));
4102
4103    return E_OK;
4104}
4105
4106t_Error FM_GetRevision(t_Handle h_Fm, t_FmRevisionInfo *p_FmRevisionInfo)
4107{
4108    t_Fm                *p_Fm = (t_Fm*)h_Fm;
4109    uint32_t            tmpReg;
4110    t_Error             err;
4111    t_FmIpcMsg          msg;
4112    t_FmIpcReply        reply;
4113    uint32_t            replyLength;
4114    t_FmIpcRevisionInfo ipcRevInfo;
4115
4116    SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
4117
4118    if (p_Fm->guestId != NCSW_MASTER_ID)
4119    {
4120        memset(&msg, 0, sizeof(msg));
4121        memset(&reply, 0, sizeof(reply));
4122        msg.msgId = FM_GET_REV;
4123        replyLength = sizeof(uint32_t) + sizeof(t_FmRevisionInfo);
4124        if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
4125                                     (uint8_t*)&msg,
4126                                     sizeof(msg.msgId),
4127                                     (uint8_t*)&reply,
4128                                     &replyLength,
4129                                     NULL,
4130                                     NULL)) != E_OK)
4131            RETURN_ERROR(MINOR, err, NO_MSG);
4132        if (replyLength != (sizeof(uint32_t) + sizeof(t_FmRevisionInfo)))
4133            RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
4134        memcpy((uint8_t*)&ipcRevInfo, reply.replyBody, sizeof(t_FmRevisionInfo));
4135        p_FmRevisionInfo->majorRev = ipcRevInfo.majorRev;
4136        p_FmRevisionInfo->minorRev = ipcRevInfo.minorRev;
4137        return (t_Error)(reply.error);
4138    }
4139
4140    /* read revision register 1 */
4141    tmpReg = GET_UINT32(p_Fm->p_FmFpmRegs->fm_ip_rev_1);
4142    p_FmRevisionInfo->majorRev = (uint8_t)((tmpReg & FPM_REV1_MAJOR_MASK) >> FPM_REV1_MAJOR_SHIFT);
4143    p_FmRevisionInfo->minorRev = (uint8_t)((tmpReg & FPM_REV1_MINOR_MASK) >> FPM_REV1_MINOR_SHIFT);
4144
4145    return E_OK;
4146}
4147
4148uint32_t FM_GetCounter(t_Handle h_Fm, e_FmCounters counter)
4149{
4150    t_Fm                *p_Fm = (t_Fm*)h_Fm;
4151    t_Error             err;
4152    uint32_t            counterValue;
4153    t_FmIpcMsg          msg;
4154    t_FmIpcReply        reply;
4155    uint32_t            replyLength, outCounter;
4156
4157    SANITY_CHECK_RETURN_VALUE(p_Fm, E_INVALID_HANDLE, 0);
4158    SANITY_CHECK_RETURN_VALUE(!p_Fm->p_FmDriverParam, E_INVALID_STATE, 0);
4159
4160
4161    if(p_Fm->guestId != NCSW_MASTER_ID)
4162    {
4163        memset(&msg, 0, sizeof(msg));
4164        memset(&reply, 0, sizeof(reply));
4165        msg.msgId = FM_GET_COUNTER;
4166        memcpy(msg.msgBody, (uint8_t *)&counter, sizeof(uint32_t));
4167        replyLength = sizeof(uint32_t) + sizeof(uint32_t);
4168        if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
4169                                     (uint8_t*)&msg,
4170                                     sizeof(msg.msgId) +sizeof(counterValue),
4171                                     (uint8_t*)&reply,
4172                                     &replyLength,
4173                                     NULL,
4174                                     NULL)) != E_OK)
4175            RETURN_ERROR(MAJOR, err, NO_MSG);
4176        if(replyLength != (sizeof(uint32_t) + sizeof(uint32_t)))
4177            RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
4178        memcpy((uint8_t*)&outCounter, reply.replyBody, sizeof(uint32_t));
4179
4180        return outCounter;
4181     }
4182
4183    switch(counter)
4184    {
4185        case(e_FM_COUNTERS_ENQ_TOTAL_FRAME):
4186            return GET_UINT32(p_Fm->p_FmQmiRegs->fmqm_etfc);
4187        case(e_FM_COUNTERS_DEQ_TOTAL_FRAME):
4188            return GET_UINT32(p_Fm->p_FmQmiRegs->fmqm_dtfc);
4189        case(e_FM_COUNTERS_DEQ_0):
4190            return GET_UINT32(p_Fm->p_FmQmiRegs->fmqm_dc0);
4191        case(e_FM_COUNTERS_DEQ_1):
4192            return GET_UINT32(p_Fm->p_FmQmiRegs->fmqm_dc1);
4193        case(e_FM_COUNTERS_DEQ_2):
4194            return GET_UINT32(p_Fm->p_FmQmiRegs->fmqm_dc2);
4195        case(e_FM_COUNTERS_DEQ_3):
4196            return GET_UINT32(p_Fm->p_FmQmiRegs->fmqm_dc3);
4197        case(e_FM_COUNTERS_DEQ_FROM_DEFAULT):
4198            return GET_UINT32(p_Fm->p_FmQmiRegs->fmqm_dfdc);
4199        case(e_FM_COUNTERS_DEQ_FROM_CONTEXT):
4200            return GET_UINT32(p_Fm->p_FmQmiRegs->fmqm_dfcc);
4201        case(e_FM_COUNTERS_DEQ_FROM_FD):
4202            return GET_UINT32(p_Fm->p_FmQmiRegs->fmqm_dffc);
4203        case(e_FM_COUNTERS_DEQ_CONFIRM):
4204            return GET_UINT32(p_Fm->p_FmQmiRegs->fmqm_dcc);
4205        case(e_FM_COUNTERS_SEMAPHOR_ENTRY_FULL_REJECT):
4206            return GET_UINT32(p_Fm->p_FmDmaRegs->fmdmsefrc);
4207        case(e_FM_COUNTERS_SEMAPHOR_QUEUE_FULL_REJECT):
4208            return GET_UINT32(p_Fm->p_FmDmaRegs->fmdmsqfrc);
4209        case(e_FM_COUNTERS_SEMAPHOR_SYNC_REJECT):
4210            return GET_UINT32(p_Fm->p_FmDmaRegs->fmdmssrc);
4211        default:
4212            break;
4213    }
4214    /* should never get here */
4215    ASSERT_COND(FALSE);
4216
4217    return 0;
4218}
4219
4220t_Error  FM_ModifyCounter(t_Handle h_Fm, e_FmCounters counter, uint32_t val)
4221{
4222    t_Fm *p_Fm = (t_Fm*)h_Fm;
4223
4224   SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
4225   SANITY_CHECK_RETURN_ERROR(!p_Fm->p_FmDriverParam, E_INVALID_STATE);
4226
4227    /* When applicable (when there is an 'enable counters' bit,
4228    check that counters are enabled */
4229    switch(counter)
4230    {
4231        case(e_FM_COUNTERS_ENQ_TOTAL_FRAME):
4232        case(e_FM_COUNTERS_DEQ_TOTAL_FRAME):
4233        case(e_FM_COUNTERS_DEQ_0):
4234        case(e_FM_COUNTERS_DEQ_1):
4235        case(e_FM_COUNTERS_DEQ_2):
4236        case(e_FM_COUNTERS_DEQ_3):
4237        case(e_FM_COUNTERS_DEQ_FROM_DEFAULT):
4238        case(e_FM_COUNTERS_DEQ_FROM_CONTEXT):
4239        case(e_FM_COUNTERS_DEQ_FROM_FD):
4240        case(e_FM_COUNTERS_DEQ_CONFIRM):
4241            if(!(GET_UINT32(p_Fm->p_FmQmiRegs->fmqm_gc) & QMI_CFG_EN_COUNTERS))
4242                RETURN_ERROR(MINOR, E_INVALID_STATE, ("Requested counter was not enabled"));
4243            break;
4244        default:
4245            break;
4246    }
4247
4248    /* Set counter */
4249    switch(counter)
4250    {
4251        case(e_FM_COUNTERS_ENQ_TOTAL_FRAME):
4252            WRITE_UINT32(p_Fm->p_FmQmiRegs->fmqm_etfc, val);
4253            break;
4254        case(e_FM_COUNTERS_DEQ_TOTAL_FRAME):
4255            WRITE_UINT32(p_Fm->p_FmQmiRegs->fmqm_dtfc, val);
4256            break;
4257        case(e_FM_COUNTERS_DEQ_0):
4258            WRITE_UINT32(p_Fm->p_FmQmiRegs->fmqm_dc0, val);
4259            break;
4260        case(e_FM_COUNTERS_DEQ_1):
4261            WRITE_UINT32(p_Fm->p_FmQmiRegs->fmqm_dc1, val);
4262            break;
4263        case(e_FM_COUNTERS_DEQ_2):
4264            WRITE_UINT32(p_Fm->p_FmQmiRegs->fmqm_dc2, val);
4265            break;
4266        case(e_FM_COUNTERS_DEQ_3):
4267            WRITE_UINT32(p_Fm->p_FmQmiRegs->fmqm_dc3, val);
4268            break;
4269        case(e_FM_COUNTERS_DEQ_FROM_DEFAULT):
4270            WRITE_UINT32(p_Fm->p_FmQmiRegs->fmqm_dfdc, val);
4271            break;
4272        case(e_FM_COUNTERS_DEQ_FROM_CONTEXT):
4273            WRITE_UINT32(p_Fm->p_FmQmiRegs->fmqm_dfcc, val);
4274            break;
4275        case(e_FM_COUNTERS_DEQ_FROM_FD):
4276            WRITE_UINT32(p_Fm->p_FmQmiRegs->fmqm_dffc, val);
4277            break;
4278        case(e_FM_COUNTERS_DEQ_CONFIRM):
4279            WRITE_UINT32(p_Fm->p_FmQmiRegs->fmqm_dcc, val);
4280            break;
4281        case(e_FM_COUNTERS_SEMAPHOR_ENTRY_FULL_REJECT):
4282            WRITE_UINT32(p_Fm->p_FmDmaRegs->fmdmsefrc, val);
4283            break;
4284        case(e_FM_COUNTERS_SEMAPHOR_QUEUE_FULL_REJECT):
4285            WRITE_UINT32(p_Fm->p_FmDmaRegs->fmdmsqfrc, val);
4286            break;
4287        case(e_FM_COUNTERS_SEMAPHOR_SYNC_REJECT):
4288            WRITE_UINT32(p_Fm->p_FmDmaRegs->fmdmssrc, val);
4289            break;
4290        default:
4291            break;
4292    }
4293
4294    return E_OK;
4295}
4296
4297void FM_SetDmaEmergency(t_Handle h_Fm, e_FmDmaMuramPort muramPort, bool enable)
4298{
4299    t_Fm *p_Fm = (t_Fm*)h_Fm;
4300    uint32_t    bitMask;
4301
4302    SANITY_CHECK_RETURN(p_Fm, E_INVALID_HANDLE);
4303    SANITY_CHECK_RETURN(!p_Fm->p_FmDriverParam, E_INVALID_STATE);
4304
4305    bitMask = (uint32_t)((muramPort==e_FM_DMA_MURAM_PORT_WRITE) ? DMA_MODE_EMERGENCY_WRITE : DMA_MODE_EMERGENCY_READ);
4306
4307    if(enable)
4308        WRITE_UINT32(p_Fm->p_FmDmaRegs->fmdmmr, GET_UINT32(p_Fm->p_FmDmaRegs->fmdmmr) | bitMask);
4309    else /* disable */
4310        WRITE_UINT32(p_Fm->p_FmDmaRegs->fmdmmr, GET_UINT32(p_Fm->p_FmDmaRegs->fmdmmr) & ~bitMask);
4311
4312    return;
4313}
4314
4315void FM_SetDmaExtBusPri(t_Handle h_Fm, e_FmDmaExtBusPri pri)
4316{
4317    t_Fm *p_Fm = (t_Fm*)h_Fm;
4318
4319    SANITY_CHECK_RETURN(p_Fm, E_INVALID_HANDLE);
4320    SANITY_CHECK_RETURN(!p_Fm->p_FmDriverParam, E_INVALID_STATE);
4321
4322    WRITE_UINT32(p_Fm->p_FmDmaRegs->fmdmmr, GET_UINT32(p_Fm->p_FmDmaRegs->fmdmmr) | ((uint32_t)pri << DMA_MODE_BUS_PRI_SHIFT) );
4323
4324    return;
4325}
4326
4327void FM_GetDmaStatus(t_Handle h_Fm, t_FmDmaStatus *p_FmDmaStatus)
4328{
4329    t_Fm                *p_Fm = (t_Fm*)h_Fm;
4330    uint32_t            tmpReg;
4331    t_Error             err;
4332    t_FmIpcMsg          msg;
4333    t_FmIpcReply        reply;
4334    uint32_t            replyLength;
4335    t_FmIpcDmaStatus    ipcDmaStatus;
4336
4337    SANITY_CHECK_RETURN(p_Fm, E_INVALID_HANDLE);
4338    SANITY_CHECK_RETURN(!p_Fm->p_FmDriverParam, E_INVALID_STATE);
4339
4340    if(p_Fm->guestId != NCSW_MASTER_ID)
4341    {
4342        memset(&msg, 0, sizeof(msg));
4343        memset(&reply, 0, sizeof(reply));
4344        msg.msgId = FM_DMA_STAT;
4345        replyLength = sizeof(uint32_t) + sizeof(t_FmIpcDmaStatus);
4346        if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
4347                                     (uint8_t*)&msg,
4348                                     sizeof(msg.msgId),
4349                                     (uint8_t*)&reply,
4350                                     &replyLength,
4351                                     NULL,
4352                                     NULL)) != E_OK)
4353        {
4354            REPORT_ERROR(MINOR, err, NO_MSG);
4355            return;
4356        }
4357        if (replyLength != (sizeof(uint32_t) + sizeof(t_FmIpcDmaStatus)))
4358        {
4359            REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
4360            return;
4361        }
4362        memcpy((uint8_t*)&ipcDmaStatus, reply.replyBody, sizeof(t_FmIpcDmaStatus));
4363
4364        p_FmDmaStatus->cmqNotEmpty = (bool)ipcDmaStatus.boolCmqNotEmpty;            /**< Command queue is not empty */
4365        p_FmDmaStatus->busError = (bool)ipcDmaStatus.boolBusError;                  /**< Bus error occurred */
4366        p_FmDmaStatus->readBufEccError = (bool)ipcDmaStatus.boolReadBufEccError;        /**< Double ECC error on buffer Read */
4367        p_FmDmaStatus->writeBufEccSysError =(bool)ipcDmaStatus.boolWriteBufEccSysError;    /**< Double ECC error on buffer write from system side */
4368        p_FmDmaStatus->writeBufEccFmError = (bool)ipcDmaStatus.boolWriteBufEccFmError;     /**< Double ECC error on buffer write from FM side */
4369        return;
4370    }
4371
4372    tmpReg = GET_UINT32(p_Fm->p_FmDmaRegs->fmdmsr);
4373
4374    p_FmDmaStatus->cmqNotEmpty = (bool)(tmpReg & DMA_STATUS_CMD_QUEUE_NOT_EMPTY);
4375    p_FmDmaStatus->busError = (bool)(tmpReg & DMA_STATUS_BUS_ERR);
4376    p_FmDmaStatus->readBufEccError = (bool)(tmpReg & DMA_STATUS_READ_ECC);
4377    p_FmDmaStatus->writeBufEccSysError = (bool)(tmpReg & DMA_STATUS_SYSTEM_WRITE_ECC);
4378    p_FmDmaStatus->writeBufEccFmError = (bool)(tmpReg & DMA_STATUS_FM_WRITE_ECC);
4379    return;
4380}
4381
4382t_Error FM_ForceIntr (t_Handle h_Fm, e_FmExceptions exception)
4383{
4384    t_Fm *p_Fm = (t_Fm*)h_Fm;
4385
4386    SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
4387    SANITY_CHECK_RETURN_ERROR(!p_Fm->p_FmDriverParam, E_INVALID_STATE);
4388
4389    switch(exception)
4390    {
4391        case e_FM_EX_QMI_DEQ_FROM_UNKNOWN_PORTID:
4392            if (!(p_Fm->p_FmStateStruct->exceptions & FM_EX_QMI_DEQ_FROM_UNKNOWN_PORTID))
4393                RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked"));
4394            WRITE_UINT32(p_Fm->p_FmQmiRegs->fmqm_eif, QMI_ERR_INTR_EN_DEQ_FROM_DEF);
4395            break;
4396        case e_FM_EX_QMI_SINGLE_ECC:
4397            if (!(p_Fm->p_FmStateStruct->exceptions & FM_EX_QMI_SINGLE_ECC))
4398                RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked"));
4399            WRITE_UINT32(p_Fm->p_FmQmiRegs->fmqm_if, QMI_INTR_EN_SINGLE_ECC);
4400            break;
4401        case e_FM_EX_QMI_DOUBLE_ECC:
4402            if (!(p_Fm->p_FmStateStruct->exceptions & FM_EX_QMI_DOUBLE_ECC))
4403                RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked"));
4404            WRITE_UINT32(p_Fm->p_FmQmiRegs->fmqm_eif, QMI_ERR_INTR_EN_DOUBLE_ECC);
4405            break;
4406        case e_FM_EX_BMI_LIST_RAM_ECC:
4407            if (!(p_Fm->p_FmStateStruct->exceptions & FM_EX_BMI_LIST_RAM_ECC))
4408                RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked"));
4409            WRITE_UINT32(p_Fm->p_FmBmiRegs->fmbm_ifr, BMI_ERR_INTR_EN_LIST_RAM_ECC);
4410            break;
4411        case e_FM_EX_BMI_PIPELINE_ECC:
4412            if (!(p_Fm->p_FmStateStruct->exceptions & FM_EX_BMI_PIPELINE_ECC))
4413                RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked"));
4414            WRITE_UINT32(p_Fm->p_FmBmiRegs->fmbm_ifr, BMI_ERR_INTR_EN_PIPELINE_ECC);
4415            break;
4416        case e_FM_EX_BMI_STATISTICS_RAM_ECC:
4417            if (!(p_Fm->p_FmStateStruct->exceptions & FM_EX_BMI_STATISTICS_RAM_ECC))
4418                RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked"));
4419            WRITE_UINT32(p_Fm->p_FmBmiRegs->fmbm_ifr, BMI_ERR_INTR_EN_STATISTICS_RAM_ECC);
4420            break;
4421        case e_FM_EX_BMI_DISPATCH_RAM_ECC:
4422            if (!(p_Fm->p_FmStateStruct->exceptions & FM_EX_BMI_DISPATCH_RAM_ECC))
4423                RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked"));
4424            WRITE_UINT32(p_Fm->p_FmBmiRegs->fmbm_ifr, BMI_ERR_INTR_EN_DISPATCH_RAM_ECC);
4425            break;
4426        default:
4427            RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception may not be forced"));
4428    }
4429
4430    return E_OK;
4431}
4432
4433void FM_Resume(t_Handle h_Fm)
4434{
4435    t_Fm            *p_Fm = (t_Fm*)h_Fm;
4436    uint32_t        tmpReg;
4437
4438    SANITY_CHECK_RETURN(p_Fm, E_INVALID_HANDLE);
4439    SANITY_CHECK_RETURN(!p_Fm->p_FmDriverParam, E_INVALID_STATE);
4440
4441    if (p_Fm->guestId == NCSW_MASTER_ID)
4442    {
4443        tmpReg  = GET_UINT32(p_Fm->p_FmFpmRegs->fpmem);
4444        /* clear tmpReg event bits in order not to clear standing events */
4445        tmpReg &= ~(FPM_EV_MASK_DOUBLE_ECC | FPM_EV_MASK_STALL | FPM_EV_MASK_SINGLE_ECC);
4446        WRITE_UINT32(p_Fm->p_FmFpmRegs->fpmem, tmpReg | FPM_EV_MASK_RELEASE_FM);
4447    }
4448    else
4449        ASSERT_COND(0); /* TODO */
4450}
4451
4452#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
4453t_Error FM_DumpRegs(t_Handle h_Fm)
4454{
4455    t_Fm            *p_Fm = (t_Fm *)h_Fm;
4456    uint8_t         i = 0;
4457    t_Error         err;
4458    t_FmIpcMsg      msg;
4459
4460    DECLARE_DUMP;
4461
4462    SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
4463    SANITY_CHECK_RETURN_ERROR(!p_Fm->p_FmDriverParam, E_INVALID_STATE);
4464
4465
4466    if(p_Fm->guestId != NCSW_MASTER_ID)
4467    {
4468        memset(&msg, 0, sizeof(msg));
4469        msg.msgId = FM_DUMP_REGS;
4470        if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
4471                                    (uint8_t*)&msg,
4472                                    sizeof(msg.msgId),
4473                                    NULL,
4474                                    NULL,
4475                                    NULL,
4476                                    NULL)) != E_OK)
4477            RETURN_ERROR(MINOR, err, NO_MSG);
4478        return E_OK;
4479    }
4480
4481
4482    DUMP_SUBTITLE(("\n"));
4483
4484    DUMP_TITLE(p_Fm->p_FmFpmRegs, ("FmFpmRegs Regs"));
4485
4486    DUMP_VAR(p_Fm->p_FmFpmRegs,fpmtnc);
4487    DUMP_VAR(p_Fm->p_FmFpmRegs,fpmpr);
4488    DUMP_VAR(p_Fm->p_FmFpmRegs,brkc);
4489    DUMP_VAR(p_Fm->p_FmFpmRegs,fpmflc);
4490    DUMP_VAR(p_Fm->p_FmFpmRegs,fpmdis1);
4491    DUMP_VAR(p_Fm->p_FmFpmRegs,fpmdis2);
4492    DUMP_VAR(p_Fm->p_FmFpmRegs,fmepi);
4493    DUMP_VAR(p_Fm->p_FmFpmRegs,fmrie);
4494
4495    DUMP_TITLE(&p_Fm->p_FmFpmRegs->fmfpfcev, ("fmfpfcev"));
4496    DUMP_SUBSTRUCT_ARRAY(i, 4)
4497    {
4498        DUMP_MEMORY(&p_Fm->p_FmFpmRegs->fmfpfcev[i], sizeof(uint32_t));
4499    }
4500
4501    DUMP_TITLE(&p_Fm->p_FmFpmRegs->fmfpfcee, ("fmfpfcee"));
4502    DUMP_SUBSTRUCT_ARRAY(i, 4)
4503    {
4504        DUMP_MEMORY(&p_Fm->p_FmFpmRegs->fmfpfcee[i], sizeof(uint32_t));
4505    }
4506
4507    DUMP_SUBTITLE(("\n"));
4508    DUMP_VAR(p_Fm->p_FmFpmRegs,fpmtsc1);
4509    DUMP_VAR(p_Fm->p_FmFpmRegs,fpmtsc2);
4510    DUMP_VAR(p_Fm->p_FmFpmRegs,fpmtsp);
4511    DUMP_VAR(p_Fm->p_FmFpmRegs,fpmtsf);
4512    DUMP_VAR(p_Fm->p_FmFpmRegs,fmrcr);
4513    DUMP_VAR(p_Fm->p_FmFpmRegs,fpmextc);
4514    DUMP_VAR(p_Fm->p_FmFpmRegs,fpmext1);
4515    DUMP_VAR(p_Fm->p_FmFpmRegs,fpmext2);
4516
4517    DUMP_TITLE(&p_Fm->p_FmFpmRegs->fpmdrd, ("fpmdrd"));
4518    DUMP_SUBSTRUCT_ARRAY(i, 16)
4519    {
4520        DUMP_MEMORY(&p_Fm->p_FmFpmRegs->fpmdrd[i], sizeof(uint32_t));
4521    }
4522
4523    DUMP_SUBTITLE(("\n"));
4524    DUMP_VAR(p_Fm->p_FmFpmRegs,fpmdra);
4525    DUMP_VAR(p_Fm->p_FmFpmRegs,fm_ip_rev_1);
4526    DUMP_VAR(p_Fm->p_FmFpmRegs,fm_ip_rev_2);
4527    DUMP_VAR(p_Fm->p_FmFpmRegs,fmrstc);
4528    DUMP_VAR(p_Fm->p_FmFpmRegs,fmcld);
4529    DUMP_VAR(p_Fm->p_FmFpmRegs,fmnpi);
4530    DUMP_VAR(p_Fm->p_FmFpmRegs,fpmem);
4531
4532    DUMP_TITLE(&p_Fm->p_FmFpmRegs->fpmcev, ("fpmcev"));
4533    DUMP_SUBSTRUCT_ARRAY(i, 4)
4534    {
4535        DUMP_MEMORY(&p_Fm->p_FmFpmRegs->fpmcev[i], sizeof(uint32_t));
4536    }
4537
4538    DUMP_TITLE(&p_Fm->p_FmFpmRegs->fmfp_ps, ("fmfp_ps"));
4539    DUMP_SUBSTRUCT_ARRAY(i, 64)
4540    {
4541        DUMP_MEMORY(&p_Fm->p_FmFpmRegs->fmfp_ps[i], sizeof(uint32_t));
4542    }
4543
4544
4545    DUMP_TITLE(p_Fm->p_FmDmaRegs, ("p_FmDmaRegs Regs"));
4546    DUMP_VAR(p_Fm->p_FmDmaRegs,fmdmsr);
4547    DUMP_VAR(p_Fm->p_FmDmaRegs,fmdmmr);
4548    DUMP_VAR(p_Fm->p_FmDmaRegs,fmdmtr);
4549    DUMP_VAR(p_Fm->p_FmDmaRegs,fmdmhy);
4550    DUMP_VAR(p_Fm->p_FmDmaRegs,fmdmsetr);
4551    DUMP_VAR(p_Fm->p_FmDmaRegs,fmdmtah);
4552    DUMP_VAR(p_Fm->p_FmDmaRegs,fmdmtal);
4553    DUMP_VAR(p_Fm->p_FmDmaRegs,fmdmtcid);
4554    DUMP_VAR(p_Fm->p_FmDmaRegs,fmdmra);
4555    DUMP_VAR(p_Fm->p_FmDmaRegs,fmdmrd);
4556    DUMP_VAR(p_Fm->p_FmDmaRegs,fmdmwcr);
4557    DUMP_VAR(p_Fm->p_FmDmaRegs,fmdmebcr);
4558    DUMP_VAR(p_Fm->p_FmDmaRegs,fmdmccqdr);
4559    DUMP_VAR(p_Fm->p_FmDmaRegs,fmdmccqvr1);
4560    DUMP_VAR(p_Fm->p_FmDmaRegs,fmdmccqvr2);
4561    DUMP_VAR(p_Fm->p_FmDmaRegs,fmdmcqvr3);
4562    DUMP_VAR(p_Fm->p_FmDmaRegs,fmdmcqvr4);
4563    DUMP_VAR(p_Fm->p_FmDmaRegs,fmdmcqvr5);
4564    DUMP_VAR(p_Fm->p_FmDmaRegs,fmdmsefrc);
4565    DUMP_VAR(p_Fm->p_FmDmaRegs,fmdmsqfrc);
4566    DUMP_VAR(p_Fm->p_FmDmaRegs,fmdmssrc);
4567    DUMP_VAR(p_Fm->p_FmDmaRegs,fmdmdcr);
4568
4569    DUMP_TITLE(&p_Fm->p_FmDmaRegs->fmdmplr, ("fmdmplr"));
4570
4571    DUMP_SUBSTRUCT_ARRAY(i, FM_SIZE_OF_LIODN_TABLE/2)
4572    {
4573        DUMP_MEMORY(&p_Fm->p_FmDmaRegs->fmdmplr[i], sizeof(uint32_t));
4574    }
4575
4576    DUMP_TITLE(p_Fm->p_FmBmiRegs, ("p_FmBmiRegs COMMON Regs"));
4577    DUMP_VAR(p_Fm->p_FmBmiRegs,fmbm_init);
4578    DUMP_VAR(p_Fm->p_FmBmiRegs,fmbm_cfg1);
4579    DUMP_VAR(p_Fm->p_FmBmiRegs,fmbm_cfg2);
4580    DUMP_VAR(p_Fm->p_FmBmiRegs,fmbm_ievr);
4581    DUMP_VAR(p_Fm->p_FmBmiRegs,fmbm_ier);
4582
4583    DUMP_TITLE(&p_Fm->p_FmBmiRegs->fmbm_arb, ("fmbm_arb"));
4584    DUMP_SUBSTRUCT_ARRAY(i, 8)
4585    {
4586        DUMP_MEMORY(&p_Fm->p_FmBmiRegs->fmbm_arb[i], sizeof(uint32_t));
4587    }
4588
4589
4590    DUMP_TITLE(p_Fm->p_FmQmiRegs, ("p_FmQmiRegs COMMON Regs"));
4591    DUMP_VAR(p_Fm->p_FmQmiRegs,fmqm_gc);
4592    DUMP_VAR(p_Fm->p_FmQmiRegs,fmqm_eie);
4593    DUMP_VAR(p_Fm->p_FmQmiRegs,fmqm_eien);
4594    DUMP_VAR(p_Fm->p_FmQmiRegs,fmqm_eif);
4595    DUMP_VAR(p_Fm->p_FmQmiRegs,fmqm_ie);
4596    DUMP_VAR(p_Fm->p_FmQmiRegs,fmqm_ien);
4597    DUMP_VAR(p_Fm->p_FmQmiRegs,fmqm_if);
4598    DUMP_VAR(p_Fm->p_FmQmiRegs,fmqm_gs);
4599    DUMP_VAR(p_Fm->p_FmQmiRegs,fmqm_ts);
4600    DUMP_VAR(p_Fm->p_FmQmiRegs,fmqm_etfc);
4601
4602    return E_OK;
4603}
4604#endif /* (defined(DEBUG_ERRORS) && ... */
4605
4606