mirror of https://github.com/F-Stack/f-stack.git
4606 lines
175 KiB
C
4606 lines
175 KiB
C
/* Copyright (c) 2008-2011 Freescale Semiconductor, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without
|
|
* modification, are permitted provided that the following conditions are met:
|
|
* * Redistributions of source code must retain the above copyright
|
|
* notice, this list of conditions and the following disclaimer.
|
|
* * Redistributions in binary form must reproduce the above copyright
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
* documentation and/or other materials provided with the distribution.
|
|
* * Neither the name of Freescale Semiconductor nor the
|
|
* names of its contributors may be used to endorse or promote products
|
|
* derived from this software without specific prior written permission.
|
|
*
|
|
*
|
|
* ALTERNATIVELY, this software may be distributed under the terms of the
|
|
* GNU General Public License ("GPL") as published by the Free Software
|
|
* Foundation, either version 2 of that License or (at your option) any
|
|
* later version.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
|
|
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
* DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
|
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
*/
|
|
|
|
/******************************************************************************
|
|
@File fm.c
|
|
|
|
@Description FM driver routines implementation.
|
|
*//***************************************************************************/
|
|
#include "std_ext.h"
|
|
#include "error_ext.h"
|
|
#include "xx_ext.h"
|
|
#include "string_ext.h"
|
|
#include "sprint_ext.h"
|
|
#include "debug_ext.h"
|
|
#include "fm_muram_ext.h"
|
|
|
|
#include "fm_common.h"
|
|
#include "fm_ipc.h"
|
|
#include "fm.h"
|
|
|
|
|
|
/****************************************/
|
|
/* static functions */
|
|
/****************************************/
|
|
|
|
static volatile bool blockingFlag = FALSE;
|
|
static void IpcMsgCompletionCB(t_Handle h_Fm,
|
|
uint8_t *p_Msg,
|
|
uint8_t *p_Reply,
|
|
uint32_t replyLength,
|
|
t_Error status)
|
|
{
|
|
UNUSED(h_Fm);UNUSED(p_Msg);UNUSED(p_Reply);UNUSED(replyLength);UNUSED(status);
|
|
blockingFlag = FALSE;
|
|
}
|
|
|
|
static bool IsFmanCtrlCodeLoaded(t_Fm *p_Fm)
|
|
{
|
|
t_FMIramRegs *p_Iram;
|
|
|
|
ASSERT_COND(p_Fm);
|
|
p_Iram = (t_FMIramRegs *)UINT_TO_PTR(p_Fm->baseAddr + FM_MM_IMEM);
|
|
|
|
return (bool)!!(GET_UINT32(p_Iram->iready) & IRAM_READY);
|
|
}
|
|
|
|
static t_Error CheckFmParameters(t_Fm *p_Fm)
|
|
{
|
|
if (IsFmanCtrlCodeLoaded(p_Fm) && !p_Fm->p_FmDriverParam->resetOnInit)
|
|
RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Old FMan CTRL code is loaded; FM must be reset!"));
|
|
if(!p_Fm->p_FmDriverParam->dmaAxiDbgNumOfBeats || (p_Fm->p_FmDriverParam->dmaAxiDbgNumOfBeats > DMA_MODE_MAX_AXI_DBG_NUM_OF_BEATS))
|
|
RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("axiDbgNumOfBeats has to be in the range 1 - %d", DMA_MODE_MAX_AXI_DBG_NUM_OF_BEATS));
|
|
if(p_Fm->p_FmDriverParam->dmaCamNumOfEntries % DMA_CAM_UNITS)
|
|
RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dmaCamNumOfEntries has to be divisble by %d", DMA_CAM_UNITS));
|
|
if(!p_Fm->p_FmDriverParam->dmaCamNumOfEntries || (p_Fm->p_FmDriverParam->dmaCamNumOfEntries > DMA_MODE_MAX_CAM_NUM_OF_ENTRIES))
|
|
RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dmaCamNumOfEntries has to be in the range 1 - %d", DMA_MODE_MAX_CAM_NUM_OF_ENTRIES));
|
|
if(p_Fm->p_FmDriverParam->dmaCommQThresholds.assertEmergency > DMA_THRESH_MAX_COMMQ)
|
|
RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dmaCommQThresholds.assertEmergency can not be larger than %d", DMA_THRESH_MAX_COMMQ));
|
|
if(p_Fm->p_FmDriverParam->dmaCommQThresholds.clearEmergency > DMA_THRESH_MAX_COMMQ)
|
|
RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dmaCommQThresholds.clearEmergency can not be larger than %d", DMA_THRESH_MAX_COMMQ));
|
|
if(p_Fm->p_FmDriverParam->dmaCommQThresholds.clearEmergency >= p_Fm->p_FmDriverParam->dmaCommQThresholds.assertEmergency)
|
|
RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dmaCommQThresholds.clearEmergency must be smaller than dmaCommQThresholds.assertEmergency"));
|
|
if(p_Fm->p_FmDriverParam->dmaReadBufThresholds.assertEmergency > DMA_THRESH_MAX_BUF)
|
|
RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dmaReadBufThresholds.assertEmergency can not be larger than %d", DMA_THRESH_MAX_BUF));
|
|
if(p_Fm->p_FmDriverParam->dmaReadBufThresholds.clearEmergency > DMA_THRESH_MAX_BUF)
|
|
RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dmaReadBufThresholds.clearEmergency can not be larger than %d", DMA_THRESH_MAX_BUF));
|
|
if(p_Fm->p_FmDriverParam->dmaReadBufThresholds.clearEmergency >= p_Fm->p_FmDriverParam->dmaReadBufThresholds.assertEmergency)
|
|
RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dmaReadBufThresholds.clearEmergency must be smaller than dmaReadBufThresholds.assertEmergency"));
|
|
if(p_Fm->p_FmDriverParam->dmaWriteBufThresholds.assertEmergency > DMA_THRESH_MAX_BUF)
|
|
RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dmaWriteBufThresholds.assertEmergency can not be larger than %d", DMA_THRESH_MAX_BUF));
|
|
if(p_Fm->p_FmDriverParam->dmaWriteBufThresholds.clearEmergency > DMA_THRESH_MAX_BUF)
|
|
RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dmaWriteBufThresholds.clearEmergency can not be larger than %d", DMA_THRESH_MAX_BUF));
|
|
if(p_Fm->p_FmDriverParam->dmaWriteBufThresholds.clearEmergency >= p_Fm->p_FmDriverParam->dmaWriteBufThresholds.assertEmergency)
|
|
RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dmaWriteBufThresholds.clearEmergency must be smaller than dmaWriteBufThresholds.assertEmergency"));
|
|
|
|
if(!p_Fm->p_FmStateStruct->fmClkFreq)
|
|
RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fmClkFreq must be set."));
|
|
if (USEC_TO_CLK(p_Fm->p_FmDriverParam->dmaWatchdog, p_Fm->p_FmStateStruct->fmClkFreq) > DMA_MAX_WATCHDOG)
|
|
RETURN_ERROR(MAJOR, E_INVALID_VALUE,
|
|
("dmaWatchdog depends on FM clock. dmaWatchdog(in microseconds) * clk (in Mhz), may not exceed 0x08x", DMA_MAX_WATCHDOG));
|
|
|
|
#ifdef FM_PARTITION_ARRAY
|
|
{
|
|
t_FmRevisionInfo revInfo;
|
|
uint8_t i;
|
|
|
|
FM_GetRevision(p_Fm, &revInfo);
|
|
if ((revInfo.majorRev == 1) && (revInfo.minorRev == 0))
|
|
for (i=0; i<FM_SIZE_OF_LIODN_TABLE; i++)
|
|
if (p_Fm->p_FmDriverParam->liodnBasePerPort[i] & ~FM_LIODN_BASE_MASK)
|
|
RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("liodn number is out of range"));
|
|
}
|
|
#endif /* FM_PARTITION_ARRAY */
|
|
|
|
if(p_Fm->p_FmStateStruct->totalFifoSize % BMI_FIFO_UNITS)
|
|
RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("totalFifoSize number has to be divisible by %d", BMI_FIFO_UNITS));
|
|
if(!p_Fm->p_FmStateStruct->totalFifoSize || (p_Fm->p_FmStateStruct->totalFifoSize > BMI_MAX_FIFO_SIZE))
|
|
RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("totalFifoSize number has to be in the range 256 - %d", BMI_MAX_FIFO_SIZE));
|
|
if(!p_Fm->p_FmStateStruct->totalNumOfTasks || (p_Fm->p_FmStateStruct->totalNumOfTasks > BMI_MAX_NUM_OF_TASKS))
|
|
RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("totalNumOfTasks number has to be in the range 1 - %d", BMI_MAX_NUM_OF_TASKS));
|
|
if(!p_Fm->p_FmStateStruct->maxNumOfOpenDmas || (p_Fm->p_FmStateStruct->maxNumOfOpenDmas > BMI_MAX_NUM_OF_DMAS))
|
|
RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("maxNumOfOpenDmas number has to be in the range 1 - %d", BMI_MAX_NUM_OF_DMAS));
|
|
|
|
if(p_Fm->p_FmDriverParam->thresholds.dispLimit > FPM_MAX_DISP_LIMIT)
|
|
RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("thresholds.dispLimit can't be greater than %d", FPM_MAX_DISP_LIMIT));
|
|
|
|
if(!p_Fm->f_Exception)
|
|
RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Exceptions callback not provided"));
|
|
if(!p_Fm->f_BusError)
|
|
RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Exceptions callback not provided"));
|
|
|
|
return E_OK;
|
|
}
|
|
|
|
static void SendIpcIsr(t_Fm *p_Fm, uint32_t macEvent, uint32_t pendingReg)
|
|
{
|
|
t_Error err;
|
|
t_FmIpcIsr fmIpcIsr;
|
|
t_FmIpcMsg msg;
|
|
|
|
ASSERT_COND(p_Fm->guestId == NCSW_MASTER_ID);
|
|
ASSERT_COND(p_Fm->h_IpcSessions[p_Fm->intrMng[macEvent].guestId]);
|
|
if (p_Fm->intrMng[macEvent].guestId != NCSW_MASTER_ID)
|
|
{
|
|
memset(&msg, 0, sizeof(msg));
|
|
msg.msgId = FM_GUEST_ISR;
|
|
fmIpcIsr.pendingReg = pendingReg;
|
|
fmIpcIsr.boolErr = FALSE;
|
|
memcpy(msg.msgBody, &fmIpcIsr, sizeof(fmIpcIsr));
|
|
if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[p_Fm->intrMng[macEvent].guestId],
|
|
(uint8_t*)&msg,
|
|
sizeof(msg.msgId) + sizeof(fmIpcIsr),
|
|
NULL,
|
|
NULL,
|
|
NULL,
|
|
NULL)) != E_OK)
|
|
REPORT_ERROR(MINOR, err, NO_MSG);
|
|
return;
|
|
}
|
|
else
|
|
p_Fm->intrMng[macEvent].f_Isr(p_Fm->intrMng[macEvent].h_SrcHandle);
|
|
}
|
|
|
|
static void BmiErrEvent(t_Fm *p_Fm)
|
|
{
|
|
uint32_t event, mask, force;
|
|
|
|
event = GET_UINT32(p_Fm->p_FmBmiRegs->fmbm_ievr);
|
|
mask = GET_UINT32(p_Fm->p_FmBmiRegs->fmbm_ier);
|
|
event &= mask;
|
|
|
|
/* clear the forced events */
|
|
force = GET_UINT32(p_Fm->p_FmBmiRegs->fmbm_ifr);
|
|
if(force & event)
|
|
WRITE_UINT32(p_Fm->p_FmBmiRegs->fmbm_ifr, force & ~event);
|
|
|
|
|
|
/* clear the acknowledged events */
|
|
WRITE_UINT32(p_Fm->p_FmBmiRegs->fmbm_ievr, event);
|
|
|
|
if(event & BMI_ERR_INTR_EN_PIPELINE_ECC)
|
|
p_Fm->f_Exception(p_Fm->h_App,e_FM_EX_BMI_PIPELINE_ECC);
|
|
if(event & BMI_ERR_INTR_EN_LIST_RAM_ECC)
|
|
p_Fm->f_Exception(p_Fm->h_App,e_FM_EX_BMI_LIST_RAM_ECC);
|
|
if(event & BMI_ERR_INTR_EN_STATISTICS_RAM_ECC)
|
|
p_Fm->f_Exception(p_Fm->h_App,e_FM_EX_BMI_STATISTICS_RAM_ECC);
|
|
if(event & BMI_ERR_INTR_EN_DISPATCH_RAM_ECC)
|
|
p_Fm->f_Exception(p_Fm->h_App,e_FM_EX_BMI_DISPATCH_RAM_ECC);
|
|
}
|
|
|
|
static void QmiErrEvent(t_Fm *p_Fm)
|
|
{
|
|
uint32_t event, mask, force;
|
|
|
|
event = GET_UINT32(p_Fm->p_FmQmiRegs->fmqm_eie);
|
|
mask = GET_UINT32(p_Fm->p_FmQmiRegs->fmqm_eien);
|
|
|
|
event &= mask;
|
|
|
|
/* clear the forced events */
|
|
force = GET_UINT32(p_Fm->p_FmQmiRegs->fmqm_eif);
|
|
if(force & event)
|
|
WRITE_UINT32(p_Fm->p_FmQmiRegs->fmqm_eif, force & ~event);
|
|
|
|
/* clear the acknowledged events */
|
|
WRITE_UINT32(p_Fm->p_FmQmiRegs->fmqm_eie, event);
|
|
|
|
if(event & QMI_ERR_INTR_EN_DOUBLE_ECC)
|
|
p_Fm->f_Exception(p_Fm->h_App,e_FM_EX_QMI_DOUBLE_ECC);
|
|
if(event & QMI_ERR_INTR_EN_DEQ_FROM_DEF)
|
|
p_Fm->f_Exception(p_Fm->h_App,e_FM_EX_QMI_DEQ_FROM_UNKNOWN_PORTID);
|
|
}
|
|
|
|
static void DmaErrEvent(t_Fm *p_Fm)
|
|
{
|
|
uint64_t addr=0;
|
|
uint32_t status, mask, tmpReg=0;
|
|
uint8_t tnum;
|
|
uint8_t hardwarePortId;
|
|
uint8_t relativePortId;
|
|
uint16_t liodn;
|
|
|
|
status = GET_UINT32(p_Fm->p_FmDmaRegs->fmdmsr);
|
|
mask = GET_UINT32(p_Fm->p_FmDmaRegs->fmdmmr);
|
|
|
|
/* get bus error regs befor clearing BER */
|
|
if ((status & DMA_STATUS_BUS_ERR) && (mask & DMA_MODE_BER))
|
|
{
|
|
addr = (uint64_t)GET_UINT32(p_Fm->p_FmDmaRegs->fmdmtal);
|
|
addr |= ((uint64_t)(GET_UINT32(p_Fm->p_FmDmaRegs->fmdmtah)) << 32);
|
|
|
|
/* get information about the owner of that bus error */
|
|
tmpReg = GET_UINT32(p_Fm->p_FmDmaRegs->fmdmtcid);
|
|
}
|
|
|
|
/* clear set events */
|
|
WRITE_UINT32(p_Fm->p_FmDmaRegs->fmdmsr, status);
|
|
|
|
if ((status & DMA_STATUS_BUS_ERR) && (mask & DMA_MODE_BER))
|
|
{
|
|
hardwarePortId = (uint8_t)(((tmpReg & DMA_TRANSFER_PORTID_MASK) >> DMA_TRANSFER_PORTID_SHIFT));
|
|
HW_PORT_ID_TO_SW_PORT_ID(relativePortId, hardwarePortId);
|
|
tnum = (uint8_t)((tmpReg & DMA_TRANSFER_TNUM_MASK) >> DMA_TRANSFER_TNUM_SHIFT);
|
|
liodn = (uint16_t)(tmpReg & DMA_TRANSFER_LIODN_MASK);
|
|
ASSERT_COND(p_Fm->p_FmStateStruct->portsTypes[hardwarePortId] != e_FM_PORT_TYPE_DUMMY);
|
|
p_Fm->f_BusError(p_Fm->h_App, p_Fm->p_FmStateStruct->portsTypes[hardwarePortId], relativePortId, addr, tnum, liodn);
|
|
}
|
|
if(mask & DMA_MODE_ECC)
|
|
{
|
|
if (status & DMA_STATUS_READ_ECC)
|
|
p_Fm->f_Exception(p_Fm->h_App, e_FM_EX_DMA_READ_ECC);
|
|
if (status & DMA_STATUS_SYSTEM_WRITE_ECC)
|
|
p_Fm->f_Exception(p_Fm->h_App, e_FM_EX_DMA_SYSTEM_WRITE_ECC);
|
|
if (status & DMA_STATUS_FM_WRITE_ECC)
|
|
p_Fm->f_Exception(p_Fm->h_App, e_FM_EX_DMA_FM_WRITE_ECC);
|
|
}
|
|
}
|
|
|
|
static void FpmErrEvent(t_Fm *p_Fm)
|
|
{
|
|
uint32_t event;
|
|
|
|
event = GET_UINT32(p_Fm->p_FmFpmRegs->fpmem);
|
|
|
|
/* clear the all occurred events */
|
|
WRITE_UINT32(p_Fm->p_FmFpmRegs->fpmem, event);
|
|
|
|
if((event & FPM_EV_MASK_DOUBLE_ECC) && (event & FPM_EV_MASK_DOUBLE_ECC_EN))
|
|
p_Fm->f_Exception(p_Fm->h_App,e_FM_EX_FPM_DOUBLE_ECC);
|
|
if((event & FPM_EV_MASK_STALL) && (event & FPM_EV_MASK_STALL_EN))
|
|
p_Fm->f_Exception(p_Fm->h_App,e_FM_EX_FPM_STALL_ON_TASKS);
|
|
if((event & FPM_EV_MASK_SINGLE_ECC) && (event & FPM_EV_MASK_SINGLE_ECC_EN))
|
|
p_Fm->f_Exception(p_Fm->h_App,e_FM_EX_FPM_SINGLE_ECC);
|
|
}
|
|
|
|
static void MuramErrIntr(t_Fm *p_Fm)
|
|
{
|
|
uint32_t event, mask;
|
|
|
|
event = GET_UINT32(p_Fm->p_FmFpmRegs->fmrcr);
|
|
mask = GET_UINT32(p_Fm->p_FmFpmRegs->fmrie);
|
|
|
|
/* clear MURAM event bit */
|
|
WRITE_UINT32(p_Fm->p_FmFpmRegs->fmrcr, event & ~FPM_RAM_CTL_IRAM_ECC);
|
|
|
|
ASSERT_COND(event & FPM_RAM_CTL_MURAM_ECC);
|
|
ASSERT_COND(event & FPM_RAM_CTL_RAMS_ECC_EN);
|
|
|
|
if ((mask & FPM_MURAM_ECC_ERR_EX_EN))
|
|
p_Fm->f_Exception(p_Fm->h_App, e_FM_EX_MURAM_ECC);
|
|
}
|
|
|
|
static void IramErrIntr(t_Fm *p_Fm)
|
|
{
|
|
uint32_t event, mask;
|
|
|
|
event = GET_UINT32(p_Fm->p_FmFpmRegs->fmrcr) ;
|
|
mask = GET_UINT32(p_Fm->p_FmFpmRegs->fmrie);
|
|
/* clear the acknowledged events (do not clear IRAM event) */
|
|
WRITE_UINT32(p_Fm->p_FmFpmRegs->fmrcr, event & ~FPM_RAM_CTL_MURAM_ECC);
|
|
|
|
ASSERT_COND(event & FPM_RAM_CTL_IRAM_ECC);
|
|
ASSERT_COND(event & FPM_RAM_CTL_IRAM_ECC_EN);
|
|
|
|
if ((mask & FPM_IRAM_ECC_ERR_EX_EN))
|
|
p_Fm->f_Exception(p_Fm->h_App, e_FM_EX_IRAM_ECC);
|
|
}
|
|
|
|
static void QmiEvent(t_Fm *p_Fm)
|
|
{
|
|
uint32_t event, mask, force;
|
|
|
|
event = GET_UINT32(p_Fm->p_FmQmiRegs->fmqm_ie);
|
|
mask = GET_UINT32(p_Fm->p_FmQmiRegs->fmqm_ien);
|
|
|
|
event &= mask;
|
|
|
|
/* clear the forced events */
|
|
force = GET_UINT32(p_Fm->p_FmQmiRegs->fmqm_if);
|
|
if(force & event)
|
|
WRITE_UINT32(p_Fm->p_FmQmiRegs->fmqm_if, force & ~event);
|
|
|
|
/* clear the acknowledged events */
|
|
WRITE_UINT32(p_Fm->p_FmQmiRegs->fmqm_ie, event);
|
|
|
|
if(event & QMI_INTR_EN_SINGLE_ECC)
|
|
p_Fm->f_Exception(p_Fm->h_App,e_FM_EX_QMI_SINGLE_ECC);
|
|
}
|
|
|
|
static void UnimplementedIsr(t_Handle h_Arg)
|
|
{
|
|
UNUSED(h_Arg);
|
|
|
|
REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Unimplemented Isr!"));
|
|
}
|
|
|
|
static void UnimplementedFmanCtrlIsr(t_Handle h_Arg, uint32_t event)
|
|
{
|
|
UNUSED(h_Arg); UNUSED(event);
|
|
|
|
REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Unimplemented FmCtl Isr!"));
|
|
}
|
|
|
|
static void FmEnableTimeStamp(t_Fm *p_Fm)
|
|
{
|
|
uint32_t tmpReg;
|
|
uint64_t fraction;
|
|
uint32_t integer;
|
|
uint8_t count1MicroBit = 8;
|
|
uint32_t tsFrequency = (uint32_t)(1<<count1MicroBit); /* in Mhz */
|
|
|
|
/* configure timestamp so that bit 8 will count 1 microsecond */
|
|
/* Find effective count rate at TIMESTAMP least significant bits:
|
|
Effective_Count_Rate = 1MHz x 2^8 = 256MHz
|
|
Find frequency ratio between effective count rate and the clock:
|
|
Effective_Count_Rate / CLK e.g. for 600 MHz clock:
|
|
256/600 = 0.4266666... */
|
|
integer = tsFrequency/p_Fm->p_FmStateStruct->fmClkFreq;
|
|
/* we multiply by 2^16 to keep the fraction of the division */
|
|
/* we do not divid back, since we write this value as fraction - see spec */
|
|
fraction = ((tsFrequency << 16) - (integer << 16)*p_Fm->p_FmStateStruct->fmClkFreq)/p_Fm->p_FmStateStruct->fmClkFreq;
|
|
/* we check remainder of the division in order to round up if not integer */
|
|
if(((tsFrequency << 16) - (integer << 16)*p_Fm->p_FmStateStruct->fmClkFreq) % p_Fm->p_FmStateStruct->fmClkFreq)
|
|
fraction++;
|
|
|
|
tmpReg = (integer << FPM_TS_INT_SHIFT) | (uint16_t)fraction;
|
|
WRITE_UINT32(p_Fm->p_FmFpmRegs->fpmtsc2, tmpReg);
|
|
|
|
/* enable timestamp with original clock */
|
|
WRITE_UINT32(p_Fm->p_FmFpmRegs->fpmtsc1, FPM_TS_CTL_EN);
|
|
|
|
p_Fm->p_FmStateStruct->count1MicroBit = count1MicroBit;
|
|
p_Fm->p_FmStateStruct->enabledTimeStamp = TRUE;
|
|
}
|
|
|
|
static void FreeInitResources(t_Fm *p_Fm)
|
|
{
|
|
if (p_Fm->camBaseAddr)
|
|
FM_MURAM_FreeMem(p_Fm->h_FmMuram, UINT_TO_PTR(p_Fm->camBaseAddr));
|
|
if (p_Fm->fifoBaseAddr)
|
|
FM_MURAM_FreeMem(p_Fm->h_FmMuram, UINT_TO_PTR(p_Fm->fifoBaseAddr));
|
|
if (p_Fm->resAddr)
|
|
FM_MURAM_FreeMem(p_Fm->h_FmMuram, UINT_TO_PTR(p_Fm->resAddr));
|
|
}
|
|
|
|
static t_Error ClearIRam(t_Fm *p_Fm)
|
|
{
|
|
t_FMIramRegs *p_Iram;
|
|
int i;
|
|
|
|
ASSERT_COND(p_Fm);
|
|
p_Iram = (t_FMIramRegs *)UINT_TO_PTR(p_Fm->baseAddr + FM_MM_IMEM);
|
|
|
|
/* Enable the auto-increment */
|
|
WRITE_UINT32(p_Iram->iadd, IRAM_IADD_AIE);
|
|
while (GET_UINT32(p_Iram->iadd) != IRAM_IADD_AIE) ;
|
|
|
|
for (i=0; i < (FM_IRAM_SIZE/4); i++)
|
|
WRITE_UINT32(p_Iram->idata, 0xffffffff);
|
|
|
|
WRITE_UINT32(p_Iram->iadd, FM_IRAM_SIZE - 4);
|
|
CORE_MemoryBarrier();
|
|
while (GET_UINT32(p_Iram->idata) != 0xffffffff) ;
|
|
|
|
return E_OK;
|
|
}
|
|
|
|
static t_Error LoadFmanCtrlCode(t_Fm *p_Fm)
|
|
{
|
|
t_FMIramRegs *p_Iram;
|
|
int i;
|
|
uint32_t tmp;
|
|
uint8_t compTo16;
|
|
|
|
ASSERT_COND(p_Fm);
|
|
p_Iram = (t_FMIramRegs *)UINT_TO_PTR(p_Fm->baseAddr + FM_MM_IMEM);
|
|
|
|
/* Enable the auto-increment */
|
|
WRITE_UINT32(p_Iram->iadd, IRAM_IADD_AIE);
|
|
while (GET_UINT32(p_Iram->iadd) != IRAM_IADD_AIE) ;
|
|
|
|
for (i=0; i < (p_Fm->p_FmDriverParam->firmware.size / 4); i++)
|
|
WRITE_UINT32(p_Iram->idata, p_Fm->p_FmDriverParam->firmware.p_Code[i]);
|
|
|
|
compTo16 = (uint8_t)(p_Fm->p_FmDriverParam->firmware.size % 16);
|
|
if(compTo16)
|
|
for (i=0; i < ((16-compTo16) / 4); i++)
|
|
WRITE_UINT32(p_Iram->idata, 0xffffffff);
|
|
|
|
WRITE_UINT32(p_Iram->iadd,p_Fm->p_FmDriverParam->firmware.size-4);
|
|
while(GET_UINT32(p_Iram->iadd) != (p_Fm->p_FmDriverParam->firmware.size-4)) ;
|
|
|
|
/* verify that writing has completed */
|
|
while (GET_UINT32(p_Iram->idata) != p_Fm->p_FmDriverParam->firmware.p_Code[(p_Fm->p_FmDriverParam->firmware.size / 4)-1]) ;
|
|
|
|
if (p_Fm->p_FmDriverParam->fwVerify)
|
|
{
|
|
WRITE_UINT32(p_Iram->iadd, IRAM_IADD_AIE);
|
|
while (GET_UINT32(p_Iram->iadd) != IRAM_IADD_AIE) ;
|
|
for (i=0; i < (p_Fm->p_FmDriverParam->firmware.size / 4); i++)
|
|
if ((tmp=GET_UINT32(p_Iram->idata)) != p_Fm->p_FmDriverParam->firmware.p_Code[i])
|
|
RETURN_ERROR(MAJOR, E_WRITE_FAILED,
|
|
("UCode write error : write 0x%x, read 0x%x",
|
|
p_Fm->p_FmDriverParam->firmware.p_Code[i],tmp));
|
|
WRITE_UINT32(p_Iram->iadd, 0x0);
|
|
}
|
|
|
|
/* Enable patch from IRAM */
|
|
WRITE_UINT32(p_Iram->iready, IRAM_READY);
|
|
XX_UDelay(1000);
|
|
|
|
DBG(INFO, ("FMan-Controller code (ver %d.%d) loaded to IRAM.",
|
|
((uint8_t *)p_Fm->p_FmDriverParam->firmware.p_Code)[5],
|
|
((uint8_t *)p_Fm->p_FmDriverParam->firmware.p_Code)[7]));
|
|
|
|
return E_OK;
|
|
}
|
|
|
|
static void GuestErrorIsr(t_Fm *p_Fm, uint32_t pending)
|
|
{
|
|
#define FM_G_CALL_1G_MAC_ERR_ISR(_id) \
|
|
do { \
|
|
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);\
|
|
} while (0)
|
|
#define FM_G_CALL_10G_MAC_ERR_ISR(_id) \
|
|
do { \
|
|
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);\
|
|
} while (0)
|
|
|
|
/* error interrupts */
|
|
if (pending & ERR_INTR_EN_1G_MAC0)
|
|
FM_G_CALL_1G_MAC_ERR_ISR(0);
|
|
if (pending & ERR_INTR_EN_1G_MAC1)
|
|
FM_G_CALL_1G_MAC_ERR_ISR(1);
|
|
if (pending & ERR_INTR_EN_1G_MAC2)
|
|
FM_G_CALL_1G_MAC_ERR_ISR(2);
|
|
if (pending & ERR_INTR_EN_1G_MAC3)
|
|
FM_G_CALL_1G_MAC_ERR_ISR(3);
|
|
if (pending & ERR_INTR_EN_1G_MAC4)
|
|
FM_G_CALL_1G_MAC_ERR_ISR(4);
|
|
if (pending & ERR_INTR_EN_10G_MAC0)
|
|
FM_G_CALL_10G_MAC_ERR_ISR(0);
|
|
}
|
|
|
|
static void GuestEventIsr(t_Fm *p_Fm, uint32_t pending)
|
|
{
|
|
#define FM_G_CALL_1G_MAC_TMR_ISR(_id) \
|
|
do { \
|
|
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);\
|
|
} while (0)
|
|
|
|
if (pending & INTR_EN_1G_MAC0_TMR)
|
|
FM_G_CALL_1G_MAC_TMR_ISR(0);
|
|
if (pending & INTR_EN_1G_MAC1_TMR)
|
|
FM_G_CALL_1G_MAC_TMR_ISR(1);
|
|
if (pending & INTR_EN_1G_MAC2_TMR)
|
|
FM_G_CALL_1G_MAC_TMR_ISR(2);
|
|
if (pending & INTR_EN_1G_MAC3_TMR)
|
|
FM_G_CALL_1G_MAC_TMR_ISR(3);
|
|
if (pending & INTR_EN_1G_MAC4_TMR)
|
|
FM_G_CALL_1G_MAC_TMR_ISR(4);
|
|
if(pending & INTR_EN_TMR)
|
|
p_Fm->intrMng[e_FM_EV_TMR].f_Isr(p_Fm->intrMng[e_FM_EV_TMR].h_SrcHandle);
|
|
}
|
|
|
|
|
|
/****************************************/
|
|
/* Inter-Module functions */
|
|
/****************************************/
|
|
static t_Error FmGuestHandleIpcMsgCB(t_Handle h_Fm,
|
|
uint8_t *p_Msg,
|
|
uint32_t msgLength,
|
|
uint8_t *p_Reply,
|
|
uint32_t *p_ReplyLength)
|
|
{
|
|
t_Fm *p_Fm = (t_Fm*)h_Fm;
|
|
t_FmIpcMsg *p_IpcMsg = (t_FmIpcMsg*)p_Msg;
|
|
|
|
UNUSED(p_Reply);
|
|
SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
|
|
SANITY_CHECK_RETURN_ERROR((msgLength > sizeof(uint32_t)), E_INVALID_VALUE);
|
|
|
|
#ifdef DISABLE_SANITY_CHECKS
|
|
UNUSED(msgLength);
|
|
#endif /* DISABLE_SANITY_CHECKS */
|
|
|
|
ASSERT_COND(p_Msg);
|
|
|
|
*p_ReplyLength = 0;
|
|
|
|
switch(p_IpcMsg->msgId)
|
|
{
|
|
case (FM_GUEST_ISR):
|
|
{
|
|
t_FmIpcIsr ipcIsr;
|
|
|
|
memcpy((uint8_t*)&ipcIsr, p_IpcMsg->msgBody, sizeof(t_FmIpcIsr));
|
|
if(ipcIsr.boolErr)
|
|
GuestErrorIsr(p_Fm, ipcIsr.pendingReg);
|
|
else
|
|
GuestEventIsr(p_Fm, ipcIsr.pendingReg);
|
|
break;
|
|
}
|
|
default:
|
|
*p_ReplyLength = 0;
|
|
RETURN_ERROR(MINOR, E_INVALID_SELECTION, ("command not found!!!"));
|
|
}
|
|
return E_OK;
|
|
}
|
|
|
|
static t_Error FmHandleIpcMsgCB(t_Handle h_Fm,
|
|
uint8_t *p_Msg,
|
|
uint32_t msgLength,
|
|
uint8_t *p_Reply,
|
|
uint32_t *p_ReplyLength)
|
|
{
|
|
t_Fm *p_Fm = (t_Fm*)h_Fm;
|
|
t_FmIpcMsg *p_IpcMsg = (t_FmIpcMsg*)p_Msg;
|
|
t_FmIpcReply *p_IpcReply = (t_FmIpcReply*)p_Reply;
|
|
|
|
SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
|
|
SANITY_CHECK_RETURN_ERROR((msgLength >= sizeof(uint32_t)), E_INVALID_VALUE);
|
|
|
|
#ifdef DISABLE_SANITY_CHECKS
|
|
UNUSED(msgLength);
|
|
#endif /* DISABLE_SANITY_CHECKS */
|
|
|
|
ASSERT_COND(p_IpcMsg);
|
|
|
|
memset(p_IpcReply, 0, (sizeof(uint8_t) * FM_IPC_MAX_REPLY_SIZE));
|
|
*p_ReplyLength = 0;
|
|
|
|
switch(p_IpcMsg->msgId)
|
|
{
|
|
case (FM_GET_SET_PORT_PARAMS):
|
|
{
|
|
t_FmIpcPortInInitParams ipcInitParams;
|
|
t_FmInterModulePortInitParams initParams;
|
|
t_FmIpcPhysAddr ipcPhysAddr;
|
|
|
|
memcpy((uint8_t*)&ipcInitParams, p_IpcMsg->msgBody, sizeof(t_FmIpcPortInInitParams));
|
|
initParams.hardwarePortId = ipcInitParams.hardwarePortId;
|
|
initParams.portType = (e_FmPortType)ipcInitParams.enumPortType;
|
|
initParams.independentMode = (bool)(ipcInitParams.boolIndependentMode);
|
|
initParams.liodnOffset = ipcInitParams.liodnOffset;
|
|
initParams.numOfTasks = ipcInitParams.numOfTasks;
|
|
initParams.numOfExtraTasks = ipcInitParams.numOfExtraTasks;
|
|
initParams.numOfOpenDmas = ipcInitParams.numOfOpenDmas;
|
|
initParams.numOfExtraOpenDmas = ipcInitParams.numOfExtraOpenDmas;
|
|
initParams.sizeOfFifo = ipcInitParams.sizeOfFifo;
|
|
initParams.extraSizeOfFifo = ipcInitParams.extraSizeOfFifo;
|
|
initParams.deqPipelineDepth = ipcInitParams.deqPipelineDepth;
|
|
initParams.liodnBase = ipcInitParams.liodnBase;
|
|
|
|
p_IpcReply->error = (uint32_t)FmGetSetPortParams(h_Fm, &initParams);
|
|
ipcPhysAddr.high = initParams.fmMuramPhysBaseAddr.high;
|
|
ipcPhysAddr.low = initParams.fmMuramPhysBaseAddr.low;
|
|
memcpy(p_IpcReply->replyBody, (uint8_t*)&ipcPhysAddr, sizeof(t_FmIpcPhysAddr));
|
|
*p_ReplyLength = sizeof(uint32_t) + sizeof(t_FmIpcPhysAddr);
|
|
break;
|
|
}
|
|
case (FM_SET_SIZE_OF_FIFO):
|
|
{
|
|
t_FmIpcPortFifoParams ipcPortFifoParams;
|
|
t_FmInterModulePortRxPoolsParams rxPoolsParams;
|
|
|
|
memcpy((uint8_t*)&ipcPortFifoParams, p_IpcMsg->msgBody, sizeof(t_FmIpcPortFifoParams));
|
|
rxPoolsParams.numOfPools = ipcPortFifoParams.numOfPools;
|
|
rxPoolsParams.secondLargestBufSize = ipcPortFifoParams.secondLargestBufSize;
|
|
rxPoolsParams.largestBufSize = ipcPortFifoParams.largestBufSize;
|
|
|
|
p_IpcReply->error = (uint32_t)FmSetSizeOfFifo(h_Fm, ipcPortFifoParams.rsrcParams.hardwarePortId,
|
|
(e_FmPortType)ipcPortFifoParams.enumPortType,
|
|
(bool)ipcPortFifoParams.boolIndependentMode,
|
|
&ipcPortFifoParams.rsrcParams.val,
|
|
ipcPortFifoParams.rsrcParams.extra,
|
|
ipcPortFifoParams.deqPipelineDepth,
|
|
&rxPoolsParams,
|
|
(bool)ipcPortFifoParams.boolInitialConfig);
|
|
memcpy(p_IpcReply->replyBody, (uint8_t*)&ipcPortFifoParams.rsrcParams.val, sizeof(uint32_t));
|
|
*p_ReplyLength = sizeof(uint32_t) + sizeof(uint32_t);
|
|
break;
|
|
}
|
|
case (FM_SET_NUM_OF_TASKS):
|
|
{
|
|
t_FmIpcPortRsrcParams ipcPortRsrcParams;
|
|
|
|
memcpy((uint8_t*)&ipcPortRsrcParams, p_IpcMsg->msgBody, sizeof(t_FmIpcPortRsrcParams));
|
|
p_IpcReply->error = (uint32_t)FmSetNumOfTasks(h_Fm, ipcPortRsrcParams.hardwarePortId,
|
|
(uint8_t)ipcPortRsrcParams.val,
|
|
(uint8_t)ipcPortRsrcParams.extra,
|
|
(bool)ipcPortRsrcParams.boolInitialConfig);
|
|
*p_ReplyLength = sizeof(uint32_t);
|
|
break;
|
|
}
|
|
case (FM_SET_NUM_OF_OPEN_DMAS):
|
|
{
|
|
t_FmIpcPortRsrcParams ipcPortRsrcParams;
|
|
|
|
memcpy((uint8_t*)&ipcPortRsrcParams, p_IpcMsg->msgBody, sizeof(t_FmIpcPortRsrcParams));
|
|
p_IpcReply->error = (uint32_t)FmSetNumOfOpenDmas(h_Fm, ipcPortRsrcParams.hardwarePortId,
|
|
(uint8_t)ipcPortRsrcParams.val,
|
|
(uint8_t)ipcPortRsrcParams.extra,
|
|
(bool)ipcPortRsrcParams.boolInitialConfig);
|
|
*p_ReplyLength = sizeof(uint32_t);
|
|
break;
|
|
}
|
|
case (FM_RESUME_STALLED_PORT):
|
|
*p_ReplyLength = sizeof(uint32_t);
|
|
p_IpcReply->error = (uint32_t)FmResumeStalledPort(h_Fm, p_IpcMsg->msgBody[0]);
|
|
break;
|
|
case (FM_MASTER_IS_ALIVE):
|
|
{
|
|
uint8_t guestId = p_IpcMsg->msgBody[0];
|
|
/* build the FM master partition IPC address */
|
|
memset(p_Fm->fmIpcHandlerModuleName[guestId], 0, (sizeof(char)) * MODULE_NAME_SIZE);
|
|
if(Sprint (p_Fm->fmIpcHandlerModuleName[guestId], "FM_%d_%d",p_Fm->p_FmStateStruct->fmId, guestId) != (guestId<10 ? 6:7))
|
|
RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Sprint failed"));
|
|
p_Fm->h_IpcSessions[guestId] = XX_IpcInitSession(p_Fm->fmIpcHandlerModuleName[guestId], p_Fm->fmModuleName);
|
|
if (p_Fm->h_IpcSessions[guestId] == NULL)
|
|
RETURN_ERROR(MAJOR, E_NOT_AVAILABLE, ("FM Master IPC session for guest %d", guestId));
|
|
*(uint8_t*)(p_IpcReply->replyBody) = 1;
|
|
*p_ReplyLength = sizeof(uint32_t) + sizeof(uint8_t);
|
|
break;
|
|
}
|
|
case (FM_IS_PORT_STALLED):
|
|
{
|
|
bool tmp;
|
|
|
|
p_IpcReply->error = (uint32_t)FmIsPortStalled(h_Fm, p_IpcMsg->msgBody[0], &tmp);
|
|
*(uint8_t*)(p_IpcReply->replyBody) = (uint8_t)tmp;
|
|
*p_ReplyLength = sizeof(uint32_t) + sizeof(uint8_t);
|
|
break;
|
|
}
|
|
case (FM_RESET_MAC):
|
|
{
|
|
t_FmIpcMacParams ipcMacParams;
|
|
|
|
memcpy((uint8_t*)&ipcMacParams, p_IpcMsg->msgBody, sizeof(t_FmIpcMacParams));
|
|
p_IpcReply->error = (uint32_t)FmResetMac(p_Fm,
|
|
(e_FmMacType)(ipcMacParams.enumType),
|
|
ipcMacParams.id);
|
|
*p_ReplyLength = sizeof(uint32_t);
|
|
break;
|
|
}
|
|
case (FM_SET_MAC_MAX_FRAME):
|
|
{
|
|
t_Error err;
|
|
t_FmIpcMacMaxFrameParams ipcMacMaxFrameParams;
|
|
|
|
memcpy((uint8_t*)&ipcMacMaxFrameParams, p_IpcMsg->msgBody, sizeof(t_FmIpcMacMaxFrameParams));
|
|
if ((err = FmSetMacMaxFrame(p_Fm,
|
|
(e_FmMacType)(ipcMacMaxFrameParams.macParams.enumType),
|
|
ipcMacMaxFrameParams.macParams.id,
|
|
ipcMacMaxFrameParams.maxFrameLength)) != E_OK)
|
|
REPORT_ERROR(MINOR, err, NO_MSG);
|
|
break;
|
|
}
|
|
case (FM_GET_CLK_FREQ):
|
|
memcpy(p_IpcReply->replyBody, (uint8_t*)&p_Fm->p_FmStateStruct->fmClkFreq, sizeof(uint16_t));
|
|
*p_ReplyLength = sizeof(uint32_t) + sizeof(uint16_t);
|
|
break;
|
|
case (FM_FREE_PORT):
|
|
{
|
|
t_FmInterModulePortFreeParams portParams;
|
|
t_FmIpcPortFreeParams ipcPortParams;
|
|
|
|
memcpy((uint8_t*)&ipcPortParams, p_IpcMsg->msgBody, sizeof(t_FmIpcPortFreeParams));
|
|
portParams.hardwarePortId = ipcPortParams.hardwarePortId;
|
|
portParams.portType = (e_FmPortType)(ipcPortParams.enumPortType);
|
|
#ifdef FM_QMI_DEQ_OPTIONS_SUPPORT
|
|
portParams.deqPipelineDepth = ipcPortParams.deqPipelineDepth;
|
|
#endif /* FM_QMI_DEQ_OPTIONS_SUPPORT */
|
|
FmFreePortParams(h_Fm, &portParams);
|
|
break;
|
|
}
|
|
case (FM_REGISTER_INTR):
|
|
{
|
|
t_FmIpcRegisterIntr ipcRegIntr;
|
|
|
|
memcpy((uint8_t*)&ipcRegIntr, p_IpcMsg->msgBody, sizeof(ipcRegIntr));
|
|
p_Fm->intrMng[ipcRegIntr.event].guestId = ipcRegIntr.guestId;
|
|
break;
|
|
}
|
|
#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
|
|
case (FM_DUMP_REGS):
|
|
{
|
|
t_Error err;
|
|
if ((err = FM_DumpRegs(h_Fm)) != E_OK)
|
|
REPORT_ERROR(MINOR, err, NO_MSG);
|
|
break;
|
|
}
|
|
case (FM_DUMP_PORT_REGS):
|
|
{
|
|
t_Error err;
|
|
|
|
if ((err = FmDumpPortRegs(h_Fm, p_IpcMsg->msgBody[0])) != E_OK)
|
|
REPORT_ERROR(MINOR, err, NO_MSG);
|
|
break;
|
|
}
|
|
#endif /* (defined(DEBUG_ERRORS) && ... */
|
|
case (FM_GET_REV):
|
|
{
|
|
t_FmRevisionInfo revInfo;
|
|
t_FmIpcRevisionInfo ipcRevInfo;
|
|
|
|
p_IpcReply->error = (uint32_t)FM_GetRevision(h_Fm, &revInfo);
|
|
ipcRevInfo.majorRev = revInfo.majorRev;
|
|
ipcRevInfo.minorRev = revInfo.minorRev;
|
|
memcpy(p_IpcReply->replyBody, (uint8_t*)&ipcRevInfo, sizeof(t_FmIpcRevisionInfo));
|
|
*p_ReplyLength = sizeof(uint32_t) + sizeof(t_FmIpcRevisionInfo);
|
|
break;
|
|
}
|
|
case (FM_DMA_STAT):
|
|
{
|
|
t_FmDmaStatus dmaStatus;
|
|
t_FmIpcDmaStatus ipcDmaStatus;
|
|
|
|
FM_GetDmaStatus(h_Fm, &dmaStatus);
|
|
ipcDmaStatus.boolCmqNotEmpty = (uint8_t)dmaStatus.cmqNotEmpty;
|
|
ipcDmaStatus.boolBusError = (uint8_t)dmaStatus.busError;
|
|
ipcDmaStatus.boolReadBufEccError = (uint8_t)dmaStatus.readBufEccError;
|
|
ipcDmaStatus.boolWriteBufEccSysError = (uint8_t)dmaStatus.writeBufEccSysError;
|
|
ipcDmaStatus.boolWriteBufEccFmError = (uint8_t)dmaStatus.writeBufEccFmError;
|
|
memcpy(p_IpcReply->replyBody, (uint8_t*)&ipcDmaStatus, sizeof(t_FmIpcDmaStatus));
|
|
*p_ReplyLength = sizeof(uint32_t) + sizeof(t_FmIpcDmaStatus);
|
|
break;
|
|
}
|
|
case (FM_ALLOC_FMAN_CTRL_EVENT_REG):
|
|
p_IpcReply->error = (uint32_t)FmAllocFmanCtrlEventReg(h_Fm, (uint8_t*)p_IpcReply->replyBody);
|
|
*p_ReplyLength = sizeof(uint32_t) + sizeof(uint8_t);
|
|
break;
|
|
case (FM_FREE_FMAN_CTRL_EVENT_REG):
|
|
FmFreeFmanCtrlEventReg(h_Fm, p_IpcMsg->msgBody[0]);
|
|
break;
|
|
case (FM_GET_TIMESTAMP_SCALE):
|
|
{
|
|
uint32_t timeStamp = FmGetTimeStampScale(h_Fm);
|
|
|
|
memcpy(p_IpcReply->replyBody, (uint8_t*)&timeStamp, sizeof(uint32_t));
|
|
*p_ReplyLength = sizeof(uint32_t) + sizeof(uint32_t);
|
|
break;
|
|
}
|
|
case (FM_GET_COUNTER):
|
|
{
|
|
e_FmCounters inCounter;
|
|
uint32_t outCounter;
|
|
|
|
memcpy((uint8_t*)&inCounter, p_IpcMsg->msgBody, sizeof(uint32_t));
|
|
outCounter = FM_GetCounter(h_Fm, inCounter);
|
|
memcpy(p_IpcReply->replyBody, (uint8_t*)&outCounter, sizeof(uint32_t));
|
|
*p_ReplyLength = sizeof(uint32_t) + sizeof(uint32_t);
|
|
break;
|
|
}
|
|
case (FM_SET_FMAN_CTRL_EVENTS_ENABLE):
|
|
{
|
|
t_FmIpcFmanEvents ipcFmanEvents;
|
|
|
|
memcpy((uint8_t*)&ipcFmanEvents, p_IpcMsg->msgBody, sizeof(t_FmIpcFmanEvents));
|
|
FmSetFmanCtrlIntr(h_Fm,
|
|
ipcFmanEvents.eventRegId,
|
|
ipcFmanEvents.enableEvents);
|
|
break;
|
|
}
|
|
case (FM_GET_FMAN_CTRL_EVENTS_ENABLE):
|
|
{
|
|
uint32_t tmp = FmGetFmanCtrlIntr(h_Fm, p_IpcMsg->msgBody[0]);
|
|
|
|
memcpy(p_IpcReply->replyBody, (uint8_t*)&tmp, sizeof(uint32_t));
|
|
*p_ReplyLength = sizeof(uint32_t) + sizeof(uint32_t);
|
|
break;
|
|
}
|
|
case (FM_GET_PHYS_MURAM_BASE):
|
|
{
|
|
t_FmPhysAddr physAddr;
|
|
t_FmIpcPhysAddr ipcPhysAddr;
|
|
|
|
FmGetPhysicalMuramBase(h_Fm, &physAddr);
|
|
ipcPhysAddr.high = physAddr.high;
|
|
ipcPhysAddr.low = physAddr.low;
|
|
memcpy(p_IpcReply->replyBody, (uint8_t*)&ipcPhysAddr, sizeof(t_FmIpcPhysAddr));
|
|
*p_ReplyLength = sizeof(uint32_t) + sizeof(t_FmIpcPhysAddr);
|
|
break;
|
|
}
|
|
case (FM_ENABLE_RAM_ECC):
|
|
{
|
|
t_Error err;
|
|
|
|
if (((err = FM_EnableRamsEcc(h_Fm)) != E_OK) ||
|
|
((err = FM_SetException(h_Fm, e_FM_EX_IRAM_ECC, TRUE)) != E_OK) ||
|
|
((err = FM_SetException(h_Fm, e_FM_EX_MURAM_ECC, TRUE)) != E_OK))
|
|
REPORT_ERROR(MINOR, err, NO_MSG);
|
|
break;
|
|
}
|
|
case (FM_DISABLE_RAM_ECC):
|
|
{
|
|
t_Error err;
|
|
|
|
if (((err = FM_SetException(h_Fm, e_FM_EX_IRAM_ECC, FALSE)) != E_OK) ||
|
|
((err = FM_SetException(h_Fm, e_FM_EX_MURAM_ECC, FALSE)) != E_OK) ||
|
|
((err = FM_DisableRamsEcc(h_Fm)) != E_OK))
|
|
REPORT_ERROR(MINOR, err, NO_MSG);
|
|
break;
|
|
}
|
|
case (FM_SET_NUM_OF_FMAN_CTRL):
|
|
{
|
|
t_Error err;
|
|
t_FmIpcPortNumOfFmanCtrls ipcPortNumOfFmanCtrls;
|
|
|
|
memcpy((uint8_t*)&ipcPortNumOfFmanCtrls, p_IpcMsg->msgBody, sizeof(t_FmIpcPortNumOfFmanCtrls));
|
|
if ((err = FmSetNumOfRiscsPerPort(h_Fm,
|
|
ipcPortNumOfFmanCtrls.hardwarePortId,
|
|
ipcPortNumOfFmanCtrls.numOfFmanCtrls)) != E_OK)
|
|
REPORT_ERROR(MINOR, err, NO_MSG);
|
|
break;
|
|
}
|
|
#ifdef FM_TX_ECC_FRMS_ERRATA_10GMAC_A004
|
|
case (FM_10G_TX_ECC_WA):
|
|
p_IpcReply->error = (uint32_t)Fm10GTxEccWorkaround(h_Fm, p_IpcMsg->msgBody[0]);
|
|
*p_ReplyLength = sizeof(uint32_t);
|
|
break;
|
|
#endif /* FM_TX_ECC_FRMS_ERRATA_10GMAC_A004 */
|
|
default:
|
|
*p_ReplyLength = 0;
|
|
RETURN_ERROR(MINOR, E_INVALID_SELECTION, ("command not found!!!"));
|
|
}
|
|
return E_OK;
|
|
}
|
|
|
|
static void ErrorIsrCB(t_Handle h_Fm)
|
|
{
|
|
#define FM_M_CALL_1G_MAC_ERR_ISR(_id) \
|
|
{ \
|
|
if (p_Fm->guestId != p_Fm->intrMng[(e_FmInterModuleEvent)(e_FM_EV_ERR_1G_MAC0+_id)].guestId) \
|
|
SendIpcIsr(p_Fm, (e_FmInterModuleEvent)(e_FM_EV_ERR_1G_MAC0+_id), pending); \
|
|
else \
|
|
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);\
|
|
}
|
|
t_Fm *p_Fm = (t_Fm*)h_Fm;
|
|
uint32_t pending;
|
|
|
|
SANITY_CHECK_RETURN(h_Fm, E_INVALID_HANDLE);
|
|
|
|
/* error interrupts */
|
|
pending = GET_UINT32(p_Fm->p_FmFpmRegs->fmepi);
|
|
if (!pending)
|
|
return;
|
|
|
|
if(pending & ERR_INTR_EN_BMI)
|
|
BmiErrEvent(p_Fm);
|
|
if(pending & ERR_INTR_EN_QMI)
|
|
QmiErrEvent(p_Fm);
|
|
if(pending & ERR_INTR_EN_FPM)
|
|
FpmErrEvent(p_Fm);
|
|
if(pending & ERR_INTR_EN_DMA)
|
|
DmaErrEvent(p_Fm);
|
|
if(pending & ERR_INTR_EN_IRAM)
|
|
IramErrIntr(p_Fm);
|
|
if(pending & ERR_INTR_EN_MURAM)
|
|
MuramErrIntr(p_Fm);
|
|
if(pending & ERR_INTR_EN_PRS)
|
|
p_Fm->intrMng[e_FM_EV_ERR_PRS].f_Isr(p_Fm->intrMng[e_FM_EV_ERR_PRS].h_SrcHandle);
|
|
if(pending & ERR_INTR_EN_PLCR)
|
|
p_Fm->intrMng[e_FM_EV_ERR_PLCR].f_Isr(p_Fm->intrMng[e_FM_EV_ERR_PLCR].h_SrcHandle);
|
|
if(pending & ERR_INTR_EN_KG)
|
|
p_Fm->intrMng[e_FM_EV_ERR_KG].f_Isr(p_Fm->intrMng[e_FM_EV_ERR_KG].h_SrcHandle);
|
|
|
|
/* MAC events may belong to different partitions */
|
|
if(pending & ERR_INTR_EN_1G_MAC0)
|
|
FM_M_CALL_1G_MAC_ERR_ISR(0);
|
|
if(pending & ERR_INTR_EN_1G_MAC1)
|
|
FM_M_CALL_1G_MAC_ERR_ISR(1);
|
|
if(pending & ERR_INTR_EN_1G_MAC2)
|
|
FM_M_CALL_1G_MAC_ERR_ISR(2);
|
|
if(pending & ERR_INTR_EN_1G_MAC3)
|
|
FM_M_CALL_1G_MAC_ERR_ISR(3);
|
|
if(pending & ERR_INTR_EN_1G_MAC4)
|
|
FM_M_CALL_1G_MAC_ERR_ISR(4);
|
|
if(pending & ERR_INTR_EN_10G_MAC0)
|
|
{
|
|
if (p_Fm->guestId != p_Fm->intrMng[e_FM_EV_ERR_10G_MAC0].guestId)
|
|
SendIpcIsr(p_Fm, e_FM_EV_ERR_10G_MAC0, pending);
|
|
else
|
|
p_Fm->intrMng[e_FM_EV_ERR_10G_MAC0].f_Isr(p_Fm->intrMng[e_FM_EV_ERR_10G_MAC0].h_SrcHandle);
|
|
}
|
|
}
|
|
|
|
|
|
#ifdef FM_TX_ECC_FRMS_ERRATA_10GMAC_A004
|
|
t_Error Fm10GTxEccWorkaround(t_Handle h_Fm, uint8_t macId)
|
|
{
|
|
t_Fm *p_Fm = (t_Fm*)h_Fm;
|
|
int timeout = 1000;
|
|
t_Error err = E_OK;
|
|
t_FmIpcMsg msg;
|
|
t_FmIpcReply reply;
|
|
uint32_t replyLength;
|
|
uint8_t rxHardwarePortId, txHardwarePortId;
|
|
|
|
if(p_Fm->guestId != NCSW_MASTER_ID)
|
|
{
|
|
memset(&msg, 0, sizeof(msg));
|
|
memset(&reply, 0, sizeof(reply));
|
|
msg.msgId = FM_10G_TX_ECC_WA;
|
|
msg.msgBody[0] = macId;
|
|
replyLength = sizeof(uint32_t);
|
|
if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
|
|
(uint8_t*)&msg,
|
|
sizeof(msg.msgId)+sizeof(macId),
|
|
(uint8_t*)&reply,
|
|
&replyLength,
|
|
NULL,
|
|
NULL)) != E_OK)
|
|
RETURN_ERROR(MINOR, err, NO_MSG);
|
|
if (replyLength != sizeof(uint32_t))
|
|
RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
|
|
return (t_Error)(reply.error);
|
|
}
|
|
|
|
SANITY_CHECK_RETURN_ERROR((macId == 0), E_NOT_SUPPORTED);
|
|
SANITY_CHECK_RETURN_ERROR(IsFmanCtrlCodeLoaded(p_Fm), E_INVALID_STATE);
|
|
|
|
SW_PORT_ID_TO_HW_PORT_ID(rxHardwarePortId, e_FM_PORT_TYPE_RX_10G, macId);
|
|
SW_PORT_ID_TO_HW_PORT_ID(txHardwarePortId, e_FM_PORT_TYPE_TX_10G, macId);
|
|
if ((p_Fm->p_FmStateStruct->portsTypes[rxHardwarePortId] != e_FM_PORT_TYPE_DUMMY) ||
|
|
(p_Fm->p_FmStateStruct->portsTypes[txHardwarePortId] != e_FM_PORT_TYPE_DUMMY))
|
|
RETURN_ERROR(MAJOR, E_INVALID_STATE,
|
|
("MAC should be initialized prior to rx and tx ports!"));
|
|
WRITE_UINT32(p_Fm->p_FmFpmRegs->fpmextc, 0x40000000);
|
|
CORE_MemoryBarrier();
|
|
while ((GET_UINT32(p_Fm->p_FmFpmRegs->fpmextc) & 0x40000000) &&
|
|
--timeout) ;
|
|
if (!timeout)
|
|
return ERROR_CODE(E_TIMEOUT);
|
|
return E_OK;
|
|
}
|
|
#endif /* FM_TX_ECC_FRMS_ERRATA_10GMAC_A004 */
|
|
|
|
uintptr_t FmGetPcdPrsBaseAddr(t_Handle h_Fm)
|
|
{
|
|
t_Fm *p_Fm = (t_Fm*)h_Fm;
|
|
|
|
SANITY_CHECK_RETURN_VALUE(p_Fm, E_INVALID_HANDLE, 0);
|
|
|
|
if(p_Fm->guestId != NCSW_MASTER_ID)
|
|
REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Guset"));
|
|
|
|
return (p_Fm->baseAddr + FM_MM_PRS);
|
|
}
|
|
|
|
uintptr_t FmGetPcdKgBaseAddr(t_Handle h_Fm)
|
|
{
|
|
t_Fm *p_Fm = (t_Fm*)h_Fm;
|
|
|
|
SANITY_CHECK_RETURN_VALUE(p_Fm, E_INVALID_HANDLE, 0);
|
|
|
|
if(p_Fm->guestId != NCSW_MASTER_ID)
|
|
REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Guset"));
|
|
|
|
return (p_Fm->baseAddr + FM_MM_KG);
|
|
}
|
|
|
|
uintptr_t FmGetPcdPlcrBaseAddr(t_Handle h_Fm)
|
|
{
|
|
t_Fm *p_Fm = (t_Fm*)h_Fm;
|
|
|
|
SANITY_CHECK_RETURN_VALUE(p_Fm, E_INVALID_HANDLE, 0);
|
|
|
|
if(p_Fm->guestId != NCSW_MASTER_ID)
|
|
REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Guset"));
|
|
|
|
return (p_Fm->baseAddr + FM_MM_PLCR);
|
|
}
|
|
|
|
t_Handle FmGetMuramHandle(t_Handle h_Fm)
|
|
{
|
|
t_Fm *p_Fm = (t_Fm*)h_Fm;
|
|
|
|
SANITY_CHECK_RETURN_VALUE(p_Fm, E_INVALID_HANDLE, NULL);
|
|
|
|
return (p_Fm->h_FmMuram);
|
|
}
|
|
|
|
void FmGetPhysicalMuramBase(t_Handle h_Fm, t_FmPhysAddr *p_FmPhysAddr)
|
|
{
|
|
t_Fm *p_Fm = (t_Fm*)h_Fm;
|
|
t_Error err;
|
|
t_FmIpcMsg msg;
|
|
t_FmIpcReply reply;
|
|
uint32_t replyLength;
|
|
t_FmIpcPhysAddr ipcPhysAddr;
|
|
|
|
if(p_Fm->guestId != NCSW_MASTER_ID)
|
|
{
|
|
memset(&msg, 0, sizeof(msg));
|
|
memset(&reply, 0, sizeof(reply));
|
|
msg.msgId = FM_GET_PHYS_MURAM_BASE;
|
|
replyLength = sizeof(uint32_t) + sizeof(t_FmPhysAddr);
|
|
if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
|
|
(uint8_t*)&msg,
|
|
sizeof(msg.msgId),
|
|
(uint8_t*)&reply,
|
|
&replyLength,
|
|
NULL,
|
|
NULL)) != E_OK)
|
|
{
|
|
REPORT_ERROR(MINOR, err, NO_MSG);
|
|
return;
|
|
}
|
|
if (replyLength != (sizeof(uint32_t) + sizeof(t_FmPhysAddr)))
|
|
{
|
|
REPORT_ERROR(MINOR, E_INVALID_VALUE,("IPC reply length mismatch"));
|
|
return;
|
|
}
|
|
memcpy((uint8_t*)&ipcPhysAddr, reply.replyBody, sizeof(t_FmIpcPhysAddr));
|
|
p_FmPhysAddr->high = ipcPhysAddr.high;
|
|
p_FmPhysAddr->low = ipcPhysAddr.low;
|
|
return ;
|
|
}
|
|
|
|
/* General FM driver initialization */
|
|
p_FmPhysAddr->low = (uint32_t)p_Fm->fmMuramPhysBaseAddr;
|
|
p_FmPhysAddr->high = (uint8_t)((p_Fm->fmMuramPhysBaseAddr & 0x000000ff00000000LL) >> 32);
|
|
}
|
|
|
|
t_Error FmAllocFmanCtrlEventReg(t_Handle h_Fm, uint8_t *p_EventId)
|
|
{
|
|
t_Fm *p_Fm = (t_Fm*)h_Fm;
|
|
uint8_t i;
|
|
t_Error err;
|
|
t_FmIpcMsg msg;
|
|
t_FmIpcReply reply;
|
|
uint32_t replyLength;
|
|
|
|
if(p_Fm->guestId != NCSW_MASTER_ID)
|
|
{
|
|
memset(&msg, 0, sizeof(msg));
|
|
memset(&reply, 0, sizeof(reply));
|
|
msg.msgId = FM_ALLOC_FMAN_CTRL_EVENT_REG;
|
|
replyLength = sizeof(uint32_t) + sizeof(uint8_t);
|
|
if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
|
|
(uint8_t*)&msg,
|
|
sizeof(msg.msgId),
|
|
(uint8_t*)&reply,
|
|
&replyLength,
|
|
NULL,
|
|
NULL)) != E_OK)
|
|
RETURN_ERROR(MAJOR, err, NO_MSG);
|
|
if (replyLength != (sizeof(uint32_t) + sizeof(uint8_t)))
|
|
RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
|
|
|
|
*p_EventId = *(uint8_t*)(reply.replyBody);
|
|
|
|
return (t_Error)(reply.error);
|
|
}
|
|
|
|
for(i=0;i<FM_NUM_OF_FMAN_CTRL_EVENT_REGS;i++)
|
|
if (!p_Fm->usedEventRegs[i])
|
|
{
|
|
p_Fm->usedEventRegs[i] = TRUE;
|
|
*p_EventId = i;
|
|
break;
|
|
}
|
|
|
|
if (i==FM_NUM_OF_FMAN_CTRL_EVENT_REGS)
|
|
RETURN_ERROR(MAJOR, E_BUSY, ("No resource - Fman controller event register."));
|
|
|
|
return E_OK;
|
|
}
|
|
|
|
void FmFreeFmanCtrlEventReg(t_Handle h_Fm, uint8_t eventId)
|
|
{
|
|
t_Fm *p_Fm = (t_Fm*)h_Fm;
|
|
t_Error err;
|
|
t_FmIpcMsg msg;
|
|
|
|
if(((t_Fm *)h_Fm)->guestId != NCSW_MASTER_ID)
|
|
{
|
|
memset(&msg, 0, sizeof(msg));
|
|
msg.msgId = FM_FREE_FMAN_CTRL_EVENT_REG;
|
|
msg.msgBody[0] = eventId;
|
|
if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
|
|
(uint8_t*)&msg,
|
|
sizeof(msg.msgId)+sizeof(eventId),
|
|
NULL,
|
|
NULL,
|
|
NULL,
|
|
NULL)) != E_OK)
|
|
REPORT_ERROR(MINOR, err, NO_MSG);
|
|
return;
|
|
}
|
|
|
|
((t_Fm*)h_Fm)->usedEventRegs[eventId] = FALSE;
|
|
}
|
|
|
|
void FmRegisterIntr(t_Handle h_Fm,
|
|
e_FmEventModules module,
|
|
uint8_t modId,
|
|
e_FmIntrType intrType,
|
|
void (*f_Isr) (t_Handle h_Arg),
|
|
t_Handle h_Arg)
|
|
{
|
|
t_Fm *p_Fm = (t_Fm*)h_Fm;
|
|
uint8_t event= 0;
|
|
t_FmIpcRegisterIntr fmIpcRegisterIntr;
|
|
t_Error err;
|
|
t_FmIpcMsg msg;
|
|
|
|
ASSERT_COND(h_Fm);
|
|
|
|
GET_FM_MODULE_EVENT(module, modId,intrType, event);
|
|
|
|
/* register in local FM structure */
|
|
ASSERT_COND(event != e_FM_EV_DUMMY_LAST);
|
|
p_Fm->intrMng[event].f_Isr = f_Isr;
|
|
p_Fm->intrMng[event].h_SrcHandle = h_Arg;
|
|
|
|
if(p_Fm->guestId != NCSW_MASTER_ID)
|
|
{
|
|
if(p_Fm->h_IpcSessions[0])
|
|
{
|
|
/* register in Master FM structure */
|
|
fmIpcRegisterIntr.event = event;
|
|
fmIpcRegisterIntr.guestId = p_Fm->guestId;
|
|
memset(&msg, 0, sizeof(msg));
|
|
msg.msgId = FM_REGISTER_INTR;
|
|
memcpy(msg.msgBody, &fmIpcRegisterIntr, sizeof(fmIpcRegisterIntr));
|
|
if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
|
|
(uint8_t*)&msg,
|
|
sizeof(msg.msgId) + sizeof(fmIpcRegisterIntr),
|
|
NULL,
|
|
NULL,
|
|
NULL,
|
|
NULL)) != E_OK)
|
|
REPORT_ERROR(MINOR, err, NO_MSG);
|
|
}
|
|
else
|
|
DBG(WARNING,("'Register interrupt' - unavailable - No IPC"));
|
|
}
|
|
|
|
}
|
|
|
|
void FmUnregisterIntr(t_Handle h_Fm,
|
|
e_FmEventModules module,
|
|
uint8_t modId,
|
|
e_FmIntrType intrType)
|
|
{
|
|
t_Fm *p_Fm = (t_Fm*)h_Fm;
|
|
uint8_t event= 0;
|
|
|
|
ASSERT_COND(h_Fm);
|
|
|
|
GET_FM_MODULE_EVENT(module, modId,intrType, event);
|
|
|
|
ASSERT_COND(event != e_FM_EV_DUMMY_LAST);
|
|
p_Fm->intrMng[event].f_Isr = UnimplementedIsr;
|
|
p_Fm->intrMng[event].h_SrcHandle = NULL;
|
|
}
|
|
|
|
void FmSetFmanCtrlIntr(t_Handle h_Fm, uint8_t eventRegId, uint32_t enableEvents)
|
|
{
|
|
t_Fm *p_Fm = (t_Fm*)h_Fm;
|
|
t_FmIpcFmanEvents fmanCtrl;
|
|
t_Error err;
|
|
t_FmIpcMsg msg;
|
|
|
|
if(p_Fm->guestId != NCSW_MASTER_ID)
|
|
{
|
|
fmanCtrl.eventRegId = eventRegId;
|
|
fmanCtrl.enableEvents = enableEvents;
|
|
memset(&msg, 0, sizeof(msg));
|
|
msg.msgId = FM_SET_FMAN_CTRL_EVENTS_ENABLE;
|
|
memcpy(msg.msgBody, &fmanCtrl, sizeof(fmanCtrl));
|
|
if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
|
|
(uint8_t*)&msg,
|
|
sizeof(msg.msgId)+sizeof(fmanCtrl),
|
|
NULL,
|
|
NULL,
|
|
NULL,
|
|
NULL)) != E_OK)
|
|
REPORT_ERROR(MINOR, err, NO_MSG);
|
|
return;
|
|
}
|
|
|
|
ASSERT_COND(eventRegId < FM_NUM_OF_FMAN_CTRL_EVENT_REGS);
|
|
WRITE_UINT32(p_Fm->p_FmFpmRegs->fmfpfcee[eventRegId], enableEvents);
|
|
}
|
|
|
|
uint32_t FmGetFmanCtrlIntr(t_Handle h_Fm, uint8_t eventRegId)
|
|
{
|
|
t_Fm *p_Fm = (t_Fm*)h_Fm;
|
|
t_Error err;
|
|
t_FmIpcMsg msg;
|
|
t_FmIpcReply reply;
|
|
uint32_t replyLength, ctrlIntr;
|
|
|
|
if(p_Fm->guestId != NCSW_MASTER_ID)
|
|
{
|
|
memset(&msg, 0, sizeof(msg));
|
|
memset(&reply, 0, sizeof(reply));
|
|
msg.msgId = FM_GET_FMAN_CTRL_EVENTS_ENABLE;
|
|
msg.msgBody[0] = eventRegId;
|
|
replyLength = sizeof(uint32_t) + sizeof(uint32_t);
|
|
if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
|
|
(uint8_t*)&msg,
|
|
sizeof(msg.msgId)+sizeof(eventRegId),
|
|
(uint8_t*)&reply,
|
|
&replyLength,
|
|
NULL,
|
|
NULL)) != E_OK)
|
|
{
|
|
REPORT_ERROR(MINOR, err, NO_MSG);
|
|
return 0;
|
|
}
|
|
if (replyLength != (sizeof(uint32_t) + sizeof(uint32_t)))
|
|
{
|
|
REPORT_ERROR(MINOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
|
|
return 0;
|
|
}
|
|
memcpy((uint8_t*)&ctrlIntr, reply.replyBody, sizeof(uint32_t));
|
|
return ctrlIntr;
|
|
}
|
|
|
|
return GET_UINT32(p_Fm->p_FmFpmRegs->fmfpfcee[eventRegId]);
|
|
}
|
|
|
|
void FmRegisterFmanCtrlIntr(t_Handle h_Fm, uint8_t eventRegId, void (*f_Isr) (t_Handle h_Arg, uint32_t event), t_Handle h_Arg)
|
|
{
|
|
t_Fm *p_Fm = (t_Fm*)h_Fm;
|
|
|
|
ASSERT_COND(eventRegId<FM_NUM_OF_FMAN_CTRL_EVENT_REGS);
|
|
|
|
if(p_Fm->guestId != NCSW_MASTER_ID)
|
|
{
|
|
ASSERT_COND(0);
|
|
/* TODO */
|
|
}
|
|
|
|
p_Fm->fmanCtrlIntr[eventRegId].f_Isr = f_Isr;
|
|
p_Fm->fmanCtrlIntr[eventRegId].h_SrcHandle = h_Arg;
|
|
}
|
|
|
|
void FmUnregisterFmanCtrlIntr(t_Handle h_Fm, uint8_t eventRegId)
|
|
{
|
|
t_Fm *p_Fm = (t_Fm*)h_Fm;
|
|
|
|
ASSERT_COND(eventRegId<FM_NUM_OF_FMAN_CTRL_EVENT_REGS);
|
|
|
|
if(p_Fm->guestId != NCSW_MASTER_ID)
|
|
{
|
|
ASSERT_COND(0);
|
|
/* TODO */
|
|
}
|
|
|
|
p_Fm->fmanCtrlIntr[eventRegId].f_Isr = UnimplementedFmanCtrlIsr;
|
|
p_Fm->fmanCtrlIntr[eventRegId].h_SrcHandle = NULL;
|
|
}
|
|
|
|
void FmRegisterPcd(t_Handle h_Fm, t_Handle h_FmPcd)
|
|
{
|
|
t_Fm *p_Fm = (t_Fm*)h_Fm;
|
|
|
|
if(p_Fm->h_Pcd)
|
|
REPORT_ERROR(MAJOR, E_ALREADY_EXISTS, ("PCD already set"));
|
|
|
|
p_Fm->h_Pcd = h_FmPcd;
|
|
|
|
}
|
|
|
|
void FmUnregisterPcd(t_Handle h_Fm)
|
|
{
|
|
t_Fm *p_Fm = (t_Fm*)h_Fm;
|
|
|
|
if(!p_Fm->h_Pcd)
|
|
REPORT_ERROR(MAJOR, E_ALREADY_EXISTS, ("No PCD"));
|
|
|
|
p_Fm->h_Pcd = NULL;
|
|
|
|
}
|
|
|
|
t_Handle FmGetPcdHandle(t_Handle h_Fm)
|
|
{
|
|
t_Fm *p_Fm = (t_Fm*)h_Fm;
|
|
|
|
return p_Fm->h_Pcd;
|
|
}
|
|
|
|
uint8_t FmGetId(t_Handle h_Fm)
|
|
{
|
|
t_Fm *p_Fm = (t_Fm*)h_Fm;
|
|
|
|
SANITY_CHECK_RETURN_VALUE(p_Fm, E_INVALID_HANDLE, 0xff);
|
|
|
|
return p_Fm->p_FmStateStruct->fmId;
|
|
}
|
|
|
|
t_Error FmSetNumOfRiscsPerPort(t_Handle h_Fm, uint8_t hardwarePortId, uint8_t numOfFmanCtrls)
|
|
{
|
|
|
|
t_Fm *p_Fm = (t_Fm*)h_Fm;
|
|
uint32_t tmpReg = 0;
|
|
t_Error err;
|
|
t_FmIpcPortNumOfFmanCtrls params;
|
|
t_FmIpcMsg msg;
|
|
|
|
SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
|
|
SANITY_CHECK_RETURN_ERROR(((numOfFmanCtrls > 0) && (numOfFmanCtrls < 3)) , E_INVALID_HANDLE);
|
|
|
|
if(p_Fm->guestId != NCSW_MASTER_ID)
|
|
{
|
|
memset(&msg, 0, sizeof(msg));
|
|
params.hardwarePortId = hardwarePortId;
|
|
params.numOfFmanCtrls = numOfFmanCtrls;
|
|
msg.msgId = FM_SET_NUM_OF_FMAN_CTRL;
|
|
memcpy(msg.msgBody, ¶ms, sizeof(params));
|
|
if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
|
|
(uint8_t*)&msg,
|
|
sizeof(msg.msgId) +sizeof(params),
|
|
NULL,
|
|
NULL,
|
|
NULL,
|
|
NULL)) != E_OK)
|
|
RETURN_ERROR(MINOR, err, NO_MSG);
|
|
|
|
return E_OK;
|
|
}
|
|
|
|
XX_LockSpinlock(p_Fm->h_Spinlock);
|
|
|
|
tmpReg = (uint32_t)(hardwarePortId << FPM_PORT_FM_CTL_PORTID_SHIFT);
|
|
|
|
/*TODO - maybe to put CTL# according to another criteria*/
|
|
|
|
if(numOfFmanCtrls == 2)
|
|
tmpReg = FPM_PORT_FM_CTL2 | FPM_PORT_FM_CTL1;
|
|
|
|
/* order restoration */
|
|
if(hardwarePortId%2)
|
|
tmpReg |= (FPM_PORT_FM_CTL1 << FPM_PRC_ORA_FM_CTL_SEL_SHIFT) | FPM_PORT_FM_CTL1;
|
|
else
|
|
tmpReg |= (FPM_PORT_FM_CTL2 << FPM_PRC_ORA_FM_CTL_SEL_SHIFT) | FPM_PORT_FM_CTL2;
|
|
|
|
WRITE_UINT32(p_Fm->p_FmFpmRegs->fpmpr, tmpReg);
|
|
XX_UnlockSpinlock(p_Fm->h_Spinlock);
|
|
|
|
return E_OK;
|
|
}
|
|
|
|
t_Error FmGetSetPortParams(t_Handle h_Fm,t_FmInterModulePortInitParams *p_PortParams)
|
|
{
|
|
t_Fm *p_Fm = (t_Fm*)h_Fm;
|
|
uint32_t tmpReg;
|
|
uint8_t hardwarePortId = p_PortParams->hardwarePortId;
|
|
t_FmIpcPortInInitParams portInParams;
|
|
t_FmIpcPhysAddr ipcPhysAddr;
|
|
t_Error err;
|
|
t_FmIpcMsg msg;
|
|
t_FmIpcReply reply;
|
|
uint32_t replyLength;
|
|
|
|
if(p_Fm->guestId != NCSW_MASTER_ID)
|
|
{
|
|
portInParams.hardwarePortId = p_PortParams->hardwarePortId;
|
|
portInParams.enumPortType = (uint32_t)p_PortParams->portType;
|
|
portInParams.boolIndependentMode = (uint8_t)p_PortParams->independentMode;
|
|
portInParams.liodnOffset = p_PortParams->liodnOffset;
|
|
portInParams.numOfTasks = p_PortParams->numOfTasks;
|
|
portInParams.numOfExtraTasks = p_PortParams->numOfExtraTasks;
|
|
portInParams.numOfOpenDmas = p_PortParams->numOfOpenDmas;
|
|
portInParams.numOfExtraOpenDmas = p_PortParams->numOfExtraOpenDmas;
|
|
portInParams.sizeOfFifo = p_PortParams->sizeOfFifo;
|
|
portInParams.extraSizeOfFifo = p_PortParams->extraSizeOfFifo;
|
|
portInParams.deqPipelineDepth = p_PortParams->deqPipelineDepth;
|
|
portInParams.liodnBase = p_PortParams->liodnBase;
|
|
memset(&msg, 0, sizeof(msg));
|
|
memset(&reply, 0, sizeof(reply));
|
|
msg.msgId = FM_GET_SET_PORT_PARAMS;
|
|
memcpy(msg.msgBody, &portInParams, sizeof(portInParams));
|
|
replyLength = (sizeof(uint32_t) + sizeof(p_PortParams->fmMuramPhysBaseAddr));
|
|
if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
|
|
(uint8_t*)&msg,
|
|
sizeof(msg.msgId) +sizeof(portInParams),
|
|
(uint8_t*)&reply,
|
|
&replyLength,
|
|
NULL,
|
|
NULL)) != E_OK)
|
|
RETURN_ERROR(MINOR, err, NO_MSG);
|
|
if (replyLength != (sizeof(uint32_t) + sizeof(p_PortParams->fmMuramPhysBaseAddr)))
|
|
RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
|
|
memcpy((uint8_t*)&ipcPhysAddr, reply.replyBody, sizeof(t_FmIpcPhysAddr));
|
|
p_PortParams->fmMuramPhysBaseAddr.high = ipcPhysAddr.high;
|
|
p_PortParams->fmMuramPhysBaseAddr.low = ipcPhysAddr.low;
|
|
|
|
return (t_Error)(reply.error);
|
|
}
|
|
|
|
ASSERT_COND(IN_RANGE(1, hardwarePortId, 63));
|
|
XX_LockSpinlock(p_Fm->h_Spinlock);
|
|
|
|
if(p_PortParams->independentMode)
|
|
{
|
|
/* set port parameters */
|
|
p_Fm->independentMode = p_PortParams->independentMode;
|
|
/* disable dispatch limit */
|
|
WRITE_UINT32(p_Fm->p_FmFpmRegs->fpmflc, 0);
|
|
}
|
|
|
|
if(p_PortParams->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND)
|
|
{
|
|
if(p_Fm->hcPortInitialized)
|
|
{
|
|
XX_UnlockSpinlock(p_Fm->h_Spinlock);
|
|
RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Only one host command port is allowed."));
|
|
}
|
|
else
|
|
p_Fm->hcPortInitialized = TRUE;
|
|
}
|
|
p_Fm->p_FmStateStruct->portsTypes[hardwarePortId] = p_PortParams->portType;
|
|
|
|
err = FmSetNumOfTasks(p_Fm, p_PortParams->hardwarePortId, p_PortParams->numOfTasks, p_PortParams->numOfExtraTasks, TRUE);
|
|
if(err)
|
|
{
|
|
XX_UnlockSpinlock(p_Fm->h_Spinlock);
|
|
RETURN_ERROR(MAJOR, err, NO_MSG);
|
|
}
|
|
|
|
#ifdef FM_QMI_DEQ_OPTIONS_SUPPORT
|
|
if((p_PortParams->portType != e_FM_PORT_TYPE_RX) && (p_PortParams->portType != e_FM_PORT_TYPE_RX_10G))
|
|
/* for transmit & O/H ports */
|
|
{
|
|
uint8_t enqTh;
|
|
uint8_t deqTh;
|
|
bool update = FALSE;
|
|
|
|
/* update qmi ENQ/DEQ threshold */
|
|
p_Fm->p_FmStateStruct->accumulatedNumOfDeqTnums += p_PortParams->deqPipelineDepth;
|
|
tmpReg = GET_UINT32(p_Fm->p_FmQmiRegs->fmqm_gc);
|
|
enqTh = (uint8_t)(tmpReg>>8);
|
|
/* if enqTh is too big, we reduce it to the max value that is still OK */
|
|
if(enqTh >= (QMI_MAX_NUM_OF_TNUMS - p_Fm->p_FmStateStruct->accumulatedNumOfDeqTnums))
|
|
{
|
|
enqTh = (uint8_t)(QMI_MAX_NUM_OF_TNUMS - p_Fm->p_FmStateStruct->accumulatedNumOfDeqTnums - 1);
|
|
tmpReg &= ~QMI_CFG_ENQ_MASK;
|
|
tmpReg |= ((uint32_t)enqTh << 8);
|
|
update = TRUE;
|
|
}
|
|
|
|
deqTh = (uint8_t)tmpReg;
|
|
/* if deqTh is too small, we enlarge it to the min value that is still OK.
|
|
deqTh may not be larger than 63 (QMI_MAX_NUM_OF_TNUMS-1). */
|
|
if((deqTh <= p_Fm->p_FmStateStruct->accumulatedNumOfDeqTnums) && (deqTh < QMI_MAX_NUM_OF_TNUMS-1))
|
|
{
|
|
deqTh = (uint8_t)(p_Fm->p_FmStateStruct->accumulatedNumOfDeqTnums + 1);
|
|
tmpReg &= ~QMI_CFG_DEQ_MASK;
|
|
tmpReg |= (uint32_t)deqTh;
|
|
update = TRUE;
|
|
}
|
|
if(update)
|
|
WRITE_UINT32(p_Fm->p_FmQmiRegs->fmqm_gc, tmpReg);
|
|
}
|
|
#endif /* FM_QMI_DEQ_OPTIONS_SUPPORT */
|
|
|
|
#ifdef FM_LOW_END_RESTRICTION
|
|
if((hardwarePortId==0x1) || (hardwarePortId==0x29))
|
|
{
|
|
if(p_Fm->p_FmStateStruct->lowEndRestriction)
|
|
{
|
|
XX_UnlockSpinlock(p_Fm->h_Spinlock);
|
|
RETURN_ERROR(MAJOR, E_NOT_AVAILABLE, ("OP #0 cannot work with Tx Port #1."));
|
|
}
|
|
else
|
|
p_Fm->p_FmStateStruct->lowEndRestriction = TRUE;
|
|
}
|
|
#endif /* FM_LOW_END_RESTRICTION */
|
|
|
|
err = FmSetSizeOfFifo(p_Fm,
|
|
p_PortParams->hardwarePortId,
|
|
p_PortParams->portType,
|
|
p_PortParams->independentMode,
|
|
&p_PortParams->sizeOfFifo,
|
|
p_PortParams->extraSizeOfFifo,
|
|
p_PortParams->deqPipelineDepth,
|
|
NULL,
|
|
TRUE);
|
|
if(err)
|
|
{
|
|
XX_UnlockSpinlock(p_Fm->h_Spinlock);
|
|
RETURN_ERROR(MAJOR, err, NO_MSG);
|
|
}
|
|
|
|
err = FmSetNumOfOpenDmas(p_Fm, p_PortParams->hardwarePortId, p_PortParams->numOfOpenDmas, p_PortParams->numOfExtraOpenDmas, TRUE);
|
|
if(err)
|
|
{
|
|
XX_UnlockSpinlock(p_Fm->h_Spinlock);
|
|
RETURN_ERROR(MAJOR, err, NO_MSG);
|
|
}
|
|
|
|
WRITE_UINT32(p_Fm->p_FmBmiRegs->fmbm_ppid[hardwarePortId-1], (uint32_t)p_PortParams->liodnOffset);
|
|
|
|
tmpReg = (uint32_t)(hardwarePortId << FPM_PORT_FM_CTL_PORTID_SHIFT);
|
|
if(p_PortParams->independentMode)
|
|
{
|
|
if((p_PortParams->portType==e_FM_PORT_TYPE_RX) || (p_PortParams->portType==e_FM_PORT_TYPE_RX_10G))
|
|
tmpReg |= (FPM_PORT_FM_CTL1 << FPM_PRC_ORA_FM_CTL_SEL_SHIFT) |FPM_PORT_FM_CTL1;
|
|
else
|
|
tmpReg |= (FPM_PORT_FM_CTL2 << FPM_PRC_ORA_FM_CTL_SEL_SHIFT) |FPM_PORT_FM_CTL2;
|
|
}
|
|
else
|
|
{
|
|
tmpReg |= (FPM_PORT_FM_CTL2|FPM_PORT_FM_CTL1);
|
|
|
|
/* order restoration */
|
|
if(hardwarePortId%2)
|
|
tmpReg |= (FPM_PORT_FM_CTL1 << FPM_PRC_ORA_FM_CTL_SEL_SHIFT);
|
|
else
|
|
tmpReg |= (FPM_PORT_FM_CTL2 << FPM_PRC_ORA_FM_CTL_SEL_SHIFT);
|
|
}
|
|
WRITE_UINT32(p_Fm->p_FmFpmRegs->fpmpr, tmpReg);
|
|
|
|
{
|
|
#ifdef FM_PARTITION_ARRAY
|
|
t_FmRevisionInfo revInfo;
|
|
|
|
FM_GetRevision(p_Fm, &revInfo);
|
|
if (revInfo.majorRev >= 2)
|
|
#endif /* FM_PARTITION_ARRAY */
|
|
{
|
|
/* set LIODN base for this port */
|
|
tmpReg = GET_UINT32(p_Fm->p_FmDmaRegs->fmdmplr[hardwarePortId/2]);
|
|
if(hardwarePortId%2)
|
|
{
|
|
tmpReg &= ~FM_LIODN_BASE_MASK;
|
|
tmpReg |= (uint32_t)p_PortParams->liodnBase;
|
|
}
|
|
else
|
|
{
|
|
tmpReg &= ~(FM_LIODN_BASE_MASK<< DMA_LIODN_SHIFT);
|
|
tmpReg |= (uint32_t)p_PortParams->liodnBase << DMA_LIODN_SHIFT;
|
|
}
|
|
WRITE_UINT32(p_Fm->p_FmDmaRegs->fmdmplr[hardwarePortId/2], tmpReg);
|
|
}
|
|
}
|
|
|
|
FmGetPhysicalMuramBase(p_Fm, &p_PortParams->fmMuramPhysBaseAddr);
|
|
XX_UnlockSpinlock(p_Fm->h_Spinlock);
|
|
|
|
return E_OK;
|
|
}
|
|
|
|
void FmFreePortParams(t_Handle h_Fm,t_FmInterModulePortFreeParams *p_PortParams)
|
|
{
|
|
t_Fm *p_Fm = (t_Fm*)h_Fm;
|
|
uint32_t tmpReg;
|
|
uint8_t hardwarePortId = p_PortParams->hardwarePortId;
|
|
uint8_t numOfTasks;
|
|
t_Error err;
|
|
t_FmIpcPortFreeParams portParams;
|
|
t_FmIpcMsg msg;
|
|
|
|
if(p_Fm->guestId != NCSW_MASTER_ID)
|
|
{
|
|
portParams.hardwarePortId = p_PortParams->hardwarePortId;
|
|
portParams.enumPortType = (uint32_t)p_PortParams->portType;
|
|
#ifdef FM_QMI_DEQ_OPTIONS_SUPPORT
|
|
portParams.deqPipelineDepth = p_PortParams->deqPipelineDepth;
|
|
#endif /* FM_QMI_DEQ_OPTIONS_SUPPORT */
|
|
memset(&msg, 0, sizeof(msg));
|
|
msg.msgId = FM_FREE_PORT;
|
|
memcpy(msg.msgBody, &portParams, sizeof(portParams));
|
|
if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
|
|
(uint8_t*)&msg,
|
|
sizeof(msg.msgId)+sizeof(portParams),
|
|
NULL,
|
|
NULL,
|
|
NULL,
|
|
NULL)) != E_OK)
|
|
REPORT_ERROR(MINOR, err, NO_MSG);
|
|
return;
|
|
}
|
|
|
|
ASSERT_COND(IN_RANGE(1, hardwarePortId, 63));
|
|
XX_LockSpinlock(p_Fm->h_Spinlock);
|
|
|
|
|
|
if(p_PortParams->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND)
|
|
{
|
|
ASSERT_COND(p_Fm->hcPortInitialized);
|
|
p_Fm->hcPortInitialized = FALSE;
|
|
}
|
|
|
|
p_Fm->p_FmStateStruct->portsTypes[hardwarePortId] = e_FM_PORT_TYPE_DUMMY;
|
|
|
|
tmpReg = GET_UINT32(p_Fm->p_FmBmiRegs->fmbm_pp[hardwarePortId-1]);
|
|
/* free numOfTasks */
|
|
numOfTasks = (uint8_t)(((tmpReg & BMI_NUM_OF_TASKS_MASK) >> BMI_NUM_OF_TASKS_SHIFT) + 1);
|
|
ASSERT_COND(p_Fm->p_FmStateStruct->accumulatedNumOfTasks >= numOfTasks);
|
|
p_Fm->p_FmStateStruct->accumulatedNumOfTasks -= numOfTasks;
|
|
|
|
/* free numOfOpenDmas */
|
|
ASSERT_COND(p_Fm->p_FmStateStruct->accumulatedNumOfOpenDmas >= ((tmpReg & BMI_NUM_OF_DMAS_MASK) >> BMI_NUM_OF_DMAS_SHIFT) + 1);
|
|
p_Fm->p_FmStateStruct->accumulatedNumOfOpenDmas -= (((tmpReg & BMI_NUM_OF_DMAS_MASK) >> BMI_NUM_OF_DMAS_SHIFT) + 1);
|
|
|
|
/* update total num of DMA's with committed number of open DMAS, and max uncommitted pool. */
|
|
tmpReg = GET_UINT32(p_Fm->p_FmBmiRegs->fmbm_cfg2) & ~BMI_CFG2_DMAS_MASK;
|
|
tmpReg |= (uint32_t)(p_Fm->p_FmStateStruct->accumulatedNumOfOpenDmas + p_Fm->p_FmStateStruct->extraOpenDmasPoolSize - 1) << BMI_CFG2_DMAS_SHIFT;
|
|
WRITE_UINT32(p_Fm->p_FmBmiRegs->fmbm_cfg2, tmpReg);
|
|
|
|
/* free sizeOfFifo */
|
|
tmpReg = GET_UINT32(p_Fm->p_FmBmiRegs->fmbm_pfs[hardwarePortId-1]);
|
|
ASSERT_COND(p_Fm->p_FmStateStruct->accumulatedFifoSize >=
|
|
(((tmpReg & BMI_FIFO_SIZE_MASK) + 1) * BMI_FIFO_UNITS));
|
|
p_Fm->p_FmStateStruct->accumulatedFifoSize -=
|
|
(((tmpReg & BMI_FIFO_SIZE_MASK) + 1) * BMI_FIFO_UNITS);
|
|
|
|
/* clear registers */
|
|
WRITE_UINT32(p_Fm->p_FmBmiRegs->fmbm_pp[hardwarePortId-1], 0);
|
|
WRITE_UINT32(p_Fm->p_FmBmiRegs->fmbm_pfs[hardwarePortId-1], 0);
|
|
/* WRITE_UINT32(p_Fm->p_FmBmiRegs->fmbm_ppid[hardwarePortId-1], 0); */
|
|
|
|
#ifdef FM_PORT_DISABLED_ERRATA_FMANx9
|
|
/* this errata means that when a port is taken down, other port may not use its
|
|
* resources for a while as it may still be using it (in case of reject).
|
|
*/
|
|
{
|
|
t_FmRevisionInfo revInfo;
|
|
FM_GetRevision(p_Fm, &revInfo);
|
|
if ((revInfo.majorRev == 1) && (revInfo.minorRev == 0))
|
|
XX_UDelay(100000);
|
|
}
|
|
#endif /* FM_PORT_DISABLED_ERRATA_FMANx9 */
|
|
|
|
#ifdef FM_QMI_DEQ_OPTIONS_SUPPORT
|
|
if((p_PortParams->portType != e_FM_PORT_TYPE_RX) && (p_PortParams->portType != e_FM_PORT_TYPE_RX_10G))
|
|
/* for transmit & O/H ports */
|
|
{
|
|
uint8_t enqTh;
|
|
uint8_t deqTh;
|
|
|
|
tmpReg = GET_UINT32(p_Fm->p_FmQmiRegs->fmqm_gc);
|
|
/* update qmi ENQ/DEQ threshold */
|
|
p_Fm->p_FmStateStruct->accumulatedNumOfDeqTnums -= p_PortParams->deqPipelineDepth;
|
|
|
|
/* p_Fm->p_FmStateStruct->accumulatedNumOfDeqTnums is now smaller,
|
|
so we can enlarge enqTh */
|
|
enqTh = (uint8_t)(QMI_MAX_NUM_OF_TNUMS - p_Fm->p_FmStateStruct->accumulatedNumOfDeqTnums - 1);
|
|
tmpReg &= ~QMI_CFG_ENQ_MASK;
|
|
tmpReg |= ((uint32_t)enqTh << QMI_CFG_ENQ_SHIFT);
|
|
|
|
/* p_Fm->p_FmStateStruct->accumulatedNumOfDeqTnums is now smaller,
|
|
so we can reduce deqTh */
|
|
deqTh = (uint8_t)(p_Fm->p_FmStateStruct->accumulatedNumOfDeqTnums + 1);
|
|
tmpReg &= ~QMI_CFG_DEQ_MASK;
|
|
tmpReg |= (uint32_t)deqTh;
|
|
|
|
WRITE_UINT32(p_Fm->p_FmQmiRegs->fmqm_gc, tmpReg);
|
|
}
|
|
#endif /* FM_QMI_DEQ_OPTIONS_SUPPORT */
|
|
|
|
#ifdef FM_LOW_END_RESTRICTION
|
|
if((hardwarePortId==0x1) || (hardwarePortId==0x29))
|
|
p_Fm->p_FmStateStruct->lowEndRestriction = FALSE;
|
|
#endif /* FM_LOW_END_RESTRICTION */
|
|
XX_UnlockSpinlock(p_Fm->h_Spinlock);
|
|
}
|
|
|
|
t_Error FmIsPortStalled(t_Handle h_Fm, uint8_t hardwarePortId, bool *p_IsStalled)
|
|
{
|
|
t_Fm *p_Fm = (t_Fm*)h_Fm;
|
|
uint32_t tmpReg;
|
|
t_Error err;
|
|
t_FmIpcMsg msg;
|
|
t_FmIpcReply reply;
|
|
uint32_t replyLength;
|
|
|
|
if(p_Fm->guestId != NCSW_MASTER_ID)
|
|
{
|
|
memset(&msg, 0, sizeof(msg));
|
|
memset(&reply, 0, sizeof(reply));
|
|
msg.msgId = FM_IS_PORT_STALLED;
|
|
msg.msgBody[0] = hardwarePortId;
|
|
replyLength = sizeof(uint32_t) + sizeof(uint8_t);
|
|
if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
|
|
(uint8_t*)&msg,
|
|
sizeof(msg.msgId)+sizeof(hardwarePortId),
|
|
(uint8_t*)&reply,
|
|
&replyLength,
|
|
NULL,
|
|
NULL)) != E_OK)
|
|
RETURN_ERROR(MINOR, err, NO_MSG);
|
|
if (replyLength != (sizeof(uint32_t) + sizeof(uint8_t)))
|
|
RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
|
|
|
|
*p_IsStalled = (bool)!!(*(uint8_t*)(reply.replyBody));
|
|
|
|
return (t_Error)(reply.error);
|
|
}
|
|
|
|
tmpReg = GET_UINT32(p_Fm->p_FmFpmRegs->fmfp_ps[hardwarePortId]);
|
|
*p_IsStalled = (bool)!!(tmpReg & FPM_PS_STALLED);
|
|
|
|
return E_OK;
|
|
}
|
|
|
|
t_Error FmResumeStalledPort(t_Handle h_Fm, uint8_t hardwarePortId)
|
|
{
|
|
t_Fm *p_Fm = (t_Fm*)h_Fm;
|
|
uint32_t tmpReg;
|
|
t_Error err;
|
|
bool isStalled;
|
|
t_FmIpcMsg msg;
|
|
t_FmIpcReply reply;
|
|
uint32_t replyLength;
|
|
|
|
if(p_Fm->guestId != NCSW_MASTER_ID)
|
|
{
|
|
memset(&msg, 0, sizeof(msg));
|
|
memset(&reply, 0, sizeof(reply));
|
|
msg.msgId = FM_RESUME_STALLED_PORT;
|
|
msg.msgBody[0] = hardwarePortId;
|
|
replyLength = sizeof(uint32_t);
|
|
if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
|
|
(uint8_t*)&msg,
|
|
sizeof(msg.msgId) + sizeof(hardwarePortId),
|
|
(uint8_t*)&reply,
|
|
&replyLength,
|
|
NULL,
|
|
NULL)) != E_OK)
|
|
RETURN_ERROR(MINOR, err, NO_MSG);
|
|
if (replyLength != sizeof(uint32_t))
|
|
RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
|
|
return (t_Error)(reply.error);
|
|
}
|
|
|
|
/* Get port status */
|
|
err = FmIsPortStalled(h_Fm, hardwarePortId, &isStalled);
|
|
if(err)
|
|
RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Can't get port status"));
|
|
if (!isStalled)
|
|
RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Port is not stalled"));
|
|
|
|
tmpReg = (uint32_t)((hardwarePortId << FPM_PORT_FM_CTL_PORTID_SHIFT) | FPM_PRC_REALSE_STALLED);
|
|
WRITE_UINT32(p_Fm->p_FmFpmRegs->fpmpr, tmpReg);
|
|
|
|
return E_OK;
|
|
}
|
|
|
|
t_Error FmResetMac(t_Handle h_Fm, e_FmMacType type, uint8_t macId)
|
|
{
|
|
t_Fm *p_Fm = (t_Fm*)h_Fm;
|
|
uint32_t bitMask, timeout = 1000;
|
|
t_FmIpcMacParams macParams;
|
|
t_Error err;
|
|
t_FmIpcMsg msg;
|
|
t_FmIpcReply reply;
|
|
uint32_t replyLength;
|
|
|
|
if(p_Fm->guestId != NCSW_MASTER_ID)
|
|
{
|
|
if(p_Fm->h_IpcSessions[0])
|
|
{
|
|
memset(&msg, 0, sizeof(msg));
|
|
memset(&reply, 0, sizeof(reply));
|
|
macParams.id = macId;
|
|
macParams.enumType = (uint32_t)type;
|
|
msg.msgId = FM_RESET_MAC;
|
|
memcpy(msg.msgBody, &macParams, sizeof(macParams));
|
|
replyLength = sizeof(uint32_t);
|
|
if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
|
|
(uint8_t*)&msg,
|
|
sizeof(msg.msgId)+sizeof(macParams),
|
|
(uint8_t*)&reply,
|
|
&replyLength,
|
|
NULL,
|
|
NULL)) != E_OK)
|
|
RETURN_ERROR(MINOR, err, NO_MSG);
|
|
if (replyLength != sizeof(uint32_t))
|
|
RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
|
|
return (t_Error)(reply.error);
|
|
}
|
|
else
|
|
if(!p_Fm->p_FmFpmRegs)
|
|
RETURN_ERROR(MINOR, E_INVALID_STATE, ("No IPC and no registers address"));
|
|
}
|
|
|
|
/* Get the relevant bit mask */
|
|
if (type == e_FM_MAC_10G)
|
|
{
|
|
switch(macId)
|
|
{
|
|
case(0):
|
|
bitMask = FPM_RSTC_10G0_RESET;
|
|
break;
|
|
default:
|
|
RETURN_ERROR(MINOR, E_INVALID_VALUE, ("Illegal MAC Id"));
|
|
}
|
|
}
|
|
else
|
|
{
|
|
switch(macId)
|
|
{
|
|
case(0):
|
|
bitMask = FPM_RSTC_1G0_RESET;
|
|
break;
|
|
case(1):
|
|
bitMask = FPM_RSTC_1G1_RESET;
|
|
break;
|
|
case(2):
|
|
bitMask = FPM_RSTC_1G2_RESET;
|
|
break;
|
|
case(3):
|
|
bitMask = FPM_RSTC_1G3_RESET;
|
|
break;
|
|
case(4):
|
|
bitMask = FPM_RSTC_1G4_RESET;
|
|
break;
|
|
default:
|
|
RETURN_ERROR(MINOR, E_INVALID_VALUE, ("Illegal MAC Id"));
|
|
}
|
|
}
|
|
|
|
/* reset */
|
|
WRITE_UINT32(p_Fm->p_FmFpmRegs->fmrstc, bitMask);
|
|
while ((GET_UINT32(p_Fm->p_FmFpmRegs->fmrstc) & bitMask) &&
|
|
--timeout) ;
|
|
if (!timeout)
|
|
return ERROR_CODE(E_TIMEOUT);
|
|
return E_OK;
|
|
}
|
|
|
|
t_Error FmSetMacMaxFrame(t_Handle h_Fm, e_FmMacType type, uint8_t macId, uint16_t mtu)
|
|
{
|
|
t_Fm *p_Fm = (t_Fm*)h_Fm;
|
|
t_FmIpcMacMaxFrameParams macMaxFrameLengthParams;
|
|
t_Error err;
|
|
t_FmIpcMsg msg;
|
|
|
|
if(p_Fm->guestId != NCSW_MASTER_ID)
|
|
{
|
|
memset(&msg, 0, sizeof(msg));
|
|
macMaxFrameLengthParams.macParams.id = macId;
|
|
macMaxFrameLengthParams.macParams.enumType = (uint32_t)type;
|
|
macMaxFrameLengthParams.maxFrameLength = (uint16_t)mtu;
|
|
msg.msgId = FM_SET_MAC_MAX_FRAME;
|
|
memcpy(msg.msgBody, &macMaxFrameLengthParams, sizeof(macMaxFrameLengthParams));
|
|
if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
|
|
(uint8_t*)&msg,
|
|
sizeof(msg.msgId)+sizeof(macMaxFrameLengthParams),
|
|
NULL,
|
|
NULL,
|
|
NULL,
|
|
NULL)) != E_OK)
|
|
RETURN_ERROR(MINOR, err, NO_MSG);
|
|
return E_OK;
|
|
}
|
|
|
|
#if (defined(FM_MAX_NUM_OF_10G_MACS) && (FM_MAX_NUM_OF_10G_MACS))
|
|
if (type == e_FM_MAC_10G)
|
|
p_Fm->p_FmStateStruct->macMaxFrameLengths10G[macId] = mtu;
|
|
else
|
|
#else
|
|
UNUSED(type);
|
|
#endif /* (defined(FM_MAX_NUM_OF_10G_MACS) && ... */
|
|
p_Fm->p_FmStateStruct->macMaxFrameLengths1G[macId] = mtu;
|
|
|
|
return E_OK;
|
|
}
|
|
|
|
uint16_t FmGetClockFreq(t_Handle h_Fm)
|
|
{
|
|
t_Fm *p_Fm = (t_Fm*)h_Fm;
|
|
/* for MC environment: this depends on the
|
|
* fact that fmClkFreq was properly initialized at "init". */
|
|
return p_Fm->p_FmStateStruct->fmClkFreq;
|
|
}
|
|
|
|
uint32_t FmGetTimeStampScale(t_Handle h_Fm)
|
|
{
|
|
t_Fm *p_Fm = (t_Fm*)h_Fm;
|
|
t_Error err;
|
|
t_FmIpcMsg msg;
|
|
t_FmIpcReply reply;
|
|
uint32_t replyLength, timeStamp;
|
|
|
|
if(p_Fm->guestId != NCSW_MASTER_ID)
|
|
{
|
|
memset(&msg, 0, sizeof(msg));
|
|
memset(&reply, 0, sizeof(reply));
|
|
msg.msgId = FM_GET_TIMESTAMP_SCALE;
|
|
replyLength = sizeof(uint32_t) + sizeof(uint32_t);
|
|
if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
|
|
(uint8_t*)&msg,
|
|
sizeof(msg.msgId),
|
|
(uint8_t*)&reply,
|
|
&replyLength,
|
|
NULL,
|
|
NULL)) != E_OK)
|
|
RETURN_ERROR(MINOR, err, NO_MSG);
|
|
if(replyLength != (sizeof(uint32_t) + sizeof(uint32_t)))
|
|
RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
|
|
|
|
memcpy((uint8_t*)&timeStamp, reply.replyBody, sizeof(uint32_t));
|
|
return timeStamp;
|
|
}
|
|
|
|
if(!p_Fm->p_FmStateStruct->enabledTimeStamp)
|
|
FmEnableTimeStamp(p_Fm);
|
|
|
|
return p_Fm->p_FmStateStruct->count1MicroBit;
|
|
}
|
|
|
|
bool FmRamsEccIsExternalCtl(t_Handle h_Fm)
|
|
{
|
|
t_Fm *p_Fm = (t_Fm*)h_Fm;
|
|
uint32_t tmpReg;
|
|
|
|
tmpReg = GET_UINT32(p_Fm->p_FmFpmRegs->fmrcr);
|
|
if(tmpReg & FPM_RAM_CTL_RAMS_ECC_EN_SRC_SEL)
|
|
return TRUE;
|
|
else
|
|
return FALSE;
|
|
}
|
|
|
|
t_Error FmEnableRamsEcc(t_Handle h_Fm)
|
|
{
|
|
t_Fm *p_Fm = (t_Fm*)h_Fm;
|
|
|
|
SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
|
|
|
|
p_Fm->p_FmStateStruct->ramsEccOwners++;
|
|
p_Fm->p_FmStateStruct->internalCall = TRUE;
|
|
|
|
return FM_EnableRamsEcc(p_Fm);
|
|
}
|
|
|
|
t_Error FmDisableRamsEcc(t_Handle h_Fm)
|
|
{
|
|
t_Fm *p_Fm = (t_Fm*)h_Fm;
|
|
|
|
SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
|
|
|
|
ASSERT_COND(p_Fm->p_FmStateStruct->ramsEccOwners);
|
|
p_Fm->p_FmStateStruct->ramsEccOwners--;
|
|
|
|
if(p_Fm->p_FmStateStruct->ramsEccOwners==0)
|
|
{
|
|
p_Fm->p_FmStateStruct->internalCall = TRUE;
|
|
return FM_DisableRamsEcc(p_Fm);
|
|
}
|
|
return E_OK;
|
|
}
|
|
|
|
uint8_t FmGetGuestId(t_Handle h_Fm)
|
|
{
|
|
t_Fm *p_Fm = (t_Fm*)h_Fm;
|
|
|
|
return p_Fm->guestId;
|
|
}
|
|
|
|
bool FmIsMaster(t_Handle h_Fm)
|
|
{
|
|
t_Fm *p_Fm = (t_Fm*)h_Fm;
|
|
|
|
return (p_Fm->guestId == NCSW_MASTER_ID);
|
|
}
|
|
|
|
t_Error FmSetSizeOfFifo(t_Handle h_Fm,
|
|
uint8_t hardwarePortId,
|
|
e_FmPortType portType,
|
|
bool independentMode,
|
|
uint32_t *p_SizeOfFifo,
|
|
uint32_t extraSizeOfFifo,
|
|
uint8_t deqPipelineDepth,
|
|
t_FmInterModulePortRxPoolsParams *p_RxPoolsParams,
|
|
bool initialConfig)
|
|
{
|
|
t_Fm *p_Fm = (t_Fm*)h_Fm;
|
|
uint8_t relativePortId;
|
|
uint16_t macMaxFrameLength = 0, oldVal;
|
|
uint32_t minFifoSizeRequired = 0, sizeOfFifo, tmpReg = 0;
|
|
t_FmIpcPortFifoParams fifoParams;
|
|
t_Error err;
|
|
|
|
ASSERT_COND(IN_RANGE(1, hardwarePortId, 63));
|
|
ASSERT_COND(initialConfig || p_RxPoolsParams);
|
|
|
|
if(p_Fm->guestId != NCSW_MASTER_ID)
|
|
{
|
|
t_FmIpcMsg msg;
|
|
t_FmIpcReply reply;
|
|
uint32_t replyLength;
|
|
|
|
ASSERT_COND(p_RxPoolsParams);
|
|
|
|
memset(&fifoParams, 0, sizeof(fifoParams));
|
|
fifoParams.rsrcParams.hardwarePortId = hardwarePortId;
|
|
fifoParams.rsrcParams.val = *p_SizeOfFifo;
|
|
fifoParams.rsrcParams.extra = extraSizeOfFifo;
|
|
fifoParams.enumPortType = (uint32_t)portType;
|
|
fifoParams.boolIndependentMode = (uint8_t)independentMode;
|
|
fifoParams.deqPipelineDepth = deqPipelineDepth;
|
|
fifoParams.numOfPools = p_RxPoolsParams->numOfPools;
|
|
fifoParams.secondLargestBufSize = p_RxPoolsParams->secondLargestBufSize;
|
|
fifoParams.largestBufSize = p_RxPoolsParams->largestBufSize;
|
|
fifoParams.boolInitialConfig = (uint8_t)initialConfig;
|
|
|
|
memset(&msg, 0, sizeof(msg));
|
|
memset(&reply, 0, sizeof(reply));
|
|
msg.msgId = FM_SET_SIZE_OF_FIFO;
|
|
memcpy(msg.msgBody, &fifoParams, sizeof(fifoParams));
|
|
replyLength = sizeof(uint32_t) + sizeof(uint32_t);
|
|
if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
|
|
(uint8_t*)&msg,
|
|
sizeof(msg.msgId) + sizeof(fifoParams),
|
|
(uint8_t*)&reply,
|
|
&replyLength,
|
|
NULL,
|
|
NULL)) != E_OK)
|
|
RETURN_ERROR(MINOR, err, NO_MSG);
|
|
if (replyLength != (sizeof(uint32_t) + sizeof(uint32_t)))
|
|
RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
|
|
memcpy((uint8_t*)p_SizeOfFifo, reply.replyBody, sizeof(uint32_t));
|
|
|
|
return (t_Error)(reply.error);
|
|
}
|
|
sizeOfFifo = *p_SizeOfFifo;
|
|
/* if neseccary (cases where frame length is relevant), update sizeOfFifo field. */
|
|
if((portType == e_FM_PORT_TYPE_TX) || ((portType == e_FM_PORT_TYPE_RX) && independentMode))
|
|
{
|
|
HW_PORT_ID_TO_SW_PORT_ID(relativePortId, hardwarePortId);
|
|
ASSERT_COND(relativePortId < FM_MAX_NUM_OF_1G_MACS);
|
|
macMaxFrameLength = p_Fm->p_FmStateStruct->macMaxFrameLengths1G[relativePortId];
|
|
}
|
|
|
|
#if (defined(FM_MAX_NUM_OF_10G_MACS) && (FM_MAX_NUM_OF_10G_MACS))
|
|
if((portType == e_FM_PORT_TYPE_TX_10G) || ((portType == e_FM_PORT_TYPE_RX_10G) && independentMode))
|
|
{
|
|
HW_PORT_ID_TO_SW_PORT_ID(relativePortId, hardwarePortId);
|
|
ASSERT_COND(relativePortId < FM_MAX_NUM_OF_10G_MACS);
|
|
macMaxFrameLength = p_Fm->p_FmStateStruct->macMaxFrameLengths10G[relativePortId];
|
|
}
|
|
#endif /* (defined(FM_MAX_NUM_OF_10G_MACS) && ... */
|
|
|
|
/*************************/
|
|
/* TX PORTS */
|
|
/*************************/
|
|
if((portType == e_FM_PORT_TYPE_TX) || (portType == e_FM_PORT_TYPE_TX_10G))
|
|
{
|
|
if(independentMode)
|
|
minFifoSizeRequired = (uint32_t)((macMaxFrameLength % BMI_FIFO_UNITS ?
|
|
(macMaxFrameLength/BMI_FIFO_UNITS + 1) * BMI_FIFO_UNITS :
|
|
macMaxFrameLength) +
|
|
(3*BMI_FIFO_UNITS));
|
|
else
|
|
minFifoSizeRequired = (uint32_t)((macMaxFrameLength % BMI_FIFO_UNITS ?
|
|
(macMaxFrameLength/BMI_FIFO_UNITS + 1) * BMI_FIFO_UNITS :
|
|
macMaxFrameLength) +
|
|
(deqPipelineDepth+3)*BMI_FIFO_UNITS);
|
|
}
|
|
/*************************/
|
|
/* RX IM PORTS */
|
|
/*************************/
|
|
else if(((portType == e_FM_PORT_TYPE_RX) || (portType == e_FM_PORT_TYPE_RX_10G)) && independentMode)
|
|
minFifoSizeRequired = (uint32_t)(((macMaxFrameLength % BMI_FIFO_UNITS) ?
|
|
((macMaxFrameLength/BMI_FIFO_UNITS + 1) * BMI_FIFO_UNITS) :
|
|
macMaxFrameLength) +
|
|
(4*BMI_FIFO_UNITS));
|
|
|
|
/* for Rx (non-Im) ports or OP, buffer pools are relevant for fifo size.
|
|
If this routine is called as part of the "GetSet" routine, initialConfig is TRUE
|
|
and these checks where done in the port routine.
|
|
If it is called by an explicit user request ("SetSizeOfFifo"), than these parameters
|
|
should be checked/updated */
|
|
if(!initialConfig &&
|
|
((portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING) ||
|
|
(((portType == e_FM_PORT_TYPE_RX) || (portType == e_FM_PORT_TYPE_RX_10G)) && !independentMode)))
|
|
{
|
|
if((portType == e_FM_PORT_TYPE_RX) || (portType == e_FM_PORT_TYPE_RX_10G))
|
|
{
|
|
/*************************/
|
|
/* RX non-IM PORTS */
|
|
/*************************/
|
|
#ifdef FM_FIFO_ALLOCATION_OLD_ALG
|
|
t_FmRevisionInfo revInfo;
|
|
|
|
FM_GetRevision(p_Fm, &revInfo);
|
|
if(revInfo.majorRev != 4)
|
|
minFifoSizeRequired = (uint32_t)(((p_RxPoolsParams->largestBufSize % BMI_FIFO_UNITS) ?
|
|
((p_RxPoolsParams->largestBufSize/BMI_FIFO_UNITS + 1) * BMI_FIFO_UNITS) :
|
|
p_RxPoolsParams->largestBufSize) +
|
|
(7*BMI_FIFO_UNITS));
|
|
else
|
|
#endif /* FM_FIFO_ALLOCATION_OLD_ALG */
|
|
{
|
|
if(p_RxPoolsParams->numOfPools == 1)
|
|
minFifoSizeRequired = 8*BMI_FIFO_UNITS;
|
|
else
|
|
{
|
|
minFifoSizeRequired = (uint32_t)(((p_RxPoolsParams->secondLargestBufSize % BMI_FIFO_UNITS) ?
|
|
((p_RxPoolsParams->secondLargestBufSize/BMI_FIFO_UNITS + 1) * BMI_FIFO_UNITS) :
|
|
p_RxPoolsParams->secondLargestBufSize) +
|
|
(7*BMI_FIFO_UNITS));
|
|
if((sizeOfFifo < minFifoSizeRequired))
|
|
{
|
|
DBG(WARNING, ("User set FIFO size for Rx port is not optimized. (not modified by driver)"));
|
|
minFifoSizeRequired = 8*BMI_FIFO_UNITS;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
/*************************/
|
|
/* OP PORTS */
|
|
/*************************/
|
|
/* check if pool size is not too big */
|
|
if(p_RxPoolsParams->largestBufSize > sizeOfFifo )
|
|
RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Largest pool size is bigger than ports committed fifo size"));
|
|
}
|
|
}
|
|
|
|
|
|
if (minFifoSizeRequired && (sizeOfFifo < minFifoSizeRequired))
|
|
{
|
|
sizeOfFifo = minFifoSizeRequired;
|
|
DBG(WARNING, ("FIFO size enlarged to %d for port %#x", minFifoSizeRequired, hardwarePortId));
|
|
}
|
|
|
|
if(initialConfig)
|
|
oldVal = 0;
|
|
else
|
|
{
|
|
tmpReg = GET_UINT32(p_Fm->p_FmBmiRegs->fmbm_pfs[hardwarePortId-1]);
|
|
/* read into oldVal the current extra fifo size */
|
|
oldVal = (uint16_t)((((tmpReg & BMI_EXTRA_FIFO_SIZE_MASK) + 1)*BMI_FIFO_UNITS) >> BMI_EXTRA_FIFO_SIZE_SHIFT);
|
|
}
|
|
|
|
if(extraSizeOfFifo > oldVal)
|
|
p_Fm->p_FmStateStruct->extraFifoPoolSize = NCSW_MAX(p_Fm->p_FmStateStruct->extraFifoPoolSize, extraSizeOfFifo);
|
|
|
|
if(!initialConfig)
|
|
/* read into oldVal the current num of tasks */
|
|
oldVal = (uint16_t)(((tmpReg & BMI_FIFO_SIZE_MASK) + 1)*BMI_FIFO_UNITS);
|
|
|
|
/* check that there are enough uncommitted fifo size */
|
|
if((p_Fm->p_FmStateStruct->accumulatedFifoSize - oldVal + sizeOfFifo) >
|
|
(p_Fm->p_FmStateStruct->totalFifoSize - p_Fm->p_FmStateStruct->extraFifoPoolSize))
|
|
RETURN_ERROR(MAJOR, E_NOT_AVAILABLE, ("Requested fifo size and extra size exceed total FIFO size."));
|
|
else
|
|
{
|
|
/* update acummulated */
|
|
ASSERT_COND(p_Fm->p_FmStateStruct->accumulatedFifoSize >= oldVal);
|
|
p_Fm->p_FmStateStruct->accumulatedFifoSize -= oldVal;
|
|
p_Fm->p_FmStateStruct->accumulatedFifoSize += sizeOfFifo;
|
|
/* calculate reg */
|
|
tmpReg = (uint32_t)((sizeOfFifo/BMI_FIFO_UNITS - 1) |
|
|
((extraSizeOfFifo/BMI_FIFO_UNITS) << BMI_EXTRA_FIFO_SIZE_SHIFT));
|
|
WRITE_UINT32(p_Fm->p_FmBmiRegs->fmbm_pfs[hardwarePortId-1], tmpReg);
|
|
}
|
|
*p_SizeOfFifo = sizeOfFifo;
|
|
|
|
return E_OK;
|
|
}
|
|
|
|
t_Error FmSetNumOfTasks(t_Handle h_Fm,
|
|
uint8_t hardwarePortId,
|
|
uint8_t numOfTasks,
|
|
uint8_t numOfExtraTasks,
|
|
bool initialConfig)
|
|
{
|
|
t_Fm *p_Fm = (t_Fm *)h_Fm;
|
|
uint8_t oldVal;
|
|
uint32_t tmpReg = 0;
|
|
t_FmIpcPortRsrcParams rsrcParams;
|
|
t_Error err;
|
|
|
|
if(p_Fm->guestId != NCSW_MASTER_ID)
|
|
{
|
|
t_FmIpcMsg msg;
|
|
t_FmIpcReply reply;
|
|
uint32_t replyLength;
|
|
|
|
rsrcParams.hardwarePortId = hardwarePortId;
|
|
rsrcParams.val = numOfTasks;
|
|
rsrcParams.extra = numOfExtraTasks;
|
|
rsrcParams.boolInitialConfig = (uint8_t)initialConfig;
|
|
|
|
memset(&msg, 0, sizeof(msg));
|
|
memset(&reply, 0, sizeof(reply));
|
|
msg.msgId = FM_SET_NUM_OF_TASKS;
|
|
memcpy(msg.msgBody, &rsrcParams, sizeof(rsrcParams));
|
|
replyLength = sizeof(uint32_t);
|
|
if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
|
|
(uint8_t*)&msg,
|
|
sizeof(msg.msgId) + sizeof(rsrcParams),
|
|
(uint8_t*)&reply,
|
|
&replyLength,
|
|
NULL,
|
|
NULL)) != E_OK)
|
|
RETURN_ERROR(MINOR, err, NO_MSG);
|
|
if (replyLength != sizeof(uint32_t))
|
|
RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
|
|
return (t_Error)(reply.error);
|
|
}
|
|
|
|
ASSERT_COND(IN_RANGE(1, hardwarePortId, 63));
|
|
|
|
if(initialConfig)
|
|
oldVal = 0;
|
|
else
|
|
{
|
|
tmpReg = GET_UINT32(p_Fm->p_FmBmiRegs->fmbm_pp[hardwarePortId-1]);
|
|
/* read into oldVal the current extra tasks */
|
|
oldVal = (uint8_t)((tmpReg & BMI_NUM_OF_EXTRA_TASKS_MASK) >> BMI_EXTRA_NUM_OF_TASKS_SHIFT);
|
|
}
|
|
|
|
if(numOfExtraTasks > oldVal)
|
|
p_Fm->p_FmStateStruct->extraTasksPoolSize = (uint8_t)NCSW_MAX(p_Fm->p_FmStateStruct->extraTasksPoolSize, numOfExtraTasks);
|
|
|
|
if(!initialConfig)
|
|
/* read into oldVal the current num of tasks */
|
|
oldVal = (uint8_t)(((tmpReg & BMI_NUM_OF_TASKS_MASK) >> BMI_NUM_OF_TASKS_SHIFT) + 1);
|
|
|
|
/* check that there are enough uncommitted tasks */
|
|
if((p_Fm->p_FmStateStruct->accumulatedNumOfTasks - oldVal + numOfTasks) >
|
|
(p_Fm->p_FmStateStruct->totalNumOfTasks - p_Fm->p_FmStateStruct->extraTasksPoolSize))
|
|
RETURN_ERROR(MAJOR, E_NOT_AVAILABLE,
|
|
("Requested numOfTasks and extra tasks pool for fm%d exceed total numOfTasks.",
|
|
p_Fm->p_FmStateStruct->fmId));
|
|
else
|
|
{
|
|
ASSERT_COND(p_Fm->p_FmStateStruct->accumulatedNumOfTasks >= oldVal);
|
|
/* update acummulated */
|
|
p_Fm->p_FmStateStruct->accumulatedNumOfTasks -= oldVal;
|
|
p_Fm->p_FmStateStruct->accumulatedNumOfTasks += numOfTasks;
|
|
/* calculate reg */
|
|
tmpReg = GET_UINT32(p_Fm->p_FmBmiRegs->fmbm_pp[hardwarePortId-1]) & ~(BMI_NUM_OF_TASKS_MASK | BMI_NUM_OF_EXTRA_TASKS_MASK);
|
|
tmpReg |= (uint32_t)(((numOfTasks-1) << BMI_NUM_OF_TASKS_SHIFT) |
|
|
(numOfExtraTasks << BMI_EXTRA_NUM_OF_TASKS_SHIFT));
|
|
WRITE_UINT32(p_Fm->p_FmBmiRegs->fmbm_pp[hardwarePortId-1],tmpReg);
|
|
}
|
|
|
|
return E_OK;
|
|
}
|
|
|
|
t_Error FmSetNumOfOpenDmas(t_Handle h_Fm,
|
|
uint8_t hardwarePortId,
|
|
uint8_t numOfOpenDmas,
|
|
uint8_t numOfExtraOpenDmas,
|
|
bool initialConfig)
|
|
|
|
{
|
|
t_Fm *p_Fm = (t_Fm *)h_Fm;
|
|
uint8_t oldVal;
|
|
uint32_t tmpReg = 0;
|
|
t_FmIpcPortRsrcParams rsrcParams;
|
|
t_Error err;
|
|
|
|
if(p_Fm->guestId != NCSW_MASTER_ID)
|
|
{
|
|
t_FmIpcMsg msg;
|
|
t_FmIpcReply reply;
|
|
uint32_t replyLength;
|
|
|
|
rsrcParams.hardwarePortId = hardwarePortId;
|
|
rsrcParams.val = numOfOpenDmas;
|
|
rsrcParams.extra = numOfExtraOpenDmas;
|
|
rsrcParams.boolInitialConfig = (uint8_t)initialConfig;
|
|
|
|
memset(&msg, 0, sizeof(msg));
|
|
memset(&reply, 0, sizeof(reply));
|
|
msg.msgId = FM_SET_NUM_OF_OPEN_DMAS;
|
|
memcpy(msg.msgBody, &rsrcParams, sizeof(rsrcParams));
|
|
replyLength = sizeof(uint32_t);
|
|
if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
|
|
(uint8_t*)&msg,
|
|
sizeof(msg.msgId) + sizeof(rsrcParams),
|
|
(uint8_t*)&reply,
|
|
&replyLength,
|
|
NULL,
|
|
NULL)) != E_OK)
|
|
RETURN_ERROR(MINOR, err, NO_MSG);
|
|
if (replyLength != sizeof(uint32_t))
|
|
RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
|
|
return (t_Error)(reply.error);
|
|
}
|
|
|
|
ASSERT_COND(IN_RANGE(1, hardwarePortId, 63));
|
|
|
|
if(initialConfig)
|
|
oldVal = 0;
|
|
else
|
|
{
|
|
tmpReg = GET_UINT32(p_Fm->p_FmBmiRegs->fmbm_pp[hardwarePortId-1]);
|
|
/* read into oldVal the current extra tasks */
|
|
oldVal = (uint8_t)((tmpReg & BMI_NUM_OF_EXTRA_DMAS_MASK) >> BMI_EXTRA_NUM_OF_DMAS_SHIFT);
|
|
}
|
|
|
|
if(numOfExtraOpenDmas > oldVal)
|
|
p_Fm->p_FmStateStruct->extraOpenDmasPoolSize = (uint8_t)NCSW_MAX(p_Fm->p_FmStateStruct->extraOpenDmasPoolSize, numOfExtraOpenDmas);
|
|
|
|
if(!initialConfig)
|
|
/* read into oldVal the current num of tasks */
|
|
oldVal = (uint8_t)(((tmpReg & BMI_NUM_OF_DMAS_MASK) >> BMI_NUM_OF_DMAS_SHIFT) + 1);
|
|
|
|
/* check that there are enough uncommitted open DMA's */
|
|
ASSERT_COND(p_Fm->p_FmStateStruct->accumulatedNumOfOpenDmas >= oldVal);
|
|
if((p_Fm->p_FmStateStruct->accumulatedNumOfOpenDmas - oldVal + numOfOpenDmas) >
|
|
p_Fm->p_FmStateStruct->maxNumOfOpenDmas)
|
|
RETURN_ERROR(MAJOR, E_NOT_AVAILABLE,
|
|
("Requested numOfOpenDmas for fm%d exceeds total numOfOpenDmas.",
|
|
p_Fm->p_FmStateStruct->fmId));
|
|
else
|
|
{
|
|
/* update acummulated */
|
|
p_Fm->p_FmStateStruct->accumulatedNumOfOpenDmas -= oldVal;
|
|
p_Fm->p_FmStateStruct->accumulatedNumOfOpenDmas += numOfOpenDmas;
|
|
/* calculate reg */
|
|
tmpReg = GET_UINT32(p_Fm->p_FmBmiRegs->fmbm_pp[hardwarePortId-1]) & ~(BMI_NUM_OF_DMAS_MASK | BMI_NUM_OF_EXTRA_DMAS_MASK);
|
|
tmpReg |= (uint32_t)(((numOfOpenDmas-1) << BMI_NUM_OF_DMAS_SHIFT) |
|
|
(numOfExtraOpenDmas << BMI_EXTRA_NUM_OF_DMAS_SHIFT));
|
|
WRITE_UINT32(p_Fm->p_FmBmiRegs->fmbm_pp[hardwarePortId-1], tmpReg);
|
|
|
|
/* update total num of DMA's with committed number of open DMAS, and max uncommitted pool. */
|
|
tmpReg = GET_UINT32(p_Fm->p_FmBmiRegs->fmbm_cfg2) & ~BMI_CFG2_DMAS_MASK;
|
|
tmpReg |= (uint32_t)(p_Fm->p_FmStateStruct->accumulatedNumOfOpenDmas + p_Fm->p_FmStateStruct->extraOpenDmasPoolSize - 1) << BMI_CFG2_DMAS_SHIFT;
|
|
WRITE_UINT32(p_Fm->p_FmBmiRegs->fmbm_cfg2, tmpReg);
|
|
}
|
|
|
|
return E_OK;
|
|
}
|
|
|
|
#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
|
|
t_Error FmDumpPortRegs (t_Handle h_Fm,uint8_t hardwarePortId)
|
|
{
|
|
t_Fm *p_Fm = (t_Fm *)h_Fm;
|
|
t_FmIpcMsg msg;
|
|
t_Error err;
|
|
|
|
DECLARE_DUMP;
|
|
|
|
if(p_Fm->guestId != NCSW_MASTER_ID)
|
|
{
|
|
memset(&msg, 0, sizeof(msg));
|
|
msg.msgId = FM_DUMP_PORT_REGS;
|
|
msg.msgBody[0] = hardwarePortId;
|
|
if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
|
|
(uint8_t*)&msg,
|
|
sizeof(msg.msgId)+sizeof(hardwarePortId),
|
|
NULL,
|
|
NULL,
|
|
NULL,
|
|
NULL)) != E_OK)
|
|
RETURN_ERROR(MINOR, err, NO_MSG);
|
|
return E_OK;
|
|
}
|
|
|
|
SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
|
|
|
|
DUMP_TITLE(&p_Fm->p_FmBmiRegs->fmbm_pp[hardwarePortId-1], ("fmbm_pp for port %u", (hardwarePortId)));
|
|
DUMP_MEMORY(&p_Fm->p_FmBmiRegs->fmbm_pp[hardwarePortId-1], sizeof(uint32_t));
|
|
|
|
DUMP_TITLE(&p_Fm->p_FmBmiRegs->fmbm_pfs[hardwarePortId-1], ("fmbm_pfs for port %u", (hardwarePortId )));
|
|
DUMP_MEMORY(&p_Fm->p_FmBmiRegs->fmbm_pfs[hardwarePortId-1], sizeof(uint32_t));
|
|
|
|
DUMP_TITLE(&p_Fm->p_FmBmiRegs->fmbm_ppid[hardwarePortId-1], ("bm_ppid for port %u", (hardwarePortId)));
|
|
DUMP_MEMORY(&p_Fm->p_FmBmiRegs->fmbm_ppid[hardwarePortId-1], sizeof(uint32_t));
|
|
|
|
return E_OK;
|
|
}
|
|
#endif /* (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0)) */
|
|
|
|
|
|
/*****************************************************************************/
|
|
/* API Init unit functions */
|
|
/*****************************************************************************/
|
|
t_Handle FM_Config(t_FmParams *p_FmParam)
|
|
{
|
|
t_Fm *p_Fm;
|
|
uint8_t i;
|
|
uintptr_t baseAddr;
|
|
|
|
SANITY_CHECK_RETURN_VALUE(p_FmParam, E_NULL_POINTER, NULL);
|
|
SANITY_CHECK_RETURN_VALUE(((p_FmParam->firmware.p_Code && p_FmParam->firmware.size) ||
|
|
(!p_FmParam->firmware.p_Code && !p_FmParam->firmware.size)),
|
|
E_INVALID_VALUE, NULL);
|
|
|
|
baseAddr = p_FmParam->baseAddr;
|
|
|
|
/* Allocate FM structure */
|
|
p_Fm = (t_Fm *) XX_Malloc(sizeof(t_Fm));
|
|
if (!p_Fm)
|
|
{
|
|
REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM driver structure"));
|
|
return NULL;
|
|
}
|
|
memset(p_Fm, 0, sizeof(t_Fm));
|
|
|
|
p_Fm->p_FmStateStruct = (t_FmStateStruct *) XX_Malloc(sizeof(t_FmStateStruct));
|
|
if (!p_Fm->p_FmStateStruct)
|
|
{
|
|
XX_Free(p_Fm);
|
|
REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM Status structure"));
|
|
return NULL;
|
|
}
|
|
memset(p_Fm->p_FmStateStruct, 0, sizeof(t_FmStateStruct));
|
|
|
|
/* Initialize FM parameters which will be kept by the driver */
|
|
p_Fm->p_FmStateStruct->fmId = p_FmParam->fmId;
|
|
p_Fm->guestId = p_FmParam->guestId;
|
|
|
|
for(i=0; i<FM_MAX_NUM_OF_HW_PORT_IDS; i++)
|
|
p_Fm->p_FmStateStruct->portsTypes[i] = e_FM_PORT_TYPE_DUMMY;
|
|
|
|
/* Allocate the FM driver's parameters structure */
|
|
p_Fm->p_FmDriverParam = (t_FmDriverParam *)XX_Malloc(sizeof(t_FmDriverParam));
|
|
if (!p_Fm->p_FmDriverParam)
|
|
{
|
|
XX_Free(p_Fm->p_FmStateStruct);
|
|
XX_Free(p_Fm);
|
|
REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM driver parameters"));
|
|
return NULL;
|
|
}
|
|
memset(p_Fm->p_FmDriverParam, 0, sizeof(t_FmDriverParam));
|
|
|
|
/* Initialize FM parameters which will be kept by the driver */
|
|
p_Fm->p_FmStateStruct->fmId = p_FmParam->fmId;
|
|
p_Fm->h_FmMuram = p_FmParam->h_FmMuram;
|
|
p_Fm->h_App = p_FmParam->h_App;
|
|
p_Fm->p_FmStateStruct->fmClkFreq = p_FmParam->fmClkFreq;
|
|
p_Fm->f_Exception = p_FmParam->f_Exception;
|
|
p_Fm->f_BusError = p_FmParam->f_BusError;
|
|
p_Fm->p_FmFpmRegs = (t_FmFpmRegs *)UINT_TO_PTR(baseAddr + FM_MM_FPM);
|
|
p_Fm->p_FmBmiRegs = (t_FmBmiRegs *)UINT_TO_PTR(baseAddr + FM_MM_BMI);
|
|
p_Fm->p_FmQmiRegs = (t_FmQmiRegs *)UINT_TO_PTR(baseAddr + FM_MM_QMI);
|
|
p_Fm->p_FmDmaRegs = (t_FmDmaRegs *)UINT_TO_PTR(baseAddr + FM_MM_DMA);
|
|
p_Fm->baseAddr = baseAddr;
|
|
p_Fm->p_FmStateStruct->irq = p_FmParam->irq;
|
|
p_Fm->p_FmStateStruct->errIrq = p_FmParam->errIrq;
|
|
p_Fm->hcPortInitialized = FALSE;
|
|
p_Fm->independentMode = FALSE;
|
|
p_Fm->p_FmStateStruct->ramsEccEnable = FALSE;
|
|
p_Fm->p_FmStateStruct->totalNumOfTasks = DEFAULT_totalNumOfTasks;
|
|
p_Fm->p_FmStateStruct->totalFifoSize = DEFAULT_totalFifoSize;
|
|
p_Fm->p_FmStateStruct->maxNumOfOpenDmas = DEFAULT_maxNumOfOpenDmas;
|
|
p_Fm->p_FmStateStruct->extraFifoPoolSize = FM_MAX_NUM_OF_RX_PORTS*BMI_FIFO_UNITS;
|
|
p_Fm->p_FmStateStruct->exceptions = DEFAULT_exceptions;
|
|
for(i = 0;i<FM_MAX_NUM_OF_1G_MACS;i++)
|
|
p_Fm->p_FmStateStruct->macMaxFrameLengths1G[i] = DEFAULT_mtu;
|
|
#if defined(FM_MAX_NUM_OF_10G_MACS) && (FM_MAX_NUM_OF_10G_MACS)
|
|
for(i = 0;i<FM_MAX_NUM_OF_10G_MACS;i++)
|
|
p_Fm->p_FmStateStruct->macMaxFrameLengths10G[i] = DEFAULT_mtu;
|
|
#endif /*defined(FM_MAX_NUM_OF_10G_MACS) && (FM_MAX_NUM_OF_10G_MACS)*/
|
|
|
|
p_Fm->h_Spinlock = XX_InitSpinlock();
|
|
if (!p_Fm->h_Spinlock)
|
|
{
|
|
XX_Free(p_Fm->p_FmDriverParam);
|
|
XX_Free(p_Fm->p_FmStateStruct);
|
|
XX_Free(p_Fm);
|
|
REPORT_ERROR(MAJOR, E_INVALID_STATE, ("cant allocate spinlock!"));
|
|
return NULL;
|
|
}
|
|
|
|
#ifdef FM_PARTITION_ARRAY
|
|
/* Initialize FM driver parameters parameters (for initialization phase only) */
|
|
memcpy(p_Fm->p_FmDriverParam->liodnBasePerPort, p_FmParam->liodnBasePerPort, FM_SIZE_OF_LIODN_TABLE*sizeof(uint16_t));
|
|
#endif /* FM_PARTITION_ARRAY */
|
|
|
|
/*p_Fm->p_FmDriverParam->numOfPartitions = p_FmParam->numOfPartitions; */
|
|
p_Fm->p_FmDriverParam->enCounters = FALSE;
|
|
|
|
p_Fm->p_FmDriverParam->resetOnInit = DEFAULT_resetOnInit;
|
|
|
|
p_Fm->p_FmDriverParam->thresholds.dispLimit = DEFAULT_dispLimit;
|
|
p_Fm->p_FmDriverParam->thresholds.prsDispTh = DEFAULT_prsDispTh;
|
|
p_Fm->p_FmDriverParam->thresholds.plcrDispTh = DEFAULT_plcrDispTh;
|
|
p_Fm->p_FmDriverParam->thresholds.kgDispTh = DEFAULT_kgDispTh;
|
|
p_Fm->p_FmDriverParam->thresholds.bmiDispTh = DEFAULT_bmiDispTh;
|
|
p_Fm->p_FmDriverParam->thresholds.qmiEnqDispTh = DEFAULT_qmiEnqDispTh;
|
|
p_Fm->p_FmDriverParam->thresholds.qmiDeqDispTh = DEFAULT_qmiDeqDispTh;
|
|
p_Fm->p_FmDriverParam->thresholds.fmCtl1DispTh = DEFAULT_fmCtl1DispTh;
|
|
p_Fm->p_FmDriverParam->thresholds.fmCtl2DispTh = DEFAULT_fmCtl2DispTh;
|
|
|
|
p_Fm->p_FmDriverParam->dmaStopOnBusError = DEFAULT_dmaStopOnBusError;
|
|
|
|
p_Fm->p_FmDriverParam->dmaCacheOverride = DEFAULT_cacheOverride;
|
|
p_Fm->p_FmDriverParam->dmaAidMode = DEFAULT_aidMode;
|
|
p_Fm->p_FmDriverParam->dmaAidOverride = DEFAULT_aidOverride;
|
|
p_Fm->p_FmDriverParam->dmaAxiDbgNumOfBeats = DEFAULT_axiDbgNumOfBeats;
|
|
p_Fm->p_FmDriverParam->dmaCamNumOfEntries = DEFAULT_dmaCamNumOfEntries;
|
|
p_Fm->p_FmDriverParam->dmaWatchdog = DEFAULT_dmaWatchdog;
|
|
|
|
p_Fm->p_FmDriverParam->dmaCommQThresholds.clearEmergency = DEFAULT_dmaCommQLow;
|
|
p_Fm->p_FmDriverParam->dmaCommQThresholds.assertEmergency = DEFAULT_dmaCommQHigh;
|
|
p_Fm->p_FmDriverParam->dmaReadBufThresholds.clearEmergency = DEFAULT_dmaReadIntBufLow;
|
|
p_Fm->p_FmDriverParam->dmaReadBufThresholds.assertEmergency = DEFAULT_dmaReadIntBufHigh;
|
|
p_Fm->p_FmDriverParam->dmaWriteBufThresholds.clearEmergency = DEFAULT_dmaWriteIntBufLow;
|
|
p_Fm->p_FmDriverParam->dmaWriteBufThresholds.assertEmergency = DEFAULT_dmaWriteIntBufHigh;
|
|
p_Fm->p_FmDriverParam->dmaSosEmergency = DEFAULT_dmaSosEmergency;
|
|
|
|
p_Fm->p_FmDriverParam->dmaDbgCntMode = DEFAULT_dmaDbgCntMode;
|
|
|
|
p_Fm->p_FmDriverParam->dmaEnEmergency = FALSE;
|
|
p_Fm->p_FmDriverParam->dmaEnEmergencySmoother = FALSE;
|
|
p_Fm->p_FmDriverParam->catastrophicErr = DEFAULT_catastrophicErr;
|
|
p_Fm->p_FmDriverParam->dmaErr = DEFAULT_dmaErr;
|
|
p_Fm->p_FmDriverParam->haltOnExternalActivation = DEFAULT_haltOnExternalActivation;
|
|
p_Fm->p_FmDriverParam->haltOnUnrecoverableEccError = DEFAULT_haltOnUnrecoverableEccError;
|
|
p_Fm->p_FmDriverParam->enIramTestMode = FALSE;
|
|
p_Fm->p_FmDriverParam->enMuramTestMode = FALSE;
|
|
p_Fm->p_FmDriverParam->externalEccRamsEnable = DEFAULT_externalEccRamsEnable;
|
|
|
|
p_Fm->p_FmDriverParam->fwVerify = DEFAULT_VerifyUcode;
|
|
p_Fm->p_FmDriverParam->firmware.size = p_FmParam->firmware.size;
|
|
if (p_Fm->p_FmDriverParam->firmware.size)
|
|
{
|
|
p_Fm->p_FmDriverParam->firmware.p_Code = (uint32_t *)XX_Malloc(p_Fm->p_FmDriverParam->firmware.size);
|
|
if (!p_Fm->p_FmDriverParam->firmware.p_Code)
|
|
{
|
|
XX_FreeSpinlock(p_Fm->h_Spinlock);
|
|
XX_Free(p_Fm->p_FmStateStruct);
|
|
XX_Free(p_Fm->p_FmDriverParam);
|
|
XX_Free(p_Fm);
|
|
REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM firmware code"));
|
|
return NULL;
|
|
}
|
|
memcpy(p_Fm->p_FmDriverParam->firmware.p_Code, p_FmParam->firmware.p_Code, p_Fm->p_FmDriverParam->firmware.size);
|
|
}
|
|
|
|
return p_Fm;
|
|
}
|
|
|
|
/**************************************************************************//**
|
|
@Function FM_Init
|
|
|
|
@Description Initializes the FM module
|
|
|
|
@Param[in] h_Fm - FM module descriptor
|
|
|
|
@Return E_OK on success; Error code otherwise.
|
|
*//***************************************************************************/
|
|
t_Error FM_Init(t_Handle h_Fm)
|
|
{
|
|
t_Fm *p_Fm = (t_Fm*)h_Fm;
|
|
t_FmDriverParam *p_FmDriverParam = NULL;
|
|
t_Error err = E_OK;
|
|
uint32_t tmpReg, cfgReg = 0;
|
|
int i;
|
|
uint16_t periodInFmClocks;
|
|
uint8_t remainder;
|
|
t_FmRevisionInfo revInfo;
|
|
|
|
SANITY_CHECK_RETURN_ERROR(h_Fm, E_INVALID_HANDLE);
|
|
|
|
if(p_Fm->guestId != NCSW_MASTER_ID)
|
|
{
|
|
uint8_t isMasterAlive;
|
|
t_FmIpcMsg msg;
|
|
t_FmIpcReply reply;
|
|
uint32_t replyLength;
|
|
|
|
/* build the FM guest partition IPC address */
|
|
if(Sprint (p_Fm->fmModuleName, "FM_%d_%d",p_Fm->p_FmStateStruct->fmId, p_Fm->guestId) != (p_Fm->guestId<10 ? 6:7))
|
|
RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Sprint failed"));
|
|
|
|
/* build the FM master partition IPC address */
|
|
memset(p_Fm->fmIpcHandlerModuleName, 0, (sizeof(char)) * MODULE_NAME_SIZE);
|
|
if(Sprint (p_Fm->fmIpcHandlerModuleName[0], "FM_%d_%d",p_Fm->p_FmStateStruct->fmId, NCSW_MASTER_ID) != 6)
|
|
RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Sprint failed"));
|
|
|
|
for(i=0;i<e_FM_EV_DUMMY_LAST;i++)
|
|
p_Fm->intrMng[i].f_Isr = UnimplementedIsr;
|
|
|
|
p_Fm->h_IpcSessions[0] = XX_IpcInitSession(p_Fm->fmIpcHandlerModuleName[0], p_Fm->fmModuleName);
|
|
if (p_Fm->h_IpcSessions[0])
|
|
{
|
|
err = XX_IpcRegisterMsgHandler(p_Fm->fmModuleName, FmGuestHandleIpcMsgCB, p_Fm, FM_IPC_MAX_REPLY_SIZE);
|
|
if(err)
|
|
RETURN_ERROR(MAJOR, err, NO_MSG);
|
|
|
|
memset(&msg, 0, sizeof(msg));
|
|
memset(&reply, 0, sizeof(reply));
|
|
msg.msgId = FM_MASTER_IS_ALIVE;
|
|
msg.msgBody[0] = p_Fm->guestId;
|
|
replyLength = sizeof(uint32_t) + sizeof(uint8_t);
|
|
do
|
|
{
|
|
blockingFlag = TRUE;
|
|
if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
|
|
(uint8_t*)&msg,
|
|
sizeof(msg.msgId)+sizeof(p_Fm->guestId),
|
|
(uint8_t*)&reply,
|
|
&replyLength,
|
|
IpcMsgCompletionCB,
|
|
h_Fm)) != E_OK)
|
|
REPORT_ERROR(MINOR, err, NO_MSG);
|
|
while(blockingFlag) ;
|
|
if(replyLength != (sizeof(uint32_t) + sizeof(uint8_t)))
|
|
REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
|
|
isMasterAlive = *(uint8_t*)(reply.replyBody);
|
|
} while (!isMasterAlive);
|
|
|
|
memset(&msg, 0, sizeof(msg));
|
|
memset(&reply, 0, sizeof(reply));
|
|
msg.msgId = FM_GET_CLK_FREQ;
|
|
replyLength = sizeof(uint32_t) + sizeof(p_Fm->p_FmStateStruct->fmClkFreq);
|
|
if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
|
|
(uint8_t*)&msg,
|
|
sizeof(msg.msgId),
|
|
(uint8_t*)&reply,
|
|
&replyLength,
|
|
NULL,
|
|
NULL)) != E_OK)
|
|
RETURN_ERROR(MAJOR, err, NO_MSG);
|
|
if(replyLength != (sizeof(uint32_t) + sizeof(p_Fm->p_FmStateStruct->fmClkFreq)))
|
|
RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
|
|
memcpy((uint8_t*)&p_Fm->p_FmStateStruct->fmClkFreq, reply.replyBody, sizeof(uint16_t));
|
|
}
|
|
else
|
|
{
|
|
DBG(WARNING, ("FM Guest mode - without IPC"));
|
|
if(!p_Fm->p_FmStateStruct->fmClkFreq )
|
|
RETURN_ERROR(MAJOR, E_INVALID_STATE, ("No fmClkFreq configured for guest without IPC"));
|
|
if(!p_Fm->baseAddr)
|
|
RETURN_ERROR(MAJOR, E_INVALID_STATE, ("No baseAddr configured for guest without IPC"));
|
|
}
|
|
|
|
XX_Free(p_Fm->p_FmDriverParam);
|
|
p_Fm->p_FmDriverParam = NULL;
|
|
|
|
if ((p_Fm->guestId == NCSW_MASTER_ID) ||
|
|
(p_Fm->h_IpcSessions[0]))
|
|
{
|
|
FM_DisableRamsEcc(p_Fm);
|
|
FmMuramClear(p_Fm->h_FmMuram);
|
|
FM_EnableRamsEcc(p_Fm);
|
|
}
|
|
|
|
return E_OK;
|
|
}
|
|
|
|
SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
|
|
|
|
FM_GetRevision(p_Fm, &revInfo);
|
|
|
|
#ifdef FM_NO_DISPATCH_RAM_ECC
|
|
if (revInfo.majorRev != 4)
|
|
p_Fm->p_FmStateStruct->exceptions &= ~FM_EX_BMI_DISPATCH_RAM_ECC;
|
|
#endif /* FM_NO_DISPATCH_RAM_ECC */
|
|
|
|
#ifdef FM_RAM_LIST_ERR_IRQ_ERRATA_FMAN8
|
|
if ((revInfo.majorRev == 1) && (revInfo.minorRev == 0))
|
|
p_Fm->p_FmStateStruct->exceptions &= ~FM_EX_BMI_LIST_RAM_ECC;
|
|
#endif /* FM_RAM_LIST_ERR_IRQ_ERRATA_FMAN8 */
|
|
|
|
#ifdef FM_BMI_PIPELINE_ERR_IRQ_ERRATA_FMAN9
|
|
if ((revInfo.majorRev == 1) && (revInfo.minorRev == 0))
|
|
p_Fm->p_FmStateStruct->exceptions &= ~FM_EX_BMI_PIPELINE_ECC;
|
|
#endif /* FM_BMI_PIPELINE_ERR_IRQ_ERRATA_FMAN9 */
|
|
|
|
#ifdef FM_QMI_NO_ECC_EXCEPTIONS
|
|
if (revInfo.majorRev == 4)
|
|
p_Fm->p_FmStateStruct->exceptions &= ~(FM_EX_QMI_SINGLE_ECC | FM_EX_QMI_DOUBLE_ECC);
|
|
#endif /* FM_QMI_NO_ECC_EXCEPTIONS */
|
|
|
|
CHECK_INIT_PARAMETERS(p_Fm, CheckFmParameters);
|
|
|
|
p_FmDriverParam = p_Fm->p_FmDriverParam;
|
|
|
|
FmMuramClear(p_Fm->h_FmMuram);
|
|
|
|
#ifdef FM_UCODE_NOT_RESET_ERRATA_BUGZILLA6173
|
|
if (p_FmDriverParam->resetOnInit)
|
|
{
|
|
t_FMIramRegs *p_Iram = (t_FMIramRegs *)UINT_TO_PTR(p_Fm->baseAddr + FM_MM_IMEM);
|
|
uint32_t debug_reg;
|
|
|
|
/* write to IRAM first location the debug instruction */
|
|
WRITE_UINT32(p_Iram->iadd, 0);
|
|
while (GET_UINT32(p_Iram->iadd) != 0) ;
|
|
WRITE_UINT32(p_Iram->idata, FM_UCODE_DEBUG_INSTRUCTION);
|
|
|
|
WRITE_UINT32(p_Iram->iadd, 0);
|
|
while (GET_UINT32(p_Iram->iadd) != 0) ;
|
|
while (GET_UINT32(p_Iram->idata) != FM_UCODE_DEBUG_INSTRUCTION) ;
|
|
|
|
/* Enable patch from IRAM */
|
|
WRITE_UINT32(p_Iram->iready, IRAM_READY);
|
|
XX_UDelay(100);
|
|
|
|
/* reset FMAN */
|
|
WRITE_UINT32(p_Fm->p_FmFpmRegs->fmrstc, FPM_RSTC_FM_RESET);
|
|
XX_UDelay(100);
|
|
|
|
/* verify breakpoint debug status register */
|
|
debug_reg = GET_UINT32(*(uint32_t *)UINT_TO_PTR(p_Fm->baseAddr + FM_DEBUG_STATUS_REGISTER_OFFSET));
|
|
#ifndef NCSW_LINUX
|
|
if(!debug_reg)
|
|
RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Invalid debug status register value = 0"));
|
|
#else
|
|
if(!debug_reg)
|
|
DBG(INFO,("Invalid debug status register value = 0"));
|
|
#endif
|
|
/*************************************/
|
|
/* Load FMan-Controller code to Iram */
|
|
/*************************************/
|
|
if (ClearIRam(p_Fm) != E_OK)
|
|
RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
|
|
if (p_Fm->p_FmDriverParam->firmware.p_Code &&
|
|
(LoadFmanCtrlCode(p_Fm) != E_OK))
|
|
RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
|
|
XX_UDelay(100);
|
|
|
|
/* reset FMAN again to start the microcode */
|
|
WRITE_UINT32(p_Fm->p_FmFpmRegs->fmrstc, FPM_RSTC_FM_RESET);
|
|
XX_UDelay(1000);
|
|
}
|
|
else
|
|
{
|
|
#endif /* FM_UCODE_NOT_RESET_ERRATA_BUGZILLA6173 */
|
|
if(p_FmDriverParam->resetOnInit)
|
|
{
|
|
WRITE_UINT32(p_Fm->p_FmFpmRegs->fmrstc, FPM_RSTC_FM_RESET);
|
|
XX_UDelay(100);
|
|
}
|
|
|
|
/*************************************/
|
|
/* Load FMan-Controller code to Iram */
|
|
/*************************************/
|
|
if (ClearIRam(p_Fm) != E_OK)
|
|
RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
|
|
if (p_Fm->p_FmDriverParam->firmware.p_Code &&
|
|
(LoadFmanCtrlCode(p_Fm) != E_OK))
|
|
RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
|
|
#ifdef FM_UCODE_NOT_RESET_ERRATA_BUGZILLA6173
|
|
}
|
|
#endif /* FM_UCODE_NOT_RESET_ERRATA_BUGZILLA6173 */
|
|
|
|
#ifdef FM_CAPWAP_SUPPORT
|
|
/* save first 256 byte in MURAM */
|
|
p_Fm->resAddr = PTR_TO_UINT(FM_MURAM_AllocMem(p_Fm->h_FmMuram, 256, 0));
|
|
if (!p_Fm->resAddr)
|
|
RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM alloc for reserved Area failed"));
|
|
|
|
WRITE_BLOCK(UINT_TO_PTR(p_Fm->resAddr), 0, 256);
|
|
#endif /* FM_CAPWAP_SUPPORT */
|
|
|
|
/* General FM driver initialization */
|
|
p_Fm->fmMuramPhysBaseAddr = (uint64_t)(XX_VirtToPhys(UINT_TO_PTR(p_Fm->baseAddr + FM_MM_MURAM)));
|
|
for(i=0;i<e_FM_EV_DUMMY_LAST;i++)
|
|
p_Fm->intrMng[i].f_Isr = UnimplementedIsr;
|
|
for(i=0;i<FM_NUM_OF_FMAN_CTRL_EVENT_REGS;i++)
|
|
p_Fm->fmanCtrlIntr[i].f_Isr = UnimplementedFmanCtrlIsr;
|
|
|
|
/**********************/
|
|
/* Init DMA Registers */
|
|
/**********************/
|
|
/* clear status reg events */
|
|
tmpReg = (DMA_STATUS_BUS_ERR | DMA_STATUS_READ_ECC | DMA_STATUS_SYSTEM_WRITE_ECC | DMA_STATUS_FM_WRITE_ECC);
|
|
/*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);*/
|
|
WRITE_UINT32(p_Fm->p_FmDmaRegs->fmdmsr, GET_UINT32(p_Fm->p_FmDmaRegs->fmdmsr) | tmpReg);
|
|
|
|
/* configure mode register */
|
|
tmpReg = 0;
|
|
tmpReg |= p_FmDriverParam->dmaCacheOverride << DMA_MODE_CACHE_OR_SHIFT;
|
|
if(p_FmDriverParam->dmaAidOverride)
|
|
tmpReg |= DMA_MODE_AID_OR;
|
|
if (p_Fm->p_FmStateStruct->exceptions & FM_EX_DMA_BUS_ERROR)
|
|
tmpReg |= DMA_MODE_BER;
|
|
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))
|
|
tmpReg |= DMA_MODE_ECC;
|
|
if(p_FmDriverParam->dmaStopOnBusError)
|
|
tmpReg |= DMA_MODE_SBER;
|
|
tmpReg |= (uint32_t)(p_FmDriverParam->dmaAxiDbgNumOfBeats - 1) << DMA_MODE_AXI_DBG_SHIFT;
|
|
if (p_FmDriverParam->dmaEnEmergency)
|
|
{
|
|
tmpReg |= p_FmDriverParam->dmaEmergency.emergencyBusSelect;
|
|
tmpReg |= p_FmDriverParam->dmaEmergency.emergencyLevel << DMA_MODE_EMERGENCY_LEVEL_SHIFT;
|
|
if(p_FmDriverParam->dmaEnEmergencySmoother)
|
|
WRITE_UINT32(p_Fm->p_FmDmaRegs->fmdmemsr, p_FmDriverParam->dmaEmergencySwitchCounter);
|
|
}
|
|
tmpReg |= ((p_FmDriverParam->dmaCamNumOfEntries/DMA_CAM_UNITS) - 1) << DMA_MODE_CEN_SHIFT;
|
|
|
|
tmpReg |= DMA_MODE_SECURE_PROT;
|
|
tmpReg |= p_FmDriverParam->dmaDbgCntMode << DMA_MODE_DBG_SHIFT;
|
|
tmpReg |= p_FmDriverParam->dmaAidMode << DMA_MODE_AID_MODE_SHIFT;
|
|
|
|
#ifdef FM_PEDANTIC_DMA
|
|
tmpReg |= DMA_MODE_EMERGENCY_READ;
|
|
#endif /* FM_PEDANTIC_DMA */
|
|
|
|
WRITE_UINT32(p_Fm->p_FmDmaRegs->fmdmmr, tmpReg);
|
|
|
|
/* configure thresholds register */
|
|
tmpReg = ((uint32_t)p_FmDriverParam->dmaCommQThresholds.assertEmergency << DMA_THRESH_COMMQ_SHIFT) |
|
|
((uint32_t)p_FmDriverParam->dmaReadBufThresholds.assertEmergency << DMA_THRESH_READ_INT_BUF_SHIFT) |
|
|
((uint32_t)p_FmDriverParam->dmaWriteBufThresholds.assertEmergency);
|
|
WRITE_UINT32(p_Fm->p_FmDmaRegs->fmdmtr, tmpReg);
|
|
|
|
/* configure hysteresis register */
|
|
tmpReg = ((uint32_t)p_FmDriverParam->dmaCommQThresholds.clearEmergency << DMA_THRESH_COMMQ_SHIFT) |
|
|
((uint32_t)p_FmDriverParam->dmaReadBufThresholds.clearEmergency << DMA_THRESH_READ_INT_BUF_SHIFT) |
|
|
((uint32_t)p_FmDriverParam->dmaWriteBufThresholds.clearEmergency);
|
|
WRITE_UINT32(p_Fm->p_FmDmaRegs->fmdmhy, tmpReg);
|
|
|
|
/* configure emergency threshold */
|
|
WRITE_UINT32(p_Fm->p_FmDmaRegs->fmdmsetr, p_FmDriverParam->dmaSosEmergency);
|
|
|
|
/* configure Watchdog */
|
|
WRITE_UINT32(p_Fm->p_FmDmaRegs->fmdmwcr, USEC_TO_CLK(p_FmDriverParam->dmaWatchdog, p_Fm->p_FmStateStruct->fmClkFreq));
|
|
|
|
/* Allocate MURAM for CAM */
|
|
p_Fm->camBaseAddr = PTR_TO_UINT(FM_MURAM_AllocMem(p_Fm->h_FmMuram,
|
|
(uint32_t)(p_FmDriverParam->dmaCamNumOfEntries*DMA_CAM_SIZEOF_ENTRY),
|
|
DMA_CAM_ALIGN));
|
|
if (!p_Fm->camBaseAddr )
|
|
RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM alloc for DMA CAM failed"));
|
|
|
|
WRITE_BLOCK(UINT_TO_PTR(p_Fm->camBaseAddr), 0, (uint32_t)(p_FmDriverParam->dmaCamNumOfEntries*DMA_CAM_SIZEOF_ENTRY));
|
|
|
|
/* VirtToPhys */
|
|
WRITE_UINT32(p_Fm->p_FmDmaRegs->fmdmebcr,
|
|
(uint32_t)(XX_VirtToPhys(UINT_TO_PTR(p_Fm->camBaseAddr)) - p_Fm->fmMuramPhysBaseAddr));
|
|
|
|
#ifdef FM_PARTITION_ARRAY
|
|
{
|
|
t_FmRevisionInfo revInfo;
|
|
FM_GetRevision(p_Fm, &revInfo);
|
|
if ((revInfo.majorRev == 1) && (revInfo.minorRev == 0))
|
|
/* liodn-partitions */
|
|
for (i=0 ; i<FM_SIZE_OF_LIODN_TABLE ; i+=2)
|
|
{
|
|
tmpReg = (((uint32_t)p_FmDriverParam->liodnBasePerPort[i] << DMA_LIODN_SHIFT) |
|
|
(uint32_t)p_FmDriverParam->liodnBasePerPort[i+1]);
|
|
WRITE_UINT32(p_Fm->p_FmDmaRegs->fmdmplr[i/2], tmpReg);
|
|
}
|
|
}
|
|
#endif /* FM_PARTITION_ARRAY */
|
|
|
|
/**********************/
|
|
/* Init FPM Registers */
|
|
/**********************/
|
|
tmpReg = (uint32_t)(p_FmDriverParam->thresholds.dispLimit << FPM_DISP_LIMIT_SHIFT);
|
|
WRITE_UINT32(p_Fm->p_FmFpmRegs->fpmflc, tmpReg);
|
|
|
|
tmpReg = (((uint32_t)p_FmDriverParam->thresholds.prsDispTh << FPM_THR1_PRS_SHIFT) |
|
|
((uint32_t)p_FmDriverParam->thresholds.kgDispTh << FPM_THR1_KG_SHIFT) |
|
|
((uint32_t)p_FmDriverParam->thresholds.plcrDispTh << FPM_THR1_PLCR_SHIFT) |
|
|
((uint32_t)p_FmDriverParam->thresholds.bmiDispTh << FPM_THR1_BMI_SHIFT));
|
|
WRITE_UINT32(p_Fm->p_FmFpmRegs->fpmdis1, tmpReg);
|
|
|
|
tmpReg = (((uint32_t)p_FmDriverParam->thresholds.qmiEnqDispTh << FPM_THR2_QMI_ENQ_SHIFT) |
|
|
((uint32_t)p_FmDriverParam->thresholds.qmiDeqDispTh << FPM_THR2_QMI_DEQ_SHIFT) |
|
|
((uint32_t)p_FmDriverParam->thresholds.fmCtl1DispTh << FPM_THR2_FM_CTL1_SHIFT) |
|
|
((uint32_t)p_FmDriverParam->thresholds.fmCtl2DispTh << FPM_THR2_FM_CTL2_SHIFT));
|
|
WRITE_UINT32(p_Fm->p_FmFpmRegs->fpmdis2, tmpReg);
|
|
|
|
/* define exceptions and error behavior */
|
|
tmpReg = 0;
|
|
/* Clear events */
|
|
tmpReg |= (FPM_EV_MASK_STALL | FPM_EV_MASK_DOUBLE_ECC | FPM_EV_MASK_SINGLE_ECC);
|
|
/* enable interrupts */
|
|
if(p_Fm->p_FmStateStruct->exceptions & FM_EX_FPM_STALL_ON_TASKS)
|
|
tmpReg |= FPM_EV_MASK_STALL_EN;
|
|
if(p_Fm->p_FmStateStruct->exceptions & FM_EX_FPM_SINGLE_ECC)
|
|
tmpReg |= FPM_EV_MASK_SINGLE_ECC_EN;
|
|
if(p_Fm->p_FmStateStruct->exceptions & FM_EX_FPM_DOUBLE_ECC)
|
|
tmpReg |= FPM_EV_MASK_DOUBLE_ECC_EN;
|
|
tmpReg |= (p_Fm->p_FmDriverParam->catastrophicErr << FPM_EV_MASK_CAT_ERR_SHIFT);
|
|
tmpReg |= (p_Fm->p_FmDriverParam->dmaErr << FPM_EV_MASK_DMA_ERR_SHIFT);
|
|
if(!p_Fm->p_FmDriverParam->haltOnExternalActivation)
|
|
tmpReg |= FPM_EV_MASK_EXTERNAL_HALT;
|
|
if(!p_Fm->p_FmDriverParam->haltOnUnrecoverableEccError)
|
|
tmpReg |= FPM_EV_MASK_ECC_ERR_HALT;
|
|
WRITE_UINT32(p_Fm->p_FmFpmRegs->fpmem, tmpReg);
|
|
|
|
/* clear all fmCtls event registers */
|
|
for(i=0;i<FM_NUM_OF_FMAN_CTRL_EVENT_REGS;i++)
|
|
WRITE_UINT32(p_Fm->p_FmFpmRegs->fpmcev[i], 0xFFFFFFFF);
|
|
|
|
/* RAM ECC - enable and clear events*/
|
|
/* first we need to clear all parser memory, as it is uninitialized and
|
|
may cause ECC errors */
|
|
tmpReg = 0;
|
|
/* event bits */
|
|
tmpReg = (FPM_RAM_CTL_MURAM_ECC | FPM_RAM_CTL_IRAM_ECC);
|
|
/* Rams enable is not effected by the RCR bit, but by a COP configuration */
|
|
if(p_Fm->p_FmDriverParam->externalEccRamsEnable)
|
|
tmpReg |= FPM_RAM_CTL_RAMS_ECC_EN_SRC_SEL;
|
|
|
|
/* enable test mode */
|
|
if(p_FmDriverParam->enMuramTestMode)
|
|
tmpReg |= FPM_RAM_CTL_MURAM_TEST_ECC;
|
|
if(p_FmDriverParam->enIramTestMode)
|
|
tmpReg |= FPM_RAM_CTL_IRAM_TEST_ECC;
|
|
WRITE_UINT32(p_Fm->p_FmFpmRegs->fmrcr, tmpReg);
|
|
|
|
tmpReg = 0;
|
|
if(p_Fm->p_FmStateStruct->exceptions & FM_EX_IRAM_ECC)
|
|
{
|
|
tmpReg |= FPM_IRAM_ECC_ERR_EX_EN;
|
|
FmEnableRamsEcc(p_Fm);
|
|
}
|
|
if(p_Fm->p_FmStateStruct->exceptions & FM_EX_NURAM_ECC)
|
|
{
|
|
tmpReg |= FPM_MURAM_ECC_ERR_EX_EN;
|
|
FmEnableRamsEcc(p_Fm);
|
|
}
|
|
WRITE_UINT32(p_Fm->p_FmFpmRegs->fmrie, tmpReg);
|
|
|
|
/**********************/
|
|
/* Init BMI Registers */
|
|
/**********************/
|
|
|
|
/* define common resources */
|
|
/* allocate MURAM for FIFO according to total size */
|
|
p_Fm->fifoBaseAddr = PTR_TO_UINT(FM_MURAM_AllocMem(p_Fm->h_FmMuram,
|
|
p_Fm->p_FmStateStruct->totalFifoSize,
|
|
BMI_FIFO_ALIGN));
|
|
if (!p_Fm->fifoBaseAddr)
|
|
{
|
|
FreeInitResources(p_Fm);
|
|
RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM alloc for FIFO failed"));
|
|
}
|
|
|
|
tmpReg = (uint32_t)(XX_VirtToPhys(UINT_TO_PTR(p_Fm->fifoBaseAddr)) - p_Fm->fmMuramPhysBaseAddr);
|
|
tmpReg = tmpReg / BMI_FIFO_ALIGN;
|
|
|
|
tmpReg |= ((p_Fm->p_FmStateStruct->totalFifoSize/BMI_FIFO_UNITS - 1) << BMI_CFG1_FIFO_SIZE_SHIFT);
|
|
WRITE_UINT32(p_Fm->p_FmBmiRegs->fmbm_cfg1, tmpReg);
|
|
|
|
tmpReg = ((uint32_t)(p_Fm->p_FmStateStruct->totalNumOfTasks - 1) << BMI_CFG2_TASKS_SHIFT );
|
|
/* num of DMA's will be dynamically updated when each port is set */
|
|
WRITE_UINT32(p_Fm->p_FmBmiRegs->fmbm_cfg2, tmpReg);
|
|
|
|
/* define unmaskable exceptions, enable and clear events */
|
|
tmpReg = 0;
|
|
WRITE_UINT32(p_Fm->p_FmBmiRegs->fmbm_ievr, (BMI_ERR_INTR_EN_LIST_RAM_ECC |
|
|
BMI_ERR_INTR_EN_PIPELINE_ECC |
|
|
BMI_ERR_INTR_EN_STATISTICS_RAM_ECC |
|
|
BMI_ERR_INTR_EN_DISPATCH_RAM_ECC));
|
|
if(p_Fm->p_FmStateStruct->exceptions & FM_EX_BMI_LIST_RAM_ECC)
|
|
tmpReg |= BMI_ERR_INTR_EN_LIST_RAM_ECC;
|
|
if(p_Fm->p_FmStateStruct->exceptions & FM_EX_BMI_PIPELINE_ECC)
|
|
tmpReg |= BMI_ERR_INTR_EN_PIPELINE_ECC;
|
|
if(p_Fm->p_FmStateStruct->exceptions & FM_EX_BMI_STATISTICS_RAM_ECC)
|
|
tmpReg |= BMI_ERR_INTR_EN_STATISTICS_RAM_ECC;
|
|
if(p_Fm->p_FmStateStruct->exceptions & FM_EX_BMI_DISPATCH_RAM_ECC)
|
|
tmpReg |= BMI_ERR_INTR_EN_DISPATCH_RAM_ECC;
|
|
WRITE_UINT32(p_Fm->p_FmBmiRegs->fmbm_ier, tmpReg);
|
|
|
|
/**********************/
|
|
/* Init QMI Registers */
|
|
/**********************/
|
|
/* Clear error interrupt events */
|
|
WRITE_UINT32(p_Fm->p_FmQmiRegs->fmqm_eie, (QMI_ERR_INTR_EN_DOUBLE_ECC | QMI_ERR_INTR_EN_DEQ_FROM_DEF));
|
|
tmpReg = 0;
|
|
if(p_Fm->p_FmStateStruct->exceptions & FM_EX_QMI_DEQ_FROM_UNKNOWN_PORTID)
|
|
tmpReg |= QMI_ERR_INTR_EN_DEQ_FROM_DEF;
|
|
if(p_Fm->p_FmStateStruct->exceptions & FM_EX_QMI_DOUBLE_ECC)
|
|
tmpReg |= QMI_ERR_INTR_EN_DOUBLE_ECC;
|
|
/* enable events */
|
|
WRITE_UINT32(p_Fm->p_FmQmiRegs->fmqm_eien, tmpReg);
|
|
|
|
if(p_Fm->p_FmDriverParam->tnumAgingPeriod)
|
|
{
|
|
/* tnumAgingPeriod is in units of microseconds, p_FmClockFreq is in Mhz */
|
|
periodInFmClocks = (uint16_t)(p_Fm->p_FmDriverParam->tnumAgingPeriod*p_Fm->p_FmStateStruct->fmClkFreq);
|
|
/* periodInFmClocks must be a 64 multiply */
|
|
remainder = (uint8_t)(periodInFmClocks % 64);
|
|
if (remainder > 64)
|
|
tmpReg = (uint32_t)((periodInFmClocks/64) + 1);
|
|
else
|
|
{
|
|
tmpReg = (uint32_t)(periodInFmClocks/64);
|
|
if(!tmpReg)
|
|
tmpReg = 1;
|
|
}
|
|
tmpReg <<= QMI_TAPC_TAP;
|
|
WRITE_UINT32(p_Fm->p_FmQmiRegs->fmqm_tapc, tmpReg);
|
|
|
|
}
|
|
tmpReg = 0;
|
|
/* Clear interrupt events */
|
|
WRITE_UINT32(p_Fm->p_FmQmiRegs->fmqm_ie, QMI_INTR_EN_SINGLE_ECC);
|
|
if(p_Fm->p_FmStateStruct->exceptions & FM_EX_QMI_SINGLE_ECC)
|
|
tmpReg |= QMI_INTR_EN_SINGLE_ECC;
|
|
/* enable events */
|
|
WRITE_UINT32(p_Fm->p_FmQmiRegs->fmqm_ien, tmpReg);
|
|
|
|
/* clear & enable global counters - calculate reg and save for later,
|
|
because it's the same reg for QMI enable */
|
|
if(p_Fm->p_FmDriverParam->enCounters)
|
|
cfgReg = QMI_CFG_EN_COUNTERS;
|
|
#ifdef FM_QMI_DEQ_OPTIONS_SUPPORT
|
|
cfgReg |= (uint32_t)(((QMI_DEF_TNUMS_THRESH) << 8) | (uint32_t)QMI_DEF_TNUMS_THRESH);
|
|
#endif /* FM_QMI_DEQ_OPTIONS_SUPPORT */
|
|
|
|
if (p_Fm->p_FmStateStruct->irq != NO_IRQ)
|
|
{
|
|
XX_SetIntr(p_Fm->p_FmStateStruct->irq, FM_EventIsr, p_Fm);
|
|
XX_EnableIntr(p_Fm->p_FmStateStruct->irq);
|
|
}
|
|
|
|
if (p_Fm->p_FmStateStruct->errIrq != NO_IRQ)
|
|
{
|
|
XX_SetIntr(p_Fm->p_FmStateStruct->errIrq, ErrorIsrCB, p_Fm);
|
|
XX_EnableIntr(p_Fm->p_FmStateStruct->errIrq);
|
|
}
|
|
|
|
/* build the FM master partition IPC address */
|
|
if (Sprint (p_Fm->fmModuleName, "FM_%d_%d",p_Fm->p_FmStateStruct->fmId, NCSW_MASTER_ID) != 6)
|
|
RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Sprint failed"));
|
|
|
|
err = XX_IpcRegisterMsgHandler(p_Fm->fmModuleName, FmHandleIpcMsgCB, p_Fm, FM_IPC_MAX_REPLY_SIZE);
|
|
if(err)
|
|
RETURN_ERROR(MAJOR, err, NO_MSG);
|
|
|
|
/**********************/
|
|
/* Enable all modules */
|
|
/**********************/
|
|
WRITE_UINT32(p_Fm->p_FmBmiRegs->fmbm_init, BMI_INIT_START);
|
|
WRITE_UINT32(p_Fm->p_FmQmiRegs->fmqm_gc, cfgReg | QMI_CFG_ENQ_EN | QMI_CFG_DEQ_EN);
|
|
|
|
if (p_Fm->p_FmDriverParam->firmware.p_Code)
|
|
{
|
|
XX_Free(p_Fm->p_FmDriverParam->firmware.p_Code);
|
|
p_Fm->p_FmDriverParam->firmware.p_Code = NULL;
|
|
}
|
|
|
|
XX_Free(p_Fm->p_FmDriverParam);
|
|
p_Fm->p_FmDriverParam = NULL;
|
|
|
|
return E_OK;
|
|
}
|
|
|
|
/**************************************************************************//**
|
|
@Function FM_Free
|
|
|
|
@Description Frees all resources that were assigned to FM module.
|
|
|
|
Calling this routine invalidates the descriptor.
|
|
|
|
@Param[in] h_Fm - FM module descriptor
|
|
|
|
@Return E_OK on success; Error code otherwise.
|
|
*//***************************************************************************/
|
|
t_Error FM_Free(t_Handle h_Fm)
|
|
{
|
|
t_Fm *p_Fm = (t_Fm*)h_Fm;
|
|
|
|
SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
|
|
|
|
if (p_Fm->guestId != NCSW_MASTER_ID)
|
|
{
|
|
XX_IpcUnregisterMsgHandler(p_Fm->fmModuleName);
|
|
|
|
if(!p_Fm->recoveryMode)
|
|
XX_Free(p_Fm->p_FmStateStruct);
|
|
|
|
XX_Free(p_Fm);
|
|
|
|
return E_OK;
|
|
}
|
|
|
|
/* disable BMI and QMI */
|
|
WRITE_UINT32(p_Fm->p_FmBmiRegs->fmbm_init, 0);
|
|
WRITE_UINT32(p_Fm->p_FmQmiRegs->fmqm_gc, 0);
|
|
|
|
/* release BMI resources */
|
|
WRITE_UINT32(p_Fm->p_FmBmiRegs->fmbm_cfg2, 0);
|
|
WRITE_UINT32(p_Fm->p_FmBmiRegs->fmbm_cfg1, 0);
|
|
|
|
/* disable ECC */
|
|
WRITE_UINT32(p_Fm->p_FmFpmRegs->fmrcr, 0);
|
|
|
|
if ((p_Fm->guestId == NCSW_MASTER_ID) && (p_Fm->fmModuleName[0] != 0))
|
|
XX_IpcUnregisterMsgHandler(p_Fm->fmModuleName);
|
|
|
|
if (p_Fm->p_FmStateStruct)
|
|
{
|
|
if (p_Fm->p_FmStateStruct->irq != NO_IRQ)
|
|
{
|
|
XX_DisableIntr(p_Fm->p_FmStateStruct->irq);
|
|
XX_FreeIntr(p_Fm->p_FmStateStruct->irq);
|
|
}
|
|
if (p_Fm->p_FmStateStruct->errIrq != NO_IRQ)
|
|
{
|
|
XX_DisableIntr(p_Fm->p_FmStateStruct->errIrq);
|
|
XX_FreeIntr(p_Fm->p_FmStateStruct->errIrq);
|
|
}
|
|
}
|
|
|
|
if (p_Fm->h_Spinlock)
|
|
XX_FreeSpinlock(p_Fm->h_Spinlock);
|
|
|
|
if (p_Fm->p_FmDriverParam)
|
|
{
|
|
if (p_Fm->p_FmDriverParam->firmware.p_Code)
|
|
XX_Free(p_Fm->p_FmDriverParam->firmware.p_Code);
|
|
XX_Free(p_Fm->p_FmDriverParam);
|
|
p_Fm->p_FmDriverParam = NULL;
|
|
}
|
|
|
|
FreeInitResources(p_Fm);
|
|
|
|
if (!p_Fm->recoveryMode && p_Fm->p_FmStateStruct)
|
|
XX_Free(p_Fm->p_FmStateStruct);
|
|
|
|
XX_Free(p_Fm);
|
|
|
|
return E_OK;
|
|
}
|
|
|
|
/*************************************************/
|
|
/* API Advanced Init unit functions */
|
|
/*************************************************/
|
|
|
|
t_Error FM_ConfigResetOnInit(t_Handle h_Fm, bool enable)
|
|
{
|
|
|
|
t_Fm *p_Fm = (t_Fm*)h_Fm;
|
|
|
|
SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
|
|
SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
|
|
|
|
p_Fm->p_FmDriverParam->resetOnInit = enable;
|
|
|
|
return E_OK;
|
|
}
|
|
|
|
|
|
t_Error FM_ConfigTotalNumOfTasks(t_Handle h_Fm, uint8_t totalNumOfTasks)
|
|
{
|
|
t_Fm *p_Fm = (t_Fm*)h_Fm;
|
|
|
|
SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
|
|
SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
|
|
|
|
p_Fm->p_FmStateStruct->totalNumOfTasks = totalNumOfTasks;
|
|
|
|
return E_OK;
|
|
}
|
|
|
|
t_Error FM_ConfigTotalFifoSize(t_Handle h_Fm, uint32_t totalFifoSize)
|
|
{
|
|
t_Fm *p_Fm = (t_Fm*)h_Fm;
|
|
|
|
SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
|
|
SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
|
|
|
|
p_Fm->p_FmStateStruct->totalFifoSize = totalFifoSize;
|
|
|
|
return E_OK;
|
|
}
|
|
|
|
t_Error FM_ConfigMaxNumOfOpenDmas(t_Handle h_Fm, uint8_t maxNumOfOpenDmas)
|
|
{
|
|
t_Fm *p_Fm = (t_Fm*)h_Fm;
|
|
|
|
SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
|
|
SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
|
|
|
|
p_Fm->p_FmStateStruct->maxNumOfOpenDmas = maxNumOfOpenDmas;
|
|
|
|
return E_OK;
|
|
}
|
|
|
|
t_Error FM_ConfigThresholds(t_Handle h_Fm, t_FmThresholds *p_FmThresholds)
|
|
{
|
|
t_Fm *p_Fm = (t_Fm*)h_Fm;
|
|
|
|
SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
|
|
SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
|
|
|
|
memcpy(&p_Fm->p_FmDriverParam->thresholds, p_FmThresholds, sizeof(t_FmThresholds));
|
|
|
|
return E_OK;
|
|
}
|
|
|
|
t_Error FM_ConfigDmaCacheOverride(t_Handle h_Fm, e_FmDmaCacheOverride cacheOverride)
|
|
{
|
|
t_Fm *p_Fm = (t_Fm*)h_Fm;
|
|
|
|
SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
|
|
SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
|
|
|
|
p_Fm->p_FmDriverParam->dmaCacheOverride = cacheOverride;
|
|
|
|
return E_OK;
|
|
}
|
|
|
|
t_Error FM_ConfigDmaAidOverride(t_Handle h_Fm, bool aidOverride)
|
|
{
|
|
t_Fm *p_Fm = (t_Fm*)h_Fm;
|
|
|
|
SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
|
|
SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
|
|
|
|
p_Fm->p_FmDriverParam->dmaAidOverride = aidOverride;
|
|
|
|
return E_OK;
|
|
}
|
|
|
|
t_Error FM_ConfigDmaAidMode(t_Handle h_Fm, e_FmDmaAidMode aidMode)
|
|
{
|
|
t_Fm *p_Fm = (t_Fm*)h_Fm;
|
|
|
|
SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
|
|
SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
|
|
|
|
p_Fm->p_FmDriverParam->dmaAidMode = aidMode;
|
|
|
|
return E_OK;
|
|
}
|
|
|
|
t_Error FM_ConfigDmaAxiDbgNumOfBeats(t_Handle h_Fm, uint8_t axiDbgNumOfBeats)
|
|
{
|
|
t_Fm *p_Fm = (t_Fm*)h_Fm;
|
|
|
|
SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
|
|
SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
|
|
|
|
p_Fm->p_FmDriverParam->dmaAxiDbgNumOfBeats = axiDbgNumOfBeats;
|
|
|
|
return E_OK;
|
|
}
|
|
|
|
t_Error FM_ConfigDmaCamNumOfEntries(t_Handle h_Fm, uint8_t numOfEntries)
|
|
{
|
|
t_Fm *p_Fm = (t_Fm*)h_Fm;
|
|
|
|
SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
|
|
SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
|
|
|
|
p_Fm->p_FmDriverParam->dmaCamNumOfEntries = numOfEntries;
|
|
|
|
return E_OK;
|
|
}
|
|
|
|
t_Error FM_ConfigDmaWatchdog(t_Handle h_Fm, uint32_t watchdogValue)
|
|
{
|
|
t_Fm *p_Fm = (t_Fm*)h_Fm;
|
|
|
|
SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
|
|
SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
|
|
|
|
#ifdef FM_NO_WATCHDOG
|
|
{
|
|
t_FmRevisionInfo revInfo;
|
|
FM_GetRevision(h_Fm, &revInfo);
|
|
if (revInfo.majorRev != 4)
|
|
RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("watchdog!"));
|
|
}
|
|
#endif /* FM_NO_WATCHDOG */
|
|
|
|
p_Fm->p_FmDriverParam->dmaWatchdog = watchdogValue;
|
|
|
|
return E_OK;
|
|
}
|
|
|
|
t_Error FM_ConfigDmaWriteBufThresholds(t_Handle h_Fm, t_FmDmaThresholds *p_FmDmaThresholds)
|
|
|
|
{
|
|
t_Fm *p_Fm = (t_Fm*)h_Fm;
|
|
|
|
SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
|
|
SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
|
|
|
|
memcpy(&p_Fm->p_FmDriverParam->dmaWriteBufThresholds, p_FmDmaThresholds, sizeof(t_FmDmaThresholds));
|
|
|
|
return E_OK;
|
|
}
|
|
|
|
t_Error FM_ConfigDmaCommQThresholds(t_Handle h_Fm, t_FmDmaThresholds *p_FmDmaThresholds)
|
|
{
|
|
t_Fm *p_Fm = (t_Fm*)h_Fm;
|
|
|
|
SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
|
|
SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
|
|
|
|
memcpy(&p_Fm->p_FmDriverParam->dmaCommQThresholds, p_FmDmaThresholds, sizeof(t_FmDmaThresholds));
|
|
|
|
return E_OK;
|
|
}
|
|
|
|
t_Error FM_ConfigDmaReadBufThresholds(t_Handle h_Fm, t_FmDmaThresholds *p_FmDmaThresholds)
|
|
{
|
|
t_Fm *p_Fm = (t_Fm*)h_Fm;
|
|
|
|
SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
|
|
SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
|
|
|
|
memcpy(&p_Fm->p_FmDriverParam->dmaReadBufThresholds, p_FmDmaThresholds, sizeof(t_FmDmaThresholds));
|
|
|
|
return E_OK;
|
|
}
|
|
|
|
t_Error FM_ConfigDmaEmergency(t_Handle h_Fm, t_FmDmaEmergency *p_Emergency)
|
|
{
|
|
t_Fm *p_Fm = (t_Fm*)h_Fm;
|
|
|
|
SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
|
|
SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
|
|
|
|
p_Fm->p_FmDriverParam->dmaEnEmergency = TRUE;
|
|
memcpy(&p_Fm->p_FmDriverParam->dmaEmergency, p_Emergency, sizeof(t_FmDmaEmergency));
|
|
|
|
return E_OK;
|
|
}
|
|
|
|
t_Error FM_ConfigDmaEmergencySmoother(t_Handle h_Fm, uint32_t emergencyCnt)
|
|
{
|
|
t_Fm *p_Fm = (t_Fm*)h_Fm;
|
|
|
|
SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
|
|
SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
|
|
|
|
if(!p_Fm->p_FmDriverParam->dmaEnEmergency)
|
|
RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("FM_ConfigEnDmaEmergencySmoother may be called only after FM_ConfigEnDmaEmergency"));
|
|
|
|
p_Fm->p_FmDriverParam->dmaEnEmergencySmoother = TRUE;
|
|
p_Fm->p_FmDriverParam->dmaEmergencySwitchCounter = emergencyCnt;
|
|
|
|
return E_OK;
|
|
}
|
|
|
|
t_Error FM_ConfigDmaDbgCounter(t_Handle h_Fm, e_FmDmaDbgCntMode fmDmaDbgCntMode)
|
|
{
|
|
t_Fm *p_Fm = (t_Fm*)h_Fm;
|
|
|
|
SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
|
|
SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
|
|
|
|
p_Fm->p_FmDriverParam->dmaDbgCntMode = fmDmaDbgCntMode;
|
|
|
|
return E_OK;
|
|
}
|
|
|
|
t_Error FM_ConfigDmaStopOnBusErr(t_Handle h_Fm, bool stop)
|
|
{
|
|
t_Fm *p_Fm = (t_Fm*)h_Fm;
|
|
|
|
SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
|
|
SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
|
|
|
|
p_Fm->p_FmDriverParam->dmaStopOnBusError = stop;
|
|
|
|
return E_OK;
|
|
}
|
|
|
|
t_Error FM_ConfigDmaSosEmergencyThreshold(t_Handle h_Fm, uint32_t dmaSosEmergency)
|
|
{
|
|
t_Fm *p_Fm = (t_Fm*)h_Fm;
|
|
|
|
SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
|
|
SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
|
|
|
|
p_Fm->p_FmDriverParam->dmaSosEmergency = dmaSosEmergency;
|
|
|
|
return E_OK;
|
|
}
|
|
|
|
t_Error FM_ConfigEnableCounters(t_Handle h_Fm)
|
|
{
|
|
t_Fm *p_Fm = (t_Fm*)h_Fm;
|
|
|
|
SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
|
|
SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
|
|
|
|
p_Fm->p_FmDriverParam->enCounters = TRUE;
|
|
|
|
return E_OK;
|
|
}
|
|
|
|
t_Error FM_ConfigDmaErr(t_Handle h_Fm, e_FmDmaErr dmaErr)
|
|
{
|
|
t_Fm *p_Fm = (t_Fm*)h_Fm;
|
|
|
|
SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
|
|
SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
|
|
|
|
p_Fm->p_FmDriverParam->dmaErr = dmaErr;
|
|
|
|
return E_OK;
|
|
}
|
|
|
|
t_Error FM_ConfigCatastrophicErr(t_Handle h_Fm, e_FmCatastrophicErr catastrophicErr)
|
|
{
|
|
t_Fm *p_Fm = (t_Fm*)h_Fm;
|
|
|
|
SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
|
|
SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
|
|
|
|
p_Fm->p_FmDriverParam->catastrophicErr = catastrophicErr;
|
|
|
|
return E_OK;
|
|
}
|
|
|
|
t_Error FM_ConfigEnableMuramTestMode(t_Handle h_Fm)
|
|
{
|
|
t_Fm *p_Fm = (t_Fm*)h_Fm;
|
|
|
|
SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
|
|
SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
|
|
|
|
p_Fm->p_FmDriverParam->enMuramTestMode = TRUE;
|
|
|
|
return E_OK;
|
|
}
|
|
|
|
t_Error FM_ConfigEnableIramTestMode(t_Handle h_Fm)
|
|
{
|
|
t_Fm *p_Fm = (t_Fm*)h_Fm;
|
|
|
|
SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
|
|
SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
|
|
|
|
p_Fm->p_FmDriverParam->enIramTestMode = TRUE;
|
|
|
|
return E_OK;
|
|
}
|
|
|
|
t_Error FM_ConfigHaltOnExternalActivation(t_Handle h_Fm, bool enable)
|
|
{
|
|
t_Fm *p_Fm = (t_Fm*)h_Fm;
|
|
|
|
SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
|
|
SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
|
|
|
|
#ifdef FM_HALT_SIG_ERRATA_GEN12
|
|
{
|
|
t_FmRevisionInfo revInfo;
|
|
FM_GetRevision(h_Fm, &revInfo);
|
|
if ((revInfo.majorRev == 1) && (revInfo.minorRev == 0))
|
|
RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("HaltOnExternalActivation!"));
|
|
}
|
|
#endif /* FM_HALT_SIG_ERRATA_GEN12 */
|
|
|
|
p_Fm->p_FmDriverParam->haltOnExternalActivation = enable;
|
|
|
|
return E_OK;
|
|
}
|
|
|
|
t_Error FM_ConfigHaltOnUnrecoverableEccError(t_Handle h_Fm, bool enable)
|
|
{
|
|
t_Fm *p_Fm = (t_Fm*)h_Fm;
|
|
|
|
SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
|
|
SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
|
|
|
|
#ifdef FM_ECC_HALT_NO_SYNC_ERRATA_10GMAC_A008
|
|
RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("HaltOnEccError!"));
|
|
#endif /* FM_ECC_HALT_NO_SYNC_ERRATA_10GMAC_A008 */
|
|
|
|
p_Fm->p_FmDriverParam->haltOnUnrecoverableEccError = enable;
|
|
|
|
return E_OK;
|
|
}
|
|
|
|
t_Error FM_ConfigException(t_Handle h_Fm, e_FmExceptions exception, bool enable)
|
|
{
|
|
t_Fm *p_Fm = (t_Fm*)h_Fm;
|
|
uint32_t bitMask = 0;
|
|
t_FmRevisionInfo revInfo;
|
|
|
|
SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
|
|
|
|
FM_GetRevision(p_Fm, &revInfo);
|
|
#ifdef FM_BMI_PIPELINE_ERR_IRQ_ERRATA_FMAN9
|
|
if((exception == e_FM_EX_BMI_PIPELINE_ECC) && (enable))
|
|
{
|
|
if ((revInfo.majorRev == 1) && (revInfo.minorRev == 0))
|
|
{
|
|
REPORT_ERROR(MINOR, E_NOT_SUPPORTED, ("e_FM_EX_BMI_PIPELINE_ECC!"));
|
|
return E_OK;
|
|
}
|
|
}
|
|
#endif /* FM_BMI_PIPELINE_ERR_IRQ_ERRATA_FMAN9 */
|
|
#ifdef FM_RAM_LIST_ERR_IRQ_ERRATA_FMAN8
|
|
if((exception == e_FM_EX_BMI_LIST_RAM_ECC) && (enable))
|
|
{
|
|
if ((revInfo.majorRev == 1) && (revInfo.minorRev == 0))
|
|
{
|
|
REPORT_ERROR(MINOR, E_NOT_SUPPORTED, ("e_FM_EX_BMI_LIST_RAM_ECC!"));
|
|
return E_OK;
|
|
}
|
|
}
|
|
#endif /* FM_RAM_LIST_ERR_IRQ_ERRATA_FMAN8 */
|
|
#ifdef FM_QMI_NO_ECC_EXCEPTIONS
|
|
if(((exception == e_FM_EX_QMI_SINGLE_ECC) || (exception == e_FM_EX_QMI_DOUBLE_ECC)) &&
|
|
enable)
|
|
{
|
|
if (revInfo.majorRev == 4)
|
|
{
|
|
REPORT_ERROR(MINOR, E_NOT_SUPPORTED, ("QMI ECC exception!"));
|
|
return E_OK;
|
|
}
|
|
}
|
|
#endif /* FM_QMI_NO_ECC_EXCEPTIONS */
|
|
#ifdef FM_NO_DISPATCH_RAM_ECC
|
|
if((exception == e_FM_EX_BMI_DISPATCH_RAM_ECC) && (enable))
|
|
{
|
|
if (revInfo.majorRev != 4)
|
|
{
|
|
REPORT_ERROR(MINOR, E_NOT_SUPPORTED, ("e_FM_EX_BMI_DISPATCH_RAM_ECC!"));
|
|
return E_OK;
|
|
}
|
|
}
|
|
#endif /* FM_NO_DISPATCH_RAM_ECC */
|
|
|
|
GET_EXCEPTION_FLAG(bitMask, exception);
|
|
if(bitMask)
|
|
{
|
|
if (enable)
|
|
p_Fm->p_FmStateStruct->exceptions |= bitMask;
|
|
else
|
|
p_Fm->p_FmStateStruct->exceptions &= ~bitMask;
|
|
}
|
|
else
|
|
RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined exception"));
|
|
|
|
return E_OK;
|
|
}
|
|
|
|
t_Error FM_ConfigExternalEccRamsEnable(t_Handle h_Fm, bool enable)
|
|
{
|
|
t_Fm *p_Fm = (t_Fm*)h_Fm;
|
|
|
|
SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
|
|
|
|
p_Fm->p_FmDriverParam->externalEccRamsEnable = enable;
|
|
|
|
return E_OK;
|
|
}
|
|
|
|
t_Error FM_ConfigTnumAgingPeriod(t_Handle h_Fm, uint16_t tnumAgingPeriod)
|
|
{
|
|
t_Fm *p_Fm = (t_Fm*)h_Fm;
|
|
#ifdef FM_NO_TNUM_AGING
|
|
t_FmRevisionInfo revInfo;
|
|
#endif /* FM_NO_TNUM_AGING */
|
|
|
|
SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
|
|
|
|
#ifdef FM_NO_TNUM_AGING
|
|
FM_GetRevision(h_Fm, &revInfo);
|
|
if (revInfo.majorRev != 4)
|
|
RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("FM_ConfigTnumAgingPeriod!"));
|
|
#endif /* FM_NO_TNUM_AGING */
|
|
|
|
p_Fm->p_FmDriverParam->tnumAgingPeriod = tnumAgingPeriod;
|
|
|
|
return E_OK;
|
|
|
|
}
|
|
|
|
/****************************************************/
|
|
/* API Run-time Control uint functions */
|
|
/****************************************************/
|
|
t_Handle FM_GetPcdHandle(t_Handle h_Fm)
|
|
{
|
|
SANITY_CHECK_RETURN_VALUE(h_Fm, E_INVALID_HANDLE, NULL);
|
|
SANITY_CHECK_RETURN_VALUE(!((t_Fm*)h_Fm)->p_FmDriverParam, E_INVALID_STATE, NULL);
|
|
|
|
return ((t_Fm*)h_Fm)->h_Pcd;
|
|
}
|
|
|
|
void FM_EventIsr(t_Handle h_Fm)
|
|
{
|
|
#define FM_M_CALL_1G_MAC_TMR_ISR(_id) \
|
|
{ \
|
|
if (p_Fm->guestId != p_Fm->intrMng[(e_FmInterModuleEvent)(e_FM_EV_1G_MAC0_TMR+_id)].guestId) \
|
|
SendIpcIsr(p_Fm, (e_FmInterModuleEvent)(e_FM_EV_1G_MAC0_TMR+_id), pending); \
|
|
else \
|
|
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);\
|
|
}
|
|
t_Fm *p_Fm = (t_Fm*)h_Fm;
|
|
uint32_t pending, event;
|
|
|
|
SANITY_CHECK_RETURN(h_Fm, E_INVALID_HANDLE);
|
|
|
|
/* normal interrupts */
|
|
pending = GET_UINT32(p_Fm->p_FmFpmRegs->fmnpi);
|
|
ASSERT_COND(pending);
|
|
if (pending & INTR_EN_BMI)
|
|
REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("BMI Event - undefined!"));
|
|
if (pending & INTR_EN_QMI)
|
|
QmiEvent(p_Fm);
|
|
if (pending & INTR_EN_PRS)
|
|
p_Fm->intrMng[e_FM_EV_PRS].f_Isr(p_Fm->intrMng[e_FM_EV_PRS].h_SrcHandle);
|
|
if (pending & INTR_EN_PLCR)
|
|
p_Fm->intrMng[e_FM_EV_PLCR].f_Isr(p_Fm->intrMng[e_FM_EV_PLCR].h_SrcHandle);
|
|
if (pending & INTR_EN_KG)
|
|
p_Fm->intrMng[e_FM_EV_KG].f_Isr(p_Fm->intrMng[e_FM_EV_KG].h_SrcHandle);
|
|
if (pending & INTR_EN_TMR)
|
|
p_Fm->intrMng[e_FM_EV_TMR].f_Isr(p_Fm->intrMng[e_FM_EV_TMR].h_SrcHandle);
|
|
|
|
/* MAC events may belong to different partitions */
|
|
if (pending & INTR_EN_1G_MAC0_TMR)
|
|
FM_M_CALL_1G_MAC_TMR_ISR(0);
|
|
if (pending & INTR_EN_1G_MAC1_TMR)
|
|
FM_M_CALL_1G_MAC_TMR_ISR(1);
|
|
if (pending & INTR_EN_1G_MAC2_TMR)
|
|
FM_M_CALL_1G_MAC_TMR_ISR(2);
|
|
if (pending & INTR_EN_1G_MAC3_TMR)
|
|
FM_M_CALL_1G_MAC_TMR_ISR(3);
|
|
if (pending & INTR_EN_1G_MAC4_TMR)
|
|
FM_M_CALL_1G_MAC_TMR_ISR(4);
|
|
|
|
/* IM port events may belong to different partitions */
|
|
if (pending & INTR_EN_REV0)
|
|
{
|
|
event = GET_UINT32(p_Fm->p_FmFpmRegs->fmfpfcev[0]) & GET_UINT32(p_Fm->p_FmFpmRegs->fmfpfcee[0]);
|
|
WRITE_UINT32(p_Fm->p_FmFpmRegs->fpmcev[0], event);
|
|
if (p_Fm->guestId != p_Fm->intrMng[e_FM_EV_FMAN_CTRL_0].guestId)
|
|
/*TODO IPC ISR For Fman Ctrl */
|
|
ASSERT_COND(0);
|
|
/* SendIpcIsr(p_Fm, e_FM_EV_FMAN_CTRL_0, pending); */
|
|
else
|
|
p_Fm->fmanCtrlIntr[0].f_Isr(p_Fm->fmanCtrlIntr[0].h_SrcHandle, event);
|
|
|
|
}
|
|
if (pending & INTR_EN_REV1)
|
|
{
|
|
event = GET_UINT32(p_Fm->p_FmFpmRegs->fmfpfcev[1]) & GET_UINT32(p_Fm->p_FmFpmRegs->fmfpfcee[1]);
|
|
WRITE_UINT32(p_Fm->p_FmFpmRegs->fpmcev[1], event);
|
|
if (p_Fm->guestId != p_Fm->intrMng[e_FM_EV_FMAN_CTRL_1].guestId)
|
|
/*TODO IPC ISR For Fman Ctrl */
|
|
ASSERT_COND(0);
|
|
/* SendIpcIsr(p_Fm, e_FM_EV_FMAN_CTRL_1, pending); */
|
|
else
|
|
p_Fm->fmanCtrlIntr[1].f_Isr(p_Fm->fmanCtrlIntr[1].h_SrcHandle, event);
|
|
|
|
}
|
|
if (pending & INTR_EN_REV2)
|
|
{
|
|
event = GET_UINT32(p_Fm->p_FmFpmRegs->fmfpfcev[2]) & GET_UINT32(p_Fm->p_FmFpmRegs->fmfpfcee[2]);
|
|
WRITE_UINT32(p_Fm->p_FmFpmRegs->fpmcev[2], event);
|
|
if (p_Fm->guestId != p_Fm->intrMng[e_FM_EV_FMAN_CTRL_2].guestId)
|
|
/*TODO IPC ISR For Fman Ctrl */
|
|
ASSERT_COND(0);
|
|
/* SendIpcIsr(p_Fm, e_FM_EV_FMAN_CTRL_2, pending); */
|
|
else
|
|
p_Fm->fmanCtrlIntr[2].f_Isr(p_Fm->fmanCtrlIntr[2].h_SrcHandle, event);
|
|
}
|
|
if (pending & INTR_EN_REV3)
|
|
{
|
|
event = GET_UINT32(p_Fm->p_FmFpmRegs->fmfpfcev[3]) & GET_UINT32(p_Fm->p_FmFpmRegs->fmfpfcee[3]);
|
|
WRITE_UINT32(p_Fm->p_FmFpmRegs->fpmcev[3], event);
|
|
if (p_Fm->guestId != p_Fm->intrMng[e_FM_EV_FMAN_CTRL_3].guestId)
|
|
/*TODO IPC ISR For Fman Ctrl */
|
|
ASSERT_COND(0);
|
|
/* SendIpcIsr(p_Fm, e_FM_EV_FMAN_CTRL_2, pendin3); */
|
|
else
|
|
p_Fm->fmanCtrlIntr[3].f_Isr(p_Fm->fmanCtrlIntr[3].h_SrcHandle, event);
|
|
}
|
|
}
|
|
|
|
t_Error FM_ErrorIsr(t_Handle h_Fm)
|
|
{
|
|
t_Fm *p_Fm = (t_Fm*)h_Fm;
|
|
|
|
SANITY_CHECK_RETURN_ERROR(h_Fm, E_INVALID_HANDLE);
|
|
|
|
/* error interrupts */
|
|
if (GET_UINT32(p_Fm->p_FmFpmRegs->fmepi) == 0)
|
|
return ERROR_CODE(E_EMPTY);
|
|
|
|
ErrorIsrCB(p_Fm);
|
|
return E_OK;
|
|
}
|
|
|
|
t_Error FM_SetPortsBandwidth(t_Handle h_Fm, t_FmPortsBandwidthParams *p_PortsBandwidth)
|
|
{
|
|
t_Fm *p_Fm = (t_Fm*)h_Fm;
|
|
int i;
|
|
uint8_t sum;
|
|
uint8_t hardwarePortId;
|
|
uint32_t tmpRegs[8] = {0,0,0,0,0,0,0,0};
|
|
uint8_t relativePortId, shift, weight, maxPercent = 0;
|
|
|
|
SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
|
|
SANITY_CHECK_RETURN_ERROR(!p_Fm->p_FmDriverParam, E_INVALID_STATE);
|
|
|
|
/* check that all ports add up to 100% */
|
|
sum = 0;
|
|
for (i=0;i<p_PortsBandwidth->numOfPorts;i++)
|
|
sum +=p_PortsBandwidth->portsBandwidths[i].bandwidth;
|
|
if (sum != 100)
|
|
RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Sum of ports bandwidth differ from 100%"));
|
|
|
|
/* find highest precent */
|
|
for (i=0;i<p_PortsBandwidth->numOfPorts;i++)
|
|
{
|
|
if (p_PortsBandwidth->portsBandwidths[i].bandwidth > maxPercent)
|
|
maxPercent = p_PortsBandwidth->portsBandwidths[i].bandwidth;
|
|
}
|
|
|
|
/* calculate weight for each port */
|
|
for (i=0;i<p_PortsBandwidth->numOfPorts;i++)
|
|
{
|
|
weight = (uint8_t)((p_PortsBandwidth->portsBandwidths[i].bandwidth * PORT_MAX_WEIGHT )/maxPercent);
|
|
/* we want even division between 1-to-PORT_MAX_WEIGHT. so if exect division
|
|
is not reached, we round up so that:
|
|
0 until maxPercent/PORT_MAX_WEIGHT get "1"
|
|
maxPercent/PORT_MAX_WEIGHT+1 until (maxPercent/PORT_MAX_WEIGHT)*2 get "2"
|
|
...
|
|
maxPercent - maxPercent/PORT_MAX_WEIGHT until maxPercent get "PORT_MAX_WEIGHT: */
|
|
if ((uint8_t)((p_PortsBandwidth->portsBandwidths[i].bandwidth * PORT_MAX_WEIGHT ) % maxPercent))
|
|
weight++;
|
|
|
|
/* find the location of this port within the register */
|
|
SW_PORT_ID_TO_HW_PORT_ID(hardwarePortId,
|
|
p_PortsBandwidth->portsBandwidths[i].type,
|
|
p_PortsBandwidth->portsBandwidths[i].relativePortId);
|
|
relativePortId = (uint8_t)(hardwarePortId % 8);
|
|
shift = (uint8_t)(32-4*(relativePortId+1));
|
|
|
|
|
|
if(weight > 1)
|
|
/* Add this port to tmpReg */
|
|
/* (each 8 ports result in one register)*/
|
|
tmpRegs[hardwarePortId/8] |= ((weight-1) << shift);
|
|
}
|
|
|
|
for(i=0;i<8;i++)
|
|
if(tmpRegs[i])
|
|
WRITE_UINT32(p_Fm->p_FmBmiRegs->fmbm_arb[i], tmpRegs[i]);
|
|
|
|
return E_OK;
|
|
}
|
|
|
|
t_Error FM_EnableRamsEcc(t_Handle h_Fm)
|
|
{
|
|
t_Fm *p_Fm = (t_Fm*)h_Fm;
|
|
uint32_t tmpReg;
|
|
|
|
SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
|
|
|
|
if(p_Fm->guestId != NCSW_MASTER_ID)
|
|
{
|
|
t_FmIpcMsg msg;
|
|
t_Error err;
|
|
|
|
memset(&msg, 0, sizeof(msg));
|
|
msg.msgId = FM_ENABLE_RAM_ECC;
|
|
if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
|
|
(uint8_t*)&msg,
|
|
sizeof(msg.msgId),
|
|
NULL,
|
|
NULL,
|
|
NULL,
|
|
NULL)) != E_OK)
|
|
RETURN_ERROR(MINOR, err, NO_MSG);
|
|
return E_OK;
|
|
}
|
|
|
|
if(!p_Fm->p_FmStateStruct->internalCall)
|
|
p_Fm->p_FmStateStruct->explicitEnable = TRUE;
|
|
p_Fm->p_FmStateStruct->internalCall = FALSE;
|
|
|
|
if(p_Fm->p_FmStateStruct->ramsEccEnable)
|
|
return E_OK;
|
|
else
|
|
{
|
|
tmpReg = GET_UINT32(p_Fm->p_FmFpmRegs->fmrcr);
|
|
if(tmpReg & FPM_RAM_CTL_RAMS_ECC_EN_SRC_SEL)
|
|
{
|
|
DBG(WARNING, ("Rams ECC is configured to be controlled through JTAG"));
|
|
WRITE_UINT32(p_Fm->p_FmFpmRegs->fmrcr, tmpReg | FPM_RAM_CTL_IRAM_ECC_EN);
|
|
}
|
|
else
|
|
WRITE_UINT32(p_Fm->p_FmFpmRegs->fmrcr, tmpReg | (FPM_RAM_CTL_RAMS_ECC_EN | FPM_RAM_CTL_IRAM_ECC_EN));
|
|
p_Fm->p_FmStateStruct->ramsEccEnable = TRUE;
|
|
}
|
|
|
|
return E_OK;
|
|
}
|
|
|
|
t_Error FM_DisableRamsEcc(t_Handle h_Fm)
|
|
{
|
|
t_Fm *p_Fm = (t_Fm*)h_Fm;
|
|
uint32_t tmpReg;
|
|
bool explicitDisable = FALSE;
|
|
|
|
SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
|
|
SANITY_CHECK_RETURN_ERROR(!p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
|
|
|
|
if(p_Fm->guestId != NCSW_MASTER_ID)
|
|
{
|
|
t_Error err;
|
|
t_FmIpcMsg msg;
|
|
|
|
memset(&msg, 0, sizeof(msg));
|
|
msg.msgId = FM_DISABLE_RAM_ECC;
|
|
if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
|
|
(uint8_t*)&msg,
|
|
sizeof(msg.msgId),
|
|
NULL,
|
|
NULL,
|
|
NULL,
|
|
NULL)) != E_OK)
|
|
RETURN_ERROR(MINOR, err, NO_MSG);
|
|
return E_OK;
|
|
}
|
|
|
|
if(!p_Fm->p_FmStateStruct->internalCall)
|
|
explicitDisable = TRUE;
|
|
p_Fm->p_FmStateStruct->internalCall = FALSE;
|
|
|
|
/* if rams are already disabled, or if rams were explicitly enabled and are
|
|
currently called indirectly (not explicitly), ignore this call. */
|
|
if(!p_Fm->p_FmStateStruct->ramsEccEnable || (p_Fm->p_FmStateStruct->explicitEnable && !explicitDisable))
|
|
return E_OK;
|
|
else
|
|
{
|
|
if(p_Fm->p_FmStateStruct->explicitEnable)
|
|
/* This is the case were both explicit are TRUE.
|
|
Turn off this flag for cases were following ramsEnable
|
|
routines are called */
|
|
p_Fm->p_FmStateStruct->explicitEnable = FALSE;
|
|
|
|
tmpReg = GET_UINT32(p_Fm->p_FmFpmRegs->fmrcr);
|
|
if(tmpReg & FPM_RAM_CTL_RAMS_ECC_EN_SRC_SEL)
|
|
{
|
|
DBG(WARNING, ("Rams ECC is configured to be controlled through JTAG"));
|
|
WRITE_UINT32(p_Fm->p_FmFpmRegs->fmrcr, tmpReg & ~FPM_RAM_CTL_IRAM_ECC_EN);
|
|
}
|
|
else
|
|
WRITE_UINT32(p_Fm->p_FmFpmRegs->fmrcr, tmpReg & ~(FPM_RAM_CTL_RAMS_ECC_EN | FPM_RAM_CTL_IRAM_ECC_EN));
|
|
p_Fm->p_FmStateStruct->ramsEccEnable = FALSE;
|
|
}
|
|
|
|
return E_OK;
|
|
}
|
|
|
|
t_Error FM_SetException(t_Handle h_Fm, e_FmExceptions exception, bool enable)
|
|
{
|
|
t_Fm *p_Fm = (t_Fm*)h_Fm;
|
|
uint32_t bitMask = 0;
|
|
uint32_t tmpReg;
|
|
|
|
SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
|
|
SANITY_CHECK_RETURN_ERROR(!p_Fm->p_FmDriverParam, E_INVALID_STATE);
|
|
|
|
GET_EXCEPTION_FLAG(bitMask, exception);
|
|
if(bitMask)
|
|
{
|
|
if (enable)
|
|
p_Fm->p_FmStateStruct->exceptions |= bitMask;
|
|
else
|
|
p_Fm->p_FmStateStruct->exceptions &= ~bitMask;
|
|
|
|
switch(exception)
|
|
{
|
|
case(e_FM_EX_DMA_BUS_ERROR):
|
|
tmpReg = GET_UINT32(p_Fm->p_FmDmaRegs->fmdmmr);
|
|
if(enable)
|
|
tmpReg |= DMA_MODE_BER;
|
|
else
|
|
tmpReg &= ~DMA_MODE_BER;
|
|
/* disable bus error */
|
|
WRITE_UINT32(p_Fm->p_FmDmaRegs->fmdmmr, tmpReg);
|
|
break;
|
|
case(e_FM_EX_DMA_READ_ECC):
|
|
case(e_FM_EX_DMA_SYSTEM_WRITE_ECC):
|
|
case(e_FM_EX_DMA_FM_WRITE_ECC):
|
|
tmpReg = GET_UINT32(p_Fm->p_FmDmaRegs->fmdmmr);
|
|
if(enable)
|
|
tmpReg |= DMA_MODE_ECC;
|
|
else
|
|
tmpReg &= ~DMA_MODE_ECC;
|
|
WRITE_UINT32(p_Fm->p_FmDmaRegs->fmdmmr, tmpReg);
|
|
break;
|
|
case(e_FM_EX_FPM_STALL_ON_TASKS):
|
|
tmpReg = GET_UINT32(p_Fm->p_FmFpmRegs->fpmem);
|
|
if(enable)
|
|
tmpReg |= FPM_EV_MASK_STALL_EN;
|
|
else
|
|
tmpReg &= ~FPM_EV_MASK_STALL_EN;
|
|
WRITE_UINT32(p_Fm->p_FmFpmRegs->fpmem, tmpReg);
|
|
break;
|
|
case(e_FM_EX_FPM_SINGLE_ECC):
|
|
tmpReg = GET_UINT32(p_Fm->p_FmFpmRegs->fpmem);
|
|
if(enable)
|
|
tmpReg |= FPM_EV_MASK_SINGLE_ECC_EN;
|
|
else
|
|
tmpReg &= ~FPM_EV_MASK_SINGLE_ECC_EN;
|
|
WRITE_UINT32(p_Fm->p_FmFpmRegs->fpmem, tmpReg);
|
|
break;
|
|
case( e_FM_EX_FPM_DOUBLE_ECC):
|
|
tmpReg = GET_UINT32(p_Fm->p_FmFpmRegs->fpmem);
|
|
if(enable)
|
|
tmpReg |= FPM_EV_MASK_DOUBLE_ECC_EN;
|
|
else
|
|
tmpReg &= ~FPM_EV_MASK_DOUBLE_ECC_EN;
|
|
WRITE_UINT32(p_Fm->p_FmFpmRegs->fpmem, tmpReg);
|
|
break;
|
|
case( e_FM_EX_QMI_SINGLE_ECC):
|
|
tmpReg = GET_UINT32(p_Fm->p_FmQmiRegs->fmqm_ien);
|
|
if(enable)
|
|
{
|
|
#ifdef FM_QMI_NO_ECC_EXCEPTIONS
|
|
t_FmRevisionInfo revInfo;
|
|
FM_GetRevision(p_Fm, &revInfo);
|
|
if (revInfo.majorRev == 4)
|
|
{
|
|
REPORT_ERROR(MINOR, E_NOT_SUPPORTED, ("e_FM_EX_QMI_SINGLE_ECC"));
|
|
return E_OK;
|
|
}
|
|
#endif /* FM_QMI_NO_ECC_EXCEPTIONS */
|
|
tmpReg |= QMI_INTR_EN_SINGLE_ECC;
|
|
}
|
|
else
|
|
tmpReg &= ~QMI_INTR_EN_SINGLE_ECC;
|
|
WRITE_UINT32(p_Fm->p_FmQmiRegs->fmqm_ien, tmpReg);
|
|
break;
|
|
case(e_FM_EX_QMI_DOUBLE_ECC):
|
|
tmpReg = GET_UINT32(p_Fm->p_FmQmiRegs->fmqm_eien);
|
|
if(enable)
|
|
{
|
|
#ifdef FM_QMI_NO_ECC_EXCEPTIONS
|
|
t_FmRevisionInfo revInfo;
|
|
FM_GetRevision(p_Fm, &revInfo);
|
|
if (revInfo.majorRev == 4)
|
|
{
|
|
REPORT_ERROR(MINOR, E_NOT_SUPPORTED, ("e_FM_EX_QMI_DOUBLE_ECC"));
|
|
return E_OK;
|
|
}
|
|
#endif /* FM_QMI_NO_ECC_EXCEPTIONS */
|
|
tmpReg |= QMI_ERR_INTR_EN_DOUBLE_ECC;
|
|
}
|
|
else
|
|
tmpReg &= ~QMI_ERR_INTR_EN_DOUBLE_ECC;
|
|
WRITE_UINT32(p_Fm->p_FmQmiRegs->fmqm_eien, tmpReg);
|
|
break;
|
|
case(e_FM_EX_QMI_DEQ_FROM_UNKNOWN_PORTID):
|
|
tmpReg = GET_UINT32(p_Fm->p_FmQmiRegs->fmqm_eien);
|
|
if(enable)
|
|
tmpReg |= QMI_ERR_INTR_EN_DEQ_FROM_DEF;
|
|
else
|
|
tmpReg &= ~QMI_ERR_INTR_EN_DEQ_FROM_DEF;
|
|
WRITE_UINT32(p_Fm->p_FmQmiRegs->fmqm_eien, tmpReg);
|
|
break;
|
|
case(e_FM_EX_BMI_LIST_RAM_ECC):
|
|
tmpReg = GET_UINT32(p_Fm->p_FmBmiRegs->fmbm_ier);
|
|
if(enable)
|
|
{
|
|
#ifdef FM_RAM_LIST_ERR_IRQ_ERRATA_FMAN8
|
|
t_FmRevisionInfo revInfo;
|
|
FM_GetRevision(p_Fm, &revInfo);
|
|
if ((revInfo.majorRev == 1) && (revInfo.minorRev == 0))
|
|
{
|
|
REPORT_ERROR(MINOR, E_NOT_SUPPORTED, ("e_FM_EX_BMI_LIST_RAM_ECC"));
|
|
return E_OK;
|
|
}
|
|
#endif /* FM_RAM_LIST_ERR_IRQ_ERRATA_FMAN8 */
|
|
tmpReg |= BMI_ERR_INTR_EN_LIST_RAM_ECC;
|
|
}
|
|
else
|
|
tmpReg &= ~BMI_ERR_INTR_EN_LIST_RAM_ECC;
|
|
WRITE_UINT32(p_Fm->p_FmBmiRegs->fmbm_ier, tmpReg);
|
|
break;
|
|
case(e_FM_EX_BMI_PIPELINE_ECC):
|
|
tmpReg = GET_UINT32(p_Fm->p_FmBmiRegs->fmbm_ier);
|
|
if(enable)
|
|
{
|
|
#ifdef FM_BMI_PIPELINE_ERR_IRQ_ERRATA_FMAN9
|
|
t_FmRevisionInfo revInfo;
|
|
FM_GetRevision(p_Fm, &revInfo);
|
|
if ((revInfo.majorRev == 1) && (revInfo.minorRev == 0))
|
|
{
|
|
REPORT_ERROR(MINOR, E_NOT_SUPPORTED, ("e_FM_EX_BMI_PIPELINE_ECCBMI_LIST_RAM_ECC"));
|
|
return E_OK;
|
|
}
|
|
#endif /* FM_BMI_PIPELINE_ERR_IRQ_ERRATA_FMAN9 */
|
|
tmpReg |= BMI_ERR_INTR_EN_PIPELINE_ECC;
|
|
}
|
|
else
|
|
tmpReg &= ~BMI_ERR_INTR_EN_PIPELINE_ECC;
|
|
WRITE_UINT32(p_Fm->p_FmBmiRegs->fmbm_ier, tmpReg);
|
|
break;
|
|
case(e_FM_EX_BMI_STATISTICS_RAM_ECC):
|
|
tmpReg = GET_UINT32(p_Fm->p_FmBmiRegs->fmbm_ier);
|
|
if(enable)
|
|
tmpReg |= BMI_ERR_INTR_EN_STATISTICS_RAM_ECC;
|
|
else
|
|
tmpReg &= ~BMI_ERR_INTR_EN_STATISTICS_RAM_ECC;
|
|
WRITE_UINT32(p_Fm->p_FmBmiRegs->fmbm_ier, tmpReg);
|
|
break;
|
|
case(e_FM_EX_BMI_DISPATCH_RAM_ECC):
|
|
tmpReg = GET_UINT32(p_Fm->p_FmBmiRegs->fmbm_ier);
|
|
if(enable)
|
|
{
|
|
#ifdef FM_NO_DISPATCH_RAM_ECC
|
|
t_FmRevisionInfo revInfo;
|
|
FM_GetRevision(p_Fm, &revInfo);
|
|
if (revInfo.majorRev != 4)
|
|
{
|
|
REPORT_ERROR(MINOR, E_NOT_SUPPORTED, ("e_FM_EX_BMI_DISPATCH_RAM_ECC"));
|
|
return E_OK;
|
|
}
|
|
#endif /* FM_NO_DISPATCH_RAM_ECC */
|
|
tmpReg |= BMI_ERR_INTR_EN_DISPATCH_RAM_ECC;
|
|
}
|
|
else
|
|
tmpReg &= ~BMI_ERR_INTR_EN_DISPATCH_RAM_ECC;
|
|
WRITE_UINT32(p_Fm->p_FmBmiRegs->fmbm_ier, tmpReg);
|
|
break;
|
|
case(e_FM_EX_IRAM_ECC):
|
|
tmpReg = GET_UINT32(p_Fm->p_FmFpmRegs->fmrie);
|
|
if(enable)
|
|
{
|
|
/* enable ECC if not enabled */
|
|
FmEnableRamsEcc(p_Fm);
|
|
/* enable ECC interrupts */
|
|
tmpReg |= FPM_IRAM_ECC_ERR_EX_EN;
|
|
}
|
|
else
|
|
{
|
|
/* ECC mechanism may be disabled, depending on driver status */
|
|
FmDisableRamsEcc(p_Fm);
|
|
tmpReg &= ~FPM_IRAM_ECC_ERR_EX_EN;
|
|
}
|
|
WRITE_UINT32(p_Fm->p_FmFpmRegs->fmrie, tmpReg);
|
|
break;
|
|
|
|
case(e_FM_EX_MURAM_ECC):
|
|
tmpReg = GET_UINT32(p_Fm->p_FmFpmRegs->fmrie);
|
|
if(enable)
|
|
{
|
|
/* enable ECC if not enabled */
|
|
FmEnableRamsEcc(p_Fm);
|
|
/* enable ECC interrupts */
|
|
tmpReg |= FPM_MURAM_ECC_ERR_EX_EN;
|
|
}
|
|
else
|
|
{
|
|
/* ECC mechanism may be disabled, depending on driver status */
|
|
FmDisableRamsEcc(p_Fm);
|
|
tmpReg &= ~FPM_MURAM_ECC_ERR_EX_EN;
|
|
}
|
|
|
|
WRITE_UINT32(p_Fm->p_FmFpmRegs->fmrie, tmpReg);
|
|
break;
|
|
default:
|
|
RETURN_ERROR(MINOR, E_INVALID_SELECTION, NO_MSG);
|
|
}
|
|
}
|
|
else
|
|
RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined exception"));
|
|
|
|
return E_OK;
|
|
}
|
|
|
|
t_Error FM_GetRevision(t_Handle h_Fm, t_FmRevisionInfo *p_FmRevisionInfo)
|
|
{
|
|
t_Fm *p_Fm = (t_Fm*)h_Fm;
|
|
uint32_t tmpReg;
|
|
t_Error err;
|
|
t_FmIpcMsg msg;
|
|
t_FmIpcReply reply;
|
|
uint32_t replyLength;
|
|
t_FmIpcRevisionInfo ipcRevInfo;
|
|
|
|
SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
|
|
|
|
if (p_Fm->guestId != NCSW_MASTER_ID)
|
|
{
|
|
memset(&msg, 0, sizeof(msg));
|
|
memset(&reply, 0, sizeof(reply));
|
|
msg.msgId = FM_GET_REV;
|
|
replyLength = sizeof(uint32_t) + sizeof(t_FmRevisionInfo);
|
|
if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
|
|
(uint8_t*)&msg,
|
|
sizeof(msg.msgId),
|
|
(uint8_t*)&reply,
|
|
&replyLength,
|
|
NULL,
|
|
NULL)) != E_OK)
|
|
RETURN_ERROR(MINOR, err, NO_MSG);
|
|
if (replyLength != (sizeof(uint32_t) + sizeof(t_FmRevisionInfo)))
|
|
RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
|
|
memcpy((uint8_t*)&ipcRevInfo, reply.replyBody, sizeof(t_FmRevisionInfo));
|
|
p_FmRevisionInfo->majorRev = ipcRevInfo.majorRev;
|
|
p_FmRevisionInfo->minorRev = ipcRevInfo.minorRev;
|
|
return (t_Error)(reply.error);
|
|
}
|
|
|
|
/* read revision register 1 */
|
|
tmpReg = GET_UINT32(p_Fm->p_FmFpmRegs->fm_ip_rev_1);
|
|
p_FmRevisionInfo->majorRev = (uint8_t)((tmpReg & FPM_REV1_MAJOR_MASK) >> FPM_REV1_MAJOR_SHIFT);
|
|
p_FmRevisionInfo->minorRev = (uint8_t)((tmpReg & FPM_REV1_MINOR_MASK) >> FPM_REV1_MINOR_SHIFT);
|
|
|
|
return E_OK;
|
|
}
|
|
|
|
uint32_t FM_GetCounter(t_Handle h_Fm, e_FmCounters counter)
|
|
{
|
|
t_Fm *p_Fm = (t_Fm*)h_Fm;
|
|
t_Error err;
|
|
uint32_t counterValue;
|
|
t_FmIpcMsg msg;
|
|
t_FmIpcReply reply;
|
|
uint32_t replyLength, outCounter;
|
|
|
|
SANITY_CHECK_RETURN_VALUE(p_Fm, E_INVALID_HANDLE, 0);
|
|
SANITY_CHECK_RETURN_VALUE(!p_Fm->p_FmDriverParam, E_INVALID_STATE, 0);
|
|
|
|
|
|
if(p_Fm->guestId != NCSW_MASTER_ID)
|
|
{
|
|
memset(&msg, 0, sizeof(msg));
|
|
memset(&reply, 0, sizeof(reply));
|
|
msg.msgId = FM_GET_COUNTER;
|
|
memcpy(msg.msgBody, (uint8_t *)&counter, sizeof(uint32_t));
|
|
replyLength = sizeof(uint32_t) + sizeof(uint32_t);
|
|
if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
|
|
(uint8_t*)&msg,
|
|
sizeof(msg.msgId) +sizeof(counterValue),
|
|
(uint8_t*)&reply,
|
|
&replyLength,
|
|
NULL,
|
|
NULL)) != E_OK)
|
|
RETURN_ERROR(MAJOR, err, NO_MSG);
|
|
if(replyLength != (sizeof(uint32_t) + sizeof(uint32_t)))
|
|
RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
|
|
memcpy((uint8_t*)&outCounter, reply.replyBody, sizeof(uint32_t));
|
|
|
|
return outCounter;
|
|
}
|
|
|
|
switch(counter)
|
|
{
|
|
case(e_FM_COUNTERS_ENQ_TOTAL_FRAME):
|
|
return GET_UINT32(p_Fm->p_FmQmiRegs->fmqm_etfc);
|
|
case(e_FM_COUNTERS_DEQ_TOTAL_FRAME):
|
|
return GET_UINT32(p_Fm->p_FmQmiRegs->fmqm_dtfc);
|
|
case(e_FM_COUNTERS_DEQ_0):
|
|
return GET_UINT32(p_Fm->p_FmQmiRegs->fmqm_dc0);
|
|
case(e_FM_COUNTERS_DEQ_1):
|
|
return GET_UINT32(p_Fm->p_FmQmiRegs->fmqm_dc1);
|
|
case(e_FM_COUNTERS_DEQ_2):
|
|
return GET_UINT32(p_Fm->p_FmQmiRegs->fmqm_dc2);
|
|
case(e_FM_COUNTERS_DEQ_3):
|
|
return GET_UINT32(p_Fm->p_FmQmiRegs->fmqm_dc3);
|
|
case(e_FM_COUNTERS_DEQ_FROM_DEFAULT):
|
|
return GET_UINT32(p_Fm->p_FmQmiRegs->fmqm_dfdc);
|
|
case(e_FM_COUNTERS_DEQ_FROM_CONTEXT):
|
|
return GET_UINT32(p_Fm->p_FmQmiRegs->fmqm_dfcc);
|
|
case(e_FM_COUNTERS_DEQ_FROM_FD):
|
|
return GET_UINT32(p_Fm->p_FmQmiRegs->fmqm_dffc);
|
|
case(e_FM_COUNTERS_DEQ_CONFIRM):
|
|
return GET_UINT32(p_Fm->p_FmQmiRegs->fmqm_dcc);
|
|
case(e_FM_COUNTERS_SEMAPHOR_ENTRY_FULL_REJECT):
|
|
return GET_UINT32(p_Fm->p_FmDmaRegs->fmdmsefrc);
|
|
case(e_FM_COUNTERS_SEMAPHOR_QUEUE_FULL_REJECT):
|
|
return GET_UINT32(p_Fm->p_FmDmaRegs->fmdmsqfrc);
|
|
case(e_FM_COUNTERS_SEMAPHOR_SYNC_REJECT):
|
|
return GET_UINT32(p_Fm->p_FmDmaRegs->fmdmssrc);
|
|
default:
|
|
break;
|
|
}
|
|
/* should never get here */
|
|
ASSERT_COND(FALSE);
|
|
|
|
return 0;
|
|
}
|
|
|
|
t_Error FM_ModifyCounter(t_Handle h_Fm, e_FmCounters counter, uint32_t val)
|
|
{
|
|
t_Fm *p_Fm = (t_Fm*)h_Fm;
|
|
|
|
SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
|
|
SANITY_CHECK_RETURN_ERROR(!p_Fm->p_FmDriverParam, E_INVALID_STATE);
|
|
|
|
/* When applicable (when there is an 'enable counters' bit,
|
|
check that counters are enabled */
|
|
switch(counter)
|
|
{
|
|
case(e_FM_COUNTERS_ENQ_TOTAL_FRAME):
|
|
case(e_FM_COUNTERS_DEQ_TOTAL_FRAME):
|
|
case(e_FM_COUNTERS_DEQ_0):
|
|
case(e_FM_COUNTERS_DEQ_1):
|
|
case(e_FM_COUNTERS_DEQ_2):
|
|
case(e_FM_COUNTERS_DEQ_3):
|
|
case(e_FM_COUNTERS_DEQ_FROM_DEFAULT):
|
|
case(e_FM_COUNTERS_DEQ_FROM_CONTEXT):
|
|
case(e_FM_COUNTERS_DEQ_FROM_FD):
|
|
case(e_FM_COUNTERS_DEQ_CONFIRM):
|
|
if(!(GET_UINT32(p_Fm->p_FmQmiRegs->fmqm_gc) & QMI_CFG_EN_COUNTERS))
|
|
RETURN_ERROR(MINOR, E_INVALID_STATE, ("Requested counter was not enabled"));
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
/* Set counter */
|
|
switch(counter)
|
|
{
|
|
case(e_FM_COUNTERS_ENQ_TOTAL_FRAME):
|
|
WRITE_UINT32(p_Fm->p_FmQmiRegs->fmqm_etfc, val);
|
|
break;
|
|
case(e_FM_COUNTERS_DEQ_TOTAL_FRAME):
|
|
WRITE_UINT32(p_Fm->p_FmQmiRegs->fmqm_dtfc, val);
|
|
break;
|
|
case(e_FM_COUNTERS_DEQ_0):
|
|
WRITE_UINT32(p_Fm->p_FmQmiRegs->fmqm_dc0, val);
|
|
break;
|
|
case(e_FM_COUNTERS_DEQ_1):
|
|
WRITE_UINT32(p_Fm->p_FmQmiRegs->fmqm_dc1, val);
|
|
break;
|
|
case(e_FM_COUNTERS_DEQ_2):
|
|
WRITE_UINT32(p_Fm->p_FmQmiRegs->fmqm_dc2, val);
|
|
break;
|
|
case(e_FM_COUNTERS_DEQ_3):
|
|
WRITE_UINT32(p_Fm->p_FmQmiRegs->fmqm_dc3, val);
|
|
break;
|
|
case(e_FM_COUNTERS_DEQ_FROM_DEFAULT):
|
|
WRITE_UINT32(p_Fm->p_FmQmiRegs->fmqm_dfdc, val);
|
|
break;
|
|
case(e_FM_COUNTERS_DEQ_FROM_CONTEXT):
|
|
WRITE_UINT32(p_Fm->p_FmQmiRegs->fmqm_dfcc, val);
|
|
break;
|
|
case(e_FM_COUNTERS_DEQ_FROM_FD):
|
|
WRITE_UINT32(p_Fm->p_FmQmiRegs->fmqm_dffc, val);
|
|
break;
|
|
case(e_FM_COUNTERS_DEQ_CONFIRM):
|
|
WRITE_UINT32(p_Fm->p_FmQmiRegs->fmqm_dcc, val);
|
|
break;
|
|
case(e_FM_COUNTERS_SEMAPHOR_ENTRY_FULL_REJECT):
|
|
WRITE_UINT32(p_Fm->p_FmDmaRegs->fmdmsefrc, val);
|
|
break;
|
|
case(e_FM_COUNTERS_SEMAPHOR_QUEUE_FULL_REJECT):
|
|
WRITE_UINT32(p_Fm->p_FmDmaRegs->fmdmsqfrc, val);
|
|
break;
|
|
case(e_FM_COUNTERS_SEMAPHOR_SYNC_REJECT):
|
|
WRITE_UINT32(p_Fm->p_FmDmaRegs->fmdmssrc, val);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
return E_OK;
|
|
}
|
|
|
|
void FM_SetDmaEmergency(t_Handle h_Fm, e_FmDmaMuramPort muramPort, bool enable)
|
|
{
|
|
t_Fm *p_Fm = (t_Fm*)h_Fm;
|
|
uint32_t bitMask;
|
|
|
|
SANITY_CHECK_RETURN(p_Fm, E_INVALID_HANDLE);
|
|
SANITY_CHECK_RETURN(!p_Fm->p_FmDriverParam, E_INVALID_STATE);
|
|
|
|
bitMask = (uint32_t)((muramPort==e_FM_DMA_MURAM_PORT_WRITE) ? DMA_MODE_EMERGENCY_WRITE : DMA_MODE_EMERGENCY_READ);
|
|
|
|
if(enable)
|
|
WRITE_UINT32(p_Fm->p_FmDmaRegs->fmdmmr, GET_UINT32(p_Fm->p_FmDmaRegs->fmdmmr) | bitMask);
|
|
else /* disable */
|
|
WRITE_UINT32(p_Fm->p_FmDmaRegs->fmdmmr, GET_UINT32(p_Fm->p_FmDmaRegs->fmdmmr) & ~bitMask);
|
|
|
|
return;
|
|
}
|
|
|
|
void FM_SetDmaExtBusPri(t_Handle h_Fm, e_FmDmaExtBusPri pri)
|
|
{
|
|
t_Fm *p_Fm = (t_Fm*)h_Fm;
|
|
|
|
SANITY_CHECK_RETURN(p_Fm, E_INVALID_HANDLE);
|
|
SANITY_CHECK_RETURN(!p_Fm->p_FmDriverParam, E_INVALID_STATE);
|
|
|
|
WRITE_UINT32(p_Fm->p_FmDmaRegs->fmdmmr, GET_UINT32(p_Fm->p_FmDmaRegs->fmdmmr) | ((uint32_t)pri << DMA_MODE_BUS_PRI_SHIFT) );
|
|
|
|
return;
|
|
}
|
|
|
|
void FM_GetDmaStatus(t_Handle h_Fm, t_FmDmaStatus *p_FmDmaStatus)
|
|
{
|
|
t_Fm *p_Fm = (t_Fm*)h_Fm;
|
|
uint32_t tmpReg;
|
|
t_Error err;
|
|
t_FmIpcMsg msg;
|
|
t_FmIpcReply reply;
|
|
uint32_t replyLength;
|
|
t_FmIpcDmaStatus ipcDmaStatus;
|
|
|
|
SANITY_CHECK_RETURN(p_Fm, E_INVALID_HANDLE);
|
|
SANITY_CHECK_RETURN(!p_Fm->p_FmDriverParam, E_INVALID_STATE);
|
|
|
|
if(p_Fm->guestId != NCSW_MASTER_ID)
|
|
{
|
|
memset(&msg, 0, sizeof(msg));
|
|
memset(&reply, 0, sizeof(reply));
|
|
msg.msgId = FM_DMA_STAT;
|
|
replyLength = sizeof(uint32_t) + sizeof(t_FmIpcDmaStatus);
|
|
if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
|
|
(uint8_t*)&msg,
|
|
sizeof(msg.msgId),
|
|
(uint8_t*)&reply,
|
|
&replyLength,
|
|
NULL,
|
|
NULL)) != E_OK)
|
|
{
|
|
REPORT_ERROR(MINOR, err, NO_MSG);
|
|
return;
|
|
}
|
|
if (replyLength != (sizeof(uint32_t) + sizeof(t_FmIpcDmaStatus)))
|
|
{
|
|
REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
|
|
return;
|
|
}
|
|
memcpy((uint8_t*)&ipcDmaStatus, reply.replyBody, sizeof(t_FmIpcDmaStatus));
|
|
|
|
p_FmDmaStatus->cmqNotEmpty = (bool)ipcDmaStatus.boolCmqNotEmpty; /**< Command queue is not empty */
|
|
p_FmDmaStatus->busError = (bool)ipcDmaStatus.boolBusError; /**< Bus error occurred */
|
|
p_FmDmaStatus->readBufEccError = (bool)ipcDmaStatus.boolReadBufEccError; /**< Double ECC error on buffer Read */
|
|
p_FmDmaStatus->writeBufEccSysError =(bool)ipcDmaStatus.boolWriteBufEccSysError; /**< Double ECC error on buffer write from system side */
|
|
p_FmDmaStatus->writeBufEccFmError = (bool)ipcDmaStatus.boolWriteBufEccFmError; /**< Double ECC error on buffer write from FM side */
|
|
return;
|
|
}
|
|
|
|
tmpReg = GET_UINT32(p_Fm->p_FmDmaRegs->fmdmsr);
|
|
|
|
p_FmDmaStatus->cmqNotEmpty = (bool)(tmpReg & DMA_STATUS_CMD_QUEUE_NOT_EMPTY);
|
|
p_FmDmaStatus->busError = (bool)(tmpReg & DMA_STATUS_BUS_ERR);
|
|
p_FmDmaStatus->readBufEccError = (bool)(tmpReg & DMA_STATUS_READ_ECC);
|
|
p_FmDmaStatus->writeBufEccSysError = (bool)(tmpReg & DMA_STATUS_SYSTEM_WRITE_ECC);
|
|
p_FmDmaStatus->writeBufEccFmError = (bool)(tmpReg & DMA_STATUS_FM_WRITE_ECC);
|
|
return;
|
|
}
|
|
|
|
t_Error FM_ForceIntr (t_Handle h_Fm, e_FmExceptions exception)
|
|
{
|
|
t_Fm *p_Fm = (t_Fm*)h_Fm;
|
|
|
|
SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
|
|
SANITY_CHECK_RETURN_ERROR(!p_Fm->p_FmDriverParam, E_INVALID_STATE);
|
|
|
|
switch(exception)
|
|
{
|
|
case e_FM_EX_QMI_DEQ_FROM_UNKNOWN_PORTID:
|
|
if (!(p_Fm->p_FmStateStruct->exceptions & FM_EX_QMI_DEQ_FROM_UNKNOWN_PORTID))
|
|
RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked"));
|
|
WRITE_UINT32(p_Fm->p_FmQmiRegs->fmqm_eif, QMI_ERR_INTR_EN_DEQ_FROM_DEF);
|
|
break;
|
|
case e_FM_EX_QMI_SINGLE_ECC:
|
|
if (!(p_Fm->p_FmStateStruct->exceptions & FM_EX_QMI_SINGLE_ECC))
|
|
RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked"));
|
|
WRITE_UINT32(p_Fm->p_FmQmiRegs->fmqm_if, QMI_INTR_EN_SINGLE_ECC);
|
|
break;
|
|
case e_FM_EX_QMI_DOUBLE_ECC:
|
|
if (!(p_Fm->p_FmStateStruct->exceptions & FM_EX_QMI_DOUBLE_ECC))
|
|
RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked"));
|
|
WRITE_UINT32(p_Fm->p_FmQmiRegs->fmqm_eif, QMI_ERR_INTR_EN_DOUBLE_ECC);
|
|
break;
|
|
case e_FM_EX_BMI_LIST_RAM_ECC:
|
|
if (!(p_Fm->p_FmStateStruct->exceptions & FM_EX_BMI_LIST_RAM_ECC))
|
|
RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked"));
|
|
WRITE_UINT32(p_Fm->p_FmBmiRegs->fmbm_ifr, BMI_ERR_INTR_EN_LIST_RAM_ECC);
|
|
break;
|
|
case e_FM_EX_BMI_PIPELINE_ECC:
|
|
if (!(p_Fm->p_FmStateStruct->exceptions & FM_EX_BMI_PIPELINE_ECC))
|
|
RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked"));
|
|
WRITE_UINT32(p_Fm->p_FmBmiRegs->fmbm_ifr, BMI_ERR_INTR_EN_PIPELINE_ECC);
|
|
break;
|
|
case e_FM_EX_BMI_STATISTICS_RAM_ECC:
|
|
if (!(p_Fm->p_FmStateStruct->exceptions & FM_EX_BMI_STATISTICS_RAM_ECC))
|
|
RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked"));
|
|
WRITE_UINT32(p_Fm->p_FmBmiRegs->fmbm_ifr, BMI_ERR_INTR_EN_STATISTICS_RAM_ECC);
|
|
break;
|
|
case e_FM_EX_BMI_DISPATCH_RAM_ECC:
|
|
if (!(p_Fm->p_FmStateStruct->exceptions & FM_EX_BMI_DISPATCH_RAM_ECC))
|
|
RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked"));
|
|
WRITE_UINT32(p_Fm->p_FmBmiRegs->fmbm_ifr, BMI_ERR_INTR_EN_DISPATCH_RAM_ECC);
|
|
break;
|
|
default:
|
|
RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception may not be forced"));
|
|
}
|
|
|
|
return E_OK;
|
|
}
|
|
|
|
void FM_Resume(t_Handle h_Fm)
|
|
{
|
|
t_Fm *p_Fm = (t_Fm*)h_Fm;
|
|
uint32_t tmpReg;
|
|
|
|
SANITY_CHECK_RETURN(p_Fm, E_INVALID_HANDLE);
|
|
SANITY_CHECK_RETURN(!p_Fm->p_FmDriverParam, E_INVALID_STATE);
|
|
|
|
if (p_Fm->guestId == NCSW_MASTER_ID)
|
|
{
|
|
tmpReg = GET_UINT32(p_Fm->p_FmFpmRegs->fpmem);
|
|
/* clear tmpReg event bits in order not to clear standing events */
|
|
tmpReg &= ~(FPM_EV_MASK_DOUBLE_ECC | FPM_EV_MASK_STALL | FPM_EV_MASK_SINGLE_ECC);
|
|
WRITE_UINT32(p_Fm->p_FmFpmRegs->fpmem, tmpReg | FPM_EV_MASK_RELEASE_FM);
|
|
}
|
|
else
|
|
ASSERT_COND(0); /* TODO */
|
|
}
|
|
|
|
#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
|
|
t_Error FM_DumpRegs(t_Handle h_Fm)
|
|
{
|
|
t_Fm *p_Fm = (t_Fm *)h_Fm;
|
|
uint8_t i = 0;
|
|
t_Error err;
|
|
t_FmIpcMsg msg;
|
|
|
|
DECLARE_DUMP;
|
|
|
|
SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
|
|
SANITY_CHECK_RETURN_ERROR(!p_Fm->p_FmDriverParam, E_INVALID_STATE);
|
|
|
|
|
|
if(p_Fm->guestId != NCSW_MASTER_ID)
|
|
{
|
|
memset(&msg, 0, sizeof(msg));
|
|
msg.msgId = FM_DUMP_REGS;
|
|
if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
|
|
(uint8_t*)&msg,
|
|
sizeof(msg.msgId),
|
|
NULL,
|
|
NULL,
|
|
NULL,
|
|
NULL)) != E_OK)
|
|
RETURN_ERROR(MINOR, err, NO_MSG);
|
|
return E_OK;
|
|
}
|
|
|
|
|
|
DUMP_SUBTITLE(("\n"));
|
|
|
|
DUMP_TITLE(p_Fm->p_FmFpmRegs, ("FmFpmRegs Regs"));
|
|
|
|
DUMP_VAR(p_Fm->p_FmFpmRegs,fpmtnc);
|
|
DUMP_VAR(p_Fm->p_FmFpmRegs,fpmpr);
|
|
DUMP_VAR(p_Fm->p_FmFpmRegs,brkc);
|
|
DUMP_VAR(p_Fm->p_FmFpmRegs,fpmflc);
|
|
DUMP_VAR(p_Fm->p_FmFpmRegs,fpmdis1);
|
|
DUMP_VAR(p_Fm->p_FmFpmRegs,fpmdis2);
|
|
DUMP_VAR(p_Fm->p_FmFpmRegs,fmepi);
|
|
DUMP_VAR(p_Fm->p_FmFpmRegs,fmrie);
|
|
|
|
DUMP_TITLE(&p_Fm->p_FmFpmRegs->fmfpfcev, ("fmfpfcev"));
|
|
DUMP_SUBSTRUCT_ARRAY(i, 4)
|
|
{
|
|
DUMP_MEMORY(&p_Fm->p_FmFpmRegs->fmfpfcev[i], sizeof(uint32_t));
|
|
}
|
|
|
|
DUMP_TITLE(&p_Fm->p_FmFpmRegs->fmfpfcee, ("fmfpfcee"));
|
|
DUMP_SUBSTRUCT_ARRAY(i, 4)
|
|
{
|
|
DUMP_MEMORY(&p_Fm->p_FmFpmRegs->fmfpfcee[i], sizeof(uint32_t));
|
|
}
|
|
|
|
DUMP_SUBTITLE(("\n"));
|
|
DUMP_VAR(p_Fm->p_FmFpmRegs,fpmtsc1);
|
|
DUMP_VAR(p_Fm->p_FmFpmRegs,fpmtsc2);
|
|
DUMP_VAR(p_Fm->p_FmFpmRegs,fpmtsp);
|
|
DUMP_VAR(p_Fm->p_FmFpmRegs,fpmtsf);
|
|
DUMP_VAR(p_Fm->p_FmFpmRegs,fmrcr);
|
|
DUMP_VAR(p_Fm->p_FmFpmRegs,fpmextc);
|
|
DUMP_VAR(p_Fm->p_FmFpmRegs,fpmext1);
|
|
DUMP_VAR(p_Fm->p_FmFpmRegs,fpmext2);
|
|
|
|
DUMP_TITLE(&p_Fm->p_FmFpmRegs->fpmdrd, ("fpmdrd"));
|
|
DUMP_SUBSTRUCT_ARRAY(i, 16)
|
|
{
|
|
DUMP_MEMORY(&p_Fm->p_FmFpmRegs->fpmdrd[i], sizeof(uint32_t));
|
|
}
|
|
|
|
DUMP_SUBTITLE(("\n"));
|
|
DUMP_VAR(p_Fm->p_FmFpmRegs,fpmdra);
|
|
DUMP_VAR(p_Fm->p_FmFpmRegs,fm_ip_rev_1);
|
|
DUMP_VAR(p_Fm->p_FmFpmRegs,fm_ip_rev_2);
|
|
DUMP_VAR(p_Fm->p_FmFpmRegs,fmrstc);
|
|
DUMP_VAR(p_Fm->p_FmFpmRegs,fmcld);
|
|
DUMP_VAR(p_Fm->p_FmFpmRegs,fmnpi);
|
|
DUMP_VAR(p_Fm->p_FmFpmRegs,fpmem);
|
|
|
|
DUMP_TITLE(&p_Fm->p_FmFpmRegs->fpmcev, ("fpmcev"));
|
|
DUMP_SUBSTRUCT_ARRAY(i, 4)
|
|
{
|
|
DUMP_MEMORY(&p_Fm->p_FmFpmRegs->fpmcev[i], sizeof(uint32_t));
|
|
}
|
|
|
|
DUMP_TITLE(&p_Fm->p_FmFpmRegs->fmfp_ps, ("fmfp_ps"));
|
|
DUMP_SUBSTRUCT_ARRAY(i, 64)
|
|
{
|
|
DUMP_MEMORY(&p_Fm->p_FmFpmRegs->fmfp_ps[i], sizeof(uint32_t));
|
|
}
|
|
|
|
|
|
DUMP_TITLE(p_Fm->p_FmDmaRegs, ("p_FmDmaRegs Regs"));
|
|
DUMP_VAR(p_Fm->p_FmDmaRegs,fmdmsr);
|
|
DUMP_VAR(p_Fm->p_FmDmaRegs,fmdmmr);
|
|
DUMP_VAR(p_Fm->p_FmDmaRegs,fmdmtr);
|
|
DUMP_VAR(p_Fm->p_FmDmaRegs,fmdmhy);
|
|
DUMP_VAR(p_Fm->p_FmDmaRegs,fmdmsetr);
|
|
DUMP_VAR(p_Fm->p_FmDmaRegs,fmdmtah);
|
|
DUMP_VAR(p_Fm->p_FmDmaRegs,fmdmtal);
|
|
DUMP_VAR(p_Fm->p_FmDmaRegs,fmdmtcid);
|
|
DUMP_VAR(p_Fm->p_FmDmaRegs,fmdmra);
|
|
DUMP_VAR(p_Fm->p_FmDmaRegs,fmdmrd);
|
|
DUMP_VAR(p_Fm->p_FmDmaRegs,fmdmwcr);
|
|
DUMP_VAR(p_Fm->p_FmDmaRegs,fmdmebcr);
|
|
DUMP_VAR(p_Fm->p_FmDmaRegs,fmdmccqdr);
|
|
DUMP_VAR(p_Fm->p_FmDmaRegs,fmdmccqvr1);
|
|
DUMP_VAR(p_Fm->p_FmDmaRegs,fmdmccqvr2);
|
|
DUMP_VAR(p_Fm->p_FmDmaRegs,fmdmcqvr3);
|
|
DUMP_VAR(p_Fm->p_FmDmaRegs,fmdmcqvr4);
|
|
DUMP_VAR(p_Fm->p_FmDmaRegs,fmdmcqvr5);
|
|
DUMP_VAR(p_Fm->p_FmDmaRegs,fmdmsefrc);
|
|
DUMP_VAR(p_Fm->p_FmDmaRegs,fmdmsqfrc);
|
|
DUMP_VAR(p_Fm->p_FmDmaRegs,fmdmssrc);
|
|
DUMP_VAR(p_Fm->p_FmDmaRegs,fmdmdcr);
|
|
|
|
DUMP_TITLE(&p_Fm->p_FmDmaRegs->fmdmplr, ("fmdmplr"));
|
|
|
|
DUMP_SUBSTRUCT_ARRAY(i, FM_SIZE_OF_LIODN_TABLE/2)
|
|
{
|
|
DUMP_MEMORY(&p_Fm->p_FmDmaRegs->fmdmplr[i], sizeof(uint32_t));
|
|
}
|
|
|
|
DUMP_TITLE(p_Fm->p_FmBmiRegs, ("p_FmBmiRegs COMMON Regs"));
|
|
DUMP_VAR(p_Fm->p_FmBmiRegs,fmbm_init);
|
|
DUMP_VAR(p_Fm->p_FmBmiRegs,fmbm_cfg1);
|
|
DUMP_VAR(p_Fm->p_FmBmiRegs,fmbm_cfg2);
|
|
DUMP_VAR(p_Fm->p_FmBmiRegs,fmbm_ievr);
|
|
DUMP_VAR(p_Fm->p_FmBmiRegs,fmbm_ier);
|
|
|
|
DUMP_TITLE(&p_Fm->p_FmBmiRegs->fmbm_arb, ("fmbm_arb"));
|
|
DUMP_SUBSTRUCT_ARRAY(i, 8)
|
|
{
|
|
DUMP_MEMORY(&p_Fm->p_FmBmiRegs->fmbm_arb[i], sizeof(uint32_t));
|
|
}
|
|
|
|
|
|
DUMP_TITLE(p_Fm->p_FmQmiRegs, ("p_FmQmiRegs COMMON Regs"));
|
|
DUMP_VAR(p_Fm->p_FmQmiRegs,fmqm_gc);
|
|
DUMP_VAR(p_Fm->p_FmQmiRegs,fmqm_eie);
|
|
DUMP_VAR(p_Fm->p_FmQmiRegs,fmqm_eien);
|
|
DUMP_VAR(p_Fm->p_FmQmiRegs,fmqm_eif);
|
|
DUMP_VAR(p_Fm->p_FmQmiRegs,fmqm_ie);
|
|
DUMP_VAR(p_Fm->p_FmQmiRegs,fmqm_ien);
|
|
DUMP_VAR(p_Fm->p_FmQmiRegs,fmqm_if);
|
|
DUMP_VAR(p_Fm->p_FmQmiRegs,fmqm_gs);
|
|
DUMP_VAR(p_Fm->p_FmQmiRegs,fmqm_ts);
|
|
DUMP_VAR(p_Fm->p_FmQmiRegs,fmqm_etfc);
|
|
|
|
return E_OK;
|
|
}
|
|
#endif /* (defined(DEBUG_ERRORS) && ... */
|
|
|