Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/sys/contrib/ncsw/Peripherals/QM/qm.c
48378 views
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;
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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))
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
1273