openbcm

Git mirror of https://github.com/Broadcom-Network-Switching-Software/OpenBCM
git clone git://git.finwo.net/mirror/broadcom/openbcm
Log | Files | Refs | README

field.h (56235B)


      1 /**
      2  *  \file bcm_int/dnx/field/field.h
      3  * 
      4  *  Internal DNX RX APIs
      5 PIs This license is set out in https://raw.githubusercontent.com/Broadcom-Network-Switching-Software/OpenBCM/master/Legal/LICENSE file.
      6 PIs 
      7 PIs Copyright 2007-2020 Broadcom Inc. All rights reserved.
      8  */
      9 
     10 #ifndef DNX_FIELD_H_INCLUDED
     11 /* { */
     12 #define DNX_FIELD_H_INCLUDED
     13 
     14 #ifndef BCM_DNX_SUPPORT
     15 #error "This file is for use by DNX (JR2) family only!"
     16 #endif
     17 
     18 /*
     19  * { Include files
     20  */
     21 
     22 #include <include/bcm/field.h>
     23 #include <soc/dnx/dbal/dbal.h>
     24 #include <bcm/types.h>
     25 #include <soc/dnx/dnx_data/auto_generated/dnx_data_device.h>
     26 #include <soc/dnx/dnx_data/auto_generated/dnx_data_field.h>
     27 #include <include/soc/dnx/swstate/auto_generated/types/dnx_field_types.h>
     28 #include <shared/bsl.h>
     29 
     30 /*
     31  * } Include files
     32  */
     33 
     34 /*
     35  * { Macros
     36  */
     37 /**
     38  * If DBX_FIELD_BRUTE_FORCE_DEINIT_INIT is non-zero then, in order to release
     39  * all resources, allocated for 'field' tests', the whole field sw state and related
     40  * resources (sorted list, hash table, occupation bitmap, legacy sw state) are
     41  * released. On final version, all code under this define should disappear and
     42  * be replaced by directed release (such as 'filed_group_destroy'.
     43  */
     44 #define DBX_FIELD_BRUTE_FORCE_DEINIT_INIT  1
     45 
     46 /** Set bit in unsigned int*/
     47 #define DNX_FIELD_UINT_SET_BIT(val,bit)  ((val) |= 1u<<(bit))
     48 
     49 /** Check if bit is set in unsigned int*/
     50 #define DNX_FIELD_UINT_IS_BIT_SET(val,bit)  (((val)&(1u<<(bit)))? TRUE : FALSE)
     51 
     52 /** Set bit in array of uint32*/
     53 #define DNX_FIELD_ARR32_SET_BIT(val,bit)  (((val)[(bit)/32]) |= 1u<<((bit)%32))
     54 
     55 /** Check if bit is Set in array of uint32*/
     56 #define DNX_FIELD_ARR32_IS_BIT_SET(val,bit)  (( ((val)[(bit)/32]) & (1u<<((bit)%32)))? TRUE : FALSE)
     57 
     58 /** Find number of elements in an static array*/
     59 #define DNX_FIELD_NOF_ELEMENTS_ARRAY(arr)  (sizeof(arr)/sizeof(arr[0]))
     60 
     61 /** Print to user, if printing is enabled.*/
     62 #if defined(BROADCOM_DEBUG)
     63 #define DNX_FIELD_PRINT(stuff) (bsl_printf stuff)
     64 #else
     65 #define DNX_FIELD_PRINT(stuff)
     66 #endif
     67 
     68 #ifndef MIN
     69 #define MIN(a, b) (((a)<(b)) ? (a) : (b))
     70 #endif
     71 
     72 #ifndef MAX
     73 #define MAX(a, b) (((a)>(b)) ? (a) : (b))
     74 #endif
     75 
     76 /*
     77  * Enums
     78  * {
     79  */
     80 /*
     81  * Enum for the source of the state table as read from the SOC property pmf_state_table_rmw_source.
     82  */
     83 typedef enum dnx_field_state_table_source_e
     84 {
     85     DNX_FIELD_STATE_TABLE_SOURCE_INVALID = 0,
     86     DNX_FIELD_STATE_TABLE_SOURCE_IPMF1_KEY_J = 1,       /* MSB of initial key J in iPMF1 */
     87     DNX_FIELD_STATE_TABLE_SOURCE_IPMF1_KEY_F = 2,       /* LSB of initial key F in iPMF1 */
     88     DNX_FIELD_STATE_TABLE_SOURCE_IPMF2_KEY_J = 3,       /* MSB of key J in iPMF2 */
     89     DNX_FIELD_STATE_TABLE_SOURCE_COUNT = 4
     90 } dnx_field_state_table_source_t;
     91 
     92 /**
     93  * This enum contains compare modes (pairs) values for the first and second compare keys
     94  */
     95 typedef enum
     96 {
     97     DNX_FIELD_CONTEXT_COMPARE_MODE_PAIR_1 = 0,
     98     DNX_FIELD_CONTEXT_COMPARE_MODE_PAIR_2 = 1,
     99 } dnx_field_context_compare_mode_pair_e;
    100 
    101 /*
    102  * Enums
    103  * }
    104  */
    105 
    106 /*
    107  * FEM-related definitions.
    108  * {
    109  */
    110 /*
    111  * Verify the fem_bit_format is valid for specified unit
    112  * 'fem_bit_format' is the format indication for each bit on table,
    113  * say, FIELD_PMF_A_FEM_FIELD_SELECT_FEMS_2_15_MAP (element FIELD_FEM_BIT_VAL)
    114  * See dnx_field_fem_bit_info_t (element 'fem_bit_format')
    115  * See dnx_field_fem_bit_format_e
    116  */
    117 #define DNX_FIELD_FEM_BIT_FORMAT_VERIFY(_fem_bit_format)  \
    118     if (((unsigned int) _fem_bit_format >= (unsigned int) (DNX_FIELD_FEM_BIT_FORMAT_NUM)) ||       \
    119                 ((unsigned int) _fem_bit_format < (unsigned int) (DNX_FIELD_FEM_BIT_FORMAT_FIRST))) \
    120     { \
    121         SHR_ERR_EXIT(_SHR_E_PARAM, \
    122                      "fem_bit_format (%d) is out of range (Should be between %d and %d)\r\n", \
    123                      _fem_bit_format, DNX_FIELD_FEM_BIT_FORMAT_FIRST, DNX_FIELD_FEM_BIT_FORMAT_NUM - 1); \
    124     }
    125 /*
    126  * Verify the fem_id is valid for specified unit
    127  */
    128 #define DNX_FIELD_FEM_ID_VERIFY(_unit,_fem_id)  \
    129     if ((unsigned int) _fem_id >= (unsigned int) (dnx_data_field.stage.stage_info_get(unit, DNX_FIELD_STAGE_IPMF1)->nof_fem_id)) \
    130     { \
    131         SHR_ERR_EXIT(_SHR_E_PARAM, \
    132                      "fem_id (%d) is out of range (Should be between %d and %d)\r\n", \
    133                      _fem_id, 0, dnx_data_field.stage.stage_info_get(unit, DNX_FIELD_STAGE_IPMF1)->nof_fem_id - 1); \
    134     }
    135 /*
    136  * Verify the fem_condition_entry (of type dnx_field_fem_condition_entry_t) is valid for specified unit
    137  * - First, verify the the 'fem_action_valid' element is within range
    138  *   (smaller than DBAL_NOF_ENUM_FIELD_FEM_ACTION_VALID_VALUES
    139  * - Second, if it is valid (DBAL_ENUM_FVAL_FIELD_FEM_ACTION_VALID_FEM_ACTIONS_IS_ACTIVE),
    140  *   verify that the 'fem_map_index'; element is within range (0 - 3).
    141  */
    142 #define DNX_FIELD_FEM_CONDITION_ENTRY_VERIFY(_unit,_fem_condition_entry)  \
    143     if ((unsigned int)((_fem_condition_entry).fem_action_valid) < (unsigned int)DBAL_NOF_ENUM_FIELD_FEM_ACTION_VALID_VALUES) \
    144     { \
    145         if (((_fem_condition_entry).fem_action_valid) == DBAL_ENUM_FVAL_FIELD_FEM_ACTION_VALID_FEM_ACTIONS_IS_ACTIVE) \
    146         { \
    147             if ((unsigned int) ((_fem_condition_entry).fem_map_index) >= (unsigned int) (dnx_data_field.stage.stage_info_get(unit, DNX_FIELD_STAGE_IPMF1)->nof_fem_map_index)) \
    148             { \
    149                 SHR_ERR_EXIT(_SHR_E_PARAM, \
    150                      "fem_condition_entry.fem_map_index (%d) is out of range (Should be between %d and %d)\r\n", \
    151                      ((_fem_condition_entry).fem_map_index), 0, DBAL_NOF_ENUM_FIELD_FEM_ACTION_VALID_VALUES - 1); \
    152             } \
    153         } \
    154     } \
    155     else    \
    156     { \
    157         SHR_ERR_EXIT(_SHR_E_PARAM, \
    158              "fem_condition_entry.fem_action_valid (%d) is out of range (Should be between %d and %d)\r\n", \
    159              ((_fem_condition_entry).fem_action_valid), 0, dnx_data_field.stage.stage_info_get(unit, DNX_FIELD_STAGE_IPMF1)->nof_fem_map_index - 1); \
    160     }
    161 /*
    162  * Verify the fem_program is valid for specified unit
    163  */
    164 #define DNX_FIELD_FEM_PROGRAM_VERIFY(_unit,_fem_program)  \
    165     if ((unsigned int) _fem_program >= (unsigned int) (dnx_data_field.stage.stage_info_get(unit, DNX_FIELD_STAGE_IPMF1)->nof_fem_programs)) \
    166     { \
    167         SHR_ERR_EXIT(_SHR_E_PARAM, \
    168                      "fem_program (%d) is out of range (Should be between %d and %d)\r\n", \
    169                      _fem_program, 0, dnx_data_field.stage.stage_info_get(unit, DNX_FIELD_STAGE_IPMF1)->nof_fem_programs - 1); \
    170     }
    171 /*
    172  * Verify the fem_program is valid for specified unit
    173  */
    174 #define DNX_FIELD_FEM_MAP_INDEX_VERIFY(_unit,_fem_map_index)  \
    175     if ((unsigned int) _fem_map_index >= (unsigned int) (dnx_data_field.stage.stage_info_get(unit, DNX_FIELD_STAGE_IPMF1)->nof_fem_map_index)) \
    176     { \
    177         SHR_ERR_EXIT(_SHR_E_PARAM, \
    178                      "fem_map_index (%d) is out of range (Should be between %d and %d)\r\n", \
    179                      _fem_map_index, 0, dnx_data_field.stage.stage_info_get(unit, DNX_FIELD_STAGE_IPMF1)->nof_fem_map_index - 1); \
    180     }
    181 /*
    182  * Step by which 'fem key select' moves along result input.For each step, 32 are specified which
    183  * become the final input to FEM machine.
    184  * (See dbal_enum_value_field_field_pmf_a_fem_key_select_e)
    185  */
    186 #define DNX_FIELD_FEM_INPUT_OFFSET_RESOLUTION dnx_data_field.stage.stage_info_get(unit, DNX_FIELD_STAGE_IPMF1)->fem_key_select_resolution_in_bits
    187 /*
    188  * Number of meaningful data bits, in the common cases of TCAM and DE, on 'fem key select'.
    189  * (See dbal_enum_value_field_field_pmf_a_fem_key_select_e)
    190  */
    191 #define DNX_FIELD_FEM_COMMON_INPUT_SIZE dnx_data_field.stage.stage_info_get(unit, DNX_FIELD_STAGE_IPMF1)->nof_bits_in_fem_key_select
    192 /*
    193  * Verify some input parameters for dnx_field_fem_action_add():
    194  *   input_offset
    195  *   input_size
    196  *   fg_id
    197  */
    198 #define DNX_FIELD_INPUT_SIZE_OFFSET_VERIFY(_unit, _input_offset, _input_size, _fg_id)  \
    199     { \
    200         /*    \
    201          * Reach here if _input_offset is a multiple of DNX_FIELD_FEM_INPUT_OFFSET_RESOLUTION    \
    202          * (as it should be)    \
    203          */    \
    204         dnx_field_action_length_type_e _action_length_type;    \
    205         dnx_field_key_length_type_e _key_length_type;    \
    206         unsigned int _block_size;    \
    207         dnx_field_group_type_e _fg_type;    \
    208         _block_size = 0;    \
    209         SHR_IF_ERR_EXIT(dnx_field_group_type_get(_unit, _fg_id, &_fg_type));    \
    210         /*    \
    211          */    \
    212         switch (_fg_type)    \
    213         {    \
    214             case (DNX_FIELD_GROUP_TYPE_DIRECT_EXTRACTION):    \
    215             {    \
    216                 if ((_input_offset % DNX_FIELD_FEM_INPUT_OFFSET_RESOLUTION) != 0) \
    217                 { \
    218                     SHR_ERR_EXIT(_SHR_E_PARAM, \
    219                              "\r\n"  \
    220                              "For a direct extraction field group, input_offset (%d) should be a multiple of %d. Quit\r\n", \
    221                              _input_offset, DNX_FIELD_FEM_INPUT_OFFSET_RESOLUTION);    \
    222                 } \
    223                 if (_input_size != DNX_FIELD_FEM_COMMON_INPUT_SIZE) \
    224                 { \
    225                     SHR_ERR_EXIT(_SHR_E_PARAM, \
    226                              "\r\n"  \
    227                              "For a direct extraction field group, input_size (%d) should be %d. Quit\r\n", \
    228                              _input_size, DNX_FIELD_FEM_COMMON_INPUT_SIZE);    \
    229                 } \
    230                 SHR_IF_ERR_EXIT(dnx_field_group_key_length_type_get(_unit,_fg_id,&_key_length_type));    \
    231                 /*  \
    232                  * Input size is 'full key' for both 'half key' and 'full key'. That's how HW works...  \
    233                  */      \
    234                 if ((_key_length_type == DNX_FIELD_KEY_LENGTH_TYPE_HALF) || (_key_length_type == DNX_FIELD_KEY_LENGTH_TYPE_SINGLE))    \
    235                 {    \
    236                     _block_size = dnx_data_field.dir_ext.single_key_size_get(unit);    \
    237                 }    \
    238                 else    \
    239                 {    \
    240                     SHR_ERR_EXIT(_SHR_E_PARAM,    \
    241                              "\r\n"  \
    242                              "For a direct extraction field group, this key 'length type' is not allowed, key_length_type=%d (%s)\r\n",    \
    243                              _key_length_type, dnx_field_key_length_type_e_get_name(_key_length_type));    \
    244                 }    \
    245                 break;    \
    246             }    \
    247             case (DNX_FIELD_GROUP_TYPE_TCAM):    \
    248             case (DNX_FIELD_GROUP_TYPE_DIRECT_TABLE_TCAM):    \
    249             {    \
    250                 if ((_input_offset % DNX_FIELD_FEM_INPUT_OFFSET_RESOLUTION) != 0) \
    251                 { \
    252                     SHR_ERR_EXIT(_SHR_E_PARAM, \
    253                              "\r\n"  \
    254                              "For a TCAM field group, input_offset (%d) should be a multiple of %d. Quit\r\n", \
    255                              _input_offset, DNX_FIELD_FEM_INPUT_OFFSET_RESOLUTION);    \
    256                 } \
    257                 if (_input_size != DNX_FIELD_FEM_COMMON_INPUT_SIZE) \
    258                 { \
    259                     SHR_ERR_EXIT(_SHR_E_PARAM, \
    260                              "\r\n"  \
    261                              "For a TCAM field group,, input_size (%d) should be %d. Quit\r\n", \
    262                              _input_size, DNX_FIELD_FEM_COMMON_INPUT_SIZE);    \
    263                 } \
    264                 SHR_IF_ERR_EXIT(dnx_field_group_action_length_type_get(_unit,_fg_id,&_action_length_type));    \
    265                 /*    \
    266                  * Load block_size by the number of bits in the payload buffer (that    \
    267                  * contains all actions plus, potentially, some spare)    \
    268                  */    \
    269                 SHR_IF_ERR_EXIT(dnx_field_group_action_length_to_bit_size(_unit,_action_length_type,&_block_size));    \
    270                 break;    \
    271             }    \
    272             case (DNX_FIELD_GROUP_TYPE_EXEM):    \
    273             {    \
    274                   \
    275                 _block_size = 60; \
    276                 break;    \
    277             }    \
    278             case (DNX_FIELD_GROUP_TYPE_CONST):    \
    279             {    \
    280                 if (_input_offset != 0) \
    281                 { \
    282                     SHR_ERR_EXIT(_SHR_E_PARAM, \
    283                              "\r\n"  \
    284                              "For a Const field group, input_offset (%d) should be 0. Quit\r\n", \
    285                              _input_offset);    \
    286                 } \
    287                 if (_input_size != 0) \
    288                 { \
    289                     SHR_ERR_EXIT(_SHR_E_PARAM, \
    290                              "\r\n"  \
    291                              "For a Const field group,, input_size (%d) should be 0. Quit\r\n", \
    292                              _input_size);    \
    293                 } \
    294                 break;    \
    295             }    \
    296             default:    \
    297             {    \
    298                 SHR_IF_ERR_EXIT(dnx_field_group_action_length_type_get(_unit,_fg_id,&_action_length_type));    \
    299                 /*    \
    300                  * Load block_size by the number of bits in the payload buffer (that    \
    301                  * contains all actions plus, potentially, some spare    \
    302                  */    \
    303                 SHR_IF_ERR_EXIT(dnx_field_group_action_length_to_bit_size(_unit,_action_length_type,&_block_size));    \
    304                 break;    \
    305             }    \
    306         }    \
    307         /*    \
    308          * At this point, 'block_size' contains the number of bits in the buffer that makes    \
    309          * the 'input' to the FEM.    \
    310          * Make sure it contains specified '_input_offset' plus the 32 bits required to make    \
    311          * the 'chunk' that FEM uses.    \
    312          */    \
    313         if ((_input_offset + dnx_data_field.stage.stage_info_get(unit, DNX_FIELD_STAGE_IPMF1)->nof_bits_in_fem_key_select ) > _block_size)    \
    314         {    \
    315             SHR_ERR_EXIT(_SHR_E_PARAM,    \
    316                          "\r\n"  \
    317                          "Number of bits in 'container buffer' for input to FEM (%d) is smaller than \r\n"    \
    318                          "required for 'input_offset' (%d) plus 'chunk' size (%d). fg_type is %d (%s). Quit.\r\n",    \
    319                          _block_size, _input_offset, dnx_data_field.stage.stage_info_get(unit, DNX_FIELD_STAGE_IPMF1)->nof_bits_in_fem_key_select,    \
    320                          _fg_type, dnx_field_group_type_e_get_name(_fg_type));    \
    321         }    \
    322     }
    323 /*
    324  * }
    325  */
    326 
    327 /*
    328  * Action priority related definitions.
    329  * The Action priority is an encoding of the preferred FES.
    330  * SeeBCM_FIELD_ACTION_POSITION and BCM_FIELD_ACTION_PRIORITY.
    331  * {
    332  */
    333 
    334 /**
    335  * The position of the preferred location within the FES array represented in dnx_field_action_priority_t.
    336  * Parallel to BCM_FIELD_ACTION_ARRAY_OFFSET.
    337  */
    338 #define DNX_FIELD_ACTION_PRIORITY_FES_POSITION_PRIORITY_OFFSET       0
    339 
    340 /**
    341  * \brief
    342  *   Retrieve the part of the encoded priority which contains the
    343  *   position within the array of the corresponding FES or FEM.
    344  *
    345  * \param [in] priority -
    346  *   Encoded action priority, with mandatory position.
    347  *                        (dnx_field_action_priority_t)
    348  * \return
    349  *   FES/FEM position within FES/FEM array (dnx_field_action_position_t).
    350  */
    351 #define DNX_FIELD_ACTION_PRIORITY_PRIORITY_POSITION(priority)                 \
    352         (((priority) >> DNX_FIELD_ACTION_PRIORITY_FES_POSITION_PRIORITY_OFFSET)   \
    353         & BCM_FIELD_ACTION_PRIORITY_MASK)
    354 
    355 /**
    356  * \brief Retrieve the part of the encoded priority which contains the numerical priority.
    357  * \param [in] priority - Encoded action priority.
    358  *                        (dnx_field_action_priority_t)
    359  * \return
    360  *      Numerical priority (dnx_field_action_numerical_priority_t).
    361  */
    362 #define DNX_FIELD_ACTION_PRIORITY_FES_PRIORITY_NUMERICAL(priority)                \
    363         (((priority) >> DNX_FIELD_ACTION_PRIORITY_FES_POSITION_PRIORITY_OFFSET)   \
    364         & BCM_FIELD_ACTION_PRIORITY_MASK)
    365 
    366 /**
    367  * \brief Retrieve the FES ID
    368  *
    369  * \param [in] priority - Encoded action priority
    370  *                        (dnx_field_action_priority_t)
    371  * \return
    372  *      FES array (dnx_field_action_array_t).
    373  */
    374 #define DNX_FIELD_ACTION_PRIORITY_ARRAY(priority)                \
    375         (((priority) >> BCM_FIELD_ACTION_ARRAY_OFFSET)           \
    376         & BCM_FIELD_ACTION_ARRAY_MASK)
    377 
    378 /**
    379  * \brief Retrieve whether encoded priority (dnx_field_action_priority_t) mandated position or not.
    380  * \param [in] priority - Encoded action priority (dnx_field_action_priority_t).
    381  * \return
    382  *      TRUE if position is mandatory.
    383  *      FALSE if numerical priority.
    384  */
    385 #define DNX_FIELD_ACTION_PRIORITY_IS_POSITION(priority)                                   \
    386         ((((priority) & SAL_BIT(BCM_FIELD_ACTION_POSITION_PRIORITY_FLAG_OFFSET)) != 0) &&  \
    387          (((priority) & SAL_BIT(BCM_FIELD_ACTION_VALID_OFFSET)) != 0))
    388 
    389 /**
    390  * \brief Retrieve whether encoded priority (dnx_field_action_priority_t) has "don't care" bit set.
    391  * \param [in] priority - Encoded action priority (dnx_field_action_priority_t).
    392  * \return
    393  *      TRUE if priority has "don't care" bit set.
    394  *      FALSE otherwise.
    395  */
    396 #define DNX_FIELD_ACTION_PRIORITY_FES_PRIORITY_IS_DONT_CARE_BIT_SET(priority)                \
    397         (((priority) & SAL_BIT(BCM_FIELD_ACTION_DONT_CARE_OFFSET)) != 0)
    398 
    399 /**
    400  * \brief Retrieve whether encoded priority (dnx_field_action_priority_t) has the valid bit set.
    401  *        That alone does not make the priority valid.
    402  * \param [in] priority - Encoded action priority (dnx_field_action_priority_t).
    403  * \return
    404  *      TRUE if priority has valid bit set.
    405  *      FALSE otherwise.
    406  */
    407 #define DNX_FIELD_ACTION_PRIORITY_FES_PRIORITY_IS_VALID_BIT_SET(priority)                \
    408         (((priority) & SAL_BIT(BCM_FIELD_ACTION_VALID_OFFSET)) != 0)
    409 
    410 /**
    411  * \brief
    412  *        Verify that the action priority is a legal value
    413  *        Because we want to only have one "don't care" value and one "invalid" value, we prohibit the use of the
    414  *        flags for other values.
    415  * \param [in] priority - Action priority.
    416  * \return
    417  *      None.
    418           */
    419 #define DNX_FIELD_ACTION_PRIORITY_VERIFY(priority)                                                                \
    420 {                                                                                                                 \
    421     if ((DNX_FIELD_ACTION_PRIORITY_FES_PRIORITY_IS_VALID_BIT_SET(priority)) &&                                    \
    422         (DNX_FIELD_ACTION_PRIORITY_FES_PRIORITY_IS_DONT_CARE_BIT_SET(priority)) &&                                \
    423         (priority != BCM_FIELD_ACTION_DONT_CARE))                                                                 \
    424     {                                                                                                             \
    425         SHR_ERR_EXIT(_SHR_E_PARAM,                                                                                \
    426                      "Action priority 0x%08x has the \"Care\" bit set, but isn't \"don't care\" priority.\r\n",   \
    427                      priority);                                                                                   \
    428     }                                                                                                             \
    429     if ((DNX_FIELD_ACTION_PRIORITY_FES_PRIORITY_IS_VALID_BIT_SET(priority) == FALSE) &&                           \
    430         (priority != DNX_FIELD_ACTION_PRIORITY_INVALID) && (priority != BCM_FIELD_ACTION_INVALIDATE))             \
    431     {                                                                                                             \
    432         SHR_ERR_EXIT(_SHR_E_PARAM,                                                                                \
    433                      "Action priority 0x%08x has the \"valid\" bit zero, but isn't the invalid priority.\r\n",    \
    434                      priority);                                                                                   \
    435     }                                                                                                             \
    436 }
    437 
    438 /**
    439  * \brief
    440  *        Get the FES ID from a priority with mandatory position.
    441  *        We allow only even arrays for EFES, the odd arrays are for FEM.
    442  * \param [out] _fes_id  - The FES ID encoded by the priority.
    443  * \param [in] _unit     - Device ID.
    444  * \param [in] _field_stage    - The field stage.
    445  * \param [in] _priority - Encoded action priority.
    446  * \return
    447  *      None.
    448  */
    449 #define DNX_FIELD_ACTION_PRIORITY_POSITION_FES_ID_GET(_fes_id, _unit, _field_stage, _priority)                      \
    450 {                                                                                                                   \
    451     int _nof_fes_id_in_array;                                                                                       \
    452     int _nof_fes_id_in_stage;                                                                                       \
    453     int _nof_fes_array;                                                                                             \
    454     dnx_field_action_array_t _fes_array;                                                                            \
    455     dnx_field_action_position_t _fes_position;                                                                      \
    456     if (DNX_FIELD_ACTION_PRIORITY_IS_POSITION(_priority)==FALSE)                                       \
    457     {                                                                                                               \
    458         SHR_ERR_EXIT(_SHR_E_PARAM,                                                                                  \
    459                      "Action priority 0x%08x Is not a mandatory position priority.\r\n",                            \
    460                      _priority);                                                                                    \
    461     }                                                                                                               \
    462     _fes_array = DNX_FIELD_ACTION_PRIORITY_ARRAY(_priority);                                                        \
    463     if (dnx_data_field.common_max_val.nof_array_ids_get(_unit) <= _fes_array)                                       \
    464     {                                                                                                               \
    465         SHR_ERR_EXIT(_SHR_E_PARAM,                                                                                  \
    466                      "\r\n"                                                                                         \
    467                      "Action priority 0x%08X uses array id %d which is larger than max allowed (%d).\r\n",          \
    468                      _priority, _fes_array, dnx_data_field.common_max_val.nof_array_ids_get(_unit) - 1);            \
    469     }                                                                                                               \
    470     _fes_position = DNX_FIELD_ACTION_PRIORITY_PRIORITY_POSITION(_priority);                                         \
    471     _nof_fes_id_in_array = dnx_data_field.stage.stage_info_get(_unit, _field_stage)->nof_fes_id_per_array;          \
    472     _nof_fes_array = dnx_data_field.stage.stage_info_get(_unit, _field_stage)->nof_fes_array;                       \
    473     _nof_fes_id_in_stage = dnx_data_field.stage.stage_info_get(_unit, _field_stage)->nof_fes_instruction_per_context;\
    474     if (_nof_fes_array  <= 0)                                                                                       \
    475     {                                                                                                               \
    476         SHR_ERR_EXIT(_SHR_E_PARAM, "Stage \"%s\" (%d) has no EFES.\r\n", dnx_field_stage_text(_unit, _field_stage), _field_stage);\
    477     }                                                                                                               \
    478     if ((dnx_data_field.common_max_val.array_id_type_get(_unit,_fes_array)->is_fes) != 1)                           \
    479     {                                                                                                               \
    480         SHR_ERR_EXIT(_SHR_E_PARAM,                                                                                  \
    481                      "\r\n"                                                                                         \
    482                      "Action priority 0x%08X uses array %d which is not a FES array.\r\n",                          \
    483                      _priority, _fes_array);                                                                        \
    484     }                                                                                                               \
    485     if (dnx_data_field.common_max_val.array_id_type_get(_unit, _fes_array)->fes_array_index > (_nof_fes_array - 1)) \
    486     {                                                                                                               \
    487         SHR_ERR_EXIT(_SHR_E_PARAM,                                                                                  \
    488                      "Action priority 0x%08X encodes FES array %d, while the maximum for stage \"%s\" is %d.\r\n",  \
    489                      _priority, DNX_FIELD_ACTION_PRIORITY_ARRAY(_priority), dnx_field_stage_text(_unit, _field_stage),\
    490                      _nof_fes_array-1);                                                                             \
    491     }                                                                                                               \
    492     if (_fes_position >= _nof_fes_id_in_array)                                                                      \
    493     {                                                                                                               \
    494         SHR_ERR_EXIT(_SHR_E_PARAM,                                                                                  \
    495                      "Action priority 0x%08X encodes FES position within array %d, "                                \
    496                      "while the maximum for stage   \"%s\" is %d.\r\n",                                             \
    497                      _priority, DNX_FIELD_ACTION_PRIORITY_PRIORITY_POSITION(_priority),                             \
    498                      dnx_field_stage_text(_unit, _field_stage), _nof_fes_id_in_array-1);                            \
    499     }                                                                                                               \
    500     _fes_id = (dnx_data_field.common_max_val.array_id_type_get(_unit, _fes_array)->fes_array_index * _nof_fes_id_in_array) + _fes_position;  \
    501     if (_fes_id >= _nof_fes_id_in_stage)                                                                            \
    502     {                                                                                                               \
    503         SHR_ERR_EXIT(_SHR_E_PARAM,                                                                                  \
    504                      "Action priority 0x%08X encodes FES ID %d, while the maximum for stage \"%s\" is %d.\r\n",     \
    505                      _priority, _fes_id, dnx_field_stage_text(_unit, _field_stage), _nof_fes_id_in_stage-1);        \
    506     }                                                                                                               \
    507 }
    508 
    509 /**
    510  * \brief
    511  *        Get the EFES array and position within array from a FES ID
    512  * \param [out] _array  - The EFES array.
    513  * \param [out] _position  - The EFES position within the array.
    514  * \param [in] _unit     - Device ID.
    515  * \param [in] _field_stage  - The field stage.
    516  * \param [in] _fes_id - EFES ID, which array and position, should be returned.
    517  * \return
    518  *      None.
    519  */
    520 #define DNX_FIELD_ACTION_FES_ID_ARRAY_POSITION_GET(_array, _position, _unit, _field_stage, _fes_id)               \
    521 {                                                                                                                 \
    522     int _nof_fes_id_in_array;                                                                                     \
    523     int _nof_fes_id_in_stage;                                                                                     \
    524     int _nof_fes_array;                                                                                           \
    525     _nof_fes_id_in_array = dnx_data_field.stage.stage_info_get(_unit, _field_stage)->nof_fes_id_per_array;        \
    526     _nof_fes_array = dnx_data_field.stage.stage_info_get(_unit, _field_stage)->nof_fes_array;                     \
    527     _nof_fes_id_in_stage = dnx_data_field.stage.stage_info_get(_unit, _field_stage)->nof_fes_instruction_per_context;\
    528     if (_nof_fes_array  <= 0)                                                                                     \
    529     {                                                                                                             \
    530         SHR_ERR_EXIT(_SHR_E_PARAM, "Stage \"%s\" (%d) has no EFES. \r\n", dnx_field_stage_text(_unit, _field_stage), _field_stage);\
    531     }                                                                                                             \
    532     if (_fes_id >= _nof_fes_id_in_stage)                                                                          \
    533     {                                                                                                             \
    534         SHR_ERR_EXIT(_SHR_E_PARAM,                                                                                \
    535                      "EFES ID %d is bigger then the maximum for stage \"%s\" is %d.\r\n",                         \
    536                      _fes_id, dnx_field_stage_text(_unit, _field_stage), _nof_fes_id_in_stage - 1);               \
    537     }                                                                                                             \
    538     _array = ((_fes_id / _nof_fes_id_in_array) * 2);                                                              \
    539     _position = (_fes_id % _nof_fes_id_in_array);                                                                 \
    540     if ((_array/2) >= _nof_fes_array)                                                                             \
    541     {                                                                                                             \
    542      SHR_ERR_EXIT(_SHR_E_PARAM,                                                                                   \
    543                   "EFES ARRAY %d is bigger then the maximum for stage \"%s\" is %d.\r\n",                         \
    544                    _array, dnx_field_stage_text(_unit, _field_stage), _nof_fes_array - 1);                        \
    545     }                                                                                                             \
    546 }
    547 /**
    548  * \brief
    549  *   Get the FEM ID from encoded 'action_priority'.
    550  *   Encoding is assumed to have been carried out using BCM_FIELD_ACTION_POSITION.
    551  *   We allow only odd array ids for FEM, the even arrays are for FEM.
    552  *   See 'remark' below.
    553  * \param [out] _fem_id  -
    554  *   The FEM ID as extracted from _action_priority.
    555  * \param [in] _unit     -
    556  *   Device ID.
    557  * \param [in] _encoded_position -
    558  *   Variable of type bcm_field_action_priority_t.
    559  *   Encoded position of a FEM. Encoding is done using 'array_id' and 'position'.
    560  *   See 'BCM_FIELD_ACTION_POSITION' and 'remark' below
    561  * \return
    562  *   See '_fem_id' above.
    563  * \remark
    564  *   'Stage' is not an input parameter here since FEMs are only relevant for IPMF2.
    565  *
    566  *   FESes and FEMs are assigned priority, related to their corresponding actions.
    567  *   The priority layout of FESes and FEMs is as follows:
    568  *
    569  * Priority:      LOW        ...       ...      HIGH
    570  * Array
    571  *   id:           0          1         2        3
    572  * Type:          FES        FEM       FES      FEM
    573  * Identifier:    0-15       0-7       16-31    8-15
    574  * \see
    575  *   * DNX_FIELD_ACTION_PRIORITY_POSITION_FES_ID_GET
    576  *   * bcm_field_fem_action_add
    577  *   * bcm_dnx_field_fem_action_add
    578  *   * bcm_field_fem_action_info_get
    579  *   * bcm_dnx_field_fem_action_info_get
    580  *   * bcm_field_fem_action_delete
    581  *   * bcm_dnx_field_fem_action_delete
    582  */
    583 #define DNX_FIELD_ACTION_PRIORITY_POSITION_FEM_ID_GET(_fem_id, _unit, _encoded_position)                          \
    584 {                                                                                                                 \
    585     int _nof_fem_id_per_array;                                                                                     \
    586     int _nof_fem_id_in_stage;                                                                                     \
    587     int _nof_fem_array;                                                                                           \
    588     dnx_field_action_position_t _fem_position;                                                                    \
    589     dnx_field_action_array_t _fem_array;                                                                          \
    590     dnx_field_stage_e _field_stage;                                                                               \
    591                                                                                                                   \
    592     if (DNX_FIELD_ACTION_PRIORITY_IS_POSITION(_encoded_position) == FALSE)                                        \
    593     {                                                                                                             \
    594         SHR_ERR_EXIT(_SHR_E_PARAM,                                                                                \
    595                      "\r\n"                                                                                       \
    596                      "_encoded_position (0x%08X) is not a 'position' one\r\n"                                     \
    597                      "==> (Bit at offset %d is zero). Quit.",                                                     \
    598                      _encoded_position, BCM_FIELD_ACTION_POSITION_PRIORITY_FLAG_OFFSET);                          \
    599     }                                                                                                             \
    600     _fem_array = DNX_FIELD_ACTION_PRIORITY_ARRAY(_encoded_position);                                              \
    601     if (dnx_data_field.common_max_val.nof_array_ids_get(_unit) <= _fem_array)                                     \
    602     {                                                                                                             \
    603         SHR_ERR_EXIT(_SHR_E_PARAM,                                                                                \
    604                      "\r\n"                                                                                       \
    605                      "_encoded_position 0x%08X uses array id %d which is larger than max allowed (%d).\r\n",      \
    606                      _encoded_position, _fem_array, dnx_data_field.common_max_val.nof_array_ids_get(_unit) - 1);  \
    607     }                                                                                                             \
    608     if ((dnx_data_field.common_max_val.array_id_type_get(_unit, _fem_array)->is_fem) != 1)                        \
    609     {                                                                                                             \
    610         SHR_ERR_EXIT(_SHR_E_PARAM,                                                                                \
    611                      "\r\n"                                                                                       \
    612                      "_encoded_position 0x%08X uses array %d which is not a FEM array.\r\n",                      \
    613                      _encoded_position, _fem_array);                                                              \
    614     }                                                                                                             \
    615     _field_stage = DNX_FIELD_STAGE_IPMF2;                                                                         \
    616     _nof_fem_id_per_array = dnx_data_field.stage.stage_info_get(_unit, _field_stage)->nof_fem_id_per_array;        \
    617     _nof_fem_array = dnx_data_field.stage.stage_info_get(_unit, _field_stage)->nof_fem_array;                     \
    618     if (_nof_fem_array  == 0)                                                                                     \
    619     {                                                                                                             \
    620         /*                                                                                                        \
    621          * This verification is redundant but is left here to cross verify DATA table.                            \
    622          */                                                                                                       \
    623         SHR_ERR_EXIT(_SHR_E_PARAM,                                                                                \
    624             "Stage \"%s\" (%d) has no FEMs. \r\n",                                                                \
    625             dnx_field_stage_text(_unit, _field_stage), _field_stage);                                             \
    626     }                                                                                                             \
    627     if (dnx_data_field.common_max_val.array_id_type_get(_unit, _fem_array)->fem_array_index > (_nof_fem_array - 1)) \
    628     {                                                                                                               \
    629         SHR_ERR_EXIT(_SHR_E_PARAM,                                                                                  \
    630                      "\r\n"                                                                                         \
    631                      "_encoded_position 0x%08X contains FEM array id %d,\r\n"                                       \
    632                      "while the maximum for stage \"%s\" is %d.\r\n",                                               \
    633                      _encoded_position, _fem_array,                                                                 \
    634                      dnx_field_stage_text(_unit, _field_stage),                                                     \
    635                      _nof_fem_array - 1);                                                                           \
    636     }                                                                                                               \
    637     _fem_position = DNX_FIELD_ACTION_PRIORITY_PRIORITY_POSITION(_encoded_position);                                 \
    638     if (_fem_position >= _nof_fem_id_per_array)                                                                      \
    639     {                                                                                                               \
    640         SHR_ERR_EXIT(_SHR_E_PARAM,                                                                                  \
    641                      "\r\n"                                                                                         \
    642                      "_encoded_position 0x%08X contains FEM position of %d within array_id %d,\r\n"                 \
    643                      "while the maximum for stage   \"%s\" is %d.\r\n",                                             \
    644                      _encoded_position, _fem_position, _fem_array,                                                  \
    645                      dnx_field_stage_text(_unit, _field_stage), _nof_fem_id_per_array-1);                            \
    646     }                                                                                                               \
    647     _fem_id =                                                                                                       \
    648         (dnx_data_field.common_max_val.array_id_type_get(                                                           \
    649                 _unit, _fem_array)->fem_array_index * _nof_fem_id_per_array) + _fem_position;                        \
    650     _nof_fem_id_in_stage = dnx_data_field.stage.stage_info_get(_unit, _field_stage)->nof_fems_per_context;          \
    651     if (_fem_id >= _nof_fem_id_in_stage)                                                                            \
    652     {                                                                                                               \
    653         SHR_ERR_EXIT(_SHR_E_PARAM,                                                                                  \
    654                      "_encoded_position 0x%08X encodes FEM ID %d, while the maximum for stage \"%s\" is %d.\r\n",   \
    655                      _encoded_position, _fem_id, dnx_field_stage_text(_unit, _field_stage), _nof_fem_id_in_stage-1);\
    656     }                                                                                                               \
    657 }
    658 /**
    659  * \brief
    660  *   Get the encoded 'action_priority' from FEM ID.
    661  *   Encoding is assumed to have been carried out using BCM_FIELD_ACTION_POSITION.
    662  *   We allow only odd array ids for FEM, the even arrays are for FEM.
    663  *   See 'remark' below.
    664  * \param [out] _encoded_position -
    665  *   Variable of type bcm_field_action_priority_t.
    666  *   Encoded position of a FEM. Encoding is done using 'array_id' and 'position'.
    667  *   See 'BCM_FIELD_ACTION_POSITION' and 'remark' below
    668  * \param [in] _unit     -
    669  *   Device ID.
    670  * \param [in] _fem_id  -
    671  *   The FEM ID.
    672  * \return
    673  *   See '_fem_id' above.
    674  * \remark
    675  *   'Stage' is not an input parameter here since FEMs are only relevant for IPMF2.
    676  *
    677  *   FESes and FEMs are assigned priority, related to their corresponding actions.
    678  *   The priority layout of FESes and FEMs is as follows:
    679  *
    680  * Priority:      LOW        ...       ...      HIGH
    681  * Array
    682  *   id:           0          1         2        3
    683  * Type:          FES        FEM       FES      FEM
    684  * Identifier:    0-15       0-7       16-31    8-15
    685  * \see
    686  *   * DNX_FIELD_ACTION_PRIORITY_POSITION_FES_ID_GET
    687  *   * DNX_FIELD_ACTION_PRIORITY_POSITION_FEM_ID_GET
    688  */
    689 #define DNX_FIELD_ACTION_FEM_ID_ENCODED_POSITION_GET(_encoded_position, _unit, _fem_id)                           \
    690 {                                                                                                                 \
    691     int _nof_fem_id_per_array;                                                                                    \
    692     int _nof_fem_array;                                                                                           \
    693     int _nof_fem_id;                                                                                              \
    694     int _array;                                                                                                   \
    695     int _position;                                                                                                \
    696     dnx_field_stage_e _field_stage = DNX_FIELD_STAGE_IPMF2;                                                       \
    697     _nof_fem_id_per_array = dnx_data_field.stage.stage_info_get(_unit, _field_stage)->nof_fem_id_per_array;       \
    698     _nof_fem_array = dnx_data_field.stage.stage_info_get(_unit, _field_stage)->nof_fem_array;                     \
    699     _nof_fem_id = dnx_data_field.stage.stage_info_get(_unit, _field_stage)->nof_fem_id;                           \
    700     if (_fem_id >= _nof_fem_id)                                                                                   \
    701     {                                                                                                             \
    702         SHR_ERR_EXIT(_SHR_E_PARAM, "FEM ID %d is bigger then the maximum %d.\r\n", _fem_id, _nof_fem_id - 1);     \
    703     }                                                                                                             \
    704     _array = (((_fem_id / _nof_fem_id_per_array) * 2) + 1);                                                       \
    705     _position = (_fem_id % _nof_fem_id_per_array);                                                                \
    706     if (((_array - 1) / 2) >= _nof_fem_array)                                                                     \
    707     {                                                                                                             \
    708      SHR_ERR_EXIT(_SHR_E_INTERNAL, "FEM ARRAY %d is bigger then the maximum %d.\r\n", _array, _nof_fem_array - 1);\
    709     }                                                                                                             \
    710     _encoded_position = BCM_FIELD_ACTION_POSITION(_array, _position);                                             \
    711 }
    712 /*
    713  * }
    714  */
    715 /*
    716  * Verify the _context_id is allocated for a specified _stage
    717  * If 'context_id' is not allocated for that '_stage', go to exit with error _SHR_E_NOT_FOUND
    718  * If '_no_print' is non-zero then just set error code and go to exit. Otherwise,
    719  * also print error message.
    720  */
    721 #define DNX_FIELD_CONTEXT_IS_ALLOCATED(_stage, _context_id, _no_print) \
    722     do \
    723     { \
    724         uint8 _is_allocated = 0; \
    725         SHR_IF_ERR_EXIT(dnx_field_context_id_is_allocated(unit, _stage, _context_id, &_is_allocated)); \
    726         if (!_is_allocated) \
    727         { \
    728             if (_no_print != 0) \
    729             { \
    730                 SHR_SET_CURRENT_ERR(_SHR_E_NOT_FOUND); \
    731             } \
    732             else \
    733             { \
    734                 SHR_ERR_EXIT(_SHR_E_NOT_FOUND, \
    735                          "context_id (%d) is not allocated to stage %s \r\n", \
    736                          _context_id, dnx_field_stage_text(unit, _stage)); \
    737             } \
    738         } \
    739     } while (0)
    740 
    741 /*
    742  * Verify the context_id is valid for specified unit
    743  */
    744 #define DNX_FIELD_CONTEXT_ID_VERIFY(_unit,_context_id)                                                   \
    745     if ((unsigned int) (_context_id) >= (unsigned int) (dnx_data_field.common_max_val.nof_contexts_get(_unit))) \
    746     { \
    747         SHR_ERR_EXIT(_SHR_E_PARAM, \
    748                      "context_id (%d) is out of range (Should be between %d and %d)\r\n", \
    749                      _context_id, 0, dnx_data_field.common_max_val.nof_contexts_get(_unit) - 1); \
    750     }
    751 
    752 /**
    753  * Verify the field group ID is in range for current unit
    754  */
    755 #define DNX_FIELD_GROUP_ID_VERIFY(_fg_id)                                                   \
    756     if ((unsigned int) (_fg_id) >= (unsigned int) (dnx_data_field.group.nof_fgs_get(unit))) \
    757     { \
    758         SHR_ERR_EXIT(_SHR_E_PARAM, \
    759                      "_fg_id (%d) is out of range (Should be between %d and %d)\r\n", \
    760                      _fg_id, 0, dnx_data_field.group.nof_fgs_get(unit) - 1); \
    761     }
    762 /**
    763  * Verify the field group ID is in range for current unit
    764  */
    765 #define DNX_FIELD_GROUP_ID_KBP_VERIFY(_fg_id)                                                   \
    766     if ((unsigned int) (_fg_id) >= (unsigned int) (dnx_data_field.kbp.nof_fgs_get(unit))) \
    767     { \
    768         SHR_ERR_EXIT(_SHR_E_PARAM, \
    769                      "_fg_id (%d) is out of range (Should be between %d and %d)\r\n", \
    770                      _fg_id, 0, dnx_data_field.kbp.nof_fgs_get(unit) - 1); \
    771     }
    772 
    773 /**
    774  * Verify the stage is valid.
    775  */
    776 #define DNX_FIELD_STAGE_VERIFY(_stage)                                                   \
    777     if (((int) (_stage) < DNX_FIELD_STAGE_FIRST) || (_stage >= DNX_FIELD_STAGE_NOF))  \
    778     {  \
    779         SHR_ERR_EXIT(_SHR_E_PARAM,  \
    780                      "\r\n" \
    781                      "field_stage (%d) is out of range (Should be between %d and %d)\r\n",  \
    782                      _stage, DNX_FIELD_STAGE_FIRST, DNX_FIELD_STAGE_NOF - 1);  \
    783     }
    784 /**
    785  * Verify that 'field group type' is valid.
    786  * See dnx_field_group_type_e
    787  */
    788 #define DNX_FIELD_FG_TYPE_VERIFY(_fg_type)                                                   \
    789     if (((int) (_fg_type) < DNX_FIELD_GROUP_TYPE_FIRST) || (_fg_type >= DNX_FIELD_GROUP_TYPE_NOF))  \
    790     {  \
    791         SHR_ERR_EXIT(_SHR_E_PARAM,  \
    792                      "\r\n" \
    793                      "fg_type (%d) is out of range (Should be between %d and %d)\r\n",  \
    794                      _fg_type, DNX_FIELD_GROUP_TYPE_FIRST, DNX_FIELD_GROUP_TYPE_NOF - 1);  \
    795     }
    796 /**
    797  * Verify that 'key id' is valid.
    798  * See dbal_enum_value_field_field_key_e
    799  */
    800 #define DNX_FIELD_KEY_ID_VERIFY(_key_id)                                                   \
    801     if (((int) (_key_id) < DBAL_ENUM_FVAL_FIELD_KEY_A) || ((_key_id) >= DBAL_NOF_ENUM_FIELD_KEY_VALUES))  \
    802     {  \
    803         SHR_ERR_EXIT(_SHR_E_PARAM,  \
    804                      "\r\n" \
    805                      "key_id (%d) is out of range (Should be between %d and %d)\r\n",  \
    806                      _key_id, DBAL_ENUM_FVAL_FIELD_KEY_A, DBAL_NOF_ENUM_FIELD_KEY_VALUES - 1);  \
    807     }
    808 /**
    809  * Verify the field group ID is valid for specified unit
    810  */
    811 #define DNX_FIELD_FG_ID_VERIFY(_unit,_fg_id)                                                   \
    812         if ((unsigned int) (_fg_id) >= (unsigned int) (dnx_data_field.group.nof_fgs_get(_unit))) \
    813         { \
    814             SHR_ERR_EXIT(_SHR_E_PARAM, \
    815                          "\r\n" \
    816                          "Field Group ID (%d) is out of range (Should be between %d and %d)\r\n", \
    817                          _fg_id, 0, dnx_data_field.group.nof_fgs_get(_unit) - 1); \
    818         }
    819 /**
    820  * Verify the compare pair ID is valid for specified unit
    821  */
    822 #define DNX_FIELD_COMPARE_PAIR_VERIFY(_unit,_pair_id)                                                   \
    823         if ((unsigned int) (_pair_id) >= (unsigned int) (dnx_data_field.common_max_val.nof_compare_pairs_get(_unit))) \
    824         { \
    825             SHR_ERR_EXIT(_SHR_E_PARAM, \
    826                          "\r\n" \
    827                          "Compare pair ID (%d) is out of range (Should be %d or %d)\r\n", \
    828                          _pair_id, 0, (dnx_data_field.common_max_val.nof_compare_pairs_get(_unit) - 1)); \
    829         }
    830 /**
    831  * Verify the ACE group ID is valid for specified unit
    832  */
    833 #define DNX_FIELD_ACE_ID_VERIFY(_unit,_ace_id)                                                      \
    834         if ((unsigned int) (_ace_id) >= (unsigned int) (dnx_data_field.ace.nof_ace_id_get(_unit))) \
    835         { \
    836             SHR_ERR_EXIT(_SHR_E_PARAM, \
    837                          "ACE ID (%d) is out of range (Should be between %d and %d)\r\n", \
    838                          _ace_id, 0, dnx_data_field.ace.nof_ace_id_get(_unit) - 1); \
    839         }
    840 
    841  /**
    842  * Check if an ACE format ID is within the range of ACE (ACL extension) or not (for example if it is a PPMC ACE format
    843  * or operates on outlifs).
    844  */
    845 #define DNX_FIELD_ACE_FORMAT_ID_IS_ACE(_unit, _ace_format_id)                                            \
    846     ((_ace_format_id) >= dnx_data_field.ace.ace_id_pmf_alloc_first_get(_unit) &&                           \
    847      (_ace_format_id) <= dnx_data_field.ace.ace_id_pmf_alloc_last_get(_unit))
    848 
    849 /**
    850  * Check if an ACE key ID is within the range of ACE (ACL extension) or not (for example if it is a PPMC ACE format
    851  * or operates on outlifs).
    852  */
    853 #define DNX_FIELD_ACE_KEY_IS_ACE(_unit, _ace_key)                                            \
    854     ((_ace_key) >= dnx_data_field.ace.min_key_range_pmf_get(_unit) &&                          \
    855      (_ace_key) <= dnx_data_field.ace.max_key_range_pmf_get(_unit))
    856 
    857 /**
    858  * Check if any of the input types of the supplied _qual_info(dnx_field_qual_attach_info_t) is cascaded.
    859  * If yes, sets the return parameter '_cascaded' to TRUE, else it stays FALSE.
    860  */
    861 #define DNX_FIELD_IS_ANY_QUAL_CASCADED(_unit, _qual_info, _cascaded)                                                            \
    862     do                                                                                                                          \
    863     {                                                                                                                           \
    864         int _qual_index;                                                                                                         \
    865         _cascaded = FALSE;                                                                                                      \
    866         for (_qual_index = 0; _qual_index < DNX_DATA_MAX_FIELD_GROUP_NOF_QUALS_PER_FG &&                                          \
    867                  _qual_info[_qual_index].input_type != DNX_FIELD_INPUT_TYPE_INVALID; _qual_index++)                               \
    868         {                                                                                                                       \
    869             if (_qual_info[_qual_index].input_type == DNX_FIELD_INPUT_TYPE_CASCADED)                                             \
    870             {                                                                                                                   \
    871                 _cascaded = TRUE;                                                                                              \
    872                 break;                                                                                                          \
    873             }                                                                                                                   \
    874         }                                                                                                                       \
    875     }                                                                                                                           \
    876     while(0)
    877 
    878 /*
    879  * } Macros
    880  */
    881 
    882 /*
    883  * { Define
    884  */
    885 
    886 /*
    887  * 'Invalid' indication for FEM_KEY_SELECT field (in IPPC_PMF_FEM_PROGRAM)
    888  * This should occupy the same number of bits as FEM_KEY_SELECT field,
    889  * all set to '1' (Maximal value within this field).
    890  */
    891 #define DNX_FIELD_FEM_KEY_SELECT_INVALID 127
    892 /*
    893  * 'Invalid' indication for range min/max value
    894  */
    895 #define DNX_FIELD_RANGE_VALUE_INVALID (-1)
    896 
    897 /**
    898  * Default context is created for case when TCAM CS is miss and context 0 is chosen by defualt
    899  * If user dont want to configure preselectors he can use default context for grou_context_attach
    900  * The default context is created on init for all stages
    901  */
    902 #define DNX_FIELD_CONTEXT_ID_DEFAULT(_unit) (dnx_data_field.context.default_context_get(_unit))
    903 
    904 /** The FES program ID that is the default FES program ID and performs only invalid actions.*/
    905 #define DNX_ALGO_FIELD_ZERO_FES_PROGRAM           0
    906 /** The FES action mask ID that is the default mask.*/
    907 #define DNX_ALGO_FIELD_ZERO_FES_ACTION_MASK_ID    0
    908 /** The default FES action mask, defined as the one that does nothing to the action output.*/
    909 #define DNX_ALGO_FIELD_ALL_ZERO_FES_ACTION_MASK   0
    910 /**
    911  * The FES action mask ID that is the default mask for the ACE ACR.
    912  * Different from DNX_ALGO_FIELD_ZERO_FES_ACTION_MASK_ID because the ACE ACR has a different number of action masks
    913  * than the PMF EFESes.
    914  */
    915 #define DNX_ALGO_FIELD_ZERO_FES_ACE_ACTION_MASK_ID    0
    916 
    917 /**
    918  * The default value of the 'input argument' parameter in attach info.
    919  * At the moment serves only as the default layer index.
    920  */
    921 #define DNX_FIELD_ATTACH_INFO_FIELD_INPUT_ARG_DEFAULT  (0)
    922 /**
    923  * The default value of the 'offset' parameter in attach info.
    924  */
    925 #define DNX_FIELD_ATTACH_INFO_FIELD_OFFSET_DEFAULT (0)
    926 /**
    927  * Determines if we allow the user to disable the valid bit for non-void actions in a
    928  * lookup field group (TCAM, EXEM, ACE...).
    929  * The reason we prohibit users from not nosing valid bits for non void actions on all field groups except
    930  * direct exraction and KBP, is that we cannot disable them if we have a miss.
    931  * Once we have the use of the EFES 2msb feature we could disable those actions if we have a miss,
    932  * and we expect to enable this constant (or tight it altogether.)
    933  */
    934 #define DNX_FIELD_ALLOW_VALID_BIT_CHOICE_FOR_LOOKUP_FG (0)
    935 /**
    936  * In order to determine if the MDB profile supports EXEM, we determine the minimum capacity for EXEM
    937  * for which we allow an EXEM field group to be configured.
    938  */
    939 #define DNX_FIELD_EXEM_MINIMUM_CAPACITY (3)
    940 /**
    941  * The maximum number of context selection qualifiers for a single stage.
    942  */
    943 #define DNX_FIELD_CS_QUAL_NOF_MAX (42)
    944 /**
    945  * The minimum number of ACL keys for to be reserved in KBP for each FWD context.
    946  */
    947 #define DNX_FIELD_KBP_ACL_KEYS_MIN (2)
    948 /**
    949  * The minimum number of bits required for VMV.
    950  * At least 2 bits to support up to one quarter entries, plus 2 bits for EFES 2MSB feature.
    951  */
    952 #define DNX_FIELD_EXEM_MIN_VMV_SIZE (2+2)
    953 
    954 /*
    955  * } Define Constant
    956  */
    957 
    958 /*
    959  * { Define Constant Invalids
    960  */
    961 /**
    962  * Invalid indication for 'FEM program'.
    963  * See, for example, dnx_field_actions_fem_set() or dnx_field_fem_action_add()
    964  */
    965 #define DNX_FIELD_FEM_PROGRAM_INVALID      ((dnx_field_fem_program_t)(-1))
    966 /*
    967  * } Define
    968  */
    969 
    970 #endif /* DNX_FIELD_H_INCLUDED */