1 /******************************************************************************
2
3 � 1995-2003, 2004, 2005-2011 Freescale Semiconductor, Inc.
4 All rights reserved.
5
6 This is proprietary source code of Freescale Semiconductor Inc.,
7 and its use is subject to the NetComm Device Drivers EULA.
8 The copyright notice above does not evidence any actual or intended
9 publication of such source code.
10
11 ALTERNATIVELY, redistribution and use in source and binary forms, with
12 or without modification, are permitted provided that the following
13 conditions are met:
14 * Redistributions of source code must retain the above copyright
15 notice, this list of conditions and the following disclaimer.
16 * Redistributions in binary form must reproduce the above copyright
17 notice, this list of conditions and the following disclaimer in the
18 documentation and/or other materials provided with the distribution.
19 * Neither the name of Freescale Semiconductor nor the
20 names of its contributors may be used to endorse or promote products
21 derived from this software without specific prior written permission.
22
23 THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
24 EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
25 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
26 DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
27 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
28 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
29 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
30 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
32 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 *
34
35 **************************************************************************/
36 /******************************************************************************
37 @File qm.c
38
39 @Description QM & Portal implementation
40 *//***************************************************************************/
41
42 #include <sys/cdefs.h>
43 #include <sys/types.h>
44 #include <machine/atomic.h>
45 #include "error_ext.h"
46 #include "std_ext.h"
47 #include "string_ext.h"
48 #include "sprint_ext.h"
49 #include "mm_ext.h"
50 #include "core_ext.h"
51 #include "debug_ext.h"
52
53 #include "qm.h"
54
55
56 static volatile bool blockingFlag = FALSE;
QmIpcMsgCompletionCB(t_Handle h_Module,uint8_t * p_Msg,uint8_t * p_Reply,uint32_t replyLength,t_Error status)57 static void QmIpcMsgCompletionCB(t_Handle h_Module,
58 uint8_t *p_Msg,
59 uint8_t *p_Reply,
60 uint32_t replyLength,
61 t_Error status)
62 {
63 SANITY_CHECK_RETURN(h_Module, E_INVALID_HANDLE);
64
65 UNUSED(p_Msg);UNUSED(p_Reply);UNUSED(replyLength);UNUSED(status);UNUSED(h_Module);
66 blockingFlag = FALSE;
67 }
68
QmHandleIpcMsgCB(t_Handle h_Qm,uint8_t * p_Msg,uint32_t msgLength,uint8_t * p_Reply,uint32_t * p_ReplyLength)69 static t_Error QmHandleIpcMsgCB(t_Handle h_Qm,
70 uint8_t *p_Msg,
71 uint32_t msgLength,
72 uint8_t *p_Reply,
73 uint32_t *p_ReplyLength)
74 {
75 t_Qm *p_Qm = (t_Qm*)h_Qm;
76 t_QmIpcMsg *p_IpcMsg = (t_QmIpcMsg*)p_Msg;
77 t_QmIpcReply *p_IpcReply = (t_QmIpcReply *)p_Reply;
78
79 SANITY_CHECK_RETURN_ERROR(p_Qm, E_INVALID_HANDLE);
80 SANITY_CHECK_RETURN_ERROR((msgLength >= sizeof(uint32_t)), E_INVALID_VALUE);
81
82 #ifdef DISABLE_SANITY_CHECKS
83 UNUSED(msgLength);
84 #endif /* DISABLE_SANITY_CHECKS */
85
86 ASSERT_COND(p_IpcMsg);
87
88 memset(p_IpcReply, 0, (sizeof(uint8_t) * QM_IPC_MAX_REPLY_SIZE));
89 *p_ReplyLength = 0;
90
91 switch(p_IpcMsg->msgId)
92 {
93 case (QM_MASTER_IS_ALIVE):
94 *(uint8_t*)p_IpcReply->replyBody = 1;
95 *p_ReplyLength = sizeof(uint32_t) + sizeof(uint8_t);
96 break;
97 case (QM_FORCE_FQID):
98 {
99 t_QmIpcFqidParams ipcFqid;
100 uint32_t fqid;
101
102 memcpy((uint8_t*)&ipcFqid, p_IpcMsg->msgBody, sizeof(t_QmIpcFqidParams));
103 fqid = QmFqidGet(p_Qm, ipcFqid.size, 1, TRUE, ipcFqid.fqid);
104 memcpy(p_IpcReply->replyBody, (uint8_t*)&fqid, sizeof(uint32_t));
105 *p_ReplyLength = sizeof(uint32_t) + sizeof(uint32_t);
106 break;
107 }
108 case (QM_PUT_FQID):
109 {
110 t_Error err;
111 t_QmIpcFqidParams ipcFqid;
112
113 memcpy((uint8_t*)&ipcFqid, p_IpcMsg->msgBody, sizeof(t_QmIpcFqidParams));
114 if ((err = QmFqidPut(p_Qm, ipcFqid.fqid)) != E_OK)
115 REPORT_ERROR(MINOR, err, NO_MSG);
116 break;
117 }
118 case (QM_GET_COUNTER):
119 {
120 t_QmIpcGetCounter ipcCounter;
121 uint32_t count;
122
123 memcpy((uint8_t*)&ipcCounter, p_IpcMsg->msgBody, sizeof(t_QmIpcGetCounter));
124 count = QmGetCounter(p_Qm, (e_QmInterModuleCounters)ipcCounter.enumId);
125 memcpy(p_IpcReply->replyBody, (uint8_t*)&count, sizeof(uint32_t));
126 *p_ReplyLength = sizeof(uint32_t) + sizeof(uint32_t);
127 break;
128 }
129 case (QM_GET_SET_PORTAL_PARAMS):
130 {
131 t_Error err;
132 t_QmIpcPortalInitParams ipcPortalInitParams;
133 t_QmInterModulePortalInitParams portalInitParams;
134
135 memcpy((uint8_t*)&ipcPortalInitParams, p_IpcMsg->msgBody, sizeof(t_QmIpcPortalInitParams));
136 portalInitParams.portalId = ipcPortalInitParams.portalId;
137 portalInitParams.stashDestQueue = ipcPortalInitParams.stashDestQueue;
138 portalInitParams.liodn = ipcPortalInitParams.liodn;
139 portalInitParams.dqrrLiodn = ipcPortalInitParams.dqrrLiodn;
140 portalInitParams.fdFqLiodn = ipcPortalInitParams.fdFqLiodn;
141 if ((err = QmGetSetPortalParams(p_Qm, &portalInitParams)) != E_OK)
142 REPORT_ERROR(MINOR, err, NO_MSG);
143 break;
144 }
145 case (QM_GET_REVISION):
146 {
147 t_QmRevisionInfo revInfo;
148 t_QmIpcRevisionInfo ipcRevInfo;
149
150 p_IpcReply->error = (uint32_t)QmGetRevision(h_Qm, &revInfo);
151 ipcRevInfo.majorRev = revInfo.majorRev;
152 ipcRevInfo.minorRev = revInfo.minorRev;
153 memcpy(p_IpcReply->replyBody, (uint8_t*)&ipcRevInfo, sizeof(t_QmIpcRevisionInfo));
154 *p_ReplyLength = sizeof(uint32_t) + sizeof(t_QmIpcRevisionInfo);
155 break;
156 }
157 default:
158 *p_ReplyLength = 0;
159 RETURN_ERROR(MINOR, E_INVALID_SELECTION, ("command not found!!!"));
160 }
161 return E_OK;
162 }
163
CheckQmParameters(t_Qm * p_Qm)164 static t_Error CheckQmParameters(t_Qm *p_Qm)
165 {
166 if ((p_Qm->p_QmDriverParams->partFqidBase + p_Qm->p_QmDriverParams->partNumOfFqids) > QM_MAX_NUM_OF_FQIDS)
167 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("partFqidBase+partNumOfFqids out of range!!!"));
168 if ((p_Qm->partCgsBase + p_Qm->partNumOfCgs) > QM_MAX_NUM_OF_CGS)
169 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("partCgsBase+partNumOfCgs out of range!!!"));
170
171 if (p_Qm->guestId == NCSW_MASTER_ID)
172 {
173 uint64_t phyAddr;
174
175 phyAddr = XX_VirtToPhys(UINT_TO_PTR(p_Qm->p_QmDriverParams->swPortalsBaseAddress));
176
177 if (phyAddr & 0x00000000001fffffLL)
178 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("swPortalsBaseAddress isn't properly aligned"));
179 if (!p_Qm->p_QmDriverParams->rtFramesDepth)
180 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("rtFramesDepth must be larger than '0'!!!"));
181 if (p_Qm->p_QmDriverParams->rtFramesDepth > ((16*MEGABYTE)*3))
182 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("rtFramesDepth must be equal or smaller than 48MB!!!"));
183 if (!p_Qm->p_QmDriverParams->totalNumOfFqids)
184 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("totalNumOfFqids must be larger than '0'!!!"));
185 if (p_Qm->p_QmDriverParams->totalNumOfFqids > (16*MEGABYTE))
186 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("totalNumOfFqids must be equal or smaller than 16MB!!!"));
187 if(!p_Qm->f_Exception)
188 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Exceptions callback not provided"));
189 }
190
191 return E_OK;
192 }
193
QmInitPfdr(t_Qm * p_Qm,uint32_t pfdr_start,uint32_t num)194 static t_Error QmInitPfdr(t_Qm *p_Qm, uint32_t pfdr_start, uint32_t num)
195 {
196 uint8_t rslt;
197 uint32_t timeout = 100000;
198
199 ASSERT_COND(p_Qm);
200
201 ASSERT_COND(pfdr_start && !(pfdr_start & 7) && !(num & 7) && num);
202
203 /* Make sure te command interface is 'idle' */
204 rslt = MCR_get_rslt(GET_UINT32(p_Qm->p_QmRegs->mcr));
205 if (!MCR_rslt_idle(rslt))
206 RETURN_ERROR(CRITICAL,E_INVALID_STATE,("QMAN_MCR isn't idle"));
207
208 /* Write the MCR command params then the verb */
209 WRITE_UINT32(p_Qm->p_QmRegs->mcp0, pfdr_start);
210 /* TODO: remove this - it's a workaround for a model bug that is
211 * corrected in more recent versions. We use the workaround until
212 * everyone has upgraded. */
213 WRITE_UINT32(p_Qm->p_QmRegs->mcp1, (pfdr_start + num - 16));
214 WRITE_UINT32(p_Qm->p_QmRegs->mcp1, (pfdr_start + num - 1));
215
216 mb();
217 WRITE_UINT32(p_Qm->p_QmRegs->mcr, MCR_INIT_PFDR);
218
219 /* Poll for the result */
220 do {
221 XX_UDelay(1);
222 rslt = MCR_get_rslt(GET_UINT32(p_Qm->p_QmRegs->mcr));
223 } while(!MCR_rslt_idle(rslt) && --timeout);
224
225 if (MCR_rslt_ok(rslt))
226 return E_OK;
227 WRITE_UINT32(p_Qm->p_QmRegs->mcr, 0);
228 if (!timeout)
229 RETURN_ERROR(MAJOR, E_TIMEOUT, NO_MSG);
230 if (MCR_rslt_eaccess(rslt))
231 RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
232 if (MCR_rslt_inval(rslt))
233 RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG);
234 RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Unexpected result from MCR_INIT_PFDR: %02x\n", rslt));
235 }
236
QmSetWqScheduling(t_Qm * p_Qm,e_QmWqClass wqClass,uint8_t csElev,uint8_t csw2,uint8_t csw3,uint8_t csw4,uint8_t csw5,uint8_t csw6,uint8_t csw7)237 static __inline__ void QmSetWqScheduling(t_Qm *p_Qm,
238 e_QmWqClass wqClass,
239 uint8_t csElev,
240 uint8_t csw2,
241 uint8_t csw3,
242 uint8_t csw4,
243 uint8_t csw5,
244 uint8_t csw6,
245 uint8_t csw7)
246 {
247 ASSERT_COND(p_Qm);
248
249 WRITE_UINT32(p_Qm->p_QmRegs->wq_cs_cfg[wqClass],
250 (uint32_t)(((csElev & 0xff) << 24) |
251 ((csw2 & 0x7) << 20) |
252 ((csw3 & 0x7) << 16) |
253 ((csw4 & 0x7) << 12) |
254 ((csw5 & 0x7) << 8) |
255 ((csw6 & 0x7) << 4) |
256 (csw7 & 0x7)));
257 }
258
ReserveFqids(t_Qm * p_Qm,uint32_t size,uint32_t alignment,bool force,uint32_t base)259 static uint32_t ReserveFqids(t_Qm *p_Qm, uint32_t size, uint32_t alignment, bool force, uint32_t base)
260 {
261 uint64_t ans;
262 uint32_t intFlags;
263
264 intFlags = XX_LockIntrSpinlock(p_Qm->lock);
265 if (force)
266 ans = MM_GetForce(p_Qm->h_FqidMm,
267 (uint64_t)base,
268 (uint64_t)size,
269 "QM FQID MEM");
270 else
271 ans = MM_Get(p_Qm->h_FqidMm,
272 (uint64_t)size,
273 alignment,
274 "QM FQID MEM");
275 if (ans == ILLEGAL_BASE)
276 {
277 XX_UnlockIntrSpinlock(p_Qm->lock, intFlags);
278 return (uint32_t)ans;
279 }
280 base = (uint32_t)ans;
281 ans = MM_GetForce(p_Qm->h_RsrvFqidMm,
282 (uint64_t)base,
283 (uint64_t)size,
284 "QM rsrv FQID MEM");
285 if (ans == ILLEGAL_BASE)
286 {
287 MM_Put(p_Qm->h_FqidMm, (uint64_t)base);
288 XX_UnlockIntrSpinlock(p_Qm->lock, intFlags);
289 return (uint32_t)ans;
290 }
291 XX_UnlockIntrSpinlock(p_Qm->lock, intFlags);
292
293 return (uint32_t)base;
294 }
295
FreeInitResources(t_Qm * p_Qm)296 static void FreeInitResources(t_Qm *p_Qm)
297 {
298 if (p_Qm->p_FqdBase)
299 XX_FreeSmart(p_Qm->p_FqdBase);
300 if (p_Qm->p_PfdrBase)
301 XX_FreeSmart(p_Qm->p_PfdrBase);
302 if (p_Qm->h_Session)
303 XX_IpcFreeSession(p_Qm->h_Session);
304 if (p_Qm->h_RsrvFqidMm)
305 MM_Free(p_Qm->h_RsrvFqidMm);
306 if (p_Qm->h_FqidMm)
307 MM_Free(p_Qm->h_FqidMm);
308 }
309
310
311 /****************************************/
312 /* Inter-Module functions */
313 /****************************************/
314
QmGetCounter(t_Handle h_Qm,e_QmInterModuleCounters counter)315 uint32_t QmGetCounter(t_Handle h_Qm, e_QmInterModuleCounters counter)
316 {
317 t_Qm *p_Qm = (t_Qm*)h_Qm;
318
319 SANITY_CHECK_RETURN_VALUE(p_Qm, E_INVALID_HANDLE, 0);
320 SANITY_CHECK_RETURN_VALUE((((p_Qm->guestId == NCSW_MASTER_ID) && p_Qm->p_QmRegs) ||
321 (p_Qm->guestId != NCSW_MASTER_ID)), E_INVALID_STATE, 0);
322
323 if ((p_Qm->guestId == NCSW_MASTER_ID) ||
324 (!p_Qm->h_Session && p_Qm->p_QmRegs))
325 {
326 switch(counter)
327 {
328 case(e_QM_IM_COUNTERS_SFDR_IN_USE):
329 return GET_UINT32(p_Qm->p_QmRegs->sfdr_in_use);
330 case(e_QM_IM_COUNTERS_PFDR_IN_USE):
331 return (p_Qm->numOfPfdr - GET_UINT32(p_Qm->p_QmRegs->pfdr_fpc));
332 case(e_QM_IM_COUNTERS_PFDR_FREE_POOL):
333 return (GET_UINT32(p_Qm->p_QmRegs->pfdr_fpc) - GET_UINT32(p_Qm->p_QmRegs->pfdr_cfg));
334 default:
335 break;
336 }
337 /* should never get here */
338 ASSERT_COND(FALSE);
339 }
340 else if (p_Qm->h_Session)
341 {
342 t_QmIpcMsg msg;
343 t_QmIpcReply reply;
344 t_QmIpcGetCounter ipcCounter;
345 uint32_t replyLength, count;
346 t_Error errCode = E_OK;
347
348 memset(&msg, 0, sizeof(t_QmIpcMsg));
349 memset(&reply, 0, sizeof(t_QmIpcReply));
350 ipcCounter.enumId = (uint32_t)counter;
351 msg.msgId = QM_GET_COUNTER;
352 memcpy(msg.msgBody, &ipcCounter, sizeof(t_QmIpcGetCounter));
353 replyLength = sizeof(uint32_t) + sizeof(uint32_t);
354 if ((errCode = XX_IpcSendMessage(p_Qm->h_Session,
355 (uint8_t*)&msg,
356 sizeof(msg.msgId) + sizeof(t_QmIpcGetCounter),
357 (uint8_t*)&reply,
358 &replyLength,
359 NULL,
360 NULL)) != E_OK)
361 REPORT_ERROR(MAJOR, errCode, NO_MSG);
362 if (replyLength != (sizeof(uint32_t) + sizeof(uint32_t)))
363 REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
364 if ((errCode == E_OK) && (replyLength == (sizeof(uint32_t) + sizeof(uint32_t))))
365 {
366 memcpy((uint8_t*)&count, reply.replyBody, sizeof(uint32_t));
367 return count;
368 }
369 }
370 else
371 REPORT_ERROR(WARNING, E_NOT_SUPPORTED,
372 ("In 'guest', either IPC or 'baseAddress' is required!"));
373
374 return 0;
375 }
376
QmGetRevision(t_Handle h_Qm,t_QmRevisionInfo * p_QmRevisionInfo)377 t_Error QmGetRevision(t_Handle h_Qm, t_QmRevisionInfo *p_QmRevisionInfo)
378 {
379 t_Qm *p_Qm = (t_Qm *)h_Qm;
380 uint32_t tmpReg;
381
382 SANITY_CHECK_RETURN_ERROR(p_Qm, E_INVALID_HANDLE);
383 SANITY_CHECK_RETURN_ERROR(p_QmRevisionInfo, E_NULL_POINTER);
384 SANITY_CHECK_RETURN_ERROR((((p_Qm->guestId == NCSW_MASTER_ID) && p_Qm->p_QmRegs) ||
385 (p_Qm->guestId != NCSW_MASTER_ID)), E_INVALID_STATE);
386
387 if ((p_Qm->guestId == NCSW_MASTER_ID) ||
388 (!p_Qm->h_Session && p_Qm->p_QmRegs))
389 {
390 /* read revision register 1 */
391 tmpReg = GET_UINT32(p_Qm->p_QmRegs->ip_rev_1);
392 p_QmRevisionInfo->majorRev = (uint8_t)((tmpReg & REV1_MAJOR_MASK) >> REV1_MAJOR_SHIFT);
393 p_QmRevisionInfo->minorRev = (uint8_t)((tmpReg & REV1_MINOR_MASK) >> REV1_MINOR_SHIFT);
394 }
395 else if (p_Qm->h_Session)
396 {
397 t_QmIpcMsg msg;
398 t_QmIpcReply reply;
399 t_QmIpcRevisionInfo ipcRevInfo;
400 uint32_t replyLength;
401 t_Error errCode = E_OK;
402
403 memset(&msg, 0, sizeof(t_QmIpcMsg));
404 memset(&reply, 0, sizeof(reply));
405 msg.msgId = QM_GET_REVISION;
406 replyLength = sizeof(uint32_t) + sizeof(t_QmIpcRevisionInfo);
407 if ((errCode = XX_IpcSendMessage(p_Qm->h_Session,
408 (uint8_t*)&msg,
409 sizeof(msg.msgId),
410 (uint8_t*)&reply,
411 &replyLength,
412 NULL,
413 NULL)) != E_OK)
414 RETURN_ERROR(MAJOR, errCode, NO_MSG);
415 if (replyLength != (sizeof(uint32_t) + sizeof(t_QmIpcRevisionInfo)))
416 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
417
418 memcpy((uint8_t*)&ipcRevInfo, reply.replyBody, sizeof(t_QmIpcRevisionInfo));
419 p_QmRevisionInfo->majorRev = ipcRevInfo.majorRev;
420 p_QmRevisionInfo->minorRev = ipcRevInfo.minorRev;
421
422 return (t_Error)(reply.error);
423 }
424 else
425 RETURN_ERROR(WARNING, E_NOT_SUPPORTED,
426 ("In 'guest', either IPC or 'baseAddress' is required!"));
427
428 return E_OK;
429 }
430
QmGetSetPortalParams(t_Handle h_Qm,t_QmInterModulePortalInitParams * p_PortalParams)431 t_Error QmGetSetPortalParams(t_Handle h_Qm, t_QmInterModulePortalInitParams *p_PortalParams)
432 {
433 t_Qm *p_Qm = (t_Qm *)h_Qm;
434 t_QmRevisionInfo revInfo;
435 uint32_t lioReg,ioReg;
436
437 SANITY_CHECK_RETURN_ERROR(p_Qm, E_INVALID_HANDLE);
438 SANITY_CHECK_RETURN_ERROR(p_PortalParams, E_NULL_POINTER);
439
440 if (p_Qm->guestId == NCSW_MASTER_ID)
441 {
442 QmGetRevision(p_Qm, &revInfo);
443
444 if ((revInfo.majorRev == 1) && (revInfo.minorRev == 0))
445 {
446 lioReg = (uint32_t)(p_PortalParams->stashDestQueue << 24) |
447 (p_PortalParams->liodn << 16) |
448 (p_PortalParams->dqrrLiodn);
449 ioReg = (p_PortalParams->fdFqLiodn);
450 }
451 else
452 {
453 lioReg = (uint32_t)(p_PortalParams->liodn << 16) |
454 (p_PortalParams->dqrrLiodn);
455 ioReg = (uint32_t)(p_PortalParams->stashDestQueue << 16) |
456 (p_PortalParams->fdFqLiodn);
457 }
458
459 WRITE_UINT32(p_Qm->p_QmRegs->swpConfRegs[p_PortalParams->portalId].lio_cfg, lioReg);
460 WRITE_UINT32(p_Qm->p_QmRegs->swpConfRegs[p_PortalParams->portalId].io_cfg, ioReg);
461 }
462 else if (p_Qm->h_Session)
463 {
464 t_QmIpcMsg msg;
465 t_QmIpcPortalInitParams portalParams;
466 t_Error errCode;
467
468 memset(&msg, 0, sizeof(t_QmIpcMsg));
469 portalParams.portalId = p_PortalParams->portalId;
470 portalParams.stashDestQueue = p_PortalParams->stashDestQueue;
471 portalParams.liodn = p_PortalParams->liodn;
472 portalParams.dqrrLiodn = p_PortalParams->dqrrLiodn;
473 portalParams.fdFqLiodn = p_PortalParams->fdFqLiodn;
474 msg.msgId = QM_GET_SET_PORTAL_PARAMS;
475 memcpy(msg.msgBody, &portalParams, sizeof(t_QmIpcPortalInitParams));
476 XX_LockSpinlock(p_Qm->lock);
477 if ((errCode = XX_IpcSendMessage(p_Qm->h_Session,
478 (uint8_t*)&msg,
479 sizeof(msg.msgId) + sizeof(t_QmIpcPortalInitParams),
480 NULL,
481 NULL,
482 NULL,
483 NULL)) != E_OK)
484 {
485 XX_UnlockSpinlock(p_Qm->lock);
486 RETURN_ERROR(MAJOR, errCode, NO_MSG);
487 }
488 XX_UnlockSpinlock(p_Qm->lock);
489 }
490 else
491 DBG(WARNING, ("Can't set portal parameters (e.g. liodns). " \
492 "probably QM is running in guest-mode with no IPC!"));
493
494 return E_OK;
495 }
496
QmFqidGet(t_Qm * p_Qm,uint32_t size,uint32_t alignment,bool force,uint32_t base)497 uint32_t QmFqidGet(t_Qm *p_Qm, uint32_t size, uint32_t alignment, bool force, uint32_t base)
498 {
499 uint64_t ans;
500 uint32_t intFlags;
501
502 intFlags = XX_LockIntrSpinlock(p_Qm->lock);
503 if (force)
504 {
505 ans = MM_GetForce(p_Qm->h_FqidMm,
506 (uint64_t)base,
507 (uint64_t)size,
508 "QM FQID MEM");
509 if (ans == ILLEGAL_BASE)
510 {
511 ans = MM_GetForce(p_Qm->h_RsrvFqidMm,
512 (uint64_t)base,
513 (uint64_t)size,
514 "QM rsrv FQID MEM");
515 if (ans == ILLEGAL_BASE)
516 ans = base;
517 else if (p_Qm->h_Session)
518 {
519 t_QmIpcMsg msg;
520 t_QmIpcReply reply;
521 uint32_t replyLength;
522 t_QmIpcFqidParams ipcFqid;
523 t_Error errCode = E_OK;
524
525 memset(&msg, 0, sizeof(t_QmIpcMsg));
526 memset(&reply, 0, sizeof(t_QmIpcReply));
527 ipcFqid.fqid = base;
528 ipcFqid.size = size;
529 msg.msgId = QM_FORCE_FQID;
530 memcpy(msg.msgBody, &ipcFqid, sizeof(t_QmIpcFqidParams));
531 replyLength = sizeof(uint32_t) + sizeof(uint32_t);
532 if ((errCode = XX_IpcSendMessage(p_Qm->h_Session,
533 (uint8_t*)&msg,
534 sizeof(msg.msgId) + sizeof(t_QmIpcFqidParams),
535 (uint8_t*)&reply,
536 &replyLength,
537 NULL,
538 NULL)) != E_OK)
539 REPORT_ERROR(MAJOR, errCode, NO_MSG);
540 if (replyLength != (sizeof(uint32_t) + sizeof(uint32_t)))
541 REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
542
543 if ((errCode != E_OK) ||
544 (replyLength != (sizeof(uint32_t) + sizeof(uint32_t))))
545 ans = ILLEGAL_BASE;
546 else
547 memcpy((uint8_t*)&ans, reply.replyBody, sizeof(uint32_t));
548 }
549 else
550 {
551 DBG(WARNING, ("No Ipc - can't validate fqid."));
552 ans = base;
553 }
554 }
555 }
556 else
557 ans = MM_Get(p_Qm->h_FqidMm,
558 size,
559 alignment,
560 "QM FQID MEM");
561 XX_UnlockIntrSpinlock(p_Qm->lock, intFlags);
562
563 KASSERT(ans < UINT32_MAX, ("Oops, %jx > UINT32_MAX!\n", (uintmax_t)ans));
564 return (uint32_t)ans;
565 }
566
QmFqidPut(t_Qm * p_Qm,uint32_t base)567 t_Error QmFqidPut(t_Qm *p_Qm, uint32_t base)
568 {
569 uint32_t intFlags;
570
571 intFlags = XX_LockIntrSpinlock(p_Qm->lock);
572 /* Check maybe this fqid was reserved in the past */
573 if (MM_GetForce(p_Qm->h_RsrvFqidMm,
574 (uint64_t)base,
575 (uint64_t)1,
576 "QM rsrv FQID MEM") == ILLEGAL_BASE)
577 {
578 XX_UnlockIntrSpinlock(p_Qm->lock, intFlags);
579 return E_OK;
580 }
581 else
582 MM_PutForce(p_Qm->h_RsrvFqidMm,
583 (uint64_t)base,
584 (uint64_t)1);
585 if (MM_InRange(p_Qm->h_FqidMm, (uint64_t)base))
586 {
587 if (MM_Put(p_Qm->h_FqidMm, (uint64_t)base) != 0)
588 {
589 XX_UnlockIntrSpinlock(p_Qm->lock, intFlags);
590 return E_OK;
591 }
592 else
593 {
594 XX_UnlockIntrSpinlock(p_Qm->lock, intFlags);
595 return ERROR_CODE(E_NOT_FOUND);
596 }
597 }
598 else if (p_Qm->h_Session)
599 {
600 t_QmIpcMsg msg;
601 t_QmIpcFqidParams ipcFqid;
602 t_Error errCode = E_OK;
603
604 memset(&msg, 0, sizeof(t_QmIpcMsg));
605 ipcFqid.fqid = (uint8_t)base;
606 ipcFqid.size = 0;
607 msg.msgId = QM_PUT_FQID;
608 memcpy(msg.msgBody, &ipcFqid, sizeof(t_QmIpcFqidParams));
609 if ((errCode = XX_IpcSendMessage(p_Qm->h_Session,
610 (uint8_t*)&msg,
611 sizeof(msg.msgId) + sizeof(t_QmIpcFqidParams),
612 NULL,
613 NULL,
614 NULL,
615 NULL)) != E_OK)
616 {
617 XX_UnlockIntrSpinlock(p_Qm->lock, intFlags);
618 RETURN_ERROR(MAJOR, errCode, NO_MSG);
619 }
620 }
621 else
622 DBG(WARNING, ("No Ipc - can't validate fqid."));
623 XX_UnlockIntrSpinlock(p_Qm->lock, intFlags);
624
625 return E_OK;
626 }
627
QmGetCgId(t_Handle h_Qm,uint8_t * p_CgId)628 t_Error QmGetCgId(t_Handle h_Qm, uint8_t *p_CgId)
629 {
630 t_Qm *p_Qm = (t_Qm *)h_Qm;
631 uint16_t i;
632
633 for(i = p_Qm->partCgsBase;i<p_Qm->partCgsBase+p_Qm->partNumOfCgs;i++)
634 if (!p_Qm->cgsUsed[i])
635 {
636 p_Qm->cgsUsed[i] = (uint8_t)TRUE;
637 *p_CgId = (uint8_t)i;
638 break;
639 }
640 if(i == (p_Qm->partCgsBase+p_Qm->partNumOfCgs))
641 RETURN_ERROR(MINOR, E_BUSY, ("No available CG"));
642 else
643 return E_OK;
644 }
645
QmFreeCgId(t_Handle h_Qm,uint8_t cgId)646 t_Error QmFreeCgId(t_Handle h_Qm, uint8_t cgId)
647 {
648 t_Qm *p_Qm = (t_Qm *)h_Qm;
649
650 if (!p_Qm->cgsUsed[cgId])
651 RETURN_ERROR(MINOR, E_INVALID_STATE, ("CG is not in use"));
652 else
653 p_Qm->cgsUsed[cgId] = (uint8_t)FALSE;
654
655 return E_OK;
656 }
657
658
659 /****************************************/
660 /* API Init unit functions */
661 /****************************************/
662
QM_Config(t_QmParam * p_QmParam)663 t_Handle QM_Config(t_QmParam *p_QmParam)
664 {
665 t_Qm *p_Qm;
666 uint8_t i;
667
668 SANITY_CHECK_RETURN_VALUE(p_QmParam, E_INVALID_HANDLE, NULL);
669
670 p_Qm = (t_Qm *)XX_Malloc(sizeof(t_Qm));
671 if (!p_Qm)
672 {
673 REPORT_ERROR(MAJOR, E_NO_MEMORY, ("QM obj!!!"));
674 return NULL;
675 }
676 memset(p_Qm, 0, sizeof(t_Qm));
677 p_Qm->p_QmDriverParams = (t_QmDriverParams *)XX_Malloc(sizeof(t_QmDriverParams));
678 if (!p_Qm->p_QmDriverParams)
679 {
680 XX_Free(p_Qm);
681 REPORT_ERROR(MAJOR, E_NO_MEMORY, ("Qm driver parameters"));
682 return NULL;
683 }
684 memset(p_Qm->p_QmDriverParams, 0, sizeof(t_QmDriverParams));
685
686 p_Qm->guestId = p_QmParam->guestId;
687 p_Qm->p_QmDriverParams->partFqidBase = p_QmParam->partFqidBase;
688 p_Qm->p_QmDriverParams->partNumOfFqids = p_QmParam->partNumOfFqids;
689 p_Qm->partCgsBase = p_QmParam->partCgsBase;
690 p_Qm->partNumOfCgs = p_QmParam->partNumOfCgs;
691 p_Qm->p_QmRegs = (t_QmRegs *)UINT_TO_PTR(p_QmParam->baseAddress);
692
693 if (p_Qm->guestId == NCSW_MASTER_ID)
694 {
695 p_Qm->exceptions = DEFAULT_exceptions;
696 p_Qm->f_Exception = p_QmParam->f_Exception;
697 p_Qm->h_App = p_QmParam->h_App;
698 p_Qm->errIrq = p_QmParam->errIrq;
699 p_Qm->p_QmDriverParams->liodn = p_QmParam->liodn;
700 p_Qm->p_QmDriverParams->rtFramesDepth = DEFAULT_rtFramesDepth;
701 p_Qm->p_QmDriverParams->fqdMemPartitionId = p_QmParam->fqdMemPartitionId;
702 p_Qm->p_QmDriverParams->pfdrMemPartitionId = p_QmParam->pfdrMemPartitionId;
703 p_Qm->p_QmDriverParams->swPortalsBaseAddress = p_QmParam->swPortalsBaseAddress;
704 p_Qm->p_QmDriverParams->totalNumOfFqids = p_QmParam->totalNumOfFqids;
705 p_Qm->p_QmDriverParams->pfdrThreshold = DEFAULT_pfdrThreshold;
706 p_Qm->p_QmDriverParams->sfdrThreshold = DEFAULT_sfdrThreshold;
707 p_Qm->p_QmDriverParams->pfdrBaseConstant = DEFAULT_pfdrBaseConstant;
708 for(i= 0;i<DPAA_MAX_NUM_OF_DC_PORTALS;i++)
709 p_Qm->p_QmDriverParams->dcPortalsParams[i].sendToSw =
710 (bool)((i < e_DPAA_DCPORTAL2) ? FALSE : TRUE);
711
712 #ifdef QMAN_SFDR_LEAK_ERRATA_QMAN5
713 {
714 #define WORKAROUND_TMP_VAL 0x00000003
715 t_QmRevisionInfo revInfo;
716 QmGetRevision(p_Qm, &revInfo);
717 if ((revInfo.majorRev == 1) && (revInfo.minorRev == 0))
718 {
719 uint32_t *tmp = (uint32_t *)UINT_TO_PTR(p_QmParam->baseAddress + 0xbf0);
720 uint32_t tmpReg = WORKAROUND_TMP_VAL;
721 WRITE_UINT32(*tmp, tmpReg);
722 while ((tmpReg = GET_UINT32(*tmp)) != WORKAROUND_TMP_VAL) ;
723 }
724 }
725 #endif /* QMAN_SFDR_LEAK_ERRATA_QMAN5 */
726 }
727
728 /* build the QM partition IPC address */
729 memset(p_Qm->moduleName, 0, MODULE_NAME_SIZE);
730 if(Sprint (p_Qm->moduleName, "QM_0_%d",p_Qm->guestId) != (p_Qm->guestId<10 ? 6:7))
731 {
732 XX_Free(p_Qm->p_QmDriverParams);
733 XX_Free(p_Qm);
734 REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Sprint failed"));
735 return NULL;
736 }
737
738 return p_Qm;
739 }
740
QM_Init(t_Handle h_Qm)741 t_Error QM_Init(t_Handle h_Qm)
742 {
743 t_Qm *p_Qm = (t_Qm *)h_Qm;
744 t_QmDriverParams *p_QmDriverParams;
745 t_Error err;
746
747 SANITY_CHECK_RETURN_ERROR(p_Qm, E_INVALID_HANDLE);
748 SANITY_CHECK_RETURN_ERROR(p_Qm->p_QmDriverParams, E_INVALID_HANDLE);
749
750 CHECK_INIT_PARAMETERS(p_Qm, CheckQmParameters);
751
752 p_QmDriverParams = p_Qm->p_QmDriverParams;
753
754 if (p_QmDriverParams->partNumOfFqids)
755 {
756 if (MM_Init(&p_Qm->h_FqidMm, p_QmDriverParams->partFqidBase, p_QmDriverParams->partNumOfFqids) != E_OK)
757 RETURN_ERROR(MAJOR, E_INVALID_HANDLE, ("QM-FQIDS-MEM partition!!!"));
758 if (MM_Init(&p_Qm->h_RsrvFqidMm, p_QmDriverParams->partFqidBase, p_QmDriverParams->partNumOfFqids) != E_OK)
759 RETURN_ERROR(MAJOR, E_INVALID_HANDLE, ("QM-Reserve-FQIDS-MEM partition!!!"));
760 }
761
762 if (p_Qm->guestId == NCSW_MASTER_ID)
763 {
764 uint64_t phyAddr;
765 t_QmRevisionInfo revInfo;
766 uint32_t dsSize, exp, i;
767
768 QmGetRevision(p_Qm, &revInfo);
769 DBG(TRACE, ("Qman ver:%02x,%02x", revInfo.majorRev, revInfo.minorRev));
770
771 phyAddr = XX_VirtToPhys(UINT_TO_PTR(p_QmDriverParams->swPortalsBaseAddress));
772 WRITE_UINT32(p_Qm->p_QmRegs->qcsp_bare, ((uint32_t)(phyAddr >> 32) & 0x000000ff));
773 WRITE_UINT32(p_Qm->p_QmRegs->qcsp_bar, (uint32_t)phyAddr);
774 WRITE_UINT32(p_Qm->p_QmRegs->liodnr, (uint16_t)p_QmDriverParams->liodn);
775
776 /* FQD memory */
777 dsSize = (uint32_t)(p_QmDriverParams->totalNumOfFqids * FQD_ENTRY_SIZE);
778 LOG2(dsSize, exp);
779 if (!POWER_OF_2(dsSize)) (exp++);
780 dsSize = (uint32_t)(1 << exp);
781 if (dsSize < (4*KILOBYTE))
782 {
783 dsSize = (4*KILOBYTE);
784 LOG2(dsSize, exp);
785 }
786 p_Qm->p_FqdBase = XX_MallocSmart(dsSize, (int)p_QmDriverParams->fqdMemPartitionId, dsSize);
787 if (!p_Qm->p_FqdBase)
788 {
789 RETURN_ERROR(MAJOR, E_NO_MEMORY, ("FQD obj!!!"));
790 }
791 memset(p_Qm->p_FqdBase, 0, dsSize);
792 mb();
793 for (i=0; i<dsSize; i+=64)
794 dcbf(PTR_MOVE(p_Qm->p_FqdBase, i));
795 mb();
796
797 phyAddr = XX_VirtToPhys(p_Qm->p_FqdBase);
798 WRITE_UINT32(p_Qm->p_QmRegs->fqd_bare, ((uint32_t)(phyAddr >> 32) & 0x000000ff));
799 WRITE_UINT32(p_Qm->p_QmRegs->fqd_bar, (uint32_t)phyAddr);
800 WRITE_UINT32(p_Qm->p_QmRegs->fqd_ar, AR_ENABLE | (exp - 1));
801
802 /* PFDR memory */
803 dsSize = (uint32_t)(p_QmDriverParams->rtFramesDepth * (PFDR_ENTRY_SIZE/3));
804 LOG2(dsSize, exp);
805 if (!POWER_OF_2(dsSize)) (exp++);
806 dsSize = (uint32_t)(1 << exp);
807 if (dsSize < (4*KILOBYTE))
808 {
809 dsSize = (4*KILOBYTE);
810 LOG2(dsSize, exp);
811 }
812
813 p_Qm->p_PfdrBase = XX_MallocSmart(dsSize, (int)p_QmDriverParams->pfdrMemPartitionId, dsSize);
814 if (!p_Qm->p_PfdrBase)
815 RETURN_ERROR(MAJOR, E_NO_MEMORY, ("PFDR obj!!!"));
816
817 phyAddr = XX_VirtToPhys(p_Qm->p_PfdrBase);
818 WRITE_UINT32(p_Qm->p_QmRegs->pfdr_bare, ((uint32_t)(phyAddr >> 32) & 0x000000ff));
819 WRITE_UINT32(p_Qm->p_QmRegs->pfdr_bar, (uint32_t)phyAddr);
820 WRITE_UINT32(p_Qm->p_QmRegs->pfdr_ar, AR_ENABLE | (exp - 1));
821
822 if (QmInitPfdr(p_Qm, 8, dsSize / 64 - 8) != E_OK)
823 RETURN_ERROR(MAJOR, E_INVALID_STATE, ("PFDR init failed!!!"));
824
825 /* thresholds */
826 WRITE_UINT32(p_Qm->p_QmRegs->pfdr_fp_lwit, (p_Qm->p_QmDriverParams->pfdrThreshold & 0xffffff));
827 WRITE_UINT32(p_Qm->p_QmRegs->pfdr_cfg, p_Qm->p_QmDriverParams->pfdrBaseConstant);
828 WRITE_UINT32(p_Qm->p_QmRegs->sfdr_cfg, (p_Qm->p_QmDriverParams->sfdrThreshold & 0x3ff));
829
830 p_Qm->numOfPfdr = GET_UINT32(p_Qm->p_QmRegs->pfdr_fpc);
831
832 /* corenet initiator settings */
833 WRITE_UINT32(p_Qm->p_QmRegs->ci_sched_cfg,
834 (CI_SCHED_CFG_EN |
835 (DEFAULT_initiatorSrcciv << CI_SCHED_CFG_SRCCIV_SHIFT) |
836 (DEFAULT_initiatorSrqW << CI_SCHED_CFG_SRQ_W_SHIFT) |
837 (DEFAULT_initiatorRwW << CI_SCHED_CFG_RW_W_SHIFT) |
838 (DEFAULT_initiatorBmanW << CI_SCHED_CFG_BMAN_W_SHIFT)));
839
840 /* HID settings */
841 if ((revInfo.majorRev == 1) && (revInfo.minorRev == 0))
842 /* offset 0x0bf0 */
843 WRITE_UINT32(p_Qm->p_QmRegs->res23[144], 0x3);
844 else
845 WRITE_UINT32(p_Qm->p_QmRegs->res23[144], 0x0);
846
847 for(i=0;i<DPAA_MAX_NUM_OF_DC_PORTALS;i++)
848 {
849 if(p_Qm->p_QmDriverParams->dcPortalsParams[i].sendToSw)
850 WRITE_UINT32(p_Qm->p_QmRegs->dcpConfRegs[i].cfg,
851 p_Qm->p_QmDriverParams->dcPortalsParams[i].swPortalId);
852 else
853 WRITE_UINT32(p_Qm->p_QmRegs->dcpConfRegs[i].cfg, QM_DCP_CFG_ED);
854 }
855
856 #ifdef QMAN_WQ_CS_CFG_ERRATA_QMAN4
857 {
858 t_QmRevisionInfo revInfo;
859 QmGetRevision(p_Qm, &revInfo);
860 if ((revInfo.majorRev == 1) && (revInfo.minorRev == 0))
861 {
862 QmSetWqScheduling(p_Qm, e_QM_WQ_SW_PORTALS,0,1,1,1,1,1,1);
863 QmSetWqScheduling(p_Qm, e_QM_WQ_POOLS,0,1,1,1,1,1,1);
864 QmSetWqScheduling(p_Qm, e_QM_WQ_DCP0,0,1,1,1,1,1,1);
865 QmSetWqScheduling(p_Qm, e_QM_WQ_DCP1,0,1,1,1,1,1,1);
866 QmSetWqScheduling(p_Qm, e_QM_WQ_DCP2,0,1,1,1,1,1,1);
867 QmSetWqScheduling(p_Qm, e_QM_WQ_DCP3,0,1,1,1,1,1,1);
868 }
869 }
870 #endif /* QMAN_WQ_CS_CFG_ERRATA_QMAN4 */
871
872 WRITE_UINT32(p_Qm->p_QmRegs->err_isr, p_Qm->exceptions);
873 WRITE_UINT32(p_Qm->p_QmRegs->err_ier, p_Qm->exceptions);
874 WRITE_UINT32(p_Qm->p_QmRegs->err_isdr, 0x0);
875 if (p_Qm->errIrq != NO_IRQ)
876 {
877 XX_SetIntr(p_Qm->errIrq, QM_ErrorIsr, p_Qm);
878 XX_EnableIntr(p_Qm->errIrq);
879 }
880 if ((err = XX_IpcRegisterMsgHandler(p_Qm->moduleName, QmHandleIpcMsgCB, p_Qm, QM_IPC_MAX_REPLY_SIZE)) != E_OK)
881 RETURN_ERROR(MAJOR, err, NO_MSG);
882 }
883 else /* guest mode */
884 {
885 char masterModuleName[MODULE_NAME_SIZE];
886
887 memset(masterModuleName, 0, MODULE_NAME_SIZE);
888 if(Sprint (masterModuleName, "QM_0_%d", NCSW_MASTER_ID) != (NCSW_MASTER_ID<10 ? 6:7))
889 {
890 RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Sprint failed"));
891 }
892
893 p_Qm->h_Session = XX_IpcInitSession(masterModuleName, p_Qm->moduleName);
894 if (p_Qm->h_Session)
895 {
896 t_QmIpcMsg msg;
897 uint8_t isMasterAlive = 0;
898 t_QmIpcReply reply;
899 uint32_t replyLength;
900
901 memset(&msg, 0, sizeof(t_QmIpcMsg));
902 memset(&reply, 0, sizeof(t_QmIpcReply));
903 msg.msgId = QM_MASTER_IS_ALIVE;
904 do
905 {
906 blockingFlag = TRUE;
907 replyLength = sizeof(uint32_t) + sizeof(uint8_t);
908 if ((err = XX_IpcSendMessage(p_Qm->h_Session,
909 (uint8_t*)&msg,
910 sizeof(msg.msgId),
911 (uint8_t*)&reply,
912 &replyLength,
913 QmIpcMsgCompletionCB,
914 p_Qm)) != E_OK)
915 REPORT_ERROR(MAJOR, err, NO_MSG);
916 while(blockingFlag) ;
917 if(replyLength != (sizeof(uint32_t) + sizeof(uint8_t)))
918 REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
919 isMasterAlive = *(uint8_t*)(reply.replyBody);
920 } while (!isMasterAlive);
921 }
922 }
923
924 p_Qm->lock = XX_InitSpinlock();
925 XX_Free(p_Qm->p_QmDriverParams);
926 p_Qm->p_QmDriverParams = NULL;
927
928 return E_OK;
929 }
930
QM_Free(t_Handle h_Qm)931 t_Error QM_Free(t_Handle h_Qm)
932 {
933 t_Qm *p_Qm = (t_Qm *)h_Qm;
934
935 SANITY_CHECK_RETURN_ERROR(p_Qm, E_INVALID_HANDLE);
936
937 if (p_Qm->lock)
938 XX_FreeSpinlock(p_Qm->lock);
939
940 if (p_Qm->guestId == NCSW_MASTER_ID)
941 {
942 XX_IpcUnregisterMsgHandler(p_Qm->moduleName);
943 if (p_Qm->errIrq != NO_IRQ)
944 {
945 XX_DisableIntr(p_Qm->errIrq);
946 XX_FreeIntr(p_Qm->errIrq);
947 }
948 }
949 FreeInitResources(p_Qm);
950
951 if (p_Qm->p_QmDriverParams)
952 XX_Free(p_Qm->p_QmDriverParams);
953
954 XX_Free(p_Qm);
955
956 return E_OK;
957 }
958
QM_ConfigRTFramesDepth(t_Handle h_Qm,uint32_t rtFramesDepth)959 t_Error QM_ConfigRTFramesDepth(t_Handle h_Qm, uint32_t rtFramesDepth)
960 {
961 t_Qm *p_Qm = (t_Qm *)h_Qm;
962
963 SANITY_CHECK_RETURN_ERROR(p_Qm, E_INVALID_HANDLE);
964 SANITY_CHECK_RETURN_ERROR(p_Qm->p_QmDriverParams, E_INVALID_HANDLE);
965
966 p_Qm->p_QmDriverParams->rtFramesDepth = rtFramesDepth;
967
968 return E_OK;
969 }
970
QM_ConfigPfdrThreshold(t_Handle h_Qm,uint32_t threshold)971 t_Error QM_ConfigPfdrThreshold(t_Handle h_Qm, uint32_t threshold)
972 {
973 t_Qm *p_Qm = (t_Qm *)h_Qm;
974
975 SANITY_CHECK_RETURN_ERROR(p_Qm, E_INVALID_HANDLE);
976 SANITY_CHECK_RETURN_ERROR(p_Qm->p_QmDriverParams, E_INVALID_HANDLE);
977
978 p_Qm->p_QmDriverParams->pfdrThreshold = threshold;
979
980 return E_OK;
981 }
982
QM_ConfigSfdrReservationThreshold(t_Handle h_Qm,uint32_t threshold)983 t_Error QM_ConfigSfdrReservationThreshold(t_Handle h_Qm, uint32_t threshold)
984 {
985 t_Qm *p_Qm = (t_Qm *)h_Qm;
986
987 SANITY_CHECK_RETURN_ERROR(p_Qm, E_INVALID_HANDLE);
988 SANITY_CHECK_RETURN_ERROR(p_Qm->p_QmDriverParams, E_INVALID_HANDLE);
989
990 p_Qm->p_QmDriverParams->sfdrThreshold = threshold;
991
992 return E_OK;
993 }
994
995
QM_ConfigErrorRejectionNotificationDest(t_Handle h_Qm,e_DpaaDcPortal id,t_QmDcPortalParams * p_Params)996 t_Error QM_ConfigErrorRejectionNotificationDest(t_Handle h_Qm, e_DpaaDcPortal id, t_QmDcPortalParams *p_Params)
997 {
998 UNUSED(h_Qm); UNUSED(id); UNUSED(p_Params);
999
1000 RETURN_ERROR(INFO, E_NOT_SUPPORTED, ("Only default ERN destination available."));
1001 }
1002
1003
QM_Poll(t_Handle h_Qm,e_QmPortalPollSource source)1004 t_Error QM_Poll(t_Handle h_Qm, e_QmPortalPollSource source)
1005 {
1006 t_Qm *p_Qm = (t_Qm *)h_Qm;
1007 t_QmPortal *p_QmPortal;
1008
1009 SANITY_CHECK_RETURN_ERROR(p_Qm, E_INVALID_HANDLE);
1010 p_QmPortal = QmGetPortalHandle(p_Qm);
1011 SANITY_CHECK_RETURN_ERROR(p_QmPortal, E_INVALID_HANDLE);
1012
1013 return QM_PORTAL_Poll(p_QmPortal, source);
1014 }
1015
QM_GetCounter(t_Handle h_Qm,e_QmCounters counter)1016 uint32_t QM_GetCounter(t_Handle h_Qm, e_QmCounters counter)
1017 {
1018 t_Qm *p_Qm = (t_Qm *)h_Qm;
1019
1020 SANITY_CHECK_RETURN_VALUE(p_Qm, E_INVALID_HANDLE, 0);
1021 SANITY_CHECK_RETURN_VALUE(!p_Qm->p_QmDriverParams, E_INVALID_STATE, 0);
1022
1023 switch(counter)
1024 {
1025 case(e_QM_COUNTERS_SFDR_IN_USE):
1026 return QmGetCounter(p_Qm, e_QM_IM_COUNTERS_SFDR_IN_USE);
1027 case(e_QM_COUNTERS_PFDR_IN_USE):
1028 return QmGetCounter(p_Qm, e_QM_IM_COUNTERS_PFDR_IN_USE);
1029 case(e_QM_COUNTERS_PFDR_FREE_POOL):
1030 return QmGetCounter(p_Qm, e_QM_IM_COUNTERS_PFDR_FREE_POOL);
1031 default:
1032 break;
1033 }
1034 /* should never get here */
1035 ASSERT_COND(FALSE);
1036
1037 return 0;
1038 }
1039
QM_ErrorIsr(t_Handle h_Qm)1040 void QM_ErrorIsr(t_Handle h_Qm)
1041 {
1042 t_Qm *p_Qm = (t_Qm *)h_Qm;
1043 uint32_t tmpReg;
1044
1045 SANITY_CHECK_RETURN(p_Qm, E_INVALID_HANDLE);
1046
1047 if (p_Qm->guestId != NCSW_MASTER_ID)
1048 {
1049 REPORT_ERROR(WARNING, E_INVALID_OPERATION, ("Master Only"));
1050 return;
1051 }
1052
1053 tmpReg = GET_UINT32(p_Qm->p_QmRegs->err_isr);
1054 tmpReg &= GET_UINT32(p_Qm->p_QmRegs->err_ier);
1055 WRITE_UINT32(p_Qm->p_QmRegs->err_isr, tmpReg);
1056
1057 if (tmpReg & QM_EX_CORENET_INITIATOR_DATA)
1058 p_Qm->f_Exception(p_Qm->h_App, e_QM_EX_CORENET_INITIATOR_DATA);
1059 if (tmpReg & QM_EX_CORENET_TARGET_DATA)
1060 p_Qm->f_Exception(p_Qm->h_App, e_QM_EX_CORENET_TARGET_DATA);
1061 if (tmpReg & QM_EX_CORENET_INVALID_TARGET_TRANSACTION)
1062 p_Qm->f_Exception(p_Qm->h_App, e_QM_EX_CORENET_INVALID_TARGET_TRANSACTION);
1063 if (tmpReg & QM_EX_PFDR_THRESHOLD)
1064 p_Qm->f_Exception(p_Qm->h_App, e_QM_EX_PFDR_THRESHOLD);
1065 if (tmpReg & QM_EX_MULTI_ECC)
1066 p_Qm->f_Exception(p_Qm->h_App, e_QM_EX_MULTI_ECC);
1067 if (tmpReg & QM_EX_SINGLE_ECC)
1068 p_Qm->f_Exception(p_Qm->h_App, e_QM_EX_SINGLE_ECC);
1069 if (tmpReg & QM_EX_PFDR_ENQUEUE_BLOCKED)
1070 p_Qm->f_Exception(p_Qm->h_App, e_QM_EX_PFDR_ENQUEUE_BLOCKED);
1071 if (tmpReg & QM_EX_INVALID_COMMAND)
1072 p_Qm->f_Exception(p_Qm->h_App, e_QM_EX_INVALID_COMMAND);
1073 if (tmpReg & QM_EX_DEQUEUE_DCP)
1074 p_Qm->f_Exception(p_Qm->h_App, e_QM_EX_DEQUEUE_DCP);
1075 if (tmpReg & QM_EX_DEQUEUE_FQ)
1076 p_Qm->f_Exception(p_Qm->h_App, e_QM_EX_DEQUEUE_FQ);
1077 if (tmpReg & QM_EX_DEQUEUE_SOURCE)
1078 p_Qm->f_Exception(p_Qm->h_App, e_QM_EX_DEQUEUE_SOURCE);
1079 if (tmpReg & QM_EX_DEQUEUE_QUEUE)
1080 p_Qm->f_Exception(p_Qm->h_App, e_QM_EX_DEQUEUE_QUEUE);
1081 if (tmpReg & QM_EX_ENQUEUE_OVERFLOW)
1082 p_Qm->f_Exception(p_Qm->h_App, e_QM_EX_ENQUEUE_OVERFLOW);
1083 if (tmpReg & QM_EX_ENQUEUE_STATE)
1084 p_Qm->f_Exception(p_Qm->h_App, e_QM_EX_ENQUEUE_STATE);
1085 if (tmpReg & QM_EX_ENQUEUE_CHANNEL)
1086 p_Qm->f_Exception(p_Qm->h_App, e_QM_EX_ENQUEUE_CHANNEL);
1087 if (tmpReg & QM_EX_ENQUEUE_QUEUE)
1088 p_Qm->f_Exception(p_Qm->h_App, e_QM_EX_ENQUEUE_QUEUE);
1089 }
1090
QM_SetException(t_Handle h_Qm,e_QmExceptions exception,bool enable)1091 t_Error QM_SetException(t_Handle h_Qm, e_QmExceptions exception, bool enable)
1092 {
1093 t_Qm *p_Qm = (t_Qm*)h_Qm;
1094 t_Error err = E_OK;
1095
1096 SANITY_CHECK_RETURN_ERROR(p_Qm, E_INVALID_HANDLE);
1097 SANITY_CHECK_RETURN_ERROR(!p_Qm->p_QmDriverParams, E_INVALID_HANDLE);
1098
1099 if ((err = SetException(p_Qm, exception, enable)) != E_OK)
1100 RETURN_ERROR(MINOR, err, NO_MSG);
1101
1102 WRITE_UINT32(p_Qm->p_QmRegs->err_ier, p_Qm->exceptions);
1103
1104 return E_OK;
1105 }
1106
QM_GetRevision(t_Handle h_Qm,t_QmRevisionInfo * p_QmRevisionInfo)1107 t_Error QM_GetRevision(t_Handle h_Qm, t_QmRevisionInfo *p_QmRevisionInfo)
1108 {
1109 t_Qm *p_Qm = (t_Qm*)h_Qm;
1110
1111 SANITY_CHECK_RETURN_ERROR(p_Qm, E_INVALID_HANDLE);
1112 SANITY_CHECK_RETURN_ERROR(p_QmRevisionInfo, E_NULL_POINTER);
1113
1114 return QmGetRevision(p_Qm, p_QmRevisionInfo);
1115 }
1116
QM_ReserveQueues(t_Handle h_Qm,t_QmRsrvFqrParams * p_QmFqrParams,uint32_t * p_BaseFqid)1117 t_Error QM_ReserveQueues(t_Handle h_Qm, t_QmRsrvFqrParams *p_QmFqrParams, uint32_t *p_BaseFqid)
1118 {
1119 t_Qm *p_Qm = (t_Qm*)h_Qm;
1120
1121 SANITY_CHECK_RETURN_ERROR(p_Qm, E_INVALID_HANDLE);
1122 SANITY_CHECK_RETURN_ERROR(!p_Qm->p_QmDriverParams, E_INVALID_HANDLE);
1123
1124 *p_BaseFqid = ReserveFqids(p_Qm,
1125 (uint32_t)((p_QmFqrParams->useForce && !p_QmFqrParams->numOfFqids) ?
1126 1 : p_QmFqrParams->numOfFqids),
1127 p_QmFqrParams->qs.nonFrcQs.align,
1128 p_QmFqrParams->useForce,
1129 p_QmFqrParams->qs.frcQ.fqid);
1130 if (*p_BaseFqid == ILLEGAL_BASE)
1131 RETURN_ERROR(CRITICAL,E_INVALID_STATE,("can't allocate a fqid"));
1132
1133 return E_OK;
1134 }
1135
QM_GetErrorInformation(t_Handle h_Qm,t_QmErrorInfo * p_errInfo)1136 t_Error QM_GetErrorInformation(t_Handle h_Qm, t_QmErrorInfo *p_errInfo)
1137 {
1138 uint32_t ecsr, ecir;
1139 t_Qm *p_Qm = (t_Qm*)h_Qm;
1140 t_Error err = E_OK;
1141
1142 SANITY_CHECK_RETURN_ERROR(p_Qm, E_INVALID_HANDLE);
1143 SANITY_CHECK_RETURN_ERROR(!p_Qm->p_QmDriverParams, E_INVALID_HANDLE);
1144 SANITY_CHECK_RETURN_ERROR(p_errInfo, E_NULL_POINTER);
1145
1146 ecsr = GET_UINT32(p_Qm->p_QmRegs->ecsr);
1147 ecir = GET_UINT32(p_Qm->p_QmRegs->ecir);
1148 if ((ecsr & QM_EX_MULTI_ECC) ||
1149 (ecsr & QM_EX_SINGLE_ECC))
1150 {
1151 err = E_NOT_SUPPORTED;
1152 REPORT_ERROR(INFO, E_NOT_SUPPORTED, ("single and multi ecc, use QM_DumpRegs"));
1153 }
1154 if ((ecsr & QM_EX_ENQUEUE_QUEUE) ||
1155 (ecsr & QM_EX_ENQUEUE_STATE) ||
1156 (ecsr & QM_EX_ENQUEUE_OVERFLOW) ||
1157 (ecsr & QM_EX_DEQUEUE_DCP) ||
1158 (ecsr & QM_EX_DEQUEUE_FQ) ||
1159 (ecsr & QM_EX_DEQUEUE_QUEUE) ||
1160 (ecsr & QM_EX_DEQUEUE_SOURCE) ||
1161 (ecsr & QM_EX_INVALID_COMMAND))
1162 {
1163 p_errInfo->portalValid = TRUE;
1164 p_errInfo->hwPortal = (bool)(ecir & ECIR_PORTAL_TYPE);
1165 if (p_errInfo->hwPortal)
1166 p_errInfo->dcpId = (e_DpaaDcPortal)((ecir & ECIR_PORTAL_MASK) >> ECIR_PORTAL_SHIFT);
1167 else
1168 p_errInfo->swPortalId = (e_DpaaSwPortal)((ecir & ECIR_PORTAL_MASK) >> ECIR_PORTAL_SHIFT);
1169 }
1170
1171 if ((ecsr & QM_EX_ENQUEUE_QUEUE) ||
1172 (ecsr & QM_EX_ENQUEUE_STATE) ||
1173 (ecsr & QM_EX_ENQUEUE_OVERFLOW) ||
1174 (ecsr & QM_EX_ENQUEUE_CHANNEL) ||
1175 (ecsr & QM_EX_DEQUEUE_QUEUE) ||
1176 (ecsr & QM_EX_DEQUEUE_FQ))
1177 {
1178 p_errInfo->fqidValid = TRUE;
1179 p_errInfo->fqid = ((ecir & ECIR_FQID_MASK) >> ECIR_FQID_SHIFT);
1180 }
1181
1182 WRITE_UINT32(p_Qm->p_QmRegs->ecsr, ecsr);
1183
1184 return ERROR_CODE(err);
1185 }
1186
1187 #if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
QM_DumpRegs(t_Handle h_Qm)1188 t_Error QM_DumpRegs(t_Handle h_Qm)
1189 {
1190 t_Qm *p_Qm = (t_Qm *)h_Qm;
1191 uint8_t i = 0;
1192
1193 DECLARE_DUMP;
1194
1195 SANITY_CHECK_RETURN_ERROR(p_Qm, E_INVALID_HANDLE);
1196 SANITY_CHECK_RETURN_ERROR(!p_Qm->p_QmDriverParams, E_INVALID_STATE);
1197
1198 DUMP_SUBTITLE(("\n"));
1199 DUMP_TITLE(p_Qm->p_QmRegs, ("QmRegs Regs"));
1200
1201 DUMP_SUBSTRUCT_ARRAY(i, QM_NUM_OF_SWP)
1202 {
1203 DUMP_VAR(&p_Qm->p_QmRegs->swpConfRegs[i], lio_cfg);
1204 DUMP_VAR(&p_Qm->p_QmRegs->swpConfRegs[i], io_cfg);
1205 DUMP_VAR(&p_Qm->p_QmRegs->swpConfRegs[i], dd_cfg);
1206 }
1207 DUMP_VAR(p_Qm->p_QmRegs, qman_dd_cfg);
1208 DUMP_VAR(p_Qm->p_QmRegs, qcsp_dd_ihrsr);
1209 DUMP_VAR(p_Qm->p_QmRegs, qcsp_dd_ihrfr);
1210 DUMP_VAR(p_Qm->p_QmRegs, qcsp_dd_hasr);
1211 DUMP_VAR(p_Qm->p_QmRegs, dcp_dd_ihrsr);
1212 DUMP_VAR(p_Qm->p_QmRegs, dcp_dd_ihrfr);
1213 DUMP_VAR(p_Qm->p_QmRegs, dcp_dd_hasr);
1214 DUMP_SUBSTRUCT_ARRAY(i, QM_NUM_OF_DCP)
1215 {
1216 DUMP_VAR(&p_Qm->p_QmRegs->dcpConfRegs[i], cfg);
1217 DUMP_VAR(&p_Qm->p_QmRegs->dcpConfRegs[i], dd_cfg);
1218 DUMP_VAR(&p_Qm->p_QmRegs->dcpConfRegs[i], dlm_cfg);
1219 DUMP_VAR(&p_Qm->p_QmRegs->dcpConfRegs[i], dlm_avg);
1220 }
1221 DUMP_VAR(p_Qm->p_QmRegs, pfdr_fpc);
1222 DUMP_VAR(p_Qm->p_QmRegs, pfdr_fp_head);
1223 DUMP_VAR(p_Qm->p_QmRegs, pfdr_fp_tail);
1224 DUMP_VAR(p_Qm->p_QmRegs, pfdr_fp_lwit);
1225 DUMP_VAR(p_Qm->p_QmRegs, pfdr_cfg);
1226 DUMP_VAR(p_Qm->p_QmRegs, sfdr_cfg);
1227 DUMP_VAR(p_Qm->p_QmRegs, sfdr_in_use);
1228 DUMP_ARR(p_Qm->p_QmRegs, wq_cs_cfg);
1229 DUMP_VAR(p_Qm->p_QmRegs, wq_def_enq_wqid);
1230 DUMP_ARR(p_Qm->p_QmRegs, wq_sc_dd_cfg);
1231 DUMP_ARR(p_Qm->p_QmRegs, wq_pc_dd_cs_cfg);
1232 DUMP_ARR(p_Qm->p_QmRegs, wq_dc0_dd_cs_cfg);
1233 DUMP_ARR(p_Qm->p_QmRegs, wq_dc1_dd_cs_cfg);
1234 DUMP_VAR(p_Qm->p_QmRegs, wq_dc2_dd_cs_cfg);
1235 DUMP_VAR(p_Qm->p_QmRegs, wq_dc3_dd_cs_cfg);
1236 DUMP_VAR(p_Qm->p_QmRegs, cm_cfg);
1237 DUMP_VAR(p_Qm->p_QmRegs, ecsr);
1238 DUMP_VAR(p_Qm->p_QmRegs, ecir);
1239 DUMP_VAR(p_Qm->p_QmRegs, eadr);
1240 DUMP_ARR(p_Qm->p_QmRegs, edata);
1241 DUMP_VAR(p_Qm->p_QmRegs, sbet);
1242 DUMP_ARR(p_Qm->p_QmRegs, sbec);
1243 DUMP_VAR(p_Qm->p_QmRegs, mcr);
1244 DUMP_VAR(p_Qm->p_QmRegs, mcp0);
1245 DUMP_VAR(p_Qm->p_QmRegs, mcp1);
1246 DUMP_ARR(p_Qm->p_QmRegs, mr);
1247 DUMP_VAR(p_Qm->p_QmRegs, idle_stat);
1248 DUMP_VAR(p_Qm->p_QmRegs, ip_rev_1);
1249 DUMP_VAR(p_Qm->p_QmRegs, ip_rev_2);
1250 DUMP_VAR(p_Qm->p_QmRegs, fqd_bare);
1251 DUMP_VAR(p_Qm->p_QmRegs, fqd_bar);
1252 DUMP_VAR(p_Qm->p_QmRegs, fqd_ar);
1253 DUMP_VAR(p_Qm->p_QmRegs, pfdr_bare);
1254 DUMP_VAR(p_Qm->p_QmRegs, pfdr_bar);
1255 DUMP_VAR(p_Qm->p_QmRegs, pfdr_ar);
1256 DUMP_VAR(p_Qm->p_QmRegs, qcsp_bare);
1257 DUMP_VAR(p_Qm->p_QmRegs, qcsp_bar);
1258 DUMP_VAR(p_Qm->p_QmRegs, ci_sched_cfg);
1259 DUMP_VAR(p_Qm->p_QmRegs, srcidr);
1260 DUMP_VAR(p_Qm->p_QmRegs, liodnr);
1261 DUMP_VAR(p_Qm->p_QmRegs, ci_rlm_cfg);
1262 DUMP_VAR(p_Qm->p_QmRegs, ci_rlm_avg);
1263 DUMP_VAR(p_Qm->p_QmRegs, err_isr);
1264 DUMP_VAR(p_Qm->p_QmRegs, err_ier);
1265 DUMP_VAR(p_Qm->p_QmRegs, err_isdr);
1266 DUMP_VAR(p_Qm->p_QmRegs, err_iir);
1267 DUMP_VAR(p_Qm->p_QmRegs, err_her);
1268
1269 return E_OK;
1270 }
1271 #endif /* (defined(DEBUG_ERRORS) && ... */
1272