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