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