1 /* Copyright (c) 2008-2011 Freescale Semiconductor, Inc. 2 * All rights reserved. 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 @File fm_plcr.c 35 36 @Description FM PCD POLICER... 37 *//***************************************************************************/ 38 #include "std_ext.h" 39 #include "error_ext.h" 40 #include "string_ext.h" 41 #include "debug_ext.h" 42 #include "net_ext.h" 43 #include "fm_ext.h" 44 45 #include "fm_common.h" 46 #include "fm_pcd.h" 47 #include "fm_hc.h" 48 #include "fm_pcd_ipc.h" 49 50 51 static bool FmPcdPlcrIsProfileShared(t_Handle h_FmPcd, uint16_t absoluteProfileId) 52 { 53 t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; 54 uint16_t i; 55 56 SANITY_CHECK_RETURN_VALUE(p_FmPcd, E_INVALID_HANDLE, FALSE); 57 58 for(i=0;i<p_FmPcd->p_FmPcdPlcr->numOfSharedProfiles;i++) 59 if(p_FmPcd->p_FmPcdPlcr->sharedProfilesIds[i] == absoluteProfileId) 60 return TRUE; 61 return FALSE; 62 } 63 64 static t_Error SetProfileNia(t_FmPcd *p_FmPcd, e_FmPcdEngine nextEngine, u_FmPcdPlcrNextEngineParams *p_NextEngineParams, uint32_t *nextAction) 65 { 66 uint32_t nia; 67 uint16_t absoluteProfileId = (uint16_t)(PTR_TO_UINT(p_NextEngineParams->h_Profile)-1); 68 uint8_t relativeSchemeId, physicatSchemeId; 69 70 nia = FM_PCD_PLCR_NIA_VALID; 71 72 switch (nextEngine) 73 { 74 case e_FM_PCD_DONE : 75 switch (p_NextEngineParams->action) 76 { 77 case e_FM_PCD_DROP_FRAME : 78 nia |= (NIA_ENG_BMI | NIA_BMI_AC_DISCARD); 79 break; 80 case e_FM_PCD_ENQ_FRAME: 81 nia |= (NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME); 82 break; 83 default: 84 RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG); 85 } 86 break; 87 case e_FM_PCD_KG: 88 physicatSchemeId = (uint8_t)(PTR_TO_UINT(p_NextEngineParams->h_DirectScheme)-1); 89 relativeSchemeId = FmPcdKgGetRelativeSchemeId(p_FmPcd, physicatSchemeId); 90 if(relativeSchemeId == FM_PCD_KG_NUM_OF_SCHEMES) 91 RETURN_ERROR(MAJOR, E_NOT_IN_RANGE, NO_MSG); 92 if (!FmPcdKgIsSchemeValidSw(p_FmPcd, relativeSchemeId)) 93 RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid direct scheme.")); 94 if(!KgIsSchemeAlwaysDirect(p_FmPcd, relativeSchemeId)) 95 RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Policer Profile may point only to a scheme that is always direct.")); 96 nia |= NIA_ENG_KG | NIA_KG_DIRECT | physicatSchemeId; 97 break; 98 case e_FM_PCD_PLCR: 99 if(!FmPcdPlcrIsProfileShared(p_FmPcd, absoluteProfileId)) 100 RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Next profile must be a shared profile")); 101 if(!FmPcdPlcrIsProfileValid(p_FmPcd, absoluteProfileId)) 102 RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid profile ")); 103 nia |= NIA_ENG_PLCR | NIA_PLCR_ABSOLUTE | absoluteProfileId; 104 break; 105 default: 106 RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG); 107 } 108 109 *nextAction = nia; 110 111 return E_OK; 112 } 113 114 static uint32_t FPP_Function(uint32_t fpp) 115 { 116 if(fpp > 15) 117 return 15 - (0x1f - fpp); 118 else 119 return 16 + fpp; 120 } 121 122 static void GetInfoRateReg(e_FmPcdPlcrRateMode rateMode, 123 uint32_t rate, 124 uint64_t tsuInTenthNano, 125 uint32_t fppShift, 126 uint64_t *p_Integer, 127 uint64_t *p_Fraction) 128 { 129 uint64_t tmp, div; 130 131 if(rateMode == e_FM_PCD_PLCR_BYTE_MODE) 132 { 133 /* now we calculate the initial integer for the bigger rate */ 134 /* from Kbps to Bytes/TSU */ 135 tmp = (uint64_t)rate; 136 tmp *= 1000; /* kb --> b */ 137 tmp *= tsuInTenthNano; /* bps --> bpTsu(in 10nano) */ 138 139 div = 1000000000; /* nano */ 140 div *= 10; /* 10 nano */ 141 div *= 8; /* bit to byte */ 142 } 143 else 144 { 145 /* now we calculate the initial integer for the bigger rate */ 146 /* from Kbps to Bytes/TSU */ 147 tmp = (uint64_t)rate; 148 tmp *= tsuInTenthNano; /* bps --> bpTsu(in 10nano) */ 149 150 div = 1000000000; /* nano */ 151 div *= 10; /* 10 nano */ 152 } 153 *p_Integer = (tmp<<fppShift)/div; 154 155 /* for calculating the fraction, we will recalculate cir and deduct the integer. 156 * For precision, we will multiply by 2^16. we do not divid back, since we write 157 * this value as fraction - see spec. 158 */ 159 *p_Fraction = (((tmp<<fppShift)<<16) - ((*p_Integer<<16)*div))/div; 160 } 161 162 /* .......... */ 163 164 static void calcRates(t_Handle h_FmPcd, t_FmPcdPlcrNonPassthroughAlgParams *p_NonPassthroughAlgParam, 165 uint32_t *cir, uint32_t *cbs, uint32_t *pir_eir, uint32_t *pbs_ebs, uint32_t *fpp) 166 { 167 t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; 168 uint64_t integer, fraction; 169 uint32_t temp, tsuInTenthNanos, bitFor1Micro; 170 uint8_t fppShift=0; 171 172 bitFor1Micro = FmGetTimeStampScale(p_FmPcd->h_Fm); /* TimeStamp per nano seconds units */ 173 /* we want the tsu to count 10 nano for better precision normally tsu is 3.9 nano, now we will get 39 */ 174 tsuInTenthNanos = (uint32_t)(1000*10/(1<<bitFor1Micro)); 175 176 /* we choose the faster rate to calibrate fpp */ 177 if (p_NonPassthroughAlgParam->comittedInfoRate > p_NonPassthroughAlgParam->peakOrAccessiveInfoRate) 178 GetInfoRateReg(p_NonPassthroughAlgParam->rateMode, p_NonPassthroughAlgParam->comittedInfoRate, tsuInTenthNanos, 0, &integer, &fraction); 179 else 180 GetInfoRateReg(p_NonPassthroughAlgParam->rateMode, p_NonPassthroughAlgParam->peakOrAccessiveInfoRate, tsuInTenthNanos, 0, &integer, &fraction); 181 182 183 /* we shift integer, as in cir/pir it is represented by the MSB 16 bits, and 184 * the LSB bits are for the fraction */ 185 temp = (uint32_t)((integer<<16) & 0x00000000FFFFFFFF); 186 /* temp is effected by the rate. For low rates it may be as low as 0, and then we'll 187 * take max fpp=31. 188 * For high rates it will never exceed the 32 bit reg (after the 16 shift), as it is 189 * limited by the 10G physical port. 190 */ 191 if(temp != 0) 192 { 193 /* count zeroes left of the higher used bit (in order to shift the value such that 194 * unused bits may be used for fraction). 195 */ 196 while ((temp & 0x80000000) == 0) 197 { 198 temp = temp << 1; 199 fppShift++; 200 } 201 if(fppShift > 15) 202 { 203 REPORT_ERROR(MAJOR, E_INVALID_SELECTION, ("timeStampPeriod to Information rate ratio is too small")); 204 return; 205 } 206 } 207 else 208 { 209 temp = (uint32_t)fraction; /* fraction will alyas be smaller than 2^16 */ 210 if(!temp) 211 /* integer and fraction are 0, we set fpp to its max val */ 212 fppShift = 31; 213 else 214 { 215 /* integer was 0 but fraction is not. fpp is 16 for the integer, 216 * + all left zeroes of the fraction. */ 217 fppShift=16; 218 /* count zeroes left of the higher used bit (in order to shift the value such that 219 * unused bits may be used for fraction). 220 */ 221 while ((temp & 0x8000) == 0) 222 { 223 temp = temp << 1; 224 fppShift++; 225 } 226 } 227 } 228 229 /* 230 * This means that the FM TS register will now be used so that 'count' bits are for 231 * fraction and the rest for integer */ 232 /* now we re-calculate cir */ 233 GetInfoRateReg(p_NonPassthroughAlgParam->rateMode, p_NonPassthroughAlgParam->comittedInfoRate, tsuInTenthNanos, fppShift, &integer, &fraction); 234 *cir = (uint32_t)(integer << 16 | (fraction & 0xFFFF)); 235 GetInfoRateReg(p_NonPassthroughAlgParam->rateMode, p_NonPassthroughAlgParam->peakOrAccessiveInfoRate, tsuInTenthNanos, fppShift, &integer, &fraction); 236 *pir_eir = (uint32_t)(integer << 16 | (fraction & 0xFFFF)); 237 238 *cbs = p_NonPassthroughAlgParam->comittedBurstSize; 239 *pbs_ebs = p_NonPassthroughAlgParam->peakOrAccessiveBurstSize; 240 241 /* get fpp as it should be written to reg.*/ 242 *fpp = FPP_Function(fppShift); 243 244 } 245 246 static void WritePar(t_FmPcd *p_FmPcd, uint32_t par) 247 { 248 t_FmPcdPlcrRegs *p_FmPcdPlcrRegs = p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs; 249 250 ASSERT_COND(FmIsMaster(p_FmPcd->h_Fm)); 251 WRITE_UINT32(p_FmPcdPlcrRegs->fmpl_par, par); 252 253 while(GET_UINT32(p_FmPcdPlcrRegs->fmpl_par) & FM_PCD_PLCR_PAR_GO) ; 254 255 } 256 257 /*********************************************/ 258 /*............Policer Exception..............*/ 259 /*********************************************/ 260 static void PcdPlcrException(t_Handle h_FmPcd) 261 { 262 t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd; 263 uint32_t event, mask, force; 264 265 ASSERT_COND(FmIsMaster(p_FmPcd->h_Fm)); 266 event = GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_evr); 267 mask = GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_ier); 268 269 event &= mask; 270 271 /* clear the forced events */ 272 force = GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_ifr); 273 if(force & event) 274 WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_ifr, force & ~event); 275 276 277 WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_evr, event); 278 279 if(event & FM_PCD_PLCR_PRAM_SELF_INIT_COMPLETE) 280 p_FmPcd->f_Exception(p_FmPcd->h_App,e_FM_PCD_PLCR_EXCEPTION_PRAM_SELF_INIT_COMPLETE); 281 if(event & FM_PCD_PLCR_ATOMIC_ACTION_COMPLETE) 282 p_FmPcd->f_Exception(p_FmPcd->h_App,e_FM_PCD_PLCR_EXCEPTION_ATOMIC_ACTION_COMPLETE); 283 284 } 285 286 /* ..... */ 287 288 static void PcdPlcrErrorException(t_Handle h_FmPcd) 289 { 290 t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd; 291 uint32_t event, force, captureReg, mask; 292 293 ASSERT_COND(FmIsMaster(p_FmPcd->h_Fm)); 294 event = GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_eevr); 295 mask = GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_eier); 296 297 event &= mask; 298 299 /* clear the forced events */ 300 force = GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_eifr); 301 if(force & event) 302 WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_eifr, force & ~event); 303 304 WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_eevr, event); 305 306 if(event & FM_PCD_PLCR_DOUBLE_ECC) 307 p_FmPcd->f_Exception(p_FmPcd->h_App,e_FM_PCD_PLCR_EXCEPTION_DOUBLE_ECC); 308 if(event & FM_PCD_PLCR_INIT_ENTRY_ERROR) 309 { 310 captureReg = GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_upcr); 311 /*ASSERT_COND(captureReg & PLCR_ERR_UNINIT_CAP); 312 p_UnInitCapt->profileNum = (uint8_t)(captureReg & PLCR_ERR_UNINIT_NUM_MASK); 313 p_UnInitCapt->portId = (uint8_t)((captureReg & PLCR_ERR_UNINIT_PID_MASK) >>PLCR_ERR_UNINIT_PID_SHIFT) ; 314 p_UnInitCapt->absolute = (bool)(captureReg & PLCR_ERR_UNINIT_ABSOLUTE_MASK);*/ 315 p_FmPcd->f_FmPcdIndexedException(p_FmPcd->h_App,e_FM_PCD_PLCR_EXCEPTION_INIT_ENTRY_ERROR,(uint16_t)(captureReg & PLCR_ERR_UNINIT_NUM_MASK)); 316 WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_upcr, PLCR_ERR_UNINIT_CAP); 317 } 318 } 319 320 void FmPcdPlcrUpatePointedOwner(t_Handle h_FmPcd, uint16_t absoluteProfileId, bool add) 321 { 322 t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; 323 324 ASSERT_COND(p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId].valid); 325 326 if(add) 327 p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId].pointedOwners++; 328 else 329 p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId].pointedOwners--; 330 } 331 332 uint32_t FmPcdPlcrGetPointedOwners(t_Handle h_FmPcd, uint16_t absoluteProfileId) 333 { 334 t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; 335 336 ASSERT_COND(p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId].valid); 337 338 return p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId].pointedOwners; 339 } 340 uint32_t FmPcdPlcrGetRequiredAction(t_Handle h_FmPcd, uint16_t absoluteProfileId) 341 { 342 t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; 343 344 ASSERT_COND(p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId].valid); 345 346 return p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId].requiredAction; 347 } 348 349 t_Error FmPcdPlcrAllocProfiles(t_Handle h_FmPcd, uint8_t hardwarePortId, uint16_t numOfProfiles) 350 { 351 t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; 352 t_FmPcdIpcPlcrAllocParams ipcPlcrParams; 353 t_Error err = E_OK; 354 uint16_t base; 355 uint16_t swPortIndex = 0; 356 t_FmPcdIpcMsg msg; 357 uint32_t replyLength; 358 t_FmPcdIpcReply reply; 359 360 SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE); 361 362 if(!numOfProfiles) 363 return E_OK; 364 365 memset(&ipcPlcrParams, 0, sizeof(ipcPlcrParams)); 366 367 if(p_FmPcd->guestId != NCSW_MASTER_ID) 368 { 369 /* Alloc resources using IPC messaging */ 370 memset(&reply, 0, sizeof(reply)); 371 memset(&msg, 0, sizeof(msg)); 372 ipcPlcrParams.num = numOfProfiles; 373 ipcPlcrParams.hardwarePortId = hardwarePortId; 374 msg.msgId = FM_PCD_ALLOC_PROFILES; 375 memcpy(msg.msgBody, &ipcPlcrParams, sizeof(ipcPlcrParams)); 376 replyLength = sizeof(uint32_t) + sizeof(uint16_t); 377 if ((err = XX_IpcSendMessage(p_FmPcd->h_IpcSession, 378 (uint8_t*)&msg, 379 sizeof(msg.msgId) +sizeof(ipcPlcrParams), 380 (uint8_t*)&reply, 381 &replyLength, 382 NULL, 383 NULL)) != E_OK) 384 RETURN_ERROR(MAJOR, err,NO_MSG); 385 if (replyLength != sizeof(uint32_t) + sizeof(uint16_t)) 386 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch")); 387 if((t_Error)reply.error != E_OK) 388 RETURN_ERROR(MAJOR, (t_Error)reply.error, ("PLCR profiles allocation failed")); 389 390 memcpy((uint8_t*)&base, reply.replyBody, sizeof(uint16_t)); 391 } 392 else /* master */ 393 { 394 err = PlcrAllocProfiles(p_FmPcd, hardwarePortId, numOfProfiles, &base); 395 if(err) 396 RETURN_ERROR(MAJOR, err,NO_MSG); 397 } 398 HW_PORT_ID_TO_SW_PORT_INDX(swPortIndex, hardwarePortId); 399 400 p_FmPcd->p_FmPcdPlcr->portsMapping[swPortIndex].numOfProfiles = numOfProfiles; 401 p_FmPcd->p_FmPcdPlcr->portsMapping[swPortIndex].profilesBase = base; 402 403 return E_OK; 404 } 405 406 t_Error FmPcdPlcrFreeProfiles(t_Handle h_FmPcd, uint8_t hardwarePortId) 407 { 408 t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; 409 t_FmPcdIpcPlcrAllocParams ipcPlcrParams; 410 t_Error err = E_OK; 411 uint16_t swPortIndex = 0; 412 t_FmPcdIpcMsg msg; 413 uint32_t replyLength; 414 t_FmPcdIpcReply reply; 415 416 SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE); 417 418 HW_PORT_ID_TO_SW_PORT_INDX(swPortIndex, hardwarePortId); 419 420 if(p_FmPcd->guestId != NCSW_MASTER_ID) 421 { 422 /* Alloc resources using IPC messaging */ 423 memset(&reply, 0, sizeof(reply)); 424 memset(&msg, 0, sizeof(msg)); 425 ipcPlcrParams.num = p_FmPcd->p_FmPcdPlcr->portsMapping[swPortIndex].numOfProfiles; 426 ipcPlcrParams.hardwarePortId = hardwarePortId; 427 ipcPlcrParams.plcrProfilesBase = p_FmPcd->p_FmPcdPlcr->portsMapping[swPortIndex].profilesBase; 428 msg.msgId = FM_PCD_FREE_PROFILES; 429 memcpy(msg.msgBody, &ipcPlcrParams, sizeof(ipcPlcrParams)); 430 replyLength = sizeof(uint32_t); 431 if ((err = XX_IpcSendMessage(p_FmPcd->h_IpcSession, 432 (uint8_t*)&msg, 433 sizeof(msg.msgId) +sizeof(ipcPlcrParams), 434 (uint8_t*)&reply, 435 &replyLength, 436 NULL, 437 NULL)) != E_OK) 438 RETURN_ERROR(MAJOR, err,NO_MSG); 439 if (replyLength != sizeof(uint32_t)) 440 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch")); 441 if ((t_Error)reply.error != E_OK) 442 RETURN_ERROR(MINOR, (t_Error)reply.error, ("PLCR Free Profiles failed")); 443 } 444 else /* master */ 445 { 446 err = PlcrFreeProfiles(p_FmPcd, hardwarePortId, p_FmPcd->p_FmPcdPlcr->portsMapping[swPortIndex].numOfProfiles, p_FmPcd->p_FmPcdPlcr->portsMapping[swPortIndex].profilesBase); 447 if(err) 448 RETURN_ERROR(MAJOR, err,NO_MSG); 449 } 450 p_FmPcd->p_FmPcdPlcr->portsMapping[swPortIndex].numOfProfiles = 0; 451 p_FmPcd->p_FmPcdPlcr->portsMapping[swPortIndex].profilesBase = 0; 452 453 return E_OK; 454 } 455 456 bool FmPcdPlcrIsProfileValid(t_Handle h_FmPcd, uint16_t absoluteProfileId) 457 { 458 t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; 459 t_FmPcdPlcr *p_FmPcdPlcr = p_FmPcd->p_FmPcdPlcr; 460 461 return p_FmPcdPlcr->profiles[absoluteProfileId].valid; 462 } 463 464 t_Error PlcrAllocProfiles(t_FmPcd *p_FmPcd, uint8_t hardwarePortId, uint16_t numOfProfiles, uint16_t *p_Base) 465 { 466 t_FmPcdPlcrRegs *p_Regs = p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs; 467 uint32_t profilesFound, log2Num, tmpReg32; 468 uint32_t intFlags; 469 uint16_t first, i; 470 471 SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE); 472 473 ASSERT_COND(FmIsMaster(p_FmPcd->h_Fm)); 474 if(!numOfProfiles) 475 return E_OK; 476 477 ASSERT_COND(hardwarePortId); 478 479 if (numOfProfiles>FM_PCD_PLCR_NUM_ENTRIES) 480 RETURN_ERROR(MINOR, E_INVALID_VALUE, ("numProfiles is too big.")); 481 482 if (!POWER_OF_2(numOfProfiles)) 483 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("numProfiles must be a power of 2.")); 484 485 intFlags = FmPcdLock(p_FmPcd); 486 487 if(GET_UINT32(p_Regs->fmpl_pmr[hardwarePortId-1]) & FM_PCD_PLCR_PMR_V) 488 { 489 FmPcdUnlock(p_FmPcd, intFlags); 490 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("The requesting port has already an allocated profiles window.")); 491 } 492 493 first = 0; 494 profilesFound = 0; 495 for(i=0;i<FM_PCD_PLCR_NUM_ENTRIES;) 496 { 497 if(!p_FmPcd->p_FmPcdPlcr->profiles[i].profilesMng.allocated) 498 { 499 profilesFound++; 500 i++; 501 if(profilesFound == numOfProfiles) 502 break; 503 } 504 else 505 { 506 profilesFound = 0; 507 /* advance i to the next aligned address */ 508 first = i = (uint8_t)(first + numOfProfiles); 509 } 510 } 511 if(profilesFound == numOfProfiles) 512 { 513 for(i = first; i<first + numOfProfiles; i++) 514 { 515 p_FmPcd->p_FmPcdPlcr->profiles[i].profilesMng.allocated = TRUE; 516 p_FmPcd->p_FmPcdPlcr->profiles[i].profilesMng.ownerId = hardwarePortId; 517 } 518 } 519 else 520 { 521 FmPcdUnlock(p_FmPcd, intFlags); 522 RETURN_ERROR(MINOR, E_FULL, ("No profiles.")); 523 } 524 525 /**********************FMPL_PMRx******************/ 526 LOG2((uint64_t)numOfProfiles, log2Num); 527 tmpReg32 = first; 528 tmpReg32 |= log2Num << 16; 529 tmpReg32 |= FM_PCD_PLCR_PMR_V; 530 WRITE_UINT32(p_Regs->fmpl_pmr[hardwarePortId-1], tmpReg32); 531 532 *p_Base = first; 533 534 FmPcdUnlock(p_FmPcd, intFlags); 535 536 return E_OK; 537 } 538 539 t_Error PlcrAllocSharedProfiles(t_FmPcd *p_FmPcd, uint16_t numOfProfiles, uint16_t *profilesIds) 540 { 541 uint32_t profilesFound; 542 uint16_t i, k=0; 543 544 SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE); 545 546 ASSERT_COND(FmIsMaster(p_FmPcd->h_Fm)); 547 if(!numOfProfiles) 548 return E_OK; 549 550 if (numOfProfiles>FM_PCD_PLCR_NUM_ENTRIES) 551 RETURN_ERROR(MINOR, E_INVALID_VALUE, ("numProfiles is too big.")); 552 553 profilesFound = 0; 554 for(i=0;i<FM_PCD_PLCR_NUM_ENTRIES; i++) 555 { 556 if(!p_FmPcd->p_FmPcdPlcr->profiles[i].profilesMng.allocated) 557 { 558 profilesFound++; 559 profilesIds[k] = i; 560 k++; 561 if(profilesFound == numOfProfiles) 562 break; 563 } 564 } 565 if(profilesFound != numOfProfiles) 566 RETURN_ERROR(MAJOR, E_INVALID_STATE,NO_MSG); 567 for(i = 0;i<k;i++) 568 { 569 p_FmPcd->p_FmPcdPlcr->profiles[profilesIds[i]].profilesMng.allocated = TRUE; 570 p_FmPcd->p_FmPcdPlcr->profiles[profilesIds[i]].profilesMng.ownerId = 0; 571 } 572 573 return E_OK; 574 } 575 576 t_Error PlcrFreeProfiles(t_FmPcd *p_FmPcd, uint8_t hardwarePortId, uint16_t numOfProfiles, uint16_t base) 577 { 578 t_FmPcdPlcrRegs *p_Regs = p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs; 579 uint16_t i; 580 581 SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE); 582 SANITY_CHECK_RETURN_ERROR(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_HANDLE); 583 584 ASSERT_COND(FmIsMaster(p_FmPcd->h_Fm)); 585 ASSERT_COND(IN_RANGE(1, hardwarePortId, 63)); 586 WRITE_UINT32(p_Regs->fmpl_pmr[hardwarePortId-1], 0); 587 588 for(i = base; i<base+numOfProfiles;i++) 589 { 590 ASSERT_COND(p_FmPcd->p_FmPcdPlcr->profiles[i].profilesMng.ownerId == hardwarePortId); 591 ASSERT_COND(p_FmPcd->p_FmPcdPlcr->profiles[i].profilesMng.allocated); 592 593 p_FmPcd->p_FmPcdPlcr->profiles[i].profilesMng.allocated = FALSE; 594 p_FmPcd->p_FmPcdPlcr->profiles[i].profilesMng.ownerId = 0; 595 } 596 597 return E_OK; 598 } 599 600 void PlcrFreeSharedProfiles(t_FmPcd *p_FmPcd, uint16_t numOfProfiles, uint16_t *profilesIds) 601 { 602 uint16_t i; 603 604 SANITY_CHECK_RETURN(p_FmPcd, E_INVALID_HANDLE); 605 606 ASSERT_COND(FmIsMaster(p_FmPcd->h_Fm)); 607 for(i=0;i<numOfProfiles; i++) 608 { 609 ASSERT_COND(p_FmPcd->p_FmPcdPlcr->profiles[profilesIds[i]].profilesMng.allocated); 610 p_FmPcd->p_FmPcdPlcr->profiles[profilesIds[i]].profilesMng.allocated = FALSE; 611 } 612 } 613 614 void PlcrEnable(t_FmPcd *p_FmPcd) 615 { 616 t_FmPcdPlcrRegs *p_Regs = p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs; 617 618 WRITE_UINT32(p_Regs->fmpl_gcr, GET_UINT32(p_Regs->fmpl_gcr) | FM_PCD_PLCR_GCR_EN); 619 } 620 621 void PlcrDisable(t_FmPcd *p_FmPcd) 622 { 623 t_FmPcdPlcrRegs *p_Regs = p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs; 624 625 WRITE_UINT32(p_Regs->fmpl_gcr, GET_UINT32(p_Regs->fmpl_gcr) & ~FM_PCD_PLCR_GCR_EN); 626 } 627 628 t_Error FM_PCD_SetPlcrStatistics(t_Handle h_FmPcd, bool enable) 629 { 630 t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; 631 uint32_t tmpReg32; 632 633 SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE); 634 SANITY_CHECK_RETURN_ERROR(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_HANDLE); 635 SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdPlcr, E_INVALID_HANDLE); 636 637 if(!FmIsMaster(p_FmPcd->h_Fm)) 638 RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("FM_PCD_SetPlcrStatistics - guest mode!")); 639 640 tmpReg32 = GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_gcr); 641 if(enable) 642 tmpReg32 |= FM_PCD_PLCR_GCR_STEN; 643 else 644 tmpReg32 &= ~FM_PCD_PLCR_GCR_STEN; 645 646 WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_gcr, tmpReg32); 647 return E_OK; 648 } 649 650 t_Error FM_PCD_ConfigPlcrAutoRefreshMode(t_Handle h_FmPcd, bool enable) 651 { 652 t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; 653 654 SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE); 655 SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdDriverParam, E_INVALID_HANDLE); 656 SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdPlcr, E_INVALID_HANDLE); 657 658 if(!FmIsMaster(p_FmPcd->h_Fm)) 659 RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("FM_PCD_ConfigPlcrAutoRefreshMode - guest mode!")); 660 661 p_FmPcd->p_FmPcdDriverParam->plcrAutoRefresh = enable; 662 663 return E_OK; 664 } 665 666 667 t_Error FmPcdPlcrBuildProfile(t_Handle h_FmPcd, t_FmPcdPlcrProfileParams *p_Profile, t_FmPcdPlcrInterModuleProfileRegs *p_PlcrRegs) 668 { 669 670 t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; 671 t_Error err = E_OK; 672 uint32_t pemode, gnia, ynia, rnia; 673 674 /* Set G, Y, R Nia */ 675 err = SetProfileNia(p_FmPcd, p_Profile->nextEngineOnGreen, &(p_Profile->paramsOnGreen), &gnia); 676 if(err) 677 RETURN_ERROR(MAJOR, err, NO_MSG); 678 err = SetProfileNia(p_FmPcd, p_Profile->nextEngineOnYellow, &(p_Profile->paramsOnYellow), &ynia); 679 if(err) 680 RETURN_ERROR(MAJOR, err, NO_MSG); 681 err = SetProfileNia(p_FmPcd, p_Profile->nextEngineOnRed, &(p_Profile->paramsOnRed), &rnia); 682 if(err) 683 RETURN_ERROR(MAJOR, err, NO_MSG); 684 685 686 /* Mode fmpl_pemode */ 687 pemode = FM_PCD_PLCR_PEMODE_PI; 688 689 switch (p_Profile->algSelection) 690 { 691 case e_FM_PCD_PLCR_PASS_THROUGH: 692 p_PlcrRegs->fmpl_pecir = 0; 693 p_PlcrRegs->fmpl_pecbs = 0; 694 p_PlcrRegs->fmpl_pepepir_eir = 0; 695 p_PlcrRegs->fmpl_pepbs_ebs = 0; 696 p_PlcrRegs->fmpl_pelts = 0; 697 p_PlcrRegs->fmpl_pects = 0; 698 p_PlcrRegs->fmpl_pepts_ets = 0; 699 pemode &= ~FM_PCD_PLCR_PEMODE_ALG_MASK; 700 switch (p_Profile->colorMode) 701 { 702 case e_FM_PCD_PLCR_COLOR_BLIND: 703 pemode |= FM_PCD_PLCR_PEMODE_CBLND; 704 switch (p_Profile->color.dfltColor) 705 { 706 case e_FM_PCD_PLCR_GREEN: 707 pemode &= ~FM_PCD_PLCR_PEMODE_DEFC_MASK; 708 break; 709 case e_FM_PCD_PLCR_YELLOW: 710 pemode |= FM_PCD_PLCR_PEMODE_DEFC_Y; 711 break; 712 case e_FM_PCD_PLCR_RED: 713 pemode |= FM_PCD_PLCR_PEMODE_DEFC_R; 714 break; 715 case e_FM_PCD_PLCR_OVERRIDE: 716 pemode |= FM_PCD_PLCR_PEMODE_DEFC_OVERRIDE; 717 break; 718 default: 719 RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG); 720 } 721 722 break; 723 case e_FM_PCD_PLCR_COLOR_AWARE: 724 pemode &= ~FM_PCD_PLCR_PEMODE_CBLND; 725 break; 726 default: 727 RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG); 728 } 729 break; 730 731 case e_FM_PCD_PLCR_RFC_2698: 732 /* Select algorithm MODE[ALG] = "01" */ 733 pemode |= FM_PCD_PLCR_PEMODE_ALG_RFC2698; 734 if (p_Profile->nonPassthroughAlgParams.comittedInfoRate > p_Profile->nonPassthroughAlgParams.peakOrAccessiveInfoRate) 735 RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("in RFC2698 Peak rate must be equal or larger than comittedInfoRate.")); 736 goto cont_rfc; 737 case e_FM_PCD_PLCR_RFC_4115: 738 /* Select algorithm MODE[ALG] = "10" */ 739 pemode |= FM_PCD_PLCR_PEMODE_ALG_RFC4115; 740 cont_rfc: 741 /* Select Color-Blind / Color-Aware operation (MODE[CBLND]) */ 742 switch (p_Profile->colorMode) 743 { 744 case e_FM_PCD_PLCR_COLOR_BLIND: 745 pemode |= FM_PCD_PLCR_PEMODE_CBLND; 746 break; 747 case e_FM_PCD_PLCR_COLOR_AWARE: 748 pemode &= ~FM_PCD_PLCR_PEMODE_CBLND; 749 /*In color aware more select override color interpretation (MODE[OVCLR]) */ 750 switch (p_Profile->color.override) 751 { 752 case e_FM_PCD_PLCR_GREEN: 753 pemode &= ~FM_PCD_PLCR_PEMODE_OVCLR_MASK; 754 break; 755 case e_FM_PCD_PLCR_YELLOW: 756 pemode |= FM_PCD_PLCR_PEMODE_OVCLR_Y; 757 break; 758 case e_FM_PCD_PLCR_RED: 759 pemode |= FM_PCD_PLCR_PEMODE_OVCLR_R; 760 break; 761 case e_FM_PCD_PLCR_OVERRIDE: 762 pemode |= FM_PCD_PLCR_PEMODE_OVCLR_G_NC; 763 break; 764 default: 765 RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG); 766 } 767 break; 768 default: 769 RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG); 770 } 771 /* Select Measurement Unit Mode to BYTE or PACKET (MODE[PKT]) */ 772 switch (p_Profile->nonPassthroughAlgParams.rateMode) 773 { 774 case e_FM_PCD_PLCR_BYTE_MODE : 775 pemode &= ~FM_PCD_PLCR_PEMODE_PKT; 776 switch (p_Profile->nonPassthroughAlgParams.byteModeParams.frameLengthSelection) 777 { 778 case e_FM_PCD_PLCR_L2_FRM_LEN: 779 pemode |= FM_PCD_PLCR_PEMODE_FLS_L2; 780 break; 781 case e_FM_PCD_PLCR_L3_FRM_LEN: 782 pemode |= FM_PCD_PLCR_PEMODE_FLS_L3; 783 break; 784 case e_FM_PCD_PLCR_L4_FRM_LEN: 785 pemode |= FM_PCD_PLCR_PEMODE_FLS_L4; 786 break; 787 case e_FM_PCD_PLCR_FULL_FRM_LEN: 788 pemode |= FM_PCD_PLCR_PEMODE_FLS_FULL; 789 break; 790 default: 791 RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG); 792 } 793 switch (p_Profile->nonPassthroughAlgParams.byteModeParams.rollBackFrameSelection) 794 { 795 case e_FM_PCD_PLCR_ROLLBACK_L2_FRM_LEN: 796 pemode &= ~FM_PCD_PLCR_PEMODE_RBFLS; 797 break; 798 case e_FM_PCD_PLCR_ROLLBACK_FULL_FRM_LEN: 799 pemode |= FM_PCD_PLCR_PEMODE_RBFLS; 800 break; 801 default: 802 RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG); 803 } 804 break; 805 case e_FM_PCD_PLCR_PACKET_MODE : 806 pemode |= FM_PCD_PLCR_PEMODE_PKT; 807 break; 808 default: 809 RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG); 810 } 811 /* Select timeStamp floating point position (MODE[FPP]) to fit the actual traffic rates. For PACKET 812 mode with low traffic rates move the fixed point to the left to increase fraction accuracy. For BYTE 813 mode with high traffic rates move the fixed point to the right to increase integer accuracy. */ 814 815 /* Configure Traffic Parameters*/ 816 { 817 uint32_t cir=0, cbs=0, pir_eir=0, pbs_ebs=0, fpp=0; 818 819 calcRates(h_FmPcd, &p_Profile->nonPassthroughAlgParams, &cir, &cbs, &pir_eir, &pbs_ebs, &fpp); 820 821 /* Set Committed Information Rate (CIR) */ 822 p_PlcrRegs->fmpl_pecir = cir; 823 /* Set Committed Burst Size (CBS). */ 824 p_PlcrRegs->fmpl_pecbs = cbs; 825 /* Set Peak Information Rate (PIR_EIR used as PIR) */ 826 p_PlcrRegs->fmpl_pepepir_eir = pir_eir; 827 /* Set Peak Burst Size (PBS_EBS used as PBS) */ 828 p_PlcrRegs->fmpl_pepbs_ebs = pbs_ebs; 829 830 /* Initialize the Metering Buckets to be full (write them with 0xFFFFFFFF. */ 831 /* Peak Rate Token Bucket Size (PTS_ETS used as PTS) */ 832 p_PlcrRegs->fmpl_pepts_ets = 0xFFFFFFFF; 833 /* Committed Rate Token Bucket Size (CTS) */ 834 p_PlcrRegs->fmpl_pects = 0xFFFFFFFF; 835 836 /* Set the FPP based on calculation */ 837 pemode |= (fpp << FM_PCD_PLCR_PEMODE_FPP_SHIFT); 838 } 839 break; /* FM_PCD_PLCR_PEMODE_ALG_RFC2698 , FM_PCD_PLCR_PEMODE_ALG_RFC4115 */ 840 default: 841 RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG); 842 } 843 844 p_PlcrRegs->fmpl_pemode = pemode; 845 846 p_PlcrRegs->fmpl_pegnia = gnia; 847 p_PlcrRegs->fmpl_peynia = ynia; 848 p_PlcrRegs->fmpl_pernia = rnia; 849 850 /* Zero Counters */ 851 p_PlcrRegs->fmpl_pegpc = 0; 852 p_PlcrRegs->fmpl_peypc = 0; 853 p_PlcrRegs->fmpl_perpc = 0; 854 p_PlcrRegs->fmpl_perypc = 0; 855 p_PlcrRegs->fmpl_perrpc = 0; 856 857 return E_OK; 858 } 859 860 void FmPcdPlcrValidateProfileSw(t_Handle h_FmPcd, uint16_t absoluteProfileId) 861 { 862 t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; 863 864 ASSERT_COND(!p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId].valid); 865 p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId].valid = TRUE; 866 } 867 868 void FmPcdPlcrInvalidateProfileSw(t_Handle h_FmPcd, uint16_t absoluteProfileId) 869 { 870 t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; 871 872 ASSERT_COND(p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId].valid); 873 p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId].valid = FALSE; 874 } 875 876 t_Handle PlcrConfig(t_FmPcd *p_FmPcd, t_FmPcdParams *p_FmPcdParams) 877 { 878 t_FmPcdPlcr *p_FmPcdPlcr; 879 /*uint8_t i=0;*/ 880 881 UNUSED(p_FmPcd); 882 UNUSED(p_FmPcdParams); 883 884 p_FmPcdPlcr = (t_FmPcdPlcr *) XX_Malloc(sizeof(t_FmPcdPlcr)); 885 if (!p_FmPcdPlcr) 886 { 887 REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM Policer structure allocation FAILED")); 888 return NULL; 889 } 890 memset(p_FmPcdPlcr, 0, sizeof(t_FmPcdPlcr)); 891 if(p_FmPcd->guestId == NCSW_MASTER_ID) 892 { 893 p_FmPcdPlcr->p_FmPcdPlcrRegs = (t_FmPcdPlcrRegs *)UINT_TO_PTR(FmGetPcdPlcrBaseAddr(p_FmPcdParams->h_Fm)); 894 p_FmPcd->p_FmPcdDriverParam->plcrAutoRefresh = DEFAULT_plcrAutoRefresh; 895 p_FmPcd->exceptions |= (DEFAULT_fmPcdPlcrExceptions | DEFAULT_fmPcdPlcrErrorExceptions); 896 } 897 898 p_FmPcdPlcr->numOfSharedProfiles = DEFAULT_numOfSharedPlcrProfiles; 899 900 return p_FmPcdPlcr; 901 } 902 903 t_Error PlcrInit(t_FmPcd *p_FmPcd) 904 { 905 t_FmPcdDriverParam *p_Param = p_FmPcd->p_FmPcdDriverParam; 906 t_FmPcdPlcr *p_FmPcdPlcr = p_FmPcd->p_FmPcdPlcr; 907 uint32_t tmpReg32 = 0; 908 t_Error err = E_OK; 909 t_FmPcdPlcrRegs *p_Regs = p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs; 910 t_FmPcdIpcMsg msg; 911 uint32_t replyLength; 912 t_FmPcdIpcReply reply; 913 914 if ((p_FmPcd->guestId != NCSW_MASTER_ID) && 915 (p_FmPcdPlcr->numOfSharedProfiles)) 916 { 917 int i, j, index = 0; 918 uint32_t walking1Mask = 0x80000000; 919 uint32_t sharedProfilesMask[FM_PCD_PLCR_NUM_ENTRIES/32]; 920 921 memset(sharedProfilesMask, 0, FM_PCD_PLCR_NUM_ENTRIES/32 * sizeof(uint32_t)); 922 memset(&reply, 0, sizeof(reply)); 923 memset(&msg, 0, sizeof(msg)); 924 msg.msgId = FM_PCD_ALLOC_SHARED_PROFILES; 925 memcpy(msg.msgBody, (uint8_t *)&p_FmPcdPlcr->numOfSharedProfiles, sizeof(uint16_t)); 926 replyLength = sizeof(uint32_t) + sizeof(sharedProfilesMask); 927 if ((err = XX_IpcSendMessage(p_FmPcd->h_IpcSession, 928 (uint8_t*)&msg, 929 sizeof(msg.msgId)+ sizeof(p_FmPcdPlcr->numOfSharedProfiles), 930 (uint8_t*)&reply, 931 &replyLength, 932 NULL, 933 NULL)) != E_OK) 934 RETURN_ERROR(MAJOR, err,NO_MSG); 935 if (replyLength != (sizeof(uint32_t) + sizeof(sharedProfilesMask))) 936 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch")); 937 938 memcpy(sharedProfilesMask, reply.replyBody, sizeof(sharedProfilesMask)); 939 /* translate 8 regs of 32 bits masks into an array of up to 256 indexes. */ 940 for(i = 0; i<FM_PCD_PLCR_NUM_ENTRIES/32 ; i++) 941 { 942 if(sharedProfilesMask[i]) 943 { 944 for(j = 0 ; j<32 ; j++) 945 { 946 if(sharedProfilesMask[i] & walking1Mask) 947 p_FmPcd->p_FmPcdPlcr->sharedProfilesIds[index++] = (uint16_t)(i*32+j); 948 walking1Mask >>= 1; 949 } 950 walking1Mask = 0x80000000; 951 } 952 } 953 return (t_Error)reply.error; 954 } 955 956 if(p_FmPcdPlcr->numOfSharedProfiles) 957 { 958 err = PlcrAllocSharedProfiles(p_FmPcd, p_FmPcdPlcr->numOfSharedProfiles, p_FmPcd->p_FmPcdPlcr->sharedProfilesIds); 959 if(err) 960 RETURN_ERROR(MAJOR, err,NO_MSG); 961 } 962 963 /**********************FMPL_GCR******************/ 964 tmpReg32 = 0; 965 tmpReg32 |= FM_PCD_PLCR_GCR_STEN; 966 if(p_Param->plcrAutoRefresh) 967 tmpReg32 |= FM_PCD_PLCR_GCR_DAR; 968 tmpReg32 |= NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME; 969 970 WRITE_UINT32(p_Regs->fmpl_gcr, tmpReg32); 971 /**********************FMPL_GCR******************/ 972 973 /**********************FMPL_EEVR******************/ 974 WRITE_UINT32(p_Regs->fmpl_eevr, (FM_PCD_PLCR_DOUBLE_ECC | FM_PCD_PLCR_INIT_ENTRY_ERROR)); 975 /**********************FMPL_EEVR******************/ 976 /**********************FMPL_EIER******************/ 977 tmpReg32 = 0; 978 if(p_FmPcd->exceptions & FM_PCD_EX_PLCR_DOUBLE_ECC) 979 { 980 FmEnableRamsEcc(p_FmPcd->h_Fm); 981 tmpReg32 |= FM_PCD_PLCR_DOUBLE_ECC; 982 } 983 if(p_FmPcd->exceptions & FM_PCD_EX_PLCR_INIT_ENTRY_ERROR) 984 tmpReg32 |= FM_PCD_PLCR_INIT_ENTRY_ERROR; 985 WRITE_UINT32(p_Regs->fmpl_eier, tmpReg32); 986 /**********************FMPL_EIER******************/ 987 988 /**********************FMPL_EVR******************/ 989 WRITE_UINT32(p_Regs->fmpl_evr, (FM_PCD_PLCR_PRAM_SELF_INIT_COMPLETE | FM_PCD_PLCR_ATOMIC_ACTION_COMPLETE)); 990 /**********************FMPL_EVR******************/ 991 /**********************FMPL_IER******************/ 992 tmpReg32 = 0; 993 if(p_FmPcd->exceptions & FM_PCD_EX_PLCR_PRAM_SELF_INIT_COMPLETE) 994 tmpReg32 |= FM_PCD_PLCR_PRAM_SELF_INIT_COMPLETE; 995 if(p_FmPcd->exceptions & FM_PCD_EX_PLCR_ATOMIC_ACTION_COMPLETE ) 996 tmpReg32 |= FM_PCD_PLCR_ATOMIC_ACTION_COMPLETE; 997 WRITE_UINT32(p_Regs->fmpl_ier, tmpReg32); 998 /**********************FMPL_IER******************/ 999 1000 /* register even if no interrupts enabled, to allow future enablement */ 1001 FmRegisterIntr(p_FmPcd->h_Fm, e_FM_MOD_PLCR, 0, e_FM_INTR_TYPE_ERR, PcdPlcrErrorException, p_FmPcd); 1002 FmRegisterIntr(p_FmPcd->h_Fm, e_FM_MOD_PLCR, 0, e_FM_INTR_TYPE_NORMAL, PcdPlcrException, p_FmPcd); 1003 1004 /* driver initializes one DFLT profile at the last entry*/ 1005 /**********************FMPL_DPMR******************/ 1006 tmpReg32 = 0; 1007 WRITE_UINT32(p_Regs->fmpl_dpmr, tmpReg32); 1008 p_FmPcd->p_FmPcdPlcr->profiles[0].profilesMng.allocated = TRUE; 1009 1010 return E_OK; 1011 } 1012 1013 t_Error PlcrFree(t_FmPcd *p_FmPcd) 1014 { 1015 t_Error err; 1016 t_FmPcdIpcSharedPlcrAllocParams ipcSharedPlcrParams; 1017 t_FmPcdIpcMsg msg; 1018 1019 FmUnregisterIntr(p_FmPcd->h_Fm, e_FM_MOD_PLCR, 0, e_FM_INTR_TYPE_ERR); 1020 FmUnregisterIntr(p_FmPcd->h_Fm, e_FM_MOD_PLCR, 0, e_FM_INTR_TYPE_NORMAL); 1021 1022 if(p_FmPcd->p_FmPcdPlcr->numOfSharedProfiles) 1023 { 1024 if(p_FmPcd->guestId != NCSW_MASTER_ID) 1025 { 1026 int i; 1027 memset(ipcSharedPlcrParams.sharedProfilesMask, 0, sizeof(ipcSharedPlcrParams.sharedProfilesMask)); 1028 /* Free resources using IPC messaging */ 1029 ipcSharedPlcrParams.num = p_FmPcd->p_FmPcdPlcr->numOfSharedProfiles; 1030 1031 /* translate the allocated profile id's to a 32bit * 8regs mask */ 1032 for(i = 0;i<p_FmPcd->p_FmPcdPlcr->numOfSharedProfiles;i++) 1033 ipcSharedPlcrParams.sharedProfilesMask[p_FmPcd->p_FmPcdPlcr->sharedProfilesIds[i]/32] |= (0x80000000 >> (p_FmPcd->p_FmPcdPlcr->sharedProfilesIds[i] % 32)); 1034 1035 memset(&msg, 0, sizeof(msg)); 1036 msg.msgId = FM_PCD_FREE_SHARED_PROFILES; 1037 memcpy(msg.msgBody, &ipcSharedPlcrParams, sizeof(ipcSharedPlcrParams)); 1038 if ((err = XX_IpcSendMessage(p_FmPcd->h_IpcSession, 1039 (uint8_t*)&msg, 1040 sizeof(msg.msgId)+sizeof(ipcSharedPlcrParams), 1041 NULL, 1042 NULL, 1043 NULL, 1044 NULL)) != E_OK) 1045 RETURN_ERROR(MAJOR, err,NO_MSG); 1046 } 1047 /* else 1048 PlcrFreeSharedProfiles(p_FmPcd, p_FmPcd->p_FmPcdPlcr->numOfSharedProfiles, p_FmPcd->p_FmPcdPlcr->sharedProfilesIds);*/ 1049 } 1050 return E_OK; 1051 } 1052 1053 t_Error FmPcdPlcrGetAbsoluteProfileId(t_Handle h_FmPcd, 1054 e_FmPcdProfileTypeSelection profileType, 1055 t_Handle h_FmPort, 1056 uint16_t relativeProfile, 1057 uint16_t *p_AbsoluteId) 1058 { 1059 t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; 1060 t_FmPcdPlcr *p_FmPcdPlcr = p_FmPcd->p_FmPcdPlcr; 1061 uint8_t i; 1062 1063 switch (profileType) 1064 { 1065 case e_FM_PCD_PLCR_PORT_PRIVATE: 1066 /* get port PCD id from port handle */ 1067 for(i=0;i<FM_MAX_NUM_OF_PORTS;i++) 1068 if(p_FmPcd->p_FmPcdPlcr->portsMapping[i].h_FmPort == h_FmPort) 1069 break; 1070 if (i == FM_MAX_NUM_OF_PORTS) 1071 RETURN_ERROR(MAJOR, E_INVALID_STATE , ("Invalid port handle.")); 1072 1073 if(!p_FmPcd->p_FmPcdPlcr->portsMapping[i].numOfProfiles) 1074 RETURN_ERROR(MAJOR, E_INVALID_SELECTION , ("Port has no allocated profiles")); 1075 if(relativeProfile >= p_FmPcd->p_FmPcdPlcr->portsMapping[i].numOfProfiles) 1076 RETURN_ERROR(MAJOR, E_INVALID_SELECTION , ("Profile id is out of range")); 1077 *p_AbsoluteId = (uint16_t)(p_FmPcd->p_FmPcdPlcr->portsMapping[i].profilesBase + relativeProfile); 1078 break; 1079 case e_FM_PCD_PLCR_SHARED: 1080 if(relativeProfile >= p_FmPcdPlcr->numOfSharedProfiles) 1081 RETURN_ERROR(MAJOR, E_INVALID_SELECTION , ("Profile id is out of range")); 1082 *p_AbsoluteId = (uint16_t)(p_FmPcdPlcr->sharedProfilesIds[relativeProfile]); 1083 break; 1084 default: 1085 RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("Invalid policer profile type")); 1086 } 1087 return E_OK; 1088 } 1089 1090 uint16_t FmPcdPlcrGetPortProfilesBase(t_Handle h_FmPcd, uint8_t hardwarePortId) 1091 { 1092 t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd; 1093 uint16_t swPortIndex = 0; 1094 1095 HW_PORT_ID_TO_SW_PORT_INDX(swPortIndex, hardwarePortId); 1096 1097 return p_FmPcd->p_FmPcdPlcr->portsMapping[swPortIndex].profilesBase; 1098 } 1099 1100 uint16_t FmPcdPlcrGetPortNumOfProfiles(t_Handle h_FmPcd, uint8_t hardwarePortId) 1101 { 1102 t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd; 1103 uint16_t swPortIndex = 0; 1104 1105 HW_PORT_ID_TO_SW_PORT_INDX(swPortIndex, hardwarePortId); 1106 1107 return p_FmPcd->p_FmPcdPlcr->portsMapping[swPortIndex].numOfProfiles; 1108 1109 } 1110 uint32_t FmPcdPlcrBuildWritePlcrActionReg(uint16_t absoluteProfileId) 1111 { 1112 return (uint32_t)(FM_PCD_PLCR_PAR_GO | 1113 ((uint32_t)absoluteProfileId << FM_PCD_PLCR_PAR_PNUM_SHIFT)); 1114 } 1115 1116 uint32_t FmPcdPlcrBuildWritePlcrActionRegs(uint16_t absoluteProfileId) 1117 { 1118 return (uint32_t)(FM_PCD_PLCR_PAR_GO | 1119 ((uint32_t)absoluteProfileId << FM_PCD_PLCR_PAR_PNUM_SHIFT) | 1120 FM_PCD_PLCR_PAR_PWSEL_MASK); 1121 } 1122 1123 bool FmPcdPlcrHwProfileIsValid(uint32_t profileModeReg) 1124 { 1125 1126 if(profileModeReg & FM_PCD_PLCR_PEMODE_PI) 1127 return TRUE; 1128 else 1129 return FALSE; 1130 } 1131 1132 uint32_t FmPcdPlcrBuildReadPlcrActionReg(uint16_t absoluteProfileId) 1133 { 1134 return (uint32_t)(FM_PCD_PLCR_PAR_GO | 1135 FM_PCD_PLCR_PAR_R | 1136 ((uint32_t)absoluteProfileId << FM_PCD_PLCR_PAR_PNUM_SHIFT) | 1137 FM_PCD_PLCR_PAR_PWSEL_MASK); 1138 } 1139 1140 uint32_t FmPcdPlcrBuildCounterProfileReg(e_FmPcdPlcrProfileCounters counter) 1141 { 1142 switch(counter) 1143 { 1144 case(e_FM_PCD_PLCR_PROFILE_GREEN_PACKET_TOTAL_COUNTER): 1145 return FM_PCD_PLCR_PAR_PWSEL_PEGPC; 1146 case(e_FM_PCD_PLCR_PROFILE_YELLOW_PACKET_TOTAL_COUNTER): 1147 return FM_PCD_PLCR_PAR_PWSEL_PEYPC; 1148 case(e_FM_PCD_PLCR_PROFILE_RED_PACKET_TOTAL_COUNTER) : 1149 return FM_PCD_PLCR_PAR_PWSEL_PERPC; 1150 case(e_FM_PCD_PLCR_PROFILE_RECOLOURED_YELLOW_PACKET_TOTAL_COUNTER) : 1151 return FM_PCD_PLCR_PAR_PWSEL_PERYPC; 1152 case(e_FM_PCD_PLCR_PROFILE_RECOLOURED_RED_PACKET_TOTAL_COUNTER) : 1153 return FM_PCD_PLCR_PAR_PWSEL_PERRPC; 1154 default: 1155 REPORT_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG); 1156 return 0; 1157 } 1158 } 1159 1160 uint32_t FmPcdPlcrBuildNiaProfileReg(bool green, bool yellow, bool red) 1161 { 1162 1163 uint32_t tmpReg32 = 0; 1164 1165 if(green) 1166 tmpReg32 |= FM_PCD_PLCR_PAR_PWSEL_PEGNIA; 1167 if(yellow) 1168 tmpReg32 |= FM_PCD_PLCR_PAR_PWSEL_PEYNIA; 1169 if(red) 1170 tmpReg32 |= FM_PCD_PLCR_PAR_PWSEL_PERNIA; 1171 1172 return tmpReg32; 1173 } 1174 1175 void FmPcdPlcrUpdateRequiredAction(t_Handle h_FmPcd, uint16_t absoluteProfileId, uint32_t requiredAction) 1176 { 1177 t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; 1178 1179 ASSERT_COND(p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId].valid); 1180 1181 p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId].requiredAction = requiredAction; 1182 } 1183 1184 t_Error FmPcdPlcrProfileTryLock(t_Handle h_FmPcd, uint16_t profileId, bool intr) 1185 { 1186 t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd; 1187 bool ans; 1188 if (intr) 1189 ans = TRY_LOCK(NULL, &p_FmPcd->p_FmPcdPlcr->profiles[profileId].lock); 1190 else 1191 ans = TRY_LOCK(p_FmPcd->h_Spinlock, &p_FmPcd->p_FmPcdPlcr->profiles[profileId].lock); 1192 if (ans) 1193 return E_OK; 1194 return ERROR_CODE(E_BUSY); 1195 } 1196 1197 void FmPcdPlcrReleaseProfileLock(t_Handle h_FmPcd, uint16_t profileId) 1198 { 1199 RELEASE_LOCK(((t_FmPcd*)h_FmPcd)->p_FmPcdPlcr->profiles[profileId].lock); 1200 } 1201 1202 /**************************************************/ 1203 /*............Policer API.........................*/ 1204 /**************************************************/ 1205 1206 t_Handle FM_PCD_PlcrSetProfile(t_Handle h_FmPcd, 1207 t_FmPcdPlcrProfileParams *p_Profile) 1208 { 1209 t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; 1210 t_FmPcdPlcrRegs *p_FmPcdPlcrRegs; 1211 t_FmPcdPlcrInterModuleProfileRegs plcrProfileReg; 1212 uint32_t intFlags; 1213 uint16_t absoluteProfileId; 1214 t_Error err = E_OK; 1215 uint32_t tmpReg32; 1216 1217 SANITY_CHECK_RETURN_VALUE(p_FmPcd, E_INVALID_HANDLE, NULL); 1218 SANITY_CHECK_RETURN_VALUE(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_STATE, NULL); 1219 SANITY_CHECK_RETURN_VALUE(p_FmPcd->p_FmPcdPlcr, E_INVALID_HANDLE, NULL); 1220 1221 if (p_FmPcd->h_Hc) 1222 return FmHcPcdPlcrSetProfile(p_FmPcd->h_Hc, p_Profile); 1223 1224 p_FmPcdPlcrRegs = p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs; 1225 SANITY_CHECK_RETURN_VALUE(p_FmPcdPlcrRegs, E_INVALID_HANDLE, NULL); 1226 1227 if (p_Profile->modify) 1228 { 1229 absoluteProfileId = (uint16_t)(PTR_TO_UINT(p_Profile->id.h_Profile)-1); 1230 if (absoluteProfileId >= FM_PCD_PLCR_NUM_ENTRIES) 1231 { 1232 REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("profileId too Big ")); 1233 return NULL; 1234 } 1235 if (FmPcdPlcrProfileTryLock(p_FmPcd, absoluteProfileId, FALSE)) 1236 return NULL; 1237 } 1238 else 1239 { 1240 intFlags = FmPcdLock(p_FmPcd); 1241 err = FmPcdPlcrGetAbsoluteProfileId(h_FmPcd, 1242 p_Profile->id.newParams.profileType, 1243 p_Profile->id.newParams.h_FmPort, 1244 p_Profile->id.newParams.relativeProfileId, 1245 &absoluteProfileId); 1246 if (absoluteProfileId >= FM_PCD_PLCR_NUM_ENTRIES) 1247 { 1248 REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("profileId too Big ")); 1249 return NULL; 1250 } 1251 if(err) 1252 { 1253 FmPcdUnlock(p_FmPcd, intFlags); 1254 REPORT_ERROR(MAJOR, err, NO_MSG); 1255 return NULL; 1256 } 1257 err = FmPcdPlcrProfileTryLock(p_FmPcd, absoluteProfileId, TRUE); 1258 FmPcdUnlock(p_FmPcd, intFlags); 1259 if (err) 1260 return NULL; 1261 } 1262 1263 /* if no override, check first that this profile is unused */ 1264 if(!p_Profile->modify) 1265 { 1266 /* read specified profile into profile registers */ 1267 tmpReg32 = FmPcdPlcrBuildReadPlcrActionReg(absoluteProfileId); 1268 intFlags = FmPcdLock(p_FmPcd); 1269 WritePar(p_FmPcd, tmpReg32); 1270 tmpReg32 = GET_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_pemode); 1271 FmPcdUnlock(p_FmPcd, intFlags); 1272 if (tmpReg32 & FM_PCD_PLCR_PEMODE_PI) 1273 { 1274 RELEASE_LOCK(p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId].lock); 1275 REPORT_ERROR(MAJOR, E_ALREADY_EXISTS, ("Policer Profile is already used")); 1276 return NULL; 1277 } 1278 } 1279 1280 memset(&plcrProfileReg, 0, sizeof(t_FmPcdPlcrInterModuleProfileRegs)); 1281 1282 err = FmPcdPlcrBuildProfile(h_FmPcd, p_Profile, &plcrProfileReg); 1283 if(err) 1284 { 1285 RELEASE_LOCK(p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId].lock); 1286 REPORT_ERROR(MAJOR, err, NO_MSG); 1287 return NULL; 1288 } 1289 1290 p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId].nextEngineOnGreen = p_Profile->nextEngineOnGreen; 1291 memcpy(&p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId].paramsOnGreen, &(p_Profile->paramsOnGreen), sizeof(u_FmPcdPlcrNextEngineParams)); 1292 1293 p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId].nextEngineOnYellow = p_Profile->nextEngineOnYellow; 1294 memcpy(&p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId].paramsOnYellow, &(p_Profile->paramsOnYellow), sizeof(u_FmPcdPlcrNextEngineParams)); 1295 1296 p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId].nextEngineOnRed = p_Profile->nextEngineOnRed; 1297 memcpy(&p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId].paramsOnRed, &(p_Profile->paramsOnRed), sizeof(u_FmPcdPlcrNextEngineParams)); 1298 1299 intFlags = FmPcdLock(p_FmPcd); 1300 WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_pemode , plcrProfileReg.fmpl_pemode); 1301 WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_pegnia , plcrProfileReg.fmpl_pegnia); 1302 WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_peynia , plcrProfileReg.fmpl_peynia); 1303 WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_pernia , plcrProfileReg.fmpl_pernia); 1304 WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_pecir , plcrProfileReg.fmpl_pecir); 1305 WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_pecbs , plcrProfileReg.fmpl_pecbs); 1306 WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_pepepir_eir,plcrProfileReg.fmpl_pepepir_eir); 1307 WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_pepbs_ebs,plcrProfileReg.fmpl_pepbs_ebs); 1308 WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_pelts , plcrProfileReg.fmpl_pelts); 1309 WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_pects , plcrProfileReg.fmpl_pects); 1310 WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_pepts_ets,plcrProfileReg.fmpl_pepts_ets); 1311 WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_pegpc , plcrProfileReg.fmpl_pegpc); 1312 WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_peypc , plcrProfileReg.fmpl_peypc); 1313 WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_perpc , plcrProfileReg.fmpl_perpc); 1314 WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_perypc , plcrProfileReg.fmpl_perypc); 1315 WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_perrpc , plcrProfileReg.fmpl_perrpc); 1316 1317 tmpReg32 = FmPcdPlcrBuildWritePlcrActionRegs(absoluteProfileId); 1318 WritePar(p_FmPcd, tmpReg32); 1319 1320 FmPcdUnlock(p_FmPcd, intFlags); 1321 1322 if (!p_Profile->modify) 1323 FmPcdPlcrValidateProfileSw(p_FmPcd,absoluteProfileId); 1324 1325 RELEASE_LOCK(p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId].lock); 1326 1327 return UINT_TO_PTR((uint64_t)absoluteProfileId+1); 1328 } 1329 1330 t_Error FM_PCD_PlcrDeleteProfile(t_Handle h_FmPcd, t_Handle h_Profile) 1331 { 1332 t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; 1333 uint16_t profileIndx = (uint16_t)(PTR_TO_UINT(h_Profile)-1); 1334 uint32_t tmpReg32, intFlags; 1335 1336 SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE); 1337 SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdPlcr, E_INVALID_HANDLE); 1338 SANITY_CHECK_RETURN_ERROR((profileIndx < FM_PCD_PLCR_NUM_ENTRIES), E_INVALID_SELECTION); 1339 1340 if (p_FmPcd->h_Hc) 1341 return FmHcPcdPlcrDeleteProfile(p_FmPcd->h_Hc, h_Profile); 1342 1343 FmPcdPlcrInvalidateProfileSw(p_FmPcd,profileIndx); 1344 1345 intFlags = FmPcdLock(p_FmPcd); 1346 WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->profileRegs.fmpl_pemode, ~FM_PCD_PLCR_PEMODE_PI); 1347 1348 tmpReg32 = FmPcdPlcrBuildWritePlcrActionRegs(profileIndx); 1349 WritePar(p_FmPcd, tmpReg32); 1350 FmPcdUnlock(p_FmPcd, intFlags); 1351 1352 return E_OK; 1353 } 1354 1355 /* ......... */ 1356 /***************************************************/ 1357 /*............Policer Profile Counter..............*/ 1358 /***************************************************/ 1359 uint32_t FM_PCD_PlcrGetProfileCounter(t_Handle h_FmPcd, t_Handle h_Profile, e_FmPcdPlcrProfileCounters counter) 1360 { 1361 t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; 1362 uint16_t profileIndx = (uint16_t)(PTR_TO_UINT(h_Profile)-1); 1363 t_FmPcdPlcrRegs *p_FmPcdPlcrRegs; 1364 uint32_t intFlags, counterVal = 0; 1365 1366 SANITY_CHECK_RETURN_VALUE(p_FmPcd, E_INVALID_HANDLE, 0); 1367 SANITY_CHECK_RETURN_VALUE(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_STATE, 0); 1368 SANITY_CHECK_RETURN_VALUE(p_FmPcd->p_FmPcdPlcr, E_INVALID_HANDLE, 0); 1369 1370 if (p_FmPcd->h_Hc) 1371 return FmHcPcdPlcrGetProfileCounter(p_FmPcd->h_Hc, h_Profile, counter); 1372 1373 p_FmPcdPlcrRegs = p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs; 1374 SANITY_CHECK_RETURN_VALUE(p_FmPcdPlcrRegs, E_INVALID_HANDLE, 0); 1375 1376 if (profileIndx >= FM_PCD_PLCR_NUM_ENTRIES) 1377 { 1378 REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("profileId too Big ")); 1379 return 0; 1380 } 1381 intFlags = FmPcdLock(p_FmPcd); 1382 WritePar(p_FmPcd, FmPcdPlcrBuildReadPlcrActionReg(profileIndx)); 1383 1384 if(!FmPcdPlcrHwProfileIsValid(GET_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_pemode))) 1385 { 1386 REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("Uninitialized profile")); 1387 FmPcdUnlock(p_FmPcd, intFlags); 1388 return 0; 1389 } 1390 1391 switch (counter) 1392 { 1393 case e_FM_PCD_PLCR_PROFILE_GREEN_PACKET_TOTAL_COUNTER: 1394 counterVal = (GET_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_pegpc)); 1395 break; 1396 case e_FM_PCD_PLCR_PROFILE_YELLOW_PACKET_TOTAL_COUNTER: 1397 counterVal = GET_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_peypc); 1398 break; 1399 case e_FM_PCD_PLCR_PROFILE_RED_PACKET_TOTAL_COUNTER: 1400 counterVal = GET_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_perpc); 1401 break; 1402 case e_FM_PCD_PLCR_PROFILE_RECOLOURED_YELLOW_PACKET_TOTAL_COUNTER: 1403 counterVal = GET_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_perypc); 1404 break; 1405 case e_FM_PCD_PLCR_PROFILE_RECOLOURED_RED_PACKET_TOTAL_COUNTER: 1406 counterVal = GET_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_perrpc); 1407 break; 1408 default: 1409 REPORT_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG); 1410 break; 1411 } 1412 FmPcdUnlock(p_FmPcd, intFlags); 1413 1414 return counterVal; 1415 } 1416 1417 1418 t_Error FmPcdPlcrCcGetSetParams(t_Handle h_FmPcd, uint16_t profileIndx ,uint32_t requiredAction) 1419 { 1420 t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd; 1421 t_FmPcdPlcr *p_FmPcdPlcr = p_FmPcd->p_FmPcdPlcr; 1422 t_FmPcdPlcrRegs *p_FmPcdPlcrRegs = p_FmPcdPlcr->p_FmPcdPlcrRegs; 1423 uint32_t tmpReg32, intFlags; 1424 1425 if (p_FmPcd->h_Hc) 1426 return FmHcPcdPlcrCcGetSetParams(p_FmPcd->h_Hc, profileIndx, requiredAction); 1427 1428 if (profileIndx >= FM_PCD_PLCR_NUM_ENTRIES) 1429 RETURN_ERROR(MAJOR, E_INVALID_VALUE,("Policer profile out of range")); 1430 1431 if (FmPcdPlcrProfileTryLock(p_FmPcd, profileIndx, FALSE)) 1432 RETURN_ERROR(MAJOR, E_INVALID_STATE,("Lock on PP FAILED")); 1433 1434 intFlags = FmPcdLock(p_FmPcd); 1435 WritePar(p_FmPcd, FmPcdPlcrBuildReadPlcrActionReg(profileIndx)); 1436 1437 if(!FmPcdPlcrHwProfileIsValid(GET_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_pemode))) 1438 { 1439 FmPcdUnlock(p_FmPcd, intFlags); 1440 RELEASE_LOCK(p_FmPcd->p_FmPcdPlcr->profiles[profileIndx].lock); 1441 RETURN_ERROR(MAJOR, E_INVALID_VALUE,("Policer profile is not valid")); 1442 } 1443 1444 ASSERT_COND(p_FmPcd->p_FmPcdPlcr->profiles[profileIndx].valid); 1445 1446 if(!p_FmPcd->p_FmPcdPlcr->profiles[profileIndx].pointedOwners || 1447 !(p_FmPcd->p_FmPcdPlcr->profiles[profileIndx].requiredAction & requiredAction)) 1448 { 1449 if(requiredAction & UPDATE_NIA_ENQ_WITHOUT_DMA) 1450 { 1451 if((p_FmPcd->p_FmPcdPlcr->profiles[profileIndx].nextEngineOnGreen!= e_FM_PCD_DONE) || 1452 (p_FmPcd->p_FmPcdPlcr->profiles[profileIndx].nextEngineOnYellow!= e_FM_PCD_DONE) || 1453 (p_FmPcd->p_FmPcdPlcr->profiles[profileIndx].nextEngineOnRed!= e_FM_PCD_DONE)) 1454 { 1455 FmPcdUnlock(p_FmPcd, intFlags); 1456 RETURN_ERROR (MAJOR, E_OK, ("In this case the next engine can be e_FM_PCD_DONE")); 1457 } 1458 1459 if(p_FmPcd->p_FmPcdPlcr->profiles[profileIndx].paramsOnGreen.action == e_FM_PCD_ENQ_FRAME) 1460 { 1461 tmpReg32 = GET_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_pegnia); 1462 if(!(tmpReg32 & (NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME))) 1463 { 1464 FmPcdUnlock(p_FmPcd, intFlags); 1465 RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Next engine of this policer profile has to be assigned to FM_PCD_DONE")); 1466 } 1467 tmpReg32 |= NIA_BMI_AC_ENQ_FRAME_WITHOUT_DMA; 1468 WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_pegnia, tmpReg32); 1469 tmpReg32 = FmPcdPlcrBuildWritePlcrActionReg(profileIndx); 1470 tmpReg32 |= FM_PCD_PLCR_PAR_PWSEL_PEGNIA; 1471 WritePar(p_FmPcd, tmpReg32); 1472 } 1473 1474 if(p_FmPcd->p_FmPcdPlcr->profiles[profileIndx].paramsOnYellow.action == e_FM_PCD_ENQ_FRAME) 1475 { 1476 tmpReg32 = GET_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_peynia); 1477 if(!(tmpReg32 & (NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME))) 1478 { 1479 FmPcdUnlock(p_FmPcd, intFlags); 1480 RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Next engine of this policer profile has to be assigned to FM_PCD_DONE")); 1481 } 1482 tmpReg32 |= NIA_BMI_AC_ENQ_FRAME_WITHOUT_DMA; 1483 WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_peynia, tmpReg32); 1484 tmpReg32 = FmPcdPlcrBuildWritePlcrActionReg(profileIndx); 1485 tmpReg32 |= FM_PCD_PLCR_PAR_PWSEL_PEYNIA; 1486 WritePar(p_FmPcd, tmpReg32); 1487 } 1488 1489 if(p_FmPcd->p_FmPcdPlcr->profiles[profileIndx].paramsOnRed.action == e_FM_PCD_ENQ_FRAME) 1490 { 1491 tmpReg32 = GET_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_pernia); 1492 if(!(tmpReg32 & (NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME))) 1493 { 1494 FmPcdUnlock(p_FmPcd, intFlags); 1495 RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Next engine of this policer profile has to be assigned to FM_PCD_DONE")); 1496 } 1497 tmpReg32 |= NIA_BMI_AC_ENQ_FRAME_WITHOUT_DMA; 1498 WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_pernia, tmpReg32); 1499 tmpReg32 = FmPcdPlcrBuildWritePlcrActionReg(profileIndx); 1500 tmpReg32 |= FM_PCD_PLCR_PAR_PWSEL_PERNIA; 1501 WritePar(p_FmPcd, tmpReg32); 1502 } 1503 } 1504 } 1505 FmPcdUnlock(p_FmPcd, intFlags); 1506 1507 p_FmPcd->p_FmPcdPlcr->profiles[profileIndx].pointedOwners += 1; 1508 p_FmPcd->p_FmPcdPlcr->profiles[profileIndx].requiredAction |= requiredAction; 1509 1510 RELEASE_LOCK(p_FmPcd->p_FmPcdPlcr->profiles[profileIndx].lock); 1511 1512 return E_OK; 1513 } 1514 1515 t_Error FM_PCD_PlcrSetProfileCounter(t_Handle h_FmPcd, t_Handle h_Profile, e_FmPcdPlcrProfileCounters counter, uint32_t value) 1516 { 1517 t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; 1518 uint16_t profileIndx = (uint16_t)(PTR_TO_UINT(h_Profile)-1); 1519 t_FmPcdPlcrRegs *p_FmPcdPlcrRegs; 1520 uint32_t tmpReg32, intFlags; 1521 1522 SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE); 1523 SANITY_CHECK_RETURN_ERROR(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_STATE); 1524 SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdPlcr, E_INVALID_HANDLE); 1525 1526 if (p_FmPcd->h_Hc) 1527 return FmHcPcdPlcrSetProfileCounter(p_FmPcd->h_Hc, h_Profile, counter, value); 1528 1529 p_FmPcdPlcrRegs = p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs; 1530 SANITY_CHECK_RETURN_ERROR(p_FmPcdPlcrRegs, E_INVALID_HANDLE); 1531 1532 intFlags = FmPcdLock(p_FmPcd); 1533 switch (counter) 1534 { 1535 case e_FM_PCD_PLCR_PROFILE_GREEN_PACKET_TOTAL_COUNTER: 1536 WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_pegpc, value); 1537 break; 1538 case e_FM_PCD_PLCR_PROFILE_YELLOW_PACKET_TOTAL_COUNTER: 1539 WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_peypc, value); 1540 break; 1541 case e_FM_PCD_PLCR_PROFILE_RED_PACKET_TOTAL_COUNTER: 1542 WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_perpc, value); 1543 break; 1544 case e_FM_PCD_PLCR_PROFILE_RECOLOURED_YELLOW_PACKET_TOTAL_COUNTER: 1545 WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_perypc ,value); 1546 break; 1547 case e_FM_PCD_PLCR_PROFILE_RECOLOURED_RED_PACKET_TOTAL_COUNTER: 1548 WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_perrpc ,value); 1549 break; 1550 default: 1551 RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG); 1552 } 1553 1554 /* Activate the atomic write action by writing FMPL_PAR with: GO=1, RW=1, PSI=0, PNUM = 1555 * Profile Number, PWSEL=0xFFFF (select all words). 1556 */ 1557 tmpReg32 = FmPcdPlcrBuildWritePlcrActionReg(profileIndx); 1558 tmpReg32 |= FmPcdPlcrBuildCounterProfileReg(counter); 1559 WritePar(p_FmPcd, tmpReg32); 1560 FmPcdUnlock(p_FmPcd, intFlags); 1561 1562 return E_OK; 1563 } 1564 1565 t_Error FM_PCD_ConfigPlcrNumOfSharedProfiles(t_Handle h_FmPcd, uint16_t numOfSharedPlcrProfiles) 1566 { 1567 t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; 1568 1569 SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE); 1570 SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdDriverParam, E_INVALID_HANDLE); 1571 SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdPlcr, E_INVALID_HANDLE); 1572 1573 p_FmPcd->p_FmPcdPlcr->numOfSharedProfiles = numOfSharedPlcrProfiles; 1574 1575 return E_OK; 1576 } 1577 1578 1579 /* ... */ 1580 1581 #if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0)) 1582 t_Error FM_PCD_PlcrDumpRegs(t_Handle h_FmPcd) 1583 { 1584 t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; 1585 int i = 0; 1586 t_FmPcdIpcMsg msg; 1587 1588 DECLARE_DUMP; 1589 1590 SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE); 1591 SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdPlcr, E_INVALID_HANDLE); 1592 SANITY_CHECK_RETURN_ERROR(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_STATE); 1593 1594 if(p_FmPcd->guestId != NCSW_MASTER_ID) 1595 { 1596 memset(&msg, 0, sizeof(msg)); 1597 msg.msgId = FM_PCD_PLCR_DUMP_REGS; 1598 return XX_IpcSendMessage(p_FmPcd->h_IpcSession, 1599 (uint8_t*)&msg, 1600 sizeof(msg.msgId), 1601 NULL, 1602 NULL, 1603 NULL, 1604 NULL); 1605 } 1606 else 1607 { 1608 DUMP_SUBTITLE(("\n")); 1609 DUMP_TITLE(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs, ("FmPcdPlcrRegs Regs")); 1610 1611 DUMP_VAR(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs,fmpl_gcr); 1612 DUMP_VAR(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs,fmpl_gsr); 1613 DUMP_VAR(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs,fmpl_evr); 1614 DUMP_VAR(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs,fmpl_ier); 1615 DUMP_VAR(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs,fmpl_ifr); 1616 DUMP_VAR(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs,fmpl_eevr); 1617 DUMP_VAR(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs,fmpl_eier); 1618 DUMP_VAR(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs,fmpl_eifr); 1619 DUMP_VAR(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs,fmpl_rpcnt); 1620 DUMP_VAR(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs,fmpl_ypcnt); 1621 DUMP_VAR(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs,fmpl_rrpcnt); 1622 DUMP_VAR(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs,fmpl_rypcnt); 1623 DUMP_VAR(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs,fmpl_tpcnt); 1624 DUMP_VAR(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs,fmpl_flmcnt); 1625 1626 DUMP_VAR(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs,fmpl_serc); 1627 DUMP_VAR(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs,fmpl_upcr); 1628 DUMP_VAR(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs,fmpl_dpmr); 1629 1630 1631 DUMP_TITLE(&p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_pmr, ("fmpl_pmr")); 1632 DUMP_SUBSTRUCT_ARRAY(i, 63) 1633 { 1634 DUMP_MEMORY(&p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_pmr[i], sizeof(uint32_t)); 1635 } 1636 1637 return E_OK; 1638 } 1639 } 1640 1641 t_Error FM_PCD_PlcrProfileDumpRegs(t_Handle h_FmPcd, t_Handle h_Profile) 1642 { 1643 t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; 1644 t_FmPcdPlcrInterModuleProfileRegs *p_ProfilesRegs; 1645 uint32_t tmpReg, intFlags; 1646 uint16_t profileIndx = (uint16_t)(PTR_TO_UINT(h_Profile)-1); 1647 t_FmPcdIpcMsg msg; 1648 1649 DECLARE_DUMP; 1650 1651 SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE); 1652 SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdPlcr, E_INVALID_HANDLE); 1653 SANITY_CHECK_RETURN_ERROR(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_STATE); 1654 1655 if(p_FmPcd->guestId != NCSW_MASTER_ID) 1656 { 1657 memset(&msg, 0, sizeof(msg)); 1658 msg.msgId = FM_PCD_PLCR_PROFILE_DUMP_REGS; 1659 memcpy(msg.msgBody, (uint8_t *)&h_Profile, sizeof(uint32_t)); 1660 return XX_IpcSendMessage(p_FmPcd->h_IpcSession, 1661 (uint8_t*)&msg, 1662 sizeof(msg.msgId) + sizeof(uint32_t), 1663 NULL, 1664 NULL, 1665 NULL, 1666 NULL); 1667 } 1668 else 1669 { 1670 DUMP_SUBTITLE(("\n")); 1671 DUMP_TITLE(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs, ("FmPcdPlcrRegs Profile Regs")); 1672 1673 p_ProfilesRegs = &p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->profileRegs; 1674 1675 tmpReg = FmPcdPlcrBuildReadPlcrActionReg((uint16_t)profileIndx); 1676 intFlags = FmPcdLock(p_FmPcd); 1677 WritePar(p_FmPcd, tmpReg); 1678 1679 DUMP_TITLE(p_ProfilesRegs, ("Profile %d regs", profileIndx)); 1680 1681 DUMP_VAR(p_ProfilesRegs, fmpl_pemode); 1682 DUMP_VAR(p_ProfilesRegs, fmpl_pegnia); 1683 DUMP_VAR(p_ProfilesRegs, fmpl_peynia); 1684 DUMP_VAR(p_ProfilesRegs, fmpl_pernia); 1685 DUMP_VAR(p_ProfilesRegs, fmpl_pecir); 1686 DUMP_VAR(p_ProfilesRegs, fmpl_pecbs); 1687 DUMP_VAR(p_ProfilesRegs, fmpl_pepepir_eir); 1688 DUMP_VAR(p_ProfilesRegs, fmpl_pepbs_ebs); 1689 DUMP_VAR(p_ProfilesRegs, fmpl_pelts); 1690 DUMP_VAR(p_ProfilesRegs, fmpl_pects); 1691 DUMP_VAR(p_ProfilesRegs, fmpl_pepts_ets); 1692 DUMP_VAR(p_ProfilesRegs, fmpl_pegpc); 1693 DUMP_VAR(p_ProfilesRegs, fmpl_peypc); 1694 DUMP_VAR(p_ProfilesRegs, fmpl_perpc); 1695 DUMP_VAR(p_ProfilesRegs, fmpl_perypc); 1696 DUMP_VAR(p_ProfilesRegs, fmpl_perrpc); 1697 FmPcdUnlock(p_FmPcd, intFlags); 1698 1699 return E_OK; 1700 } 1701 } 1702 #endif /* (defined(DEBUG_ERRORS) && ... */ 1703