1 /*
2 * Copyright 2008-2012 Freescale Semiconductor Inc.
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 /******************************************************************************
35 @File fm.c
36
37 @Description FM driver routines implementation.
38 *//***************************************************************************/
39 #include "std_ext.h"
40 #include "error_ext.h"
41 #include "xx_ext.h"
42 #include "string_ext.h"
43 #include "sprint_ext.h"
44 #include "debug_ext.h"
45 #include "fm_muram_ext.h"
46 #include <linux/math64.h>
47
48 #include "fm_common.h"
49 #include "fm_ipc.h"
50 #include "fm.h"
51 #include "fsl_fman.h"
52
53
54 /****************************************/
55 /* static functions */
56 /****************************************/
57
58 static volatile bool blockingFlag = FALSE;
IpcMsgCompletionCB(t_Handle h_Fm,uint8_t * p_Msg,uint8_t * p_Reply,uint32_t replyLength,t_Error status)59 static void IpcMsgCompletionCB(t_Handle h_Fm,
60 uint8_t *p_Msg,
61 uint8_t *p_Reply,
62 uint32_t replyLength,
63 t_Error status)
64 {
65 UNUSED(h_Fm);UNUSED(p_Msg);UNUSED(p_Reply);UNUSED(replyLength);UNUSED(status);
66 blockingFlag = FALSE;
67 }
68
FreeInitResources(t_Fm * p_Fm)69 static void FreeInitResources(t_Fm *p_Fm)
70 {
71 if (p_Fm->camBaseAddr)
72 FM_MURAM_FreeMem(p_Fm->h_FmMuram, UINT_TO_PTR(p_Fm->camBaseAddr));
73 if (p_Fm->fifoBaseAddr)
74 FM_MURAM_FreeMem(p_Fm->h_FmMuram, UINT_TO_PTR(p_Fm->fifoBaseAddr));
75 if (p_Fm->resAddr)
76 FM_MURAM_FreeMem(p_Fm->h_FmMuram, UINT_TO_PTR(p_Fm->resAddr));
77 }
78
IsFmanCtrlCodeLoaded(t_Fm * p_Fm)79 static bool IsFmanCtrlCodeLoaded(t_Fm *p_Fm)
80 {
81 t_FMIramRegs *p_Iram;
82
83 ASSERT_COND(p_Fm);
84 p_Iram = (t_FMIramRegs *)UINT_TO_PTR(p_Fm->baseAddr + FM_MM_IMEM);
85
86 return (bool)!!(GET_UINT32(p_Iram->iready) & IRAM_READY);
87 }
88
CheckFmParameters(t_Fm * p_Fm)89 static t_Error CheckFmParameters(t_Fm *p_Fm)
90 {
91 if (IsFmanCtrlCodeLoaded(p_Fm) && !p_Fm->resetOnInit)
92 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Old FMan CTRL code is loaded; FM must be reset!"));
93 #if (DPAA_VERSION < 11)
94 if (!p_Fm->p_FmDriverParam->dma_axi_dbg_num_of_beats ||
95 (p_Fm->p_FmDriverParam->dma_axi_dbg_num_of_beats > DMA_MODE_MAX_AXI_DBG_NUM_OF_BEATS))
96 RETURN_ERROR(MAJOR, E_INVALID_VALUE,
97 ("axiDbgNumOfBeats has to be in the range 1 - %d", DMA_MODE_MAX_AXI_DBG_NUM_OF_BEATS));
98 #endif /* (DPAA_VERSION < 11) */
99 if (p_Fm->p_FmDriverParam->dma_cam_num_of_entries % DMA_CAM_UNITS)
100 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dma_cam_num_of_entries has to be divisble by %d", DMA_CAM_UNITS));
101 // if (!p_Fm->p_FmDriverParam->dma_cam_num_of_entries || (p_Fm->p_FmDriverParam->dma_cam_num_of_entries > DMA_MODE_MAX_CAM_NUM_OF_ENTRIES))
102 // RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dma_cam_num_of_entries has to be in the range 1 - %d", DMA_MODE_MAX_CAM_NUM_OF_ENTRIES));
103 if (p_Fm->p_FmDriverParam->dma_comm_qtsh_asrt_emer > DMA_THRESH_MAX_COMMQ)
104 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dma_comm_qtsh_asrt_emer can not be larger than %d", DMA_THRESH_MAX_COMMQ));
105 if (p_Fm->p_FmDriverParam->dma_comm_qtsh_clr_emer > DMA_THRESH_MAX_COMMQ)
106 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dma_comm_qtsh_clr_emer can not be larger than %d", DMA_THRESH_MAX_COMMQ));
107 if (p_Fm->p_FmDriverParam->dma_comm_qtsh_clr_emer >= p_Fm->p_FmDriverParam->dma_comm_qtsh_asrt_emer)
108 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dma_comm_qtsh_clr_emer must be smaller than dma_comm_qtsh_asrt_emer"));
109 #if (DPAA_VERSION < 11)
110 if (p_Fm->p_FmDriverParam->dma_read_buf_tsh_asrt_emer > DMA_THRESH_MAX_BUF)
111 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dma_read_buf_tsh_asrt_emer can not be larger than %d", DMA_THRESH_MAX_BUF));
112 if (p_Fm->p_FmDriverParam->dma_read_buf_tsh_clr_emer > DMA_THRESH_MAX_BUF)
113 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dma_read_buf_tsh_clr_emer can not be larger than %d", DMA_THRESH_MAX_BUF));
114 if (p_Fm->p_FmDriverParam->dma_read_buf_tsh_clr_emer >= p_Fm->p_FmDriverParam->dma_read_buf_tsh_asrt_emer)
115 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dma_read_buf_tsh_clr_emer must be smaller than dma_read_buf_tsh_asrt_emer"));
116 if (p_Fm->p_FmDriverParam->dma_write_buf_tsh_asrt_emer > DMA_THRESH_MAX_BUF)
117 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dma_write_buf_tsh_asrt_emer can not be larger than %d", DMA_THRESH_MAX_BUF));
118 if (p_Fm->p_FmDriverParam->dma_write_buf_tsh_clr_emer > DMA_THRESH_MAX_BUF)
119 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dma_write_buf_tsh_clr_emer can not be larger than %d", DMA_THRESH_MAX_BUF));
120 if (p_Fm->p_FmDriverParam->dma_write_buf_tsh_clr_emer >= p_Fm->p_FmDriverParam->dma_write_buf_tsh_asrt_emer)
121 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dma_write_buf_tsh_clr_emer must be smaller than dma_write_buf_tsh_asrt_emer"));
122 #else /* (DPAA_VERSION >= 11) */
123 if ((p_Fm->p_FmDriverParam->dma_dbg_cnt_mode == E_FMAN_DMA_DBG_CNT_INT_READ_EM)||
124 (p_Fm->p_FmDriverParam->dma_dbg_cnt_mode == E_FMAN_DMA_DBG_CNT_INT_WRITE_EM) ||
125 (p_Fm->p_FmDriverParam->dma_dbg_cnt_mode == E_FMAN_DMA_DBG_CNT_RAW_WAR_PROT))
126 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dma_dbg_cnt_mode value not supported by this integration."));
127 if ((p_Fm->p_FmDriverParam->dma_emergency_bus_select == FM_DMA_MURAM_READ_EMERGENCY)||
128 (p_Fm->p_FmDriverParam->dma_emergency_bus_select == FM_DMA_MURAM_WRITE_EMERGENCY))
129 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("emergencyBusSelect value not supported by this integration."));
130 if (p_Fm->p_FmDriverParam->dma_stop_on_bus_error)
131 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dma_stop_on_bus_error not supported by this integration."));
132 #ifdef FM_AID_MODE_NO_TNUM_SW005
133 if (p_Fm->p_FmDriverParam->dma_aid_mode != E_FMAN_DMA_AID_OUT_PORT_ID)
134 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dma_aid_mode not supported by this integration."));
135 #endif /* FM_AID_MODE_NO_TNUM_SW005 */
136 if (p_Fm->p_FmDriverParam->dma_axi_dbg_num_of_beats)
137 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dma_axi_dbg_num_of_beats not supported by this integration."));
138 #endif /* (DPAA_VERSION < 11) */
139
140 if (!p_Fm->p_FmStateStruct->fmClkFreq)
141 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fmClkFreq must be set."));
142 if (USEC_TO_CLK(p_Fm->p_FmDriverParam->dma_watchdog, p_Fm->p_FmStateStruct->fmClkFreq) > DMA_MAX_WATCHDOG)
143 RETURN_ERROR(MAJOR, E_INVALID_VALUE,
144 ("dma_watchdog depends on FM clock. dma_watchdog(in microseconds) * clk (in Mhz), may not exceed 0x08x", DMA_MAX_WATCHDOG));
145
146 #if (DPAA_VERSION >= 11)
147 if ((p_Fm->partVSPBase + p_Fm->partNumOfVSPs) > FM_VSP_MAX_NUM_OF_ENTRIES)
148 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("partVSPBase+partNumOfVSPs out of range!!!"));
149 #endif /* (DPAA_VERSION >= 11) */
150
151 if (p_Fm->p_FmStateStruct->totalFifoSize % BMI_FIFO_UNITS)
152 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("totalFifoSize number has to be divisible by %d", BMI_FIFO_UNITS));
153 if (!p_Fm->p_FmStateStruct->totalFifoSize ||
154 (p_Fm->p_FmStateStruct->totalFifoSize > BMI_MAX_FIFO_SIZE))
155 RETURN_ERROR(MAJOR, E_INVALID_VALUE,
156 ("totalFifoSize (currently defined as %d) has to be in the range of 256 to %d",
157 p_Fm->p_FmStateStruct->totalFifoSize,
158 BMI_MAX_FIFO_SIZE));
159 if (!p_Fm->p_FmStateStruct->totalNumOfTasks ||
160 (p_Fm->p_FmStateStruct->totalNumOfTasks > BMI_MAX_NUM_OF_TASKS))
161 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("totalNumOfTasks number has to be in the range 1 - %d", BMI_MAX_NUM_OF_TASKS));
162
163 #ifdef FM_HAS_TOTAL_DMAS
164 if (!p_Fm->p_FmStateStruct->maxNumOfOpenDmas ||
165 (p_Fm->p_FmStateStruct->maxNumOfOpenDmas > BMI_MAX_NUM_OF_DMAS))
166 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("maxNumOfOpenDmas number has to be in the range 1 - %d", BMI_MAX_NUM_OF_DMAS));
167 #endif /* FM_HAS_TOTAL_DMAS */
168
169 if (p_Fm->p_FmDriverParam->disp_limit_tsh > FPM_MAX_DISP_LIMIT)
170 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("disp_limit_tsh can't be greater than %d", FPM_MAX_DISP_LIMIT));
171
172 if (!p_Fm->f_Exception)
173 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Exceptions callback not provided"));
174 if (!p_Fm->f_BusError)
175 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Exceptions callback not provided"));
176
177 #ifdef FM_NO_WATCHDOG
178 if ((p_Fm->p_FmStateStruct->revInfo.majorRev == 2) &&
179 (p_Fm->p_FmDriverParam->dma_watchdog))
180 RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("watchdog!"));
181 #endif /* FM_NO_WATCHDOG */
182
183 #ifdef FM_ECC_HALT_NO_SYNC_ERRATA_10GMAC_A008
184 if ((p_Fm->p_FmStateStruct->revInfo.majorRev < 6) &&
185 (p_Fm->p_FmDriverParam->halt_on_unrecov_ecc_err))
186 RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("HaltOnEccError!"));
187 #endif /* FM_ECC_HALT_NO_SYNC_ERRATA_10GMAC_A008 */
188
189 #ifdef FM_NO_TNUM_AGING
190 if ((p_Fm->p_FmStateStruct->revInfo.majorRev != 4) &&
191 (p_Fm->p_FmStateStruct->revInfo.majorRev < 6))
192 if (p_Fm->p_FmDriverParam->tnum_aging_period)
193 RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("Tnum aging!"));
194 #endif /* FM_NO_TNUM_AGING */
195
196 /* check that user did not set revision-dependent exceptions */
197 #ifdef FM_NO_DISPATCH_RAM_ECC
198 if ((p_Fm->p_FmStateStruct->revInfo.majorRev != 4) &&
199 (p_Fm->p_FmStateStruct->revInfo.majorRev < 6))
200 if (p_Fm->userSetExceptions & FM_EX_BMI_DISPATCH_RAM_ECC)
201 RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("exception e_FM_EX_BMI_DISPATCH_RAM_ECC!"));
202 #endif /* FM_NO_DISPATCH_RAM_ECC */
203
204 #ifdef FM_QMI_NO_ECC_EXCEPTIONS
205 if (p_Fm->p_FmStateStruct->revInfo.majorRev == 4)
206 if (p_Fm->userSetExceptions & (FM_EX_QMI_SINGLE_ECC | FM_EX_QMI_DOUBLE_ECC))
207 RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("exception e_FM_EX_QMI_SINGLE_ECC/e_FM_EX_QMI_DOUBLE_ECC!"));
208 #endif /* FM_QMI_NO_ECC_EXCEPTIONS */
209
210 #ifdef FM_QMI_NO_SINGLE_ECC_EXCEPTION
211 if (p_Fm->p_FmStateStruct->revInfo.majorRev >= 6)
212 if (p_Fm->userSetExceptions & FM_EX_QMI_SINGLE_ECC)
213 RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("exception e_FM_EX_QMI_SINGLE_ECC!"));
214 #endif /* FM_QMI_NO_SINGLE_ECC_EXCEPTION */
215
216 return E_OK;
217 }
218
219
SendIpcIsr(t_Fm * p_Fm,uint32_t macEvent,uint32_t pendingReg)220 static void SendIpcIsr(t_Fm *p_Fm, uint32_t macEvent, uint32_t pendingReg)
221 {
222 ASSERT_COND(p_Fm->guestId == NCSW_MASTER_ID);
223
224 if (p_Fm->intrMng[macEvent].guestId == NCSW_MASTER_ID)
225 p_Fm->intrMng[macEvent].f_Isr(p_Fm->intrMng[macEvent].h_SrcHandle);
226
227 /* If the MAC is running on guest-partition and we have IPC session with it,
228 we inform him about the event through IPC; otherwise, we ignore the event. */
229 else if (p_Fm->h_IpcSessions[p_Fm->intrMng[macEvent].guestId])
230 {
231 t_Error err;
232 t_FmIpcIsr fmIpcIsr;
233 t_FmIpcMsg msg;
234
235 memset(&msg, 0, sizeof(msg));
236 msg.msgId = FM_GUEST_ISR;
237 fmIpcIsr.pendingReg = pendingReg;
238 fmIpcIsr.boolErr = FALSE;
239 memcpy(msg.msgBody, &fmIpcIsr, sizeof(fmIpcIsr));
240 err = XX_IpcSendMessage(p_Fm->h_IpcSessions[p_Fm->intrMng[macEvent].guestId],
241 (uint8_t*)&msg,
242 sizeof(msg.msgId) + sizeof(fmIpcIsr),
243 NULL,
244 NULL,
245 NULL,
246 NULL);
247 if (err != E_OK)
248 REPORT_ERROR(MINOR, err, NO_MSG);
249 }
250 else
251 DBG(TRACE, ("FM Guest mode, without IPC - can't call ISR!"));
252 }
253
BmiErrEvent(t_Fm * p_Fm)254 static void BmiErrEvent(t_Fm *p_Fm)
255 {
256 uint32_t event;
257 struct fman_bmi_regs *bmi_rg = p_Fm->p_FmBmiRegs;
258
259
260 event = fman_get_bmi_err_event(bmi_rg);
261
262 if (event & BMI_ERR_INTR_EN_STORAGE_PROFILE_ECC)
263 p_Fm->f_Exception(p_Fm->h_App,e_FM_EX_BMI_STORAGE_PROFILE_ECC);
264 if (event & BMI_ERR_INTR_EN_LIST_RAM_ECC)
265 p_Fm->f_Exception(p_Fm->h_App,e_FM_EX_BMI_LIST_RAM_ECC);
266 if (event & BMI_ERR_INTR_EN_STATISTICS_RAM_ECC)
267 p_Fm->f_Exception(p_Fm->h_App,e_FM_EX_BMI_STATISTICS_RAM_ECC);
268 if (event & BMI_ERR_INTR_EN_DISPATCH_RAM_ECC)
269 p_Fm->f_Exception(p_Fm->h_App,e_FM_EX_BMI_DISPATCH_RAM_ECC);
270 }
271
QmiErrEvent(t_Fm * p_Fm)272 static void QmiErrEvent(t_Fm *p_Fm)
273 {
274 uint32_t event;
275 struct fman_qmi_regs *qmi_rg = p_Fm->p_FmQmiRegs;
276
277 event = fman_get_qmi_err_event(qmi_rg);
278
279 if (event & QMI_ERR_INTR_EN_DOUBLE_ECC)
280 p_Fm->f_Exception(p_Fm->h_App,e_FM_EX_QMI_DOUBLE_ECC);
281 if (event & QMI_ERR_INTR_EN_DEQ_FROM_DEF)
282 p_Fm->f_Exception(p_Fm->h_App,e_FM_EX_QMI_DEQ_FROM_UNKNOWN_PORTID);
283 }
284
DmaErrEvent(t_Fm * p_Fm)285 static void DmaErrEvent(t_Fm *p_Fm)
286 {
287 uint32_t status, com_id;
288 uint8_t tnum;
289 uint8_t hardwarePortId;
290 uint8_t relativePortId;
291 uint16_t liodn;
292 struct fman_dma_regs *dma_rg = p_Fm->p_FmDmaRegs;
293
294 status = fman_get_dma_err_event(dma_rg);
295
296 if (status & DMA_STATUS_BUS_ERR)
297 {
298 com_id = fman_get_dma_com_id(dma_rg);
299 hardwarePortId = (uint8_t)(((com_id & DMA_TRANSFER_PORTID_MASK) >> DMA_TRANSFER_PORTID_SHIFT));
300 ASSERT_COND(IN_RANGE(1, hardwarePortId, 63));
301 HW_PORT_ID_TO_SW_PORT_ID(relativePortId, hardwarePortId);
302 tnum = (uint8_t)((com_id & DMA_TRANSFER_TNUM_MASK) >> DMA_TRANSFER_TNUM_SHIFT);
303 liodn = (uint16_t)(com_id & DMA_TRANSFER_LIODN_MASK);
304 ASSERT_COND(p_Fm->p_FmStateStruct->portsTypes[hardwarePortId] != e_FM_PORT_TYPE_DUMMY);
305 p_Fm->f_BusError(p_Fm->h_App,
306 p_Fm->p_FmStateStruct->portsTypes[hardwarePortId],
307 relativePortId,
308 fman_get_dma_addr(dma_rg),
309 tnum,
310 liodn);
311 }
312 if (status & DMA_STATUS_FM_SPDAT_ECC)
313 p_Fm->f_Exception(p_Fm->h_App, e_FM_EX_DMA_SINGLE_PORT_ECC);
314 if (status & DMA_STATUS_READ_ECC)
315 p_Fm->f_Exception(p_Fm->h_App, e_FM_EX_DMA_READ_ECC);
316 if (status & DMA_STATUS_SYSTEM_WRITE_ECC)
317 p_Fm->f_Exception(p_Fm->h_App, e_FM_EX_DMA_SYSTEM_WRITE_ECC);
318 if (status & DMA_STATUS_FM_WRITE_ECC)
319 p_Fm->f_Exception(p_Fm->h_App, e_FM_EX_DMA_FM_WRITE_ECC);
320 }
321
FpmErrEvent(t_Fm * p_Fm)322 static void FpmErrEvent(t_Fm *p_Fm)
323 {
324 uint32_t event;
325 struct fman_fpm_regs *fpm_rg = p_Fm->p_FmFpmRegs;
326
327 event = fman_get_fpm_err_event(fpm_rg);
328
329 if ((event & FPM_EV_MASK_DOUBLE_ECC) && (event & FPM_EV_MASK_DOUBLE_ECC_EN))
330 p_Fm->f_Exception(p_Fm->h_App,e_FM_EX_FPM_DOUBLE_ECC);
331 if ((event & FPM_EV_MASK_STALL) && (event & FPM_EV_MASK_STALL_EN))
332 p_Fm->f_Exception(p_Fm->h_App,e_FM_EX_FPM_STALL_ON_TASKS);
333 if ((event & FPM_EV_MASK_SINGLE_ECC) && (event & FPM_EV_MASK_SINGLE_ECC_EN))
334 p_Fm->f_Exception(p_Fm->h_App,e_FM_EX_FPM_SINGLE_ECC);
335 }
336
MuramErrIntr(t_Fm * p_Fm)337 static void MuramErrIntr(t_Fm *p_Fm)
338 {
339 uint32_t event;
340 struct fman_fpm_regs *fpm_rg = p_Fm->p_FmFpmRegs;
341
342 event = fman_get_muram_err_event(fpm_rg);
343
344 if (event & FPM_RAM_MURAM_ECC)
345 p_Fm->f_Exception(p_Fm->h_App, e_FM_EX_MURAM_ECC);
346 }
347
IramErrIntr(t_Fm * p_Fm)348 static void IramErrIntr(t_Fm *p_Fm)
349 {
350 uint32_t event;
351 struct fman_fpm_regs *fpm_rg = p_Fm->p_FmFpmRegs;
352
353 event = fman_get_iram_err_event(fpm_rg);
354
355 if (event & FPM_RAM_IRAM_ECC)
356 p_Fm->f_Exception(p_Fm->h_App, e_FM_EX_IRAM_ECC);
357 }
358
QmiEvent(t_Fm * p_Fm)359 static void QmiEvent(t_Fm *p_Fm)
360 {
361 uint32_t event;
362 struct fman_qmi_regs *qmi_rg = p_Fm->p_FmQmiRegs;
363
364 event = fman_get_qmi_event(qmi_rg);
365
366 if (event & QMI_INTR_EN_SINGLE_ECC)
367 p_Fm->f_Exception(p_Fm->h_App,e_FM_EX_QMI_SINGLE_ECC);
368 }
369
UnimplementedIsr(t_Handle h_Arg)370 static void UnimplementedIsr(t_Handle h_Arg)
371 {
372 UNUSED(h_Arg);
373
374 REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Unimplemented ISR!"));
375 }
376
UnimplementedFmanCtrlIsr(t_Handle h_Arg,uint32_t event)377 static void UnimplementedFmanCtrlIsr(t_Handle h_Arg, uint32_t event)
378 {
379 UNUSED(h_Arg); UNUSED(event);
380
381 REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Unimplemented FmCtl ISR!"));
382 }
383
EnableTimeStamp(t_Fm * p_Fm)384 static void EnableTimeStamp(t_Fm *p_Fm)
385 {
386 struct fman_fpm_regs *fpm_rg = p_Fm->p_FmFpmRegs;
387
388 ASSERT_COND(p_Fm->p_FmStateStruct);
389 ASSERT_COND(p_Fm->p_FmStateStruct->count1MicroBit);
390
391 fman_enable_time_stamp(fpm_rg, p_Fm->p_FmStateStruct->count1MicroBit, p_Fm->p_FmStateStruct->fmClkFreq);
392
393 p_Fm->p_FmStateStruct->enabledTimeStamp = TRUE;
394 }
395
ClearIRam(t_Fm * p_Fm)396 static t_Error ClearIRam(t_Fm *p_Fm)
397 {
398 t_FMIramRegs *p_Iram;
399 int i;
400 int iram_size;
401
402 ASSERT_COND(p_Fm);
403 p_Iram = (t_FMIramRegs *)UINT_TO_PTR(p_Fm->baseAddr + FM_MM_IMEM);
404 iram_size = FM_IRAM_SIZE(p_Fm->p_FmStateStruct->revInfo.majorRev,p_Fm->p_FmStateStruct->revInfo.minorRev);
405
406 /* Enable the auto-increment */
407 WRITE_UINT32(p_Iram->iadd, IRAM_IADD_AIE);
408 while (GET_UINT32(p_Iram->iadd) != IRAM_IADD_AIE) ;
409
410 for (i=0; i < (iram_size/4); i++)
411 WRITE_UINT32(p_Iram->idata, 0xffffffff);
412
413 WRITE_UINT32(p_Iram->iadd, iram_size - 4);
414 CORE_MemoryBarrier();
415 while (GET_UINT32(p_Iram->idata) != 0xffffffff) ;
416
417 return E_OK;
418 }
419
LoadFmanCtrlCode(t_Fm * p_Fm)420 static t_Error LoadFmanCtrlCode(t_Fm *p_Fm)
421 {
422 t_FMIramRegs *p_Iram;
423 int i;
424 uint32_t tmp;
425 uint8_t compTo16;
426
427 ASSERT_COND(p_Fm);
428 p_Iram = (t_FMIramRegs *)UINT_TO_PTR(p_Fm->baseAddr + FM_MM_IMEM);
429
430 /* Enable the auto-increment */
431 WRITE_UINT32(p_Iram->iadd, IRAM_IADD_AIE);
432 while (GET_UINT32(p_Iram->iadd) != IRAM_IADD_AIE) ;
433
434 for (i=0; i < (p_Fm->firmware.size / 4); i++)
435 WRITE_UINT32(p_Iram->idata, p_Fm->firmware.p_Code[i]);
436
437 compTo16 = (uint8_t)(p_Fm->firmware.size % 16);
438 if (compTo16)
439 for (i=0; i < ((16-compTo16) / 4); i++)
440 WRITE_UINT32(p_Iram->idata, 0xffffffff);
441
442 WRITE_UINT32(p_Iram->iadd,p_Fm->firmware.size-4);
443 while (GET_UINT32(p_Iram->iadd) != (p_Fm->firmware.size-4)) ;
444
445 /* verify that writing has completed */
446 while (GET_UINT32(p_Iram->idata) != p_Fm->firmware.p_Code[(p_Fm->firmware.size / 4)-1]) ;
447
448 if (p_Fm->fwVerify)
449 {
450 WRITE_UINT32(p_Iram->iadd, IRAM_IADD_AIE);
451 while (GET_UINT32(p_Iram->iadd) != IRAM_IADD_AIE) ;
452 for (i=0; i < (p_Fm->firmware.size / 4); i++)
453 {
454 tmp = GET_UINT32(p_Iram->idata);
455 if (tmp != p_Fm->firmware.p_Code[i])
456 RETURN_ERROR(MAJOR, E_WRITE_FAILED,
457 ("UCode write error : write 0x%x, read 0x%x",
458 p_Fm->firmware.p_Code[i],tmp));
459 }
460 WRITE_UINT32(p_Iram->iadd, 0x0);
461 }
462
463 /* Enable patch from IRAM */
464 WRITE_UINT32(p_Iram->iready, IRAM_READY);
465 XX_UDelay(1000);
466
467 DBG(INFO, ("FMan-Controller code (ver %d.%d.%d) loaded to IRAM.",
468 ((uint16_t *)p_Fm->firmware.p_Code)[2],
469 ((uint8_t *)p_Fm->firmware.p_Code)[6],
470 ((uint8_t *)p_Fm->firmware.p_Code)[7]));
471
472 return E_OK;
473 }
474
475 #ifdef FM_UCODE_NOT_RESET_ERRATA_BUGZILLA6173
FwNotResetErratumBugzilla6173WA(t_Fm * p_Fm)476 static t_Error FwNotResetErratumBugzilla6173WA(t_Fm *p_Fm)
477 {
478 t_FMIramRegs *p_Iram = (t_FMIramRegs *)UINT_TO_PTR(p_Fm->baseAddr + FM_MM_IMEM);
479 uint32_t tmpReg;
480 uint32_t savedSpliodn[63];
481
482 /* write to IRAM first location the debug instruction */
483 WRITE_UINT32(p_Iram->iadd, 0);
484 while (GET_UINT32(p_Iram->iadd) != 0) ;
485 WRITE_UINT32(p_Iram->idata, FM_FW_DEBUG_INSTRUCTION);
486
487 WRITE_UINT32(p_Iram->iadd, 0);
488 while (GET_UINT32(p_Iram->iadd) != 0) ;
489 while (GET_UINT32(p_Iram->idata) != FM_FW_DEBUG_INSTRUCTION) ;
490
491 /* Enable patch from IRAM */
492 WRITE_UINT32(p_Iram->iready, IRAM_READY);
493 CORE_MemoryBarrier();
494 XX_UDelay(100);
495 IO2MemCpy32((uint8_t *)savedSpliodn,
496 (uint8_t *)p_Fm->p_FmBmiRegs->fmbm_spliodn,
497 63*sizeof(uint32_t));
498
499 /* reset FMAN */
500 WRITE_UINT32(p_Fm->p_FmFpmRegs->fm_rstc, FPM_RSTC_FM_RESET);
501 CORE_MemoryBarrier();
502 XX_UDelay(100);
503
504 /* verify breakpoint debug status register */
505 tmpReg = GET_UINT32(*(uint32_t *)UINT_TO_PTR(p_Fm->baseAddr + FM_DEBUG_STATUS_REGISTER_OFFSET));
506 if (!tmpReg)
507 REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Invalid debug status register value is '0'"));
508
509 /*************************************/
510 /* Load FMan-Controller code to IRAM */
511 /*************************************/
512 ClearIRam(p_Fm);
513 if (p_Fm->firmware.p_Code &&
514 (LoadFmanCtrlCode(p_Fm) != E_OK))
515 RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
516 XX_UDelay(100);
517
518 /* reset FMAN again to start the microcode */
519 WRITE_UINT32(p_Fm->p_FmFpmRegs->fm_rstc, FPM_RSTC_FM_RESET);
520 CORE_MemoryBarrier();
521 XX_UDelay(100);
522 Mem2IOCpy32((uint8_t *)p_Fm->p_FmBmiRegs->fmbm_spliodn,
523 (uint8_t *)savedSpliodn,
524 63*sizeof(uint32_t));
525
526 if (fman_is_qmi_halt_not_busy_state(p_Fm->p_FmQmiRegs))
527 {
528 fman_resume(p_Fm->p_FmFpmRegs);
529 CORE_MemoryBarrier();
530 XX_UDelay(100);
531 }
532
533 return E_OK;
534 }
535 #endif /* FM_UCODE_NOT_RESET_ERRATA_BUGZILLA6173 */
536
GuestErrorIsr(t_Fm * p_Fm,uint32_t pending)537 static void GuestErrorIsr(t_Fm *p_Fm, uint32_t pending)
538 {
539 #define FM_G_CALL_1G_MAC_ERR_ISR(_id) \
540 do { \
541 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);\
542 } while (0)
543 #define FM_G_CALL_10G_MAC_ERR_ISR(_id) \
544 do { \
545 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);\
546 } while (0)
547
548 /* error interrupts */
549 if (pending & ERR_INTR_EN_1G_MAC0)
550 FM_G_CALL_1G_MAC_ERR_ISR(0);
551 if (pending & ERR_INTR_EN_1G_MAC1)
552 FM_G_CALL_1G_MAC_ERR_ISR(1);
553 if (pending & ERR_INTR_EN_1G_MAC2)
554 FM_G_CALL_1G_MAC_ERR_ISR(2);
555 if (pending & ERR_INTR_EN_1G_MAC3)
556 FM_G_CALL_1G_MAC_ERR_ISR(3);
557 if (pending & ERR_INTR_EN_1G_MAC4)
558 FM_G_CALL_1G_MAC_ERR_ISR(4);
559 if (pending & ERR_INTR_EN_1G_MAC5)
560 FM_G_CALL_1G_MAC_ERR_ISR(5);
561 if (pending & ERR_INTR_EN_1G_MAC6)
562 FM_G_CALL_1G_MAC_ERR_ISR(6);
563 if (pending & ERR_INTR_EN_1G_MAC7)
564 FM_G_CALL_1G_MAC_ERR_ISR(7);
565 if (pending & ERR_INTR_EN_10G_MAC0)
566 FM_G_CALL_10G_MAC_ERR_ISR(0);
567 if (pending & ERR_INTR_EN_10G_MAC1)
568 FM_G_CALL_10G_MAC_ERR_ISR(1);
569 }
570
GuestEventIsr(t_Fm * p_Fm,uint32_t pending)571 static void GuestEventIsr(t_Fm *p_Fm, uint32_t pending)
572 {
573 #define FM_G_CALL_1G_MAC_ISR(_id) \
574 do { \
575 p_Fm->intrMng[(e_FmInterModuleEvent)(e_FM_EV_1G_MAC0+_id)].f_Isr(p_Fm->intrMng[(e_FmInterModuleEvent)(e_FM_EV_1G_MAC0+_id)].h_SrcHandle);\
576 } while (0)
577 #define FM_G_CALL_10G_MAC_ISR(_id) \
578 do { \
579 p_Fm->intrMng[(e_FmInterModuleEvent)(e_FM_EV_10G_MAC0+_id)].f_Isr(p_Fm->intrMng[(e_FmInterModuleEvent)(e_FM_EV_10G_MAC0+_id)].h_SrcHandle);\
580 } while (0)
581
582 if (pending & INTR_EN_1G_MAC0)
583 FM_G_CALL_1G_MAC_ISR(0);
584 if (pending & INTR_EN_1G_MAC1)
585 FM_G_CALL_1G_MAC_ISR(1);
586 if (pending & INTR_EN_1G_MAC2)
587 FM_G_CALL_1G_MAC_ISR(2);
588 if (pending & INTR_EN_1G_MAC3)
589 FM_G_CALL_1G_MAC_ISR(3);
590 if (pending & INTR_EN_1G_MAC4)
591 FM_G_CALL_1G_MAC_ISR(4);
592 if (pending & INTR_EN_1G_MAC5)
593 FM_G_CALL_1G_MAC_ISR(5);
594 if (pending & INTR_EN_1G_MAC6)
595 FM_G_CALL_1G_MAC_ISR(6);
596 if (pending & INTR_EN_1G_MAC7)
597 FM_G_CALL_1G_MAC_ISR(7);
598 if (pending & INTR_EN_10G_MAC0)
599 FM_G_CALL_10G_MAC_ISR(0);
600 if (pending & INTR_EN_10G_MAC1)
601 FM_G_CALL_10G_MAC_ISR(1);
602 if (pending & INTR_EN_TMR)
603 p_Fm->intrMng[e_FM_EV_TMR].f_Isr(p_Fm->intrMng[e_FM_EV_TMR].h_SrcHandle);
604 }
605
606 #if (DPAA_VERSION >= 11)
SetVSPWindow(t_Handle h_Fm,uint8_t hardwarePortId,uint8_t baseStorageProfile,uint8_t log2NumOfProfiles)607 static t_Error SetVSPWindow(t_Handle h_Fm,
608 uint8_t hardwarePortId,
609 uint8_t baseStorageProfile,
610 uint8_t log2NumOfProfiles)
611 {
612 t_Fm *p_Fm = (t_Fm *)h_Fm;
613
614 ASSERT_COND(h_Fm);
615 ASSERT_COND(IN_RANGE(1, hardwarePortId, 63));
616
617 if ((p_Fm->guestId != NCSW_MASTER_ID) &&
618 !p_Fm->p_FmBmiRegs &&
619 p_Fm->h_IpcSessions[0])
620 {
621 t_FmIpcVspSetPortWindow fmIpcVspSetPortWindow;
622 t_FmIpcMsg msg;
623 t_Error err = E_OK;
624
625 memset(&msg, 0, sizeof(msg));
626 memset(&fmIpcVspSetPortWindow, 0, sizeof(t_FmIpcVspSetPortWindow));
627 fmIpcVspSetPortWindow.hardwarePortId = hardwarePortId;
628 fmIpcVspSetPortWindow.baseStorageProfile = baseStorageProfile;
629 fmIpcVspSetPortWindow.log2NumOfProfiles = log2NumOfProfiles;
630 msg.msgId = FM_VSP_SET_PORT_WINDOW;
631 memcpy(msg.msgBody, &fmIpcVspSetPortWindow, sizeof(t_FmIpcVspSetPortWindow));
632
633 err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
634 (uint8_t*)&msg,
635 sizeof(msg.msgId),
636 NULL,
637 NULL,
638 NULL,
639 NULL);
640 if (err != E_OK)
641 RETURN_ERROR(MINOR, err, NO_MSG);
642 return E_OK;
643 }
644 else if (!p_Fm->p_FmBmiRegs)
645 RETURN_ERROR(MINOR, E_NOT_SUPPORTED,
646 ("Either IPC or 'baseAddress' is required!"));
647
648 fman_set_vsp_window(p_Fm->p_FmBmiRegs,
649 hardwarePortId,
650 baseStorageProfile,
651 log2NumOfProfiles);
652
653 return E_OK;
654 }
655
AllocVSPsForPartition(t_Handle h_Fm,uint8_t base,uint8_t numOfProfiles,uint8_t guestId)656 static uint8_t AllocVSPsForPartition(t_Handle h_Fm, uint8_t base, uint8_t numOfProfiles, uint8_t guestId)
657 {
658 t_Fm *p_Fm = (t_Fm *)h_Fm;
659 uint8_t profilesFound = 0;
660 int i = 0;
661 uint32_t intFlags;
662
663 if (!numOfProfiles)
664 return E_OK;
665
666 if ((numOfProfiles > FM_VSP_MAX_NUM_OF_ENTRIES) ||
667 (base + numOfProfiles > FM_VSP_MAX_NUM_OF_ENTRIES))
668 return (uint8_t)ILLEGAL_BASE;
669
670 if (p_Fm->h_IpcSessions[0])
671 {
672 t_FmIpcResourceAllocParams ipcAllocParams;
673 t_FmIpcMsg msg;
674 t_FmIpcReply reply;
675 t_Error err;
676 uint32_t replyLength;
677
678 memset(&msg, 0, sizeof(msg));
679 memset(&reply, 0, sizeof(reply));
680 memset(&ipcAllocParams, 0, sizeof(t_FmIpcResourceAllocParams));
681 ipcAllocParams.guestId = p_Fm->guestId;
682 ipcAllocParams.num = p_Fm->partNumOfVSPs;
683 ipcAllocParams.base = p_Fm->partVSPBase;
684 msg.msgId = FM_VSP_ALLOC;
685 memcpy(msg.msgBody, &ipcAllocParams, sizeof(t_FmIpcResourceAllocParams));
686 replyLength = sizeof(uint32_t) + sizeof(uint8_t);
687 err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
688 (uint8_t*)&msg,
689 sizeof(msg.msgId) + sizeof(t_FmIpcResourceAllocParams),
690 (uint8_t*)&reply,
691 &replyLength,
692 NULL,
693 NULL);
694 if ((err != E_OK) ||
695 (replyLength != (sizeof(uint32_t) + sizeof(uint8_t))))
696 RETURN_ERROR(MAJOR, err, NO_MSG);
697 else
698 memcpy((uint8_t*)&p_Fm->partVSPBase, reply.replyBody, sizeof(uint8_t));
699 if (p_Fm->partVSPBase == (uint8_t)(ILLEGAL_BASE))
700 RETURN_ERROR(MAJOR, err, NO_MSG);
701 }
702 if (p_Fm->guestId != NCSW_MASTER_ID)
703 {
704 DBG(WARNING, ("FM Guest mode, without IPC - can't validate VSP range!"));
705 return (uint8_t)ILLEGAL_BASE;
706 }
707
708 intFlags = XX_LockIntrSpinlock(p_Fm->h_Spinlock);
709 for (i = base; i < base + numOfProfiles; i++)
710 if (p_Fm->p_FmSp->profiles[i].profilesMng.ownerId == (uint8_t)ILLEGAL_BASE)
711 profilesFound++;
712 else
713 break;
714
715 if (profilesFound == numOfProfiles)
716 for (i = base; i<base + numOfProfiles; i++)
717 p_Fm->p_FmSp->profiles[i].profilesMng.ownerId = guestId;
718 else
719 {
720 XX_UnlockIntrSpinlock(p_Fm->h_Spinlock, intFlags);
721 return (uint8_t)ILLEGAL_BASE;
722 }
723 XX_UnlockIntrSpinlock(p_Fm->h_Spinlock, intFlags);
724
725 return base;
726 }
727
FreeVSPsForPartition(t_Handle h_Fm,uint8_t base,uint8_t numOfProfiles,uint8_t guestId)728 static void FreeVSPsForPartition(t_Handle h_Fm, uint8_t base, uint8_t numOfProfiles, uint8_t guestId)
729 {
730 t_Fm *p_Fm = (t_Fm *)h_Fm;
731 int i = 0;
732
733 ASSERT_COND(p_Fm);
734
735 if (p_Fm->h_IpcSessions[0])
736 {
737 t_FmIpcResourceAllocParams ipcAllocParams;
738 t_FmIpcMsg msg;
739 t_FmIpcReply reply;
740 uint32_t replyLength;
741 t_Error err;
742
743 memset(&msg, 0, sizeof(msg));
744 memset(&reply, 0, sizeof(reply));
745 memset(&ipcAllocParams, 0, sizeof(t_FmIpcResourceAllocParams));
746 ipcAllocParams.guestId = p_Fm->guestId;
747 ipcAllocParams.num = p_Fm->partNumOfVSPs;
748 ipcAllocParams.base = p_Fm->partVSPBase;
749 msg.msgId = FM_VSP_FREE;
750 memcpy(msg.msgBody, &ipcAllocParams, sizeof(t_FmIpcResourceAllocParams));
751 replyLength = sizeof(uint32_t) + sizeof(uint8_t);
752 err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
753 (uint8_t*)&msg,
754 sizeof(msg.msgId) + sizeof(t_FmIpcResourceAllocParams),
755 (uint8_t*)&reply,
756 &replyLength,
757 NULL,
758 NULL);
759 if (err != E_OK)
760 REPORT_ERROR(MAJOR, err, NO_MSG);
761 return;
762 }
763 if (p_Fm->guestId != NCSW_MASTER_ID)
764 {
765 DBG(WARNING, ("FM Guest mode, without IPC - can't validate VSP range!"));
766 return;
767 }
768
769 ASSERT_COND(p_Fm->p_FmSp);
770
771 for (i=base; i<numOfProfiles; i++)
772 {
773 if (p_Fm->p_FmSp->profiles[i].profilesMng.ownerId == guestId)
774 p_Fm->p_FmSp->profiles[i].profilesMng.ownerId = (uint8_t)ILLEGAL_BASE;
775 else
776 DBG(WARNING, ("Request for freeing storage profile window which wasn't allocated to this partition"));
777 }
778 }
779 #endif /* (DPAA_VERSION >= 11) */
780
FmGuestHandleIpcMsgCB(t_Handle h_Fm,uint8_t * p_Msg,uint32_t msgLength,uint8_t * p_Reply,uint32_t * p_ReplyLength)781 static t_Error FmGuestHandleIpcMsgCB(t_Handle h_Fm,
782 uint8_t *p_Msg,
783 uint32_t msgLength,
784 uint8_t *p_Reply,
785 uint32_t *p_ReplyLength)
786 {
787 t_Fm *p_Fm = (t_Fm*)h_Fm;
788 t_FmIpcMsg *p_IpcMsg = (t_FmIpcMsg*)p_Msg;
789
790 UNUSED(p_Reply);
791 SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
792 SANITY_CHECK_RETURN_ERROR((msgLength > sizeof(uint32_t)), E_INVALID_VALUE);
793
794 #ifdef DISABLE_SANITY_CHECKS
795 UNUSED(msgLength);
796 #endif /* DISABLE_SANITY_CHECKS */
797
798 ASSERT_COND(p_Msg);
799
800 *p_ReplyLength = 0;
801
802 switch (p_IpcMsg->msgId)
803 {
804 case (FM_GUEST_ISR):
805 {
806 t_FmIpcIsr ipcIsr;
807
808 memcpy((uint8_t*)&ipcIsr, p_IpcMsg->msgBody, sizeof(t_FmIpcIsr));
809 if (ipcIsr.boolErr)
810 GuestErrorIsr(p_Fm, ipcIsr.pendingReg);
811 else
812 GuestEventIsr(p_Fm, ipcIsr.pendingReg);
813 break;
814 }
815 default:
816 *p_ReplyLength = 0;
817 RETURN_ERROR(MINOR, E_INVALID_SELECTION, ("command not found!!!"));
818 }
819 return E_OK;
820 }
821
FmHandleIpcMsgCB(t_Handle h_Fm,uint8_t * p_Msg,uint32_t msgLength,uint8_t * p_Reply,uint32_t * p_ReplyLength)822 static t_Error FmHandleIpcMsgCB(t_Handle h_Fm,
823 uint8_t *p_Msg,
824 uint32_t msgLength,
825 uint8_t *p_Reply,
826 uint32_t *p_ReplyLength)
827 {
828 t_Error err;
829 t_Fm *p_Fm = (t_Fm*)h_Fm;
830 t_FmIpcMsg *p_IpcMsg = (t_FmIpcMsg*)p_Msg;
831 t_FmIpcReply *p_IpcReply = (t_FmIpcReply*)p_Reply;
832
833 SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
834 SANITY_CHECK_RETURN_ERROR((msgLength >= sizeof(uint32_t)), E_INVALID_VALUE);
835
836 #ifdef DISABLE_SANITY_CHECKS
837 UNUSED(msgLength);
838 #endif /* DISABLE_SANITY_CHECKS */
839
840 ASSERT_COND(p_IpcMsg);
841
842 memset(p_IpcReply, 0, (sizeof(uint8_t) * FM_IPC_MAX_REPLY_SIZE));
843 *p_ReplyLength = 0;
844
845 switch (p_IpcMsg->msgId)
846 {
847 case (FM_GET_SET_PORT_PARAMS):
848 {
849 t_FmIpcPortInInitParams ipcInitParams;
850 t_FmInterModulePortInitParams initParams;
851 t_FmIpcPortOutInitParams ipcOutInitParams;
852
853 memcpy((uint8_t*)&ipcInitParams, p_IpcMsg->msgBody, sizeof(t_FmIpcPortInInitParams));
854 initParams.hardwarePortId = ipcInitParams.hardwarePortId;
855 initParams.portType = (e_FmPortType)ipcInitParams.enumPortType;
856 initParams.independentMode = (bool)(ipcInitParams.boolIndependentMode);
857 initParams.liodnOffset = ipcInitParams.liodnOffset;
858 initParams.numOfTasks = ipcInitParams.numOfTasks;
859 initParams.numOfExtraTasks = ipcInitParams.numOfExtraTasks;
860 initParams.numOfOpenDmas = ipcInitParams.numOfOpenDmas;
861 initParams.numOfExtraOpenDmas = ipcInitParams.numOfExtraOpenDmas;
862 initParams.sizeOfFifo = ipcInitParams.sizeOfFifo;
863 initParams.extraSizeOfFifo = ipcInitParams.extraSizeOfFifo;
864 initParams.deqPipelineDepth = ipcInitParams.deqPipelineDepth;
865 initParams.maxFrameLength = ipcInitParams.maxFrameLength;
866 initParams.liodnBase = ipcInitParams.liodnBase;
867
868 p_IpcReply->error = (uint32_t)FmGetSetPortParams(h_Fm, &initParams);
869
870 ipcOutInitParams.ipcPhysAddr.high = initParams.fmMuramPhysBaseAddr.high;
871 ipcOutInitParams.ipcPhysAddr.low = initParams.fmMuramPhysBaseAddr.low;
872 ipcOutInitParams.sizeOfFifo = initParams.sizeOfFifo;
873 ipcOutInitParams.extraSizeOfFifo = initParams.extraSizeOfFifo;
874 ipcOutInitParams.numOfTasks = initParams.numOfTasks;
875 ipcOutInitParams.numOfExtraTasks = initParams.numOfExtraTasks;
876 ipcOutInitParams.numOfOpenDmas = initParams.numOfOpenDmas;
877 ipcOutInitParams.numOfExtraOpenDmas = initParams.numOfExtraOpenDmas;
878 memcpy(p_IpcReply->replyBody, (uint8_t*)&ipcOutInitParams, sizeof(ipcOutInitParams));
879 *p_ReplyLength = sizeof(uint32_t) + sizeof(t_FmIpcPortOutInitParams);
880 break;
881 }
882 case (FM_SET_SIZE_OF_FIFO):
883 {
884 t_FmIpcPortRsrcParams ipcPortRsrcParams;
885
886 memcpy((uint8_t*)&ipcPortRsrcParams, p_IpcMsg->msgBody, sizeof(t_FmIpcPortRsrcParams));
887 p_IpcReply->error = (uint32_t)FmSetSizeOfFifo(h_Fm,
888 ipcPortRsrcParams.hardwarePortId,
889 &ipcPortRsrcParams.val,
890 &ipcPortRsrcParams.extra,
891 (bool)ipcPortRsrcParams.boolInitialConfig);
892 *p_ReplyLength = sizeof(uint32_t);
893 break;
894 }
895 case (FM_SET_NUM_OF_TASKS):
896 {
897 t_FmIpcPortRsrcParams ipcPortRsrcParams;
898
899 memcpy((uint8_t*)&ipcPortRsrcParams, p_IpcMsg->msgBody, sizeof(t_FmIpcPortRsrcParams));
900 p_IpcReply->error = (uint32_t)FmSetNumOfTasks(h_Fm, ipcPortRsrcParams.hardwarePortId,
901 (uint8_t*)&ipcPortRsrcParams.val,
902 (uint8_t*)&ipcPortRsrcParams.extra,
903 (bool)ipcPortRsrcParams.boolInitialConfig);
904 *p_ReplyLength = sizeof(uint32_t);
905 break;
906 }
907 case (FM_SET_NUM_OF_OPEN_DMAS):
908 {
909 t_FmIpcPortRsrcParams ipcPortRsrcParams;
910
911 memcpy((uint8_t*)&ipcPortRsrcParams, p_IpcMsg->msgBody, sizeof(t_FmIpcPortRsrcParams));
912 p_IpcReply->error = (uint32_t)FmSetNumOfOpenDmas(h_Fm, ipcPortRsrcParams.hardwarePortId,
913 (uint8_t*)&ipcPortRsrcParams.val,
914 (uint8_t*)&ipcPortRsrcParams.extra,
915 (bool)ipcPortRsrcParams.boolInitialConfig);
916 *p_ReplyLength = sizeof(uint32_t);
917 break;
918 }
919 case (FM_RESUME_STALLED_PORT):
920 *p_ReplyLength = sizeof(uint32_t);
921 p_IpcReply->error = (uint32_t)FmResumeStalledPort(h_Fm, p_IpcMsg->msgBody[0]);
922 break;
923 case (FM_MASTER_IS_ALIVE):
924 {
925 uint8_t guestId = p_IpcMsg->msgBody[0];
926 /* build the FM master partition IPC address */
927 memset(p_Fm->fmIpcHandlerModuleName[guestId], 0, (sizeof(char)) * MODULE_NAME_SIZE);
928 if (Sprint (p_Fm->fmIpcHandlerModuleName[guestId], "FM_%d_%d",p_Fm->p_FmStateStruct->fmId, guestId) != (guestId<10 ? 6:7))
929 RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Sprint failed"));
930 p_Fm->h_IpcSessions[guestId] = XX_IpcInitSession(p_Fm->fmIpcHandlerModuleName[guestId], p_Fm->fmModuleName);
931 if (p_Fm->h_IpcSessions[guestId] == NULL)
932 RETURN_ERROR(MAJOR, E_NOT_AVAILABLE, ("FM Master IPC session for guest %d", guestId));
933 *(uint8_t*)(p_IpcReply->replyBody) = 1;
934 *p_ReplyLength = sizeof(uint32_t) + sizeof(uint8_t);
935 break;
936 }
937 case (FM_IS_PORT_STALLED):
938 {
939 bool tmp;
940
941 p_IpcReply->error = (uint32_t)FmIsPortStalled(h_Fm, p_IpcMsg->msgBody[0], &tmp);
942 *(uint8_t*)(p_IpcReply->replyBody) = (uint8_t)tmp;
943 *p_ReplyLength = sizeof(uint32_t) + sizeof(uint8_t);
944 break;
945 }
946 case (FM_RESET_MAC):
947 {
948 t_FmIpcMacParams ipcMacParams;
949
950 memcpy((uint8_t*)&ipcMacParams, p_IpcMsg->msgBody, sizeof(t_FmIpcMacParams));
951 p_IpcReply->error = (uint32_t)FmResetMac(p_Fm,
952 (e_FmMacType)(ipcMacParams.enumType),
953 ipcMacParams.id);
954 *p_ReplyLength = sizeof(uint32_t);
955 break;
956 }
957 case (FM_SET_MAC_MAX_FRAME):
958 {
959 t_FmIpcMacMaxFrameParams ipcMacMaxFrameParams;
960
961 memcpy((uint8_t*)&ipcMacMaxFrameParams, p_IpcMsg->msgBody, sizeof(t_FmIpcMacMaxFrameParams));
962 err = FmSetMacMaxFrame(p_Fm,
963 (e_FmMacType)(ipcMacMaxFrameParams.macParams.enumType),
964 ipcMacMaxFrameParams.macParams.id,
965 ipcMacMaxFrameParams.maxFrameLength);
966 if (err != E_OK)
967 REPORT_ERROR(MINOR, err, NO_MSG);
968 break;
969 }
970 #if (DPAA_VERSION >= 11)
971 case (FM_VSP_ALLOC) :
972 {
973 t_FmIpcResourceAllocParams ipcAllocParams;
974 uint8_t vspBase;
975 memcpy(&ipcAllocParams, p_IpcMsg->msgBody, sizeof(t_FmIpcResourceAllocParams));
976 vspBase = AllocVSPsForPartition(h_Fm, (uint8_t)ipcAllocParams.base, (uint8_t)ipcAllocParams.num, ipcAllocParams.guestId);
977 memcpy(p_IpcReply->replyBody, (uint8_t*)&vspBase, sizeof(uint8_t));
978 *p_ReplyLength = sizeof(uint32_t) + sizeof(uint8_t);
979 break;
980 }
981 case (FM_VSP_FREE) :
982 {
983 t_FmIpcResourceAllocParams ipcAllocParams;
984 memcpy(&ipcAllocParams, p_IpcMsg->msgBody, sizeof(t_FmIpcResourceAllocParams));
985 FreeVSPsForPartition(h_Fm, (uint8_t)ipcAllocParams.base, (uint8_t)ipcAllocParams.num, ipcAllocParams.guestId);
986 break;
987 }
988 case (FM_VSP_SET_PORT_WINDOW) :
989 {
990 t_FmIpcVspSetPortWindow ipcVspSetPortWindow;
991 memcpy(&ipcVspSetPortWindow, p_IpcMsg->msgBody, sizeof(t_FmIpcVspSetPortWindow));
992 err = SetVSPWindow(h_Fm,
993 ipcVspSetPortWindow.hardwarePortId,
994 ipcVspSetPortWindow.baseStorageProfile,
995 ipcVspSetPortWindow.log2NumOfProfiles);
996 return err;
997 }
998 case (FM_SET_CONG_GRP_PFC_PRIO) :
999 {
1000 t_FmIpcSetCongestionGroupPfcPriority fmIpcSetCongestionGroupPfcPriority;
1001 memcpy(&fmIpcSetCongestionGroupPfcPriority, p_IpcMsg->msgBody, sizeof(t_FmIpcSetCongestionGroupPfcPriority));
1002 err = FmSetCongestionGroupPFCpriority(h_Fm,
1003 fmIpcSetCongestionGroupPfcPriority.congestionGroupId,
1004 fmIpcSetCongestionGroupPfcPriority.priorityBitMap);
1005 return err;
1006 }
1007 #endif /* (DPAA_VERSION >= 11) */
1008
1009 case (FM_FREE_PORT):
1010 {
1011 t_FmInterModulePortFreeParams portParams;
1012 t_FmIpcPortFreeParams ipcPortParams;
1013
1014 memcpy((uint8_t*)&ipcPortParams, p_IpcMsg->msgBody, sizeof(t_FmIpcPortFreeParams));
1015 portParams.hardwarePortId = ipcPortParams.hardwarePortId;
1016 portParams.portType = (e_FmPortType)(ipcPortParams.enumPortType);
1017 portParams.deqPipelineDepth = ipcPortParams.deqPipelineDepth;
1018 FmFreePortParams(h_Fm, &portParams);
1019 break;
1020 }
1021 case (FM_REGISTER_INTR):
1022 {
1023 t_FmIpcRegisterIntr ipcRegIntr;
1024
1025 memcpy((uint8_t*)&ipcRegIntr, p_IpcMsg->msgBody, sizeof(ipcRegIntr));
1026 p_Fm->intrMng[ipcRegIntr.event].guestId = ipcRegIntr.guestId;
1027 break;
1028 }
1029 case (FM_GET_PARAMS):
1030 {
1031 t_FmIpcParams ipcParams;
1032
1033 /* Get clock frequency */
1034 ipcParams.fmClkFreq = p_Fm->p_FmStateStruct->fmClkFreq;
1035 ipcParams.fmMacClkFreq = p_Fm->p_FmStateStruct->fmMacClkFreq;
1036
1037 fman_get_revision(p_Fm->p_FmFpmRegs,&ipcParams.majorRev,&ipcParams.minorRev);
1038
1039 memcpy(p_IpcReply->replyBody, (uint8_t*)&ipcParams, sizeof(t_FmIpcParams));
1040 *p_ReplyLength = sizeof(uint32_t) + sizeof(t_FmIpcParams);
1041 break;
1042 }
1043 case (FM_GET_FMAN_CTRL_CODE_REV):
1044 {
1045 t_FmCtrlCodeRevisionInfo fmanCtrlRevInfo;
1046 t_FmIpcFmanCtrlCodeRevisionInfo ipcRevInfo;
1047
1048 p_IpcReply->error = (uint32_t)FM_GetFmanCtrlCodeRevision(h_Fm, &fmanCtrlRevInfo);
1049 ipcRevInfo.packageRev = fmanCtrlRevInfo.packageRev;
1050 ipcRevInfo.majorRev = fmanCtrlRevInfo.majorRev;
1051 ipcRevInfo.minorRev = fmanCtrlRevInfo.minorRev;
1052 memcpy(p_IpcReply->replyBody, (uint8_t*)&ipcRevInfo, sizeof(t_FmIpcFmanCtrlCodeRevisionInfo));
1053 *p_ReplyLength = sizeof(uint32_t) + sizeof(t_FmIpcFmanCtrlCodeRevisionInfo);
1054 break;
1055 }
1056
1057 case (FM_DMA_STAT):
1058 {
1059 t_FmDmaStatus dmaStatus;
1060 t_FmIpcDmaStatus ipcDmaStatus;
1061
1062 FM_GetDmaStatus(h_Fm, &dmaStatus);
1063 ipcDmaStatus.boolCmqNotEmpty = (uint8_t)dmaStatus.cmqNotEmpty;
1064 ipcDmaStatus.boolBusError = (uint8_t)dmaStatus.busError;
1065 ipcDmaStatus.boolReadBufEccError = (uint8_t)dmaStatus.readBufEccError;
1066 ipcDmaStatus.boolWriteBufEccSysError = (uint8_t)dmaStatus.writeBufEccSysError;
1067 ipcDmaStatus.boolWriteBufEccFmError = (uint8_t)dmaStatus.writeBufEccFmError;
1068 ipcDmaStatus.boolSinglePortEccError = (uint8_t)dmaStatus.singlePortEccError;
1069 memcpy(p_IpcReply->replyBody, (uint8_t*)&ipcDmaStatus, sizeof(t_FmIpcDmaStatus));
1070 *p_ReplyLength = sizeof(uint32_t) + sizeof(t_FmIpcDmaStatus);
1071 break;
1072 }
1073 case (FM_ALLOC_FMAN_CTRL_EVENT_REG):
1074 p_IpcReply->error = (uint32_t)FmAllocFmanCtrlEventReg(h_Fm, (uint8_t*)p_IpcReply->replyBody);
1075 *p_ReplyLength = sizeof(uint32_t) + sizeof(uint8_t);
1076 break;
1077 case (FM_FREE_FMAN_CTRL_EVENT_REG):
1078 FmFreeFmanCtrlEventReg(h_Fm, p_IpcMsg->msgBody[0]);
1079 break;
1080 case (FM_GET_TIMESTAMP_SCALE):
1081 {
1082 uint32_t timeStamp = FmGetTimeStampScale(h_Fm);
1083
1084 memcpy(p_IpcReply->replyBody, (uint8_t*)&timeStamp, sizeof(uint32_t));
1085 *p_ReplyLength = sizeof(uint32_t) + sizeof(uint32_t);
1086 break;
1087 }
1088 case (FM_GET_COUNTER):
1089 {
1090 e_FmCounters inCounter;
1091 uint32_t outCounter;
1092
1093 memcpy((uint8_t*)&inCounter, p_IpcMsg->msgBody, sizeof(uint32_t));
1094 outCounter = FM_GetCounter(h_Fm, inCounter);
1095 memcpy(p_IpcReply->replyBody, (uint8_t*)&outCounter, sizeof(uint32_t));
1096 *p_ReplyLength = sizeof(uint32_t) + sizeof(uint32_t);
1097 break;
1098 }
1099 case (FM_SET_FMAN_CTRL_EVENTS_ENABLE):
1100 {
1101 t_FmIpcFmanEvents ipcFmanEvents;
1102
1103 memcpy((uint8_t*)&ipcFmanEvents, p_IpcMsg->msgBody, sizeof(t_FmIpcFmanEvents));
1104 FmSetFmanCtrlIntr(h_Fm,
1105 ipcFmanEvents.eventRegId,
1106 ipcFmanEvents.enableEvents);
1107 break;
1108 }
1109 case (FM_GET_FMAN_CTRL_EVENTS_ENABLE):
1110 {
1111 uint32_t tmp = FmGetFmanCtrlIntr(h_Fm, p_IpcMsg->msgBody[0]);
1112
1113 memcpy(p_IpcReply->replyBody, (uint8_t*)&tmp, sizeof(uint32_t));
1114 *p_ReplyLength = sizeof(uint32_t) + sizeof(uint32_t);
1115 break;
1116 }
1117 case (FM_GET_PHYS_MURAM_BASE):
1118 {
1119 t_FmPhysAddr physAddr;
1120 t_FmIpcPhysAddr ipcPhysAddr;
1121
1122 FmGetPhysicalMuramBase(h_Fm, &physAddr);
1123 ipcPhysAddr.high = physAddr.high;
1124 ipcPhysAddr.low = physAddr.low;
1125 memcpy(p_IpcReply->replyBody, (uint8_t*)&ipcPhysAddr, sizeof(t_FmIpcPhysAddr));
1126 *p_ReplyLength = sizeof(uint32_t) + sizeof(t_FmIpcPhysAddr);
1127 break;
1128 }
1129 case (FM_ENABLE_RAM_ECC):
1130 {
1131 if (((err = FM_EnableRamsEcc(h_Fm)) != E_OK) ||
1132 ((err = FM_SetException(h_Fm, e_FM_EX_IRAM_ECC, TRUE)) != E_OK) ||
1133 ((err = FM_SetException(h_Fm, e_FM_EX_MURAM_ECC, TRUE)) != E_OK))
1134 #if (!(defined(DEBUG_ERRORS)) || (DEBUG_ERRORS == 0))
1135 UNUSED(err);
1136 #else
1137 REPORT_ERROR(MINOR, err, NO_MSG);
1138 #endif /* (!(defined(DEBUG_ERRORS)) || (DEBUG_ERRORS == 0)) */
1139 break;
1140 }
1141 case (FM_DISABLE_RAM_ECC):
1142 {
1143
1144 if (((err = FM_SetException(h_Fm, e_FM_EX_IRAM_ECC, FALSE)) != E_OK) ||
1145 ((err = FM_SetException(h_Fm, e_FM_EX_MURAM_ECC, FALSE)) != E_OK) ||
1146 ((err = FM_DisableRamsEcc(h_Fm)) != E_OK))
1147 #if (!(defined(DEBUG_ERRORS)) || (DEBUG_ERRORS == 0))
1148 UNUSED(err);
1149 #else
1150 REPORT_ERROR(MINOR, err, NO_MSG);
1151 #endif /* (!(defined(DEBUG_ERRORS)) || (DEBUG_ERRORS == 0)) */
1152 break;
1153 }
1154 case (FM_SET_NUM_OF_FMAN_CTRL):
1155 {
1156 t_FmIpcPortNumOfFmanCtrls ipcPortNumOfFmanCtrls;
1157
1158 memcpy((uint8_t*)&ipcPortNumOfFmanCtrls, p_IpcMsg->msgBody, sizeof(t_FmIpcPortNumOfFmanCtrls));
1159 err = FmSetNumOfRiscsPerPort(h_Fm,
1160 ipcPortNumOfFmanCtrls.hardwarePortId,
1161 ipcPortNumOfFmanCtrls.numOfFmanCtrls,
1162 ipcPortNumOfFmanCtrls.orFmanCtrl);
1163 if (err != E_OK)
1164 REPORT_ERROR(MINOR, err, NO_MSG);
1165 break;
1166 }
1167 #ifdef FM_TX_ECC_FRMS_ERRATA_10GMAC_A004
1168 case (FM_10G_TX_ECC_WA):
1169 p_IpcReply->error = (uint32_t)Fm10GTxEccWorkaround(h_Fm, p_IpcMsg->msgBody[0]);
1170 *p_ReplyLength = sizeof(uint32_t);
1171 break;
1172 #endif /* FM_TX_ECC_FRMS_ERRATA_10GMAC_A004 */
1173 default:
1174 *p_ReplyLength = 0;
1175 RETURN_ERROR(MINOR, E_INVALID_SELECTION, ("command not found!!!"));
1176 }
1177 return E_OK;
1178 }
1179
1180
1181 /****************************************/
1182 /* Inter-Module functions */
1183 /****************************************/
1184 #ifdef FM_TX_ECC_FRMS_ERRATA_10GMAC_A004
Fm10GTxEccWorkaround(t_Handle h_Fm,uint8_t macId)1185 t_Error Fm10GTxEccWorkaround(t_Handle h_Fm, uint8_t macId)
1186 {
1187 t_Fm *p_Fm = (t_Fm*)h_Fm;
1188 t_Error err = E_OK;
1189 t_FmIpcMsg msg;
1190 t_FmIpcReply reply;
1191 uint32_t replyLength;
1192 uint8_t rxHardwarePortId, txHardwarePortId;
1193 struct fman_fpm_regs *fpm_rg = p_Fm->p_FmFpmRegs;
1194
1195 if (p_Fm->guestId != NCSW_MASTER_ID)
1196 {
1197 memset(&msg, 0, sizeof(msg));
1198 memset(&reply, 0, sizeof(reply));
1199 msg.msgId = FM_10G_TX_ECC_WA;
1200 msg.msgBody[0] = macId;
1201 replyLength = sizeof(uint32_t);
1202 if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
1203 (uint8_t*)&msg,
1204 sizeof(msg.msgId)+sizeof(macId),
1205 (uint8_t*)&reply,
1206 &replyLength,
1207 NULL,
1208 NULL)) != E_OK)
1209 RETURN_ERROR(MINOR, err, NO_MSG);
1210 if (replyLength != sizeof(uint32_t))
1211 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
1212 return (t_Error)(reply.error);
1213 }
1214
1215 SANITY_CHECK_RETURN_ERROR((macId == 0), E_NOT_SUPPORTED);
1216 SANITY_CHECK_RETURN_ERROR(IsFmanCtrlCodeLoaded(p_Fm), E_INVALID_STATE);
1217
1218 rxHardwarePortId = SwPortIdToHwPortId(e_FM_PORT_TYPE_RX_10G,
1219 macId,
1220 p_Fm->p_FmStateStruct->revInfo.majorRev,
1221 p_Fm->p_FmStateStruct->revInfo.minorRev);
1222 txHardwarePortId = SwPortIdToHwPortId(e_FM_PORT_TYPE_TX_10G,
1223 macId,
1224 p_Fm->p_FmStateStruct->revInfo.majorRev,
1225 p_Fm->p_FmStateStruct->revInfo.minorRev);
1226 if ((p_Fm->p_FmStateStruct->portsTypes[rxHardwarePortId] != e_FM_PORT_TYPE_DUMMY) ||
1227 (p_Fm->p_FmStateStruct->portsTypes[txHardwarePortId] != e_FM_PORT_TYPE_DUMMY))
1228 RETURN_ERROR(MAJOR, E_INVALID_STATE,
1229 ("MAC should be initialized prior to Rx and Tx ports!"));
1230
1231 return fman_set_erratum_10gmac_a004_wa(fpm_rg);
1232 }
1233 #endif /* FM_TX_ECC_FRMS_ERRATA_10GMAC_A004 */
1234
FmGetTnumAgingPeriod(t_Handle h_Fm)1235 uint16_t FmGetTnumAgingPeriod(t_Handle h_Fm)
1236 {
1237 t_Fm *p_Fm = (t_Fm *)h_Fm;
1238
1239 SANITY_CHECK_RETURN_VALUE(p_Fm, E_INVALID_HANDLE, 0);
1240 SANITY_CHECK_RETURN_VALUE(!p_Fm->p_FmDriverParam, E_INVALID_STATE, 0);
1241
1242 return p_Fm->tnumAgingPeriod;
1243 }
1244
FmSetPortPreFetchConfiguration(t_Handle h_Fm,uint8_t portNum,bool preFetchConfigured)1245 t_Error FmSetPortPreFetchConfiguration(t_Handle h_Fm,
1246 uint8_t portNum,
1247 bool preFetchConfigured)
1248 {
1249 t_Fm *p_Fm = (t_Fm*)h_Fm;
1250
1251 SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
1252 SANITY_CHECK_RETURN_ERROR(!p_Fm->p_FmDriverParam, E_INVALID_STATE);
1253
1254 p_Fm->portsPreFetchConfigured[portNum] = TRUE;
1255 p_Fm->portsPreFetchValue[portNum] = preFetchConfigured;
1256
1257 return E_OK;
1258 }
1259
FmGetPortPreFetchConfiguration(t_Handle h_Fm,uint8_t portNum,bool * p_PortConfigured,bool * p_PreFetchConfigured)1260 t_Error FmGetPortPreFetchConfiguration(t_Handle h_Fm,
1261 uint8_t portNum,
1262 bool *p_PortConfigured,
1263 bool *p_PreFetchConfigured)
1264 {
1265 t_Fm *p_Fm = (t_Fm*)h_Fm;
1266
1267 SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
1268 SANITY_CHECK_RETURN_ERROR(!p_Fm->p_FmDriverParam, E_INVALID_STATE);
1269
1270 /* If the prefetch wasn't configured yet (not enable or disabled)
1271 we return the value TRUE as it was already configured */
1272 if (!p_Fm->portsPreFetchConfigured[portNum])
1273 {
1274 *p_PortConfigured = FALSE;
1275 *p_PreFetchConfigured = FALSE;
1276 }
1277 else
1278 {
1279 *p_PortConfigured = TRUE;
1280 *p_PreFetchConfigured = (p_Fm->portsPreFetchConfigured[portNum]);
1281 }
1282
1283 return E_OK;
1284 }
1285
FmSetCongestionGroupPFCpriority(t_Handle h_Fm,uint32_t congestionGroupId,uint8_t priorityBitMap)1286 t_Error FmSetCongestionGroupPFCpriority(t_Handle h_Fm,
1287 uint32_t congestionGroupId,
1288 uint8_t priorityBitMap)
1289 {
1290 t_Fm *p_Fm = (t_Fm *)h_Fm;
1291 uint32_t regNum;
1292
1293 ASSERT_COND(h_Fm);
1294
1295 if (congestionGroupId > FM_PORT_NUM_OF_CONGESTION_GRPS)
1296 RETURN_ERROR(MAJOR, E_INVALID_VALUE,
1297 ("Congestion group ID bigger than %d",
1298 FM_PORT_NUM_OF_CONGESTION_GRPS));
1299
1300 if (p_Fm->guestId == NCSW_MASTER_ID)
1301 {
1302 ASSERT_COND(p_Fm->baseAddr);
1303 regNum = (FM_PORT_NUM_OF_CONGESTION_GRPS - 1 - congestionGroupId) / 4;
1304 fman_set_congestion_group_pfc_priority((uint32_t *)((p_Fm->baseAddr+FM_MM_CGP)),
1305 congestionGroupId,
1306 priorityBitMap,
1307 regNum);
1308 }
1309 else if (p_Fm->h_IpcSessions[0])
1310 {
1311 t_Error err;
1312 t_FmIpcMsg msg;
1313 t_FmIpcSetCongestionGroupPfcPriority fmIpcSetCongestionGroupPfcPriority;
1314
1315 memset(&msg, 0, sizeof(msg));
1316 memset(&fmIpcSetCongestionGroupPfcPriority, 0, sizeof(t_FmIpcSetCongestionGroupPfcPriority));
1317 fmIpcSetCongestionGroupPfcPriority.congestionGroupId = congestionGroupId;
1318 fmIpcSetCongestionGroupPfcPriority.priorityBitMap = priorityBitMap;
1319
1320 msg.msgId = FM_SET_CONG_GRP_PFC_PRIO;
1321 memcpy(msg.msgBody, &fmIpcSetCongestionGroupPfcPriority, sizeof(t_FmIpcSetCongestionGroupPfcPriority));
1322
1323 err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
1324 (uint8_t*)&msg,
1325 sizeof(msg.msgId),
1326 NULL,
1327 NULL,
1328 NULL,
1329 NULL);
1330 if (err != E_OK)
1331 RETURN_ERROR(MINOR, err, NO_MSG);
1332 }
1333 else
1334 RETURN_ERROR(MAJOR, E_INVALID_STATE, ("guest without IPC!"));
1335
1336 return E_OK;
1337 }
1338
FmGetPcdPrsBaseAddr(t_Handle h_Fm)1339 uintptr_t FmGetPcdPrsBaseAddr(t_Handle h_Fm)
1340 {
1341 t_Fm *p_Fm = (t_Fm*)h_Fm;
1342
1343 SANITY_CHECK_RETURN_VALUE(p_Fm, E_INVALID_HANDLE, 0);
1344
1345 if (!p_Fm->baseAddr)
1346 {
1347 REPORT_ERROR(MAJOR, E_INVALID_STATE,
1348 ("No base-addr; probably Guest with IPC!"));
1349 return 0;
1350 }
1351
1352 return (p_Fm->baseAddr + FM_MM_PRS);
1353 }
1354
FmGetPcdKgBaseAddr(t_Handle h_Fm)1355 uintptr_t FmGetPcdKgBaseAddr(t_Handle h_Fm)
1356 {
1357 t_Fm *p_Fm = (t_Fm*)h_Fm;
1358
1359 SANITY_CHECK_RETURN_VALUE(p_Fm, E_INVALID_HANDLE, 0);
1360
1361 if (!p_Fm->baseAddr)
1362 {
1363 REPORT_ERROR(MAJOR, E_INVALID_STATE,
1364 ("No base-addr; probably Guest with IPC!"));
1365 return 0;
1366 }
1367
1368 return (p_Fm->baseAddr + FM_MM_KG);
1369 }
1370
FmGetPcdPlcrBaseAddr(t_Handle h_Fm)1371 uintptr_t FmGetPcdPlcrBaseAddr(t_Handle h_Fm)
1372 {
1373 t_Fm *p_Fm = (t_Fm*)h_Fm;
1374
1375 SANITY_CHECK_RETURN_VALUE(p_Fm, E_INVALID_HANDLE, 0);
1376
1377 if (!p_Fm->baseAddr)
1378 {
1379 REPORT_ERROR(MAJOR, E_INVALID_STATE,
1380 ("No base-addr; probably Guest with IPC!"));
1381 return 0;
1382 }
1383
1384 return (p_Fm->baseAddr + FM_MM_PLCR);
1385 }
1386
1387 #if (DPAA_VERSION >= 11)
FmGetVSPBaseAddr(t_Handle h_Fm)1388 uintptr_t FmGetVSPBaseAddr(t_Handle h_Fm)
1389 {
1390 t_Fm *p_Fm = (t_Fm*)h_Fm;
1391
1392 SANITY_CHECK_RETURN_VALUE(p_Fm, E_INVALID_HANDLE, 0);
1393
1394 return p_Fm->vspBaseAddr;
1395 }
1396 #endif /* (DPAA_VERSION >= 11) */
1397
FmGetMuramHandle(t_Handle h_Fm)1398 t_Handle FmGetMuramHandle(t_Handle h_Fm)
1399 {
1400 t_Fm *p_Fm = (t_Fm*)h_Fm;
1401
1402 SANITY_CHECK_RETURN_VALUE(p_Fm, E_INVALID_HANDLE, NULL);
1403
1404 return (p_Fm->h_FmMuram);
1405 }
1406
FmGetPhysicalMuramBase(t_Handle h_Fm,t_FmPhysAddr * p_FmPhysAddr)1407 void FmGetPhysicalMuramBase(t_Handle h_Fm, t_FmPhysAddr *p_FmPhysAddr)
1408 {
1409 t_Fm *p_Fm = (t_Fm*)h_Fm;
1410
1411 if (p_Fm->fmMuramPhysBaseAddr)
1412 {
1413 /* General FM driver initialization */
1414 p_FmPhysAddr->low = (uint32_t)p_Fm->fmMuramPhysBaseAddr;
1415 p_FmPhysAddr->high = (uint8_t)((p_Fm->fmMuramPhysBaseAddr & 0x000000ff00000000LL) >> 32);
1416 return;
1417 }
1418
1419 ASSERT_COND(p_Fm->guestId != NCSW_MASTER_ID);
1420
1421 if (p_Fm->h_IpcSessions[0])
1422 {
1423 t_Error err;
1424 t_FmIpcMsg msg;
1425 t_FmIpcReply reply;
1426 uint32_t replyLength;
1427 t_FmIpcPhysAddr ipcPhysAddr;
1428
1429 memset(&msg, 0, sizeof(msg));
1430 memset(&reply, 0, sizeof(reply));
1431 msg.msgId = FM_GET_PHYS_MURAM_BASE;
1432 replyLength = sizeof(uint32_t) + sizeof(t_FmPhysAddr);
1433 err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
1434 (uint8_t*)&msg,
1435 sizeof(msg.msgId),
1436 (uint8_t*)&reply,
1437 &replyLength,
1438 NULL,
1439 NULL);
1440 if (err != E_OK)
1441 {
1442 REPORT_ERROR(MINOR, err, NO_MSG);
1443 return;
1444 }
1445 if (replyLength != (sizeof(uint32_t) + sizeof(t_FmPhysAddr)))
1446 {
1447 REPORT_ERROR(MINOR, E_INVALID_VALUE,("IPC reply length mismatch"));
1448 return;
1449 }
1450 memcpy((uint8_t*)&ipcPhysAddr, reply.replyBody, sizeof(t_FmIpcPhysAddr));
1451 p_FmPhysAddr->high = ipcPhysAddr.high;
1452 p_FmPhysAddr->low = ipcPhysAddr.low;
1453 }
1454 else
1455 REPORT_ERROR(MINOR, E_NOT_SUPPORTED,
1456 ("running in guest-mode without neither IPC nor mapped register!"));
1457 }
1458
1459 #if (DPAA_VERSION >= 11)
FmVSPAllocForPort(t_Handle h_Fm,e_FmPortType portType,uint8_t portId,uint8_t numOfVSPs)1460 t_Error FmVSPAllocForPort (t_Handle h_Fm,
1461 e_FmPortType portType,
1462 uint8_t portId,
1463 uint8_t numOfVSPs)
1464 {
1465 t_Fm *p_Fm = (t_Fm *)h_Fm;
1466 t_Error err = E_OK;
1467 uint32_t profilesFound, intFlags;
1468 uint8_t first, i;
1469 uint8_t log2Num;
1470 uint8_t swPortIndex=0, hardwarePortId;
1471
1472 SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
1473
1474 if (!numOfVSPs)
1475 return E_OK;
1476
1477 if (numOfVSPs > FM_VSP_MAX_NUM_OF_ENTRIES)
1478 RETURN_ERROR(MINOR, E_INVALID_VALUE, ("numProfiles can not be bigger than %d.",FM_VSP_MAX_NUM_OF_ENTRIES));
1479
1480 if (!POWER_OF_2(numOfVSPs))
1481 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("numProfiles must be a power of 2."));
1482
1483 LOG2((uint64_t)numOfVSPs, log2Num);
1484
1485 if ((log2Num == 0) || (p_Fm->partVSPBase == 0))
1486 first = 0;
1487 else
1488 first = 1<<log2Num;
1489
1490 if (first > (p_Fm->partVSPBase + p_Fm->partNumOfVSPs))
1491 RETURN_ERROR(MINOR, E_INVALID_VALUE, ("can not allocate storage profile port window"));
1492
1493 if (first < p_Fm->partVSPBase)
1494 while (first < p_Fm->partVSPBase)
1495 first = first + numOfVSPs;
1496
1497 if ((first + numOfVSPs) > (p_Fm->partVSPBase + p_Fm->partNumOfVSPs))
1498 RETURN_ERROR(MINOR, E_INVALID_VALUE, ("can not allocate storage profile port window"));
1499
1500 intFlags = XX_LockIntrSpinlock(p_Fm->h_Spinlock);
1501 profilesFound = 0;
1502 for (i=first; i < p_Fm->partVSPBase + p_Fm->partNumOfVSPs; )
1503 {
1504 if (!p_Fm->p_FmSp->profiles[i].profilesMng.allocated)
1505 {
1506 profilesFound++;
1507 i++;
1508 if (profilesFound == numOfVSPs)
1509 break;
1510 }
1511 else
1512 {
1513 profilesFound = 0;
1514 /* advance i to the next aligned address */
1515 first = i = (uint8_t)(first + numOfVSPs);
1516 }
1517 }
1518 if (profilesFound == numOfVSPs)
1519 for (i = first; i<first + numOfVSPs; i++)
1520 p_Fm->p_FmSp->profiles[i].profilesMng.allocated = TRUE;
1521 else
1522 {
1523 XX_UnlockIntrSpinlock(p_Fm->h_Spinlock, intFlags);
1524 RETURN_ERROR(MINOR, E_FULL, ("No profiles."));
1525 }
1526
1527 hardwarePortId = SwPortIdToHwPortId(portType,
1528 portId,
1529 p_Fm->p_FmStateStruct->revInfo.majorRev,
1530 p_Fm->p_FmStateStruct->revInfo.minorRev);
1531 HW_PORT_ID_TO_SW_PORT_INDX(swPortIndex, hardwarePortId);
1532
1533 p_Fm->p_FmSp->portsMapping[swPortIndex].numOfProfiles = numOfVSPs;
1534 p_Fm->p_FmSp->portsMapping[swPortIndex].profilesBase = first;
1535
1536 if ((err = SetVSPWindow(h_Fm,hardwarePortId, first,log2Num)) != E_OK)
1537 for (i = first; i < first + numOfVSPs; i++)
1538 p_Fm->p_FmSp->profiles[i].profilesMng.allocated = FALSE;
1539
1540 XX_UnlockIntrSpinlock(p_Fm->h_Spinlock, intFlags);
1541
1542 return err;
1543 }
1544
FmVSPFreeForPort(t_Handle h_Fm,e_FmPortType portType,uint8_t portId)1545 t_Error FmVSPFreeForPort(t_Handle h_Fm,
1546 e_FmPortType portType,
1547 uint8_t portId)
1548 {
1549 t_Fm *p_Fm = (t_Fm *)h_Fm;
1550 uint8_t swPortIndex=0, hardwarePortId, first, numOfVSPs, i;
1551 uint32_t intFlags;
1552
1553 SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
1554
1555 hardwarePortId = SwPortIdToHwPortId(portType,
1556 portId,
1557 p_Fm->p_FmStateStruct->revInfo.majorRev,
1558 p_Fm->p_FmStateStruct->revInfo.minorRev);
1559 HW_PORT_ID_TO_SW_PORT_INDX(swPortIndex, hardwarePortId);
1560
1561 numOfVSPs = (uint8_t)p_Fm->p_FmSp->portsMapping[swPortIndex].numOfProfiles;
1562 first = (uint8_t)p_Fm->p_FmSp->portsMapping[swPortIndex].profilesBase;
1563
1564 intFlags = XX_LockIntrSpinlock(p_Fm->h_Spinlock);
1565 for (i = first; i < first + numOfVSPs; i++)
1566 p_Fm->p_FmSp->profiles[i].profilesMng.allocated = FALSE;
1567 XX_UnlockIntrSpinlock(p_Fm->h_Spinlock, intFlags);
1568
1569 p_Fm->p_FmSp->portsMapping[swPortIndex].numOfProfiles = 0;
1570 p_Fm->p_FmSp->portsMapping[swPortIndex].profilesBase = 0;
1571
1572 return E_OK;
1573 }
1574 #endif /* (DPAA_VERSION >= 11) */
1575
FmAllocFmanCtrlEventReg(t_Handle h_Fm,uint8_t * p_EventId)1576 t_Error FmAllocFmanCtrlEventReg(t_Handle h_Fm, uint8_t *p_EventId)
1577 {
1578 t_Fm *p_Fm = (t_Fm*)h_Fm;
1579 uint8_t i;
1580
1581 SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
1582
1583 if ((p_Fm->guestId != NCSW_MASTER_ID) &&
1584 p_Fm->h_IpcSessions[0])
1585 {
1586 t_Error err;
1587 t_FmIpcMsg msg;
1588 t_FmIpcReply reply;
1589 uint32_t replyLength;
1590
1591 memset(&msg, 0, sizeof(msg));
1592 memset(&reply, 0, sizeof(reply));
1593 msg.msgId = FM_ALLOC_FMAN_CTRL_EVENT_REG;
1594 replyLength = sizeof(uint32_t) + sizeof(uint8_t);
1595 if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
1596 (uint8_t*)&msg,
1597 sizeof(msg.msgId),
1598 (uint8_t*)&reply,
1599 &replyLength,
1600 NULL,
1601 NULL)) != E_OK)
1602 RETURN_ERROR(MAJOR, err, NO_MSG);
1603
1604 if (replyLength != (sizeof(uint32_t) + sizeof(uint8_t)))
1605 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
1606
1607 *p_EventId = *(uint8_t*)(reply.replyBody);
1608
1609 return (t_Error)(reply.error);
1610 }
1611 else if (p_Fm->guestId != NCSW_MASTER_ID)
1612 RETURN_ERROR(MINOR, E_NOT_SUPPORTED,
1613 ("running in guest-mode without IPC!"));
1614
1615 for (i=0;i<FM_NUM_OF_FMAN_CTRL_EVENT_REGS;i++)
1616 if (!p_Fm->usedEventRegs[i])
1617 {
1618 p_Fm->usedEventRegs[i] = TRUE;
1619 *p_EventId = i;
1620 break;
1621 }
1622
1623 if (i==FM_NUM_OF_FMAN_CTRL_EVENT_REGS)
1624 RETURN_ERROR(MAJOR, E_BUSY, ("No resource - FMan controller event register."));
1625
1626 return E_OK;
1627 }
1628
FmFreeFmanCtrlEventReg(t_Handle h_Fm,uint8_t eventId)1629 void FmFreeFmanCtrlEventReg(t_Handle h_Fm, uint8_t eventId)
1630 {
1631 t_Fm *p_Fm = (t_Fm*)h_Fm;
1632
1633 SANITY_CHECK_RETURN(p_Fm, E_INVALID_HANDLE);
1634
1635 if ((p_Fm->guestId != NCSW_MASTER_ID) &&
1636 p_Fm->h_IpcSessions[0])
1637 {
1638 t_Error err;
1639 t_FmIpcMsg msg;
1640
1641 memset(&msg, 0, sizeof(msg));
1642 msg.msgId = FM_FREE_FMAN_CTRL_EVENT_REG;
1643 msg.msgBody[0] = eventId;
1644 err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
1645 (uint8_t*)&msg,
1646 sizeof(msg.msgId)+sizeof(eventId),
1647 NULL,
1648 NULL,
1649 NULL,
1650 NULL);
1651 if (err != E_OK)
1652 REPORT_ERROR(MINOR, err, NO_MSG);
1653 return;
1654 }
1655 else if (p_Fm->guestId != NCSW_MASTER_ID)
1656 {
1657 REPORT_ERROR(MINOR, E_NOT_SUPPORTED,
1658 ("running in guest-mode without IPC!"));
1659 return;
1660 }
1661
1662 ((t_Fm*)h_Fm)->usedEventRegs[eventId] = FALSE;
1663 }
1664
FmSetFmanCtrlIntr(t_Handle h_Fm,uint8_t eventRegId,uint32_t enableEvents)1665 void FmSetFmanCtrlIntr(t_Handle h_Fm, uint8_t eventRegId, uint32_t enableEvents)
1666 {
1667 t_Fm *p_Fm = (t_Fm*)h_Fm;
1668 struct fman_fpm_regs *fpm_rg = p_Fm->p_FmFpmRegs;
1669
1670 if ((p_Fm->guestId != NCSW_MASTER_ID) &&
1671 !p_Fm->p_FmFpmRegs &&
1672 p_Fm->h_IpcSessions[0])
1673 {
1674 t_FmIpcFmanEvents fmanCtrl;
1675 t_Error err;
1676 t_FmIpcMsg msg;
1677
1678 fmanCtrl.eventRegId = eventRegId;
1679 fmanCtrl.enableEvents = enableEvents;
1680 memset(&msg, 0, sizeof(msg));
1681 msg.msgId = FM_SET_FMAN_CTRL_EVENTS_ENABLE;
1682 memcpy(msg.msgBody, &fmanCtrl, sizeof(fmanCtrl));
1683 err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
1684 (uint8_t*)&msg,
1685 sizeof(msg.msgId)+sizeof(fmanCtrl),
1686 NULL,
1687 NULL,
1688 NULL,
1689 NULL);
1690 if (err != E_OK)
1691 REPORT_ERROR(MINOR, err, NO_MSG);
1692 return;
1693 }
1694 else if (!p_Fm->p_FmFpmRegs)
1695 {
1696 REPORT_ERROR(MINOR, E_NOT_SUPPORTED,
1697 ("Either IPC or 'baseAddress' is required!"));
1698 return;
1699 }
1700
1701 ASSERT_COND(eventRegId < FM_NUM_OF_FMAN_CTRL_EVENT_REGS);
1702 fman_set_ctrl_intr(fpm_rg, eventRegId, enableEvents);
1703 }
1704
FmGetFmanCtrlIntr(t_Handle h_Fm,uint8_t eventRegId)1705 uint32_t FmGetFmanCtrlIntr(t_Handle h_Fm, uint8_t eventRegId)
1706 {
1707 t_Fm *p_Fm = (t_Fm*)h_Fm;
1708 struct fman_fpm_regs *fpm_rg = p_Fm->p_FmFpmRegs;
1709
1710 if ((p_Fm->guestId != NCSW_MASTER_ID) &&
1711 !p_Fm->p_FmFpmRegs &&
1712 p_Fm->h_IpcSessions[0])
1713 {
1714 t_Error err;
1715 t_FmIpcMsg msg;
1716 t_FmIpcReply reply;
1717 uint32_t replyLength, ctrlIntr;
1718
1719 memset(&msg, 0, sizeof(msg));
1720 memset(&reply, 0, sizeof(reply));
1721 msg.msgId = FM_GET_FMAN_CTRL_EVENTS_ENABLE;
1722 msg.msgBody[0] = eventRegId;
1723 replyLength = sizeof(uint32_t) + sizeof(uint32_t);
1724 err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
1725 (uint8_t*)&msg,
1726 sizeof(msg.msgId)+sizeof(eventRegId),
1727 (uint8_t*)&reply,
1728 &replyLength,
1729 NULL,
1730 NULL);
1731 if (err != E_OK)
1732 {
1733 REPORT_ERROR(MINOR, err, NO_MSG);
1734 return 0;
1735 }
1736 if (replyLength != (sizeof(uint32_t) + sizeof(uint32_t)))
1737 {
1738 REPORT_ERROR(MINOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
1739 return 0;
1740 }
1741 memcpy((uint8_t*)&ctrlIntr, reply.replyBody, sizeof(uint32_t));
1742 return ctrlIntr;
1743 }
1744 else if (!p_Fm->p_FmFpmRegs)
1745 {
1746 REPORT_ERROR(MINOR, E_NOT_SUPPORTED,
1747 ("Either IPC or 'baseAddress' is required!"));
1748 return 0;
1749 }
1750
1751 return fman_get_ctrl_intr(fpm_rg, eventRegId);
1752 }
1753
FmRegisterIntr(t_Handle h_Fm,e_FmEventModules module,uint8_t modId,e_FmIntrType intrType,void (* f_Isr)(t_Handle h_Arg),t_Handle h_Arg)1754 void FmRegisterIntr(t_Handle h_Fm,
1755 e_FmEventModules module,
1756 uint8_t modId,
1757 e_FmIntrType intrType,
1758 void (*f_Isr) (t_Handle h_Arg),
1759 t_Handle h_Arg)
1760 {
1761 t_Fm *p_Fm = (t_Fm*)h_Fm;
1762 int event = 0;
1763
1764 ASSERT_COND(h_Fm);
1765
1766 GET_FM_MODULE_EVENT(module, modId, intrType, event);
1767 ASSERT_COND(event < e_FM_EV_DUMMY_LAST);
1768
1769 /* register in local FM structure */
1770 p_Fm->intrMng[event].f_Isr = f_Isr;
1771 p_Fm->intrMng[event].h_SrcHandle = h_Arg;
1772
1773 if ((p_Fm->guestId != NCSW_MASTER_ID) &&
1774 p_Fm->h_IpcSessions[0])
1775 {
1776 t_FmIpcRegisterIntr fmIpcRegisterIntr;
1777 t_Error err;
1778 t_FmIpcMsg msg;
1779
1780 /* register in Master FM structure */
1781 fmIpcRegisterIntr.event = (uint32_t)event;
1782 fmIpcRegisterIntr.guestId = p_Fm->guestId;
1783 memset(&msg, 0, sizeof(msg));
1784 msg.msgId = FM_REGISTER_INTR;
1785 memcpy(msg.msgBody, &fmIpcRegisterIntr, sizeof(fmIpcRegisterIntr));
1786 err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
1787 (uint8_t*)&msg,
1788 sizeof(msg.msgId) + sizeof(fmIpcRegisterIntr),
1789 NULL,
1790 NULL,
1791 NULL,
1792 NULL);
1793 if (err != E_OK)
1794 REPORT_ERROR(MINOR, err, NO_MSG);
1795 }
1796 else if (p_Fm->guestId != NCSW_MASTER_ID)
1797 REPORT_ERROR(MINOR, E_NOT_SUPPORTED,
1798 ("running in guest-mode without IPC!"));
1799 }
1800
FmUnregisterIntr(t_Handle h_Fm,e_FmEventModules module,uint8_t modId,e_FmIntrType intrType)1801 void FmUnregisterIntr(t_Handle h_Fm,
1802 e_FmEventModules module,
1803 uint8_t modId,
1804 e_FmIntrType intrType)
1805 {
1806 t_Fm *p_Fm = (t_Fm*)h_Fm;
1807 int event = 0;
1808
1809 ASSERT_COND(h_Fm);
1810
1811 GET_FM_MODULE_EVENT(module, modId,intrType, event);
1812 ASSERT_COND(event < e_FM_EV_DUMMY_LAST);
1813
1814 p_Fm->intrMng[event].f_Isr = UnimplementedIsr;
1815 p_Fm->intrMng[event].h_SrcHandle = NULL;
1816 }
1817
FmRegisterFmanCtrlIntr(t_Handle h_Fm,uint8_t eventRegId,void (* f_Isr)(t_Handle h_Arg,uint32_t event),t_Handle h_Arg)1818 void FmRegisterFmanCtrlIntr(t_Handle h_Fm, uint8_t eventRegId, void (*f_Isr) (t_Handle h_Arg, uint32_t event), t_Handle h_Arg)
1819 {
1820 t_Fm *p_Fm = (t_Fm*)h_Fm;
1821
1822 ASSERT_COND(eventRegId<FM_NUM_OF_FMAN_CTRL_EVENT_REGS);
1823
1824 if (p_Fm->guestId != NCSW_MASTER_ID)
1825 {
1826 REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("FM in guest-mode"));
1827 return;
1828 }
1829
1830 p_Fm->fmanCtrlIntr[eventRegId].f_Isr = f_Isr;
1831 p_Fm->fmanCtrlIntr[eventRegId].h_SrcHandle = h_Arg;
1832 }
1833
FmUnregisterFmanCtrlIntr(t_Handle h_Fm,uint8_t eventRegId)1834 void FmUnregisterFmanCtrlIntr(t_Handle h_Fm, uint8_t eventRegId)
1835 {
1836 t_Fm *p_Fm = (t_Fm*)h_Fm;
1837
1838 ASSERT_COND(eventRegId<FM_NUM_OF_FMAN_CTRL_EVENT_REGS);
1839
1840 if (p_Fm->guestId != NCSW_MASTER_ID)
1841 {
1842 REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("FM in guest-mode"));
1843 return;
1844 }
1845
1846 p_Fm->fmanCtrlIntr[eventRegId].f_Isr = UnimplementedFmanCtrlIsr;
1847 p_Fm->fmanCtrlIntr[eventRegId].h_SrcHandle = NULL;
1848 }
1849
FmRegisterPcd(t_Handle h_Fm,t_Handle h_FmPcd)1850 void FmRegisterPcd(t_Handle h_Fm, t_Handle h_FmPcd)
1851 {
1852 t_Fm *p_Fm = (t_Fm*)h_Fm;
1853
1854 if (p_Fm->h_Pcd)
1855 REPORT_ERROR(MAJOR, E_ALREADY_EXISTS, ("PCD already set"));
1856
1857 p_Fm->h_Pcd = h_FmPcd;
1858 }
1859
FmUnregisterPcd(t_Handle h_Fm)1860 void FmUnregisterPcd(t_Handle h_Fm)
1861 {
1862 t_Fm *p_Fm = (t_Fm*)h_Fm;
1863
1864 if (!p_Fm->h_Pcd)
1865 REPORT_ERROR(MAJOR, E_NOT_FOUND, ("PCD handle!"));
1866
1867 p_Fm->h_Pcd = NULL;
1868 }
1869
FmGetPcdHandle(t_Handle h_Fm)1870 t_Handle FmGetPcdHandle(t_Handle h_Fm)
1871 {
1872 t_Fm *p_Fm = (t_Fm*)h_Fm;
1873
1874 return p_Fm->h_Pcd;
1875 }
1876
FmGetId(t_Handle h_Fm)1877 uint8_t FmGetId(t_Handle h_Fm)
1878 {
1879 t_Fm *p_Fm = (t_Fm*)h_Fm;
1880
1881 SANITY_CHECK_RETURN_VALUE(p_Fm, E_INVALID_HANDLE, 0xff);
1882
1883 return p_Fm->p_FmStateStruct->fmId;
1884 }
1885
FmReset(t_Handle h_Fm)1886 t_Error FmReset(t_Handle h_Fm)
1887 {
1888 t_Fm *p_Fm = (t_Fm*)h_Fm;
1889
1890 SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
1891
1892 WRITE_UINT32(p_Fm->p_FmFpmRegs->fm_rstc, FPM_RSTC_FM_RESET);
1893 CORE_MemoryBarrier();
1894 XX_UDelay(100);
1895
1896 return E_OK;
1897 }
1898
FmSetNumOfRiscsPerPort(t_Handle h_Fm,uint8_t hardwarePortId,uint8_t numOfFmanCtrls,t_FmFmanCtrl orFmanCtrl)1899 t_Error FmSetNumOfRiscsPerPort(t_Handle h_Fm,
1900 uint8_t hardwarePortId,
1901 uint8_t numOfFmanCtrls,
1902 t_FmFmanCtrl orFmanCtrl)
1903 {
1904
1905 t_Fm *p_Fm = (t_Fm*)h_Fm;
1906 struct fman_fpm_regs *fpm_rg;
1907
1908 SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
1909 SANITY_CHECK_RETURN_ERROR(((numOfFmanCtrls > 0) && (numOfFmanCtrls < 3)) , E_INVALID_HANDLE);
1910
1911 fpm_rg = p_Fm->p_FmFpmRegs;
1912 if ((p_Fm->guestId != NCSW_MASTER_ID) &&
1913 !p_Fm->p_FmFpmRegs &&
1914 p_Fm->h_IpcSessions[0])
1915 {
1916 t_Error err;
1917 t_FmIpcPortNumOfFmanCtrls params;
1918 t_FmIpcMsg msg;
1919
1920 memset(&msg, 0, sizeof(msg));
1921 params.hardwarePortId = hardwarePortId;
1922 params.numOfFmanCtrls = numOfFmanCtrls;
1923 params.orFmanCtrl = orFmanCtrl;
1924 msg.msgId = FM_SET_NUM_OF_FMAN_CTRL;
1925 memcpy(msg.msgBody, ¶ms, sizeof(params));
1926 err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
1927 (uint8_t*)&msg,
1928 sizeof(msg.msgId) +sizeof(params),
1929 NULL,
1930 NULL,
1931 NULL,
1932 NULL);
1933 if (err != E_OK)
1934 RETURN_ERROR(MINOR, err, NO_MSG);
1935 return E_OK;
1936 }
1937 else if (!p_Fm->p_FmFpmRegs)
1938 RETURN_ERROR(MINOR, E_NOT_SUPPORTED,
1939 ("Either IPC or 'baseAddress' is required!"));
1940
1941 fman_set_num_of_riscs_per_port(fpm_rg, hardwarePortId, numOfFmanCtrls, orFmanCtrl);
1942
1943 return E_OK;
1944 }
1945
FmGetSetPortParams(t_Handle h_Fm,t_FmInterModulePortInitParams * p_PortParams)1946 t_Error FmGetSetPortParams(t_Handle h_Fm, t_FmInterModulePortInitParams *p_PortParams)
1947 {
1948 t_Fm *p_Fm = (t_Fm*)h_Fm;
1949 t_Error err;
1950 uint32_t intFlags;
1951 uint8_t hardwarePortId = p_PortParams->hardwarePortId, macId;
1952 struct fman_rg fman_rg;
1953
1954 fman_rg.bmi_rg = p_Fm->p_FmBmiRegs;
1955 fman_rg.qmi_rg = p_Fm->p_FmQmiRegs;
1956 fman_rg.fpm_rg = p_Fm->p_FmFpmRegs;
1957 fman_rg.dma_rg = p_Fm->p_FmDmaRegs;
1958
1959 if (p_Fm->guestId != NCSW_MASTER_ID)
1960 {
1961 t_FmIpcPortInInitParams portInParams;
1962 t_FmIpcPortOutInitParams portOutParams;
1963 t_FmIpcMsg msg;
1964 t_FmIpcReply reply;
1965 uint32_t replyLength;
1966
1967 portInParams.hardwarePortId = p_PortParams->hardwarePortId;
1968 portInParams.enumPortType = (uint32_t)p_PortParams->portType;
1969 portInParams.boolIndependentMode= (uint8_t)p_PortParams->independentMode;
1970 portInParams.liodnOffset = p_PortParams->liodnOffset;
1971 portInParams.numOfTasks = p_PortParams->numOfTasks;
1972 portInParams.numOfExtraTasks = p_PortParams->numOfExtraTasks;
1973 portInParams.numOfOpenDmas = p_PortParams->numOfOpenDmas;
1974 portInParams.numOfExtraOpenDmas = p_PortParams->numOfExtraOpenDmas;
1975 portInParams.sizeOfFifo = p_PortParams->sizeOfFifo;
1976 portInParams.extraSizeOfFifo = p_PortParams->extraSizeOfFifo;
1977 portInParams.deqPipelineDepth = p_PortParams->deqPipelineDepth;
1978 portInParams.maxFrameLength = p_PortParams->maxFrameLength;
1979 portInParams.liodnBase = p_PortParams->liodnBase;
1980
1981 memset(&msg, 0, sizeof(msg));
1982 memset(&reply, 0, sizeof(reply));
1983 msg.msgId = FM_GET_SET_PORT_PARAMS;
1984 memcpy(msg.msgBody, &portInParams, sizeof(portInParams));
1985 replyLength = (sizeof(uint32_t) + sizeof(t_FmIpcPortOutInitParams));
1986 if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
1987 (uint8_t*)&msg,
1988 sizeof(msg.msgId) +sizeof(portInParams),
1989 (uint8_t*)&reply,
1990 &replyLength,
1991 NULL,
1992 NULL)) != E_OK)
1993 RETURN_ERROR(MINOR, err, NO_MSG);
1994 if (replyLength != (sizeof(uint32_t) + sizeof(t_FmIpcPortOutInitParams)))
1995 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
1996 memcpy((uint8_t*)&portOutParams, reply.replyBody, sizeof(t_FmIpcPortOutInitParams));
1997
1998 p_PortParams->fmMuramPhysBaseAddr.high = portOutParams.ipcPhysAddr.high;
1999 p_PortParams->fmMuramPhysBaseAddr.low = portOutParams.ipcPhysAddr.low;
2000 p_PortParams->numOfTasks = portOutParams.numOfTasks;
2001 p_PortParams->numOfExtraTasks = portOutParams.numOfExtraTasks;
2002 p_PortParams->numOfOpenDmas = portOutParams.numOfOpenDmas;
2003 p_PortParams->numOfExtraOpenDmas = portOutParams.numOfExtraOpenDmas;
2004 p_PortParams->sizeOfFifo = portOutParams.sizeOfFifo;
2005 p_PortParams->extraSizeOfFifo = portOutParams.extraSizeOfFifo;
2006
2007 return (t_Error)(reply.error);
2008 }
2009
2010 ASSERT_COND(IN_RANGE(1, hardwarePortId, 63));
2011
2012 intFlags = XX_LockIntrSpinlock(p_Fm->h_Spinlock);
2013 if (p_PortParams->independentMode)
2014 {
2015 /* set port parameters */
2016 p_Fm->independentMode = p_PortParams->independentMode;
2017 /* disable dispatch limit */
2018 fman_qmi_disable_dispatch_limit(fman_rg.fpm_rg);
2019 }
2020
2021 if (p_PortParams->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND)
2022 {
2023 if (p_Fm->hcPortInitialized)
2024 {
2025 XX_UnlockIntrSpinlock(p_Fm->h_Spinlock, intFlags);
2026 RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Only one host command port is allowed."));
2027 }
2028 else
2029 p_Fm->hcPortInitialized = TRUE;
2030 }
2031 p_Fm->p_FmStateStruct->portsTypes[hardwarePortId] = p_PortParams->portType;
2032
2033 err = FmSetNumOfTasks(p_Fm, hardwarePortId, &p_PortParams->numOfTasks, &p_PortParams->numOfExtraTasks, TRUE);
2034 if (err)
2035 {
2036 XX_UnlockIntrSpinlock(p_Fm->h_Spinlock, intFlags);
2037 RETURN_ERROR(MAJOR, err, NO_MSG);
2038 }
2039
2040 #ifdef FM_QMI_NO_DEQ_OPTIONS_SUPPORT
2041 if (p_Fm->p_FmStateStruct->revInfo.majorRev != 4)
2042 #endif /* FM_QMI_NO_DEQ_OPTIONS_SUPPORT */
2043 if ((p_PortParams->portType != e_FM_PORT_TYPE_RX) &&
2044 (p_PortParams->portType != e_FM_PORT_TYPE_RX_10G))
2045 /* for transmit & O/H ports */
2046 {
2047 uint8_t enqTh;
2048 uint8_t deqTh;
2049
2050 /* update qmi ENQ/DEQ threshold */
2051 p_Fm->p_FmStateStruct->accumulatedNumOfDeqTnums += p_PortParams->deqPipelineDepth;
2052 enqTh = fman_get_qmi_enq_th(fman_rg.qmi_rg);
2053 /* if enqTh is too big, we reduce it to the max value that is still OK */
2054 if (enqTh >= (QMI_MAX_NUM_OF_TNUMS - p_Fm->p_FmStateStruct->accumulatedNumOfDeqTnums))
2055 {
2056 enqTh = (uint8_t)(QMI_MAX_NUM_OF_TNUMS - p_Fm->p_FmStateStruct->accumulatedNumOfDeqTnums - 1);
2057 fman_set_qmi_enq_th(fman_rg.qmi_rg, enqTh);
2058 }
2059
2060 deqTh = fman_get_qmi_deq_th(fman_rg.qmi_rg);
2061 /* if deqTh is too small, we enlarge it to the min value that is still OK.
2062 deqTh may not be larger than 63 (QMI_MAX_NUM_OF_TNUMS-1). */
2063 if ((deqTh <= p_Fm->p_FmStateStruct->accumulatedNumOfDeqTnums) && (deqTh < QMI_MAX_NUM_OF_TNUMS-1))
2064 {
2065 deqTh = (uint8_t)(p_Fm->p_FmStateStruct->accumulatedNumOfDeqTnums + 1);
2066 fman_set_qmi_deq_th(fman_rg.qmi_rg, deqTh);
2067 }
2068 }
2069
2070 #ifdef FM_LOW_END_RESTRICTION
2071 if ((hardwarePortId==0x1) || (hardwarePortId==0x29))
2072 {
2073 if (p_Fm->p_FmStateStruct->lowEndRestriction)
2074 {
2075 XX_UnlockIntrSpinlock(p_Fm->h_Spinlock, intFlags);
2076 RETURN_ERROR(MAJOR, E_NOT_AVAILABLE, ("OP #0 cannot work with Tx Port #1."));
2077 }
2078 else
2079 p_Fm->p_FmStateStruct->lowEndRestriction = TRUE;
2080 }
2081 #endif /* FM_LOW_END_RESTRICTION */
2082
2083 err = FmSetSizeOfFifo(p_Fm,
2084 hardwarePortId,
2085 &p_PortParams->sizeOfFifo,
2086 &p_PortParams->extraSizeOfFifo,
2087 TRUE);
2088 if (err)
2089 {
2090 XX_UnlockIntrSpinlock(p_Fm->h_Spinlock, intFlags);
2091 RETURN_ERROR(MAJOR, err, NO_MSG);
2092 }
2093
2094 err = FmSetNumOfOpenDmas(p_Fm,
2095 hardwarePortId,
2096 &p_PortParams->numOfOpenDmas,
2097 &p_PortParams->numOfExtraOpenDmas,
2098 TRUE);
2099 if (err)
2100 {
2101 XX_UnlockIntrSpinlock(p_Fm->h_Spinlock, intFlags);
2102 RETURN_ERROR(MAJOR, err, NO_MSG);
2103 }
2104
2105 fman_set_liodn_per_port(&fman_rg,
2106 hardwarePortId,
2107 p_PortParams->liodnBase,
2108 p_PortParams->liodnOffset);
2109
2110 if (p_Fm->p_FmStateStruct->revInfo.majorRev < 6)
2111 fman_set_order_restoration_per_port(fman_rg.fpm_rg,
2112 hardwarePortId,
2113 p_PortParams->independentMode,
2114 !!((p_PortParams->portType==e_FM_PORT_TYPE_RX) || (p_PortParams->portType==e_FM_PORT_TYPE_RX_10G)));
2115
2116 HW_PORT_ID_TO_SW_PORT_ID(macId, hardwarePortId);
2117
2118 #if defined(FM_MAX_NUM_OF_10G_MACS) && (FM_MAX_NUM_OF_10G_MACS)
2119 if ((p_PortParams->portType == e_FM_PORT_TYPE_TX_10G) ||
2120 (p_PortParams->portType == e_FM_PORT_TYPE_RX_10G))
2121 {
2122 ASSERT_COND(macId < FM_MAX_NUM_OF_10G_MACS);
2123 if (p_PortParams->maxFrameLength >= p_Fm->p_FmStateStruct->macMaxFrameLengths10G[macId])
2124 p_Fm->p_FmStateStruct->portMaxFrameLengths10G[macId] = p_PortParams->maxFrameLength;
2125 else
2126 RETURN_ERROR(MINOR, E_INVALID_VALUE, ("Port maxFrameLength is smaller than MAC current MTU"));
2127 }
2128 else
2129 #endif /* defined(FM_MAX_NUM_OF_10G_MACS) && ... */
2130 if ((p_PortParams->portType == e_FM_PORT_TYPE_TX) ||
2131 (p_PortParams->portType == e_FM_PORT_TYPE_RX))
2132 {
2133 ASSERT_COND(macId < FM_MAX_NUM_OF_1G_MACS);
2134 if (p_PortParams->maxFrameLength >= p_Fm->p_FmStateStruct->macMaxFrameLengths1G[macId])
2135 p_Fm->p_FmStateStruct->portMaxFrameLengths1G[macId] = p_PortParams->maxFrameLength;
2136 else
2137 RETURN_ERROR(MINOR, E_INVALID_VALUE, ("Port maxFrameLength is smaller than MAC current MTU"));
2138 }
2139
2140 FmGetPhysicalMuramBase(p_Fm, &p_PortParams->fmMuramPhysBaseAddr);
2141 XX_UnlockIntrSpinlock(p_Fm->h_Spinlock, intFlags);
2142
2143 return E_OK;
2144 }
2145
FmFreePortParams(t_Handle h_Fm,t_FmInterModulePortFreeParams * p_PortParams)2146 void FmFreePortParams(t_Handle h_Fm,t_FmInterModulePortFreeParams *p_PortParams)
2147 {
2148 t_Fm *p_Fm = (t_Fm*)h_Fm;
2149 uint32_t intFlags;
2150 uint8_t hardwarePortId = p_PortParams->hardwarePortId;
2151 uint8_t numOfTasks, numOfDmas, macId;
2152 uint16_t sizeOfFifo;
2153 t_Error err;
2154 t_FmIpcPortFreeParams portParams;
2155 t_FmIpcMsg msg;
2156 struct fman_qmi_regs *qmi_rg = p_Fm->p_FmQmiRegs;
2157 struct fman_bmi_regs *bmi_rg = p_Fm->p_FmBmiRegs;
2158
2159 if (p_Fm->guestId != NCSW_MASTER_ID)
2160 {
2161 portParams.hardwarePortId = p_PortParams->hardwarePortId;
2162 portParams.enumPortType = (uint32_t)p_PortParams->portType;
2163 portParams.deqPipelineDepth = p_PortParams->deqPipelineDepth;
2164 memset(&msg, 0, sizeof(msg));
2165 msg.msgId = FM_FREE_PORT;
2166 memcpy(msg.msgBody, &portParams, sizeof(portParams));
2167 err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
2168 (uint8_t*)&msg,
2169 sizeof(msg.msgId)+sizeof(portParams),
2170 NULL,
2171 NULL,
2172 NULL,
2173 NULL);
2174 if (err != E_OK)
2175 REPORT_ERROR(MINOR, err, NO_MSG);
2176 return;
2177 }
2178
2179 ASSERT_COND(IN_RANGE(1, hardwarePortId, 63));
2180
2181 intFlags = XX_LockIntrSpinlock(p_Fm->h_Spinlock);
2182
2183 if (p_PortParams->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND)
2184 {
2185 ASSERT_COND(p_Fm->hcPortInitialized);
2186 p_Fm->hcPortInitialized = FALSE;
2187 }
2188
2189 p_Fm->p_FmStateStruct->portsTypes[hardwarePortId] = e_FM_PORT_TYPE_DUMMY;
2190
2191 /* free numOfTasks */
2192 numOfTasks = fman_get_num_of_tasks(bmi_rg, hardwarePortId);
2193 ASSERT_COND(p_Fm->p_FmStateStruct->accumulatedNumOfTasks >= numOfTasks);
2194 p_Fm->p_FmStateStruct->accumulatedNumOfTasks -= numOfTasks;
2195
2196 /* free numOfOpenDmas */
2197 numOfDmas = fman_get_num_of_dmas(bmi_rg, hardwarePortId);
2198 ASSERT_COND(p_Fm->p_FmStateStruct->accumulatedNumOfOpenDmas >= numOfDmas);
2199 p_Fm->p_FmStateStruct->accumulatedNumOfOpenDmas -= numOfDmas;
2200
2201 #ifdef FM_HAS_TOTAL_DMAS
2202 if (p_Fm->p_FmStateStruct->revInfo.majorRev < 6)
2203 {
2204 /* update total num of DMA's with committed number of open DMAS, and max uncommitted pool. */
2205 fman_set_num_of_open_dmas(bmi_rg,
2206 hardwarePortId,
2207 1,
2208 0,
2209 (uint8_t)(p_Fm->p_FmStateStruct->accumulatedNumOfOpenDmas + p_Fm->p_FmStateStruct->extraOpenDmasPoolSize));
2210 }
2211 #endif /* FM_HAS_TOTAL_DMAS */
2212
2213 /* free sizeOfFifo */
2214 sizeOfFifo = fman_get_size_of_fifo(bmi_rg, hardwarePortId);
2215 ASSERT_COND(p_Fm->p_FmStateStruct->accumulatedFifoSize >= (sizeOfFifo * BMI_FIFO_UNITS));
2216 p_Fm->p_FmStateStruct->accumulatedFifoSize -= (sizeOfFifo * BMI_FIFO_UNITS);
2217
2218 #ifdef FM_QMI_NO_DEQ_OPTIONS_SUPPORT
2219 if (p_Fm->p_FmStateStruct->revInfo.majorRev != 4)
2220 #endif /* FM_QMI_NO_DEQ_OPTIONS_SUPPORT */
2221 if ((p_PortParams->portType != e_FM_PORT_TYPE_RX) &&
2222 (p_PortParams->portType != e_FM_PORT_TYPE_RX_10G))
2223 /* for transmit & O/H ports */
2224 {
2225 uint8_t enqTh;
2226 uint8_t deqTh;
2227
2228 /* update qmi ENQ/DEQ threshold */
2229 p_Fm->p_FmStateStruct->accumulatedNumOfDeqTnums -= p_PortParams->deqPipelineDepth;
2230
2231 /* p_Fm->p_FmStateStruct->accumulatedNumOfDeqTnums is now smaller,
2232 so we can enlarge enqTh */
2233 enqTh = (uint8_t)(QMI_MAX_NUM_OF_TNUMS - p_Fm->p_FmStateStruct->accumulatedNumOfDeqTnums - 1);
2234
2235 /* p_Fm->p_FmStateStruct->accumulatedNumOfDeqTnums is now smaller,
2236 so we can reduce deqTh */
2237 deqTh = (uint8_t)(p_Fm->p_FmStateStruct->accumulatedNumOfDeqTnums + 1);
2238
2239 fman_set_qmi_enq_th(qmi_rg, enqTh);
2240 fman_set_qmi_deq_th(qmi_rg, deqTh);
2241 }
2242
2243 HW_PORT_ID_TO_SW_PORT_ID(macId, hardwarePortId);
2244
2245 #if defined(FM_MAX_NUM_OF_10G_MACS) && (FM_MAX_NUM_OF_10G_MACS)
2246 if ((p_PortParams->portType == e_FM_PORT_TYPE_TX_10G) ||
2247 (p_PortParams->portType == e_FM_PORT_TYPE_RX_10G))
2248 {
2249 ASSERT_COND(macId < FM_MAX_NUM_OF_10G_MACS);
2250 p_Fm->p_FmStateStruct->portMaxFrameLengths10G[macId] = 0;
2251 }
2252 else
2253 #endif /* defined(FM_MAX_NUM_OF_10G_MACS) && ... */
2254 if ((p_PortParams->portType == e_FM_PORT_TYPE_TX) ||
2255 (p_PortParams->portType == e_FM_PORT_TYPE_RX))
2256 {
2257 ASSERT_COND(macId < FM_MAX_NUM_OF_1G_MACS);
2258 p_Fm->p_FmStateStruct->portMaxFrameLengths1G[macId] = 0;
2259 }
2260
2261 #ifdef FM_LOW_END_RESTRICTION
2262 if ((hardwarePortId==0x1) || (hardwarePortId==0x29))
2263 p_Fm->p_FmStateStruct->lowEndRestriction = FALSE;
2264 #endif /* FM_LOW_END_RESTRICTION */
2265 XX_UnlockIntrSpinlock(p_Fm->h_Spinlock, intFlags);
2266 }
2267
FmIsPortStalled(t_Handle h_Fm,uint8_t hardwarePortId,bool * p_IsStalled)2268 t_Error FmIsPortStalled(t_Handle h_Fm, uint8_t hardwarePortId, bool *p_IsStalled)
2269 {
2270 t_Fm *p_Fm = (t_Fm*)h_Fm;
2271 t_Error err;
2272 t_FmIpcMsg msg;
2273 t_FmIpcReply reply;
2274 uint32_t replyLength;
2275 struct fman_fpm_regs *fpm_rg = p_Fm->p_FmFpmRegs;
2276
2277 if ((p_Fm->guestId != NCSW_MASTER_ID) &&
2278 !p_Fm->baseAddr &&
2279 p_Fm->h_IpcSessions[0])
2280 {
2281 memset(&msg, 0, sizeof(msg));
2282 memset(&reply, 0, sizeof(reply));
2283 msg.msgId = FM_IS_PORT_STALLED;
2284 msg.msgBody[0] = hardwarePortId;
2285 replyLength = sizeof(uint32_t) + sizeof(uint8_t);
2286 err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
2287 (uint8_t*)&msg,
2288 sizeof(msg.msgId)+sizeof(hardwarePortId),
2289 (uint8_t*)&reply,
2290 &replyLength,
2291 NULL,
2292 NULL);
2293 if (err != E_OK)
2294 RETURN_ERROR(MINOR, err, NO_MSG);
2295 if (replyLength != (sizeof(uint32_t) + sizeof(uint8_t)))
2296 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
2297
2298 *p_IsStalled = (bool)!!(*(uint8_t*)(reply.replyBody));
2299
2300 return (t_Error)(reply.error);
2301 }
2302 else if (!p_Fm->baseAddr)
2303 RETURN_ERROR(MINOR, E_NOT_SUPPORTED,
2304 ("Either IPC or 'baseAddress' is required!"));
2305
2306 *p_IsStalled = fman_is_port_stalled(fpm_rg, hardwarePortId);
2307
2308 return E_OK;
2309 }
2310
FmResumeStalledPort(t_Handle h_Fm,uint8_t hardwarePortId)2311 t_Error FmResumeStalledPort(t_Handle h_Fm, uint8_t hardwarePortId)
2312 {
2313 t_Fm *p_Fm = (t_Fm*)h_Fm;
2314 t_Error err;
2315 bool isStalled;
2316 struct fman_fpm_regs *fpm_rg = p_Fm->p_FmFpmRegs;
2317
2318 if ((p_Fm->guestId != NCSW_MASTER_ID) &&
2319 !p_Fm->baseAddr &&
2320 p_Fm->h_IpcSessions[0])
2321 {
2322 t_FmIpcMsg msg;
2323 t_FmIpcReply reply;
2324 uint32_t replyLength;
2325
2326 memset(&msg, 0, sizeof(msg));
2327 memset(&reply, 0, sizeof(reply));
2328 msg.msgId = FM_RESUME_STALLED_PORT;
2329 msg.msgBody[0] = hardwarePortId;
2330 replyLength = sizeof(uint32_t);
2331 err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
2332 (uint8_t*)&msg,
2333 sizeof(msg.msgId) + sizeof(hardwarePortId),
2334 (uint8_t*)&reply,
2335 &replyLength,
2336 NULL,
2337 NULL);
2338 if (err != E_OK)
2339 RETURN_ERROR(MINOR, err, NO_MSG);
2340 if (replyLength != sizeof(uint32_t))
2341 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
2342 return (t_Error)(reply.error);
2343 }
2344 else if (!p_Fm->baseAddr)
2345 RETURN_ERROR(MINOR, E_NOT_SUPPORTED,
2346 ("Either IPC or 'baseAddress' is required!"));
2347
2348 if (p_Fm->p_FmStateStruct->revInfo.majorRev >= 6)
2349 RETURN_ERROR(MINOR, E_NOT_AVAILABLE, ("Not available for this FM revision!"));
2350
2351 /* Get port status */
2352 err = FmIsPortStalled(h_Fm, hardwarePortId, &isStalled);
2353 if (err)
2354 RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Can't get port status"));
2355 if (!isStalled)
2356 return E_OK;
2357
2358 fman_resume_stalled_port(fpm_rg, hardwarePortId);
2359
2360 return E_OK;
2361 }
2362
FmResetMac(t_Handle h_Fm,e_FmMacType type,uint8_t macId)2363 t_Error FmResetMac(t_Handle h_Fm, e_FmMacType type, uint8_t macId)
2364 {
2365 t_Fm *p_Fm = (t_Fm*)h_Fm;
2366 t_Error err;
2367 struct fman_fpm_regs *fpm_rg = p_Fm->p_FmFpmRegs;
2368
2369 #if (DPAA_VERSION >= 11)
2370 if (p_Fm->p_FmStateStruct->revInfo.majorRev >= 6)
2371 RETURN_ERROR(MINOR, E_NOT_SUPPORTED,
2372 ("FMan MAC reset!"));
2373 #endif /*(DPAA_VERSION >= 11)*/
2374
2375 if ((p_Fm->guestId != NCSW_MASTER_ID) &&
2376 !p_Fm->baseAddr &&
2377 p_Fm->h_IpcSessions[0])
2378 {
2379 t_FmIpcMacParams macParams;
2380 t_FmIpcMsg msg;
2381 t_FmIpcReply reply;
2382 uint32_t replyLength;
2383
2384 memset(&msg, 0, sizeof(msg));
2385 memset(&reply, 0, sizeof(reply));
2386 macParams.id = macId;
2387 macParams.enumType = (uint32_t)type;
2388 msg.msgId = FM_RESET_MAC;
2389 memcpy(msg.msgBody, &macParams, sizeof(macParams));
2390 replyLength = sizeof(uint32_t);
2391 err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
2392 (uint8_t*)&msg,
2393 sizeof(msg.msgId)+sizeof(macParams),
2394 (uint8_t*)&reply,
2395 &replyLength,
2396 NULL,
2397 NULL);
2398 if (err != E_OK)
2399 RETURN_ERROR(MINOR, err, NO_MSG);
2400 if (replyLength != sizeof(uint32_t))
2401 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
2402 return (t_Error)(reply.error);
2403 }
2404 else if (!p_Fm->baseAddr)
2405 RETURN_ERROR(MINOR, E_NOT_SUPPORTED,
2406 ("Either IPC or 'baseAddress' is required!"));
2407
2408 err = (t_Error)fman_reset_mac(fpm_rg, macId, !!(type == e_FM_MAC_10G));
2409
2410 if (err == -EBUSY)
2411 return ERROR_CODE(E_TIMEOUT);
2412 else if (err)
2413 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal MAC ID"));
2414
2415 return E_OK;
2416 }
2417
FmSetMacMaxFrame(t_Handle h_Fm,e_FmMacType type,uint8_t macId,uint16_t mtu)2418 t_Error FmSetMacMaxFrame(t_Handle h_Fm, e_FmMacType type, uint8_t macId, uint16_t mtu)
2419 {
2420 t_Fm *p_Fm = (t_Fm*)h_Fm;
2421
2422 if ((p_Fm->guestId != NCSW_MASTER_ID) &&
2423 p_Fm->h_IpcSessions[0])
2424 {
2425 t_FmIpcMacMaxFrameParams macMaxFrameLengthParams;
2426 t_Error err;
2427 t_FmIpcMsg msg;
2428
2429 memset(&msg, 0, sizeof(msg));
2430 macMaxFrameLengthParams.macParams.id = macId;
2431 macMaxFrameLengthParams.macParams.enumType = (uint32_t)type;
2432 macMaxFrameLengthParams.maxFrameLength = (uint16_t)mtu;
2433 msg.msgId = FM_SET_MAC_MAX_FRAME;
2434 memcpy(msg.msgBody, &macMaxFrameLengthParams, sizeof(macMaxFrameLengthParams));
2435 err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
2436 (uint8_t*)&msg,
2437 sizeof(msg.msgId)+sizeof(macMaxFrameLengthParams),
2438 NULL,
2439 NULL,
2440 NULL,
2441 NULL);
2442 if (err != E_OK)
2443 RETURN_ERROR(MINOR, err, NO_MSG);
2444 return E_OK;
2445 }
2446 else if (p_Fm->guestId != NCSW_MASTER_ID)
2447 RETURN_ERROR(MINOR, E_NOT_SUPPORTED,
2448 ("running in guest-mode without IPC!"));
2449
2450 /* if port is already initialized, check that MaxFrameLength is smaller
2451 * or equal to the port's max */
2452 #if (defined(FM_MAX_NUM_OF_10G_MACS) && (FM_MAX_NUM_OF_10G_MACS))
2453 if (type == e_FM_MAC_10G)
2454 {
2455 if ((!p_Fm->p_FmStateStruct->portMaxFrameLengths10G[macId])
2456 || (p_Fm->p_FmStateStruct->portMaxFrameLengths10G[macId] &&
2457 (mtu <= p_Fm->p_FmStateStruct->portMaxFrameLengths10G[macId])))
2458 p_Fm->p_FmStateStruct->macMaxFrameLengths10G[macId] = mtu;
2459 else
2460 RETURN_ERROR(MINOR, E_INVALID_VALUE, ("MAC maxFrameLength is larger than Port maxFrameLength"));
2461
2462 }
2463 else
2464 #else
2465 UNUSED(type);
2466 #endif /* (defined(FM_MAX_NUM_OF_10G_MACS) && ... */
2467 if ((!p_Fm->p_FmStateStruct->portMaxFrameLengths1G[macId])
2468 || (p_Fm->p_FmStateStruct->portMaxFrameLengths1G[macId] &&
2469 (mtu <= p_Fm->p_FmStateStruct->portMaxFrameLengths1G[macId])))
2470 p_Fm->p_FmStateStruct->macMaxFrameLengths1G[macId] = mtu;
2471 else
2472 RETURN_ERROR(MINOR, E_INVALID_VALUE, ("MAC maxFrameLength is larger than Port maxFrameLength"));
2473
2474 return E_OK;
2475 }
2476
FmGetClockFreq(t_Handle h_Fm)2477 uint16_t FmGetClockFreq(t_Handle h_Fm)
2478 {
2479 t_Fm *p_Fm = (t_Fm*)h_Fm;
2480
2481 /* for multicore environment: this depends on the
2482 * fact that fmClkFreq was properly initialized at "init". */
2483 return p_Fm->p_FmStateStruct->fmClkFreq;
2484 }
2485
FmGetMacClockFreq(t_Handle h_Fm)2486 uint16_t FmGetMacClockFreq(t_Handle h_Fm)
2487 {
2488 t_Fm *p_Fm = (t_Fm*)h_Fm;
2489
2490 return p_Fm->p_FmStateStruct->fmMacClkFreq;
2491 }
2492
FmGetTimeStampScale(t_Handle h_Fm)2493 uint32_t FmGetTimeStampScale(t_Handle h_Fm)
2494 {
2495 t_Fm *p_Fm = (t_Fm*)h_Fm;
2496
2497 if ((p_Fm->guestId != NCSW_MASTER_ID) &&
2498 !p_Fm->baseAddr &&
2499 p_Fm->h_IpcSessions[0])
2500 {
2501 t_Error err;
2502 t_FmIpcMsg msg;
2503 t_FmIpcReply reply;
2504 uint32_t replyLength, timeStamp;
2505
2506 memset(&msg, 0, sizeof(msg));
2507 memset(&reply, 0, sizeof(reply));
2508 msg.msgId = FM_GET_TIMESTAMP_SCALE;
2509 replyLength = sizeof(uint32_t) + sizeof(uint32_t);
2510 if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
2511 (uint8_t*)&msg,
2512 sizeof(msg.msgId),
2513 (uint8_t*)&reply,
2514 &replyLength,
2515 NULL,
2516 NULL)) != E_OK)
2517 {
2518 REPORT_ERROR(MAJOR, err, NO_MSG);
2519 return 0;
2520 }
2521 if (replyLength != (sizeof(uint32_t) + sizeof(uint32_t)))
2522 {
2523 REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
2524 return 0;
2525 }
2526
2527 memcpy((uint8_t*)&timeStamp, reply.replyBody, sizeof(uint32_t));
2528 return timeStamp;
2529 }
2530 else if ((p_Fm->guestId != NCSW_MASTER_ID) &&
2531 p_Fm->baseAddr)
2532 {
2533 if (!(GET_UINT32(p_Fm->p_FmFpmRegs->fmfp_tsc1) & FPM_TS_CTL_EN))
2534 {
2535 REPORT_ERROR(MAJOR, E_INVALID_STATE, ("timestamp is not enabled!"));
2536 return 0;
2537 }
2538 }
2539 else if (p_Fm->guestId != NCSW_MASTER_ID)
2540 DBG(WARNING, ("No IPC - can't validate FM if timestamp enabled."));
2541
2542 return p_Fm->p_FmStateStruct->count1MicroBit;
2543 }
2544
FmEnableRamsEcc(t_Handle h_Fm)2545 t_Error FmEnableRamsEcc(t_Handle h_Fm)
2546 {
2547 t_Fm *p_Fm = (t_Fm*)h_Fm;
2548
2549 SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
2550
2551 p_Fm->p_FmStateStruct->ramsEccOwners++;
2552 p_Fm->p_FmStateStruct->internalCall = TRUE;
2553
2554 return FM_EnableRamsEcc(p_Fm);
2555 }
2556
FmDisableRamsEcc(t_Handle h_Fm)2557 t_Error FmDisableRamsEcc(t_Handle h_Fm)
2558 {
2559 t_Fm *p_Fm = (t_Fm*)h_Fm;
2560
2561 SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
2562
2563 ASSERT_COND(p_Fm->p_FmStateStruct->ramsEccOwners);
2564 p_Fm->p_FmStateStruct->ramsEccOwners--;
2565
2566 if (p_Fm->p_FmStateStruct->ramsEccOwners==0)
2567 {
2568 p_Fm->p_FmStateStruct->internalCall = TRUE;
2569 return FM_DisableRamsEcc(p_Fm);
2570 }
2571
2572 return E_OK;
2573 }
2574
FmGetGuestId(t_Handle h_Fm)2575 uint8_t FmGetGuestId(t_Handle h_Fm)
2576 {
2577 t_Fm *p_Fm = (t_Fm*)h_Fm;
2578
2579 return p_Fm->guestId;
2580 }
2581
FmIsMaster(t_Handle h_Fm)2582 bool FmIsMaster(t_Handle h_Fm)
2583 {
2584 t_Fm *p_Fm = (t_Fm*)h_Fm;
2585
2586 return (p_Fm->guestId == NCSW_MASTER_ID);
2587 }
2588
FmSetSizeOfFifo(t_Handle h_Fm,uint8_t hardwarePortId,uint32_t * p_SizeOfFifo,uint32_t * p_ExtraSizeOfFifo,bool initialConfig)2589 t_Error FmSetSizeOfFifo(t_Handle h_Fm,
2590 uint8_t hardwarePortId,
2591 uint32_t *p_SizeOfFifo,
2592 uint32_t *p_ExtraSizeOfFifo,
2593 bool initialConfig)
2594 {
2595 t_Fm *p_Fm = (t_Fm*)h_Fm;
2596 t_FmIpcPortRsrcParams rsrcParams;
2597 t_Error err;
2598 struct fman_bmi_regs *bmi_rg = p_Fm->p_FmBmiRegs;
2599 uint32_t sizeOfFifo = *p_SizeOfFifo, extraSizeOfFifo = *p_ExtraSizeOfFifo;
2600 uint16_t currentVal = 0, currentExtraVal = 0;
2601
2602 if ((p_Fm->guestId != NCSW_MASTER_ID) &&
2603 !p_Fm->baseAddr &&
2604 p_Fm->h_IpcSessions[0])
2605 {
2606 t_FmIpcMsg msg;
2607 t_FmIpcReply reply;
2608 uint32_t replyLength;
2609
2610 rsrcParams.hardwarePortId = hardwarePortId;
2611 rsrcParams.val = sizeOfFifo;
2612 rsrcParams.extra = extraSizeOfFifo;
2613 rsrcParams.boolInitialConfig = (uint8_t)initialConfig;
2614
2615 memset(&msg, 0, sizeof(msg));
2616 memset(&reply, 0, sizeof(reply));
2617 msg.msgId = FM_SET_SIZE_OF_FIFO;
2618 memcpy(msg.msgBody, &rsrcParams, sizeof(rsrcParams));
2619 replyLength = sizeof(uint32_t);
2620 if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
2621 (uint8_t*)&msg,
2622 sizeof(msg.msgId) + sizeof(rsrcParams),
2623 (uint8_t*)&reply,
2624 &replyLength,
2625 NULL,
2626 NULL)) != E_OK)
2627 RETURN_ERROR(MINOR, err, NO_MSG);
2628 if (replyLength != sizeof(uint32_t))
2629 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
2630 return (t_Error)(reply.error);
2631 }
2632 else if ((p_Fm->guestId != NCSW_MASTER_ID) &&
2633 p_Fm->baseAddr)
2634 {
2635 DBG(WARNING, ("No IPC - can't validate FM total-fifo size."));
2636 fman_set_size_of_fifo(bmi_rg, hardwarePortId, sizeOfFifo, extraSizeOfFifo);
2637 }
2638 else if (p_Fm->guestId != NCSW_MASTER_ID)
2639 RETURN_ERROR(MAJOR, E_NOT_SUPPORTED,
2640 ("running in guest-mode without neither IPC nor mapped register!"));
2641
2642 if (!initialConfig)
2643 {
2644 /* !initialConfig - runtime change of existing value.
2645 * - read the current FIFO and extra FIFO size */
2646 currentExtraVal = fman_get_size_of_extra_fifo(bmi_rg, hardwarePortId);
2647 currentVal = fman_get_size_of_fifo(bmi_rg, hardwarePortId);
2648 }
2649
2650 if (extraSizeOfFifo > currentExtraVal)
2651 {
2652 if (extraSizeOfFifo && !p_Fm->p_FmStateStruct->extraFifoPoolSize)
2653 /* if this is the first time a port requires extraFifoPoolSize, the total extraFifoPoolSize
2654 * must be initialized to 1 buffer per port
2655 */
2656 p_Fm->p_FmStateStruct->extraFifoPoolSize = FM_MAX_NUM_OF_RX_PORTS*BMI_FIFO_UNITS;
2657
2658 p_Fm->p_FmStateStruct->extraFifoPoolSize = MAX(p_Fm->p_FmStateStruct->extraFifoPoolSize, extraSizeOfFifo);
2659 }
2660
2661 /* check that there are enough uncommitted fifo size */
2662 if ((p_Fm->p_FmStateStruct->accumulatedFifoSize - currentVal + sizeOfFifo) >
2663 (p_Fm->p_FmStateStruct->totalFifoSize - p_Fm->p_FmStateStruct->extraFifoPoolSize)){
2664 REPORT_ERROR(MAJOR, E_INVALID_VALUE,
2665 ("Port request fifo size + accumulated size > total FIFO size:"));
2666 RETURN_ERROR(MAJOR, E_INVALID_VALUE,
2667 ("port 0x%x requested %d bytes, extra size = %d, accumulated size = %d total size = %d",
2668 hardwarePortId, sizeOfFifo, p_Fm->p_FmStateStruct->extraFifoPoolSize,
2669 p_Fm->p_FmStateStruct->accumulatedFifoSize,
2670 p_Fm->p_FmStateStruct->totalFifoSize));
2671 }
2672 else
2673 {
2674 /* update accumulated */
2675 ASSERT_COND(p_Fm->p_FmStateStruct->accumulatedFifoSize >= currentVal);
2676 p_Fm->p_FmStateStruct->accumulatedFifoSize -= currentVal;
2677 p_Fm->p_FmStateStruct->accumulatedFifoSize += sizeOfFifo;
2678 fman_set_size_of_fifo(bmi_rg, hardwarePortId, sizeOfFifo, extraSizeOfFifo);
2679 }
2680
2681 return E_OK;
2682 }
2683
FmSetNumOfTasks(t_Handle h_Fm,uint8_t hardwarePortId,uint8_t * p_NumOfTasks,uint8_t * p_NumOfExtraTasks,bool initialConfig)2684 t_Error FmSetNumOfTasks(t_Handle h_Fm,
2685 uint8_t hardwarePortId,
2686 uint8_t *p_NumOfTasks,
2687 uint8_t *p_NumOfExtraTasks,
2688 bool initialConfig)
2689 {
2690 t_Fm *p_Fm = (t_Fm *)h_Fm;
2691 t_Error err;
2692 struct fman_bmi_regs *bmi_rg = p_Fm->p_FmBmiRegs;
2693 uint8_t currentVal = 0, currentExtraVal = 0, numOfTasks = *p_NumOfTasks, numOfExtraTasks = *p_NumOfExtraTasks;
2694
2695 ASSERT_COND(IN_RANGE(1, hardwarePortId, 63));
2696
2697 if ((p_Fm->guestId != NCSW_MASTER_ID) &&
2698 !p_Fm->baseAddr &&
2699 p_Fm->h_IpcSessions[0])
2700 {
2701 t_FmIpcPortRsrcParams rsrcParams;
2702 t_FmIpcMsg msg;
2703 t_FmIpcReply reply;
2704 uint32_t replyLength;
2705
2706 rsrcParams.hardwarePortId = hardwarePortId;
2707 rsrcParams.val = numOfTasks;
2708 rsrcParams.extra = numOfExtraTasks;
2709 rsrcParams.boolInitialConfig = (uint8_t)initialConfig;
2710
2711 memset(&msg, 0, sizeof(msg));
2712 memset(&reply, 0, sizeof(reply));
2713 msg.msgId = FM_SET_NUM_OF_TASKS;
2714 memcpy(msg.msgBody, &rsrcParams, sizeof(rsrcParams));
2715 replyLength = sizeof(uint32_t);
2716 if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
2717 (uint8_t*)&msg,
2718 sizeof(msg.msgId) + sizeof(rsrcParams),
2719 (uint8_t*)&reply,
2720 &replyLength,
2721 NULL,
2722 NULL)) != E_OK)
2723 RETURN_ERROR(MINOR, err, NO_MSG);
2724 if (replyLength != sizeof(uint32_t))
2725 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
2726 return (t_Error)(reply.error);
2727 }
2728 else if ((p_Fm->guestId != NCSW_MASTER_ID) &&
2729 p_Fm->baseAddr)
2730 {
2731 DBG(WARNING, ("No IPC - can't validate FM total-num-of-tasks."));
2732 fman_set_num_of_tasks(bmi_rg, hardwarePortId, numOfTasks, numOfExtraTasks);
2733 }
2734 else if (p_Fm->guestId != NCSW_MASTER_ID)
2735 RETURN_ERROR(MAJOR, E_NOT_SUPPORTED,
2736 ("running in guest-mode without neither IPC nor mapped register!"));
2737
2738 if (!initialConfig)
2739 {
2740 /* !initialConfig - runtime change of existing value.
2741 * - read the current number of tasks */
2742 currentVal = fman_get_num_of_tasks(bmi_rg, hardwarePortId);
2743 currentExtraVal = fman_get_num_extra_tasks(bmi_rg, hardwarePortId);
2744 }
2745
2746 if (numOfExtraTasks > currentExtraVal)
2747 p_Fm->p_FmStateStruct->extraTasksPoolSize =
2748 (uint8_t)MAX(p_Fm->p_FmStateStruct->extraTasksPoolSize, numOfExtraTasks);
2749
2750 /* check that there are enough uncommitted tasks */
2751 if ((p_Fm->p_FmStateStruct->accumulatedNumOfTasks - currentVal + numOfTasks) >
2752 (p_Fm->p_FmStateStruct->totalNumOfTasks - p_Fm->p_FmStateStruct->extraTasksPoolSize))
2753 RETURN_ERROR(MAJOR, E_NOT_AVAILABLE,
2754 ("Requested numOfTasks and extra tasks pool for fm%d exceed total numOfTasks.",
2755 p_Fm->p_FmStateStruct->fmId));
2756 else
2757 {
2758 ASSERT_COND(p_Fm->p_FmStateStruct->accumulatedNumOfTasks >= currentVal);
2759 /* update accumulated */
2760 p_Fm->p_FmStateStruct->accumulatedNumOfTasks -= currentVal;
2761 p_Fm->p_FmStateStruct->accumulatedNumOfTasks += numOfTasks;
2762 fman_set_num_of_tasks(bmi_rg, hardwarePortId, numOfTasks, numOfExtraTasks);
2763 }
2764
2765 return E_OK;
2766 }
2767
FmSetNumOfOpenDmas(t_Handle h_Fm,uint8_t hardwarePortId,uint8_t * p_NumOfOpenDmas,uint8_t * p_NumOfExtraOpenDmas,bool initialConfig)2768 t_Error FmSetNumOfOpenDmas(t_Handle h_Fm,
2769 uint8_t hardwarePortId,
2770 uint8_t *p_NumOfOpenDmas,
2771 uint8_t *p_NumOfExtraOpenDmas,
2772 bool initialConfig)
2773
2774 {
2775 t_Fm *p_Fm = (t_Fm *)h_Fm;
2776 t_Error err;
2777 struct fman_bmi_regs *bmi_rg = p_Fm->p_FmBmiRegs;
2778 uint8_t numOfOpenDmas = *p_NumOfOpenDmas, numOfExtraOpenDmas = *p_NumOfExtraOpenDmas;
2779 uint8_t totalNumDmas = 0, currentVal = 0, currentExtraVal = 0;
2780
2781 ASSERT_COND(IN_RANGE(1, hardwarePortId, 63));
2782
2783 if ((p_Fm->guestId != NCSW_MASTER_ID) &&
2784 !p_Fm->baseAddr &&
2785 p_Fm->h_IpcSessions[0])
2786 {
2787 t_FmIpcPortRsrcParams rsrcParams;
2788 t_FmIpcMsg msg;
2789 t_FmIpcReply reply;
2790 uint32_t replyLength;
2791
2792 rsrcParams.hardwarePortId = hardwarePortId;
2793 rsrcParams.val = numOfOpenDmas;
2794 rsrcParams.extra = numOfExtraOpenDmas;
2795 rsrcParams.boolInitialConfig = (uint8_t)initialConfig;
2796
2797 memset(&msg, 0, sizeof(msg));
2798 memset(&reply, 0, sizeof(reply));
2799 msg.msgId = FM_SET_NUM_OF_OPEN_DMAS;
2800 memcpy(msg.msgBody, &rsrcParams, sizeof(rsrcParams));
2801 replyLength = sizeof(uint32_t);
2802 if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
2803 (uint8_t*)&msg,
2804 sizeof(msg.msgId) + sizeof(rsrcParams),
2805 (uint8_t*)&reply,
2806 &replyLength,
2807 NULL,
2808 NULL)) != E_OK)
2809 RETURN_ERROR(MINOR, err, NO_MSG);
2810 if (replyLength != sizeof(uint32_t))
2811 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
2812 return (t_Error)(reply.error);
2813 }
2814 #ifdef FM_HAS_TOTAL_DMAS
2815 else if (p_Fm->guestId != NCSW_MASTER_ID)
2816 RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("running in guest-mode without IPC!"));
2817 #else
2818 else if ((p_Fm->guestId != NCSW_MASTER_ID) &&
2819 p_Fm->baseAddr &&
2820 (p_Fm->p_FmStateStruct->revInfo.majorRev >= 6))
2821 {
2822 /*DBG(WARNING, ("No IPC - can't validate FM total-num-of-dmas."));*/
2823
2824 if (!numOfOpenDmas)
2825 {
2826 /* first config without explic it value: Do Nothing - reset value shouldn't be
2827 changed, read register for port save */
2828 *p_NumOfOpenDmas = fman_get_num_of_dmas(bmi_rg, hardwarePortId);
2829 *p_NumOfExtraOpenDmas = fman_get_num_extra_dmas(bmi_rg, hardwarePortId);
2830 }
2831 else
2832 /* whether it is the first time with explicit value, or runtime "set" - write register */
2833 fman_set_num_of_open_dmas(bmi_rg,
2834 hardwarePortId,
2835 numOfOpenDmas,
2836 numOfExtraOpenDmas,
2837 p_Fm->p_FmStateStruct->accumulatedNumOfOpenDmas + p_Fm->p_FmStateStruct->extraOpenDmasPoolSize);
2838 }
2839 else if (p_Fm->guestId != NCSW_MASTER_ID)
2840 RETURN_ERROR(MAJOR, E_NOT_SUPPORTED,
2841 ("running in guest-mode without neither IPC nor mapped register!"));
2842 #endif /* FM_HAS_TOTAL_DMAS */
2843
2844 if (!initialConfig)
2845 {
2846 /* !initialConfig - runtime change of existing value.
2847 * - read the current number of open Dma's */
2848 currentExtraVal = fman_get_num_extra_dmas(bmi_rg, hardwarePortId);
2849 currentVal = fman_get_num_of_dmas(bmi_rg, hardwarePortId);
2850 }
2851
2852 #ifdef FM_NO_GUARANTEED_RESET_VALUES
2853 /* it's illegal to be in a state where this is not the first set and no value is specified */
2854 ASSERT_COND(initialConfig || numOfOpenDmas);
2855 if (!numOfOpenDmas)
2856 {
2857 /* !numOfOpenDmas - first configuration according to values in regs.
2858 * - read the current number of open Dma's */
2859 currentExtraVal = fman_get_num_extra_dmas(bmi_rg, hardwarePortId);
2860 currentVal = fman_get_num_of_dmas(bmi_rg, hardwarePortId);
2861 /* This is the first configuration and user did not specify value (!numOfOpenDmas),
2862 * reset values will be used and we just save these values for resource management */
2863 p_Fm->p_FmStateStruct->extraOpenDmasPoolSize =
2864 (uint8_t)MAX(p_Fm->p_FmStateStruct->extraOpenDmasPoolSize, currentExtraVal);
2865 p_Fm->p_FmStateStruct->accumulatedNumOfOpenDmas += currentVal;
2866 *p_NumOfOpenDmas = currentVal;
2867 *p_NumOfExtraOpenDmas = currentExtraVal;
2868 return E_OK;
2869 }
2870 #endif /* FM_NO_GUARANTEED_RESET_VALUES */
2871
2872 if (numOfExtraOpenDmas > currentExtraVal)
2873 p_Fm->p_FmStateStruct->extraOpenDmasPoolSize =
2874 (uint8_t)MAX(p_Fm->p_FmStateStruct->extraOpenDmasPoolSize, numOfExtraOpenDmas);
2875
2876 #ifdef FM_HAS_TOTAL_DMAS
2877 if ((p_Fm->p_FmStateStruct->revInfo.majorRev < 6) &&
2878 (p_Fm->p_FmStateStruct->accumulatedNumOfOpenDmas - currentVal + numOfOpenDmas >
2879 p_Fm->p_FmStateStruct->maxNumOfOpenDmas))
2880 RETURN_ERROR(MAJOR, E_NOT_AVAILABLE,
2881 ("Requested numOfOpenDmas for fm%d exceeds total numOfOpenDmas.",
2882 p_Fm->p_FmStateStruct->fmId));
2883 #else
2884 if ((p_Fm->p_FmStateStruct->revInfo.majorRev >= 6) &&
2885 #ifdef FM_HEAVY_TRAFFIC_SEQUENCER_HANG_ERRATA_FMAN_A006981
2886 !((p_Fm->p_FmStateStruct->revInfo.majorRev == 6) &&
2887 (p_Fm->p_FmStateStruct->revInfo.minorRev == 0)) &&
2888 #endif /* FM_HEAVY_TRAFFIC_SEQUENCER_HANG_ERRATA_FMAN_A006981 */
2889 (p_Fm->p_FmStateStruct->accumulatedNumOfOpenDmas - currentVal + numOfOpenDmas > DMA_THRESH_MAX_COMMQ + 1))
2890 RETURN_ERROR(MAJOR, E_NOT_AVAILABLE,
2891 ("Requested numOfOpenDmas for fm%d exceeds DMA Command queue (%d)",
2892 p_Fm->p_FmStateStruct->fmId, DMA_THRESH_MAX_COMMQ+1));
2893 #endif /* FM_HAS_TOTAL_DMAS */
2894 else
2895 {
2896 ASSERT_COND(p_Fm->p_FmStateStruct->accumulatedNumOfOpenDmas >= currentVal);
2897 /* update acummulated */
2898 p_Fm->p_FmStateStruct->accumulatedNumOfOpenDmas -= currentVal;
2899 p_Fm->p_FmStateStruct->accumulatedNumOfOpenDmas += numOfOpenDmas;
2900
2901 #ifdef FM_HAS_TOTAL_DMAS
2902 if (p_Fm->p_FmStateStruct->revInfo.majorRev < 6)
2903 totalNumDmas = (uint8_t)(p_Fm->p_FmStateStruct->accumulatedNumOfOpenDmas + p_Fm->p_FmStateStruct->extraOpenDmasPoolSize);
2904 #endif /* FM_HAS_TOTAL_DMAS */
2905 fman_set_num_of_open_dmas(bmi_rg,
2906 hardwarePortId,
2907 numOfOpenDmas,
2908 numOfExtraOpenDmas,
2909 totalNumDmas);
2910 }
2911
2912 return E_OK;
2913 }
2914
2915 #if (DPAA_VERSION >= 11)
FmVSPCheckRelativeProfile(t_Handle h_Fm,e_FmPortType portType,uint8_t portId,uint16_t relativeProfile)2916 t_Error FmVSPCheckRelativeProfile(t_Handle h_Fm,
2917 e_FmPortType portType,
2918 uint8_t portId,
2919 uint16_t relativeProfile)
2920 {
2921 t_Fm *p_Fm;
2922 t_FmSp *p_FmPcdSp;
2923 uint8_t swPortIndex=0, hardwarePortId;
2924
2925 ASSERT_COND(h_Fm);
2926 p_Fm = (t_Fm*)h_Fm;
2927
2928 hardwarePortId = SwPortIdToHwPortId(portType,
2929 portId,
2930 p_Fm->p_FmStateStruct->revInfo.majorRev,
2931 p_Fm->p_FmStateStruct->revInfo.minorRev);
2932 ASSERT_COND(hardwarePortId);
2933 HW_PORT_ID_TO_SW_PORT_INDX(swPortIndex, hardwarePortId);
2934
2935 p_FmPcdSp = p_Fm->p_FmSp;
2936 ASSERT_COND(p_FmPcdSp);
2937
2938 if (!p_FmPcdSp->portsMapping[swPortIndex].numOfProfiles)
2939 RETURN_ERROR(MAJOR, E_INVALID_STATE , ("Port has no allocated profiles"));
2940 if (relativeProfile >= p_FmPcdSp->portsMapping[swPortIndex].numOfProfiles)
2941 RETURN_ERROR(MAJOR, E_NOT_IN_RANGE , ("Profile id is out of range"));
2942
2943 return E_OK;
2944 }
2945
FmVSPGetAbsoluteProfileId(t_Handle h_Fm,e_FmPortType portType,uint8_t portId,uint16_t relativeProfile,uint16_t * p_AbsoluteId)2946 t_Error FmVSPGetAbsoluteProfileId(t_Handle h_Fm,
2947 e_FmPortType portType,
2948 uint8_t portId,
2949 uint16_t relativeProfile,
2950 uint16_t *p_AbsoluteId)
2951 {
2952 t_Fm *p_Fm;
2953 t_FmSp *p_FmPcdSp;
2954 uint8_t swPortIndex=0, hardwarePortId;
2955 t_Error err;
2956
2957 ASSERT_COND(h_Fm);
2958 p_Fm = (t_Fm*)h_Fm;
2959
2960 err = FmVSPCheckRelativeProfile(h_Fm, portType, portId, relativeProfile);
2961 if (err != E_OK)
2962 return err;
2963
2964 hardwarePortId = SwPortIdToHwPortId(portType,
2965 portId,
2966 p_Fm->p_FmStateStruct->revInfo.majorRev,
2967 p_Fm->p_FmStateStruct->revInfo.minorRev);
2968 ASSERT_COND(hardwarePortId);
2969 HW_PORT_ID_TO_SW_PORT_INDX(swPortIndex, hardwarePortId);
2970
2971 p_FmPcdSp = p_Fm->p_FmSp;
2972 ASSERT_COND(p_FmPcdSp);
2973
2974 *p_AbsoluteId = (uint16_t)(p_FmPcdSp->portsMapping[swPortIndex].profilesBase + relativeProfile);
2975
2976 return E_OK;
2977 }
2978 #endif /* (DPAA_VERSION >= 11) */
2979
InitFmDma(t_Fm * p_Fm)2980 static t_Error InitFmDma(t_Fm *p_Fm)
2981 {
2982 t_Error err;
2983
2984 err = (t_Error)fman_dma_init(p_Fm->p_FmDmaRegs, p_Fm->p_FmDriverParam);
2985 if (err != E_OK)
2986 return err;
2987
2988 /* Allocate MURAM for CAM */
2989 p_Fm->camBaseAddr = PTR_TO_UINT(FM_MURAM_AllocMem(p_Fm->h_FmMuram,
2990 (uint32_t)(p_Fm->p_FmDriverParam->dma_cam_num_of_entries*DMA_CAM_SIZEOF_ENTRY),
2991 DMA_CAM_ALIGN));
2992 if (!p_Fm->camBaseAddr)
2993 RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM alloc for DMA CAM failed"));
2994
2995 WRITE_BLOCK(UINT_TO_PTR(p_Fm->camBaseAddr),
2996 0,
2997 (uint32_t)(p_Fm->p_FmDriverParam->dma_cam_num_of_entries*DMA_CAM_SIZEOF_ENTRY));
2998
2999 if (p_Fm->p_FmStateStruct->revInfo.majorRev == 2)
3000 {
3001 FM_MURAM_FreeMem(p_Fm->h_FmMuram, UINT_TO_PTR(p_Fm->camBaseAddr));
3002
3003 p_Fm->camBaseAddr = PTR_TO_UINT(FM_MURAM_AllocMem(p_Fm->h_FmMuram,
3004 (uint32_t)(p_Fm->p_FmDriverParam->dma_cam_num_of_entries*72 + 128),
3005 64));
3006 if (!p_Fm->camBaseAddr)
3007 RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM alloc for DMA CAM failed"));
3008
3009 WRITE_BLOCK(UINT_TO_PTR(p_Fm->camBaseAddr),
3010 0,
3011 (uint32_t)(p_Fm->p_FmDriverParam->dma_cam_num_of_entries*72 + 128));
3012
3013 switch(p_Fm->p_FmDriverParam->dma_cam_num_of_entries)
3014 {
3015 case (8):
3016 WRITE_UINT32(*(uint32_t*)p_Fm->camBaseAddr, 0xff000000);
3017 break;
3018 case (16):
3019 WRITE_UINT32(*(uint32_t*)p_Fm->camBaseAddr, 0xffff0000);
3020 break;
3021 case (24):
3022 WRITE_UINT32(*(uint32_t*)p_Fm->camBaseAddr, 0xffffff00);
3023 break;
3024 case (32):
3025 WRITE_UINT32(*(uint32_t*)p_Fm->camBaseAddr, 0xffffffff);
3026 break;
3027 default:
3028 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("wrong dma_cam_num_of_entries"));
3029 }
3030 }
3031
3032 p_Fm->p_FmDriverParam->cam_base_addr =
3033 (uint32_t)(XX_VirtToPhys(UINT_TO_PTR(p_Fm->camBaseAddr)) - p_Fm->fmMuramPhysBaseAddr);
3034
3035 return E_OK;
3036 }
3037
InitFmFpm(t_Fm * p_Fm)3038 static t_Error InitFmFpm(t_Fm *p_Fm)
3039 {
3040 return (t_Error)fman_fpm_init(p_Fm->p_FmFpmRegs, p_Fm->p_FmDriverParam);
3041 }
3042
InitFmBmi(t_Fm * p_Fm)3043 static t_Error InitFmBmi(t_Fm *p_Fm)
3044 {
3045 return (t_Error)fman_bmi_init(p_Fm->p_FmBmiRegs, p_Fm->p_FmDriverParam);
3046 }
3047
InitFmQmi(t_Fm * p_Fm)3048 static t_Error InitFmQmi(t_Fm *p_Fm)
3049 {
3050 return (t_Error)fman_qmi_init(p_Fm->p_FmQmiRegs, p_Fm->p_FmDriverParam);
3051 }
3052
InitGuestMode(t_Fm * p_Fm)3053 static t_Error InitGuestMode(t_Fm *p_Fm)
3054 {
3055 t_Error err = E_OK;
3056 int i;
3057 t_FmIpcMsg msg;
3058 t_FmIpcReply reply;
3059 uint32_t replyLength;
3060
3061 ASSERT_COND(p_Fm);
3062 ASSERT_COND(p_Fm->guestId != NCSW_MASTER_ID);
3063
3064 /* build the FM guest partition IPC address */
3065 if (Sprint (p_Fm->fmModuleName, "FM_%d_%d",p_Fm->p_FmStateStruct->fmId, p_Fm->guestId) != (p_Fm->guestId<10 ? 6:7))
3066 RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Sprint failed"));
3067
3068 /* build the FM master partition IPC address */
3069 memset(p_Fm->fmIpcHandlerModuleName, 0, (sizeof(char)) * MODULE_NAME_SIZE);
3070 if (Sprint (p_Fm->fmIpcHandlerModuleName[0], "FM_%d_%d",p_Fm->p_FmStateStruct->fmId, NCSW_MASTER_ID) != 6)
3071 RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Sprint failed"));
3072
3073 for (i=0;i<e_FM_EV_DUMMY_LAST;i++)
3074 p_Fm->intrMng[i].f_Isr = UnimplementedIsr;
3075
3076 p_Fm->h_IpcSessions[0] = XX_IpcInitSession(p_Fm->fmIpcHandlerModuleName[0], p_Fm->fmModuleName);
3077 if (p_Fm->h_IpcSessions[0])
3078 {
3079 uint8_t isMasterAlive;
3080 t_FmIpcParams ipcParams;
3081
3082 err = XX_IpcRegisterMsgHandler(p_Fm->fmModuleName, FmGuestHandleIpcMsgCB, p_Fm, FM_IPC_MAX_REPLY_SIZE);
3083 if (err)
3084 RETURN_ERROR(MAJOR, err, NO_MSG);
3085
3086 memset(&msg, 0, sizeof(msg));
3087 memset(&reply, 0, sizeof(reply));
3088 msg.msgId = FM_MASTER_IS_ALIVE;
3089 msg.msgBody[0] = p_Fm->guestId;
3090 replyLength = sizeof(uint32_t) + sizeof(uint8_t);
3091 do
3092 {
3093 blockingFlag = TRUE;
3094 if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
3095 (uint8_t*)&msg,
3096 sizeof(msg.msgId)+sizeof(p_Fm->guestId),
3097 (uint8_t*)&reply,
3098 &replyLength,
3099 IpcMsgCompletionCB,
3100 p_Fm)) != E_OK)
3101 REPORT_ERROR(MINOR, err, NO_MSG);
3102 while (blockingFlag) ;
3103 if (replyLength != (sizeof(uint32_t) + sizeof(uint8_t)))
3104 REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
3105 isMasterAlive = *(uint8_t*)(reply.replyBody);
3106 } while (!isMasterAlive);
3107
3108 /* read FM parameters and save */
3109 memset(&msg, 0, sizeof(msg));
3110 memset(&reply, 0, sizeof(reply));
3111 msg.msgId = FM_GET_PARAMS;
3112 replyLength = sizeof(uint32_t) + sizeof(t_FmIpcParams);
3113 if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
3114 (uint8_t*)&msg,
3115 sizeof(msg.msgId),
3116 (uint8_t*)&reply,
3117 &replyLength,
3118 NULL,
3119 NULL)) != E_OK)
3120 RETURN_ERROR(MAJOR, err, NO_MSG);
3121 if (replyLength != (sizeof(uint32_t) + sizeof(t_FmIpcParams)))
3122 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
3123 memcpy((uint8_t*)&ipcParams, reply.replyBody, sizeof(t_FmIpcParams));
3124
3125 p_Fm->p_FmStateStruct->fmClkFreq = ipcParams.fmClkFreq;
3126 p_Fm->p_FmStateStruct->fmMacClkFreq = ipcParams.fmMacClkFreq;
3127 p_Fm->p_FmStateStruct->revInfo.majorRev = ipcParams.majorRev;
3128 p_Fm->p_FmStateStruct->revInfo.minorRev = ipcParams.minorRev;
3129 }
3130 else
3131 {
3132 DBG(WARNING, ("FM Guest mode - without IPC"));
3133 if (!p_Fm->p_FmStateStruct->fmClkFreq)
3134 RETURN_ERROR(MAJOR, E_INVALID_STATE, ("No fmClkFreq configured for guest without IPC"));
3135 if (p_Fm->baseAddr)
3136 {
3137 fman_get_revision(p_Fm->p_FmFpmRegs,
3138 &p_Fm->p_FmStateStruct->revInfo.majorRev,
3139 &p_Fm->p_FmStateStruct->revInfo.minorRev);
3140
3141 }
3142 }
3143
3144 #if (DPAA_VERSION >= 11)
3145 p_Fm->partVSPBase = AllocVSPsForPartition(p_Fm, p_Fm->partVSPBase, p_Fm->partNumOfVSPs, p_Fm->guestId);
3146 if (p_Fm->partVSPBase == (uint8_t)(ILLEGAL_BASE))
3147 DBG(WARNING, ("partition VSPs allocation is FAILED"));
3148 #endif /* (DPAA_VERSION >= 11) */
3149
3150 /* General FM driver initialization */
3151 if (p_Fm->baseAddr)
3152 p_Fm->fmMuramPhysBaseAddr =
3153 (uint64_t)(XX_VirtToPhys(UINT_TO_PTR(p_Fm->baseAddr + FM_MM_MURAM)));
3154
3155 XX_Free(p_Fm->p_FmDriverParam);
3156 p_Fm->p_FmDriverParam = NULL;
3157
3158 if ((p_Fm->guestId == NCSW_MASTER_ID) ||
3159 (p_Fm->h_IpcSessions[0]))
3160 {
3161 FM_DisableRamsEcc(p_Fm);
3162 FmMuramClear(p_Fm->h_FmMuram);
3163 FM_EnableRamsEcc(p_Fm);
3164 }
3165
3166 return E_OK;
3167 }
3168
FmanExceptionTrans(e_FmExceptions exception)3169 static __inline__ enum fman_exceptions FmanExceptionTrans(e_FmExceptions exception)
3170 {
3171 switch (exception) {
3172 case e_FM_EX_DMA_BUS_ERROR:
3173 return E_FMAN_EX_DMA_BUS_ERROR;
3174 case e_FM_EX_DMA_READ_ECC:
3175 return E_FMAN_EX_DMA_READ_ECC;
3176 case e_FM_EX_DMA_SYSTEM_WRITE_ECC:
3177 return E_FMAN_EX_DMA_SYSTEM_WRITE_ECC;
3178 case e_FM_EX_DMA_FM_WRITE_ECC:
3179 return E_FMAN_EX_DMA_FM_WRITE_ECC;
3180 case e_FM_EX_FPM_STALL_ON_TASKS:
3181 return E_FMAN_EX_FPM_STALL_ON_TASKS;
3182 case e_FM_EX_FPM_SINGLE_ECC:
3183 return E_FMAN_EX_FPM_SINGLE_ECC;
3184 case e_FM_EX_FPM_DOUBLE_ECC:
3185 return E_FMAN_EX_FPM_DOUBLE_ECC;
3186 case e_FM_EX_QMI_SINGLE_ECC:
3187 return E_FMAN_EX_QMI_SINGLE_ECC;
3188 case e_FM_EX_QMI_DOUBLE_ECC:
3189 return E_FMAN_EX_QMI_DOUBLE_ECC;
3190 case e_FM_EX_QMI_DEQ_FROM_UNKNOWN_PORTID:
3191 return E_FMAN_EX_QMI_DEQ_FROM_UNKNOWN_PORTID;
3192 case e_FM_EX_BMI_LIST_RAM_ECC:
3193 return E_FMAN_EX_BMI_LIST_RAM_ECC;
3194 case e_FM_EX_BMI_STORAGE_PROFILE_ECC:
3195 return E_FMAN_EX_BMI_STORAGE_PROFILE_ECC;
3196 case e_FM_EX_BMI_STATISTICS_RAM_ECC:
3197 return E_FMAN_EX_BMI_STATISTICS_RAM_ECC;
3198 case e_FM_EX_BMI_DISPATCH_RAM_ECC:
3199 return E_FMAN_EX_BMI_DISPATCH_RAM_ECC;
3200 case e_FM_EX_IRAM_ECC:
3201 return E_FMAN_EX_IRAM_ECC;
3202 case e_FM_EX_MURAM_ECC:
3203 return E_FMAN_EX_MURAM_ECC;
3204 default:
3205 return E_FMAN_EX_DMA_BUS_ERROR;
3206 }
3207 }
3208
SwPortIdToHwPortId(e_FmPortType type,uint8_t relativePortId,uint8_t majorRev,uint8_t minorRev)3209 uint8_t SwPortIdToHwPortId(e_FmPortType type, uint8_t relativePortId, uint8_t majorRev, uint8_t minorRev)
3210 {
3211 switch (type)
3212 {
3213 case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
3214 case (e_FM_PORT_TYPE_OH_HOST_COMMAND):
3215 CHECK_PORT_ID_OH_PORTS(relativePortId);
3216 return (uint8_t)(BASE_OH_PORTID + (relativePortId));
3217 case (e_FM_PORT_TYPE_RX):
3218 CHECK_PORT_ID_1G_RX_PORTS(relativePortId);
3219 return (uint8_t)(BASE_1G_RX_PORTID + (relativePortId));
3220 case (e_FM_PORT_TYPE_RX_10G):
3221 /* The 10G port in T1024 (FMan Version 6.4) is the first port.
3222 * This is the reason why the 1G port offset is used.
3223 */
3224 if (majorRev == 6 && minorRev == 4)
3225 {
3226 CHECK_PORT_ID_1G_RX_PORTS(relativePortId);
3227 return (uint8_t)(BASE_1G_RX_PORTID + (relativePortId));
3228 }
3229 else
3230 {
3231 CHECK_PORT_ID_10G_RX_PORTS(relativePortId);
3232 return (uint8_t)(BASE_10G_RX_PORTID + (relativePortId));
3233 }
3234 case (e_FM_PORT_TYPE_TX):
3235 CHECK_PORT_ID_1G_TX_PORTS(relativePortId);
3236 return (uint8_t)(BASE_1G_TX_PORTID + (relativePortId));
3237 case (e_FM_PORT_TYPE_TX_10G):
3238 /* The 10G port in T1024 (FMan Version 6.4) is the first port.
3239 * This is the reason why the 1G port offset is used.
3240 */
3241 if (majorRev == 6 && minorRev == 4)
3242 {
3243 CHECK_PORT_ID_1G_TX_PORTS(relativePortId);
3244 return (uint8_t)(BASE_1G_TX_PORTID + (relativePortId));
3245 }
3246 else
3247 {
3248 CHECK_PORT_ID_10G_TX_PORTS(relativePortId);
3249 return (uint8_t)(BASE_10G_TX_PORTID + (relativePortId));
3250 }
3251 default:
3252 REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal port type"));
3253 return 0;
3254 }
3255 }
3256
3257 #if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
FmDumpPortRegs(t_Handle h_Fm,uint8_t hardwarePortId)3258 t_Error FmDumpPortRegs (t_Handle h_Fm, uint8_t hardwarePortId)
3259 {
3260 t_Fm *p_Fm = (t_Fm *)h_Fm;
3261
3262 DECLARE_DUMP;
3263
3264 ASSERT_COND(IN_RANGE(1, hardwarePortId, 63));
3265
3266 SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
3267 SANITY_CHECK_RETURN_ERROR(((p_Fm->guestId == NCSW_MASTER_ID) ||
3268 p_Fm->baseAddr), E_INVALID_OPERATION);
3269
3270 DUMP_TITLE(&p_Fm->p_FmBmiRegs->fmbm_pp[hardwarePortId-1], ("fmbm_pp for port %u", (hardwarePortId)));
3271 DUMP_MEMORY(&p_Fm->p_FmBmiRegs->fmbm_pp[hardwarePortId-1], sizeof(uint32_t));
3272
3273 DUMP_TITLE(&p_Fm->p_FmBmiRegs->fmbm_pfs[hardwarePortId-1], ("fmbm_pfs for port %u", (hardwarePortId )));
3274 DUMP_MEMORY(&p_Fm->p_FmBmiRegs->fmbm_pfs[hardwarePortId-1], sizeof(uint32_t));
3275
3276 DUMP_TITLE(&p_Fm->p_FmBmiRegs->fmbm_spliodn[hardwarePortId-1], ("fmbm_spliodn for port %u", (hardwarePortId)));
3277 DUMP_MEMORY(&p_Fm->p_FmBmiRegs->fmbm_spliodn[hardwarePortId-1], sizeof(uint32_t));
3278
3279 DUMP_TITLE(&p_Fm->p_FmFpmRegs->fmfp_ps[hardwarePortId], ("fmfp_ps for port %u", (hardwarePortId)));
3280 DUMP_MEMORY(&p_Fm->p_FmFpmRegs->fmfp_ps[hardwarePortId], sizeof(uint32_t));
3281
3282 DUMP_TITLE(&p_Fm->p_FmDmaRegs->fmdmplr[hardwarePortId/2], ("fmdmplr for port %u", (hardwarePortId)));
3283 DUMP_MEMORY(&p_Fm->p_FmDmaRegs->fmdmplr[hardwarePortId/2], sizeof(uint32_t));
3284
3285 return E_OK;
3286 }
3287 #endif /* (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0)) */
3288
3289
3290 /*****************************************************************************/
3291 /* API Init unit functions */
3292 /*****************************************************************************/
FM_Config(t_FmParams * p_FmParam)3293 t_Handle FM_Config(t_FmParams *p_FmParam)
3294 {
3295 t_Fm *p_Fm;
3296 uint8_t i;
3297 uintptr_t baseAddr;
3298
3299 SANITY_CHECK_RETURN_VALUE(p_FmParam, E_NULL_POINTER, NULL);
3300 SANITY_CHECK_RETURN_VALUE(((p_FmParam->firmware.p_Code && p_FmParam->firmware.size) ||
3301 (!p_FmParam->firmware.p_Code && !p_FmParam->firmware.size)),
3302 E_INVALID_VALUE, NULL);
3303
3304 baseAddr = p_FmParam->baseAddr;
3305
3306 /* Allocate FM structure */
3307 p_Fm = (t_Fm *) XX_Malloc(sizeof(t_Fm));
3308 if (!p_Fm)
3309 {
3310 REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM driver structure"));
3311 return NULL;
3312 }
3313 memset(p_Fm, 0, sizeof(t_Fm));
3314
3315 p_Fm->p_FmStateStruct = (t_FmStateStruct *) XX_Malloc(sizeof(t_FmStateStruct));
3316 if (!p_Fm->p_FmStateStruct)
3317 {
3318 XX_Free(p_Fm);
3319 REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM Status structure"));
3320 return NULL;
3321 }
3322 memset(p_Fm->p_FmStateStruct, 0, sizeof(t_FmStateStruct));
3323
3324 /* Initialize FM parameters which will be kept by the driver */
3325 p_Fm->p_FmStateStruct->fmId = p_FmParam->fmId;
3326 p_Fm->guestId = p_FmParam->guestId;
3327
3328 for (i=0; i<FM_MAX_NUM_OF_HW_PORT_IDS; i++)
3329 p_Fm->p_FmStateStruct->portsTypes[i] = e_FM_PORT_TYPE_DUMMY;
3330
3331 /* Allocate the FM driver's parameters structure */
3332 p_Fm->p_FmDriverParam = (struct fman_cfg *)XX_Malloc(sizeof(struct fman_cfg));
3333 if (!p_Fm->p_FmDriverParam)
3334 {
3335 XX_Free(p_Fm->p_FmStateStruct);
3336 XX_Free(p_Fm);
3337 REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM driver parameters"));
3338 return NULL;
3339 }
3340 memset(p_Fm->p_FmDriverParam, 0, sizeof(struct fman_cfg));
3341
3342 #if (DPAA_VERSION >= 11)
3343 p_Fm->p_FmSp = (t_FmSp *)XX_Malloc(sizeof(t_FmSp));
3344 if (!p_Fm->p_FmSp)
3345 {
3346 XX_Free(p_Fm->p_FmDriverParam);
3347 XX_Free(p_Fm->p_FmStateStruct);
3348 XX_Free(p_Fm);
3349 REPORT_ERROR(MAJOR, E_NO_MEMORY, ("allocation for internal data structure failed"));
3350 return NULL;
3351 }
3352 memset(p_Fm->p_FmSp, 0, sizeof(t_FmSp));
3353
3354 for (i=0; i<FM_VSP_MAX_NUM_OF_ENTRIES; i++)
3355 p_Fm->p_FmSp->profiles[i].profilesMng.ownerId = (uint8_t)ILLEGAL_BASE;
3356 #endif /* (DPAA_VERSION >= 11) */
3357
3358 /* Initialize FM parameters which will be kept by the driver */
3359 p_Fm->p_FmStateStruct->fmId = p_FmParam->fmId;
3360 p_Fm->h_FmMuram = p_FmParam->h_FmMuram;
3361 p_Fm->h_App = p_FmParam->h_App;
3362 p_Fm->p_FmStateStruct->fmClkFreq = p_FmParam->fmClkFreq;
3363 p_Fm->p_FmStateStruct->fmMacClkFreq = p_FmParam->fmClkFreq / ((!p_FmParam->fmMacClkRatio)? 2: p_FmParam->fmMacClkRatio);
3364 p_Fm->f_Exception = p_FmParam->f_Exception;
3365 p_Fm->f_BusError = p_FmParam->f_BusError;
3366 p_Fm->p_FmFpmRegs = (struct fman_fpm_regs *)UINT_TO_PTR(baseAddr + FM_MM_FPM);
3367 p_Fm->p_FmBmiRegs = (struct fman_bmi_regs *)UINT_TO_PTR(baseAddr + FM_MM_BMI);
3368 p_Fm->p_FmQmiRegs = (struct fman_qmi_regs *)UINT_TO_PTR(baseAddr + FM_MM_QMI);
3369 p_Fm->p_FmDmaRegs = (struct fman_dma_regs *)UINT_TO_PTR(baseAddr + FM_MM_DMA);
3370 p_Fm->p_FmRegs = (struct fman_regs *)UINT_TO_PTR(baseAddr + FM_MM_BMI);
3371 p_Fm->baseAddr = baseAddr;
3372 p_Fm->p_FmStateStruct->irq = p_FmParam->irq;
3373 p_Fm->p_FmStateStruct->errIrq = p_FmParam->errIrq;
3374 p_Fm->hcPortInitialized = FALSE;
3375 p_Fm->independentMode = FALSE;
3376
3377 p_Fm->h_Spinlock = XX_InitSpinlock();
3378 if (!p_Fm->h_Spinlock)
3379 {
3380 XX_Free(p_Fm->p_FmDriverParam);
3381 XX_Free(p_Fm->p_FmStateStruct);
3382 XX_Free(p_Fm);
3383 REPORT_ERROR(MAJOR, E_INVALID_STATE, ("can't allocate spinlock!"));
3384 return NULL;
3385 }
3386
3387 #if (DPAA_VERSION >= 11)
3388 p_Fm->partVSPBase = p_FmParam->partVSPBase;
3389 p_Fm->partNumOfVSPs = p_FmParam->partNumOfVSPs;
3390 p_Fm->vspBaseAddr = p_FmParam->vspBaseAddr;
3391 #endif /* (DPAA_VERSION >= 11) */
3392
3393 fman_defconfig(p_Fm->p_FmDriverParam,
3394 !!(p_Fm->guestId == NCSW_MASTER_ID));
3395 /* overide macros dependent parameters */
3396 #ifdef FM_PEDANTIC_DMA
3397 p_Fm->p_FmDriverParam->pedantic_dma = TRUE;
3398 p_Fm->p_FmDriverParam->dma_aid_override = TRUE;
3399 #endif /* FM_PEDANTIC_DMA */
3400 #ifndef FM_QMI_NO_DEQ_OPTIONS_SUPPORT
3401 p_Fm->p_FmDriverParam->qmi_deq_option_support = TRUE;
3402 #endif /* !FM_QMI_NO_DEQ_OPTIONS_SUPPORT */
3403
3404 p_Fm->p_FmStateStruct->ramsEccEnable = FALSE;
3405 p_Fm->p_FmStateStruct->extraFifoPoolSize = 0;
3406 p_Fm->p_FmStateStruct->exceptions = DEFAULT_exceptions;
3407 p_Fm->resetOnInit = DEFAULT_resetOnInit;
3408 p_Fm->f_ResetOnInitOverride = DEFAULT_resetOnInitOverrideCallback;
3409 p_Fm->fwVerify = DEFAULT_VerifyUcode;
3410 p_Fm->firmware.size = p_FmParam->firmware.size;
3411 if (p_Fm->firmware.size)
3412 {
3413 p_Fm->firmware.p_Code = (uint32_t *)XX_Malloc(p_Fm->firmware.size);
3414 if (!p_Fm->firmware.p_Code)
3415 {
3416 XX_FreeSpinlock(p_Fm->h_Spinlock);
3417 XX_Free(p_Fm->p_FmStateStruct);
3418 XX_Free(p_Fm->p_FmDriverParam);
3419 XX_Free(p_Fm);
3420 REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM firmware code"));
3421 return NULL;
3422 }
3423 memcpy(p_Fm->firmware.p_Code, p_FmParam->firmware.p_Code ,p_Fm->firmware.size);
3424 }
3425
3426 if (p_Fm->guestId != NCSW_MASTER_ID)
3427 return p_Fm;
3428
3429 /* read revision */
3430 /* Chip dependent, will be configured in Init */
3431 fman_get_revision(p_Fm->p_FmFpmRegs,
3432 &p_Fm->p_FmStateStruct->revInfo.majorRev,
3433 &p_Fm->p_FmStateStruct->revInfo.minorRev);
3434
3435 #ifdef FM_AID_MODE_NO_TNUM_SW005
3436 if (p_Fm->p_FmStateStruct->revInfo.majorRev >= 6)
3437 p_Fm->p_FmDriverParam->dma_aid_mode = e_FM_DMA_AID_OUT_PORT_ID;
3438 #endif /* FM_AID_MODE_NO_TNUM_SW005 */
3439 #ifndef FM_QMI_NO_DEQ_OPTIONS_SUPPORT
3440 if (p_Fm->p_FmStateStruct->revInfo.majorRev != 4)
3441 p_Fm->p_FmDriverParam->qmi_def_tnums_thresh = QMI_DEF_TNUMS_THRESH;
3442 #endif /* FM_QMI_NO_DEQ_OPTIONS_SUPPORT */
3443
3444 p_Fm->p_FmStateStruct->totalFifoSize = 0;
3445 p_Fm->p_FmStateStruct->totalNumOfTasks =
3446 DEFAULT_totalNumOfTasks(p_Fm->p_FmStateStruct->revInfo.majorRev,
3447 p_Fm->p_FmStateStruct->revInfo.minorRev);
3448
3449 #ifdef FM_HAS_TOTAL_DMAS
3450 p_Fm->p_FmStateStruct->maxNumOfOpenDmas = BMI_MAX_NUM_OF_DMAS;
3451 #endif /* FM_HAS_TOTAL_DMAS */
3452 #if (DPAA_VERSION < 11)
3453 p_Fm->p_FmDriverParam->dma_comm_qtsh_clr_emer = DEFAULT_dmaCommQLow;
3454 p_Fm->p_FmDriverParam->dma_comm_qtsh_asrt_emer = DEFAULT_dmaCommQHigh;
3455 p_Fm->p_FmDriverParam->dma_cam_num_of_entries = DEFAULT_dmaCamNumOfEntries;
3456 p_Fm->p_FmDriverParam->dma_read_buf_tsh_clr_emer = DEFAULT_dmaReadIntBufLow;
3457 p_Fm->p_FmDriverParam->dma_read_buf_tsh_asrt_emer = DEFAULT_dmaReadIntBufHigh;
3458 p_Fm->p_FmDriverParam->dma_write_buf_tsh_clr_emer = DEFAULT_dmaWriteIntBufLow;
3459 p_Fm->p_FmDriverParam->dma_write_buf_tsh_asrt_emer = DEFAULT_dmaWriteIntBufHigh;
3460 p_Fm->p_FmDriverParam->dma_axi_dbg_num_of_beats = DEFAULT_axiDbgNumOfBeats;
3461 #endif /* (DPAA_VERSION < 11) */
3462 #ifdef FM_NO_TNUM_AGING
3463 p_Fm->p_FmDriverParam->tnum_aging_period = 0;
3464 #endif
3465 p_Fm->tnumAgingPeriod = p_Fm->p_FmDriverParam->tnum_aging_period;
3466
3467 return p_Fm;
3468 }
3469
3470 /**************************************************************************//**
3471 @Function FM_Init
3472
3473 @Description Initializes the FM module
3474
3475 @Param[in] h_Fm - FM module descriptor
3476
3477 @Return E_OK on success; Error code otherwise.
3478 *//***************************************************************************/
FM_Init(t_Handle h_Fm)3479 t_Error FM_Init(t_Handle h_Fm)
3480 {
3481 t_Fm *p_Fm = (t_Fm*)h_Fm;
3482 struct fman_cfg *p_FmDriverParam = NULL;
3483 t_Error err = E_OK;
3484 int i;
3485 t_FmRevisionInfo revInfo;
3486 struct fman_rg fman_rg;
3487
3488 SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
3489 SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
3490
3491 fman_rg.bmi_rg = p_Fm->p_FmBmiRegs;
3492 fman_rg.qmi_rg = p_Fm->p_FmQmiRegs;
3493 fman_rg.fpm_rg = p_Fm->p_FmFpmRegs;
3494 fman_rg.dma_rg = p_Fm->p_FmDmaRegs;
3495
3496 p_Fm->p_FmStateStruct->count1MicroBit = FM_TIMESTAMP_1_USEC_BIT;
3497 p_Fm->p_FmDriverParam->num_of_fman_ctrl_evnt_regs = FM_NUM_OF_FMAN_CTRL_EVENT_REGS;
3498
3499 if (p_Fm->guestId != NCSW_MASTER_ID)
3500 return InitGuestMode(p_Fm);
3501
3502 /* if user didn't configured totalFifoSize - (totalFifoSize=0) we configure default
3503 * according to chip. otherwise, we use user's configuration.
3504 */
3505 if (p_Fm->p_FmStateStruct->totalFifoSize == 0)
3506 p_Fm->p_FmStateStruct->totalFifoSize = DEFAULT_totalFifoSize(p_Fm->p_FmStateStruct->revInfo.majorRev,
3507 p_Fm->p_FmStateStruct->revInfo.minorRev);
3508
3509 CHECK_INIT_PARAMETERS(p_Fm, CheckFmParameters);
3510
3511 p_FmDriverParam = p_Fm->p_FmDriverParam;
3512
3513 FM_GetRevision(p_Fm, &revInfo);
3514
3515 /* clear revision-dependent non existing exception */
3516 #ifdef FM_NO_DISPATCH_RAM_ECC
3517 if ((revInfo.majorRev != 4) &&
3518 (revInfo.majorRev < 6))
3519 p_Fm->p_FmStateStruct->exceptions &= ~FM_EX_BMI_DISPATCH_RAM_ECC;
3520 #endif /* FM_NO_DISPATCH_RAM_ECC */
3521
3522 #ifdef FM_QMI_NO_ECC_EXCEPTIONS
3523 if (revInfo.majorRev == 4)
3524 p_Fm->p_FmStateStruct->exceptions &= ~(FM_EX_QMI_SINGLE_ECC | FM_EX_QMI_DOUBLE_ECC);
3525 #endif /* FM_QMI_NO_ECC_EXCEPTIONS */
3526
3527 #ifdef FM_QMI_NO_SINGLE_ECC_EXCEPTION
3528 if (revInfo.majorRev >= 6)
3529 p_Fm->p_FmStateStruct->exceptions &= ~FM_EX_QMI_SINGLE_ECC;
3530 #endif /* FM_QMI_NO_SINGLE_ECC_EXCEPTION */
3531
3532 FmMuramClear(p_Fm->h_FmMuram);
3533
3534 /* clear CPG */
3535 IOMemSet32(UINT_TO_PTR(p_Fm->baseAddr + FM_MM_CGP), 0, FM_PORT_NUM_OF_CONGESTION_GRPS);
3536
3537 /* add to the default exceptions the user's definitions */
3538 p_Fm->p_FmStateStruct->exceptions |= p_Fm->userSetExceptions;
3539
3540 /* Reset the FM if required */
3541 if (p_Fm->resetOnInit)
3542 {
3543 #ifdef FM_UCODE_NOT_RESET_ERRATA_BUGZILLA6173
3544 if ((err = FwNotResetErratumBugzilla6173WA(p_Fm)) != E_OK)
3545 RETURN_ERROR(MAJOR, err, NO_MSG);
3546 #else /* not FM_UCODE_NOT_RESET_ERRATA_BUGZILLA6173 */
3547
3548 if (p_Fm->f_ResetOnInitOverride)
3549 {
3550 /* Perform user specific FMan reset */
3551 p_Fm->f_ResetOnInitOverride(h_Fm);
3552 }
3553 else
3554 {
3555 /* Perform FMan reset */
3556 FmReset(h_Fm);
3557 }
3558
3559 if (fman_is_qmi_halt_not_busy_state(p_Fm->p_FmQmiRegs))
3560 {
3561 fman_resume(p_Fm->p_FmFpmRegs);
3562 XX_UDelay(100);
3563 }
3564 #endif /* not FM_UCODE_NOT_RESET_ERRATA_BUGZILLA6173 */
3565 }
3566
3567 #ifdef FM_UCODE_NOT_RESET_ERRATA_BUGZILLA6173
3568 if (!p_Fm->resetOnInit) /* Skip operations done in errata workaround */
3569 {
3570 #endif /* FM_UCODE_NOT_RESET_ERRATA_BUGZILLA6173 */
3571 /* Load FMan-Controller code to IRAM */
3572
3573 ClearIRam(p_Fm);
3574
3575 if (p_Fm->firmware.p_Code && (LoadFmanCtrlCode(p_Fm) != E_OK))
3576 RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
3577 #ifdef FM_UCODE_NOT_RESET_ERRATA_BUGZILLA6173
3578 }
3579 #endif /* FM_UCODE_NOT_RESET_ERRATA_BUGZILLA6173 */
3580
3581 #ifdef FM_CAPWAP_SUPPORT
3582 /* save first 256 byte in MURAM */
3583 p_Fm->resAddr = PTR_TO_UINT(FM_MURAM_AllocMem(p_Fm->h_FmMuram, 256, 0));
3584 if (!p_Fm->resAddr)
3585 RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM alloc for reserved Area failed"));
3586
3587 WRITE_BLOCK(UINT_TO_PTR(p_Fm->resAddr), 0, 256);
3588 #endif /* FM_CAPWAP_SUPPORT */
3589
3590 #if (DPAA_VERSION >= 11)
3591 p_Fm->partVSPBase = AllocVSPsForPartition(h_Fm, p_Fm->partVSPBase, p_Fm->partNumOfVSPs, p_Fm->guestId);
3592 if (p_Fm->partVSPBase == (uint8_t)(ILLEGAL_BASE))
3593 DBG(WARNING, ("partition VSPs allocation is FAILED"));
3594 #endif /* (DPAA_VERSION >= 11) */
3595
3596 /* General FM driver initialization */
3597 p_Fm->fmMuramPhysBaseAddr =
3598 (uint64_t)(XX_VirtToPhys(UINT_TO_PTR(p_Fm->baseAddr + FM_MM_MURAM)));
3599
3600 for (i=0;i<e_FM_EV_DUMMY_LAST;i++)
3601 p_Fm->intrMng[i].f_Isr = UnimplementedIsr;
3602 for (i=0;i<FM_NUM_OF_FMAN_CTRL_EVENT_REGS;i++)
3603 p_Fm->fmanCtrlIntr[i].f_Isr = UnimplementedFmanCtrlIsr;
3604
3605 p_FmDriverParam->exceptions = p_Fm->p_FmStateStruct->exceptions;
3606
3607 /**********************/
3608 /* Init DMA Registers */
3609 /**********************/
3610 err = InitFmDma(p_Fm);
3611 if (err != E_OK)
3612 {
3613 FreeInitResources(p_Fm);
3614 RETURN_ERROR(MAJOR, err, NO_MSG);
3615 }
3616
3617 /**********************/
3618 /* Init FPM Registers */
3619 /**********************/
3620 err = InitFmFpm(p_Fm);
3621 if (err != E_OK)
3622 {
3623 FreeInitResources(p_Fm);
3624 RETURN_ERROR(MAJOR, err, NO_MSG);
3625 }
3626
3627 /* define common resources */
3628 /* allocate MURAM for FIFO according to total size */
3629 p_Fm->fifoBaseAddr = PTR_TO_UINT(FM_MURAM_AllocMem(p_Fm->h_FmMuram,
3630 p_Fm->p_FmStateStruct->totalFifoSize,
3631 BMI_FIFO_ALIGN));
3632 if (!p_Fm->fifoBaseAddr)
3633 {
3634 FreeInitResources(p_Fm);
3635 RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM alloc for BMI FIFO failed"));
3636 }
3637
3638 p_FmDriverParam->fifo_base_addr = (uint32_t)(XX_VirtToPhys(UINT_TO_PTR(p_Fm->fifoBaseAddr)) - p_Fm->fmMuramPhysBaseAddr);
3639 p_FmDriverParam->total_fifo_size = p_Fm->p_FmStateStruct->totalFifoSize;
3640 p_FmDriverParam->total_num_of_tasks = p_Fm->p_FmStateStruct->totalNumOfTasks;
3641 p_FmDriverParam->clk_freq = p_Fm->p_FmStateStruct->fmClkFreq;
3642
3643 /**********************/
3644 /* Init BMI Registers */
3645 /**********************/
3646 err = InitFmBmi(p_Fm);
3647 if (err != E_OK)
3648 {
3649 FreeInitResources(p_Fm);
3650 RETURN_ERROR(MAJOR, err, NO_MSG);
3651 }
3652
3653 /**********************/
3654 /* Init QMI Registers */
3655 /**********************/
3656 err = InitFmQmi(p_Fm);
3657 if (err != E_OK)
3658 {
3659 FreeInitResources(p_Fm);
3660 RETURN_ERROR(MAJOR, err, NO_MSG);
3661 }
3662
3663 /* build the FM master partition IPC address */
3664 if (Sprint (p_Fm->fmModuleName, "FM_%d_%d",p_Fm->p_FmStateStruct->fmId, NCSW_MASTER_ID) != 6)
3665 {
3666 FreeInitResources(p_Fm);
3667 RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Sprint failed"));
3668 }
3669
3670 err = XX_IpcRegisterMsgHandler(p_Fm->fmModuleName, FmHandleIpcMsgCB, p_Fm, FM_IPC_MAX_REPLY_SIZE);
3671 if (err)
3672 {
3673 FreeInitResources(p_Fm);
3674 RETURN_ERROR(MAJOR, err, NO_MSG);
3675 }
3676
3677 /* Register the FM interrupts handlers */
3678 if (p_Fm->p_FmStateStruct->irq != NO_IRQ)
3679 {
3680 XX_SetIntr(p_Fm->p_FmStateStruct->irq, FM_EventIsr, p_Fm);
3681 XX_EnableIntr(p_Fm->p_FmStateStruct->irq);
3682 }
3683
3684 if (p_Fm->p_FmStateStruct->errIrq != NO_IRQ)
3685 {
3686 XX_SetIntr(p_Fm->p_FmStateStruct->errIrq, (void (*) (t_Handle))FM_ErrorIsr, p_Fm);
3687 XX_EnableIntr(p_Fm->p_FmStateStruct->errIrq);
3688 }
3689
3690 err = (t_Error)fman_enable(&fman_rg , p_FmDriverParam);
3691 if (err != E_OK)
3692 return err; /* FIXME */
3693
3694 EnableTimeStamp(p_Fm);
3695
3696 if (p_Fm->firmware.p_Code)
3697 {
3698 XX_Free(p_Fm->firmware.p_Code);
3699 p_Fm->firmware.p_Code = NULL;
3700 }
3701
3702 XX_Free(p_Fm->p_FmDriverParam);
3703 p_Fm->p_FmDriverParam = NULL;
3704
3705 return E_OK;
3706 }
3707
3708 /**************************************************************************//**
3709 @Function FM_Free
3710
3711 @Description Frees all resources that were assigned to FM module.
3712
3713 Calling this routine invalidates the descriptor.
3714
3715 @Param[in] h_Fm - FM module descriptor
3716
3717 @Return E_OK on success; Error code otherwise.
3718 *//***************************************************************************/
FM_Free(t_Handle h_Fm)3719 t_Error FM_Free(t_Handle h_Fm)
3720 {
3721 t_Fm *p_Fm = (t_Fm*)h_Fm;
3722 struct fman_rg fman_rg;
3723
3724 SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
3725
3726 fman_rg.bmi_rg = p_Fm->p_FmBmiRegs;
3727 fman_rg.qmi_rg = p_Fm->p_FmQmiRegs;
3728 fman_rg.fpm_rg = p_Fm->p_FmFpmRegs;
3729 fman_rg.dma_rg = p_Fm->p_FmDmaRegs;
3730
3731 if (p_Fm->guestId != NCSW_MASTER_ID)
3732 {
3733 #if (DPAA_VERSION >= 11)
3734 FreeVSPsForPartition(h_Fm, p_Fm->partVSPBase, p_Fm->partNumOfVSPs, p_Fm->guestId);
3735
3736 if (p_Fm->p_FmSp)
3737 {
3738 XX_Free(p_Fm->p_FmSp);
3739 p_Fm->p_FmSp = NULL;
3740 }
3741 #endif /* (DPAA_VERSION >= 11) */
3742
3743 if (p_Fm->fmModuleName[0] != 0)
3744 XX_IpcUnregisterMsgHandler(p_Fm->fmModuleName);
3745
3746 if (!p_Fm->recoveryMode)
3747 XX_Free(p_Fm->p_FmStateStruct);
3748
3749 XX_Free(p_Fm);
3750
3751 return E_OK;
3752 }
3753
3754 fman_free_resources(&fman_rg);
3755
3756 if ((p_Fm->guestId == NCSW_MASTER_ID) && (p_Fm->fmModuleName[0] != 0))
3757 XX_IpcUnregisterMsgHandler(p_Fm->fmModuleName);
3758
3759 if (p_Fm->p_FmStateStruct)
3760 {
3761 if (p_Fm->p_FmStateStruct->irq != NO_IRQ)
3762 {
3763 XX_DisableIntr(p_Fm->p_FmStateStruct->irq);
3764 XX_FreeIntr(p_Fm->p_FmStateStruct->irq);
3765 }
3766 if (p_Fm->p_FmStateStruct->errIrq != NO_IRQ)
3767 {
3768 XX_DisableIntr(p_Fm->p_FmStateStruct->errIrq);
3769 XX_FreeIntr(p_Fm->p_FmStateStruct->errIrq);
3770 }
3771 }
3772
3773 #if (DPAA_VERSION >= 11)
3774 FreeVSPsForPartition(h_Fm, p_Fm->partVSPBase, p_Fm->partNumOfVSPs, p_Fm->guestId);
3775
3776 if (p_Fm->p_FmSp)
3777 {
3778 XX_Free(p_Fm->p_FmSp);
3779 p_Fm->p_FmSp = NULL;
3780 }
3781 #endif /* (DPAA_VERSION >= 11) */
3782
3783 if (p_Fm->h_Spinlock)
3784 XX_FreeSpinlock(p_Fm->h_Spinlock);
3785
3786 if (p_Fm->p_FmDriverParam)
3787 {
3788 if (p_Fm->firmware.p_Code)
3789 XX_Free(p_Fm->firmware.p_Code);
3790 XX_Free(p_Fm->p_FmDriverParam);
3791 p_Fm->p_FmDriverParam = NULL;
3792 }
3793
3794 FreeInitResources(p_Fm);
3795
3796 if (!p_Fm->recoveryMode && p_Fm->p_FmStateStruct)
3797 XX_Free(p_Fm->p_FmStateStruct);
3798
3799 XX_Free(p_Fm);
3800
3801 return E_OK;
3802 }
3803
3804 /*************************************************/
3805 /* API Advanced Init unit functions */
3806 /*************************************************/
3807
FM_ConfigResetOnInit(t_Handle h_Fm,bool enable)3808 t_Error FM_ConfigResetOnInit(t_Handle h_Fm, bool enable)
3809 {
3810 t_Fm *p_Fm = (t_Fm*)h_Fm;
3811
3812 SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
3813 SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
3814 SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
3815
3816 p_Fm->resetOnInit = enable;
3817
3818 return E_OK;
3819 }
3820
FM_ConfigResetOnInitOverrideCallback(t_Handle h_Fm,t_FmResetOnInitOverrideCallback * f_ResetOnInitOverride)3821 t_Error FM_ConfigResetOnInitOverrideCallback(t_Handle h_Fm, t_FmResetOnInitOverrideCallback *f_ResetOnInitOverride)
3822 {
3823 t_Fm *p_Fm = (t_Fm*)h_Fm;
3824
3825 SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
3826 SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
3827 SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
3828
3829 p_Fm->f_ResetOnInitOverride = f_ResetOnInitOverride;
3830
3831 return E_OK;
3832 }
3833
FM_ConfigTotalFifoSize(t_Handle h_Fm,uint32_t totalFifoSize)3834 t_Error FM_ConfigTotalFifoSize(t_Handle h_Fm, uint32_t totalFifoSize)
3835 {
3836 t_Fm *p_Fm = (t_Fm*)h_Fm;
3837
3838 SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
3839 SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
3840 SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
3841
3842 p_Fm->p_FmStateStruct->totalFifoSize = totalFifoSize;
3843
3844 return E_OK;
3845 }
3846
FM_ConfigDmaCacheOverride(t_Handle h_Fm,e_FmDmaCacheOverride cacheOverride)3847 t_Error FM_ConfigDmaCacheOverride(t_Handle h_Fm, e_FmDmaCacheOverride cacheOverride)
3848 {
3849 t_Fm *p_Fm = (t_Fm*)h_Fm;
3850 enum fman_dma_cache_override fsl_cache_override;
3851
3852 SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
3853 SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
3854 SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
3855
3856 FMAN_CACHE_OVERRIDE_TRANS(fsl_cache_override, cacheOverride)
3857 p_Fm->p_FmDriverParam->dma_cache_override = fsl_cache_override;
3858
3859 return E_OK;
3860 }
3861
FM_ConfigDmaAidOverride(t_Handle h_Fm,bool aidOverride)3862 t_Error FM_ConfigDmaAidOverride(t_Handle h_Fm, bool aidOverride)
3863 {
3864 t_Fm *p_Fm = (t_Fm*)h_Fm;
3865
3866 SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
3867 SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
3868 SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
3869
3870 p_Fm->p_FmDriverParam->dma_aid_override = aidOverride;
3871
3872 return E_OK;
3873 }
3874
FM_ConfigDmaAidMode(t_Handle h_Fm,e_FmDmaAidMode aidMode)3875 t_Error FM_ConfigDmaAidMode(t_Handle h_Fm, e_FmDmaAidMode aidMode)
3876 {
3877 t_Fm *p_Fm = (t_Fm*)h_Fm;
3878 enum fman_dma_aid_mode fsl_aid_mode;
3879
3880 SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
3881 SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
3882 SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
3883
3884 FMAN_AID_MODE_TRANS(fsl_aid_mode, aidMode);
3885 p_Fm->p_FmDriverParam->dma_aid_mode = fsl_aid_mode;
3886
3887 return E_OK;
3888 }
3889
FM_ConfigDmaAxiDbgNumOfBeats(t_Handle h_Fm,uint8_t axiDbgNumOfBeats)3890 t_Error FM_ConfigDmaAxiDbgNumOfBeats(t_Handle h_Fm, uint8_t axiDbgNumOfBeats)
3891 {
3892 t_Fm *p_Fm = (t_Fm*)h_Fm;
3893
3894 SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
3895 SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
3896 SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
3897
3898 #if (DPAA_VERSION >= 11)
3899 RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("Not available for this FM revision!"));
3900 #else
3901 p_Fm->p_FmDriverParam->dma_axi_dbg_num_of_beats = axiDbgNumOfBeats;
3902
3903 return E_OK;
3904 #endif /* (DPAA_VERSION >= 11) */
3905 }
3906
FM_ConfigDmaCamNumOfEntries(t_Handle h_Fm,uint8_t numOfEntries)3907 t_Error FM_ConfigDmaCamNumOfEntries(t_Handle h_Fm, uint8_t numOfEntries)
3908 {
3909 t_Fm *p_Fm = (t_Fm*)h_Fm;
3910
3911 SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
3912 SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
3913 SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
3914
3915 p_Fm->p_FmDriverParam->dma_cam_num_of_entries = numOfEntries;
3916
3917 return E_OK;
3918 }
3919
FM_ConfigDmaDbgCounter(t_Handle h_Fm,e_FmDmaDbgCntMode fmDmaDbgCntMode)3920 t_Error FM_ConfigDmaDbgCounter(t_Handle h_Fm, e_FmDmaDbgCntMode fmDmaDbgCntMode)
3921 {
3922 t_Fm *p_Fm = (t_Fm*)h_Fm;
3923 enum fman_dma_dbg_cnt_mode fsl_dma_dbg_cnt;
3924
3925 SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
3926 SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
3927 SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
3928
3929 FMAN_DMA_DBG_CNT_TRANS(fsl_dma_dbg_cnt, fmDmaDbgCntMode);
3930 p_Fm->p_FmDriverParam->dma_dbg_cnt_mode = fsl_dma_dbg_cnt;
3931
3932 return E_OK;
3933 }
3934
FM_ConfigDmaStopOnBusErr(t_Handle h_Fm,bool stop)3935 t_Error FM_ConfigDmaStopOnBusErr(t_Handle h_Fm, bool stop)
3936 {
3937 t_Fm *p_Fm = (t_Fm*)h_Fm;
3938
3939 SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
3940 SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
3941 SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
3942
3943 p_Fm->p_FmDriverParam->dma_stop_on_bus_error = stop;
3944
3945 return E_OK;
3946 }
3947
FM_ConfigDmaEmergency(t_Handle h_Fm,t_FmDmaEmergency * p_Emergency)3948 t_Error FM_ConfigDmaEmergency(t_Handle h_Fm, t_FmDmaEmergency *p_Emergency)
3949 {
3950 t_Fm *p_Fm = (t_Fm*)h_Fm;
3951 enum fman_dma_emergency_level fsl_dma_emer;
3952
3953 SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
3954 SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
3955 SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
3956
3957 FMAN_DMA_EMER_TRANS(fsl_dma_emer, p_Emergency->emergencyLevel);
3958 p_Fm->p_FmDriverParam->dma_en_emergency = TRUE;
3959 p_Fm->p_FmDriverParam->dma_emergency_bus_select = (uint32_t)p_Emergency->emergencyBusSelect;
3960 p_Fm->p_FmDriverParam->dma_emergency_level = fsl_dma_emer;
3961
3962 return E_OK;
3963 }
3964
FM_ConfigDmaEmergencySmoother(t_Handle h_Fm,uint32_t emergencyCnt)3965 t_Error FM_ConfigDmaEmergencySmoother(t_Handle h_Fm, uint32_t emergencyCnt)
3966 {
3967 t_Fm *p_Fm = (t_Fm*)h_Fm;
3968
3969 SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
3970 SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
3971 SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
3972
3973 p_Fm->p_FmDriverParam->dma_en_emergency_smoother = TRUE;
3974 p_Fm->p_FmDriverParam->dma_emergency_switch_counter = emergencyCnt;
3975
3976 return E_OK;
3977 }
3978
FM_ConfigDmaErr(t_Handle h_Fm,e_FmDmaErr dmaErr)3979 t_Error FM_ConfigDmaErr(t_Handle h_Fm, e_FmDmaErr dmaErr)
3980 {
3981 t_Fm *p_Fm = (t_Fm*)h_Fm;
3982 enum fman_dma_err fsl_dma_err;
3983
3984 SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
3985 SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
3986 SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
3987
3988 FMAN_DMA_ERR_TRANS(fsl_dma_err, dmaErr);
3989 p_Fm->p_FmDriverParam->dma_err = fsl_dma_err;
3990
3991 return E_OK;
3992 }
3993
FM_ConfigCatastrophicErr(t_Handle h_Fm,e_FmCatastrophicErr catastrophicErr)3994 t_Error FM_ConfigCatastrophicErr(t_Handle h_Fm, e_FmCatastrophicErr catastrophicErr)
3995 {
3996 t_Fm *p_Fm = (t_Fm*)h_Fm;
3997 enum fman_catastrophic_err fsl_catastrophic_err;
3998
3999 SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
4000 SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
4001 SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
4002
4003 FMAN_CATASTROPHIC_ERR_TRANS(fsl_catastrophic_err, catastrophicErr);
4004 p_Fm->p_FmDriverParam->catastrophic_err = fsl_catastrophic_err;
4005
4006 return E_OK;
4007 }
4008
FM_ConfigEnableMuramTestMode(t_Handle h_Fm)4009 t_Error FM_ConfigEnableMuramTestMode(t_Handle h_Fm)
4010 {
4011 t_Fm *p_Fm = (t_Fm*)h_Fm;
4012
4013 SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
4014 SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
4015 SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
4016
4017 if (p_Fm->p_FmStateStruct->revInfo.majorRev >= 6)
4018 RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("Not available for this FM revision!"));
4019
4020 p_Fm->p_FmDriverParam->en_muram_test_mode = TRUE;
4021
4022 return E_OK;
4023 }
4024
FM_ConfigEnableIramTestMode(t_Handle h_Fm)4025 t_Error FM_ConfigEnableIramTestMode(t_Handle h_Fm)
4026 {
4027 t_Fm *p_Fm = (t_Fm*)h_Fm;
4028
4029 SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE );
4030 SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
4031 SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
4032
4033 if (p_Fm->p_FmStateStruct->revInfo.majorRev >= 6)
4034 RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("Not available for this FM revision!"));
4035
4036 p_Fm->p_FmDriverParam->en_iram_test_mode = TRUE;
4037
4038 return E_OK;
4039 }
4040
FM_ConfigHaltOnExternalActivation(t_Handle h_Fm,bool enable)4041 t_Error FM_ConfigHaltOnExternalActivation(t_Handle h_Fm, bool enable)
4042 {
4043 t_Fm *p_Fm = (t_Fm*)h_Fm;
4044
4045 SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
4046 SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
4047 SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
4048
4049 p_Fm->p_FmDriverParam->halt_on_external_activ = enable;
4050
4051 return E_OK;
4052 }
4053
FM_ConfigHaltOnUnrecoverableEccError(t_Handle h_Fm,bool enable)4054 t_Error FM_ConfigHaltOnUnrecoverableEccError(t_Handle h_Fm, bool enable)
4055 {
4056 t_Fm *p_Fm = (t_Fm*)h_Fm;
4057
4058 SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
4059 SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
4060 SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
4061
4062 if (p_Fm->p_FmStateStruct->revInfo.majorRev >= 6)
4063 RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("Not available for this FM revision!"));
4064
4065 p_Fm->p_FmDriverParam->halt_on_unrecov_ecc_err = enable;
4066
4067 return E_OK;
4068 }
4069
FM_ConfigException(t_Handle h_Fm,e_FmExceptions exception,bool enable)4070 t_Error FM_ConfigException(t_Handle h_Fm, e_FmExceptions exception, bool enable)
4071 {
4072 t_Fm *p_Fm = (t_Fm*)h_Fm;
4073 uint32_t bitMask = 0;
4074
4075 SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
4076 SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
4077 SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
4078
4079 GET_EXCEPTION_FLAG(bitMask, exception);
4080 if (bitMask)
4081 {
4082 if (enable)
4083 p_Fm->userSetExceptions |= bitMask;
4084 else
4085 p_Fm->p_FmStateStruct->exceptions &= ~bitMask;
4086 }
4087 else
4088 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined exception"));
4089
4090 return E_OK;
4091 }
4092
FM_ConfigExternalEccRamsEnable(t_Handle h_Fm,bool enable)4093 t_Error FM_ConfigExternalEccRamsEnable(t_Handle h_Fm, bool enable)
4094 {
4095 t_Fm *p_Fm = (t_Fm*)h_Fm;
4096
4097 SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
4098 SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
4099 SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
4100
4101 p_Fm->p_FmDriverParam->external_ecc_rams_enable = enable;
4102
4103 return E_OK;
4104 }
4105
FM_ConfigTnumAgingPeriod(t_Handle h_Fm,uint16_t tnumAgingPeriod)4106 t_Error FM_ConfigTnumAgingPeriod(t_Handle h_Fm, uint16_t tnumAgingPeriod)
4107 {
4108 t_Fm *p_Fm = (t_Fm*)h_Fm;
4109
4110 SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
4111 SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
4112 SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
4113
4114 p_Fm->p_FmDriverParam->tnum_aging_period = tnumAgingPeriod;
4115 p_Fm->tnumAgingPeriod = p_Fm->p_FmDriverParam->tnum_aging_period;
4116
4117 return E_OK;
4118 }
4119
4120 /****************************************************/
4121 /* Hidden-DEBUG Only API */
4122 /****************************************************/
4123
FM_ConfigThresholds(t_Handle h_Fm,t_FmThresholds * p_FmThresholds)4124 t_Error FM_ConfigThresholds(t_Handle h_Fm, t_FmThresholds *p_FmThresholds)
4125 {
4126 t_Fm *p_Fm = (t_Fm*)h_Fm;
4127
4128 SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
4129 SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
4130 SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
4131
4132 p_Fm->p_FmDriverParam->disp_limit_tsh = p_FmThresholds->dispLimit;
4133 p_Fm->p_FmDriverParam->prs_disp_tsh = p_FmThresholds->prsDispTh;
4134 p_Fm->p_FmDriverParam->plcr_disp_tsh = p_FmThresholds->plcrDispTh;
4135 p_Fm->p_FmDriverParam->kg_disp_tsh = p_FmThresholds->kgDispTh;
4136 p_Fm->p_FmDriverParam->bmi_disp_tsh = p_FmThresholds->bmiDispTh;
4137 p_Fm->p_FmDriverParam->qmi_enq_disp_tsh = p_FmThresholds->qmiEnqDispTh;
4138 p_Fm->p_FmDriverParam->qmi_deq_disp_tsh = p_FmThresholds->qmiDeqDispTh;
4139 p_Fm->p_FmDriverParam->fm_ctl1_disp_tsh = p_FmThresholds->fmCtl1DispTh;
4140 p_Fm->p_FmDriverParam->fm_ctl2_disp_tsh = p_FmThresholds->fmCtl2DispTh;
4141
4142 return E_OK;
4143 }
4144
FM_ConfigDmaSosEmergencyThreshold(t_Handle h_Fm,uint32_t dmaSosEmergency)4145 t_Error FM_ConfigDmaSosEmergencyThreshold(t_Handle h_Fm, uint32_t dmaSosEmergency)
4146 {
4147 t_Fm *p_Fm = (t_Fm*)h_Fm;
4148
4149 SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
4150 SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
4151 SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
4152
4153 p_Fm->p_FmDriverParam->dma_sos_emergency = dmaSosEmergency;
4154
4155 return E_OK;
4156 }
4157
FM_ConfigDmaWriteBufThresholds(t_Handle h_Fm,t_FmDmaThresholds * p_FmDmaThresholds)4158 t_Error FM_ConfigDmaWriteBufThresholds(t_Handle h_Fm, t_FmDmaThresholds *p_FmDmaThresholds)
4159
4160 {
4161 t_Fm *p_Fm = (t_Fm*)h_Fm;
4162
4163 SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
4164 SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
4165 SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
4166
4167 #if (DPAA_VERSION >= 11)
4168 RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("Not available for this FM revision!"));
4169 #else
4170 p_Fm->p_FmDriverParam->dma_write_buf_tsh_asrt_emer = p_FmDmaThresholds->assertEmergency;
4171 p_Fm->p_FmDriverParam->dma_write_buf_tsh_clr_emer = p_FmDmaThresholds->clearEmergency;
4172
4173 return E_OK;
4174 #endif
4175 }
4176
FM_ConfigDmaCommQThresholds(t_Handle h_Fm,t_FmDmaThresholds * p_FmDmaThresholds)4177 t_Error FM_ConfigDmaCommQThresholds(t_Handle h_Fm, t_FmDmaThresholds *p_FmDmaThresholds)
4178 {
4179 t_Fm *p_Fm = (t_Fm*)h_Fm;
4180
4181 SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
4182 SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
4183 SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
4184
4185 p_Fm->p_FmDriverParam->dma_comm_qtsh_asrt_emer = p_FmDmaThresholds->assertEmergency;
4186 p_Fm->p_FmDriverParam->dma_comm_qtsh_clr_emer = p_FmDmaThresholds->clearEmergency;
4187
4188 return E_OK;
4189 }
4190
FM_ConfigDmaReadBufThresholds(t_Handle h_Fm,t_FmDmaThresholds * p_FmDmaThresholds)4191 t_Error FM_ConfigDmaReadBufThresholds(t_Handle h_Fm, t_FmDmaThresholds *p_FmDmaThresholds)
4192 {
4193 t_Fm *p_Fm = (t_Fm*)h_Fm;
4194
4195 SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
4196 SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
4197 SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
4198
4199 #if (DPAA_VERSION >= 11)
4200 RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("Not available for this FM revision!"));
4201 #else
4202 p_Fm->p_FmDriverParam->dma_read_buf_tsh_clr_emer = p_FmDmaThresholds->clearEmergency;
4203 p_Fm->p_FmDriverParam->dma_read_buf_tsh_asrt_emer = p_FmDmaThresholds->assertEmergency;
4204
4205 return E_OK;
4206 #endif
4207 }
4208
FM_ConfigDmaWatchdog(t_Handle h_Fm,uint32_t watchdogValue)4209 t_Error FM_ConfigDmaWatchdog(t_Handle h_Fm, uint32_t watchdogValue)
4210 {
4211 t_Fm *p_Fm = (t_Fm*)h_Fm;
4212
4213 SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
4214 SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
4215 SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
4216
4217 p_Fm->p_FmDriverParam->dma_watchdog = watchdogValue;
4218
4219 return E_OK;
4220 }
4221
FM_ConfigEnableCounters(t_Handle h_Fm)4222 t_Error FM_ConfigEnableCounters(t_Handle h_Fm)
4223 {
4224 t_Fm *p_Fm = (t_Fm*)h_Fm;
4225
4226 SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
4227 SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
4228 UNUSED(p_Fm);
4229
4230 return E_OK;
4231 }
4232
FmGetSetParams(t_Handle h_Fm,t_FmGetSetParams * p_Params)4233 t_Error FmGetSetParams(t_Handle h_Fm, t_FmGetSetParams *p_Params)
4234 {
4235 t_Fm* p_Fm = (t_Fm*)h_Fm;
4236 if (p_Params->setParams.type & UPDATE_FM_CLD)
4237 {
4238 WRITE_UINT32(p_Fm->p_FmFpmRegs->fm_cld, GET_UINT32(
4239 p_Fm->p_FmFpmRegs->fm_cld) | 0x00000800);
4240 }
4241 if (p_Params->setParams.type & CLEAR_IRAM_READY)
4242 {
4243 t_FMIramRegs *p_Iram = (t_FMIramRegs *)UINT_TO_PTR(p_Fm->baseAddr + FM_MM_IMEM);
4244 WRITE_UINT32(p_Iram->iready,GET_UINT32(p_Iram->iready) & ~IRAM_READY);
4245 }
4246 if (p_Params->setParams.type & UPDATE_FPM_EXTC)
4247 WRITE_UINT32(p_Fm->p_FmFpmRegs->fmfp_extc,0x80000000);
4248 if (p_Params->setParams.type & UPDATE_FPM_EXTC_CLEAR)
4249 WRITE_UINT32(p_Fm->p_FmFpmRegs->fmfp_extc,0x00800000);
4250 if (p_Params->setParams.type & UPDATE_FPM_BRKC_SLP)
4251 {
4252 if (p_Params->setParams.sleep)
4253 WRITE_UINT32(p_Fm->p_FmFpmRegs->fmfp_brkc, GET_UINT32(
4254 p_Fm->p_FmFpmRegs->fmfp_brkc) | FPM_BRKC_SLP);
4255 else
4256 WRITE_UINT32(p_Fm->p_FmFpmRegs->fmfp_brkc, GET_UINT32(
4257 p_Fm->p_FmFpmRegs->fmfp_brkc) & ~FPM_BRKC_SLP);
4258 }
4259 if (p_Params->getParams.type & GET_FM_CLD)
4260 p_Params->getParams.fm_cld = GET_UINT32(p_Fm->p_FmFpmRegs->fm_cld);
4261 if (p_Params->getParams.type & GET_FMQM_GS)
4262 p_Params->getParams.fmqm_gs = GET_UINT32(p_Fm->p_FmQmiRegs->fmqm_gs);
4263 if (p_Params->getParams.type & GET_FM_NPI)
4264 p_Params->getParams.fm_npi = GET_UINT32(p_Fm->p_FmFpmRegs->fm_npi);
4265 if (p_Params->getParams.type & GET_FMFP_EXTC)
4266 p_Params->getParams.fmfp_extc = GET_UINT32(p_Fm->p_FmFpmRegs->fmfp_extc);
4267 return E_OK;
4268 }
4269
4270
4271 /****************************************************/
4272 /* API Run-time Control uint functions */
4273 /****************************************************/
FM_EventIsr(t_Handle h_Fm)4274 void FM_EventIsr(t_Handle h_Fm)
4275 {
4276 #define FM_M_CALL_1G_MAC_ISR(_id) \
4277 { \
4278 if (p_Fm->guestId != p_Fm->intrMng[(e_FmInterModuleEvent)(e_FM_EV_1G_MAC0+_id)].guestId) \
4279 SendIpcIsr(p_Fm, (e_FmInterModuleEvent)(e_FM_EV_1G_MAC0+_id), pending); \
4280 else \
4281 p_Fm->intrMng[(e_FmInterModuleEvent)(e_FM_EV_1G_MAC0+_id)].f_Isr(p_Fm->intrMng[(e_FmInterModuleEvent)(e_FM_EV_1G_MAC0+_id)].h_SrcHandle);\
4282 }
4283 #define FM_M_CALL_10G_MAC_ISR(_id) \
4284 { \
4285 if (p_Fm->guestId != p_Fm->intrMng[(e_FmInterModuleEvent)(e_FM_EV_10G_MAC0+_id)].guestId) \
4286 SendIpcIsr(p_Fm, (e_FmInterModuleEvent)(e_FM_EV_10G_MAC0+_id), pending); \
4287 else \
4288 p_Fm->intrMng[(e_FmInterModuleEvent)(e_FM_EV_10G_MAC0+_id)].f_Isr(p_Fm->intrMng[(e_FmInterModuleEvent)(e_FM_EV_10G_MAC0+_id)].h_SrcHandle);\
4289 }
4290 t_Fm *p_Fm = (t_Fm*)h_Fm;
4291 uint32_t pending, event;
4292 struct fman_fpm_regs *fpm_rg;
4293
4294 SANITY_CHECK_RETURN(p_Fm, E_INVALID_HANDLE);
4295 SANITY_CHECK_RETURN(!p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
4296 SANITY_CHECK_RETURN((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
4297
4298 fpm_rg = p_Fm->p_FmFpmRegs;
4299
4300 /* normal interrupts */
4301 pending = fman_get_normal_pending(fpm_rg);
4302 if (!pending)
4303 return;
4304 if (pending & INTR_EN_WAKEUP) // this is a wake up from sleep interrupt
4305 {
4306 t_FmGetSetParams fmGetSetParams;
4307 memset(&fmGetSetParams, 0, sizeof (t_FmGetSetParams));
4308 fmGetSetParams.setParams.type = UPDATE_FPM_BRKC_SLP;
4309 fmGetSetParams.setParams.sleep = 0;
4310 FmGetSetParams(h_Fm, &fmGetSetParams);
4311 }
4312 if (pending & INTR_EN_QMI)
4313 QmiEvent(p_Fm);
4314 if (pending & INTR_EN_PRS)
4315 p_Fm->intrMng[e_FM_EV_PRS].f_Isr(p_Fm->intrMng[e_FM_EV_PRS].h_SrcHandle);
4316 if (pending & INTR_EN_PLCR)
4317 p_Fm->intrMng[e_FM_EV_PLCR].f_Isr(p_Fm->intrMng[e_FM_EV_PLCR].h_SrcHandle);
4318 if (pending & INTR_EN_TMR)
4319 p_Fm->intrMng[e_FM_EV_TMR].f_Isr(p_Fm->intrMng[e_FM_EV_TMR].h_SrcHandle);
4320
4321 /* MAC events may belong to different partitions */
4322 if (pending & INTR_EN_1G_MAC0)
4323 FM_M_CALL_1G_MAC_ISR(0);
4324 if (pending & INTR_EN_1G_MAC1)
4325 FM_M_CALL_1G_MAC_ISR(1);
4326 if (pending & INTR_EN_1G_MAC2)
4327 FM_M_CALL_1G_MAC_ISR(2);
4328 if (pending & INTR_EN_1G_MAC3)
4329 FM_M_CALL_1G_MAC_ISR(3);
4330 if (pending & INTR_EN_1G_MAC4)
4331 FM_M_CALL_1G_MAC_ISR(4);
4332 if (pending & INTR_EN_1G_MAC5)
4333 FM_M_CALL_1G_MAC_ISR(5);
4334 if (pending & INTR_EN_1G_MAC6)
4335 FM_M_CALL_1G_MAC_ISR(6);
4336 if (pending & INTR_EN_1G_MAC7)
4337 FM_M_CALL_1G_MAC_ISR(7);
4338 if (pending & INTR_EN_10G_MAC0)
4339 FM_M_CALL_10G_MAC_ISR(0);
4340 if (pending & INTR_EN_10G_MAC1)
4341 FM_M_CALL_10G_MAC_ISR(1);
4342
4343 /* IM port events may belong to different partitions */
4344 if (pending & INTR_EN_REV0)
4345 {
4346 event = fman_get_controller_event(fpm_rg, 0);
4347 if (p_Fm->guestId != p_Fm->intrMng[e_FM_EV_FMAN_CTRL_0].guestId)
4348 /*TODO IPC ISR For Fman Ctrl */
4349 ASSERT_COND(0);
4350 /* SendIpcIsr(p_Fm, e_FM_EV_FMAN_CTRL_0, pending); */
4351 else
4352 p_Fm->fmanCtrlIntr[0].f_Isr(p_Fm->fmanCtrlIntr[0].h_SrcHandle, event);
4353
4354 }
4355 if (pending & INTR_EN_REV1)
4356 {
4357 event = fman_get_controller_event(fpm_rg, 1);
4358 if (p_Fm->guestId != p_Fm->intrMng[e_FM_EV_FMAN_CTRL_1].guestId)
4359 /*TODO IPC ISR For Fman Ctrl */
4360 ASSERT_COND(0);
4361 /* SendIpcIsr(p_Fm, e_FM_EV_FMAN_CTRL_1, pending); */
4362 else
4363 p_Fm->fmanCtrlIntr[1].f_Isr(p_Fm->fmanCtrlIntr[1].h_SrcHandle, event);
4364 }
4365 if (pending & INTR_EN_REV2)
4366 {
4367 event = fman_get_controller_event(fpm_rg, 2);
4368 if (p_Fm->guestId != p_Fm->intrMng[e_FM_EV_FMAN_CTRL_2].guestId)
4369 /*TODO IPC ISR For Fman Ctrl */
4370 ASSERT_COND(0);
4371 /* SendIpcIsr(p_Fm, e_FM_EV_FMAN_CTRL_2, pending); */
4372 else
4373 p_Fm->fmanCtrlIntr[2].f_Isr(p_Fm->fmanCtrlIntr[2].h_SrcHandle, event);
4374 }
4375 if (pending & INTR_EN_REV3)
4376 {
4377 event = fman_get_controller_event(fpm_rg, 3);
4378 if (p_Fm->guestId != p_Fm->intrMng[e_FM_EV_FMAN_CTRL_3].guestId)
4379 /*TODO IPC ISR For Fman Ctrl */
4380 ASSERT_COND(0);
4381 /* SendIpcIsr(p_Fm, e_FM_EV_FMAN_CTRL_2, pendin3); */
4382 else
4383 p_Fm->fmanCtrlIntr[3].f_Isr(p_Fm->fmanCtrlIntr[3].h_SrcHandle, event);
4384 }
4385 #ifdef FM_MACSEC_SUPPORT
4386 if (pending & INTR_EN_MACSEC_MAC0)
4387 {
4388 if (p_Fm->guestId != p_Fm->intrMng[e_FM_EV_MACSEC_MAC0].guestId)
4389 SendIpcIsr(p_Fm, e_FM_EV_MACSEC_MAC0, pending);
4390 else
4391 p_Fm->intrMng[e_FM_EV_MACSEC_MAC0].f_Isr(p_Fm->intrMng[e_FM_EV_MACSEC_MAC0].h_SrcHandle);
4392 }
4393 #endif /* FM_MACSEC_SUPPORT */
4394 }
4395
FM_ErrorIsr(t_Handle h_Fm)4396 t_Error FM_ErrorIsr(t_Handle h_Fm)
4397 {
4398 #define FM_M_CALL_1G_MAC_ERR_ISR(_id) \
4399 { \
4400 if (p_Fm->guestId != p_Fm->intrMng[(e_FmInterModuleEvent)(e_FM_EV_ERR_1G_MAC0+_id)].guestId) \
4401 SendIpcIsr(p_Fm, (e_FmInterModuleEvent)(e_FM_EV_ERR_1G_MAC0+_id), pending); \
4402 else \
4403 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);\
4404 }
4405 #define FM_M_CALL_10G_MAC_ERR_ISR(_id) \
4406 { \
4407 if (p_Fm->guestId != p_Fm->intrMng[(e_FmInterModuleEvent)(e_FM_EV_ERR_10G_MAC0+_id)].guestId) \
4408 SendIpcIsr(p_Fm, (e_FmInterModuleEvent)(e_FM_EV_ERR_10G_MAC0+_id), pending); \
4409 else \
4410 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);\
4411 }
4412 t_Fm *p_Fm = (t_Fm*)h_Fm;
4413 uint32_t pending;
4414 struct fman_fpm_regs *fpm_rg;
4415
4416 SANITY_CHECK_RETURN_ERROR(h_Fm, E_INVALID_HANDLE);
4417 SANITY_CHECK_RETURN_ERROR(!p_Fm->p_FmDriverParam, E_INVALID_STATE);
4418 SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
4419
4420 fpm_rg = p_Fm->p_FmFpmRegs;
4421
4422 /* error interrupts */
4423 pending = fman_get_fpm_error_interrupts(fpm_rg);
4424 if (!pending)
4425 return ERROR_CODE(E_EMPTY);
4426
4427 if (pending & ERR_INTR_EN_BMI)
4428 BmiErrEvent(p_Fm);
4429 if (pending & ERR_INTR_EN_QMI)
4430 QmiErrEvent(p_Fm);
4431 if (pending & ERR_INTR_EN_FPM)
4432 FpmErrEvent(p_Fm);
4433 if (pending & ERR_INTR_EN_DMA)
4434 DmaErrEvent(p_Fm);
4435 if (pending & ERR_INTR_EN_IRAM)
4436 IramErrIntr(p_Fm);
4437 if (pending & ERR_INTR_EN_MURAM)
4438 MuramErrIntr(p_Fm);
4439 if (pending & ERR_INTR_EN_PRS)
4440 p_Fm->intrMng[e_FM_EV_ERR_PRS].f_Isr(p_Fm->intrMng[e_FM_EV_ERR_PRS].h_SrcHandle);
4441 if (pending & ERR_INTR_EN_PLCR)
4442 p_Fm->intrMng[e_FM_EV_ERR_PLCR].f_Isr(p_Fm->intrMng[e_FM_EV_ERR_PLCR].h_SrcHandle);
4443 if (pending & ERR_INTR_EN_KG)
4444 p_Fm->intrMng[e_FM_EV_ERR_KG].f_Isr(p_Fm->intrMng[e_FM_EV_ERR_KG].h_SrcHandle);
4445
4446 /* MAC events may belong to different partitions */
4447 if (pending & ERR_INTR_EN_1G_MAC0)
4448 FM_M_CALL_1G_MAC_ERR_ISR(0);
4449 if (pending & ERR_INTR_EN_1G_MAC1)
4450 FM_M_CALL_1G_MAC_ERR_ISR(1);
4451 if (pending & ERR_INTR_EN_1G_MAC2)
4452 FM_M_CALL_1G_MAC_ERR_ISR(2);
4453 if (pending & ERR_INTR_EN_1G_MAC3)
4454 FM_M_CALL_1G_MAC_ERR_ISR(3);
4455 if (pending & ERR_INTR_EN_1G_MAC4)
4456 FM_M_CALL_1G_MAC_ERR_ISR(4);
4457 if (pending & ERR_INTR_EN_1G_MAC5)
4458 FM_M_CALL_1G_MAC_ERR_ISR(5);
4459 if (pending & ERR_INTR_EN_1G_MAC6)
4460 FM_M_CALL_1G_MAC_ERR_ISR(6);
4461 if (pending & ERR_INTR_EN_1G_MAC7)
4462 FM_M_CALL_1G_MAC_ERR_ISR(7);
4463 if (pending & ERR_INTR_EN_10G_MAC0)
4464 FM_M_CALL_10G_MAC_ERR_ISR(0);
4465 if (pending & ERR_INTR_EN_10G_MAC1)
4466 FM_M_CALL_10G_MAC_ERR_ISR(1);
4467
4468 #ifdef FM_MACSEC_SUPPORT
4469 if (pending & ERR_INTR_EN_MACSEC_MAC0)
4470 {
4471 if (p_Fm->guestId != p_Fm->intrMng[e_FM_EV_ERR_MACSEC_MAC0].guestId)
4472 SendIpcIsr(p_Fm, e_FM_EV_ERR_MACSEC_MAC0, pending);
4473 else
4474 p_Fm->intrMng[e_FM_EV_ERR_MACSEC_MAC0].f_Isr(p_Fm->intrMng[e_FM_EV_ERR_MACSEC_MAC0].h_SrcHandle);
4475 }
4476 #endif /* FM_MACSEC_SUPPORT */
4477
4478 return E_OK;
4479 }
4480
FM_SetPortsBandwidth(t_Handle h_Fm,t_FmPortsBandwidthParams * p_PortsBandwidth)4481 t_Error FM_SetPortsBandwidth(t_Handle h_Fm, t_FmPortsBandwidthParams *p_PortsBandwidth)
4482 {
4483 t_Fm *p_Fm = (t_Fm*)h_Fm;
4484 int i;
4485 uint8_t sum;
4486 uint8_t hardwarePortId;
4487 uint8_t weights[64];
4488 uint8_t weight, maxPercent = 0;
4489 struct fman_bmi_regs *bmi_rg;
4490
4491 SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
4492 SANITY_CHECK_RETURN_ERROR(!p_Fm->p_FmDriverParam, E_INVALID_STATE);
4493 SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
4494
4495 bmi_rg = p_Fm->p_FmBmiRegs;
4496
4497 memset(weights, 0, (sizeof(uint8_t) * 64));
4498
4499 /* check that all ports add up to 100% */
4500 sum = 0;
4501 for (i=0; i < p_PortsBandwidth->numOfPorts; i++)
4502 sum +=p_PortsBandwidth->portsBandwidths[i].bandwidth;
4503 if (sum != 100)
4504 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Sum of ports bandwidth differ from 100%"));
4505
4506 /* find highest percent */
4507 for (i=0; i < p_PortsBandwidth->numOfPorts; i++)
4508 {
4509 if (p_PortsBandwidth->portsBandwidths[i].bandwidth > maxPercent)
4510 maxPercent = p_PortsBandwidth->portsBandwidths[i].bandwidth;
4511 }
4512
4513 ASSERT_COND(maxPercent > 0); /* guaranteed by sum = 100 */
4514
4515 /* calculate weight for each port */
4516 for (i=0; i < p_PortsBandwidth->numOfPorts; i++)
4517 {
4518 weight = (uint8_t)((p_PortsBandwidth->portsBandwidths[i].bandwidth * PORT_MAX_WEIGHT ) / maxPercent);
4519 /* we want even division between 1-to-PORT_MAX_WEIGHT. so if exact division
4520 is not reached, we round up so that:
4521 0 until maxPercent/PORT_MAX_WEIGHT get "1"
4522 maxPercent/PORT_MAX_WEIGHT+1 until (maxPercent/PORT_MAX_WEIGHT)*2 get "2"
4523 ...
4524 maxPercent - maxPercent/PORT_MAX_WEIGHT until maxPercent get "PORT_MAX_WEIGHT: */
4525 if ((uint8_t)((p_PortsBandwidth->portsBandwidths[i].bandwidth * PORT_MAX_WEIGHT ) % maxPercent))
4526 weight++;
4527
4528 /* find the location of this port within the register */
4529 hardwarePortId =
4530 SwPortIdToHwPortId(p_PortsBandwidth->portsBandwidths[i].type,
4531 p_PortsBandwidth->portsBandwidths[i].relativePortId,
4532 p_Fm->p_FmStateStruct->revInfo.majorRev,
4533 p_Fm->p_FmStateStruct->revInfo.minorRev);
4534
4535 ASSERT_COND(IN_RANGE(1, hardwarePortId, 63));
4536 weights[hardwarePortId] = weight;
4537 }
4538
4539 fman_set_ports_bandwidth(bmi_rg, weights);
4540
4541 return E_OK;
4542 }
4543
FM_EnableRamsEcc(t_Handle h_Fm)4544 t_Error FM_EnableRamsEcc(t_Handle h_Fm)
4545 {
4546 t_Fm *p_Fm = (t_Fm*)h_Fm;
4547 struct fman_fpm_regs *fpm_rg;
4548
4549 SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
4550
4551 fpm_rg = p_Fm->p_FmFpmRegs;
4552
4553 if (p_Fm->guestId != NCSW_MASTER_ID)
4554 {
4555 t_FmIpcMsg msg;
4556 t_Error err;
4557
4558 memset(&msg, 0, sizeof(msg));
4559 msg.msgId = FM_ENABLE_RAM_ECC;
4560 err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
4561 (uint8_t*)&msg,
4562 sizeof(msg.msgId),
4563 NULL,
4564 NULL,
4565 NULL,
4566 NULL);
4567 if (err != E_OK)
4568 RETURN_ERROR(MINOR, err, NO_MSG);
4569 return E_OK;
4570 }
4571
4572 if (!p_Fm->p_FmStateStruct->internalCall)
4573 p_Fm->p_FmStateStruct->explicitEnable = TRUE;
4574 p_Fm->p_FmStateStruct->internalCall = FALSE;
4575
4576 if (p_Fm->p_FmStateStruct->ramsEccEnable)
4577 return E_OK;
4578 else
4579 {
4580 fman_enable_rams_ecc(fpm_rg);
4581 p_Fm->p_FmStateStruct->ramsEccEnable = TRUE;
4582 }
4583
4584 return E_OK;
4585 }
4586
FM_DisableRamsEcc(t_Handle h_Fm)4587 t_Error FM_DisableRamsEcc(t_Handle h_Fm)
4588 {
4589 t_Fm *p_Fm = (t_Fm*)h_Fm;
4590 bool explicitDisable = FALSE;
4591 struct fman_fpm_regs *fpm_rg;
4592
4593 SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
4594 SANITY_CHECK_RETURN_ERROR(!p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
4595
4596 fpm_rg = p_Fm->p_FmFpmRegs;
4597
4598 if (p_Fm->guestId != NCSW_MASTER_ID)
4599 {
4600 t_Error err;
4601 t_FmIpcMsg msg;
4602
4603 memset(&msg, 0, sizeof(msg));
4604 msg.msgId = FM_DISABLE_RAM_ECC;
4605 if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
4606 (uint8_t*)&msg,
4607 sizeof(msg.msgId),
4608 NULL,
4609 NULL,
4610 NULL,
4611 NULL)) != E_OK)
4612 RETURN_ERROR(MINOR, err, NO_MSG);
4613 return E_OK;
4614 }
4615
4616 if (!p_Fm->p_FmStateStruct->internalCall)
4617 explicitDisable = TRUE;
4618 p_Fm->p_FmStateStruct->internalCall = FALSE;
4619
4620 /* if rams are already disabled, or if rams were explicitly enabled and are
4621 currently called indirectly (not explicitly), ignore this call. */
4622 if (!p_Fm->p_FmStateStruct->ramsEccEnable ||
4623 (p_Fm->p_FmStateStruct->explicitEnable && !explicitDisable))
4624 return E_OK;
4625 else
4626 {
4627 if (p_Fm->p_FmStateStruct->explicitEnable)
4628 /* This is the case were both explicit are TRUE.
4629 Turn off this flag for cases were following ramsEnable
4630 routines are called */
4631 p_Fm->p_FmStateStruct->explicitEnable = FALSE;
4632
4633 fman_enable_rams_ecc(fpm_rg);
4634 p_Fm->p_FmStateStruct->ramsEccEnable = FALSE;
4635 }
4636
4637 return E_OK;
4638 }
4639
FM_SetException(t_Handle h_Fm,e_FmExceptions exception,bool enable)4640 t_Error FM_SetException(t_Handle h_Fm, e_FmExceptions exception, bool enable)
4641 {
4642 t_Fm *p_Fm = (t_Fm*)h_Fm;
4643 uint32_t bitMask = 0;
4644 enum fman_exceptions fslException;
4645 struct fman_rg fman_rg;
4646
4647 SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
4648 SANITY_CHECK_RETURN_ERROR(!p_Fm->p_FmDriverParam, E_INVALID_STATE);
4649
4650 fman_rg.bmi_rg = p_Fm->p_FmBmiRegs;
4651 fman_rg.qmi_rg = p_Fm->p_FmQmiRegs;
4652 fman_rg.fpm_rg = p_Fm->p_FmFpmRegs;
4653 fman_rg.dma_rg = p_Fm->p_FmDmaRegs;
4654
4655 GET_EXCEPTION_FLAG(bitMask, exception);
4656 if (bitMask)
4657 {
4658 if (enable)
4659 p_Fm->p_FmStateStruct->exceptions |= bitMask;
4660 else
4661 p_Fm->p_FmStateStruct->exceptions &= ~bitMask;
4662
4663 fslException = FmanExceptionTrans(exception);
4664
4665 return (t_Error)fman_set_exception(&fman_rg,
4666 fslException,
4667 enable);
4668 }
4669 else
4670 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined exception"));
4671
4672 return E_OK;
4673 }
4674
FM_GetRevision(t_Handle h_Fm,t_FmRevisionInfo * p_FmRevisionInfo)4675 t_Error FM_GetRevision(t_Handle h_Fm, t_FmRevisionInfo *p_FmRevisionInfo)
4676 {
4677 t_Fm *p_Fm = (t_Fm*)h_Fm;
4678
4679 p_FmRevisionInfo->majorRev = p_Fm->p_FmStateStruct->revInfo.majorRev;
4680 p_FmRevisionInfo->minorRev = p_Fm->p_FmStateStruct->revInfo.minorRev;
4681
4682 return E_OK;
4683 }
4684
FM_GetFmanCtrlCodeRevision(t_Handle h_Fm,t_FmCtrlCodeRevisionInfo * p_RevisionInfo)4685 t_Error FM_GetFmanCtrlCodeRevision(t_Handle h_Fm, t_FmCtrlCodeRevisionInfo *p_RevisionInfo)
4686 {
4687 t_Fm *p_Fm = (t_Fm*)h_Fm;
4688 t_FMIramRegs *p_Iram;
4689 uint32_t revInfo;
4690
4691 SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
4692 SANITY_CHECK_RETURN_ERROR(p_RevisionInfo, E_NULL_POINTER);
4693
4694 if ((p_Fm->guestId != NCSW_MASTER_ID) &&
4695 p_Fm->h_IpcSessions[0])
4696 {
4697 t_Error err;
4698 t_FmIpcMsg msg;
4699 t_FmIpcReply reply;
4700 uint32_t replyLength;
4701 t_FmIpcFmanCtrlCodeRevisionInfo ipcRevInfo;
4702
4703 memset(&msg, 0, sizeof(msg));
4704 memset(&reply, 0, sizeof(reply));
4705 msg.msgId = FM_GET_FMAN_CTRL_CODE_REV;
4706 replyLength = sizeof(uint32_t) + sizeof(t_FmCtrlCodeRevisionInfo);
4707 if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
4708 (uint8_t*)&msg,
4709 sizeof(msg.msgId),
4710 (uint8_t*)&reply,
4711 &replyLength,
4712 NULL,
4713 NULL)) != E_OK)
4714 RETURN_ERROR(MINOR, err, NO_MSG);
4715 if (replyLength != (sizeof(uint32_t) + sizeof(t_FmCtrlCodeRevisionInfo)))
4716 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
4717 memcpy((uint8_t*)&ipcRevInfo, reply.replyBody, sizeof(t_FmCtrlCodeRevisionInfo));
4718 p_RevisionInfo->packageRev = ipcRevInfo.packageRev;
4719 p_RevisionInfo->majorRev = ipcRevInfo.majorRev;
4720 p_RevisionInfo->minorRev = ipcRevInfo.minorRev;
4721 return (t_Error)(reply.error);
4722 }
4723 else if (p_Fm->guestId != NCSW_MASTER_ID)
4724 RETURN_ERROR(MINOR, E_NOT_SUPPORTED,
4725 ("running in guest-mode without IPC!"));
4726
4727 p_Iram = (t_FMIramRegs *)UINT_TO_PTR(p_Fm->baseAddr + FM_MM_IMEM);
4728 WRITE_UINT32(p_Iram->iadd, 0x4);
4729 while (GET_UINT32(p_Iram->iadd) != 0x4) ;
4730 revInfo = GET_UINT32(p_Iram->idata);
4731 p_RevisionInfo->packageRev = (uint16_t)((revInfo & 0xFFFF0000) >> 16);
4732 p_RevisionInfo->majorRev = (uint8_t)((revInfo & 0x0000FF00) >> 8);
4733 p_RevisionInfo->minorRev = (uint8_t)(revInfo & 0x000000FF);
4734
4735 return E_OK;
4736 }
4737
FM_GetCounter(t_Handle h_Fm,e_FmCounters counter)4738 uint32_t FM_GetCounter(t_Handle h_Fm, e_FmCounters counter)
4739 {
4740 t_Fm *p_Fm = (t_Fm*)h_Fm;
4741 t_Error err;
4742 uint32_t counterValue;
4743 struct fman_rg fman_rg;
4744 enum fman_counters fsl_counter;
4745
4746 SANITY_CHECK_RETURN_VALUE(p_Fm, E_INVALID_HANDLE, 0);
4747 SANITY_CHECK_RETURN_VALUE(!p_Fm->p_FmDriverParam, E_INVALID_STATE, 0);
4748
4749 fman_rg.bmi_rg = p_Fm->p_FmBmiRegs;
4750 fman_rg.qmi_rg = p_Fm->p_FmQmiRegs;
4751 fman_rg.fpm_rg = p_Fm->p_FmFpmRegs;
4752 fman_rg.dma_rg = p_Fm->p_FmDmaRegs;
4753
4754 if ((p_Fm->guestId != NCSW_MASTER_ID) &&
4755 !p_Fm->baseAddr &&
4756 p_Fm->h_IpcSessions[0])
4757 {
4758 t_FmIpcMsg msg;
4759 t_FmIpcReply reply;
4760 uint32_t replyLength, outCounter;
4761
4762 memset(&msg, 0, sizeof(msg));
4763 memset(&reply, 0, sizeof(reply));
4764 msg.msgId = FM_GET_COUNTER;
4765 memcpy(msg.msgBody, (uint8_t *)&counter, sizeof(uint32_t));
4766 replyLength = sizeof(uint32_t) + sizeof(uint32_t);
4767 err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
4768 (uint8_t*)&msg,
4769 sizeof(msg.msgId) +sizeof(counterValue),
4770 (uint8_t*)&reply,
4771 &replyLength,
4772 NULL,
4773 NULL);
4774 if (err != E_OK)
4775 {
4776 REPORT_ERROR(MAJOR, err, NO_MSG);
4777 return 0;
4778 }
4779 if (replyLength != (sizeof(uint32_t) + sizeof(uint32_t)))
4780 {
4781 REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
4782 return 0;
4783 }
4784
4785 memcpy((uint8_t*)&outCounter, reply.replyBody, sizeof(uint32_t));
4786 return outCounter;
4787 }
4788 else if (!p_Fm->baseAddr)
4789 {
4790 REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Either IPC or 'baseAddress' is required!"));
4791 return 0;
4792 }
4793
4794 /* When applicable (when there is an 'enable counters' bit,
4795 check that counters are enabled */
4796 switch (counter)
4797 {
4798 case (e_FM_COUNTERS_DEQ_1):
4799 case (e_FM_COUNTERS_DEQ_2):
4800 case (e_FM_COUNTERS_DEQ_3):
4801 if ((p_Fm->p_FmStateStruct->revInfo.majorRev == 4) ||
4802 (p_Fm->p_FmStateStruct->revInfo.majorRev >= 6))
4803 {
4804 REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Requested counter not supported"));
4805 return 0;
4806 }
4807 case (e_FM_COUNTERS_ENQ_TOTAL_FRAME):
4808 case (e_FM_COUNTERS_DEQ_TOTAL_FRAME):
4809 case (e_FM_COUNTERS_DEQ_0):
4810 case (e_FM_COUNTERS_DEQ_FROM_DEFAULT):
4811 case (e_FM_COUNTERS_DEQ_FROM_CONTEXT):
4812 case (e_FM_COUNTERS_DEQ_FROM_FD):
4813 case (e_FM_COUNTERS_DEQ_CONFIRM):
4814 if (!(GET_UINT32(p_Fm->p_FmQmiRegs->fmqm_gc) & QMI_CFG_EN_COUNTERS))
4815 {
4816 REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Requested counter was not enabled"));
4817 return 0;
4818 }
4819 break;
4820 default:
4821 break;
4822 }
4823
4824 FMAN_COUNTERS_TRANS(fsl_counter, counter);
4825 return fman_get_counter(&fman_rg, fsl_counter);
4826 }
4827
FM_ModifyCounter(t_Handle h_Fm,e_FmCounters counter,uint32_t val)4828 t_Error FM_ModifyCounter(t_Handle h_Fm, e_FmCounters counter, uint32_t val)
4829 {
4830 t_Fm *p_Fm = (t_Fm*)h_Fm;
4831 struct fman_rg fman_rg;
4832 enum fman_counters fsl_counter;
4833
4834 SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
4835 SANITY_CHECK_RETURN_ERROR(!p_Fm->p_FmDriverParam, E_INVALID_STATE);
4836
4837 fman_rg.bmi_rg = p_Fm->p_FmBmiRegs;
4838 fman_rg.qmi_rg = p_Fm->p_FmQmiRegs;
4839 fman_rg.fpm_rg = p_Fm->p_FmFpmRegs;
4840 fman_rg.dma_rg = p_Fm->p_FmDmaRegs;
4841
4842 FMAN_COUNTERS_TRANS(fsl_counter, counter);
4843 return (t_Error)fman_modify_counter(&fman_rg, fsl_counter, val);
4844 }
4845
FM_SetDmaEmergency(t_Handle h_Fm,e_FmDmaMuramPort muramPort,bool enable)4846 void FM_SetDmaEmergency(t_Handle h_Fm, e_FmDmaMuramPort muramPort, bool enable)
4847 {
4848 t_Fm *p_Fm = (t_Fm*)h_Fm;
4849 struct fman_dma_regs *dma_rg;
4850
4851 SANITY_CHECK_RETURN(p_Fm, E_INVALID_HANDLE);
4852 SANITY_CHECK_RETURN(!p_Fm->p_FmDriverParam, E_INVALID_STATE);
4853
4854 dma_rg = p_Fm->p_FmDmaRegs;
4855
4856 fman_set_dma_emergency(dma_rg, !!(muramPort==e_FM_DMA_MURAM_PORT_WRITE), enable);
4857 }
4858
FM_SetDmaExtBusPri(t_Handle h_Fm,e_FmDmaExtBusPri pri)4859 void FM_SetDmaExtBusPri(t_Handle h_Fm, e_FmDmaExtBusPri pri)
4860 {
4861 t_Fm *p_Fm = (t_Fm*)h_Fm;
4862 struct fman_dma_regs *dma_rg;
4863
4864 SANITY_CHECK_RETURN(p_Fm, E_INVALID_HANDLE);
4865 SANITY_CHECK_RETURN(!p_Fm->p_FmDriverParam, E_INVALID_STATE);
4866
4867 dma_rg = p_Fm->p_FmDmaRegs;
4868
4869 fman_set_dma_ext_bus_pri(dma_rg, pri);
4870 }
4871
FM_GetDmaStatus(t_Handle h_Fm,t_FmDmaStatus * p_FmDmaStatus)4872 void FM_GetDmaStatus(t_Handle h_Fm, t_FmDmaStatus *p_FmDmaStatus)
4873 {
4874 t_Fm *p_Fm = (t_Fm*)h_Fm;
4875 uint32_t dmaStatus;
4876 struct fman_dma_regs *dma_rg;
4877
4878 SANITY_CHECK_RETURN(p_Fm, E_INVALID_HANDLE);
4879 SANITY_CHECK_RETURN(!p_Fm->p_FmDriverParam, E_INVALID_STATE);
4880
4881 dma_rg = p_Fm->p_FmDmaRegs;
4882
4883 if ((p_Fm->guestId != NCSW_MASTER_ID) &&
4884 !p_Fm->baseAddr &&
4885 p_Fm->h_IpcSessions[0])
4886 {
4887 t_FmIpcDmaStatus ipcDmaStatus;
4888 t_FmIpcMsg msg;
4889 t_FmIpcReply reply;
4890 t_Error err;
4891 uint32_t replyLength;
4892
4893 memset(&msg, 0, sizeof(msg));
4894 memset(&reply, 0, sizeof(reply));
4895 msg.msgId = FM_DMA_STAT;
4896 replyLength = sizeof(uint32_t) + sizeof(t_FmIpcDmaStatus);
4897 err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
4898 (uint8_t*)&msg,
4899 sizeof(msg.msgId),
4900 (uint8_t*)&reply,
4901 &replyLength,
4902 NULL,
4903 NULL);
4904 if (err != E_OK)
4905 {
4906 REPORT_ERROR(MINOR, err, NO_MSG);
4907 return;
4908 }
4909 if (replyLength != (sizeof(uint32_t) + sizeof(t_FmIpcDmaStatus)))
4910 {
4911 REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
4912 return;
4913 }
4914 memcpy((uint8_t*)&ipcDmaStatus, reply.replyBody, sizeof(t_FmIpcDmaStatus));
4915
4916 p_FmDmaStatus->cmqNotEmpty = (bool)ipcDmaStatus.boolCmqNotEmpty; /**< Command queue is not empty */
4917 p_FmDmaStatus->busError = (bool)ipcDmaStatus.boolBusError; /**< Bus error occurred */
4918 p_FmDmaStatus->readBufEccError = (bool)ipcDmaStatus.boolReadBufEccError; /**< Double ECC error on buffer Read */
4919 p_FmDmaStatus->writeBufEccSysError =(bool)ipcDmaStatus.boolWriteBufEccSysError; /**< Double ECC error on buffer write from system side */
4920 p_FmDmaStatus->writeBufEccFmError = (bool)ipcDmaStatus.boolWriteBufEccFmError; /**< Double ECC error on buffer write from FM side */
4921 p_FmDmaStatus->singlePortEccError = (bool)ipcDmaStatus.boolSinglePortEccError; /**< Double ECC error on buffer write from FM side */
4922 return;
4923 }
4924 else if (!p_Fm->baseAddr)
4925 {
4926 REPORT_ERROR(MINOR, E_NOT_SUPPORTED,
4927 ("Either IPC or 'baseAddress' is required!"));
4928 return;
4929 }
4930
4931 dmaStatus = fman_get_dma_status(dma_rg);
4932
4933 p_FmDmaStatus->cmqNotEmpty = (bool)(dmaStatus & DMA_STATUS_CMD_QUEUE_NOT_EMPTY);
4934 p_FmDmaStatus->busError = (bool)(dmaStatus & DMA_STATUS_BUS_ERR);
4935 if (p_Fm->p_FmStateStruct->revInfo.majorRev >= 6)
4936 p_FmDmaStatus->singlePortEccError = (bool)(dmaStatus & DMA_STATUS_FM_SPDAT_ECC);
4937 else
4938 {
4939 p_FmDmaStatus->readBufEccError = (bool)(dmaStatus & DMA_STATUS_READ_ECC);
4940 p_FmDmaStatus->writeBufEccSysError = (bool)(dmaStatus & DMA_STATUS_SYSTEM_WRITE_ECC);
4941 p_FmDmaStatus->writeBufEccFmError = (bool)(dmaStatus & DMA_STATUS_FM_WRITE_ECC);
4942 }
4943 }
4944
FM_Resume(t_Handle h_Fm)4945 void FM_Resume(t_Handle h_Fm)
4946 {
4947 t_Fm *p_Fm = (t_Fm*)h_Fm;
4948 struct fman_fpm_regs *fpm_rg;
4949
4950 SANITY_CHECK_RETURN(p_Fm, E_INVALID_HANDLE);
4951 SANITY_CHECK_RETURN(!p_Fm->p_FmDriverParam, E_INVALID_STATE);
4952 SANITY_CHECK_RETURN((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
4953
4954 fpm_rg = p_Fm->p_FmFpmRegs;
4955
4956 fman_resume(fpm_rg);
4957 }
4958
FM_GetSpecialOperationCoding(t_Handle h_Fm,fmSpecialOperations_t spOper,uint8_t * p_SpOperCoding)4959 t_Error FM_GetSpecialOperationCoding(t_Handle h_Fm,
4960 fmSpecialOperations_t spOper,
4961 uint8_t *p_SpOperCoding)
4962 {
4963 t_Fm *p_Fm = (t_Fm*)h_Fm;
4964 t_FmCtrlCodeRevisionInfo revInfo;
4965 t_Error err;
4966
4967 SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
4968 SANITY_CHECK_RETURN_ERROR(!p_Fm->p_FmDriverParam, E_INVALID_STATE);
4969 SANITY_CHECK_RETURN_ERROR(p_SpOperCoding, E_NULL_POINTER);
4970
4971 if (!spOper)
4972 {
4973 *p_SpOperCoding = 0;
4974 return E_OK;
4975 }
4976
4977 if ((err = FM_GetFmanCtrlCodeRevision(p_Fm, &revInfo)) != E_OK)
4978 {
4979 DBG(WARNING, ("FM in guest-mode without IPC, can't validate firmware revision."));
4980 revInfo.packageRev = IP_OFFLOAD_PACKAGE_NUMBER;
4981 }
4982 else if (!IS_OFFLOAD_PACKAGE(revInfo.packageRev))
4983 RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("Fman ctrl code package"));
4984
4985 switch (spOper)
4986 {
4987 case (FM_SP_OP_CAPWAP_DTLS_DEC):
4988 *p_SpOperCoding = 9;
4989 break;
4990 case (FM_SP_OP_CAPWAP_DTLS_ENC):
4991 *p_SpOperCoding = 10;
4992 break;
4993 case (FM_SP_OP_IPSEC|FM_SP_OP_IPSEC_UPDATE_UDP_LEN|FM_SP_OP_IPSEC_MANIP):
4994 case (FM_SP_OP_IPSEC|FM_SP_OP_IPSEC_UPDATE_UDP_LEN|FM_SP_OP_IPSEC_MANIP|FM_SP_OP_RPD):
4995 *p_SpOperCoding = 5;
4996 break;
4997 case (FM_SP_OP_IPSEC|FM_SP_OP_IPSEC_MANIP):
4998 case (FM_SP_OP_IPSEC|FM_SP_OP_IPSEC_MANIP|FM_SP_OP_RPD):
4999 *p_SpOperCoding = 6;
5000 break;
5001 case (FM_SP_OP_IPSEC|FM_SP_OP_IPSEC_UPDATE_UDP_LEN|FM_SP_OP_RPD):
5002 *p_SpOperCoding = 3;
5003 break;
5004 case (FM_SP_OP_IPSEC|FM_SP_OP_IPSEC_UPDATE_UDP_LEN):
5005 *p_SpOperCoding = 1;
5006 break;
5007 case (FM_SP_OP_IPSEC|FM_SP_OP_IPSEC_UPDATE_UDP_LEN|FM_SP_OP_IPSEC_NO_ETH_HDR):
5008 *p_SpOperCoding = 12;
5009 break;
5010 case (FM_SP_OP_IPSEC|FM_SP_OP_RPD):
5011 *p_SpOperCoding = 4;
5012 break;
5013 case (FM_SP_OP_IPSEC):
5014 *p_SpOperCoding = 2;
5015 break;
5016 case (FM_SP_OP_DCL4C):
5017 *p_SpOperCoding = 7;
5018 break;
5019 case (FM_SP_OP_CLEAR_RPD):
5020 *p_SpOperCoding = 8;
5021 break;
5022 default:
5023 RETURN_ERROR(MINOR, E_INVALID_VALUE, NO_MSG);
5024 }
5025
5026 return E_OK;
5027 }
5028
FM_CtrlMonStart(t_Handle h_Fm)5029 t_Error FM_CtrlMonStart(t_Handle h_Fm)
5030 {
5031 t_Fm *p_Fm = (t_Fm *)h_Fm;
5032 t_FmTrbRegs *p_MonRegs;
5033 uint8_t i;
5034
5035 SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
5036 SANITY_CHECK_RETURN_ERROR(!p_Fm->p_FmDriverParam, E_INVALID_STATE);
5037 SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
5038
5039 WRITE_UINT32(p_Fm->p_FmFpmRegs->fmfp_brkc,
5040 GET_UINT32(p_Fm->p_FmFpmRegs->fmfp_brkc) | FPM_BRKC_RDBG);
5041
5042 for (i = 0; i < FM_NUM_OF_CTRL; i++)
5043 {
5044 p_MonRegs = (t_FmTrbRegs *)UINT_TO_PTR(p_Fm->baseAddr + FM_MM_TRB(i));
5045
5046 /* Reset control registers */
5047 WRITE_UINT32(p_MonRegs->tcrh, TRB_TCRH_RESET);
5048 WRITE_UINT32(p_MonRegs->tcrl, TRB_TCRL_RESET);
5049
5050 /* Configure: counter #1 counts all stalls in risc - ldsched stall
5051 counter #2 counts all stalls in risc - other stall*/
5052 WRITE_UINT32(p_MonRegs->tcrl, TRB_TCRL_RESET | TRB_TCRL_UTIL);
5053
5054 /* Enable monitoring */
5055 WRITE_UINT32(p_MonRegs->tcrh, TRB_TCRH_ENABLE_COUNTERS);
5056 }
5057
5058 return E_OK;
5059 }
5060
FM_CtrlMonStop(t_Handle h_Fm)5061 t_Error FM_CtrlMonStop(t_Handle h_Fm)
5062 {
5063 t_Fm *p_Fm = (t_Fm *)h_Fm;
5064 t_FmTrbRegs *p_MonRegs;
5065 uint8_t i;
5066
5067 SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
5068 SANITY_CHECK_RETURN_ERROR(!p_Fm->p_FmDriverParam, E_INVALID_STATE);
5069 SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
5070
5071 for (i = 0; i < FM_NUM_OF_CTRL; i++)
5072 {
5073 p_MonRegs = (t_FmTrbRegs *)UINT_TO_PTR(p_Fm->baseAddr + FM_MM_TRB(i));
5074 WRITE_UINT32(p_MonRegs->tcrh, TRB_TCRH_DISABLE_COUNTERS);
5075 }
5076
5077 WRITE_UINT32(p_Fm->p_FmFpmRegs->fmfp_brkc,
5078 GET_UINT32(p_Fm->p_FmFpmRegs->fmfp_brkc) & ~FPM_BRKC_RDBG);
5079
5080 return E_OK;
5081 }
5082
FM_CtrlMonGetCounters(t_Handle h_Fm,uint8_t fmCtrlIndex,t_FmCtrlMon * p_Mon)5083 t_Error FM_CtrlMonGetCounters(t_Handle h_Fm, uint8_t fmCtrlIndex, t_FmCtrlMon *p_Mon)
5084 {
5085 t_Fm *p_Fm = (t_Fm *)h_Fm;
5086 t_FmTrbRegs *p_MonRegs;
5087 uint64_t clkCnt, utilValue, effValue;
5088
5089 SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
5090 SANITY_CHECK_RETURN_ERROR(!p_Fm->p_FmDriverParam, E_INVALID_STATE);
5091 SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
5092 SANITY_CHECK_RETURN_ERROR(p_Mon, E_NULL_POINTER);
5093
5094 if (fmCtrlIndex >= FM_NUM_OF_CTRL)
5095 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("FM Controller index"));
5096
5097 p_MonRegs = (t_FmTrbRegs *)UINT_TO_PTR(p_Fm->baseAddr + FM_MM_TRB(fmCtrlIndex));
5098
5099 clkCnt = (uint64_t)
5100 ((uint64_t)GET_UINT32(p_MonRegs->tpcch) << 32 | GET_UINT32(p_MonRegs->tpccl));
5101
5102 utilValue = (uint64_t)
5103 ((uint64_t)GET_UINT32(p_MonRegs->tpc1h) << 32 | GET_UINT32(p_MonRegs->tpc1l));
5104
5105 effValue = (uint64_t)
5106 ((uint64_t)GET_UINT32(p_MonRegs->tpc2h) << 32 | GET_UINT32(p_MonRegs->tpc2l));
5107
5108 p_Mon->percentCnt[0] = (uint8_t)(((clkCnt - utilValue) * 100) / clkCnt);
5109 if (clkCnt != utilValue)
5110 p_Mon->percentCnt[1] = (uint8_t)((((clkCnt - utilValue) - effValue) * 100) / (clkCnt - utilValue));
5111 else
5112 p_Mon->percentCnt[1] = 0;
5113
5114 return E_OK;
5115 }
5116
FM_GetMuramHandle(t_Handle h_Fm)5117 t_Handle FM_GetMuramHandle(t_Handle h_Fm)
5118 {
5119 t_Fm *p_Fm = (t_Fm*)h_Fm;
5120
5121 SANITY_CHECK_RETURN_VALUE(p_Fm, E_INVALID_HANDLE, NULL);
5122
5123 return (p_Fm->h_FmMuram);
5124 }
5125
5126 /****************************************************/
5127 /* Hidden-DEBUG Only API */
5128 /****************************************************/
FM_ForceIntr(t_Handle h_Fm,e_FmExceptions exception)5129 t_Error FM_ForceIntr (t_Handle h_Fm, e_FmExceptions exception)
5130 {
5131 t_Fm *p_Fm = (t_Fm*)h_Fm;
5132 enum fman_exceptions fslException;
5133 struct fman_rg fman_rg;
5134
5135 SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
5136 SANITY_CHECK_RETURN_ERROR(!p_Fm->p_FmDriverParam, E_INVALID_STATE);
5137
5138 fman_rg.bmi_rg = p_Fm->p_FmBmiRegs;
5139 fman_rg.qmi_rg = p_Fm->p_FmQmiRegs;
5140 fman_rg.fpm_rg = p_Fm->p_FmFpmRegs;
5141 fman_rg.dma_rg = p_Fm->p_FmDmaRegs;
5142
5143 switch (exception)
5144 {
5145 case e_FM_EX_QMI_DEQ_FROM_UNKNOWN_PORTID:
5146 if (!(p_Fm->p_FmStateStruct->exceptions & FM_EX_QMI_DEQ_FROM_UNKNOWN_PORTID))
5147 RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked"));
5148 break;
5149 case e_FM_EX_QMI_SINGLE_ECC:
5150 if (p_Fm->p_FmStateStruct->revInfo.majorRev >= 6)
5151 RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("e_FM_EX_QMI_SINGLE_ECC not supported on this integration."));
5152
5153 if (!(p_Fm->p_FmStateStruct->exceptions & FM_EX_QMI_SINGLE_ECC))
5154 RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked"));
5155 break;
5156 case e_FM_EX_QMI_DOUBLE_ECC:
5157 if (!(p_Fm->p_FmStateStruct->exceptions & FM_EX_QMI_DOUBLE_ECC))
5158 RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked"));
5159 break;
5160 case e_FM_EX_BMI_LIST_RAM_ECC:
5161 if (!(p_Fm->p_FmStateStruct->exceptions & FM_EX_BMI_LIST_RAM_ECC))
5162 RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked"));
5163 break;
5164 case e_FM_EX_BMI_STORAGE_PROFILE_ECC:
5165 if (!(p_Fm->p_FmStateStruct->exceptions & FM_EX_BMI_STORAGE_PROFILE_ECC))
5166 RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked"));
5167 break;
5168 case e_FM_EX_BMI_STATISTICS_RAM_ECC:
5169 if (!(p_Fm->p_FmStateStruct->exceptions & FM_EX_BMI_STATISTICS_RAM_ECC))
5170 RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked"));
5171 break;
5172 case e_FM_EX_BMI_DISPATCH_RAM_ECC:
5173 if (!(p_Fm->p_FmStateStruct->exceptions & FM_EX_BMI_DISPATCH_RAM_ECC))
5174 RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked"));
5175 break;
5176 default:
5177 RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception may not be forced"));
5178 }
5179
5180 fslException = FmanExceptionTrans(exception);
5181 fman_force_intr (&fman_rg, fslException);
5182
5183 return E_OK;
5184 }
5185
FmGetPcd(t_Handle h_Fm)5186 t_Handle FmGetPcd(t_Handle h_Fm)
5187 {
5188 return ((t_Fm*)h_Fm)->h_Pcd;
5189 }
5190 #if (DPAA_VERSION >= 11)
5191 extern void *g_MemacRegs;
5192 void fm_clk_down(void);
5193 uint32_t fman_memac_get_event(void *regs, uint32_t ev_mask);
FM_ChangeClock(t_Handle h_Fm,int hardwarePortId)5194 void FM_ChangeClock(t_Handle h_Fm, int hardwarePortId)
5195 {
5196 int macId;
5197 uint32_t event, rcr;
5198 t_Fm *p_Fm = (t_Fm*)h_Fm;
5199 rcr = GET_UINT32(p_Fm->p_FmFpmRegs->fm_rcr);
5200 rcr |= 0x04000000;
5201 WRITE_UINT32(p_Fm->p_FmFpmRegs->fm_rcr, rcr);
5202
5203 HW_PORT_ID_TO_SW_PORT_ID(macId, hardwarePortId);
5204 do
5205 {
5206 event = fman_memac_get_event(g_MemacRegs, 0xFFFFFFFF);
5207 } while ((event & 0x00000020) == 0);
5208 fm_clk_down();
5209 rcr = GET_UINT32(p_Fm->p_FmFpmRegs->fm_rcr);
5210 rcr &= ~0x04000000;
5211 WRITE_UINT32(p_Fm->p_FmFpmRegs->fm_rcr, rcr);
5212 }
5213 #endif
5214