1 /* 2 * Copyright 2008-2012 Freescale Semiconductor Inc. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions are met: 6 * * Redistributions of source code must retain the above copyright 7 * notice, this list of conditions and the following disclaimer. 8 * * Redistributions in binary form must reproduce the above copyright 9 * notice, this list of conditions and the following disclaimer in the 10 * documentation and/or other materials provided with the distribution. 11 * * Neither the name of Freescale Semiconductor nor the 12 * names of its contributors may be used to endorse or promote products 13 * derived from this software without specific prior written permission. 14 * 15 * 16 * ALTERNATIVELY, this software may be distributed under the terms of the 17 * GNU General Public License ("GPL") as published by the Free Software 18 * Foundation, either version 2 of that License or (at your option) any 19 * later version. 20 * 21 * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY 22 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 23 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 24 * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY 25 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 26 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 27 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 28 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 30 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 */ 32 33 34 /****************************************************************************** 35 @File fm_pcd.c 36 37 @Description FM PCD ... 38 *//***************************************************************************/ 39 #include "std_ext.h" 40 #include "error_ext.h" 41 #include "string_ext.h" 42 #include "xx_ext.h" 43 #include "sprint_ext.h" 44 #include "debug_ext.h" 45 #include "net_ext.h" 46 #include "fm_ext.h" 47 #include "fm_pcd_ext.h" 48 49 #include "fm_common.h" 50 #include "fm_pcd.h" 51 #include "fm_pcd_ipc.h" 52 #include "fm_hc.h" 53 #include "fm_muram_ext.h" 54 55 56 /****************************************/ 57 /* static functions */ 58 /****************************************/ 59 60 static t_Error CheckFmPcdParameters(t_FmPcd *p_FmPcd) 61 { 62 if (!p_FmPcd->h_Fm) 63 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("h_Fm has to be initialized")); 64 65 if (p_FmPcd->guestId == NCSW_MASTER_ID) 66 { 67 if (p_FmPcd->p_FmPcdKg && !p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs) 68 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Something WRONG")); 69 70 if (p_FmPcd->p_FmPcdPlcr && !p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs) 71 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Something WRONG")); 72 73 if (!p_FmPcd->f_Exception) 74 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("f_FmPcdExceptions has to be initialized")); 75 76 if ((!p_FmPcd->f_FmPcdIndexedException) && (p_FmPcd->p_FmPcdPlcr || p_FmPcd->p_FmPcdKg)) 77 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("f_FmPcdIndexedException has to be initialized")); 78 79 if (p_FmPcd->p_FmPcdDriverParam->prsMaxParseCycleLimit > PRS_MAX_CYCLE_LIMIT) 80 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("prsMaxParseCycleLimit has to be less than 8191")); 81 } 82 83 return E_OK; 84 } 85 86 static volatile bool blockingFlag = FALSE; 87 static void IpcMsgCompletionCB(t_Handle h_FmPcd, 88 uint8_t *p_Msg, 89 uint8_t *p_Reply, 90 uint32_t replyLength, 91 t_Error status) 92 { 93 UNUSED(h_FmPcd);UNUSED(p_Msg);UNUSED(p_Reply);UNUSED(replyLength);UNUSED(status); 94 blockingFlag = FALSE; 95 } 96 97 static t_Error IpcMsgHandlerCB(t_Handle h_FmPcd, 98 uint8_t *p_Msg, 99 uint32_t msgLength, 100 uint8_t *p_Reply, 101 uint32_t *p_ReplyLength) 102 { 103 t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; 104 t_Error err = E_OK; 105 t_FmPcdIpcMsg *p_IpcMsg = (t_FmPcdIpcMsg*)p_Msg; 106 t_FmPcdIpcReply *p_IpcReply = (t_FmPcdIpcReply*)p_Reply; 107 108 SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE); 109 SANITY_CHECK_RETURN_ERROR((msgLength >= sizeof(uint32_t)), E_INVALID_VALUE); 110 111 #ifdef DISABLE_SANITY_CHECKS 112 UNUSED(msgLength); 113 #endif /* DISABLE_SANITY_CHECKS */ 114 115 ASSERT_COND(p_Msg); 116 117 memset(p_IpcReply, 0, (sizeof(uint8_t) * FM_PCD_MAX_REPLY_SIZE)); 118 *p_ReplyLength = 0; 119 120 switch (p_IpcMsg->msgId) 121 { 122 case (FM_PCD_MASTER_IS_ALIVE): 123 *(uint8_t*)(p_IpcReply->replyBody) = 1; 124 p_IpcReply->error = E_OK; 125 *p_ReplyLength = sizeof(uint32_t) + sizeof(uint8_t); 126 break; 127 case (FM_PCD_MASTER_IS_ENABLED): 128 /* count partitions registrations */ 129 if (p_FmPcd->enabled) 130 p_FmPcd->numOfEnabledGuestPartitionsPcds++; 131 *(uint8_t*)(p_IpcReply->replyBody) = (uint8_t)p_FmPcd->enabled; 132 p_IpcReply->error = E_OK; 133 *p_ReplyLength = sizeof(uint32_t) + sizeof(uint8_t); 134 break; 135 case (FM_PCD_GUEST_DISABLE): 136 if (p_FmPcd->numOfEnabledGuestPartitionsPcds) 137 { 138 p_FmPcd->numOfEnabledGuestPartitionsPcds--; 139 p_IpcReply->error = E_OK; 140 } 141 else 142 { 143 REPORT_ERROR(MINOR, E_INVALID_STATE,("Trying to disable an unregistered partition")); 144 p_IpcReply->error = E_INVALID_STATE; 145 } 146 *p_ReplyLength = sizeof(uint32_t); 147 break; 148 case (FM_PCD_GET_COUNTER): 149 { 150 e_FmPcdCounters inCounter; 151 uint32_t outCounter; 152 153 memcpy((uint8_t*)&inCounter, p_IpcMsg->msgBody, sizeof(uint32_t)); 154 outCounter = FM_PCD_GetCounter(h_FmPcd, inCounter); 155 memcpy(p_IpcReply->replyBody, (uint8_t*)&outCounter, sizeof(uint32_t)); 156 p_IpcReply->error = E_OK; 157 *p_ReplyLength = sizeof(uint32_t) + sizeof(uint32_t); 158 break; 159 } 160 case (FM_PCD_ALLOC_KG_SCHEMES): 161 { 162 t_FmPcdIpcKgSchemesParams ipcSchemesParams; 163 164 memcpy((uint8_t*)&ipcSchemesParams, p_IpcMsg->msgBody, sizeof(t_FmPcdIpcKgSchemesParams)); 165 err = FmPcdKgAllocSchemes(h_FmPcd, 166 ipcSchemesParams.numOfSchemes, 167 ipcSchemesParams.guestId, 168 p_IpcReply->replyBody); 169 p_IpcReply->error = err; 170 *p_ReplyLength = sizeof(uint32_t) + ipcSchemesParams.numOfSchemes*sizeof(uint8_t); 171 break; 172 } 173 case (FM_PCD_FREE_KG_SCHEMES): 174 { 175 t_FmPcdIpcKgSchemesParams ipcSchemesParams; 176 177 memcpy((uint8_t*)&ipcSchemesParams, p_IpcMsg->msgBody, sizeof(t_FmPcdIpcKgSchemesParams)); 178 err = FmPcdKgFreeSchemes(h_FmPcd, 179 ipcSchemesParams.numOfSchemes, 180 ipcSchemesParams.guestId, 181 ipcSchemesParams.schemesIds); 182 p_IpcReply->error = err; 183 *p_ReplyLength = sizeof(uint32_t); 184 break; 185 } 186 case (FM_PCD_ALLOC_KG_CLSPLAN): 187 { 188 t_FmPcdIpcKgClsPlanParams ipcKgClsPlanParams; 189 190 memcpy((uint8_t*)&ipcKgClsPlanParams, p_IpcMsg->msgBody, sizeof(t_FmPcdIpcKgClsPlanParams)); 191 err = KgAllocClsPlanEntries(h_FmPcd, 192 ipcKgClsPlanParams.numOfClsPlanEntries, 193 ipcKgClsPlanParams.guestId, 194 p_IpcReply->replyBody); 195 p_IpcReply->error = err; 196 *p_ReplyLength = sizeof(uint32_t) + sizeof(uint8_t); 197 break; 198 } 199 case (FM_PCD_FREE_KG_CLSPLAN): 200 { 201 t_FmPcdIpcKgClsPlanParams ipcKgClsPlanParams; 202 203 memcpy((uint8_t*)&ipcKgClsPlanParams, p_IpcMsg->msgBody, sizeof(t_FmPcdIpcKgClsPlanParams)); 204 KgFreeClsPlanEntries(h_FmPcd, 205 ipcKgClsPlanParams.numOfClsPlanEntries, 206 ipcKgClsPlanParams.guestId, 207 ipcKgClsPlanParams.clsPlanBase); 208 *p_ReplyLength = sizeof(uint32_t); 209 break; 210 } 211 case (FM_PCD_ALLOC_PROFILES): 212 { 213 t_FmIpcResourceAllocParams ipcAllocParams; 214 uint16_t base; 215 memcpy(&ipcAllocParams, p_IpcMsg->msgBody, sizeof(t_FmIpcResourceAllocParams)); 216 base = PlcrAllocProfilesForPartition(h_FmPcd, 217 ipcAllocParams.base, 218 ipcAllocParams.num, 219 ipcAllocParams.guestId); 220 memcpy(p_IpcReply->replyBody, (uint16_t*)&base, sizeof(uint16_t)); 221 *p_ReplyLength = sizeof(uint32_t) + sizeof(uint16_t); 222 break; 223 } 224 case (FM_PCD_FREE_PROFILES): 225 { 226 t_FmIpcResourceAllocParams ipcAllocParams; 227 memcpy(&ipcAllocParams, p_IpcMsg->msgBody, sizeof(t_FmIpcResourceAllocParams)); 228 PlcrFreeProfilesForPartition(h_FmPcd, 229 ipcAllocParams.base, 230 ipcAllocParams.num, 231 ipcAllocParams.guestId); 232 break; 233 } 234 case (FM_PCD_SET_PORT_PROFILES): 235 { 236 t_FmIpcResourceAllocParams ipcAllocParams; 237 memcpy(&ipcAllocParams, p_IpcMsg->msgBody, sizeof(t_FmIpcResourceAllocParams)); 238 PlcrSetPortProfiles(h_FmPcd, 239 ipcAllocParams.guestId, 240 ipcAllocParams.num, 241 ipcAllocParams.base); 242 break; 243 } 244 case (FM_PCD_CLEAR_PORT_PROFILES): 245 { 246 t_FmIpcResourceAllocParams ipcAllocParams; 247 memcpy(&ipcAllocParams, p_IpcMsg->msgBody, sizeof(t_FmIpcResourceAllocParams)); 248 PlcrClearPortProfiles(h_FmPcd, 249 ipcAllocParams.guestId); 250 break; 251 } 252 case (FM_PCD_GET_SW_PRS_OFFSET): 253 { 254 t_FmPcdIpcSwPrsLable ipcSwPrsLable; 255 uint32_t swPrsOffset; 256 257 memcpy((uint8_t*)&ipcSwPrsLable, p_IpcMsg->msgBody, sizeof(t_FmPcdIpcSwPrsLable)); 258 swPrsOffset = 259 FmPcdGetSwPrsOffset(h_FmPcd, 260 (e_NetHeaderType)ipcSwPrsLable.enumHdr, 261 ipcSwPrsLable.indexPerHdr); 262 memcpy(p_IpcReply->replyBody, (uint8_t*)&swPrsOffset, sizeof(uint32_t)); 263 *p_ReplyLength = sizeof(uint32_t) + sizeof(uint32_t); 264 break; 265 } 266 case (FM_PCD_PRS_INC_PORT_STATS): 267 { 268 t_FmPcdIpcPrsIncludePort ipcPrsIncludePort; 269 270 memcpy((uint8_t*)&ipcPrsIncludePort, p_IpcMsg->msgBody, sizeof(t_FmPcdIpcPrsIncludePort)); 271 PrsIncludePortInStatistics(h_FmPcd, 272 ipcPrsIncludePort.hardwarePortId, 273 ipcPrsIncludePort.include); 274 break; 275 } 276 default: 277 *p_ReplyLength = 0; 278 RETURN_ERROR(MINOR, E_INVALID_SELECTION, ("command not found!!!")); 279 } 280 return E_OK; 281 } 282 283 static uint32_t NetEnvLock(t_Handle h_NetEnv) 284 { 285 ASSERT_COND(h_NetEnv); 286 return XX_LockIntrSpinlock(((t_FmPcdNetEnv*)h_NetEnv)->h_Spinlock); 287 } 288 289 static void NetEnvUnlock(t_Handle h_NetEnv, uint32_t intFlags) 290 { 291 ASSERT_COND(h_NetEnv); 292 XX_UnlockIntrSpinlock(((t_FmPcdNetEnv*)h_NetEnv)->h_Spinlock, intFlags); 293 } 294 295 static void EnqueueLockToFreeLst(t_FmPcd *p_FmPcd, t_FmPcdLock *p_Lock) 296 { 297 uint32_t intFlags; 298 299 intFlags = XX_LockIntrSpinlock(p_FmPcd->h_Spinlock); 300 NCSW_LIST_AddToTail(&p_Lock->node, &p_FmPcd->freeLocksLst); 301 XX_UnlockIntrSpinlock(p_FmPcd->h_Spinlock, intFlags); 302 } 303 304 static t_FmPcdLock * DequeueLockFromFreeLst(t_FmPcd *p_FmPcd) 305 { 306 t_FmPcdLock *p_Lock = NULL; 307 uint32_t intFlags; 308 309 intFlags = XX_LockIntrSpinlock(p_FmPcd->h_Spinlock); 310 if (!NCSW_LIST_IsEmpty(&p_FmPcd->freeLocksLst)) 311 { 312 p_Lock = FM_PCD_LOCK_OBJ(p_FmPcd->freeLocksLst.p_Next); 313 NCSW_LIST_DelAndInit(&p_Lock->node); 314 } 315 if (p_FmPcd->h_Spinlock) 316 XX_UnlockIntrSpinlock(p_FmPcd->h_Spinlock, intFlags); 317 318 return p_Lock; 319 } 320 321 static void EnqueueLockToAcquiredLst(t_FmPcd *p_FmPcd, t_FmPcdLock *p_Lock) 322 { 323 uint32_t intFlags; 324 325 intFlags = XX_LockIntrSpinlock(p_FmPcd->h_Spinlock); 326 NCSW_LIST_AddToTail(&p_Lock->node, &p_FmPcd->acquiredLocksLst); 327 XX_UnlockIntrSpinlock(p_FmPcd->h_Spinlock, intFlags); 328 } 329 330 static t_Error FillFreeLocksLst(t_FmPcd *p_FmPcd) 331 { 332 t_FmPcdLock *p_Lock; 333 int i; 334 335 for (i=0; i<10; i++) 336 { 337 p_Lock = (t_FmPcdLock *)XX_Malloc(sizeof(t_FmPcdLock)); 338 if (!p_Lock) 339 RETURN_ERROR(MINOR, E_NO_MEMORY, ("FM-PCD lock obj!")); 340 memset(p_Lock, 0, sizeof(t_FmPcdLock)); 341 INIT_LIST(&p_Lock->node); 342 p_Lock->h_Spinlock = XX_InitSpinlock(); 343 if (!p_Lock->h_Spinlock) 344 { 345 XX_Free(p_Lock); 346 RETURN_ERROR(MINOR, E_INVALID_STATE, ("FM-PCD spinlock obj!")); 347 } 348 EnqueueLockToFreeLst(p_FmPcd, p_Lock); 349 } 350 351 return E_OK; 352 } 353 354 static void ReleaseFreeLocksLst(t_FmPcd *p_FmPcd) 355 { 356 t_FmPcdLock *p_Lock; 357 358 p_Lock = DequeueLockFromFreeLst(p_FmPcd); 359 while (p_Lock) 360 { 361 XX_FreeSpinlock(p_Lock->h_Spinlock); 362 XX_Free(p_Lock); 363 p_Lock = DequeueLockFromFreeLst(p_FmPcd); 364 } 365 } 366 367 368 369 /*****************************************************************************/ 370 /* Inter-module API routines */ 371 /*****************************************************************************/ 372 373 void FmPcdSetClsPlanGrpId(t_FmPcd *p_FmPcd, uint8_t netEnvId, uint8_t clsPlanGrpId) 374 { 375 ASSERT_COND(p_FmPcd); 376 p_FmPcd->netEnvs[netEnvId].clsPlanGrpId = clsPlanGrpId; 377 } 378 379 t_Error PcdGetClsPlanGrpParams(t_FmPcd *p_FmPcd, t_FmPcdKgInterModuleClsPlanGrpParams *p_GrpParams) 380 { 381 uint8_t netEnvId = p_GrpParams->netEnvId; 382 int i, k, j; 383 384 ASSERT_COND(p_FmPcd); 385 if (p_FmPcd->netEnvs[netEnvId].clsPlanGrpId != ILLEGAL_CLS_PLAN) 386 { 387 p_GrpParams->grpExists = TRUE; 388 p_GrpParams->clsPlanGrpId = p_FmPcd->netEnvs[netEnvId].clsPlanGrpId; 389 return E_OK; 390 } 391 392 for (i=0; ((i < FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS) && 393 (p_FmPcd->netEnvs[netEnvId].units[i].hdrs[0].hdr != HEADER_TYPE_NONE)); i++) 394 { 395 for (k=0; ((k < FM_PCD_MAX_NUM_OF_INTERCHANGEABLE_HDRS) && 396 (p_FmPcd->netEnvs[netEnvId].units[i].hdrs[k].hdr != HEADER_TYPE_NONE)); k++) 397 { 398 /* if an option exists, add it to the opts list */ 399 if (p_FmPcd->netEnvs[netEnvId].units[i].hdrs[k].opt) 400 { 401 /* check if this option already exists, add if it doesn't */ 402 for (j = 0;j<p_GrpParams->numOfOptions;j++) 403 { 404 if (p_GrpParams->options[j] == p_FmPcd->netEnvs[netEnvId].units[i].hdrs[k].opt) 405 break; 406 } 407 p_GrpParams->optVectors[j] |= p_FmPcd->netEnvs[netEnvId].unitsVectors[i]; 408 if (j == p_GrpParams->numOfOptions) 409 { 410 p_GrpParams->options[p_GrpParams->numOfOptions] = p_FmPcd->netEnvs[netEnvId].units[i].hdrs[k].opt; 411 p_GrpParams->numOfOptions++; 412 } 413 } 414 } 415 } 416 417 if (p_GrpParams->numOfOptions == 0) 418 { 419 if (p_FmPcd->p_FmPcdKg->emptyClsPlanGrpId != ILLEGAL_CLS_PLAN) 420 { 421 p_GrpParams->grpExists = TRUE; 422 p_GrpParams->clsPlanGrpId = p_FmPcd->p_FmPcdKg->emptyClsPlanGrpId; 423 } 424 } 425 426 return E_OK; 427 428 } 429 430 t_Error PcdGetVectorForOpt(t_FmPcd *p_FmPcd, uint8_t netEnvId, protocolOpt_t opt, uint32_t *p_Vector) 431 { 432 uint8_t j,k; 433 434 *p_Vector = 0; 435 436 ASSERT_COND(p_FmPcd); 437 for (j=0; ((j < FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS) && 438 (p_FmPcd->netEnvs[netEnvId].units[j].hdrs[0].hdr != HEADER_TYPE_NONE)); j++) 439 { 440 for (k=0; ((k < FM_PCD_MAX_NUM_OF_INTERCHANGEABLE_HDRS) && 441 (p_FmPcd->netEnvs[netEnvId].units[j].hdrs[k].hdr != HEADER_TYPE_NONE)); k++) 442 { 443 if (p_FmPcd->netEnvs[netEnvId].units[j].hdrs[k].opt == opt) 444 *p_Vector |= p_FmPcd->netEnvs[netEnvId].unitsVectors[j]; 445 } 446 } 447 448 if (!*p_Vector) 449 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Requested option was not defined for this Network Environment Characteristics module")); 450 else 451 return E_OK; 452 } 453 454 t_Error PcdGetUnitsVector(t_FmPcd *p_FmPcd, t_NetEnvParams *p_Params) 455 { 456 int i; 457 458 ASSERT_COND(p_FmPcd); 459 ASSERT_COND(p_Params->netEnvId < FM_MAX_NUM_OF_PORTS); 460 461 p_Params->vector = 0; 462 for (i=0; i<p_Params->numOfDistinctionUnits ;i++) 463 { 464 if (p_FmPcd->netEnvs[p_Params->netEnvId].units[p_Params->unitIds[i]].hdrs[0].hdr == HEADER_TYPE_NONE) 465 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Requested unit was not defined for this Network Environment Characteristics module")); 466 ASSERT_COND(p_FmPcd->netEnvs[p_Params->netEnvId].unitsVectors[p_Params->unitIds[i]]); 467 p_Params->vector |= p_FmPcd->netEnvs[p_Params->netEnvId].unitsVectors[p_Params->unitIds[i]]; 468 } 469 470 return E_OK; 471 } 472 473 bool PcdNetEnvIsUnitWithoutOpts(t_FmPcd *p_FmPcd, uint8_t netEnvId, uint32_t unitVector) 474 { 475 int i=0, k; 476 477 ASSERT_COND(p_FmPcd); 478 /* check whether a given unit may be used by non-clsPlan users. */ 479 /* first, recognize the unit by its vector */ 480 while (p_FmPcd->netEnvs[netEnvId].units[i].hdrs[0].hdr != HEADER_TYPE_NONE) 481 { 482 if (p_FmPcd->netEnvs[netEnvId].unitsVectors[i] == unitVector) 483 { 484 for (k=0; 485 ((k < FM_PCD_MAX_NUM_OF_INTERCHANGEABLE_HDRS) && 486 (p_FmPcd->netEnvs[netEnvId].units[i].hdrs[k].hdr != HEADER_TYPE_NONE)); 487 k++) 488 /* check that no option exists */ 489 if ((protocolOpt_t)p_FmPcd->netEnvs[netEnvId].units[i].hdrs[k].opt) 490 return FALSE; 491 break; 492 } 493 i++; 494 } 495 /* assert that a unit was found to mach the vector */ 496 ASSERT_COND(p_FmPcd->netEnvs[netEnvId].units[i].hdrs[0].hdr != HEADER_TYPE_NONE); 497 498 return TRUE; 499 } 500 bool FmPcdNetEnvIsHdrExist(t_Handle h_FmPcd, uint8_t netEnvId, e_NetHeaderType hdr) 501 { 502 t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; 503 int i, k; 504 505 ASSERT_COND(p_FmPcd); 506 507 for (i=0; ((i < FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS) && 508 (p_FmPcd->netEnvs[netEnvId].units[i].hdrs[0].hdr != HEADER_TYPE_NONE)); i++) 509 { 510 for (k=0; ((k < FM_PCD_MAX_NUM_OF_INTERCHANGEABLE_HDRS) && 511 (p_FmPcd->netEnvs[netEnvId].units[i].hdrs[k].hdr != HEADER_TYPE_NONE)); k++) 512 if (p_FmPcd->netEnvs[netEnvId].units[i].hdrs[k].hdr == hdr) 513 return TRUE; 514 } 515 for (i=0; ((i < FM_PCD_MAX_NUM_OF_ALIAS_HDRS) && 516 (p_FmPcd->netEnvs[netEnvId].aliasHdrs[i].hdr != HEADER_TYPE_NONE)); i++) 517 { 518 if (p_FmPcd->netEnvs[netEnvId].aliasHdrs[i].hdr == hdr) 519 return TRUE; 520 } 521 522 return FALSE; 523 } 524 525 uint8_t FmPcdNetEnvGetUnitId(t_FmPcd *p_FmPcd, uint8_t netEnvId, e_NetHeaderType hdr, bool interchangeable, protocolOpt_t opt) 526 { 527 uint8_t i, k; 528 529 ASSERT_COND(p_FmPcd); 530 531 if (interchangeable) 532 { 533 for (i=0; (i < FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS) && 534 (p_FmPcd->netEnvs[netEnvId].units[i].hdrs[0].hdr != HEADER_TYPE_NONE); i++) 535 { 536 for (k=0; (k < FM_PCD_MAX_NUM_OF_INTERCHANGEABLE_HDRS) && 537 (p_FmPcd->netEnvs[netEnvId].units[i].hdrs[k].hdr != HEADER_TYPE_NONE); k++) 538 { 539 if ((p_FmPcd->netEnvs[netEnvId].units[i].hdrs[k].hdr == hdr) && 540 (p_FmPcd->netEnvs[netEnvId].units[i].hdrs[k].opt == opt)) 541 542 return i; 543 } 544 } 545 } 546 else 547 { 548 for (i=0; (i < FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS) && 549 (p_FmPcd->netEnvs[netEnvId].units[i].hdrs[0].hdr != HEADER_TYPE_NONE); i++) 550 if ((p_FmPcd->netEnvs[netEnvId].units[i].hdrs[0].hdr == hdr) && 551 (p_FmPcd->netEnvs[netEnvId].units[i].hdrs[0].opt == opt) && 552 (p_FmPcd->netEnvs[netEnvId].units[i].hdrs[1].hdr == HEADER_TYPE_NONE)) 553 return i; 554 555 for (i=0; (i < FM_PCD_MAX_NUM_OF_ALIAS_HDRS) && 556 (p_FmPcd->netEnvs[netEnvId].aliasHdrs[i].hdr != HEADER_TYPE_NONE); i++) 557 if ((p_FmPcd->netEnvs[netEnvId].aliasHdrs[i].hdr == hdr) && 558 (p_FmPcd->netEnvs[netEnvId].aliasHdrs[i].opt == opt)) 559 return p_FmPcd->netEnvs[netEnvId].aliasHdrs[i].aliasHdr; 560 } 561 562 return FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS; 563 } 564 565 t_Error FmPcdUnregisterReassmPort(t_Handle h_FmPcd, t_Handle h_ReasmCommonPramTbl) 566 { 567 t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; 568 t_FmPcdCcReassmTimeoutParams ccReassmTimeoutParams = {0}; 569 uint8_t result; 570 t_Error err = E_OK; 571 572 ASSERT_COND(p_FmPcd); 573 ASSERT_COND(h_ReasmCommonPramTbl); 574 575 ccReassmTimeoutParams.iprcpt = (uint32_t)(XX_VirtToPhys(h_ReasmCommonPramTbl) - p_FmPcd->physicalMuramBase); 576 ccReassmTimeoutParams.activate = FALSE; /*Disable Timeout Task*/ 577 578 if ((err = FmHcPcdCcTimeoutReassm(p_FmPcd->h_Hc, &ccReassmTimeoutParams, &result)) != E_OK) 579 RETURN_ERROR(MAJOR, err, NO_MSG); 580 581 switch (result) 582 { 583 case (0): 584 return E_OK; 585 case (1): 586 RETURN_ERROR(MAJOR, E_INVALID_STATE, ("")); 587 case (2): 588 RETURN_ERROR(MAJOR, E_INVALID_STATE, ("")); 589 case (3): 590 RETURN_ERROR(MAJOR, E_INVALID_HANDLE, ("Disable Timeout Task with invalid IPRCPT")); 591 default: 592 RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG); 593 } 594 595 return E_OK; 596 } 597 598 e_NetHeaderType FmPcdGetAliasHdr(t_FmPcd *p_FmPcd, uint8_t netEnvId, e_NetHeaderType hdr) 599 { 600 int i; 601 602 ASSERT_COND(p_FmPcd); 603 ASSERT_COND(netEnvId < FM_MAX_NUM_OF_PORTS); 604 605 for (i=0; (i < FM_PCD_MAX_NUM_OF_ALIAS_HDRS) 606 && (p_FmPcd->netEnvs[netEnvId].aliasHdrs[i].hdr != HEADER_TYPE_NONE); i++) 607 { 608 if (p_FmPcd->netEnvs[netEnvId].aliasHdrs[i].hdr == hdr) 609 return p_FmPcd->netEnvs[netEnvId].aliasHdrs[i].aliasHdr; 610 } 611 612 return HEADER_TYPE_NONE; 613 } 614 615 void FmPcdPortRegister(t_Handle h_FmPcd, t_Handle h_FmPort, uint8_t hardwarePortId) 616 { 617 t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; 618 uint16_t swPortIndex = 0; 619 620 ASSERT_COND(h_FmPcd); 621 HW_PORT_ID_TO_SW_PORT_INDX(swPortIndex, hardwarePortId); 622 p_FmPcd->p_FmPcdPlcr->portsMapping[swPortIndex].h_FmPort = h_FmPort; 623 } 624 625 uint32_t FmPcdGetLcv(t_Handle h_FmPcd, uint32_t netEnvId, uint8_t hdrNum) 626 { 627 t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; 628 629 ASSERT_COND(h_FmPcd); 630 return p_FmPcd->netEnvs[netEnvId].lcvs[hdrNum]; 631 } 632 633 uint32_t FmPcdGetMacsecLcv(t_Handle h_FmPcd, uint32_t netEnvId) 634 { 635 t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; 636 637 ASSERT_COND(h_FmPcd); 638 return p_FmPcd->netEnvs[netEnvId].macsecVector; 639 } 640 641 uint8_t FmPcdGetNetEnvId(t_Handle h_NetEnv) 642 { 643 return ((t_FmPcdNetEnv*)h_NetEnv)->netEnvId; 644 } 645 646 void FmPcdIncNetEnvOwners(t_Handle h_FmPcd, uint8_t netEnvId) 647 { 648 uint32_t intFlags; 649 650 ASSERT_COND(h_FmPcd); 651 652 intFlags = NetEnvLock(&((t_FmPcd*)h_FmPcd)->netEnvs[netEnvId]); 653 ((t_FmPcd*)h_FmPcd)->netEnvs[netEnvId].owners++; 654 NetEnvUnlock(&((t_FmPcd*)h_FmPcd)->netEnvs[netEnvId], intFlags); 655 } 656 657 void FmPcdDecNetEnvOwners(t_Handle h_FmPcd, uint8_t netEnvId) 658 { 659 uint32_t intFlags; 660 661 ASSERT_COND(h_FmPcd); 662 ASSERT_COND(((t_FmPcd*)h_FmPcd)->netEnvs[netEnvId].owners); 663 664 intFlags = NetEnvLock(&((t_FmPcd*)h_FmPcd)->netEnvs[netEnvId]); 665 ((t_FmPcd*)h_FmPcd)->netEnvs[netEnvId].owners--; 666 NetEnvUnlock(&((t_FmPcd*)h_FmPcd)->netEnvs[netEnvId], intFlags); 667 } 668 669 uint32_t FmPcdLock(t_Handle h_FmPcd) 670 { 671 ASSERT_COND(h_FmPcd); 672 return XX_LockIntrSpinlock(((t_FmPcd*)h_FmPcd)->h_Spinlock); 673 } 674 675 void FmPcdUnlock(t_Handle h_FmPcd, uint32_t intFlags) 676 { 677 ASSERT_COND(h_FmPcd); 678 XX_UnlockIntrSpinlock(((t_FmPcd*)h_FmPcd)->h_Spinlock, intFlags); 679 } 680 681 t_FmPcdLock * FmPcdAcquireLock(t_Handle h_FmPcd) 682 { 683 t_FmPcdLock *p_Lock; 684 ASSERT_COND(h_FmPcd); 685 p_Lock = DequeueLockFromFreeLst((t_FmPcd*)h_FmPcd); 686 if (!p_Lock) 687 { 688 FillFreeLocksLst(h_FmPcd); 689 p_Lock = DequeueLockFromFreeLst((t_FmPcd*)h_FmPcd); 690 } 691 692 if (p_Lock) 693 EnqueueLockToAcquiredLst((t_FmPcd*)h_FmPcd, p_Lock); 694 return p_Lock; 695 } 696 697 void FmPcdReleaseLock(t_Handle h_FmPcd, t_FmPcdLock *p_Lock) 698 { 699 uint32_t intFlags; 700 ASSERT_COND(h_FmPcd); 701 intFlags = FmPcdLock(h_FmPcd); 702 NCSW_LIST_DelAndInit(&p_Lock->node); 703 FmPcdUnlock(h_FmPcd, intFlags); 704 EnqueueLockToFreeLst((t_FmPcd*)h_FmPcd, p_Lock); 705 } 706 707 bool FmPcdLockTryLockAll(t_Handle h_FmPcd) 708 { 709 uint32_t intFlags; 710 t_List *p_Pos, *p_SavedPos=NULL; 711 712 ASSERT_COND(h_FmPcd); 713 intFlags = FmPcdLock(h_FmPcd); 714 NCSW_LIST_FOR_EACH(p_Pos, &((t_FmPcd*)h_FmPcd)->acquiredLocksLst) 715 { 716 t_FmPcdLock *p_Lock = FM_PCD_LOCK_OBJ(p_Pos); 717 if (!FmPcdLockTryLock(p_Lock)) 718 { 719 p_SavedPos = p_Pos; 720 break; 721 } 722 } 723 if (p_SavedPos) 724 { 725 NCSW_LIST_FOR_EACH(p_Pos, &((t_FmPcd*)h_FmPcd)->acquiredLocksLst) 726 { 727 t_FmPcdLock *p_Lock = FM_PCD_LOCK_OBJ(p_Pos); 728 if (p_Pos == p_SavedPos) 729 break; 730 FmPcdLockUnlock(p_Lock); 731 } 732 } 733 FmPcdUnlock(h_FmPcd, intFlags); 734 735 CORE_MemoryBarrier(); 736 737 if (p_SavedPos) 738 return FALSE; 739 740 return TRUE; 741 } 742 743 void FmPcdLockUnlockAll(t_Handle h_FmPcd) 744 { 745 uint32_t intFlags; 746 t_List *p_Pos; 747 748 ASSERT_COND(h_FmPcd); 749 intFlags = FmPcdLock(h_FmPcd); 750 NCSW_LIST_FOR_EACH(p_Pos, &((t_FmPcd*)h_FmPcd)->acquiredLocksLst) 751 { 752 t_FmPcdLock *p_Lock = FM_PCD_LOCK_OBJ(p_Pos); 753 p_Lock->flag = FALSE; 754 } 755 FmPcdUnlock(h_FmPcd, intFlags); 756 757 CORE_MemoryBarrier(); 758 } 759 760 t_Error FmPcdHcSync(t_Handle h_FmPcd) 761 { 762 ASSERT_COND(h_FmPcd); 763 ASSERT_COND(((t_FmPcd*)h_FmPcd)->h_Hc); 764 765 return FmHcPcdSync(((t_FmPcd*)h_FmPcd)->h_Hc); 766 } 767 768 t_Handle FmPcdGetHcHandle(t_Handle h_FmPcd) 769 { 770 ASSERT_COND(h_FmPcd); 771 return ((t_FmPcd*)h_FmPcd)->h_Hc; 772 } 773 774 bool FmPcdIsAdvancedOffloadSupported(t_Handle h_FmPcd) 775 { 776 ASSERT_COND(h_FmPcd); 777 return ((t_FmPcd*)h_FmPcd)->advancedOffloadSupport; 778 } 779 /*********************** End of inter-module routines ************************/ 780 781 782 /****************************************/ 783 /* API Init unit functions */ 784 /****************************************/ 785 786 t_Handle FM_PCD_Config(t_FmPcdParams *p_FmPcdParams) 787 { 788 t_FmPcd *p_FmPcd = NULL; 789 t_FmPhysAddr physicalMuramBase; 790 uint8_t i; 791 792 SANITY_CHECK_RETURN_VALUE(p_FmPcdParams, E_INVALID_HANDLE,NULL); 793 794 p_FmPcd = (t_FmPcd *) XX_Malloc(sizeof(t_FmPcd)); 795 if (!p_FmPcd) 796 { 797 REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM PCD")); 798 return NULL; 799 } 800 memset(p_FmPcd, 0, sizeof(t_FmPcd)); 801 802 p_FmPcd->p_FmPcdDriverParam = (t_FmPcdDriverParam *) XX_Malloc(sizeof(t_FmPcdDriverParam)); 803 if (!p_FmPcd->p_FmPcdDriverParam) 804 { 805 XX_Free(p_FmPcd); 806 REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM PCD Driver Param")); 807 return NULL; 808 } 809 memset(p_FmPcd->p_FmPcdDriverParam, 0, sizeof(t_FmPcdDriverParam)); 810 811 p_FmPcd->h_Fm = p_FmPcdParams->h_Fm; 812 p_FmPcd->guestId = FmGetGuestId(p_FmPcd->h_Fm); 813 p_FmPcd->h_FmMuram = FmGetMuramHandle(p_FmPcd->h_Fm); 814 if (p_FmPcd->h_FmMuram) 815 { 816 FmGetPhysicalMuramBase(p_FmPcdParams->h_Fm, &physicalMuramBase); 817 p_FmPcd->physicalMuramBase = (uint64_t)((uint64_t)(&physicalMuramBase)->low | ((uint64_t)(&physicalMuramBase)->high << 32)); 818 } 819 820 for (i = 0; i<FM_MAX_NUM_OF_PORTS; i++) 821 p_FmPcd->netEnvs[i].clsPlanGrpId = ILLEGAL_CLS_PLAN; 822 823 if (p_FmPcdParams->useHostCommand) 824 { 825 t_FmHcParams hcParams; 826 827 memset(&hcParams, 0, sizeof(hcParams)); 828 hcParams.h_Fm = p_FmPcd->h_Fm; 829 hcParams.h_FmPcd = (t_Handle)p_FmPcd; 830 memcpy((uint8_t*)&hcParams.params, (uint8_t*)&p_FmPcdParams->hc, sizeof(t_FmPcdHcParams)); 831 p_FmPcd->h_Hc = FmHcConfigAndInit(&hcParams); 832 if (!p_FmPcd->h_Hc) 833 { 834 REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM PCD HC")); 835 FM_PCD_Free(p_FmPcd); 836 return NULL; 837 } 838 } 839 else if (p_FmPcd->guestId != NCSW_MASTER_ID) 840 REPORT_ERROR(MAJOR, E_INVALID_STATE, ("No Host Command defined for a guest partition.")); 841 842 if (p_FmPcdParams->kgSupport) 843 { 844 p_FmPcd->p_FmPcdKg = (t_FmPcdKg *)KgConfig(p_FmPcd, p_FmPcdParams); 845 if (!p_FmPcd->p_FmPcdKg) 846 { 847 REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM PCD Keygen")); 848 FM_PCD_Free(p_FmPcd); 849 return NULL; 850 } 851 } 852 853 if (p_FmPcdParams->plcrSupport) 854 { 855 p_FmPcd->p_FmPcdPlcr = (t_FmPcdPlcr *)PlcrConfig(p_FmPcd, p_FmPcdParams); 856 if (!p_FmPcd->p_FmPcdPlcr) 857 { 858 REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM PCD Policer")); 859 FM_PCD_Free(p_FmPcd); 860 return NULL; 861 } 862 } 863 864 if (p_FmPcdParams->prsSupport) 865 { 866 p_FmPcd->p_FmPcdPrs = (t_FmPcdPrs *)PrsConfig(p_FmPcd, p_FmPcdParams); 867 if (!p_FmPcd->p_FmPcdPrs) 868 { 869 REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM PCD Parser")); 870 FM_PCD_Free(p_FmPcd); 871 return NULL; 872 } 873 } 874 875 p_FmPcd->h_Spinlock = XX_InitSpinlock(); 876 if (!p_FmPcd->h_Spinlock) 877 { 878 REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM PCD spinlock")); 879 FM_PCD_Free(p_FmPcd); 880 return NULL; 881 } 882 INIT_LIST(&p_FmPcd->freeLocksLst); 883 INIT_LIST(&p_FmPcd->acquiredLocksLst); 884 885 p_FmPcd->numOfEnabledGuestPartitionsPcds = 0; 886 887 p_FmPcd->f_Exception = p_FmPcdParams->f_Exception; 888 p_FmPcd->f_FmPcdIndexedException = p_FmPcdParams->f_ExceptionId; 889 p_FmPcd->h_App = p_FmPcdParams->h_App; 890 891 p_FmPcd->p_CcShadow = NULL; 892 p_FmPcd->ccShadowSize = 0; 893 p_FmPcd->ccShadowAlign = 0; 894 895 p_FmPcd->h_ShadowSpinlock = XX_InitSpinlock(); 896 if (!p_FmPcd->h_ShadowSpinlock) 897 { 898 REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM PCD shadow spinlock")); 899 FM_PCD_Free(p_FmPcd); 900 return NULL; 901 } 902 903 return p_FmPcd; 904 } 905 906 t_Error FM_PCD_Init(t_Handle h_FmPcd) 907 { 908 t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; 909 t_Error err = E_OK; 910 t_FmPcdIpcMsg msg; 911 912 SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE); 913 SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdDriverParam, E_INVALID_HANDLE); 914 915 FM_GetRevision(p_FmPcd->h_Fm, &p_FmPcd->fmRevInfo); 916 917 if (p_FmPcd->guestId != NCSW_MASTER_ID) 918 { 919 memset(p_FmPcd->fmPcdIpcHandlerModuleName, 0, (sizeof(char)) * MODULE_NAME_SIZE); 920 if (Sprint (p_FmPcd->fmPcdIpcHandlerModuleName, "FM_PCD_%d_%d", FmGetId(p_FmPcd->h_Fm), NCSW_MASTER_ID) != 10) 921 RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Sprint failed")); 922 memset(p_FmPcd->fmPcdModuleName, 0, (sizeof(char)) * MODULE_NAME_SIZE); 923 if (Sprint (p_FmPcd->fmPcdModuleName, "FM_PCD_%d_%d",FmGetId(p_FmPcd->h_Fm), p_FmPcd->guestId) != (p_FmPcd->guestId<10 ? 10:11)) 924 RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Sprint failed")); 925 926 p_FmPcd->h_IpcSession = XX_IpcInitSession(p_FmPcd->fmPcdIpcHandlerModuleName, p_FmPcd->fmPcdModuleName); 927 if (p_FmPcd->h_IpcSession) 928 { 929 t_FmPcdIpcReply reply; 930 uint32_t replyLength; 931 uint8_t isMasterAlive = 0; 932 933 memset(&msg, 0, sizeof(msg)); 934 memset(&reply, 0, sizeof(reply)); 935 msg.msgId = FM_PCD_MASTER_IS_ALIVE; 936 msg.msgBody[0] = p_FmPcd->guestId; 937 blockingFlag = TRUE; 938 939 do 940 { 941 replyLength = sizeof(uint32_t) + sizeof(isMasterAlive); 942 if ((err = XX_IpcSendMessage(p_FmPcd->h_IpcSession, 943 (uint8_t*)&msg, 944 sizeof(msg.msgId)+sizeof(p_FmPcd->guestId), 945 (uint8_t*)&reply, 946 &replyLength, 947 IpcMsgCompletionCB, 948 h_FmPcd)) != E_OK) 949 REPORT_ERROR(MAJOR, err, NO_MSG); 950 while (blockingFlag) ; 951 if (replyLength != (sizeof(uint32_t) + sizeof(isMasterAlive))) 952 REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch")); 953 isMasterAlive = *(uint8_t*)(reply.replyBody); 954 } while (!isMasterAlive); 955 } 956 } 957 958 CHECK_INIT_PARAMETERS(p_FmPcd, CheckFmPcdParameters); 959 960 if (p_FmPcd->p_FmPcdKg) 961 { 962 err = KgInit(p_FmPcd); 963 if (err) 964 RETURN_ERROR(MAJOR, err, NO_MSG); 965 } 966 967 if (p_FmPcd->p_FmPcdPlcr) 968 { 969 err = PlcrInit(p_FmPcd); 970 if (err) 971 RETURN_ERROR(MAJOR, err, NO_MSG); 972 } 973 974 if (p_FmPcd->p_FmPcdPrs) 975 { 976 err = PrsInit(p_FmPcd); 977 if (err) 978 RETURN_ERROR(MAJOR, err, NO_MSG); 979 } 980 981 if (p_FmPcd->guestId == NCSW_MASTER_ID) 982 { 983 /* register to inter-core messaging mechanism */ 984 memset(p_FmPcd->fmPcdModuleName, 0, (sizeof(char)) * MODULE_NAME_SIZE); 985 if (Sprint (p_FmPcd->fmPcdModuleName, "FM_PCD_%d_%d",FmGetId(p_FmPcd->h_Fm),NCSW_MASTER_ID) != 10) 986 RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Sprint failed")); 987 err = XX_IpcRegisterMsgHandler(p_FmPcd->fmPcdModuleName, IpcMsgHandlerCB, p_FmPcd, FM_PCD_MAX_REPLY_SIZE); 988 if (err) 989 RETURN_ERROR(MAJOR, err, NO_MSG); 990 } 991 992 /* IPv6 Frame-Id used for fragmentation */ 993 p_FmPcd->ipv6FrameIdAddr = PTR_TO_UINT(FM_MURAM_AllocMem(p_FmPcd->h_FmMuram, 4, 4)); 994 if (!p_FmPcd->ipv6FrameIdAddr) 995 { 996 FM_PCD_Free(p_FmPcd); 997 RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM allocation for IPv6 Frame-Id")); 998 } 999 IOMemSet32(UINT_TO_PTR(p_FmPcd->ipv6FrameIdAddr), 0, 4); 1000 1001 /* CAPWAP Frame-Id used for fragmentation */ 1002 p_FmPcd->capwapFrameIdAddr = PTR_TO_UINT(FM_MURAM_AllocMem(p_FmPcd->h_FmMuram, 2, 4)); 1003 if (!p_FmPcd->capwapFrameIdAddr) 1004 { 1005 FM_PCD_Free(p_FmPcd); 1006 RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM allocation for CAPWAP Frame-Id")); 1007 } 1008 IOMemSet32(UINT_TO_PTR(p_FmPcd->capwapFrameIdAddr), 0, 2); 1009 1010 XX_Free(p_FmPcd->p_FmPcdDriverParam); 1011 p_FmPcd->p_FmPcdDriverParam = NULL; 1012 1013 FmRegisterPcd(p_FmPcd->h_Fm, p_FmPcd); 1014 1015 return E_OK; 1016 } 1017 1018 t_Error FM_PCD_Free(t_Handle h_FmPcd) 1019 { 1020 t_FmPcd *p_FmPcd =(t_FmPcd *)h_FmPcd; 1021 t_Error err = E_OK; 1022 1023 if (p_FmPcd->ipv6FrameIdAddr) 1024 FM_MURAM_FreeMem(p_FmPcd->h_FmMuram, UINT_TO_PTR(p_FmPcd->ipv6FrameIdAddr)); 1025 1026 if (p_FmPcd->capwapFrameIdAddr) 1027 FM_MURAM_FreeMem(p_FmPcd->h_FmMuram, UINT_TO_PTR(p_FmPcd->capwapFrameIdAddr)); 1028 1029 if (p_FmPcd->enabled) 1030 FM_PCD_Disable(p_FmPcd); 1031 1032 if (p_FmPcd->p_FmPcdDriverParam) 1033 { 1034 XX_Free(p_FmPcd->p_FmPcdDriverParam); 1035 p_FmPcd->p_FmPcdDriverParam = NULL; 1036 } 1037 1038 if (p_FmPcd->p_FmPcdKg) 1039 { 1040 if ((err = KgFree(p_FmPcd)) != E_OK) 1041 RETURN_ERROR(MINOR, err, NO_MSG); 1042 XX_Free(p_FmPcd->p_FmPcdKg); 1043 p_FmPcd->p_FmPcdKg = NULL; 1044 } 1045 1046 if (p_FmPcd->p_FmPcdPlcr) 1047 { 1048 PlcrFree(p_FmPcd); 1049 XX_Free(p_FmPcd->p_FmPcdPlcr); 1050 p_FmPcd->p_FmPcdPlcr = NULL; 1051 } 1052 1053 if (p_FmPcd->p_FmPcdPrs) 1054 { 1055 if (p_FmPcd->guestId == NCSW_MASTER_ID) 1056 PrsFree(p_FmPcd); 1057 XX_Free(p_FmPcd->p_FmPcdPrs); 1058 p_FmPcd->p_FmPcdPrs = NULL; 1059 } 1060 1061 if (p_FmPcd->h_Hc) 1062 { 1063 FmHcFree(p_FmPcd->h_Hc); 1064 p_FmPcd->h_Hc = NULL; 1065 } 1066 1067 XX_IpcUnregisterMsgHandler(p_FmPcd->fmPcdModuleName); 1068 1069 FmUnregisterPcd(p_FmPcd->h_Fm); 1070 1071 ReleaseFreeLocksLst(p_FmPcd); 1072 1073 if (p_FmPcd->h_Spinlock) 1074 XX_FreeSpinlock(p_FmPcd->h_Spinlock); 1075 1076 if (p_FmPcd->h_ShadowSpinlock) 1077 XX_FreeSpinlock(p_FmPcd->h_ShadowSpinlock); 1078 1079 XX_Free(p_FmPcd); 1080 1081 return E_OK; 1082 } 1083 1084 t_Error FM_PCD_ConfigException(t_Handle h_FmPcd, e_FmPcdExceptions exception, bool enable) 1085 { 1086 t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; 1087 uint32_t bitMask = 0; 1088 1089 SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE); 1090 1091 if (p_FmPcd->guestId != NCSW_MASTER_ID) 1092 RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("FM_PCD_ConfigException - guest mode!")); 1093 1094 GET_FM_PCD_EXCEPTION_FLAG(bitMask, exception); 1095 if (bitMask) 1096 { 1097 if (enable) 1098 p_FmPcd->exceptions |= bitMask; 1099 else 1100 p_FmPcd->exceptions &= ~bitMask; 1101 } 1102 else 1103 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined exception")); 1104 1105 return E_OK; 1106 } 1107 1108 t_Error FM_PCD_ConfigHcFramesDataMemory(t_Handle h_FmPcd, uint8_t memId) 1109 { 1110 t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; 1111 1112 SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE); 1113 SANITY_CHECK_RETURN_ERROR(p_FmPcd->h_Hc, E_INVALID_HANDLE); 1114 1115 return FmHcSetFramesDataMemory(p_FmPcd->h_Hc, memId); 1116 } 1117 1118 t_Error FM_PCD_Enable(t_Handle h_FmPcd) 1119 { 1120 t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; 1121 t_Error err = E_OK; 1122 1123 SANITY_CHECK_RETURN_ERROR(h_FmPcd, E_INVALID_HANDLE); 1124 1125 if (p_FmPcd->enabled) 1126 return E_OK; 1127 1128 if ((p_FmPcd->guestId != NCSW_MASTER_ID) && 1129 p_FmPcd->h_IpcSession) 1130 { 1131 uint8_t enabled; 1132 t_FmPcdIpcMsg msg; 1133 t_FmPcdIpcReply reply; 1134 uint32_t replyLength; 1135 1136 memset(&reply, 0, sizeof(reply)); 1137 memset(&msg, 0, sizeof(msg)); 1138 msg.msgId = FM_PCD_MASTER_IS_ENABLED; 1139 replyLength = sizeof(uint32_t) + sizeof(enabled); 1140 if ((err = XX_IpcSendMessage(p_FmPcd->h_IpcSession, 1141 (uint8_t*)&msg, 1142 sizeof(msg.msgId), 1143 (uint8_t*)&reply, 1144 &replyLength, 1145 NULL, 1146 NULL)) != E_OK) 1147 RETURN_ERROR(MAJOR, err, NO_MSG); 1148 if (replyLength != sizeof(uint32_t) + sizeof(enabled)) 1149 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch")); 1150 p_FmPcd->enabled = (bool)!!(*(uint8_t*)(reply.replyBody)); 1151 if (!p_FmPcd->enabled) 1152 RETURN_ERROR(MAJOR, E_INVALID_STATE, ("FM-PCD master should be enabled first!")); 1153 1154 return E_OK; 1155 } 1156 else if (p_FmPcd->guestId != NCSW_MASTER_ID) 1157 RETURN_ERROR(MINOR, E_NOT_SUPPORTED, 1158 ("running in guest-mode without IPC!")); 1159 1160 if (p_FmPcd->p_FmPcdKg) 1161 KgEnable(p_FmPcd); 1162 1163 if (p_FmPcd->p_FmPcdPlcr) 1164 PlcrEnable(p_FmPcd); 1165 1166 if (p_FmPcd->p_FmPcdPrs) 1167 PrsEnable(p_FmPcd); 1168 1169 p_FmPcd->enabled = TRUE; 1170 1171 return E_OK; 1172 } 1173 1174 t_Error FM_PCD_Disable(t_Handle h_FmPcd) 1175 { 1176 t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; 1177 t_Error err = E_OK; 1178 1179 SANITY_CHECK_RETURN_ERROR(h_FmPcd, E_INVALID_HANDLE); 1180 1181 if (!p_FmPcd->enabled) 1182 return E_OK; 1183 1184 if ((p_FmPcd->guestId != NCSW_MASTER_ID) && 1185 p_FmPcd->h_IpcSession) 1186 { 1187 t_FmPcdIpcMsg msg; 1188 t_FmPcdIpcReply reply; 1189 uint32_t replyLength; 1190 1191 memset(&reply, 0, sizeof(reply)); 1192 memset(&msg, 0, sizeof(msg)); 1193 msg.msgId = FM_PCD_GUEST_DISABLE; 1194 replyLength = sizeof(uint32_t); 1195 if ((err = XX_IpcSendMessage(p_FmPcd->h_IpcSession, 1196 (uint8_t*)&msg, 1197 sizeof(msg.msgId), 1198 (uint8_t*)&reply, 1199 &replyLength, 1200 NULL, 1201 NULL)) != E_OK) 1202 RETURN_ERROR(MAJOR, err, NO_MSG); 1203 if (replyLength != sizeof(uint32_t)) 1204 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch")); 1205 if (reply.error == E_OK) 1206 p_FmPcd->enabled = FALSE; 1207 1208 return (t_Error)(reply.error); 1209 } 1210 else if (p_FmPcd->guestId != NCSW_MASTER_ID) 1211 RETURN_ERROR(MINOR, E_NOT_SUPPORTED, 1212 ("running in guest-mode without IPC!")); 1213 1214 if (p_FmPcd->numOfEnabledGuestPartitionsPcds != 0) 1215 RETURN_ERROR(MAJOR, E_INVALID_STATE, 1216 ("Trying to disable a master partition PCD while" 1217 "guest partitions are still enabled!")); 1218 1219 if (p_FmPcd->p_FmPcdKg) 1220 KgDisable(p_FmPcd); 1221 1222 if (p_FmPcd->p_FmPcdPlcr) 1223 PlcrDisable(p_FmPcd); 1224 1225 if (p_FmPcd->p_FmPcdPrs) 1226 PrsDisable(p_FmPcd); 1227 1228 p_FmPcd->enabled = FALSE; 1229 1230 return E_OK; 1231 } 1232 1233 t_Handle FM_PCD_NetEnvCharacteristicsSet(t_Handle h_FmPcd, t_FmPcdNetEnvParams *p_NetEnvParams) 1234 { 1235 t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; 1236 uint32_t intFlags, specialUnits = 0; 1237 uint8_t bitId = 0; 1238 uint8_t i, j, k; 1239 uint8_t netEnvCurrId; 1240 uint8_t ipsecAhUnit = 0,ipsecEspUnit = 0; 1241 bool ipsecAhExists = FALSE, ipsecEspExists = FALSE, shim1Selected = FALSE; 1242 uint8_t hdrNum; 1243 t_FmPcdNetEnvParams *p_ModifiedNetEnvParams; 1244 1245 SANITY_CHECK_RETURN_VALUE(h_FmPcd, E_INVALID_STATE, NULL); 1246 SANITY_CHECK_RETURN_VALUE(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_STATE, NULL); 1247 SANITY_CHECK_RETURN_VALUE(p_NetEnvParams, E_NULL_POINTER, NULL); 1248 1249 intFlags = FmPcdLock(p_FmPcd); 1250 1251 /* find a new netEnv */ 1252 for (i = 0; i < FM_MAX_NUM_OF_PORTS; i++) 1253 if (!p_FmPcd->netEnvs[i].used) 1254 break; 1255 1256 if (i== FM_MAX_NUM_OF_PORTS) 1257 { 1258 REPORT_ERROR(MAJOR, E_FULL,("No more than %d netEnv's allowed.", FM_MAX_NUM_OF_PORTS)); 1259 FmPcdUnlock(p_FmPcd, intFlags); 1260 return NULL; 1261 } 1262 1263 p_FmPcd->netEnvs[i].used = TRUE; 1264 FmPcdUnlock(p_FmPcd, intFlags); 1265 1266 /* As anyone doesn't have handle of this netEnv yet, no need 1267 to protect it with spinlocks */ 1268 1269 p_ModifiedNetEnvParams = (t_FmPcdNetEnvParams *)XX_Malloc(sizeof(t_FmPcdNetEnvParams)); 1270 if (!p_ModifiedNetEnvParams) 1271 { 1272 REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FmPcdNetEnvParams")); 1273 return NULL; 1274 } 1275 1276 memcpy(p_ModifiedNetEnvParams, p_NetEnvParams, sizeof(t_FmPcdNetEnvParams)); 1277 p_NetEnvParams = p_ModifiedNetEnvParams; 1278 1279 netEnvCurrId = (uint8_t)i; 1280 1281 /* clear from previous use */ 1282 memset(&p_FmPcd->netEnvs[netEnvCurrId].units, 0, FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS * sizeof(t_FmPcdIntDistinctionUnit)); 1283 memset(&p_FmPcd->netEnvs[netEnvCurrId].aliasHdrs, 0, FM_PCD_MAX_NUM_OF_ALIAS_HDRS * sizeof(t_FmPcdNetEnvAliases)); 1284 memcpy(&p_FmPcd->netEnvs[netEnvCurrId].units, p_NetEnvParams->units, p_NetEnvParams->numOfDistinctionUnits*sizeof(t_FmPcdIntDistinctionUnit)); 1285 1286 p_FmPcd->netEnvs[netEnvCurrId].netEnvId = netEnvCurrId; 1287 p_FmPcd->netEnvs[netEnvCurrId].h_FmPcd = p_FmPcd; 1288 1289 p_FmPcd->netEnvs[netEnvCurrId].clsPlanGrpId = ILLEGAL_CLS_PLAN; 1290 1291 /* check that header with opt is not interchanged with the same header */ 1292 for (i = 0; (i < FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS) 1293 && (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[0].hdr != HEADER_TYPE_NONE); i++) 1294 { 1295 for (k = 0; (k < FM_PCD_MAX_NUM_OF_INTERCHANGEABLE_HDRS) 1296 && (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr != HEADER_TYPE_NONE); k++) 1297 { 1298 /* if an option exists, check that other headers are not the same header 1299 without option */ 1300 if (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].opt) 1301 { 1302 for (j = 0; (j < FM_PCD_MAX_NUM_OF_INTERCHANGEABLE_HDRS) 1303 && (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[j].hdr != HEADER_TYPE_NONE); j++) 1304 { 1305 if ((p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[j].hdr == p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr) && 1306 !p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[j].opt) 1307 { 1308 REPORT_ERROR(MINOR, E_FULL, 1309 ("Illegal unit - header with opt may not be interchangeable with the same header without opt")); 1310 XX_Free(p_ModifiedNetEnvParams); 1311 return NULL; 1312 } 1313 } 1314 } 1315 } 1316 } 1317 1318 /* Specific headers checking */ 1319 for (i = 0; (i < FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS) 1320 && (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[0].hdr != HEADER_TYPE_NONE); i++) 1321 { 1322 for (k = 0; (k < FM_PCD_MAX_NUM_OF_INTERCHANGEABLE_HDRS) 1323 && (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr != HEADER_TYPE_NONE); k++) 1324 { 1325 /* Some headers pairs may not be defined on different units as the parser 1326 doesn't distinguish */ 1327 /* IPSEC_AH and IPSEC_SPI can't be 2 units, */ 1328 /* check that header with opt is not interchanged with the same header */ 1329 if (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr == HEADER_TYPE_IPSEC_AH) 1330 { 1331 if (ipsecEspExists && (ipsecEspUnit != i)) 1332 { 1333 REPORT_ERROR(MINOR, E_INVALID_STATE, ("HEADER_TYPE_IPSEC_AH and HEADER_TYPE_IPSEC_ESP may not be defined in separate units")); 1334 XX_Free(p_ModifiedNetEnvParams); 1335 return NULL; 1336 } 1337 else 1338 { 1339 ipsecAhUnit = i; 1340 ipsecAhExists = TRUE; 1341 } 1342 } 1343 if (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr == HEADER_TYPE_IPSEC_ESP) 1344 { 1345 if (ipsecAhExists && (ipsecAhUnit != i)) 1346 { 1347 REPORT_ERROR(MINOR, E_INVALID_STATE, ("HEADER_TYPE_IPSEC_AH and HEADER_TYPE_IPSEC_ESP may not be defined in separate units")); 1348 XX_Free(p_ModifiedNetEnvParams); 1349 return NULL; 1350 } 1351 else 1352 { 1353 ipsecEspUnit = i; 1354 ipsecEspExists = TRUE; 1355 } 1356 } 1357 /* ENCAP_ESP */ 1358 if (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr == HEADER_TYPE_UDP_ENCAP_ESP) 1359 { 1360 /* IPSec UDP encapsulation is currently set to use SHIM1 */ 1361 p_FmPcd->netEnvs[netEnvCurrId].aliasHdrs[specialUnits].hdr = HEADER_TYPE_UDP_ENCAP_ESP; 1362 p_FmPcd->netEnvs[netEnvCurrId].aliasHdrs[specialUnits++].aliasHdr = HEADER_TYPE_USER_DEFINED_SHIM1; 1363 p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr = HEADER_TYPE_USER_DEFINED_SHIM1; 1364 p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].opt = 0; 1365 } 1366 #if (DPAA_VERSION >= 11) || ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT)) 1367 /* UDP_LITE */ 1368 if (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr == HEADER_TYPE_UDP_LITE) 1369 { 1370 p_FmPcd->netEnvs[netEnvCurrId].aliasHdrs[specialUnits].hdr = HEADER_TYPE_UDP_LITE; 1371 p_FmPcd->netEnvs[netEnvCurrId].aliasHdrs[specialUnits++].aliasHdr = HEADER_TYPE_UDP; 1372 p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr = HEADER_TYPE_UDP; 1373 p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].opt = 0; 1374 } 1375 #endif /* (DPAA_VERSION >= 11) || ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT)) */ 1376 1377 /* IP FRAG */ 1378 if ((p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr == HEADER_TYPE_IPv4) && 1379 (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].opt == IPV4_FRAG_1)) 1380 { 1381 /* If IPv4+Frag, we need to set 2 units - SHIM 2 and IPv4. We first set SHIM2, and than check if 1382 * IPv4 exists. If so we don't need to set an extra unit 1383 * We consider as "having IPv4" any IPv4 without interchangable headers 1384 * but including any options. */ 1385 p_FmPcd->netEnvs[netEnvCurrId].aliasHdrs[specialUnits].hdr = HEADER_TYPE_IPv4; 1386 p_FmPcd->netEnvs[netEnvCurrId].aliasHdrs[specialUnits].opt = IPV4_FRAG_1; 1387 p_FmPcd->netEnvs[netEnvCurrId].aliasHdrs[specialUnits++].aliasHdr = HEADER_TYPE_USER_DEFINED_SHIM2; 1388 p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr = HEADER_TYPE_USER_DEFINED_SHIM2; 1389 p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].opt = 0; 1390 1391 /* check if IPv4 header exists by itself */ 1392 if (FmPcdNetEnvGetUnitId(p_FmPcd, netEnvCurrId, HEADER_TYPE_IPv4, FALSE, 0) == FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS) 1393 { 1394 p_FmPcd->netEnvs[netEnvCurrId].units[p_NetEnvParams->numOfDistinctionUnits].hdrs[0].hdr = HEADER_TYPE_IPv4; 1395 p_FmPcd->netEnvs[netEnvCurrId].units[p_NetEnvParams->numOfDistinctionUnits++].hdrs[0].opt = 0; 1396 } 1397 } 1398 if ((p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr == HEADER_TYPE_IPv6) && 1399 (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].opt == IPV6_FRAG_1)) 1400 { 1401 /* If IPv6+Frag, we need to set 2 units - SHIM 2 and IPv6. We first set SHIM2, and than check if 1402 * IPv4 exists. If so we don't need to set an extra unit 1403 * We consider as "having IPv6" any IPv6 without interchangable headers 1404 * but including any options. */ 1405 p_FmPcd->netEnvs[netEnvCurrId].aliasHdrs[specialUnits].hdr = HEADER_TYPE_IPv6; 1406 p_FmPcd->netEnvs[netEnvCurrId].aliasHdrs[specialUnits].opt = IPV6_FRAG_1; 1407 p_FmPcd->netEnvs[netEnvCurrId].aliasHdrs[specialUnits++].aliasHdr = HEADER_TYPE_USER_DEFINED_SHIM2; 1408 p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr = HEADER_TYPE_USER_DEFINED_SHIM2; 1409 p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].opt = 0; 1410 1411 /* check if IPv6 header exists by itself */ 1412 if (FmPcdNetEnvGetUnitId(p_FmPcd, netEnvCurrId, HEADER_TYPE_IPv6, FALSE, 0) == FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS) 1413 { 1414 p_FmPcd->netEnvs[netEnvCurrId].units[p_NetEnvParams->numOfDistinctionUnits].hdrs[0].hdr = HEADER_TYPE_IPv6; 1415 p_FmPcd->netEnvs[netEnvCurrId].units[p_NetEnvParams->numOfDistinctionUnits++].hdrs[0].opt = 0; 1416 } 1417 } 1418 #if (DPAA_VERSION >= 11) 1419 /* CAPWAP FRAG */ 1420 if ((p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr == HEADER_TYPE_CAPWAP) && 1421 (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].opt == CAPWAP_FRAG_1)) 1422 { 1423 p_FmPcd->netEnvs[netEnvCurrId].aliasHdrs[specialUnits].hdr = HEADER_TYPE_CAPWAP; 1424 p_FmPcd->netEnvs[netEnvCurrId].aliasHdrs[specialUnits].opt = CAPWAP_FRAG_1; 1425 p_FmPcd->netEnvs[netEnvCurrId].aliasHdrs[specialUnits++].aliasHdr = HEADER_TYPE_USER_DEFINED_SHIM2; 1426 p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr = HEADER_TYPE_USER_DEFINED_SHIM2; 1427 p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].opt = 0; 1428 } 1429 #endif /* (DPAA_VERSION >= 11) */ 1430 } 1431 } 1432 1433 /* if private header (shim), check that no other headers specified */ 1434 for (i = 0; (i < FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS) 1435 && (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[0].hdr != HEADER_TYPE_NONE); i++) 1436 { 1437 if (IS_PRIVATE_HEADER(p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[0].hdr)) 1438 if (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[1].hdr != HEADER_TYPE_NONE) 1439 { 1440 REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("SHIM header may not be interchanged with other headers")); 1441 XX_Free(p_ModifiedNetEnvParams); 1442 return NULL; 1443 } 1444 } 1445 1446 for (i = 0; i < p_NetEnvParams->numOfDistinctionUnits; i++) 1447 { 1448 if (IS_PRIVATE_HEADER(p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[0].hdr)) 1449 switch (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[0].hdr) 1450 { 1451 case (HEADER_TYPE_USER_DEFINED_SHIM1): 1452 if (shim1Selected) 1453 { 1454 REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("SHIM header cannot be selected with UDP_IPSEC_ESP")); 1455 XX_Free(p_ModifiedNetEnvParams); 1456 return NULL; 1457 } 1458 shim1Selected = TRUE; 1459 p_FmPcd->netEnvs[netEnvCurrId].unitsVectors[i] = 0x00000001; 1460 break; 1461 case (HEADER_TYPE_USER_DEFINED_SHIM2): 1462 p_FmPcd->netEnvs[netEnvCurrId].unitsVectors[i] = 0x00000002; 1463 break; 1464 default: 1465 REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Requested SHIM not supported")); 1466 } 1467 else 1468 { 1469 p_FmPcd->netEnvs[netEnvCurrId].unitsVectors[i] = (uint32_t)(0x80000000 >> bitId++); 1470 1471 if (IS_SPECIAL_HEADER(p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[0].hdr)) 1472 p_FmPcd->netEnvs[netEnvCurrId].macsecVector = p_FmPcd->netEnvs[netEnvCurrId].unitsVectors[i]; 1473 } 1474 } 1475 1476 /* define a set of hardware parser LCV's according to the defined netenv */ 1477 1478 /* set an array of LCV's for each header in the netEnv */ 1479 for (i = 0; (i < FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS) 1480 && (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[0].hdr != HEADER_TYPE_NONE); i++) 1481 { 1482 /* private headers have no LCV in the hard parser */ 1483 if (!IS_PRIVATE_HEADER(p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[0].hdr)) 1484 { 1485 for (k = 0; (k < FM_PCD_MAX_NUM_OF_INTERCHANGEABLE_HDRS) 1486 && (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr != HEADER_TYPE_NONE); k++) 1487 { 1488 hdrNum = GetPrsHdrNum(p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr); 1489 if ((hdrNum == ILLEGAL_HDR_NUM) || (hdrNum == NO_HDR_NUM)) 1490 { 1491 REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, NO_MSG); 1492 XX_Free(p_ModifiedNetEnvParams); 1493 return NULL; 1494 } 1495 p_FmPcd->netEnvs[netEnvCurrId].lcvs[hdrNum] |= p_FmPcd->netEnvs[netEnvCurrId].unitsVectors[i]; 1496 } 1497 } 1498 } 1499 XX_Free(p_ModifiedNetEnvParams); 1500 1501 p_FmPcd->netEnvs[netEnvCurrId].h_Spinlock = XX_InitSpinlock(); 1502 if (!p_FmPcd->netEnvs[netEnvCurrId].h_Spinlock) 1503 { 1504 REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM Pcd NetEnv spinlock")); 1505 return NULL; 1506 } 1507 return &p_FmPcd->netEnvs[netEnvCurrId]; 1508 } 1509 1510 t_Error FM_PCD_NetEnvCharacteristicsDelete(t_Handle h_NetEnv) 1511 { 1512 t_FmPcdNetEnv *p_NetEnv = (t_FmPcdNetEnv*)h_NetEnv; 1513 t_FmPcd *p_FmPcd = p_NetEnv->h_FmPcd; 1514 uint32_t intFlags; 1515 uint8_t netEnvId = p_NetEnv->netEnvId; 1516 1517 SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_STATE); 1518 SANITY_CHECK_RETURN_ERROR(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_STATE); 1519 1520 /* check that no port is bound to this netEnv */ 1521 if (p_FmPcd->netEnvs[netEnvId].owners) 1522 { 1523 RETURN_ERROR(MINOR, E_INVALID_STATE, 1524 ("Trying to delete a netEnv that has ports/schemes/trees/clsPlanGrps bound to")); 1525 } 1526 1527 intFlags = FmPcdLock(p_FmPcd); 1528 1529 p_FmPcd->netEnvs[netEnvId].used = FALSE; 1530 p_FmPcd->netEnvs[netEnvId].clsPlanGrpId = ILLEGAL_CLS_PLAN; 1531 1532 memset(p_FmPcd->netEnvs[netEnvId].units, 0, sizeof(t_FmPcdIntDistinctionUnit)*FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS); 1533 memset(p_FmPcd->netEnvs[netEnvId].unitsVectors, 0, sizeof(uint32_t)*FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS); 1534 memset(p_FmPcd->netEnvs[netEnvId].lcvs, 0, sizeof(uint32_t)*FM_PCD_PRS_NUM_OF_HDRS); 1535 1536 if (p_FmPcd->netEnvs[netEnvId].h_Spinlock) 1537 XX_FreeSpinlock(p_FmPcd->netEnvs[netEnvId].h_Spinlock); 1538 1539 FmPcdUnlock(p_FmPcd, intFlags); 1540 return E_OK; 1541 } 1542 1543 void FM_PCD_HcTxConf(t_Handle h_FmPcd, t_DpaaFD *p_Fd) 1544 { 1545 t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; 1546 1547 SANITY_CHECK_RETURN(h_FmPcd, E_INVALID_STATE); 1548 1549 FmHcTxConf(p_FmPcd->h_Hc, p_Fd); 1550 } 1551 1552 t_Error FM_PCD_SetAdvancedOffloadSupport(t_Handle h_FmPcd) 1553 { 1554 t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; 1555 t_FmCtrlCodeRevisionInfo revInfo; 1556 t_Error err; 1557 1558 SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE); 1559 SANITY_CHECK_RETURN_ERROR(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_STATE); 1560 SANITY_CHECK_RETURN_ERROR(!p_FmPcd->enabled, E_INVALID_STATE); 1561 1562 if ((err = FM_GetFmanCtrlCodeRevision(p_FmPcd->h_Fm, &revInfo)) != E_OK) 1563 { 1564 DBG(WARNING, ("FM in guest-mode without IPC, can't validate firmware revision.")); 1565 revInfo.packageRev = IP_OFFLOAD_PACKAGE_NUMBER; 1566 } 1567 if (!IS_OFFLOAD_PACKAGE(revInfo.packageRev)) 1568 RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("Fman ctrl code package")); 1569 1570 if (!p_FmPcd->h_Hc) 1571 RETURN_ERROR(MAJOR, E_INVALID_HANDLE, ("HC must be initialized in this mode")); 1572 1573 p_FmPcd->advancedOffloadSupport = TRUE; 1574 1575 return E_OK; 1576 } 1577 1578 uint32_t FM_PCD_GetCounter(t_Handle h_FmPcd, e_FmPcdCounters counter) 1579 { 1580 t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; 1581 uint32_t outCounter = 0; 1582 t_Error err; 1583 1584 SANITY_CHECK_RETURN_VALUE(h_FmPcd, E_INVALID_HANDLE, 0); 1585 SANITY_CHECK_RETURN_VALUE(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_STATE, 0); 1586 1587 switch (counter) 1588 { 1589 case (e_FM_PCD_KG_COUNTERS_TOTAL): 1590 if (!p_FmPcd->p_FmPcdKg) 1591 { 1592 REPORT_ERROR(MAJOR, E_INVALID_STATE, ("KeyGen is not activated")); 1593 return 0; 1594 } 1595 if ((p_FmPcd->guestId != NCSW_MASTER_ID) && 1596 !p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs && 1597 !p_FmPcd->h_IpcSession) 1598 { 1599 REPORT_ERROR(MINOR, E_NOT_SUPPORTED, 1600 ("running in guest-mode without neither IPC nor mapped register!")); 1601 return 0; 1602 } 1603 break; 1604 1605 case (e_FM_PCD_PLCR_COUNTERS_YELLOW): 1606 case (e_FM_PCD_PLCR_COUNTERS_RED): 1607 case (e_FM_PCD_PLCR_COUNTERS_RECOLORED_TO_RED): 1608 case (e_FM_PCD_PLCR_COUNTERS_RECOLORED_TO_YELLOW): 1609 case (e_FM_PCD_PLCR_COUNTERS_TOTAL): 1610 case (e_FM_PCD_PLCR_COUNTERS_LENGTH_MISMATCH): 1611 if (!p_FmPcd->p_FmPcdPlcr) 1612 { 1613 REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Policer is not activated")); 1614 return 0; 1615 } 1616 if ((p_FmPcd->guestId != NCSW_MASTER_ID) && 1617 !p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs && 1618 !p_FmPcd->h_IpcSession) 1619 { 1620 REPORT_ERROR(MINOR, E_NOT_SUPPORTED, 1621 ("running in \"guest-mode\" without neither IPC nor mapped register!")); 1622 return 0; 1623 } 1624 1625 /* check that counters are enabled */ 1626 if (p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs && 1627 !(GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_gcr) & FM_PCD_PLCR_GCR_STEN)) 1628 { 1629 REPORT_ERROR(MINOR, E_INVALID_STATE, ("Requested counter was not enabled")); 1630 return 0; 1631 } 1632 ASSERT_COND(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs || 1633 ((p_FmPcd->guestId != NCSW_MASTER_ID) && p_FmPcd->h_IpcSession)); 1634 break; 1635 1636 case (e_FM_PCD_PRS_COUNTERS_PARSE_DISPATCH): 1637 case (e_FM_PCD_PRS_COUNTERS_L2_PARSE_RESULT_RETURNED): 1638 case (e_FM_PCD_PRS_COUNTERS_L3_PARSE_RESULT_RETURNED): 1639 case (e_FM_PCD_PRS_COUNTERS_L4_PARSE_RESULT_RETURNED): 1640 case (e_FM_PCD_PRS_COUNTERS_SHIM_PARSE_RESULT_RETURNED): 1641 case (e_FM_PCD_PRS_COUNTERS_L2_PARSE_RESULT_RETURNED_WITH_ERR): 1642 case (e_FM_PCD_PRS_COUNTERS_L3_PARSE_RESULT_RETURNED_WITH_ERR): 1643 case (e_FM_PCD_PRS_COUNTERS_L4_PARSE_RESULT_RETURNED_WITH_ERR): 1644 case (e_FM_PCD_PRS_COUNTERS_SHIM_PARSE_RESULT_RETURNED_WITH_ERR): 1645 case (e_FM_PCD_PRS_COUNTERS_SOFT_PRS_CYCLES): 1646 case (e_FM_PCD_PRS_COUNTERS_SOFT_PRS_STALL_CYCLES): 1647 case (e_FM_PCD_PRS_COUNTERS_HARD_PRS_CYCLE_INCL_STALL_CYCLES): 1648 case (e_FM_PCD_PRS_COUNTERS_MURAM_READ_CYCLES): 1649 case (e_FM_PCD_PRS_COUNTERS_MURAM_READ_STALL_CYCLES): 1650 case (e_FM_PCD_PRS_COUNTERS_MURAM_WRITE_CYCLES): 1651 case (e_FM_PCD_PRS_COUNTERS_MURAM_WRITE_STALL_CYCLES): 1652 case (e_FM_PCD_PRS_COUNTERS_FPM_COMMAND_STALL_CYCLES): 1653 if (!p_FmPcd->p_FmPcdPrs) 1654 { 1655 REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Parser is not activated")); 1656 return 0; 1657 } 1658 if ((p_FmPcd->guestId != NCSW_MASTER_ID) && 1659 !p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs && 1660 !p_FmPcd->h_IpcSession) 1661 { 1662 REPORT_ERROR(MINOR, E_NOT_SUPPORTED, 1663 ("running in guest-mode without neither IPC nor mapped register!")); 1664 return 0; 1665 } 1666 break; 1667 default: 1668 REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Unsupported type of counter")); 1669 return 0; 1670 } 1671 1672 if ((p_FmPcd->guestId != NCSW_MASTER_ID) && 1673 p_FmPcd->h_IpcSession) 1674 { 1675 t_FmPcdIpcMsg msg; 1676 t_FmPcdIpcReply reply; 1677 uint32_t replyLength; 1678 1679 memset(&msg, 0, sizeof(msg)); 1680 memset(&reply, 0, sizeof(reply)); 1681 msg.msgId = FM_PCD_GET_COUNTER; 1682 memcpy(msg.msgBody, (uint8_t *)&counter, sizeof(uint32_t)); 1683 replyLength = sizeof(uint32_t) + sizeof(uint32_t); 1684 if ((err = XX_IpcSendMessage(p_FmPcd->h_IpcSession, 1685 (uint8_t*)&msg, 1686 sizeof(msg.msgId) +sizeof(uint32_t), 1687 (uint8_t*)&reply, 1688 &replyLength, 1689 NULL, 1690 NULL)) != E_OK) 1691 RETURN_ERROR(MAJOR, err, NO_MSG); 1692 if (replyLength != sizeof(uint32_t) + sizeof(uint32_t)) 1693 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch")); 1694 1695 memcpy((uint8_t*)&outCounter, reply.replyBody, sizeof(uint32_t)); 1696 return outCounter; 1697 } 1698 1699 switch (counter) 1700 { 1701 /* Parser statistics */ 1702 case (e_FM_PCD_PRS_COUNTERS_PARSE_DISPATCH): 1703 return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_pds); 1704 case (e_FM_PCD_PRS_COUNTERS_L2_PARSE_RESULT_RETURNED): 1705 return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_l2rrs); 1706 case (e_FM_PCD_PRS_COUNTERS_L3_PARSE_RESULT_RETURNED): 1707 return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_l3rrs); 1708 case (e_FM_PCD_PRS_COUNTERS_L4_PARSE_RESULT_RETURNED): 1709 return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_l4rrs); 1710 case (e_FM_PCD_PRS_COUNTERS_SHIM_PARSE_RESULT_RETURNED): 1711 return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_srrs); 1712 case (e_FM_PCD_PRS_COUNTERS_L2_PARSE_RESULT_RETURNED_WITH_ERR): 1713 return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_l2rres); 1714 case (e_FM_PCD_PRS_COUNTERS_L3_PARSE_RESULT_RETURNED_WITH_ERR): 1715 return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_l3rres); 1716 case (e_FM_PCD_PRS_COUNTERS_L4_PARSE_RESULT_RETURNED_WITH_ERR): 1717 return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_l4rres); 1718 case (e_FM_PCD_PRS_COUNTERS_SHIM_PARSE_RESULT_RETURNED_WITH_ERR): 1719 return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_srres); 1720 case (e_FM_PCD_PRS_COUNTERS_SOFT_PRS_CYCLES): 1721 return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_spcs); 1722 case (e_FM_PCD_PRS_COUNTERS_SOFT_PRS_STALL_CYCLES): 1723 return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_spscs); 1724 case (e_FM_PCD_PRS_COUNTERS_HARD_PRS_CYCLE_INCL_STALL_CYCLES): 1725 return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_hxscs); 1726 case (e_FM_PCD_PRS_COUNTERS_MURAM_READ_CYCLES): 1727 return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_mrcs); 1728 case (e_FM_PCD_PRS_COUNTERS_MURAM_READ_STALL_CYCLES): 1729 return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_mrscs); 1730 case (e_FM_PCD_PRS_COUNTERS_MURAM_WRITE_CYCLES): 1731 return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_mwcs); 1732 case (e_FM_PCD_PRS_COUNTERS_MURAM_WRITE_STALL_CYCLES): 1733 return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_mwscs); 1734 case (e_FM_PCD_PRS_COUNTERS_FPM_COMMAND_STALL_CYCLES): 1735 return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_fcscs); 1736 case (e_FM_PCD_KG_COUNTERS_TOTAL): 1737 return GET_UINT32(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->fmkg_tpc); 1738 1739 /* Policer statistics */ 1740 case (e_FM_PCD_PLCR_COUNTERS_YELLOW): 1741 return GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_ypcnt); 1742 case (e_FM_PCD_PLCR_COUNTERS_RED): 1743 return GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_rpcnt); 1744 case (e_FM_PCD_PLCR_COUNTERS_RECOLORED_TO_RED): 1745 return GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_rrpcnt); 1746 case (e_FM_PCD_PLCR_COUNTERS_RECOLORED_TO_YELLOW): 1747 return GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_rypcnt); 1748 case (e_FM_PCD_PLCR_COUNTERS_TOTAL): 1749 return GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_tpcnt); 1750 case (e_FM_PCD_PLCR_COUNTERS_LENGTH_MISMATCH): 1751 return GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_flmcnt); 1752 } 1753 return 0; 1754 } 1755 1756 t_Error FM_PCD_SetException(t_Handle h_FmPcd, e_FmPcdExceptions exception, bool enable) 1757 { 1758 t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; 1759 uint32_t bitMask = 0, tmpReg; 1760 1761 SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE); 1762 SANITY_CHECK_RETURN_ERROR(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_STATE); 1763 1764 if (p_FmPcd->guestId != NCSW_MASTER_ID) 1765 RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("FM_PCD_SetException - guest mode!")); 1766 1767 GET_FM_PCD_EXCEPTION_FLAG(bitMask, exception); 1768 1769 if (bitMask) 1770 { 1771 if (enable) 1772 p_FmPcd->exceptions |= bitMask; 1773 else 1774 p_FmPcd->exceptions &= ~bitMask; 1775 1776 switch (exception) 1777 { 1778 case (e_FM_PCD_KG_EXCEPTION_DOUBLE_ECC): 1779 case (e_FM_PCD_KG_EXCEPTION_KEYSIZE_OVERFLOW): 1780 if (!p_FmPcd->p_FmPcdKg) 1781 RETURN_ERROR(MINOR, E_INVALID_STATE, ("Can't ask for this interrupt - keygen is not working")); 1782 break; 1783 case (e_FM_PCD_PLCR_EXCEPTION_DOUBLE_ECC): 1784 case (e_FM_PCD_PLCR_EXCEPTION_INIT_ENTRY_ERROR): 1785 case (e_FM_PCD_PLCR_EXCEPTION_PRAM_SELF_INIT_COMPLETE): 1786 case (e_FM_PCD_PLCR_EXCEPTION_ATOMIC_ACTION_COMPLETE): 1787 if (!p_FmPcd->p_FmPcdPlcr) 1788 RETURN_ERROR(MINOR, E_INVALID_STATE, ("Can't ask for this interrupt - policer is not working")); 1789 break; 1790 case (e_FM_PCD_PRS_EXCEPTION_DOUBLE_ECC): 1791 case (e_FM_PCD_PRS_EXCEPTION_SINGLE_ECC): 1792 if (!p_FmPcd->p_FmPcdPrs) 1793 RETURN_ERROR(MINOR, E_INVALID_STATE, ("Can't ask for this interrupt - parser is not working")); 1794 break; 1795 } 1796 1797 switch (exception) 1798 { 1799 case (e_FM_PCD_KG_EXCEPTION_DOUBLE_ECC): 1800 tmpReg = GET_UINT32(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->fmkg_eeer); 1801 if (enable) 1802 tmpReg |= FM_EX_KG_DOUBLE_ECC; 1803 else 1804 tmpReg &= ~FM_EX_KG_DOUBLE_ECC; 1805 WRITE_UINT32(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->fmkg_eeer, tmpReg); 1806 break; 1807 case (e_FM_PCD_KG_EXCEPTION_KEYSIZE_OVERFLOW): 1808 tmpReg = GET_UINT32(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->fmkg_eeer); 1809 if (enable) 1810 tmpReg |= FM_EX_KG_KEYSIZE_OVERFLOW; 1811 else 1812 tmpReg &= ~FM_EX_KG_KEYSIZE_OVERFLOW; 1813 WRITE_UINT32(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->fmkg_eeer, tmpReg); 1814 break; 1815 case (e_FM_PCD_PRS_EXCEPTION_DOUBLE_ECC): 1816 tmpReg = GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_perer); 1817 if (enable) 1818 tmpReg |= FM_PCD_PRS_DOUBLE_ECC; 1819 else 1820 tmpReg &= ~FM_PCD_PRS_DOUBLE_ECC; 1821 WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_perer, tmpReg); 1822 break; 1823 case (e_FM_PCD_PRS_EXCEPTION_SINGLE_ECC): 1824 tmpReg = GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_pever); 1825 if (enable) 1826 tmpReg |= FM_PCD_PRS_SINGLE_ECC; 1827 else 1828 tmpReg &= ~FM_PCD_PRS_SINGLE_ECC; 1829 WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_pever, tmpReg); 1830 break; 1831 case (e_FM_PCD_PLCR_EXCEPTION_DOUBLE_ECC): 1832 tmpReg = GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_eier); 1833 if (enable) 1834 tmpReg |= FM_PCD_PLCR_DOUBLE_ECC; 1835 else 1836 tmpReg &= ~FM_PCD_PLCR_DOUBLE_ECC; 1837 WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_eier, tmpReg); 1838 break; 1839 case (e_FM_PCD_PLCR_EXCEPTION_INIT_ENTRY_ERROR): 1840 tmpReg = GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_eier); 1841 if (enable) 1842 tmpReg |= FM_PCD_PLCR_INIT_ENTRY_ERROR; 1843 else 1844 tmpReg &= ~FM_PCD_PLCR_INIT_ENTRY_ERROR; 1845 WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_eier, tmpReg); 1846 break; 1847 case (e_FM_PCD_PLCR_EXCEPTION_PRAM_SELF_INIT_COMPLETE): 1848 tmpReg = GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_ier); 1849 if (enable) 1850 tmpReg |= FM_PCD_PLCR_PRAM_SELF_INIT_COMPLETE; 1851 else 1852 tmpReg &= ~FM_PCD_PLCR_PRAM_SELF_INIT_COMPLETE; 1853 WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_ier, tmpReg); 1854 break; 1855 case (e_FM_PCD_PLCR_EXCEPTION_ATOMIC_ACTION_COMPLETE): 1856 tmpReg = GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_ier); 1857 if (enable) 1858 tmpReg |= FM_PCD_PLCR_ATOMIC_ACTION_COMPLETE; 1859 else 1860 tmpReg &= ~FM_PCD_PLCR_ATOMIC_ACTION_COMPLETE; 1861 WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_ier, tmpReg); 1862 break; 1863 } 1864 /* for ECC exceptions driver automatically enables ECC mechanism, if disabled. 1865 Driver may disable them automatically, depending on driver's status */ 1866 if (enable && ((exception == e_FM_PCD_KG_EXCEPTION_DOUBLE_ECC) | 1867 (exception == e_FM_PCD_PLCR_EXCEPTION_DOUBLE_ECC) | 1868 (exception == e_FM_PCD_PRS_EXCEPTION_DOUBLE_ECC) | 1869 (exception == e_FM_PCD_PRS_EXCEPTION_SINGLE_ECC))) 1870 FmEnableRamsEcc(p_FmPcd->h_Fm); 1871 if (!enable && ((exception == e_FM_PCD_KG_EXCEPTION_DOUBLE_ECC) | 1872 (exception == e_FM_PCD_PLCR_EXCEPTION_DOUBLE_ECC) | 1873 (exception == e_FM_PCD_PRS_EXCEPTION_DOUBLE_ECC) | 1874 (exception == e_FM_PCD_PRS_EXCEPTION_SINGLE_ECC))) 1875 FmDisableRamsEcc(p_FmPcd->h_Fm); 1876 } 1877 1878 return E_OK; 1879 } 1880 1881 t_Error FM_PCD_ForceIntr (t_Handle h_FmPcd, e_FmPcdExceptions exception) 1882 { 1883 t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; 1884 1885 SANITY_CHECK_RETURN_ERROR(h_FmPcd, E_INVALID_HANDLE); 1886 SANITY_CHECK_RETURN_ERROR(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_STATE); 1887 1888 if (p_FmPcd->guestId != NCSW_MASTER_ID) 1889 RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("FM_PCD_ForceIntr - guest mode!")); 1890 1891 switch (exception) 1892 { 1893 case (e_FM_PCD_KG_EXCEPTION_DOUBLE_ECC): 1894 case (e_FM_PCD_KG_EXCEPTION_KEYSIZE_OVERFLOW): 1895 if (!p_FmPcd->p_FmPcdKg) 1896 RETURN_ERROR(MINOR, E_INVALID_STATE, ("Can't ask for this interrupt - keygen is not working")); 1897 break; 1898 case (e_FM_PCD_PLCR_EXCEPTION_DOUBLE_ECC): 1899 case (e_FM_PCD_PLCR_EXCEPTION_INIT_ENTRY_ERROR): 1900 case (e_FM_PCD_PLCR_EXCEPTION_PRAM_SELF_INIT_COMPLETE): 1901 case (e_FM_PCD_PLCR_EXCEPTION_ATOMIC_ACTION_COMPLETE): 1902 if (!p_FmPcd->p_FmPcdPlcr) 1903 RETURN_ERROR(MINOR, E_INVALID_STATE, ("Can't ask for this interrupt - policer is not working")); 1904 break; 1905 case (e_FM_PCD_PRS_EXCEPTION_DOUBLE_ECC): 1906 case (e_FM_PCD_PRS_EXCEPTION_SINGLE_ECC): 1907 if (!p_FmPcd->p_FmPcdPrs) 1908 RETURN_ERROR(MINOR, E_INVALID_STATE, ("Can't ask for this interrupt -parsrer is not working")); 1909 break; 1910 default: 1911 RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid interrupt requested")); 1912 } 1913 switch (exception) 1914 { 1915 case e_FM_PCD_PRS_EXCEPTION_DOUBLE_ECC: 1916 if (!(p_FmPcd->exceptions & FM_PCD_EX_PRS_DOUBLE_ECC)) 1917 RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked")); 1918 break; 1919 case e_FM_PCD_PRS_EXCEPTION_SINGLE_ECC: 1920 if (!(p_FmPcd->exceptions & FM_PCD_EX_PRS_SINGLE_ECC)) 1921 RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked")); 1922 break; 1923 case e_FM_PCD_KG_EXCEPTION_DOUBLE_ECC: 1924 if (!(p_FmPcd->exceptions & FM_EX_KG_DOUBLE_ECC)) 1925 RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked")); 1926 WRITE_UINT32(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->fmkg_feer, FM_EX_KG_DOUBLE_ECC); 1927 break; 1928 case e_FM_PCD_KG_EXCEPTION_KEYSIZE_OVERFLOW: 1929 if (!(p_FmPcd->exceptions & FM_EX_KG_KEYSIZE_OVERFLOW)) 1930 RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked")); 1931 WRITE_UINT32(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->fmkg_feer, FM_EX_KG_KEYSIZE_OVERFLOW); 1932 break; 1933 case e_FM_PCD_PLCR_EXCEPTION_DOUBLE_ECC: 1934 if (!(p_FmPcd->exceptions & FM_PCD_EX_PLCR_DOUBLE_ECC)) 1935 RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked")); 1936 WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_eifr, FM_PCD_PLCR_DOUBLE_ECC); 1937 break; 1938 case e_FM_PCD_PLCR_EXCEPTION_INIT_ENTRY_ERROR: 1939 if (!(p_FmPcd->exceptions & FM_PCD_EX_PLCR_INIT_ENTRY_ERROR)) 1940 RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked")); 1941 WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_eifr, FM_PCD_PLCR_INIT_ENTRY_ERROR); 1942 break; 1943 case e_FM_PCD_PLCR_EXCEPTION_PRAM_SELF_INIT_COMPLETE: 1944 if (!(p_FmPcd->exceptions & FM_PCD_EX_PLCR_PRAM_SELF_INIT_COMPLETE)) 1945 RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked")); 1946 WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_ifr, FM_PCD_PLCR_PRAM_SELF_INIT_COMPLETE); 1947 break; 1948 case e_FM_PCD_PLCR_EXCEPTION_ATOMIC_ACTION_COMPLETE: 1949 if (!(p_FmPcd->exceptions & FM_PCD_EX_PLCR_ATOMIC_ACTION_COMPLETE)) 1950 RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked")); 1951 WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_ifr, FM_PCD_PLCR_ATOMIC_ACTION_COMPLETE); 1952 break; 1953 } 1954 1955 return E_OK; 1956 } 1957 1958 1959 t_Error FM_PCD_ModifyCounter(t_Handle h_FmPcd, e_FmPcdCounters counter, uint32_t value) 1960 { 1961 t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; 1962 1963 SANITY_CHECK_RETURN_ERROR(h_FmPcd, E_INVALID_HANDLE); 1964 SANITY_CHECK_RETURN_ERROR(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_STATE); 1965 1966 if (p_FmPcd->guestId != NCSW_MASTER_ID) 1967 RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("FM_PCD_ModifyCounter - guest mode!")); 1968 1969 switch (counter) 1970 { 1971 case (e_FM_PCD_KG_COUNTERS_TOTAL): 1972 if (!p_FmPcd->p_FmPcdKg) 1973 RETURN_ERROR(MINOR, E_INVALID_STATE, ("Invalid counters - KeyGen is not working")); 1974 break; 1975 case (e_FM_PCD_PLCR_COUNTERS_YELLOW): 1976 case (e_FM_PCD_PLCR_COUNTERS_RED): 1977 case (e_FM_PCD_PLCR_COUNTERS_RECOLORED_TO_RED): 1978 case (e_FM_PCD_PLCR_COUNTERS_RECOLORED_TO_YELLOW): 1979 case (e_FM_PCD_PLCR_COUNTERS_TOTAL): 1980 case (e_FM_PCD_PLCR_COUNTERS_LENGTH_MISMATCH): 1981 if (!p_FmPcd->p_FmPcdPlcr) 1982 RETURN_ERROR(MINOR, E_INVALID_STATE, ("Invalid counters - Policer is not working")); 1983 if (!(GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_gcr) & FM_PCD_PLCR_GCR_STEN)) 1984 RETURN_ERROR(MINOR, E_INVALID_STATE, ("Requested counter was not enabled")); 1985 break; 1986 case (e_FM_PCD_PRS_COUNTERS_PARSE_DISPATCH): 1987 case (e_FM_PCD_PRS_COUNTERS_L2_PARSE_RESULT_RETURNED): 1988 case (e_FM_PCD_PRS_COUNTERS_L3_PARSE_RESULT_RETURNED): 1989 case (e_FM_PCD_PRS_COUNTERS_L4_PARSE_RESULT_RETURNED): 1990 case (e_FM_PCD_PRS_COUNTERS_SHIM_PARSE_RESULT_RETURNED): 1991 case (e_FM_PCD_PRS_COUNTERS_L2_PARSE_RESULT_RETURNED_WITH_ERR): 1992 case (e_FM_PCD_PRS_COUNTERS_L3_PARSE_RESULT_RETURNED_WITH_ERR): 1993 case (e_FM_PCD_PRS_COUNTERS_L4_PARSE_RESULT_RETURNED_WITH_ERR): 1994 case (e_FM_PCD_PRS_COUNTERS_SHIM_PARSE_RESULT_RETURNED_WITH_ERR): 1995 case (e_FM_PCD_PRS_COUNTERS_SOFT_PRS_CYCLES): 1996 case (e_FM_PCD_PRS_COUNTERS_SOFT_PRS_STALL_CYCLES): 1997 case (e_FM_PCD_PRS_COUNTERS_HARD_PRS_CYCLE_INCL_STALL_CYCLES): 1998 case (e_FM_PCD_PRS_COUNTERS_MURAM_READ_CYCLES): 1999 case (e_FM_PCD_PRS_COUNTERS_MURAM_READ_STALL_CYCLES): 2000 case (e_FM_PCD_PRS_COUNTERS_MURAM_WRITE_CYCLES): 2001 case (e_FM_PCD_PRS_COUNTERS_MURAM_WRITE_STALL_CYCLES): 2002 case (e_FM_PCD_PRS_COUNTERS_FPM_COMMAND_STALL_CYCLES): 2003 if (!p_FmPcd->p_FmPcdPrs) 2004 RETURN_ERROR(MINOR, E_INVALID_STATE, ("Unsupported type of counter")); 2005 break; 2006 default: 2007 RETURN_ERROR(MINOR, E_INVALID_STATE, ("Unsupported type of counter")); 2008 } 2009 switch (counter) 2010 { 2011 case (e_FM_PCD_PRS_COUNTERS_PARSE_DISPATCH): 2012 WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_pds, value); 2013 break; 2014 case (e_FM_PCD_PRS_COUNTERS_L2_PARSE_RESULT_RETURNED): 2015 WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_l2rrs, value); 2016 break; 2017 case (e_FM_PCD_PRS_COUNTERS_L3_PARSE_RESULT_RETURNED): 2018 WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_l3rrs, value); 2019 break; 2020 case (e_FM_PCD_PRS_COUNTERS_L4_PARSE_RESULT_RETURNED): 2021 WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_l4rrs, value); 2022 break; 2023 case (e_FM_PCD_PRS_COUNTERS_SHIM_PARSE_RESULT_RETURNED): 2024 WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_srrs, value); 2025 break; 2026 case (e_FM_PCD_PRS_COUNTERS_L2_PARSE_RESULT_RETURNED_WITH_ERR): 2027 WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_l2rres, value); 2028 break; 2029 case (e_FM_PCD_PRS_COUNTERS_L3_PARSE_RESULT_RETURNED_WITH_ERR): 2030 WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_l3rres, value); 2031 break; 2032 case (e_FM_PCD_PRS_COUNTERS_L4_PARSE_RESULT_RETURNED_WITH_ERR): 2033 WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_l4rres, value); 2034 break; 2035 case (e_FM_PCD_PRS_COUNTERS_SHIM_PARSE_RESULT_RETURNED_WITH_ERR): 2036 WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_srres, value); 2037 break; 2038 case (e_FM_PCD_PRS_COUNTERS_SOFT_PRS_CYCLES): 2039 WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_spcs, value); 2040 break; 2041 case (e_FM_PCD_PRS_COUNTERS_SOFT_PRS_STALL_CYCLES): 2042 WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_spscs, value); 2043 break; 2044 case (e_FM_PCD_PRS_COUNTERS_HARD_PRS_CYCLE_INCL_STALL_CYCLES): 2045 WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_hxscs, value); 2046 break; 2047 case (e_FM_PCD_PRS_COUNTERS_MURAM_READ_CYCLES): 2048 WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_mrcs, value); 2049 break; 2050 case (e_FM_PCD_PRS_COUNTERS_MURAM_READ_STALL_CYCLES): 2051 WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_mrscs, value); 2052 break; 2053 case (e_FM_PCD_PRS_COUNTERS_MURAM_WRITE_CYCLES): 2054 WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_mwcs, value); 2055 break; 2056 case (e_FM_PCD_PRS_COUNTERS_MURAM_WRITE_STALL_CYCLES): 2057 WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_mwscs, value); 2058 break; 2059 case (e_FM_PCD_PRS_COUNTERS_FPM_COMMAND_STALL_CYCLES): 2060 WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_fcscs, value); 2061 break; 2062 case (e_FM_PCD_KG_COUNTERS_TOTAL): 2063 WRITE_UINT32(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->fmkg_tpc,value); 2064 break; 2065 2066 /*Policer counters*/ 2067 case (e_FM_PCD_PLCR_COUNTERS_YELLOW): 2068 WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_ypcnt, value); 2069 break; 2070 case (e_FM_PCD_PLCR_COUNTERS_RED): 2071 WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_rpcnt, value); 2072 break; 2073 case (e_FM_PCD_PLCR_COUNTERS_RECOLORED_TO_RED): 2074 WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_rrpcnt, value); 2075 break; 2076 case (e_FM_PCD_PLCR_COUNTERS_RECOLORED_TO_YELLOW): 2077 WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_rypcnt, value); 2078 break; 2079 case (e_FM_PCD_PLCR_COUNTERS_TOTAL): 2080 WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_tpcnt, value); 2081 break; 2082 case (e_FM_PCD_PLCR_COUNTERS_LENGTH_MISMATCH): 2083 WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_flmcnt, value); 2084 break; 2085 } 2086 2087 return E_OK; 2088 } 2089 2090 t_Handle FM_PCD_GetHcPort(t_Handle h_FmPcd) 2091 { 2092 t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; 2093 return FmHcGetPort(p_FmPcd->h_Hc); 2094 } 2095 2096