The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/contrib/ncsw/Peripherals/FM/Pcd/fm_plcr.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

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

Cache object: 016c7617e72599b576a6e00266df4bd2


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.